/*
* Mesa 3-D graphics library
- * Version: 6.5.1
+ * Version: 7.2.1
*
- * Copyright (C) 1999-2006 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"),
*/
-#include "glheader.h"
-#include "context.h"
-#include "macros.h"
-#include "imports.h"
-#include "fbobject.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/formats.h"
+#include "main/macros.h"
+#include "main/imports.h"
#include "s_depth.h"
#include "s_context.h"
+/**
+ * Clamp fragment Z values to the depth near/far range (glDepthRange()).
+ * This is used when GL_ARB_depth_clamp/GL_DEPTH_CLAMP is turned on.
+ * In that case, vertexes are not clipped against the near/far planes
+ * so rasterization will produce fragment Z values outside the usual
+ * [0,1] range.
+ */
+void
+_swrast_depth_clamp_span( GLcontext *ctx, SWspan *span )
+{
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+ const GLuint count = span->end;
+ GLint *zValues = (GLint *) span->array->z; /* sign change */
+ GLint min, max;
+ GLfloat min_f, max_f;
+ GLuint i;
+
+ if (ctx->Viewport.Near < ctx->Viewport.Far) {
+ min_f = ctx->Viewport.Near;
+ max_f = ctx->Viewport.Far;
+ } else {
+ min_f = ctx->Viewport.Far;
+ max_f = ctx->Viewport.Near;
+ }
+
+ /* Convert floating point values in [0,1] to device Z coordinates in
+ * [0, DepthMax].
+ * ex: If the the Z buffer has 24 bits, DepthMax = 0xffffff.
+ *
+ * XXX this all falls apart if we have 31 or more bits of Z because
+ * the triangle rasterization code produces unsigned Z values. Negative
+ * vertex Z values come out as large fragment Z uints.
+ */
+ min = (GLint) (min_f * fb->_DepthMaxF);
+ max = (GLint) (max_f * fb->_DepthMaxF);
+ if (max < 0)
+ max = 0x7fffffff; /* catch over flow for 30-bit z */
+
+ /* Note that we do the comparisons here using signed integers.
+ */
+ for (i = 0; i < count; i++) {
+ if (zValues[i] < min)
+ zValues[i] = min;
+ if (zValues[i] > max)
+ zValues[i] = max;
+ }
+}
+
+
+
/*
* Apply depth test to span of fragments.
*/
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);
+ passed = depth_test_span16(ctx, count, zbuffer, zValues, mask);
+ rb->PutRow(ctx, rb, count, x, y, zbuffer, mask);
}
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);
+ passed = depth_test_span32(ctx, count, zbuffer, zValues, mask);
+ rb->PutRow(ctx, rb, count, x, y, zbuffer, mask);
}
}
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, NULL);
+ 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, NULL);
+ depth_test_span32(ctx, count, zbuffer, z, mask);
+ rb->PutValues(ctx, rb, count, x, y, zbuffer, mask);
}
}
if (!rb) {
/* really only doing this to prevent FP exceptions later */
_mesa_bzero(depth, n * sizeof(GLfloat));
+ return;
}
ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
_swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb,
GLint n, GLint x, GLint y, GLuint depth[] )
{
+ GLuint depthBits;
+
if (!rb) {
/* really only doing this to prevent FP exceptions later */
- _mesa_bzero(depth, n * sizeof(GLfloat));
+ _mesa_bzero(depth, n * sizeof(GLuint));
+ return;
}
+ depthBits = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS);
+
ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
if (y < 0 || y >= (GLint) rb->Height ||
if (rb->DataType == GL_UNSIGNED_INT) {
rb->GetRow(ctx, rb, n, x, y, depth);
- if (rb->DepthBits < 32) {
- GLuint shift = 32 - rb->DepthBits;
+ if (depthBits < 32) {
+ GLuint shift = 32 - depthBits;
GLint i;
for (i = 0; i < n; i++) {
GLuint z = depth[i];
GLushort temp[MAX_WIDTH];
GLint i;
rb->GetRow(ctx, rb, n, x, y, temp);
- if (rb->DepthBits == 16) {
+ if (depthBits == 16) {
for (i = 0; i < n; i++) {
GLuint z = temp[i];
depth[i] = (z << 16) | z;
}
}
else {
- GLuint shift = 16 - rb->DepthBits;
+ GLuint shift = 16 - depthBits;
for (i = 0; i < n; i++) {
GLuint z = temp[i];
depth[i] = (z << (shift + 16)) | (z << shift); /* XXX lsb bits? */
GLuint clearValue;
GLint x, y, width, height;
- if (!rb || !ctx->Depth.Mask || !rb->Data) {
+ if (!rb || !ctx->Depth.Mask) {
/* no depth buffer, or writing to it is disabled */
return;
}