summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Justen <jordan.l.justen@intel.com>2014-12-30 08:41:29 +0000
committerJordan Justen <jordan.l.justen@intel.com>2015-01-06 11:11:55 -0800
commit0da086c64e3a962a3e470e2e9fed421d97b148e4 (patch)
tree955bfc19aa3efadaafcfe89ff3bbd5d8fafad919
parent934e41c0b31cffa4efc08f61cff2389e3149b3f3 (diff)
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c57
1 files changed, 49 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 7a25ef541b..b5d3f08702 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;
@@ -549,6 +567,25 @@ brw_print_dirty_count(struct dirty_bit_map *bit_map)
}
}
+static uint64_t
+get_dirty_atoms(struct brw_context *brw)
+{
+ struct brw_state_flags *state = &brw->state.dirty;
+ 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:
*/
@@ -626,14 +663,18 @@ 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(brw);
+ uint64_t emitted_atoms_mask = ~0ull;
+ struct brw_state_flags flags = *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 != flags.mesa || state->brw != flags.brw)) {
+ dirty_atoms |= get_dirty_atoms(brw);
+ flags = *state;
+ }
}
}