radv: fix handling primitive ID and clip/cull distances with GPL

When compiling the pre-rasterization stages with GPL, we can't know if
the fragment shader reads the primitive ID or the clip/cull distances
as inputs and we have to export them unconditionally.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18699>
This commit is contained in:
Samuel Pitoiset
2022-09-20 11:19:13 +02:00
committed by Marge Bot
parent 630bb53e68
commit 0c6f52a999
2 changed files with 26 additions and 18 deletions

View File

@@ -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);
}

View File

@@ -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)) {