Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/CMakeLists.txt1
-rw-r--r--source/blender/draw/intern/draw_attributes.cc3
-rw-r--r--source/blender/draw/intern/draw_cache_extract.hh2
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.cc2
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc26
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.cc325
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh.hh79
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc38
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc387
-rw-r--r--source/blender/gpu/GPU_material.h11
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c35
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vertex_color.cc7
12 files changed, 252 insertions, 664 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index d20745f28c0..9744f2e3cee 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -67,7 +67,6 @@ set(SRC
intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc
intern/mesh_extractors/extract_mesh_vbo_tan.cc
intern/mesh_extractors/extract_mesh_vbo_uv.cc
- intern/mesh_extractors/extract_mesh_vbo_vcol.cc
intern/mesh_extractors/extract_mesh_vbo_weights.cc
intern/draw_attributes.cc
intern/draw_cache_impl_curve.cc
diff --git a/source/blender/draw/intern/draw_attributes.cc b/source/blender/draw/intern/draw_attributes.cc
index 3f187aef8e6..011d72e9e8f 100644
--- a/source/blender/draw/intern/draw_attributes.cc
+++ b/source/blender/draw/intern/draw_attributes.cc
@@ -88,7 +88,7 @@ bool drw_custom_data_match_attribute(const CustomData *custom_data,
int *r_layer_index,
eCustomDataType *r_type)
{
- const eCustomDataType possible_attribute_types[7] = {
+ const eCustomDataType possible_attribute_types[8] = {
CD_PROP_BOOL,
CD_PROP_INT8,
CD_PROP_INT32,
@@ -96,6 +96,7 @@ bool drw_custom_data_match_attribute(const CustomData *custom_data,
CD_PROP_FLOAT2,
CD_PROP_FLOAT3,
CD_PROP_COLOR,
+ CD_PROP_BYTE_COLOR,
};
for (int i = 0; i < ARRAY_SIZE(possible_attribute_types); i++) {
diff --git a/source/blender/draw/intern/draw_cache_extract.hh b/source/blender/draw/intern/draw_cache_extract.hh
index c7127d169e1..203da22406c 100644
--- a/source/blender/draw/intern/draw_cache_extract.hh
+++ b/source/blender/draw/intern/draw_cache_extract.hh
@@ -55,7 +55,6 @@ enum {
struct DRW_MeshCDMask {
uint32_t uv : 8;
uint32_t tan : 8;
- uint32_t vcol : 8;
uint32_t orco : 1;
uint32_t tan_orco : 1;
uint32_t sculpt_overlays : 1;
@@ -111,7 +110,6 @@ struct MeshBufferList {
GPUVertBuf *weights; /* extend */
GPUVertBuf *uv;
GPUVertBuf *tan;
- GPUVertBuf *vcol;
GPUVertBuf *sculpt_data;
GPUVertBuf *orco;
/* Only for edit mode. */
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc
index 380736ef656..b1d1631cb6d 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc
@@ -619,7 +619,6 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
EXTRACT_ADD_REQUESTED(vbo, lnor);
EXTRACT_ADD_REQUESTED(vbo, uv);
EXTRACT_ADD_REQUESTED(vbo, tan);
- EXTRACT_ADD_REQUESTED(vbo, vcol);
EXTRACT_ADD_REQUESTED(vbo, sculpt_data);
EXTRACT_ADD_REQUESTED(vbo, orco);
EXTRACT_ADD_REQUESTED(vbo, edge_fac);
@@ -848,7 +847,6 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache,
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_angle);
EXTRACT_ADD_REQUESTED(ibo, lines_paint_mask);
EXTRACT_ADD_REQUESTED(ibo, lines_adjacency);
- EXTRACT_ADD_REQUESTED(vbo, vcol);
EXTRACT_ADD_REQUESTED(vbo, weights);
EXTRACT_ADD_REQUESTED(vbo, sculpt_data);
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
index 77cbb5efa12..fc09606f9f3 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
@@ -431,6 +431,30 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
}
}
+static void retrieve_active_attribute_names(MeshRenderData &mr,
+ const Object &object,
+ const Mesh &mesh)
+{
+ const Mesh *mesh_final = editmesh_final_or_this(&object, &mesh);
+ const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(mesh_final);
+ const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(mesh_final);
+
+ /* Necessary because which attributes are active/default is stored in #CustomData. */
+ Mesh me_query = blender::dna::shallow_zero_initialize();
+ BKE_id_attribute_copy_domains_temp(
+ ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id);
+
+ mr.active_color_name = nullptr;
+ mr.default_color_name = nullptr;
+
+ if (const CustomDataLayer *active = BKE_id_attributes_active_color_get(&me_query.id)) {
+ mr.active_color_name = active->name;
+ }
+ if (const CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id)) {
+ mr.default_color_name = render->name;
+ }
+}
+
MeshRenderData *mesh_render_data_create(Object *object,
Mesh *me,
const bool is_editmode,
@@ -566,6 +590,8 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len);
}
+ retrieve_active_attribute_names(*mr, *object, *me);
+
return mr;
}
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc
index e93b1a66b66..d3d9db13005 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc
@@ -21,6 +21,7 @@
#include "BLI_math_vector.h"
#include "BLI_span.hh"
#include "BLI_string.h"
+#include "BLI_string_ref.hh"
#include "BLI_task.h"
#include "BLI_utildefines.h"
@@ -67,6 +68,7 @@
using blender::IndexRange;
using blender::Map;
using blender::Span;
+using blender::StringRefNull;
/* ---------------------------------------------------------------------- */
/** \name Dependencies between buffer and batch
@@ -115,8 +117,6 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
MBC_SURFACE_PER_MAT;
case BUFFER_INDEX(vbo.tan):
return MBC_SURFACE_PER_MAT;
- case BUFFER_INDEX(vbo.vcol):
- return MBC_SURFACE | MBC_SURFACE_PER_MAT;
case BUFFER_INDEX(vbo.sculpt_data):
return MBC_SCULPT_OVERLAYS;
case BUFFER_INDEX(vbo.orco):
@@ -236,87 +236,11 @@ BLI_INLINE void mesh_cd_layers_type_clear(DRW_MeshCDMask *a)
*((uint32_t *)a) = 0;
}
-BLI_INLINE const Mesh *editmesh_final_or_this(const Object *object, const Mesh *me)
-{
- if (me->edit_mesh != nullptr) {
- Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object);
- if (editmesh_eval_final != nullptr) {
- return editmesh_eval_final;
- }
- }
-
- return me;
-}
-
static void mesh_cd_calc_edit_uv_layer(const Mesh *UNUSED(me), DRW_MeshCDMask *cd_used)
{
cd_used->edit_uv = 1;
}
-BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me)
-{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
- case ME_WRAPPER_TYPE_SUBD:
- case ME_WRAPPER_TYPE_MDATA:
- return &me->ldata;
- break;
- case ME_WRAPPER_TYPE_BMESH:
- return &me->edit_mesh->bm->ldata;
- break;
- }
-
- BLI_assert(0);
- return &me->ldata;
-}
-
-BLI_INLINE const CustomData *mesh_cd_pdata_get_from_mesh(const Mesh *me)
-{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
- case ME_WRAPPER_TYPE_SUBD:
- case ME_WRAPPER_TYPE_MDATA:
- return &me->pdata;
- break;
- case ME_WRAPPER_TYPE_BMESH:
- return &me->edit_mesh->bm->pdata;
- break;
- }
-
- BLI_assert(0);
- return &me->pdata;
-}
-
-BLI_INLINE const CustomData *mesh_cd_edata_get_from_mesh(const Mesh *me)
-{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
- case ME_WRAPPER_TYPE_SUBD:
- case ME_WRAPPER_TYPE_MDATA:
- return &me->edata;
- break;
- case ME_WRAPPER_TYPE_BMESH:
- return &me->edit_mesh->bm->edata;
- break;
- }
-
- BLI_assert(0);
- return &me->edata;
-}
-
-BLI_INLINE const CustomData *mesh_cd_vdata_get_from_mesh(const Mesh *me)
-{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
- case ME_WRAPPER_TYPE_SUBD:
- case ME_WRAPPER_TYPE_MDATA:
- return &me->vdata;
- break;
- case ME_WRAPPER_TYPE_BMESH:
- return &me->edit_mesh->bm->vdata;
- break;
- }
-
- BLI_assert(0);
- return &me->vdata;
-}
-
static void mesh_cd_calc_active_uv_layer(const Object *object,
const Mesh *me,
DRW_MeshCDMask *cd_used)
@@ -341,75 +265,6 @@ static void mesh_cd_calc_active_mask_uv_layer(const Object *object,
}
}
-static void mesh_cd_calc_active_mloopcol_layer(const Object *object,
- const Mesh *me,
- DRW_MeshCDMask *cd_used)
-{
- const Mesh *me_final = editmesh_final_or_this(object, me);
- Mesh me_query = blender::dna::shallow_zero_initialize();
-
- const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final);
- const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final);
-
- BKE_id_attribute_copy_domains_temp(
- ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id);
-
- const CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me_query.id);
- int layer_i = BKE_id_attribute_to_index(
- &me_query.id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
-
- if (layer_i != -1) {
- cd_used->vcol |= (1UL << (uint)layer_i);
- }
-}
-
-static uint mesh_cd_calc_gpu_layers_vcol_used(const Mesh *me_query,
- const CustomData *cd_vdata,
- const CustomData *cd_ldata,
- const char name[])
-{
- const CustomDataLayer *layer = nullptr;
- eAttrDomain domain;
-
- if (name[0]) {
- int layer_i = 0;
-
- domain = ATTR_DOMAIN_POINT;
- layer_i = CustomData_get_named_layer_index(cd_vdata, CD_PROP_COLOR, name);
- layer_i = layer_i == -1 ?
- CustomData_get_named_layer_index(cd_vdata, CD_PROP_BYTE_COLOR, name) :
- layer_i;
-
- if (layer_i == -1) {
- domain = ATTR_DOMAIN_CORNER;
- layer_i = layer_i == -1 ? CustomData_get_named_layer_index(cd_ldata, CD_PROP_COLOR, name) :
- layer_i;
- layer_i = layer_i == -1 ?
- CustomData_get_named_layer_index(cd_ldata, CD_PROP_BYTE_COLOR, name) :
- layer_i;
- }
-
- /* NOTE: this is not the same as the layer_i below. */
- if (layer_i != -1) {
- layer = (domain == ATTR_DOMAIN_POINT ? cd_vdata : cd_ldata)->layers + layer_i;
- }
- }
- else {
- layer = BKE_id_attributes_render_color_get(&me_query->id);
- }
-
- if (!layer) {
- return -1;
- }
-
- /* NOTE: this is the logical index into the color attribute list,
- * not the customdata index. */
- int vcol_i = BKE_id_attribute_to_index(
- (ID *)me_query, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
-
- return vcol_i;
-}
-
static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
const Mesh *me,
struct GPUMaterial **gpumat_array,
@@ -433,6 +288,9 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
DRW_MeshCDMask cd_used;
mesh_cd_layers_type_clear(&cd_used);
+ const CustomDataLayer *default_color = BKE_id_attributes_render_color_get(&me_query.id);
+ const StringRefNull default_color_name = default_color ? default_color->name : "";
+
for (int i = 0; i < gpumat_array_len; i++) {
GPUMaterial *gpumat = gpumat_array[i];
if (gpumat) {
@@ -443,6 +301,10 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
int layer = -1;
std::optional<eAttrDomain> domain;
+ if (gpu_attr->is_default_color) {
+ name = default_color_name.c_str();
+ }
+
if (type == CD_AUTO_FROM_NAME) {
/* We need to deduce what exact layer is used.
*
@@ -452,38 +314,6 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name);
type = CD_MTFACE;
- if (layer == -1) {
- layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name);
- if (layer != -1) {
- type = CD_PROP_COLOR;
- domain = ATTR_DOMAIN_POINT;
- }
- }
-
- if (layer == -1) {
- layer = CustomData_get_named_layer(cd_ldata, CD_PROP_COLOR, name);
- if (layer != -1) {
- type = CD_PROP_COLOR;
- domain = ATTR_DOMAIN_CORNER;
- }
- }
-
- if (layer == -1) {
- layer = CustomData_get_named_layer(cd_vdata, CD_PROP_BYTE_COLOR, name);
- if (layer != -1) {
- type = CD_PROP_BYTE_COLOR;
- domain = ATTR_DOMAIN_POINT;
- }
- }
-
- if (layer == -1) {
- layer = CustomData_get_named_layer(cd_ldata, CD_PROP_BYTE_COLOR, name);
- if (layer != -1) {
- type = CD_PROP_BYTE_COLOR;
- domain = ATTR_DOMAIN_CORNER;
- }
- }
-
#if 0 /* Tangents are always from UV's - this will never happen. */
if (layer == -1) {
layer = CustomData_get_named_layer(cd_ldata, CD_TANGENT, name);
@@ -556,28 +386,8 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
cd_used.orco = 1;
break;
}
-
- /* NOTE: attr->type will always be CD_PROP_COLOR even for
- * CD_PROP_BYTE_COLOR layers, see node_shader_gpu_vertex_color in
- * node_shader_vertex_color.cc.
- */
- case CD_MCOL:
case CD_PROP_BYTE_COLOR:
- case CD_PROP_COLOR: {
- /* First check Color attributes, when not found check mesh attributes. Geometry nodes
- * can generate those layers. */
- int vcol_bit = mesh_cd_calc_gpu_layers_vcol_used(&me_query, cd_vdata, cd_ldata, name);
-
- if (vcol_bit != -1) {
- cd_used.vcol |= 1UL << (uint)vcol_bit;
- break;
- }
-
- if (layer != -1 && domain.has_value()) {
- drw_attributes_add_request(attributes, name, type, layer, *domain);
- }
- break;
- }
+ case CD_PROP_COLOR:
case CD_PROP_FLOAT3:
case CD_PROP_BOOL:
case CD_PROP_INT8:
@@ -863,10 +673,9 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
FOREACH_MESH_BUFFER_CACHE (cache, mbc) {
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.uv);
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.tan);
- GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.vcol);
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.orco);
}
- DRWBatchFlag batch_map = BATCH_MAP(vbo.uv, vbo.tan, vbo.vcol, vbo.orco);
+ DRWBatchFlag batch_map = BATCH_MAP(vbo.uv, vbo.tan, vbo.orco);
mesh_batch_cache_discard_batch(cache, batch_map);
mesh_cd_layers_type_clear(&cache->cd_used);
}
@@ -1070,42 +879,35 @@ static void texpaint_request_active_uv(MeshBatchCache *cache, Object *object, Me
mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
}
-static void texpaint_request_active_vcol(MeshBatchCache *cache, Object *object, Mesh *me)
-{
- DRW_MeshCDMask cd_needed;
- mesh_cd_layers_type_clear(&cd_needed);
- mesh_cd_calc_active_mloopcol_layer(object, me, &cd_needed);
-
- BLI_assert(cd_needed.vcol != 0 &&
- "No MLOOPCOL layer available in vertpaint, but batches requested anyway!");
-
- mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
-}
-
-static void sculpt_request_active_vcol(MeshBatchCache *cache, Object *object, Mesh *me)
+static void request_active_and_default_color_attributes(const Object &object,
+ const Mesh &mesh,
+ DRW_Attributes &attributes)
{
- const Mesh *me_final = editmesh_final_or_this(object, me);
+ const Mesh *me_final = editmesh_final_or_this(&object, &mesh);
const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final);
const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final);
+ /* Necessary because which attributes are active/default is stored in #CustomData. */
Mesh me_query = blender::dna::shallow_zero_initialize();
BKE_id_attribute_copy_domains_temp(
ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id);
- const CustomDataLayer *active = BKE_id_attributes_active_color_get(&me_query.id);
- const CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id);
-
- int active_i = BKE_id_attribute_to_index(
- &me_query.id, active, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
- int render_i = BKE_id_attribute_to_index(
- &me_query.id, render, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
+ auto request_color_attribute = [&](const char *name) {
+ int layer_index;
+ eCustomDataType type;
+ if (drw_custom_data_match_attribute(cd_vdata, name, &layer_index, &type)) {
+ drw_attributes_add_request(&attributes, name, type, layer_index, ATTR_DOMAIN_POINT);
+ }
+ else if (drw_custom_data_match_attribute(cd_ldata, name, &layer_index, &type)) {
+ drw_attributes_add_request(&attributes, name, type, layer_index, ATTR_DOMAIN_CORNER);
+ }
+ };
- if (active_i >= 0) {
- cache->cd_needed.vcol |= 1UL << (uint)active_i;
+ if (const CustomDataLayer *active = BKE_id_attributes_active_color_get(&me_query.id)) {
+ request_color_attribute(active->name);
}
-
- if (render_i >= 0) {
- cache->cd_needed.vcol |= 1UL << (uint)render_i;
+ if (const CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id)) {
+ request_color_attribute(render->name);
}
}
@@ -1214,7 +1016,13 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(Object *object, Mesh
GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Object *object, Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
- texpaint_request_active_vcol(cache, object, me);
+
+ DRW_Attributes attrs_needed{};
+ request_active_and_default_color_attributes(*object, *me, attrs_needed);
+
+ ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex;
+ drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex);
+
mesh_batch_cache_request_surface_batches(cache);
return cache->batch.surface;
}
@@ -1222,7 +1030,13 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Object *object, Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_surface_sculpt(Object *object, Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
- sculpt_request_active_vcol(cache, object, me);
+
+ DRW_Attributes attrs_needed{};
+ request_active_and_default_color_attributes(*object, *me, attrs_needed);
+
+ ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex;
+ drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex);
+
mesh_batch_cache_request_surface_batches(cache);
return cache->batch.surface;
}
@@ -1621,9 +1435,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
if (cache->cd_used.sculpt_overlays != cache->cd_needed.sculpt_overlays) {
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.sculpt_data);
}
- if ((cache->cd_used.vcol & cache->cd_needed.vcol) != cache->cd_needed.vcol) {
- GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.vcol);
- }
if (!drw_attributes_overlap(&cache->attr_used, &cache->attr_needed)) {
for (int i = 0; i < GPU_MAX_ATTR; i++) {
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.attr[i]);
@@ -1710,15 +1521,26 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
MeshBufferList *mbuflist = &cache->final.buff;
/* Initialize batches and request VBO's & IBO's. */
- assert_deps_valid(
- MBC_SURFACE,
- {BUFFER_INDEX(ibo.tris), BUFFER_INDEX(vbo.lnor), BUFFER_INDEX(vbo.pos_nor),
- BUFFER_INDEX(vbo.uv), BUFFER_INDEX(vbo.vcol), BUFFER_INDEX(vbo.attr[0]),
- BUFFER_INDEX(vbo.attr[1]), BUFFER_INDEX(vbo.attr[2]), BUFFER_INDEX(vbo.attr[3]),
- BUFFER_INDEX(vbo.attr[4]), BUFFER_INDEX(vbo.attr[5]), BUFFER_INDEX(vbo.attr[6]),
- BUFFER_INDEX(vbo.attr[7]), BUFFER_INDEX(vbo.attr[8]), BUFFER_INDEX(vbo.attr[9]),
- BUFFER_INDEX(vbo.attr[10]), BUFFER_INDEX(vbo.attr[11]), BUFFER_INDEX(vbo.attr[12]),
- BUFFER_INDEX(vbo.attr[13]), BUFFER_INDEX(vbo.attr[14])});
+ assert_deps_valid(MBC_SURFACE,
+ {BUFFER_INDEX(ibo.tris),
+ BUFFER_INDEX(vbo.lnor),
+ BUFFER_INDEX(vbo.pos_nor),
+ BUFFER_INDEX(vbo.uv),
+ BUFFER_INDEX(vbo.attr[0]),
+ BUFFER_INDEX(vbo.attr[1]),
+ BUFFER_INDEX(vbo.attr[2]),
+ BUFFER_INDEX(vbo.attr[3]),
+ BUFFER_INDEX(vbo.attr[4]),
+ BUFFER_INDEX(vbo.attr[5]),
+ BUFFER_INDEX(vbo.attr[6]),
+ BUFFER_INDEX(vbo.attr[7]),
+ BUFFER_INDEX(vbo.attr[8]),
+ BUFFER_INDEX(vbo.attr[9]),
+ BUFFER_INDEX(vbo.attr[10]),
+ BUFFER_INDEX(vbo.attr[11]),
+ BUFFER_INDEX(vbo.attr[12]),
+ BUFFER_INDEX(vbo.attr[13]),
+ BUFFER_INDEX(vbo.attr[14])});
if (DRW_batch_requested(cache->batch.surface, GPU_PRIM_TRIS)) {
DRW_ibo_request(cache->batch.surface, &mbuflist->ibo.tris);
/* Order matters. First ones override latest VBO's attributes. */
@@ -1727,9 +1549,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
if (cache->cd_used.uv != 0) {
DRW_vbo_request(cache->batch.surface, &mbuflist->vbo.uv);
}
- if (cache->cd_used.vcol != 0) {
- DRW_vbo_request(cache->batch.surface, &mbuflist->vbo.vcol);
- }
drw_add_attributes_vbo(cache->batch.surface, mbuflist, &cache->attr_used);
}
assert_deps_valid(MBC_ALL_VERTS, {BUFFER_INDEX(vbo.pos_nor)});
@@ -1807,12 +1626,12 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
assert_deps_valid(
MBC_SURFACE_PER_MAT,
{BUFFER_INDEX(vbo.lnor), BUFFER_INDEX(vbo.pos_nor), BUFFER_INDEX(vbo.uv),
- BUFFER_INDEX(vbo.tan), BUFFER_INDEX(vbo.vcol), BUFFER_INDEX(vbo.orco),
- BUFFER_INDEX(vbo.attr[0]), BUFFER_INDEX(vbo.attr[1]), BUFFER_INDEX(vbo.attr[2]),
- BUFFER_INDEX(vbo.attr[3]), BUFFER_INDEX(vbo.attr[4]), BUFFER_INDEX(vbo.attr[5]),
- BUFFER_INDEX(vbo.attr[6]), BUFFER_INDEX(vbo.attr[7]), BUFFER_INDEX(vbo.attr[8]),
- BUFFER_INDEX(vbo.attr[9]), BUFFER_INDEX(vbo.attr[10]), BUFFER_INDEX(vbo.attr[11]),
- BUFFER_INDEX(vbo.attr[12]), BUFFER_INDEX(vbo.attr[13]), BUFFER_INDEX(vbo.attr[14])});
+ BUFFER_INDEX(vbo.tan), BUFFER_INDEX(vbo.orco), BUFFER_INDEX(vbo.attr[0]),
+ BUFFER_INDEX(vbo.attr[1]), BUFFER_INDEX(vbo.attr[2]), BUFFER_INDEX(vbo.attr[3]),
+ BUFFER_INDEX(vbo.attr[4]), BUFFER_INDEX(vbo.attr[5]), BUFFER_INDEX(vbo.attr[6]),
+ BUFFER_INDEX(vbo.attr[7]), BUFFER_INDEX(vbo.attr[8]), BUFFER_INDEX(vbo.attr[9]),
+ BUFFER_INDEX(vbo.attr[10]), BUFFER_INDEX(vbo.attr[11]), BUFFER_INDEX(vbo.attr[12]),
+ BUFFER_INDEX(vbo.attr[13]), BUFFER_INDEX(vbo.attr[14])});
assert_deps_valid(MBC_SURFACE_PER_MAT, {TRIS_PER_MAT_INDEX});
for (int i = 0; i < cache->mat_len; i++) {
if (DRW_batch_requested(cache->surface_per_mat[i], GPU_PRIM_TRIS)) {
@@ -1826,9 +1645,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
if ((cache->cd_used.tan != 0) || (cache->cd_used.tan_orco != 0)) {
DRW_vbo_request(cache->surface_per_mat[i], &mbuflist->vbo.tan);
}
- if (cache->cd_used.vcol != 0) {
- DRW_vbo_request(cache->surface_per_mat[i], &mbuflist->vbo.vcol);
- }
if (cache->cd_used.orco != 0) {
DRW_vbo_request(cache->surface_per_mat[i], &mbuflist->vbo.orco);
}
@@ -1994,7 +1810,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
assert_final_deps_valid(BUFFER_INDEX(vbo.lnor));
assert_final_deps_valid(BUFFER_INDEX(vbo.pos_nor));
assert_final_deps_valid(BUFFER_INDEX(vbo.uv));
- assert_final_deps_valid(BUFFER_INDEX(vbo.vcol));
assert_final_deps_valid(BUFFER_INDEX(vbo.sculpt_data));
assert_final_deps_valid(BUFFER_INDEX(vbo.weights));
assert_final_deps_valid(BUFFER_INDEX(vbo.edge_fac));
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
index 8052b277d45..a4773736f0c 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
@@ -86,6 +86,9 @@ struct MeshRenderData {
float (*loop_normals)[3];
int *lverts, *ledges;
+ const char *active_color_name;
+ const char *default_color_name;
+
struct {
int *tri_first_index;
int *mat_tri_len;
@@ -93,6 +96,82 @@ struct MeshRenderData {
} poly_sorted;
};
+BLI_INLINE const Mesh *editmesh_final_or_this(const Object *object, const Mesh *me)
+{
+ if (me->edit_mesh != nullptr) {
+ Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object);
+ if (editmesh_eval_final != nullptr) {
+ return editmesh_eval_final;
+ }
+ }
+
+ return me;
+}
+
+BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me)
+{
+ switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ case ME_WRAPPER_TYPE_SUBD:
+ case ME_WRAPPER_TYPE_MDATA:
+ return &me->ldata;
+ break;
+ case ME_WRAPPER_TYPE_BMESH:
+ return &me->edit_mesh->bm->ldata;
+ break;
+ }
+
+ BLI_assert(0);
+ return &me->ldata;
+}
+
+BLI_INLINE const CustomData *mesh_cd_pdata_get_from_mesh(const Mesh *me)
+{
+ switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ case ME_WRAPPER_TYPE_SUBD:
+ case ME_WRAPPER_TYPE_MDATA:
+ return &me->pdata;
+ break;
+ case ME_WRAPPER_TYPE_BMESH:
+ return &me->edit_mesh->bm->pdata;
+ break;
+ }
+
+ BLI_assert(0);
+ return &me->pdata;
+}
+
+BLI_INLINE const CustomData *mesh_cd_edata_get_from_mesh(const Mesh *me)
+{
+ switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ case ME_WRAPPER_TYPE_SUBD:
+ case ME_WRAPPER_TYPE_MDATA:
+ return &me->edata;
+ break;
+ case ME_WRAPPER_TYPE_BMESH:
+ return &me->edit_mesh->bm->edata;
+ break;
+ }
+
+ BLI_assert(0);
+ return &me->edata;
+}
+
+BLI_INLINE const CustomData *mesh_cd_vdata_get_from_mesh(const Mesh *me)
+{
+ switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ case ME_WRAPPER_TYPE_SUBD:
+ case ME_WRAPPER_TYPE_MDATA:
+ return &me->vdata;
+ break;
+ case ME_WRAPPER_TYPE_BMESH:
+ return &me->edit_mesh->bm->vdata;
+ break;
+ }
+
+ BLI_assert(0);
+ return &me->vdata;
+}
+
BLI_INLINE BMFace *bm_original_face_get(const MeshRenderData *mr, int idx)
{
return ((mr->p_origindex != NULL) && (mr->p_origindex[idx] != ORIGINDEX_NONE) && mr->bm) ?
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 b98af3be17f..7f16837022c 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
@@ -9,6 +9,7 @@
#include <functional>
+#include "BLI_color.hh"
#include "BLI_math_vec_types.hh"
#include "BLI_string.h"
@@ -74,6 +75,18 @@ template<> struct AttributeTypeConverter<MPropCol, gpuMeshCol> {
}
};
+template<> struct AttributeTypeConverter<ColorGeometry4b, gpuMeshCol> {
+ static gpuMeshCol convert_value(ColorGeometry4b value)
+ {
+ gpuMeshCol result;
+ result.r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.r]);
+ result.g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.g]);
+ result.b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.b]);
+ result.a = unit_float_to_ushort_clamp(value.a * (1.0f / 255.0f));
+ return result;
+ }
+};
+
/* Return the number of component for the attribute's value type, or 0 if is it unsupported. */
static uint gpu_component_size_for_attribute_type(eCustomDataType type)
{
@@ -90,6 +103,7 @@ static uint gpu_component_size_for_attribute_type(eCustomDataType type)
case CD_PROP_FLOAT3:
return 3;
case CD_PROP_COLOR:
+ case CD_PROP_BYTE_COLOR:
return 4;
default:
return 0;
@@ -102,6 +116,7 @@ static GPUVertFetchMode get_fetch_mode_for_type(eCustomDataType type)
case CD_PROP_INT32:
return GPU_FETCH_INT_TO_FLOAT;
case CD_PROP_COLOR:
+ case CD_PROP_BYTE_COLOR:
return GPU_FETCH_INT_TO_FLOAT_UNIT;
default:
return GPU_FETCH_FLOAT;
@@ -114,13 +129,15 @@ static GPUVertCompType get_comp_type_for_type(eCustomDataType type)
case CD_PROP_INT32:
return GPU_COMP_I32;
case CD_PROP_COLOR:
+ case CD_PROP_BYTE_COLOR:
return GPU_COMP_U16;
default:
return GPU_COMP_F32;
}
}
-static void init_vbo_for_attribute(GPUVertBuf *vbo,
+static void init_vbo_for_attribute(const MeshRenderData &mr,
+ GPUVertBuf *vbo,
const DRW_AttributeRequest &request,
bool build_on_device,
uint32_t len)
@@ -140,6 +157,13 @@ static void init_vbo_for_attribute(GPUVertBuf *vbo,
GPU_vertformat_deinterleave(&format);
GPU_vertformat_attr_add(&format, attr_name, comp_type, comp_size, fetch_mode);
+ if (mr.active_color_name && STREQ(request.attribute_name, mr.active_color_name)) {
+ GPU_vertformat_alias_add(&format, "ac");
+ }
+ if (mr.default_color_name && STREQ(request.attribute_name, mr.default_color_name)) {
+ GPU_vertformat_alias_add(&format, "c");
+ }
+
if (build_on_device) {
GPU_vertbuf_init_build_on_device(vbo, &format, len);
}
@@ -262,7 +286,7 @@ static void extract_attr_init(
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
- init_vbo_for_attribute(vbo, request, false, static_cast<uint32_t>(mr->loop_len));
+ init_vbo_for_attribute(*mr, vbo, request, false, static_cast<uint32_t>(mr->loop_len));
/* TODO(@kevindietrich): float3 is used for scalar attributes as the implicit conversion done by
* OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following the
@@ -290,6 +314,9 @@ static void extract_attr_init(
case CD_PROP_COLOR:
extract_attr_generic<MPropCol, gpuMeshCol>(mr, vbo, request);
break;
+ case CD_PROP_BYTE_COLOR:
+ extract_attr_generic<ColorGeometry4b, gpuMeshCol>(mr, vbo, request);
+ break;
default:
BLI_assert_unreachable();
}
@@ -338,12 +365,15 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
case CD_PROP_COLOR:
extract_attr_generic<MPropCol, gpuMeshCol>(mr, src_data, request);
break;
+ case CD_PROP_BYTE_COLOR:
+ extract_attr_generic<ColorGeometry4b, gpuMeshCol>(mr, src_data, request);
+ break;
default:
BLI_assert_unreachable();
}
GPUVertBuf *dst_buffer = static_cast<GPUVertBuf *>(buffer);
- init_vbo_for_attribute(dst_buffer, request, true, subdiv_cache->num_subdiv_loops);
+ init_vbo_for_attribute(*mr, dst_buffer, request, true, subdiv_cache->num_subdiv_loops);
/* Ensure data is uploaded properly. */
GPU_vertbuf_tag_dirty(src_data);
@@ -352,7 +382,7 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
dst_buffer,
static_cast<int>(dimensions),
0,
- request.cd_type == CD_PROP_COLOR);
+ ELEM(request.cd_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR));
GPU_vertbuf_discard(src_data);
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc
deleted file mode 100644
index 419cbb0267f..00000000000
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc
+++ /dev/null
@@ -1,387 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright 2021 Blender Foundation. All rights reserved. */
-
-/** \file
- * \ingroup draw
- */
-
-#include "MEM_guardedalloc.h"
-
-#include "BKE_attribute.h"
-#include "BLI_string.h"
-#include "BLI_vector.hh"
-
-#include "draw_subdivision.h"
-#include "extract_mesh.hh"
-
-namespace blender::draw {
-
-struct VColRef {
- const CustomDataLayer *layer;
- eAttrDomain domain;
-};
-
-/** Get all vcol layers as AttributeRefs.
- *
- * \param vcol_layers: bitmask to filter vcol layers by, each bit
- * corresponds to the integer position of the attribute
- * within the global color attribute list.
- */
-static Vector<VColRef> get_vcol_refs(const CustomData *cd_vdata,
- const CustomData *cd_ldata,
- const uint vcol_layers)
-{
- Vector<VColRef> refs;
- uint layeri = 0;
-
- auto buildList = [&](const CustomData *cdata, eAttrDomain domain) {
- for (int i = 0; i < cdata->totlayer; i++) {
- const CustomDataLayer *layer = cdata->layers + i;
-
- if (!(CD_TYPE_AS_MASK(layer->type) & CD_MASK_COLOR_ALL)) {
- continue;
- }
-
- if (layer->flag & CD_FLAG_TEMPORARY) {
- continue;
- }
-
- if (!(vcol_layers & (1UL << layeri))) {
- layeri++;
- continue;
- }
-
- VColRef ref = {};
- ref.domain = domain;
- ref.layer = layer;
-
- refs.append(ref);
- layeri++;
- }
- };
-
- buildList(cd_vdata, ATTR_DOMAIN_POINT);
- buildList(cd_ldata, ATTR_DOMAIN_CORNER);
-
- return refs;
-}
-
-/* ---------------------------------------------------------------------- */
-/** \name Extract VCol
- * \{ */
-
-/* Initialize the common vertex format for vcol for coarse and subdivided meshes. */
-static void init_vcol_format(GPUVertFormat *format,
- const MeshBatchCache *cache,
- const CustomData *cd_vdata,
- const CustomData *cd_ldata,
- const CustomDataLayer *active,
- const CustomDataLayer *render)
-{
- GPU_vertformat_deinterleave(format);
-
- const uint32_t vcol_layers = cache->cd_used.vcol;
-
- Vector<VColRef> refs = get_vcol_refs(cd_vdata, cd_ldata, vcol_layers);
-
- for (const VColRef &ref : refs) {
- char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
-
- GPU_vertformat_safe_attr_name(ref.layer->name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
-
- /* VCol layer name. */
- BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
- GPU_vertformat_attr_add(format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- /* Active layer name. */
- if (ref.layer == active) {
- GPU_vertformat_alias_add(format, "ac");
- }
-
- /* Active render layer name. */
- if (ref.layer == render) {
- GPU_vertformat_alias_add(format, "c");
- }
- }
-}
-
-/* Vertex format for vertex colors, only used during the coarse data upload for the subdivision
- * case. */
-static GPUVertFormat *get_coarse_vcol_format()
-{
- static GPUVertFormat format = {0};
- if (format.attr_len == 0) {
- GPU_vertformat_attr_add(&format, "cCol", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- GPU_vertformat_alias_add(&format, "c");
- GPU_vertformat_alias_add(&format, "ac");
- }
- return &format;
-}
-
-struct gpuMeshVcol {
- ushort r, g, b, a;
-};
-
-static void extract_vcol_init(const MeshRenderData *mr,
- MeshBatchCache *cache,
- void *buf,
- void *UNUSED(tls_data))
-{
- GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
- GPUVertFormat format = {0};
-
- const CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata :
- &mr->me->vdata;
- const CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata :
- &mr->me->ldata;
-
- Mesh me_query = blender::dna::shallow_zero_initialize();
-
- BKE_id_attribute_copy_domains_temp(
- ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id);
-
- const CustomDataLayer *active_color = BKE_id_attributes_active_color_get(&me_query.id);
- const CustomDataLayer *render_color = BKE_id_attributes_render_color_get(&me_query.id);
-
- const uint32_t vcol_layers = cache->cd_used.vcol;
- init_vcol_format(&format, cache, cd_vdata, cd_ldata, active_color, render_color);
-
- GPU_vertbuf_init_with_format(vbo, &format);
- GPU_vertbuf_data_alloc(vbo, mr->loop_len);
-
- gpuMeshVcol *vcol_data = (gpuMeshVcol *)GPU_vertbuf_get_data(vbo);
-
- Vector<VColRef> refs = get_vcol_refs(cd_vdata, cd_ldata, vcol_layers);
-
- for (const VColRef &ref : refs) {
- const CustomData *cdata = ref.domain == ATTR_DOMAIN_POINT ? cd_vdata : cd_ldata;
-
- if (mr->extract_type == MR_EXTRACT_BMESH) {
- int cd_ofs = ref.layer->offset;
-
- if (cd_ofs == -1) {
- vcol_data += ref.domain == ATTR_DOMAIN_POINT ? mr->bm->totvert : mr->bm->totloop;
- continue;
- }
-
- BMIter iter;
- const bool is_byte = ref.layer->type == CD_PROP_BYTE_COLOR;
- const bool is_point = ref.domain == ATTR_DOMAIN_POINT;
-
- BMFace *f;
- BM_ITER_MESH (f, &iter, mr->bm, BM_FACES_OF_MESH) {
- const BMLoop *l_iter = f->l_first;
- do {
- const BMElem *elem = is_point ? reinterpret_cast<const BMElem *>(l_iter->v) :
- reinterpret_cast<const BMElem *>(l_iter);
- if (is_byte) {
- const MLoopCol *mloopcol = (const MLoopCol *)BM_ELEM_CD_GET_VOID_P(elem, cd_ofs);
- vcol_data->r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mloopcol->r]);
- vcol_data->g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mloopcol->g]);
- vcol_data->b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mloopcol->b]);
- vcol_data->a = unit_float_to_ushort_clamp(mloopcol->a * (1.0f / 255.0f));
- vcol_data++;
- }
- else {
- const MPropCol *mpcol = (const MPropCol *)BM_ELEM_CD_GET_VOID_P(elem, cd_ofs);
- vcol_data->r = unit_float_to_ushort_clamp(mpcol->color[0]);
- vcol_data->g = unit_float_to_ushort_clamp(mpcol->color[1]);
- vcol_data->b = unit_float_to_ushort_clamp(mpcol->color[2]);
- vcol_data->a = unit_float_to_ushort_clamp(mpcol->color[3]);
- vcol_data++;
- }
- } while ((l_iter = l_iter->next) != f->l_first);
- }
- }
- else {
- int totloop = mr->loop_len;
- const int idx = CustomData_get_named_layer_index(cdata, ref.layer->type, ref.layer->name);
-
- const MLoopCol *mcol = nullptr;
- const MPropCol *pcol = nullptr;
- const MLoop *mloop = mr->mloop;
-
- if (ref.layer->type == CD_PROP_COLOR) {
- pcol = static_cast<const MPropCol *>(cdata->layers[idx].data);
- }
- else {
- mcol = static_cast<const MLoopCol *>(cdata->layers[idx].data);
- }
-
- const bool is_corner = ref.domain == ATTR_DOMAIN_CORNER;
-
- for (int i = 0; i < totloop; i++, mloop++) {
- const int v_i = is_corner ? i : mloop->v;
-
- if (mcol) {
- vcol_data->r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[v_i].r]);
- vcol_data->g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[v_i].g]);
- vcol_data->b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[v_i].b]);
- vcol_data->a = unit_float_to_ushort_clamp(mcol[v_i].a * (1.0f / 255.0f));
- vcol_data++;
- }
- else if (pcol) {
- vcol_data->r = unit_float_to_ushort_clamp(pcol[v_i].color[0]);
- vcol_data->g = unit_float_to_ushort_clamp(pcol[v_i].color[1]);
- vcol_data->b = unit_float_to_ushort_clamp(pcol[v_i].color[2]);
- vcol_data->a = unit_float_to_ushort_clamp(pcol[v_i].color[3]);
- vcol_data++;
- }
- }
- }
- }
-}
-
-static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *mr,
- MeshBatchCache *cache,
- void *buffer,
- void *UNUSED(data))
-{
- GPUVertBuf *dst_buffer = static_cast<GPUVertBuf *>(buffer);
- const Mesh *coarse_mesh = subdiv_cache->mesh;
-
- bool extract_bmesh = mr->extract_type == MR_EXTRACT_BMESH;
-
- const CustomData *cd_vdata = extract_bmesh ? &coarse_mesh->edit_mesh->bm->vdata :
- &coarse_mesh->vdata;
- const CustomData *cd_ldata = extract_bmesh ? &coarse_mesh->edit_mesh->bm->ldata :
- &coarse_mesh->ldata;
- const int totloop = extract_bmesh ? coarse_mesh->edit_mesh->bm->totloop : coarse_mesh->totloop;
-
- Mesh me_query = blender::dna::shallow_copy(*coarse_mesh);
- BKE_id_attribute_copy_domains_temp(
- ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id);
-
- const CustomDataLayer *active_color = BKE_id_attributes_active_color_get(&me_query.id);
- const CustomDataLayer *render_color = BKE_id_attributes_render_color_get(&me_query.id);
-
- GPUVertFormat format = {0};
- init_vcol_format(
- &format, cache, &coarse_mesh->vdata, &coarse_mesh->ldata, active_color, render_color);
-
- GPU_vertbuf_init_build_on_device(dst_buffer, &format, subdiv_cache->num_subdiv_loops);
-
- GPUVertBuf *src_data = GPU_vertbuf_calloc();
- /* Dynamic as we upload and interpolate layers one at a time. */
- GPU_vertbuf_init_with_format_ex(src_data, get_coarse_vcol_format(), GPU_USAGE_DYNAMIC);
-
- GPU_vertbuf_data_alloc(src_data, totloop);
-
- gpuMeshVcol *mesh_vcol = (gpuMeshVcol *)GPU_vertbuf_get_data(src_data);
-
- const uint vcol_layers = cache->cd_used.vcol;
-
- Vector<VColRef> refs = get_vcol_refs(cd_vdata, cd_ldata, vcol_layers);
-
- /* Index of the vertex color layer in the compact buffer. Used vertex color layers are stored in
- * a single buffer. */
- int pack_layer_index = 0;
- for (const VColRef &ref : refs) {
- /* Include stride in offset, we use a stride of 2 since colors are packed into 2 uints. */
- const int dst_offset = (int)subdiv_cache->num_subdiv_loops * 2 * pack_layer_index++;
-
- const CustomData *cdata = ref.domain == ATTR_DOMAIN_POINT ? cd_vdata : cd_ldata;
- int layer_i = CustomData_get_named_layer_index(cdata, ref.layer->type, ref.layer->name);
-
- if (layer_i == -1) {
- printf("%s: missing color layer %s\n", __func__, ref.layer->name);
- continue;
- }
-
- gpuMeshVcol *vcol = mesh_vcol;
-
- const bool is_vert = ref.domain == ATTR_DOMAIN_POINT;
-
- if (extract_bmesh) {
- BMesh *bm = coarse_mesh->edit_mesh->bm;
- BMIter iter;
- BMFace *f;
- int cd_ofs = cdata->layers[layer_i].offset;
- const bool is_byte = ref.layer->type == CD_PROP_BYTE_COLOR;
-
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- const BMLoop *l_iter = f->l_first;
-
- do {
- const BMElem *elem = is_vert ? reinterpret_cast<const BMElem *>(l_iter->v) :
- reinterpret_cast<const BMElem *>(l_iter);
-
- if (is_byte) {
- const MLoopCol *mcol2 = static_cast<const MLoopCol *>(
- BM_ELEM_CD_GET_VOID_P(elem, cd_ofs));
-
- vcol->r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->r]);
- vcol->g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->g]);
- vcol->b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->b]);
- vcol->a = unit_float_to_ushort_clamp(mcol2->a * (1.0f / 255.0f));
- }
- else {
- const MPropCol *pcol2 = static_cast<const MPropCol *>(
- BM_ELEM_CD_GET_VOID_P(elem, cd_ofs));
-
- vcol->r = unit_float_to_ushort_clamp(pcol2->color[0]);
- vcol->g = unit_float_to_ushort_clamp(pcol2->color[1]);
- vcol->b = unit_float_to_ushort_clamp(pcol2->color[2]);
- vcol->a = unit_float_to_ushort_clamp(pcol2->color[3]);
- }
-
- vcol++;
- } while ((l_iter = l_iter->next) != f->l_first);
- }
- }
- else {
- const MLoop *ml = coarse_mesh->mloop;
- const MLoopCol *mcol = nullptr;
- const MPropCol *pcol = nullptr;
-
- if (ref.layer->type == CD_PROP_COLOR) {
- pcol = static_cast<const MPropCol *>(cdata->layers[layer_i].data);
- }
- else {
- mcol = static_cast<const MLoopCol *>(cdata->layers[layer_i].data);
- }
-
- for (int ml_index = 0; ml_index < coarse_mesh->totloop; ml_index++, vcol++, ml++) {
- int idx = is_vert ? ml->v : ml_index;
-
- if (mcol) {
- vcol->r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[idx].r]);
- vcol->g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[idx].g]);
- vcol->b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[idx].b]);
- vcol->a = unit_float_to_ushort_clamp(mcol[idx].a * (1.0f / 255.0f));
- }
- else if (pcol) {
- vcol->r = unit_float_to_ushort_clamp(pcol[idx].color[0]);
- vcol->g = unit_float_to_ushort_clamp(pcol[idx].color[1]);
- vcol->b = unit_float_to_ushort_clamp(pcol[idx].color[2]);
- vcol->a = unit_float_to_ushort_clamp(pcol[idx].color[3]);
- }
- }
- }
-
- /* Ensure data is uploaded properly. */
- GPU_vertbuf_tag_dirty(src_data);
- draw_subdiv_interp_custom_data(subdiv_cache, src_data, dst_buffer, 4, dst_offset, true);
- }
-
- GPU_vertbuf_discard(src_data);
-}
-
-constexpr MeshExtract create_extractor_vcol()
-{
- MeshExtract extractor = {nullptr};
- extractor.init = extract_vcol_init;
- extractor.init_subdiv = extract_vcol_init_subdiv;
- extractor.data_type = MR_DATA_NONE;
- extractor.data_size = 0;
- extractor.use_threading = false;
- extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.vcol);
- return extractor;
-}
-
-/** \} */
-
-} // namespace blender::draw
-
-const MeshExtract extract_vcol = blender::draw::create_extractor_vcol();
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index c0633f0323d..3ca465fa57a 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -131,6 +131,11 @@ typedef void (*GPUCodegenCallbackFn)(void *thunk, GPUMaterial *mat, GPUCodegenOu
GPUNodeLink *GPU_constant(const float *num);
GPUNodeLink *GPU_uniform(const float *num);
GPUNodeLink *GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name);
+/**
+ * Add a GPU attribute that refers to the default color attribute on a geometry.
+ * The name, type, and domain are unknown and do not depend on the material.
+ */
+GPUNodeLink *GPU_attribute_default_color(GPUMaterial *mat);
GPUNodeLink *GPU_attribute_with_default(GPUMaterial *mat,
eCustomDataType type,
const char *name,
@@ -266,6 +271,12 @@ typedef struct GPUMaterialAttribute {
eGPUDefaultValue default_value; /* Only for volumes attributes. */
int id;
int users;
+ /**
+ * If true, the corresponding attribute is the specified default color attribute on the mesh,
+ * if it exists. In that case the type and name data can vary per geometry, so it will not be
+ * valid here.
+ */
+ bool is_default_color;
} GPUMaterialAttribute;
typedef struct GPUMaterialTexture {
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index 1338c5312c2..684070dbdc0 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -328,13 +328,14 @@ void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph)
/* Attributes and Textures */
-static char attr_prefix_get(eCustomDataType type)
+static char attr_prefix_get(GPUMaterialAttribute *attr)
{
- switch (type) {
+ if (attr->is_default_color) {
+ return 'c';
+ }
+ switch (attr->type) {
case CD_TANGENT:
return 't';
- case CD_MCOL:
- return 'c';
case CD_AUTO_FROM_NAME:
return 'a';
case CD_HAIRLENGTH:
@@ -353,7 +354,7 @@ static void attr_input_name(GPUMaterialAttribute *attr)
STRNCPY(attr->input_name, "orco");
}
else {
- attr->input_name[0] = attr_prefix_get(attr->type);
+ attr->input_name[0] = attr_prefix_get(attr);
attr->input_name[1] = '\0';
if (attr->name[0] != '\0') {
/* XXX FIXME: see notes in mesh_render_data_create() */
@@ -365,13 +366,15 @@ static void attr_input_name(GPUMaterialAttribute *attr)
/** Add a new varying attribute of given type and name. Returns NULL if out of slots. */
static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph,
eCustomDataType type,
- const char *name)
+ const char *name,
+ const bool is_default_color)
{
/* Find existing attribute. */
int num_attributes = 0;
GPUMaterialAttribute *attr = graph->attributes.first;
for (; attr; attr = attr->next) {
- if (attr->type == type && STREQ(attr->name, name)) {
+ if (attr->type == type && STREQ(attr->name, name) &&
+ attr->is_default_color == is_default_color) {
break;
}
num_attributes++;
@@ -380,6 +383,7 @@ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph,
/* Add new requested attribute if it's within GPU limits. */
if (attr == NULL) {
attr = MEM_callocN(sizeof(*attr), __func__);
+ attr->is_default_color = is_default_color;
attr->type = type;
STRNCPY(attr->name, name);
attr_input_name(attr);
@@ -471,7 +475,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
GPUNodeLink *GPU_attribute(GPUMaterial *mat, const eCustomDataType type, const char *name)
{
GPUNodeGraph *graph = gpu_material_node_graph(mat);
- GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, type, name);
+ GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, type, name, false);
if (type == CD_ORCO) {
/* OPTI: orco might be computed from local positions and needs object infos. */
@@ -490,6 +494,21 @@ GPUNodeLink *GPU_attribute(GPUMaterial *mat, const eCustomDataType type, const c
return link;
}
+GPUNodeLink *GPU_attribute_default_color(GPUMaterial *mat)
+{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, CD_AUTO_FROM_NAME, "", true);
+ if (attr == NULL) {
+ static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f};
+ return GPU_constant(zero_data);
+ }
+ attr->is_default_color = true;
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_ATTR;
+ link->attr = attr;
+ return link;
+}
+
GPUNodeLink *GPU_attribute_with_default(GPUMaterial *mat,
const eCustomDataType type,
const char *name,
diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
index 830f02d8df1..c636cc976e6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
@@ -42,9 +42,8 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
GPUNodeStack *out)
{
NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage;
- /* NOTE: using CD_AUTO_FROM_NAME instead of CD_MCOL or CD_PROP_COLOR for named attributes
- * as geometry nodes may overwrite data which will also change the eCustomDataType.
- * This will also make EEVEE and Cycles
+ /* NOTE: Using #CD_AUTO_FROM_NAME is necessary because there are multiple color attribute types,
+ * and the type may change during evaluation anyway. This will also make EEVEE and Cycles
* consistent. See T93179. */
GPUNodeLink *vertexColorLink;
@@ -53,7 +52,7 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
vertexColorLink = GPU_attribute(mat, CD_AUTO_FROM_NAME, vertexColor->layer_name);
}
else { /* Fall back on active render color attribute. */
- vertexColorLink = GPU_attribute(mat, CD_MCOL, vertexColor->layer_name);
+ vertexColorLink = GPU_attribute_default_color(mat);
}
return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);