mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 15:48:36 +02:00
swrast: do depth/stencil clearing with Map/UnmapRenderbuffer()
Another step toward getting rid of the renderbuffer PutRow/etc functions. v2: fix assorted depth/stencil clear bugs found by Eric Reviewed-by: José Fonseca <jfonseca@vmware.com>
This commit is contained in:
parent
fb758aab27
commit
fd104a8459
5 changed files with 318 additions and 153 deletions
|
|
@ -195,6 +195,8 @@ clear_color_buffers(struct gl_context *ctx)
|
|||
void
|
||||
_swrast_Clear(struct gl_context *ctx, GLbitfield buffers)
|
||||
{
|
||||
const GLbitfield BUFFER_DS = BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL;
|
||||
|
||||
#ifdef DEBUG_FOO
|
||||
{
|
||||
const GLbitfield legalBits =
|
||||
|
|
@ -216,24 +218,39 @@ _swrast_Clear(struct gl_context *ctx, GLbitfield buffers)
|
|||
if (SWRAST_CONTEXT(ctx)->NewState)
|
||||
_swrast_validate_derived(ctx);
|
||||
|
||||
swrast_render_start(ctx);
|
||||
|
||||
/* do software clearing here */
|
||||
if (buffers) {
|
||||
if ((buffers & BUFFER_BITS_COLOR)
|
||||
&& (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) {
|
||||
clear_color_buffers(ctx);
|
||||
}
|
||||
if (buffers & BUFFER_BIT_DEPTH) {
|
||||
_swrast_clear_depth_buffer(ctx, ctx->DrawBuffer->_DepthBuffer);
|
||||
}
|
||||
if (buffers & BUFFER_BIT_ACCUM) {
|
||||
_mesa_clear_accum_buffer(ctx);
|
||||
}
|
||||
if (buffers & BUFFER_BIT_STENCIL) {
|
||||
_swrast_clear_stencil_buffer(ctx, ctx->DrawBuffer->_StencilBuffer);
|
||||
}
|
||||
if ((buffers & BUFFER_BITS_COLOR)
|
||||
&& (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) {
|
||||
/* XXX remove the swrast_render_start/finish() calls after
|
||||
* clear_color_buffers() is converted to use Map/UnmapRenderbuffer()
|
||||
* The other clearing functions don't need these calls.
|
||||
*/
|
||||
swrast_render_start(ctx);
|
||||
clear_color_buffers(ctx);
|
||||
swrast_render_finish(ctx);
|
||||
}
|
||||
|
||||
swrast_render_finish(ctx);
|
||||
if (buffers & BUFFER_BIT_ACCUM) {
|
||||
_mesa_clear_accum_buffer(ctx);
|
||||
}
|
||||
|
||||
if (buffers & BUFFER_DS) {
|
||||
struct gl_renderbuffer *depthRb =
|
||||
ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
|
||||
struct gl_renderbuffer *stencilRb =
|
||||
ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
|
||||
|
||||
if ((buffers & BUFFER_DS) == BUFFER_DS && depthRb == stencilRb) {
|
||||
/* clear depth and stencil together */
|
||||
_swrast_clear_depth_stencil_buffer(ctx);
|
||||
}
|
||||
else {
|
||||
/* clear depth, stencil separately */
|
||||
if (buffers & BUFFER_BIT_DEPTH) {
|
||||
_swrast_clear_depth_buffer(ctx);
|
||||
}
|
||||
if (buffers & BUFFER_BIT_STENCIL) {
|
||||
_swrast_clear_stencil_buffer(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "main/glheader.h"
|
||||
#include "main/context.h"
|
||||
#include "main/formats.h"
|
||||
#include "main/format_pack.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/imports.h"
|
||||
|
||||
|
|
@ -1312,14 +1313,21 @@ _swrast_read_depth_span_float( struct gl_context *ctx, struct gl_renderbuffer *r
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear the given z/depth renderbuffer.
|
||||
* Clear the given z/depth renderbuffer. If the buffer is a combined
|
||||
* depth+stencil buffer, only the Z bits will be touched.
|
||||
*/
|
||||
void
|
||||
_swrast_clear_depth_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb )
|
||||
_swrast_clear_depth_buffer(struct gl_context *ctx)
|
||||
{
|
||||
struct gl_renderbuffer *rb =
|
||||
ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
|
||||
GLuint clearValue;
|
||||
GLint x, y, width, height;
|
||||
GLubyte *map;
|
||||
GLint rowStride, i, j;
|
||||
GLbitfield mapMode;
|
||||
|
||||
if (!rb || !ctx->Depth.Mask) {
|
||||
/* no depth buffer, or writing to it is disabled */
|
||||
|
|
@ -1334,7 +1342,132 @@ _swrast_clear_depth_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb )
|
|||
clearValue = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF);
|
||||
}
|
||||
|
||||
assert(rb->_BaseFormat == GL_DEPTH_COMPONENT);
|
||||
/* compute region to clear */
|
||||
x = ctx->DrawBuffer->_Xmin;
|
||||
y = ctx->DrawBuffer->_Ymin;
|
||||
width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
|
||||
height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
|
||||
|
||||
mapMode = GL_MAP_WRITE_BIT;
|
||||
if (rb->Format == MESA_FORMAT_S8_Z24 ||
|
||||
rb->Format == MESA_FORMAT_X8_Z24 ||
|
||||
rb->Format == MESA_FORMAT_Z24_S8 ||
|
||||
rb->Format == MESA_FORMAT_Z24_X8) {
|
||||
mapMode |= GL_MAP_READ_BIT;
|
||||
}
|
||||
|
||||
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
|
||||
mapMode, &map, &rowStride);
|
||||
if (!map) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth)");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (rb->Format) {
|
||||
case MESA_FORMAT_Z16:
|
||||
{
|
||||
GLfloat clear = (GLfloat) ctx->Depth.Clear;
|
||||
GLushort clearVal = 0;
|
||||
_mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
|
||||
if (clearVal == 0xffff && width * 2 == rowStride) {
|
||||
/* common case */
|
||||
memset(map, 0xff, width * height * 2);
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < height; i++) {
|
||||
GLushort *row = (GLushort *) map;
|
||||
for (j = 0; j < width; j++) {
|
||||
row[j] = clearVal;
|
||||
}
|
||||
map += rowStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MESA_FORMAT_Z32:
|
||||
case MESA_FORMAT_Z32_FLOAT:
|
||||
{
|
||||
GLfloat clear = (GLfloat) ctx->Depth.Clear;
|
||||
GLuint clearVal = 0;
|
||||
_mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
|
||||
for (i = 0; i < height; i++) {
|
||||
GLuint *row = (GLuint *) map;
|
||||
for (j = 0; j < width; j++) {
|
||||
row[j] = clearVal;
|
||||
}
|
||||
map += rowStride;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MESA_FORMAT_S8_Z24:
|
||||
case MESA_FORMAT_X8_Z24:
|
||||
case MESA_FORMAT_Z24_S8:
|
||||
case MESA_FORMAT_Z24_X8:
|
||||
{
|
||||
GLfloat clear = (GLfloat) ctx->Depth.Clear;
|
||||
GLuint clearVal = 0;
|
||||
GLuint mask;
|
||||
|
||||
if (rb->Format == MESA_FORMAT_S8_Z24 ||
|
||||
rb->Format == MESA_FORMAT_X8_Z24)
|
||||
mask = 0xff000000;
|
||||
else
|
||||
mask = 0xff;
|
||||
|
||||
_mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
|
||||
for (i = 0; i < height; i++) {
|
||||
GLuint *row = (GLuint *) map;
|
||||
for (j = 0; j < width; j++) {
|
||||
row[j] = (row[j] & mask) | clearVal;
|
||||
}
|
||||
map += rowStride;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case MESA_FORMAT_Z32_FLOAT_X24S8:
|
||||
/* XXX untested */
|
||||
{
|
||||
GLfloat clearVal = (GLfloat) ctx->Depth.Clear;
|
||||
for (i = 0; i < height; i++) {
|
||||
GLfloat *row = (GLfloat *) map;
|
||||
for (j = 0; j < width; j++) {
|
||||
row[j * 2] = clearVal;
|
||||
}
|
||||
map += rowStride;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(ctx, "Unexpected depth buffer format %s"
|
||||
" in _swrast_clear_depth_buffer()",
|
||||
_mesa_get_format_name(rb->Format));
|
||||
}
|
||||
|
||||
ctx->Driver.UnmapRenderbuffer(ctx, rb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clear both depth and stencil values in a combined depth+stencil buffer.
|
||||
*/
|
||||
void
|
||||
_swrast_clear_depth_stencil_buffer(struct gl_context *ctx)
|
||||
{
|
||||
const GLubyte stencilBits = ctx->DrawBuffer->Visual.stencilBits;
|
||||
const GLuint writeMask = ctx->Stencil.WriteMask[0];
|
||||
const GLuint stencilMax = (1 << stencilBits) - 1;
|
||||
struct gl_renderbuffer *rb =
|
||||
ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
|
||||
GLint x, y, width, height;
|
||||
GLbitfield mapMode;
|
||||
GLubyte *map;
|
||||
GLint rowStride, i, j;
|
||||
|
||||
/* check that we really have a combined depth+stencil buffer */
|
||||
assert(rb == ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer);
|
||||
|
||||
/* compute region to clear */
|
||||
x = ctx->DrawBuffer->_Xmin;
|
||||
|
|
@ -1342,59 +1475,85 @@ _swrast_clear_depth_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb )
|
|||
width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
|
||||
height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
|
||||
|
||||
if (rb->GetPointer(ctx, rb, 0, 0)) {
|
||||
/* Direct buffer access is possible. Either this is just malloc'd
|
||||
* memory, or perhaps the driver mmap'd the zbuffer memory.
|
||||
*/
|
||||
if (rb->DataType == GL_UNSIGNED_SHORT) {
|
||||
if ((clearValue & 0xff) == ((clearValue >> 8) & 0xff) &&
|
||||
((GLushort *) rb->GetPointer(ctx, rb, 0, 0) + width ==
|
||||
(GLushort *) rb->GetPointer(ctx, rb, 0, 1))) {
|
||||
/* optimized case */
|
||||
GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y);
|
||||
GLuint len = width * height * sizeof(GLushort);
|
||||
memset(dst, (clearValue & 0xff), len);
|
||||
mapMode = GL_MAP_WRITE_BIT;
|
||||
if ((writeMask & stencilMax) != stencilMax) {
|
||||
/* need to mask stencil values */
|
||||
mapMode |= GL_MAP_READ_BIT;
|
||||
}
|
||||
|
||||
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
|
||||
mapMode, &map, &rowStride);
|
||||
if (!map) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth+stencil)");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (rb->Format) {
|
||||
case MESA_FORMAT_S8_Z24:
|
||||
case MESA_FORMAT_Z24_S8:
|
||||
{
|
||||
GLfloat zClear = (GLfloat) ctx->Depth.Clear;
|
||||
GLuint clear = 0, mask;
|
||||
|
||||
_mesa_pack_float_z_row(rb->Format, 1, &zClear, &clear);
|
||||
|
||||
if (rb->Format == MESA_FORMAT_S8_Z24) {
|
||||
mask = ((~writeMask) & 0xff) << 24;
|
||||
clear |= (ctx->Stencil.Clear & writeMask & 0xff) << 24;
|
||||
}
|
||||
else {
|
||||
/* general case */
|
||||
GLint i, j;
|
||||
for (i = 0; i < height; i++) {
|
||||
GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y + i);
|
||||
mask = ((~writeMask) & 0xff);
|
||||
clear |= (ctx->Stencil.Clear & writeMask & 0xff);
|
||||
}
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
GLuint *row = (GLuint *) map;
|
||||
if (mask != 0x0) {
|
||||
for (j = 0; j < width; j++) {
|
||||
dst[j] = clearValue;
|
||||
row[j] = (row[j] & mask) | clear;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
GLint i, j;
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_INT);
|
||||
for (i = 0; i < height; i++) {
|
||||
GLuint *dst = (GLuint *) rb->GetPointer(ctx, rb, x, y + i);
|
||||
for (j = 0; j < width; j++) {
|
||||
dst[j] = clearValue;
|
||||
else {
|
||||
for (j = 0; j < width; j++) {
|
||||
row[j] = clear;
|
||||
}
|
||||
}
|
||||
map += rowStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Direct access not possible. Use PutRow to write new values. */
|
||||
if (rb->DataType == GL_UNSIGNED_SHORT) {
|
||||
GLushort clearVal16 = (GLushort) (clearValue & 0xffff);
|
||||
GLint i;
|
||||
break;
|
||||
case MESA_FORMAT_Z32_FLOAT_X24S8:
|
||||
/* XXX untested */
|
||||
{
|
||||
const GLfloat zClear = (GLfloat) ctx->Depth.Clear;
|
||||
const GLuint sClear = ctx->Stencil.Clear & writeMask;
|
||||
const GLuint sMask = (~writeMask) & 0xff;
|
||||
for (i = 0; i < height; i++) {
|
||||
rb->PutMonoRow(ctx, rb, width, x, y + i, &clearVal16, NULL);
|
||||
GLfloat *zRow = (GLfloat *) map;
|
||||
GLuint *sRow = (GLuint *) map;
|
||||
for (j = 0; j < width; j++) {
|
||||
zRow[j * 2 + 0] = zClear;
|
||||
}
|
||||
if (sMask != 0) {
|
||||
for (j = 0; j < width; j++) {
|
||||
sRow[j * 2 + 1] = (sRow[j * 2 + 1] & sMask) | sClear;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (j = 0; j < width; j++) {
|
||||
sRow[j * 2 + 1] = sClear;
|
||||
}
|
||||
}
|
||||
map += rowStride;
|
||||
}
|
||||
}
|
||||
else if (rb->DataType == GL_UNSIGNED_INT) {
|
||||
GLint i;
|
||||
ASSERT(sizeof(clearValue) == sizeof(GLuint));
|
||||
for (i = 0; i < height; i++) {
|
||||
rb->PutMonoRow(ctx, rb, width, x, y + i, &clearValue, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
_mesa_problem(ctx, "bad depth renderbuffer DataType");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(ctx, "Unexpected depth buffer format %s"
|
||||
" in _swrast_clear_depth_buffer()",
|
||||
_mesa_get_format_name(rb->Format));
|
||||
}
|
||||
|
||||
ctx->Driver.UnmapRenderbuffer(ctx, rb);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,10 @@ _swrast_read_depth_span_float( struct gl_context *ctx, struct gl_renderbuffer *r
|
|||
GLint n, GLint x, GLint y, GLfloat depth[] );
|
||||
|
||||
extern void
|
||||
_swrast_clear_depth_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb );
|
||||
_swrast_clear_depth_buffer(struct gl_context *ctx);
|
||||
|
||||
extern void
|
||||
_swrast_clear_depth_stencil_buffer(struct gl_context *ctx);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1124,121 +1124,107 @@ _swrast_write_stencil_span(struct gl_context *ctx, GLint n, GLint x, GLint y,
|
|||
|
||||
|
||||
/**
|
||||
* Clear the stencil buffer.
|
||||
* Clear the stencil buffer. If the buffer is a combined
|
||||
* depth+stencil buffer, only the stencil bits will be touched.
|
||||
*/
|
||||
void
|
||||
_swrast_clear_stencil_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb )
|
||||
_swrast_clear_stencil_buffer(struct gl_context *ctx)
|
||||
{
|
||||
struct gl_renderbuffer *rb =
|
||||
ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
|
||||
const GLubyte stencilBits = ctx->DrawBuffer->Visual.stencilBits;
|
||||
const GLuint mask = ctx->Stencil.WriteMask[0];
|
||||
const GLuint invMask = ~mask;
|
||||
const GLuint clearVal = (ctx->Stencil.Clear & mask);
|
||||
const GLuint writeMask = ctx->Stencil.WriteMask[0];
|
||||
const GLuint stencilMax = (1 << stencilBits) - 1;
|
||||
GLint x, y, width, height;
|
||||
GLubyte *map;
|
||||
GLint rowStride, i, j;
|
||||
GLbitfield mapMode;
|
||||
|
||||
if (!rb || mask == 0)
|
||||
if (!rb || writeMask == 0)
|
||||
return;
|
||||
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE ||
|
||||
rb->DataType == GL_UNSIGNED_SHORT);
|
||||
|
||||
ASSERT(rb->_BaseFormat == GL_STENCIL_INDEX);
|
||||
|
||||
/* compute region to clear */
|
||||
x = ctx->DrawBuffer->_Xmin;
|
||||
y = ctx->DrawBuffer->_Ymin;
|
||||
width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
|
||||
height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
|
||||
|
||||
if (rb->GetPointer(ctx, rb, 0, 0)) {
|
||||
/* Direct buffer access */
|
||||
if ((mask & stencilMax) != stencilMax) {
|
||||
/* need to mask the clear */
|
||||
if (rb->DataType == GL_UNSIGNED_BYTE) {
|
||||
GLint i, j;
|
||||
for (i = 0; i < height; i++) {
|
||||
GLubyte *stencil = (GLubyte*) rb->GetPointer(ctx, rb, x, y + i);
|
||||
for (j = 0; j < width; j++) {
|
||||
stencil[j] = (stencil[j] & invMask) | clearVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
GLint i, j;
|
||||
for (i = 0; i < height; i++) {
|
||||
GLushort *stencil = (GLushort*) rb->GetPointer(ctx, rb, x, y + i);
|
||||
for (j = 0; j < width; j++) {
|
||||
stencil[j] = (stencil[j] & invMask) | clearVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* no bit masking */
|
||||
if (width == (GLint) rb->Width && rb->DataType == GL_UNSIGNED_BYTE) {
|
||||
/* optimized case */
|
||||
/* Note: bottom-to-top raster assumed! */
|
||||
GLubyte *stencil = (GLubyte *) rb->GetPointer(ctx, rb, x, y);
|
||||
GLuint len = width * height * sizeof(GLubyte);
|
||||
memset(stencil, clearVal, len);
|
||||
}
|
||||
else {
|
||||
/* general case */
|
||||
GLint i;
|
||||
for (i = 0; i < height; i++) {
|
||||
GLvoid *stencil = rb->GetPointer(ctx, rb, x, y + i);
|
||||
if (rb->DataType == GL_UNSIGNED_BYTE) {
|
||||
memset(stencil, clearVal, width);
|
||||
}
|
||||
else {
|
||||
_mesa_memset16((short unsigned int*) stencil, clearVal, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mapMode = GL_MAP_WRITE_BIT;
|
||||
if ((writeMask & stencilMax) != stencilMax) {
|
||||
/* need to mask stencil values */
|
||||
mapMode |= GL_MAP_READ_BIT;
|
||||
}
|
||||
else {
|
||||
/* no direct access */
|
||||
if ((mask & stencilMax) != stencilMax) {
|
||||
/* need to mask the clear */
|
||||
if (rb->DataType == GL_UNSIGNED_BYTE) {
|
||||
GLint i, j;
|
||||
else if (_mesa_get_format_bits(rb->Format, GL_DEPTH_BITS) > 0) {
|
||||
/* combined depth+stencil, need to mask Z values */
|
||||
mapMode |= GL_MAP_READ_BIT;
|
||||
}
|
||||
|
||||
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
|
||||
mapMode, &map, &rowStride);
|
||||
if (!map) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(stencil)");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (rb->Format) {
|
||||
case MESA_FORMAT_S8:
|
||||
{
|
||||
GLubyte clear = ctx->Stencil.Clear & writeMask & 0xff;
|
||||
GLubyte mask = (~writeMask) & 0xff;
|
||||
if (mask != 0) {
|
||||
/* masked clear */
|
||||
for (i = 0; i < height; i++) {
|
||||
GLubyte stencil[MAX_WIDTH];
|
||||
rb->GetRow(ctx, rb, width, x, y + i, stencil);
|
||||
GLubyte *row = map;
|
||||
for (j = 0; j < width; j++) {
|
||||
stencil[j] = (stencil[j] & invMask) | clearVal;
|
||||
row[j] = (row[j] & mask) | clear;
|
||||
}
|
||||
rb->PutRow(ctx, rb, width, x, y + i, stencil, NULL);
|
||||
map += rowStride;
|
||||
}
|
||||
}
|
||||
else if (rowStride == width) {
|
||||
/* clear whole buffer */
|
||||
memset(map, clear, width * height);
|
||||
}
|
||||
else {
|
||||
GLint i, j;
|
||||
/* clear scissored */
|
||||
for (i = 0; i < height; i++) {
|
||||
GLushort stencil[MAX_WIDTH];
|
||||
rb->GetRow(ctx, rb, width, x, y + i, stencil);
|
||||
for (j = 0; j < width; j++) {
|
||||
stencil[j] = (stencil[j] & invMask) | clearVal;
|
||||
}
|
||||
rb->PutRow(ctx, rb, width, x, y + i, stencil, NULL);
|
||||
memset(map, clear, width);
|
||||
map += rowStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* no bit masking */
|
||||
const GLubyte clear8 = (GLubyte) clearVal;
|
||||
const GLushort clear16 = (GLushort) clearVal;
|
||||
const void *clear;
|
||||
GLint i;
|
||||
if (rb->DataType == GL_UNSIGNED_BYTE) {
|
||||
clear = &clear8;
|
||||
}
|
||||
else {
|
||||
clear = &clear16;
|
||||
}
|
||||
break;
|
||||
case MESA_FORMAT_S8_Z24:
|
||||
{
|
||||
GLuint clear = (ctx->Stencil.Clear & writeMask & 0xff) << 24;
|
||||
GLuint mask = (((~writeMask) & 0xff) << 24) | 0xffffff;
|
||||
for (i = 0; i < height; i++) {
|
||||
rb->PutMonoRow(ctx, rb, width, x, y + i, clear, NULL);
|
||||
GLuint *row = (GLuint *) map;
|
||||
for (j = 0; j < width; j++) {
|
||||
row[j] = (row[j] & mask) | clear;
|
||||
}
|
||||
map += rowStride;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MESA_FORMAT_Z24_S8:
|
||||
{
|
||||
GLuint clear = ctx->Stencil.Clear & writeMask & 0xff;
|
||||
GLuint mask = 0xffffff00 | ((~writeMask) & 0xff);
|
||||
for (i = 0; i < height; i++) {
|
||||
GLuint *row = (GLuint *) map;
|
||||
for (j = 0; j < width; j++) {
|
||||
row[j] = (row[j] & mask) | clear;
|
||||
}
|
||||
map += rowStride;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(ctx, "Unexpected stencil buffer format %s"
|
||||
" in _swrast_clear_stencil_buffer()",
|
||||
_mesa_get_format_name(rb->Format));
|
||||
}
|
||||
|
||||
ctx->Driver.UnmapRenderbuffer(ctx, rb);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ _swrast_write_stencil_span( struct gl_context *ctx, GLint n, GLint x, GLint y,
|
|||
|
||||
|
||||
extern void
|
||||
_swrast_clear_stencil_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb );
|
||||
_swrast_clear_stencil_buffer(struct gl_context *ctx);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue