diff options
Diffstat (limited to 'source/blender/draw')
13 files changed, 81 insertions, 74 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c index d4b1d421603..58897272425 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.c +++ b/source/blender/draw/engines/eevee/eevee_shaders.c @@ -647,7 +647,8 @@ GPUShader *EEVEE_shaders_effect_motion_blur_velocity_tiles_expand_sh_get(void) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Ambient Occlusion */ +/** \name Ambient Occlusion + * \{ */ GPUShader *EEVEE_shaders_effect_ambient_occlusion_sh_get(void) { @@ -679,7 +680,8 @@ GPUShader *EEVEE_shaders_effect_ambient_occlusion_debug_sh_get(void) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Render Passes */ +/** \name Render Passes + * \{ */ GPUShader *EEVEE_shaders_renderpasses_post_process_sh_get(void) { @@ -693,7 +695,8 @@ GPUShader *EEVEE_shaders_renderpasses_post_process_sh_get(void) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Screen Raytrace */ +/** \name Screen Raytrace + * \{ */ struct GPUShader *EEVEE_shaders_effect_screen_raytrace_sh_get(EEVEE_SSRShaderOptions options) { @@ -730,7 +733,8 @@ struct GPUShader *EEVEE_shaders_effect_screen_raytrace_sh_get(EEVEE_SSRShaderOpt /** \} */ /* -------------------------------------------------------------------- */ -/** \name Shadows */ +/** \name Shadows + * \{ */ struct GPUShader *EEVEE_shaders_shadow_sh_get() { @@ -753,7 +757,8 @@ struct GPUShader *EEVEE_shaders_shadow_accum_sh_get() /** \} */ /* -------------------------------------------------------------------- */ -/** \name Subsurface */ +/** \name Subsurface + * \{ */ struct GPUShader *EEVEE_shaders_subsurface_first_pass_sh_get() { @@ -786,7 +791,8 @@ struct GPUShader *EEVEE_shaders_subsurface_translucency_sh_get() /** \} */ /* -------------------------------------------------------------------- */ -/** \name Volumes */ +/** \name Volumes + * \{ */ struct GPUShader *EEVEE_shaders_volumes_clear_sh_get() { 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 d11d868d4d2..312a05e0b3b 100644 --- a/source/blender/draw/engines/image/image_private.h +++ b/source/blender/draw/engines/image/image_private.h @@ -34,7 +34,7 @@ struct GPUTexture; /* *********** LISTS *********** */ /* GPUViewport.storage - * Is freed everytime the viewport engine changes */ + * Is freed every time the viewport engine changes. */ typedef struct IMAGE_PassList { DRWPass *image_pass; } IMAGE_PassList; @@ -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/engines/overlay/overlay_edit_uv.c b/source/blender/draw/engines/overlay/overlay_edit_uv.c index 109db6433e0..adbf7168394 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_uv.c +++ b/source/blender/draw/engines/overlay/overlay_edit_uv.c @@ -96,16 +96,19 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata) (ts->uv_selectmode == UV_SELECT_FACE); const bool do_uvstretching_overlay = is_image_type && is_uv_editor && is_edit_mode && ((sima->flag & SI_DRAW_STRETCH) != 0); + const bool do_tex_paint_shadows = (sima->flag & SI_NO_DRAW_TEXPAINT) == 0; + pd->edit_uv.do_faces = do_faces && !do_uvstretching_overlay; pd->edit_uv.do_face_dots = do_faces && do_face_dots; pd->edit_uv.do_uv_overlay = do_uv_overlay; - pd->edit_uv.do_uv_shadow_overlay = - is_image_type && - ((is_paint_mode && - ((draw_ctx->object_mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_EDIT)) != 0)) || - (is_view_mode && ((draw_ctx->object_mode & (OB_MODE_TEXTURE_PAINT)) != 0)) || - (do_uv_overlay && (show_modified_uvs))); + pd->edit_uv.do_uv_shadow_overlay = is_image_type && + ((is_paint_mode && do_tex_paint_shadows && + ((draw_ctx->object_mode & + (OB_MODE_TEXTURE_PAINT | OB_MODE_EDIT)) != 0)) || + (is_view_mode && do_tex_paint_shadows && + ((draw_ctx->object_mode & (OB_MODE_TEXTURE_PAINT)) != 0)) || + (do_uv_overlay && (show_modified_uvs))); pd->edit_uv.do_uv_stretching_overlay = do_uvstretching_overlay; pd->edit_uv.uv_opacity = sima->uv_opacity; pd->edit_uv.do_tiled_image_overlay = is_image_type && is_tiled_image; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl index b77e168889f..856654549ca 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl @@ -8,6 +8,8 @@ out vec4 fragColor; void main() { float depth = texture(depthBuffer, uvcoordsvar.st).r; + /* Fix issues with Intel drivers (see T80023). */ + fragColor = vec4(0.0); /* Discard background pixels. */ if (depth == 1.0) { discard; diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 8983826f16f..d377f09ac73 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -131,6 +131,9 @@ typedef struct WORKBENCH_PassList { struct DRWPass *transp_accum_ps; struct DRWPass *transp_accum_infront_ps; + struct DRWPass *transp_depth_infront_ps; + struct DRWPass *transp_depth_ps; + struct DRWPass *shadow_ps[2]; struct DRWPass *merge_infront_ps; diff --git a/source/blender/draw/engines/workbench/workbench_transparent.c b/source/blender/draw/engines/workbench/workbench_transparent.c index 1c8575ddc12..94fcd8b5a9d 100644 --- a/source/blender/draw/engines/workbench/workbench_transparent.c +++ b/source/blender/draw/engines/workbench/workbench_transparent.c @@ -91,16 +91,18 @@ void workbench_transparent_cache_init(WORKBENCH_Data *vedata) { int transp = 1; for (int infront = 0; infront < 2; infront++) { - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_OIT; + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_OIT | + wpd->cull_state | wpd->clip_state; DRWPass *pass; if (infront) { - DRW_PASS_CREATE(psl->transp_accum_infront_ps, state | wpd->cull_state | wpd->clip_state); - pass = psl->transp_accum_infront_ps; + psl->transp_accum_infront_ps = pass = DRW_pass_create("transp_accum_infront", state); + DRW_PASS_INSTANCE_CREATE( + psl->transp_depth_infront_ps, pass, state | DRW_STATE_WRITE_DEPTH); } else { - DRW_PASS_CREATE(psl->transp_accum_ps, state | wpd->cull_state | wpd->clip_state); - pass = psl->transp_accum_ps; + psl->transp_accum_ps = pass = DRW_pass_create("transp_accum", state); + DRW_PASS_INSTANCE_CREATE(psl->transp_depth_ps, pass, state | DRW_STATE_WRITE_DEPTH); } for (eWORKBENCH_DataType data = 0; data < WORKBENCH_DATATYPE_MAX; data++) { @@ -159,20 +161,17 @@ void workbench_transparent_draw_depth_pass(WORKBENCH_Data *data) const bool do_transparent_depth_pass = psl->outline_ps || wpd->dof_enabled || do_xray_depth_pass; if (do_transparent_depth_pass) { - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; - if (!DRW_pass_is_empty(psl->transp_accum_ps)) { + if (!DRW_pass_is_empty(psl->transp_depth_ps)) { GPU_framebuffer_bind(fbl->opaque_fb); /* TODO(fclem) Disable writing to first two buffers. Unnecessary waste of bandwidth. */ - DRW_pass_state_set(psl->transp_accum_ps, state | wpd->cull_state | wpd->clip_state); - DRW_draw_pass(psl->transp_accum_ps); + DRW_draw_pass(psl->transp_depth_ps); } - if (!DRW_pass_is_empty(psl->transp_accum_infront_ps)) { + if (!DRW_pass_is_empty(psl->transp_depth_infront_ps)) { GPU_framebuffer_bind(fbl->opaque_infront_fb); /* TODO(fclem) Disable writing to first two buffers. Unnecessary waste of bandwidth. */ - DRW_pass_state_set(psl->transp_accum_infront_ps, state | wpd->cull_state | wpd->clip_state); - DRW_draw_pass(psl->transp_accum_infront_ps); + DRW_draw_pass(psl->transp_depth_infront_ps); } } } diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 30c6f0ad4dc..2744c55a231 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -581,10 +581,6 @@ bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup); DRWPass *DRW_pass_create(const char *name, DRWState state); DRWPass *DRW_pass_create_instance(const char *name, DRWPass *original, DRWState state); void DRW_pass_link(DRWPass *first, DRWPass *second); -/* TODO Replace with passes inheritance. */ -void DRW_pass_state_set(DRWPass *pass, DRWState state); -void DRW_pass_state_add(DRWPass *pass, DRWState state); -void DRW_pass_state_remove(DRWPass *pass, DRWState state); void DRW_pass_foreach_shgroup(DRWPass *pass, void (*callback)(void *userData, DRWShadingGroup *shgroup), void *userData); diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 81842f5d2ec..7fe3bc0f071 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -1947,7 +1947,7 @@ DRWPass *DRW_pass_create(const char *name, DRWState state) { DRWPass *pass = BLI_memblock_alloc(DST.vmempool->passes); pass->state = state | DRW_STATE_PROGRAM_POINT_SIZE; - if (((G.debug_value > 20) && (G.debug_value < 30)) || (G.debug & G_DEBUG)) { + if (G.debug & G_DEBUG_GPU) { BLI_strncpy(pass->name, name, MAX_PASS_NAME); } @@ -1962,6 +1962,8 @@ DRWPass *DRW_pass_create(const char *name, DRWState state) return pass; } +/* Create an instance of the original pass that will execute the same drawcalls but with its own + * DRWState. */ DRWPass *DRW_pass_create_instance(const char *name, DRWPass *original, DRWState state) { DRWPass *pass = DRW_pass_create(name, state); @@ -1980,6 +1982,10 @@ void DRW_pass_link(DRWPass *first, DRWPass *second) bool DRW_pass_is_empty(DRWPass *pass) { + if (pass->original) { + return DRW_pass_is_empty(pass->original); + } + LISTBASE_FOREACH (DRWShadingGroup *, shgroup, &pass->shgroups) { if (!DRW_shgroup_is_empty(shgroup)) { return false; @@ -1988,21 +1994,6 @@ bool DRW_pass_is_empty(DRWPass *pass) return true; } -void DRW_pass_state_set(DRWPass *pass, DRWState state) -{ - pass->state = state | DRW_STATE_PROGRAM_POINT_SIZE; -} - -void DRW_pass_state_add(DRWPass *pass, DRWState state) -{ - pass->state |= state; -} - -void DRW_pass_state_remove(DRWPass *pass, DRWState state) -{ - pass->state &= ~state; -} - void DRW_pass_foreach_shgroup(DRWPass *pass, void (*callback)(void *userData, DRWShadingGroup *shgrp), void *userData) diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 3033cf70b29..86f19c6cfd7 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -231,7 +231,7 @@ void DRW_draw_cursor_2d(void) /* Draw nice Anti Aliased cursor. */ GPU_line_width(1.0f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); /* Draw lines */ @@ -248,7 +248,7 @@ void DRW_draw_cursor_2d(void) GPU_batch_draw(cursor_batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); GPU_matrix_pop(); GPU_matrix_projection_set(original_proj); 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(); } |