WIP: Draw: Sub Handles #105175

Closed
Miguel Pozo wants to merge 5 commits from pragma37/blender:pull-thin-handles-2 into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
6 changed files with 25 additions and 13 deletions
Showing only changes of commit dfad92c464 - Show all commits

View File

@ -126,13 +126,15 @@ GPU_SHADER_CREATE_INFO(workbench_next_prepass)
GPU_SHADER_CREATE_INFO(workbench_color_material)
.define("WORKBENCH_COLOR_MATERIAL")
.storage_buf(WB_MATERIAL_SLOT, Qualifier::READ, "vec4", "materials_data[]");
.storage_buf(WB_MATERIAL_SLOT, Qualifier::READ, "vec4", "materials_data[]")
.storage_buf(WB_MATERIAL_START_SLOT, Qualifier::READ, "uint", "material_start_indices[]");
GPU_SHADER_CREATE_INFO(workbench_color_texture)
.define("WORKBENCH_COLOR_TEXTURE")
.define("WORKBENCH_TEXTURE_IMAGE_ARRAY")
.define("WORKBENCH_COLOR_MATERIAL")
.storage_buf(WB_MATERIAL_SLOT, Qualifier::READ, "vec4", "materials_data[]")
.storage_buf(WB_MATERIAL_START_SLOT, Qualifier::READ, "uint", "material_start_indices[]")
.sampler(1, ImageType::FLOAT_2D, "imageTexture", Frequency::BATCH)
.sampler(2, ImageType::FLOAT_2D_ARRAY, "imageTileArray", Frequency::BATCH)
.sampler(3, ImageType::FLOAT_1D_ARRAY, "imageTileData", Frequency::BATCH)

View File

@ -17,7 +17,8 @@ void workbench_material_data_get(int handle,
#else
# ifdef WORKBENCH_COLOR_MATERIAL
vec4 data = materials_data[handle];
uint index = material_start_indices[resource_id] + sub_resource_id;
vec4 data = materials_data[index];
# else
vec4 data = vec4(0.0);
# endif

View File

@ -1,10 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* TEXTURE SLOTS */
#define WB_MATCAP_SLOT 0
#define WB_TEXTURE_SLOT 1
#define WB_TILE_ARRAY_SLOT 2
#define WB_TILE_DATA_SLOT 3
#define WB_MATERIAL_SLOT 0
/* UBO SLOTS */
#define WB_WORLD_SLOT 4
/* SSBO SLOTS */
#define WB_MATERIAL_SLOT 0
#define WB_MATERIAL_START_SLOT 1
#define WB_RESOLVE_GROUP_SIZE 8

View File

@ -38,6 +38,8 @@ class Instance {
DofPass dof_ps;
AntiAliasingPass anti_aliasing_ps;
uint material_count = 0;
/* An array of nullptr GPUMaterial pointers so we can call DRW_cache_object_surface_material_get.
* They never get actually used. */
Vector<GPUMaterial *> dummy_gpu_materials = {1, nullptr, {}};
@ -68,6 +70,7 @@ class Instance {
resolution,
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW);
material_count = 0;
opaque_ps.sync(scene_state, resources);
transparent_ps.sync(scene_state, resources);
@ -82,6 +85,7 @@ class Instance {
void end_sync()
{
resources.material_buf.push_update();
resources.per_obj_material_start_buf.push_update();
}
void object_sync(Manager &manager, ObjectRef &ob_ref)
@ -177,6 +181,7 @@ class Instance {
void mesh_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
{
ResourceHandle handle = manager.resource_handle(ob_ref);
resources.per_obj_material_start_buf.get_or_resize(handle.resource_index()) = material_count;
bool has_transparent_material = false;
if (object_state.sculpt_pbvh) {
@ -186,7 +191,7 @@ class Instance {
}
else {
if (object_state.use_per_material_batches) {
const int material_count = DRW_cache_object_material_count_get(ob_ref.object);
const int slot_count = DRW_cache_object_material_count_get(ob_ref.object);
struct GPUBatch **batches;
if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
@ -194,20 +199,18 @@ class Instance {
}
else {
batches = DRW_cache_object_surface_material_get(
ob_ref.object, get_dummy_gpu_materials(material_count), material_count);
ob_ref.object, get_dummy_gpu_materials(slot_count), slot_count);
}
if (batches) {
for (auto i : IndexRange(material_count)) {
for (auto i : IndexRange(slot_count)) {
if (batches[i] == nullptr) {
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);
ResourceHandle _handle = handle;
_handle.sub_index = i;
Material &mat = resources.material_buf.get_or_resize(_handle.resource_index());
Material &mat = resources.material_buf.get_or_resize(material_count++);
if (::Material *_mat = BKE_object_material_get_eval(ob_ref.object, i + 1)) {
mat = Material(*_mat);
@ -247,7 +250,7 @@ class Instance {
}
if (batch) {
Material &mat = resources.material_buf.get_or_resize(handle.resource_index());
Material &mat = resources.material_buf.get_or_resize(material_count++);
if (object_state.color_type == V3D_SHADING_OBJECT_COLOR) {
mat = Material(*ob_ref.object);

View File

@ -22,8 +22,9 @@ void MeshPass::init_pass(SceneResources &resources, DRWState state, int clip_pla
PassMain::init();
state_set(state, clip_planes);
bind_texture(WB_MATCAP_SLOT, resources.matcap_tx);
bind_ssbo(WB_MATERIAL_SLOT, &resources.material_buf);
bind_ubo(WB_WORLD_SLOT, resources.world_buf);
bind_ssbo(WB_MATERIAL_SLOT, &resources.material_buf);
bind_ssbo(WB_MATERIAL_START_SLOT, &resources.per_obj_material_start_buf);
if (clip_planes > 0) {
bind_ubo(DRW_CLIPPING_UBO_SLOT, resources.clip_planes_buf);
}

View File

@ -148,6 +148,7 @@ struct SceneResources {
TextureFromPool depth_in_front_tx = "wb_depth_in_front_tx";
StorageVectorBuffer<Material> material_buf = {"material_buf"};
StorageVectorBuffer<uint> per_obj_material_start_buf = {"per_obj_material_start_buf"};
UniformBuffer<WorldData> world_buf = {};
UniformArrayBuffer<float4, 6> clip_planes_buf;