summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>1999-12-10 19:09:21 +0000
committerBrian Paul <[email protected]>1999-12-10 19:09:21 +0000
commit5c3bee503999fbc0d7c65462ff62f9e38fe40e33 (patch)
tree0c6d7bf09b9dbd5a50eb79cb1e1e29cd35d8edb3 /src/mesa/main
parentf5abeebf491f8f8d0ae57d602fb3166b52b475b6 (diff)
changes in hardware depth buffer support
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/context.c71
-rw-r--r--src/mesa/main/context.h8
-rw-r--r--src/mesa/main/dd.h46
-rw-r--r--src/mesa/main/depth.c672
-rw-r--r--src/mesa/main/depth.h63
-rw-r--r--src/mesa/main/stencil.c12
6 files changed, 512 insertions, 360 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 69d0a0320de..0d756de63e9 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1,4 +1,4 @@
-/* $Id: context.c,v 1.26 1999/12/04 21:23:17 brianp Exp $ */
+/* $Id: context.c,v 1.27 1999/12/10 19:09:21 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -1277,10 +1277,11 @@ GLcontext *gl_create_context( GLvisual *visual,
/* Fill in some driver defaults now.
*/
+#if 0
ctx->Driver.AllocDepthBuffer = gl_alloc_depth_buffer;
ctx->Driver.ReadDepthSpanFloat = gl_read_depth_span_float;
ctx->Driver.ReadDepthSpanInt = gl_read_depth_span_int;
-
+#endif
#ifdef PROFILE
init_timings( ctx );
@@ -1427,18 +1428,47 @@ void gl_destroy_context( GLcontext *ctx )
* encapsulates the depth, stencil and accum buffers and related
* parameters.
* Input: visual - a GLvisual pointer
+ * softwareDepth - create/use a software depth buffer?
+ * softwareStencil - create/use a software stencil buffer?
+ * softwareAccum - create/use a software accum buffer?
+ * softwareAlpha - create/use a software alpha buffer?
+
* Return: pointer to new GLframebuffer struct or NULL if error.
*/
-GLframebuffer *gl_create_framebuffer( GLvisual *visual )
+GLframebuffer *gl_create_framebuffer( GLvisual *visual,
+ GLboolean softwareDepth,
+ GLboolean softwareStencil,
+ GLboolean softwareAccum,
+ GLboolean softwareAlpha )
{
GLframebuffer *buffer;
- buffer = (GLframebuffer *) CALLOC( sizeof(GLframebuffer) );
+ buffer = CALLOC_STRUCT(gl_frame_buffer);
if (!buffer) {
return NULL;
}
+ /* sanity checks */
+ if (softwareDepth ) {
+ assert(visual->DepthBits > 0);
+ }
+ if (softwareStencil) {
+ assert(visual->StencilBits > 0);
+ }
+ if (softwareAccum) {
+ assert(visual->RGBAflag);
+ assert(visual->AccumBits > 0);
+ }
+ if (softwareAlpha) {
+ assert(visual->RGBAflag);
+ assert(visual->AlphaBits > 0);
+ }
+
buffer->Visual = visual;
+ buffer->UseSoftwareDepthBuffer = softwareDepth;
+ buffer->UseSoftwareStencilBuffer = softwareStencil;
+ buffer->UseSoftwareAccumBuffer = softwareAccum;
+ buffer->UseSoftwareAlphaBuffers = softwareAlpha;
return buffer;
}
@@ -1694,15 +1724,15 @@ _mesa_ResizeBuffersMESA( void )
ctx->DrawBuffer->Height = buf_height;
/* Reallocate other buffers if needed. */
- if (ctx->Visual->DepthBits>0) {
+ if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
/* reallocate depth buffer */
- (*ctx->Driver.AllocDepthBuffer)( ctx );
+ gl_alloc_depth_buffer( ctx );
}
- if (ctx->Visual->StencilBits>0) {
+ if (ctx->DrawBuffer->UseSoftwareStencilBuffer) {
/* reallocate stencil buffer */
gl_alloc_stencil_buffer( ctx );
}
- if (ctx->Visual->AccumBits>0) {
+ if (ctx->DrawBuffer->UseSoftwareAccumBuffer) {
/* reallocate accum buffer */
gl_alloc_accum_buffer( ctx );
}
@@ -2197,31 +2227,6 @@ void gl_update_state( GLcontext *ctx )
ctx->DrawBuffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
}
}
-
- /* The driver isn't managing the depth buffer.
- */
- if (ctx->Driver.AllocDepthBuffer == gl_alloc_depth_buffer)
- {
- if (ctx->Depth.Mask) {
- switch (ctx->Depth.Func) {
- case GL_LESS:
- ctx->Driver.DepthTestSpan = gl_depth_test_span_less;
- ctx->Driver.DepthTestPixels = gl_depth_test_pixels_less;
- break;
- case GL_GREATER:
- ctx->Driver.DepthTestSpan = gl_depth_test_span_greater;
- ctx->Driver.DepthTestPixels = gl_depth_test_pixels_greater;
- break;
- default:
- ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
- ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
- }
- }
- else {
- ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
- ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
- }
- }
}
if (ctx->NewState & NEW_LIGHTING) {
diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h
index df510afb3f6..32dd613c140 100644
--- a/src/mesa/main/context.h
+++ b/src/mesa/main/context.h
@@ -1,4 +1,4 @@
-/* $Id: context.h,v 1.4 1999/11/24 18:48:31 brianp Exp $ */
+/* $Id: context.h,v 1.5 1999/12/10 19:09:22 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -97,7 +97,11 @@ extern void gl_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask);
* It bundles up the depth buffer, stencil buffer and accum buffers into a
* single entity.
*/
-extern GLframebuffer *gl_create_framebuffer( GLvisual *visual );
+extern GLframebuffer *gl_create_framebuffer( GLvisual *visual,
+ GLboolean softwareDepth,
+ GLboolean softwareStencil,
+ GLboolean softwareAccum,
+ GLboolean softwareAlpha );
extern void gl_destroy_framebuffer( GLframebuffer *buffer );
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 904fa4849db..7a6d65437d7 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -1,4 +1,4 @@
-/* $Id: dd.h,v 1.7 1999/12/10 16:14:40 brianp Exp $ */
+/* $Id: dd.h,v 1.8 1999/12/10 19:09:22 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -393,42 +393,40 @@ struct dd_function_table {
*** Either ALL or NONE of these functions must be implemented!
***/
- void (*AllocDepthBuffer)( GLcontext *ctx );
- /*
- * Called when the depth buffer must be allocated or possibly resized.
+ void (*WriteDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLdepth depth[], const GLubyte mask[] );
+ /* Write a horizontal span of values into the depth buffer. Only write
+ * depth[i] value if mask[i] is nonzero.
*/
- GLuint (*DepthTestSpan)( GLcontext *ctx,
- GLuint n, GLint x, GLint y, const GLdepth z[],
- GLubyte mask[] );
- void (*DepthTestPixels)( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
- /*
- * Apply the depth buffer test to an span/array of pixels and return
- * an updated pixel mask. This function is not used when accelerated
- * point, line, polygon functions are used.
+ void (*ReadDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y,
+ GLdepth depth[] );
+ /* Read a horizontal span of values from the depth buffer.
*/
- void (*ReadDepthSpanFloat)( GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLfloat depth[]);
- void (*ReadDepthSpanInt)( GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLdepth depth[] );
- /*
- * Return depth values as integers for glReadPixels.
- * Floats should be returned in the range [0,1].
- * Ints (GLdepth) values should be in the range [0,MAXDEPTH].
+
+ void (*WriteDepthPixels)( GLcontext *ctx, GLuint n,
+ const GLint x[], const GLint y[],
+ const GLdepth depth[], const GLubyte mask[] );
+ /* Write an array of randomly positioned depth values into the
+ * depth buffer. Only write depth[i] value if mask[i] is nonzero.
+ */
+
+ void (*ReadDepthPixels)( GLcontext *ctx, GLuint n,
+ const GLint x[], const GLint y[],
+ GLdepth depth[] );
+ /* Read an array of randomly positioned depth values from the depth buffer.
*/
+
/***
*** For supporting hardware stencil buffers:
*** Either ALL or NONE of these functions must be implemented!
***/
void (*WriteStencilSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLstencil stencil[],
- const GLubyte mask[] );
+ const GLstencil stencil[], const GLubyte mask[] );
/* Write a horizontal span of stencil values into the stencil buffer.
* If mask is NULL, write all stencil values.
* Else, only write stencil[i] if mask[i] is non-zero.
diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c
index 746b8188ba8..b2fa94757e3 100644
--- a/src/mesa/main/depth.c
+++ b/src/mesa/main/depth.c
@@ -1,4 +1,4 @@
-/* $Id: depth.c,v 1.10 1999/11/24 18:48:31 brianp Exp $ */
+/* $Id: depth.c,v 1.11 1999/12/10 19:09:22 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -24,6 +24,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+
#ifdef PC_HEADER
#include "all.h"
#else
@@ -32,6 +33,7 @@
#include "enums.h"
#include "depth.h"
#include "mem.h"
+#include "pb.h"
#include "types.h"
#endif
@@ -128,28 +130,16 @@ _mesa_DepthMask( GLboolean flag )
/*
- * Depth test horizontal spans of fragments. These functions are called
- * via ctx->Driver.depth_test_span only.
- *
- * Input: n - number of pixels in the span
- * x, y - location of leftmost pixel in span in window coords
- * z - array [n] of integer depth values
- * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw)
- * Return: number of pixels which passed depth test
- */
-
-
-/*
- * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
+ * Do depth test for an array of fragments. This is used both for
+ * software and hardware Z buffers.
+ * Input: zbuffer - array of z values in the zbuffer
+ * z - array of fragment z values
+ * Return: number of fragments which pass the test.
*/
-GLuint gl_depth_test_span_generic( GLcontext* ctx,
- GLuint n, GLint x, GLint y,
- const GLdepth z[],
- GLubyte mask[] )
+static GLuint
+depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
+ GLdepth zbuffer[], const GLdepth z[], GLubyte mask[] )
{
- GLdepth *zptr = Z_ADDRESS( ctx, x, y );
- GLubyte *m = mask;
- GLuint i;
GLuint passed = 0;
/* switch cases ordered from most frequent to less frequent */
@@ -157,30 +147,32 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx,
case GL_LESS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
- for (i=0; i<n; i++,zptr++,m++) {
- if (*m) {
- if (z[i] < *zptr) {
+ GLuint i;
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ if (z[i] < zbuffer[i]) {
/* pass */
- *zptr = z[i];
+ zbuffer[i] = z[i];
passed++;
}
else {
/* fail */
- *m = 0;
+ mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
- for (i=0; i<n; i++,zptr++,m++) {
- if (*m) {
- if (z[i] < *zptr) {
+ GLuint i;
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ if (z[i] < zbuffer[i]) {
/* pass */
passed++;
}
else {
- *m = 0;
+ mask[i] = 0;
}
}
}
@@ -189,28 +181,30 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx,
case GL_LEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] <= *zptr) {
- *zptr = z[i];
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ if (z[i] <= zbuffer[i]) {
+ zbuffer[i] = z[i];
passed++;
}
else {
- *m = 0;
+ mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] <= *zptr) {
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ if (z[i] <= zbuffer[i]) {
/* pass */
passed++;
}
else {
- *m = 0;
+ mask[i] = 0;
}
}
}
@@ -219,28 +213,30 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx,
case GL_GEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] >= *zptr) {
- *zptr = z[i];
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ if (z[i] >= zbuffer[i]) {
+ zbuffer[i] = z[i];
passed++;
}
else {
- *m = 0;
+ mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] >= *zptr) {
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ if (z[i] >= zbuffer[i]) {
/* pass */
passed++;
}
else {
- *m = 0;
+ mask[i] = 0;
}
}
}
@@ -249,28 +245,30 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx,
case GL_GREATER:
if (ctx->Depth.Mask) {
/* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] > *zptr) {
- *zptr = z[i];
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ if (z[i] > zbuffer[i]) {
+ zbuffer[i] = z[i];
passed++;
}
else {
- *m = 0;
+ mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] > *zptr) {
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ if (z[i] > zbuffer[i]) {
/* pass */
passed++;
}
else {
- *m = 0;
+ mask[i] = 0;
}
}
}
@@ -279,28 +277,30 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx,
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] != *zptr) {
- *zptr = z[i];
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ if (z[i] != zbuffer[i]) {
+ zbuffer[i] = z[i];
passed++;
}
else {
- *m = 0;
+ mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] != *zptr) {
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ if (z[i] != zbuffer[i]) {
/* pass */
passed++;
}
else {
- *m = 0;
+ mask[i] = 0;
}
}
}
@@ -309,28 +309,30 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx,
case GL_EQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] == *zptr) {
- *zptr = z[i];
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ if (z[i] == zbuffer[i]) {
+ zbuffer[i] = z[i];
passed++;
}
else {
- *m =0;
+ mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] == *zptr) {
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ if (z[i] == zbuffer[i]) {
/* pass */
passed++;
}
else {
- *m =0;
+ mask[i] = 0;
}
}
}
@@ -339,9 +341,10 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx,
case GL_ALWAYS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- *zptr = z[i];
+ GLuint i;
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ zbuffer[i] = z[i];
passed++;
}
}
@@ -352,13 +355,11 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx,
}
break;
case GL_NEVER:
- for (i=0;i<n;i++) {
- mask[i] = 0;
- }
+ MEMSET(mask, 0, n * sizeof(GLubyte));
break;
default:
- gl_problem(ctx, "Bad depth func in gl_depth_test_span_generic");
- } /*switch*/
+ gl_problem(ctx, "Bad depth func in depth_test_span");
+ }
return passed;
}
@@ -366,93 +367,57 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx,
/*
- * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE).
+ * Apply depth test to span of fragments. Hardware or software z buffer.
*/
-GLuint gl_depth_test_span_less( GLcontext* ctx,
- GLuint n, GLint x, GLint y, const GLdepth z[],
- GLubyte mask[] )
+GLuint
+gl_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLdepth z[], GLubyte mask[] )
{
- GLdepth *zptr = Z_ADDRESS( ctx, x, y );
- GLuint i;
- GLuint passed = 0;
+ GLdepth zbuffer[MAX_WIDTH];
+ GLdepth *zptr;
+ GLuint passed;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] < zptr[i]) {
- /* pass */
- zptr[i] = z[i];
- passed++;
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
+ if (ctx->Driver.ReadDepthSpan) {
+ /* read depth values out of hardware Z buffer */
+ (*ctx->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
+ zptr = zbuffer;
+ }
+ else {
+ /* test against software depth buffer values */
+ zptr = Z_ADDRESS( ctx, x, y );
}
- return passed;
-}
-
-/*
- * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE).
- */
-GLuint gl_depth_test_span_greater( GLcontext* ctx,
- GLuint n, GLint x, GLint y,
- const GLdepth z[],
- GLubyte mask[] )
-{
- GLdepth *zptr = Z_ADDRESS( ctx, x, y );
- GLuint i;
- GLuint passed = 0;
+ passed = depth_test_span( ctx, n, x, y, zptr, z, mask );
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] > zptr[i]) {
- /* pass */
- zptr[i] = z[i];
- passed++;
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
+ if (ctx->Driver.WriteDepthSpan) {
+ /* write updated depth values into hardware Z buffer */
+ assert(zptr == zbuffer);
+ (*ctx->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask);
}
+
return passed;
}
-/*
- * Depth test an array of randomly positioned fragments.
- */
-
-
-#define ZADDR_SETUP GLdepth *depthbuffer = ctx->Buffer->Depth; \
- GLint width = ctx->Buffer->Width;
-
-#define ZADDR( X, Y ) (depthbuffer + (Y) * width + (X) )
-
-
/*
- * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
+ * Do depth testing for an array of fragments using software Z buffer.
*/
-void gl_depth_test_pixels_generic( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
+static void
+software_depth_test_pixels( GLcontext *ctx, GLuint n,
+ const GLint x[], const GLint y[],
+ const GLdepth z[], GLubyte mask[] )
{
- register GLdepth *zptr;
- register GLuint i;
-
/* 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]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] < *zptr) {
/* pass */
*zptr = z[i];
@@ -466,9 +431,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
}
else {
/* Don't update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] < *zptr) {
/* pass */
}
@@ -483,9 +449,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
case GL_LEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] <= *zptr) {
/* pass */
*zptr = z[i];
@@ -499,9 +466,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
}
else {
/* Don't update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] <= *zptr) {
/* pass */
}
@@ -516,9 +484,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
case GL_GEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] >= *zptr) {
/* pass */
*zptr = z[i];
@@ -532,9 +501,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
}
else {
/* Don't update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] >= *zptr) {
/* pass */
}
@@ -549,9 +519,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
case GL_GREATER:
if (ctx->Depth.Mask) {
/* Update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] > *zptr) {
/* pass */
*zptr = z[i];
@@ -565,9 +536,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
}
else {
/* Don't update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] > *zptr) {
/* pass */
}
@@ -582,9 +554,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] != *zptr) {
/* pass */
*zptr = z[i];
@@ -598,9 +571,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
}
else {
/* Don't update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] != *zptr) {
/* pass */
}
@@ -615,9 +589,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
case GL_EQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] == *zptr) {
/* pass */
*zptr = z[i];
@@ -631,9 +606,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
}
else {
/* Don't update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
if (z[i] == *zptr) {
/* pass */
}
@@ -648,9 +624,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
case GL_ALWAYS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
+ GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
+ GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
*zptr = z[i];
}
}
@@ -661,71 +638,274 @@ void gl_depth_test_pixels_generic( GLcontext* ctx,
break;
case GL_NEVER:
/* depth test never passes */
- for (i=0;i<n;i++) {
- mask[i] = 0;
- }
+ MEMSET(mask, 0, n * sizeof(GLubyte));
break;
default:
- gl_problem(ctx, "Bad depth func in gl_depth_test_pixels_generic");
- } /*switch*/
+ gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
+ }
}
/*
- * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ).
+ * 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.
*/
-void gl_depth_test_pixels_less( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
+static void
+hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
+ const GLdepth z[], GLubyte mask[] )
{
- GLdepth *zptr;
- GLuint i;
-
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
- if (z[i] < *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
+ /* 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 */
+ MEMSET(mask, 0, n * sizeof(GLubyte));
+ break;
+ default:
+ gl_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
}
}
-/*
- * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ).
- */
-void gl_depth_test_pixels_greater( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
+
+void gl_depth_test_pixels( GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLdepth z[], GLubyte mask[] )
{
- GLdepth *zptr;
- GLuint i;
-
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(ctx,x[i],y[i]);
- if (z[i] > *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
+ if (ctx->Driver.ReadDepthPixels) {
+ /* read depth values from hardware Z buffer */
+ GLdepth zbuffer[PB_SIZE];
+ (*ctx->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
+
+ hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
+
+ /* update hardware Z buffer with new values */
+ assert(ctx->Driver.WriteDepthPixels);
+ (*ctx->Driver.WriteDepthPixels)(ctx, n, x, y, z, mask );
+ }
+ else {
+ /* software depth testing */
+ software_depth_test_pixels(ctx, n, x, y, z, mask);
}
}
+
/**********************************************************************/
/***** Read Depth Buffer *****/
/**********************************************************************/
@@ -733,7 +913,7 @@ void gl_depth_test_pixels_greater( GLcontext* ctx,
/*
* Return a span of depth values from the depth buffer as floats in [0,1].
- * This function is only called through Driver.read_depth_span_float()
+ * 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
@@ -741,46 +921,29 @@ void gl_depth_test_pixels_greater( GLcontext* ctx,
void gl_read_depth_span_float( GLcontext* ctx,
GLuint n, GLint x, GLint y, GLfloat depth[] )
{
- GLdepth *zptr;
- GLfloat scale;
- GLuint i;
-
- scale = 1.0F / DEPTH_SCALE;
+ const GLfloat scale = 1.0F / DEPTH_SCALE;
if (ctx->DrawBuffer->Depth) {
- zptr = Z_ADDRESS( ctx, x, y );
- for (i=0;i<n;i++) {
+ /* read from software depth buffer */
+ const GLdepth *zptr = Z_ADDRESS( ctx, x, y );
+ GLuint i;
+ for (i = 0; i < n; i++) {
depth[i] = (GLfloat) zptr[i] * scale;
}
}
- else {
- for (i=0;i<n;i++) {
- depth[i] = 0.0F;
+ else if (ctx->Driver.ReadDepthSpan) {
+ /* read from hardware depth buffer */
+ GLdepth d[MAX_WIDTH];
+ GLuint i;
+ assert(n <= MAX_WIDTH);
+ (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, d );
+ for (i = 0; i < n; i++) {
+ depth[i] = d[i] * scale;
}
}
-}
-
-
-/*
- * Return a span of depth values from the depth buffer as integers in
- * [0,MAX_DEPTH].
- * This function is only called through Driver.read_depth_span_int()
- * Input: n - how many pixels
- * x,y - location of first pixel
- * Output: depth - the array of depth values
- */
-void gl_read_depth_span_int( GLcontext* ctx,
- GLuint n, GLint x, GLint y, GLdepth depth[] )
-{
- if (ctx->DrawBuffer->Depth) {
- GLdepth *zptr = Z_ADDRESS( ctx, x, y );
- MEMCPY( depth, zptr, n * sizeof(GLdepth) );
- }
else {
- GLuint i;
- for (i=0;i<n;i++) {
- depth[i] = 0;
- }
+ /* no depth buffer */
+ MEMSET(depth, 0, n * sizeof(GLfloat));
}
}
@@ -800,20 +963,22 @@ void gl_read_depth_span_int( GLcontext* ctx,
void gl_alloc_depth_buffer( GLcontext* ctx )
{
/* deallocate current depth buffer if present */
- if (ctx->DrawBuffer->Depth) {
- FREE(ctx->DrawBuffer->Depth);
- ctx->DrawBuffer->Depth = NULL;
- }
+ if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
+ if (ctx->DrawBuffer->Depth) {
+ FREE(ctx->DrawBuffer->Depth);
+ ctx->DrawBuffer->Depth = NULL;
+ }
- /* allocate new depth buffer, but don't initialize it */
- ctx->DrawBuffer->Depth = (GLdepth *) MALLOC( ctx->DrawBuffer->Width
- * ctx->DrawBuffer->Height
- * sizeof(GLdepth) );
- if (!ctx->DrawBuffer->Depth) {
- /* out of memory */
- ctx->Depth.Test = GL_FALSE;
- ctx->NewState |= NEW_RASTER_OPS;
- gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
+ /* allocate new depth buffer, but don't initialize it */
+ ctx->DrawBuffer->Depth = (GLdepth *) MALLOC( ctx->DrawBuffer->Width
+ * ctx->DrawBuffer->Height
+ * sizeof(GLdepth) );
+ if (!ctx->DrawBuffer->Depth) {
+ /* out of memory */
+ ctx->Depth.Test = GL_FALSE;
+ ctx->NewState |= NEW_RASTER_OPS;
+ gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
+ }
}
}
@@ -854,8 +1019,8 @@ void gl_clear_depth_buffer( GLcontext* ctx )
/* clear whole buffer */
if (sizeof(GLdepth)==2 && (clear_value&0xff)==(clear_value>>8)) {
/* lower and upper bytes of clear_value are same, use MEMSET */
- MEMSET( ctx->DrawBuffer->Depth, clear_value&0xff,
- 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height);
+ MEMSET( ctx->DrawBuffer->Depth, clear_value & 0xff,
+ 2*ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
}
else {
GLdepth *d = ctx->DrawBuffer->Depth;
@@ -879,6 +1044,3 @@ void gl_clear_depth_buffer( GLcontext* ctx )
}
}
}
-
-
-
diff --git a/src/mesa/main/depth.h b/src/mesa/main/depth.h
index c579e3d9fb9..f31909ad7be 100644
--- a/src/mesa/main/depth.h
+++ b/src/mesa/main/depth.h
@@ -1,4 +1,4 @@
-/* $Id: depth.h,v 1.4 1999/11/24 18:48:31 brianp Exp $ */
+/* $Id: depth.h,v 1.5 1999/12/10 19:09:22 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -33,69 +33,54 @@
/*
- * Return the address of the Z-buffer value for window coordinate (x,y):
+ * Immediate-mode API entrpoints
*/
-#define Z_ADDRESS( CTX, X, Y ) \
- ((CTX)->DrawBuffer->Depth + (CTX)->DrawBuffer->Width * (Y) + (X))
-
-
-
-
-extern GLuint
-gl_depth_test_span_generic( GLcontext* ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
-
-extern GLuint
-gl_depth_test_span_less( GLcontext* ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
-
-extern GLuint
-gl_depth_test_span_greater( GLcontext* ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
+extern void
+_mesa_ClearDepth( GLclampd depth );
extern void
-gl_depth_test_pixels_generic( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
+_mesa_DepthFunc( GLenum func );
-extern void
-gl_depth_test_pixels_less( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
extern void
-gl_depth_test_pixels_greater( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
+_mesa_DepthMask( GLboolean flag );
-extern void gl_read_depth_span_float( GLcontext* ctx,
- GLuint n, GLint x, GLint y,
- GLfloat depth[] );
-extern void gl_read_depth_span_int( GLcontext* ctx, GLuint n, GLint x, GLint y,
- GLdepth depth[] );
+/*
+ * Return the address of the Z-buffer value for window coordinate (x,y):
+ */
+#define Z_ADDRESS( CTX, X, Y ) \
+ ((CTX)->DrawBuffer->Depth + (CTX)->DrawBuffer->Width * (Y) + (X))
-extern void gl_alloc_depth_buffer( GLcontext* ctx );
-extern void gl_clear_depth_buffer( GLcontext* ctx );
+extern GLuint
+gl_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLdepth z[], GLubyte mask[] );
+extern void
+gl_depth_test_pixels( GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLdepth z[], GLubyte mask[] );
extern void
-_mesa_ClearDepth( GLclampd depth );
+gl_read_depth_span_float( GLcontext *ctx, GLuint n, GLint x, GLint y,
+ GLfloat depth[] );
+
extern void
-_mesa_DepthFunc( GLenum func );
+gl_alloc_depth_buffer( GLcontext* ctx );
extern void
-_mesa_DepthMask( GLboolean flag );
+gl_clear_depth_buffer( GLcontext* ctx );
+
#endif
diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c
index c4eb1ea442d..2f9ec8aa010 100644
--- a/src/mesa/main/stencil.c
+++ b/src/mesa/main/stencil.c
@@ -1,4 +1,4 @@
-/* $Id: stencil.c,v 1.12 1999/12/10 16:15:04 brianp Exp $ */
+/* $Id: stencil.c,v 1.13 1999/12/10 19:09:22 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -30,6 +30,7 @@
#else
#include "glheader.h"
#include "context.h"
+#include "depth.h"
#include "mem.h"
#include "pb.h"
#include "stencil.h"
@@ -579,8 +580,7 @@ stencil_and_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
MEMCPY(oldmask, mask, n * sizeof(GLubyte));
/* apply the depth test */
- if (ctx->Driver.DepthTestSpan)
- (*ctx->Driver.DepthTestSpan)( ctx, n, x, y, z, mask );
+ gl_depth_test_span(ctx, n, x, y, z, mask);
/* Set the stencil pass/fail flags according to result of depth testing.
* if oldmask[i] == 0 then
@@ -1059,8 +1059,7 @@ gl_stencil_and_depth_test_pixels( GLcontext *ctx,
MEMCPY(oldmask, mask, n * sizeof(GLubyte));
- if (ctx->Driver.DepthTestPixels)
- (*ctx->Driver.DepthTestPixels)( ctx, n, x, y, z, mask );
+ gl_depth_test_pixels(ctx, n, x, y, z, mask);
for (i=0;i<n;i++) {
ASSERT(mask[i] == 0 || mask[i] == 1);
@@ -1100,8 +1099,7 @@ gl_stencil_and_depth_test_pixels( GLcontext *ctx,
MEMCPY(oldmask, mask, n * sizeof(GLubyte));
- if (ctx->Driver.DepthTestPixels)
- (*ctx->Driver.DepthTestPixels)( ctx, n, x, y, z, mask );
+ gl_depth_test_pixels(ctx, n, x, y, z, mask);
for (i=0;i<n;i++) {
ASSERT(mask[i] == 0 || mask[i] == 1);