/*
* Mesa 3-D graphics library
- * Version: 7.2.1
*
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
#include "main/macros.h"
#include "main/imports.h"
+#include "s_context.h"
#include "s_depth.h"
#include "s_span.h"
GLfloat min_f, max_f;
GLuint i;
- if (ctx->Viewport.Near < ctx->Viewport.Far) {
- min_f = ctx->Viewport.Near;
- max_f = ctx->Viewport.Far;
+ if (ctx->ViewportArray[0].Near < ctx->ViewportArray[0].Far) {
+ min_f = ctx->ViewportArray[0].Near;
+ max_f = ctx->ViewportArray[0].Far;
} else {
- min_f = ctx->Viewport.Far;
- max_f = ctx->Viewport.Near;
+ min_f = ctx->ViewportArray[0].Far;
+ max_f = ctx->ViewportArray[0].Near;
}
/* Convert floating point values in [0,1] to device Z coordinates in
}
-/**
- * Get array of 16-bit z values from the depth buffer. With clipping.
- */
-static void
-get_z16_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[],
- GLushort zbuffer[])
-{
- const GLint w = rb->Width, h = rb->Height;
- const GLubyte *map = (const GLubyte *) rb->Data;
- GLuint i;
-
- if (rb->Format == MESA_FORMAT_Z16) {
- const GLuint rowStride = rb->RowStride * 2;
- for (i = 0; i < count; i++) {
- if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
- zbuffer[i] = *((GLushort *) (map + y[i] * rowStride + x[i] * 2));
- }
- }
- }
- else {
- const GLuint bpp = _mesa_get_format_bytes(rb->Format);
- const GLuint rowStride = rb->RowStride * bpp;
- for (i = 0; i < count; i++) {
- if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
- GLuint d32;
- const GLubyte *src = map + y[i] * rowStride + x[i] * bpp;
- _mesa_unpack_uint_z_row(rb->Format, 1, src, &d32);
- zbuffer[i] = d32 >> 16;
- }
- }
- }
-}
-
-
/**
* Get array of 32-bit z values from the depth buffer. With clipping.
+ * Note: the returned values are always in the range [0, 2^32-1].
*/
static void
get_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
GLuint count, const GLint x[], const GLint y[],
GLuint zbuffer[])
{
+ struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
const GLint w = rb->Width, h = rb->Height;
- const GLubyte *map = (const GLubyte *) rb->Data;
+ const GLubyte *map = _swrast_pixel_address(rb, 0, 0);
GLuint i;
- if (rb->Format == MESA_FORMAT_Z32) {
- const GLint rowStride = rb->RowStride * 4;
+ if (rb->Format == MESA_FORMAT_Z_UNORM32) {
+ const GLint rowStride = srb->RowStride;
for (i = 0; i < count; i++) {
if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
zbuffer[i] = *((GLuint *) (map + y[i] * rowStride + x[i] * 4));
}
else {
const GLint bpp = _mesa_get_format_bytes(rb->Format);
- const GLint rowStride = rb->RowStride * bpp;
+ const GLint rowStride = srb->RowStride;
for (i = 0; i < count; i++) {
if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
const GLubyte *src = map + y[i] * rowStride+ x[i] * bpp;
}
}
+
+/**
+ * Put an array of 32-bit z values into the depth buffer.
+ * Note: the z values are always in the range [0, 2^32-1].
+ */
static void
put_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
GLuint count, const GLint x[], const GLint y[],
const GLuint zvalues[], const GLubyte mask[])
{
+ struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
const GLint w = rb->Width, h = rb->Height;
- GLubyte *map = (GLubyte *) rb->Data;
+ GLubyte *map = _swrast_pixel_address(rb, 0, 0);
GLuint i;
- if (rb->Format == MESA_FORMAT_Z32) {
- const GLuint rowStride = rb->RowStride * 4;
+ if (rb->Format == MESA_FORMAT_Z_UNORM32) {
+ const GLint rowStride = srb->RowStride;
for (i = 0; i < count; i++) {
if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
GLuint *dst = (GLuint *) (map + y[i] * rowStride + x[i] * 4);
else {
gl_pack_uint_z_func packZ = _mesa_get_pack_uint_z_func(rb->Format);
const GLint bpp = _mesa_get_format_bytes(rb->Format);
- const GLint rowStride = rb->RowStride * bpp;
+ const GLint rowStride = srb->RowStride;
for (i = 0; i < count; i++) {
if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
void *dst = map + y[i] * rowStride + x[i] * bpp;
}
-/**
- * Return the address of a Z value in a renderbuffer.
- */
-static INLINE void *
-get_z_address(struct gl_renderbuffer *rb, GLint x, GLint y)
-{
- const GLint bpp = _mesa_get_format_bytes(rb->Format);
- const GLint rowStride = rb->RowStride * bpp;
- return (GLubyte *) rb->Data + y * rowStride + x * bpp;
-}
-
-
-
/**
* Apply depth (Z) buffer testing to the span.
* \return approx number of pixels that passed (only zero is reliable)
struct gl_framebuffer *fb = ctx->DrawBuffer;
struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
const GLint bpp = _mesa_get_format_bytes(rb->Format);
- void *zStart = get_z_address(rb, span->x, span->y);
+ void *zStart;
const GLuint count = span->end;
const GLuint *fragZ = span->array->z;
GLubyte *mask = span->array->mask;
void *zBufferVals;
GLuint *zBufferTemp = NULL;
GLuint passed;
+ GLuint zBits = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS);
GLboolean ztest16 = GL_FALSE;
- GLboolean ztest24 = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS) == 24;
- if (rb->Format == MESA_FORMAT_Z16 && !(span->arrayMask & SPAN_XY)) {
+ if (span->arrayMask & SPAN_XY)
+ zStart = NULL;
+ else
+ zStart = _swrast_pixel_address(rb, span->x, span->y);
+
+ if (rb->Format == MESA_FORMAT_Z_UNORM16 && !(span->arrayMask & SPAN_XY)) {
/* directly read/write row of 16-bit Z values */
zBufferVals = zStart;
ztest16 = GL_TRUE;
}
- else if (rb->Format == MESA_FORMAT_Z32 && !(span->arrayMask & SPAN_XY)) {
+ else if (rb->Format == MESA_FORMAT_Z_UNORM32 && !(span->arrayMask & SPAN_XY)) {
/* directly read/write row of 32-bit Z values */
zBufferVals = zStart;
}
else {
+ if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED) {
+ _mesa_problem(ctx, "Incorrectly writing swrast's integer depth "
+ "values to %s depth buffer",
+ _mesa_get_format_name(rb->Format));
+ }
+
/* copy Z buffer values into temp buffer (32-bit Z values) */
- zBufferTemp = (GLuint *) malloc(count * sizeof(GLuint));
+ zBufferTemp = malloc(count * sizeof(GLuint));
if (!zBufferTemp)
return 0;
_mesa_unpack_uint_z_row(rb->Format, count, zStart, zBufferTemp);
}
- if (ztest24) {
+ if (zBits == 24) {
GLuint i;
/* Convert depth buffer values from 32 to 24 bits to match the
* fragment Z values generated by rasterization.
zBufferTemp[i] >>= 8;
}
}
+ else if (zBits == 16) {
+ GLuint i;
+ /* Convert depth buffer values from 32 to 16 bits */
+ for (i = 0; i < count; i++) {
+ zBufferTemp[i] >>= 16;
+ }
+ }
+ else {
+ assert(zBits == 32);
+ }
zBufferVals = zBufferTemp;
}
if (zBufferTemp) {
/* need to write temp Z values back into the buffer */
- if (ztest24) {
+ /* Convert depth buffer values back to 32-bit values. The least
+ * significant bits don't matter since they'll get dropped when
+ * they're packed back into the depth buffer.
+ */
+ if (zBits == 24) {
GLuint i;
- /* Convert depth buffer values back to 32-bit values. The least
- * significant bits don't matter since they'll get dropped when
- * they're packed back into the depth buffer.
- */
for (i = 0; i < count; i++) {
zBufferTemp[i] = (zBufferTemp[i] << 8);
}
}
+ else if (zBits == 16) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ zBufferTemp[i] = zBufferTemp[i] << 16;
+ }
+ }
if (span->arrayMask & SPAN_XY) {
/* random locations */
_swrast_depth_bounds_test( struct gl_context *ctx, SWspan *span )
{
struct gl_framebuffer *fb = ctx->DrawBuffer;
- struct gl_renderbuffer *rb = fb->_DepthBuffer;
+ struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ GLubyte *zStart;
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;
+ GLuint *zBufferTemp;
+ const GLuint *zBufferVals;
- if (rb->DataType == GL_UNSIGNED_SHORT) {
- /* get 16-bit values */
- GLushort zbuffer16[MAX_WIDTH], *zbuffer;
- if (span->arrayMask & SPAN_XY) {
- get_z16_values(ctx, rb, count, span->array->x, span->array->y,
- zbuffer16);
- zbuffer = zbuffer16;
- }
- else {
- zbuffer = (GLushort*) rb->GetPointer(ctx, rb, span->x, span->y);
- if (!zbuffer) {
- rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer16);
- zbuffer = zbuffer16;
- }
- }
- assert(zbuffer);
+ zBufferTemp = malloc(count * sizeof(GLuint));
+ if (!zBufferTemp) {
+ /* don't generate a stream of OUT_OF_MEMORY errors here */
+ return GL_FALSE;
+ }
- /* 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;
- }
- }
+ if (span->arrayMask & SPAN_XY)
+ zStart = NULL;
+ else
+ zStart = _swrast_pixel_address(rb, span->x, span->y);
+
+ if (rb->Format == MESA_FORMAT_Z_UNORM32 && !(span->arrayMask & SPAN_XY)) {
+ /* directly access 32-bit values in the depth buffer */
+ zBufferVals = (const GLuint *) zStart;
}
else {
- /* get 32-bit values */
- GLuint zbuffer32[MAX_WIDTH], *zbuffer;
- ASSERT(rb->DataType == GL_UNSIGNED_INT);
+ /* unpack Z values into a temporary array */
if (span->arrayMask & SPAN_XY) {
get_z32_values(ctx, rb, count, span->array->x, span->array->y,
- zbuffer32);
- zbuffer = zbuffer32;
+ zBufferTemp);
}
else {
- zbuffer = (GLuint*) rb->GetPointer(ctx, rb, span->x, span->y);
- if (!zbuffer) {
- rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer32);
- zbuffer = zbuffer32;
- }
+ _mesa_unpack_uint_z_row(rb->Format, count, zStart, zBufferTemp);
}
- assert(zbuffer);
+ zBufferVals = zBufferTemp;
+ }
- /* 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;
- }
+ /* Now do the tests */
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ if (zBufferVals[i] < zMin || zBufferVals[i] > zMax)
+ mask[i] = GL_FALSE;
+ else
+ anyPass = GL_TRUE;
}
}
+ free(zBufferTemp);
+
return anyPass;
}
* bounds.
*/
void
-_swrast_read_depth_span_float( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLint n, GLint x, GLint y, GLfloat depth[] )
+_swrast_read_depth_span_float(struct gl_context *ctx,
+ struct gl_renderbuffer *rb,
+ GLint n, GLint x, GLint y, GLfloat depth[])
{
- const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
-
if (!rb) {
/* really only doing this to prevent FP exceptions later */
memset(depth, 0, n * sizeof(GLfloat));
return;
}
- ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
-
if (y < 0 || y >= (GLint) rb->Height ||
x + n <= 0 || x >= (GLint) rb->Width) {
/* span is completely outside framebuffer */
return;
}
- if (rb->DataType == GL_UNSIGNED_INT) {
- GLuint temp[MAX_WIDTH];
- GLint i;
- rb->GetRow(ctx, rb, n, x, y, temp);
- for (i = 0; i < n; i++) {
- depth[i] = temp[i] * scale;
- }
- }
- else if (rb->DataType == GL_UNSIGNED_SHORT) {
- GLushort temp[MAX_WIDTH];
- GLint i;
- rb->GetRow(ctx, rb, n, x, y, temp);
- for (i = 0; i < n; i++) {
- depth[i] = temp[i] * scale;
- }
- }
- else {
- _mesa_problem(ctx, "Invalid depth renderbuffer data type");
- }
+ _mesa_unpack_float_z_row(rb->Format, n, _swrast_pixel_address(rb, x, y),
+ depth);
}
{
struct gl_renderbuffer *rb =
ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
- GLuint clearValue;
GLint x, y, width, height;
GLubyte *map;
GLint rowStride, i, j;
return;
}
- /* compute integer clearing value */
- if (ctx->Depth.Clear == 1.0) {
- clearValue = ctx->DrawBuffer->_DepthMax;
- }
- else {
- clearValue = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF);
- }
-
/* compute region to clear */
x = ctx->DrawBuffer->_Xmin;
y = ctx->DrawBuffer->_Ymin;
height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
mapMode = GL_MAP_WRITE_BIT;
- if (rb->Format == MESA_FORMAT_S8_Z24 ||
- rb->Format == MESA_FORMAT_X8_Z24 ||
- rb->Format == MESA_FORMAT_Z24_S8 ||
- rb->Format == MESA_FORMAT_Z24_X8) {
+ if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT ||
+ rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT ||
+ rb->Format == MESA_FORMAT_S8_UINT_Z24_UNORM ||
+ rb->Format == MESA_FORMAT_X8_UINT_Z24_UNORM) {
mapMode |= GL_MAP_READ_BIT;
}
}
switch (rb->Format) {
- case MESA_FORMAT_Z16:
+ case MESA_FORMAT_Z_UNORM16:
{
GLfloat clear = (GLfloat) ctx->Depth.Clear;
GLushort clearVal = 0;
}
}
break;
- case MESA_FORMAT_Z32:
- case MESA_FORMAT_Z32_FLOAT:
+ case MESA_FORMAT_Z_UNORM32:
+ case MESA_FORMAT_Z_FLOAT32:
{
GLfloat clear = (GLfloat) ctx->Depth.Clear;
GLuint clearVal = 0;
}
}
break;
- case MESA_FORMAT_S8_Z24:
- case MESA_FORMAT_X8_Z24:
- case MESA_FORMAT_Z24_S8:
- case MESA_FORMAT_Z24_X8:
+ case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_Z24_UNORM_X8_UINT:
+ case MESA_FORMAT_S8_UINT_Z24_UNORM:
+ case MESA_FORMAT_X8_UINT_Z24_UNORM:
{
GLfloat clear = (GLfloat) ctx->Depth.Clear;
GLuint clearVal = 0;
GLuint mask;
- if (rb->Format == MESA_FORMAT_S8_Z24 ||
- rb->Format == MESA_FORMAT_X8_Z24)
+ if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT ||
+ rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT)
mask = 0xff000000;
else
mask = 0xff;
}
break;
- case MESA_FORMAT_Z32_FLOAT_X24S8:
+ case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
/* XXX untested */
{
GLfloat clearVal = (GLfloat) ctx->Depth.Clear;
}
switch (rb->Format) {
- case MESA_FORMAT_S8_Z24:
- case MESA_FORMAT_Z24_S8:
+ case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_S8_UINT_Z24_UNORM:
{
GLfloat zClear = (GLfloat) ctx->Depth.Clear;
GLuint clear = 0, mask;
_mesa_pack_float_z_row(rb->Format, 1, &zClear, &clear);
- if (rb->Format == MESA_FORMAT_S8_Z24) {
+ if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT) {
mask = ((~writeMask) & 0xff) << 24;
clear |= (ctx->Stencil.Clear & writeMask & 0xff) << 24;
}
}
}
break;
- case MESA_FORMAT_Z32_FLOAT_X24S8:
+ case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
/* XXX untested */
{
const GLfloat zClear = (GLfloat) ctx->Depth.Clear;