Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_texture.c
| Show First 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | struct GPUTexture { | ||||
| GLenum target; /* GL_TEXTURE_* */ | GLenum target; /* GL_TEXTURE_* */ | ||||
| GLenum target_base; /* same as target, (but no multisample) | GLenum target_base; /* same as target, (but no multisample) | ||||
| * use it for unbinding */ | * use it for unbinding */ | ||||
| GLuint bindcode; /* opengl identifier for texture */ | GLuint bindcode; /* opengl identifier for texture */ | ||||
| GPUTextureFormat format; | GPUTextureFormat format; | ||||
| GPUTextureFormatFlag format_flag; | GPUTextureFormatFlag format_flag; | ||||
| unsigned int bytesize; /* number of byte for one pixel */ | unsigned short flag; | ||||
| unsigned short max_miplvl; /* number of mipmaps that the texture has. */ | |||||
| int components; /* number of color/alpha channels */ | int components; /* number of color/alpha channels */ | ||||
| int samples; /* number of samples for multisamples textures. 0 if not multisample target */ | int samples; /* number of samples for multisamples textures. 0 if not multisample target */ | ||||
| int fb_attachment[GPU_TEX_MAX_FBO_ATTACHED]; | int fb_attachment[GPU_TEX_MAX_FBO_ATTACHED]; | ||||
| GPUFrameBuffer *fb[GPU_TEX_MAX_FBO_ATTACHED]; | GPUFrameBuffer *fb[GPU_TEX_MAX_FBO_ATTACHED]; | ||||
| }; | }; | ||||
| /* ------ Memory Management ------- */ | /* ------ Memory Management ------- */ | ||||
| /* Records every texture allocation / free | /* Records every texture allocation / free | ||||
| * to estimate the Texture Pool Memory consumption */ | * to estimate the Texture Pool Memory consumption */ | ||||
| static unsigned int memory_usage; | static unsigned int memory_usage; | ||||
| static unsigned int gpu_get_bytesize(GPUTextureFormat data_type); | |||||
| static unsigned int gpu_texture_memory_footprint_compute(GPUTexture *tex) | static unsigned int gpu_texture_memory_footprint_compute(GPUTexture *tex) | ||||
| { | { | ||||
| unsigned int memsize; | |||||
| int samp = max_ii(tex->samples, 1); | int samp = max_ii(tex->samples, 1); | ||||
| unsigned int bytesize = gpu_get_bytesize(tex->format); | |||||
| switch (tex->target) { | switch (tex->target) { | ||||
| case GL_TEXTURE_1D: | case GL_TEXTURE_1D: | ||||
| return tex->bytesize * tex->w * samp; | memsize = bytesize * tex->w * samp; | ||||
| break; | |||||
| case GL_TEXTURE_1D_ARRAY: | case GL_TEXTURE_1D_ARRAY: | ||||
| case GL_TEXTURE_2D: | case GL_TEXTURE_2D: | ||||
| return tex->bytesize * tex->w * tex->h * samp; | memsize = bytesize * tex->w * tex->h * samp; | ||||
| break; | |||||
| case GL_TEXTURE_2D_ARRAY: | case GL_TEXTURE_2D_ARRAY: | ||||
| case GL_TEXTURE_3D: | case GL_TEXTURE_3D: | ||||
| return tex->bytesize * tex->w * tex->h * tex->d * samp; | memsize = bytesize * tex->w * tex->h * tex->d * samp; | ||||
| break; | |||||
| case GL_TEXTURE_CUBE_MAP: | case GL_TEXTURE_CUBE_MAP: | ||||
| return tex->bytesize * 6 * tex->w * tex->h * samp; | memsize = bytesize * 6 * tex->w * tex->h * samp; | ||||
| break; | |||||
| case GL_TEXTURE_CUBE_MAP_ARRAY: | case GL_TEXTURE_CUBE_MAP_ARRAY: | ||||
| return tex->bytesize * 6 * tex->w * tex->h * tex->d * samp; | memsize = bytesize * 6 * tex->w * tex->h * tex->d * samp; | ||||
| break; | |||||
| default: | default: | ||||
| BLI_assert(0); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| if (tex->max_miplvl != 0) { | |||||
| /* Just to get an idea of the memory used here is computed | |||||
| * as if the maximum number of mipmaps was generated. */ | |||||
| memsize += memsize / 3; | |||||
| } | |||||
| return memsize; | |||||
| } | } | ||||
| static void gpu_texture_memory_footprint_add(GPUTexture *tex) | static void gpu_texture_memory_footprint_add(GPUTexture *tex) | ||||
| { | { | ||||
| memory_usage += gpu_texture_memory_footprint_compute(tex); | memory_usage += gpu_texture_memory_footprint_compute(tex); | ||||
| } | } | ||||
| static void gpu_texture_memory_footprint_remove(GPUTexture *tex) | static void gpu_texture_memory_footprint_remove(GPUTexture *tex) | ||||
| { | { | ||||
| memory_usage -= gpu_texture_memory_footprint_compute(tex); | memory_usage -= gpu_texture_memory_footprint_compute(tex); | ||||
| } | } | ||||
| unsigned int GPU_texture_memory_usage_get(void) | unsigned int GPU_texture_memory_usage_get(void) | ||||
| { | { | ||||
| return memory_usage; | return memory_usage; | ||||
| } | } | ||||
| /* -------------------------------- */ | /* -------------------------------- */ | ||||
| static unsigned short gpu_mipmap_max_level_calc(GPUTexture *tex) | |||||
| { | |||||
| return 1 + floor(log2(MAX3(tex->w, tex->h, tex->d))); | |||||
| } | |||||
| static int gpu_get_component_count(GPUTextureFormat format) | static int gpu_get_component_count(GPUTextureFormat format) | ||||
| { | { | ||||
| switch (format) { | switch (format) { | ||||
| case GPU_RGBA8: | case GPU_RGBA8: | ||||
| case GPU_RGBA16F: | case GPU_RGBA16F: | ||||
| case GPU_RGBA16: | case GPU_RGBA16: | ||||
| case GPU_RGBA32F: | case GPU_RGBA32F: | ||||
| return 4; | return 4; | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | else { | ||||
| else { | else { | ||||
| return GPU_DATA_FLOAT; | return GPU_DATA_FLOAT; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Definitely not complete, edit according to the gl specification. */ | /* Definitely not complete, edit according to the gl specification. */ | ||||
| static GLenum gpu_get_gl_dataformat(GPUTextureFormat data_type, GPUTextureFormatFlag *format_flag) | static GLenum gpu_get_gl_dataformat(GPUTextureFormat data_type, GPUTextureFormatFlag *format_flag) | ||||
| { | { | ||||
| if (ELEM(data_type, | if (ELEM(data_type, | ||||
fclem: typo: bits * | |||||
Done Inline Actionschange function name to gpu_format_to_gl_internalformat fclem: change function name to `gpu_format_to_gl_internalformat` | |||||
| GPU_DEPTH_COMPONENT24, | GPU_DEPTH_COMPONENT24, | ||||
| GPU_DEPTH_COMPONENT16, | GPU_DEPTH_COMPONENT16, | ||||
Done Inline ActionsI don't really like this. Keep the switch case and duplicate for gl_internalformat_to_gpu_format. fclem: I don't really like this. Keep the switch case and duplicate for… | |||||
| GPU_DEPTH_COMPONENT32F)) | GPU_DEPTH_COMPONENT32F)) | ||||
| { | { | ||||
Done Inline Actionschange function name to gl_internalformat_to_gpu_format fclem: change function name to `gl_internalformat_to_gpu_format` | |||||
| *format_flag |= GPU_FORMAT_DEPTH; | *format_flag |= GPU_FORMAT_DEPTH; | ||||
| return GL_DEPTH_COMPONENT; | return GL_DEPTH_COMPONENT; | ||||
| } | } | ||||
| else if (data_type == GPU_DEPTH24_STENCIL8) { | else if (data_type == GPU_DEPTH24_STENCIL8) { | ||||
| *format_flag |= GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL; | *format_flag |= GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL; | ||||
| return GL_DEPTH_STENCIL; | return GL_DEPTH_STENCIL; | ||||
| } | } | ||||
| else { | else { | ||||
| ▲ Show 20 Lines • Show All 244 Lines • ▼ Show 20 Lines | GPUTexture *GPU_texture_create_nD( | ||||
| tex->w = w; | tex->w = w; | ||||
| tex->h = h; | tex->h = h; | ||||
| tex->d = d; | tex->d = d; | ||||
| tex->samples = samples; | tex->samples = samples; | ||||
| tex->number = -1; | tex->number = -1; | ||||
| tex->refcount = 1; | tex->refcount = 1; | ||||
| tex->format = tex_format; | tex->format = tex_format; | ||||
| tex->components = gpu_get_component_count(tex_format); | tex->components = gpu_get_component_count(tex_format); | ||||
| tex->bytesize = gpu_get_bytesize(tex_format); | |||||
| tex->format_flag = 0; | tex->format_flag = 0; | ||||
| if (n == 2) { | if (n == 2) { | ||||
| if (d == 0) | if (d == 0) | ||||
| tex->target_base = tex->target = GL_TEXTURE_2D; | tex->target_base = tex->target = GL_TEXTURE_2D; | ||||
| else | else | ||||
| tex->target_base = tex->target = GL_TEXTURE_2D_ARRAY; | tex->target_base = tex->target = GL_TEXTURE_2D_ARRAY; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 134 Lines • ▼ Show 20 Lines | static GPUTexture *GPU_texture_cube_create( | ||||
| tex->w = w; | tex->w = w; | ||||
| tex->h = w; | tex->h = w; | ||||
| tex->d = d; | tex->d = d; | ||||
| tex->samples = 0; | tex->samples = 0; | ||||
| tex->number = -1; | tex->number = -1; | ||||
| tex->refcount = 1; | tex->refcount = 1; | ||||
| tex->format = tex_format; | tex->format = tex_format; | ||||
| tex->components = gpu_get_component_count(tex_format); | tex->components = gpu_get_component_count(tex_format); | ||||
| tex->bytesize = gpu_get_bytesize(tex_format); | |||||
| tex->format_flag = GPU_FORMAT_CUBE; | tex->format_flag = GPU_FORMAT_CUBE; | ||||
| if (d == 0) { | if (d == 0) { | ||||
| tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP; | tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP; | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert(false && "Cubemap array Not implemented yet"); | BLI_assert(false && "Cubemap array Not implemented yet"); | ||||
| // tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY; | // tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY; | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); | GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); | ||||
| tex->number = -1; | tex->number = -1; | ||||
| tex->refcount = 1; | tex->refcount = 1; | ||||
| tex->format = tex_format; | tex->format = tex_format; | ||||
| tex->components = gpu_get_component_count(tex_format); | tex->components = gpu_get_component_count(tex_format); | ||||
| tex->format_flag = 0; | tex->format_flag = 0; | ||||
| tex->target_base = tex->target = GL_TEXTURE_BUFFER; | tex->target_base = tex->target = GL_TEXTURE_BUFFER; | ||||
| tex->bytesize = gpu_get_bytesize(tex_format); | |||||
| GLenum internalformat = gpu_get_gl_internalformat(tex_format); | GLenum internalformat = gpu_get_gl_internalformat(tex_format); | ||||
| gpu_get_gl_dataformat(tex_format, &tex->format_flag); | gpu_get_gl_dataformat(tex_format, &tex->format_flag); | ||||
| if (!(ELEM(tex_format, GPU_R8, GPU_R16) || | if (!(ELEM(tex_format, GPU_R8, GPU_R16) || | ||||
| ELEM(tex_format, GPU_R16F, GPU_R32F) || | ELEM(tex_format, GPU_R16F, GPU_R32F) || | ||||
| ELEM(tex_format, GPU_R8I, GPU_R16I, GPU_R32I) || | ELEM(tex_format, GPU_R8I, GPU_R16I, GPU_R32I) || | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | else | ||||
| gettarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; | gettarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; | ||||
| glBindTexture(textarget, tex->bindcode); | glBindTexture(textarget, tex->bindcode); | ||||
| glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_WIDTH, &w); | glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_WIDTH, &w); | ||||
| glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_HEIGHT, &h); | glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_HEIGHT, &h); | ||||
| tex->w = w; | tex->w = w; | ||||
| tex->h = h; | tex->h = h; | ||||
| glBindTexture(textarget, 0); | glBindTexture(textarget, 0); | ||||
| gpu_texture_memory_footprint_add(tex); | |||||
| } | } | ||||
| return tex; | return tex; | ||||
| } | } | ||||
| GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap) | GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap) | ||||
| { | { | ||||
| GPUTexture *tex = prv->gputexture[0]; | GPUTexture *tex = prv->gputexture[0]; | ||||
| GLuint bindcode = 0; | GLuint bindcode = 0; | ||||
| if (tex) | |||||
| bindcode = tex->bindcode; | |||||
| /* this binds a texture, so that's why we restore it to 0 */ | |||||
| if (bindcode == 0) { | |||||
| GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], GL_TEXTURE_2D, mipmap, 0, NULL); | |||||
| } | |||||
| if (tex) { | if (tex) { | ||||
| tex->bindcode = bindcode; | BLI_assert(tex->bindcode != 0); | ||||
| glBindTexture(GL_TEXTURE_2D, 0); | |||||
| return tex; | return tex; | ||||
| } | } | ||||
| tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); | /* this binds a texture, so that's why we restore it to 0 */ | ||||
| tex->bindcode = bindcode; | GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], GL_TEXTURE_2D, mipmap, 0, NULL); | ||||
| tex->number = -1; | |||||
| tex->refcount = 1; | |||||
| tex->target = GL_TEXTURE_2D; | |||||
| tex->target_base = GL_TEXTURE_2D; | |||||
| tex->format = -1; | |||||
| tex->components = -1; | |||||
| prv->gputexture[0] = tex; | |||||
| if (!glIsTexture(tex->bindcode)) { | |||||
| GPU_print_error_debug("Blender Texture Not Loaded"); | |||||
| } | |||||
| else { | |||||
| GLint w, h; | |||||
| glBindTexture(GL_TEXTURE_2D, tex->bindcode); | |||||
| glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); | |||||
| glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); | |||||
| tex->w = w; | tex = GPU_texture_from_bindcode(GL_TEXTURE_2D, bindcode); | ||||
| tex->h = h; | |||||
| } | |||||
| glBindTexture(GL_TEXTURE_2D, 0); | tex->max_miplvl = mipmap && GPU_get_mipmap() ? gpu_mipmap_max_level_calc(tex) : 0; | ||||
| prv->gputexture[0] = tex; | |||||
| return tex; | return tex; | ||||
| } | } | ||||
| GPUTexture *GPU_texture_create_1D( | GPUTexture *GPU_texture_create_1D( | ||||
| int w, GPUTextureFormat tex_format, const float *pixels, char err_out[256]) | int w, GPUTextureFormat tex_format, const float *pixels, char err_out[256]) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | GPUTexture *GPU_texture_create_cube( | ||||
| return GPU_texture_cube_create(w, 0, fpixels_px, fpixels_py, fpixels_pz, fpixels_nx, fpixels_ny, fpixels_nz, | return GPU_texture_cube_create(w, 0, fpixels_px, fpixels_py, fpixels_pz, fpixels_nx, fpixels_ny, fpixels_nz, | ||||
| tex_format, GPU_DATA_FLOAT, err_out); | tex_format, GPU_DATA_FLOAT, err_out); | ||||
| } | } | ||||
| GPUTexture *GPU_texture_create_from_vertbuf(GPUVertBuf *vert) | GPUTexture *GPU_texture_create_from_vertbuf(GPUVertBuf *vert) | ||||
| { | { | ||||
| GPUVertFormat *format = &vert->format; | GPUVertFormat *format = &vert->format; | ||||
| GPUVertAttr *attr = &format->attribs[0]; | GPUVertAttr *attr = &format->attribs[0]; | ||||
| /* Detect incompatible cases (not supported by texture buffers) */ | /* Detect incompatible cases (not supported by texture buffers) */ | ||||
Done Inline Actionswhy uint? fclem: why uint? | |||||
Done Inline ActionsPrefer testing miplvl > tex->mipmaps. fclem: Prefer testing miplvl > tex->mipmaps. | |||||
Done Inline ActionsPrefer testing miplvl <= tex->mipmaps fclem: Prefer testing miplvl <= tex->mipmaps | |||||
| BLI_assert(format->attr_len == 1 && vert->vbo_id != 0); | BLI_assert(format->attr_len == 1 && vert->vbo_id != 0); | ||||
| BLI_assert(attr->comp_len != 3); /* Not until OGL 4.0 */ | BLI_assert(attr->comp_len != 3); /* Not until OGL 4.0 */ | ||||
| BLI_assert(attr->comp_type != GPU_COMP_I10); | BLI_assert(attr->comp_type != GPU_COMP_I10); | ||||
| BLI_assert(attr->fetch_mode != GPU_FETCH_INT_TO_FLOAT); | BLI_assert(attr->fetch_mode != GPU_FETCH_INT_TO_FLOAT); | ||||
| unsigned int byte_per_comp = attr->sz / attr->comp_len; | unsigned int byte_per_comp = attr->sz / attr->comp_len; | ||||
| bool is_uint = ELEM(attr->comp_type, GPU_COMP_U8, GPU_COMP_U16, GPU_COMP_U32); | bool is_uint = ELEM(attr->comp_type, GPU_COMP_U8, GPU_COMP_U16, GPU_COMP_U32); | ||||
| ▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | GPUTexture *GPU_texture_create_from_vertbuf(GPUVertBuf *vert) | ||||
| return GPU_texture_create_buffer(data_type, vert->vbo_id); | return GPU_texture_create_buffer(data_type, vert->vbo_id); | ||||
| } | } | ||||
| void GPU_texture_add_mipmap( | void GPU_texture_add_mipmap( | ||||
| GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl, const void *pixels) | GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl, const void *pixels) | ||||
| { | { | ||||
| BLI_assert((int)tex->format > -1); | BLI_assert((int)tex->format > -1); | ||||
| BLI_assert(tex->components > -1); | BLI_assert(tex->components > -1); | ||||
| BLI_assert(tex->max_miplvl < miplvl); | |||||
| gpu_validate_data_format(tex->format, gpu_data_format); | gpu_validate_data_format(tex->format, gpu_data_format); | ||||
| GLenum internalformat = gpu_get_gl_internalformat(tex->format); | GLenum internalformat = gpu_get_gl_internalformat(tex->format); | ||||
| GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag); | GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag); | ||||
| GLenum data_type = gpu_get_gl_datatype(gpu_data_format); | GLenum data_type = gpu_get_gl_datatype(gpu_data_format); | ||||
| glBindTexture(tex->target, tex->bindcode); | glBindTexture(tex->target, tex->bindcode); | ||||
| Show All 14 Lines | case GL_TEXTURE_2D_ARRAY: | ||||
| glTexImage3D(tex->target, miplvl, internalformat, size[0], size[1], size[2], 0, data_format, data_type, pixels); | glTexImage3D(tex->target, miplvl, internalformat, size[0], size[1], size[2], 0, data_format, data_type, pixels); | ||||
| break; | break; | ||||
| case GL_TEXTURE_2D_MULTISAMPLE: | case GL_TEXTURE_2D_MULTISAMPLE: | ||||
| /* Multisample textures cannot have mipmaps. */ | /* Multisample textures cannot have mipmaps. */ | ||||
| default: | default: | ||||
| BLI_assert(!"tex->target mode not supported"); | BLI_assert(!"tex->target mode not supported"); | ||||
| } | } | ||||
| tex->max_miplvl = miplvl; | |||||
| glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, miplvl); | glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, miplvl); | ||||
| glBindTexture(tex->target, 0); | glBindTexture(tex->target, 0); | ||||
| } | } | ||||
| void GPU_texture_update_sub( | void GPU_texture_update_sub( | ||||
| GPUTexture *tex, GPUDataFormat gpu_data_format, const void *pixels, | GPUTexture *tex, GPUDataFormat gpu_data_format, const void *pixels, | ||||
| int offset_x, int offset_y, int offset_z, int width, int height, int depth) | int offset_x, int offset_y, int offset_z, int width, int height, int depth) | ||||
| { | { | ||||
| BLI_assert((int)tex->format > -1); | BLI_assert((int)tex->format > -1); | ||||
| BLI_assert(tex->components > -1); | BLI_assert(tex->components > -1); | ||||
| GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag); | GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag); | ||||
| GLenum data_type = gpu_get_gl_datatype(gpu_data_format); | GLenum data_type = gpu_get_gl_datatype(gpu_data_format); | ||||
| GLint alignment; | GLint alignment; | ||||
| unsigned int bytesize = gpu_get_bytesize(tex->format); | |||||
| /* The default pack size for textures is 4, which won't work for byte based textures */ | /* The default pack size for textures is 4, which won't work for byte based textures */ | ||||
| if (tex->bytesize == 1) { | if (bytesize == 1) { | ||||
| glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); | glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); | ||||
| glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||||
| } | } | ||||
| glBindTexture(tex->target, tex->bindcode); | glBindTexture(tex->target, tex->bindcode); | ||||
| switch (tex->target) { | switch (tex->target) { | ||||
| case GL_TEXTURE_1D: | case GL_TEXTURE_1D: | ||||
| glTexSubImage1D(tex->target, 0, offset_x, width, data_format, data_type, pixels); | glTexSubImage1D(tex->target, 0, offset_x, width, data_format, data_type, pixels); | ||||
| Show All 10 Lines | case GL_TEXTURE_2D_ARRAY: | ||||
| glTexSubImage3D( | glTexSubImage3D( | ||||
| tex->target, 0, offset_x, offset_y, offset_z, | tex->target, 0, offset_x, offset_y, offset_z, | ||||
| width, height, depth, data_format, data_type, pixels); | width, height, depth, data_format, data_type, pixels); | ||||
| break; | break; | ||||
| default: | default: | ||||
| BLI_assert(!"tex->target mode not supported"); | BLI_assert(!"tex->target mode not supported"); | ||||
| } | } | ||||
| if (tex->bytesize == 1) { | if (bytesize == 1) { | ||||
| glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); | glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); | ||||
| } | } | ||||
| glBindTexture(tex->target, 0); | glBindTexture(tex->target, 0); | ||||
| } | } | ||||
| void *GPU_texture_read(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl) | void *GPU_texture_read(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl) | ||||
| { | { | ||||
| BLI_assert(tex->max_miplvl <= miplvl); | |||||
| int size[3] = {0, 0, 0}; | int size[3] = {0, 0, 0}; | ||||
| GPU_texture_get_mipmap_size(tex, miplvl, size); | GPU_texture_get_mipmap_size(tex, miplvl, size); | ||||
| gpu_validate_data_format(tex->format, gpu_data_format); | gpu_validate_data_format(tex->format, gpu_data_format); | ||||
| size_t buf_size = gpu_texture_memory_footprint_compute(tex); | size_t buf_size = gpu_texture_memory_footprint_compute(tex); | ||||
| size_t samples_count = max_ii(1, tex->samples); | size_t samples_count = max_ii(1, tex->samples); | ||||
| ▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | if (_tex->number == -1) { \ | ||||
| return; \ | return; \ | ||||
| } \ | } \ | ||||
| } while (0); | } while (0); | ||||
| void GPU_texture_generate_mipmap(GPUTexture *tex) | void GPU_texture_generate_mipmap(GPUTexture *tex) | ||||
| { | { | ||||
| WARN_NOT_BOUND(tex); | WARN_NOT_BOUND(tex); | ||||
| gpu_texture_memory_footprint_remove(tex); | |||||
| glActiveTexture(GL_TEXTURE0 + tex->number); | glActiveTexture(GL_TEXTURE0 + tex->number); | ||||
| glGenerateMipmap(tex->target_base); | glGenerateMipmap(tex->target_base); | ||||
| tex->max_miplvl = gpu_mipmap_max_level_calc(tex); | |||||
| gpu_texture_memory_footprint_add(tex); | |||||
| } | } | ||||
| void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare) | void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare) | ||||
| { | { | ||||
| WARN_NOT_BOUND(tex); | WARN_NOT_BOUND(tex); | ||||
| /* Could become an assertion ? (fclem) */ | /* Could become an assertion ? (fclem) */ | ||||
| if (!GPU_texture_depth(tex)) | if (!GPU_texture_depth(tex)) | ||||
| ▲ Show 20 Lines • Show All 210 Lines • Show Last 20 Lines | |||||
typo: bits *