v3dv/descriptor: support for dynamic ubo/ssbo
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
committed by
Marge Bot
parent
404220cc71
commit
5d1089b88d
@@ -2346,16 +2346,28 @@ v3dv_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
|
||||
const uint32_t *pDynamicOffsets)
|
||||
{
|
||||
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
V3DV_FROM_HANDLE(v3dv_pipeline_layout, layout, _layout);
|
||||
|
||||
uint32_t dyn_index = 0;
|
||||
|
||||
assert(pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||
assert(firstSet + descriptorSetCount <= MAX_SETS);
|
||||
|
||||
struct v3dv_descriptor_state *descriptor_state =
|
||||
&cmd_buffer->state.descriptor_state;
|
||||
|
||||
for (uint32_t i = 0; i < descriptorSetCount; i++) {
|
||||
V3DV_FROM_HANDLE(v3dv_descriptor_set, set, pDescriptorSets[i]);
|
||||
uint32_t index = firstSet + i;
|
||||
|
||||
cmd_buffer->state.descriptor_state.descriptor_sets[index] = set;
|
||||
cmd_buffer->state.descriptor_state.valid |= (1u << index);
|
||||
descriptor_state->descriptor_sets[index] = set;
|
||||
descriptor_state->valid |= (1u << index);
|
||||
|
||||
for (uint32_t j = 0; j < set->layout->dynamic_offset_count; j++, dyn_index++) {
|
||||
uint32_t idx = j + layout->set[i + firstSet].dynamic_offset_start;
|
||||
|
||||
descriptor_state->dynamic_offsets[idx] = pDynamicOffsets[dyn_index];
|
||||
}
|
||||
}
|
||||
|
||||
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_DESCRIPTOR_SETS;
|
||||
|
||||
@@ -51,12 +51,21 @@ v3dv_CreatePipelineLayout(VkDevice _device,
|
||||
|
||||
layout->num_sets = pCreateInfo->setLayoutCount;
|
||||
|
||||
uint32_t dynamic_offset_count = 0;
|
||||
for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) {
|
||||
V3DV_FROM_HANDLE(v3dv_descriptor_set_layout, set_layout,
|
||||
pCreateInfo->pSetLayouts[set]);
|
||||
layout->set[set].layout = set_layout;
|
||||
|
||||
layout->set[set].dynamic_offset_start = dynamic_offset_count;
|
||||
for (uint32_t b = 0; b < set_layout->binding_count; b++) {
|
||||
dynamic_offset_count += set_layout->binding[b].array_size *
|
||||
set_layout->binding[b].dynamic_offset_count;
|
||||
}
|
||||
}
|
||||
|
||||
layout->dynamic_offset_count = dynamic_offset_count;
|
||||
|
||||
*pPipelineLayout = v3dv_pipeline_layout_to_handle(layout);
|
||||
|
||||
return VK_SUCCESS;
|
||||
@@ -94,6 +103,9 @@ v3dv_CreateDescriptorPool(VkDevice _device,
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||
break;
|
||||
default:
|
||||
unreachable("Unimplemented descriptor type");
|
||||
break;
|
||||
@@ -264,6 +276,7 @@ v3dv_CreateDescriptorSetLayout(VkDevice _device,
|
||||
set_layout->shader_stages = 0;
|
||||
|
||||
uint32_t descriptor_count = 0;
|
||||
uint32_t dynamic_offset_count = 0;
|
||||
|
||||
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
|
||||
const VkDescriptorSetLayoutBinding *binding = bindings + i;
|
||||
@@ -273,6 +286,10 @@ v3dv_CreateDescriptorSetLayout(VkDevice _device,
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||
set_layout->binding[binding_number].dynamic_offset_count = 1;
|
||||
break;
|
||||
default:
|
||||
unreachable("Unknown descriptor type\n");
|
||||
break;
|
||||
@@ -281,8 +298,11 @@ v3dv_CreateDescriptorSetLayout(VkDevice _device,
|
||||
set_layout->binding[binding_number].type = binding->descriptorType;
|
||||
set_layout->binding[binding_number].array_size = binding->descriptorCount;
|
||||
set_layout->binding[binding_number].descriptor_index = descriptor_count;
|
||||
set_layout->binding[binding_number].dynamic_offset_index = dynamic_offset_count;
|
||||
|
||||
descriptor_count += binding->descriptorCount;
|
||||
dynamic_offset_count += binding->descriptorCount *
|
||||
set_layout->binding[binding_number].dynamic_offset_count;
|
||||
|
||||
/* FIXME: right now we don't use shader_stages. We could explore if we
|
||||
* could use it to add another filter to upload or allocate the
|
||||
@@ -294,6 +314,7 @@ v3dv_CreateDescriptorSetLayout(VkDevice _device,
|
||||
vk_free2(&device->alloc, pAllocator, bindings);
|
||||
|
||||
set_layout->descriptor_count = descriptor_count;
|
||||
set_layout->dynamic_offset_count = dynamic_offset_count;
|
||||
|
||||
*pSetLayout = v3dv_descriptor_set_layout_to_handle(set_layout);
|
||||
|
||||
@@ -435,6 +456,8 @@ v3dv_UpdateDescriptorSets(VkDevice _device,
|
||||
|
||||
switch(writeset->descriptorType) {
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
|
||||
const VkDescriptorBufferInfo *buffer_info = writeset->pBufferInfo + j;
|
||||
|
||||
@@ -975,8 +975,6 @@ pipeline_compile_graphics(struct v3dv_pipeline *pipeline,
|
||||
next_stage = stages[stage];
|
||||
}
|
||||
|
||||
V3DV_FROM_HANDLE(v3dv_pipeline_layout, layout, pCreateInfo->layout);
|
||||
|
||||
/* Compiling to vir */
|
||||
for (int stage = MESA_SHADER_STAGES - 1; stage >= 0; stage--) {
|
||||
if (stages[stage] == NULL || stages[stage]->entrypoint == NULL)
|
||||
@@ -984,7 +982,7 @@ pipeline_compile_graphics(struct v3dv_pipeline *pipeline,
|
||||
|
||||
struct v3dv_pipeline_stage *p_stage = stages[stage];
|
||||
|
||||
pipeline_lower_nir(pipeline, p_stage, layout);
|
||||
pipeline_lower_nir(pipeline, p_stage, pipeline->layout);
|
||||
|
||||
switch(stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
@@ -1608,6 +1606,9 @@ pipeline_init(struct v3dv_pipeline *pipeline,
|
||||
|
||||
pipeline->device = device;
|
||||
|
||||
V3DV_FROM_HANDLE(v3dv_pipeline_layout, layout, pCreateInfo->layout);
|
||||
pipeline->layout = layout;
|
||||
|
||||
V3DV_FROM_HANDLE(v3dv_render_pass, render_pass, pCreateInfo->renderPass);
|
||||
assert(pCreateInfo->subpass < render_pass->subpass_count);
|
||||
pipeline->subpass = &render_pass->subpasses[pCreateInfo->subpass];
|
||||
|
||||
@@ -123,6 +123,11 @@ pack_emit_reloc(void *cl, const void *reloc) {}
|
||||
|
||||
#define MAX_PUSH_CONSTANTS_SIZE 128
|
||||
|
||||
#define MAX_DYNAMIC_UNIFORM_BUFFERS 16
|
||||
#define MAX_DYNAMIC_STORAGE_BUFFERS 8
|
||||
#define MAX_DYNAMIC_BUFFERS \
|
||||
(MAX_DYNAMIC_UNIFORM_BUFFERS + MAX_DYNAMIC_STORAGE_BUFFERS)
|
||||
|
||||
struct v3dv_instance;
|
||||
|
||||
#ifdef USE_V3D_SIMULATOR
|
||||
@@ -574,6 +579,7 @@ struct v3dv_vertex_binding {
|
||||
struct v3dv_descriptor_state {
|
||||
struct v3dv_descriptor_set *descriptor_sets[MAX_SETS];
|
||||
uint32_t valid;
|
||||
uint32_t dynamic_offsets[MAX_DYNAMIC_BUFFERS];
|
||||
};
|
||||
|
||||
struct v3dv_cmd_buffer_state {
|
||||
@@ -772,6 +778,9 @@ struct v3dv_descriptor_set_binding_layout {
|
||||
uint32_t array_size;
|
||||
|
||||
uint32_t descriptor_index;
|
||||
|
||||
uint32_t dynamic_offset_count;
|
||||
uint32_t dynamic_offset_index;
|
||||
};
|
||||
|
||||
struct v3dv_descriptor_set_layout {
|
||||
@@ -786,6 +795,9 @@ struct v3dv_descriptor_set_layout {
|
||||
/* Number of descriptors in this descriptor set */
|
||||
uint32_t descriptor_count;
|
||||
|
||||
/* Number of dynamic offsets used by this descriptor set */
|
||||
uint16_t dynamic_offset_count;
|
||||
|
||||
/* Bindings in this descriptor set */
|
||||
struct v3dv_descriptor_set_binding_layout binding[0];
|
||||
};
|
||||
@@ -797,6 +809,7 @@ struct v3dv_pipeline_layout {
|
||||
} set[MAX_SETS];
|
||||
|
||||
uint32_t num_sets;
|
||||
uint32_t dynamic_offset_count;
|
||||
};
|
||||
|
||||
struct v3dv_descriptor_map {
|
||||
@@ -824,6 +837,8 @@ struct v3dv_pipeline {
|
||||
|
||||
struct v3dv_dynamic_state dynamic_state;
|
||||
|
||||
struct v3dv_pipeline_layout *layout;
|
||||
|
||||
enum v3dv_ez_state ez_state;
|
||||
|
||||
bool primitive_restart;
|
||||
|
||||
@@ -27,10 +27,31 @@
|
||||
|
||||
#include "v3dv_private.h"
|
||||
|
||||
static bool
|
||||
descriptor_type_is_dynamic(VkDescriptorType type)
|
||||
{
|
||||
switch (type) {
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
return false;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
assert(!"descriptor type not supported.\n");
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct v3dv_descriptor *
|
||||
get_descriptor(struct v3dv_descriptor_state *descriptor_state,
|
||||
struct v3dv_descriptor_map *map,
|
||||
uint32_t index)
|
||||
struct v3dv_pipeline_layout *pipeline_layout,
|
||||
uint32_t index,
|
||||
uint32_t *dynamic_offset)
|
||||
{
|
||||
assert(index >= 0 && index < map->num_desc);
|
||||
|
||||
@@ -50,6 +71,14 @@ get_descriptor(struct v3dv_descriptor_state *descriptor_state,
|
||||
uint32_t array_index = map->array_index[index];
|
||||
assert(array_index < binding_layout->array_size);
|
||||
|
||||
if (descriptor_type_is_dynamic(binding_layout->type)) {
|
||||
uint32_t dynamic_offset_index =
|
||||
pipeline_layout->set[set_number].dynamic_offset_start +
|
||||
binding_layout->dynamic_offset_index + array_index;
|
||||
|
||||
*dynamic_offset = descriptor_state->dynamic_offsets[dynamic_offset_index];
|
||||
}
|
||||
|
||||
return &set->descriptors[binding_layout->descriptor_index + array_index];
|
||||
}
|
||||
|
||||
@@ -172,6 +201,8 @@ v3dv_write_uniforms(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
v3d_unit_data_get_offset(data) :
|
||||
0; /* FIXME */
|
||||
|
||||
uint32_t dynamic_offset = 0;
|
||||
|
||||
/* For ubos, index is shifted, as 0 is reserved for push constants.
|
||||
*/
|
||||
struct v3dv_descriptor *descriptor = NULL;
|
||||
@@ -191,13 +222,15 @@ v3dv_write_uniforms(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
data;
|
||||
|
||||
descriptor =
|
||||
get_descriptor(descriptor_state, map, index);
|
||||
get_descriptor(descriptor_state, map,
|
||||
pipeline->layout,
|
||||
index, &dynamic_offset);
|
||||
assert(descriptor);
|
||||
}
|
||||
|
||||
cl_aligned_reloc(&job->indirect, &uniforms,
|
||||
descriptor->bo,
|
||||
descriptor->offset + offset);
|
||||
descriptor->offset + offset + dynamic_offset);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user