[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