i965: Make FS uniforms be the actual type of the uniform at upload time.
authorEric Anholt <eric@anholt.net>
Mon, 25 Oct 2010 19:52:29 +0000 (12:52 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 27 Oct 2010 20:54:35 +0000 (13:54 -0700)
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
src/mesa/drivers/dri/i965/brw_curbe.c
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_wm_pass0.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/gen6_wm_state.c

index 4a0709b4468ebdf08eb3e9153b806a8014bc4386..335339515a248550b0d8050bc759d1261f792f64 100644 (file)
@@ -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
index 9ce0d8decdce7f7f91c6f9ea2de352cdf4fc2e2e..7b823eb201b0a54d9250c44a6ca46aaf577eb2b1 100644 (file)
@@ -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]);
+      }
    }
 
 
index 5f6deb841cd5fc39c99ca983384baf4466f99b31..e322ee4f118222154c6f0251687e59b8212ef18b 100644 (file)
@@ -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;
index 8fc960b44567ac393c072912ba0cfd7b0626524e..d6aa9f957a240da5e2c0c8de28ad8c4c31fd849d 100644 (file)
@@ -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
index dd5ddea9204306f025e1967861f0a770cb8fe29c..76fc94df1f6bbcaaec3652c11950fa97a7696ffb 100644 (file)
@@ -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);
 
index 82d127720d63e6acb939c203c93b520bc42e581d..36d4ab93ba9dc5e1ea05bfe0d2208453cee01012 100644 (file)
@@ -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);
    }