gallium: Clean up driver clear() interface.
Only allows clearing currently bound buffers, but colour and depth/stencil in a single call.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
@@ -29,6 +30,7 @@
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
* Brian Paul
|
||||
* Michel Dänzer
|
||||
*/
|
||||
|
||||
#include "main/glheader.h"
|
||||
@@ -373,101 +375,6 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||
|
||||
|
||||
|
||||
static void
|
||||
clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||
{
|
||||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
|
||||
if (!strb->surface)
|
||||
return;
|
||||
|
||||
if (check_clear_color_with_quad( ctx, rb )) {
|
||||
/* masking or scissoring */
|
||||
clear_with_quad(ctx, GL_TRUE, GL_FALSE, GL_FALSE);
|
||||
}
|
||||
else {
|
||||
/* clear whole buffer w/out masking */
|
||||
uint clearValue;
|
||||
/* NOTE: we always pass the clear color as PIPE_FORMAT_A8R8G8B8_UNORM
|
||||
* at this time!
|
||||
*/
|
||||
util_pack_color(ctx->Color.ClearColor, PIPE_FORMAT_A8R8G8B8_UNORM, &clearValue);
|
||||
ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||
{
|
||||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
|
||||
if (!strb->surface)
|
||||
return;
|
||||
|
||||
if (check_clear_depth_with_quad(ctx, rb)) {
|
||||
/* scissoring or we have a combined depth/stencil buffer */
|
||||
clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_FALSE);
|
||||
}
|
||||
else {
|
||||
/* simple clear of whole buffer */
|
||||
uint clearValue = util_pack_z(strb->surface->format, ctx->Depth.Clear);
|
||||
ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||
{
|
||||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
|
||||
if (!strb->surface)
|
||||
return;
|
||||
|
||||
if (check_clear_stencil_with_quad(ctx, rb)) {
|
||||
/* masking or scissoring or combined depth/stencil buffer */
|
||||
clear_with_quad(ctx, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
}
|
||||
else {
|
||||
/* simple clear of whole buffer */
|
||||
GLuint clearValue = ctx->Stencil.Clear;
|
||||
|
||||
switch (strb->surface->format) {
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
clearValue <<= 24;
|
||||
break;
|
||||
default:
|
||||
; /* no-op, stencil value is in least significant bits */
|
||||
}
|
||||
|
||||
ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||
{
|
||||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
|
||||
if (!strb->surface)
|
||||
return;
|
||||
|
||||
if (check_clear_depth_stencil_with_quad(ctx, rb)) {
|
||||
/* masking or scissoring */
|
||||
clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_TRUE);
|
||||
}
|
||||
else {
|
||||
/* clear whole buffer w/out masking */
|
||||
GLuint clearValue = util_pack_z_stencil(strb->surface->format,
|
||||
ctx->Depth.Clear,
|
||||
ctx->Stencil.Clear);
|
||||
ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void st_flush_clear( struct st_context *st )
|
||||
{
|
||||
/* Release vertex buffer to avoid synchronous rendering if we were
|
||||
@@ -493,51 +400,89 @@ static void st_clear(GLcontext *ctx, GLbitfield mask)
|
||||
= ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
|
||||
struct gl_renderbuffer *stencilRb
|
||||
= ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
|
||||
GLbitfield cmask = mask & BUFFER_BITS_COLOR;
|
||||
GLbitfield quad_buffers = 0;
|
||||
GLbitfield clear_buffers = 0;
|
||||
GLuint i;
|
||||
|
||||
/* This makes sure the softpipe has the latest scissor, etc values */
|
||||
/* This makes sure the pipe has the latest scissor, etc values */
|
||||
st_validate_state( st );
|
||||
|
||||
/*
|
||||
* XXX TO-DO:
|
||||
* If we're going to use clear_with_quad() for any reason, use it to
|
||||
* clear as many other buffers as possible.
|
||||
* As it is now, we sometimes call clear_with_quad() three times to clear
|
||||
* color/depth/stencil individually...
|
||||
*/
|
||||
if (mask & BUFFER_BITS_COLOR) {
|
||||
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
|
||||
GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
|
||||
|
||||
if (cmask) {
|
||||
GLuint b;
|
||||
for (b = 0; cmask; b++) {
|
||||
if (cmask & (1 << b)) {
|
||||
if (mask & (1 << b)) {
|
||||
struct gl_renderbuffer *rb
|
||||
= ctx->DrawBuffer->Attachment[b].Renderbuffer;
|
||||
assert(rb);
|
||||
clear_color_buffer(ctx, rb);
|
||||
cmask &= ~(1 << b); /* turn off bit */
|
||||
}
|
||||
assert(b < BUFFER_COUNT);
|
||||
}
|
||||
}
|
||||
struct st_renderbuffer *strb;
|
||||
|
||||
if (mask & BUFFER_BIT_ACCUM) {
|
||||
st_clear_accum_buffer(ctx,
|
||||
ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
|
||||
assert(rb);
|
||||
|
||||
strb = st_renderbuffer(rb);
|
||||
|
||||
if (!strb->surface)
|
||||
continue;
|
||||
|
||||
if (check_clear_color_with_quad( ctx, rb ))
|
||||
quad_buffers |= PIPE_CLEAR_COLOR;
|
||||
else
|
||||
clear_buffers |= PIPE_CLEAR_COLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) {
|
||||
/* clearing combined depth + stencil */
|
||||
clear_depth_stencil_buffer(ctx, depthRb);
|
||||
struct st_renderbuffer *strb = st_renderbuffer(depthRb);
|
||||
|
||||
if (strb->surface) {
|
||||
if (check_clear_depth_stencil_with_quad(ctx, depthRb))
|
||||
quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
|
||||
else
|
||||
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* separate depth/stencil clears */
|
||||
if (mask & BUFFER_BIT_DEPTH) {
|
||||
clear_depth_buffer(ctx, depthRb);
|
||||
struct st_renderbuffer *strb = st_renderbuffer(depthRb);
|
||||
|
||||
if (strb->surface) {
|
||||
if (check_clear_depth_with_quad(ctx, depthRb))
|
||||
quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
|
||||
else
|
||||
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
|
||||
}
|
||||
}
|
||||
if (mask & BUFFER_BIT_STENCIL) {
|
||||
clear_stencil_buffer(ctx, stencilRb);
|
||||
struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
|
||||
|
||||
if (strb->surface) {
|
||||
if (check_clear_stencil_with_quad(ctx, stencilRb))
|
||||
quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
|
||||
else
|
||||
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're going to use clear_with_quad() for any reason, use it for
|
||||
* everything possible.
|
||||
*/
|
||||
if (quad_buffers) {
|
||||
quad_buffers |= clear_buffers;
|
||||
clear_with_quad(ctx,
|
||||
quad_buffers & PIPE_CLEAR_COLOR,
|
||||
mask & BUFFER_BIT_DEPTH,
|
||||
mask & BUFFER_BIT_STENCIL);
|
||||
} else if (clear_buffers)
|
||||
ctx->st->pipe->clear(ctx->st->pipe, clear_buffers, ctx->Color.ClearColor,
|
||||
ctx->Depth.Clear, ctx->Stencil.Clear);
|
||||
|
||||
if (mask & BUFFER_BIT_ACCUM)
|
||||
st_clear_accum_buffer(ctx,
|
||||
ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user