/* See also: ia_css_dma_configure_from_info() */ static bool calculate_isys2401_dma_port_cfg( const input_system_cfg_t *isys_cfg, bool raw_packed, bool metadata, isys2401_dma_port_cfg_t *cfg) { int32_t bits_per_pixel; int32_t pixels_per_line; int32_t align_req_in_bytes; /* TODO: Move metadata away from isys_cfg to application layer */ if (metadata) { bits_per_pixel = isys_cfg->metadata.bits_per_pixel; pixels_per_line = isys_cfg->metadata.pixels_per_line; align_req_in_bytes = isys_cfg->metadata.align_req_in_bytes; } else { bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel; pixels_per_line = isys_cfg->input_port_resolution.pixels_per_line; align_req_in_bytes = isys_cfg->input_port_resolution.align_req_in_bytes; } cfg->stride = calculate_stride(bits_per_pixel, pixels_per_line, raw_packed, align_req_in_bytes); if (!raw_packed) bits_per_pixel = CEIL_MUL(bits_per_pixel, 8); cfg->elements = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel; cfg->cropping = 0; cfg->width = CEIL_DIV(cfg->stride, HIVE_ISP_DDR_WORD_BYTES); return true; }
static bool acquire_ib_buffer( int32_t bits_per_pixel, int32_t pixels_per_line, int32_t lines_per_frame, int32_t align_in_bytes, bool online, ib_buffer_t *buf) { buf->stride = calculate_stride(bits_per_pixel, pixels_per_line, false, align_in_bytes); if (online) buf->lines = 4; /* use double buffering for online usecases */ else buf->lines = 2; (void)(lines_per_frame); return ia_css_isys_ibuf_rmgr_acquire(buf->stride * buf->lines, &buf->start_addr); }
static bool calculate_ibuf_ctrl_cfg( const input_system_channel_t *channel, const input_system_input_port_t *input_port, const input_system_cfg_t *isys_cfg, ibuf_ctrl_cfg_t *cfg) { const int32_t bits_per_byte = 8; int32_t bits_per_pixel; int32_t bytes_per_pixel; int32_t left_padding; (void)input_port; bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel; bytes_per_pixel = ceil_div(bits_per_pixel, bits_per_byte); left_padding = CEIL_MUL(isys_cfg->output_port_attr.left_padding, ISP_VEC_NELEMS) * bytes_per_pixel; cfg->online = isys_cfg->online; cfg->dma_cfg.channel = channel->dma_channel; cfg->dma_cfg.cmd = _DMA_V2_MOVE_A2B_NO_SYNC_CHK_COMMAND; cfg->dma_cfg.shift_returned_items = 0; cfg->dma_cfg.elems_per_word_in_ibuf = 0; cfg->dma_cfg.elems_per_word_in_dest = 0; cfg->ib_buffer.start_addr = channel->ib_buffer.start_addr; cfg->ib_buffer.stride = channel->ib_buffer.stride; cfg->ib_buffer.lines = channel->ib_buffer.lines; /* * [email protected]: * "dest_buf_cfg" should be part of the input system output * port configuration. * * TODO: move "dest_buf_cfg" to the input system output * port configuration. */ /* input_buf addr only available in sched mode; this buffer is allocated in isp, crun mode addr can be passed by after ISP allocation */ if (cfg->online) { cfg->dest_buf_cfg.start_addr = ISP_INPUT_BUF_START_ADDR + left_padding; cfg->dest_buf_cfg.stride = bytes_per_pixel * isys_cfg->output_port_attr.max_isp_input_width; cfg->dest_buf_cfg.lines = LINES_OF_ISP_INPUT_BUF; } else if (isys_cfg->raw_packed) { cfg->dest_buf_cfg.stride = calculate_stride(bits_per_pixel, isys_cfg->input_port_resolution.pixels_per_line, isys_cfg->raw_packed, isys_cfg->input_port_resolution.align_req_in_bytes); } else { cfg->dest_buf_cfg.stride = channel->ib_buffer.stride; } /* * [email protected]: * "items_per_store" is hard coded as "1", which is ONLY valid * when the CSI-MIPI long packet is transferred. * * TODO: After the 1st stage of MERR+, make the proper solution to * configure "items_per_store" so that it can also handle the CSI-MIPI * short packet. */ cfg->items_per_store = 1; cfg->stores_per_frame = isys_cfg->input_port_resolution.lines_per_frame; cfg->stream2mmio_cfg.sync_cmd = _STREAM2MMIO_CMD_TOKEN_SYNC_FRAME; /* TODO: Define conditions as when to use store words vs store packets */ cfg->stream2mmio_cfg.store_cmd = _STREAM2MMIO_CMD_TOKEN_STORE_PACKETS; return true; }
unsigned int loadKTX(const char * filename, unsigned int tex) { FILE * fp; GLuint temp = 0; GLuint retval = 0; header h; size_t data_start, data_end; unsigned char * data; GLenum target = GL_NONE; fp = fopen(filename, "rb"); if (!fp) return 0; if (fread(&h, sizeof(h), 1, fp) != 1) goto fail_read; if (memcmp(h.identifier, identifier, sizeof(identifier)) != 0) goto fail_header; if (h.endianness == 0x04030201) { // No swap needed } else if (h.endianness == 0x01020304) { // Swap needed h.endianness = swap32(h.endianness); h.gltype = swap32(h.gltype); h.gltypesize = swap32(h.gltypesize); h.glformat = swap32(h.glformat); h.glinternalformat = swap32(h.glinternalformat); h.glbaseinternalformat = swap32(h.glbaseinternalformat); h.pixelwidth = swap32(h.pixelwidth); h.pixelheight = swap32(h.pixelheight); h.pixeldepth = swap32(h.pixeldepth); h.arrayelements = swap32(h.arrayelements); h.faces = swap32(h.faces); h.miplevels = swap32(h.miplevels); h.keypairbytes = swap32(h.keypairbytes); } else { goto fail_header; } // Guess target (texture type) if (h.pixelheight == 0) { if (h.arrayelements == 0) { target = GL_TEXTURE_1D; } else { target = GL_TEXTURE_1D_ARRAY; } } else if (h.pixeldepth == 0) { if (h.arrayelements == 0) { if (h.faces == 0) { target = GL_TEXTURE_2D; } else { target = GL_TEXTURE_CUBE_MAP; } } else { if (h.faces == 0) { target = GL_TEXTURE_2D_ARRAY; } else { target = GL_TEXTURE_CUBE_MAP_ARRAY; } } } else { target = GL_TEXTURE_3D; } // Check for insanity... if (target == GL_NONE || // Couldn't figure out target (h.pixelwidth == 0) || // Texture has no width??? (h.pixelheight == 0 && h.pixeldepth != 0)) // Texture has depth but no height??? { goto fail_header; } temp = tex; if (tex == 0) { glGenTextures(1, &tex); } glBindTexture(target, tex); data_start = ftell(fp) + h.keypairbytes; fseek(fp, 0, SEEK_END); data_end = ftell(fp); fseek(fp, data_start, SEEK_SET); data = new unsigned char [data_end - data_start]; memset(data, 0, data_end - data_start); fread(data, 1, data_end - data_start, fp); if (h.miplevels == 0) { h.miplevels = 1; } switch (target) { case GL_TEXTURE_1D: glTexStorage1D(GL_TEXTURE_1D, h.miplevels, h.glinternalformat, h.pixelwidth); glTexSubImage1D(GL_TEXTURE_1D, 0, 0, h.pixelwidth, h.glformat, h.glinternalformat, data); break; case GL_TEXTURE_2D: glTexStorage2D(GL_TEXTURE_2D, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight); { unsigned char * ptr = data; unsigned int height = h.pixelheight; unsigned int width = h.pixelwidth; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (unsigned int i = 0; i < h.miplevels; i++) { glTexSubImage2D(GL_TEXTURE_2D, i, 0, 0, width, height, h.glformat, h.gltype, ptr); ptr += height * calculate_stride(h, width, 1); height >>= 1; width >>= 1; if (!height) height = 1; if (!width) width = 1; } } break; case GL_TEXTURE_3D: glTexStorage3D(GL_TEXTURE_3D, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight, h.pixeldepth); glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.pixeldepth, h.glformat, h.gltype, data); break; case GL_TEXTURE_1D_ARRAY: glTexStorage2D(GL_TEXTURE_1D_ARRAY, h.miplevels, h.glinternalformat, h.pixelwidth, h.arrayelements); glTexSubImage2D(GL_TEXTURE_1D_ARRAY, 0, 0, 0, h.pixelwidth, h.arrayelements, h.glformat, h.gltype, data); break; case GL_TEXTURE_2D_ARRAY: glTexStorage3D(GL_TEXTURE_2D_ARRAY, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight, h.arrayelements); glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.arrayelements, h.glformat, h.gltype, data); break; case GL_TEXTURE_CUBE_MAP: glTexStorage2D(GL_TEXTURE_CUBE_MAP, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight); // glTexSubImage3D(GL_TEXTURE_CUBE_MAP, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.faces, h.glformat, h.gltype, data); { unsigned int face_size = calculate_face_size(h); for (unsigned int i = 0; i < h.faces; i++) { glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, h.pixelwidth, h.pixelheight, h.glformat, h.gltype, data + face_size * i); } } break; case GL_TEXTURE_CUBE_MAP_ARRAY: glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight, h.arrayelements); glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.faces * h.arrayelements, h.glformat, h.gltype, data); break; default: // Should never happen goto fail_target; } if (h.miplevels == 1) { glGenerateMipmap(target); } retval = tex; fail_target: delete [] data; fail_header:; fail_read:; fclose(fp); return retval; }
unsigned int calculate_face_size(const header& h) { unsigned int stride = calculate_stride(h, h.pixelwidth); return stride * h.pixelheight; }