Mesa (main): virgl: Move double operands to a temp to avoid double-swizzling bugs.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Feb 14 23:34:35 UTC 2022


Module: Mesa
Branch: main
Commit: 036d7172c24a18eca653fa95eb40b70719ce4d7e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=036d7172c24a18eca653fa95eb40b70719ce4d7e

Author: Emma Anholt <emma at anholt.net>
Date:   Mon Jan 10 11:34:01 2022 -0800

virgl: Move double operands to a temp to avoid double-swizzling bugs.

virglrenderer applies the swizzle when packing doubles.  Since we use scan
now, we can just use the file count for texture detection.

Reviewed-by: Gert Wollny <gert.wollny at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15014>

---

 src/gallium/drivers/virgl/virgl_tgsi.c | 50 ++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/virgl/virgl_tgsi.c b/src/gallium/drivers/virgl/virgl_tgsi.c
index a473f3dfc74..b28b60996fd 100644
--- a/src/gallium/drivers/virgl/virgl_tgsi.c
+++ b/src/gallium/drivers/virgl/virgl_tgsi.c
@@ -28,6 +28,7 @@
 
 #include "tgsi/tgsi_transform.h"
 #include "tgsi/tgsi_info.h"
+#include "tgsi/tgsi_scan.h"
 #include "virgl_context.h"
 #include "virgl_screen.h"
 
@@ -54,14 +55,15 @@ enum virgl_input_temps {
 
 struct virgl_transform_context {
    struct tgsi_transform_context base;
+   struct tgsi_shader_info info;
+
    bool cull_enabled;
    bool has_precise;
-   bool has_textures;
    bool fake_fp64;
 
    unsigned next_temp;
 
-   unsigned tex_temp;
+   unsigned src_temp;
 
    unsigned writemask_fixup_outs[5];
    unsigned writemask_fixup_temps;
@@ -128,10 +130,6 @@ virgl_tgsi_transform_declaration(struct tgsi_transform_context *ctx,
    case TGSI_FILE_TEMPORARY:
       vtctx->next_temp = MAX2(vtctx->next_temp, decl->Range.Last + 1);
       break;
-   case TGSI_FILE_SAMPLER:
-   case TGSI_FILE_SAMPLER_VIEW:
-      vtctx->has_textures = true;
-      break;
    default:
       break;
    }
@@ -189,9 +187,10 @@ virgl_tgsi_transform_prolog(struct tgsi_transform_context * ctx)
 {
    struct virgl_transform_context *vtctx = (struct virgl_transform_context *)ctx;
 
-   if (vtctx->has_textures) {
-      vtctx->tex_temp = vtctx->next_temp++;
-      tgsi_transform_temp_decl(ctx, vtctx->tex_temp);
+   if (vtctx->info.uses_doubles || vtctx->info.file_count[TGSI_FILE_SAMPLER_VIEW]) {
+      vtctx->src_temp = vtctx->next_temp;
+      vtctx->next_temp += 4;
+      tgsi_transform_temps_decl(ctx, vtctx->src_temp, vtctx->src_temp + 3);
    }
 
    if (vtctx->num_writemask_fixups) {
@@ -280,14 +279,13 @@ virgl_tgsi_transform_instruction(struct tgsi_transform_context *ctx,
     */
    if (tgsi_get_opcode_info(inst->Instruction.Opcode)->is_tex &&
        inst->Src[0].Register.File == TGSI_FILE_IMMEDIATE) {
-      assert(vtctx->has_textures);
       tgsi_transform_op1_inst(ctx, TGSI_OPCODE_MOV,
-                              TGSI_FILE_TEMPORARY, vtctx->tex_temp,
+                              TGSI_FILE_TEMPORARY, vtctx->src_temp,
                               TGSI_WRITEMASK_XYZW,
                               inst->Src[0].Register.File,
                               inst->Src[0].Register.Index);
       inst->Src[0].Register.File = TGSI_FILE_TEMPORARY;
-      inst->Src[0].Register.Index = vtctx->tex_temp;
+      inst->Src[0].Register.Index = vtctx->src_temp;
    }
 
    for (unsigned i = 0; i < inst->Instruction.NumDstRegs; i++) {
@@ -316,6 +314,32 @@ virgl_tgsi_transform_instruction(struct tgsi_transform_context *ctx,
 
       for (int j = 0; j < ARRAY_SIZE(vtctx->input_temp); j++)
          virgl_tgsi_rewrite_src_for_input_temp(&vtctx->input_temp[j], &inst->Src[i]);
+
+      /* virglrenderer double inputs twice, so move them to temps and drop the
+       * swizzle from the double op.
+       */
+      if (tgsi_opcode_infer_src_type(inst->Instruction.Opcode, i) == TGSI_TYPE_DOUBLE) {
+         struct tgsi_full_instruction temp_inst = tgsi_default_full_instruction();
+         temp_inst.Instruction.Opcode = TGSI_OPCODE_MOV;
+         temp_inst.Instruction.NumDstRegs = 1;
+         temp_inst.Dst[0].Register.File = TGSI_FILE_TEMPORARY,
+         temp_inst.Dst[0].Register.Index = vtctx->src_temp + i;
+         temp_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZ;
+         temp_inst.Instruction.NumSrcRegs = 1;
+         tgsi_transform_src_reg_xyzw(&temp_inst.Src[0], inst->Src[i].Register.File, inst->Src[i].Register.Index);
+         temp_inst.Src[0].Register.SwizzleX = inst->Src[i].Register.SwizzleX;
+         temp_inst.Src[0].Register.SwizzleY = inst->Src[i].Register.SwizzleY;
+         temp_inst.Src[0].Register.SwizzleZ = inst->Src[i].Register.SwizzleZ;
+         temp_inst.Src[0].Register.SwizzleW = inst->Src[i].Register.SwizzleW;
+         ctx->emit_instruction(ctx, &temp_inst);
+
+         inst->Src[i].Register.File = TGSI_FILE_TEMPORARY;
+         inst->Src[i].Register.Index = vtctx->src_temp + i;
+         inst->Src[i].Register.SwizzleX = TGSI_SWIZZLE_X;
+         inst->Src[i].Register.SwizzleY = TGSI_SWIZZLE_Y;
+         inst->Src[i].Register.SwizzleZ = TGSI_SWIZZLE_Z;
+         inst->Src[i].Register.SwizzleW = TGSI_SWIZZLE_W;
+      }
    }
    ctx->emit_instruction(ctx, inst);
 
@@ -356,6 +380,8 @@ struct tgsi_token *virgl_tgsi_transform(struct virgl_screen *vscreen, const stru
    for (int i = 0; i < ARRAY_SIZE(transform.input_temp); i++)
       transform.input_temp[i].index = ~0;
 
+   tgsi_scan_shader(tokens_in, &transform.info);
+
    tgsi_transform_shader(tokens_in, new_tokens, newLen, &transform.base);
 
    return new_tokens;



More information about the mesa-commit mailing list