#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "imports.h"
#include "s_depth.h"
#include "s_context.h"
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) )
static GLuint
depth_test_span16( GLcontext *ctx, GLuint n,
GLushort zbuffer[], const GLdepth z[], GLubyte mask[] )
{
GLuint passed = 0;
switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_LEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GREATER:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_EQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_ALWAYS:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
zbuffer[i] = z[i];
passed++;
}
}
}
else {
passed = n;
}
break;
case GL_NEVER:
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in depth_test_span16");
}
return passed;
}
static GLuint
depth_test_span32( GLcontext *ctx, GLuint n,
GLuint zbuffer[], const GLdepth z[], GLubyte mask[] )
{
GLuint passed = 0;
switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_LEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GREATER:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_EQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_ALWAYS:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
zbuffer[i] = z[i];
passed++;
}
}
}
else {
passed = n;
}
break;
case GL_NEVER:
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in depth_test_span32");
}
return passed;
}
static GLuint
depth_test_span( GLcontext *ctx, struct sw_span *span)
{
const GLint x = span->x;
const GLint y = span->y;
const GLuint n = span->end;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
ASSERT((span->arrayMask & SPAN_XY) == 0);
ASSERT(span->arrayMask & SPAN_Z);
if (swrast->Driver.ReadDepthSpan) {
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;
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);
}
else {
GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
passed = depth_test_span32(ctx, n, zptr, span->array->z, span->array->mask);
}
#if 1
if (passed < span->end) {
span->writeAll = GL_FALSE;
}
#else
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 --;
}
#endif
return passed;
}
}
static void
software_depth_test_pixels16( GLcontext *ctx, GLuint n,
const GLint x[], const GLint y[],
const GLdepth z[], GLubyte mask[] )
{
switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] < *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] < *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_LEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] <= *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] <= *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] >= *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] >= *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GREATER:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] > *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] > *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] != *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] != *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_EQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] == *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] == *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_ALWAYS:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
*zptr = z[i];
}
}
}
else {
}
break;
case GL_NEVER:
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
}
}
static void
software_depth_test_pixels32( GLcontext *ctx, GLuint n,
const GLint x[], const GLint y[],
const GLdepth z[], GLubyte mask[] )
{
switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] < *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] < *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_LEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] <= *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] <= *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] >= *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] >= *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GREATER:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] > *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] > *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] != *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] != *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_EQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] == *zptr) {
*zptr = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] == *zptr) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_ALWAYS:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
*zptr = z[i];
}
}
}
else {
}
break;
case GL_NEVER:
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
}
}
static void
hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
const GLdepth z[], GLubyte mask[] )
{
switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
zbuffer[i] = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_LEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
zbuffer[i] = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
zbuffer[i] = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GREATER:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
zbuffer[i] = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
zbuffer[i] = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_EQUAL:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
zbuffer[i] = z[i];
}
else {
mask[i] = 0;
}
}
}
}
else {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_ALWAYS:
if (ctx->Depth.Mask) {
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
zbuffer[i] = z[i];
}
}
}
else {
}
break;
case GL_NEVER:
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
}
}
static GLuint
depth_test_pixels( GLcontext *ctx, struct sw_span *span )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint n = span->end;
const GLint *x = span->array->x;
const GLint *y = span->array->y;
const GLdepth *z = span->array->z;
GLubyte *mask = span->array->mask;
if (swrast->Driver.ReadDepthPixels) {
GLdepth zbuffer[MAX_WIDTH];
(*swrast->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
assert(swrast->Driver.WriteDepthPixels);
(*swrast->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask );
}
else {
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);
}
return n;
}
GLuint
_mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
{
if (span->arrayMask & SPAN_XY)
return depth_test_pixels(ctx, span);
else
return depth_test_span(ctx, span);
}
void
_mesa_read_depth_span( GLcontext *ctx,
GLint n, GLint x, GLint y, GLdepth depth[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
GLint i;
for (i = 0; i < n; i++)
depth[i] = 0;
return;
}
if (x < 0) {
GLint dx = -x;
GLint i;
for (i = 0; i < dx; i++)
depth[i] = 0;
x = 0;
n -= dx;
depth += dx;
}
if (x + n > (GLint) ctx->DrawBuffer->Width) {
GLint dx = x + n - (GLint) ctx->DrawBuffer->Width;
GLint i;
for (i = 0; i < dx; i++)
depth[n - i - 1] = 0;
n -= dx;
}
if (n <= 0) {
return;
}
if (ctx->DrawBuffer->DepthBuffer) {
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];
}
}
}
else if (swrast->Driver.ReadDepthSpan) {
(*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, depth );
}
else {
_mesa_bzero(depth, n * sizeof(GLfloat));
}
}
void
_mesa_read_depth_span_float( GLcontext *ctx,
GLint n, GLint x, GLint y, GLfloat depth[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLfloat scale = 1.0F / ctx->DepthMaxF;
if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
GLint i;
for (i = 0; i < n; i++)
depth[i] = 0.0F;
return;
}
if (x < 0) {
GLint dx = -x;
GLint i;
for (i = 0; i < dx; i++)
depth[i] = 0.0F;
n -= dx;
x = 0;
}
if (x + n > (GLint) ctx->DrawBuffer->Width) {
GLint dx = x + n - (GLint) ctx->DrawBuffer->Width;
GLint i;
for (i = 0; i < dx; i++)
depth[n - i - 1] = 0.0F;
n -= dx;
}
if (n <= 0) {
return;
}
if (ctx->DrawBuffer->DepthBuffer) {
if (ctx->Visual.depthBits <= 16) {
const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
GLint i;
for (i = 0; i < n; i++) {
depth[i] = (GLfloat) zptr[i] * scale;
}
}
else {
const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
GLint i;
for (i = 0; i < n; i++) {
depth[i] = (GLfloat) zptr[i] * scale;
}
}
}
else if (swrast->Driver.ReadDepthSpan) {
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 {
_mesa_bzero(depth, n * sizeof(GLfloat));
}
}
void
_mesa_alloc_depth_buffer( GLframebuffer *buffer )
{
GLint bytesPerValue;
ASSERT(buffer->UseSoftwareDepthBuffer);
if (buffer->DepthBuffer) {
MESA_PBUFFER_FREE(buffer->DepthBuffer);
buffer->DepthBuffer = NULL;
}
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) {
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");
}
}
}
void
_mesa_clear_depth_buffer( GLcontext *ctx )
{
if (ctx->Visual.depthBits == 0
|| !ctx->DrawBuffer->DepthBuffer
|| !ctx->Depth.Mask) {
return;
}
if (ctx->Scissor.Enabled) {
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;
}
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;
}
dRow += rowStride;
}
}
}
else {
if (ctx->Visual.depthBits <= 16) {
const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax);
if ((clearValue & 0xff) == (clearValue >> 8)) {
if (clearValue == 0) {
_mesa_bzero(ctx->DrawBuffer->DepthBuffer,
2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height);
}
else {
MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff,
2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
}
}
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 {
const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax);
if (clearValue == 0) {
_mesa_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--;
}
}
}
}
}