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); }