From 288504fac7b659da6bd45f22ccfb39d130250f9c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 15 Mar 2011 18:36:00 +0100 Subject: [PATCH] i915g: split up static state Early Z support is set in the DST_VARS command. Hence split up static state emission to avoid reissuing to much on fragment shader changes, especially the costly dst buffer relocations. Signed-off-by: Daniel Vetter --- src/gallium/drivers/i915/i915_context.c | 1 + src/gallium/drivers/i915/i915_context.h | 13 ++++++-- src/gallium/drivers/i915/i915_flush.c | 1 + src/gallium/drivers/i915/i915_state_emit.c | 33 ++++++++++++------- src/gallium/drivers/i915/i915_state_static.c | 34 ++++++++++++-------- 5 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index cb3de82a104..7a98ef73c1f 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -185,6 +185,7 @@ i915_create_context(struct pipe_screen *screen, void *priv) i915->hardware_dirty = ~0; i915->immediate_dirty = ~0; i915->dynamic_dirty = ~0; + i915->static_dirty = ~0; i915->flush_dirty = 0; return &i915->base; diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index e42c9dc923b..dacf50e870d 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -245,9 +245,10 @@ struct i915_context { struct i915_state current; unsigned hardware_dirty; - unsigned immediate_dirty; - unsigned dynamic_dirty; - unsigned flush_dirty; + unsigned immediate_dirty : I915_MAX_IMMEDIATE; + unsigned dynamic_dirty : I915_MAX_DYNAMIC; + unsigned static_dirty : 4; + unsigned flush_dirty : 2; struct i915_winsys_buffer *validation_buffers[2 + 1 + I915_TEX_UNITS]; int num_validation_buffers; @@ -317,6 +318,12 @@ struct i915_context { #define I915_FLUSH_CACHE 1 #define I915_PIPELINE_FLUSH 2 +/* split up static state */ +#define I915_DST_BUF_COLOR 1 +#define I915_DST_BUF_DEPTH 2 +#define I915_DST_VARS 4 +#define I915_DST_RECT 8 + static INLINE void i915_set_flush_dirty(struct i915_context *i915, unsigned flush) { diff --git a/src/gallium/drivers/i915/i915_flush.c b/src/gallium/drivers/i915/i915_flush.c index a5407cfd184..b4e81147c4f 100644 --- a/src/gallium/drivers/i915/i915_flush.c +++ b/src/gallium/drivers/i915/i915_flush.c @@ -74,6 +74,7 @@ void i915_flush(struct i915_context *i915, struct pipe_fence_handle **fence) i915->hardware_dirty = ~0; i915->immediate_dirty = ~0; i915->dynamic_dirty = ~0; + i915->static_dirty = ~0; /* kernel emits flushes in between batchbuffers */ i915->flush_dirty = 0; } diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 096aa93cf09..0155cd83510 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -173,25 +173,31 @@ emit_dynamic(struct i915_context *i915) static void validate_static(struct i915_context *i915, unsigned *batch_space) { - *batch_space = 2 + 5; /* including DRAW_RECT */ + *batch_space = 0; - if (i915->current.cbuf_bo) { + if (i915->current.cbuf_bo && (i915->static_dirty & I915_DST_BUF_COLOR)) { i915->validation_buffers[i915->num_validation_buffers++] = i915->current.cbuf_bo; *batch_space += 3; } - if (i915->current.depth_bo) { + if (i915->current.depth_bo && (i915->static_dirty & I915_DST_BUF_DEPTH)) { i915->validation_buffers[i915->num_validation_buffers++] = i915->current.depth_bo; *batch_space += 3; } + + if (i915->static_dirty & I915_DST_VARS) + *batch_space += 2; + + if (i915->static_dirty & I915_DST_RECT) + *batch_space += 5; } static void emit_static(struct i915_context *i915) { - if (i915->current.cbuf_bo) { + if (i915->current.cbuf_bo && (i915->static_dirty & I915_DST_BUF_COLOR)) { OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(i915->current.cbuf_flags); OUT_RELOC(i915->current.cbuf_bo, @@ -201,7 +207,7 @@ emit_static(struct i915_context *i915) /* What happens if no zbuf?? */ - if (i915->current.depth_bo) { + if (i915->current.depth_bo && (i915->static_dirty & I915_DST_BUF_DEPTH)) { OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(i915->current.depth_flags); OUT_RELOC(i915->current.depth_bo, @@ -209,7 +215,7 @@ emit_static(struct i915_context *i915) 0); } - { + if (i915->static_dirty & I915_DST_VARS) { OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); OUT_BATCH(i915->current.dst_buf_vars); } @@ -273,7 +279,7 @@ emit_sampler(struct i915_context *i915) if (i915->current.sampler_enable_nr) { int i; - OUT_BATCH( _3DSTATE_SAMPLER_STATE | + OUT_BATCH( _3DSTATE_SAMPLER_STATE | (3 * i915->current.sampler_enable_nr) ); OUT_BATCH( i915->current.sampler_enable_flags ); @@ -355,11 +361,13 @@ emit_program(struct i915_context *i915) static void emit_draw_rect(struct i915_context *i915) { - OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); - OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS); - OUT_BATCH(i915->current.draw_offset); - OUT_BATCH(i915->current.draw_size); - OUT_BATCH(i915->current.draw_offset); + if (i915->static_dirty & I915_DST_RECT) { + OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); + OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS); + OUT_BATCH(i915->current.draw_offset); + OUT_BATCH(i915->current.draw_size); + OUT_BATCH(i915->current.draw_offset); + } } static boolean @@ -446,5 +454,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) i915->hardware_dirty = 0; i915->immediate_dirty = 0; i915->dynamic_dirty = 0; + i915->static_dirty = 0; i915->flush_dirty = 0; } diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c index 70b3dffee3d..39d6a4c8b96 100644 --- a/src/gallium/drivers/i915/i915_state_static.c +++ b/src/gallium/drivers/i915/i915_state_static.c @@ -83,9 +83,9 @@ static void update_framebuffer(struct i915_context *i915) struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; unsigned cformat, zformat; - unsigned x, y, w, h; + unsigned x, y; int layer; - uint32_t draw_offset; + uint32_t draw_offset, draw_size, dst_buf_vars; if (cbuf_surface) { struct i915_texture *tex = i915_texture(cbuf_surface->texture); @@ -107,6 +107,7 @@ static void update_framebuffer(struct i915_context *i915) x = y = 0; } cformat = translate_format(cformat); + i915->static_dirty |= I915_DST_BUF_COLOR; /* What happens if no zbuf?? */ @@ -126,25 +127,32 @@ static void update_framebuffer(struct i915_context *i915) i915->current.depth_bo = NULL; zformat = 0; } - - i915->current.dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - cformat | - zformat; + i915->static_dirty |= I915_DST_BUF_DEPTH; + + dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + cformat | + zformat; + if (i915->current.dst_buf_vars != dst_buf_vars) { + i915->current.dst_buf_vars = dst_buf_vars; + i915->static_dirty |= I915_DST_VARS; + } /* drawing rect calculations */ draw_offset = x | (y << 16); + draw_size = (i915->framebuffer.width - 1 + x) | + ((i915->framebuffer.height - 1 + y) << 16); if (i915->current.draw_offset != draw_offset) { i915->current.draw_offset = draw_offset; i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH); + i915->static_dirty |= I915_DST_RECT; + } else if (i915->current.draw_size != draw_size) { + i915->current.draw_size = draw_size; + i915->static_dirty |= I915_DST_RECT; } - w = i915->framebuffer.width; - h = i915->framebuffer.height; - i915->current.draw_size = (w - 1 + x) | ((h - 1 + y) << 16); - i915->hardware_dirty |= I915_HW_STATIC; /* flush the cache in case we sample from the old renderbuffers */ -- 2.30.2