[Mesa-dev] [RFC PATCH 15/40] i965: Upload uniforms to the constant buffer

Abdiel Janulgue abdiel.janulgue at linux.intel.com
Sun Jan 4 06:04:29 PST 2015


When uploading uniform constants to the uniform constant buffer, this
patch aligns each entry to a 4k-sized boundary so that the gather table
is able to refer to the individual bank using the hw-binding table index
and the constant buffer offset to fetch to the constant entry.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>
---
 src/mesa/drivers/dri/i965/brw_context.h   |  1 +
 src/mesa/drivers/dri/i965/brw_state.h     |  3 +++
 src/mesa/drivers/dri/i965/gen6_vs_state.c | 29 ++++++++++++-----------
 src/mesa/drivers/dri/i965/gen7_vs_state.c | 39 +++++++++++++++++++++++++++++++
 4 files changed, 59 insertions(+), 13 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index e2a6415..e0a1759 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -932,6 +932,7 @@ struct brw_stage_state
 
    uint32_t push_const_offset; /* Offset in the batchbuffer */
    int push_const_size; /* in 256-bit register increments */
+   uint32_t const_bo_offset;  /* Offset within the constant buffer */
 
    /* Binding table: pointers to SURFACE_STATE entries. */
    uint32_t bind_bo_offset;
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 16355bd..6e506a4 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -310,6 +310,9 @@ void gen7_enable_hw_binding_tables(struct brw_context *brw);
 void gen7_disable_hw_binding_tables(struct brw_context *brw);
 void gen7_reset_rs_pool_offsets(struct brw_context *brw);
 void gen7_toggle_gather_constants(struct brw_context *brw, bool enable);
+void gen7_upload_constant_buffer_data(struct brw_context* brw,
+                                      struct brw_stage_state *stage_state,
+                                      const struct brw_stage_prog_data *prog_data);
 
 #ifdef __cplusplus
 }
diff --git a/src/mesa/drivers/dri/i965/gen6_vs_state.c b/src/mesa/drivers/dri/i965/gen6_vs_state.c
index e365cc6..c1950d1 100644
--- a/src/mesa/drivers/dri/i965/gen6_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_vs_state.c
@@ -70,20 +70,23 @@ gen6_upload_push_constants(struct brw_context *brw,
       gl_constant_value *param;
       int i;
 
-      param = brw_state_batch(brw, type,
-			      prog_data->nr_params * sizeof(gl_constant_value),
-			      32, &stage_state->push_const_offset);
+      if (brw->gather_pool.bo != NULL) {
+         gen7_upload_constant_buffer_data(brw, stage_state, prog_data);
+      } else {
+         param = brw_state_batch(brw, type,
+                                 prog_data->nr_params * sizeof(gl_constant_value),
+                                 32, &stage_state->push_const_offset);
 
-      STATIC_ASSERT(sizeof(gl_constant_value) == sizeof(float));
-
-      /* _NEW_PROGRAM_CONSTANTS
-       *
-       * Also _NEW_TRANSFORM -- we may reference clip planes other than as a
-       * side effect of dereferencing uniforms, so _NEW_PROGRAM_CONSTANTS
-       * wouldn't be set for them.
-      */
-      for (i = 0; i < prog_data->nr_params; i++) {
-         param[i] = *prog_data->param[i];
+         STATIC_ASSERT(sizeof(gl_constant_value) == sizeof(float));
+         /* _NEW_PROGRAM_CONSTANTS
+          *
+          * Also _NEW_TRANSFORM -- we may reference clip planes other than as a
+          * side effect of dereferencing uniforms, so _NEW_PROGRAM_CONSTANTS
+          * wouldn't be set for them.
+          */
+         for (i = 0; i < prog_data->nr_params; i++) {
+            param[i] = *prog_data->param[i];
+         }
       }
 
       if (0) {
diff --git a/src/mesa/drivers/dri/i965/gen7_vs_state.c b/src/mesa/drivers/dri/i965/gen7_vs_state.c
index 404dd20..5f8e8b0 100644
--- a/src/mesa/drivers/dri/i965/gen7_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_vs_state.c
@@ -31,6 +31,45 @@
 
 
 void
+gen7_upload_constant_buffer_data(struct brw_context* brw,
+                                 struct brw_stage_state *stage_state,
+                                 const struct brw_stage_prog_data *prog_data)
+{
+   static const uint64_t const_state_stage[MESA_SHADER_FRAGMENT + 1] =
+   {
+      _NEW_VERTEX_CONSTANTS,
+      _NEW_GEOMETRY_CONSTANTS,
+      _NEW_FRAGMENT_CONSTANTS
+   };
+
+   /* If current constant data does not fit in current constant buffer bank,
+    * move to next slot. 
+    */
+   uint32_t alloc_size = brw->constants.next_offset + (prog_data->nr_params * sizeof(gl_constant_value));
+   uint32_t next_bank = ALIGN(brw->constants.next_offset + 1, 4096);
+   if (alloc_size > next_bank ) {
+      brw->constants.next_offset = next_bank;
+   }
+   alloc_size = brw->constants.next_offset + (prog_data->nr_params * sizeof(gl_constant_value));
+
+   if (alloc_size > brw->constants.bo->size) {
+      gen7_reset_rs_pool_offsets(brw);
+      gen7_upload_constant_buffer_data(brw, stage_state, prog_data);
+   } else {
+      int i;
+      gl_constant_value *param = brw->constants.bo->virtual + brw->constants.next_offset;
+      stage_state->const_bo_offset = brw->constants.next_offset;
+
+      for (i = 0; i < prog_data->nr_params; i++) {
+         param[i] = *prog_data->param[i];
+      }
+
+      /*  Align to a 256-bit register row */
+      brw->constants.next_offset += ALIGN(prog_data->nr_params * sizeof(gl_constant_value), 32);
+   }
+}
+
+void
 gen7_upload_constant_state(struct brw_context *brw,
                            const struct brw_stage_state *stage_state,
                            bool active, unsigned opcode)
-- 
1.9.1



More information about the mesa-dev mailing list