Commit: ce6cc756c3fb252706f4a6497cc9926241cde3ec Author: Clément Foucault Date: Thu Jun 28 15:30:48 2018 +0200 Branches: temp-eeveelightcache https://developer.blender.org/rBce6cc756c3fb252706f4a6497cc9926241cde3ec
GPUTexture: Refactor to have more flexibility. New features: - Get mipmap level size from a texture. - Use explicit GPUDataFormat to specify how the input (or output) data is formated when uploading (or reading) texture data. - Can upload different mipmap level after base level. =================================================================== M source/blender/blenfont/intern/blf_glyph.c M source/blender/gpu/GPU_texture.h M source/blender/gpu/intern/gpu_texture.c =================================================================== diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 84388bedb7b..8dc11443124 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -239,7 +239,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) } unsigned char *pixels = MEM_callocN((size_t)gc->p2_width * (size_t)gc->p2_height, "BLF texture init"); - GPUTexture *tex = GPU_texture_create_2D(gc->p2_width, gc->p2_height, GPU_R8, (const float *)pixels, error); + GPUTexture *tex = GPU_texture_create_nD(gc->p2_width, gc->p2_height, 0, 2, pixels, GPU_R8, GPU_DATA_UNSIGNED_BYTE, 0, false, error); MEM_freeN(pixels); gc->textures[gc->texture_current] = tex; GPU_texture_bind(tex, 0); @@ -476,7 +476,7 @@ void blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y) BLI_assert(g->height > 0); } - GPU_texture_update_sub(g->tex, g->bitmap, g->offset_x, g->offset_y, 0, g->width, g->height, 0); + GPU_texture_update_sub(g->tex, GPU_DATA_UNSIGNED_BYTE, g->bitmap, g->offset_x, g->offset_y, 0, g->width, g->height, 0); g->uv[0][0] = ((float)g->offset_x) / ((float)gc->p2_width); g->uv[0][1] = ((float)g->offset_y) / ((float)gc->p2_height); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 66dfcb80379..3fb6aefc29f 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -142,6 +142,15 @@ typedef enum GPUTextureFormat { GPU_DEPTH_COMPONENT16, } GPUTextureFormat; +typedef enum GPUDataFormat { + GPU_DATA_FLOAT, + GPU_DATA_INT, + GPU_DATA_UNSIGNED_INT, + GPU_DATA_UNSIGNED_BYTE, + GPU_DATA_UNSIGNED_INT_24_8, + GPU_DATA_10_11_11_REV, +} GPUDataFormat; + /* These map directly to the GL_ blend functions, to minimize API add as needed*/ typedef enum GPUBlendFunction { GPU_ONE, @@ -157,6 +166,12 @@ typedef enum GPUFilterFunction { unsigned int GPU_texture_memory_usage_get(void); +/* TODO make it static function again. (create function with GPUDataFormat exposed) */ +GPUTexture *GPU_texture_create_nD( + int w, int h, int d, int n, const void *pixels, + GPUTextureFormat tex_format, GPUDataFormat gpu_data_format, int samples, + const bool can_rescale, char err_out[256]); + GPUTexture *GPU_texture_create_1D( int w, GPUTextureFormat data_type, const float *pixels, char err_out[256]); GPUTexture *GPU_texture_create_2D( @@ -179,12 +194,14 @@ GPUTexture *GPU_texture_from_blender( struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, double time); GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap); -void GPU_texture_update(GPUTexture *tex, const void *pixels); +void GPU_texture_add_mipmap(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl, const void *pixels); + +void GPU_texture_update(GPUTexture *tex, GPUDataFormat data_format, const void *pixels); void GPU_texture_update_sub( - GPUTexture *tex, 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); -void *GPU_texture_read(GPUTexture *tex, int miplvl); +void *GPU_texture_read(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl); void GPU_invalid_tex_init(void); void GPU_invalid_tex_bind(int mode); @@ -224,6 +241,8 @@ bool GPU_texture_stencil(const GPUTexture *tex); bool GPU_texture_integer(const GPUTexture *tex); int GPU_texture_opengl_bindcode(const GPUTexture *tex); +void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size); + void GPU_blend(bool enable); void GPU_blend_set_func_separate(GPUBlendFunction src_rgb, GPUBlendFunction dst_rgb, GPUBlendFunction src_alpha, GPUBlendFunction dst_alpha); void GPU_blend_set_func(GPUBlendFunction sfactor, GPUBlendFunction dfactor); diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index 8d2b9640c9e..08490eeb6c2 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -134,73 +134,159 @@ unsigned int GPU_texture_memory_usage_get(void) /* -------------------------------- */ -static GLenum gpu_texture_get_format( - int components, GPUTextureFormat data_type, - GLenum *format, GLenum *data_format, GPUTextureFormatFlag *format_flag, unsigned int *bytesize) +static int gpu_get_component_count(GPUTextureFormat format) +{ + switch (format) { + case GPU_RGBA8: + case GPU_RGBA16F: + case GPU_RGBA16: + case GPU_RGBA32F: + return 4; + case GPU_RGB16F: + case GPU_R11F_G11F_B10F: + return 3; + case GPU_RG8: + case GPU_RG16: + case GPU_RG16F: + case GPU_RG16I: + case GPU_RG16UI: + case GPU_RG32F: + return 2; + default: + return 1; + } +} + +/* Definitely not complete, edit according to the gl specification. */ +static void gpu_validate_data_format(GPUTextureFormat tex_format, GPUDataFormat data_format) +{ + if (ELEM(tex_format, GPU_DEPTH_COMPONENT24, + GPU_DEPTH_COMPONENT16, + GPU_DEPTH_COMPONENT32F)) + { + BLI_assert(data_format == GPU_DATA_FLOAT); + } + else if (tex_format == GPU_DEPTH24_STENCIL8) { + BLI_assert(data_format == GPU_DATA_UNSIGNED_INT_24_8); + } + else { + /* Integer formats */ + if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) { + if (ELEM(tex_format, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) { + BLI_assert(data_format == GPU_DATA_UNSIGNED_INT); + } + else { + BLI_assert(data_format == GPU_DATA_INT); + } + } + /* Byte formats */ + else if (ELEM(tex_format, GPU_R8, GPU_RG8, GPU_RGBA8)) { + BLI_assert(ELEM(data_format, GPU_DATA_UNSIGNED_BYTE, GPU_DATA_FLOAT)); + } + /* Special case */ + else if (ELEM(tex_format, GPU_R11F_G11F_B10F)) { + BLI_assert(ELEM(data_format, GPU_DATA_10_11_11_REV)); + } + /* Float formats */ + else { + BLI_assert(ELEM(data_format, GPU_DATA_FLOAT)); + } + } +} + +static GPUDataFormat gpu_get_data_format_from_tex_format(GPUTextureFormat tex_format) +{ + if (ELEM(tex_format, GPU_DEPTH_COMPONENT24, + GPU_DEPTH_COMPONENT16, + GPU_DEPTH_COMPONENT32F)) + { + return GPU_DATA_FLOAT; + } + else if (tex_format == GPU_DEPTH24_STENCIL8) { + return GPU_DATA_UNSIGNED_INT_24_8; + } + else { + /* Integer formats */ + if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) { + if (ELEM(tex_format, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) { + return GPU_DATA_UNSIGNED_INT; + } + else { + return GPU_DATA_INT; + } + } + /* Byte formats */ + else if (ELEM(tex_format, GPU_R8)) { + return GPU_DATA_UNSIGNED_BYTE; + } + /* Special case */ + else if (ELEM(tex_format, GPU_R11F_G11F_B10F)) { + return GPU_DATA_10_11_11_REV; + } + else { + return GPU_DATA_FLOAT; + } + } +} + +/* Definitely not complete, edit according to the gl specification. */ +static GLenum gpu_get_gl_dataformat(GPUTextureFormat data_type, GPUTextureFormatFlag *format_flag) { if (ELEM(data_type, GPU_DEPTH_COMPONENT24, GPU_DEPTH_COMPONENT16, GPU_DEPTH_COMPONENT32F)) { *format_flag |= GPU_FORMAT_DEPTH; - *data_format = GL_FLOAT; - *format = GL_DEPTH_COMPONENT; + return GL_DEPTH_COMPONENT; } else if (data_type == GPU_DEPTH24_STENCIL8) { *format_flag |= GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL; - *data_format = GL_UNSIGNED_INT_24_8; - *format = GL_DEPTH_STENCIL; + return GL_DEPTH_STENCIL; } else { /* Integer formats */ if (ELEM(data_type, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) { - if (ELEM(data_type, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) { - *data_format = GL_UNSIGNED_INT; - } - else { - *data_format = GL_INT; - } - *format_flag |= GPU_FORMAT_INTEGER; - switch (components) { - case 1: *format = GL_RED_INTEGER; break; - case 2: *format = GL_RG_INTEGER; break; - case 3: *format = GL_RGB_INTEGER; break; - case 4: *format = GL_RGBA_INTEGER; break; - default: break; + switch (gpu_get_component_count(data_type)) { + case 1: return GL_RED_INTEGER; break; + case 2: return GL_RG_INTEGER; break; + case 3: return GL_RGB_INTEGER; break; + case 4: return GL_RGBA_INTEGER; break; } } else if (ELEM(data_type, GPU_R8)) { - *data_format = GL_UNSIGNED_BYTE; - *format = GL_RED; + *format_flag |= GPU_FORMAT_FLOAT; + return GL_RED; } else { - *data_format = GL_FLOAT; *format_flag |= GPU_FORMAT_FLOAT; - switch (components) { - case 1: *format = GL_RED; break; - case 2: *format = GL_RG; break; - case 3: *format = GL_RGB; break; - case 4: *format = GL_RGBA; break; - default: break; + switch (gpu_get_component_count(data_type)) { + case 1: return GL_RED; break; + case 2: return GL_RG; break; + case 3: return GL_RGB; break; + case 4: return GL_RGBA; break; } } } + BLI_assert(0); + *format_flag |= GPU_FORMAT_FLOAT; + return GL_RGBA; +} + +static unsigned int gpu_get_bytesize(GPUTextureFormat data_type) +{ switch (data_type) { case GPU_RGBA32F: - *bytesize = 32; - break; + return 32; case GPU_RG32F: case GPU_RGBA16F: case GPU_RGBA16: - *bytesize = 16; - break; + return 16; case GPU_RGB16F: - *bytesize = 12; - break; + return 12; case GPU_RG16F: case GPU_RG16I: case GPU_RG16UI: @@ -212,28 +298,28 @@ static GLenum gpu_texture_get_format( case GPU_R32F: case GPU_R32UI: case GPU_R32I: - *bytesize = 4; - break; + return 4; case GPU_DEPTH_COMPONENT24: - *bytesize = 3; - break; + return 3; case GPU_DEPTH_COMPONENT16: case GPU_R16F: + case GPU_R16UI: case GPU_R16I: case GPU_RG8: - *bytesize = 2; - break; + return 2; case GPU_R8: - *bytesize = 1; - break; + return 1; default: - *bytesize = 0; - break; + BLI_assert(!"Texture format incorrect or unsupported\n"); + return 0; } +} +static GLenum gpu_get_gl_internalformat(GPUTextureFormat format) +{ /* You can add any of the available type to this list * For available types see GPU_texture.h */ - switch (data_type) { + switch (format) { /* Forma @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs