diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-07-27 14:37:14 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-07-27 14:37:22 +0300 |
commit | 0b04f0e4e63ff88e493bedb6bd9ea4fe5b3557ca (patch) | |
tree | be7c2a550cdd64c8d4c27ce030df7d75b13320d0 /source/blender/gpu | |
parent | bfeb94ecccbf9222ef46294db88ca678e3c529fc (diff) |
GPU: Fix crash and missing texture due to recent C++ port
Fix T79306 DRW: small issues with yesterday commits modifying TEXTARGET
Fix T79303 Image texture node crashes EEVEE when connected to a shader output
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_draw.h | 16 | ||||
-rw-r--r-- | source/blender/gpu/GPU_texture.h | 15 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.c | 26 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_texture_image.cc | 93 |
4 files changed, 87 insertions, 63 deletions
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index b364bd0ef95..01af654b52f 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -58,21 +58,7 @@ float GPU_get_anisotropic(void); void GPU_paint_update_image( struct Image *ima, struct ImageUser *iuser, int x, int y, int w, int h); -void GPU_create_gl_tex(unsigned int *bind, - unsigned int *rect, - float *frect, - int rectw, - int recth, - int textarget, - bool mipmap, - bool half_float, - bool use_srgb, - struct Image *ima); -void GPU_create_gl_tex_compressed(unsigned int *bind, - int textarget, - struct Image *ima, - struct ImBuf *ibuf); -bool GPU_upload_dxt_texture(struct ImBuf *ibuf, bool use_srgb); +bool GPU_upload_dxt_texture(struct ImBuf *ibuf, bool use_srgb, uint *bindcode); void GPU_free_image(struct Image *ima); void GPU_free_images(struct Main *bmain); void GPU_free_images_anim(struct Main *bmain); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 813ee71eb22..d7f5d6272f4 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -41,6 +41,15 @@ struct PreviewImage; struct GPUFrameBuffer; typedef struct GPUTexture GPUTexture; +/* Used to get the correct gpu texture from an Image datablock. */ +typedef enum eGPUTextureTarget { + TEXTARGET_2D = 0, + TEXTARGET_CUBE_MAP, + TEXTARGET_2D_ARRAY, + TEXTARGET_TILE_MAPPING, + TEXTARGET_COUNT, +} eGPUTextureTarget; + /* GPU Samplers state * - Specify the sampler state to bind a texture with. * - Internally used by textures. @@ -222,16 +231,16 @@ GPUTexture *GPU_texture_create_cube_array( GPUTexture *GPU_texture_create_from_vertbuf(struct GPUVertBuf *vert); GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat data_type, const uint buffer); -GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode); +GPUTexture *GPU_texture_from_bindcode(eGPUTextureTarget target, int bindcode); GPUTexture *GPU_texture_from_blender(struct Image *ima, struct ImageUser *iuser, struct ImBuf *ibuf, - int textarget); + eGPUTextureTarget target); /* movie clip drawing */ GPUTexture *GPU_texture_from_movieclip(struct MovieClip *clip, struct MovieClipUser *cuser, - int textarget); + eGPUTextureTarget target); void GPU_free_texture_movieclip(struct MovieClip *clip); void GPU_texture_add_mipmap(GPUTexture *tex, diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index e3d0dcdf65b..88424cb4cec 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -1186,18 +1186,24 @@ GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint return tex; } -static GLenum convert_target_to_gl(int target) -{ - static const GLenum table[] = { - [TEXTARGET_2D] = GL_TEXTURE_2D, - [TEXTARGET_CUBE_MAP] = GL_TEXTURE_CUBE_MAP, - [TEXTARGET_2D_ARRAY] = GL_TEXTURE_2D_ARRAY, - [TEXTARGET_TILE_MAPPING] = GL_TEXTURE_1D_ARRAY, - }; - return table[target]; +static GLenum convert_target_to_gl(eGPUTextureTarget target) +{ + switch (target) { + case TEXTARGET_2D: + return GL_TEXTURE_2D; + case TEXTARGET_CUBE_MAP: + return GL_TEXTURE_CUBE_MAP; + case TEXTARGET_2D_ARRAY: + return GL_TEXTURE_2D_ARRAY; + case TEXTARGET_TILE_MAPPING: + return GL_TEXTURE_1D_ARRAY; + default: + BLI_assert(0); + return GL_TEXTURE_2D; + } } -GPUTexture *GPU_texture_from_bindcode(int target, int bindcode) +GPUTexture *GPU_texture_from_bindcode(eGPUTextureTarget target, int bindcode) { GLenum textarget = convert_target_to_gl(target); diff --git a/source/blender/gpu/intern/gpu_texture_image.cc b/source/blender/gpu/intern/gpu_texture_image.cc index bbc54651b87..97c74c83230 100644 --- a/source/blender/gpu/intern/gpu_texture_image.cc +++ b/source/blender/gpu/intern/gpu_texture_image.cc @@ -63,6 +63,20 @@ static void gpu_free_image(Image *ima, const bool immediate); static void gpu_free_unused_buffers(void); +static void gpu_create_gl_tex_compressed(unsigned int *bind, + eGPUTextureTarget textarget, + Image *ima, + ImBuf *ibuf); +static void gpu_create_gl_tex(uint *bind, + uint *rect, + float *frect, + int rectw, + int recth, + eGPUTextureTarget textarget, + bool mipmap, + bool half_float, + bool use_srgb, + Image *ima); //* Checking powers of two for images since OpenGL ES requires it */ #ifdef WITH_DDS @@ -456,7 +470,7 @@ static uint gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf) return bindcode; } -static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) +static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, eGPUTextureTarget textarget) { uint bindcode = 0; const bool mipmap = GPU_get_mipmap(); @@ -465,7 +479,7 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) #ifdef WITH_DDS if (ibuf->ftype == IMB_FTYPE_DDS) { /* DDS is loaded directly in compressed form. */ - GPU_create_gl_tex_compressed(&bindcode, textarget, ima, ibuf); + gpu_create_gl_tex_compressed(&bindcode, textarget, ima, ibuf); return bindcode; } #endif @@ -518,7 +532,7 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) } /* Create OpenGL texture. */ - GPU_create_gl_tex(&bindcode, + gpu_create_gl_tex(&bindcode, (uint *)rect, rect_float, ibuf->x, @@ -542,7 +556,7 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) static GPUTexture **gpu_get_movieclip_gputexture(MovieClip *clip, MovieClipUser *cuser, - GLenum textarget) + eGPUTextureTarget textarget) { LISTBASE_FOREACH (MovieClip_RuntimeGPUTexture *, tex, &clip->runtime.gputextures) { if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) { @@ -558,12 +572,7 @@ static GPUTexture **gpu_get_movieclip_gputexture(MovieClip *clip, BLI_addtail(&clip->runtime.gputextures, tex); } - if (textarget == GL_TEXTURE_2D) { - return &tex->gputexture[TEXTARGET_2D]; - } - else if (textarget == GL_TEXTURE_CUBE_MAP) { - return &tex->gputexture[TEXTARGET_CUBE_MAP]; - } + return &tex->gputexture[textarget]; } } return NULL; @@ -841,7 +850,10 @@ static void gpu_texture_update_from_ibuf( * * `iuser` and `ibuf` are mutual exclusive parameters. The caller can pass the `ibuf` when already * available. It is also required when requesting the GPUTexture for a render result. */ -GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, ImBuf *ibuf, int textarget) +GPUTexture *GPU_texture_from_blender(Image *ima, + ImageUser *iuser, + ImBuf *ibuf, + eGPUTextureTarget textarget) { #ifndef GPU_STANDALONE if (ima == NULL) { @@ -915,7 +927,9 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, ImBuf *ibuf, return NULL; } -GPUTexture *GPU_texture_from_movieclip(MovieClip *clip, MovieClipUser *cuser, int textarget) +GPUTexture *GPU_texture_from_movieclip(MovieClip *clip, + MovieClipUser *cuser, + eGPUTextureTarget textarget) { #ifndef GPU_STANDALONE if (clip == NULL) { @@ -1039,17 +1053,19 @@ static void gpu_del_cube_map(void **cube_map) } /* Image *ima can be NULL */ -void GPU_create_gl_tex(uint *bind, - uint *rect, - float *frect, - int rectw, - int recth, - int textarget, - bool mipmap, - bool half_float, - bool use_srgb, - Image *ima) +static void gpu_create_gl_tex(uint *bind, + uint *rect, + float *frect, + int rectw, + int recth, + eGPUTextureTarget target, + bool mipmap, + bool half_float, + bool use_srgb, + Image *ima) { + GLenum textarget = (target == TEXTARGET_2D) ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP; + ImBuf *ibuf = NULL; if (textarget == GL_TEXTURE_2D && is_over_resolution_limit(textarget, rectw, recth)) { @@ -1140,13 +1156,14 @@ void GPU_create_gl_tex(uint *bind, } /** - * GPU_upload_dxt_texture() assumes that the texture is already bound and ready to go. - * This is so the viewport and the BGE can share some code. * Returns false if the provided ImBuf doesn't have a supported DXT compression format */ -bool GPU_upload_dxt_texture(ImBuf *ibuf, bool use_srgb) +bool GPU_upload_dxt_texture(ImBuf *ibuf, bool use_srgb, uint *bindcode) { #ifdef WITH_DDS + glGenTextures(1, (GLuint *)bindcode); + glBindTexture(GL_TEXTURE_2D, *bindcode); + GLint format = 0; int blocksize, height, width, i, size, offset = 0; @@ -1170,6 +1187,7 @@ bool GPU_upload_dxt_texture(ImBuf *ibuf, bool use_srgb) if (format == 0) { fprintf(stderr, "Unable to find a suitable DXT compression, falling back to uncompressed\n"); + glDeleteTextures(1, (GLuint *)bindcode); return false; } @@ -1177,6 +1195,7 @@ bool GPU_upload_dxt_texture(ImBuf *ibuf, bool use_srgb) fprintf( stderr, "Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n"); + glDeleteTextures(1, (GLuint *)bindcode); return false; } @@ -1210,6 +1229,7 @@ bool GPU_upload_dxt_texture(ImBuf *ibuf, bool use_srgb) /* set number of mipmap levels we have, needed in case they don't go down to 1x1 */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i - 1); + glBindTexture(GL_TEXTURE_2D, 0); return true; #else UNUSED_VARS(ibuf, use_srgb); @@ -1217,7 +1237,10 @@ bool GPU_upload_dxt_texture(ImBuf *ibuf, bool use_srgb) #endif } -void GPU_create_gl_tex_compressed(unsigned int *bind, int textarget, Image *ima, ImBuf *ibuf) +static void gpu_create_gl_tex_compressed(unsigned int *bind, + eGPUTextureTarget textarget, + Image *ima, + ImBuf *ibuf) { /* For DDS we only support data, scene linear and sRGB. Converting to * different colorspace would break the compression. */ @@ -1229,19 +1252,19 @@ void GPU_create_gl_tex_compressed(unsigned int *bind, int textarget, Image *ima, #ifndef WITH_DDS (void)ibuf; /* Fall back to uncompressed if DDS isn't enabled */ - GPU_create_gl_tex( + gpu_create_gl_tex( bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima); #else - glGenTextures(1, (GLuint *)bind); - glBindTexture(textarget, *bind); - if (textarget == GL_TEXTURE_2D && GPU_upload_dxt_texture(ibuf, use_srgb) == 0) { - glDeleteTextures(1, (GLuint *)bind); - GPU_create_gl_tex( - bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima); + if (textarget == TEXTARGET_2D) { + if (GPU_upload_dxt_texture(ibuf, use_srgb, bind)) { + /* All went fine! */ + return; + } } - - glBindTexture(textarget, 0); + /* Fallback. */ + gpu_create_gl_tex( + bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima); #endif } |