ac: update enabled channels mask when optimizing PARAM exports
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Thu, 1 Mar 2018 10:54:21 +0000 (11:54 +0100)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 6 Mar 2018 09:37:52 +0000 (10:37 +0100)
When the mask is not 0xf we need to update the number of
enabled channels, otherwise the hardware won't emit the
components that are combined.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
src/amd/common/ac_llvm_build.c

index 8140184b3ba3cb6099410db8f956a63ee9eb4d3c..da2213d40baa0aa0beb477151e8f604129361b77 100644 (file)
@@ -1777,6 +1777,7 @@ void ac_get_image_intr_name(const char *base_name,
 }
 
 #define AC_EXP_TARGET (HAVE_LLVM >= 0x0500 ? 0 : 3)
+#define AC_EXP_ENABLED_CHANNELS (HAVE_LLVM >= 0x0500 ? 1 : 0)
 #define AC_EXP_OUT0 (HAVE_LLVM >= 0x0500 ? 2 : 5)
 
 enum ac_ir_type {
@@ -1849,7 +1850,8 @@ static bool ac_eliminate_const_output(uint8_t *vs_output_param_offset,
        return true;
 }
 
-static bool ac_eliminate_duplicated_output(uint8_t *vs_output_param_offset,
+static bool ac_eliminate_duplicated_output(struct ac_llvm_context *ctx,
+                                          uint8_t *vs_output_param_offset,
                                           uint32_t num_outputs,
                                           struct ac_vs_exports *processed,
                                           struct ac_vs_exp_inst *exp)
@@ -1901,6 +1903,10 @@ static bool ac_eliminate_duplicated_output(uint8_t *vs_output_param_offset,
         */
        struct ac_vs_exp_inst *match = &processed->exp[p];
 
+       /* Get current enabled channels mask. */
+       LLVMValueRef arg = LLVMGetOperand(match->inst, AC_EXP_ENABLED_CHANNELS);
+       unsigned enabled_channels = LLVMConstIntGetZExtValue(arg);
+
        while (copy_back_channels) {
                unsigned chan = u_bit_scan(&copy_back_channels);
 
@@ -1908,6 +1914,13 @@ static bool ac_eliminate_duplicated_output(uint8_t *vs_output_param_offset,
                LLVMSetOperand(match->inst, AC_EXP_OUT0 + chan,
                               exp->chan[chan].value);
                match->chan[chan] = exp->chan[chan];
+
+               /* Update number of enabled channels because the original mask
+                * is not always 0xf.
+                */
+               enabled_channels |= (1 << chan);
+               LLVMSetOperand(match->inst, AC_EXP_ENABLED_CHANNELS,
+                              LLVMConstInt(ctx->i32, enabled_channels, 0));
        }
 
        /* The PARAM export is duplicated. Kill it. */
@@ -1995,7 +2008,8 @@ void ac_optimize_vs_outputs(struct ac_llvm_context *ctx,
                        /* Eliminate constant and duplicated PARAM exports. */
                        if (ac_eliminate_const_output(vs_output_param_offset,
                                                      num_outputs, &exp) ||
-                           ac_eliminate_duplicated_output(vs_output_param_offset,
+                           ac_eliminate_duplicated_output(ctx,
+                                                          vs_output_param_offset,
                                                           num_outputs, &exports,
                                                           &exp)) {
                                removed_any = true;