Fix #119787: Curves viewport attribute drawing crash

Caused by 1cca960677.

That commit stated that creating the final subdivided attribute didn't
free the "proc" attribute buffer that contains the data from the Curves
control points. However that wasn't the case, given the call to
`GPU_VERTBUF_DISCARD_SAFE` in that function. That caused a crash when
the overlay engine and EEVEE both wanted to access the VBO and it was
discarded the second time. To fix that, only regenerate the
`proc_attributes_buf` when it doesn't already exist.

This matches the "ensure" behavior that already exists for the
`cache.final[subdiv].attributes_buf` buffer, so conceptually it
seems fine.

Pull Request: https://projects.blender.org/blender/blender/pulls/119795
This commit is contained in:
Hans Goudey 2024-03-22 17:19:50 +01:00 committed by Hans Goudey
parent 303014bfac
commit 7f4a4fa605
1 changed files with 27 additions and 14 deletions

View File

@ -313,24 +313,20 @@ static void curves_batch_cache_ensure_procedural_final_attr(CurvesEvalCache &cac
final_cache.strands_res * cache.strands_len);
}
static void curves_batch_ensure_attribute(const Curves &curves,
CurvesEvalCache &cache,
const DRW_AttributeRequest &request,
const int subdiv,
const int index)
static void curves_batch_ensure_proc_attribute(const Curves &curves,
CurvesEvalCache &cache,
const DRW_AttributeRequest &request,
const int index,
const GPUVertFormat *format)
{
if (cache.proc_attributes_buf[index] != nullptr) {
return;
}
GPU_VERTBUF_DISCARD_SAFE(cache.proc_attributes_buf[index]);
char sampler_name[32];
drw_curves_get_attribute_sampler_name(request.attribute_name, sampler_name);
GPUVertFormat format = {0};
GPU_vertformat_deinterleave(&format);
/* All attributes use vec4, see comment below. */
GPU_vertformat_attr_add(&format, sampler_name, GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
cache.proc_attributes_buf[index] = GPU_vertbuf_create_with_format_ex(
&format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY);
format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY);
GPUVertBuf *attr_vbo = cache.proc_attributes_buf[index];
GPU_vertbuf_data_alloc(attr_vbo,
@ -352,6 +348,23 @@ static void curves_batch_ensure_attribute(const Curves &curves,
attributes.domain_size(request.domain)};
attribute.varray.materialize(vbo_span);
}
static void curves_batch_ensure_attribute(const Curves &curves,
CurvesEvalCache &cache,
const DRW_AttributeRequest &request,
const int subdiv,
const int index)
{
char sampler_name[32];
drw_curves_get_attribute_sampler_name(request.attribute_name, sampler_name);
GPUVertFormat format = {0};
GPU_vertformat_deinterleave(&format);
/* All attributes use vec4, see comment below. */
GPU_vertformat_attr_add(&format, sampler_name, GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
curves_batch_ensure_proc_attribute(curves, cache, request, index, &format);
/* Existing final data may have been for a different attribute (with a different name or domain),
* free the data. */