More work on glClear.
Add a 'mask' param to region_fill() to help with clearing combined Z/stencil buffers, glColorMask, etc.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user