summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2015-01-01 01:23:09 +0000
committerJordan Justen <jordan.l.justen@intel.com>2015-01-01 01:23:09 +0000
commit88cbbce9e7fc5e9edd98f03be0d3ee61dadea26e (patch)
tree9ad1cd32f3a59f4588f7302809a6e731adde119c
parent2a1f6192d4b5f5f67963be556d84ab206a0f1495 (diff)
atom based state upload - wippbo+blit+atoms
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index a579781a85..d312f753c2 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -37,6 +37,9 @@
#include "intel_batchbuffer.h"
#include "intel_buffers.h"
+static uint64_t mesa_flag_to_atoms[64] = { 0 };
+static uint64_t brw_flag_to_atoms[64] = { 0 };
+
static const struct brw_tracked_state *gen4_atoms[] =
{
&brw_vs_prog, /* must do before GS prog, state base address. */
@@ -373,6 +376,7 @@ void brw_init_state( struct brw_context *brw )
num_atoms = ARRAY_SIZE(gen4_atoms);
}
+ assert(num_atoms < 64);
brw->atoms = atoms;
brw->num_atoms = num_atoms;
@@ -382,6 +386,20 @@ void brw_init_state( struct brw_context *brw )
atoms++;
}
+ for (int i = 0; i < brw->num_atoms; i++) {
+ const struct brw_tracked_state *atom = brw->atoms[i];
+ int f;
+ for (GLuint flags = atom->dirty.mesa; flags; flags &= ~(1ull << f)) {
+ f = ffs(flags) - 1;
+ mesa_flag_to_atoms[f] |= 1ull << i;
+ }
+
+ for (uint64_t flags = atom->dirty.brw; flags; flags &= ~(1ull << f)) {
+ f = ffsll(flags) - 1;
+ brw_flag_to_atoms[f] |= 1ull << i;
+ }
+ }
+
brw_upload_initial_gpu_state(brw);
brw->state.dirty.mesa = ~0;
@@ -547,6 +565,24 @@ brw_print_dirty_count(struct dirty_bit_map *bit_map)
}
}
+static uint64_t
+get_dirty_atoms(struct brw_state_flags *state)
+{
+ int f;
+ uint64_t dirty_atoms = 0;
+ for (GLuint flags = state->mesa; flags; flags &= ~(1ull << f)) {
+ f = ffs(flags) - 1;
+ dirty_atoms |= mesa_flag_to_atoms[f];
+ }
+
+ for (uint64_t flags = state->brw; flags; flags &= ~(1ull << f)) {
+ f = ffsll(flags) - 1;
+ dirty_atoms |= brw_flag_to_atoms[f];
+ }
+
+ return dirty_atoms;
+}
+
/***********************************************************************
* Emit all state:
*/
@@ -624,14 +660,28 @@ void brw_upload_state(struct brw_context *brw)
assert(!check_state(&examined, &generated));
prev = *state;
}
- }
- else {
- for (i = 0; i < brw->num_atoms; i++) {
- const struct brw_tracked_state *atom = brw->atoms[i];
-
- if (check_state(state, &atom->dirty)) {
- atom->emit(brw);
- }
+ } else {
+ uint64_t dirty_atoms = get_dirty_atoms(state);
+ uint64_t emitted_atoms_mask = ~0ull;
+ struct brw_state_flags last_state = *state;
+ while (dirty_atoms & emitted_atoms_mask) {
+ int a = ffsll(dirty_atoms & emitted_atoms_mask) - 1;
+ brw->atoms[a]->emit(brw);
+ emitted_atoms_mask &= ~(1ull << a);
+ if (unlikely(state->mesa != last_state.mesa || state->brw != last_state.brw)) {
+ last_state.mesa ^= state->mesa;
+ last_state.brw ^= state->brw;
+ const uint64_t new_dirty_atoms = get_dirty_atoms(&last_state);
+
+ /* Make sure an older atom wasn't flagged as dirty. If it was,
+ * then it would indicate that the state atoms aren't ordered
+ * correctly.
+ */
+ assert(unlikely(INTEL_DEBUG && (new_dirty_atoms & ((1ull << (a + 1)) - 1) == 0)));
+
+ dirty_atoms |= get_dirty_atoms(&last_state) & ~((1ull << (a + 1)) - 1);
+ last_state = *state;
+ }
}
}