X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_depth.c;h=26e23f02d597e62503aba443f5ce4e3f845d09b0;hb=ca792be42b238bd1c8f8a99ad72ea8558cbbfc32;hp=e7517b1e9edf7d3e3ce4588309d312fe0577abd1;hpb=77df88727cb0a423dd5cb41498c2302d9df4fce7;p=mesa.git diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c index e7517b1e9ed..26e23f02d59 100644 --- a/src/mesa/swrast/s_depth.c +++ b/src/mesa/swrast/s_depth.c @@ -1,10 +1,8 @@ -/* $Id: s_depth.c,v 1.23 2002/08/07 00:45:07 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 7.2.1 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul 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"), @@ -25,55 +23,26 @@ */ -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "mem.h" +#include "main/glheader.h" +#include "main/context.h" +#include "main/macros.h" +#include "main/imports.h" +#include "main/fbobject.h" #include "s_depth.h" #include "s_context.h" +#include "s_span.h" /** - * Return address of depth buffer value for given window coord. - */ -GLvoid * -_mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y) -{ - if (ctx->Visual.depthBits <= 16) - return (GLushort *) ctx->DrawBuffer->DepthBuffer - + ctx->DrawBuffer->Width * y + x; - else - return (GLuint *) ctx->DrawBuffer->DepthBuffer - + ctx->DrawBuffer->Width * y + x; -} - - -#define Z_ADDRESS16( CTX, X, Y ) \ - ( ((GLushort *) (CTX)->DrawBuffer->DepthBuffer) \ - + (CTX)->DrawBuffer->Width * (Y) + (X) ) - -#define Z_ADDRESS32( CTX, X, Y ) \ - ( ((GLuint *) (CTX)->DrawBuffer->DepthBuffer) \ - + (CTX)->DrawBuffer->Width * (Y) + (X) ) - - - -/**********************************************************************/ -/***** Depth Testing Functions *****/ -/**********************************************************************/ - - -/* - * Do depth test for an array of fragments. This is used both for - * software and hardware Z buffers. + * Do depth test for a horizontal span of fragments. * Input: zbuffer - array of z values in the zbuffer * z - array of fragment z values * Return: number of fragments which pass the test. */ static GLuint depth_test_span16( GLcontext *ctx, GLuint n, - GLushort zbuffer[], const GLdepth z[], GLubyte mask[] ) + GLushort zbuffer[], const GLuint z[], GLubyte mask[] ) { GLuint passed = 0; @@ -290,7 +259,7 @@ depth_test_span16( GLcontext *ctx, GLuint n, } break; case GL_NEVER: - BZERO(mask, n * sizeof(GLubyte)); + _mesa_bzero(mask, n * sizeof(GLubyte)); break; default: _mesa_problem(ctx, "Bad depth func in depth_test_span16"); @@ -302,7 +271,7 @@ depth_test_span16( GLcontext *ctx, GLuint n, static GLuint depth_test_span32( GLcontext *ctx, GLuint n, - GLuint zbuffer[], const GLdepth z[], GLubyte mask[] ) + GLuint zbuffer[], const GLuint z[], GLubyte mask[] ) { GLuint passed = 0; @@ -519,7 +488,7 @@ depth_test_span32( GLcontext *ctx, GLuint n, } break; case GL_NEVER: - BZERO(mask, n * sizeof(GLubyte)); + _mesa_bzero(mask, n * sizeof(GLubyte)); break; default: _mesa_problem(ctx, "Bad depth func in depth_test_span32"); @@ -531,74 +500,70 @@ depth_test_span32( GLcontext *ctx, GLuint n, /* - * Apply depth test to span of fragments. Hardware or software z buffer. + * Apply depth test to span of fragments. */ static GLuint -depth_test_span( GLcontext *ctx, struct sw_span *span) +depth_test_span( GLcontext *ctx, SWspan *span) { + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->_DepthBuffer; const GLint x = span->x; const GLint y = span->y; - const GLuint n = span->end; - SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLuint count = span->end; + const GLuint *zValues = span->array->z; + GLubyte *mask = span->array->mask; + GLuint passed; ASSERT((span->arrayMask & SPAN_XY) == 0); ASSERT(span->arrayMask & SPAN_Z); - if (swrast->Driver.ReadDepthSpan) { - /* hardware-based depth buffer */ - GLdepth zbuffer[MAX_WIDTH]; - GLuint passed; - (*swrast->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer); - passed = depth_test_span32(ctx, n, zbuffer, span->array->z, - span->array->mask); - ASSERT(swrast->Driver.WriteDepthSpan); - (*swrast->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, - span->array->mask); - if (passed < n) - span->writeAll = GL_FALSE; - return passed; - } - else { - GLuint passed; - /* software depth buffer */ - if (ctx->Visual.depthBits <= 16) { - GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y); - passed = depth_test_span16(ctx, n, zptr, span->array->z, span->array->mask); + if (rb->GetPointer(ctx, rb, 0, 0)) { + /* Directly access buffer */ + if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort *zbuffer = (GLushort *) rb->GetPointer(ctx, rb, x, y); + passed = depth_test_span16(ctx, count, zbuffer, zValues, mask); } else { - GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y); - passed = depth_test_span32(ctx, n, zptr, span->array->z, span->array->mask); + GLuint *zbuffer = (GLuint *) rb->GetPointer(ctx, rb, x, y); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + passed = depth_test_span32(ctx, count, zbuffer, zValues, mask); } -#if 1 - if (passed < span->end) { - span->writeAll = GL_FALSE; + } + else { + /* read depth values from buffer, test, write back */ + if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort zbuffer[MAX_WIDTH]; + rb->GetRow(ctx, rb, count, x, y, zbuffer); + passed = depth_test_span16(ctx, count, zbuffer, zValues, mask); + rb->PutRow(ctx, rb, count, x, y, zbuffer, mask); } -#else - /* this causes a glDrawPixels(GL_DEPTH_COMPONENT) conformance failure */ - if (passed < span->end) { - span->writeAll = GL_FALSE; - if (passed == 0) { - span->end = 0; - return 0; - } - while (span->end > 0 && span->mask[span->end - 1] == 0) - span->end --; + else { + GLuint zbuffer[MAX_WIDTH]; + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->GetRow(ctx, rb, count, x, y, zbuffer); + passed = depth_test_span32(ctx, count, zbuffer, zValues, mask); + rb->PutRow(ctx, rb, count, x, y, zbuffer, mask); } -#endif - return passed; } + + if (passed < count) { + span->writeAll = GL_FALSE; + } + return passed; } +#define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X)) + /* - * Do depth testing for an array of fragments using software Z buffer. + * Do depth testing for an array of fragments at assorted locations. */ static void -software_depth_test_pixels16( GLcontext *ctx, GLuint n, - const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ) +direct_depth_test_pixels16(GLcontext *ctx, GLushort *zStart, GLuint stride, + GLuint n, const GLint x[], const GLint y[], + const GLuint z[], GLubyte mask[] ) { /* switch cases ordered from most frequent to less frequent */ switch (ctx->Depth.Func) { @@ -608,7 +573,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i= *zptr) { /* pass */ *zptr = z[i]; @@ -695,7 +660,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i= *zptr) { /* pass */ } @@ -713,7 +678,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i *zptr) { /* pass */ *zptr = z[i]; @@ -730,7 +695,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i *zptr) { /* pass */ } @@ -748,7 +713,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; iDepth.Func) { @@ -854,7 +819,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i= *zptr) { /* pass */ *zptr = z[i]; @@ -941,7 +906,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i= *zptr) { /* pass */ } @@ -959,7 +924,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i *zptr) { /* pass */ *zptr = z[i]; @@ -976,7 +941,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i *zptr) { /* pass */ } @@ -994,7 +959,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; iDepth.Func) { - case GL_LESS: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; iDepth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; iDepth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; i= zbuffer[i]) { - /* pass */ - zbuffer[i] = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - GLuint i; - for (i=0; i= zbuffer[i]) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_GREATER: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; i zbuffer[i]) { - /* pass */ - zbuffer[i] = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - GLuint i; - for (i=0; i zbuffer[i]) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_NOTEQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; iDepth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; iDepth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; iend; + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->_DepthBuffer; + const GLuint count = span->end; const GLint *x = span->array->x; const GLint *y = span->array->y; - const GLdepth *z = span->array->z; + const GLuint *z = span->array->z; GLubyte *mask = span->array->mask; - if (swrast->Driver.ReadDepthPixels) { - /* read depth values from hardware Z buffer */ - GLdepth zbuffer[MAX_WIDTH]; - (*swrast->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer); - - hardware_depth_test_pixels( ctx, n, zbuffer, z, mask ); - - /* update hardware Z buffer with new values */ - assert(swrast->Driver.WriteDepthPixels); - (*swrast->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask ); + if (rb->GetPointer(ctx, rb, 0, 0)) { + /* Directly access values */ + if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort *zStart = (GLushort *) rb->Data; + GLuint stride = rb->Width; + direct_depth_test_pixels16(ctx, zStart, stride, count, x, y, z, mask); + } + else { + GLuint *zStart = (GLuint *) rb->Data; + GLuint stride = rb->Width; + ASSERT(rb->DataType == GL_UNSIGNED_INT); + direct_depth_test_pixels32(ctx, zStart, stride, count, x, y, z, mask); + } } else { - /* software depth testing */ - if (ctx->Visual.depthBits <= 16) - software_depth_test_pixels16(ctx, n, x, y, z, mask); - else - software_depth_test_pixels32(ctx, n, x, y, z, mask); + /* read depth values from buffer, test, write back */ + if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort zbuffer[MAX_WIDTH]; + _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLushort)); + depth_test_span16(ctx, count, zbuffer, z, mask); + rb->PutValues(ctx, rb, count, x, y, zbuffer, mask); + } + else { + GLuint zbuffer[MAX_WIDTH]; + ASSERT(rb->DataType == GL_UNSIGNED_INT); + _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLuint)); + depth_test_span32(ctx, count, zbuffer, z, mask); + rb->PutValues(ctx, rb, count, x, y, zbuffer, mask); + } } - return n; /* not really correct, but OK */ + + return count; /* not really correct, but OK */ } @@ -1355,7 +1101,7 @@ depth_test_pixels( GLcontext *ctx, struct sw_span *span ) * \return approx number of pixels that passed (only zero is reliable) */ GLuint -_mesa_depth_test_span( GLcontext *ctx, struct sw_span *span) +_swrast_depth_test_span( GLcontext *ctx, SWspan *span) { if (span->arrayMask & SPAN_XY) return depth_test_pixels(ctx, span); @@ -1364,6 +1110,85 @@ _mesa_depth_test_span( GLcontext *ctx, struct sw_span *span) } +/** + * GL_EXT_depth_bounds_test extension. + * Discard fragments depending on whether the corresponding Z-buffer + * values are outside the depth bounds test range. + * Note: we test the Z buffer values, not the fragment Z values! + * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass + */ +GLboolean +_swrast_depth_bounds_test( GLcontext *ctx, SWspan *span ) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->_DepthBuffer; + GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F); + GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F); + GLubyte *mask = span->array->mask; + const GLuint count = span->end; + GLuint i; + GLboolean anyPass = GL_FALSE; + + if (rb->DataType == GL_UNSIGNED_SHORT) { + /* get 16-bit values */ + GLushort zbuffer16[MAX_WIDTH], *zbuffer; + if (span->arrayMask & SPAN_XY) { + _swrast_get_values(ctx, rb, count, span->array->x, span->array->y, + zbuffer16, sizeof(GLushort)); + zbuffer = zbuffer16; + } + else { + zbuffer = (GLushort*) rb->GetPointer(ctx, rb, span->x, span->y); + if (!zbuffer) { + rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer16); + zbuffer = zbuffer16; + } + } + assert(zbuffer); + + /* Now do the tests */ + for (i = 0; i < count; i++) { + if (mask[i]) { + if (zbuffer[i] < zMin || zbuffer[i] > zMax) + mask[i] = GL_FALSE; + else + anyPass = GL_TRUE; + } + } + } + else { + /* get 32-bit values */ + GLuint zbuffer32[MAX_WIDTH], *zbuffer; + ASSERT(rb->DataType == GL_UNSIGNED_INT); + if (span->arrayMask & SPAN_XY) { + _swrast_get_values(ctx, rb, count, span->array->x, span->array->y, + zbuffer32, sizeof(GLuint)); + zbuffer = zbuffer32; + } + else { + zbuffer = (GLuint*) rb->GetPointer(ctx, rb, span->x, span->y); + if (!zbuffer) { + rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer32); + zbuffer = zbuffer32; + } + } + assert(zbuffer); + + /* Now do the tests */ + for (i = 0; i < count; i++) { + if (mask[i]) { + if (zbuffer[i] < zMin || zbuffer[i] > zMax) + mask[i] = GL_FALSE; + else + anyPass = GL_TRUE; + } + } + } + + return anyPass; +} + + /**********************************************************************/ /***** Read Depth Buffer *****/ @@ -1371,21 +1196,29 @@ _mesa_depth_test_span( GLcontext *ctx, struct sw_span *span) /** - * Read a span of depth values from the depth buffer. - * This function does clipping before calling the device driver function. + * Read a span of depth values from the given depth renderbuffer, returning + * the values as GLfloats. + * This function does clipping to prevent reading outside the depth buffer's + * bounds. Though the clipping is redundant when we're called from + * _swrast_ReadPixels. */ void -_mesa_read_depth_span( GLcontext *ctx, - GLint n, GLint x, GLint y, GLdepth depth[] ) +_swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb, + GLint n, GLint x, GLint y, GLfloat depth[] ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF; - if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height || - x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) { + if (!rb) { + /* really only doing this to prevent FP exceptions later */ + _mesa_bzero(depth, n * sizeof(GLfloat)); + } + + ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT); + + if (y < 0 || y >= (GLint) rb->Height || + x + n <= 0 || x >= (GLint) rb->Width) { /* span is completely outside framebuffer */ - GLint i; - for (i = 0; i < n; i++) - depth[i] = 0; + _mesa_bzero(depth, n * sizeof(GLfloat)); return; } @@ -1393,73 +1226,62 @@ _mesa_read_depth_span( GLcontext *ctx, GLint dx = -x; GLint i; for (i = 0; i < dx; i++) - depth[i] = 0; + depth[i] = 0.0; x = 0; n -= dx; depth += dx; } - if (x + n > (GLint) ctx->DrawBuffer->Width) { - GLint dx = x + n - (GLint) ctx->DrawBuffer->Width; + if (x + n > (GLint) rb->Width) { + GLint dx = x + n - (GLint) rb->Width; GLint i; for (i = 0; i < dx; i++) - depth[n - i - 1] = 0; + depth[n - i - 1] = 0.0; n -= dx; } if (n <= 0) { return; } - if (ctx->DrawBuffer->DepthBuffer) { - /* read from software depth buffer */ - if (ctx->Visual.depthBits <= 16) { - const GLushort *zptr = Z_ADDRESS16( ctx, x, y ); - GLint i; - for (i = 0; i < n; i++) { - depth[i] = zptr[i]; - } - } - else { - const GLuint *zptr = Z_ADDRESS32( ctx, x, y ); - GLint i; - for (i = 0; i < n; i++) { - depth[i] = zptr[i]; - } + if (rb->DataType == GL_UNSIGNED_INT) { + GLuint temp[MAX_WIDTH]; + GLint i; + rb->GetRow(ctx, rb, n, x, y, temp); + for (i = 0; i < n; i++) { + depth[i] = temp[i] * scale; } } - else if (swrast->Driver.ReadDepthSpan) { - /* read from hardware depth buffer */ - (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, depth ); + else if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort temp[MAX_WIDTH]; + GLint i; + rb->GetRow(ctx, rb, n, x, y, temp); + for (i = 0; i < n; i++) { + depth[i] = temp[i] * scale; + } } else { - /* no depth buffer */ - BZERO(depth, n * sizeof(GLfloat)); + _mesa_problem(ctx, "Invalid depth renderbuffer data type"); } - } - - /** - * Return a span of depth values from the depth buffer as floats in [0,1]. - * This is used for both hardware and software depth buffers. - * Input: n - how many pixels - * x,y - location of first pixel - * Output: depth - the array of depth values + * As above, but return 32-bit GLuint values. */ void -_mesa_read_depth_span_float( GLcontext *ctx, - GLint n, GLint x, GLint y, GLfloat depth[] ) +_swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb, + GLint n, GLint x, GLint y, GLuint depth[] ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLfloat scale = 1.0F / ctx->DepthMaxF; + if (!rb) { + /* really only doing this to prevent FP exceptions later */ + _mesa_bzero(depth, n * sizeof(GLfloat)); + } - if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height || - x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) { + ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT); + + if (y < 0 || y >= (GLint) rb->Height || + x + n <= 0 || x >= (GLint) rb->Width) { /* span is completely outside framebuffer */ - GLint i; - for (i = 0; i < n; i++) - depth[i] = 0.0F; + _mesa_bzero(depth, n * sizeof(GLfloat)); return; } @@ -1467,216 +1289,141 @@ _mesa_read_depth_span_float( GLcontext *ctx, GLint dx = -x; GLint i; for (i = 0; i < dx; i++) - depth[i] = 0.0F; - n -= dx; + depth[i] = 0; x = 0; + n -= dx; + depth += dx; } - if (x + n > (GLint) ctx->DrawBuffer->Width) { - GLint dx = x + n - (GLint) ctx->DrawBuffer->Width; + if (x + n > (GLint) rb->Width) { + GLint dx = x + n - (GLint) rb->Width; GLint i; for (i = 0; i < dx; i++) - depth[n - i - 1] = 0.0F; + depth[n - i - 1] = 0; n -= dx; } if (n <= 0) { return; } - if (ctx->DrawBuffer->DepthBuffer) { - /* read from software depth buffer */ - if (ctx->Visual.depthBits <= 16) { - const GLushort *zptr = Z_ADDRESS16( ctx, x, y ); + if (rb->DataType == GL_UNSIGNED_INT) { + rb->GetRow(ctx, rb, n, x, y, depth); + if (rb->DepthBits < 32) { + GLuint shift = 32 - rb->DepthBits; GLint i; for (i = 0; i < n; i++) { - depth[i] = (GLfloat) zptr[i] * scale; + GLuint z = depth[i]; + depth[i] = z << shift; /* XXX lsb bits? */ } } - else { - const GLuint *zptr = Z_ADDRESS32( ctx, x, y ); - GLint i; + } + else if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort temp[MAX_WIDTH]; + GLint i; + rb->GetRow(ctx, rb, n, x, y, temp); + if (rb->DepthBits == 16) { for (i = 0; i < n; i++) { - depth[i] = (GLfloat) zptr[i] * scale; + GLuint z = temp[i]; + depth[i] = (z << 16) | z; } } - } - else if (swrast->Driver.ReadDepthSpan) { - /* read from hardware depth buffer */ - GLdepth d[MAX_WIDTH]; - GLint i; - assert(n <= MAX_WIDTH); - (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, d ); - for (i = 0; i < n; i++) { - depth[i] = d[i] * scale; + else { + GLuint shift = 16 - rb->DepthBits; + for (i = 0; i < n; i++) { + GLuint z = temp[i]; + depth[i] = (z << (shift + 16)) | (z << shift); /* XXX lsb bits? */ + } } } else { - /* no depth buffer */ - BZERO(depth, n * sizeof(GLfloat)); + _mesa_problem(ctx, "Invalid depth renderbuffer data type"); } } -/**********************************************************************/ -/***** Allocate and Clear Depth Buffer *****/ -/**********************************************************************/ - - - /** - * Allocate a new depth buffer. If there's already a depth buffer allocated - * it will be free()'d. The new depth buffer will be uniniitalized. - * This function is only called through Driver.alloc_depth_buffer. + * Clear the given z/depth renderbuffer. */ void -_mesa_alloc_depth_buffer( GLframebuffer *buffer ) +_swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb ) { - GLint bytesPerValue; - - ASSERT(buffer->UseSoftwareDepthBuffer); + GLuint clearValue; + GLint x, y, width, height; - /* deallocate current depth buffer if present */ - if (buffer->DepthBuffer) { - MESA_PBUFFER_FREE(buffer->DepthBuffer); - buffer->DepthBuffer = NULL; - } - - /* allocate new depth buffer, but don't initialize it */ - if (buffer->Visual.depthBits <= 16) - bytesPerValue = sizeof(GLushort); - else - bytesPerValue = sizeof(GLuint); - - buffer->DepthBuffer = MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height - * bytesPerValue); - - if (!buffer->DepthBuffer) { - /* out of memory */ - GET_CURRENT_CONTEXT(ctx); - if (ctx) { - ctx->Depth.Test = GL_FALSE; - ctx->NewState |= _NEW_DEPTH; - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer"); - } - } -} - - -/** - * Clear the depth buffer. If the depth buffer doesn't exist yet we'll - * allocate it now. - * This function is only called through Driver.clear_depth_buffer. - */ -void -_mesa_clear_depth_buffer( GLcontext *ctx ) -{ - if (ctx->Visual.depthBits == 0 - || !ctx->DrawBuffer->DepthBuffer - || !ctx->Depth.Mask) { + if (!rb || !ctx->Depth.Mask) { /* no depth buffer, or writing to it is disabled */ return; } - /* The loops in this function have been written so the IRIX 5.3 - * C compiler can unroll them. Hopefully other compilers can too! - */ + /* compute integer clearing value */ + if (ctx->Depth.Clear == 1.0) { + clearValue = ctx->DrawBuffer->_DepthMax; + } + else { + clearValue = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF); + } - if (ctx->Scissor.Enabled) { - /* only clear scissor region */ - if (ctx->Visual.depthBits <= 16) { - const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax); - const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - const GLint rowStride = ctx->DrawBuffer->Width; - GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer - + ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin; - GLint i, j; - for (i = 0; i < rows; i++) { - for (j = 0; j < cols; j++) { - dRow[j] = clearValue; + 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; + + 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); + _mesa_memset(dst, (clearValue & 0xff), len); + } + else { + /* general case */ + GLint i, j; + for (i = 0; i < height; i++) { + GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y + i); + for (j = 0; j < width; j++) { + dst[j] = clearValue; + } } - dRow += rowStride; } } else { - const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax); - const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - const GLint rowStride = ctx->DrawBuffer->Width; - GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer - + ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin; GLint i, j; - for (i = 0; i < rows; i++) { - for (j = 0; j < cols; j++) { - dRow[j] = clearValue; + 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; } - dRow += rowStride; } } } else { - /* clear whole buffer */ - if (ctx->Visual.depthBits <= 16) { - const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax); - if ((clearValue & 0xff) == (clearValue >> 8)) { - if (clearValue == 0) { - BZERO(ctx->DrawBuffer->DepthBuffer, - 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height); - } - else { - /* lower and upper bytes of clear_value are same, use MEMSET */ - MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff, - 2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height); - } + /* Direct access not possible. Use PutRow to write new values. */ + if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort clearVal16 = (GLushort) (clearValue & 0xffff); + GLint i; + for (i = 0; i < height; i++) { + rb->PutMonoRow(ctx, rb, width, x, y + i, &clearVal16, NULL); } - else { - GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer; - GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; - while (n >= 16) { - d[0] = clearValue; d[1] = clearValue; - d[2] = clearValue; d[3] = clearValue; - d[4] = clearValue; d[5] = clearValue; - d[6] = clearValue; d[7] = clearValue; - d[8] = clearValue; d[9] = clearValue; - d[10] = clearValue; d[11] = clearValue; - d[12] = clearValue; d[13] = clearValue; - d[14] = clearValue; d[15] = clearValue; - d += 16; - n -= 16; - } - while (n > 0) { - *d++ = clearValue; - n--; - } + } + 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 { - /* >16 bit depth buffer */ - const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax); - if (clearValue == 0) { - BZERO(ctx->DrawBuffer->DepthBuffer, - ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint)); - } - else { - GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; - GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer; - while (n >= 16) { - d[0] = clearValue; d[1] = clearValue; - d[2] = clearValue; d[3] = clearValue; - d[4] = clearValue; d[5] = clearValue; - d[6] = clearValue; d[7] = clearValue; - d[8] = clearValue; d[9] = clearValue; - d[10] = clearValue; d[11] = clearValue; - d[12] = clearValue; d[13] = clearValue; - d[14] = clearValue; d[15] = clearValue; - d += 16; - n -= 16; - } - while (n > 0) { - *d++ = clearValue; - n--; - } - } + _mesa_problem(ctx, "bad depth renderbuffer DataType"); } } }