Mesa (master): i965: Add support for struct, array, and matrix uniforms to FS backend.

Eric Anholt anholt at kemper.freedesktop.org
Tue Sep 28 16:38:04 UTC 2010


Module: Mesa
Branch: master
Commit: 6bf12c8b7366a9db8c88b9cacaa06266b41a73b5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6bf12c8b7366a9db8c88b9cacaa06266b41a73b5

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Sep 28 09:31:56 2010 -0700

i965: Add support for struct, array, and matrix uniforms to FS backend.

Fixes 16 piglit cases.

---

 src/mesa/drivers/dri/i965/brw_fs.cpp |   75 +++++++++++++++++++++++++++-------
 1 files changed, 60 insertions(+), 15 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 4f88ca1..4a63fc6 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -453,6 +453,7 @@ public:
    void emit_fb_writes();
 
    struct brw_reg interp_reg(int location, int channel);
+   int setup_uniform_values(int loc, const glsl_type *type);
 
    struct brw_context *brw;
    struct intel_context *intel;
@@ -541,6 +542,64 @@ fs_visitor::variable_storage(ir_variable *var)
    return (fs_reg *)hash_table_find(this->variable_ht, var);
 }
 
+/* Our support for uniforms is piggy-backed on the struct
+ * gl_fragment_program, because that's where the values actually
+ * get stored, rather than in some global gl_shader_program uniform
+ * store.
+ */
+int
+fs_visitor::setup_uniform_values(int loc, const glsl_type *type)
+{
+   const struct gl_program *fp = &this->brw->fragment_program->Base;
+   unsigned int offset = 0;
+   float *vec_values;
+
+   if (type->is_matrix()) {
+      const glsl_type *column = glsl_type::get_instance(GLSL_TYPE_FLOAT,
+							type->vector_elements,
+							1);
+
+      for (unsigned int i = 0; i < type->matrix_columns; i++) {
+	 offset += setup_uniform_values(loc + offset, column);
+      }
+
+      return offset;
+   }
+
+   switch (type->base_type) {
+   case GLSL_TYPE_FLOAT:
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_INT:
+   case GLSL_TYPE_BOOL:
+      vec_values = fp->Parameters->ParameterValues[loc];
+      for (unsigned int i = 0; i < type->vector_elements; i++) {
+	 c->prog_data.param[c->prog_data.nr_params++] = &vec_values[i];
+      }
+      return 1;
+
+   case GLSL_TYPE_STRUCT:
+      for (unsigned int i = 0; i < type->length; i++) {
+	 offset += setup_uniform_values(loc + offset,
+					type->fields.structure[i].type);
+      }
+      return offset;
+
+   case GLSL_TYPE_ARRAY:
+      for (unsigned int i = 0; i < type->length; i++) {
+	 offset += setup_uniform_values(loc + offset, type->fields.array);
+      }
+      return offset;
+
+   case GLSL_TYPE_SAMPLER:
+      /* The sampler takes up a slot, but we don't use any values from it. */
+      return 1;
+
+   default:
+      assert(!"not reached");
+      return 0;
+   }
+}
+
 void
 fs_visitor::visit(ir_variable *ir)
 {
@@ -560,23 +619,9 @@ fs_visitor::visit(ir_variable *ir)
    }
 
    if (ir->mode == ir_var_uniform) {
-      const float *vec_values;
       int param_index = c->prog_data.nr_params;
 
-      /* FINISHME: This is wildly incomplete. */
-      assert(ir->type->is_scalar() || ir->type->is_vector() ||
-	     ir->type->is_sampler());
-
-      const struct gl_program *fp = &this->brw->fragment_program->Base;
-      /* Our support for uniforms is piggy-backed on the struct
-       * gl_fragment_program, because that's where the values actually
-       * get stored, rather than in some global gl_shader_program uniform
-       * store.
-       */
-      vec_values = fp->Parameters->ParameterValues[ir->location];
-      for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
-	 c->prog_data.param[c->prog_data.nr_params++] = &vec_values[i];
-      }
+      setup_uniform_values(ir->location, ir->type);
 
       reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index);
    }




More information about the mesa-commit mailing list