Fix T98392: GPU subdivision crash with knife tools
The face dots normals may not be always requested, thus leading to a crash by null pointer dereference.
This commit is contained in:
parent
38a2576ace
commit
55e3930b25
Notes:
blender-bot
2023-02-13 15:21:05 +01:00
Referenced by commit 7f7ed8e098
, Fix T98571: corrupted face selection drawing with GPU subdivision
Referenced by issue #98392, GPU Subdivision: Crash when knife cut is made on object with mirror modifier
|
@ -69,6 +69,7 @@ enum {
|
|||
SHADER_PATCH_EVALUATION,
|
||||
SHADER_PATCH_EVALUATION_FVAR,
|
||||
SHADER_PATCH_EVALUATION_FACE_DOTS,
|
||||
SHADER_PATCH_EVALUATION_FACE_DOTS_WITH_NORMALS,
|
||||
SHADER_COMP_CUSTOM_DATA_INTERP_1D,
|
||||
SHADER_COMP_CUSTOM_DATA_INTERP_2D,
|
||||
SHADER_COMP_CUSTOM_DATA_INTERP_3D,
|
||||
|
@ -107,7 +108,8 @@ static const char *get_shader_code(int shader_type)
|
|||
}
|
||||
case SHADER_PATCH_EVALUATION:
|
||||
case SHADER_PATCH_EVALUATION_FVAR:
|
||||
case SHADER_PATCH_EVALUATION_FACE_DOTS: {
|
||||
case SHADER_PATCH_EVALUATION_FACE_DOTS:
|
||||
case SHADER_PATCH_EVALUATION_FACE_DOTS_WITH_NORMALS: {
|
||||
return datatoc_common_subdiv_patch_evaluation_comp_glsl;
|
||||
}
|
||||
case SHADER_COMP_CUSTOM_DATA_INTERP_1D:
|
||||
|
@ -163,6 +165,9 @@ static const char *get_shader_name(int shader_type)
|
|||
case SHADER_PATCH_EVALUATION_FACE_DOTS: {
|
||||
return "subdiv patch evaluation face dots";
|
||||
}
|
||||
case SHADER_PATCH_EVALUATION_FACE_DOTS_WITH_NORMALS: {
|
||||
return "subdiv patch evaluation face dots with normals";
|
||||
}
|
||||
case SHADER_COMP_CUSTOM_DATA_INTERP_1D: {
|
||||
return "subdiv custom data interp 1D";
|
||||
}
|
||||
|
@ -206,6 +211,13 @@ static GPUShader *get_patch_evaluation_shader(int shader_type)
|
|||
"#define OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES\n"
|
||||
"#define FDOTS_EVALUATION\n";
|
||||
}
|
||||
else if (shader_type == SHADER_PATCH_EVALUATION_FACE_DOTS_WITH_NORMALS) {
|
||||
defines =
|
||||
"#define OSD_PATCH_BASIS_GLSL\n"
|
||||
"#define OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES\n"
|
||||
"#define FDOTS_EVALUATION\n"
|
||||
"#define FOTS_NORMALS\n";
|
||||
}
|
||||
else {
|
||||
defines =
|
||||
"#define OSD_PATCH_BASIS_GLSL\n"
|
||||
|
@ -1625,7 +1637,9 @@ void draw_subdiv_build_fdots_buffers(const DRWSubdivCache *cache,
|
|||
get_patch_param_format());
|
||||
evaluator->wrapPatchParamBuffer(evaluator, &patch_param_buffer_interface);
|
||||
|
||||
GPUShader *shader = get_patch_evaluation_shader(SHADER_PATCH_EVALUATION_FACE_DOTS);
|
||||
GPUShader *shader = get_patch_evaluation_shader(
|
||||
fdots_nor ? SHADER_PATCH_EVALUATION_FACE_DOTS_WITH_NORMALS :
|
||||
SHADER_PATCH_EVALUATION_FACE_DOTS);
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
int binding_point = 0;
|
||||
|
@ -1638,7 +1652,11 @@ void draw_subdiv_build_fdots_buffers(const DRWSubdivCache *cache,
|
|||
GPU_vertbuf_bind_as_ssbo(patch_index_buffer, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(patch_param_buffer, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(fdots_pos, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(fdots_nor, binding_point++);
|
||||
/* F-dots normals may not be requested, still reserve the binding point. */
|
||||
if (fdots_nor) {
|
||||
GPU_vertbuf_bind_as_ssbo(fdots_nor, binding_point);
|
||||
}
|
||||
binding_point++;
|
||||
GPU_indexbuf_bind_as_ssbo(fdots_indices, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(cache->extra_coarse_face_data, binding_point++);
|
||||
BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS);
|
||||
|
|
|
@ -110,8 +110,11 @@ static void extract_fdots_init_subdiv(const DRWSubdivCache *subdiv_cache,
|
|||
GPUVertBuf *fdots_nor_vbo = cache->final.buff.vbo.fdots_nor;
|
||||
GPUIndexBuf *fdots_pos_ibo = cache->final.buff.ibo.fdots;
|
||||
|
||||
GPU_vertbuf_init_build_on_device(
|
||||
fdots_nor_vbo, get_fdots_nor_format_subdiv(), subdiv_cache->num_coarse_poly);
|
||||
/* The normals may not be requested. */
|
||||
if (fdots_nor_vbo) {
|
||||
GPU_vertbuf_init_build_on_device(
|
||||
fdots_nor_vbo, get_fdots_nor_format_subdiv(), subdiv_cache->num_coarse_poly);
|
||||
}
|
||||
GPU_vertbuf_init_build_on_device(
|
||||
fdots_pos_vbo, get_fdots_pos_format(), subdiv_cache->num_coarse_poly);
|
||||
GPU_indexbuf_init_build_on_device(fdots_pos_ibo, subdiv_cache->num_coarse_poly);
|
||||
|
|
|
@ -70,10 +70,12 @@ layout(std430, binding = 8) writeonly buffer outputVertices
|
|||
FDotVert output_verts[];
|
||||
};
|
||||
|
||||
# ifdef FDOTS_NORMALS
|
||||
layout(std430, binding = 9) writeonly buffer outputNormals
|
||||
{
|
||||
FDotNor output_nors[];
|
||||
};
|
||||
# endif
|
||||
|
||||
layout(std430, binding = 10) writeonly buffer outputFdotsIndices
|
||||
{
|
||||
|
@ -375,13 +377,15 @@ void main()
|
|||
fnor.flag = get_face_flag(coarse_quad_index);
|
||||
|
||||
output_verts[coarse_quad_index] = vert;
|
||||
# ifdef FDOTS_NORMALS
|
||||
output_nors[coarse_quad_index] = fnor;
|
||||
# endif
|
||||
|
||||
if (is_face_hidden(coarse_quad_index)) {
|
||||
output_indices[coarse_quad_index] = 0xffffffff;
|
||||
output_indices[coarse_quad_index] = 0xffffffff;
|
||||
}
|
||||
else {
|
||||
output_indices[coarse_quad_index] = coarse_quad_index;
|
||||
output_indices[coarse_quad_index] = coarse_quad_index;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue