summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2015-08-29 00:49:40 +0200
committerMarek Olšák <[email protected]>2015-09-01 21:51:14 +0200
commit87c1e9e19c6baa8c6fb03b0894c72744a07cde63 (patch)
treee0cab820884e5a272c876f3fdf0a020fdbbe05aa /src
parent2fe040ee61d3c08e8d38c3552ad4e7b5060074a1 (diff)
radeonsi: use a bitmask for tracking dirty atoms
This mainly removes the cache misses when checking the dirty flags. Not much else though. Reviewed-by: Alex Deucher <[email protected]> Acked-by: Christian König <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeonsi/si_hw_context.c10
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h8
-rw-r--r--src/gallium/drivers/radeonsi/si_state_draw.c13
3 files changed, 18 insertions, 13 deletions
diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c
index f821ad33ff3..2381b6c0004 100644
--- a/src/gallium/drivers/radeonsi/si_hw_context.c
+++ b/src/gallium/drivers/radeonsi/si_hw_context.c
@@ -31,7 +31,6 @@ void si_need_cs_space(struct si_context *ctx, unsigned num_dw,
boolean count_draw_in)
{
struct radeon_winsys_cs *cs = ctx->b.rings.gfx.cs;
- int i;
/* There are two memory usage counters in the winsys for all buffers
* that have been added (cs_add_reloc) and two counters in the pipe
@@ -59,11 +58,10 @@ void si_need_cs_space(struct si_context *ctx, unsigned num_dw,
num_dw += cs->cdw;
if (count_draw_in) {
- for (i = 0; i < SI_NUM_ATOMS; i++) {
- if (ctx->atoms.array[i]->dirty) {
- num_dw += ctx->atoms.array[i]->num_dw;
- }
- }
+ unsigned mask = ctx->dirty_atoms;
+
+ while (mask)
+ num_dw += ctx->atoms.array[u_bit_scan(&mask)]->num_dw;
/* The number of dwords all the dirty states would take. */
num_dw += si_pm4_dirty_dw(ctx);
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 5ca83e7a2d2..35104cf7848 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -155,6 +155,7 @@ struct si_context {
struct si_shader_selector *fixed_func_tcs_shader;
union si_state_atoms atoms;
+ unsigned dirty_atoms; /* mask */
struct si_framebuffer framebuffer;
struct si_vertex_element *vertex_elements;
@@ -339,7 +340,12 @@ static inline void
si_set_atom_dirty(struct si_context *sctx,
struct r600_atom *atom, bool dirty)
{
- atom->dirty = dirty;
+ unsigned bit = 1 << (atom->id - 1);
+
+ if (dirty)
+ sctx->dirty_atoms |= bit;
+ else
+ sctx->dirty_atoms &= ~bit;
}
static inline void
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index 2ff58d1f332..81575b53dd8 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -729,7 +729,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
{
struct si_context *sctx = (struct si_context *)ctx;
struct pipe_index_buffer ib = {};
- unsigned i;
+ unsigned mask;
if (!info->count && !info->indirect &&
(info->indexed || !info->count_from_stream_output))
@@ -821,12 +821,13 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
si_need_cs_space(sctx, 0, TRUE);
/* Emit states. */
- for (i = 0; i < SI_NUM_ATOMS; i++) {
- if (sctx->atoms.array[i]->dirty) {
- sctx->atoms.array[i]->emit(&sctx->b, sctx->atoms.array[i]);
- sctx->atoms.array[i]->dirty = false;
- }
+ mask = sctx->dirty_atoms;
+ while (mask) {
+ struct r600_atom *atom = sctx->atoms.array[u_bit_scan(&mask)];
+
+ atom->emit(&sctx->b, atom);
}
+ sctx->dirty_atoms = 0;
si_pm4_emit_dirty(sctx);
si_emit_scratch_reloc(sctx);