Skip to contentSkip to conversation

Add precise/invariant semantics to TGSI

RFC In review Karol Herbst 8 participants 19 messages Jun 11, 2017 – Jun 13, 2017 6 messages not in the archive

lore
Share & tools
lore
#0 lore raw

cover Add precise/invariant semantics to TGSI

Running Tomb Raider on Nouveau I found some flicker caused by ignoring precise modifiers on variables inside Nouveau.

This series add precise/invariant handling to TGSI, which can be then used by drivers to disable certain unsafe optimisations which may otherwise alter calculations, which depend on having the same result across shaders.

This series fixes this bug in Tomb Raider and one CTS test for 4.4 and 4.5

Note on Patch 3: I really dislike how I tell glsl_to_tgsi_visitor to apply the precise flag on instruction emited in ir_assignment->rhs->accept(); but I found no other easy way to handle this. Maybe somebody of you has a better idea?

Karol Herbst (9):
tgsi: add precise flag to tgsi_instruction tgsi/dump: print _PRECISE modifier on Instrutions st/glsl_to_tgsi: handle precise modifier
tgsi: populate precise
tgsi/text: parse _PRECISE modifier
nv50/ir: add precise field to Instruction nv50/ir/tgsi: handle precise for most ALU instructions nv50/ir: disable mul+add to mad for precise instructions nv50/ir/tgsi: split mad to mul+add

 src/gallium/auxiliary/tgsi/tgsi_build.c            |  4 +
 src/gallium/auxiliary/tgsi/tgsi_dump.c             |  4 +
 src/gallium/auxiliary/tgsi/tgsi_text.c             | 15 +++-
 src/gallium/auxiliary/tgsi/tgsi_ureg.c             | 14 +++-
 src/gallium/auxiliary/tgsi/tgsi_ureg.h             | 20 ++++-
 src/gallium/auxiliary/util/u_simple_shaders.c      |  2 +-
 src/gallium/drivers/nouveau/codegen/nv50_ir.h      |  1 +
 .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp  | 16 ++++
 .../drivers/nouveau/codegen/nv50_ir_peephole.cpp   |  6 +-
 src/gallium/include/pipe/p_shader_tokens.h         |  3 +-
 src/gallium/state_trackers/nine/nine_shader.c      |  6 +-
 src/mesa/state_tracker/st_atifs_to_tgsi.c          | 38 ++++-----
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp         | 92 +++++++++++++++++-----
 src/mesa/state_tracker/st_mesa_to_tgsi.c           |  8 +-
 src/mesa/state_tracker/st_pbo.c                    |  2 +-
 15 files changed, 172 insertions(+), 59 deletions(-)
Signature · 6 lines
2.13.1

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

A message that is not in the archive (sent off-list or not yet received): 20170611184239.7204-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#2 lore raw

RFC 1/9 tgsi: add precise flag to tgsi_instruction

---
 src/gallium/auxiliary/tgsi/tgsi_build.c    | 1 +
 src/gallium/include/pipe/p_shader_tokens.h | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)
src/gallium/auxiliary/tgsi/tgsi_build.c +1 -0
index 00843241f8..55e4d064ed 100644
@@ -642,6 +642,7 @@ tgsi_default_instruction( void )
    instruction.Label = 0;
    instruction.Texture = 0;
    instruction.Memory = 0;
+   instruction.Precise = 0;
    instruction.Padding = 0;
 
    return instruction;
src/gallium/include/pipe/p_shader_tokens.h +2 -1
index 1e08d97329..aa0fb3e3b3 100644
@@ -638,7 +638,8 @@ struct tgsi_instruction
    unsigned Label      : 1;
    unsigned Texture    : 1;
    unsigned Memory     : 1;
-   unsigned Padding    : 2;
+   unsigned Precise    : 1;
+   unsigned Padding    : 1;
 };
 
 /*
Signature · 6 lines
2.13.1

_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
#3 lore raw

RFC 2/9 tgsi/dump: print _PRECISE modifier on Instrutions

In reply to a message not in the archive
---
 src/gallium/auxiliary/tgsi/tgsi_dump.c | 4 ++++
 1 file changed, 4 insertions(+)
src/gallium/auxiliary/tgsi/tgsi_dump.c +4 -0
index f6eba7424b..b58e64511c 100644
@@ -584,6 +584,10 @@ iter_instruction(
       TXT( "_SAT" );
    }
 
+   if (inst->Instruction.Precise) {
+      TXT( "_PRECISE" );
+   }
+
    for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
       const struct tgsi_full_dst_register *dst = &inst->Dst[i];
 
Signature · 6 lines
2.13.1

_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
#4 lore raw

RFC 4/9 tgsi: populate precise

In reply to a message not in the archive

Only implemented for glsl->tgsi. Other converters just set precise to 0.

---
 src/gallium/auxiliary/tgsi/tgsi_build.c       |  3 +++
 src/gallium/auxiliary/tgsi/tgsi_ureg.c        | 14 +++++++---
 src/gallium/auxiliary/tgsi/tgsi_ureg.h        | 20 +++++++++++---
 src/gallium/auxiliary/util/u_simple_shaders.c |  2 +-
 src/gallium/state_trackers/nine/nine_shader.c |  6 ++---
 src/mesa/state_tracker/st_atifs_to_tgsi.c     | 38 +++++++++++++--------------
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp    | 12 ++++-----
 src/mesa/state_tracker/st_mesa_to_tgsi.c      |  8 +++---
 src/mesa/state_tracker/st_pbo.c               |  2 +-
 9 files changed, 65 insertions(+), 40 deletions(-)
src/gallium/auxiliary/tgsi/tgsi_build.c +3 -0
index 55e4d064ed..144a017768 100644
@@ -651,6 +651,7 @@ tgsi_default_instruction( void )
 static struct tgsi_instruction
 tgsi_build_instruction(unsigned opcode,
                        unsigned saturate,
+                       unsigned precise,
                        unsigned num_dst_regs,
                        unsigned num_src_regs,
                        struct tgsi_header *header)
@@ -665,6 +666,7 @@ tgsi_build_instruction(unsigned opcode,
    instruction = tgsi_default_instruction();
    instruction.Opcode = opcode;
    instruction.Saturate = saturate;
+   instruction.Precise = precise;
    instruction.NumDstRegs = num_dst_regs;
    instruction.NumSrcRegs = num_src_regs;
 
@@ -1061,6 +1063,7 @@ tgsi_build_full_instruction(
 
    *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode,
                                          full_inst->Instruction.Saturate,
+                                         full_inst->Instruction.Precise,
                                          full_inst->Instruction.NumDstRegs,
                                          full_inst->Instruction.NumSrcRegs,
                                          header);
src/gallium/auxiliary/tgsi/tgsi_ureg.c +11 -3
index 5bd779728a..56db2252c5 100644
@@ -1213,6 +1213,7 @@ struct ureg_emit_insn_result
 ureg_emit_insn(struct ureg_program *ureg,
                unsigned opcode,
                boolean saturate,
+               unsigned precise,
                unsigned num_dst,
                unsigned num_src)
 {
@@ -1226,6 +1227,7 @@ ureg_emit_insn(struct ureg_program *ureg,
    out[0].insn = tgsi_default_instruction();
    out[0].insn.Opcode = opcode;
    out[0].insn.Saturate = saturate;
+   out[0].insn.Precise = precise;
    out[0].insn.NumDstRegs = num_dst;
    out[0].insn.NumSrcRegs = num_src;
 
@@ -1354,7 +1356,8 @@ ureg_insn(struct ureg_program *ureg,
           const struct ureg_dst *dst,
           unsigned nr_dst,
           const struct ureg_src *src,
-          unsigned nr_src )
+          unsigned nr_src,
+          unsigned precise )
 {
    struct ureg_emit_insn_result insn;
    unsigned i;
@@ -1369,6 +1372,7 @@ ureg_insn(struct ureg_program *ureg,
    insn = ureg_emit_insn(ureg,
                          opcode,
                          saturate,
+                         precise,
                          nr_dst,
                          nr_src);
 
@@ -1391,7 +1395,8 @@ ureg_tex_insn(struct ureg_program *ureg,
               const struct tgsi_texture_offset *texoffsets,
               unsigned nr_offset,
               const struct ureg_src *src,
-              unsigned nr_src )
+              unsigned nr_src,
+              unsigned precise )
 {
    struct ureg_emit_insn_result insn;
    unsigned i;
@@ -1406,6 +1411,7 @@ ureg_tex_insn(struct ureg_program *ureg,
    insn = ureg_emit_insn(ureg,
                          opcode,
                          saturate,
+                         precise,
                          nr_dst,
                          nr_src);
 
@@ -1434,7 +1440,8 @@ ureg_memory_insn(struct ureg_program *ureg,
                  unsigned nr_src,
                  unsigned qualifier,
                  unsigned texture,
-                 unsigned format)
+                 unsigned format,
+                 unsigned precise)
 {
    struct ureg_emit_insn_result insn;
    unsigned i;
@@ -1442,6 +1449,7 @@ ureg_memory_insn(struct ureg_program *ureg,
    insn = ureg_emit_insn(ureg,
                          opcode,
                          FALSE,
+                         precise,
                          nr_dst,
                          nr_src);
 
src/gallium/auxiliary/tgsi/tgsi_ureg.h +17 -3
index 54f95ba565..105c85abd5 100644
@@ -546,7 +546,8 @@ ureg_insn(struct ureg_program *ureg,
           const struct ureg_dst *dst,
           unsigned nr_dst,
           const struct ureg_src *src,
-          unsigned nr_src );
+          unsigned nr_src,
+          unsigned precise);
 
 
 void
@@ -559,7 +560,8 @@ ureg_tex_insn(struct ureg_program *ureg,
               const struct tgsi_texture_offset *texoffsets,
               unsigned nr_offset,
               const struct ureg_src *src,
-              unsigned nr_src );
+              unsigned nr_src,
+              unsigned precise);
 
 
 void
@@ -571,7 +573,8 @@ ureg_memory_insn(struct ureg_program *ureg,
                  unsigned nr_src,
                  unsigned qualifier,
                  unsigned texture,
-                 unsigned format);
+                 unsigned format,
+                 unsigned precise);
 
 /***********************************************************************
  * Internal instruction helpers, don't call these directly:
@@ -586,6 +589,7 @@ struct ureg_emit_insn_result
 ureg_emit_insn(struct ureg_program *ureg,
                unsigned opcode,
                boolean saturate,
+               unsigned precise,
                unsigned num_dst,
                unsigned num_src);
 
@@ -632,6 +636,7 @@ static inline void ureg_##op( struct ureg_program *ureg )       \
                          opcode,                                \
                          FALSE,                                 \
                          0,                                     \
+                         0,                                     \
                          0);                                    \
    ureg_fixup_insn_size( ureg, insn.insn_token );               \
 }
@@ -646,6 +651,7 @@ static inline void ureg_##op( struct ureg_program *ureg,        \
                          opcode,                                \
                          FALSE,                                 \
                          0,                                     \
+                         0,                                     \
                          1);                                    \
    ureg_emit_src( ureg, src );                                  \
    ureg_fixup_insn_size( ureg, insn.insn_token );               \
@@ -661,6 +667,7 @@ static inline void ureg_##op( struct ureg_program *ureg,        \
                          opcode,                                \
                          FALSE,                                 \
                          0,                                     \
+                         0,                                     \
                          0);                                    \
    ureg_emit_label( ureg, insn.extended_token, label_token );   \
    ureg_fixup_insn_size( ureg, insn.insn_token );               \
@@ -677,6 +684,7 @@ static inline void ureg_##op( struct ureg_program *ureg,        \
                          opcode,                                \
                          FALSE,                                 \
                          0,                                     \
+                         0,                                     \
                          1);                                    \
    ureg_emit_label( ureg, insn.extended_token, label_token );   \
    ureg_emit_src( ureg, src );                                  \
@@ -694,6 +702,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
+                         0,                                             \
                          1,                                             \
                          0);                                            \
    ureg_emit_dst( ureg, dst );                                          \
@@ -713,6 +722,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
+                         0,                                             \
                          1,                                             \
                          1);                                            \
    ureg_emit_dst( ureg, dst );                                          \
@@ -733,6 +743,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
+                         0,                                             \
                          1,                                             \
                          2);                                            \
    ureg_emit_dst( ureg, dst );                                          \
@@ -756,6 +767,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
+                         0,                                             \
                          1,                                             \
                          2);                                            \
    ureg_emit_texture( ureg, insn.extended_token, target,                \
@@ -780,6 +792,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
+                         0,                                             \
                          1,                                             \
                          3);                                            \
    ureg_emit_dst( ureg, dst );                                          \
@@ -806,6 +819,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
+                         0,                                             \
                          1,                                             \
                          4);                                            \
    ureg_emit_texture( ureg, insn.extended_token, target,                \
src/gallium/auxiliary/util/u_simple_shaders.c +1 -1
index 5874d0e9aa..79331b5638 100644
@@ -954,7 +954,7 @@ util_make_geometry_passthrough_shader(struct pipe_context *pipe,
    }
 
    /* EMIT IMM[0] */
-   ureg_insn(ureg, TGSI_OPCODE_EMIT, NULL, 0, &imm, 1);
+   ureg_insn(ureg, TGSI_OPCODE_EMIT, NULL, 0, &imm, 1, 0);
 
    /* END */
    ureg_END(ureg);
src/gallium/state_trackers/nine/nine_shader.c +3 -3
index 40fb6be88f..f405090811 100644
@@ -1879,7 +1879,7 @@ DECL_SPECIAL(IFC)
     struct ureg_dst tmp = ureg_writemask(tx_scratch(tx), TGSI_WRITEMASK_X);
     src[0] = tx_src_param(tx, &tx->insn.src[0]);
     src[1] = tx_src_param(tx, &tx->insn.src[1]);
-    ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2);
+    ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2, 0);
     ureg_IF(tx->ureg, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), tx_cond(tx));
     return D3D_OK;
 }
@@ -1897,7 +1897,7 @@ DECL_SPECIAL(BREAKC)
     struct ureg_dst tmp = ureg_writemask(tx_scratch(tx), TGSI_WRITEMASK_X);
     src[0] = tx_src_param(tx, &tx->insn.src[0]);
     src[1] = tx_src_param(tx, &tx->insn.src[1]);
-    ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2);
+    ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2, 0);
     ureg_IF(tx->ureg, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), tx_cond(tx));
     ureg_BRK(tx->ureg);
     tx_endcond(tx);
@@ -3029,7 +3029,7 @@ NineTranslateInstruction_Generic(struct shader_translator *tx)
 
     ureg_insn(tx->ureg, tx->insn.info->opcode,
               dst, tx->insn.ndst,
-              src, tx->insn.nsrc);
+              src, tx->insn.nsrc, 0);
     return D3D_OK;
 }
 
src/mesa/state_tracker/st_atifs_to_tgsi.c +19 -19
index 338ced56ed..e0a6ff7131 100644
@@ -105,18 +105,18 @@ apply_swizzle(struct st_translate *t,
       imm[0] = src;
       imm[1] = ureg_imm4f(t->ureg, 1.0f, 1.0f, 0.0f, 0.0f);
       imm[2] = ureg_imm4f(t->ureg, 0.0f, 0.0f, 1.0f, 1.0f);
-      ureg_insn(t->ureg, TGSI_OPCODE_MAD, &tmp[0], 1, imm, 3);
+      ureg_insn(t->ureg, TGSI_OPCODE_MAD, &tmp[0], 1, imm, 3, 0);
 
       if (swizzle == GL_SWIZZLE_STR_DR_ATI) {
          imm[0] = ureg_scalar(src, TGSI_SWIZZLE_Z);
       } else {
          imm[0] = ureg_scalar(src, TGSI_SWIZZLE_W);
       }
-      ureg_insn(t->ureg, TGSI_OPCODE_RCP, &tmp[1], 1, &imm[0], 1);
+      ureg_insn(t->ureg, TGSI_OPCODE_RCP, &tmp[1], 1, &imm[0], 1, 0);
 
       imm[0] = ureg_src(tmp[0]);
       imm[1] = ureg_src(tmp[1]);
-      ureg_insn(t->ureg, TGSI_OPCODE_MUL, &tmp[0], 1, imm, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_MUL, &tmp[0], 1, imm, 2, 0);
 
       return ureg_src(tmp[0]);
    }
@@ -170,35 +170,35 @@ prepare_argument(struct st_translate *t, const unsigned argId,
       src = ureg_scalar(src, TGSI_SWIZZLE_W);
       break;
    }
-   ureg_insn(t->ureg, TGSI_OPCODE_MOV, &arg, 1, &src, 1);
+   ureg_insn(t->ureg, TGSI_OPCODE_MOV, &arg, 1, &src, 1, 0);
 
    if (srcReg->argMod & GL_COMP_BIT_ATI) {
       struct ureg_src modsrc[2];
       modsrc[0] = ureg_imm1f(t->ureg, 1.0f);
       modsrc[1] = ureg_negate(ureg_src(arg));
 
-      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2, 0);
    }
    if (srcReg->argMod & GL_BIAS_BIT_ATI) {
       struct ureg_src modsrc[2];
       modsrc[0] = ureg_src(arg);
       modsrc[1] = ureg_imm1f(t->ureg, -0.5f);
 
-      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2, 0);
    }
    if (srcReg->argMod & GL_2X_BIT_ATI) {
       struct ureg_src modsrc[2];
       modsrc[0] = ureg_src(arg);
       modsrc[1] = ureg_src(arg);
 
-      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2, 0);
    }
    if (srcReg->argMod & GL_NEGATE_BIT_ATI) {
       struct ureg_src modsrc[2];
       modsrc[0] = ureg_src(arg);
       modsrc[1] = ureg_imm1f(t->ureg, -1.0f);
 
-      ureg_insn(t->ureg, TGSI_OPCODE_MUL, &arg, 1, modsrc, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_MUL, &arg, 1, modsrc, 2, 0);
    }
    return  ureg_src(arg);
 }
@@ -217,25 +217,25 @@ emit_special_inst(struct st_translate *t, const struct instruction_desc *desc,
       tmp[0] = get_temp(t, MAX_NUM_FRAGMENT_REGISTERS_ATI + 2); /* re-purpose a3 */
       src[0] = ureg_imm1f(t->ureg, 0.5f);
       src[1] = ureg_negate(args[2]);
-      ureg_insn(t->ureg, TGSI_OPCODE_ADD, tmp, 1, src, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_ADD, tmp, 1, src, 2, 0);
       src[0] = ureg_src(tmp[0]);
       src[1] = args[0];
       src[2] = args[1];
-      ureg_insn(t->ureg, TGSI_OPCODE_CMP, dst, 1, src, 3);
+      ureg_insn(t->ureg, TGSI_OPCODE_CMP, dst, 1, src, 3, 0);
    } else if (!strcmp(desc->name, "CND0")) {
       src[0] = args[2];
       src[1] = args[1];
       src[2] = args[0];
-      ureg_insn(t->ureg, TGSI_OPCODE_CMP, dst, 1, src, 3);
+      ureg_insn(t->ureg, TGSI_OPCODE_CMP, dst, 1, src, 3, 0);
    } else if (!strcmp(desc->name, "DOT2_ADD")) {
       /* note: DP2A is not implemented in most pipe drivers */
       tmp[0] = get_temp(t, MAX_NUM_FRAGMENT_REGISTERS_ATI); /* re-purpose a1 */
       src[0] = args[0];
       src[1] = args[1];
-      ureg_insn(t->ureg, TGSI_OPCODE_DP2, tmp, 1, src, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_DP2, tmp, 1, src, 2, 0);
       src[0] = ureg_src(tmp[0]);
       src[1] = ureg_scalar(args[2], TGSI_SWIZZLE_Z);
-      ureg_insn(t->ureg, TGSI_OPCODE_ADD, dst, 1, src, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_ADD, dst, 1, src, 2, 0);
    }
 }
 
@@ -249,7 +249,7 @@ emit_arith_inst(struct st_translate *t,
       return;
    }
 
-   ureg_insn(t->ureg, desc->TGSI_opcode, dst, 1, args, argcount);
+   ureg_insn(t->ureg, desc->TGSI_opcode, dst, 1, args, argcount, 0);
 }
 
 static void
@@ -292,7 +292,7 @@ emit_dstmod(struct st_translate *t,
    if (dstMod & GL_SATURATE_BIT_ATI) {
       dst = ureg_saturate(dst);
    }
-   ureg_insn(t->ureg, TGSI_OPCODE_MUL, &dst, 1, src, 2);
+   ureg_insn(t->ureg, TGSI_OPCODE_MUL, &dst, 1, src, 2, 0);
 }
 
 /**
@@ -334,9 +334,9 @@ compile_setupinst(struct st_translate *t,
       src[1] = t->samplers[r];
       /* the texture target is still unknown, it will be fixed in the draw call */
       ureg_tex_insn(t->ureg, TGSI_OPCODE_TEX, dst, 1, TGSI_TEXTURE_2D,
-                    TGSI_RETURN_TYPE_FLOAT, NULL, 0, src, 2);
+                    TGSI_RETURN_TYPE_FLOAT, NULL, 0, src, 2, 0);
    } else if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
-      ureg_insn(t->ureg, TGSI_OPCODE_MOV, dst, 1, src, 1);
+      ureg_insn(t->ureg, TGSI_OPCODE_MOV, dst, 1, src, 1, 0);
    }
 
    t->regs_written[t->current_pass][r] = true;
@@ -408,11 +408,11 @@ finalize_shader(struct st_translate *t, unsigned numPasses)
       /* copy the result into the OUT slot */
       dst[0] = t->outputs[t->outputMapping[FRAG_RESULT_COLOR]];
       src[0] = ureg_src(t->temps[0]);
-      ureg_insn(t->ureg, TGSI_OPCODE_MOV, dst, 1, src, 1);
+      ureg_insn(t->ureg, TGSI_OPCODE_MOV, dst, 1, src, 1, 0);
    }
 
    /* signal the end of the program */
-   ureg_insn(t->ureg, TGSI_OPCODE_END, dst, 0, src, 0);
+   ureg_insn(t->ureg, TGSI_OPCODE_END, dst, 0, src, 0, 0);
 }
 
 /**
src/mesa/state_tracker/st_glsl_to_tgsi.cpp +6 -6
index 19f90f21fe..ecd9f9f280 100644
@@ -5900,7 +5900,7 @@ compile_tgsi_instruction(struct st_translate *t,
    case TGSI_OPCODE_IF:
    case TGSI_OPCODE_UIF:
       assert(num_dst == 0);
-      ureg_insn(ureg, inst->op, NULL, 0, src, num_src);
+      ureg_insn(ureg, inst->op, NULL, 0, src, num_src, inst->precise);
       return;
 
    case TGSI_OPCODE_TEX:
@@ -5935,7 +5935,7 @@ compile_tgsi_instruction(struct st_translate *t,
                     tex_target,
                     st_translate_texture_type(inst->tex_type),
                     texoffsets, inst->tex_offset_num_offset,
-                    src, num_src);
+                    src, num_src, inst->precise);
       return;
 
    case TGSI_OPCODE_RESQ:
@@ -5966,7 +5966,7 @@ compile_tgsi_instruction(struct st_translate *t,
       assert(src[0].File != TGSI_FILE_NULL);
       ureg_memory_insn(ureg, inst->op, dst, num_dst, src, num_src,
                        inst->buffer_access,
-                       tex_target, inst->image_format);
+                       tex_target, inst->image_format, inst->precise);
       break;
 
    case TGSI_OPCODE_STORE:
@@ -5984,19 +5984,19 @@ compile_tgsi_instruction(struct st_translate *t,
       assert(dst[0].File != TGSI_FILE_NULL);
       ureg_memory_insn(ureg, inst->op, dst, num_dst, src, num_src,
                        inst->buffer_access,
-                       tex_target, inst->image_format);
+                       tex_target, inst->image_format, inst->precise);
       break;
 
    case TGSI_OPCODE_SCS:
       dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY);
-      ureg_insn(ureg, inst->op, dst, num_dst, src, num_src);
+      ureg_insn(ureg, inst->op, dst, num_dst, src, num_src, inst->precise);
       break;
 
    default:
       ureg_insn(ureg,
                 inst->op,
                 dst, num_dst,
-                src, num_src);
+                src, num_src, inst->precise);
       break;
    }
 }
src/mesa/state_tracker/st_mesa_to_tgsi.c +4 -4
index 984ff92130..f11013c116 100644
@@ -558,7 +558,7 @@ compile_instruction(
                                                inst->TexShadow ),
                      TGSI_RETURN_TYPE_FLOAT,
                      NULL, 0,
-                     src, num_src );
+                     src, num_src, 0 );
       return;
 
    case OPCODE_SCS:
@@ -566,7 +566,7 @@ compile_instruction(
       ureg_insn( ureg, 
                  translate_opcode( inst->Opcode ), 
                  dst, num_dst, 
-                 src, num_src );
+                 src, num_src, 0 );
       break;
 
    case OPCODE_XPD:
@@ -574,7 +574,7 @@ compile_instruction(
       ureg_insn( ureg, 
                  translate_opcode( inst->Opcode ), 
                  dst, num_dst, 
-                 src, num_src );
+                 src, num_src, 0 );
       break;
 
    case OPCODE_RSQ:
@@ -593,7 +593,7 @@ compile_instruction(
       ureg_insn( ureg, 
                  translate_opcode( inst->Opcode ), 
                  dst, num_dst, 
-                 src, num_src );
+                 src, num_src, 0);
       break;
    }
 }
src/mesa/state_tracker/st_pbo.c +1 -1
index 303c8535b2..3dff1609e8 100644
@@ -528,7 +528,7 @@ create_fs(struct st_context *st, bool download, enum pipe_texture_target target,
       op[0] = ureg_src(temp0);
       op[1] = ureg_src(temp1);
       ureg_memory_insn(ureg, TGSI_OPCODE_STORE, &out, 1, op, 2, 0,
-                             TGSI_TEXTURE_BUFFER, PIPE_FORMAT_NONE);
+                             TGSI_TEXTURE_BUFFER, PIPE_FORMAT_NONE, 0);
 
       ureg_release_temporary(ureg, temp1);
    } else {
Signature · 6 lines
2.13.1

_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau

A message that is not in the archive (sent off-list or not yet received): 20170611184239.7204-5-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#6 lore raw

Re: [Mesa-dev] [RFC 4/9] tgsi: populate precise

Quoted 82 lines · Karol Herbst

Only implemented for glsl->tgsi. Other converters just set precise to 0.

---
  src/gallium/auxiliary/tgsi/tgsi_build.c       |  3 +++
  src/gallium/auxiliary/tgsi/tgsi_ureg.c        | 14 +++++++---
  src/gallium/auxiliary/tgsi/tgsi_ureg.h        | 20 +++++++++++---
  src/gallium/auxiliary/util/u_simple_shaders.c |  2 +-
  src/gallium/state_trackers/nine/nine_shader.c |  6 ++---
  src/mesa/state_tracker/st_atifs_to_tgsi.c     | 38 +++++++++++++--------------
  src/mesa/state_tracker/st_glsl_to_tgsi.cpp    | 12 ++++-----
  src/mesa/state_tracker/st_mesa_to_tgsi.c      |  8 +++---
  src/mesa/state_tracker/st_pbo.c               |  2 +-
  9 files changed, 65 insertions(+), 40 deletions(-)
src/gallium/auxiliary/tgsi/tgsi_build.c +3 -0
index 55e4d064ed..144a017768 100644
@@ -651,6 +651,7 @@ tgsi_default_instruction( void )
  static struct tgsi_instruction
  tgsi_build_instruction(unsigned opcode,
                         unsigned saturate,
+                       unsigned precise,
                         unsigned num_dst_regs,
                         unsigned num_src_regs,
                         struct tgsi_header *header)
@@ -665,6 +666,7 @@ tgsi_build_instruction(unsigned opcode,
     instruction = tgsi_default_instruction();
     instruction.Opcode = opcode;
     instruction.Saturate = saturate;
+   instruction.Precise = precise;
     instruction.NumDstRegs = num_dst_regs;
     instruction.NumSrcRegs = num_src_regs;
 
@@ -1061,6 +1063,7 @@ tgsi_build_full_instruction(
 
     *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode,
                                           full_inst->Instruction.Saturate,
+                                         full_inst->Instruction.Precise,
                                           full_inst->Instruction.NumDstRegs,
                                           full_inst->Instruction.NumSrcRegs,
                                           header);
src/gallium/auxiliary/tgsi/tgsi_ureg.c +5 -1
index 5bd779728a..56db2252c5 100644
@@ -1213,6 +1213,7 @@ struct ureg_emit_insn_result
  ureg_emit_insn(struct ureg_program *ureg,
                 unsigned opcode,
                 boolean saturate,
+               unsigned precise,
                 unsigned num_dst,
                 unsigned num_src)
  {
@@ -1226,6 +1227,7 @@ ureg_emit_insn(struct ureg_program *ureg,
     out[0].insn = tgsi_default_instruction();
     out[0].insn.Opcode = opcode;
     out[0].insn.Saturate = saturate;
+   out[0].insn.Precise = precise;
     out[0].insn.NumDstRegs = num_dst;
     out[0].insn.NumSrcRegs = num_src;
 
@@ -1354,7 +1356,8 @@ ureg_insn(struct ureg_program *ureg,
            const struct ureg_dst *dst,
            unsigned nr_dst,
            const struct ureg_src *src,
-          unsigned nr_src )
+          unsigned nr_src,
+          unsigned precise )
  {
     struct ureg_emit_insn_result insn;
     unsigned i;
@@ -1369,6 +1372,7 @@ ureg_insn(struct ureg_program *ureg,
     insn = ureg_emit_insn(ureg,
                           opcode,
                           saturate,
+                         precise,
                           nr_dst,
                           nr_src);
 

src/gallium/auxiliary/tgsi/tgsi_ureg.c ureg_tex_insn(struct ureg_program *ureg, · line 1399

Quoted 6 lines
src/gallium/auxiliary/tgsi/tgsi_ureg.c +2 -1
@@ -1391,7 +1395,8 @@ ureg_tex_insn(struct ureg_program *ureg,
                const struct tgsi_texture_offset *texoffsets,
                unsigned nr_offset,
                const struct ureg_src *src,
-              unsigned nr_src )
+              unsigned nr_src,
+              unsigned precise )

What does `precise' mean for tex instructions?

Quoted 12 lines
src/gallium/auxiliary/tgsi/tgsi_ureg.c +1 -0
  {
     struct ureg_emit_insn_result insn;
     unsigned i;
@@ -1406,6 +1411,7 @@ ureg_tex_insn(struct ureg_program *ureg,
     insn = ureg_emit_insn(ureg,
                           opcode,
                           saturate,
+                         precise,
                           nr_dst,
                           nr_src);
 

src/gallium/auxiliary/tgsi/tgsi_ureg.c ureg_memory_insn(struct ureg_program *ureg, · line 1444

Quoted 6 lines
src/gallium/auxiliary/tgsi/tgsi_ureg.c +2 -1
@@ -1434,7 +1440,8 @@ ureg_memory_insn(struct ureg_program *ureg,
                   unsigned nr_src,
                   unsigned qualifier,
                   unsigned texture,
-                 unsigned format)
+                 unsigned format,
+                 unsigned precise)

Same question. I can't think of a possible meaning, in which case the parameter should be dropped.

Cheers,
Nicolai

Quoted 427 lines
src/gallium/auxiliary/tgsi/tgsi_ureg.c +1 -0
  {
     struct ureg_emit_insn_result insn;
     unsigned i;
@@ -1442,6 +1449,7 @@ ureg_memory_insn(struct ureg_program *ureg,
     insn = ureg_emit_insn(ureg,
                           opcode,
                           FALSE,
+                         precise,
                           nr_dst,
                           nr_src);
 
src/gallium/auxiliary/tgsi/tgsi_ureg.h +17 -3
index 54f95ba565..105c85abd5 100644
@@ -546,7 +546,8 @@ ureg_insn(struct ureg_program *ureg,
            const struct ureg_dst *dst,
            unsigned nr_dst,
            const struct ureg_src *src,
-          unsigned nr_src );
+          unsigned nr_src,
+          unsigned precise);
 
 
  void
@@ -559,7 +560,8 @@ ureg_tex_insn(struct ureg_program *ureg,
                const struct tgsi_texture_offset *texoffsets,
                unsigned nr_offset,
                const struct ureg_src *src,
-              unsigned nr_src );
+              unsigned nr_src,
+              unsigned precise);
 
 
  void
@@ -571,7 +573,8 @@ ureg_memory_insn(struct ureg_program *ureg,
                   unsigned nr_src,
                   unsigned qualifier,
                   unsigned texture,
-                 unsigned format);
+                 unsigned format,
+                 unsigned precise);
 
  /***********************************************************************
   * Internal instruction helpers, don't call these directly:
@@ -586,6 +589,7 @@ struct ureg_emit_insn_result
  ureg_emit_insn(struct ureg_program *ureg,
                 unsigned opcode,
                 boolean saturate,
+               unsigned precise,
                 unsigned num_dst,
                 unsigned num_src);
 
@@ -632,6 +636,7 @@ static inline void ureg_##op( struct ureg_program *ureg )       \
                           opcode,                                \
                           FALSE,                                 \
                           0,                                     \
+                         0,                                     \
                           0);                                    \
     ureg_fixup_insn_size( ureg, insn.insn_token );               \
  }
@@ -646,6 +651,7 @@ static inline void ureg_##op( struct ureg_program *ureg,        \
                           opcode,                                \
                           FALSE,                                 \
                           0,                                     \
+                         0,                                     \
                           1);                                    \
     ureg_emit_src( ureg, src );                                  \
     ureg_fixup_insn_size( ureg, insn.insn_token );               \
@@ -661,6 +667,7 @@ static inline void ureg_##op( struct ureg_program *ureg,        \
                           opcode,                                \
                           FALSE,                                 \
                           0,                                     \
+                         0,                                     \
                           0);                                    \
     ureg_emit_label( ureg, insn.extended_token, label_token );   \
     ureg_fixup_insn_size( ureg, insn.insn_token );               \
@@ -677,6 +684,7 @@ static inline void ureg_##op( struct ureg_program *ureg,        \
                           opcode,                                \
                           FALSE,                                 \
                           0,                                     \
+                         0,                                     \
                           1);                                    \
     ureg_emit_label( ureg, insn.extended_token, label_token );   \
     ureg_emit_src( ureg, src );                                  \
@@ -694,6 +702,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
     insn = ureg_emit_insn(ureg,                                          \
                           opcode,                                        \
                           dst.Saturate,                                  \
+                         0,                                             \
                           1,                                             \
                           0);                                            \
     ureg_emit_dst( ureg, dst );                                          \
@@ -713,6 +722,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
     insn = ureg_emit_insn(ureg,                                          \
                           opcode,                                        \
                           dst.Saturate,                                  \
+                         0,                                             \
                           1,                                             \
                           1);                                            \
     ureg_emit_dst( ureg, dst );                                          \
@@ -733,6 +743,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
     insn = ureg_emit_insn(ureg,                                          \
                           opcode,                                        \
                           dst.Saturate,                                  \
+                         0,                                             \
                           1,                                             \
                           2);                                            \
     ureg_emit_dst( ureg, dst );                                          \
@@ -756,6 +767,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
     insn = ureg_emit_insn(ureg,                                          \
                           opcode,                                        \
                           dst.Saturate,                                  \
+                         0,                                             \
                           1,                                             \
                           2);                                            \
     ureg_emit_texture( ureg, insn.extended_token, target,                \
@@ -780,6 +792,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
     insn = ureg_emit_insn(ureg,                                          \
                           opcode,                                        \
                           dst.Saturate,                                  \
+                         0,                                             \
                           1,                                             \
                           3);                                            \
     ureg_emit_dst( ureg, dst );                                          \
@@ -806,6 +819,7 @@ static inline void ureg_##op( struct ureg_program *ureg,                \
     insn = ureg_emit_insn(ureg,                                          \
                           opcode,                                        \
                           dst.Saturate,                                  \
+                         0,                                             \
                           1,                                             \
                           4);                                            \
     ureg_emit_texture( ureg, insn.extended_token, target,                \
src/gallium/auxiliary/util/u_simple_shaders.c +1 -1
index 5874d0e9aa..79331b5638 100644
@@ -954,7 +954,7 @@ util_make_geometry_passthrough_shader(struct pipe_context *pipe,
     }
 
     /* EMIT IMM[0] */
-   ureg_insn(ureg, TGSI_OPCODE_EMIT, NULL, 0, &imm, 1);
+   ureg_insn(ureg, TGSI_OPCODE_EMIT, NULL, 0, &imm, 1, 0);
 
     /* END */
     ureg_END(ureg);
src/gallium/state_trackers/nine/nine_shader.c +3 -3
index 40fb6be88f..f405090811 100644
@@ -1879,7 +1879,7 @@ DECL_SPECIAL(IFC)
      struct ureg_dst tmp = ureg_writemask(tx_scratch(tx), TGSI_WRITEMASK_X);
      src[0] = tx_src_param(tx, &tx->insn.src[0]);
      src[1] = tx_src_param(tx, &tx->insn.src[1]);
-    ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2);
+    ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2, 0);
      ureg_IF(tx->ureg, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), tx_cond(tx));
      return D3D_OK;
  }
@@ -1897,7 +1897,7 @@ DECL_SPECIAL(BREAKC)
      struct ureg_dst tmp = ureg_writemask(tx_scratch(tx), TGSI_WRITEMASK_X);
      src[0] = tx_src_param(tx, &tx->insn.src[0]);
      src[1] = tx_src_param(tx, &tx->insn.src[1]);
-    ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2);
+    ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2, 0);
      ureg_IF(tx->ureg, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), tx_cond(tx));
      ureg_BRK(tx->ureg);
      tx_endcond(tx);
@@ -3029,7 +3029,7 @@ NineTranslateInstruction_Generic(struct shader_translator *tx)
 
      ureg_insn(tx->ureg, tx->insn.info->opcode,
                dst, tx->insn.ndst,
-              src, tx->insn.nsrc);
+              src, tx->insn.nsrc, 0);
      return D3D_OK;
  }
 
src/mesa/state_tracker/st_atifs_to_tgsi.c +19 -19
index 338ced56ed..e0a6ff7131 100644
@@ -105,18 +105,18 @@ apply_swizzle(struct st_translate *t,
        imm[0] = src;
        imm[1] = ureg_imm4f(t->ureg, 1.0f, 1.0f, 0.0f, 0.0f);
        imm[2] = ureg_imm4f(t->ureg, 0.0f, 0.0f, 1.0f, 1.0f);
-      ureg_insn(t->ureg, TGSI_OPCODE_MAD, &tmp[0], 1, imm, 3);
+      ureg_insn(t->ureg, TGSI_OPCODE_MAD, &tmp[0], 1, imm, 3, 0);
 
        if (swizzle == GL_SWIZZLE_STR_DR_ATI) {
           imm[0] = ureg_scalar(src, TGSI_SWIZZLE_Z);
        } else {
           imm[0] = ureg_scalar(src, TGSI_SWIZZLE_W);
        }
-      ureg_insn(t->ureg, TGSI_OPCODE_RCP, &tmp[1], 1, &imm[0], 1);
+      ureg_insn(t->ureg, TGSI_OPCODE_RCP, &tmp[1], 1, &imm[0], 1, 0);
 
        imm[0] = ureg_src(tmp[0]);
        imm[1] = ureg_src(tmp[1]);
-      ureg_insn(t->ureg, TGSI_OPCODE_MUL, &tmp[0], 1, imm, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_MUL, &tmp[0], 1, imm, 2, 0);
 
        return ureg_src(tmp[0]);
     }
@@ -170,35 +170,35 @@ prepare_argument(struct st_translate *t, const unsigned argId,
        src = ureg_scalar(src, TGSI_SWIZZLE_W);
        break;
     }
-   ureg_insn(t->ureg, TGSI_OPCODE_MOV, &arg, 1, &src, 1);
+   ureg_insn(t->ureg, TGSI_OPCODE_MOV, &arg, 1, &src, 1, 0);
 
     if (srcReg->argMod & GL_COMP_BIT_ATI) {
        struct ureg_src modsrc[2];
        modsrc[0] = ureg_imm1f(t->ureg, 1.0f);
        modsrc[1] = ureg_negate(ureg_src(arg));
 
-      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2, 0);
     }
     if (srcReg->argMod & GL_BIAS_BIT_ATI) {
        struct ureg_src modsrc[2];
        modsrc[0] = ureg_src(arg);
        modsrc[1] = ureg_imm1f(t->ureg, -0.5f);
 
-      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2, 0);
     }
     if (srcReg->argMod & GL_2X_BIT_ATI) {
        struct ureg_src modsrc[2];
        modsrc[0] = ureg_src(arg);
        modsrc[1] = ureg_src(arg);
 
-      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2, 0);
     }
     if (srcReg->argMod & GL_NEGATE_BIT_ATI) {
        struct ureg_src modsrc[2];
        modsrc[0] = ureg_src(arg);
        modsrc[1] = ureg_imm1f(t->ureg, -1.0f);
 
-      ureg_insn(t->ureg, TGSI_OPCODE_MUL, &arg, 1, modsrc, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_MUL, &arg, 1, modsrc, 2, 0);
     }
     return  ureg_src(arg);
  }
@@ -217,25 +217,25 @@ emit_special_inst(struct st_translate *t, const struct instruction_desc *desc,
        tmp[0] = get_temp(t, MAX_NUM_FRAGMENT_REGISTERS_ATI + 2); /* re-purpose a3 */
        src[0] = ureg_imm1f(t->ureg, 0.5f);
        src[1] = ureg_negate(args[2]);
-      ureg_insn(t->ureg, TGSI_OPCODE_ADD, tmp, 1, src, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_ADD, tmp, 1, src, 2, 0);
        src[0] = ureg_src(tmp[0]);
        src[1] = args[0];
        src[2] = args[1];
-      ureg_insn(t->ureg, TGSI_OPCODE_CMP, dst, 1, src, 3);
+      ureg_insn(t->ureg, TGSI_OPCODE_CMP, dst, 1, src, 3, 0);
     } else if (!strcmp(desc->name, "CND0")) {
        src[0] = args[2];
        src[1] = args[1];
        src[2] = args[0];
-      ureg_insn(t->ureg, TGSI_OPCODE_CMP, dst, 1, src, 3);
+      ureg_insn(t->ureg, TGSI_OPCODE_CMP, dst, 1, src, 3, 0);
     } else if (!strcmp(desc->name, "DOT2_ADD")) {
        /* note: DP2A is not implemented in most pipe drivers */
        tmp[0] = get_temp(t, MAX_NUM_FRAGMENT_REGISTERS_ATI); /* re-purpose a1 */
        src[0] = args[0];
        src[1] = args[1];
-      ureg_insn(t->ureg, TGSI_OPCODE_DP2, tmp, 1, src, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_DP2, tmp, 1, src, 2, 0);
        src[0] = ureg_src(tmp[0]);
        src[1] = ureg_scalar(args[2], TGSI_SWIZZLE_Z);
-      ureg_insn(t->ureg, TGSI_OPCODE_ADD, dst, 1, src, 2);
+      ureg_insn(t->ureg, TGSI_OPCODE_ADD, dst, 1, src, 2, 0);
     }
  }
 
@@ -249,7 +249,7 @@ emit_arith_inst(struct st_translate *t,
        return;
     }
 
-   ureg_insn(t->ureg, desc->TGSI_opcode, dst, 1, args, argcount);
+   ureg_insn(t->ureg, desc->TGSI_opcode, dst, 1, args, argcount, 0);
  }
 
  static void
@@ -292,7 +292,7 @@ emit_dstmod(struct st_translate *t,
     if (dstMod & GL_SATURATE_BIT_ATI) {
        dst = ureg_saturate(dst);
     }
-   ureg_insn(t->ureg, TGSI_OPCODE_MUL, &dst, 1, src, 2);
+   ureg_insn(t->ureg, TGSI_OPCODE_MUL, &dst, 1, src, 2, 0);
  }
 
  /**
@@ -334,9 +334,9 @@ compile_setupinst(struct st_translate *t,
        src[1] = t->samplers[r];
        /* the texture target is still unknown, it will be fixed in the draw call */
        ureg_tex_insn(t->ureg, TGSI_OPCODE_TEX, dst, 1, TGSI_TEXTURE_2D,
-                    TGSI_RETURN_TYPE_FLOAT, NULL, 0, src, 2);
+                    TGSI_RETURN_TYPE_FLOAT, NULL, 0, src, 2, 0);
     } else if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
-      ureg_insn(t->ureg, TGSI_OPCODE_MOV, dst, 1, src, 1);
+      ureg_insn(t->ureg, TGSI_OPCODE_MOV, dst, 1, src, 1, 0);
     }
 
     t->regs_written[t->current_pass][r] = true;
@@ -408,11 +408,11 @@ finalize_shader(struct st_translate *t, unsigned numPasses)
        /* copy the result into the OUT slot */
        dst[0] = t->outputs[t->outputMapping[FRAG_RESULT_COLOR]];
        src[0] = ureg_src(t->temps[0]);
-      ureg_insn(t->ureg, TGSI_OPCODE_MOV, dst, 1, src, 1);
+      ureg_insn(t->ureg, TGSI_OPCODE_MOV, dst, 1, src, 1, 0);
     }
 
     /* signal the end of the program */
-   ureg_insn(t->ureg, TGSI_OPCODE_END, dst, 0, src, 0);
+   ureg_insn(t->ureg, TGSI_OPCODE_END, dst, 0, src, 0, 0);
  }
 
  /**
src/mesa/state_tracker/st_glsl_to_tgsi.cpp +6 -6
index 19f90f21fe..ecd9f9f280 100644
@@ -5900,7 +5900,7 @@ compile_tgsi_instruction(struct st_translate *t,
     case TGSI_OPCODE_IF:
     case TGSI_OPCODE_UIF:
        assert(num_dst == 0);
-      ureg_insn(ureg, inst->op, NULL, 0, src, num_src);
+      ureg_insn(ureg, inst->op, NULL, 0, src, num_src, inst->precise);
        return;
 
     case TGSI_OPCODE_TEX:
@@ -5935,7 +5935,7 @@ compile_tgsi_instruction(struct st_translate *t,
                      tex_target,
                      st_translate_texture_type(inst->tex_type),
                      texoffsets, inst->tex_offset_num_offset,
-                    src, num_src);
+                    src, num_src, inst->precise);
        return;
 
     case TGSI_OPCODE_RESQ:
@@ -5966,7 +5966,7 @@ compile_tgsi_instruction(struct st_translate *t,
        assert(src[0].File != TGSI_FILE_NULL);
        ureg_memory_insn(ureg, inst->op, dst, num_dst, src, num_src,
                         inst->buffer_access,
-                       tex_target, inst->image_format);
+                       tex_target, inst->image_format, inst->precise);
        break;
 
     case TGSI_OPCODE_STORE:
@@ -5984,19 +5984,19 @@ compile_tgsi_instruction(struct st_translate *t,
        assert(dst[0].File != TGSI_FILE_NULL);
        ureg_memory_insn(ureg, inst->op, dst, num_dst, src, num_src,
                         inst->buffer_access,
-                       tex_target, inst->image_format);
+                       tex_target, inst->image_format, inst->precise);
        break;
 
     case TGSI_OPCODE_SCS:
        dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY);
-      ureg_insn(ureg, inst->op, dst, num_dst, src, num_src);
+      ureg_insn(ureg, inst->op, dst, num_dst, src, num_src, inst->precise);
        break;
 
     default:
        ureg_insn(ureg,
                  inst->op,
                  dst, num_dst,
-                src, num_src);
+                src, num_src, inst->precise);
        break;
     }
  }
src/mesa/state_tracker/st_mesa_to_tgsi.c +4 -4
index 984ff92130..f11013c116 100644
@@ -558,7 +558,7 @@ compile_instruction(
                                                 inst->TexShadow ),
                       TGSI_RETURN_TYPE_FLOAT,
                       NULL, 0,
-                     src, num_src );
+                     src, num_src, 0 );
        return;
 
     case OPCODE_SCS:
@@ -566,7 +566,7 @@ compile_instruction(
        ureg_insn( ureg,
                   translate_opcode( inst->Opcode ),
                   dst, num_dst,
-                 src, num_src );
+                 src, num_src, 0 );
        break;
 
     case OPCODE_XPD:
@@ -574,7 +574,7 @@ compile_instruction(
        ureg_insn( ureg,
                   translate_opcode( inst->Opcode ),
                   dst, num_dst,
-                 src, num_src );
+                 src, num_src, 0 );
        break;
 
     case OPCODE_RSQ:
@@ -593,7 +593,7 @@ compile_instruction(
        ureg_insn( ureg,
                   translate_opcode( inst->Opcode ),
                   dst, num_dst,
-                 src, num_src );
+                 src, num_src, 0);
        break;
     }
  }
src/mesa/state_tracker/st_pbo.c +1 -1
index 303c8535b2..3dff1609e8 100644
@@ -528,7 +528,7 @@ create_fs(struct st_context *st, bool download, enum pipe_texture_target target,
        op[0] = ureg_src(temp0);
        op[1] = ureg_src(temp1);
        ureg_memory_insn(ureg, TGSI_OPCODE_STORE, &out, 1, op, 2, 0,
-                             TGSI_TEXTURE_BUFFER, PIPE_FORMAT_NONE);
+                             TGSI_TEXTURE_BUFFER, PIPE_FORMAT_NONE, 0);
 
        ureg_release_temporary(ureg, temp1);
     } else {
Signature · 6 lines
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
#7 lore raw

RFC 5/9 tgsi/text: parse _PRECISE modifier

In reply to a message not in the archive
---
 src/gallium/auxiliary/tgsi/tgsi_text.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
src/gallium/auxiliary/tgsi/tgsi_text.c +13 -2
index 93a05568f4..c5fcb3283d 100644
@@ -999,6 +999,7 @@ parse_texoffset_operand(
 static boolean
 match_inst(const char **pcur,
            unsigned *saturate,
+           unsigned *precise,
            const struct tgsi_opcode_info *info)
 {
    const char *cur = *pcur;
@@ -1007,6 +1008,7 @@ match_inst(const char **pcur,
    if (str_match_nocase_whole(&cur, info->mnemonic)) {
       *pcur = cur;
       *saturate = 0;
+      *precise = 0;
       return TRUE;
    }
 
@@ -1015,8 +1017,15 @@ match_inst(const char **pcur,
       if (str_match_nocase_whole(&cur, "_SAT")) {
          *pcur = cur;
          *saturate = 1;
-         return TRUE;
       }
+
+      if (str_match_nocase_whole(&cur, "_PRECISE")) {
+         *pcur = cur;
+         *precise = 1;
+      }
+
+      if (*precise || *saturate)
+         return TRUE;
    }
 
    return FALSE;
@@ -1029,6 +1038,7 @@ parse_instruction(
 {
    uint i;
    uint saturate = 0;
+   uint precise = 0;
    const struct tgsi_opcode_info *info;
    struct tgsi_full_instruction inst;
    const char *cur;
@@ -1043,7 +1053,7 @@ parse_instruction(
       cur = ctx->cur;
 
       info = tgsi_get_opcode_info( i );
-      if (match_inst(&cur, &saturate, info)) {
+      if (match_inst(&cur, &saturate, &precise, info)) {
          if (info->num_dst + info->num_src + info->is_tex == 0) {
             ctx->cur = cur;
             break;
@@ -1064,6 +1074,7 @@ parse_instruction(
 
    inst.Instruction.Opcode = i;
    inst.Instruction.Saturate = saturate;
+   inst.Instruction.Precise = precise;
    inst.Instruction.NumDstRegs = info->num_dst;
    inst.Instruction.NumSrcRegs = info->num_src;
 
Signature · 6 lines
2.13.1

_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
#8 lore raw

Re: [RFC 5/9] tgsi/text: parse _PRECISE modifier

Quoted 26 lines · Karol Herbst
---
  src/gallium/auxiliary/tgsi/tgsi_text.c | 15 +++++++++++++--
  1 file changed, 13 insertions(+), 2 deletions(-)
src/gallium/auxiliary/tgsi/tgsi_text.c +2 -0
index 93a05568f4..c5fcb3283d 100644
@@ -999,6 +999,7 @@ parse_texoffset_operand(
  static boolean
  match_inst(const char **pcur,
             unsigned *saturate,
+           unsigned *precise,
             const struct tgsi_opcode_info *info)
  {
     const char *cur = *pcur;
@@ -1007,6 +1008,7 @@ match_inst(const char **pcur,
     if (str_match_nocase_whole(&cur, info->mnemonic)) {
        *pcur = cur;
        *saturate = 0;
+      *precise = 0;
        return TRUE;
     }
 

src/gallium/auxiliary/tgsi/tgsi_text.c match_inst(const char **pcur, · line 1025

Quoted 10 lines
src/gallium/auxiliary/tgsi/tgsi_text.c +5 -1
@@ -1015,8 +1017,15 @@ match_inst(const char **pcur,
        if (str_match_nocase_whole(&cur, "_SAT")) {
           *pcur = cur;
           *saturate = 1;
-         return TRUE;
        }
+
+      if (str_match_nocase_whole(&cur, "_PRECISE")) {
+         *pcur = cur;
+         *precise = 1;
+      }

I think this doesn't properly handle the case where both _SAT and _PRECISE are present, because of using str_match_nocase_whole.

Cheers,
Nicolai

Quoted 32 lines
src/gallium/auxiliary/tgsi/tgsi_text.c +6 -1
+
+      if (*precise || *saturate)
+         return TRUE;
     }
 
     return FALSE;
@@ -1029,6 +1038,7 @@ parse_instruction(
  {
     uint i;
     uint saturate = 0;
+   uint precise = 0;
     const struct tgsi_opcode_info *info;
     struct tgsi_full_instruction inst;
     const char *cur;
@@ -1043,7 +1053,7 @@ parse_instruction(
        cur = ctx->cur;
 
        info = tgsi_get_opcode_info( i );
-      if (match_inst(&cur, &saturate, info)) {
+      if (match_inst(&cur, &saturate, &precise, info)) {
           if (info->num_dst + info->num_src + info->is_tex == 0) {
              ctx->cur = cur;
              break;
@@ -1064,6 +1074,7 @@ parse_instruction(
 
     inst.Instruction.Opcode = i;
     inst.Instruction.Saturate = saturate;
+   inst.Instruction.Precise = precise;
     inst.Instruction.NumDstRegs = info->num_dst;
     inst.Instruction.NumSrcRegs = info->num_src;
 
Signature · 6 lines
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev
#9 lore raw

RFC 6/9 nv50/ir: add precise field to Instruction

In reply to a message not in the archive
---
 src/gallium/drivers/nouveau/codegen/nv50_ir.h | 1 +
 1 file changed, 1 insertion(+)
src/gallium/drivers/nouveau/codegen/nv50_ir.h +1 -0
index 5c09fed05c..6835c4fa8c 100644
@@ -884,6 +884,7 @@ public:
    unsigned perPatch   : 1;
    unsigned exit       : 1; // terminate program after insn
    unsigned mask       : 4; // for vector ops
+   unsigned precise    : 1; // prevent algebraic optimisations like mul+add to mad
 
    int8_t postFactor; // MUL/DIV(if < 0) by 1 << postFactor
 
Signature · 6 lines
2.13.1

_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
#10 lore raw

RFC 7/9 nv50/ir/tgsi: handle precise for most ALU instructions

In reply to a message not in the archive
---
 src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 2 ++
 1 file changed, 2 insertions(+)
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp +2 -0
index 1264dd4834..c633185893 100644
@@ -3179,6 +3179,7 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
          geni->subOp = tgsi::opcodeToSubOp(tgsi.getOpcode());
          if (op == OP_MUL && dstTy == TYPE_F32)
             geni->dnz = info->io.mul_zero_wins;
+         geni->precise = insn->Instruction.Precise;
       }
       break;
    case TGSI_OPCODE_MAD:
@@ -3192,6 +3193,7 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
          geni = mkOp3(op, dstTy, dst0[c], src0, src1, src2);
          if (dstTy == TYPE_F32)
             geni->dnz = info->io.mul_zero_wins;
+         geni->precise = insn->Instruction.Precise;
       }
       break;
    case TGSI_OPCODE_MOV:
Signature · 6 lines
2.13.1

_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
#11 lore raw

RFC 8/9 nv50/ir: disable mul+add to mad for precise instructions

In reply to a message not in the archive

fixes missrendering in TombRaider

---
 src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp +5 -1
index 4c92a1efb5..85f3f44832 100644
@@ -1669,6 +1669,10 @@ AlgebraicOpt::handleABS(Instruction *abs)
 bool
 AlgebraicOpt::handleADD(Instruction *add)
 {
+   // we can't optimize to SAD/MAD if the instruction is tagged as precise
+   if (add->precise)
+      return false;
+
    Value *src0 = add->getSrc(0);
    Value *src1 = add->getSrc(1);
 
@@ -1712,7 +1716,7 @@ AlgebraicOpt::tryADDToMADOrSAD(Instruction *add, operation toOp)
       return false;
 
    if (src->getInsn()->saturate || src->getInsn()->postFactor ||
-       src->getInsn()->dnz)
+       src->getInsn()->dnz || src->getInsn()->precise)
       return false;
 
    if (toOp == OP_SAD) {
Signature · 6 lines
2.13.1

_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
Reviewed-by
#12 lore raw
In reply to a message not in the archive
Quoted 6 lines · Karol Herbst

Running Tomb Raider on Nouveau I found some flicker caused by ignoring precise modifiers on variables inside Nouveau.

This series add precise/invariant handling to TGSI, which can be then used by drivers to disable certain unsafe optimisations which may otherwise alter calculations, which depend on having the same result across shaders.

It's kind of amazing that we got this far without doing this. On the radeonsi side, it's probably related to how conservative LLVM is.

But this series is a good idea, since it might allow us to become more aggressive with optimizations in radeonsi as well.

Quoted 5 lines

This series fixes this bug in Tomb Raider and one CTS test for 4.4 and 4.5

Note on Patch 3: I really dislike how I tell glsl_to_tgsi_visitor to apply the precise flag on instruction emited in ir_assignment->rhs->accept(); but I found no other easy way to handle this. Maybe somebody of you has a better idea?

Sent a suggestion, as well as comments on patches 4 & 5. Patches 1 & 2:

Quoted 29 lines

Karol Herbst (9):
tgsi: add precise flag to tgsi_instruction tgsi/dump: print _PRECISE modifier on Instrutions st/glsl_to_tgsi: handle precise modifier
tgsi: populate precise
tgsi/text: parse _PRECISE modifier
nv50/ir: add precise field to Instruction nv50/ir/tgsi: handle precise for most ALU instructions nv50/ir: disable mul+add to mad for precise instructions nv50/ir/tgsi: split mad to mul+add

  src/gallium/auxiliary/tgsi/tgsi_build.c            |  4 +
  src/gallium/auxiliary/tgsi/tgsi_dump.c             |  4 +
  src/gallium/auxiliary/tgsi/tgsi_text.c             | 15 +++-
  src/gallium/auxiliary/tgsi/tgsi_ureg.c             | 14 +++-
  src/gallium/auxiliary/tgsi/tgsi_ureg.h             | 20 ++++-
  src/gallium/auxiliary/util/u_simple_shaders.c      |  2 +-
  src/gallium/drivers/nouveau/codegen/nv50_ir.h      |  1 +
  .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp  | 16 ++++
  .../drivers/nouveau/codegen/nv50_ir_peephole.cpp   |  6 +-
  src/gallium/include/pipe/p_shader_tokens.h         |  3 +-
  src/gallium/state_trackers/nine/nine_shader.c      |  6 +-
  src/mesa/state_tracker/st_atifs_to_tgsi.c          | 38 ++++-----
  src/mesa/state_tracker/st_glsl_to_tgsi.cpp         | 92 +++++++++++++++++-----
  src/mesa/state_tracker/st_mesa_to_tgsi.c           |  8 +-
  src/mesa/state_tracker/st_pbo.c                    |  2 +-
  15 files changed, 172 insertions(+), 59 deletions(-)
Signature · 6 lines
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
Reviewed-by
#13 lore raw

This looks like the right idea to me too. It may sound a bit weird to do that per instruction, but d3d11 does that as well. (Some d3d versions just have a global flag basically forbidding or allowing any such fast math optimizations in the assembly, but I'm not actually sure everybody honors that without tesselation...)

For 1/9:

2/9 has a typo in the commit short log ("Instrutions").

FWIW surely on nv50 you could keep a single mad instruction for umad (sad maybe too?). (I'm actually wondering if the hw really can't do unfused float multiply+add as a single instruction but I know next to nothing about nvidia hw...)

Roland

Am 12.06.2017 um 12:42 schrieb Nicolai Hähnle:

Quoted 27 lines · Karol Herbst
Quoted 8 lines

Running Tomb Raider on Nouveau I found some flicker caused by ignoring precise
modifiers on variables inside Nouveau.

This series add precise/invariant handling to TGSI, which can be then used by
drivers to disable certain unsafe optimisations which may otherwise alter calculations, which depend on having the same result across shaders.

It's kind of amazing that we got this far without doing this. On the radeonsi side, it's probably related to how conservative LLVM is.

But this series is a good idea, since it might allow us to become more aggressive with optimizations in radeonsi as well.

Quoted 9 lines

This series fixes this bug in Tomb Raider and one CTS test for 4.4 and 4.5

Note on Patch 3: I really dislike how I tell glsl_to_tgsi_visitor to apply the
precise flag on instruction emited in ir_assignment->rhs->accept(); but I found
no other easy way to handle this. Maybe somebody of you has a better idea?

Quoted 37 lines

Sent a suggestion, as well as comments on patches 4 & 5. Patches 1 & 2:

Quoted 30 lines

Karol Herbst (9):
tgsi: add precise flag to tgsi_instruction tgsi/dump: print _PRECISE modifier on Instrutions st/glsl_to_tgsi: handle precise modifier
tgsi: populate precise
tgsi/text: parse _PRECISE modifier
nv50/ir: add precise field to Instruction nv50/ir/tgsi: handle precise for most ALU instructions nv50/ir: disable mul+add to mad for precise instructions nv50/ir/tgsi: split mad to mul+add

  src/gallium/auxiliary/tgsi/tgsi_build.c            |  4 +
  src/gallium/auxiliary/tgsi/tgsi_dump.c             |  4 +
  src/gallium/auxiliary/tgsi/tgsi_text.c             | 15 +++-
  src/gallium/auxiliary/tgsi/tgsi_ureg.c             | 14 +++-
  src/gallium/auxiliary/tgsi/tgsi_ureg.h             | 20 ++++-
  src/gallium/auxiliary/util/u_simple_shaders.c      |  2 +-
  src/gallium/drivers/nouveau/codegen/nv50_ir.h      |  1 +
  .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp  | 16 ++++
  .../drivers/nouveau/codegen/nv50_ir_peephole.cpp   |  6 +-
  src/gallium/include/pipe/p_shader_tokens.h         |  3 +-
  src/gallium/state_trackers/nine/nine_shader.c      |  6 +-
  src/mesa/state_tracker/st_atifs_to_tgsi.c          | 38 ++++-----
  src/mesa/state_tracker/st_glsl_to_tgsi.cpp         | 92
+++++++++++++++++-----
  src/mesa/state_tracker/st_mesa_to_tgsi.c           |  8 +-
  src/mesa/state_tracker/st_pbo.c                    |  2 +-
  15 files changed, 172 insertions(+), 59 deletions(-)

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

#14 lore raw

Am 13.06.2017 um 01:57 schrieb Roland Scheidegger:

Quoted 8 lines

This looks like the right idea to me too. It may sound a bit weird to do that per instruction, but d3d11 does that as well. (Some d3d versions just have a global flag basically forbidding or allowing any such fast math optimizations in the assembly, but I'm not actually sure everybody honors that without tesselation...)

For 1/9:

I forgot to mention, could you add some bits in gallium docs (source/tgsi.rst) for this? Not sure where maybe under Modifiers or some such.

Roland

Quoted 76 lines

2/9 has a typo in the commit short log ("Instrutions").

FWIW surely on nv50 you could keep a single mad instruction for umad (sad maybe too?). (I'm actually wondering if the hw really can't do unfused float multiply+add as a single instruction but I know next to nothing about nvidia hw...)

Roland

Am 12.06.2017 um 12:42 schrieb Nicolai Hähnle:

Quoted 64 lines · Karol Herbst
Quoted 8 lines

Running Tomb Raider on Nouveau I found some flicker caused by ignoring precise
modifiers on variables inside Nouveau.

This series add precise/invariant handling to TGSI, which can be then used by
drivers to disable certain unsafe optimisations which may otherwise alter calculations, which depend on having the same result across shaders.

It's kind of amazing that we got this far without doing this. On the radeonsi side, it's probably related to how conservative LLVM is.

But this series is a good idea, since it might allow us to become more aggressive with optimizations in radeonsi as well.

Quoted 9 lines

This series fixes this bug in Tomb Raider and one CTS test for 4.4 and 4.5

Note on Patch 3: I really dislike how I tell glsl_to_tgsi_visitor to apply the
precise flag on instruction emited in ir_assignment->rhs->accept(); but I found
no other easy way to handle this. Maybe somebody of you has a better idea?

Sent a suggestion, as well as comments on patches 4 & 5. Patches 1 & 2:

Quoted 30 lines

Karol Herbst (9):
tgsi: add precise flag to tgsi_instruction tgsi/dump: print _PRECISE modifier on Instrutions st/glsl_to_tgsi: handle precise modifier
tgsi: populate precise
tgsi/text: parse _PRECISE modifier
nv50/ir: add precise field to Instruction nv50/ir/tgsi: handle precise for most ALU instructions nv50/ir: disable mul+add to mad for precise instructions nv50/ir/tgsi: split mad to mul+add

  src/gallium/auxiliary/tgsi/tgsi_build.c            |  4 +
  src/gallium/auxiliary/tgsi/tgsi_dump.c             |  4 +
  src/gallium/auxiliary/tgsi/tgsi_text.c             | 15 +++-
  src/gallium/auxiliary/tgsi/tgsi_ureg.c             | 14 +++-
  src/gallium/auxiliary/tgsi/tgsi_ureg.h             | 20 ++++-
  src/gallium/auxiliary/util/u_simple_shaders.c      |  2 +-
  src/gallium/drivers/nouveau/codegen/nv50_ir.h      |  1 +
  .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp  | 16 ++++
  .../drivers/nouveau/codegen/nv50_ir_peephole.cpp   |  6 +-
  src/gallium/include/pipe/p_shader_tokens.h         |  3 +-
  src/gallium/state_trackers/nine/nine_shader.c      |  6 +-
  src/mesa/state_tracker/st_atifs_to_tgsi.c          | 38 ++++-----
  src/mesa/state_tracker/st_glsl_to_tgsi.cpp         | 92
+++++++++++++++++-----
  src/mesa/state_tracker/st_mesa_to_tgsi.c           |  8 +-
  src/mesa/state_tracker/st_pbo.c                    |  2 +-
  15 files changed, 172 insertions(+), 59 deletions(-)

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

A message that is not in the archive (sent off-list or not yet received): 8a99cdc6-c415-1423-dd1b-13a09f902288-pghWNbHTmq7QT0dZR+AlfA@public.gmane.org

#16 lore raw
Quoted 4 lines · Roland Scheidegger

FWIW surely on nv50 you could keep a single mad instruction for umad (sad maybe too?). (I'm actually wondering if the hw really can't do unfused float multiply+add as a single instruction but I know next to nothing about nvidia hw...)

The compiler should reassociate a mul + add into a mad where possible. In actuality, IMAD is actually super-slow... allegedly slower than IMUL + IADD. Not sure why. Maxwell added a XMAD operation which is faster but we haven't figured out how to operate it yet. I'm not aware of a muladd version of fma on fermi and newer (GL 4.0). The tesla series does have a floating point mul+add (but no fma).
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau

A message that is not in the archive (sent off-list or not yet received): CAKb7UviKiLbRG+z4paq8=-6epuWtKSxty2DHw6SQ1LZ+ULQgmw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org

#18 lore raw

Am 13.06.2017 um 02:05 schrieb Ilia Mirkin:

Quoted 6 lines · Roland Scheidegger
Quoted 4 lines

FWIW surely on nv50 you could keep a single mad instruction for umad (sad maybe too?). (I'm actually wondering if the hw really can't do unfused float multiply+add as a single instruction but I know next to nothing about nvidia hw...)

Quoted 7 lines

The compiler should reassociate a mul + add into a mad where possible. In actuality, IMAD is actually super-slow... allegedly slower than IMUL + IADD. Not sure why. Maxwell added a XMAD operation which is faster but we haven't figured out how to operate it yet. I'm not aware of a muladd version of fma on fermi and newer (GL 4.0). The tesla series does have a floating point mul+add (but no fma).

Interesting. radeons seem to always have a unfused mad. pre-gcn parts apparently only have a 32bit fma with parts supporting double precision. The same restriction is stated for gcn parts in the isa docs, which obviously doesn't make sense, but I have no idea if the fma is full speed...

Roland
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau

A message that is not in the archive (sent off-list or not yet received): 6ffa13fd-c90b-bda6-b243-13c4857346f7-pghWNbHTmq7QT0dZR+AlfA@public.gmane.org

#20 lore raw
Quoted 15 lines · Roland Scheidegger

Am 13.06.2017 um 02:05 schrieb Ilia Mirkin:

Quoted 6 lines · Roland Scheidegger
Quoted 4 lines

FWIW surely on nv50 you could keep a single mad instruction for umad (sad maybe too?). (I'm actually wondering if the hw really can't do unfused float multiply+add as a single instruction but I know next to nothing about nvidia hw...)

Quoted 7 lines

The compiler should reassociate a mul + add into a mad where possible. In actuality, IMAD is actually super-slow... allegedly slower than IMUL + IADD. Not sure why. Maxwell added a XMAD operation which is faster but we haven't figured out how to operate it yet. I'm not aware of a muladd version of fma on fermi and newer (GL 4.0). The tesla series does have a floating point mul+add (but no fma).

Quoted 4 lines

Interesting. radeons seem to always have a unfused mad. pre-gcn parts apparently only have a 32bit fma with parts supporting double precision. The same restriction is stated for gcn parts in the isa docs, which obviously doesn't make sense, but I have no idea if the fma is full speed...

fma is full-rate on Tahiti and Hawaii and quarter-rate on other GCN chips. FP64 opcodes are always 2x or 4x slower than fma_f32.

Marek
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau

#21 lore raw

RFC 3/9 st/glsl_to_tgsi: handle precise modifier

In reply to Karol Herbst

all subexpression inside an ir_assignment needs to be tagged as precise.

---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 80 ++++++++++++++++++++++++------
 1 file changed, 65 insertions(+), 15 deletions(-)
src/mesa/state_tracker/st_glsl_to_tgsi.cpp +65 -15
index c5d2e0fcd2..19f90f21fe 100644
@@ -87,6 +87,13 @@ static int swizzle_for_type(const glsl_type *type, int component = 0)
    return swizzle;
 }
 
+static unsigned is_precise(const ir_variable *ir)
+{
+   if (!ir)
+      return 0;
+   return ir->data.precise || ir->data.invariant;
+}
+
 /**
  * This struct is a corresponding struct to TGSI ureg_src.
  */
@@ -296,6 +303,7 @@ public:
    ir_instruction *ir;
 
    unsigned op:8; /**< TGSI opcode */
+   unsigned precise:1;
    unsigned saturate:1;
    unsigned is_64bit_expanded:1;
    unsigned sampler_base:5;
@@ -435,6 +443,7 @@ public:
    bool have_fma;
    bool use_shared_memory;
    bool has_tex_txf_lz;
+   unsigned precise;
 
    variable_storage *find_variable_storage(ir_variable *var);
 
@@ -505,13 +514,29 @@ public:
                                       st_src_reg src0 = undef_src,
                                       st_src_reg src1 = undef_src,
                                       st_src_reg src2 = undef_src,
-                                      st_src_reg src3 = undef_src);
+                                      st_src_reg src3 = undef_src,
+                                      unsigned precise = 0);
 
    glsl_to_tgsi_instruction *emit_asm(ir_instruction *ir, unsigned op,
                                       st_dst_reg dst, st_dst_reg dst1,
                                       st_src_reg src0 = undef_src,
                                       st_src_reg src1 = undef_src,
                                       st_src_reg src2 = undef_src,
+                                      st_src_reg src3 = undef_src,
+                                      unsigned precise = 0);
+
+   glsl_to_tgsi_instruction *emit_asm(ir_expression *ir, unsigned op,
+                                      st_dst_reg dst = undef_dst,
+                                      st_src_reg src0 = undef_src,
+                                      st_src_reg src1 = undef_src,
+                                      st_src_reg src2 = undef_src,
+                                      st_src_reg src3 = undef_src);
+
+   glsl_to_tgsi_instruction *emit_asm(ir_expression *ir, unsigned op,
+                                      st_dst_reg dst, st_dst_reg dst1,
+                                      st_src_reg src0 = undef_src,
+                                      st_src_reg src1 = undef_src,
+                                      st_src_reg src2 = undef_src,
                                       st_src_reg src3 = undef_src);
 
    unsigned get_opcode(unsigned op,
@@ -650,7 +675,8 @@ glsl_to_tgsi_instruction *
 glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
                                st_dst_reg dst, st_dst_reg dst1,
                                st_src_reg src0, st_src_reg src1,
-                               st_src_reg src2, st_src_reg src3)
+                               st_src_reg src2, st_src_reg src3,
+                               unsigned precise)
 {
    glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction();
    int num_reladdr = 0, i, j;
@@ -691,6 +717,7 @@ glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
    STATIC_ASSERT(TGSI_OPCODE_LAST <= 255);
 
    inst->op = op;
+   inst->precise = precise;
    inst->info = tgsi_get_opcode_info(op);
    inst->dst[0] = dst;
    inst->dst[1] = dst1;
@@ -881,9 +908,28 @@ glsl_to_tgsi_instruction *
 glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
                                st_dst_reg dst,
                                st_src_reg src0, st_src_reg src1,
+                               st_src_reg src2, st_src_reg src3,
+                               unsigned precise)
+{
+   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3, precise);
+}
+
+glsl_to_tgsi_instruction *
+glsl_to_tgsi_visitor::emit_asm(ir_expression *ir, unsigned op,
+                               st_dst_reg dst,
+                               st_src_reg src0, st_src_reg src1,
+                               st_src_reg src2, st_src_reg src3)
+{
+   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3, this->precise);
+}
+
+glsl_to_tgsi_instruction *
+glsl_to_tgsi_visitor::emit_asm(ir_expression *ir, unsigned op,
+                               st_dst_reg dst, st_dst_reg dst1,
+                               st_src_reg src0, st_src_reg src1,
                                st_src_reg src2, st_src_reg src3)
 {
-   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3);
+   return emit_asm(ir, op, dst, dst1, src0, src1, src2, src3, this->precise);
 }
 
 /**
@@ -1116,7 +1162,7 @@ glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
    if (dst.index >= this->num_address_regs)
       this->num_address_regs = dst.index + 1;
 
-   emit_asm(NULL, op, dst, src0);
+   emit_asm((ir_instruction *)NULL, op, dst, src0);
 }
 
 int
@@ -1406,11 +1452,11 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
 void
 glsl_to_tgsi_visitor::visit(ir_loop *ir)
 {
-   emit_asm(NULL, TGSI_OPCODE_BGNLOOP);
+   emit_asm((ir_instruction *)NULL, TGSI_OPCODE_BGNLOOP);
 
    visit_exec_list(&ir->body_instructions, this);
 
-   emit_asm(NULL, TGSI_OPCODE_ENDLOOP);
+   emit_asm((ir_instruction *)NULL, TGSI_OPCODE_ENDLOOP);
 }
 
 void
@@ -1418,10 +1464,10 @@ glsl_to_tgsi_visitor::visit(ir_loop_jump *ir)
 {
    switch (ir->mode) {
    case ir_loop_jump::jump_break:
-      emit_asm(NULL, TGSI_OPCODE_BRK);
+      emit_asm((ir_instruction *)NULL, TGSI_OPCODE_BRK);
       break;
    case ir_loop_jump::jump_continue:
-      emit_asm(NULL, TGSI_OPCODE_CONT);
+      emit_asm((ir_instruction *)NULL, TGSI_OPCODE_CONT);
       break;
    }
 }
@@ -2703,7 +2749,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
             st_dst_reg dst = st_dst_reg(get_temp(var->type));
             st_src_reg src = st_src_reg(PROGRAM_OUTPUT, decl->mesa_index,
                                         var->type, component, decl->array_id);
-            emit_asm(NULL, TGSI_OPCODE_FBFETCH, dst, src);
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_FBFETCH, dst, src);
             entry = new(mem_ctx) variable_storage(var, dst.file, dst.index,
                                                   dst.array_id);
          } else {
@@ -3148,7 +3194,10 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir)
    st_dst_reg l;
    st_src_reg r;
 
+   /* all generated instructions need to be flaged as precise */
+   this->precise = is_precise(ir->lhs->variable_referenced());
    ir->rhs->accept(this);
+   this->precise = 0;
    r = this->result;
 
    l = get_assignment_lhs(ir->lhs, this, &dst_component);
@@ -3233,7 +3282,8 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir)
        */
       glsl_to_tgsi_instruction *inst, *new_inst;
       inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail();
-      new_inst = emit_asm(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2], inst->src[3]);
+      new_inst = emit_asm(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2], inst->src[3],
+                          is_precise(ir->lhs->variable_referenced()));
       new_inst->saturate = inst->saturate;
       inst->dead_mask = inst->dst[0].writemask;
    } else {
@@ -4072,16 +4122,16 @@ glsl_to_tgsi_visitor::calc_deref_offsets(ir_dereference *tail,
 
          deref_arr->array_index->accept(this);
          if (*array_elements != 1)
-            emit_asm(NULL, TGSI_OPCODE_MUL, temp_dst, this->result, st_src_reg_for_int(*array_elements));
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_MUL, temp_dst, this->result, st_src_reg_for_int(*array_elements));
          else
-            emit_asm(NULL, TGSI_OPCODE_MOV, temp_dst, this->result);
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_MOV, temp_dst, this->result);
 
          if (indirect->file == PROGRAM_UNDEFINED)
             *indirect = temp_reg;
          else {
             temp_dst = st_dst_reg(*indirect);
             temp_dst.writemask = 1;
-            emit_asm(NULL, TGSI_OPCODE_ADD, temp_dst, *indirect, temp_reg);
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_ADD, temp_dst, *indirect, temp_reg);
          }
       } else
          *index += array_index->value.u[0] * *array_elements;
@@ -4141,7 +4191,7 @@ glsl_to_tgsi_visitor::canonicalize_gather_offset(st_src_reg offset)
       st_src_reg tmp = get_temp(glsl_type::ivec2_type);
       st_dst_reg tmp_dst = st_dst_reg(tmp);
       tmp_dst.writemask = WRITEMASK_XY;
-      emit_asm(NULL, TGSI_OPCODE_MOV, tmp_dst, offset);
+      emit_asm((ir_instruction *)NULL, TGSI_OPCODE_MOV, tmp_dst, offset);
       return tmp;
    }
 
@@ -6777,7 +6827,7 @@ get_mesa_program_tgsi(struct gl_context *ctx,
    v->renumber_registers();
 
    /* Write the END instruction. */
-   v->emit_asm(NULL, TGSI_OPCODE_END);
+   v->emit_asm((ir_instruction *)NULL, TGSI_OPCODE_END);
 
    if (ctx->_Shader->Flags & GLSL_DUMP) {
       _mesa_log("\n");
Signature · 6 lines
2.13.1

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

A message that is not in the archive (sent off-list or not yet received): 20170611184239.7204-4-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#23 lore raw

Re: [Mesa-dev] [RFC 3/9] st/glsl_to_tgsi: handle precise modifier

Quoted 60 lines · Karol Herbst

all subexpression inside an ir_assignment needs to be tagged as precise.

---
  src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 80 ++++++++++++++++++++++++------
  1 file changed, 65 insertions(+), 15 deletions(-)
src/mesa/state_tracker/st_glsl_to_tgsi.cpp +17 -1
index c5d2e0fcd2..19f90f21fe 100644
@@ -87,6 +87,13 @@ static int swizzle_for_type(const glsl_type *type, int component = 0)
     return swizzle;
  }
 
+static unsigned is_precise(const ir_variable *ir)
+{
+   if (!ir)
+      return 0;
+   return ir->data.precise || ir->data.invariant;
+}
+
  /**
   * This struct is a corresponding struct to TGSI ureg_src.
   */
@@ -296,6 +303,7 @@ public:
     ir_instruction *ir;
 
     unsigned op:8; /**< TGSI opcode */
+   unsigned precise:1;
     unsigned saturate:1;
     unsigned is_64bit_expanded:1;
     unsigned sampler_base:5;
@@ -435,6 +443,7 @@ public:
     bool have_fma;
     bool use_shared_memory;
     bool has_tex_txf_lz;
+   unsigned precise;
 
     variable_storage *find_variable_storage(ir_variable *var);
 
@@ -505,13 +514,29 @@ public:
                                        st_src_reg src0 = undef_src,
                                        st_src_reg src1 = undef_src,
                                        st_src_reg src2 = undef_src,
-                                      st_src_reg src3 = undef_src);
+                                      st_src_reg src3 = undef_src,
+                                      unsigned precise = 0);
 
     glsl_to_tgsi_instruction *emit_asm(ir_instruction *ir, unsigned op,
                                        st_dst_reg dst, st_dst_reg dst1,
                                        st_src_reg src0 = undef_src,
                                        st_src_reg src1 = undef_src,
                                        st_src_reg src2 = undef_src,
+                                      st_src_reg src3 = undef_src,
+                                      unsigned precise = 0);
+
+   glsl_to_tgsi_instruction *emit_asm(ir_expression *ir, unsigned op,
+                                      st_dst_reg dst = undef_dst,
+                                      st_src_reg src0 = undef_src,

src/mesa/state_tracker/st_glsl_to_tgsi.cpp public: · line 540

Quoted 10 lines
src/mesa/state_tracker/st_glsl_to_tgsi.cpp +9 -0
+                                      st_src_reg src1 = undef_src,
+                                      st_src_reg src2 = undef_src,
+                                      st_src_reg src3 = undef_src);
+
+   glsl_to_tgsi_instruction *emit_asm(ir_expression *ir, unsigned op,
+                                      st_dst_reg dst, st_dst_reg dst1,
+                                      st_src_reg src0 = undef_src,
+                                      st_src_reg src1 = undef_src,
+                                      st_src_reg src2 = undef_src,
                                        st_src_reg src3 = undef_src);

Yeah, I don't like those overloads and the way they force you to add artificial casts for disambiguation.

I'd suggest to embrace the global precise flag: drop the precise parameter from emit_asm, and just source the bit from this->precise.

Please make precise a bool, and add a comment explaining that it's a flag for whether the currently evaluated expression should be precise.

Cheers,
Nicolai

Quoted 154 lines
src/mesa/state_tracker/st_glsl_to_tgsi.cpp +39 -14
     unsigned get_opcode(unsigned op,
@@ -650,7 +675,8 @@ glsl_to_tgsi_instruction *
  glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
                                 st_dst_reg dst, st_dst_reg dst1,
                                 st_src_reg src0, st_src_reg src1,
-                               st_src_reg src2, st_src_reg src3)
+                               st_src_reg src2, st_src_reg src3,
+                               unsigned precise)
  {
     glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction();
     int num_reladdr = 0, i, j;
@@ -691,6 +717,7 @@ glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
     STATIC_ASSERT(TGSI_OPCODE_LAST <= 255);
 
     inst->op = op;
+   inst->precise = precise;
     inst->info = tgsi_get_opcode_info(op);
     inst->dst[0] = dst;
     inst->dst[1] = dst1;
@@ -881,9 +908,28 @@ glsl_to_tgsi_instruction *
  glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
                                 st_dst_reg dst,
                                 st_src_reg src0, st_src_reg src1,
+                               st_src_reg src2, st_src_reg src3,
+                               unsigned precise)
+{
+   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3, precise);
+}
+
+glsl_to_tgsi_instruction *
+glsl_to_tgsi_visitor::emit_asm(ir_expression *ir, unsigned op,
+                               st_dst_reg dst,
+                               st_src_reg src0, st_src_reg src1,
+                               st_src_reg src2, st_src_reg src3)
+{
+   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3, this->precise);
+}
+
+glsl_to_tgsi_instruction *
+glsl_to_tgsi_visitor::emit_asm(ir_expression *ir, unsigned op,
+                               st_dst_reg dst, st_dst_reg dst1,
+                               st_src_reg src0, st_src_reg src1,
                                 st_src_reg src2, st_src_reg src3)
  {
-   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3);
+   return emit_asm(ir, op, dst, dst1, src0, src1, src2, src3, this->precise);
  }
 
  /**
@@ -1116,7 +1162,7 @@ glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
     if (dst.index >= this->num_address_regs)
        this->num_address_regs = dst.index + 1;
 
-   emit_asm(NULL, op, dst, src0);
+   emit_asm((ir_instruction *)NULL, op, dst, src0);
  }
 
  int
@@ -1406,11 +1452,11 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
  void
  glsl_to_tgsi_visitor::visit(ir_loop *ir)
  {
-   emit_asm(NULL, TGSI_OPCODE_BGNLOOP);
+   emit_asm((ir_instruction *)NULL, TGSI_OPCODE_BGNLOOP);
 
     visit_exec_list(&ir->body_instructions, this);
 
-   emit_asm(NULL, TGSI_OPCODE_ENDLOOP);
+   emit_asm((ir_instruction *)NULL, TGSI_OPCODE_ENDLOOP);
  }
 
  void
@@ -1418,10 +1464,10 @@ glsl_to_tgsi_visitor::visit(ir_loop_jump *ir)
  {
     switch (ir->mode) {
     case ir_loop_jump::jump_break:
-      emit_asm(NULL, TGSI_OPCODE_BRK);
+      emit_asm((ir_instruction *)NULL, TGSI_OPCODE_BRK);
        break;
     case ir_loop_jump::jump_continue:
-      emit_asm(NULL, TGSI_OPCODE_CONT);
+      emit_asm((ir_instruction *)NULL, TGSI_OPCODE_CONT);
        break;
     }
  }
@@ -2703,7 +2749,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
              st_dst_reg dst = st_dst_reg(get_temp(var->type));
              st_src_reg src = st_src_reg(PROGRAM_OUTPUT, decl->mesa_index,
                                          var->type, component, decl->array_id);
-            emit_asm(NULL, TGSI_OPCODE_FBFETCH, dst, src);
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_FBFETCH, dst, src);
              entry = new(mem_ctx) variable_storage(var, dst.file, dst.index,
                                                    dst.array_id);
           } else {
@@ -3148,7 +3194,10 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir)
     st_dst_reg l;
     st_src_reg r;
 
+   /* all generated instructions need to be flaged as precise */
+   this->precise = is_precise(ir->lhs->variable_referenced());
     ir->rhs->accept(this);
+   this->precise = 0;
     r = this->result;
 
     l = get_assignment_lhs(ir->lhs, this, &dst_component);
@@ -3233,7 +3282,8 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir)
         */
        glsl_to_tgsi_instruction *inst, *new_inst;
        inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail();
-      new_inst = emit_asm(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2], inst->src[3]);
+      new_inst = emit_asm(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2], inst->src[3],
+                          is_precise(ir->lhs->variable_referenced()));
        new_inst->saturate = inst->saturate;
        inst->dead_mask = inst->dst[0].writemask;
     } else {
@@ -4072,16 +4122,16 @@ glsl_to_tgsi_visitor::calc_deref_offsets(ir_dereference *tail,
 
           deref_arr->array_index->accept(this);
           if (*array_elements != 1)
-            emit_asm(NULL, TGSI_OPCODE_MUL, temp_dst, this->result, st_src_reg_for_int(*array_elements));
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_MUL, temp_dst, this->result, st_src_reg_for_int(*array_elements));
           else
-            emit_asm(NULL, TGSI_OPCODE_MOV, temp_dst, this->result);
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_MOV, temp_dst, this->result);
 
           if (indirect->file == PROGRAM_UNDEFINED)
              *indirect = temp_reg;
           else {
              temp_dst = st_dst_reg(*indirect);
              temp_dst.writemask = 1;
-            emit_asm(NULL, TGSI_OPCODE_ADD, temp_dst, *indirect, temp_reg);
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_ADD, temp_dst, *indirect, temp_reg);
           }
        } else
           *index += array_index->value.u[0] * *array_elements;
@@ -4141,7 +4191,7 @@ glsl_to_tgsi_visitor::canonicalize_gather_offset(st_src_reg offset)
        st_src_reg tmp = get_temp(glsl_type::ivec2_type);
        st_dst_reg tmp_dst = st_dst_reg(tmp);
        tmp_dst.writemask = WRITEMASK_XY;
-      emit_asm(NULL, TGSI_OPCODE_MOV, tmp_dst, offset);
+      emit_asm((ir_instruction *)NULL, TGSI_OPCODE_MOV, tmp_dst, offset);
        return tmp;
     }
 
@@ -6777,7 +6827,7 @@ get_mesa_program_tgsi(struct gl_context *ctx,
     v->renumber_registers();
 
     /* Write the END instruction. */
-   v->emit_asm(NULL, TGSI_OPCODE_END);
+   v->emit_asm((ir_instruction *)NULL, TGSI_OPCODE_END);
 
     if (ctx->_Shader->Flags & GLSL_DUMP) {
        _mesa_log("\n");
Signature · 6 lines
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
#24 lore raw

RFC 9/9 nv50/ir/tgsi: split mad to mul+add

In reply to Karol Herbst

fixes
KHR-GL44.gpu_shader5.precise_qualifier
KHR-GL45.gpu_shader5.precise_qualifier

---
 src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp +14 -0
index c633185893..cd45e82426 100644
@@ -3184,6 +3184,20 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
       break;
    case TGSI_OPCODE_MAD:
    case TGSI_OPCODE_UMAD:
+      FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) {
+         val0 = getSSA();
+         src0 = fetchSrc(0, c);
+         src1 = fetchSrc(1, c);
+         src2 = fetchSrc(2, c);
+         geni = mkOp2(OP_MUL, dstTy, val0, src0, src1);
+         if (dstTy == TYPE_F32)
+            geni->dnz = info->io.mul_zero_wins;
+         geni->precise = insn->Instruction.Precise;
+
+         geni = mkOp2(OP_ADD, dstTy, dst0[c], val0, src2);
+         geni->precise = insn->Instruction.Precise;
+      }
+      break;
    case TGSI_OPCODE_SAD:
    case TGSI_OPCODE_FMA:
       FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) {
Signature · 6 lines
2.13.1

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev