Use the gather table generated from the uniform uploads and ir_binop_ubo_load to gather and pack the constants to the gather pool.
Note that the 3DSTATE_CONSTANT_* packet now refers to the gather pool generated by the resource streamer instead of the constant buffer pointed to by an offset of the dynamic state base address. Signed-off-by: Abdiel Janulgue <abdiel.janul...@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 | 62 +++++++++++++++++++++++++++++-- 5 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 342157d..6536085 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -296,7 +296,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); /* gen7_misc_state.c */ void gen7_rs_control(struct brw_context *brw, int enable); 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 bce597f..025cef7 100644 --- a/src/mesa/drivers/dri/i965/gen6_vs_state.c +++ b/src/mesa/drivers/dri/i965/gen6_vs_state.c @@ -172,7 +172,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 8e673a4..798399e 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 278b3ec..adfaa59 100644 --- a/src/mesa/drivers/dri/i965/gen7_vs_state.c +++ b/src/mesa/drivers/dri/i965/gen7_vs_state.c @@ -28,28 +28,82 @@ #include "program/prog_parameter.h" #include "program/prog_statevars.h" #include "intel_batchbuffer.h" +#include "glsl/glsl_parser_extras.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 = 3 + prog_data->nr_gather_table; + + /* Ordinary uniforms are assigned to the first constant buffer slot */ + unsigned cb_valid = 1; + /* Assign subsequent constant buffer slots to UBOs if any */ + cb_valid |= (prog_data->nr_ubo_params > 0) ? + (2 << (BRW_UBO_GATHER_INDEX_APPEND + prog_data->max_ubo_const_block)) - 1 : 0; + + assert(cb_valid < 0xffff); + + BEGIN_BATCH(gather_dwords); + OUT_BATCH(gather_opcode << 16 | (gather_dwords - 2)); + OUT_BATCH(SET_FIELD(cb_valid, BRW_GATHER_BUFFER_VALID) | + SET_FIELD(BRW_UNIFORM_GATHER_INDEX_START / 16, BRW_GATHER_BINDING_TABLE_BLOCK)); + OUT_BATCH(stage_state->push_const_offset); + for (int i = 0; i < prog_data->nr_gather_table; i++) { + /* Which bo are we referring to? The uniform constant buffer or + * the UBO block? + */ + bool is_uniform = prog_data->gather_table[i].reg == -1; + int cb_offset = is_uniform ? i : (prog_data->gather_table[i].const_offset / 16); + int bt_offset = is_uniform ? 0 : + (prog_data->gather_table[i].const_block + BRW_UBO_GATHER_INDEX_APPEND); + + assert(cb_offset < 256); + assert(bt_offset < 16); + + OUT_BATCH(SET_FIELD(cb_offset, BRW_GATHER_CONST_BUFFER_OFFSET) | + SET_FIELD(prog_data->gather_table[i].channel_mask, BRW_GATHER_CHANNEL_MASK) | + bt_offset); + } + ADVANCE_BATCH(); +} 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev