summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/amd/common/ac_nir_to_llvm.c52
-rw-r--r--src/amd/common/ac_nir_to_llvm.h5
-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
5 files changed, 105 insertions, 18 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 31c3a6c2240..540de62d594 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -537,7 +537,7 @@ static void set_userdata_location_shader(struct nir_to_llvm_context *ctx,
set_userdata_location(&ctx->shader_info->user_sgprs_locs.shader_data[idx], sgpr_idx, num_sgprs);
}
-#if 0
+
static void set_userdata_location_indirect(struct ac_userdata_info *ud_info, uint8_t sgpr_idx, uint8_t num_sgprs,
uint32_t indirect_offset)
{
@@ -546,7 +546,6 @@ static void set_userdata_location_indirect(struct ac_userdata_info *ud_info, uin
ud_info->indirect = true;
ud_info->indirect_offset = indirect_offset;
}
-#endif
static void declare_tess_lds(struct nir_to_llvm_context *ctx)
{
@@ -559,6 +558,7 @@ static void declare_tess_lds(struct nir_to_llvm_context *ctx)
struct user_sgpr_info {
bool need_ring_offsets;
uint8_t sgpr_count;
+ bool indirect_all_descriptor_sets;
};
static void allocate_user_sgprs(struct nir_to_llvm_context *ctx,
@@ -623,6 +623,8 @@ static void allocate_user_sgprs(struct nir_to_llvm_context *ctx,
fprintf(stderr, "radv: TODO: add support for indirect sgprs\n");
/* need to add support for indirect descriptor sets */
assert(0);
+ user_sgpr_info->sgpr_count += 2;
+ user_sgpr_info->indirect_all_descriptor_sets = true;
} else {
user_sgpr_info->sgpr_count += util_bitcount(ctx->shader_info->info.desc_set_used_mask) * 2;
}
@@ -645,11 +647,16 @@ static void create_function(struct nir_to_llvm_context *ctx)
}
/* 1 for each descriptor set */
- for (unsigned i = 0; i < num_sets; ++i) {
- if (ctx->options->layout->set[i].layout->shader_stages & (1 << ctx->stage)) {
- array_params_mask |= (1 << arg_idx);
- arg_types[arg_idx++] = const_array(ctx->i8, 1024 * 1024);
+ if (!user_sgpr_info.indirect_all_descriptor_sets) {
+ for (unsigned i = 0; i < num_sets; ++i) {
+ if (ctx->options->layout->set[i].layout->shader_stages & (1 << ctx->stage)) {
+ array_params_mask |= (1 << arg_idx);
+ arg_types[arg_idx++] = const_array(ctx->i8, 1024 * 1024);
+ }
}
+ } else {
+ array_params_mask |= (1 << arg_idx);
+ arg_types[arg_idx++] = const_array(const_array(ctx->i8, 1024 * 1024), 32);
}
if (ctx->shader_info->info.needs_push_constants) {
@@ -801,14 +808,31 @@ static void create_function(struct nir_to_llvm_context *ctx)
ctx->ring_offsets = LLVMGetParam(ctx->main_function, arg_idx++);
}
- for (unsigned i = 0; i < num_sets; ++i) {
- if (ctx->options->layout->set[i].layout->shader_stages & (1 << ctx->stage)) {
- set_userdata_location(&ctx->shader_info->user_sgprs_locs.descriptor_sets[i], user_sgpr_idx, 2);
- user_sgpr_idx += 2;
- ctx->descriptor_sets[i] =
- LLVMGetParam(ctx->main_function, arg_idx++);
- } else
- ctx->descriptor_sets[i] = NULL;
+ if (!user_sgpr_info.indirect_all_descriptor_sets) {
+ for (unsigned i = 0; i < num_sets; ++i) {
+ if (ctx->options->layout->set[i].layout->shader_stages & (1 << ctx->stage)) {
+ set_userdata_location(&ctx->shader_info->user_sgprs_locs.descriptor_sets[i], user_sgpr_idx, 2);
+ user_sgpr_idx += 2;
+ ctx->descriptor_sets[i] =
+ LLVMGetParam(ctx->main_function, arg_idx++);
+ } else
+ ctx->descriptor_sets[i] = NULL;
+ }
+ } else {
+ uint32_t desc_sgpr_idx = user_sgpr_idx;
+ LLVMValueRef desc_sets = LLVMGetParam(ctx->main_function, arg_idx++);
+ set_userdata_location_shader(ctx, AC_UD_INDIRECT_DESCRIPTOR_SETS, user_sgpr_idx, 2);
+ user_sgpr_idx += 2;
+
+ for (unsigned i = 0; i < num_sets; ++i) {
+ if (ctx->options->layout->set[i].layout->shader_stages & (1 << ctx->stage)) {
+ set_userdata_location_indirect(&ctx->shader_info->user_sgprs_locs.descriptor_sets[i], desc_sgpr_idx, 2, i * 8);
+ ctx->descriptor_sets[i] = ac_build_indexed_load_const(&ctx->ac, desc_sets, LLVMConstInt(ctx->i32, i, false));
+
+ } else
+ ctx->descriptor_sets[i] = NULL;
+ }
+ ctx->shader_info->need_indirect_descriptor_sets = true;
}
if (ctx->shader_info->info.needs_push_constants) {
diff --git a/src/amd/common/ac_nir_to_llvm.h b/src/amd/common/ac_nir_to_llvm.h
index 7a4065ac5fa..401d284a7c4 100644
--- a/src/amd/common/ac_nir_to_llvm.h
+++ b/src/amd/common/ac_nir_to_llvm.h
@@ -83,7 +83,8 @@ struct ac_userdata_info {
enum ac_ud_index {
AC_UD_SCRATCH_RING_OFFSETS = 0,
AC_UD_PUSH_CONSTANTS = 1,
- AC_UD_SHADER_START = 2,
+ AC_UD_INDIRECT_DESCRIPTOR_SETS = 2,
+ AC_UD_SHADER_START = 3,
AC_UD_VS_VERTEX_BUFFERS = AC_UD_SHADER_START,
AC_UD_VS_BASE_VERTEX_START_INSTANCE,
AC_UD_VS_LS_TCS_IN_LAYOUT,
@@ -142,7 +143,7 @@ struct ac_shader_variant_info {
unsigned num_user_sgprs;
unsigned num_input_sgprs;
unsigned num_input_vgprs;
-
+ bool need_indirect_descriptor_sets;
union {
struct {
struct ac_vs_output_info outinfo;
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;