tgsi: fix mixed data type comparison in tgsi_point_sprite.c
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_scan.c
index 65bdab5b1cd51fa9ed19576c6ee71781bf81b6af..1baf031d73e42ffd133a2e67e2ec86dfa86c3249 100644 (file)
@@ -54,6 +54,20 @@ is_memory_file(unsigned file)
 }
 
 
+/**
+ * Is the opcode a "true" texture instruction which samples from a
+ * texture map?
+ */
+static bool
+is_texture_inst(unsigned opcode)
+{
+   return (opcode != TGSI_OPCODE_TXQ &&
+           opcode != TGSI_OPCODE_TXQS &&
+           opcode != TGSI_OPCODE_TXQ_LZ &&
+           opcode != TGSI_OPCODE_LODQ &&
+           tgsi_get_opcode_info(opcode)->is_tex);
+}
+
 static void
 scan_instruction(struct tgsi_shader_info *info,
                  const struct tgsi_full_instruction *fullinst,
@@ -149,7 +163,7 @@ scan_instruction(struct tgsi_shader_info *info,
             info->input_usage_mask[ind] |= usage_mask;
          }
 
-         if (info->processor == TGSI_PROCESSOR_FRAGMENT &&
+         if (info->processor == PIPE_SHADER_FRAGMENT &&
              !src->Register.Indirect) {
             unsigned name =
                info->input_semantic_name[src->Register.Index];
@@ -181,25 +195,48 @@ scan_instruction(struct tgsi_shader_info *info,
          info->indirect_files_read |= (1 << src->Register.File);
       }
 
-      /* MSAA samplers */
+      /* Texture samplers */
       if (src->Register.File == TGSI_FILE_SAMPLER) {
-         assert(fullinst->Instruction.Texture);
-         assert(src->Register.Index < Elements(info->is_msaa_sampler));
+         const unsigned index = src->Register.Index;
 
-         if (fullinst->Instruction.Texture &&
-             (fullinst->Texture.Texture == TGSI_TEXTURE_2D_MSAA ||
-              fullinst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY_MSAA)) {
-            info->is_msaa_sampler[src->Register.Index] = TRUE;
+         assert(fullinst->Instruction.Texture);
+         assert(index < ARRAY_SIZE(info->is_msaa_sampler));
+         assert(index < PIPE_MAX_SAMPLERS);
+
+         if (is_texture_inst(fullinst->Instruction.Opcode)) {
+            const unsigned target = fullinst->Texture.Texture;
+            assert(target < TGSI_TEXTURE_UNKNOWN);
+            /* for texture instructions, check that the texture instruction
+             * target matches the previous sampler view declaration (if there
+             * was one.)
+             */
+            if (info->sampler_targets[index] == TGSI_TEXTURE_UNKNOWN) {
+               /* probably no sampler view declaration */
+               info->sampler_targets[index] = target;
+            } else {
+               /* Make sure the texture instruction's sampler/target info
+                * agrees with the sampler view declaration.
+                */
+               assert(info->sampler_targets[index] == target);
+            }
+            /* MSAA samplers */
+            if (target == TGSI_TEXTURE_2D_MSAA ||
+                target == TGSI_TEXTURE_2D_ARRAY_MSAA) {
+               info->is_msaa_sampler[src->Register.Index] = TRUE;
+            }
          }
       }
 
       if (is_memory_file(src->Register.File)) {
          is_mem_inst = true;
 
-         if (src->Register.File == TGSI_FILE_IMAGE &&
-             !src->Register.Indirect &&
-             tgsi_get_opcode_info(fullinst->Instruction.Opcode)->is_store)
-            info->images_writemask |= 1 << src->Register.Index;
+         if (tgsi_get_opcode_info(fullinst->Instruction.Opcode)->is_store) {
+            info->writes_memory = TRUE;
+
+            if (src->Register.File == TGSI_FILE_IMAGE &&
+                !src->Register.Indirect)
+               info->images_writemask |= 1 << src->Register.Index;
+         }
       }
    }
 
@@ -215,6 +252,7 @@ scan_instruction(struct tgsi_shader_info *info,
          assert(fullinst->Instruction.Opcode == TGSI_OPCODE_STORE);
 
          is_mem_inst = true;
+         info->writes_memory = TRUE;
 
          if (dst->Register.File == TGSI_FILE_IMAGE &&
              !dst->Register.Indirect)
@@ -282,7 +320,7 @@ scan_declaration(struct tgsi_shader_info *info,
          info->input_cylindrical_wrap[reg] = (ubyte)fulldecl->Interp.CylindricalWrap;
 
          /* Vertex shaders can have inputs with holes between them. */
-         if (info->processor == TGSI_PROCESSOR_VERTEX)
+         if (info->processor == PIPE_SHADER_VERTEX)
             info->num_inputs = MAX2(info->num_inputs, reg + 1);
          else {
             info->num_inputs++;
@@ -298,8 +336,7 @@ scan_declaration(struct tgsi_shader_info *info,
              semName == TGSI_SEMANTIC_COLOR ||
              semName == TGSI_SEMANTIC_BCOLOR ||
              semName == TGSI_SEMANTIC_FOG ||
-             semName == TGSI_SEMANTIC_CLIPDIST ||
-             semName == TGSI_SEMANTIC_CULLDIST) {
+             semName == TGSI_SEMANTIC_CLIPDIST) {
             switch (fulldecl->Interp.Interpolate) {
             case TGSI_INTERPOLATE_COLOR:
             case TGSI_INTERPOLATE_PERSPECTIVE:
@@ -334,7 +371,7 @@ scan_declaration(struct tgsi_shader_info *info,
 
          if (semName == TGSI_SEMANTIC_PRIMID)
             info->uses_primid = TRUE;
-         else if (procType == TGSI_PROCESSOR_FRAGMENT) {
+         else if (procType == PIPE_SHADER_FRAGMENT) {
             if (semName == TGSI_SEMANTIC_POSITION)
                info->reads_position = TRUE;
             else if (semName == TGSI_SEMANTIC_FACE)
@@ -386,10 +423,10 @@ scan_declaration(struct tgsi_shader_info *info,
          if (semName == TGSI_SEMANTIC_COLOR)
             info->colors_written |= 1 << semIndex;
 
-         if (procType == TGSI_PROCESSOR_VERTEX ||
-             procType == TGSI_PROCESSOR_GEOMETRY ||
-             procType == TGSI_PROCESSOR_TESS_CTRL ||
-             procType == TGSI_PROCESSOR_TESS_EVAL) {
+         if (procType == PIPE_SHADER_VERTEX ||
+             procType == PIPE_SHADER_GEOMETRY ||
+             procType == PIPE_SHADER_TESS_CTRL ||
+             procType == PIPE_SHADER_TESS_EVAL) {
             switch (semName) {
             case TGSI_SEMANTIC_VIEWPORT_INDEX:
                info->writes_viewport_index = TRUE;
@@ -406,7 +443,7 @@ scan_declaration(struct tgsi_shader_info *info,
             }
          }
 
-         if (procType == TGSI_PROCESSOR_FRAGMENT) {
+         if (procType == PIPE_SHADER_FRAGMENT) {
             switch (semName) {
             case TGSI_SEMANTIC_POSITION:
                info->writes_z = TRUE;
@@ -420,13 +457,24 @@ scan_declaration(struct tgsi_shader_info *info,
             }
          }
 
-         if (procType == TGSI_PROCESSOR_VERTEX) {
+         if (procType == PIPE_SHADER_VERTEX) {
             if (semName == TGSI_SEMANTIC_EDGEFLAG) {
                info->writes_edgeflag = TRUE;
             }
          }
       } else if (file == TGSI_FILE_SAMPLER) {
-         info->samplers_declared |= 1 << reg;
+         STATIC_ASSERT(sizeof(info->samplers_declared) * 8 >= PIPE_MAX_SAMPLERS);
+         info->samplers_declared |= 1u << reg;
+      } else if (file == TGSI_FILE_SAMPLER_VIEW) {
+         unsigned target = fulldecl->SamplerView.Resource;
+         assert(target < TGSI_TEXTURE_UNKNOWN);
+         if (info->sampler_targets[reg] == TGSI_TEXTURE_UNKNOWN) {
+            /* Save sampler target for this sampler index */
+            info->sampler_targets[reg] = target;
+         } else {
+            /* if previously declared, make sure targets agree */
+            assert(info->sampler_targets[reg] == target);
+         }
       } else if (file == TGSI_FILE_IMAGE) {
          if (fulldecl->Image.Resource == TGSI_TEXTURE_BUFFER)
             info->images_buffers |= 1 << reg;
@@ -454,7 +502,7 @@ scan_property(struct tgsi_shader_info *info,
    unsigned name = fullprop->Property.PropertyName;
    unsigned value = fullprop->u[0].Data;
 
-   assert(name < Elements(info->properties));
+   assert(name < ARRAY_SIZE(info->properties));
    info->properties[name] = value;
 
    switch (name) {
@@ -486,9 +534,11 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
    memset(info, 0, sizeof(*info));
    for (i = 0; i < TGSI_FILE_COUNT; i++)
       info->file_max[i] = -1;
-   for (i = 0; i < Elements(info->const_file_max); i++)
+   for (i = 0; i < ARRAY_SIZE(info->const_file_max); i++)
       info->const_file_max[i] = -1;
    info->properties[TGSI_PROPERTY_GS_INVOCATIONS] = 1;
+   for (i = 0; i < ARRAY_SIZE(info->sampler_targets); i++)
+      info->sampler_targets[i] = TGSI_TEXTURE_UNKNOWN;
 
    /**
     ** Setup to begin parsing input shader
@@ -498,12 +548,12 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
       return;
    }
    procType = parse.FullHeader.Processor.Processor;
-   assert(procType == TGSI_PROCESSOR_FRAGMENT ||
-          procType == TGSI_PROCESSOR_VERTEX ||
-          procType == TGSI_PROCESSOR_GEOMETRY ||
-          procType == TGSI_PROCESSOR_TESS_CTRL ||
-          procType == TGSI_PROCESSOR_TESS_EVAL ||
-          procType == TGSI_PROCESSOR_COMPUTE);
+   assert(procType == PIPE_SHADER_FRAGMENT ||
+          procType == PIPE_SHADER_VERTEX ||
+          procType == PIPE_SHADER_GEOMETRY ||
+          procType == PIPE_SHADER_TESS_CTRL ||
+          procType == PIPE_SHADER_TESS_EVAL ||
+          procType == PIPE_SHADER_COMPUTE);
    info->processor = procType;
 
    /**
@@ -539,7 +589,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
    /* The dimensions of the IN decleration in geometry shader have
     * to be deduced from the type of the input primitive.
     */
-   if (procType == TGSI_PROCESSOR_GEOMETRY) {
+   if (procType == PIPE_SHADER_GEOMETRY) {
       unsigned input_primitive =
             info->properties[TGSI_PROPERTY_GS_INPUT_PRIM];
       int num_verts = u_vertices_per_prim(input_primitive);