glsl: Explicitly specify a type when reading/printing ir_texture.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 25 Feb 2011 22:29:36 +0000 (14:29 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 14 Mar 2011 20:03:50 +0000 (13:03 -0700)
This is necessary for GLSL 1.30+ shadow sampling functions, which return
a single float rather than splatting the value to a vec4 based on
GL_DEPTH_TEXTURE_MODE.

src/glsl/builtins/tools/texture_builtins.py
src/glsl/ir.cpp
src/glsl/ir.h
src/glsl/ir_print_visitor.cpp
src/glsl/ir_reader.cpp

index 2792dd8d0973bef79d0704843999741513f2c022..2fbe79010f9ffc2a2721d3edddc2d80db1220169 100755 (executable)
@@ -49,12 +49,13 @@ def generate_sigs(g, tex_inst, sampler_type, variant = 0, unused_fields = 0):
     extra_dim = get_extra_dim(sampler_type, variant & Proj, unused_fields)
     offset_dim = get_sampler_dim(sampler_type)
 
-    # Print parameters
-    print "   (signature",
     if variant & Single:
-        print "float"
+        return_type = "float"
     else:
-        print g + "vec4"
+        return_type = g + "vec4"
+
+    # Print parameters
+    print "   (signature", return_type
     print "     (parameters"
     print "       (declare (in) " + g + "sampler" + sampler_type + " sampler)"
     print "       (declare (in) " + vec_type("i" if tex_inst == "txf" else "", coord_dim + extra_dim) + " P)",
@@ -72,7 +73,7 @@ def generate_sigs(g, tex_inst, sampler_type, variant = 0, unused_fields = 0):
     if tex_inst == "txb":
         print "\n       (declare (in) float bias)",
 
-    print ")\n     ((return (" + tex_inst + " (var_ref sampler)",
+    print ")\n     ((return (" + tex_inst, return_type, "(var_ref sampler)",
 
     # Coordinate
     if extra_dim > 0:
index fc356ba52752dac3a6ee9e8e74b0362c1c3fd904..a55b7ef6536ed13ee1844b5ac1fc03ee3d8fd6cd 100644 (file)
@@ -1150,22 +1150,18 @@ ir_texture::get_opcode(const char *str)
 
 
 void
-ir_texture::set_sampler(ir_dereference *sampler)
+ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type)
 {
    assert(sampler != NULL);
+   assert(type != NULL);
    this->sampler = sampler;
+   this->type = type;
 
-   switch (sampler->type->sampler_type) {
-   case GLSL_TYPE_FLOAT:
-      this->type = glsl_type::vec4_type;
-      break;
-   case GLSL_TYPE_INT:
-      this->type = glsl_type::ivec4_type;
-      break;
-   case GLSL_TYPE_UINT:
-      this->type = glsl_type::uvec4_type;
-      break;
-   }
+   assert(sampler->type->sampler_type == type->base_type);
+   if (sampler->type->sampler_shadow)
+      assert(type->vector_elements == 4 || type->vector_elements == 1);
+   else
+      assert(type->vector_elements == 4);
 }
 
 
index f2f902c0a775939a89e915cef913d909ece30134..39d4ebc7107e1b8b1c4ea60454194c3c06cf7641 100644 (file)
@@ -1191,16 +1191,16 @@ enum ir_texture_opcode {
  * selected from \c ir_texture_opcodes.  In the printed IR, these will
  * appear as:
  *
- *                             Texel offset (0 or an expression)
- *                             | Projection divisor
- *                             | |  Shadow comparitor
- *                             | |  |
- *                             v v  v
- * (tex <sampler> <coordinate> 0 1 ( ))
- * (txb <sampler> <coordinate> 0 1 ( ) <bias>)
- * (txl <sampler> <coordinate> 0 1 ( ) <lod>)
- * (txd <sampler> <coordinate> 0 1 ( ) (dPdx dPdy))
- * (txf <sampler> <coordinate> 0       <lod>)
+ *                                    Texel offset (0 or an expression)
+ *                                    | Projection divisor
+ *                                    | |  Shadow comparitor
+ *                                    | |  |
+ *                                    v v  v
+ * (tex <type> <sampler> <coordinate> 0 1 ( ))
+ * (txb <type> <sampler> <coordinate> 0 1 ( ) <bias>)
+ * (txl <type> <sampler> <coordinate> 0 1 ( ) <lod>)
+ * (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy))
+ * (txf <type> <sampler> <coordinate> 0       <lod>)
  */
 class ir_texture : public ir_rvalue {
 public:
@@ -1226,8 +1226,8 @@ public:
     */
    const char *opcode_string();
 
-   /** Set the sampler and infer the type. */
-   void set_sampler(ir_dereference *sampler);
+   /** Set the sampler and type. */
+   void set_sampler(ir_dereference *sampler, const glsl_type *type);
 
    /**
     * Do a reverse-lookup to translate a string into an ir_texture_opcode.
index 82ccc722fa28762f4fe4fd60345450306fca9385..a84f8dfc8a1c0635043f46565cf1baf7eae35e46 100644 (file)
@@ -187,6 +187,9 @@ void ir_print_visitor::visit(ir_texture *ir)
 {
    printf("(%s ", ir->opcode_string());
 
+   print_type(ir->type);
+   printf(" ");
+
    ir->sampler->accept(this);
    printf(" ");
 
index af85e06ae0e4a2cda026c84b5aca30b7476d2373..30df257be2fe19c257c6e5355c4f218b0b043abe 100644 (file)
@@ -869,6 +869,7 @@ ir_texture *
 ir_reader::read_texture(s_expression *expr)
 {
    s_symbol *tag = NULL;
+   s_expression *s_type = NULL;
    s_expression *s_sampler = NULL;
    s_expression *s_coord = NULL;
    s_expression *s_offset = NULL;
@@ -879,11 +880,11 @@ ir_reader::read_texture(s_expression *expr)
    ir_texture_opcode op = ir_tex; /* silence warning */
 
    s_pattern tex_pattern[] =
-      { "tex", s_sampler, s_coord, s_offset, s_proj, s_shadow };
+      { "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow };
    s_pattern txf_pattern[] =
-      { "txf", s_sampler, s_coord, s_offset, s_lod };
+      { "txf", s_type, s_sampler, s_coord, s_offset, s_lod };
    s_pattern other_pattern[] =
-      { tag, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
+      { tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
 
    if (MATCH(expr, tex_pattern)) {
       op = ir_tex;
@@ -900,6 +901,14 @@ ir_reader::read_texture(s_expression *expr)
 
    ir_texture *tex = new(mem_ctx) ir_texture(op);
 
+   // Read return type
+   const glsl_type *type = read_type(s_type);
+   if (type == NULL) {
+      ir_read_error(NULL, "when reading type in (%s ...)",
+                   tex->opcode_string());
+      return NULL;
+   }
+
    // Read sampler (must be a deref)
    ir_dereference *sampler = read_dereference(s_sampler);
    if (sampler == NULL) {
@@ -907,7 +916,7 @@ ir_reader::read_texture(s_expression *expr)
                    tex->opcode_string());
       return NULL;
    }
-   tex->set_sampler(sampler);
+   tex->set_sampler(sampler, type);
 
    // Read coordinate (any rvalue)
    tex->coordinate = read_rvalue(s_coord);