i915g: split up static state
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 15 Mar 2011 17:36:00 +0000 (18:36 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 15 Mar 2011 17:36:00 +0000 (18:36 +0100)
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 <daniel.vetter@ffwll.ch>
src/gallium/drivers/i915/i915_context.c
src/gallium/drivers/i915/i915_context.h
src/gallium/drivers/i915/i915_flush.c
src/gallium/drivers/i915/i915_state_emit.c
src/gallium/drivers/i915/i915_state_static.c

index cb3de82a104417264f53273eb45c0d327b711cd0..7a98ef73c1fbd99d234f3799dd53a8900fe8cce0 100644 (file)
@@ -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;
index e42c9dc923b80a3b40c32f8a5bc6c66980836721..dacf50e870d64a4be1be2e1d9bebb132a458b4c0 100644 (file)
@@ -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)
 {
index a5407cfd18419b1d08a630fb7d9d094cd9ab6061..b4e81147c4fddda8497d63ea3afca16d099a7623 100644 (file)
@@ -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;
 }
index 096aa93cf09f49a2c66c77210b7fdb370eec09be..0155cd8351004e9420b926514169667255ed2b6e 100644 (file)
@@ -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;
 }
index 70b3dffee3ddde0acdc11f2f636a7356f564063b..39d6a4c8b9657b883550edc26abbe3056fdb191e 100644 (file)
@@ -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 */