tgsi: Prevent emission of instructions with empty writemask.
authorJosé Fonseca <jfonseca@vmware.com>
Thu, 21 Nov 2013 13:11:30 +0000 (13:11 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Fri, 22 Nov 2013 15:03:36 +0000 (15:03 +0000)
These degenerate instructions can often be emitted by state trackers
when the semantics of instructions don't match precisely.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/auxiliary/tgsi/tgsi_ureg.c
src/gallium/auxiliary/tgsi/tgsi_ureg.h

index 432ed00c71511d15f42ccdfc4609804d1c840ff3..f06858ef1775023a89668bf04e42d901583befc6 100644 (file)
@@ -1113,6 +1113,10 @@ ureg_insn(struct ureg_program *ureg,
    boolean negate = FALSE;
    unsigned swizzle[4] = { 0 };
 
+   if (nr_dst && ureg_dst_is_empty(dst[0])) {
+      return;
+   }
+
    saturate = nr_dst ? dst[0].Saturate : FALSE;
    predicate = nr_dst ? dst[0].Predicate : FALSE;
    if (predicate) {
@@ -1162,6 +1166,10 @@ ureg_tex_insn(struct ureg_program *ureg,
    boolean negate = FALSE;
    unsigned swizzle[4] = { 0 };
 
+   if (nr_dst && ureg_dst_is_empty(dst[0])) {
+      return;
+   }
+
    saturate = nr_dst ? dst[0].Saturate : FALSE;
    predicate = nr_dst ? dst[0].Predicate : FALSE;
    if (predicate) {
index cf0c75ef476386045785bf709e848d98b5a06140..e22598413aeef8da987e3dedd993b89c9cb3da7a 100644 (file)
@@ -454,6 +454,16 @@ ureg_imm1i( struct ureg_program *ureg,
    return ureg_DECL_immediate_int( ureg, &a, 1 );
 }
 
+/* Where the destination register has a valid file, but an empty
+ * writemask.
+ */
+static INLINE boolean
+ureg_dst_is_empty( struct ureg_dst dst )
+{
+   return dst.File != TGSI_FILE_NULL &&
+          dst.WriteMask == 0;
+}
+
 /***********************************************************************
  * Functions for patching up labels
  */
@@ -650,6 +660,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
 {                                                                       \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -673,6 +685,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
 {                                                                       \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -697,6 +711,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
 {                                                                       \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -723,6 +739,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
 {                                                                       \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -750,6 +768,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -777,6 +797,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
 {                                                                       \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -805,6 +827,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -835,6 +859,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
 {                                                                       \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -866,6 +892,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -897,6 +925,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
 {                                                                       \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -928,6 +958,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
 {                                                                       \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \
@@ -960,6 +992,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
    unsigned opcode = TGSI_OPCODE_##op;                                  \
    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
    struct ureg_emit_insn_result insn;                                   \
+   if (ureg_dst_is_empty(dst))                                          \
+      return;                                                           \
    insn = ureg_emit_insn(ureg,                                          \
                          opcode,                                        \
                          dst.Saturate,                                  \