summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-08-01 14:46:07 -0600
committerBrian <[email protected]>2007-08-01 14:46:07 -0600
commit0eb02a1963a25f6994b730147d0613b03424c11e (patch)
treec5c2dc736ee8d1de5ac2da60888786e7b8549ec6
parentcddce60e7b14171f7afb204be5c131ce73ce01c5 (diff)
More work on glClear.
Add a 'mask' param to region_fill() to help with clearing combined Z/stencil buffers, glColorMask, etc.
-rw-r--r--src/mesa/drivers/dri/i915pipe/intel_blit.c22
-rw-r--r--src/mesa/drivers/dri/i915pipe/intel_blit.h2
-rw-r--r--src/mesa/drivers/dri/i915pipe/intel_regions.c5
-rw-r--r--src/mesa/pipe/p_context.h3
-rw-r--r--src/mesa/pipe/softpipe/sp_clear.c127
-rw-r--r--src/mesa/pipe/softpipe/sp_region.c2
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) {