diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 0452decda6e..8d208f49cfe 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -2741,55 +2741,6 @@ radv_generate_graphics_pipeline_key(const struct radv_graphics_pipeline *pipelin return key; } -static void -radv_determine_ngg_settings(struct radv_pipeline *pipeline, - const struct radv_pipeline_key *pipeline_key, - struct radv_pipeline_stage *stages, - gl_shader_stage last_vgt_api_stage) -{ - const struct radv_physical_device *pdevice = pipeline->device->physical_device; - - /* Shader settings for VS or TES without GS. */ - if (last_vgt_api_stage == MESA_SHADER_VERTEX || - last_vgt_api_stage == MESA_SHADER_TESS_EVAL) { - uint64_t ps_inputs_read = - stages[MESA_SHADER_FRAGMENT].nir ? stages[MESA_SHADER_FRAGMENT].nir->info.inputs_read : 0; - gl_shader_stage es_stage = last_vgt_api_stage; - - unsigned num_vertices_per_prim = si_conv_prim_to_gs_out(pipeline_key->vs.topology) + 1; - if (es_stage == MESA_SHADER_TESS_EVAL) - num_vertices_per_prim = stages[es_stage].nir->info.tess.point_mode ? 1 - : stages[es_stage].nir->info.tess._primitive_mode == TESS_PRIMITIVE_ISOLINES ? 2 - : 3; - /* TODO: Enable culling for LLVM. */ - stages[es_stage].info.has_ngg_culling = radv_consider_culling( - pdevice, stages[es_stage].nir, ps_inputs_read, num_vertices_per_prim, &stages[es_stage].info) && - !radv_use_llvm_for_stage(pipeline->device, es_stage); - - nir_function_impl *impl = nir_shader_get_entrypoint(stages[es_stage].nir); - stages[es_stage].info.has_ngg_early_prim_export = exec_list_is_singular(&impl->body); - - /* Invocations that process an input vertex */ - const struct gfx10_ngg_info *ngg_info = &stages[es_stage].info.ngg_info; - unsigned max_vtx_in = MIN2(256, ngg_info->enable_vertex_grouping ? ngg_info->hw_max_esverts : num_vertices_per_prim * ngg_info->max_gsprims); - - unsigned lds_bytes_if_culling_off = 0; - /* We need LDS space when VS needs to export the primitive ID. */ - if (es_stage == MESA_SHADER_VERTEX && stages[es_stage].info.outinfo.export_prim_id) - lds_bytes_if_culling_off = max_vtx_in * 4u; - stages[es_stage].info.num_lds_blocks_when_not_culling = - DIV_ROUND_UP(lds_bytes_if_culling_off, pdevice->rad_info.lds_encode_granularity); - - /* NGG passthrough mode should be disabled when culling and when the vertex shader exports the - * primitive ID. - */ - stages[es_stage].info.is_ngg_passthrough = stages[es_stage].info.is_ngg_passthrough && - !stages[es_stage].info.has_ngg_culling && - !(es_stage == MESA_SHADER_VERTEX && - stages[es_stage].info.outinfo.export_prim_id); - } -} - static void radv_fill_shader_info_ngg(struct radv_pipeline *pipeline, const struct radv_pipeline_key *pipeline_key, @@ -2989,8 +2940,6 @@ radv_fill_shader_info(struct radv_pipeline *pipeline, stages[MESA_SHADER_TESS_EVAL].nir ? MESA_SHADER_TESS_EVAL : MESA_SHADER_VERTEX; stages[hw_vs_api_stage].info.workgroup_size = stages[hw_vs_api_stage].info.wave_size; } - - radv_determine_ngg_settings(pipeline, pipeline_key, stages, last_vgt_api_stage); } static void diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c index 266f04023df..77f70f68621 100644 --- a/src/amd/vulkan/radv_shader_info.c +++ b/src/amd/vulkan/radv_shader_info.c @@ -1173,6 +1173,53 @@ gfx10_get_ngg_info(const struct radv_device *device, struct radv_pipeline_stage es_info->workgroup_size = workgroup_size; } +static void +radv_determine_ngg_settings(struct radv_device *device, struct radv_pipeline_stage *es_stage, + struct radv_pipeline_stage *fs_stage, + const struct radv_pipeline_key *pipeline_key) +{ + assert(es_stage->stage == MESA_SHADER_VERTEX || es_stage->stage == MESA_SHADER_TESS_EVAL); + assert(fs_stage->stage == MESA_SHADER_FRAGMENT); + + uint64_t ps_inputs_read = fs_stage->nir->info.inputs_read; + + unsigned num_vertices_per_prim = si_conv_prim_to_gs_out(pipeline_key->vs.topology) + 1; + if (es_stage->stage == MESA_SHADER_TESS_EVAL) { + num_vertices_per_prim = es_stage->nir->info.tess.point_mode ? 1 : + es_stage->nir->info.tess._primitive_mode == TESS_PRIMITIVE_ISOLINES ? 2 : 3; + } + + /* TODO: Enable culling for LLVM. */ + es_stage->info.has_ngg_culling = + radv_consider_culling(device->physical_device, es_stage->nir, ps_inputs_read, + num_vertices_per_prim, &es_stage->info) && + !radv_use_llvm_for_stage(device, es_stage->stage); + + nir_function_impl *impl = nir_shader_get_entrypoint(es_stage->nir); + es_stage->info.has_ngg_early_prim_export = exec_list_is_singular(&impl->body); + + /* Invocations that process an input vertex */ + const struct gfx10_ngg_info *ngg_info = &es_stage->info.ngg_info; + unsigned max_vtx_in = MIN2(256, ngg_info->enable_vertex_grouping ? + ngg_info->hw_max_esverts : num_vertices_per_prim * ngg_info->max_gsprims); + + unsigned lds_bytes_if_culling_off = 0; + /* We need LDS space when VS needs to export the primitive ID. */ + if (es_stage->stage == MESA_SHADER_VERTEX && es_stage->info.outinfo.export_prim_id) + lds_bytes_if_culling_off = max_vtx_in * 4u; + + es_stage->info.num_lds_blocks_when_not_culling = + DIV_ROUND_UP(lds_bytes_if_culling_off, + device->physical_device->rad_info.lds_encode_granularity); + + /* NGG passthrough mode should be disabled when culling and when the vertex shader + * exports the primitive ID. + */ + es_stage->info.is_ngg_passthrough = es_stage->info.is_ngg_passthrough && + !es_stage->info.has_ngg_culling && !(es_stage->stage == MESA_SHADER_VERTEX && + es_stage->info.outinfo.export_prim_id); +} + static void radv_link_shaders_info(struct radv_device *device, struct radv_pipeline_stage *producer, struct radv_pipeline_stage *consumer, @@ -1217,6 +1264,11 @@ radv_link_shaders_info(struct radv_device *device, consumer->stage == MESA_SHADER_GEOMETRY ? consumer : NULL; gfx10_get_ngg_info(device, producer, gs_stage); + + /* Determine other NGG settings like culling for VS or TES without GS. */ + if (!gs_stage) { + radv_determine_ngg_settings(device, producer, consumer, pipeline_key); + } } else if (consumer->stage == MESA_SHADER_GEOMETRY) { gfx9_get_gs_info(device, producer, consumer); }