diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c index d0a1747edbf..59f1033e632 100644 --- a/src/amd/common/ac_gpu_info.c +++ b/src/amd/common/ac_gpu_info.c @@ -1670,6 +1670,8 @@ bool ac_query_gpu_info(int fd, void *dev_p, struct radeon_info *info, info->conformant_trunc_coord = info->drm_minor >= 52 && device_info.ids_flags & AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD; + + info->has_attr_ring = info->attribute_ring_size_per_se > 0; } if (info->gfx_level >= GFX11 && debug_get_bool_option("AMD_USERQ", false)) { diff --git a/src/amd/common/ac_gpu_info.h b/src/amd/common/ac_gpu_info.h index 603a4d83757..e78e16a058d 100644 --- a/src/amd/common/ac_gpu_info.h +++ b/src/amd/common/ac_gpu_info.h @@ -285,6 +285,7 @@ struct radeon_info { uint32_t pos_ring_offset; /* GFX12+ */ uint32_t prim_ring_offset; /* GFX12+ */ uint32_t total_attribute_pos_prim_ring_size; /* GFX11+ */ + bool has_attr_ring; /* Render backends (color + depth blocks). */ uint32_t r300_num_gb_pipes; diff --git a/src/amd/common/nir/ac_nir_lower_ngg.c b/src/amd/common/nir/ac_nir_lower_ngg.c index 55c209a14aa..7af9b402859 100644 --- a/src/amd/common/nir/ac_nir_lower_ngg.c +++ b/src/amd/common/nir/ac_nir_lower_ngg.c @@ -245,10 +245,11 @@ emit_ngg_nogs_prim_export(nir_builder *b, lower_ngg_nogs_state *s, nir_def *arg) ac_nir_export_primitive(b, arg, NULL); - /* Store implicit primitive ID when configured as a per-primitive output on GFX10.3. + /* Store implicit primitive ID when configured as a per-primitive output on + * GPUs without an attribute ring. * Because this uses the export space, do it together with the primitive export. */ - if (s->options->gfx_level == GFX10_3 && s->options->export_primitive_id_per_prim) { + if (!s->options->hw_info->has_attr_ring && s->options->export_primitive_id_per_prim) { const uint8_t offset = s->options->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID]; nir_def *prim_id = nir_load_primitive_id(b); nir_def *undef = nir_undef(b, 1, 32); @@ -293,14 +294,15 @@ emit_ngg_nogs_prim_id_store_shared(nir_builder *b, lower_ngg_nogs_state *s) nir_pop_if(b, if_gs_thread); } -/* Store implicit primitive ID when configured as a per-primitive output on GFX11+. - * This is done separately from the primitive export on GFX11 in order to +/* Store implicit primitive ID when configured as a per-primitive output + * on GPUs with an attribute ring. + * This is done separately from the primitive export in order to * optimize attribute ring access. */ static void emit_ngg_nogs_prim_id_store_per_prim_to_attr_ring(nir_builder *b, lower_ngg_nogs_state *s) { - assert(s->options->gfx_level >= GFX11); + assert(s->options->hw_info->has_attr_ring); nir_def *is_gs_thread = nir_load_var(b, s->gs_exported_var); nir_def *highest_gs_thread = nir_ufind_msb(b, nir_ballot(b, 1, s->options->wave_size, is_gs_thread)); @@ -1826,7 +1828,7 @@ ac_nir_lower_ngg_nogs(nir_shader *shader, const ac_nir_lower_ngg_options *option /* Wait for GS threads to store primitive ID in LDS. */ nir_barrier(b, .execution_scope = SCOPE_WORKGROUP, .memory_scope = SCOPE_WORKGROUP, .memory_semantics = NIR_MEMORY_ACQ_REL, .memory_modes = nir_var_mem_shared); - } else if (options->export_primitive_id_per_prim && options->gfx_level >= GFX11) { + } else if (options->export_primitive_id_per_prim && options->hw_info->has_attr_ring) { emit_ngg_nogs_prim_id_store_per_prim_to_attr_ring(b, &state); } @@ -1837,7 +1839,7 @@ ac_nir_lower_ngg_nogs(nir_shader *shader, const ac_nir_lower_ngg_options *option * scheduling. */ nir_def *num_es_threads = NULL; - if (state.options->gfx_level >= GFX11 && options->can_cull) { + if (options->hw_info->has_attr_ring && options->can_cull) { nir_def *es_accepted_mask = nir_ballot(b, 1, options->wave_size, nir_load_var(b, es_accepted_var)); num_es_threads = nir_bit_count(b, es_accepted_mask); @@ -1943,7 +1945,7 @@ ac_nir_lower_ngg_nogs(nir_shader *shader, const ac_nir_lower_ngg_options *option options->force_vrs, !wait_attr_ring, export_outputs, &state.out, NULL); - if (options->has_param_exports && options->gfx_level <= GFX10_3) { + if (options->has_param_exports && !options->hw_info->has_attr_ring) { ac_nir_export_parameters(b, options->vs_output_param_offset, b->shader->info.outputs_written, b->shader->info.outputs_written_16bit, @@ -1953,7 +1955,7 @@ ac_nir_lower_ngg_nogs(nir_shader *shader, const ac_nir_lower_ngg_options *option if (if_pos_exports) nir_pop_if(b, if_pos_exports); - if (options->has_param_exports && options->gfx_level >= GFX11) { + if (options->has_param_exports && options->hw_info->has_attr_ring) { if (!phis_created) { b->cursor = nir_after_cf_node(&if_es_thread->cf_node); ac_nir_create_output_phis(b, b->shader->info.outputs_written, b->shader->info.outputs_written_16bit, &state.out); @@ -2414,7 +2416,7 @@ ngg_gs_export_vertices(nir_builder *b, nir_def *max_num_out_vtx, nir_def *tid_in s->options->force_vrs, !wait_attr_ring, export_outputs, &s->out, NULL); - if (s->options->has_param_exports && s->options->gfx_level < GFX11) { + if (s->options->has_param_exports && !s->options->hw_info->has_attr_ring) { /* Emit vertex parameter exports. * Only the vertex export threads should do this. */ @@ -2426,7 +2428,7 @@ ngg_gs_export_vertices(nir_builder *b, nir_def *max_num_out_vtx, nir_def *tid_in nir_pop_if(b, if_vtx_export_thread); - if (s->options->has_param_exports && s->options->gfx_level >= GFX11) { + if (s->options->has_param_exports && s->options->hw_info->has_attr_ring) { /* Store vertex parameters to attribute ring. * For optimal attribute ring access, this should happen in top level CF. */ diff --git a/src/amd/vulkan/winsys/null/radv_null_winsys.c b/src/amd/vulkan/winsys/null/radv_null_winsys.c index 378a3b5afe8..4960d936092 100644 --- a/src/amd/vulkan/winsys/null/radv_null_winsys.c +++ b/src/amd/vulkan/winsys/null/radv_null_winsys.c @@ -117,6 +117,7 @@ radv_null_winsys_query_info(struct radeon_winsys *rws, struct radeon_info *gpu_i gpu_info->has_3d_cube_border_color_mipmap = true; gpu_info->has_image_opcodes = true; + gpu_info->has_attr_ring = gpu_info->gfx_level >= GFX11; gpu_info->has_attr_ring_wait_bug = gpu_info->gfx_level == GFX11 || gpu_info->gfx_level == GFX11_5; if (gpu_info->family == CHIP_NAVI31 || gpu_info->family == CHIP_NAVI32)