/* * Mesa 3-D graphics library * Version: 6.5 * * Copyright (C) 1999-2006 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"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * 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. */ #include "main/glheader.h" #include "main/imports.h" #include "main/context.h" #include "main/formats.h" #include "main/mtypes.h" #include "main/renderbuffer.h" #include "swrast/s_depthstencil.h" /** * Adaptor/wrappers for GL_DEPTH_STENCIL renderbuffers. * * The problem with a GL_DEPTH_STENCIL renderbuffer is that sometimes we * want to treat it as a stencil buffer, other times we want to treat it * as a depth/z buffer and still other times when we want to treat it as * a combined Z+stencil buffer! That implies we need three different sets * of Get/Put functions. * * We solve this by wrapping the Z24_S8 or S8_Z24 renderbuffer with depth and * stencil adaptors, each with the right kind of depth/stencil Get/Put functions. */ static void * nop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y) { (void) ctx; (void) rb; (void) x; (void) y; return NULL; } /** * Delete a depth or stencil wrapper renderbuffer. */ static void delete_wrapper(struct gl_renderbuffer *rb) { ASSERT(rb->Format == MESA_FORMAT_S8 || rb->Format == MESA_FORMAT_X8_Z24 || rb->Format == MESA_FORMAT_Z32_FLOAT); _mesa_reference_renderbuffer(&rb->Wrapped, NULL); free(rb); } /** * Realloc storage for wrapper. */ static GLboolean alloc_wrapper_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { /* just pass this on to the wrapped renderbuffer */ struct gl_renderbuffer *dsrb = rb->Wrapped; GLboolean retVal; (void) internalFormat; ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 || dsrb->Format == MESA_FORMAT_Z24_X8 || dsrb->Format == MESA_FORMAT_S8_Z24 || dsrb->Format == MESA_FORMAT_X8_Z24); retVal = dsrb->AllocStorage(ctx, dsrb, dsrb->InternalFormat, width, height); if (retVal) { rb->Width = width; rb->Height = height; rb->RowStride = dsrb->RowStride; } return retVal; } /*====================================================================== * Depth wrapper around depth/stencil renderbuffer */ static void get_row_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count, GLint x, GLint y, void *values) { struct gl_renderbuffer *dsrb = z24rb->Wrapped; GLuint temp[MAX_WIDTH], i; GLuint *dst = (GLuint *) values; const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y); ASSERT(z24rb->DataType == GL_UNSIGNED_INT); ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT); if (!src) { dsrb->GetRow(ctx, dsrb, count, x, y, temp); src = temp; } if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { dst[i] = src[i] >> 8; } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { dst[i] = src[i] & 0xffffff; } } } static void get_values_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count, const GLint x[], const GLint y[], void *values) { struct gl_renderbuffer *dsrb = z24rb->Wrapped; GLuint temp[MAX_WIDTH], i; GLuint *dst = (GLuint *) values; ASSERT(z24rb->DataType == GL_UNSIGNED_INT); ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT); ASSERT(count <= MAX_WIDTH); /* don't bother trying direct access */ dsrb->GetValues(ctx, dsrb, count, x, y, temp); if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { dst[i] = temp[i] >> 8; } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { dst[i] = temp[i] & 0xffffff; } } } static void put_row_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count, GLint x, GLint y, const void *values, const GLubyte *mask) { struct gl_renderbuffer *dsrb = z24rb->Wrapped; const GLuint *src = (const GLuint *) values; GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y); ASSERT(z24rb->DataType == GL_UNSIGNED_INT); ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT); if (dst) { /* direct access */ GLuint i; if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { dst[i] = (src[i] << 8) | (dst[i] & 0xff); } } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { if (!mask || mask[i]) { dst[i] = (src[i] & 0xffffff) | (dst[i] & 0xff000000); } } } } else { /* get, modify, put */ GLuint temp[MAX_WIDTH], i; dsrb->GetRow(ctx, dsrb, count, x, y, temp); if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i] = (src[i] << 8) | (temp[i] & 0xff); } } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i] = (src[i] & 0xffffff) | (temp[i] & 0xff000000); } } } dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask); } } static void put_values_z24(struct gl_context *ctx, struct gl_renderbuffer *z24rb, GLuint count, const GLint x[], const GLint y[], const void *values, const GLubyte *mask) { struct gl_renderbuffer *dsrb = z24rb->Wrapped; const GLuint *src = (const GLuint *) values; ASSERT(z24rb->DataType == GL_UNSIGNED_INT); ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT); if (dsrb->GetPointer(ctx, dsrb, 0, 0)) { /* direct access */ GLuint i; if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]); *dst = (src[i] << 8) | (*dst & 0xff); } } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { if (!mask || mask[i]) { GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]); *dst = (src[i] & 0xffffff) | (*dst & 0xff000000); } } } } else { /* get, modify, put */ GLuint temp[MAX_WIDTH], i; dsrb->GetValues(ctx, dsrb, count, x, y, temp); if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i] = (src[i] << 8) | (temp[i] & 0xff); } } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i] = (src[i] & 0xffffff) | (temp[i] & 0xff000000); } } } dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask); } } /** * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like * a depth renderbuffer. * \return new depth renderbuffer */ static struct gl_renderbuffer * new_z24_renderbuffer_wrapper(struct gl_context *ctx, struct gl_renderbuffer *dsrb) { struct gl_renderbuffer *z24rb; ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 || dsrb->Format == MESA_FORMAT_Z24_X8 || dsrb->Format == MESA_FORMAT_S8_Z24 || dsrb->Format == MESA_FORMAT_X8_Z24); ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT); z24rb = ctx->Driver.NewRenderbuffer(ctx, 0); if (!z24rb) return NULL; /* NOTE: need to do manual refcounting here */ z24rb->Wrapped = dsrb; dsrb->RefCount++; z24rb->Name = dsrb->Name; z24rb->RefCount = 0; z24rb->Width = dsrb->Width; z24rb->Height = dsrb->Height; z24rb->RowStride = dsrb->RowStride; z24rb->InternalFormat = GL_DEPTH_COMPONENT24; z24rb->Format = MESA_FORMAT_X8_Z24; z24rb->_BaseFormat = GL_DEPTH_COMPONENT; z24rb->DataType = GL_UNSIGNED_INT; z24rb->Data = NULL; z24rb->Delete = delete_wrapper; z24rb->AllocStorage = alloc_wrapper_storage; z24rb->GetPointer = nop_get_pointer; z24rb->GetRow = get_row_z24; z24rb->GetValues = get_values_z24; z24rb->PutRow = put_row_z24; z24rb->PutValues = put_values_z24; return z24rb; } static void get_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count, GLint x, GLint y, void *values) { struct gl_renderbuffer *dsrb = z32frb->Wrapped; GLfloat temp[MAX_WIDTH*2]; GLfloat *dst = (GLfloat *) values; const GLfloat *src = (const GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y); GLuint i; ASSERT(z32frb->DataType == GL_FLOAT); ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8); if (!src) { dsrb->GetRow(ctx, dsrb, count, x, y, temp); src = temp; } for (i = 0; i < count; i++) { dst[i] = src[i*2]; } } static void get_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count, const GLint x[], const GLint y[], void *values) { struct gl_renderbuffer *dsrb = z32frb->Wrapped; GLfloat temp[MAX_WIDTH*2]; GLfloat *dst = (GLfloat *) values; GLuint i; ASSERT(z32frb->DataType == GL_FLOAT); ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8); ASSERT(count <= MAX_WIDTH); /* don't bother trying direct access */ dsrb->GetValues(ctx, dsrb, count, x, y, temp); for (i = 0; i < count; i++) { dst[i] = temp[i*2]; } } static void put_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count, GLint x, GLint y, const void *values, const GLubyte *mask) { struct gl_renderbuffer *dsrb = z32frb->Wrapped; const GLfloat *src = (const GLfloat *) values; GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y); ASSERT(z32frb->DataType == GL_FLOAT); ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8); if (dst) { /* direct access */ GLuint i; for (i = 0; i < count; i++) { if (!mask || mask[i]) { dst[i*2] = src[i]; } } } else { /* get, modify, put */ GLfloat temp[MAX_WIDTH*2]; GLuint i; dsrb->GetRow(ctx, dsrb, count, x, y, temp); for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i*2] = src[i]; } } dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask); } } static void put_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count, const GLint x[], const GLint y[], const void *values, const GLubyte *mask) { struct gl_renderbuffer *dsrb = z32frb->Wrapped; const GLfloat *src = (const GLfloat *) values; ASSERT(z32frb->DataType == GL_FLOAT); ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8); if (dsrb->GetPointer(ctx, dsrb, 0, 0)) { /* direct access */ GLuint i; for (i = 0; i < count; i++) { if (!mask || mask[i]) { GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]); *dst = src[i]; } } } else { /* get, modify, put */ GLfloat temp[MAX_WIDTH*2]; GLuint i; dsrb->GetValues(ctx, dsrb, count, x, y, temp); for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i*2] = src[i]; } } dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask); } } /** * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like * a depth renderbuffer. * \return new depth renderbuffer */ static struct gl_renderbuffer * new_z32f_renderbuffer_wrapper(struct gl_context *ctx, struct gl_renderbuffer *dsrb) { struct gl_renderbuffer *z32frb; ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8); ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); z32frb = ctx->Driver.NewRenderbuffer(ctx, 0); if (!z32frb) return NULL; /* NOTE: need to do manual refcounting here */ z32frb->Wrapped = dsrb; dsrb->RefCount++; z32frb->Name = dsrb->Name; z32frb->RefCount = 0; z32frb->Width = dsrb->Width; z32frb->Height = dsrb->Height; z32frb->RowStride = dsrb->RowStride; z32frb->InternalFormat = GL_DEPTH_COMPONENT32F; z32frb->Format = MESA_FORMAT_Z32_FLOAT; z32frb->_BaseFormat = GL_DEPTH_COMPONENT; z32frb->DataType = GL_FLOAT; z32frb->Data = NULL; z32frb->Delete = delete_wrapper; z32frb->AllocStorage = alloc_wrapper_storage; z32frb->GetPointer = nop_get_pointer; z32frb->GetRow = get_row_z32f; z32frb->GetValues = get_values_z32f; z32frb->PutRow = put_row_z32f; z32frb->PutValues = put_values_z32f; return z32frb; } /*====================================================================== * Stencil wrapper around depth/stencil renderbuffer */ static void get_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count, GLint x, GLint y, void *values) { struct gl_renderbuffer *dsrb = s8rb->Wrapped; GLuint temp[MAX_WIDTH*2], i; GLubyte *dst = (GLubyte *) values; const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y); ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE); ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT || dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); if (!src) { dsrb->GetRow(ctx, dsrb, count, x, y, temp); src = temp; } if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) { for (i = 0; i < count; i++) { dst[i] = src[i*2+1] & 0xff; } } else if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { dst[i] = src[i] & 0xff; } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { dst[i] = src[i] >> 24; } } } static void get_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count, const GLint x[], const GLint y[], void *values) { struct gl_renderbuffer *dsrb = s8rb->Wrapped; GLuint temp[MAX_WIDTH*2], i; GLubyte *dst = (GLubyte *) values; ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE); ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT || dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); ASSERT(count <= MAX_WIDTH); /* don't bother trying direct access */ dsrb->GetValues(ctx, dsrb, count, x, y, temp); if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) { for (i = 0; i < count; i++) { dst[i] = temp[i*2+1] & 0xff; } } else if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { dst[i] = temp[i] & 0xff; } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { dst[i] = temp[i] >> 24; } } } static void put_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count, GLint x, GLint y, const void *values, const GLubyte *mask) { struct gl_renderbuffer *dsrb = s8rb->Wrapped; const GLubyte *src = (const GLubyte *) values; GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y); ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE); ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT || dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); if (dst) { /* direct access */ GLuint i; if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { dst[i*2+1] = src[i]; } } } else if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { dst[i] = (dst[i] & 0xffffff00) | src[i]; } } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { if (!mask || mask[i]) { dst[i] = (dst[i] & 0xffffff) | (src[i] << 24); } } } } else { /* get, modify, put */ GLuint temp[MAX_WIDTH*2], i; dsrb->GetRow(ctx, dsrb, count, x, y, temp); if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i*2+1] = src[i]; } } } else if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i] = (temp[i] & 0xffffff00) | src[i]; } } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i] = (temp[i] & 0xffffff) | (src[i] << 24); } } } dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask); } } static void put_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count, const GLint x[], const GLint y[], const void *values, const GLubyte *mask) { struct gl_renderbuffer *dsrb = s8rb->Wrapped; const GLubyte *src = (const GLubyte *) values; ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE); ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT || dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); if (dsrb->GetPointer(ctx, dsrb, 0, 0)) { /* direct access */ GLuint i; if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]); dst[1] = src[i]; } } } else if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]); *dst = (*dst & 0xffffff00) | src[i]; } } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { if (!mask || mask[i]) { GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]); *dst = (*dst & 0xffffff) | (src[i] << 24); } } } } else { /* get, modify, put */ GLuint temp[MAX_WIDTH*2], i; dsrb->GetValues(ctx, dsrb, count, x, y, temp); if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i*2+1] = src[i]; } } } else if (dsrb->Format == MESA_FORMAT_Z24_S8) { for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i] = (temp[i] & 0xffffff00) | src[i]; } } } else { assert(dsrb->Format == MESA_FORMAT_S8_Z24); for (i = 0; i < count; i++) { if (!mask || mask[i]) { temp[i] = (temp[i] & 0xffffff) | (src[i] << 24); } } } dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask); } } /** * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like * a stencil renderbuffer. * \return new stencil renderbuffer */ static struct gl_renderbuffer * new_s8_renderbuffer_wrapper(struct gl_context *ctx, struct gl_renderbuffer *dsrb) { struct gl_renderbuffer *s8rb; ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 || dsrb->Format == MESA_FORMAT_S8_Z24 || dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8); ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT || dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); s8rb = ctx->Driver.NewRenderbuffer(ctx, 0); if (!s8rb) return NULL; /* NOTE: need to do manual refcounting here */ s8rb->Wrapped = dsrb; dsrb->RefCount++; s8rb->Name = dsrb->Name; s8rb->RefCount = 0; s8rb->Width = dsrb->Width; s8rb->Height = dsrb->Height; s8rb->RowStride = dsrb->RowStride; s8rb->InternalFormat = GL_STENCIL_INDEX8_EXT; s8rb->Format = MESA_FORMAT_S8; s8rb->_BaseFormat = GL_STENCIL_INDEX; s8rb->DataType = GL_UNSIGNED_BYTE; s8rb->Data = NULL; s8rb->Delete = delete_wrapper; s8rb->AllocStorage = alloc_wrapper_storage; s8rb->GetPointer = nop_get_pointer; s8rb->GetRow = get_row_s8; s8rb->GetValues = get_values_s8; s8rb->PutRow = put_row_s8; s8rb->PutValues = put_values_s8; return s8rb; } /** * Update the framebuffer's _DepthBuffer field using the renderbuffer * found at the given attachment index. * * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer, * create and install a depth wrapper/adaptor. * * \param fb the framebuffer whose _DepthBuffer field to update */ void _swrast_update_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *fb) { struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; if (depthRb && _mesa_is_format_packed_depth_stencil(depthRb->Format)) { /* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */ if (!fb->_DepthBuffer || fb->_DepthBuffer->Wrapped != depthRb || _mesa_get_format_base_format(fb->_DepthBuffer->Format) != GL_DEPTH_COMPONENT) { /* need to update wrapper */ struct gl_renderbuffer *wrapper; if (depthRb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) { wrapper = new_z32f_renderbuffer_wrapper(ctx, depthRb); } else { wrapper = new_z24_renderbuffer_wrapper(ctx, depthRb); } _mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper); } ASSERT(fb->_DepthBuffer->Wrapped == depthRb); fb->_DepthBuffer->Width = depthRb->Width; fb->_DepthBuffer->Height = depthRb->Height; } else { /* depthRb may be null */ _mesa_reference_renderbuffer(&fb->_DepthBuffer, depthRb); } } /** * Update the framebuffer's _StencilBuffer field using the renderbuffer * found at the given attachment index. * * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer, * create and install a stencil wrapper/adaptor. * * \param fb the framebuffer whose _StencilBuffer field to update */ void _swrast_update_stencil_buffer(struct gl_context *ctx, struct gl_framebuffer *fb) { struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; if (stencilRb && _mesa_is_format_packed_depth_stencil(stencilRb->Format)) { /* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */ if (!fb->_StencilBuffer || fb->_StencilBuffer->Wrapped != stencilRb || _mesa_get_format_base_format(fb->_StencilBuffer->Format) != GL_STENCIL_INDEX) { /* need to update wrapper */ struct gl_renderbuffer *wrapper = new_s8_renderbuffer_wrapper(ctx, stencilRb); _mesa_reference_renderbuffer(&fb->_StencilBuffer, wrapper); } ASSERT(fb->_StencilBuffer->Wrapped == stencilRb); fb->_StencilBuffer->Width = stencilRb->Width; fb->_StencilBuffer->Height = stencilRb->Height; } else { /* stencilRb may be null */ _mesa_reference_renderbuffer(&fb->_StencilBuffer, stencilRb); } }