summaryrefslogtreecommitdiff
path: root/src/mesa/swrast/s_depth.c
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2005-05-04 20:11:35 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2005-05-04 20:11:35 +0000
commite4b2356c07d31fbeeabb13b2fb47db703b473080 (patch)
treed8b7f1c7c9e7c84d84349485f942dd205dd4c16d /src/mesa/swrast/s_depth.c
parentebef61f5c0950572f9c6a81b08f447957461675c (diff)
Major check-in of changes for GL_EXT_framebuffer_object extension.
Main driver impacts: - new code for creating the Mesa GLframebuffer - new span/pixel read/write code Some drivers not yet updated/tested.
Diffstat (limited to 'src/mesa/swrast/s_depth.c')
-rw-r--r--src/mesa/swrast/s_depth.c912
1 files changed, 236 insertions, 676 deletions
diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c
index 0142fe1552..e36878e6fc 100644
--- a/src/mesa/swrast/s_depth.c
+++ b/src/mesa/swrast/s_depth.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 5.1
+ * Version: 6.3
*
- * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2005 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"),
@@ -27,51 +27,21 @@
#include "context.h"
#include "macros.h"
#include "imports.h"
+#include "fbobject.h"
#include "s_depth.h"
#include "s_context.h"
/**
- * Return address of depth buffer value for given window coord.
- */
-GLvoid *
-_swrast_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;
@@ -300,7 +270,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;
@@ -529,74 +499,69 @@ 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)
{
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+ struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
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 (ctx->DrawBuffer->Visual.depthBits <= 16) {
+ 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);
+ 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, NULL);
}
-#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, NULL);
}
-#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) {
@@ -606,7 +571,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] < *zptr) {
/* pass */
*zptr = z[i];
@@ -623,7 +588,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] < *zptr) {
/* pass */
}
@@ -641,7 +606,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] <= *zptr) {
/* pass */
*zptr = z[i];
@@ -658,7 +623,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] <= *zptr) {
/* pass */
}
@@ -676,7 +641,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] >= *zptr) {
/* pass */
*zptr = z[i];
@@ -693,7 +658,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] >= *zptr) {
/* pass */
}
@@ -711,7 +676,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] > *zptr) {
/* pass */
*zptr = z[i];
@@ -728,7 +693,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] > *zptr) {
/* pass */
}
@@ -746,7 +711,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] != *zptr) {
/* pass */
*zptr = z[i];
@@ -763,7 +728,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] != *zptr) {
/* pass */
}
@@ -781,7 +746,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] == *zptr) {
/* pass */
*zptr = z[i];
@@ -798,7 +763,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] == *zptr) {
/* pass */
}
@@ -816,7 +781,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
+ GLushort *zptr = Z_ADDRESS(x[i], y[i]);
*zptr = z[i];
}
}
@@ -830,19 +795,19 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
- _mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
+ _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels");
}
}
/*
- * Do depth testing for an array of fragments using software Z buffer.
+ * Do depth testing for an array of fragments with direct access to zbuffer.
*/
static void
-software_depth_test_pixels32( GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
+direct_depth_test_pixels32(GLcontext *ctx, GLuint *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) {
@@ -852,7 +817,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] < *zptr) {
/* pass */
*zptr = z[i];
@@ -869,7 +834,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] < *zptr) {
/* pass */
}
@@ -887,7 +852,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] <= *zptr) {
/* pass */
*zptr = z[i];
@@ -904,7 +869,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] <= *zptr) {
/* pass */
}
@@ -922,7 +887,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] >= *zptr) {
/* pass */
*zptr = z[i];
@@ -939,7 +904,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] >= *zptr) {
/* pass */
}
@@ -957,7 +922,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] > *zptr) {
/* pass */
*zptr = z[i];
@@ -974,7 +939,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] > *zptr) {
/* pass */
}
@@ -992,7 +957,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] != *zptr) {
/* pass */
*zptr = z[i];
@@ -1009,7 +974,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] != *zptr) {
/* pass */
}
@@ -1027,7 +992,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] == *zptr) {
/* pass */
*zptr = z[i];
@@ -1044,7 +1009,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
if (z[i] == *zptr) {
/* pass */
}
@@ -1062,7 +1027,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
+ GLuint *zptr = Z_ADDRESS(x[i], y[i]);
*zptr = z[i];
}
}
@@ -1076,275 +1041,55 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
- _mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
+ _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels");
}
}
-/*
- * Do depth testing for an array of pixels using hardware Z buffer.
- * Input/output: zbuffer - array of depth values from Z buffer
- * Input: z - array of fragment z values.
- */
-static void
-hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
- const GLdepth z[], GLubyte mask[] )
-{
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Depth.Func) {
- case GL_LESS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[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<n; i++) {
- if (mask[i]) {
- if (z[i] < zbuffer[i]) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_LEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[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<n; i++) {
- if (mask[i]) {
- if (z[i] <= zbuffer[i]) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[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<n; i++) {
- if (mask[i]) {
- if (z[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<n; i++) {
- if (mask[i]) {
- if (z[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<n; i++) {
- if (mask[i]) {
- if (z[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; i<n; i++) {
- if (mask[i]) {
- if (z[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<n; i++) {
- if (mask[i]) {
- if (z[i] != zbuffer[i]) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_EQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[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<n; i++) {
- if (mask[i]) {
- if (z[i] == zbuffer[i]) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_ALWAYS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zbuffer[i] = z[i];
- }
- }
- }
- else {
- /* Don't update Z buffer or mask */
- }
- break;
- case GL_NEVER:
- /* depth test never passes */
- _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;
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+ struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ 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;
+ 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];
+ rb->GetValues(ctx, rb, count, x, y, zbuffer);
+ depth_test_span16(ctx, count, zbuffer, z, mask );
+ rb->PutValues(ctx, rb, count, x, y, zbuffer, NULL);
+ }
+ else {
+ GLuint zbuffer[MAX_WIDTH];
+ ASSERT(rb->DataType == GL_UNSIGNED_INT);
+ rb->GetValues(ctx, rb, count, x, y, zbuffer);
+ depth_test_span32(ctx, count, zbuffer, z, mask );
+ rb->PutValues(ctx, rb, count, x, y, zbuffer, NULL);
+ }
}
- return n; /* not really correct, but OK */
+
+ return count; /* not really correct, but OK */
}
@@ -1372,24 +1117,33 @@ _swrast_depth_test_span( GLcontext *ctx, struct sw_span *span)
GLboolean
_swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLdepth zMin = (GLdepth) (ctx->Depth.BoundsMin * ctx->DepthMaxF + 0.5F);
- GLdepth zMax = (GLdepth) (ctx->Depth.BoundsMax * ctx->DepthMaxF + 0.5F);
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+ struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ 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 (swrast->Driver.ReadDepthPixels) {
- /* read depth values from hardware Z buffer */
- GLdepth zbuffer[MAX_WIDTH];
- ASSERT(span->end <= MAX_WIDTH);
- if (span->arrayMask & SPAN_XY)
- (*swrast->Driver.ReadDepthPixels)(ctx, span->end, span->array->x,
- span->array->y, zbuffer);
- else
- (*swrast->Driver.ReadDepthSpan)(ctx, span->end, span->x, span->y,
- zbuffer);
- for (i = 0; i < span->end; i++) {
+ if (rb->DataType == GL_UNSIGNED_SHORT) {
+ /* get 16-bit values */
+ GLushort zbuffer16[MAX_WIDTH], *zbuffer;
+ if (span->arrayMask & SPAN_XY) {
+ rb->GetValues(ctx, rb, count, span->array->x, span->array->y, zbuffer16);
+ zbuffer = zbuffer16;
+ }
+ else {
+ zbuffer = 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;
@@ -1399,62 +1153,32 @@ _swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span )
}
}
else {
- /* software Z buffer */
+ /* get 32-bit values */
+ GLuint zbuffer32[MAX_WIDTH], *zbuffer;
if (span->arrayMask & SPAN_XY) {
- if (ctx->Visual.depthBits <= 16) {
- /* 16 bits / Z */
- for (i = 0; i < span->end; i++) {
- if (mask[i]) {
- const GLushort *zPtr = Z_ADDRESS16(ctx, span->array->x[i],
- span->array->y[i]);
- if (*zPtr < zMin || *zPtr > zMax)
- mask[i] = GL_FALSE;
- else
- anyPass = GL_TRUE;
- }
- }
- }
- else {
- /* 32 bits / Z */
- for (i = 0; i < span->end; i++) {
- if (mask[i]) {
- const GLuint *zPtr = Z_ADDRESS32(ctx, span->array->x[i],
- span->array->y[i]);
- if (*zPtr < zMin || *zPtr > zMax)
- mask[i] = GL_FALSE;
- else
- anyPass = GL_TRUE;
- }
- }
- }
+ rb->GetValues(ctx, rb, count, span->array->x, span->array->y, zbuffer32);
+ zbuffer = zbuffer32;
}
else {
- if (ctx->Visual.depthBits <= 16) {
- /* 16 bits / Z */
- const GLushort *zPtr = Z_ADDRESS16(ctx, span->x, span->y);
- for (i = 0; i < span->end; i++) {
- if (mask[i]) {
- if (zPtr[i] < zMin || zPtr[i] > zMax)
- mask[i] = GL_FALSE;
- else
- anyPass = GL_TRUE;
- }
- }
+ zbuffer = rb->GetPointer(ctx, rb, span->x, span->y);
+ if (!zbuffer) {
+ rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer32);
+ zbuffer = zbuffer32;
}
- else {
- /* 32 bits / Z */
- const GLuint *zPtr = Z_ADDRESS32(ctx, span->x, span->y);
- for (i = 0; i < span->end; i++) {
- if (mask[i]) {
- if (zPtr[i] < zMin || zPtr[i] > zMax)
- mask[i] = GL_FALSE;
- else
- anyPass = GL_TRUE;
- }
- }
+ }
+ 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;
}
@@ -1468,15 +1192,16 @@ _swrast_depth_bounds_test( 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.
+ *
+ * XXXX this is no longer a swrast function!!!
+ *
*/
void
-_swrast_read_depth_span( GLcontext *ctx,
- GLint n, GLint x, GLint y, GLdepth depth[] )
+_swrast_read_depth_span( GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLint n, GLint x, GLint y, GLuint depth[] )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
- if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
- x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
+ if (y < 0 || y >= (GLint) rb->Height ||
+ x + (GLint) n <= 0 || x >= (GLint) rb->Width) {
/* span is completely outside framebuffer */
GLint i;
for (i = 0; i < n; i++)
@@ -1493,8 +1218,8 @@ _swrast_read_depth_span( GLcontext *ctx,
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;
@@ -1504,292 +1229,127 @@ _swrast_read_depth_span( GLcontext *ctx,
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];
- }
- }
+ /* we'll always return 32-bit values to our caller */
+ if (!rb) {
+ _mesa_bzero(depth, n * sizeof(GLuint));
}
- else if (swrast->Driver.ReadDepthSpan) {
- /* read from hardware depth buffer */
- (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, depth );
+ else if (rb->DataType == GL_UNSIGNED_INT) {
+ rb->GetRow(ctx, rb, x, y, n, depth);
}
else {
- /* no depth buffer */
- _mesa_bzero(depth, n * sizeof(GLfloat));
+ GLushort temp[MAX_WIDTH];
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
+ rb->GetRow(ctx, rb, n, x, y, temp);
+ for (i = 0; i < n; i++) {
+ depth[i] = temp[i];
+ }
}
-
}
-
-
/**
* 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
*/
void
-_swrast_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) {
- /* span is completely outside framebuffer */
- 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) {
- /* 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] = (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) {
- /* 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 {
- /* no depth buffer */
- _mesa_bzero(depth, n * sizeof(GLfloat));
- }
-}
-
-
-
-/**********************************************************************/
-/***** 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 uninitialized.
- */
-void
-_swrast_alloc_depth_buffer( GLframebuffer *buffer )
+_swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLint n, GLint x, GLint y, GLfloat depth[] )
{
- GLint bytesPerValue;
-
- ASSERT(buffer->UseSoftwareDepthBuffer);
+ const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
+ GLuint temp[MAX_WIDTH];
+ GLint i;
- /* 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);
+ assert(n <= MAX_WIDTH);
- 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");
- }
+ _swrast_read_depth_span(ctx, rb, n, x, y, temp);
+ for (i = 0; i < n; i++) {
+ depth[i] = temp[i] * scale;
}
}
/**
- * 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.
+ * Clear the depth buffer.
+ * XXX this is no longer a swrast function!!!
*/
void
-_swrast_clear_depth_buffer( GLcontext *ctx )
+_swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLuint clearValue
+ = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF);
+ GLint x, y, width, height;
- if (ctx->Visual.depthBits == 0
- || !ctx->Depth.Mask) {
+ if (!rb || !ctx->Depth.Mask) {
/* no depth buffer, or writing to it is disabled */
return;
}
- if (swrast->Driver.WriteMonoDepthSpan) {
- const GLdepth clearValue = (GLdepth)(ctx->Depth.Clear * ctx->DepthMax);
- const GLint x = ctx->DrawBuffer->_Xmin;
- const GLint y = ctx->DrawBuffer->_Ymin;
- const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
- const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
- GLint i;
-
- for (i = 0; i < height; i++) {
- (*swrast->Driver.WriteMonoDepthSpan)( ctx, width, x, y + i,
- clearValue, NULL );
- }
-
- return;
- }
-
- if (!ctx->DrawBuffer->DepthBuffer)
- return;
-
- /* The loops in this function have been written so the IRIX 5.3
- * C compiler can unroll them. Hopefully other compilers can too!
- */
-
- 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 (width == rb->Width &&
+ (clearValue & 0xff) == ((clearValue >> 8) & 0xff)) {
+ /* 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) {
- _mesa_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 clearRow[MAX_WIDTH];
+ GLint i, j;
+ for (j = 0; j < width; j++) {
+ clearRow[j] = clearValue;
}
- 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--;
- }
+ for (i = 0; i < height; i++) {
+ rb->PutRow(ctx, rb, width, x, y + i, clearRow, NULL);
}
}
else {
- /* >16 bit depth buffer */
- 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));
+ GLuint clearRow[MAX_WIDTH];
+ GLint i, j;
+ assert(rb->DataType == GL_UNSIGNED_INT);
+ for (j = 0; j < width; j++) {
+ clearRow[j] = clearValue;
}
- 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--;
- }
+ for (i = 0; i < height; i++) {
+ rb->PutRow(ctx, rb, width, x, y + i, clearRow, NULL);
}
}
}