summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Justen <jordan.l.justen@intel.com>2016-05-22 21:46:28 -0700
committerJordan Justen <jordan.l.justen@intel.com>2016-05-23 10:15:25 -0700
commit1ef3767ea473ed3112a878e7f9e3c6c87a65fa57 (patch)
tree3306dca5c664aeb5bd8d336edcef751d27963d30
parent43d775549d244c86e80ba00b4dd9add07bd72cce (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.c67
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)
{