Mesa (glsl2): ir_to_mesa: Add support for sampler arrays.

Eric Anholt anholt at kemper.freedesktop.org
Fri Aug 6 07:53:21 UTC 2010


Module: Mesa
Branch: glsl2
Commit: c234d0b25f622a7bdd3c40bc72fdbd59d8494c7c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c234d0b25f622a7bdd3c40bc72fdbd59d8494c7c

Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug  5 17:00:12 2010 -0700

ir_to_mesa: Add support for sampler arrays.

Support for samplers in general is still incomplete -- anything in a
uniform struct will still be broken.  But that doesn't appear to be
any different from master.

Fixes:
glsl-fs-uniform-sampler-array.shader_test

---

 src/mesa/program/ir_to_mesa.cpp   |   47 +++++++++++++++++++++++++++++-------
 src/mesa/program/prog_parameter.c |    7 +++--
 src/mesa/program/prog_parameter.h |    2 +-
 3 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 66b1a2f..d8a1322 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1398,10 +1398,19 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
 	    break;
 
 	 /* FINISHME: Fix up uniform name for arrays and things */
-	 if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) {
+	 if (ir->var->type->base_type == GLSL_TYPE_SAMPLER ||
+	     (ir->var->type->base_type == GLSL_TYPE_ARRAY &&
+	      ir->var->type->fields.array->base_type == GLSL_TYPE_SAMPLER)) {
+	    int array_length;
+
+	    if (ir->var->type->base_type == GLSL_TYPE_ARRAY)
+	       array_length = ir->var->type->length;
+	    else
+	       array_length = 1;
 	    int sampler = _mesa_add_sampler(this->prog->Parameters,
 					    ir->var->name,
-					    ir->var->type->gl_type);
+					    ir->var->type->gl_type,
+					    array_length);
 	    set_sampler_location(ir->var, sampler);
 
 	    entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_SAMPLER,
@@ -2035,22 +2044,42 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
    if (ir->shadow_comparitor)
       inst->tex_shadow = GL_TRUE;
 
-   ir_dereference_variable *sampler = ir->sampler->as_dereference_variable();
-   assert(sampler); /* FINISHME: sampler arrays */
+   ir_variable *sampler = ir->sampler->variable_referenced();
+
    /* generate the mapping, remove when we generate storage at
     * declaration time
     */
-   sampler->accept(this);
+   ir->sampler->accept(this);
+
+   inst->sampler = get_sampler_location(sampler);
+
+   ir_dereference_array *sampler_array = ir->sampler->as_dereference_array();
+   if (sampler_array) {
+      ir_constant *array_index =
+	 sampler_array->array_index->constant_expression_value();
+
+      /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
+       * while GLSL 1.30 requires that the array indices be constant
+       * integer expressions.  We don't expect any driver to actually
+       * work with a really variable array index, and in 1.20 all that
+       * would work would be an unrolled loop counter, so assert that
+       * we ended up with a constant at least..
+       */
+      assert(array_index);
+      inst->sampler += array_index->value.i[0];
+   }
 
-   inst->sampler = get_sampler_location(sampler->var);
+   const glsl_type *sampler_type = sampler->type;
+   while (sampler_type->base_type == GLSL_TYPE_ARRAY)
+      sampler_type = sampler_type->fields.array;
 
-   switch (sampler->type->sampler_dimensionality) {
+   switch (sampler_type->sampler_dimensionality) {
    case GLSL_SAMPLER_DIM_1D:
-      inst->tex_target = (sampler->type->sampler_array)
+      inst->tex_target = (sampler_type->sampler_array)
 	 ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
       break;
    case GLSL_SAMPLER_DIM_2D:
-      inst->tex_target = (sampler->type->sampler_array)
+      inst->tex_target = (sampler_type->sampler_array)
 	 ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
       break;
    case GLSL_SAMPLER_DIM_3D:
diff --git a/src/mesa/program/prog_parameter.c b/src/mesa/program/prog_parameter.c
index ddbfe95..fa5deaf 100644
--- a/src/mesa/program/prog_parameter.c
+++ b/src/mesa/program/prog_parameter.c
@@ -344,18 +344,19 @@ _mesa_use_uniform(struct gl_program_parameter_list *paramList,
  */
 GLint
 _mesa_add_sampler(struct gl_program_parameter_list *paramList,
-                  const char *name, GLenum datatype)
+                  const char *name, GLenum datatype, int array_length)
 {
    GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
    if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
-      ASSERT(paramList->Parameters[i].Size == 1);
+      ASSERT(paramList->Parameters[i].Size == 4 * array_length);
       ASSERT(paramList->Parameters[i].DataType == datatype);
       /* already in list */
       return (GLint) paramList->ParameterValues[i][0];
    }
    else {
       GLuint i;
-      const GLint size = 1; /* a sampler is basically a texture unit number */
+       /* One integer texture unit number goes in each parameter location. */
+      const GLint size = 4 * array_length;
       GLfloat value[4];
       GLint numSamplers = 0;
       for (i = 0; i < paramList->NumParameters; i++) {
diff --git a/src/mesa/program/prog_parameter.h b/src/mesa/program/prog_parameter.h
index cc3378a..1860f31 100644
--- a/src/mesa/program/prog_parameter.h
+++ b/src/mesa/program/prog_parameter.h
@@ -142,7 +142,7 @@ _mesa_use_uniform(struct gl_program_parameter_list *paramList,
 
 extern GLint
 _mesa_add_sampler(struct gl_program_parameter_list *paramList,
-                  const char *name, GLenum datatype);
+                  const char *name, GLenum datatype, int array_length);
 
 extern GLint
 _mesa_add_varying(struct gl_program_parameter_list *paramList,




More information about the mesa-commit mailing list