From 092cbacd8f5d5ca52141f3e052c4853e6b90419f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 12 May 2022 13:56:48 +0200 Subject: Fix T98026 EEVEE: Refression Crash when rendering Cryptomatte passes This was because the main `surface_vert.glsl` was changed to accomodate the needs of the `ShaderCreateInfo` but was still used by the cryptomatte shader. The fix is to include the same libraries as the material shaders and bypass `attrib_load()`. --- source/blender/draw/CMakeLists.txt | 1 + source/blender/draw/engines/eevee/eevee_cryptomatte.c | 8 +++----- source/blender/draw/engines/eevee/eevee_shaders.c | 6 ++++-- source/blender/draw/engines/eevee/shaders/cryptomatte_vert.glsl | 6 ++++++ 4 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 source/blender/draw/engines/eevee/shaders/cryptomatte_vert.glsl diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index ed90e77572e..1ff7585165b 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -333,6 +333,7 @@ set(GLSL_SRC engines/eevee/shaders/renderpass_lib.glsl engines/eevee/shaders/renderpass_postprocess_frag.glsl engines/eevee/shaders/cryptomatte_frag.glsl + engines/eevee/shaders/cryptomatte_vert.glsl engines/eevee/shaders/ltc_lib.glsl engines/eevee/shaders/ssr_lib.glsl engines/eevee/shaders/surface_frag.glsl diff --git a/source/blender/draw/engines/eevee/eevee_cryptomatte.c b/source/blender/draw/engines/eevee/eevee_cryptomatte.c index 50302eaa87a..b17efe4b68d 100644 --- a/source/blender/draw/engines/eevee/eevee_cryptomatte.c +++ b/source/blender/draw/engines/eevee/eevee_cryptomatte.c @@ -189,11 +189,8 @@ void EEVEE_cryptomatte_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat } } -static DRWShadingGroup *eevee_cryptomatte_shading_group_create(EEVEE_Data *vedata, - EEVEE_ViewLayerData *UNUSED(sldata), - Object *ob, - Material *material, - bool is_hair) +static DRWShadingGroup *eevee_cryptomatte_shading_group_create( + EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, Material *material, bool is_hair) { const DRWContextState *draw_ctx = DRW_context_state_get(); const ViewLayer *view_layer = draw_ctx->view_layer; @@ -229,6 +226,7 @@ static DRWShadingGroup *eevee_cryptomatte_shading_group_create(EEVEE_Data *vedat DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_cryptomatte_sh_get(is_hair), psl->cryptomatte_ps); DRW_shgroup_uniform_vec4_copy(grp, "cryptohash", cryptohash); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); return grp; } diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c index 85cc7f65126..105600d2333 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.c +++ b/source/blender/draw/engines/eevee/eevee_shaders.c @@ -183,6 +183,7 @@ extern char datatoc_closure_eval_volume_lib_glsl[]; extern char datatoc_common_uniforms_lib_glsl[]; extern char datatoc_common_utiltex_lib_glsl[]; extern char datatoc_cryptomatte_frag_glsl[]; +extern char datatoc_cryptomatte_vert_glsl[]; extern char datatoc_cubemap_lib_glsl[]; extern char datatoc_default_frag_glsl[]; extern char datatoc_lookdev_world_frag_glsl[]; @@ -305,6 +306,7 @@ static void eevee_shader_library_ensure(void) DRW_SHADER_LIB_ADD(e_data.lib, closure_eval_refraction_lib); DRW_SHADER_LIB_ADD(e_data.lib, closure_eval_surface_lib); DRW_SHADER_LIB_ADD(e_data.lib, closure_eval_volume_lib); + DRW_SHADER_LIB_ADD(e_data.lib, surface_vert); e_data.surface_lit_frag = DRW_shader_library_create_shader_string(e_data.lib, datatoc_surface_frag_glsl); @@ -718,7 +720,7 @@ GPUShader *EEVEE_shaders_cryptomatte_sh_get(bool is_hair) if (e_data.cryptomatte_sh[index] == NULL) { DynStr *ds = BLI_dynstr_new(); BLI_dynstr_append(ds, SHADER_DEFINES); - + BLI_dynstr_append(ds, "#define attrib_load(a) \n"); if (is_hair) { BLI_dynstr_append(ds, "#define HAIR_SHADER\n"); } @@ -727,7 +729,7 @@ GPUShader *EEVEE_shaders_cryptomatte_sh_get(bool is_hair) } char *defines = BLI_dynstr_get_cstring(ds); e_data.cryptomatte_sh[index] = DRW_shader_create_with_shaderlib( - datatoc_surface_vert_glsl, NULL, datatoc_cryptomatte_frag_glsl, e_data.lib, defines); + datatoc_cryptomatte_vert_glsl, NULL, datatoc_cryptomatte_frag_glsl, e_data.lib, defines); BLI_dynstr_free(ds); MEM_freeN(defines); } diff --git a/source/blender/draw/engines/eevee/shaders/cryptomatte_vert.glsl b/source/blender/draw/engines/eevee/shaders/cryptomatte_vert.glsl new file mode 100644 index 00000000000..f8dbc4772e9 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/cryptomatte_vert.glsl @@ -0,0 +1,6 @@ + +#pragma BLENDER_REQUIRE(closure_type_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_attribute_lib.glsl) +#pragma BLENDER_REQUIRE(surface_vert.glsl) -- cgit v1.2.3 From d9effc1cc64ad99c5f9f14a8f76fce9db2988c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 12 May 2022 15:11:07 +0200 Subject: Fix T98071: Overlay: UV selection inverted bewteen vertex and edge select Self describing title. Also remove the layout inside the geometry shader as they are now generated by the backend. --- source/blender/draw/engines/overlay/overlay_shader.c | 4 ++-- source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c index d63ae6750d6..48146fbddfb 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.c +++ b/source/blender/draw/engines/overlay/overlay_shader.c @@ -893,7 +893,7 @@ GPUShader *OVERLAY_shader_edit_uv_edges_get(void) { OVERLAY_Shaders *sh_data = &e_data.sh_data[0]; if (!sh_data->edit_uv_edges) { - sh_data->edit_uv_edges = GPU_shader_create_from_info_name("overlay_edit_uv_edges_select"); + sh_data->edit_uv_edges = GPU_shader_create_from_info_name("overlay_edit_uv_edges"); } return sh_data->edit_uv_edges; } @@ -903,7 +903,7 @@ GPUShader *OVERLAY_shader_edit_uv_edges_for_edge_select_get(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[0]; if (!sh_data->edit_uv_edges_for_edge_select) { sh_data->edit_uv_edges_for_edge_select = GPU_shader_create_from_info_name( - "overlay_edit_uv_edges"); + "overlay_edit_uv_edges_select"); } return sh_data->edit_uv_edges_for_edge_select; } diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl index 1012b50e0e1..ac8d33cd727 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl @@ -1,8 +1,5 @@ #pragma BLENDER_REQUIRE(common_overlay_lib.glsl) -layout(lines) in; -layout(triangle_strip, max_vertices = 4) out; - void do_vertex( vec4 pos, float selection_fac, vec2 stipple_start, vec2 stipple_pos, float coord, vec2 offset) { -- cgit v1.2.3 From 32fd85e6f995e3478c94c5c9eededbd3c325e15a Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 12 May 2022 17:19:22 +0200 Subject: Fix (unreported) bad memory access in read/write code of MeshDeform modifier. This abuse of one one size value to handle another allocated array of a different size is bad in itself, but at least now read/write code of this modifier should not risk invalid memory access anymore. NOTE: invalid memory access would in practice only happen in case endian switch would be performed at read time I think (those switches only check for given length being non-zero, not for a NULL data pointer...). --- source/blender/modifiers/intern/MOD_meshdeform.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 09e6819a2ae..c2e9e5ebe7d 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -587,7 +587,16 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md) int size = mmd->dyngridsize; BLO_write_struct_array(writer, MDefInfluence, mmd->influences_num, mmd->bindinfluences); - BLO_write_int32_array(writer, mmd->verts_num + 1, mmd->bindoffsets); + + /* NOTE: `bindoffset` is abusing `verts_num + 1` as its size, this becomes an incorrect value in + * case `verts_num == 0`, since `bindoffset` is then NULL, not a size 1 allocated array. */ + if (mmd->verts_num > 0) { + BLO_write_int32_array(writer, mmd->verts_num + 1, mmd->bindoffsets); + } + else { + BLI_assert(mmd->bindoffsets == NULL); + } + BLO_write_float3_array(writer, mmd->cage_verts_num, mmd->bindcagecos); BLO_write_struct_array(writer, MDefCell, size * size * size, mmd->dyngrid); BLO_write_struct_array(writer, MDefInfluence, mmd->influences_num, mmd->dyninfluences); @@ -599,7 +608,13 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; BLO_read_data_address(reader, &mmd->bindinfluences); - BLO_read_int32_array(reader, mmd->verts_num + 1, &mmd->bindoffsets); + + /* NOTE: `bindoffset` is abusing `verts_num + 1` as its size, this becomes an incorrect value in + * case `verts_num == 0`, since `bindoffset` is then NULL, not a size 1 allocated array. */ + if (mmd->verts_num > 0) { + BLO_read_int32_array(reader, mmd->verts_num + 1, &mmd->bindoffsets); + } + BLO_read_float3_array(reader, mmd->cage_verts_num, &mmd->bindcagecos); BLO_read_data_address(reader, &mmd->dyngrid); BLO_read_data_address(reader, &mmd->dyninfluences); -- cgit v1.2.3