diff options
Diffstat (limited to 'source/blender/gpu/opengl/gl_texture.hh')
-rw-r--r-- | source/blender/gpu/opengl/gl_texture.hh | 218 |
1 files changed, 197 insertions, 21 deletions
diff --git a/source/blender/gpu/opengl/gl_texture.hh b/source/blender/gpu/opengl/gl_texture.hh index 513cef59e85..0e054d7996a 100644 --- a/source/blender/gpu/opengl/gl_texture.hh +++ b/source/blender/gpu/opengl/gl_texture.hh @@ -39,6 +39,8 @@ #include "glew-mx.h" +struct GPUFrameBuffer; + namespace blender { namespace gpu { @@ -53,62 +55,177 @@ class GLContext { #endif class GLTexture : public Texture { + friend class GLStateManager; + private: - /** Texture unit to which this texture is bound. */ - int slot = -1; /** Target to bind the texture to (GL_TEXTURE_1D, GL_TEXTURE_2D, etc...)*/ GLenum target_ = -1; /** opengl identifier for texture. */ GLuint tex_id_ = 0; - /** Legacy workaround for texture copy. */ - GLuint copy_fb = 0; - GPUContext *copy_fb_ctx = NULL; + /** Legacy workaround for texture copy. Created when using framebuffer_get(). */ + struct GPUFrameBuffer *framebuffer_ = NULL; + /** True if this texture is bound to at least one texture unit. */ + /* TODO(fclem) How do we ensure thread safety here? */ + bool is_bound_; public: GLTexture(const char *name); ~GLTexture(); - void bind(int slot) override; - void update(void *data) override; - void update_sub(void *data, int offset[3], int size[3]) override; + void update_sub( + int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data) override; + void generate_mipmap(void) override; void copy_to(Texture *tex) override; - - void swizzle_set(char swizzle_mask[4]) override; + void clear(eGPUDataFormat format, const void *data) override; + void swizzle_set(const char swizzle_mask[4]) override; + void mip_range_set(int min, int max) override; + void *read(int mip, eGPUDataFormat format) override; /* TODO(fclem) Legacy. Should be removed at some point. */ - uint gl_bindcode_get(void) override; + uint gl_bindcode_get(void) const override; + + protected: + bool init_internal(void) override; + bool init_internal(GPUVertBuf *vbo) override; private: - void init(void); + void ensure_mipmaps(int miplvl); + GPUFrameBuffer *framebuffer_get(void); + + MEM_CXX_CLASS_ALLOC_FUNCS("GLTexture") }; -static inline GLenum target_to_gl(eGPUTextureFlag target) +inline GLenum to_gl_internal_format(eGPUTextureFormat format) +{ + /* You can add any of the available type to this list + * For available types see GPU_texture.h */ + switch (format) { + /* Formats texture & renderbuffer */ + case GPU_RGBA8UI: + return GL_RGBA8UI; + case GPU_RGBA8I: + return GL_RGBA8I; + case GPU_RGBA8: + return GL_RGBA8; + case GPU_RGBA32UI: + return GL_RGBA32UI; + case GPU_RGBA32I: + return GL_RGBA32I; + case GPU_RGBA32F: + return GL_RGBA32F; + case GPU_RGBA16UI: + return GL_RGBA16UI; + case GPU_RGBA16I: + return GL_RGBA16I; + case GPU_RGBA16F: + return GL_RGBA16F; + case GPU_RGBA16: + return GL_RGBA16; + case GPU_RG8UI: + return GL_RG8UI; + case GPU_RG8I: + return GL_RG8I; + case GPU_RG8: + return GL_RG8; + case GPU_RG32UI: + return GL_RG32UI; + case GPU_RG32I: + return GL_RG32I; + case GPU_RG32F: + return GL_RG32F; + case GPU_RG16UI: + return GL_RG16UI; + case GPU_RG16I: + return GL_RG16I; + case GPU_RG16F: + return GL_RG16F; + case GPU_RG16: + return GL_RG16; + case GPU_R8UI: + return GL_R8UI; + case GPU_R8I: + return GL_R8I; + case GPU_R8: + return GL_R8; + case GPU_R32UI: + return GL_R32UI; + case GPU_R32I: + return GL_R32I; + case GPU_R32F: + return GL_R32F; + case GPU_R16UI: + return GL_R16UI; + case GPU_R16I: + return GL_R16I; + case GPU_R16F: + return GL_R16F; + case GPU_R16: + return GL_R16; + /* Special formats texture & renderbuffer */ + case GPU_R11F_G11F_B10F: + return GL_R11F_G11F_B10F; + case GPU_DEPTH32F_STENCIL8: + return GL_DEPTH32F_STENCIL8; + case GPU_DEPTH24_STENCIL8: + return GL_DEPTH24_STENCIL8; + case GPU_SRGB8_A8: + return GL_SRGB8_ALPHA8; + /* Texture only format */ + case GPU_RGB16F: + return GL_RGB16F; + /* Special formats texture only */ + case GPU_SRGB8_A8_DXT1: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + case GPU_SRGB8_A8_DXT3: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + case GPU_SRGB8_A8_DXT5: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + case GPU_RGBA8_DXT1: + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + case GPU_RGBA8_DXT3: + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + case GPU_RGBA8_DXT5: + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + /* Depth Formats */ + case GPU_DEPTH_COMPONENT32F: + return GL_DEPTH_COMPONENT32F; + case GPU_DEPTH_COMPONENT24: + return GL_DEPTH_COMPONENT24; + case GPU_DEPTH_COMPONENT16: + return GL_DEPTH_COMPONENT16; + default: + BLI_assert(!"Texture format incorrect or unsupported\n"); + return 0; + } +} + +inline GLenum to_gl_target(eGPUTextureType type) { - switch (target & GPU_TEXTURE_TARGET) { + switch (type) { case GPU_TEXTURE_1D: return GL_TEXTURE_1D; - case GPU_TEXTURE_1D | GPU_TEXTURE_ARRAY: + case GPU_TEXTURE_1D_ARRAY: return GL_TEXTURE_1D_ARRAY; case GPU_TEXTURE_2D: return GL_TEXTURE_2D; - case GPU_TEXTURE_2D | GPU_TEXTURE_ARRAY: + case GPU_TEXTURE_2D_ARRAY: return GL_TEXTURE_2D_ARRAY; case GPU_TEXTURE_3D: return GL_TEXTURE_3D; case GPU_TEXTURE_CUBE: return GL_TEXTURE_CUBE_MAP; - case GPU_TEXTURE_CUBE | GPU_TEXTURE_ARRAY: + case GPU_TEXTURE_CUBE_ARRAY: return GL_TEXTURE_CUBE_MAP_ARRAY_ARB; case GPU_TEXTURE_BUFFER: return GL_TEXTURE_BUFFER; default: BLI_assert(0); - return GPU_TEXTURE_1D; + return GL_TEXTURE_1D; } } -static inline GLenum swizzle_to_gl(const char swizzle) +inline GLenum swizzle_to_gl(const char swizzle) { switch (swizzle) { default: @@ -131,7 +248,7 @@ static inline GLenum swizzle_to_gl(const char swizzle) } } -static inline GLenum to_gl(eGPUDataFormat format) +inline GLenum to_gl(eGPUDataFormat format) { switch (format) { case GPU_DATA_FLOAT: @@ -152,8 +269,67 @@ static inline GLenum to_gl(eGPUDataFormat format) } } +/* Definitely not complete, edit according to the gl specification. */ +inline GLenum to_gl_data_format(eGPUTextureFormat format) +{ + /* You can add any of the available type to this list + * For available types see GPU_texture.h */ + switch (format) { + case GPU_R8I: + case GPU_R8UI: + case GPU_R16I: + case GPU_R16UI: + case GPU_R32I: + case GPU_R32UI: + return GL_RED_INTEGER; + case GPU_RG8I: + case GPU_RG8UI: + case GPU_RG16I: + case GPU_RG16UI: + case GPU_RG32I: + case GPU_RG32UI: + return GL_RG_INTEGER; + case GPU_RGBA8I: + case GPU_RGBA8UI: + case GPU_RGBA16I: + case GPU_RGBA16UI: + case GPU_RGBA32I: + case GPU_RGBA32UI: + return GL_RGBA_INTEGER; + case GPU_R8: + case GPU_R16: + case GPU_R16F: + case GPU_R32F: + return GL_RED; + case GPU_RG8: + case GPU_RG16: + case GPU_RG16F: + case GPU_RG32F: + return GL_RG; + case GPU_R11F_G11F_B10F: + case GPU_RGB16F: + return GL_RGB; + case GPU_RGBA8: + case GPU_SRGB8_A8: + case GPU_RGBA16: + case GPU_RGBA16F: + case GPU_RGBA32F: + return GL_RGBA; + case GPU_DEPTH24_STENCIL8: + case GPU_DEPTH32F_STENCIL8: + return GL_DEPTH_STENCIL; + case GPU_DEPTH_COMPONENT16: + case GPU_DEPTH_COMPONENT24: + case GPU_DEPTH_COMPONENT32F: + return GL_DEPTH_COMPONENT; + default: + BLI_assert(!"Texture format incorrect or unsupported\n"); + return 0; + } +} + /* Assume Unorm / Float target. Used with glReadPixels. */ -static inline GLenum channel_len_to_gl(int channel_len) +inline GLenum channel_len_to_gl(int channel_len) { switch (channel_len) { case 1: |