radeonsi/gfx9: fix gl_ViewportIndex
authorMarek Olšák <marek.olsak@amd.com>
Mon, 1 May 2017 15:34:41 +0000 (17:34 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 3 May 2017 20:58:27 +0000 (22:58 +0200)
v2: remove unnecessary LLVMBuildAnd calls

Cc: 17.1 <mesa-stable@lists.freedesktop.org>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_state_shaders.c

index 7f771408a3754fa01cf4b14ca0fbdb4f01865409..3af878b5c20cc5a6e78df2f18b3e9824e12db548 100644 (file)
@@ -2393,8 +2393,8 @@ handle_semantic:
            shader->selector->info.writes_layer) {
                pos_args[1].enabled_channels = shader->selector->info.writes_psize |
                                               (shader->selector->info.writes_edgeflag << 1) |
-                                              (shader->selector->info.writes_layer << 2) |
-                                              (shader->selector->info.writes_viewport_index << 3);
+                                              (shader->selector->info.writes_layer << 2);
+
                pos_args[1].valid_mask = 0; /* EXEC mask */
                pos_args[1].done = 0; /* last export? */
                pos_args[1].target = V_008DFC_SQ_EXP_POS + 1;
@@ -2423,11 +2423,34 @@ handle_semantic:
                                                          ctx->f32, "");
                }
 
-               if (shader->selector->info.writes_layer)
-                       pos_args[1].out[2] = layer_value;
+               if (ctx->screen->b.chip_class >= GFX9) {
+                       /* GFX9 has the layer in out.z[10:0] and the viewport
+                        * index in out.z[19:16].
+                        */
+                       if (shader->selector->info.writes_layer)
+                               pos_args[1].out[2] = layer_value;
+
+                       if (shader->selector->info.writes_viewport_index) {
+                               LLVMValueRef v = viewport_index_value;
+
+                               v = bitcast(bld_base, TGSI_TYPE_UNSIGNED, v);
+                               v = LLVMBuildShl(ctx->gallivm.builder, v,
+                                                LLVMConstInt(ctx->i32, 16, 0), "");
+                               v = LLVMBuildOr(ctx->gallivm.builder, v,
+                                               bitcast(bld_base, TGSI_TYPE_UNSIGNED,
+                                                       pos_args[1].out[2]), "");
+                               pos_args[1].out[2] = bitcast(bld_base, TGSI_TYPE_FLOAT, v);
+                               pos_args[1].enabled_channels |= 1 << 2;
+                       }
+               } else {
+                       if (shader->selector->info.writes_layer)
+                               pos_args[1].out[2] = layer_value;
 
-               if (shader->selector->info.writes_viewport_index)
-                       pos_args[1].out[3] = viewport_index_value;
+                       if (shader->selector->info.writes_viewport_index) {
+                               pos_args[1].out[3] = viewport_index_value;
+                               pos_args[1].enabled_channels |= 1 << 3;
+                       }
+               }
        }
 
        for (i = 0; i < 4; i++)
index e4794220913d48b2c7f3860c3c9a5bcf73fd374e..b80a3478cafb1747574cd616ddfc0b4006735075 100644 (file)
@@ -867,8 +867,17 @@ static void si_shader_vs(struct si_screen *sscreen, struct si_shader *shader,
         * not sent again.
         */
        if (!gs) {
-               si_pm4_set_reg(pm4, R_028A40_VGT_GS_MODE,
-                              S_028A40_MODE(enable_prim_id ? V_028A40_GS_SCENARIO_A : 0));
+               unsigned mode = 0;
+
+               /* PrimID needs GS scenario A.
+                * GFX9 also needs it when ViewportIndex is enabled.
+                */
+               if (enable_prim_id ||
+                   (sscreen->b.chip_class >= GFX9 &&
+                    shader->selector->info.writes_viewport_index))
+                       mode = V_028A40_GS_SCENARIO_A;
+
+               si_pm4_set_reg(pm4, R_028A40_VGT_GS_MODE, S_028A40_MODE(mode));
                si_pm4_set_reg(pm4, R_028A84_VGT_PRIMITIVEID_EN, enable_prim_id);
        } else {
                si_pm4_set_reg(pm4, R_028A40_VGT_GS_MODE, si_vgt_gs_mode(gs));