From eaa3dd0cd3e94c98ada8468780d4d0190c7f0cfb Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 13 May 2025 13:35:30 +0200 Subject: [PATCH] Refactor: Remove data type from draw attribute request struct Similar to 93be6baa9c1fbd5fcaf831b389862ddf956c038c. It doesn't make sense to store the type as part of the request since we upload any generic attribute, and the vertex buffer type is just chosen depending on the attribute's type in the geometry anyway. The code in `mesh_cd_calc_used_gpu_layers` is unfortunately still way too complicated to remove the custom data layer lookup, but this gets us one step closer. Pull Request: https://projects.blender.org/blender/blender/pulls/138791 --- source/blender/draw/DRW_pbvh.hh | 8 +- source/blender/draw/intern/draw_attributes.cc | 8 +- source/blender/draw/intern/draw_attributes.hh | 5 +- .../draw/intern/draw_cache_extract_mesh.cc | 6 +- .../draw/intern/draw_cache_impl_curves.cc | 10 +- .../draw/intern/draw_cache_impl_mesh.cc | 6 +- .../draw/intern/draw_cache_impl_pointcloud.cc | 11 +- source/blender/draw/intern/draw_curves.cc | 4 +- source/blender/draw/intern/draw_pbvh.cc | 8 +- source/blender/draw/intern/draw_sculpt.cc | 8 +- .../intern/mesh_extractors/extract_mesh.hh | 4 +- .../extract_mesh_vbo_attributes.cc | 170 +++++++++++------- 12 files changed, 132 insertions(+), 116 deletions(-) diff --git a/source/blender/draw/DRW_pbvh.hh b/source/blender/draw/DRW_pbvh.hh index 0e74d1350c2..3b193cc6bbc 100644 --- a/source/blender/draw/DRW_pbvh.hh +++ b/source/blender/draw/DRW_pbvh.hh @@ -36,13 +36,7 @@ class Tree; namespace blender::draw::pbvh { -class GenericRequest { - public: - std::string name; - eCustomDataType type; - GenericRequest(const StringRef name, const eCustomDataType type) : name(name), type(type) {} - BLI_STRUCT_EQUALITY_OPERATORS_2(GenericRequest, type, name); -}; +using GenericRequest = std::string; enum class CustomRequest : int8_t { Position, diff --git a/source/blender/draw/intern/draw_attributes.cc b/source/blender/draw/intern/draw_attributes.cc index dda4246187f..bcc5b6460d6 100644 --- a/source/blender/draw/intern/draw_attributes.cc +++ b/source/blender/draw/intern/draw_attributes.cc @@ -4,7 +4,6 @@ #include "BLI_string.h" -#include "BKE_attribute.hh" #include "BKE_customdata.hh" #include "draw_attributes.hh" @@ -17,7 +16,7 @@ static bool drw_attributes_has_request(const DRW_Attributes *requests, { for (int i = 0; i < requests->num_requests; i++) { const DRW_AttributeRequest &src_req = requests->requests[i]; - if (STREQ(src_req.attribute_name, req.attribute_name) && src_req.cd_type == req.cd_type) { + if (STREQ(src_req.attribute_name, req.attribute_name)) { return true; } } @@ -66,12 +65,9 @@ bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b) return true; } -void drw_attributes_add_request(DRW_Attributes *attrs, - const char *name, - const eCustomDataType type) +void drw_attributes_add_request(DRW_Attributes *attrs, const char *name) { DRW_AttributeRequest req{}; - req.cd_type = type; STRNCPY(req.attribute_name, name); if (attrs->num_requests >= GPU_MAX_ATTR || drw_attributes_has_request(attrs, req)) { return; diff --git a/source/blender/draw/intern/draw_attributes.hh b/source/blender/draw/intern/draw_attributes.hh index 8a7d2ad9431..09caf3b8834 100644 --- a/source/blender/draw/intern/draw_attributes.hh +++ b/source/blender/draw/intern/draw_attributes.hh @@ -24,7 +24,6 @@ enum class AttrDomain : int8_t; namespace blender::draw { struct DRW_AttributeRequest { - eCustomDataType cd_type; char attribute_name[64]; }; @@ -57,9 +56,7 @@ void drw_attributes_merge(DRW_Attributes *dst, const DRW_Attributes *src, Mutex /* Return true if all requests in b are in a. */ bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b); -void drw_attributes_add_request(DRW_Attributes *attrs, - const char *name, - eCustomDataType data_type); +void drw_attributes_add_request(DRW_Attributes *attrs, const char *name); bool drw_custom_data_match_attribute(const CustomData &custom_data, const char *name, diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc index a9df1dcf557..d3a09d5fea0 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc @@ -266,7 +266,8 @@ void mesh_buffer_cache_create_requested(TaskGraph & /*task_graph*/, case VBOType::Attr14: case VBOType::Attr15: { const int8_t attr_index = int8_t(vbos_to_create[i]) - int8_t(VBOType::Attr0); - created_vbos[i] = extract_attribute(mr, cache.attr_used.requests[attr_index]); + created_vbos[i] = extract_attribute(mr, + cache.attr_used.requests[attr_index].attribute_name); break; } case VBOType::AttrViewer: @@ -451,7 +452,8 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache, const VBOType request = VBOType(int8_t(VBOType::Attr0) + i); if (vbos_to_create.contains(request)) { buffers.vbos.add_new( - request, extract_attribute_subdiv(mr, subdiv_cache, cache.attr_used.requests[i])); + request, + extract_attribute_subdiv(mr, subdiv_cache, cache.attr_used.requests[i].attribute_name)); } } } diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 1c5b7900a24..54d6a7e2d5b 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -818,7 +818,7 @@ static bool ensure_attributes(const Curves &curves, } if (layer != -1 && domain.has_value()) { - drw_attributes_add_request(&attrs_needed, name, CD_PROP_FLOAT2); + drw_attributes_add_request(&attrs_needed, name); } break; } @@ -839,7 +839,7 @@ static bool ensure_attributes(const Curves &curves, case CD_PROP_FLOAT: case CD_PROP_FLOAT2: { if (layer != -1 && domain.has_value()) { - drw_attributes_add_request(&attrs_needed, name, type); + drw_attributes_add_request(&attrs_needed, name); } break; } @@ -885,12 +885,10 @@ static void request_attribute(Curves &curves, const char *name) DRW_Attributes attributes{}; bke::CurvesGeometry &curves_geometry = curves.geometry.wrap(); - std::optional meta_data = curves_geometry.attributes().lookup_meta_data( - name); - if (!meta_data) { + if (!curves_geometry.attributes().contains(name)) { return; } - drw_attributes_add_request(&attributes, name, meta_data->data_type); + drw_attributes_add_request(&attributes, name); drw_attributes_merge(&final_cache.attr_used, &attributes, cache.render_mutex); } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index e1248f376cf..9288da007f5 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -299,7 +299,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object &object, case CD_PROP_FLOAT: case CD_PROP_FLOAT2: { if (layer != -1 && domain.has_value()) { - drw_attributes_add_request(attributes, name, type); + drw_attributes_add_request(attributes, name); } break; } @@ -694,10 +694,10 @@ static void request_active_and_default_color_attributes(const Object &object, int layer_index; eCustomDataType type; if (drw_custom_data_match_attribute(cd_vdata, name, &layer_index, &type)) { - drw_attributes_add_request(&attributes, name, type); + drw_attributes_add_request(&attributes, name); } else if (drw_custom_data_match_attribute(cd_ldata, name, &layer_index, &type)) { - drw_attributes_add_request(&attributes, name, type); + drw_attributes_add_request(&attributes, name); } } }; diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc index 6151a39b909..f55ca2fbd1c 100644 --- a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc +++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc @@ -356,12 +356,10 @@ gpu::Batch **pointcloud_surface_shaded_get(PointCloud *pointcloud, ListBase gpu_attrs = GPU_material_attributes(gpu_material); LISTBASE_FOREACH (GPUMaterialAttribute *, gpu_attr, &gpu_attrs) { const char *name = gpu_attr->name; - const std::optional meta_data = attributes.lookup_meta_data(name); - if (!meta_data) { + if (!attributes.contains(name)) { continue; } - - drw_attributes_add_request(&attrs_needed, name, meta_data->data_type); + drw_attributes_add_request(&attrs_needed, name); } } @@ -408,13 +406,12 @@ gpu::VertBuf **DRW_pointcloud_evaluated_attribute(PointCloud *pointcloud, const const bke::AttributeAccessor attributes = pointcloud->attributes(); PointCloudBatchCache &cache = *pointcloud_batch_cache_get(*pointcloud); - const std::optional meta_data = attributes.lookup_meta_data(name); - if (!meta_data) { + if (!attributes.contains(name)) { return nullptr; } { DRW_Attributes requests{}; - drw_attributes_add_request(&requests, name, meta_data->data_type); + drw_attributes_add_request(&requests, name); drw_attributes_merge(&cache.eval_cache.attr_used, &requests, cache.render_mutex); } diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 595e1885f52..ea34cbe7cbe 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -344,7 +344,7 @@ gpu::Batch *curves_sub_pass_setup_implementation(PassT &sub_ps, continue; } sub_ps.bind_texture(sampler_name, curves_cache->proc_attributes_buf[i]); - if (request.cd_type == CD_PROP_FLOAT2 && request.attribute_name == curve_data_render_uv) { + if (request.attribute_name == curve_data_render_uv) { sub_ps.bind_texture("a", curves_cache->proc_attributes_buf[i]); } } @@ -353,7 +353,7 @@ gpu::Batch *curves_sub_pass_setup_implementation(PassT &sub_ps, continue; } sub_ps.bind_texture(sampler_name, curves_cache->final.attributes_buf[i]); - if (request.cd_type == CD_PROP_FLOAT2 && request.attribute_name == point_data_render_uv) { + if (request.attribute_name == point_data_render_uv) { sub_ps.bind_texture("a", curves_cache->final.attributes_buf[i]); } } diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 75766b51b76..911e6c768c3 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -46,7 +46,7 @@ template<> struct DefaultHash { return get_default_hash(*request_type); } const GenericRequest &attr = std::get(value); - return get_default_hash(attr.name); + return get_default_hash(attr); } }; @@ -239,7 +239,7 @@ void DrawCacheImpl::tag_attribute_changed(const IndexMask &node_mask, StringRef { for (const auto &[data_request, data] : attribute_vbos_.items()) { if (const GenericRequest *request = std::get_if(&data_request)) { - if (request->name == attribute_name) { + if (*request == attribute_name) { data.tag_dirty(node_mask); } } @@ -1717,7 +1717,7 @@ Span DrawCacheImpl::ensure_attribute_data(const Object &object, } else { update_generic_attribute_mesh( - object, orig_mesh_data, mask, std::get(attr).name, vbos); + object, orig_mesh_data, mask, std::get(attr), vbos); } break; } @@ -1768,7 +1768,7 @@ Span DrawCacheImpl::ensure_attribute_data(const Object &object, } else { update_generic_attribute_bmesh( - object, orig_mesh_data, mask, std::get(attr).name, vbos); + object, orig_mesh_data, mask, std::get(attr), vbos); } break; } diff --git a/source/blender/draw/intern/draw_sculpt.cc b/source/blender/draw/intern/draw_sculpt.cc index e218aa51a2a..e61425207df 100644 --- a/source/blender/draw/intern/draw_sculpt.cc +++ b/source/blender/draw/intern/draw_sculpt.cc @@ -177,11 +177,11 @@ Vector sculpt_batches_get(const Object *ob, SculptBatchFeature feat { if (ss.bm) { if (bmesh_attribute_exists(*ss.bm, *meta_data, name)) { - attrs.append(pbvh::GenericRequest{name, meta_data->data_type}); + attrs.append(pbvh::GenericRequest(name)); } } else { - attrs.append(pbvh::GenericRequest{name, meta_data->data_type}); + attrs.append(pbvh::GenericRequest(name)); } } } @@ -214,7 +214,7 @@ Vector sculpt_batches_per_material_get(const Object *ob, for (int i = 0; i < draw_attrs.num_requests; i++) { const DRW_AttributeRequest &req = draw_attrs.requests[i]; - attrs.append(pbvh::GenericRequest{req.attribute_name, req.cd_type}); + attrs.append(pbvh::GenericRequest(req.attribute_name)); } /* UV maps are not in attribute requests. */ @@ -223,7 +223,7 @@ Vector sculpt_batches_per_material_get(const Object *ob, int layer_i = CustomData_get_layer_index_n(&mesh.corner_data, CD_PROP_FLOAT2, i); CustomDataLayer *layer = layer_i != -1 ? mesh.corner_data.layers + layer_i : nullptr; if (layer) { - attrs.append(pbvh::GenericRequest{layer->name, CD_PROP_FLOAT2}); + attrs.append(pbvh::GenericRequest(layer->name)); } } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index 9134eb44a21..62dc8f63994 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -371,10 +371,10 @@ gpu::VertBufPtr extract_sculpt_data_subdiv(const MeshRenderData &mr, gpu::VertBufPtr extract_orco(const MeshRenderData &mr); -gpu::VertBufPtr extract_attribute(const MeshRenderData &mr, const DRW_AttributeRequest &request); +gpu::VertBufPtr extract_attribute(const MeshRenderData &mr, StringRef name); gpu::VertBufPtr extract_attribute_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, - const DRW_AttributeRequest &request); + StringRef name); gpu::VertBufPtr extract_attr_viewer(const MeshRenderData &mr); } // namespace blender::draw diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc index 2335f1b87c6..c7b3c71f822 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc @@ -28,22 +28,23 @@ namespace blender::draw { static void init_vbo_for_attribute(const MeshRenderData &mr, gpu::VertBuf &vbo, - const DRW_AttributeRequest &request, + const StringRef name, + const eCustomDataType type, bool build_on_device, uint32_t len) { char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; - GPU_vertformat_safe_attr_name(request.attribute_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); + GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); /* Attributes use auto-name. */ SNPRINTF(attr_name, "a%s", attr_safe_name); - GPUVertFormat format = init_format_for_attribute(request.cd_type, attr_name); + GPUVertFormat format = init_format_for_attribute(type, attr_name); GPU_vertformat_deinterleave(&format); - if (mr.active_color_name && STREQ(request.attribute_name, mr.active_color_name)) { + if (mr.active_color_name && name == mr.active_color_name) { GPU_vertformat_alias_add(&format, "ac"); } - if (mr.default_color_name && STREQ(request.attribute_name, mr.default_color_name)) { + if (mr.default_color_name && name == mr.default_color_name) { GPU_vertformat_alias_add(&format, "c"); } @@ -204,103 +205,135 @@ static BMeshAttributeLookup lookup_bmesh_attribute(const BMesh &bm, const String return {}; } -static void extract_attribute_no_init(const MeshRenderData &mr, - const StringRef name, - gpu::VertBuf &vbo) +static void extract_attribute_data(const MeshRenderData &mr, + const BMeshAttributeLookup &attr, + gpu::VertBuf &vbo) { + bke::attribute_math::convert_to_static_type(attr.type, [&](auto dummy) { + using T = decltype(dummy); + if constexpr (!std::is_void_v::VBOType>) { + switch (attr.domain) { + case bke::AttrDomain::Point: + extract_data_bmesh_vert(*mr.bm, attr.offset, vbo); + break; + case bke::AttrDomain::Edge: + extract_data_bmesh_edge(*mr.bm, attr.offset, vbo); + break; + case bke::AttrDomain::Face: + extract_data_bmesh_face(*mr.bm, attr.offset, vbo); + break; + case bke::AttrDomain::Corner: + extract_data_bmesh_loop(*mr.bm, attr.offset, vbo); + break; + default: + BLI_assert_unreachable(); + } + } + }); +} + +static void extract_attribute_data(const MeshRenderData &mr, + const bke::GAttributeReader &attr, + gpu::VertBuf &vbo) +{ + bke::attribute_math::convert_to_static_type(attr.varray.type(), [&](auto dummy) { + using T = decltype(dummy); + if constexpr (!std::is_void_v::VBOType>) { + switch (attr.domain) { + case bke::AttrDomain::Point: + extract_data_mesh_mapped_corner(GVArraySpan(*attr).typed(), mr.corner_verts, vbo); + break; + case bke::AttrDomain::Edge: + extract_data_mesh_mapped_corner(GVArraySpan(*attr).typed(), mr.corner_edges, vbo); + break; + case bke::AttrDomain::Face: + extract_data_mesh_face(mr.faces, GVArraySpan(*attr).typed(), vbo); + break; + case bke::AttrDomain::Corner: + vertbuf_data_extract_direct(GVArraySpan(*attr).typed(), vbo); + break; + default: + BLI_assert_unreachable(); + } + } + }); +} + +gpu::VertBufPtr extract_attribute(const MeshRenderData &mr, const StringRef name) +{ + gpu::VertBuf *vbo = GPU_vertbuf_calloc(); if (mr.extract_type == MeshExtractType::BMesh) { const BMeshAttributeLookup attr = lookup_bmesh_attribute(*mr.bm, name); if (!attr) { - return; + return {}; } - - bke::attribute_math::convert_to_static_type(attr.type, [&](auto dummy) { - using T = decltype(dummy); - if constexpr (!std::is_void_v::VBOType>) { - switch (attr.domain) { - case bke::AttrDomain::Point: - extract_data_bmesh_vert(*mr.bm, attr.offset, vbo); - break; - case bke::AttrDomain::Edge: - extract_data_bmesh_edge(*mr.bm, attr.offset, vbo); - break; - case bke::AttrDomain::Face: - extract_data_bmesh_face(*mr.bm, attr.offset, vbo); - break; - case bke::AttrDomain::Corner: - extract_data_bmesh_loop(*mr.bm, attr.offset, vbo); - break; - default: - BLI_assert_unreachable(); - } - } - }); + const eCustomDataType type = attr.type; + init_vbo_for_attribute(mr, *vbo, name, type, false, uint32_t(mr.corners_num)); + extract_attribute_data(mr, attr, *vbo); } else { const bke::AttributeAccessor attributes = mr.mesh->attributes(); const bke::GAttributeReader attr = attributes.lookup(name); if (!attr) { - return; + return {}; } - - bke::attribute_math::convert_to_static_type(attr.varray.type(), [&](auto dummy) { - using T = decltype(dummy); - if constexpr (!std::is_void_v::VBOType>) { - switch (attr.domain) { - case bke::AttrDomain::Point: - extract_data_mesh_mapped_corner(GVArraySpan(*attr).typed(), mr.corner_verts, vbo); - break; - case bke::AttrDomain::Edge: - extract_data_mesh_mapped_corner(GVArraySpan(*attr).typed(), mr.corner_edges, vbo); - break; - case bke::AttrDomain::Face: - extract_data_mesh_face(mr.faces, GVArraySpan(*attr).typed(), vbo); - break; - case bke::AttrDomain::Corner: - vertbuf_data_extract_direct(GVArraySpan(*attr).typed(), vbo); - break; - default: - BLI_assert_unreachable(); - } - } - }); + const eCustomDataType type = bke::cpp_type_to_custom_data_type(attr.varray.type()); + init_vbo_for_attribute(mr, *vbo, name, type, false, uint32_t(mr.corners_num)); + extract_attribute_data(mr, attr, *vbo); } + return gpu::VertBufPtr(vbo); } -gpu::VertBufPtr extract_attribute(const MeshRenderData &mr, const DRW_AttributeRequest &request) +static gpu::VertBufPtr init_coarse_data(const eCustomDataType type, const int coarse_corners_num) { gpu::VertBuf *vbo = GPU_vertbuf_calloc(); - init_vbo_for_attribute(mr, *vbo, request, false, uint32_t(mr.corners_num)); - extract_attribute_no_init(mr, request.attribute_name, *vbo); + GPUVertFormat coarse_format = draw::init_format_for_attribute(type, "data"); + GPU_vertbuf_init_with_format_ex(*vbo, coarse_format, GPU_USAGE_STATIC); + GPU_vertbuf_data_alloc(*vbo, uint32_t(coarse_corners_num)); return gpu::VertBufPtr(vbo); } gpu::VertBufPtr extract_attribute_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, - const DRW_AttributeRequest &request) + const StringRef name) { const Mesh *coarse_mesh = subdiv_cache.mesh; /* Prepare VBO for coarse data. The compute shader only expects floats. */ - gpu::VertBuf *src_data = GPU_vertbuf_calloc(); - GPUVertFormat coarse_format = draw::init_format_for_attribute(request.cd_type, "data"); - GPU_vertbuf_init_with_format_ex(*src_data, coarse_format, GPU_USAGE_STATIC); - GPU_vertbuf_data_alloc(*src_data, uint32_t(coarse_mesh->corners_num)); - - extract_attribute_no_init(mr, request.attribute_name, *src_data); + gpu::VertBufPtr coarse_vbo; + eCustomDataType type; + if (mr.extract_type == MeshExtractType::BMesh) { + const BMeshAttributeLookup attr = lookup_bmesh_attribute(*mr.bm, name); + if (!attr) { + return {}; + } + type = attr.type; + coarse_vbo = init_coarse_data(type, coarse_mesh->corners_num); + extract_attribute_data(mr, attr, *coarse_vbo); + } + else { + const bke::AttributeAccessor attributes = mr.mesh->attributes(); + const bke::GAttributeReader attr = attributes.lookup(name); + if (!attr) { + return {}; + } + type = bke::cpp_type_to_custom_data_type(attr.varray.type()); + coarse_vbo = init_coarse_data(type, coarse_mesh->corners_num); + extract_attribute_data(mr, attr, *coarse_vbo); + } gpu::VertBuf *vbo = GPU_vertbuf_calloc(); - init_vbo_for_attribute(mr, *vbo, request, true, subdiv_cache.num_subdiv_loops); + init_vbo_for_attribute(mr, *vbo, name, type, true, subdiv_cache.num_subdiv_loops); /* Ensure data is uploaded properly. */ - GPU_vertbuf_tag_dirty(src_data); - bke::attribute_math::convert_to_static_type(request.cd_type, [&](auto dummy) { + GPU_vertbuf_tag_dirty(coarse_vbo.get()); + bke::attribute_math::convert_to_static_type(type, [&](auto dummy) { using T = decltype(dummy); using Converter = AttributeConverter; if constexpr (!std::is_void_v) { draw_subdiv_interp_custom_data(subdiv_cache, - *src_data, + *coarse_vbo, *vbo, Converter::gpu_component_type, Converter::gpu_component_len, @@ -308,7 +341,6 @@ gpu::VertBufPtr extract_attribute_subdiv(const MeshRenderData &mr, } }); - GPU_vertbuf_discard(src_data); return gpu::VertBufPtr(vbo); }