diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2011-09-25 18:14:16 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2011-10-07 14:31:17 +0200 |
commit | 661b7ef9a89b8f5a10cb8ca8a23365bce1f1cbc5 (patch) | |
tree | ddaaffba629e06e4d4630670cc325de74d3b75a8 /src/gallium/drivers/i915/i915_clear.c | |
parent | 0a6131b15c874c076781a8dc347b4e51be15801a (diff) |
i915g: hw can't fastclear both depth and color when bbp doesn't match
Do it in two passes in that case.
v2: Don't forget to handle stencil clears.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'src/gallium/drivers/i915/i915_clear.c')
-rw-r--r-- | src/gallium/drivers/i915/i915_clear.c | 122 |
1 files changed, 93 insertions, 29 deletions
diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c index a0aba0201f5..bb8ff91767a 100644 --- a/src/gallium/drivers/i915/i915_clear.c +++ b/src/gallium/drivers/i915/i915_clear.c @@ -52,9 +52,11 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, union util_color u_color; float f_depth = depth; struct i915_texture *cbuf_tex, *depth_tex; + int depth_clear_bbp, color_clear_bbp; cbuf_tex = depth_tex = NULL; clear_params = 0; + depth_clear_bbp = color_clear_bbp = 0; if (buffers & PIPE_CLEAR_COLOR) { struct pipe_surface *cbuf = i915->framebuffer.cbufs[0]; @@ -63,10 +65,13 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, cbuf_tex = i915_texture(cbuf->texture); util_pack_color(color->f, cbuf->format, &u_color); - if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4) + if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4) { clear_color = u_color.ui; - else + color_clear_bbp = 32; + } else { clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16); + color_clear_bbp = 16; + } /* correctly swizzle clear value */ if (i915->current.need_target_fixup) @@ -94,42 +99,101 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, clear_depth = packed_z_stencil; } else clear_depth = packed_z_stencil & 0xffffff00; + + depth_clear_bbp = 32; } else { clear_depth = (clear_depth & 0xffff) | (clear_depth << 16); + depth_clear_bbp = 16; } } - if (i915->hardware_dirty) - i915_emit_hardware_state(i915); + /* hw can't fastclear both depth and color if their bbp mismatch. */ + if (color_clear_bbp && depth_clear_bbp + && color_clear_bbp != depth_clear_bbp) { + if (i915->hardware_dirty) + i915_emit_hardware_state(i915); - if (!BEGIN_BATCH(1 + 7 + 7)) { - FLUSH_BATCH(NULL); + if (!BEGIN_BATCH(1 + 2*(7 + 7))) { + FLUSH_BATCH(NULL); - i915_emit_hardware_state(i915); - i915->vbo_flushed = 1; + i915_emit_hardware_state(i915); + i915->vbo_flushed = 1; - assert(BEGIN_BATCH(1 + 7 + 7)); - } + assert(BEGIN_BATCH(1 + 2*(7 + 7))); + } + + OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + + OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); + OUT_BATCH(CLEARPARAM_WRITE_COLOR | CLEARPARAM_CLEAR_RECT); + /* Used for zone init prim */ + OUT_BATCH(clear_color); + OUT_BATCH(clear_depth); + /* Used for clear rect prim */ + OUT_BATCH(clear_color8888); + OUT_BATCH_F(f_depth); + OUT_BATCH(clear_stencil); + + OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); + OUT_BATCH_F(destx + width); + OUT_BATCH_F(desty + height); + OUT_BATCH_F(destx); + OUT_BATCH_F(desty + height); + OUT_BATCH_F(destx); + OUT_BATCH_F(desty); + + OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); + OUT_BATCH((clear_params & ~CLEARPARAM_WRITE_COLOR) | + CLEARPARAM_CLEAR_RECT); + /* Used for zone init prim */ + /* Used for zone init prim */ + OUT_BATCH(clear_color); + OUT_BATCH(clear_depth); + /* Used for clear rect prim */ + OUT_BATCH(clear_color8888); + OUT_BATCH_F(f_depth); + OUT_BATCH(clear_stencil); + + OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); + OUT_BATCH_F(destx + width); + OUT_BATCH_F(desty + height); + OUT_BATCH_F(destx); + OUT_BATCH_F(desty + height); + OUT_BATCH_F(destx); + OUT_BATCH_F(desty); + } else { + if (i915->hardware_dirty) + i915_emit_hardware_state(i915); + + if (!BEGIN_BATCH(1 + 7 + 7)) { + FLUSH_BATCH(NULL); + + i915_emit_hardware_state(i915); + i915->vbo_flushed = 1; + + assert(BEGIN_BATCH(1 + 7 + 7)); + } - OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - - OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); - OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT); - /* Used for zone init prim */ - OUT_BATCH(clear_color); - OUT_BATCH(clear_depth); - /* Used for clear rect prim */ - OUT_BATCH(clear_color8888); - OUT_BATCH_F(f_depth); - OUT_BATCH(clear_stencil); - - OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); - OUT_BATCH_F(destx + width); - OUT_BATCH_F(desty + height); - OUT_BATCH_F(destx); - OUT_BATCH_F(desty + height); - OUT_BATCH_F(destx); - OUT_BATCH_F(desty); + OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + + OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); + OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT); + /* Used for zone init prim */ + OUT_BATCH(clear_color); + OUT_BATCH(clear_depth); + /* Used for clear rect prim */ + OUT_BATCH(clear_color8888); + OUT_BATCH_F(f_depth); + OUT_BATCH(clear_stencil); + + OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); + OUT_BATCH_F(destx + width); + OUT_BATCH_F(desty + height); + OUT_BATCH_F(destx); + OUT_BATCH_F(desty + height); + OUT_BATCH_F(destx); + OUT_BATCH_F(desty); + } /* Flush after clear, its expected to be a costly operation. * This is not required, just a heuristic, but without the flush we'd need to |