tgsi: use TGSI_INTERPOLATE_x arguments instead of zeros in ureg code
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_scan.c
index b8932891e4cc768df2c64317ded43a113a915927..989c57ebeed51d9b1fa7cb0525096b3412dbb0d8 100644 (file)
@@ -107,7 +107,7 @@ scan_src_operand(struct tgsi_shader_info *info,
                  const struct tgsi_full_instruction *fullinst,
                  const struct tgsi_full_src_register *src,
                  unsigned src_index,
-                 unsigned usage_mask,
+                 unsigned usage_mask_after_swizzle,
                  bool is_interp_instruction,
                  bool *is_mem_inst)
 {
@@ -115,24 +115,21 @@ scan_src_operand(struct tgsi_shader_info *info,
 
    if (info->processor == PIPE_SHADER_COMPUTE &&
        src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
-      unsigned swizzle[4], i, name;
+      unsigned name, mask;
 
       name = info->system_value_semantic_name[src->Register.Index];
-      swizzle[0] = src->Register.SwizzleX;
-      swizzle[1] = src->Register.SwizzleY;
-      swizzle[2] = src->Register.SwizzleZ;
-      swizzle[3] = src->Register.SwizzleW;
 
       switch (name) {
       case TGSI_SEMANTIC_THREAD_ID:
       case TGSI_SEMANTIC_BLOCK_ID:
-         for (i = 0; i < 4; i++) {
-            if (swizzle[i] <= TGSI_SWIZZLE_Z) {
-               if (name == TGSI_SEMANTIC_THREAD_ID)
-                  info->uses_thread_id[swizzle[i]] = true;
-               else
-                  info->uses_block_id[swizzle[i]] = true;
-            }
+         mask = usage_mask_after_swizzle & TGSI_WRITEMASK_XYZ;
+         while (mask) {
+            unsigned i = u_bit_scan(&mask);
+
+            if (name == TGSI_SEMANTIC_THREAD_ID)
+               info->uses_thread_id[i] = true;
+            else
+               info->uses_block_id[i] = true;
          }
          break;
       case TGSI_SEMANTIC_BLOCK_SIZE:
@@ -150,12 +147,12 @@ scan_src_operand(struct tgsi_shader_info *info,
    if (src->Register.File == TGSI_FILE_INPUT) {
       if (src->Register.Indirect) {
          for (ind = 0; ind < info->num_inputs; ++ind) {
-            info->input_usage_mask[ind] |= usage_mask;
+            info->input_usage_mask[ind] |= usage_mask_after_swizzle;
          }
       } else {
          assert(ind >= 0);
          assert(ind < PIPE_MAX_SHADER_INPUTS);
-         info->input_usage_mask[ind] |= usage_mask;
+         info->input_usage_mask[ind] |= usage_mask_after_swizzle;
       }
 
       if (info->processor == PIPE_SHADER_FRAGMENT) {
@@ -170,21 +167,11 @@ scan_src_operand(struct tgsi_shader_info *info,
          index = info->input_semantic_index[input];
 
          if (name == TGSI_SEMANTIC_POSITION &&
-             (src->Register.SwizzleX == TGSI_SWIZZLE_Z ||
-              src->Register.SwizzleY == TGSI_SWIZZLE_Z ||
-              src->Register.SwizzleZ == TGSI_SWIZZLE_Z ||
-              src->Register.SwizzleW == TGSI_SWIZZLE_Z))
-            info->reads_z = TRUE;
-
-         if (name == TGSI_SEMANTIC_COLOR) {
-            unsigned mask =
-               (1 << src->Register.SwizzleX) |
-               (1 << src->Register.SwizzleY) |
-               (1 << src->Register.SwizzleZ) |
-               (1 << src->Register.SwizzleW);
-
-            info->colors_read |= mask << (index * 4);
-         }
+             usage_mask_after_swizzle & TGSI_WRITEMASK_Z)
+            info->reads_z = true;
+
+         if (name == TGSI_SEMANTIC_COLOR)
+            info->colors_read |= usage_mask_after_swizzle << (index * 4);
 
          /* Process only interpolated varyings. Don't include POSITION.
           * Don't include integer varyings, because they are not
@@ -471,6 +458,29 @@ scan_instruction(struct tgsi_shader_info *info,
       scan_src_operand(info, fullinst, &fullinst->Src[i], i,
                        tgsi_util_get_inst_usage_mask(fullinst, i),
                        is_interp_instruction, &is_mem_inst);
+
+      if (fullinst->Src[i].Register.Indirect) {
+         struct tgsi_full_src_register src = {{0}};
+
+         src.Register.File = fullinst->Src[i].Indirect.File;
+         src.Register.Index = fullinst->Src[i].Indirect.Index;
+
+         scan_src_operand(info, fullinst, &src, -1,
+                          1 << fullinst->Src[i].Indirect.Swizzle,
+                          false, NULL);
+      }
+
+      if (fullinst->Src[i].Register.Dimension &&
+          fullinst->Src[i].Dimension.Indirect) {
+         struct tgsi_full_src_register src = {{0}};
+
+         src.Register.File = fullinst->Src[i].DimIndirect.File;
+         src.Register.Index = fullinst->Src[i].DimIndirect.Index;
+
+         scan_src_operand(info, fullinst, &src, -1,
+                          1 << fullinst->Src[i].DimIndirect.Swizzle,
+                          false, NULL);
+      }
    }
 
    if (fullinst->Instruction.Texture) {
@@ -479,12 +489,12 @@ scan_instruction(struct tgsi_shader_info *info,
 
          src.Register.File = fullinst->TexOffsets[i].File;
          src.Register.Index = fullinst->TexOffsets[i].Index;
-         src.Register.SwizzleX = fullinst->TexOffsets[i].SwizzleX;
-         src.Register.SwizzleY = fullinst->TexOffsets[i].SwizzleY;
-         src.Register.SwizzleZ = fullinst->TexOffsets[i].SwizzleZ;
 
          /* The usage mask is suboptimal but should be safe. */
-         scan_src_operand(info, fullinst, &src, 0, TGSI_WRITEMASK_XYZ,
+         scan_src_operand(info, fullinst, &src, -1,
+                          (1 << fullinst->TexOffsets[i].SwizzleX) |
+                          (1 << fullinst->TexOffsets[i].SwizzleY) |
+                          (1 << fullinst->TexOffsets[i].SwizzleZ),
                           false, &is_mem_inst);
       }
    }
@@ -492,13 +502,31 @@ scan_instruction(struct tgsi_shader_info *info,
    /* check for indirect register writes */
    for (i = 0; i < fullinst->Instruction.NumDstRegs; i++) {
       const struct tgsi_full_dst_register *dst = &fullinst->Dst[i];
+
       if (dst->Register.Indirect) {
+         struct tgsi_full_src_register src = {{0}};
+
+         src.Register.File = dst->Indirect.File;
+         src.Register.Index = dst->Indirect.Index;
+
+         scan_src_operand(info, fullinst, &src, -1,
+                          1 << dst->Indirect.Swizzle, false, NULL);
+
          info->indirect_files |= (1 << dst->Register.File);
          info->indirect_files_written |= (1 << dst->Register.File);
       }
 
-      if (dst->Register.Dimension && dst->Dimension.Indirect)
+      if (dst->Register.Dimension && dst->Dimension.Indirect) {
+         struct tgsi_full_src_register src = {{0}};
+
+         src.Register.File = dst->DimIndirect.File;
+         src.Register.Index = dst->DimIndirect.Index;
+
+         scan_src_operand(info, fullinst, &src, -1,
+                          1 << dst->DimIndirect.Swizzle, false, NULL);
+
          info->dim_indirect_files |= 1u << dst->Register.File;
+      }
 
       if (is_memory_file(dst->Register.File)) {
          assert(fullinst->Instruction.Opcode == TGSI_OPCODE_STORE);
@@ -1139,7 +1167,6 @@ tgsi_scan_tess_ctrl(const struct tgsi_token *tokens,
          if (main_block_tf_writemask || cond_block_tf_writemask) {
             /* Accumulate the result: */
             out->tessfactors_are_def_in_all_invocs &=
-               main_block_tf_writemask &&
                !(cond_block_tf_writemask & ~main_block_tf_writemask);
 
             /* Analyze the next code segment from scratch. */
@@ -1155,7 +1182,6 @@ tgsi_scan_tess_ctrl(const struct tgsi_token *tokens,
    /* Accumulate the result for the last code segment separated by a barrier. */
    if (main_block_tf_writemask || cond_block_tf_writemask) {
       out->tessfactors_are_def_in_all_invocs &=
-         main_block_tf_writemask &&
          !(cond_block_tf_writemask & ~main_block_tf_writemask);
    }