Skip to content

Commit

Permalink
Switch to Uniform buffers. This more than triples performance on Adre…
Browse files Browse the repository at this point in the history
…no 640
  • Loading branch information
clayjohn committed Dec 4, 2024
1 parent e9a478e commit 3c3a524
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 18 deletions.
22 changes: 21 additions & 1 deletion drivers/vulkan/rendering_device_driver_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3571,6 +3571,9 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
} break;
case UNIFORM_TYPE_UNIFORM_BUFFER: {
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
if ((layout_binding.binding == 4 && i == 3) || (layout_binding.binding == 1 && i == 1)) {
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
}
} break;
case UNIFORM_TYPE_STORAGE_BUFFER: {
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
Expand Down Expand Up @@ -3866,6 +3869,13 @@ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_creat
curr_vk_size++;
vk_sizes_count++;
}
if (p_key.uniform_type[UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC]) {
*curr_vk_size = {};
curr_vk_size->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
curr_vk_size->descriptorCount = p_key.uniform_type[UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC] * max_descriptor_sets_per_pool;
curr_vk_size++;
vk_sizes_count++;
}
DEV_ASSERT(vk_sizes_count <= UNIFORM_TYPE_MAX);
}

Expand Down Expand Up @@ -4056,11 +4066,21 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView<Bou
VkDescriptorBufferInfo *vk_buf_info = ALLOCA_SINGLE(VkDescriptorBufferInfo);
*vk_buf_info = {};
vk_buf_info->buffer = buf_info->vk_buffer;
vk_buf_info->range = 176;
vk_buf_info->range = 128;

vk_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
vk_writes[i].pBufferInfo = vk_buf_info;
} break;
case UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC: {
const BufferInfo *buf_info = (const BufferInfo *)uniform.ids[0].id;
VkDescriptorBufferInfo *vk_buf_info = ALLOCA_SINGLE(VkDescriptorBufferInfo);
*vk_buf_info = {};
vk_buf_info->buffer = buf_info->vk_buffer;
vk_buf_info->range = 128;

vk_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
vk_writes[i].pBufferInfo = vk_buf_info;
} break;
default: {
DEV_ASSERT(false);
}
Expand Down
30 changes: 17 additions & 13 deletions servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1670,8 +1670,9 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
state.max_lights_per_render = 64;
global_defines += "#define MAX_LIGHTS 64\n";
} else {
state.max_lights_per_render = DEFAULT_MAX_LIGHTS_PER_RENDER;
global_defines += "#define MAX_LIGHTS " + itos(DEFAULT_MAX_LIGHTS_PER_RENDER) + "\n";
state.max_lights_per_render = 64;
global_defines += "#define MAX_LIGHTS " + itos(64) + "\n";
WARN_PRINT("USING DESKTOP FOCUSED CODE");
}

global_defines += "\n#define SAMPLERS_BINDING_FIRST_INDEX " + itos(SAMPLERS_BINDING_FIRST_INDEX) + "\n";
Expand Down Expand Up @@ -1992,13 +1993,13 @@ void fragment() {
}

{
state.max_instances_per_buffer = uint32_t(GLOBAL_GET("rendering/2d/batching/item_buffer_size"));
state.max_instances_per_buffer = 64; //uint32_t(GLOBAL_GET("rendering/2d/batching/item_buffer_size"));
state.max_instance_buffer_size = state.max_instances_per_buffer * sizeof(InstanceData);
state.canvas_instance_batches.reserve(200);

for (uint32_t i = 0; i < BATCH_DATA_BUFFER_COUNT; i++) {
DataBuffer &db = state.canvas_instance_data_buffers[i];
db.instance_buffers.push_back(RD::get_singleton()->storage_buffer_create(state.max_instance_buffer_size));
db.instance_buffers.push_back(RD::get_singleton()->uniform_buffer_create(state.max_instance_buffer_size));
}
state.instance_data_array = memnew_arr(InstanceData, state.max_instances_per_buffer);
}
Expand Down Expand Up @@ -2915,7 +2916,7 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, CanvasSha
state.batch_texture_uniforms.write[1] = RD::Uniform(RD::UNIFORM_TYPE_TEXTURE, 1, p_batch->tex_info->normal);
state.batch_texture_uniforms.write[2] = RD::Uniform(RD::UNIFORM_TYPE_TEXTURE, 2, p_batch->tex_info->specular);
state.batch_texture_uniforms.write[3] = RD::Uniform(RD::UNIFORM_TYPE_SAMPLER, 3, p_batch->tex_info->sampler);
state.batch_texture_uniforms.write[4] = RD::Uniform(RD::UNIFORM_TYPE_STORAGE_BUFFER_DYNAMIC, 4, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]);
state.batch_texture_uniforms.write[4] = RD::Uniform(RD::UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC, 4, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]);

RID rid = RD::get_singleton()->uniform_set_create(state.batch_texture_uniforms, shader.default_version_rd_shader, BATCH_UNIFORM_SET);
ERR_FAIL_COND_MSG(rid.is_null(), "Failed to create uniform set for batch.");
Expand All @@ -2925,13 +2926,13 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, CanvasSha
RD::get_singleton()->uniform_set_set_invalidation_callback(rid, RendererCanvasRenderRD::_uniform_set_invalidation_callback, (void *)&iter->key);
}

if (state.current_batch_uniform_set != *uniform_set) {
Vector<uint32_t> offsets;
offsets.resize_zeroed(1);
offsets.write[0] = p_batch->start * sizeof(InstanceData);
state.current_batch_uniform_set = *uniform_set;
RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, *uniform_set, BATCH_UNIFORM_SET, offsets);
}
//if (state.current_batch_uniform_set != *uniform_set) {
Vector<uint32_t> offsets;
offsets.resize_zeroed(1);
offsets.write[0] = p_batch->start * sizeof(InstanceData);
state.current_batch_uniform_set = *uniform_set;
RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, *uniform_set, BATCH_UNIFORM_SET, offsets);
//}
}
PushConstant push_constant;
push_constant.base_instance_index = 0;
Expand Down Expand Up @@ -3143,6 +3144,9 @@ void RendererCanvasRenderRD::_add_to_batch(uint32_t &r_index, bool &r_batch_brok
r_batch_broken = false; // Force a new batch to be created
r_current_batch = _new_batch(r_batch_broken);
r_current_batch->start = 0;
} else {
r_batch_broken = false; // Force a new batch to be created
r_current_batch = _new_batch(r_batch_broken);
}
}

Expand All @@ -3155,7 +3159,7 @@ void RendererCanvasRenderRD::_allocate_instance_buffer() {
}

// Allocate a new buffer.
RID buf = RD::get_singleton()->storage_buffer_create(state.max_instance_buffer_size);
RID buf = RD::get_singleton()->uniform_buffer_create(state.max_instance_buffer_size);
state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.push_back(buf);
}

Expand Down
2 changes: 1 addition & 1 deletion servers/rendering/renderer_rd/shaders/canvas.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void main() {
#ifdef USE_ATTRIBUTES
uint instance_index = 0;
#else
uint instance_index = gl_InstanceIndex;
uint instance_index = 0;
instance_index_interp = instance_index;
#endif // USE_ATTRIBUTES
const InstanceData draw_data = instances.data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ struct InstanceData {

#endif
vec2 color_texture_pixel_size;
uint lights[4];
uvec4 lights;
};

//1 means enabled, 2+ means trails in use
Expand Down Expand Up @@ -181,7 +181,7 @@ layout(set = 3, binding = 1) uniform texture2D normal_texture;
layout(set = 3, binding = 2) uniform texture2D specular_texture;
layout(set = 3, binding = 3) uniform sampler texture_sampler;

layout(set = 3, binding = 4, std430) restrict readonly buffer DrawData {
layout(set = 3, binding = 4, std140) uniform DrawData {
InstanceData data;
}
instances;
1 change: 1 addition & 0 deletions servers/rendering/rendering_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3331,6 +3331,7 @@ RID RenderingDevice::uniform_set_create(const Vector<Uniform> &p_uniforms, RID p
case UNIFORM_TYPE_IMAGE_BUFFER: {
// Todo.
} break;
case UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC:
case UNIFORM_TYPE_UNIFORM_BUFFER: {
ERR_FAIL_COND_V_MSG(uniform.get_id_count() != 1, RID(),
"Uniform buffer supplied (binding: " + itos(uniform.binding) + ") must provide one ID (" + itos(uniform.get_id_count()) + " provided).");
Expand Down
1 change: 1 addition & 0 deletions servers/rendering/rendering_device_commons.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ class RenderingDeviceCommons : public Object {
UNIFORM_TYPE_STORAGE_BUFFER, // Storage buffer ("buffer" qualifier) like UBO, but supports storage, for compute mostly.
UNIFORM_TYPE_INPUT_ATTACHMENT, // Used for sub-pass read/write, for mobile mostly.
UNIFORM_TYPE_STORAGE_BUFFER_DYNAMIC,
UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC,
UNIFORM_TYPE_MAX
};

Expand Down
3 changes: 2 additions & 1 deletion servers/rendering/rendering_device_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ Error RenderingDeviceDriver::_reflect_spirv(VectorView<ShaderStageSPIRVData> p_s
may_be_writable = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
ERR_PRINT("Dynamic uniform buffer not supported.");
uniform.type = UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC;
need_block_size = true;
continue;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
Expand Down

0 comments on commit 3c3a524

Please sign in to comment.