Mesa (master): i965: Add support for builtin uniforms to the new FS backend .

Eric Anholt anholt at kemper.freedesktop.org
Tue Sep 28 23:32:13 UTC 2010


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

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Sep 28 16:23:04 2010 -0700

i965: Add support for builtin uniforms to the new FS backend.

Fixes 8 piglit tests.

---

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

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 4f5ca4e..2ecacb5 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -31,6 +31,7 @@ extern "C" {
 
 #include "main/macros.h"
 #include "main/shaderobj.h"
+#include "main/uniforms.h"
 #include "program/prog_parameter.h"
 #include "program/prog_print.h"
 #include "program/prog_optimize.h"
@@ -461,6 +462,7 @@ public:
 
    struct brw_reg interp_reg(int location, int channel);
    int setup_uniform_values(int loc, const glsl_type *type);
+   void setup_builtin_uniform_values(ir_variable *ir);
 
    struct brw_context *brw;
    const struct gl_fragment_program *fp;
@@ -607,6 +609,69 @@ fs_visitor::setup_uniform_values(int loc, const glsl_type *type)
    }
 }
 
+
+/* Our support for builtin uniforms is even scarier than non-builtin.
+ * It sits on top of the PROG_STATE_VAR parameters that are
+ * automatically updated from GL context state.
+ */
+void
+fs_visitor::setup_builtin_uniform_values(ir_variable *ir)
+{
+   const struct gl_builtin_uniform_desc *statevar = NULL;
+
+   for (unsigned int i = 0; _mesa_builtin_uniform_desc[i].name; i++) {
+      statevar = &_mesa_builtin_uniform_desc[i];
+      if (strcmp(ir->name, _mesa_builtin_uniform_desc[i].name) == 0)
+	 break;
+   }
+
+   if (!statevar->name) {
+      this->fail = true;
+      printf("Failed to find builtin uniform `%s'\n", ir->name);
+      return;
+   }
+
+   int array_count;
+   if (ir->type->is_array()) {
+      array_count = ir->type->length;
+   } else {
+      array_count = 1;
+   }
+
+   for (int a = 0; a < array_count; a++) {
+      for (unsigned int i = 0; i < statevar->num_elements; i++) {
+	 struct gl_builtin_uniform_element *element = &statevar->elements[i];
+	 int tokens[STATE_LENGTH];
+
+	 memcpy(tokens, element->tokens, sizeof(element->tokens));
+	 if (ir->type->is_array()) {
+	    tokens[1] = a;
+	 }
+
+	 /* This state reference has already been setup by ir_to_mesa,
+	  * but we'll get the same index back here.
+	  */
+	 int index = _mesa_add_state_reference(this->fp->Base.Parameters,
+					       (gl_state_index *)tokens);
+	 float *vec_values = this->fp->Base.Parameters->ParameterValues[index];
+
+	 /* Add each of the unique swizzles of the element as a
+	  * parameter.  This'll end up matching the expected layout of
+	  * the array/matrix/structure we're trying to fill in.
+	  */
+	 int last_swiz = -1;
+	 for (unsigned int i = 0; i < 4; i++) {
+	    int this_swiz = GET_SWZ(element->swizzle, i);
+	    if (this_swiz == last_swiz)
+	       break;
+	    last_swiz = this_swiz;
+
+	    c->prog_data.param[c->prog_data.nr_params++] = &vec_values[i];
+	 }
+      }
+   }
+}
+
 void
 fs_visitor::emit_fragcoord_interpolation(ir_variable *ir)
 {
@@ -751,7 +816,11 @@ fs_visitor::visit(ir_variable *ir)
    if (ir->mode == ir_var_uniform) {
       int param_index = c->prog_data.nr_params;
 
-      setup_uniform_values(ir->location, ir->type);
+      if (!strncmp(ir->name, "gl_", 3)) {
+	 setup_builtin_uniform_values(ir);
+      } else {
+	 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