radv: make sure to export the viewport index if FS needs it
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Wed, 22 Apr 2020 20:21:55 +0000 (22:21 +0200)
committerMarge Bot <eric+marge@anholt.net>
Thu, 23 Apr 2020 08:10:25 +0000 (08:10 +0000)
If FS reads gl_ViewportIndex but VS doesn't export it, it should
be zero to avoid reading garbage.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2818
Fixes: b424d49ac05 ("radv/llvm: fix exporting the viewport index if the fragment shader needs it")
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4687>

src/amd/vulkan/radv_pipeline.c
src/amd/vulkan/radv_shader.h
src/amd/vulkan/radv_shader_info.c

index f470432d20bf0b2e477048e977da614ee263ecdb..448cbebf2adc3e2d0e5e7cfd01c6dc19b6c6cefb 100644 (file)
@@ -2578,12 +2578,16 @@ radv_fill_shader_info(struct radv_pipeline *pipeline,
                        infos[MESA_SHADER_FRAGMENT].ps.layer_input;
                keys[MESA_SHADER_VERTEX].vs_common_out.export_clip_dists =
                        !!infos[MESA_SHADER_FRAGMENT].ps.num_input_clips_culls;
+               keys[MESA_SHADER_VERTEX].vs_common_out.export_viewport_index =
+                       infos[MESA_SHADER_FRAGMENT].ps.viewport_index_input;
                keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_prim_id =
                        infos[MESA_SHADER_FRAGMENT].ps.prim_id_input;
                keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_layer_id =
                        infos[MESA_SHADER_FRAGMENT].ps.layer_input;
                keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_clip_dists =
                        !!infos[MESA_SHADER_FRAGMENT].ps.num_input_clips_culls;
+               keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_viewport_index =
+                       infos[MESA_SHADER_FRAGMENT].ps.viewport_index_input;
 
                /* NGG passthrough mode can't be enabled for vertex shaders
                 * that export the primitive ID.
@@ -4351,6 +4355,15 @@ radv_pipeline_generate_ps_inputs(struct radeon_cmdbuf *ctx_cs,
                ++ps_offset;
        }
 
+       if (ps->info.ps.viewport_index_input) {
+               unsigned vs_offset = outinfo->vs_output_param_offset[VARYING_SLOT_VIEWPORT];
+               if (vs_offset != AC_EXP_PARAM_UNDEFINED)
+                       ps_input_cntl[ps_offset] = offset_to_ps_input(vs_offset, true, false, false);
+               else
+                       ps_input_cntl[ps_offset] = offset_to_ps_input(AC_EXP_PARAM_DEFAULT_VAL_0000, true, false, false);
+               ++ps_offset;
+       }
+
        if (ps->info.ps.has_pcoord) {
                unsigned val;
                val = S_028644_PT_SPRITE_TEX(1) | S_028644_OFFSET(0x20);
index 0bd33d3025f721f008ed2aa7878620b23c000ca1..23ff7ddcdcc5d4ee70682f315905fbb0fb6a55b0 100644 (file)
@@ -59,6 +59,7 @@ struct radv_vs_out_key {
        uint32_t export_prim_id:1;
        uint32_t export_layer_id:1;
        uint32_t export_clip_dists:1;
+       uint32_t export_viewport_index:1;
 };
 
 struct radv_vs_variant_key {
@@ -294,6 +295,7 @@ struct radv_shader_info {
                bool has_pcoord;
                bool prim_id_input;
                bool layer_input;
+               bool viewport_index_input;
                uint8_t num_input_clips_culls;
                uint32_t input_mask;
                uint32_t flat_shaded_mask;
index 80f93b1c0a7af2b9a32bbf0563586bc29379cf64..dfccba5600c33207af319ff2a8394e0dd0f09d8d 100644 (file)
@@ -458,6 +458,9 @@ gather_info_input_decl_ps(const nir_shader *nir, const nir_variable *var,
        case VARYING_SLOT_CLIP_DIST1:
                info->ps.num_input_clips_culls += attrib_count;
                break;
+       case VARYING_SLOT_VIEWPORT:
+               info->ps.viewport_index_input = true;
+               break;
        default:
                break;
        }
@@ -730,6 +733,23 @@ radv_nir_shader_info_pass(const struct nir_shader *nir,
                }
        }
 
+       /* Make sure to export the ViewportIndex if the fragment shader needs it. */
+       if (key->vs_common_out.export_viewport_index) {
+               switch (nir->info.stage) {
+               case MESA_SHADER_VERTEX:
+                       info->vs.output_usage_mask[VARYING_SLOT_VIEWPORT] |= 0x1;
+                       break;
+               case MESA_SHADER_TESS_EVAL:
+                       info->tes.output_usage_mask[VARYING_SLOT_VIEWPORT] |= 0x1;
+                       break;
+               case MESA_SHADER_GEOMETRY:
+                       info->gs.output_usage_mask[VARYING_SLOT_VIEWPORT] |= 0x1;
+                       break;
+               default:
+                       break;
+               }
+       }
+
        if (nir->info.stage == MESA_SHADER_FRAGMENT)
                info->ps.num_interp = nir->num_inputs;