Refactor: Remove data type from draw attribute request struct
Similar to 93be6baa9c.
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
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<bke::AttributeMetaData> 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<bke::AttributeMetaData> 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<bke::AttributeMetaData> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ template<> struct DefaultHash<draw::pbvh::AttributeRequest> {
|
||||
return get_default_hash(*request_type);
|
||||
}
|
||||
const GenericRequest &attr = std::get<GenericRequest>(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<GenericRequest>(&data_request)) {
|
||||
if (request->name == attribute_name) {
|
||||
if (*request == attribute_name) {
|
||||
data.tag_dirty(node_mask);
|
||||
}
|
||||
}
|
||||
@@ -1717,7 +1717,7 @@ Span<gpu::VertBufPtr> DrawCacheImpl::ensure_attribute_data(const Object &object,
|
||||
}
|
||||
else {
|
||||
update_generic_attribute_mesh(
|
||||
object, orig_mesh_data, mask, std::get<GenericRequest>(attr).name, vbos);
|
||||
object, orig_mesh_data, mask, std::get<GenericRequest>(attr), vbos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1768,7 +1768,7 @@ Span<gpu::VertBufPtr> DrawCacheImpl::ensure_attribute_data(const Object &object,
|
||||
}
|
||||
else {
|
||||
update_generic_attribute_bmesh(
|
||||
object, orig_mesh_data, mask, std::get<GenericRequest>(attr).name, vbos);
|
||||
object, orig_mesh_data, mask, std::get<GenericRequest>(attr), vbos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -177,11 +177,11 @@ Vector<SculptBatch> 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<SculptBatch> 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<SculptBatch> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<typename AttributeConverter<T>::VBOType>) {
|
||||
switch (attr.domain) {
|
||||
case bke::AttrDomain::Point:
|
||||
extract_data_bmesh_vert<T>(*mr.bm, attr.offset, vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Edge:
|
||||
extract_data_bmesh_edge<T>(*mr.bm, attr.offset, vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Face:
|
||||
extract_data_bmesh_face<T>(*mr.bm, attr.offset, vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Corner:
|
||||
extract_data_bmesh_loop<T>(*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<typename AttributeConverter<T>::VBOType>) {
|
||||
switch (attr.domain) {
|
||||
case bke::AttrDomain::Point:
|
||||
extract_data_mesh_mapped_corner(GVArraySpan(*attr).typed<T>(), mr.corner_verts, vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Edge:
|
||||
extract_data_mesh_mapped_corner(GVArraySpan(*attr).typed<T>(), mr.corner_edges, vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Face:
|
||||
extract_data_mesh_face(mr.faces, GVArraySpan(*attr).typed<T>(), vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Corner:
|
||||
vertbuf_data_extract_direct(GVArraySpan(*attr).typed<T>(), 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<typename AttributeConverter<T>::VBOType>) {
|
||||
switch (attr.domain) {
|
||||
case bke::AttrDomain::Point:
|
||||
extract_data_bmesh_vert<T>(*mr.bm, attr.offset, vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Edge:
|
||||
extract_data_bmesh_edge<T>(*mr.bm, attr.offset, vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Face:
|
||||
extract_data_bmesh_face<T>(*mr.bm, attr.offset, vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Corner:
|
||||
extract_data_bmesh_loop<T>(*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<typename AttributeConverter<T>::VBOType>) {
|
||||
switch (attr.domain) {
|
||||
case bke::AttrDomain::Point:
|
||||
extract_data_mesh_mapped_corner(GVArraySpan(*attr).typed<T>(), mr.corner_verts, vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Edge:
|
||||
extract_data_mesh_mapped_corner(GVArraySpan(*attr).typed<T>(), mr.corner_edges, vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Face:
|
||||
extract_data_mesh_face(mr.faces, GVArraySpan(*attr).typed<T>(), vbo);
|
||||
break;
|
||||
case bke::AttrDomain::Corner:
|
||||
vertbuf_data_extract_direct(GVArraySpan(*attr).typed<T>(), 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<T>;
|
||||
if constexpr (!std::is_void_v<typename Converter::VBOType>) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user