diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index c0b9170fedd..7b646cbf471 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -2170,14 +2170,20 @@ radv_should_export_implicit_primitive_id(const struct radv_pipeline_stage *produ const struct radv_pipeline_stage *consumer) { /* When the primitive ID is read by FS, we must ensure that it's exported by the previous vertex - * stage because it's implicit for VS or TES (but required by the Vulkan spec for GS or MS). Note - * that when the pipeline uses NGG, it's exported later during the lowering pass. + * stage because it's implicit for VS or TES (but required by the Vulkan spec for GS or MS). + * + * There is two situations to handle: + * - when the next stage is unknown (with graphics pipeline library), the primitive ID is + * exported unconditionally + * - when the pipeline uses NGG, the primitive ID is exported during NGG lowering */ assert(producer->stage == MESA_SHADER_VERTEX || producer->stage == MESA_SHADER_TESS_EVAL); - return (consumer->stage == MESA_SHADER_FRAGMENT && - (consumer->nir->info.inputs_read & VARYING_BIT_PRIMITIVE_ID) && - !(producer->nir->info.outputs_written & VARYING_BIT_PRIMITIVE_ID) && - !producer->info.is_ngg); + + if ((producer->nir->info.outputs_written & VARYING_BIT_PRIMITIVE_ID) || producer->info.is_ngg) + return false; + + return !consumer || (consumer->stage == MESA_SHADER_FRAGMENT && + (consumer->nir->info.inputs_read & VARYING_BIT_PRIMITIVE_ID)); } static bool @@ -2485,15 +2491,15 @@ radv_pipeline_link_vs(const struct radv_device *device, struct radv_pipeline_sta { assert(vs_stage->nir->info.stage == MESA_SHADER_VERTEX); + if (radv_should_export_implicit_primitive_id(vs_stage, next_stage)) { + NIR_PASS(_, vs_stage->nir, radv_export_implicit_primitive_id); + } + if (next_stage) { assert(next_stage->nir->info.stage == MESA_SHADER_TESS_CTRL || next_stage->nir->info.stage == MESA_SHADER_GEOMETRY || next_stage->nir->info.stage == MESA_SHADER_FRAGMENT); - if (radv_should_export_implicit_primitive_id(vs_stage, next_stage)) { - NIR_PASS(_, vs_stage->nir, radv_export_implicit_primitive_id); - } - if (radv_should_export_multiview(vs_stage, next_stage, pipeline_key)) { NIR_PASS(_, vs_stage->nir, radv_export_multiview); } @@ -2555,14 +2561,14 @@ radv_pipeline_link_tes(const struct radv_device *device, struct radv_pipeline_st { assert(tes_stage->nir->info.stage == MESA_SHADER_TESS_EVAL); + if (radv_should_export_implicit_primitive_id(tes_stage, next_stage)) { + NIR_PASS(_, tes_stage->nir, radv_export_implicit_primitive_id); + } + if (next_stage) { assert(next_stage->nir->info.stage == MESA_SHADER_GEOMETRY || next_stage->nir->info.stage == MESA_SHADER_FRAGMENT); - if (radv_should_export_implicit_primitive_id(tes_stage, next_stage)) { - NIR_PASS(_, tes_stage->nir, radv_export_implicit_primitive_id); - } - if (radv_should_export_multiview(tes_stage, next_stage, pipeline_key)) { NIR_PASS(_, tes_stage->nir, radv_export_multiview); } diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c index 2b6463fe034..841da243c08 100644 --- a/src/amd/vulkan/radv_shader_info.c +++ b/src/amd/vulkan/radv_shader_info.c @@ -1249,11 +1249,13 @@ radv_link_shaders_info(struct radv_device *device, struct radv_pipeline_stage *producer, struct radv_pipeline_stage *consumer, const struct radv_pipeline_key *pipeline_key) { - /* Export primitive ID or clip/cull distances if necessary. */ - if (consumer && consumer->stage == MESA_SHADER_FRAGMENT) { + /* Export primitive ID and clip/cull distances if read by the FS, or export unconditionally when + * the next stage is unknown (with graphics pipeline library). + */ + if (!consumer || consumer->stage == MESA_SHADER_FRAGMENT) { struct radv_vs_output_info *outinfo = &producer->info.outinfo; - const bool ps_prim_id_in = consumer->info.ps.prim_id_input; - const bool ps_clip_dists_in = !!consumer->info.ps.num_input_clips_culls; + const bool ps_prim_id_in = !consumer || consumer->info.ps.prim_id_input; + const bool ps_clip_dists_in = !consumer || !!consumer->info.ps.num_input_clips_culls; if (ps_prim_id_in && (producer->stage == MESA_SHADER_VERTEX || producer->stage == MESA_SHADER_TESS_EVAL)) {