From 0eb02a1963a25f6994b730147d0613b03424c11e Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 1 Aug 2007 14:46:07 -0600 Subject: [PATCH] More work on glClear. Add a 'mask' param to region_fill() to help with clearing combined Z/stencil buffers, glColorMask, etc. --- src/mesa/drivers/dri/i915pipe/intel_blit.c | 22 ++- src/mesa/drivers/dri/i915pipe/intel_blit.h | 2 +- src/mesa/drivers/dri/i915pipe/intel_regions.c | 5 +- src/mesa/pipe/p_context.h | 3 +- src/mesa/pipe/softpipe/sp_clear.c | 127 ++++++++++++------ src/mesa/pipe/softpipe/sp_region.c | 2 +- 6 files changed, 111 insertions(+), 50 deletions(-) diff --git a/src/mesa/drivers/dri/i915pipe/intel_blit.c b/src/mesa/drivers/dri/i915pipe/intel_blit.c index 8e7f294b575..109d4face26 100644 --- a/src/mesa/drivers/dri/i915pipe/intel_blit.c +++ b/src/mesa/drivers/dri/i915pipe/intel_blit.c @@ -209,9 +209,11 @@ intelEmitFillBlit(struct intel_context *intel, GLshort dst_pitch, struct _DriBufferObject *dst_buffer, GLuint dst_offset, - GLshort x, GLshort y, GLshort w, GLshort h, GLuint color) + GLshort x, GLshort y, GLshort w, GLshort h, + GLuint value, GLuint mask) { GLuint BR13, CMD; + GLboolean badMask = GL_FALSE; BATCH_LOCALS; dst_pitch *= cpp; @@ -222,16 +224,32 @@ intelEmitFillBlit(struct intel_context *intel, case 3: BR13 = dst_pitch | (0xF0 << 16) | (1 << 24); CMD = XY_COLOR_BLT_CMD; + if ((mask & 0xffff) != 0xffff) + badMask = GL_TRUE; break; case 4: BR13 = dst_pitch | (0xF0 << 16) | (1 << 24) | (1 << 25); +#if 0 CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); +#else + CMD = XY_COLOR_BLT_CMD; + if ((mask & 0xff000000) == 0xff000000) + CMD |= XY_COLOR_BLT_WRITE_ALPHA; + else if (mask & 0xff000000) + badMask = GL_TRUE; + if ((mask & 0x00ffffff) == 0x00ffffff) + CMD |= XY_COLOR_BLT_WRITE_RGB; + else if (mask & 0x00ffffff) + badMask = GL_TRUE; +#endif break; default: return; } + assert(!badMask); + DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); @@ -243,7 +261,7 @@ intelEmitFillBlit(struct intel_context *intel, OUT_BATCH(((y + h) << 16) | (x + w)); OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset); - OUT_BATCH(color); + OUT_BATCH(value); ADVANCE_BATCH(); } diff --git a/src/mesa/drivers/dri/i915pipe/intel_blit.h b/src/mesa/drivers/dri/i915pipe/intel_blit.h index 77686444fa0..46c25944775 100644 --- a/src/mesa/drivers/dri/i915pipe/intel_blit.h +++ b/src/mesa/drivers/dri/i915pipe/intel_blit.h @@ -56,7 +56,7 @@ extern void intelEmitFillBlit(struct intel_context *intel, struct _DriBufferObject *dst_buffer, GLuint dst_offset, GLshort x, GLshort y, - GLshort w, GLshort h, GLuint color); + GLshort w, GLshort h, GLuint value, GLuint mask); #endif diff --git a/src/mesa/drivers/dri/i915pipe/intel_regions.c b/src/mesa/drivers/dri/i915pipe/intel_regions.c index e95e745adc2..bdbc59e7ac2 100644 --- a/src/mesa/drivers/dri/i915pipe/intel_regions.c +++ b/src/mesa/drivers/dri/i915pipe/intel_regions.c @@ -343,7 +343,8 @@ intel_region_fill(struct pipe_context *pipe, struct pipe_region *dst, GLuint dst_offset, GLuint dstx, GLuint dsty, - GLuint width, GLuint height, GLuint color) + GLuint width, GLuint height, + GLuint value, GLuint mask) { intelScreenPrivate *intelScreen = pipe_screen(pipe); struct intel_context *intel = intelScreenContext(intelScreen); @@ -364,7 +365,7 @@ intel_region_fill(struct pipe_context *pipe, intelEmitFillBlit(intel, dst->cpp, dst->pitch, dst->buffer, dst_offset, - dstx, dsty, width, height, color); + dstx, dsty, width, height, value, mask); } /* Attach to a pbo, discarding our data. Effectively zero-copy upload diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index 8517d7ab687..8e51daae061 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -172,7 +172,8 @@ struct pipe_context { struct pipe_region *dst, GLuint dst_offset, GLuint dstx, GLuint dsty, - GLuint width, GLuint height, GLuint color); + GLuint width, GLuint height, + GLuint value, GLuint mask); void (*region_cow)(struct pipe_context *pipe, struct pipe_region *region); diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c index 6266d124be0..aa7601ab8cb 100644 --- a/src/mesa/pipe/softpipe/sp_clear.c +++ b/src/mesa/pipe/softpipe/sp_clear.c @@ -59,7 +59,39 @@ color_value(GLuint format, const GLfloat color[4]) } } +static GLuint +color_mask(GLuint format, GLuint pipeMask) +{ + GLuint mask = 0x0; + switch (format) { + case PIPE_FORMAT_U_R8_G8_B8_A8: + if (pipeMask & PIPE_MASK_R) mask |= 0xff000000; + if (pipeMask & PIPE_MASK_G) mask |= 0x00ff0000; + if (pipeMask & PIPE_MASK_B) mask |= 0x0000ff00; + if (pipeMask & PIPE_MASK_A) mask |= 0x000000ff; + break; + case PIPE_FORMAT_U_A8_R8_G8_B8: + if (pipeMask & PIPE_MASK_R) mask |= 0x00ff0000; + if (pipeMask & PIPE_MASK_G) mask |= 0x0000ff00; + if (pipeMask & PIPE_MASK_B) mask |= 0x000000ff; + if (pipeMask & PIPE_MASK_A) mask |= 0xff000000; + break; + case PIPE_FORMAT_U_R5_G6_B5: + if (pipeMask & PIPE_MASK_R) mask |= 0xf800; + if (pipeMask & PIPE_MASK_G) mask |= 0x07e0; + if (pipeMask & PIPE_MASK_B) mask |= 0x001f; + if (pipeMask & PIPE_MASK_A) mask |= 0; + break; + default: + return 0; + } + return mask; +} + +/** + * XXX maybe this belongs in the GL state tracker... + */ void softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth, GLboolean stencil, GLboolean accum) @@ -74,58 +106,67 @@ softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth, GLuint i; for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { struct pipe_surface *ps = softpipe->framebuffer.cbufs[i]; - - if (softpipe->blend.colormask == (PIPE_MASK_R | PIPE_MASK_G | - PIPE_MASK_B | PIPE_MASK_A)) { - /* no masking */ - GLuint clearVal = color_value(ps->format, - softpipe->clear_color.color); - pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal); - } - else { - /* masking */ - - /* - for (j = 0; j < h; j++) { - sps->write_mono_row_ub(sps, w, x, y + j, clr); - } - */ - } + GLuint clearVal = color_value(ps->format, + softpipe->clear_color.color); + GLuint mask = color_mask(ps->format, softpipe->blend.colormask); + pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask); } } - if (depth) { + if (depth && stencil && + softpipe->framebuffer.zbuf == softpipe->framebuffer.sbuf) { + /* clear Z and stencil together */ struct pipe_surface *ps = softpipe->framebuffer.zbuf; - GLuint clearVal; - - switch (ps->format) { - case PIPE_FORMAT_U_Z16: - clearVal = (GLuint) (softpipe->depth_test.clear * 65535.0); - break; - case PIPE_FORMAT_U_Z32: - clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffffff); - break; - case PIPE_FORMAT_S8_Z24: - clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff); - break; - default: + if (ps->format == PIPE_FORMAT_S8_Z24) { + GLuint mask = (softpipe->stencil.write_mask[0] << 8) | 0xffffff; + GLuint clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff); + clearVal |= (softpipe->stencil.clear_value << 24); + pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask); + } + else { + /* XXX Z24_S8 format? */ assert(0); } - - pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal); } + else { + /* separate Z and stencil */ + if (depth) { + struct pipe_surface *ps = softpipe->framebuffer.zbuf; + GLuint mask, clearVal; + + switch (ps->format) { + case PIPE_FORMAT_U_Z16: + clearVal = (GLuint) (softpipe->depth_test.clear * 65535.0); + mask = 0xffff; + break; + case PIPE_FORMAT_U_Z32: + clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffffff); + mask = 0xffffffff; + break; + case PIPE_FORMAT_S8_Z24: + clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff); + mask = 0xffffff; + break; + default: + assert(0); + } - if (stencil) { - struct pipe_surface *ps = softpipe->framebuffer.sbuf; - GLuint clearVal = softpipe->stencil.clear_value; - if (softpipe->stencil.write_mask[0] /*== 0xff*/) { - /* no masking */ - pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal); + pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask); } - else if (softpipe->stencil.write_mask[0] != 0x0) { - /* masking */ - /* fill with quad funcs */ - assert(0); + + if (stencil) { + struct pipe_surface *ps = softpipe->framebuffer.sbuf; + GLuint clearVal = softpipe->stencil.clear_value; + GLuint mask = 0xff; + if (softpipe->stencil.write_mask[0] /*== 0xff*/) { + /* no masking */ + pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask); + } + else if (softpipe->stencil.write_mask[0] != 0x0) { + /* masking */ + /* fill with quad funcs */ + assert(0); + } } } } diff --git a/src/mesa/pipe/softpipe/sp_region.c b/src/mesa/pipe/softpipe/sp_region.c index 4d8b35d3e71..34fbcce8ca2 100644 --- a/src/mesa/pipe/softpipe/sp_region.c +++ b/src/mesa/pipe/softpipe/sp_region.c @@ -105,7 +105,7 @@ sp_region_fill(struct pipe_context *pipe, struct pipe_region *dst, GLuint dst_offset, GLuint dstx, GLuint dsty, - GLuint width, GLuint height, GLuint value) + GLuint width, GLuint height, GLuint value, GLuint mask) { GLuint i, j; switch (dst->cpp) { -- 2.30.2