[Mesa-dev] [RFC PATCH 17/40] i965: Program the push constants state using the gather table

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


Use the gather table generated from the uniform uploads to gather
and pack the constants to the gather pool. This changes the 3DSTATE_CONSTANT_*
bits to refer to the gather pool instead of the constant buffer pointed
to by an offset of the dynamic state base address.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>
---
 src/mesa/drivers/dri/i965/brw_state.h     |  2 +-
 src/mesa/drivers/dri/i965/gen6_gs_state.c |  2 +-
 src/mesa/drivers/dri/i965/gen6_vs_state.c |  2 +-
 src/mesa/drivers/dri/i965/gen6_wm_state.c |  2 +-
 src/mesa/drivers/dri/i965/gen7_vs_state.c | 50 ++++++++++++++++++++++++++++---
 5 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 6e506a4..de99c7a 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -288,7 +288,7 @@ brw_upload_pull_constants(struct brw_context *brw,
 void
 gen7_upload_constant_state(struct brw_context *brw,
                            const struct brw_stage_state *stage_state,
-                           bool active, unsigned opcode);
+                           bool active, unsigned opcode, unsigned gather_op);
 
 /* gen8_vs_state.c */
 void
diff --git a/src/mesa/drivers/dri/i965/gen6_gs_state.c b/src/mesa/drivers/dri/i965/gen6_gs_state.c
index eb4c586..79a899e 100644
--- a/src/mesa/drivers/dri/i965/gen6_gs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_gs_state.c
@@ -48,7 +48,7 @@ gen6_upload_gs_push_constants(struct brw_context *brw)
    }
 
    if (brw->gen >= 7)
-      gen7_upload_constant_state(brw, stage_state, gp, _3DSTATE_CONSTANT_GS);
+      gen7_upload_constant_state(brw, stage_state, gp, _3DSTATE_CONSTANT_GS, _3DSTATE_GATHER_CONSTANT_GS);
 }
 
 const struct brw_tracked_state gen6_gs_push_constants = {
diff --git a/src/mesa/drivers/dri/i965/gen6_vs_state.c b/src/mesa/drivers/dri/i965/gen6_vs_state.c
index 4fd3ea2..5e71a44 100644
--- a/src/mesa/drivers/dri/i965/gen6_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_vs_state.c
@@ -152,7 +152,7 @@ gen6_upload_vs_push_constants(struct brw_context *brw)
          gen7_emit_vs_workaround_flush(brw);
 
       gen7_upload_constant_state(brw, stage_state, true /* active */,
-                                 _3DSTATE_CONSTANT_VS);
+                                 _3DSTATE_CONSTANT_VS, _3DSTATE_GATHER_CONSTANT_VS);
    }
 }
 
diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index e57b7f6..e741388 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -50,7 +50,7 @@ gen6_upload_wm_push_constants(struct brw_context *brw)
 
    if (brw->gen >= 7) {
       gen7_upload_constant_state(brw, &brw->wm.base, true,
-                                 _3DSTATE_CONSTANT_PS);
+                                 _3DSTATE_CONSTANT_PS, _3DSTATE_GATHER_CONSTANT_PS);
    }
 }
 
diff --git a/src/mesa/drivers/dri/i965/gen7_vs_state.c b/src/mesa/drivers/dri/i965/gen7_vs_state.c
index 5f8e8b0..85bd56f 100644
--- a/src/mesa/drivers/dri/i965/gen7_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_vs_state.c
@@ -29,6 +29,34 @@
 #include "program/prog_statevars.h"
 #include "intel_batchbuffer.h"
 
+static void
+gen7_submit_gather_table(struct brw_context* brw,
+                         const struct brw_stage_state *stage_state,
+                         const struct brw_stage_prog_data *prog_data,
+                         unsigned gather_opcode)
+{
+   uint32_t gather_dwords = 0;
+   /* Generate gather entry only for uniforms */
+   int num_consts = ALIGN(prog_data->nr_params, 4) / 4;
+   gather_dwords = 3 + num_consts;
+
+   /* Fetch the entries in 128-bit units. If the offset in the constant
+    * buffer pointing to the entry is > 4096 bytes, round it to the next
+    * gather bank slot. gen7_upload_constant_buffer_data() should have
+    * made sure that the entries are uploaded in the correct slots.
+    */
+   unsigned bo_offset = (stage_state->const_bo_offset / 16) % 256;
+   unsigned bti = stage_state->const_bo_offset / 4096;
+
+   BEGIN_BATCH(gather_dwords);
+   OUT_BATCH(gather_opcode << 16 | (gather_dwords - 2));
+   OUT_BATCH(0xffff << 16 | 1 << 12);
+   OUT_BATCH(stage_state->push_const_offset);
+   for (int i = 0; i < num_consts; i++) {
+      OUT_BATCH((bo_offset + i) << 8 | 0xF << 4 | bti);
+   }
+   ADVANCE_BATCH();
+}
 
 void
 gen7_upload_constant_buffer_data(struct brw_context* brw,
@@ -72,23 +100,37 @@ gen7_upload_constant_buffer_data(struct brw_context* brw,
 void
 gen7_upload_constant_state(struct brw_context *brw,
                            const struct brw_stage_state *stage_state,
-                           bool active, unsigned opcode)
+                           bool active, unsigned opcode, unsigned gather_opcode)
 {
    uint32_t mocs = brw->gen < 8 ? GEN7_MOCS_L3 : 0;
 
    /* Disable if the shader stage is inactive or there are no push constants. */
    active = active && stage_state->push_const_size != 0;
 
+   bool use_gather = (brw->gather_pool.bo != NULL);
+
+   int const_loc = use_gather ? 16 : 0;
    int dwords = brw->gen >= 8 ? 11 : 7;
+
+   struct brw_stage_prog_data *prog_data = stage_state->prog_data;
+   if (prog_data && use_gather && active) {
+      gen7_submit_gather_table(brw, stage_state, prog_data, gather_opcode);
+   }
+
    BEGIN_BATCH(dwords);
    OUT_BATCH(opcode << 16 | (dwords - 2));
-   OUT_BATCH(active ? stage_state->push_const_size : 0);
+   OUT_BATCH(active ? stage_state->push_const_size << const_loc : 0);
    OUT_BATCH(0);
    /* Pointer to the constant buffer.  Covered by the set of state flags
     * from gen6_prepare_wm_contants
     */
-   OUT_BATCH(active ? (stage_state->push_const_offset | mocs) : 0);
-   OUT_BATCH(0);
+   if (!use_gather) {
+      OUT_BATCH(active ? (stage_state->push_const_offset | mocs) : 0);
+      OUT_BATCH(0);
+   } else {
+      OUT_BATCH(0);
+      OUT_BATCH(active ? (stage_state->push_const_offset | mocs) : 0);
+   }
    OUT_BATCH(0);
    OUT_BATCH(0);
    if (brw->gen >= 8) {
-- 
1.9.1



More information about the mesa-dev mailing list