[Mesa-dev] [PATCH 15/25] i965: Add visitor support for handling image uniforms.

Francisco Jerez currojerez at riseup.net
Mon Dec 2 11:39:23 PST 2013


---
 src/mesa/drivers/dri/i965/brw_fs.cpp           | 36 +++++++++++++++------
 src/mesa/drivers/dri/i965/brw_fs.h             |  4 +++
 src/mesa/drivers/dri/i965/brw_shader.cpp       | 25 +++++++++++++++
 src/mesa/drivers/dri/i965/brw_shader.h         |  4 +++
 src/mesa/drivers/dri/i965/brw_vec4.h           |  2 ++
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 44 +++++++++++++++++---------
 6 files changed, 90 insertions(+), 25 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index cce6ed0..ca152d1 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -505,6 +505,8 @@ fs_visitor::type_size(const struct glsl_type *type)
       return 0;
    case GLSL_TYPE_ATOMIC_UINT:
       return 0;
+   case GLSL_TYPE_IMAGE:
+      return BRW_IMAGE_PARAM_SIZE;
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
    case GLSL_TYPE_INTERFACE:
@@ -871,6 +873,20 @@ fs_visitor::import_uniforms(fs_visitor *v)
    this->nr_params_remap = v->nr_params_remap;
 }
 
+void
+fs_visitor::setup_vector_uniform_values(void *values, unsigned stride,
+                                        unsigned size)
+{
+   static float zero = 0;
+
+   for (unsigned i = 0; i < size; ++i)
+      stage_prog_data->param[uniforms++] =
+         (float *)((char *)values + i * stride);
+
+   for (unsigned i = size; i < 4; ++i)
+      stage_prog_data->param[uniforms++] = &zero;
+}
+
 /* 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
@@ -887,7 +903,6 @@ fs_visitor::setup_uniform_values(ir_variable *ir)
     * order we'd walk the type, so walk the list of storage and find anything
     * with our name, or the prefix of a component that starts with our name.
     */
-   unsigned params_before = uniforms;
    for (unsigned u = 0; u < shader_prog->NumUserUniformStorage; u++) {
       struct gl_uniform_storage *storage = &shader_prog->UniformStorage[u];
 
@@ -898,17 +913,18 @@ fs_visitor::setup_uniform_values(ir_variable *ir)
          continue;
       }
 
-      unsigned slots = storage->type->component_slots();
-      if (storage->array_elements)
-         slots *= storage->array_elements;
+      if (storage->type->is_image()) {
+         setup_image_uniform_values(storage);
 
-      for (unsigned i = 0; i < slots; i++)
-         stage_prog_data->param[uniforms++] = &storage->storage[i].f;
-   }
+      } else {
+         unsigned slots = storage->type->component_slots();
+         if (storage->array_elements)
+            slots *= storage->array_elements;
 
-   /* Make sure we actually initialized the right amount of stuff here. */
-   assert(params_before + ir->type->component_slots() == uniforms);
-   (void)params_before;
+         for (unsigned i = 0; i < slots; i++)
+            stage_prog_data->param[uniforms++] = &storage->storage[i].f;
+      }
+   }
 }
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 7bfa9fd..eb71676 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -434,8 +434,12 @@ public:
    fs_reg get_timestamp();
 
    struct brw_reg interp_reg(int location, int channel);
+
+   virtual void setup_vector_uniform_values(void *values, unsigned stride,
+                                            unsigned size);
    void setup_uniform_values(ir_variable *ir);
    void setup_builtin_uniform_values(ir_variable *ir);
+
    int implied_mrf_writes(fs_inst *inst);
 
    void dump_instruction(backend_instruction *inst);
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index dc6d35e..d903bb5 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -310,6 +310,8 @@ brw_type_for_base_type(const struct glsl_type *type)
        * way to trip up if we don't.
        */
       return BRW_REGISTER_TYPE_UD;
+   case GLSL_TYPE_IMAGE:
+      return BRW_REGISTER_TYPE_UD;
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
    case GLSL_TYPE_INTERFACE:
@@ -761,3 +763,26 @@ backend_visitor::assign_common_binding_table_offsets(uint32_t next_binding_table
 
    /* prog_data->base.binding_table.size will be set by brw_mark_surface_used. */
 }
+
+void
+backend_visitor::setup_image_uniform_values(const gl_uniform_storage *storage)
+{
+   const unsigned stage = _mesa_program_target_to_index(prog->Target);
+
+   for (unsigned i = 0; i < MAX2(storage->array_elements, 1); i++) {
+      const unsigned image_idx = storage->image[stage].index + i;
+      brw_image_param *param = &stage_prog_data->image_param[image_idx];
+
+      param->surface_idx =
+         stage_prog_data->binding_table.image_start + image_idx;
+
+      setup_vector_uniform_values(&param->surface_idx, sizeof(uint32_t), 1);
+      setup_vector_uniform_values(param->offset, sizeof(uint32_t), 2);
+      setup_vector_uniform_values(param->size, sizeof(uint32_t), 3);
+      setup_vector_uniform_values(param->stride, sizeof(uint32_t), 4);
+      setup_vector_uniform_values(param->tiling, sizeof(uint32_t), 3);
+      setup_vector_uniform_values(param->swizzling, sizeof(uint32_t), 2);
+
+      brw_mark_surface_used(stage_prog_data, param->surface_idx);
+   }
+}
diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h
index 48382af..90b8157 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.h
+++ b/src/mesa/drivers/dri/i965/brw_shader.h
@@ -150,6 +150,10 @@ public:
    void assign_common_binding_table_offsets(uint32_t next_binding_table_offset);
 
    virtual void invalidate_live_intervals() = 0;
+
+   virtual void setup_vector_uniform_values(void *values, unsigned stride,
+                                            unsigned size) = 0;
+   void setup_image_uniform_values(const gl_uniform_storage *storage);
 };
 
 uint32_t brw_texture_offset(struct gl_context *ctx, ir_constant *offset);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 7e07929..989c1a9 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -377,6 +377,8 @@ public:
 
    int virtual_grf_alloc(int size);
    void setup_uniform_clipplane_values();
+   virtual void setup_vector_uniform_values(void *values, unsigned stride,
+                                            unsigned size);
    void setup_uniform_values(ir_variable *ir);
    void setup_builtin_uniform_values(ir_variable *ir);
    int setup_uniforms(int payload_reg);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 97bd26d..3e8043f 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -570,6 +570,8 @@ type_size(const struct glsl_type *type)
       return 1;
    case GLSL_TYPE_ATOMIC_UINT:
       return 0;
+   case GLSL_TYPE_IMAGE:
+      return BRW_IMAGE_PARAM_SIZE / 4;
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
    case GLSL_TYPE_INTERFACE:
@@ -631,6 +633,22 @@ dst_reg::dst_reg(class vec4_visitor *v, const struct glsl_type *type)
    this->type = brw_type_for_base_type(type);
 }
 
+void
+vec4_visitor::setup_vector_uniform_values(void *values, unsigned stride,
+                                          unsigned size)
+{
+   static float zero = 0;
+
+   for (unsigned i = 0; i < size; ++i)
+      stage_prog_data->param[4 * uniforms + i] =
+         (float *)((char *)values + i * stride);
+
+   for (unsigned i = size; i < 4; ++i)
+      stage_prog_data->param[4 * uniforms + i] = &zero;
+
+   uniform_vector_size[uniforms++] = size;
+}
+
 /* 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
@@ -657,24 +675,20 @@ vec4_visitor::setup_uniform_values(ir_variable *ir)
          continue;
       }
 
-      gl_constant_value *components = storage->storage;
-      unsigned vector_count = (MAX2(storage->array_elements, 1) *
-                               storage->type->matrix_columns);
+      if (storage->type->is_image()) {
+         setup_image_uniform_values(storage);
 
-      for (unsigned s = 0; s < vector_count; s++) {
-         uniform_vector_size[uniforms] = storage->type->vector_elements;
+      } else {
+         gl_constant_value *components = storage->storage;
+         unsigned vector_count = (MAX2(storage->array_elements, 1) *
+                                  storage->type->matrix_columns);
 
-         int i;
-         for (i = 0; i < uniform_vector_size[uniforms]; i++) {
-            stage_prog_data->param[uniforms * 4 + i] = &components->f;
-            components++;
-         }
-         for (; i < 4; i++) {
-            static float zero = 0;
-            stage_prog_data->param[uniforms * 4 + i] = &zero;
-         }
+         for (unsigned s = 0; s < vector_count; s++) {
+            setup_vector_uniform_values(&components->f, sizeof(*components),
+                                        storage->type->vector_elements);
 
-         uniforms++;
+            components += storage->type->vector_elements;
+         }
       }
    }
 }
-- 
1.8.3.4



More information about the mesa-dev mailing list