Draw: Custom IDs #105261

Merged
Clément Foucault merged 12 commits from pragma37/blender:pull-thin-handles into main 2023-03-01 21:42:37 +01:00
14 changed files with 107 additions and 42 deletions

View File

@ -40,8 +40,7 @@ GPU_SHADER_CREATE_INFO(workbench_next_mesh)
.vertex_in(2, Type::VEC4, "ac") .vertex_in(2, Type::VEC4, "ac")
.vertex_in(3, Type::VEC2, "au") .vertex_in(3, Type::VEC2, "au")
.vertex_source("workbench_prepass_vert.glsl") .vertex_source("workbench_prepass_vert.glsl")
.additional_info("draw_modelmat_new") .additional_info("draw_modelmat_new_with_custom_id", "draw_resource_handle_new");
.additional_info("draw_resource_handle_new");
GPU_SHADER_CREATE_INFO(workbench_next_curves) GPU_SHADER_CREATE_INFO(workbench_next_curves)
/* TODO Adding workbench_next_mesh to avoid shader compilation errors */ /* TODO Adding workbench_next_mesh to avoid shader compilation errors */

View File

@ -16,8 +16,12 @@ void main()
normal_interp = normalize(normal_object_to_view(nor)); normal_interp = normalize(normal_object_to_view(nor));
object_id = int(uint(resource_id) & 0xFFFFu) + 1;
#ifdef WORKBENCH_NEXT
workbench_material_data_get(
int(drw_CustomID), ac.rgb, color_interp, alpha_interp, _roughness, metallic);
#else
workbench_material_data_get( workbench_material_data_get(
resource_handle, ac.rgb, color_interp, alpha_interp, _roughness, metallic); resource_handle, ac.rgb, color_interp, alpha_interp, _roughness, metallic);
#endif
object_id = int(uint(resource_handle) & 0xFFFFu) + 1;
} }

View File

@ -68,6 +68,7 @@ class Instance {
resolution, resolution,
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW); GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW);
resources.material_buf.clear();
opaque_ps.sync(scene_state, resources); opaque_ps.sync(scene_state, resources);
transparent_ps.sync(scene_state, resources); transparent_ps.sync(scene_state, resources);
@ -202,12 +203,8 @@ class Instance {
if (batches[i] == nullptr) { if (batches[i] == nullptr) {
continue; continue;
} }
/* TODO(fclem): This create a cull-able instance for each sub-object. This is done
* for simplicity to reduce complexity. But this increase the overhead per object.
* Instead, we should use an indirection buffer to the material buffer. */
ResourceHandle _handle = i == 0 ? handle : manager.resource_handle(ob_ref);
Material &mat = resources.material_buf.get_or_resize(_handle.resource_index()); Material mat;
if (::Material *_mat = BKE_object_material_get_eval(ob_ref.object, i + 1)) { if (::Material *_mat = BKE_object_material_get_eval(ob_ref.object, i + 1)) {
mat = Material(*_mat); mat = Material(*_mat);
@ -225,7 +222,7 @@ class Instance {
get_material_image(ob_ref.object, i + 1, image, iuser, sampler_state); get_material_image(ob_ref.object, i + 1, image, iuser, sampler_state);
} }
draw_mesh(ob_ref, mat, batches[i], _handle, image, sampler_state, iuser); draw_mesh(ob_ref, mat, batches[i], handle, image, sampler_state, iuser);
} }
} }
} }
@ -247,7 +244,7 @@ class Instance {
} }
if (batch) { if (batch) {
Material &mat = resources.material_buf.get_or_resize(handle.resource_index()); Material mat;
if (object_state.color_type == V3D_SHADING_OBJECT_COLOR) { if (object_state.color_type == V3D_SHADING_OBJECT_COLOR) {
mat = Material(*ob_ref.object); mat = Material(*ob_ref.object);
@ -291,9 +288,11 @@ class Instance {
ImageUser *iuser = nullptr) ImageUser *iuser = nullptr)
{ {
const bool in_front = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0; const bool in_front = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0;
resources.material_buf.append(material);
int material_index = resources.material_buf.size() - 1;
auto draw = [&](MeshPass &pass) { auto draw = [&](MeshPass &pass) {
pass.draw(ob_ref, batch, handle, image, sampler_state, iuser); pass.draw(ob_ref, batch, handle, material_index, image, sampler_state, iuser);
}; };
if (scene_state.xray_mode || material.is_transparent()) { if (scene_state.xray_mode || material.is_transparent()) {

View File

@ -18,6 +18,7 @@ bool MeshPass::is_empty() const
void MeshPass::init_pass(SceneResources &resources, DRWState state, int clip_planes) void MeshPass::init_pass(SceneResources &resources, DRWState state, int clip_planes)
{ {
use_custom_ids = true;
is_empty_ = true; is_empty_ = true;
PassMain::init(); PassMain::init();
state_set(state, clip_planes); state_set(state, clip_planes);
@ -57,6 +58,7 @@ void MeshPass::init_subpasses(ePipelineType pipeline,
void MeshPass::draw(ObjectRef &ref, void MeshPass::draw(ObjectRef &ref,
GPUBatch *batch, GPUBatch *batch,
ResourceHandle handle, ResourceHandle handle,
uint material_index,
::Image *image /* = nullptr */, ::Image *image /* = nullptr */,
eGPUSamplerState sampler_state /* = GPU_SAMPLER_DEFAULT */, eGPUSamplerState sampler_state /* = GPU_SAMPLER_DEFAULT */,
ImageUser *iuser /* = nullptr */) ImageUser *iuser /* = nullptr */)
@ -95,11 +97,11 @@ void MeshPass::draw(ObjectRef &ref,
}; };
texture_subpass_map_.lookup_or_add_cb(TextureSubPassKey(texture, geometry_type), add_cb) texture_subpass_map_.lookup_or_add_cb(TextureSubPassKey(texture, geometry_type), add_cb)
->draw(batch, handle); ->draw(batch, handle, material_index);
return; return;
} }
} }
passes_[int(geometry_type)][int(eShaderType::MATERIAL)]->draw(batch, handle); passes_[int(geometry_type)][int(eShaderType::MATERIAL)]->draw(batch, handle, material_index);
} }
/** \} */ /** \} */

View File

@ -184,6 +184,7 @@ class MeshPass : public PassMain {
void draw(ObjectRef &ref, void draw(ObjectRef &ref,
GPUBatch *batch, GPUBatch *batch,
ResourceHandle handle, ResourceHandle handle,
uint material_index,
::Image *image = nullptr, ::Image *image = nullptr,
eGPUSamplerState sampler_state = eGPUSamplerState::GPU_SAMPLER_DEFAULT, eGPUSamplerState sampler_state = eGPUSamplerState::GPU_SAMPLER_DEFAULT,
ImageUser *iuser = nullptr); ImageUser *iuser = nullptr);

View File

@ -600,14 +600,13 @@ void DrawCommandBuf::bind(RecordingState &state,
} }
void DrawMultiBuf::bind(RecordingState &state, void DrawMultiBuf::bind(RecordingState &state,
Vector<Header, 0> &headers, Vector<Header, 0> & /*headers*/,
Vector<Undetermined, 0> &commands, Vector<Undetermined, 0> & /*commands*/,
VisibilityBuf &visibility_buf, VisibilityBuf &visibility_buf,
int visibility_word_per_draw, int visibility_word_per_draw,
int view_len) int view_len,
bool use_custom_ids)
{ {
UNUSED_VARS(headers, commands);
GPU_debug_group_begin("DrawMultiBuf.bind"); GPU_debug_group_begin("DrawMultiBuf.bind");
resource_id_count_ = 0u; resource_id_count_ = 0u;
@ -636,7 +635,7 @@ void DrawMultiBuf::bind(RecordingState &state,
group_buf_.push_update(); group_buf_.push_update();
prototype_buf_.push_update(); prototype_buf_.push_update();
/* Allocate enough for the expansion pass. */ /* Allocate enough for the expansion pass. */
resource_id_buf_.get_or_resize(resource_id_count_); resource_id_buf_.get_or_resize(resource_id_count_ * (use_custom_ids ? 2 : 1));
/* Two command per group. */ /* Two command per group. */
command_buf_.get_or_resize(group_count_ * 2); command_buf_.get_or_resize(group_count_ * 2);
@ -646,6 +645,7 @@ void DrawMultiBuf::bind(RecordingState &state,
GPU_shader_uniform_1i(shader, "prototype_len", prototype_count_); GPU_shader_uniform_1i(shader, "prototype_len", prototype_count_);
GPU_shader_uniform_1i(shader, "visibility_word_per_draw", visibility_word_per_draw); GPU_shader_uniform_1i(shader, "visibility_word_per_draw", visibility_word_per_draw);
GPU_shader_uniform_1i(shader, "view_shift", log2_ceil_u(view_len)); GPU_shader_uniform_1i(shader, "view_shift", log2_ceil_u(view_len));
GPU_shader_uniform_1b(shader, "use_custom_ids", use_custom_ids);
GPU_storagebuf_bind(group_buf_, GPU_shader_get_ssbo_binding(shader, "group_buf")); GPU_storagebuf_bind(group_buf_, GPU_shader_get_ssbo_binding(shader, "group_buf"));
GPU_storagebuf_bind(visibility_buf, GPU_shader_get_ssbo_binding(shader, "visibility_buf")); GPU_storagebuf_bind(visibility_buf, GPU_shader_get_ssbo_binding(shader, "visibility_buf"));
GPU_storagebuf_bind(prototype_buf_, GPU_shader_get_ssbo_binding(shader, "prototype_buf")); GPU_storagebuf_bind(prototype_buf_, GPU_shader_get_ssbo_binding(shader, "prototype_buf"));

View File

@ -433,7 +433,8 @@ class DrawCommandBuf {
uint instance_len, uint instance_len,
uint vertex_len, uint vertex_len,
uint vertex_first, uint vertex_first,
ResourceHandle handle) ResourceHandle handle,
uint /*custom_id*/)
{ {
vertex_first = vertex_first != -1 ? vertex_first : 0; vertex_first = vertex_first != -1 ? vertex_first : 0;
instance_len = instance_len != -1 ? instance_len : 1; instance_len = instance_len != -1 ? instance_len : 1;
@ -533,7 +534,8 @@ class DrawMultiBuf {
uint instance_len, uint instance_len,
uint vertex_len, uint vertex_len,
uint vertex_first, uint vertex_first,
ResourceHandle handle) ResourceHandle handle,
uint custom_id)
{ {
/* Custom draw-calls cannot be batched and will produce one group per draw. */ /* Custom draw-calls cannot be batched and will produce one group per draw. */
const bool custom_group = ((vertex_first != 0 && vertex_first != -1) || vertex_len != -1); const bool custom_group = ((vertex_first != 0 && vertex_first != -1) || vertex_len != -1);
@ -555,6 +557,7 @@ class DrawMultiBuf {
DrawPrototype &draw = prototype_buf_.get_or_resize(prototype_count_++); DrawPrototype &draw = prototype_buf_.get_or_resize(prototype_count_++);
draw.resource_handle = handle.raw; draw.resource_handle = handle.raw;
draw.custom_id = custom_id;
draw.instance_len = instance_len; draw.instance_len = instance_len;
draw.group_id = group_id; draw.group_id = group_id;
@ -594,7 +597,8 @@ class DrawMultiBuf {
Vector<Undetermined, 0> &commands, Vector<Undetermined, 0> &commands,
VisibilityBuf &visibility_buf, VisibilityBuf &visibility_buf,
int visibility_word_per_draw, int visibility_word_per_draw,
int view_len); int view_len,
bool use_custom_ids);
}; };
/** \} */ /** \} */

View File

@ -72,9 +72,10 @@ struct DrawPrototype {
uint group_id; uint group_id;
/* Resource handle associated with this call. Also reference visibility. */ /* Resource handle associated with this call. Also reference visibility. */
uint resource_handle; uint resource_handle;
/* Custom extra value to be used by the engines. */
uint custom_id;
/* Number of instances. */ /* Number of instances. */
uint instance_len; uint instance_len;
uint _pad0;
}; };
BLI_STATIC_ASSERT_ALIGN(DrawPrototype, 16) BLI_STATIC_ASSERT_ALIGN(DrawPrototype, 16)

View File

@ -186,7 +186,8 @@ void Manager::submit(PassMain &pass, View &view)
pass.commands_, pass.commands_,
view.get_visibility_buffer(), view.get_visibility_buffer(),
view.visibility_word_per_draw(), view.visibility_word_per_draw(),
view.view_len_); view.view_len_,
pass.use_custom_ids);
resource_bind(); resource_bind();

View File

@ -135,6 +135,8 @@ class PassBase {
public: public:
const char *debug_name; const char *debug_name;
bool use_custom_ids;
PassBase(const char *name, PassBase(const char *name,
DrawCommandBufType &draw_command_buf, DrawCommandBufType &draw_command_buf,
SubPassVector<PassBase<DrawCommandBufType>> &sub_passes, SubPassVector<PassBase<DrawCommandBufType>> &sub_passes,
@ -142,7 +144,8 @@ class PassBase {
: draw_commands_buf_(draw_command_buf), : draw_commands_buf_(draw_command_buf),
sub_passes_(sub_passes), sub_passes_(sub_passes),
shader_(shader), shader_(shader),
debug_name(name){}; debug_name(name),
use_custom_ids(false){};
/** /**
* Reset the pass command pool. * Reset the pass command pool.
@ -224,13 +227,14 @@ class PassBase {
uint instance_len = -1, uint instance_len = -1,
uint vertex_len = -1, uint vertex_len = -1,
uint vertex_first = -1, uint vertex_first = -1,
ResourceHandle handle = {0}); ResourceHandle handle = {0},
uint custom_id = 0);
/** /**
* Shorter version for the common case. * Shorter version for the common case.
* \note Implemented in derived class. Not a virtual function to avoid indirection. * \note Implemented in derived class. Not a virtual function to avoid indirection.
*/ */
void draw(GPUBatch *batch, ResourceHandle handle); void draw(GPUBatch *batch, ResourceHandle handle, uint custom_id = 0);
/** /**
* Record a procedural draw call. Geometry is **NOT** source from a GPUBatch. * Record a procedural draw call. Geometry is **NOT** source from a GPUBatch.
@ -240,7 +244,8 @@ class PassBase {
uint instance_len, uint instance_len,
uint vertex_len, uint vertex_len,
uint vertex_first = -1, uint vertex_first = -1,
ResourceHandle handle = {0}); ResourceHandle handle = {0},
uint custom_id = 0);
/** /**
* Indirect variants. * Indirect variants.
@ -654,20 +659,25 @@ template<class T> std::string PassBase<T>::serialize(std::string line_prefix) co
* \{ */ * \{ */
template<class T> template<class T>
inline void PassBase<T>::draw( inline void PassBase<T>::draw(GPUBatch *batch,
GPUBatch *batch, uint instance_len, uint vertex_len, uint vertex_first, ResourceHandle handle) uint instance_len,
uint vertex_len,
uint vertex_first,
ResourceHandle handle,
uint custom_id)
{ {
if (instance_len == 0 || vertex_len == 0) { if (instance_len == 0 || vertex_len == 0) {
return; return;
} }
BLI_assert(shader_); BLI_assert(shader_);
draw_commands_buf_.append_draw( draw_commands_buf_.append_draw(
headers_, commands_, batch, instance_len, vertex_len, vertex_first, handle); headers_, commands_, batch, instance_len, vertex_len, vertex_first, handle, custom_id);
} }
template<class T> inline void PassBase<T>::draw(GPUBatch *batch, ResourceHandle handle) template<class T>
inline void PassBase<T>::draw(GPUBatch *batch, ResourceHandle handle, uint custom_id)
{ {
this->draw(batch, -1, -1, -1, handle); this->draw(batch, -1, -1, -1, handle, custom_id);
} }
template<class T> template<class T>
@ -675,9 +685,11 @@ inline void PassBase<T>::draw_procedural(GPUPrimType primitive,
uint instance_len, uint instance_len,
uint vertex_len, uint vertex_len,
uint vertex_first, uint vertex_first,
ResourceHandle handle) ResourceHandle handle,
uint custom_id)
{ {
this->draw(procedural_batch_get(primitive), instance_len, vertex_len, vertex_first, handle); this->draw(
procedural_batch_get(primitive), instance_len, vertex_len, vertex_first, handle, custom_id);
} }
/** \} */ /** \} */

View File

@ -108,7 +108,14 @@ void main()
uint view_index = i * 32u; uint view_index = i * 32u;
while (word != 0u) { while (word != 0u) {
if ((word & 1u) != 0u) { if ((word & 1u) != 0u) {
resource_id_buf[dst_index++] = view_index | (resource_index << view_shift); if (use_custom_ids) {
resource_id_buf[dst_index * 2] = view_index | (resource_index << view_shift);
resource_id_buf[dst_index * 2 + 1] = proto.custom_id;
}
else {
resource_id_buf[dst_index] = view_index | (resource_index << view_shift);
}
dst_index++;
} }
view_index++; view_index++;
word >>= 1u; word >>= 1u;
@ -117,7 +124,13 @@ void main()
} }
else { else {
for (uint i = dst_index; i < dst_index + visible_instance_len; i++) { for (uint i = dst_index; i < dst_index + visible_instance_len; i++) {
resource_id_buf[i] = resource_index; if (use_custom_ids) {
resource_id_buf[i * 2] = resource_index;
resource_id_buf[i * 2 + 1] = proto.custom_id;
}
else {
resource_id_buf[i] = resource_index;
}
} }
} }
} }

View File

@ -189,6 +189,7 @@ GPU_SHADER_CREATE_INFO(draw_command_generate)
.push_constant(Type::INT, "prototype_len") .push_constant(Type::INT, "prototype_len")
.push_constant(Type::INT, "visibility_word_per_draw") .push_constant(Type::INT, "visibility_word_per_draw")
.push_constant(Type::INT, "view_shift") .push_constant(Type::INT, "view_shift")
.push_constant(Type::BOOL, "use_custom_ids")
.compute_source("draw_command_generate_comp.glsl"); .compute_source("draw_command_generate_comp.glsl");
/** \} */ /** \} */
@ -200,9 +201,18 @@ GPU_SHADER_CREATE_INFO(draw_command_generate)
GPU_SHADER_CREATE_INFO(draw_resource_id_new) GPU_SHADER_CREATE_INFO(draw_resource_id_new)
.define("UNIFORM_RESOURCE_ID_NEW") .define("UNIFORM_RESOURCE_ID_NEW")
/* TODO (Miguel Pozo): This is an int for compatibility.
* It should become uint once the "Next" ports are complete. */
.storage_buf(DRW_RESOURCE_ID_SLOT, Qualifier::READ, "int", "resource_id_buf[]") .storage_buf(DRW_RESOURCE_ID_SLOT, Qualifier::READ, "int", "resource_id_buf[]")
.define("drw_ResourceID", "resource_id_buf[gpu_BaseInstance + gl_InstanceID]"); .define("drw_ResourceID", "resource_id_buf[gpu_BaseInstance + gl_InstanceID]");
GPU_SHADER_CREATE_INFO(draw_resource_with_custom_id_new)
.define("UNIFORM_RESOURCE_ID_NEW")
.define("WITH_CUSTOM_IDS")
.storage_buf(DRW_RESOURCE_ID_SLOT, Qualifier::READ, "int2", "resource_id_buf[]")
.define("drw_ResourceID", "resource_id_buf[gpu_BaseInstance + gl_InstanceID].x")
.define("drw_CustomID", "resource_id_buf[gpu_BaseInstance + gl_InstanceID].y");
pragma37 marked this conversation as resolved

It isn't uint2 because of compatibility with older code. This should become a TODO.

It isn't `uint2` because of compatibility with older code. This should become a TODO.
/** /**
* Workaround the lack of gl_BaseInstance by binding the resource_id_buf as vertex buf. * Workaround the lack of gl_BaseInstance by binding the resource_id_buf as vertex buf.
*/ */
@ -210,6 +220,13 @@ GPU_SHADER_CREATE_INFO(draw_resource_id_fallback)
.define("UNIFORM_RESOURCE_ID_NEW") .define("UNIFORM_RESOURCE_ID_NEW")
.vertex_in(15, Type::INT, "drw_ResourceID"); .vertex_in(15, Type::INT, "drw_ResourceID");
pragma37 marked this conversation as resolved

Rename draw_resource_and_custom_id to draw_resource_with_custom_id.

Rename `draw_resource_and_custom_id` to `draw_resource_with_custom_id`.
GPU_SHADER_CREATE_INFO(draw_resource_with_custom_id_fallback)
.define("UNIFORM_RESOURCE_ID_NEW")
.define("WITH_CUSTOM_IDS")
.vertex_in(15, Type::IVEC2, "vertex_in_drw_ResourceID")
.define("drw_ResourceID", "vertex_in_drw_ResourceID.x")
.define("drw_CustomID", "vertex_in_drw_ResourceID.y");
/** TODO mask view id bits. */ /** TODO mask view id bits. */
GPU_SHADER_CREATE_INFO(draw_resource_handle_new).define("resource_handle", "drw_ResourceID"); GPU_SHADER_CREATE_INFO(draw_resource_handle_new).define("resource_handle", "drw_ResourceID");
@ -219,14 +236,19 @@ GPU_SHADER_CREATE_INFO(draw_resource_handle_new).define("resource_handle", "drw_
/** \name Draw Object Resources /** \name Draw Object Resources
* \{ */ * \{ */
pragma37 marked this conversation as resolved

Remove the _ suffix here.

Remove the `_` suffix here.
GPU_SHADER_CREATE_INFO(draw_modelmat_new) GPU_SHADER_CREATE_INFO(draw_modelmat_new_common)
.typedef_source("draw_shader_shared.h") .typedef_source("draw_shader_shared.h")
.storage_buf(DRW_OBJ_MAT_SLOT, Qualifier::READ, "ObjectMatrices", "drw_matrix_buf[]") .storage_buf(DRW_OBJ_MAT_SLOT, Qualifier::READ, "ObjectMatrices", "drw_matrix_buf[]")
.define("drw_ModelMatrixInverse", "drw_matrix_buf[resource_id].model_inverse") .define("drw_ModelMatrixInverse", "drw_matrix_buf[resource_id].model_inverse")
.define("drw_ModelMatrix", "drw_matrix_buf[resource_id].model") .define("drw_ModelMatrix", "drw_matrix_buf[resource_id].model")
/* TODO For compatibility with old shaders. To be removed. */ /* TODO For compatibility with old shaders. To be removed. */
.define("ModelMatrixInverse", "drw_ModelMatrixInverse") .define("ModelMatrixInverse", "drw_ModelMatrixInverse")
.define("ModelMatrix", "drw_ModelMatrix") .define("ModelMatrix", "drw_ModelMatrix");
.additional_info("draw_resource_id_new");
GPU_SHADER_CREATE_INFO(draw_modelmat_new)
.additional_info("draw_modelmat_new_common", "draw_resource_id_new");
GPU_SHADER_CREATE_INFO(draw_modelmat_new_with_custom_id)
.additional_info("draw_modelmat_new_common", "draw_resource_with_custom_id_new");
/** \} */ /** \} */

View File

@ -317,6 +317,7 @@ void gpu_shader_create_info_init()
/* WORKAROUND: Replace the use of gpu_BaseInstance by an instance attribute. */ /* WORKAROUND: Replace the use of gpu_BaseInstance by an instance attribute. */
if (GPU_shader_draw_parameters_support() == false) { if (GPU_shader_draw_parameters_support() == false) {
draw_resource_id_new = draw_resource_id_fallback; draw_resource_id_new = draw_resource_id_fallback;
draw_resource_with_custom_id_new = draw_resource_with_custom_id_fallback;
} }
#ifdef WITH_METAL_BACKEND #ifdef WITH_METAL_BACKEND

View File

@ -121,12 +121,18 @@ void GLVertArray::update_bindings(const GLuint vao,
if (batch->resource_id_buf) { if (batch->resource_id_buf) {
const ShaderInput *input = interface->attr_get("drw_ResourceID"); const ShaderInput *input = interface->attr_get("drw_ResourceID");
int component_len = 1;
pragma37 marked this conversation as resolved

Use comp_len or component_len.
size is generally reserved for size in bytes use _len suffix for the rest.
Try to avoid calling variable just len or size. They are always size of length of something.

Use `comp_len` or `component_len`. `size` is generally reserved for size in bytes use `_len` suffix for the rest. Try to avoid calling variable just `len` or `size`. They are always size of length of something.
if (input == nullptr) {
/* Uses Custom IDs */
input = interface->attr_get("vertex_in_drw_ResourceID_");
component_len = 2;
}
if (input) { if (input) {
dynamic_cast<GLStorageBuf *>(unwrap(batch->resource_id_buf))->bind_as(GL_ARRAY_BUFFER); dynamic_cast<GLStorageBuf *>(unwrap(batch->resource_id_buf))->bind_as(GL_ARRAY_BUFFER);
glEnableVertexAttribArray(input->location); glEnableVertexAttribArray(input->location);
glVertexAttribDivisor(input->location, 1); glVertexAttribDivisor(input->location, 1);
glVertexAttribIPointer( glVertexAttribIPointer(
input->location, 1, to_gl(GPU_COMP_I32), sizeof(uint32_t), (GLvoid *)nullptr); input->location, component_len, to_gl(GPU_COMP_I32), 0, (GLvoid *)nullptr);
attr_mask &= ~(1 << input->location); attr_mask &= ~(1 << input->location);
} }
} }