diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2015-01-01 01:23:09 +0000 |
---|---|---|
committer | Jordan Justen <jordan.l.justen@intel.com> | 2015-01-01 01:23:09 +0000 |
commit | 88cbbce9e7fc5e9edd98f03be0d3ee61dadea26e (patch) | |
tree | 9ad1cd32f3a59f4588f7302809a6e731adde119c | |
parent | 2a1f6192d4b5f5f67963be556d84ab206a0f1495 (diff) |
atom based state upload - wippbo+blit+atoms
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_state_upload.c | 66 |
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; + } } } |