[Mesa-dev] [PATCH 03/23] glsl: Add helper methods to glsl_type for dealing with images.

Francisco Jerez currojerez at riseup.net
Tue Nov 26 00:02:19 PST 2013


Add predicates to query if a GLSL type is or contains an image.
Rename sampler_coordinate_components() to coordinate_components() and
fix it to support calculating the number of coordinate dimensions of
image types as well as sampler types.
---
 src/glsl/builtin_functions.cpp        |  2 +-
 src/glsl/glsl_types.cpp               | 95 +++++++++++++++++++++++++----------
 src/glsl/glsl_types.h                 | 19 ++++++-
 src/glsl/tests/sampler_types_test.cpp |  2 +-
 4 files changed, 88 insertions(+), 30 deletions(-)

diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp
index 8cb75e5..a1a338d 100644
--- a/src/glsl/builtin_functions.cpp
+++ b/src/glsl/builtin_functions.cpp
@@ -3488,7 +3488,7 @@ builtin_builder::_texture(ir_texture_opcode opcode,
    ir_texture *tex = new(mem_ctx) ir_texture(opcode);
    tex->set_sampler(var_ref(s), return_type);
 
-   const int coord_size = sampler_type->sampler_coordinate_components();
+   const int coord_size = sampler_type->coordinate_components();
 
    if (coord_size == coord_type->vector_elements) {
       tex->coordinate = var_ref(P);
diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index e24417d..8a6b531 100644
--- a/src/glsl/glsl_types.cpp
+++ b/src/glsl/glsl_types.cpp
@@ -236,6 +236,21 @@ glsl_type::sampler_index() const
    }
 }
 
+bool
+glsl_type::contains_image() const
+{
+   if (this->is_array()) {
+      return this->fields.array->contains_image();
+   } else if (this->is_record()) {
+      for (unsigned int i = 0; i < this->length; i++) {
+	 if (this->fields.structure[i].type->contains_image())
+	    return true;
+      }
+      return false;
+   } else {
+      return this->is_image();
+   }
+}
 
 const glsl_type *glsl_type::get_base_type() const
 {
@@ -943,36 +958,64 @@ glsl_type::count_attribute_slots() const
 }
 
 int
-glsl_type::sampler_coordinate_components() const
+glsl_type::coordinate_components() const
 {
-   assert(is_sampler());
-
    int size;
 
-   switch (sampler_dimensionality) {
-   case GLSL_SAMPLER_DIM_1D:
-   case GLSL_SAMPLER_DIM_BUF:
-      size = 1;
-      break;
-   case GLSL_SAMPLER_DIM_2D:
-   case GLSL_SAMPLER_DIM_RECT:
-   case GLSL_SAMPLER_DIM_MS:
-   case GLSL_SAMPLER_DIM_EXTERNAL:
-      size = 2;
-      break;
-   case GLSL_SAMPLER_DIM_3D:
-   case GLSL_SAMPLER_DIM_CUBE:
-      size = 3;
-      break;
-   default:
-      assert(!"Should not get here.");
-      size = 1;
-      break;
-   }
+   if (is_sampler()) {
+      switch (sampler_dimensionality) {
+      case GLSL_SAMPLER_DIM_1D:
+      case GLSL_SAMPLER_DIM_BUF:
+         size = 1;
+         break;
+      case GLSL_SAMPLER_DIM_2D:
+      case GLSL_SAMPLER_DIM_RECT:
+      case GLSL_SAMPLER_DIM_MS:
+      case GLSL_SAMPLER_DIM_EXTERNAL:
+         size = 2;
+         break;
+      case GLSL_SAMPLER_DIM_3D:
+      case GLSL_SAMPLER_DIM_CUBE:
+         size = 3;
+         break;
+      default:
+         assert(!"Should not get here.");
+         size = 1;
+         break;
+      }
+
+      /* Array textures need an additional component for the array
+       * index. */
+      if (sampler_array)
+         size += 1;
+
+   } else if (is_image()) {
+      switch (fields.image.dimension) {
+      case GLSL_IMAGE_DIM_1D:
+      case GLSL_IMAGE_DIM_BUFFER:
+         size = 1;
+         break;
+      case GLSL_IMAGE_DIM_2D:
+      case GLSL_IMAGE_DIM_RECT:
+      case GLSL_IMAGE_DIM_MS:
+         size = 2;
+         break;
+      case GLSL_IMAGE_DIM_3D:
+      case GLSL_IMAGE_DIM_CUBE:
+         size = 3;
+         break;
+      default:
+         unreachable();
+      }
+
+      /* Array textures need an additional component for the array
+       * index. */
+      if (fields.image.array)
+         size += 1;
 
-   /* Array textures need an additional component for the array index. */
-   if (sampler_array)
-      size += 1;
+   } else {
+      unreachable();
+   }
 
    return size;
 }
diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index ea65bcd..e7b6dd8 100644
--- a/src/glsl/glsl_types.h
+++ b/src/glsl/glsl_types.h
@@ -419,6 +419,20 @@ struct glsl_type {
    gl_texture_index sampler_index() const;
 
    /**
+    * Query whether or not type is an image, or for struct and array
+    * types, contains an image.
+    */
+   bool contains_image() const;
+
+   /**
+    * Query whether or not a type is an image
+    */
+   bool is_image() const
+   {
+      return base_type == GLSL_TYPE_IMAGE;
+   }
+
+   /**
     * Query whether or not a type is an array
     */
    bool is_array() const
@@ -548,7 +562,8 @@ struct glsl_type {
    }
 
    /**
-    * Return the number of coordinate components needed for this sampler type.
+    * Return the number of coordinate components needed for this
+    * sampler or image type.
     *
     * This is based purely on the sampler's dimensionality.  For example, this
     * returns 1 for sampler1D, and 3 for sampler2DArray.
@@ -557,7 +572,7 @@ struct glsl_type {
     * a texturing built-in function, since those pack additional values (such
     * as the shadow comparitor or projector) into the coordinate type.
     */
-   int sampler_coordinate_components() const;
+   int coordinate_components() const;
 
 private:
    /**
diff --git a/src/glsl/tests/sampler_types_test.cpp b/src/glsl/tests/sampler_types_test.cpp
index 4fb30dd..86d329a 100644
--- a/src/glsl/tests/sampler_types_test.cpp
+++ b/src/glsl/tests/sampler_types_test.cpp
@@ -47,7 +47,7 @@ TEST(sampler_types, TYPE)                                   \
    EXPECT_EQ(DATA_TYPE, type->sampler_type);                \
    ARR;                                                     \
    SHAD;                                                    \
-   EXPECT_EQ(COMPS, type->sampler_coordinate_components()); \
+   EXPECT_EQ(COMPS, type->coordinate_components());         \
 }
 
 T( sampler1D,        GLSL_SAMPLER_DIM_1D,   GLSL_TYPE_FLOAT, NONARRAY, COLOR,  1)
-- 
1.8.3.4



More information about the mesa-dev mailing list