From 760cf70d63a345d8241ba4e41311b0324d9d4def Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 15 May 2025 20:43:31 +0200 Subject: [PATCH] Draw: Use VectorSet for generic attribute requests Replace `DRW_Attributes` with a VectorSet of std::string. The max number of attributes is still the same. The inline buffer size is 4, and std::string's inline buffer is smaller than the previous char array size of 64, but it seems reasonable to save those optimizations for shorter attribute names and fewer attributes. In return we significantly decrease the size of the batch caches, simplify the code, and remove the attribute name length limit. I observed roughly an 8% increase in the 30k cube objects file, a change from 12 to 13 FPS. I'm guessing this is mostly because `VectorSet` is smaller than `DRW_Attributes`. Pull Request: https://projects.blender.org/blender/blender/pulls/138946 --- source/blender/draw/intern/draw_attributes.cc | 62 +++++-------------- source/blender/draw/intern/draw_attributes.hh | 26 ++++---- .../blender/draw/intern/draw_cache_extract.hh | 6 +- .../draw/intern/draw_cache_extract_mesh.cc | 8 +-- .../draw/intern/draw_cache_impl_curves.cc | 19 +++--- .../draw/intern/draw_cache_impl_mesh.cc | 22 +++---- .../draw/intern/draw_cache_impl_pointcloud.cc | 23 ++++--- .../draw/intern/draw_context_private.hh | 4 +- source/blender/draw/intern/draw_curves.cc | 26 ++++---- .../draw/intern/draw_curves_private.hh | 7 ++- source/blender/draw/intern/draw_sculpt.cc | 7 +-- 11 files changed, 83 insertions(+), 127 deletions(-) diff --git a/source/blender/draw/intern/draw_attributes.cc b/source/blender/draw/intern/draw_attributes.cc index bcc5b6460d6..8e2c96f9a0c 100644 --- a/source/blender/draw/intern/draw_attributes.cc +++ b/source/blender/draw/intern/draw_attributes.cc @@ -2,62 +2,34 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "BLI_string.h" - #include "BKE_customdata.hh" +#include "GPU_shader.hh" + #include "draw_attributes.hh" namespace blender::draw { -/* Return true if the given DRW_AttributeRequest is already in the requests. */ -static bool drw_attributes_has_request(const DRW_Attributes *requests, - const DRW_AttributeRequest &req) -{ - 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)) { - return true; - } - } - return false; -} - -static void drw_attributes_merge_requests(const DRW_Attributes *src_requests, - DRW_Attributes *dst_requests) -{ - for (int i = 0; i < src_requests->num_requests; i++) { - if (dst_requests->num_requests == GPU_MAX_ATTR) { - return; - } - - if (drw_attributes_has_request(dst_requests, src_requests->requests[i])) { - continue; - } - - dst_requests->requests[dst_requests->num_requests] = src_requests->requests[i]; - dst_requests->num_requests += 1; - } -} - -void drw_attributes_clear(DRW_Attributes *attributes) +void drw_attributes_clear(VectorSet *attributes) { *attributes = {}; } -void drw_attributes_merge(DRW_Attributes *dst, const DRW_Attributes *src, Mutex &render_mutex) +void drw_attributes_merge(VectorSet *dst, + const VectorSet *src, + Mutex &render_mutex) { - if (src->num_requests == 0) { + if (src->is_empty()) { return; } std::lock_guard lock{render_mutex}; - drw_attributes_merge_requests(src, dst); + dst->add_multiple(src->as_span()); } -bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b) +bool drw_attributes_overlap(const VectorSet *a, const VectorSet *b) { - for (int i = 0; i < b->num_requests; i++) { - if (!drw_attributes_has_request(a, b->requests[i])) { + for (const std::string &req : b->as_span()) { + if (!a->contains(req)) { return false; } } @@ -65,20 +37,16 @@ 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) +void drw_attributes_add_request(VectorSet *attrs, const StringRef name) { - DRW_AttributeRequest req{}; - STRNCPY(req.attribute_name, name); - if (attrs->num_requests >= GPU_MAX_ATTR || drw_attributes_has_request(attrs, req)) { + if (attrs->size() >= GPU_MAX_ATTR) { return; } - - attrs->requests[attrs->num_requests] = req; - attrs->num_requests += 1; + attrs->add_as(name); } bool drw_custom_data_match_attribute(const CustomData &custom_data, - const char *name, + const StringRef name, int *r_layer_index, eCustomDataType *r_type) { diff --git a/source/blender/draw/intern/draw_attributes.hh b/source/blender/draw/intern/draw_attributes.hh index 09caf3b8834..d7c2344e6cc 100644 --- a/source/blender/draw/intern/draw_attributes.hh +++ b/source/blender/draw/intern/draw_attributes.hh @@ -10,12 +10,15 @@ #pragma once +#include + #include "DNA_customdata_types.h" #include "BLI_mutex.hh" +#include "BLI_string_ref.hh" #include "BLI_sys_types.h" -#include "GPU_shader.hh" +#include "BLI_vector_set.hh" namespace blender::bke { enum class AttrDomain : int8_t; @@ -23,15 +26,6 @@ enum class AttrDomain : int8_t; namespace blender::draw { -struct DRW_AttributeRequest { - char attribute_name[64]; -}; - -struct DRW_Attributes { - DRW_AttributeRequest requests[GPU_MAX_ATTR]; - int num_requests; -}; - struct DRW_MeshCDMask { uint32_t uv : 8; uint32_t tan : 8; @@ -49,17 +43,19 @@ struct DRW_MeshCDMask { * See `mesh_cd_layers_type_*` functions. */ static_assert(sizeof(DRW_MeshCDMask) <= sizeof(uint32_t), "DRW_MeshCDMask exceeds 32 bits"); -void drw_attributes_clear(DRW_Attributes *attributes); +void drw_attributes_clear(VectorSet *attributes); -void drw_attributes_merge(DRW_Attributes *dst, const DRW_Attributes *src, Mutex &render_mutex); +void drw_attributes_merge(VectorSet *dst, + const VectorSet *src, + Mutex &render_mutex); /* Return true if all requests in b are in a. */ -bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b); +bool drw_attributes_overlap(const VectorSet *a, const VectorSet *b); -void drw_attributes_add_request(DRW_Attributes *attrs, const char *name); +void drw_attributes_add_request(VectorSet *attrs, StringRef name); bool drw_custom_data_match_attribute(const CustomData &custom_data, - const char *name, + StringRef name, int *r_layer_index, eCustomDataType *r_type); diff --git a/source/blender/draw/intern/draw_cache_extract.hh b/source/blender/draw/intern/draw_cache_extract.hh index 33593414b86..92e38ced585 100644 --- a/source/blender/draw/intern/draw_cache_extract.hh +++ b/source/blender/draw/intern/draw_cache_extract.hh @@ -295,20 +295,20 @@ struct MeshBatchCache { DRW_MeshCDMask cd_used, cd_needed, cd_used_over_time; - DRW_Attributes attr_used, attr_needed, attr_used_over_time; + VectorSet attr_used, attr_needed, attr_used_over_time; int lastmatch; /* Valid only if edge_detection is up to date. */ bool is_manifold; + bool no_loose_wire; + /* Total areas for drawing UV Stretching. Contains the summed area in mesh * space (`tot_area`) and the summed area in uv space (`tot_uvarea`). * * Only valid after `DRW_mesh_batch_cache_create_requested` has been called. */ float tot_area, tot_uv_area; - - bool no_loose_wire; }; #define MBC_EDITUV \ diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc index d3a09d5fea0..8bdeb4fa06b 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc @@ -266,8 +266,7 @@ 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].attribute_name); + created_vbos[i] = extract_attribute(mr, cache.attr_used[attr_index]); break; } case VBOType::AttrViewer: @@ -451,9 +450,8 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache, for (const int8_t i : IndexRange(GPU_MAX_ATTR)) { 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].attribute_name)); + buffers.vbos.add_new(request, + extract_attribute_subdiv(mr, subdiv_cache, cache.attr_used[i])); } } } diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index b1331361e9d..aacb4004844 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -741,11 +741,10 @@ static bool ensure_attributes(const Curves &curves, if (gpu_material) { /* The following code should be kept in sync with `mesh_cd_calc_used_gpu_layers`. */ - DRW_Attributes attrs_needed; - drw_attributes_clear(&attrs_needed); + VectorSet attrs_needed; ListBase gpu_attrs = GPU_material_attributes(gpu_material); LISTBASE_FOREACH (const GPUMaterialAttribute *, gpu_attr, &gpu_attrs) { - const char *name = gpu_attr->name; + StringRef name = gpu_attr->name; eCustomDataType type = static_cast(gpu_attr->type); int layer = -1; std::optional domain; @@ -755,7 +754,7 @@ static bool ensure_attributes(const Curves &curves, * * We do it based on the specified name. */ - if (name[0] != '\0') { + if (!name.is_empty()) { layer = CustomData_get_named_layer(&cd_curve, CD_PROP_FLOAT2, name); type = CD_MTFACE; domain = bke::AttrDomain::Curve; @@ -861,14 +860,12 @@ static bool ensure_attributes(const Curves &curves, bool need_tf_update = false; - for (const int i : IndexRange(final_cache.attr_used.num_requests)) { - const DRW_AttributeRequest &request = final_cache.attr_used.requests[i]; - + for (const int i : final_cache.attr_used.index_range()) { if (cache.eval_cache.final.attributes_buf[i] != nullptr) { continue; } - ensure_final_attribute(curves, request.attribute_name, i, cache.eval_cache); + ensure_final_attribute(curves, final_cache.attr_used[i], i, cache.eval_cache); if (cache.eval_cache.proc_attributes_point_domain[i]) { need_tf_update = true; } @@ -882,7 +879,7 @@ static void request_attribute(Curves &curves, const char *name) CurvesBatchCache &cache = get_batch_cache(curves); CurvesEvalFinalCache &final_cache = cache.eval_cache.final; - DRW_Attributes attributes{}; + VectorSet attributes{}; bke::CurvesGeometry &curves_geometry = curves.geometry.wrap(); if (!curves_geometry.attributes().contains(name)) { @@ -1045,8 +1042,8 @@ gpu::VertBuf **DRW_curves_texture_for_evaluated_attribute(Curves *curves, request_attribute(*curves, name); int request_i = -1; - for (const int i : IndexRange(final_cache.attr_used.num_requests)) { - if (STREQ(final_cache.attr_used.requests[i].attribute_name, name)) { + for (const int i : final_cache.attr_used.index_range()) { + if (final_cache.attr_used[i] == name) { request_i = i; break; } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index 9288da007f5..50846f3144c 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -179,7 +179,7 @@ static void mesh_cd_calc_active_mask_uv_layer(const Object &object, static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object &object, const Mesh &mesh, const Span materials, - DRW_Attributes *attributes) + VectorSet *attributes) { const Mesh &me_final = editmesh_final_or_this(object, mesh); const CustomData &cd_ldata = mesh_cd_ldata_get_from_mesh(me_final); @@ -683,7 +683,7 @@ static void texpaint_request_active_uv(MeshBatchCache &cache, Object &object, Me static void request_active_and_default_color_attributes(const Object &object, const Mesh &mesh, - DRW_Attributes &attributes) + VectorSet &attributes) { const Mesh &me_final = editmesh_final_or_this(object, mesh); const CustomData &cd_vdata = mesh_cd_vdata_get_from_mesh(me_final); @@ -774,11 +774,10 @@ gpu::Batch *DRW_mesh_batch_cache_get_edit_mesh_analysis(Mesh &mesh) void DRW_mesh_get_attributes(const Object &object, const Mesh &mesh, const Span materials, - DRW_Attributes *r_attrs, + VectorSet *r_attrs, DRW_MeshCDMask *r_cd_needed) { - DRW_Attributes attrs_needed; - drw_attributes_clear(&attrs_needed); + VectorSet attrs_needed; DRW_MeshCDMask cd_needed = mesh_cd_calc_used_gpu_layers(object, mesh, materials, &attrs_needed); if (r_attrs) { @@ -794,8 +793,7 @@ Span DRW_mesh_batch_cache_get_surface_shaded( Object &object, Mesh &mesh, const Span materials) { MeshBatchCache &cache = *mesh_batch_cache_get(mesh); - DRW_Attributes attrs_needed; - drw_attributes_clear(&attrs_needed); + VectorSet attrs_needed; DRW_MeshCDMask cd_needed = mesh_cd_calc_used_gpu_layers(object, mesh, materials, &attrs_needed); BLI_assert(materials.size() == cache.mat_len); @@ -826,7 +824,7 @@ gpu::Batch *DRW_mesh_batch_cache_get_surface_vertpaint(Object &object, Mesh &mes { MeshBatchCache &cache = *mesh_batch_cache_get(mesh); - DRW_Attributes attrs_needed{}; + VectorSet attrs_needed{}; request_active_and_default_color_attributes(object, mesh, attrs_needed); drw_attributes_merge(&cache.attr_needed, &attrs_needed, mesh.runtime->render_mutex); @@ -839,7 +837,7 @@ gpu::Batch *DRW_mesh_batch_cache_get_surface_sculpt(Object &object, Mesh &mesh) { MeshBatchCache &cache = *mesh_batch_cache_get(mesh); - DRW_Attributes attrs_needed{}; + VectorSet attrs_needed{}; request_active_and_default_color_attributes(object, mesh, attrs_needed); drw_attributes_merge(&cache.attr_needed, &attrs_needed, mesh.runtime->render_mutex); @@ -1311,7 +1309,7 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, if (cache.cd_used.uv != 0) { batch.vbos.append(VBOType::UVs); } - for (const int i : IndexRange(cache.attr_used.num_requests)) { + for (const int i : cache.attr_used.index_range()) { batch.vbos.append(VBOType(int8_t(VBOType::Attr0) + i)); } batch_info.append(std::move(batch)); @@ -1654,7 +1652,7 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, ibo_requests[int(BufferList::Final)].add(IBOType::Tris); vbo_requests[int(BufferList::Final)].add(VBOType::CornerNormal); vbo_requests[int(BufferList::Final)].add(VBOType::Position); - for (const int i : IndexRange(cache.attr_used.num_requests)) { + for (const int i : cache.attr_used.index_range()) { vbo_requests[int(BufferList::Final)].add(VBOType(int8_t(VBOType::Attr0) + i)); } if (cache.cd_used.uv != 0) { @@ -1765,7 +1763,7 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, if (cache.cd_used.orco != 0) { GPU_batch_vertbuf_add(batch, buffers.vbos.lookup(VBOType::Orco).get(), false); } - for (const int i : IndexRange(cache.attr_used.num_requests)) { + for (const int i : cache.attr_used.index_range()) { GPU_batch_vertbuf_add( batch, buffers.vbos.lookup(VBOType(int8_t(VBOType::Attr0) + i)).get(), false); } diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc index f55ca2fbd1c..b5cb525ab8e 100644 --- a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc +++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc @@ -59,12 +59,12 @@ struct PointCloudEvalCache { gpu::VertBuf *attributes_buf[GPU_MAX_ATTR]; /** Attributes currently being drawn or about to be drawn. */ - DRW_Attributes attr_used; + VectorSet attr_used; /** * Attributes that were used at some point. This is used for garbage collection, to remove * attributes that are not used in shaders anymore due to user edits. */ - DRW_Attributes attr_used_over_time; + VectorSet attr_used_over_time; /** * The last time in seconds that the `attr_used` and `attr_used_over_time` were exactly the same. @@ -303,7 +303,7 @@ static void pointcloud_extract_position_and_radius(const PointCloud &pointcloud, static void pointcloud_extract_attribute(const PointCloud &pointcloud, PointCloudBatchCache &cache, - const DRW_AttributeRequest &request, + const StringRef name, int index) { gpu::VertBuf &attr_buf = *cache.eval_cache.attributes_buf[index]; @@ -316,7 +316,7 @@ static void pointcloud_extract_attribute(const PointCloud &pointcloud, * similar texture state swizzle to map the attribute correctly as for volume attributes, so we * can control the conversion ourselves. */ bke::AttributeReader attribute = attributes.lookup_or_default( - request.attribute_name, bke::AttrDomain::Point, {0.0f, 0.0f, 0.0f, 1.0f}); + name, bke::AttrDomain::Point, {0.0f, 0.0f, 0.0f, 1.0f}); static const GPUVertFormat format = [&]() { GPUVertFormat format{}; @@ -349,13 +349,12 @@ gpu::Batch **pointcloud_surface_shaded_get(PointCloud *pointcloud, { const bke::AttributeAccessor attributes = pointcloud->attributes(); PointCloudBatchCache *cache = pointcloud_batch_cache_get(*pointcloud); - DRW_Attributes attrs_needed; - drw_attributes_clear(&attrs_needed); + VectorSet attrs_needed; for (GPUMaterial *gpu_material : Span(gpu_materials, mat_len)) { ListBase gpu_attrs = GPU_material_attributes(gpu_material); LISTBASE_FOREACH (GPUMaterialAttribute *, gpu_attr, &gpu_attrs) { - const char *name = gpu_attr->name; + const StringRef name = gpu_attr->name; if (!attributes.contains(name)) { continue; } @@ -410,14 +409,14 @@ gpu::VertBuf **DRW_pointcloud_evaluated_attribute(PointCloud *pointcloud, const return nullptr; } { - DRW_Attributes requests{}; + VectorSet requests{}; drw_attributes_add_request(&requests, name); drw_attributes_merge(&cache.eval_cache.attr_used, &requests, cache.render_mutex); } int request_i = -1; - for (const int i : IndexRange(cache.eval_cache.attr_used.num_requests)) { - if (STREQ(cache.eval_cache.attr_used.requests[i].attribute_name, name)) { + for (const int i : IndexRange(cache.eval_cache.attr_used.index_range())) { + if (cache.eval_cache.attr_used[i] == name) { request_i = i; break; } @@ -474,11 +473,11 @@ void DRW_pointcloud_batch_cache_create_requested(Object *ob) DRW_ibo_request(cache.eval_cache.surface_per_mat[i], &cache.eval_cache.geom_indices); } } - for (int j = 0; j < cache.eval_cache.attr_used.num_requests; j++) { + for (const int j : cache.eval_cache.attr_used.index_range()) { DRW_vbo_request(nullptr, &cache.eval_cache.attributes_buf[j]); if (DRW_vbo_requested(cache.eval_cache.attributes_buf[j])) { - pointcloud_extract_attribute(pointcloud, cache, cache.eval_cache.attr_used.requests[j], j); + pointcloud_extract_attribute(pointcloud, cache, cache.eval_cache.attr_used[j], j); } } diff --git a/source/blender/draw/intern/draw_context_private.hh b/source/blender/draw/intern/draw_context_private.hh index ef6b7ff0e5b..c88b6f07c8c 100644 --- a/source/blender/draw/intern/draw_context_private.hh +++ b/source/blender/draw/intern/draw_context_private.hh @@ -15,6 +15,7 @@ #include "BLI_task.h" #include "BLI_threads.h" +#include "BLI_vector_set.hh" #include "GPU_batch.hh" #include "GPU_context.hh" @@ -32,7 +33,6 @@ namespace blender::draw { struct CurvesModule; struct VolumeModule; struct PointCloudModule; -struct DRW_Attributes; struct DRW_MeshCDMask; class CurveRefinePass; class View; @@ -88,7 +88,7 @@ namespace blender::draw { void DRW_mesh_get_attributes(const Object &object, const Mesh &mesh, Span materials, - DRW_Attributes *r_attrs, + VectorSet *r_attrs, DRW_MeshCDMask *r_cd_needed); } // namespace blender::draw diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index ea34cbe7cbe..cc6392c6411 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -122,8 +122,8 @@ static void drw_curves_cache_update_compute(CurvesEvalCache *cache) drw_curves_cache_update_compute(cache, curves_num, cache->final.proc_buf, cache->proc_point_buf); - const DRW_Attributes &attrs = cache->final.attr_used; - for (int i = 0; i < attrs.num_requests; i++) { + const VectorSet &attrs = cache->final.attr_used; + for (const int i : attrs.index_range()) { if (!cache->proc_attributes_point_domain[i]) { continue; } @@ -161,7 +161,7 @@ gpu::VertBuf *DRW_curves_pos_buffer_get(Object *object) return cache->final.proc_buf; } -static int attribute_index_in_material(GPUMaterial *gpu_material, const char *name) +static int attribute_index_in_material(GPUMaterial *gpu_material, const StringRef name) { if (!gpu_material) { return -1; @@ -171,7 +171,7 @@ static int attribute_index_in_material(GPUMaterial *gpu_material, const char *na ListBase gpu_attrs = GPU_material_attributes(gpu_material); LISTBASE_FOREACH (GPUMaterialAttribute *, gpu_attr, &gpu_attrs) { - if (STREQ(gpu_attr->name, name)) { + if (gpu_attr->name == name) { return index; } @@ -243,8 +243,8 @@ static CurvesEvalCache *curves_cache_get(Curves &curves, if (final_points_len > 0) { cache_update(cache->final.proc_buf, cache->proc_point_buf); - const DRW_Attributes &attrs = cache->final.attr_used; - for (int i : IndexRange(attrs.num_requests)) { + const VectorSet &attrs = cache->final.attr_used; + for (const int i : attrs.index_range()) { /* Only refine point attributes. */ if (cache->proc_attributes_point_domain[i]) { cache_update(cache->final.attributes_buf[i], cache->proc_attributes_buf[i]); @@ -333,18 +333,18 @@ gpu::Batch *curves_sub_pass_setup_implementation(PassT &sub_ps, CD_PROP_FLOAT2); } - const DRW_Attributes &attrs = curves_cache->final.attr_used; - for (int i = 0; i < attrs.num_requests; i++) { - const DRW_AttributeRequest &request = attrs.requests[i]; + const VectorSet &attrs = curves_cache->final.attr_used; + for (const int i : attrs.index_range()) { + const StringRef name = attrs[i]; char sampler_name[32]; - drw_curves_get_attribute_sampler_name(request.attribute_name, sampler_name); + drw_curves_get_attribute_sampler_name(name, sampler_name); if (!curves_cache->proc_attributes_point_domain[i]) { if (!curves_cache->proc_attributes_buf[i]) { continue; } sub_ps.bind_texture(sampler_name, curves_cache->proc_attributes_buf[i]); - if (request.attribute_name == curve_data_render_uv) { + if (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.attribute_name == point_data_render_uv) { + if (name == point_data_render_uv) { sub_ps.bind_texture("a", curves_cache->final.attributes_buf[i]); } } @@ -362,7 +362,7 @@ gpu::Batch *curves_sub_pass_setup_implementation(PassT &sub_ps, * we need to find the right index for this attribute as uniforms defining the scope of the * attributes are based on attribute loading order, which is itself based on the material's * attributes. */ - const int index = attribute_index_in_material(gpu_material, request.attribute_name); + const int index = attribute_index_in_material(gpu_material, name); if (index != -1) { curves_infos.is_point_attribute[index][0] = curves_cache->proc_attributes_point_domain[i]; } diff --git a/source/blender/draw/intern/draw_curves_private.hh b/source/blender/draw/intern/draw_curves_private.hh index 4b8c9b483ac..558b23e0af5 100644 --- a/source/blender/draw/intern/draw_curves_private.hh +++ b/source/blender/draw/intern/draw_curves_private.hh @@ -9,10 +9,11 @@ #pragma once #include +#include #include "GPU_shader.hh" -#include "draw_attributes.hh" +#include "BLI_vector_set.hh" struct Curves; namespace blender::gpu { @@ -48,13 +49,13 @@ struct CurvesEvalFinalCache { int resolution; /** Attributes currently being drawn or about to be drawn. */ - DRW_Attributes attr_used; + VectorSet attr_used; /** * Attributes that were used at some point. This is used for garbage collection, to remove * attributes that are not used in shaders anymore due to user edits. */ - DRW_Attributes attr_used_over_time; + VectorSet attr_used_over_time; /** * The last time in seconds that the `attr_used` and `attr_used_over_time` were exactly the same. diff --git a/source/blender/draw/intern/draw_sculpt.cc b/source/blender/draw/intern/draw_sculpt.cc index 6bc8f73f5bf..fc08ed7df48 100644 --- a/source/blender/draw/intern/draw_sculpt.cc +++ b/source/blender/draw/intern/draw_sculpt.cc @@ -203,7 +203,7 @@ Vector sculpt_batches_per_material_get(const Object *ob, BLI_assert(ob->type == OB_MESH); const Mesh &mesh = DRW_object_get_data_for_drawing(*ob); - DRW_Attributes draw_attrs; + VectorSet draw_attrs; DRW_MeshCDMask cd_needed; DRW_mesh_get_attributes(*ob, mesh, materials, &draw_attrs, &cd_needed); @@ -212,9 +212,8 @@ Vector sculpt_batches_per_material_get(const Object *ob, attrs.append(pbvh::CustomRequest::Position); attrs.append(pbvh::CustomRequest::Normal); - 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)); + for (const StringRef name : draw_attrs) { + attrs.append(pbvh::GenericRequest(name)); } /* UV maps are not in attribute requests. */