Reroute some clear functionality.

Still require the intelClear() call to flush batchbuffers.  That will be
removed later...
This commit is contained in:
Keith Whitwell
2007-08-02 13:59:31 +01:00
parent 1ecc648398
commit 4f442d9ef5
8 changed files with 125 additions and 182 deletions

View File

@@ -295,110 +295,14 @@ intelWindowMoved(struct intel_context *intel)
/**
* Called by ctx->Driver.Clear.
* XXX NO LONGER USED - REMOVE IN NEAR FUTURE
*/
#if 0
static void
intelClear(GLcontext *ctx, GLbitfield mask)
#else
static void
OLD_intelClear(struct pipe_context *pipe,
GLboolean color, GLboolean depth,
GLboolean stencil, GLboolean accum)
#endif
{
GLcontext *ctx = (GLcontext *) pipe->glctx;
const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
GLbitfield tri_mask = 0;
GLbitfield blit_mask = 0;
GLbitfield swrast_mask = 0;
struct gl_framebuffer *fb = ctx->DrawBuffer;
GLuint i;
GLbitfield mask; /* XXX - kludge required because softpipe_clear uses
* region->fill(), which still calls intelBlit(!), but doesn't
if (color) * flush the batchbuffer.
mask = ctx->DrawBuffer->_ColorDrawBufferMask[0]; /*XXX temporary*/ *
else * One way or another, that behaviour should stop, and then this
mask = 0x0; * function can go aawy.
*/
if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
/* HW color buffers (front, back, aux, generic FBO, etc) */
if (colorMask == ~0) {
/* clear all R,G,B,A */
/* XXX FBO: need to check if colorbuffers are software RBOs! */
blit_mask |= (mask & BUFFER_BITS_COLOR);
}
else {
/* glColorMask in effect */
tri_mask |= (mask & BUFFER_BITS_COLOR);
}
/* HW stencil */
if (stencil) {
const struct pipe_region *stencilRegion
= intel_get_rb_region(fb, BUFFER_STENCIL);
if (stencilRegion) {
/* have hw stencil */
if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
/* not clearing all stencil bits, so use triangle clearing */
tri_mask |= BUFFER_BIT_STENCIL;
}
else {
/* clearing all stencil bits, use blitting */
blit_mask |= BUFFER_BIT_STENCIL;
}
}
}
/* HW depth */
if (depth) {
/* clear depth with whatever method is used for stencil (see above) */
if (tri_mask & BUFFER_BIT_STENCIL)
tri_mask |= BUFFER_BIT_DEPTH;
else
blit_mask |= BUFFER_BIT_DEPTH;
}
/* SW fallback clearing */
swrast_mask = mask & ~tri_mask & ~blit_mask;
for (i = 0; i < BUFFER_COUNT; i++) {
GLuint bufBit = 1 << i;
if ((blit_mask | tri_mask) & bufBit) {
if (!fb->Attachment[i].Renderbuffer->ClassID) {
blit_mask &= ~bufBit;
tri_mask &= ~bufBit;
swrast_mask |= bufBit;
}
}
}
intelFlush(ctx); /* XXX intelClearWithBlit also does this */
if (blit_mask)
intelClearWithBlit(ctx, blit_mask);
#if 0
if (swrast_mask | tri_mask)
_swrast_Clear(ctx, swrast_mask | tri_mask);
#else
softpipe_clear(pipe, GL_FALSE,
(swrast_mask | tri_mask) & BUFFER_BIT_DEPTH,
(swrast_mask | tri_mask) & BUFFER_BIT_STENCIL,
(swrast_mask | tri_mask) & BUFFER_BIT_ACCUM);
#endif
}
/**
* Clear buffers. Called via pipe->clear().
*/
void void
intelClear(struct pipe_context *pipe, intelClear(struct pipe_context *pipe,
GLboolean color, GLboolean depth, GLboolean color, GLboolean depth,
@@ -407,19 +311,9 @@ intelClear(struct pipe_context *pipe,
GLcontext *ctx = (GLcontext *) pipe->glctx; GLcontext *ctx = (GLcontext *) pipe->glctx;
struct intel_context *intel = intel_context(ctx); struct intel_context *intel = intel_context(ctx);
/* XXX
* Examine stencil and color writemasks to determine if we can clear
* with blits.
*/
intelFlush(&intel->ctx);
LOCK_HARDWARE(intel);
softpipe_clear(pipe, color, depth, stencil, accum); softpipe_clear(pipe, color, depth, stencil, accum);
intel_batchbuffer_flush(intel->batch); intel_batchbuffer_flush(intel->batch);
UNLOCK_HARDWARE(intel);
} }

View File

@@ -417,7 +417,12 @@ intelCreateContext(const __GLcontextModes * mesaVis,
*/ */
st_create_context( &intel->ctx, st_create_context( &intel->ctx,
softpipe_create() ); softpipe_create() );
/* KW: Not sure I like this - we should only be talking to the
* state_tracker. The pipe code will need some way of talking to
* us, eg for batchbuffer ioctls, and there will need to be a
* buffer manager interface. So, this is a temporary hack, right?
*/
intel->pipe = intel->ctx.st->pipe; intel->pipe = intel->ctx.st->pipe;
intel->pipe->screen = intelScreen; intel->pipe->screen = intelScreen;
intel->pipe->glctx = ctx; intel->pipe->glctx = ctx;

View File

@@ -178,15 +178,7 @@ _mesa_Clear( GLbitfield mask )
} }
ASSERT(ctx->Driver.Clear); ASSERT(ctx->Driver.Clear);
#if 0
ctx->Driver.Clear(ctx, bufferMask); ctx->Driver.Clear(ctx, bufferMask);
#else
st_clear(ctx->st,
(mask & GL_COLOR_BUFFER_BIT) ? GL_TRUE : GL_FALSE,
(bufferMask & BUFFER_BIT_DEPTH) ? GL_TRUE : GL_FALSE,
(bufferMask & BUFFER_BIT_STENCIL) ? GL_TRUE : GL_FALSE,
(bufferMask & BUFFER_BIT_ACCUM) ? GL_TRUE : GL_FALSE);
#endif
} }
} }

View File

@@ -60,53 +60,20 @@ 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 This should probaby be renamed to something like pipe_clear_with_blits()
* and moved into a device-independent pipe file.
*/
void void
softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth, softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
GLboolean stencil, GLboolean accum) GLboolean stencil, GLboolean accum)
{ {
const struct softpipe_context *softpipe = softpipe_context(pipe); struct softpipe_context *softpipe = softpipe_context(pipe);
GLint x, y, w, h; GLint x, y, w, h;
softpipe_update_derived(softpipe); softpipe_update_derived(softpipe); /* not needed?? */
x = softpipe->cliprect.minx; x = 0;
y = softpipe->cliprect.miny; y = 0;
w = softpipe->cliprect.maxx - x; w = softpipe->framebuffer.cbufs[0]->width;
h = softpipe->cliprect.maxy - y; h = softpipe->framebuffer.cbufs[0]->height;
if (color) { if (color) {
GLuint i; GLuint i;
@@ -114,8 +81,7 @@ softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
struct pipe_surface *ps = softpipe->framebuffer.cbufs[i]; struct pipe_surface *ps = softpipe->framebuffer.cbufs[i];
GLuint clearVal = color_value(ps->format, GLuint clearVal = color_value(ps->format,
softpipe->clear_color.color); 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, ~0);
pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask);
} }
} }
@@ -124,10 +90,13 @@ softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
/* clear Z and stencil together */ /* clear Z and stencil together */
struct pipe_surface *ps = softpipe->framebuffer.zbuf; struct pipe_surface *ps = softpipe->framebuffer.zbuf;
if (ps->format == PIPE_FORMAT_S8_Z24) { if (ps->format == PIPE_FORMAT_S8_Z24) {
GLuint mask = (softpipe->stencil.write_mask[0] << 8) | 0xffffff; GLuint mask = (softpipe->stencil.write_mask[0] << 8) | 0xffffff;
GLuint clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff); GLuint clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff);
assert (mask == ~0);
clearVal |= (softpipe->stencil.clear_value << 24); clearVal |= (softpipe->stencil.clear_value << 24);
pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask); pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, ~0);
} }
else { else {
/* XXX Z24_S8 format? */ /* XXX Z24_S8 format? */
@@ -138,33 +107,36 @@ softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
/* separate Z and stencil */ /* separate Z and stencil */
if (depth) { if (depth) {
struct pipe_surface *ps = softpipe->framebuffer.zbuf; struct pipe_surface *ps = softpipe->framebuffer.zbuf;
GLuint mask, clearVal; GLuint clearVal;
switch (ps->format) { switch (ps->format) {
case PIPE_FORMAT_U_Z16: case PIPE_FORMAT_U_Z16:
clearVal = (GLuint) (softpipe->depth_test.clear * 65535.0); clearVal = (GLuint) (softpipe->depth_test.clear * 65535.0);
mask = 0xffff;
break; break;
case PIPE_FORMAT_U_Z32: case PIPE_FORMAT_U_Z32:
clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffffff); clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffffff);
mask = 0xffffffff;
break; break;
case PIPE_FORMAT_S8_Z24: case PIPE_FORMAT_S8_Z24:
clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff); clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff);
mask = 0xffffff;
break; break;
default: default:
assert(0); assert(0);
} }
pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask); pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, ~0);
} }
if (stencil) { if (stencil) {
struct pipe_surface *ps = softpipe->framebuffer.sbuf; struct pipe_surface *ps = softpipe->framebuffer.sbuf;
GLuint clearVal = softpipe->stencil.clear_value; 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]; GLuint mask = softpipe->stencil.write_mask[0];
assert((mask & 0xff) == 0xff);
switch (ps->format) { switch (ps->format) {
case PIPE_FORMAT_S8_Z24: case PIPE_FORMAT_S8_Z24:
clearVal = clearVal << 24; clearVal = clearVal << 24;
@@ -187,7 +159,7 @@ softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
*/ */
struct pipe_surface *ps = softpipe->framebuffer.abuf; struct pipe_surface *ps = softpipe->framebuffer.abuf;
GLuint clearVal = 0x0; /* XXX FIX */ GLuint clearVal = 0x0; /* XXX FIX */
GLuint mask = !0; GLuint mask = ~0;
assert(ps); assert(ps);
pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask); pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask);
} }

View File

@@ -191,6 +191,7 @@ STATETRACKER_SOURCES = \
state_tracker/st_atom_stencil.c \ state_tracker/st_atom_stencil.c \
state_tracker/st_atom_stipple.c \ state_tracker/st_atom_stipple.c \
state_tracker/st_atom_viewport.c \ state_tracker/st_atom_viewport.c \
state_tracker/st_cb_clear.c \
state_tracker/st_cb_program.c \ state_tracker/st_cb_program.c \
state_tracker/st_draw.c \ state_tracker/st_draw.c \
state_tracker/st_context.c \ state_tracker/st_context.c \

View File

@@ -0,0 +1,89 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
* Brian Paul
*/
#include "st_context.h"
#include "glheader.h"
#include "macros.h"
#include "enums.h"
#include "st_context.h"
#include "st_atom.h"
#include "pipe/p_context.h"
/* XXX: doesn't pick up the differences between front/back/left/right
* clears. Need to sort that out...
*/
static void st_clear(GLcontext *ctx, GLbitfield mask)
{
struct st_context *st = ctx->st;
GLboolean color = (mask & BUFFER_BITS_COLOR) ? GL_TRUE : GL_FALSE;
GLboolean depth = (mask & BUFFER_BIT_DEPTH) ? GL_TRUE : GL_FALSE;
GLboolean stencil = (mask & BUFFER_BIT_STENCIL) ? GL_TRUE : GL_FALSE;
GLboolean accum = (mask & BUFFER_BIT_ACCUM) ? GL_TRUE : GL_FALSE;
GLboolean fullscreen = 1; /* :-) */
/* This makes sure the softpipe has the latest scissor, etc values */
st_validate_state( st );
if (fullscreen) {
/* pipe->clear() should clear a particular surface, so that we
* can iterate over render buffers at this level and clear the
* 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, accum);
}
else {
/* Convert to geometry, etc:
*/
}
}
void st_init_cb_clear( struct st_context *st )
{
struct dd_function_table *functions = &st->ctx->Driver;
functions->Clear = st_clear;
}
void st_destroy_cb_clear( struct st_context *st )
{
}

View File

@@ -58,6 +58,7 @@ struct st_context *st_create_context( GLcontext *ctx,
st_init_atoms( st ); st_init_atoms( st );
st_init_draw( st ); st_init_draw( st );
st_init_cb_program( st ); st_init_cb_program( st );
st_init_cb_clear( st );
return st; return st;
} }

View File

@@ -107,14 +107,3 @@ void st_destroy_draw( struct st_context *st )
} }
/** XXX temporary here */
void
st_clear(struct st_context *st, GLboolean color, GLboolean depth,
GLboolean stencil, GLboolean accum)
{
/* This makes sure the softpipe has the latest scissor, etc values */
st_validate_state( st );
st->pipe->clear(st->pipe, color, depth, stencil, accum);
}