Mesa (master): i965: Make FS uniforms be the actual type of the uniform at upload time.

Kenneth Graunke kwg at kemper.freedesktop.org
Wed Oct 27 20:58:07 UTC 2010


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

Author: Eric Anholt <eric at anholt.net>
Date:   Mon Oct 25 12:52:29 2010 -0700

i965: Make FS uniforms be the actual type of the uniform at upload time.

This fixes some insanity that would otherwise be required for GLSL
1.30 bit ops or gen6 integer uniform operations in general, at the
cost of upload-time pain.  Given that we only have that pain because
mesa's mangling our integer uniforms to be floats, this something that
should be fixed outside of the shader codegen.

---

 src/mesa/drivers/dri/i965/brw_context.h          |   42 ++++++++++++++++++++-
 src/mesa/drivers/dri/i965/brw_curbe.c            |    6 ++-
 src/mesa/drivers/dri/i965/brw_fs.cpp             |   35 ++++++++++++++++--
 src/mesa/drivers/dri/i965/brw_wm_pass0.c         |    1 +
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |    3 +-
 src/mesa/drivers/dri/i965/gen6_wm_state.c        |    3 +-
 6 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 4a0709b..3353395 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -188,6 +188,13 @@ struct brw_shader_program {
    struct gl_shader_program base;
 };
 
+enum param_conversion {
+   PARAM_NO_CONVERT,
+   PARAM_CONVERT_F2I,
+   PARAM_CONVERT_F2U,
+   PARAM_CONVERT_F2B,
+};
+
 /* Data about a particular attempt to compile a program.  Note that
  * there can be many of these, each in a different GL state
  * corresponding to a different brw_wm_prog_key struct, with different
@@ -208,8 +215,10 @@ struct brw_wm_prog_data {
    /* Pointer to tracked values (only valid once
     * _mesa_load_state_parameters has been called at runtime).
     */
-   const GLfloat *param[MAX_UNIFORMS * 4]; /* should be: BRW_MAX_CURBE */
-   const GLfloat *pull_param[MAX_UNIFORMS * 4];
+   const float *param[MAX_UNIFORMS * 4]; /* should be: BRW_MAX_CURBE */
+   enum param_conversion param_convert[MAX_UNIFORMS * 4];
+   const float *pull_param[MAX_UNIFORMS * 4];
+   enum param_conversion pull_param_convert[MAX_UNIFORMS * 4];
 };
 
 struct brw_sf_prog_data {
@@ -800,6 +809,35 @@ brw_fragment_program_const(const struct gl_fragment_program *p)
    return (const struct brw_fragment_program *) p;
 }
 
+static inline
+float convert_param(enum param_conversion conversion, float param)
+{
+   union {
+      float f;
+      uint32_t u;
+      int32_t i;
+   } fi;
+
+   switch (conversion) {
+   case PARAM_NO_CONVERT:
+      return param;
+   case PARAM_CONVERT_F2I:
+      fi.i = param;
+      return fi.f;
+   case PARAM_CONVERT_F2U:
+      fi.u = param;
+      return fi.f;
+   case PARAM_CONVERT_F2B:
+      if (param != 0.0)
+	 fi.i = 1;
+      else
+	 fi.i = 0;
+      return fi.f;
+   default:
+      return param;
+   }
+}
+
 GLboolean brw_do_cubemap_normalize(struct exec_list *instructions);
 
 #endif
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index 9ce0d8d..7b823eb 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -199,8 +199,10 @@ static void prepare_constant_buffer(struct brw_context *brw)
       GLuint offset = brw->curbe.wm_start * 16;
 
       /* copy float constants */
-      for (i = 0; i < brw->wm.prog_data->nr_params; i++) 
-	 buf[offset + i] = *brw->wm.prog_data->param[i];
+      for (i = 0; i < brw->wm.prog_data->nr_params; i++) {
+	 buf[offset + i] = convert_param(brw->wm.prog_data->param_convert[i],
+					 *brw->wm.prog_data->param[i]);
+      }
    }
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 5f6deb8..e322ee4 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -228,6 +228,7 @@ brw_type_for_base_type(const struct glsl_type *type)
       return BRW_REGISTER_TYPE_UD;
    case GLSL_TYPE_ARRAY:
    case GLSL_TYPE_STRUCT:
+   case GLSL_TYPE_SAMPLER:
       /* These should be overridden with the type of the member when
        * dereferenced into.  BRW_REGISTER_TYPE_UD seems like a likely
        * way to trip up if we don't.
@@ -286,8 +287,26 @@ fs_visitor::setup_uniform_values(int loc, const glsl_type *type)
    case GLSL_TYPE_BOOL:
       vec_values = fp->Base.Parameters->ParameterValues[loc];
       for (unsigned int i = 0; i < type->vector_elements; i++) {
-	 assert(c->prog_data.nr_params < ARRAY_SIZE(c->prog_data.param));
-	 c->prog_data.param[c->prog_data.nr_params++] = &vec_values[i];
+	 unsigned int param = c->prog_data.nr_params++;
+
+	 assert(param < ARRAY_SIZE(c->prog_data.param));
+
+	 switch (type->base_type) {
+	 case GLSL_TYPE_FLOAT:
+	    c->prog_data.param_convert[param] = PARAM_NO_CONVERT;
+	    break;
+	 case GLSL_TYPE_UINT:
+	    c->prog_data.param_convert[param] = PARAM_CONVERT_F2U;
+	    break;
+	 case GLSL_TYPE_INT:
+	    c->prog_data.param_convert[param] = PARAM_CONVERT_F2I;
+	    break;
+	 case GLSL_TYPE_BOOL:
+	    c->prog_data.param_convert[param] = PARAM_CONVERT_F2B;
+	    break;
+	 }
+
+	 c->prog_data.param[param] = &vec_values[i];
       }
       return 1;
 
@@ -371,6 +390,8 @@ fs_visitor::setup_builtin_uniform_values(ir_variable *ir)
 	       break;
 	    last_swiz = swiz;
 
+	    c->prog_data.param_convert[c->prog_data.nr_params] =
+	       PARAM_NO_CONVERT;
 	    c->prog_data.param[c->prog_data.nr_params++] = &vec_values[swiz];
 	 }
       }
@@ -625,6 +646,7 @@ fs_visitor::visit(ir_variable *ir)
       }
 
       reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index);
+      reg->type = brw_type_for_base_type(ir->type);
    }
 
    if (!reg)
@@ -1204,6 +1226,11 @@ fs_visitor::visit(ir_texture *ir)
 	 0
       };
 
+      c->prog_data.param_convert[c->prog_data.nr_params] =
+	 PARAM_NO_CONVERT;
+      c->prog_data.param_convert[c->prog_data.nr_params + 1] =
+	 PARAM_NO_CONVERT;
+
       fs_reg scale_x = fs_reg(UNIFORM, c->prog_data.nr_params);
       fs_reg scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1);
       GLuint index = _mesa_add_state_reference(params,
@@ -2359,7 +2386,7 @@ fs_visitor::assign_curb_setup()
 						  constant_nr % 8);
 
 	    inst->src[i].file = FIXED_HW_REG;
-	    inst->src[i].fixed_hw_reg = brw_reg;
+	    inst->src[i].fixed_hw_reg = retype(brw_reg, inst->src[i].type);
 	 }
       }
    }
@@ -2566,6 +2593,8 @@ fs_visitor::setup_pull_constants()
 
    for (int i = 0; i < pull_uniform_count; i++) {
       c->prog_data.pull_param[i] = c->prog_data.param[pull_uniform_base + i];
+      c->prog_data.pull_param_convert[i] =
+	 c->prog_data.param_convert[pull_uniform_base + i];
    }
    c->prog_data.nr_params -= pull_uniform_count;
    c->prog_data.nr_pull_params = pull_uniform_count;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
index 8fc960b..d6aa9f9 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
@@ -113,6 +113,7 @@ static const struct brw_wm_ref *get_param_ref( struct brw_wm_compile *c,
       struct brw_wm_ref *ref = get_ref(c);
 
       c->prog_data.param[i] = param_ptr;
+      c->prog_data.param_convert[i] = PARAM_NO_CONVERT;
       c->nr_creg = (i+16)/16;
 
       /* Push the offsets into hw_reg.  These will be added to the
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index dd5ddea..76fc94d 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -343,7 +343,8 @@ prepare_wm_constants(struct brw_context *brw)
    drm_intel_gem_bo_map_gtt(brw->wm.const_bo);
    constants = brw->wm.const_bo->virtual;
    for (i = 0; i < brw->wm.prog_data->nr_pull_params; i++) {
-      constants[i] = *brw->wm.prog_data->pull_param[i];
+      constants[i] = convert_param(brw->wm.prog_data->pull_param_convert[i],
+				   *brw->wm.prog_data->pull_param[i]);
    }
    drm_intel_gem_bo_unmap_gtt(brw->wm.const_bo);
 
diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index 82d1277..36d4ab9 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -63,7 +63,8 @@ prepare_wm_constants(struct brw_context *brw)
       drm_intel_gem_bo_map_gtt(brw->wm.push_const_bo);
       constants = brw->wm.push_const_bo->virtual;
       for (i = 0; i < brw->wm.prog_data->nr_params; i++) {
-	 constants[i] = *brw->wm.prog_data->param[i];
+	 constants[i] = convert_param(brw->wm.prog_data->param_convert[i],
+				      *brw->wm.prog_data->param[i]);
       }
       drm_intel_gem_bo_unmap_gtt(brw->wm.push_const_bo);
    }




More information about the mesa-commit mailing list