glReadPixels done, glDrawPixels mostly done.
int dstY = y;
int w = width;
int h = height;
- int srcX = unpack->SkipPixels;
- int srcY = unpack->SkipRows;
- int rowLength = unpack->RowLength ? unpack->RowLength : width;
+ struct gl_pixelstore_attrib clippedUnpack = *unpack;
if (unpack->BufferObj->Name) {
/* unpack from PBO */
pixels = ADD_POINTERS(buf, pixels);
}
- if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) {
+ if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) {
/* This is a little tricky since all coordinates up to now have
* been in the OpenGL bottom-to-top orientation. X is top-to-bottom
* so we have to carefully compute the Y coordinates/addresses here.
*/
+ int srcX = clippedUnpack.SkipPixels;
+ int srcY = clippedUnpack.SkipRows;
+ int rowLength = clippedUnpack.RowLength;
XMesaImage ximage;
MEMSET(&ximage, 0, sizeof(XMesaImage));
ximage.width = width;
int dstY = y;
int w = width;
int h = height;
- int srcX = unpack->SkipPixels;
- int srcY = unpack->SkipRows;
- int rowLength = unpack->RowLength ? unpack->RowLength : width;
+ struct gl_pixelstore_attrib clippedUnpack = *unpack;
if (unpack->BufferObj->Name) {
/* unpack from PBO */
pixels = ADD_POINTERS(buf, pixels);
}
- if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) {
+ if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) {
/* This is a little tricky since all coordinates up to now have
* been in the OpenGL bottom-to-top orientation. X is top-to-bottom
* so we have to carefully compute the Y coordinates/addresses here.
*/
+ int srcX = clippedUnpack.SkipPixels;
+ int srcY = clippedUnpack.SkipRows;
+ int rowLength = clippedUnpack.RowLength;
XMesaImage ximage;
MEMSET(&ximage, 0, sizeof(XMesaImage));
ximage.width = width;
return GL_TRUE;
}
break;
+ case GL_DEPTH_STENCIL_EXT:
+ if (!ctx->Extensions.EXT_packed_depth_stencil ||
+ type != GL_UNSIGNED_INT_24_8_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "gl%sPixels(type)", readDraw);
+ return GL_TRUE;
+ }
+ if (ctx->DrawBuffer->Visual.depthBits == 0 ||
+ ctx->ReadBuffer->Visual.depthBits == 0 ||
+ ctx->DrawBuffer->Visual.stencilBits == 0 ||
+ ctx->ReadBuffer->Visual.stencilBits == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "gl%sPixels(no depth or stencil buffer)", readDraw);
+ return GL_TRUE;
+ }
+ break;
default:
/* this should have been caught in _mesa_is_legal_format_type() */
_mesa_problem(ctx, "unexpected format in _mesa_%sPixels", readDraw);
return GL_TRUE;
}
+ /* XXX might have to move this to the top of the function */
+ if (type == GL_UNSIGNED_INT_24_8_EXT && format != GL_DEPTH_STENCIL_EXT) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "gl%sPixels(format is not GL_DEPTH_STENCIL_EXT)", readDraw);
+ return GL_TRUE;
+ }
+
/* no errors */
return GL_FALSE;
}
return;
}
break;
+ case GL_DEPTH_STENCIL_EXT:
+ if (!ctx->Extensions.EXT_packed_depth_stencil) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels");
+ return;
+ }
+ if (ctx->DrawBuffer->Visual.depthBits == 0 ||
+ ctx->ReadBuffer->Visual.depthBits == 0 ||
+ ctx->DrawBuffer->Visual.stencilBits == 0 ||
+ ctx->ReadBuffer->Visual.stencilBits == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyPixels(no depth or stencil buffer)");
+ return;
+ }
+ break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels");
return;
{ OFF, "GL_EXT_fog_coord", F(EXT_fog_coord) },
{ OFF, "GL_EXT_histogram", F(EXT_histogram) },
{ OFF, "GL_EXT_multi_draw_arrays", F(EXT_multi_draw_arrays) },
+ { ON, "GL_EXT_packed_depth_stencil", F(EXT_packed_depth_stencil) },
{ ON, "GL_EXT_packed_pixels", F(EXT_packed_pixels) },
{ OFF, "GL_EXT_paletted_texture", F(EXT_paletted_texture) },
{ OFF, "GL_EXT_pixel_buffer_object", F(EXT_pixel_buffer_object) },
#endif
ctx->Extensions.EXT_histogram = GL_TRUE;
ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;
+ ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
ctx->Extensions.EXT_paletted_texture = GL_TRUE;
#if FEATURE_EXT_pixel_buffer_object
ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
*
}
}
else if (format == GL_DEPTH) {
- if (texImage->TexFormat->BaseFormat != GL_DEPTH_COMPONENT) {
+ if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
+ /* OK */
+ }
+ else if (ctx->Extensions.EXT_packed_depth_stencil &&
+ att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* OK */
+ }
+ else {
att->Complete = GL_FALSE;
return;
}
}
}
else if (format == GL_DEPTH) {
- if (att->Renderbuffer->_BaseFormat != GL_DEPTH_COMPONENT) {
+ if (att->Renderbuffer->_BaseFormat == GL_DEPTH_COMPONENT) {
+ /* OK */
+ }
+ else if (ctx->Extensions.EXT_packed_depth_stencil &&
+ att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* OK */
+ }
+ else {
att->Complete = GL_FALSE;
return;
}
}
else {
assert(format == GL_STENCIL);
- if (att->Renderbuffer->_BaseFormat != GL_STENCIL_INDEX) {
+ if (att->Renderbuffer->_BaseFormat == GL_STENCIL_INDEX) {
+ /* OK */
+ }
+ else if (ctx->Extensions.EXT_packed_depth_stencil &&
+ att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* OK */
+ }
+ else {
att->Complete = GL_FALSE;
return;
}
f = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->Format;
numImages++;
if (f != GL_RGB && f != GL_RGBA && f != GL_DEPTH_COMPONENT) {
+ /* XXX need GL_DEPTH_STENCIL_EXT test? */
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
return;
}
}
}
- /* Check if any renderbuffer is attached more than once */
+ /* Check if any renderbuffer is attached more than once.
+ * Note that there's one exception: a GL_DEPTH_STENCIL renderbuffer can be
+ * bound to both the stencil and depth attachment points at the same time.
+ */
for (i = 0; i < BUFFER_COUNT - 1; i++) {
struct gl_renderbuffer *rb_i = fb->Attachment[i].Renderbuffer;
if (rb_i) {
GLint j;
for (j = i + 1; j < BUFFER_COUNT; j++) {
struct gl_renderbuffer *rb_j = fb->Attachment[j].Renderbuffer;
- if (rb_i == rb_j) {
+ if (rb_i == rb_j && rb_i->_BaseFormat != GL_DEPTH_STENCIL_EXT) {
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT;
return;
}
* Given an internal format token for a render buffer, return the
* corresponding base format.
* \return one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT
- * or zero if error.
+ * GL_DEPTH_STENCIL_EXT or zero if error.
*/
static GLenum
base_internal_format(GLcontext *ctx, GLenum internalFormat)
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
return GL_DEPTH_COMPONENT;
+ case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH24_STENCIL8_EXT:
+ if (ctx->Extensions.EXT_packed_depth_stencil)
+ return GL_DEPTH_STENCIL_EXT;
+ else
+ return 0;
/* XXX add floating point formats eventually */
default:
return 0;
}
break;
case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
- if (ctx->CurrentRenderbuffer->_BaseFormat == GL_DEPTH_COMPONENT) {
+ if (ctx->CurrentRenderbuffer->_BaseFormat == GL_DEPTH_COMPONENT ||
+ ctx->CurrentRenderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
*params = ctx->CurrentRenderbuffer->DepthBits;
}
else {
}
break;
case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
- if (ctx->CurrentRenderbuffer->_BaseFormat == GL_STENCIL_INDEX) {
+ if (ctx->CurrentRenderbuffer->_BaseFormat == GL_STENCIL_INDEX ||
+ ctx->CurrentRenderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
*params = ctx->CurrentRenderbuffer->StencilBits;
}
else {
#include "glheader.h"
-#include "bufferobj.h"
#include "colormac.h"
#include "context.h"
#include "image.h"
#include "histogram.h"
#include "macros.h"
#include "pixel.h"
-#include "mtypes.h"
/** Compute ceiling of integer quotient of A divided by B. */
return sizeof(GLuint);
case GL_UNSIGNED_SHORT_8_8_MESA:
case GL_UNSIGNED_SHORT_8_8_REV_MESA:
- return sizeof(GLushort);
+ return sizeof(GLushort);
+ case GL_UNSIGNED_INT_24_8_EXT:
+ return sizeof(GLuint);
default:
return -1;
}
return 4;
case GL_YCBCR_MESA:
return 2;
+ case GL_DEPTH_STENCIL_EXT:
+ return 2;
default:
return -1;
}
return sizeof(GLushort);
else
return -1;
+ case GL_UNSIGNED_INT_24_8_EXT:
+ if (format == GL_DEPTH_STENCIL_EXT)
+ return sizeof(GLuint);
+ else
+ return -1;
default:
return -1;
}
return GL_TRUE;
else
return GL_FALSE;
+ case GL_DEPTH_STENCIL_EXT:
+ if (ctx->Extensions.EXT_packed_depth_stencil
+ && type == GL_UNSIGNED_INT_24_8_EXT)
+ return GL_TRUE;
+ else
+ return GL_FALSE;
default:
; /* fall-through */
}
srcType == GL_SHORT ||
srcType == GL_UNSIGNED_INT ||
srcType == GL_INT ||
+ srcType == GL_UNSIGNED_INT_24_8_EXT ||
srcType == GL_HALF_FLOAT_ARB ||
srcType == GL_FLOAT);
}
}
break;
+ case GL_UNSIGNED_INT_24_8_EXT:
+ {
+ GLuint i;
+ const GLuint *s = (const GLuint *) src;
+ if (unpack->SwapBytes) {
+ for (i = 0; i < n; i++) {
+ GLuint value = s[i];
+ SWAP4BYTE(value);
+ indexes[i] = value & 0xff; /* lower 8 bits */
+ }
+ }
+ else {
+ for (i = 0; i < n; i++)
+ indexes[i] = s[i] & 0xfff; /* lower 8 bits */
+ }
+ }
+ break;
+
default:
_mesa_problem(NULL, "bad srcType in extract_uint_indexes");
return;
srcType == GL_SHORT ||
srcType == GL_UNSIGNED_INT ||
srcType == GL_INT ||
+ srcType == GL_UNSIGNED_INT_24_8_EXT ||
srcType == GL_HALF_FLOAT_ARB ||
srcType == GL_FLOAT);
void
-_mesa_unpack_depth_span( const GLcontext *ctx, GLuint n, GLfloat *dest,
+_mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest, GLfloat depthScale,
GLenum srcType, const GLvoid *source,
const struct gl_pixelstore_attrib *srcPacking )
{
+ GLfloat depthTemp[MAX_WIDTH], *depthValues;
+
+ if (dstType == GL_FLOAT) {
+ depthValues = (GLfloat *) dest;
+ }
+ else {
+ depthValues = depthTemp;
+ }
+
(void) srcPacking;
switch (srcType) {
GLuint i;
const GLubyte *src = (const GLubyte *) source;
for (i = 0; i < n; i++) {
- dest[i] = BYTE_TO_FLOAT(src[i]);
+ depthValues[i] = BYTE_TO_FLOAT(src[i]);
}
}
break;
GLuint i;
const GLubyte *src = (const GLubyte *) source;
for (i = 0; i < n; i++) {
- dest[i] = UBYTE_TO_FLOAT(src[i]);
+ depthValues[i] = UBYTE_TO_FLOAT(src[i]);
}
}
break;
GLuint i;
const GLshort *src = (const GLshort *) source;
for (i = 0; i < n; i++) {
- dest[i] = SHORT_TO_FLOAT(src[i]);
+ depthValues[i] = SHORT_TO_FLOAT(src[i]);
}
}
break;
GLuint i;
const GLushort *src = (const GLushort *) source;
for (i = 0; i < n; i++) {
- dest[i] = USHORT_TO_FLOAT(src[i]);
+ depthValues[i] = USHORT_TO_FLOAT(src[i]);
}
}
break;
GLuint i;
const GLint *src = (const GLint *) source;
for (i = 0; i < n; i++) {
- dest[i] = INT_TO_FLOAT(src[i]);
+ depthValues[i] = INT_TO_FLOAT(src[i]);
}
}
break;
GLuint i;
const GLuint *src = (const GLuint *) source;
for (i = 0; i < n; i++) {
- dest[i] = UINT_TO_FLOAT(src[i]);
+ depthValues[i] = UINT_TO_FLOAT(src[i]);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */
+ if (dstType == GL_UNSIGNED_INT && ctx->Pixel.DepthScale == 1.0 &&
+ ctx->Pixel.DepthBias == 0.0 && depthScale == (GLfloat) 0xffffff) {
+ const GLuint *src = (const GLuint *) source;
+ GLuint *zValues = (GLuint *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ zValues[i] = src[i] & 0xffffff00;
+ }
+ return;
+ }
+ else {
+ const GLuint *src = (const GLuint *) source;
+ const GLfloat scale = 1.0f / 0xffffff;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ depthValues[i] = (src[i] >> 8) * scale;
}
}
break;
case GL_FLOAT:
- MEMCPY(dest, source, n * sizeof(GLfloat));
+ MEMCPY(depthValues, source, n * sizeof(GLfloat));
break;
case GL_HALF_FLOAT_ARB:
{
GLuint i;
const GLhalfARB *src = (const GLhalfARB *) source;
for (i = 0; i < n; i++) {
- dest[i] = _mesa_half_to_float(src[i]);
+ depthValues[i] = _mesa_half_to_float(src[i]);
}
}
break;
/* apply depth scale and bias and clamp to [0,1] */
if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
+ _mesa_scale_and_bias_depth(ctx, n, depthValues);
+ }
+
+ if (dstType == GL_UNSIGNED_INT) {
+ GLuint *zValues = (GLuint *) dest;
GLuint i;
for (i = 0; i < n; i++) {
- GLfloat d = dest[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
- dest[i] = CLAMP(d, 0.0F, 1.0F);
+ zValues[i] = (GLuint) (depthValues[i] * depthScale);
}
}
+ else if (dstType == GL_UNSIGNED_SHORT) {
+ GLushort *zValues = (GLushort *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ zValues[i] = (GLushort) (depthValues[i] * depthScale);
+ }
+ }
+ else {
+ ASSERT(dstType == GL_FLOAT);
+ ASSERT(depthScale == 1.0F);
+ }
}
const struct gl_pixelstore_attrib *dstPacking )
{
GLfloat depthCopy[MAX_WIDTH];
- const GLboolean bias_or_scale = ctx->Pixel.DepthBias != 0.0 ||
- ctx->Pixel.DepthScale != 1.0;
ASSERT(n <= MAX_WIDTH);
- if (bias_or_scale) {
- GLuint i;
- for (i = 0; i < n; i++) {
- GLfloat d;
- d = depthSpan[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
- depthCopy[i] = CLAMP(d, 0.0F, 1.0F);
- }
+ if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
+ _mesa_memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
+ _mesa_scale_and_bias_depth(ctx, n, depthCopy);
depthSpan = depthCopy;
}
/**
* Perform clipping for glDrawPixels. The image's window position
- * and size, and the unpack skipPixels and skipRows are adjusted so
+ * and size, and the unpack SkipPixels and SkipRows are adjusted so
* that the image region is entirely within the window and scissor bounds.
* NOTE: this will only work when glPixelZoom is (1, 1).
*
_mesa_clip_drawpixels(const GLcontext *ctx,
GLint *destX, GLint *destY,
GLsizei *width, GLsizei *height,
- GLint *skipPixels, GLint *skipRows)
+ struct gl_pixelstore_attrib *unpack)
{
const GLframebuffer *buffer = ctx->DrawBuffer;
+ if (unpack->RowLength == 0) {
+ unpack->RowLength = *width;
+ }
+
ASSERT(ctx->Pixel.ZoomX == 1.0F && ctx->Pixel.ZoomY == 1.0F);
/* left clipping */
if (*destX < buffer->_Xmin) {
- *skipPixels += (buffer->_Xmin - *destX);
+ unpack->SkipPixels += (buffer->_Xmin - *destX);
*width -= (buffer->_Xmin - *destX);
*destX = buffer->_Xmin;
}
/* bottom clipping */
if (*destY < buffer->_Ymin) {
- *skipRows += (buffer->_Ymin - *destY);
+ unpack->SkipRows += (buffer->_Ymin - *destY);
*height -= (buffer->_Ymin - *destY);
*destY = buffer->_Ymin;
}
/**
* Perform clipping for glReadPixels. The image's window position
- * and size, and the pack skipPixels and skipRows are adjusted so
- * that the image region is entirely within the window bounds.
+ * and size, and the pack skipPixels, skipRows and rowLength are adjusted
+ * so that the image region is entirely within the window bounds.
* Note: this is different from _mesa_clip_drawpixels() in that the
- * scissor box is ignored, and we use the bounds of the current "read"
- * surface;
+ * scissor box is ignored, and we use the bounds of the current readbuffer
+ * surface.
*
* \return GL_TRUE if image is ready for drawing or
* GL_FALSE if image was completely clipped away (draw nothing)
_mesa_clip_readpixels(const GLcontext *ctx,
GLint *srcX, GLint *srcY,
GLsizei *width, GLsizei *height,
- GLint *skipPixels, GLint *skipRows)
+ struct gl_pixelstore_attrib *pack)
{
const GLframebuffer *buffer = ctx->ReadBuffer;
+ if (pack->RowLength == 0) {
+ pack->RowLength = *width;
+ }
+
/* left clipping */
if (*srcX < 0) {
- *skipPixels += (0 - *srcX);
+ pack->SkipPixels += (0 - *srcX);
*width -= (0 - *srcX);
*srcX = 0;
}
/* bottom clipping */
if (*srcY < 0) {
- *skipRows += (0 - *srcY);
+ pack->SkipRows += (0 - *srcY);
*height -= (0 - *srcY);
*srcY = 0;
}
-/**
- * \file image.h
- * Image handling.
- */
-
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 1999-2004 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"),
extern void
-_mesa_unpack_depth_span( const GLcontext *ctx, GLuint n, GLfloat *dest,
+_mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest, GLfloat depthScale,
GLenum srcType, const GLvoid *source,
const struct gl_pixelstore_attrib *srcPacking );
_mesa_clip_drawpixels(const GLcontext *ctx,
GLint *destX, GLint *destY,
GLsizei *width, GLsizei *height,
- GLint *skipPixels, GLint *skipRows);
+ struct gl_pixelstore_attrib *unpack);
extern GLboolean
_mesa_clip_readpixels(const GLcontext *ctx,
GLint *destX, GLint *destY,
GLsizei *width, GLsizei *height,
- GLint *skipPixels, GLint *skipRows);
+ struct gl_pixelstore_attrib *pack);
#endif
GLubyte IntensityBits;
GLubyte IndexBits;
GLubyte DepthBits;
+ GLubyte StencilBits; /**< GL_EXT_packed_depth_stencil */
GLuint TexelBytes; /**< Bytes per texel, 0 if compressed format */
GLbitfield _ColorDrawBufferMask[MAX_DRAW_BUFFERS]; /* Mask of BUFFER_BIT_* flags */
GLint _ColorReadBufferIndex; /* -1 = None */
- /* These are computed from _Draw/ReadBufferMask, above. */
+ /* These are computed from _ColorDrawBufferMask and _ColorReadBufferIndex */
GLuint _NumColorDrawBuffers[MAX_DRAW_BUFFERS];
struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS][4];
struct gl_renderbuffer *_ColorReadBuffer;
GLboolean EXT_histogram;
GLboolean EXT_multi_draw_arrays;
GLboolean EXT_paletted_texture;
+ GLboolean EXT_packed_depth_stencil;
GLboolean EXT_packed_pixels;
GLboolean EXT_pixel_buffer_object;
GLboolean EXT_point_parameters;
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
0, /* TexelBytes */
texstore_rgb_fxt1, /* StoreTexImageFunc */
NULL, /*impossible*/ /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
0, /* TexelBytes */
texstore_rgba_fxt1, /* StoreTexImageFunc */
NULL, /*impossible*/ /* FetchTexel1D */
/*
* Mesa 3-D graphics library
- * Version: 6.1
+ * Version: 6.5
*
- * Copyright (C) 1999-2004 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"),
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
0, /* TexelBytes */
texstore_rgb_dxt1, /* StoreTexImageFunc */
NULL, /*impossible*/ /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
0, /* TexelBytes */
texstore_rgba_dxt1, /* StoreTexImageFunc */
NULL, /*impossible*/ /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
0, /* TexelBytes */
texstore_rgba_dxt3, /* StoreTexImageFunc */
NULL, /*impossible*/ /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
0, /* TexelBytes */
texstore_rgba_dxt5, /* StoreTexImageFunc */
NULL, /*impossible*/ /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
4 * sizeof(GLchan), /* TexelBytes */
_mesa_texstore_rgba, /* StoreTexImageFunc */
fetch_texel_1d_rgba, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
3 * sizeof(GLchan), /* TexelBytes */
_mesa_texstore_rgba,/*yes*/ /* StoreTexImageFunc */
fetch_texel_1d_rgb, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
sizeof(GLchan), /* TexelBytes */
_mesa_texstore_rgba,/*yes*/ /* StoreTexImageFunc */
fetch_texel_1d_alpha, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
sizeof(GLchan), /* TexelBytes */
_mesa_texstore_rgba,/*yes*/ /* StoreTexImageFunc */
fetch_texel_1d_luminance, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2 * sizeof(GLchan), /* TexelBytes */
_mesa_texstore_rgba,/*yes*/ /* StoreTexImageFunc */
fetch_texel_1d_luminance_alpha, /* FetchTexel1D */
CHAN_BITS, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
sizeof(GLchan), /* TexelBytes */
_mesa_texstore_rgba,/*yes*/ /* StoreTexImageFunc */
fetch_texel_1d_intensity, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
sizeof(GLfloat) * 8, /* DepthBits */
+ sizeof(GLfloat) * 8, /* StencilBits */
sizeof(GLfloat), /* TexelBytes */
_mesa_texstore_depth_component_float32,/* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
sizeof(GLushort) * 8, /* DepthBits */
+ sizeof(GLushort) * 8, /* StencilBits */
sizeof(GLushort), /* TexelBytes */
_mesa_texstore_depth_component16, /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
4 * sizeof(GLfloat), /* TexelBytes */
_mesa_texstore_rgba_float32, /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
4 * sizeof(GLhalfARB), /* TexelBytes */
_mesa_texstore_rgba_float16, /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
3 * sizeof(GLfloat), /* TexelBytes */
_mesa_texstore_rgba_float32,/*yes*/ /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
3 * sizeof(GLhalfARB), /* TexelBytes */
_mesa_texstore_rgba_float16,/*yes*/ /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1 * sizeof(GLfloat), /* TexelBytes */
_mesa_texstore_rgba_float32,/*yes*/ /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1 * sizeof(GLhalfARB), /* TexelBytes */
_mesa_texstore_rgba_float16,/*yes*/ /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1 * sizeof(GLfloat), /* TexelBytes */
_mesa_texstore_rgba_float32,/*yes*/ /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1 * sizeof(GLhalfARB), /* TexelBytes */
_mesa_texstore_rgba_float16,/*yes*/ /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2 * sizeof(GLfloat), /* TexelBytes */
_mesa_texstore_rgba_float32, /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2 * sizeof(GLhalfARB), /* TexelBytes */
_mesa_texstore_rgba_float16, /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
8 * sizeof(GLfloat), /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1 * sizeof(GLfloat), /* TexelBytes */
_mesa_texstore_rgba_float32,/*yes*/ /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
8 * sizeof(GLhalfARB), /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1 * sizeof(GLhalfARB), /* TexelBytes */
_mesa_texstore_rgba_float16,/*yes*/ /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
4, /* TexelBytes */
_mesa_texstore_rgba8888, /* StoreTexImageFunc */
fetch_texel_1d_rgba8888, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
4, /* TexelBytes */
_mesa_texstore_rgba8888, /* StoreTexImageFunc */
fetch_texel_1d_rgba8888_rev, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
4, /* TexelBytes */
_mesa_texstore_argb8888, /* StoreTexImageFunc */
fetch_texel_1d_argb8888, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
4, /* TexelBytes */
_mesa_texstore_argb8888, /* StoreTexImageFunc */
fetch_texel_1d_argb8888_rev, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
3, /* TexelBytes */
_mesa_texstore_rgb888, /* StoreTexImageFunc */
fetch_texel_1d_rgb888, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
3, /* TexelBytes */
_mesa_texstore_bgr888, /* StoreTexImageFunc */
fetch_texel_1d_bgr888, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_rgb565, /* StoreTexImageFunc */
fetch_texel_1d_rgb565, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_rgb565, /* StoreTexImageFunc */
fetch_texel_1d_rgb565_rev, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_argb4444, /* StoreTexImageFunc */
fetch_texel_1d_argb4444, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_argb4444, /* StoreTexImageFunc */
fetch_texel_1d_argb4444_rev, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_argb1555, /* StoreTexImageFunc */
fetch_texel_1d_argb1555, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_argb1555, /* StoreTexImageFunc */
fetch_texel_1d_argb1555_rev, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_al88, /* StoreTexImageFunc */
fetch_texel_1d_al88, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_al88, /* StoreTexImageFunc */
fetch_texel_1d_al88_rev, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1, /* TexelBytes */
_mesa_texstore_rgb332, /* StoreTexImageFunc */
fetch_texel_1d_rgb332, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1, /* TexelBytes */
_mesa_texstore_a8, /* StoreTexImageFunc */
fetch_texel_1d_a8, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1, /* TexelBytes */
_mesa_texstore_a8,/*yes*/ /* StoreTexImageFunc */
fetch_texel_1d_l8, /* FetchTexel1D */
8, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1, /* TexelBytes */
_mesa_texstore_a8,/*yes*/ /* StoreTexImageFunc */
fetch_texel_1d_i8, /* FetchTexel1D */
0, /* IntensityBits */
8, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
1, /* TexelBytes */
_mesa_texstore_ci8, /* StoreTexImageFunc */
fetch_texel_1d_ci8, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_ycbcr, /* StoreTexImageFunc */
fetch_texel_1d_ycbcr, /* FetchTexel1D */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_ycbcr, /* StoreTexImageFunc */
fetch_texel_1d_ycbcr_rev, /* FetchTexel1D */
store_texel_ycbcr_rev /* StoreTexel */
};
+const struct gl_texture_format _mesa_texformat_z24_s8 = {
+ MESA_FORMAT_Z24_S8, /* MesaFormat */
+ GL_DEPTH_STENCIL_EXT, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 24, /* DepthBits */
+ 8, /* StencilBits */
+ 4, /* TexelBytes */
+ NULL/*_mesa_texstore_z24_s8*/, /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel2D */
+ NULL, /* FetchTexel3D */
+ fetch_texel_1d_f_z24_s8, /* FetchTexel1Df */
+ fetch_texel_2d_f_z24_s8, /* FetchTexel2Df */
+ fetch_texel_3d_f_z24_s8, /* FetchTexel3Df */
+ store_texel_z24_s8 /* StoreTexel */
+};
+
/*@}*/
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
+ 0, /* StencilBits */
0, /* TexelBytes */
NULL, /* StoreTexImageFunc */
fetch_null_texel, /* FetchTexel1D */
}
}
+ if (ctx->Extensions.EXT_packed_depth_stencil) {
+ switch (internalFormat) {
+ case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH24_STENCIL8_EXT:
+ return &_mesa_texformat_z24_s8;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
_mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
return NULL;
}
MESA_FORMAT_CI8, /* CCCC CCCC */
MESA_FORMAT_YCBCR, /* YYYY YYYY UorV UorV */
MESA_FORMAT_YCBCR_REV, /* UorV UorV YYYY YYYY */
+ MESA_FORMAT_Z24_S8, /* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ SSSS SSSS */
/*@}*/
/**
extern const struct gl_texture_format _mesa_texformat_l8;
extern const struct gl_texture_format _mesa_texformat_i8;
extern const struct gl_texture_format _mesa_texformat_ci8;
-
+extern const struct gl_texture_format _mesa_texformat_z24_s8;
/*@}*/
/** \name YCbCr formats */
#endif
+/* MESA_TEXFORMAT_Z24_S8 ***************************************************/
+
+static void FETCH(f_z24_s8)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ /* only return Z, not stencil data */
+ const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ const GLfloat scale = 0xffffff;
+ texel[0] = *src * scale;
+}
+
+#if DIM == 3
+static void store_texel_z24_s8(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ /* only store Z, not stencil */
+ GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ GLfloat z = *((GLfloat *) texel);
+ GLuint zi = ((GLuint) (z * 0xffffff)) << 8;
+ *dst = zi | (*dst & 0xff);
+}
+#endif
+
+
#undef TEXEL_ADDR
#undef DIM
}
}
+ if (ctx->Extensions.EXT_packed_depth_stencil) {
+ switch (internalFormat) {
+ case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH24_STENCIL8_EXT:
+ return GL_DEPTH_STENCIL_EXT;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
return -1; /* error */
}
}
+/**
+ * Test if the given image format is a Depth/Stencil format.
+ */
+static GLboolean
+is_depthstencil_format(GLenum format)
+{
+ switch (format) {
+ case GL_DEPTH24_STENCIL8_EXT:
+ case GL_DEPTH_STENCIL_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+
/**
* Test if it is a supported compressed format.
*
if ((is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
(is_index_format(internalFormat) && !indexFormat) ||
(is_depth_format(internalFormat) != is_depth_format(format)) ||
- (is_ycbcr_format(internalFormat) != is_ycbcr_format(format))) {
+ (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) ||
+ (is_depthstencil_format(internalFormat) != is_depthstencil_format(format))) {
if (!isProxy)
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTexImage(internalFormat/format)");
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
}
+ if (!ctx->Extensions.EXT_packed_depth_stencil
+ && is_depthstencil_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ }
+
if (!pixels)
return;
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return;
}
+ else if (is_depthstencil_format(format)
+ && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return;
+ }
/* typically, this will call _mesa_get_teximage() */
ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetTexLevelParameter[if]v(pname)");
return;
+ case GL_TEXTURE_STENCIL_SIZE_EXT:
+ if (ctx->Extensions.EXT_packed_depth_stencil) {
+ *params = img->TexFormat->StencilBits;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
/* GL_ARB_texture_compression */
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
"glGetTexLevelParameter[if]v(pname)");
}
return;
+
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetTexLevelParameter[if]v(pname)");
for (row = 0; row < srcHeight; row++) {
const GLvoid *src = _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
- _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) dstRow,
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_FLOAT, (GLfloat *) dstRow, 1.0F,
srcType, src, srcPacking);
dstRow += dstRowStride;
}
+ dstZoffset * dstImageStride
+ dstYoffset * dstRowStride
+ dstXoffset * dstFormat->TexelBytes;
- GLint img, row, col;
+ GLint img, row;
for (img = 0; img < srcDepth; img++) {
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
- GLfloat depthTemp[MAX_WIDTH];
const GLvoid *src = _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
GLushort *dst16 = (GLushort *) dstRow;
- _mesa_unpack_depth_span(ctx, srcWidth, depthTemp,
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_UNSIGNED_SHORT, dst16, 65535.0F,
srcType, src, srcPacking);
- for (col = 0; col < srcWidth; col++) {
- dst16[col] = (GLushort) (depthTemp[col] * 65535.0F);
- }
dstRow += dstRowStride;
}
dstImage += dstImageStride;
_mesa_swap2((GLushort *) dest, width);
}
}
+ else if (format == GL_DEPTH_STENCIL_EXT) {
+ /* XXX special case */
+
+ }
else {
/* general case: convert row to RGBA format */
GLfloat rgba[MAX_WIDTH][4];
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
*
extern GLboolean _mesa_texstore_a8(STORE_PARAMS);
extern GLboolean _mesa_texstore_ci8(STORE_PARAMS);
extern GLboolean _mesa_texstore_ycbcr(STORE_PARAMS);
+extern GLboolean _mesa_texstore_z24_s8(STORE_PARAMS);
extern GLboolean _mesa_texstore_rgba_float32(STORE_PARAMS);
extern GLboolean _mesa_texstore_rgba_float16(STORE_PARAMS);
extern GLboolean _mesa_texstore_rgb_fxt1(STORE_PARAMS);
}
+static void
+copy_depth_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
+ GLint width, GLint height, GLint destx, GLint desty)
+{
+
+
+
+}
+
+
/**
* Do software-based glCopyPixels.
* By time we get here, all parameters will have been error-checked.
case GL_STENCIL:
copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty );
break;
+ case GL_DEPTH_STENCIL_EXT:
+ copy_depth_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty);
+ break;
default:
_mesa_problem(ctx, "unexpected type in _swrast_CopyPixels");
}
? MAX_WIDTH : (width - skipPixels);
ASSERT(span.end <= MAX_WIDTH);
for (row = 0; row < height; row++, spanY++) {
- GLfloat floatSpan[MAX_WIDTH];
const GLvoid *zSrc = _mesa_image_address2d(unpack,
pixels, width, height,
GL_DEPTH_COMPONENT, type,
span.y = spanY;
span.end = spanEnd;
- _mesa_unpack_depth_span(ctx, span.end, floatSpan, type,
- zSrc, unpack);
- /* clamp depth values to [0,1] and convert from floats to ints */
- {
- GLuint i;
- for (i = 0; i < span.end; i++) {
- span.array->z[i] = (GLuint) (floatSpan[i] * depthMax);
- }
- }
+ _mesa_unpack_depth_span(ctx, span.end,
+ GL_UNSIGNED_INT, span.array->z, depthMax,
+ type, zSrc, unpack);
if (zoom) {
_swrast_write_zoomed_depth_span(ctx, &span, desty, skipPixels);
}
}
+
+static void
+draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels)
+{
+ const GLfloat depthScale = ctx->DrawBuffer->_DepthMaxF;
+ const GLuint stencilMask = ctx->Stencil.WriteMask[0];
+ const GLuint stencilType = (STENCIL_BITS == 8) ?
+ GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
+ const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
+ struct gl_renderbuffer *depthRb, *stencilRb;
+ struct gl_pixelstore_attrib clippedUnpack = *unpack;
+ GLint i;
+
+ depthRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+ stencilRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
+
+ ASSERT(depthRb);
+ ASSERT(stencilRb);
+
+ if (!zoom) {
+ if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
+ &clippedUnpack)) {
+ /* totally clipped */
+ return;
+ }
+ }
+
+ /* XXX need to do pixelzoom! */
+
+ for (i = 0; i < height; i++) {
+ const GLuint *depthStencilSrc = (const GLuint *)
+ _mesa_image_address2d(&clippedUnpack, pixels, width, height,
+ GL_DEPTH_STENCIL_EXT, type, i, 0);
+
+ if (ctx->Depth.Mask) {
+ if (ctx->Pixel.DepthScale == 1.0F && ctx->Pixel.DepthBias == 0.0F
+ && depthRb->DepthBits == 24) {
+ /* fast path 24-bit zbuffer */
+ GLuint zValues[MAX_WIDTH];
+ GLint j;
+ ASSERT(depthRb->DataType == GL_UNSIGNED_INT);
+ for (j = 0; j < width; j++) {
+ zValues[j] = depthStencilSrc[j] >> 8;
+ }
+ if (zoom)
+ ;
+ else
+ depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL);
+ }
+ else if (ctx->Pixel.DepthScale == 1.0F && ctx->Pixel.DepthBias == 0.0F
+ && depthRb->DepthBits == 16) {
+ /* fast path 16-bit zbuffer */
+ GLushort zValues[MAX_WIDTH];
+ GLint j;
+ ASSERT(depthRb->DataType == GL_UNSIGNED_SHORT);
+ for (j = 0; j < width; j++) {
+ zValues[j] = depthStencilSrc[j] >> 16;
+ }
+ if (zoom)
+ ;
+ else
+ depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL);
+ }
+ else {
+ /* general case */
+ GLuint zValues[MAX_WIDTH];
+ _mesa_unpack_depth_span(ctx, width,
+ depthRb->DataType, zValues, depthScale,
+ type, depthStencilSrc, &clippedUnpack);
+ if (zoom)
+ ;
+ else
+ depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL);
+ }
+ }
+
+ if (stencilMask != 0x0) {
+ GLstencil stencilValues[MAX_WIDTH];
+ /* get stencil values, with shift/offset/mapping */
+ _mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues,
+ type, depthStencilSrc, &clippedUnpack,
+ ctx->_ImageTransferState);
+ if (zoom)
+ ;
+ else
+ _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues);
+ }
+
+ }
+}
+
+
+
/**
* Execute software-based glDrawPixels.
* By time we get here, all error checking will have been done.
case GL_ABGR_EXT:
draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels);
break;
+ case GL_DEPTH_STENCIL_EXT:
+ draw_depth_stencil_pixels(ctx, x, y, width, height,
+ type, unpack, pixels);
+ break;
default:
_mesa_problem(ctx, "unexpected format in _swrast_DrawPixels");
/* don't return yet, clean-up */
bias_or_scale = ctx->Pixel.DepthBias != 0.0 || ctx->Pixel.DepthScale != 1.0;
- if (type == GL_UNSIGNED_SHORT && fb->Visual.depthBits == 16
+ if (type == GL_UNSIGNED_SHORT && rb->DepthBits == 16
&& !bias_or_scale && !packing->SwapBytes) {
/* Special case: directly read 16-bit unsigned depth values. */
GLint j;
rb->GetRow(ctx, rb, width, x, y, dest);
}
}
- else if (type == GL_UNSIGNED_INT && fb->Visual.depthBits == 32
+ else if (type == GL_UNSIGNED_INT && rb->DepthBits == 24
+ && !bias_or_scale && !packing->SwapBytes) {
+ /* Special case: directly read 24-bit unsigned depth values. */
+ GLint j;
+ ASSERT(rb->InternalFormat == GL_DEPTH_COMPONENT32);
+ ASSERT(rb->DataType == GL_UNSIGNED_INT);
+ for (j = 0; j < height; j++, y++) {
+ GLuint *dest = (GLuint *)
+ _mesa_image_address2d(packing, pixels, width, height,
+ GL_DEPTH_COMPONENT, type, j, 0);
+ GLint k;
+ rb->GetRow(ctx, rb, width, x, y, dest);
+ /* convert range from 24-bit to 32-bit */
+ for (k = 0; k < width; k++) {
+ dest[k] = (dest[k] << 8) | (dest[k] >> 24);
+ }
+ }
+ }
+ else if (type == GL_UNSIGNED_INT && rb->DepthBits == 32
&& !bias_or_scale && !packing->SwapBytes) {
/* Special case: directly read 32-bit unsigned depth values. */
GLint j;
}
+/**
+ * Read combined depth/stencil values.
+ * We'll have already done error checking to be sure the expected
+ * depth and stencil buffers really exist.
+ */
+static void
+read_depth_stencil_pixels(GLcontext *ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum type, GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing )
+{
+ struct gl_renderbuffer *depthRb, *stencilRb;
+ GLint i;
+
+ depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+ stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
+
+ ASSERT(depthRb);
+ ASSERT(stencilRb);
+
+ for (i = 0; i < height; i++) {
+ GLuint zVals[MAX_WIDTH]; /* 24-bit values! */
+ GLstencil stencilVals[MAX_WIDTH];
+ GLint j;
+
+ GLuint *depthStencilDst = (GLuint *)
+ _mesa_image_address2d(packing, pixels, width, height,
+ GL_DEPTH_STENCIL_EXT, type, i, 0);
+
+ /* get depth values */
+ if (ctx->Pixel.DepthScale == 1.0
+ && ctx->Pixel.DepthBias == 0.0
+ && depthRb->DepthBits == 24) {
+ /* ideal case */
+ ASSERT(depthRb->DataType == GL_UNSIGNED_INT);
+ /* note, we've already been clipped */
+ depthRb->GetRow(ctx, depthRb, width, x, y + i, zVals);
+ }
+ else {
+ /* general case */
+ GLfloat depthVals[MAX_WIDTH];
+ _swrast_read_depth_span_float(ctx, depthRb, width, x, y + i,
+ depthVals);
+ if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
+ _mesa_scale_and_bias_depth(ctx, width, depthVals);
+ }
+ /* convert to 24-bit GLuints */
+ for (j = 0; j < width; j++) {
+ zVals[j] = FLOAT_TO_UINT(depthVals[j]) >> 8;
+ }
+ }
+
+ /* get stencil values */
+ _swrast_read_stencil_span(ctx, stencilRb, width, x, y + i, stencilVals);
+ if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) {
+ _mesa_shift_and_offset_stencil(ctx, width, stencilVals);
+ }
+ if (ctx->Pixel.MapStencilFlag) {
+ _mesa_map_stencil(ctx, width, stencilVals);
+ }
+
+ for (j = 0; j < width; j++) {
+ /* build combined Z/stencil values */
+ depthStencilDst[j] = (zVals[j] << 8) | (stencilVals[j] & 0xff);
+ }
+ }
+}
+
+
+
/**
* Software fallback routine for ctx->Driver.ReadPixels().
* By time we get here, all error checking will have been done.
GLvoid *pixels )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- struct gl_pixelstore_attrib clippedPacking;
+ struct gl_pixelstore_attrib clippedPacking = *packing;
if (swrast->NewState)
_swrast_validate_derived( ctx );
/* Do all needed clipping here, so that we can forget about it later */
- clippedPacking = *packing;
- if (clippedPacking.RowLength == 0) {
- clippedPacking.RowLength = width;
- }
- if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height,
- &clippedPacking.SkipPixels,
- &clippedPacking.SkipRows)) {
+ if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
/* The ReadPixels region is totally outside the window bounds */
return;
}
read_rgba_pixels(ctx, x, y, width, height,
format, type, pixels, &clippedPacking);
break;
+ case GL_DEPTH_STENCIL_EXT:
+ read_depth_stencil_pixels(ctx, x, y, width, height,
+ type, pixels, &clippedPacking);
+ break;
default:
_mesa_problem(ctx, "unexpected format in _swrast_ReadPixels");
/* don't return yet, clean-up */
zoomed.interpMask = span->interpMask & ~SPAN_INDEX;
zoomed.arrayMask |= SPAN_INDEX;
}
- else {
- assert(format == GL_DEPTH_COMPONENT);
+ else if (format == GL_DEPTH_COMPONENT) {
/* Copy color info */
zoomed.red = span->red;
zoomed.green = span->green;
zoomed.interpMask = span->interpMask & ~SPAN_Z;
zoomed.arrayMask |= SPAN_Z;
}
+ else if (format == GL_DEPTH_COMPONENT16 ||
+ format == GL_DEPTH_COMPONENT32) {
+ /* writing Z values directly to depth buffer, bypassing fragment ops */
+ }
+ else {
+ _mesa_problem(ctx, "Bad format in zoom_span");
+ return;
+ }
/*
* Compute which columns to draw: [c0, c1)
}
}
}
- else {
+ else if (format == GL_DEPTH_COMPONENT) {
const GLuint *zValues = (const GLuint *) src;
- assert(format == GL_DEPTH_COMPONENT);
if (ctx->Pixel.ZoomX == -1.0F) {
/* common case */
for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
else
format = GL_COLOR_INDEX;
}
-
+ else if (format == GL_DEPTH_COMPONENT32) {
+ /* 32-bit Z values */
+ struct gl_renderbuffer *rb
+ = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+ const GLuint *zSrc32 = (const GLuint *) src;
+ GLuint zDst32[MAX_WIDTH];
+ const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
+ for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
+ i = (GLint) ((j + skipCol) * xscale);
+ if (ctx->Pixel.ZoomX < 0.0) {
+ ASSERT(i <= 0);
+ i = span->end + i - 1;
+ }
+ ASSERT(i >= 0);
+ ASSERT(i < (GLint) span->end);
+ zDst32[j] = zSrc32[i];
+ }
+ rb->PutRow(ctx, rb, zoomed.end, zoomed.x, zoomed.y, zDst32, NULL);
+ return;
+ }
/* write the span in rows [r0, r1) */
if (format == GL_RGBA || format == GL_RGB) {