v3dv/descriptor: support for dynamic ubo/ssbo

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Alejandro Piñeiro
2020-02-24 11:32:57 +01:00
committed by Marge Bot
parent 404220cc71
commit 5d1089b88d
5 changed files with 92 additions and 8 deletions
+14 -2
View File
@@ -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;
+23
View File
@@ -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;
+4 -3
View File
@@ -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];
+15
View File
@@ -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;
+36 -3
View File
@@ -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;
}