diff options
author | Jordan Justen <jordan.l.justen@intel.com> | 2016-05-22 21:46:28 -0700 |
---|---|---|
committer | Jordan Justen <jordan.l.justen@intel.com> | 2016-05-23 10:15:25 -0700 |
commit | 1ef3767ea473ed3112a878e7f9e3c6c87a65fa57 (patch) | |
tree | 3306dca5c664aeb5bd8d336edcef751d27963d30 | |
parent | 43d775549d244c86e80ba00b4dd9add07bd72cce (diff) |
squash-fwd i965/cs: Add CS push constant structure
We need information about push constants in two state atoms, so we
calculated roughly the same information twice.
When we add support for uploading both a common (cross-thread) set of
push constants, combined with the previous per-thread push constant
data, things are going to get even more complicated. Therefore, move
these calculations into a separate function that stores the results
into a structure.
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
-rw-r--r-- | src/mesa/drivers/dri/i965/gen7_cs_state.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/gen7_cs_state.c b/src/mesa/drivers/dri/i965/gen7_cs_state.c index 7f484dd158..04aad13aa5 100644 --- a/src/mesa/drivers/dri/i965/gen7_cs_state.c +++ b/src/mesa/drivers/dri/i965/gen7_cs_state.c @@ -44,6 +44,73 @@ get_cs_thread_count(const struct brw_cs_prog_data *cs_prog_data) } +struct push_const_block { + unsigned dwords; /* Dword count, not reg aligned */ + unsigned regs; + unsigned size; /* Bytes, register aligned */ +}; + + +static void +fill_push_const_block_info(struct push_const_block *block, unsigned dwords) +{ + block->dwords = dwords; + block->regs = DIV_ROUND_UP(dwords, 8); + block->size = block->regs * 32; +} + + +struct push_const_info { + struct push_const_block cross_thread; + struct push_const_block per_thread; + struct push_const_block total; + bool fill_thread_id; +}; + + +static void +fill_push_const_info(const struct brw_context *brw, + const struct gl_program *prog, + const struct brw_cs_prog_data *cs_prog_data, + struct push_const_info *info) +{ + const struct brw_stage_prog_data *prog_data = + (struct brw_stage_prog_data*) cs_prog_data; + bool fill_thread_id = + cs_prog_data->thread_local_id_index >= 0 && + cs_prog_data->thread_local_id_index < prog_data->nr_params; + bool cross_thread_supported = brw->gen > 7 || brw->is_haswell; + + /* The thread ID should be stored in the last param dword */ + assert(prog_data->nr_params > 0 || !fill_thread_id); + assert(!fill_thread_id || + cs_prog_data->thread_local_id_index == prog_data->nr_params - 1); + + unsigned cross_thread_dwords, per_thread_dwords; + if (cross_thread_supported && fill_thread_id) { + /* Fill all but the last register with cross-thread payload */ + cross_thread_dwords = 8 * (cs_prog_data->thread_local_id_index / 8); + per_thread_dwords = prog_data->nr_params - cross_thread_dwords; + assert(per_thread_dwords > 0 && per_thread_dwords <= 8); + } else if (cross_thread_supported && !fill_thread_id) { + /* Fill all data using cross-thread payload */ + cross_thread_dwords = prog_data->nr_params; + per_thread_dwords = 0u; + } else { + cross_thread_dwords = 0u; + per_thread_dwords = prog_data->nr_params; + } + + fill_push_const_block_info(&info->cross_thread, cross_thread_dwords); + fill_push_const_block_info(&info->per_thread, per_thread_dwords); + + unsigned threads = get_cs_thread_count(cs_prog_data); + unsigned total_dwords = + (info->per_thread.size * threads + info->cross_thread.size) / 4; + fill_push_const_block_info(&info->total, total_dwords); +} + + static void brw_upload_cs_state(struct brw_context *brw) { |