pipe->clear() now takes a surface, rather than color/depth/stencil flags.
pipe->clear() only used to clear whole buffers (no scissor) w/out masking. Draw a colored quadrilateral in all other cases.
This commit is contained in:
@@ -1573,7 +1573,10 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
|
|||||||
|
|
||||||
st_create_context( mesaCtx,
|
st_create_context( mesaCtx,
|
||||||
softpipe_create() );
|
softpipe_create() );
|
||||||
|
mesaCtx->Driver.Clear = xmesa_clear_buffers;
|
||||||
|
/*
|
||||||
mesaCtx->st->pipe->clear = xmesa_clear;
|
mesaCtx->st->pipe->clear = xmesa_clear;
|
||||||
|
*/
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@@ -381,8 +381,8 @@ clear_nbit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
clear_buffers(GLcontext *ctx, GLbitfield buffers)
|
xmesa_clear_buffers(GLcontext *ctx, GLbitfield buffers)
|
||||||
{
|
{
|
||||||
if (ctx->DrawBuffer->Name == 0) {
|
if (ctx->DrawBuffer->Name == 0) {
|
||||||
/* this is a window system framebuffer */
|
/* this is a window system framebuffer */
|
||||||
@@ -395,7 +395,6 @@ clear_buffers(GLcontext *ctx, GLbitfield buffers)
|
|||||||
|
|
||||||
/* we can't handle color or index masking */
|
/* we can't handle color or index masking */
|
||||||
if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
|
if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
|
||||||
#if 0
|
|
||||||
if (buffers & BUFFER_BIT_FRONT_LEFT) {
|
if (buffers & BUFFER_BIT_FRONT_LEFT) {
|
||||||
/* clear front color buffer */
|
/* clear front color buffer */
|
||||||
struct gl_renderbuffer *frontRb
|
struct gl_renderbuffer *frontRb
|
||||||
@@ -419,14 +418,6 @@ clear_buffers(GLcontext *ctx, GLbitfield buffers)
|
|||||||
buffers &= ~BUFFER_BIT_BACK_LEFT;
|
buffers &= ~BUFFER_BIT_BACK_LEFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
/* Clear with state-tracker/pipe interface */
|
|
||||||
struct st_context *st = st_context(ctx);
|
|
||||||
GLboolean color = (buffers & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) ? 1: 0;
|
|
||||||
GLboolean depth = (buffers & BUFFER_BIT_DEPTH) ? 1 : 0;
|
|
||||||
GLboolean stencil = (buffers & BUFFER_BIT_STENCIL) ? 1 : 0;
|
|
||||||
st_clear(st, color, depth, stencil);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buffers)
|
if (buffers)
|
||||||
@@ -434,6 +425,7 @@ clear_buffers(GLcontext *ctx, GLbitfield buffers)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
void
|
void
|
||||||
xmesa_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
|
xmesa_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
|
||||||
GLboolean stencil, GLboolean accum)
|
GLboolean stencil, GLboolean accum)
|
||||||
@@ -458,11 +450,16 @@ xmesa_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
|
|||||||
xrb->clearFunc(ctx, xrb, x, y, w, h);
|
xrb->clearFunc(ctx, xrb, x, y, w, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, GLuint value)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef XFree86Server
|
#ifndef XFree86Server
|
||||||
/* XXX this was never tested in the Xserver environment */
|
/* XXX this was never tested in the Xserver environment */
|
||||||
|
|
||||||
@@ -1113,7 +1110,7 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
|
|||||||
driver->IndexMask = index_mask;
|
driver->IndexMask = index_mask;
|
||||||
driver->ColorMask = color_mask;
|
driver->ColorMask = color_mask;
|
||||||
driver->Enable = enable;
|
driver->Enable = enable;
|
||||||
driver->Clear = clear_buffers;
|
driver->Clear = xmesa_clear_buffers;
|
||||||
driver->Viewport = xmesa_viewport;
|
driver->Viewport = xmesa_viewport;
|
||||||
#ifndef XFree86Server
|
#ifndef XFree86Server
|
||||||
driver->CopyPixels = xmesa_CopyPixels;
|
driver->CopyPixels = xmesa_CopyPixels;
|
||||||
|
@@ -593,7 +593,10 @@ extern struct pipe_surface *
|
|||||||
xmesa_new_surface(GLcontext *ctx, struct xmesa_renderbuffer *xrb);
|
xmesa_new_surface(GLcontext *ctx, struct xmesa_renderbuffer *xrb);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
xmesa_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
|
xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, GLuint value);
|
||||||
GLboolean stencil, GLboolean accum);
|
|
||||||
|
extern void
|
||||||
|
xmesa_clear_buffers(GLcontext *ctx, GLbitfield buffers);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -60,9 +60,9 @@ struct pipe_context {
|
|||||||
GLuint numVertex, const GLfloat *verts,
|
GLuint numVertex, const GLfloat *verts,
|
||||||
GLuint numAttribs, const GLuint attribs[]);
|
GLuint numAttribs, const GLuint attribs[]);
|
||||||
|
|
||||||
/** Clear framebuffer */
|
/** Clear a surface to given value (no scissor; clear whole surface) */
|
||||||
void (*clear)(struct pipe_context *pipe, GLboolean color, GLboolean depth,
|
void (*clear)(struct pipe_context *pipe, struct pipe_surface *ps,
|
||||||
GLboolean stencil);
|
GLuint clearValue);
|
||||||
|
|
||||||
/** occlusion counting (XXX this may be temporary - we should probably
|
/** occlusion counting (XXX this may be temporary - we should probably
|
||||||
* have generic query objects with begin/end methods)
|
* have generic query objects with begin/end methods)
|
||||||
|
@@ -38,32 +38,13 @@
|
|||||||
#include "colormac.h"
|
#include "colormac.h"
|
||||||
|
|
||||||
|
|
||||||
static GLuint
|
/**
|
||||||
color_value(GLuint format, const GLfloat color[4])
|
* Clear the given surface to the specified value.
|
||||||
{
|
* No masking, no scissor (clear entire buffer).
|
||||||
GLubyte r, g, b, a;
|
*/
|
||||||
|
|
||||||
UNCLAMPED_FLOAT_TO_UBYTE(r, color[0]);
|
|
||||||
UNCLAMPED_FLOAT_TO_UBYTE(g, color[1]);
|
|
||||||
UNCLAMPED_FLOAT_TO_UBYTE(b, color[2]);
|
|
||||||
UNCLAMPED_FLOAT_TO_UBYTE(a, color[3]);
|
|
||||||
|
|
||||||
switch (format) {
|
|
||||||
case PIPE_FORMAT_U_R8_G8_B8_A8:
|
|
||||||
return (r << 24) | (g << 16) | (b << 8) | a;
|
|
||||||
case PIPE_FORMAT_U_A8_R8_G8_B8:
|
|
||||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
|
||||||
case PIPE_FORMAT_U_R5_G6_B5:
|
|
||||||
return ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
|
softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
|
||||||
GLboolean stencil)
|
GLuint clearValue)
|
||||||
{
|
{
|
||||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||||
GLint x, y, w, h;
|
GLint x, y, w, h;
|
||||||
@@ -75,81 +56,5 @@ softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
|
|||||||
w = softpipe->framebuffer.cbufs[0]->width;
|
w = softpipe->framebuffer.cbufs[0]->width;
|
||||||
h = softpipe->framebuffer.cbufs[0]->height;
|
h = softpipe->framebuffer.cbufs[0]->height;
|
||||||
|
|
||||||
if (color) {
|
pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearValue, ~0);
|
||||||
GLuint i;
|
|
||||||
for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
|
|
||||||
struct pipe_surface *ps = softpipe->framebuffer.cbufs[i];
|
|
||||||
GLuint clearVal = color_value(ps->format,
|
|
||||||
softpipe->clear_color.color);
|
|
||||||
pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, ~0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (depth && stencil &&
|
|
||||||
softpipe->framebuffer.zbuf == softpipe->framebuffer.sbuf) {
|
|
||||||
/* clear Z and stencil together */
|
|
||||||
struct pipe_surface *ps = softpipe->framebuffer.zbuf;
|
|
||||||
if (ps->format == PIPE_FORMAT_S8_Z24) {
|
|
||||||
GLuint mask = (softpipe->stencil.write_mask[0] << 8) | 0xffffff;
|
|
||||||
GLuint clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff);
|
|
||||||
|
|
||||||
assert (mask == ~0);
|
|
||||||
|
|
||||||
clearVal |= (softpipe->stencil.clear_value << 24);
|
|
||||||
pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, ~0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* XXX Z24_S8 format? */
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* separate Z and stencil */
|
|
||||||
if (depth) {
|
|
||||||
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:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, ~0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stencil) {
|
|
||||||
struct pipe_surface *ps = softpipe->framebuffer.sbuf;
|
|
||||||
GLuint clearVal = softpipe->stencil.clear_value;
|
|
||||||
|
|
||||||
/* If this is not ~0, we shouldn't get here - clear should be
|
|
||||||
* done with geometry instead.
|
|
||||||
*/
|
|
||||||
GLuint mask = softpipe->stencil.write_mask[0];
|
|
||||||
|
|
||||||
assert((mask & 0xff) == 0xff);
|
|
||||||
|
|
||||||
switch (ps->format) {
|
|
||||||
case PIPE_FORMAT_S8_Z24:
|
|
||||||
clearVal = clearVal << 24;
|
|
||||||
mask = mask << 24;
|
|
||||||
break;
|
|
||||||
case PIPE_FORMAT_U_S8:
|
|
||||||
/* nothing */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -36,8 +36,8 @@
|
|||||||
struct pipe_context;
|
struct pipe_context;
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
|
softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
|
||||||
GLboolean stencil);
|
GLuint clearValue);
|
||||||
|
|
||||||
|
|
||||||
#endif /* SP_CLEAR_H */
|
#endif /* SP_CLEAR_H */
|
||||||
|
@@ -43,6 +43,65 @@
|
|||||||
#include "vf/vf.h"
|
#include "vf/vf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static GLuint
|
||||||
|
color_value(GLuint pipeFormat, const GLfloat color[4])
|
||||||
|
{
|
||||||
|
GLubyte r, g, b, a;
|
||||||
|
|
||||||
|
UNCLAMPED_FLOAT_TO_UBYTE(r, color[0]);
|
||||||
|
UNCLAMPED_FLOAT_TO_UBYTE(g, color[1]);
|
||||||
|
UNCLAMPED_FLOAT_TO_UBYTE(b, color[2]);
|
||||||
|
UNCLAMPED_FLOAT_TO_UBYTE(a, color[3]);
|
||||||
|
|
||||||
|
switch (pipeFormat) {
|
||||||
|
case PIPE_FORMAT_U_R8_G8_B8_A8:
|
||||||
|
return (r << 24) | (g << 16) | (b << 8) | a;
|
||||||
|
case PIPE_FORMAT_U_A8_R8_G8_B8:
|
||||||
|
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||||
|
case PIPE_FORMAT_U_R5_G6_B5:
|
||||||
|
return ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GLuint
|
||||||
|
depth_value(GLuint pipeFormat, GLfloat value)
|
||||||
|
{
|
||||||
|
GLuint val;
|
||||||
|
switch (pipeFormat) {
|
||||||
|
case PIPE_FORMAT_U_Z16:
|
||||||
|
val = (GLuint) (value * 0xffffff);
|
||||||
|
break;
|
||||||
|
case PIPE_FORMAT_U_Z32:
|
||||||
|
val = (GLuint) (value * 0xffffffff);
|
||||||
|
break;
|
||||||
|
case PIPE_FORMAT_S8_Z24:
|
||||||
|
/*case PIPE_FORMAT_Z24_S8:*/
|
||||||
|
val = (GLuint) (value * 0xffffff);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
is_depth_stencil_format(GLuint pipeFormat)
|
||||||
|
{
|
||||||
|
switch (pipeFormat) {
|
||||||
|
case PIPE_FORMAT_S8_Z24:
|
||||||
|
/*case PIPE_FORMAT_Z24_S8:*/
|
||||||
|
return GL_TRUE;
|
||||||
|
default:
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw a screen-aligned quadrilateral.
|
* Draw a screen-aligned quadrilateral.
|
||||||
* Coords are window coords.
|
* Coords are window coords.
|
||||||
@@ -92,7 +151,8 @@ draw_quad(GLcontext *ctx,
|
|||||||
* Do glClear by drawing a quadrilateral.
|
* Do glClear by drawing a quadrilateral.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
clear_with_quad(GLcontext *ctx,
|
clear_with_quad(GLcontext *ctx, GLuint x0, GLuint y0,
|
||||||
|
GLuint x1, GLuint y1,
|
||||||
GLboolean color, GLboolean depth, GLboolean stencil)
|
GLboolean color, GLboolean depth, GLboolean stencil)
|
||||||
{
|
{
|
||||||
struct st_context *st = ctx->st;
|
struct st_context *st = ctx->st;
|
||||||
@@ -133,6 +193,8 @@ clear_with_quad(GLcontext *ctx,
|
|||||||
|
|
||||||
/* setup state: nothing */
|
/* setup state: nothing */
|
||||||
memset(&setup, 0, sizeof(setup));
|
memset(&setup, 0, sizeof(setup));
|
||||||
|
if (ctx->Scissor.Enabled)
|
||||||
|
setup.scissor = 1;
|
||||||
st->pipe->set_setup_state(st->pipe, &setup);
|
st->pipe->set_setup_state(st->pipe, &setup);
|
||||||
|
|
||||||
/* stencil state: always set to ref value */
|
/* stencil state: always set to ref value */
|
||||||
@@ -145,18 +207,14 @@ clear_with_quad(GLcontext *ctx,
|
|||||||
stencil_test.front_zfail_op = PIPE_STENCIL_OP_REPLACE;
|
stencil_test.front_zfail_op = PIPE_STENCIL_OP_REPLACE;
|
||||||
stencil_test.ref_value[0] = ctx->Stencil.Clear;
|
stencil_test.ref_value[0] = ctx->Stencil.Clear;
|
||||||
stencil_test.value_mask[0] = 0xff;
|
stencil_test.value_mask[0] = 0xff;
|
||||||
stencil_test.write_mask[0] = ctx->Stencil.WriteMask[0];
|
stencil_test.write_mask[0] = ctx->Stencil.WriteMask[0] & 0xff;
|
||||||
}
|
}
|
||||||
st->pipe->set_stencil_state(st->pipe, &stencil_test);
|
st->pipe->set_stencil_state(st->pipe, &stencil_test);
|
||||||
|
|
||||||
/* draw quad matching scissor rect (XXX verify coord round-off) */
|
/* draw quad matching scissor rect (XXX verify coord round-off) */
|
||||||
draw_quad(ctx,
|
draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor);
|
||||||
ctx->Scissor.X, ctx->Scissor.Y,
|
|
||||||
ctx->Scissor.X + ctx->Scissor.Width,
|
|
||||||
ctx->Scissor.Y + ctx->Scissor.Height,
|
|
||||||
ctx->Depth.Clear, ctx->Color.ClearColor);
|
|
||||||
|
|
||||||
/* Restore GL state */
|
/* Restore pipe state */
|
||||||
st->pipe->set_alpha_test_state(st->pipe, &st->state.alpha_test);
|
st->pipe->set_alpha_test_state(st->pipe, &st->state.alpha_test);
|
||||||
st->pipe->set_blend_state(st->pipe, &st->state.blend);
|
st->pipe->set_blend_state(st->pipe, &st->state.blend);
|
||||||
st->pipe->set_depth_state(st->pipe, &st->state.depth);
|
st->pipe->set_depth_state(st->pipe, &st->state.depth);
|
||||||
@@ -168,6 +226,141 @@ clear_with_quad(GLcontext *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||||
|
{
|
||||||
|
if (ctx->Color.ColorMask[0] &&
|
||||||
|
ctx->Color.ColorMask[1] &&
|
||||||
|
ctx->Color.ColorMask[2] &&
|
||||||
|
ctx->Color.ColorMask[3] &&
|
||||||
|
!ctx->Scissor.Enabled)
|
||||||
|
{
|
||||||
|
/* clear whole buffer w/out masking */
|
||||||
|
GLuint clearValue
|
||||||
|
= color_value(rb->surface->format, ctx->Color.ClearColor);
|
||||||
|
ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* masking or scissoring */
|
||||||
|
clear_with_quad(ctx,
|
||||||
|
ctx->DrawBuffer->_Xmin,
|
||||||
|
ctx->DrawBuffer->_Xmin,
|
||||||
|
ctx->DrawBuffer->_Xmax,
|
||||||
|
ctx->DrawBuffer->_Ymax,
|
||||||
|
GL_TRUE, GL_FALSE, GL_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||||
|
{
|
||||||
|
if (!ctx->Scissor.Enabled) {
|
||||||
|
/* clear whole buffer w/out masking */
|
||||||
|
GLuint clearValue
|
||||||
|
= color_value(rb->surface->format, ctx->Accum.ClearColor);
|
||||||
|
/* Note that clearValue is 32 bits but the accum buffer will
|
||||||
|
* typically be 64bpp...
|
||||||
|
*/
|
||||||
|
ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* scissoring */
|
||||||
|
/* XXX point framebuffer.cbufs[0] at the accum buffer */
|
||||||
|
clear_with_quad(ctx,
|
||||||
|
ctx->DrawBuffer->_Xmin,
|
||||||
|
ctx->DrawBuffer->_Xmin,
|
||||||
|
ctx->DrawBuffer->_Xmax,
|
||||||
|
ctx->DrawBuffer->_Ymax,
|
||||||
|
GL_TRUE, GL_FALSE, GL_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||||
|
{
|
||||||
|
if (!ctx->Scissor.Enabled &&
|
||||||
|
!is_depth_stencil_format(rb->surface->format)) {
|
||||||
|
/* clear whole depth buffer w/out masking */
|
||||||
|
GLuint clearValue = depth_value(rb->surface->format, ctx->Depth.Clear);
|
||||||
|
ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* masking or scissoring or combined z/stencil buffer */
|
||||||
|
clear_with_quad(ctx,
|
||||||
|
ctx->DrawBuffer->_Xmin,
|
||||||
|
ctx->DrawBuffer->_Xmin,
|
||||||
|
ctx->DrawBuffer->_Xmax,
|
||||||
|
ctx->DrawBuffer->_Ymax,
|
||||||
|
GL_FALSE, GL_TRUE, GL_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||||
|
{
|
||||||
|
const GLuint stencilMax = (1 << rb->StencilBits) - 1;
|
||||||
|
GLboolean maskStencil = ctx->Stencil.WriteMask[0] != stencilMax;
|
||||||
|
|
||||||
|
if (!maskStencil && !ctx->Scissor.Enabled &&
|
||||||
|
!is_depth_stencil_format(rb->surface->format)) {
|
||||||
|
/* clear whole stencil buffer w/out masking */
|
||||||
|
GLuint clearValue = ctx->Stencil.Clear;
|
||||||
|
ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* masking or scissoring */
|
||||||
|
clear_with_quad(ctx,
|
||||||
|
ctx->DrawBuffer->_Xmin,
|
||||||
|
ctx->DrawBuffer->_Xmin,
|
||||||
|
ctx->DrawBuffer->_Xmax,
|
||||||
|
ctx->DrawBuffer->_Ymax,
|
||||||
|
GL_FALSE, GL_FALSE, GL_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||||
|
{
|
||||||
|
const GLuint stencilMax = 1 << rb->StencilBits;
|
||||||
|
GLboolean maskStencil = ctx->Stencil.WriteMask[0] != stencilMax;
|
||||||
|
|
||||||
|
assert(is_depth_stencil_format(rb->surface->format));
|
||||||
|
|
||||||
|
if (!maskStencil && !ctx->Scissor.Enabled) {
|
||||||
|
/* clear whole buffer w/out masking */
|
||||||
|
GLuint clearValue = depth_value(rb->surface->format, ctx->Depth.Clear);
|
||||||
|
|
||||||
|
switch (rb->surface->format) {
|
||||||
|
case PIPE_FORMAT_S8_Z24:
|
||||||
|
clearValue |= ctx->Stencil.Clear << 24;
|
||||||
|
break;
|
||||||
|
#if 0
|
||||||
|
case PIPE_FORMAT_Z24_S8:
|
||||||
|
clearValue = (clearValue << 8) | clearVal;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* masking or scissoring */
|
||||||
|
clear_with_quad(ctx,
|
||||||
|
ctx->DrawBuffer->_Xmin,
|
||||||
|
ctx->DrawBuffer->_Xmin,
|
||||||
|
ctx->DrawBuffer->_Xmax,
|
||||||
|
ctx->DrawBuffer->_Ymax,
|
||||||
|
GL_FALSE, GL_TRUE, GL_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called via ctx->Driver.Clear()
|
* Called via ctx->Driver.Clear()
|
||||||
@@ -176,41 +369,52 @@ clear_with_quad(GLcontext *ctx,
|
|||||||
*/
|
*/
|
||||||
static void st_clear(GLcontext *ctx, GLbitfield mask)
|
static void st_clear(GLcontext *ctx, GLbitfield mask)
|
||||||
{
|
{
|
||||||
|
static const GLbitfield BUFFER_BITS_DS
|
||||||
|
= (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
|
||||||
struct st_context *st = ctx->st;
|
struct st_context *st = ctx->st;
|
||||||
GLboolean color = (mask & BUFFER_BITS_COLOR) ? GL_TRUE : GL_FALSE;
|
struct gl_renderbuffer *depthRb
|
||||||
GLboolean depth = (mask & BUFFER_BIT_DEPTH) ? GL_TRUE : GL_FALSE;
|
= ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
|
||||||
GLboolean stencil = (mask & BUFFER_BIT_STENCIL) ? GL_TRUE : GL_FALSE;
|
struct gl_renderbuffer *stencilRb
|
||||||
GLboolean accum = (mask & BUFFER_BIT_ACCUM) ? GL_TRUE : GL_FALSE;
|
= ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
|
||||||
|
|
||||||
GLboolean maskColor, maskStencil;
|
|
||||||
GLboolean fullscreen = !ctx->Scissor.Enabled;
|
|
||||||
GLuint stencilMax = stencil ? (1 << ctx->DrawBuffer->_StencilBuffer->StencilBits) : 0;
|
|
||||||
|
|
||||||
/* This makes sure the softpipe has the latest scissor, etc values */
|
/* This makes sure the softpipe has the latest scissor, etc values */
|
||||||
st_validate_state( st );
|
st_validate_state( st );
|
||||||
|
|
||||||
maskColor = color && st->state.blend.colormask != PIPE_MASK_RGBA;
|
/*
|
||||||
maskStencil = stencil && ctx->Stencil.WriteMask[0] != stencilMax;
|
* XXX TO-DO:
|
||||||
|
* If we're going to use clear_with_quad() for any reason, use it to
|
||||||
if (fullscreen && !maskColor && !maskStencil) {
|
* clear as many other buffers as possible.
|
||||||
/* pipe->clear() should clear a particular surface, so that we
|
* As it is now, we sometimes call clear_with_quad() three times to clear
|
||||||
* can iterate over render buffers at this level and clear the
|
* color/depth/stencil individually...
|
||||||
* ones GL is asking for.
|
|
||||||
*
|
|
||||||
* Will probably need something like pipe->clear_z_stencil() to
|
|
||||||
* cope with the special case of paired and unpaired z/stencil
|
|
||||||
* buffers, though could perhaps deal with them explicitly at
|
|
||||||
* this level.
|
|
||||||
*/
|
*/
|
||||||
st->pipe->clear(st->pipe, color, depth, stencil);
|
|
||||||
|
|
||||||
/* And here we would do a clear on whatever surface we are using
|
if (mask & BUFFER_BITS_COLOR) {
|
||||||
* to implement accum buffers:
|
GLuint b;
|
||||||
*/
|
for (b = 0; b < BUFFER_COUNT; b++) {
|
||||||
assert(!accum);
|
if (BUFFER_BITS_COLOR & mask & (1 << b)) {
|
||||||
|
clear_color_buffer(ctx,
|
||||||
|
ctx->DrawBuffer->Attachment[b].Renderbuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & BUFFER_BIT_ACCUM) {
|
||||||
|
clear_accum_buffer(ctx,
|
||||||
|
ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) {
|
||||||
|
/* clearing combined depth + stencil */
|
||||||
|
clear_depth_stencil_buffer(ctx, depthRb);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
clear_with_quad(ctx, color, depth, stencil);
|
/* separate depth/stencil clears */
|
||||||
|
if (mask & BUFFER_BIT_DEPTH) {
|
||||||
|
clear_depth_buffer(ctx, depthRb);
|
||||||
|
}
|
||||||
|
if (mask & BUFFER_BIT_STENCIL) {
|
||||||
|
clear_stencil_buffer(ctx, stencilRb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user