optimize drawing GL_DEPTH_STENCIL pixels into a GL_DEPTH_STENCIL renderbuffer

This commit is contained in:
Brian Paul
2005-11-17 05:00:17 +00:00
parent 5ba41dfa81
commit 74e9a43a2a
+97 -65
View File
@@ -607,7 +607,7 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
_mesa_image_address2d(unpack, pixels, width, height,
GL_DEPTH_COMPONENT, type, row, 0);
if (shift == 0) {
MEMCPY(span.array->z, zSrc, width * sizeof(GLuint));
_mesa_memcpy(span.array->z, zSrc, width * sizeof(GLuint));
}
else {
GLint col;
@@ -823,7 +823,14 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
}
/**
* This is a bit different from drawing GL_DEPTH_COMPONENT pixels.
* The only per-pixel operations that apply are depth scale/bias,
* stencil offset/shift, GL_DEPTH_WRITEMASK and GL_STENCIL_WRITEMASK,
* and pixel zoom.
* Also, only the depth buffer and stencil buffers are touched, not the
* color buffer(s).
*/
static void
draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height, GLenum type,
@@ -840,13 +847,6 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
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->_DepthBuffer;
stencilRb = ctx->DrawBuffer->_StencilBuffer;
ASSERT(depthRb);
ASSERT(stencilRb);
if (!zoom) {
if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
@@ -855,72 +855,104 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
return;
}
}
depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
ASSERT(depthRb);
ASSERT(stencilRb);
/* XXX need to handle very wide images (skippixels) */
if (depthRb->_BaseFormat == GL_DEPTH_STENCIL_EXT &&
stencilRb->_BaseFormat == GL_DEPTH_STENCIL_EXT &&
depthRb == stencilRb &&
!scaleOrBias &&
!zoom &&
ctx->Depth.Mask &&
(stencilMask & 0xff) == 0xff) {
/* This is the ideal case.
* Drawing GL_DEPTH_STENCIL pixels into a combined depth/stencil buffer.
* Plus, no pixel transfer ops, zooming, or masking needed.
*/
GLint i;
for (i = 0; i < height; i++) {
const GLuint *src = (const GLuint *)
_mesa_image_address2d(&clippedUnpack, pixels, width, height,
GL_DEPTH_STENCIL_EXT, type, i, 0);
depthRb->PutRow(ctx, depthRb, width, x, y + i, src, NULL);
}
}
else {
/* sub-optimal cases:
* Separate depth/stencil buffers, or pixel transfer ops required.
*/
/* XXX need to handle very wide images (skippixels) */
GLint i;
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);
depthRb = ctx->DrawBuffer->_DepthBuffer;
stencilRb = ctx->DrawBuffer->_StencilBuffer;
if (ctx->Depth.Mask) {
if (!scaleOrBias && ctx->DrawBuffer->Visual.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;
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 (!scaleOrBias && ctx->DrawBuffer->Visual.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)
_swrast_write_zoomed_z_span(ctx, imgX, imgY, width,
x, y + i, zValues);
else
depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL);
}
if (zoom)
_swrast_write_zoomed_z_span(ctx, imgX, imgY, width,
x, y + i, zValues);
else
depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL);
}
else if (!scaleOrBias && ctx->DrawBuffer->Visual.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)
_swrast_write_zoomed_z_span(ctx, imgX, imgY, width,
x, y + i, zValues);
else
depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL);
}
else {
/* general case */
GLuint zValues[MAX_WIDTH]; /* 16 or 32-bit Z value storage */
_mesa_unpack_depth_span(ctx, width,
depthRb->DataType, zValues, depthScale,
type, depthStencilSrc, &clippedUnpack);
if (zoom) {
_swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x,
y + i, zValues);
else if (!scaleOrBias && ctx->DrawBuffer->Visual.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)
_swrast_write_zoomed_z_span(ctx, imgX, imgY, width,
x, y + i, zValues);
else
depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL);
}
else {
depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL);
/* general case */
GLuint zValues[MAX_WIDTH]; /* 16 or 32-bit Z value storage */
_mesa_unpack_depth_span(ctx, width,
depthRb->DataType, zValues, depthScale,
type, depthStencilSrc, &clippedUnpack);
if (zoom) {
_swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x,
y + i, zValues);
}
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)
_swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width,
x, y + i, stencilValues);
else
_swrast_write_stencil_span(ctx, width, x, y + i, stencilValues);
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)
_swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width,
x, y + i, stencilValues);
else
_swrast_write_stencil_span(ctx, width, x, y + i, stencilValues);
}
}
}
}