summaryrefslogtreecommitdiffstats
path: root/src/amd/vulkan
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2017-04-18 10:21:59 +1000
committerDave Airlie <[email protected]>2017-04-19 09:00:43 +1000
commit25a5ee391d786b6d0b48b2b9aa0553e6972d97a0 (patch)
treeef9eb964cbe1f7768e0d8d52fe44234e2dabffbd /src/amd/vulkan
parentd0991b135b90b5ce90da51b6d4db7302ddd65a24 (diff)
radv/ac: add support for indirect access of descriptor sets.
We want to expose more descriptor sets to the applications, but currently we have a 1:1 mapping between shader descriptor sets and 2 user sgprs, limiting us to 4 per stage. This commit check if we don't have enough user sgprs for the number of bound sets for this shader, we can ask for them to be indirected. Two sgprs are then used to point to a buffer or 64-bit pointers to the number of allocated descriptor sets. All shaders point to the same buffer. We can use some user sgprs to inline one or two descriptor sets in future, but until we have a workload that needs this I don't think we should spend too much time on it. Reviewed-by: Bas Nieuwenhuizen <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/amd/vulkan')
-rw-r--r--src/amd/vulkan/radv_cmd_buffer.c57
-rw-r--r--src/amd/vulkan/radv_pipeline.c7
-rw-r--r--src/amd/vulkan/radv_private.h2
3 files changed, 64 insertions, 2 deletions
diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 7056d0d0266..d95daff2c79 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -1246,7 +1246,7 @@ emit_stage_descriptor_set_userdata(struct radv_cmd_buffer *cmd_buffer,
struct ac_userdata_info *desc_set_loc = &pipeline->shaders[stage]->info.user_sgprs_locs.descriptor_sets[idx];
uint32_t base_reg = shader_stage_to_user_data_0(stage, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
- if (desc_set_loc->sgpr_idx == -1)
+ if (desc_set_loc->sgpr_idx == -1 || desc_set_loc->indirect)
return;
assert(!desc_set_loc->indirect);
@@ -1314,17 +1314,72 @@ radv_flush_push_descriptors(struct radv_cmd_buffer *cmd_buffer)
}
static void
+radv_flush_indirect_descriptor_sets(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_pipeline *pipeline)
+{
+ uint32_t size = MAX_SETS * 2 * 4;
+ uint32_t offset;
+ void *ptr;
+
+ if (!radv_cmd_buffer_upload_alloc(cmd_buffer, size,
+ 256, &offset, &ptr))
+ return;
+
+ for (unsigned i = 0; i < MAX_SETS; i++) {
+ uint32_t *uptr = ((uint32_t *)ptr) + i * 2;
+ uint64_t set_va = 0;
+ struct radv_descriptor_set *set = cmd_buffer->state.descriptors[i];
+ if (set)
+ set_va = set->va;
+ uptr[0] = set_va & 0xffffffff;
+ uptr[1] = set_va >> 32;
+ }
+
+ uint64_t va = cmd_buffer->device->ws->buffer_get_va(cmd_buffer->upload.upload_bo);
+ va += offset;
+
+ if (pipeline->shaders[MESA_SHADER_VERTEX])
+ radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_VERTEX,
+ AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
+
+ if (pipeline->shaders[MESA_SHADER_FRAGMENT])
+ radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_FRAGMENT,
+ AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
+
+ if (radv_pipeline_has_gs(pipeline))
+ radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_GEOMETRY,
+ AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
+
+ if (radv_pipeline_has_tess(pipeline))
+ radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_TESS_CTRL,
+ AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
+
+ if (radv_pipeline_has_tess(pipeline))
+ radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_TESS_EVAL,
+ AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
+
+ if (pipeline->shaders[MESA_SHADER_COMPUTE])
+ radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_COMPUTE,
+ AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
+}
+
+static void
radv_flush_descriptors(struct radv_cmd_buffer *cmd_buffer,
struct radv_pipeline *pipeline,
VkShaderStageFlags stages)
{
unsigned i;
+
if (!cmd_buffer->state.descriptors_dirty)
return;
if (cmd_buffer->state.push_descriptors_dirty)
radv_flush_push_descriptors(cmd_buffer);
+ if (pipeline->need_indirect_descriptor_sets) {
+ radv_flush_indirect_descriptor_sets(cmd_buffer, pipeline);
+ }
+
for (i = 0; i < MAX_SETS; i++) {
if (!(cmd_buffer->state.descriptors_dirty & (1 << i)))
continue;
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index cf11362eade..8e71d59fae7 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -2112,6 +2112,12 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
calculate_pa_cl_vs_out_cntl(pipeline);
calculate_ps_inputs(pipeline);
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (pipeline->shaders[i]) {
+ pipeline->need_indirect_descriptor_sets |= pipeline->shaders[i]->info.need_indirect_descriptor_sets;
+ }
+ }
+
uint32_t stages = 0;
if (radv_pipeline_has_tess(pipeline)) {
stages |= S_028B54_LS_EN(V_028B54_LS_STAGE_ON) |
@@ -2270,6 +2276,7 @@ static VkResult radv_compute_pipeline_create(
pipeline->layout, NULL);
+ pipeline->need_indirect_descriptor_sets |= pipeline->shaders[MESA_SHADER_COMPUTE]->info.need_indirect_descriptor_sets;
result = radv_pipeline_scratch_init(device, pipeline);
if (result != VK_SUCCESS) {
radv_pipeline_destroy(device, pipeline, pAllocator);
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 4ace068742d..0d60aac1069 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1007,7 +1007,7 @@ struct radv_pipeline {
struct radv_pipeline_layout * layout;
bool needs_data_cache;
-
+ bool need_indirect_descriptor_sets;
struct radv_shader_variant * shaders[MESA_SHADER_STAGES];
struct radv_shader_variant *gs_copy_shader;
VkShaderStageFlags active_stages;