r300: respect extra presubtract swizzle limitations during regalloc
authorPavel Ondračka <pavel.ondracka@gmail.com>
Tue, 15 Nov 2022 21:35:05 +0000 (22:35 +0100)
committerMarge Bot <emma+marge@anholt.net>
Wed, 16 Nov 2022 19:51:47 +0000 (19:51 +0000)
Regalloc was not aware of the extra limitations and in some cases could
convert native swizzle into non-native.

Signed-off-by: Pavel Ondračka <pavel.ondracka@gmail.com>
Reviewed-by: Filip Gawin <filip@gawin.net>
Tested-by: Filip Gawin <filip@gawin.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19764>

src/gallium/drivers/r300/compiler/radeon_pair_regalloc.c

index 7832091..e7cabfa 100644 (file)
@@ -121,6 +121,7 @@ static unsigned int is_derivative(rc_opcode op)
 struct variable_get_class_cb_data {
        unsigned int * can_change_writemask;
        unsigned int conversion_swizzle;
+       struct radeon_compiler * c;
 };
 
 static void variable_get_class_read_cb(
@@ -132,7 +133,17 @@ static void variable_get_class_read_cb(
        struct variable_get_class_cb_data * d = userdata;
        unsigned int new_swizzle = rc_adjust_channels(arg->Swizzle,
                                                        d->conversion_swizzle);
-       if (!r300_swizzle_is_native_basic(new_swizzle)) {
+       /* We can't just call r300_swizzle_is_native basic here, because it ignores the
+        * extra requirements for presubtract. However, after pair translation we no longer
+        * have the rc_src_register required for the native swizzle, so we have to
+        * reconstruct it. */
+       struct rc_src_register reg = {};
+       reg.Swizzle = new_swizzle;
+       reg.File = src->File;
+
+       assert(inst->Type == RC_INSTRUCTION_PAIR);
+       /* The opcode is unimportant, we can't have TEX here. */
+       if (!d->c->SwizzleCaps->IsNative(RC_OPCODE_MAD, reg)) {
                *d->can_change_writemask = 0;
        }
 }
@@ -180,6 +191,7 @@ static unsigned variable_get_class(
                                struct variable_get_class_cb_data d;
                                d.can_change_writemask = &can_change_writemask;
                                d.conversion_swizzle = conversion_swizzle;
+                               d.c = variable->C;
                                /* If we get this far var_ptr->Inst has to
                                 * be a pair instruction.  If variable or any
                                 * of its friends are normal instructions,