From c6210f9bacdb3d8b7ba05f29136ac6f9c8f643d7 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 14 Sep 2020 09:46:30 +0200 Subject: DrawManager: Resolve Assert in Image Engine Tiled texture uses different texture structure than normal textures. Normally we add dummy textures and use them, but I found it cleaner to have 2 shaders and use the correct shader. --- source/blender/draw/engines/image/image_engine.c | 8 +++--- source/blender/draw/engines/image/image_private.h | 2 +- source/blender/draw/engines/image/image_shader.c | 17 +++++++----- .../engines/image/shaders/engine_image_frag.glsl | 31 ++++++++++++---------- source/blender/draw/tests/shaders_test.cc | 3 ++- 5 files changed, 34 insertions(+), 27 deletions(-) (limited to 'source') diff --git a/source/blender/draw/engines/image/image_engine.c b/source/blender/draw/engines/image/image_engine.c index 9f1278b473b..90bfb38dadf 100644 --- a/source/blender/draw/engines/image/image_engine.c +++ b/source/blender/draw/engines/image/image_engine.c @@ -42,8 +42,7 @@ #define SIMA_DRAW_FLAG_APPLY_ALPHA (1 << 1) #define SIMA_DRAW_FLAG_SHUFFLING (1 << 2) #define SIMA_DRAW_FLAG_DEPTH (1 << 3) -#define SIMA_DRAW_FLAG_TILED (1 << 4) -#define SIMA_DRAW_FLAG_DO_REPEAT (1 << 5) +#define SIMA_DRAW_FLAG_DO_REPEAT (1 << 4) static void image_cache_image_add(DRWShadingGroup *grp, Image *image) { @@ -179,10 +178,9 @@ static void image_cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser draw_flags |= SIMA_DRAW_FLAG_APPLY_ALPHA; } - GPUShader *shader = IMAGE_shader_image_get(); + GPUShader *shader = IMAGE_shader_image_get(is_tiled_texture); DRWShadingGroup *shgrp = DRW_shgroup_create(shader, psl->image_pass); - if (tex_tile_data != NULL) { - draw_flags |= SIMA_DRAW_FLAG_TILED; + if (is_tiled_texture) { DRW_shgroup_uniform_texture_ex(shgrp, "imageTileArray", pd->texture, state); DRW_shgroup_uniform_texture(shgrp, "imageTileData", tex_tile_data); } diff --git a/source/blender/draw/engines/image/image_private.h b/source/blender/draw/engines/image/image_private.h index defe5fd5bbb..312a05e0b3b 100644 --- a/source/blender/draw/engines/image/image_private.h +++ b/source/blender/draw/engines/image/image_private.h @@ -60,7 +60,7 @@ typedef struct IMAGE_Data { } IMAGE_Data; /* image_shader.c */ -GPUShader *IMAGE_shader_image_get(void); +GPUShader *IMAGE_shader_image_get(bool is_tiled_image); void IMAGE_shader_library_ensure(void); void IMAGE_shader_free(void); diff --git a/source/blender/draw/engines/image/image_shader.c b/source/blender/draw/engines/image/image_shader.c index 433c79e20cf..0e0c432c32f 100644 --- a/source/blender/draw/engines/image/image_shader.c +++ b/source/blender/draw/engines/image/image_shader.c @@ -37,7 +37,7 @@ extern char datatoc_engine_image_frag_glsl[]; extern char datatoc_engine_image_vert_glsl[]; typedef struct IMAGE_Shaders { - GPUShader *image_sh; + GPUShader *image_sh[2]; } IMAGE_Shaders; static struct { @@ -56,14 +56,19 @@ void IMAGE_shader_library_ensure(void) } } -GPUShader *IMAGE_shader_image_get(void) +GPUShader *IMAGE_shader_image_get(bool is_tiled_image) { + const int index = is_tiled_image ? 1 : 0; IMAGE_Shaders *sh_data = &e_data.shaders; - if (!sh_data->image_sh) { - sh_data->image_sh = DRW_shader_create_with_shaderlib( - datatoc_engine_image_vert_glsl, NULL, datatoc_engine_image_frag_glsl, e_data.lib, NULL); + if (!sh_data->image_sh[index]) { + sh_data->image_sh[index] = DRW_shader_create_with_shaderlib( + datatoc_engine_image_vert_glsl, + NULL, + datatoc_engine_image_frag_glsl, + e_data.lib, + is_tiled_image ? "#define TILED_IMAGE\n" : NULL); } - return sh_data->image_sh; + return sh_data->image_sh[index]; } void IMAGE_shader_free(void) diff --git a/source/blender/draw/engines/image/shaders/engine_image_frag.glsl b/source/blender/draw/engines/image/shaders/engine_image_frag.glsl index 5c5d9362dfc..a79f4915c4d 100644 --- a/source/blender/draw/engines/image/shaders/engine_image_frag.glsl +++ b/source/blender/draw/engines/image/shaders/engine_image_frag.glsl @@ -5,12 +5,14 @@ #define SIMA_DRAW_FLAG_APPLY_ALPHA (1 << 1) #define SIMA_DRAW_FLAG_SHUFFLING (1 << 2) #define SIMA_DRAW_FLAG_DEPTH (1 << 3) -#define SIMA_DRAW_FLAG_TILED (1 << 4) -#define SIMA_DRAW_FLAG_DO_REPEAT (1 << 5) +#define SIMA_DRAW_FLAG_DO_REPEAT (1 << 4) +#ifdef TILED_IMAGE uniform sampler2DArray imageTileArray; uniform sampler1DArray imageTileData; +#else uniform sampler2D imageTexture; +#endif uniform bool imgPremultiplied; uniform int drawFlags; @@ -25,6 +27,7 @@ in vec2 uvs; out vec4 fragColor; +#ifdef TILED_IMAGE /* TODO(fclem) deduplicate code. */ bool node_tex_tile_lookup(inout vec3 co, sampler2DArray ima, sampler1DArray map) { @@ -50,26 +53,26 @@ bool node_tex_tile_lookup(inout vec3 co, sampler2DArray ima, sampler1DArray map) co = vec3(((co.xy - tile_pos) * tile_info.zw) + tile_info.xy, tile_layer); return true; } +#endif void main() { vec4 tex_color; /* Read texture */ - if ((drawFlags & SIMA_DRAW_FLAG_TILED) != 0) { - vec3 co = vec3(uvs, 0.0); - if (node_tex_tile_lookup(co, imageTileArray, imageTileData)) { - tex_color = texture(imageTileArray, co); - } - else { - tex_color = vec4(1.0, 0.0, 1.0, 1.0); - } +#ifdef TILED_IMAGE + vec3 co = vec3(uvs, 0.0); + if (node_tex_tile_lookup(co, imageTileArray, imageTileData)) { + tex_color = texture(imageTileArray, co); } else { - vec2 uvs_clamped = ((drawFlags & SIMA_DRAW_FLAG_DO_REPEAT) != 0) ? - fract(uvs) : - clamp(uvs, vec2(0.0), vec2(1.0)); - tex_color = texture(imageTexture, uvs_clamped); + tex_color = vec4(1.0, 0.0, 1.0, 1.0); } +#else + vec2 uvs_clamped = ((drawFlags & SIMA_DRAW_FLAG_DO_REPEAT) != 0) ? + fract(uvs) : + clamp(uvs, vec2(0.0), vec2(1.0)); + tex_color = texture(imageTexture, uvs_clamped); +#endif if ((drawFlags & SIMA_DRAW_FLAG_APPLY_ALPHA) != 0) { if (!imgPremultiplied && tex_color.a != 0.0 && tex_color.a != 1.0) { diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc index 8feccc9588e..f99fa04ce75 100644 --- a/source/blender/draw/tests/shaders_test.cc +++ b/source/blender/draw/tests/shaders_test.cc @@ -156,7 +156,8 @@ TEST_F(DrawTest, image_glsl_shaders) { IMAGE_shader_library_ensure(); - EXPECT_NE(IMAGE_shader_image_get(), nullptr); + EXPECT_NE(IMAGE_shader_image_get(false), nullptr); + EXPECT_NE(IMAGE_shader_image_get(true), nullptr); IMAGE_shader_free(); } -- cgit v1.2.3