Support for combined depth/stencil renderbuffers (GL_EXT_packed_depth_stencil).
depthstencil.c provides wrappers for treating depth/stencil buffers either as regular depth or stencil renderbuffers.
This commit is contained in:
@@ -802,7 +802,8 @@ struct dd_function_table {
|
|||||||
struct gl_framebuffer * (*NewFramebuffer)(GLcontext *ctx, GLuint name);
|
struct gl_framebuffer * (*NewFramebuffer)(GLcontext *ctx, GLuint name);
|
||||||
struct gl_renderbuffer * (*NewRenderbuffer)(GLcontext *ctx, GLuint name);
|
struct gl_renderbuffer * (*NewRenderbuffer)(GLcontext *ctx, GLuint name);
|
||||||
void (*FramebufferRenderbuffer)(GLcontext *ctx,
|
void (*FramebufferRenderbuffer)(GLcontext *ctx,
|
||||||
struct gl_renderbuffer_attachment *att,
|
struct gl_framebuffer *fb,
|
||||||
|
GLenum attachment,
|
||||||
struct gl_renderbuffer *rb);
|
struct gl_renderbuffer *rb);
|
||||||
void (*RenderbufferTexture)(GLcontext *ctx,
|
void (*RenderbufferTexture)(GLcontext *ctx,
|
||||||
struct gl_renderbuffer_attachment *att,
|
struct gl_renderbuffer_attachment *att,
|
||||||
|
549
src/mesa/main/depthstencil.c
Normal file
549
src/mesa/main/depthstencil.c
Normal file
@@ -0,0 +1,549 @@
|
|||||||
|
/*
|
||||||
|
* Mesa 3-D graphics library
|
||||||
|
* Version: 6.5
|
||||||
|
*
|
||||||
|
* 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"),
|
||||||
|
* 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 "glheader.h"
|
||||||
|
#include "imports.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "fbobject.h"
|
||||||
|
#include "mtypes.h"
|
||||||
|
#include "depthstencil.h"
|
||||||
|
#include "renderbuffer.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 renderbuffer with depth and stencil
|
||||||
|
* adaptors, each with the right kind of depth/stencil Get/Put functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static void *
|
||||||
|
nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a depth or stencil renderbuffer.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
delete_wrapper(struct gl_renderbuffer *rb)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *dsrb = rb->Wrapped;
|
||||||
|
assert(dsrb);
|
||||||
|
assert(rb->InternalFormat == GL_DEPTH_COMPONENT24 ||
|
||||||
|
rb->InternalFormat == GL_STENCIL_INDEX8_EXT);
|
||||||
|
/* decrement refcount on the wrapped buffer and delete it if necessary */
|
||||||
|
dsrb->RefCount--;
|
||||||
|
if (dsrb->RefCount <= 0) {
|
||||||
|
dsrb->Delete(dsrb);
|
||||||
|
}
|
||||||
|
_mesa_free(rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*======================================================================
|
||||||
|
* Depth wrapper around depth/stencil renderbuffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_row_z24(GLcontext *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;
|
||||||
|
}
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
dst[i] = src[i] >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_values_z24(GLcontext *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);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
dst[i] = temp[i] >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_row_z24(GLcontext *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;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
dst[i] = (src[i] << 8) | (dst[i] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* get, modify, put */
|
||||||
|
GLuint temp[MAX_WIDTH], i;
|
||||||
|
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
temp[i] = (src[i] << 8) | (temp[i] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_mono_row_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
|
||||||
|
GLint x, GLint y, const void *value, const GLubyte *mask)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *dsrb = z24rb->Wrapped;
|
||||||
|
const GLuint shiftedVal = *((GLuint *) value) << 8;
|
||||||
|
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;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
dst[i] = shiftedVal | (dst[i] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* get, modify, put */
|
||||||
|
GLuint temp[MAX_WIDTH], i;
|
||||||
|
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
temp[i] = shiftedVal | (temp[i] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_values_z24(GLcontext *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 GLubyte *src = (const GLubyte *) 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;
|
||||||
|
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 {
|
||||||
|
/* get, modify, put */
|
||||||
|
GLuint temp[MAX_WIDTH], i;
|
||||||
|
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
temp[i] = (src[i] << 8) | (temp[i] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_mono_values_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb,
|
||||||
|
GLuint count, const GLint x[], const GLint y[],
|
||||||
|
const void *value, const GLubyte *mask)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *dsrb = z24rb->Wrapped;
|
||||||
|
GLuint temp[MAX_WIDTH], i;
|
||||||
|
const GLuint shiftedVal = *((GLuint *) value) << 8;
|
||||||
|
/* get, modify, put */
|
||||||
|
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
temp[i] = shiftedVal | (temp[i] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
struct gl_renderbuffer *
|
||||||
|
_mesa_new_z24_renderbuffer_wrapper(GLcontext *ctx,
|
||||||
|
struct gl_renderbuffer *dsrb)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *z24rb;
|
||||||
|
|
||||||
|
ASSERT(dsrb->_BaseFormat == GL_DEPTH_STENCIL_EXT);
|
||||||
|
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||||
|
|
||||||
|
z24rb = _mesa_new_renderbuffer(ctx, 0);
|
||||||
|
if (!z24rb)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
z24rb->Wrapped = dsrb;
|
||||||
|
z24rb->Name = dsrb->Name;
|
||||||
|
z24rb->RefCount = 1;
|
||||||
|
z24rb->Width = dsrb->Width;
|
||||||
|
z24rb->Height = dsrb->Height;
|
||||||
|
z24rb->InternalFormat = GL_DEPTH_COMPONENT24_ARB;
|
||||||
|
z24rb->_BaseFormat = GL_DEPTH_COMPONENT;
|
||||||
|
z24rb->DataType = GL_UNSIGNED_INT;
|
||||||
|
z24rb->DepthBits = 24;
|
||||||
|
z24rb->Data = NULL;
|
||||||
|
z24rb->Delete = delete_wrapper;
|
||||||
|
z24rb->GetPointer = nop_get_pointer;
|
||||||
|
z24rb->GetRow = get_row_z24;
|
||||||
|
z24rb->GetValues = get_values_z24;
|
||||||
|
z24rb->PutRow = put_row_z24;
|
||||||
|
z24rb->PutRowRGB = NULL;
|
||||||
|
z24rb->PutMonoRow = put_mono_row_z24;
|
||||||
|
z24rb->PutValues = put_values_z24;
|
||||||
|
z24rb->PutMonoValues = put_mono_values_z24;
|
||||||
|
|
||||||
|
return z24rb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*======================================================================
|
||||||
|
* Stencil wrapper around depth/stencil renderbuffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_row_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
|
||||||
|
GLint x, GLint y, void *values)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
|
||||||
|
GLuint temp[MAX_WIDTH], 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);
|
||||||
|
if (!src) {
|
||||||
|
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
|
||||||
|
src = temp;
|
||||||
|
}
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
dst[i] = src[i] & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_values_s8(GLcontext *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], i;
|
||||||
|
GLubyte *dst = (GLubyte *) values;
|
||||||
|
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
|
||||||
|
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);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
dst[i] = temp[i] & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_row_s8(GLcontext *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);
|
||||||
|
if (dst) {
|
||||||
|
/* direct access */
|
||||||
|
GLuint i;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
dst[i] = (dst[i] & 0xffffff00) | src[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* get, modify, put */
|
||||||
|
GLuint temp[MAX_WIDTH], i;
|
||||||
|
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
temp[i] = (temp[i] & 0xffffff00) | src[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_mono_row_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
|
||||||
|
GLint x, GLint y, const void *value, const GLubyte *mask)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
|
||||||
|
const GLubyte val = *((GLubyte *) value);
|
||||||
|
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
|
||||||
|
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
|
||||||
|
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||||
|
if (dst) {
|
||||||
|
/* direct access */
|
||||||
|
GLuint i;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
dst[i] = (dst[i] & 0xffffff00) | val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* get, modify, put */
|
||||||
|
GLuint temp[MAX_WIDTH], i;
|
||||||
|
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
temp[i] = (temp[i] & 0xffffff00) | val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_values_s8(GLcontext *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);
|
||||||
|
if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
|
||||||
|
/* direct access */
|
||||||
|
GLuint i;
|
||||||
|
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 {
|
||||||
|
/* get, modify, put */
|
||||||
|
GLuint temp[MAX_WIDTH], i;
|
||||||
|
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
temp[i] = (temp[i] & 0xffffff00) | src[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_mono_values_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
|
||||||
|
const GLint x[], const GLint y[],
|
||||||
|
const void *value, const GLubyte *mask)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
|
||||||
|
GLuint temp[MAX_WIDTH], i;
|
||||||
|
const GLubyte val = *((GLubyte *) value);
|
||||||
|
/* get, modify, put */
|
||||||
|
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!mask || mask[i]) {
|
||||||
|
temp[i] = (temp[i] & 0xffffff) | val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
struct gl_renderbuffer *
|
||||||
|
_mesa_new_s8_renderbuffer_wrapper(GLcontext *ctx, struct gl_renderbuffer *dsrb)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *s8rb;
|
||||||
|
|
||||||
|
ASSERT(dsrb->_BaseFormat == GL_DEPTH_STENCIL_EXT);
|
||||||
|
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||||
|
|
||||||
|
s8rb = _mesa_new_renderbuffer(ctx, 0);
|
||||||
|
if (!s8rb)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
s8rb->Wrapped = dsrb;
|
||||||
|
s8rb->Name = dsrb->Name;
|
||||||
|
s8rb->RefCount = 1;
|
||||||
|
s8rb->Width = dsrb->Width;
|
||||||
|
s8rb->Height = dsrb->Height;
|
||||||
|
s8rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
|
||||||
|
s8rb->_BaseFormat = GL_STENCIL_INDEX;
|
||||||
|
s8rb->DataType = GL_UNSIGNED_BYTE;
|
||||||
|
s8rb->StencilBits = 8;
|
||||||
|
s8rb->Data = NULL;
|
||||||
|
s8rb->Delete = delete_wrapper;
|
||||||
|
s8rb->GetPointer = nop_get_pointer;
|
||||||
|
s8rb->GetRow = get_row_s8;
|
||||||
|
s8rb->GetValues = get_values_s8;
|
||||||
|
s8rb->PutRow = put_row_s8;
|
||||||
|
s8rb->PutRowRGB = NULL;
|
||||||
|
s8rb->PutMonoRow = put_mono_row_s8;
|
||||||
|
s8rb->PutValues = put_values_s8;
|
||||||
|
s8rb->PutMonoValues = put_mono_values_s8;
|
||||||
|
|
||||||
|
return s8rb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge data from a depth renderbuffer and a stencil renderbuffer into a
|
||||||
|
* combined depth/stencil renderbuffer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_mesa_merge_depth_stencil_buffers(GLcontext *ctx,
|
||||||
|
struct gl_renderbuffer *dest,
|
||||||
|
struct gl_renderbuffer *depth,
|
||||||
|
struct gl_renderbuffer *stencil)
|
||||||
|
{
|
||||||
|
GLuint depthVals[MAX_WIDTH];
|
||||||
|
GLubyte stencilVals[MAX_WIDTH];
|
||||||
|
GLuint combined[MAX_WIDTH];
|
||||||
|
GLuint row, width;
|
||||||
|
|
||||||
|
ASSERT(dest);
|
||||||
|
ASSERT(depth);
|
||||||
|
ASSERT(stencil);
|
||||||
|
|
||||||
|
ASSERT(dest->InternalFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||||
|
ASSERT(dest->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||||
|
ASSERT(depth->InternalFormat == GL_DEPTH_COMPONENT24);
|
||||||
|
ASSERT(depth->DataType == GL_UNSIGNED_INT);
|
||||||
|
ASSERT(stencil->InternalFormat == GL_STENCIL_INDEX8_EXT);
|
||||||
|
ASSERT(stencil->DataType == GL_UNSIGNED_BYTE);
|
||||||
|
|
||||||
|
ASSERT(dest->Width == depth->Width);
|
||||||
|
ASSERT(dest->Height == depth->Height);
|
||||||
|
ASSERT(dest->Width == stencil->Width);
|
||||||
|
ASSERT(dest->Height == stencil->Height);
|
||||||
|
|
||||||
|
width = dest->Width;
|
||||||
|
for (row = 0; row < dest->Height; row++) {
|
||||||
|
GLuint i;
|
||||||
|
depth->GetRow(ctx, depth, width, 0, row, depthVals);
|
||||||
|
stencil->GetRow(ctx, stencil, width, 0, row, stencilVals);
|
||||||
|
for (i = 0; i < width; i++) {
|
||||||
|
combined[i] = (depthVals[i] << 8) | stencilVals[i];
|
||||||
|
}
|
||||||
|
dest->PutRow(ctx, dest, width, 0, row, combined, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split combined depth/stencil renderbuffer data into separate depth/stencil
|
||||||
|
* buffers.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_mesa_split_depth_stencil_buffer(GLcontext *ctx,
|
||||||
|
struct gl_renderbuffer *source,
|
||||||
|
struct gl_renderbuffer *depth,
|
||||||
|
struct gl_renderbuffer *stencil)
|
||||||
|
{
|
||||||
|
GLuint depthVals[MAX_WIDTH];
|
||||||
|
GLubyte stencilVals[MAX_WIDTH];
|
||||||
|
GLuint combined[MAX_WIDTH];
|
||||||
|
GLuint row, width;
|
||||||
|
|
||||||
|
ASSERT(source);
|
||||||
|
ASSERT(depth);
|
||||||
|
ASSERT(stencil);
|
||||||
|
|
||||||
|
ASSERT(source->InternalFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||||
|
ASSERT(source->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||||
|
ASSERT(depth->InternalFormat == GL_DEPTH_COMPONENT24);
|
||||||
|
ASSERT(depth->DataType == GL_UNSIGNED_INT);
|
||||||
|
ASSERT(stencil->InternalFormat == GL_STENCIL_INDEX8_EXT);
|
||||||
|
ASSERT(stencil->DataType == GL_UNSIGNED_BYTE);
|
||||||
|
|
||||||
|
ASSERT(source->Width == depth->Width);
|
||||||
|
ASSERT(source->Height == depth->Height);
|
||||||
|
ASSERT(source->Width == stencil->Width);
|
||||||
|
ASSERT(source->Height == stencil->Height);
|
||||||
|
|
||||||
|
width = source->Width;
|
||||||
|
for (row = 0; row < source->Height; row++) {
|
||||||
|
GLuint i;
|
||||||
|
source->GetRow(ctx, source, width, 0, row, combined);
|
||||||
|
for (i = 0; i < width; i++) {
|
||||||
|
depthVals[i] = combined[i] >> 8;
|
||||||
|
stencilVals[i] = combined[i] & 0xff;
|
||||||
|
}
|
||||||
|
depth->PutRow(ctx, depth, width, 0, row, depthVals, NULL);
|
||||||
|
stencil->PutRow(ctx, stencil, width, 0, row, stencilVals, NULL);
|
||||||
|
}
|
||||||
|
}
|
55
src/mesa/main/depthstencil.h
Normal file
55
src/mesa/main/depthstencil.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Mesa 3-D graphics library
|
||||||
|
* Version: 6.5
|
||||||
|
*
|
||||||
|
* 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"),
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DEPTHSTENCIL_H
|
||||||
|
#define DEPTHSTENCIL_H
|
||||||
|
|
||||||
|
|
||||||
|
extern struct gl_renderbuffer *
|
||||||
|
_mesa_new_z24_renderbuffer_wrapper(GLcontext *ctx,
|
||||||
|
struct gl_renderbuffer *dsrb);
|
||||||
|
|
||||||
|
|
||||||
|
extern struct gl_renderbuffer *
|
||||||
|
_mesa_new_s8_renderbuffer_wrapper(GLcontext *ctx,
|
||||||
|
struct gl_renderbuffer *dsrb);
|
||||||
|
|
||||||
|
|
||||||
|
extern void
|
||||||
|
_mesa_merge_depth_stencil_buffers(GLcontext *ctx,
|
||||||
|
struct gl_renderbuffer *dest,
|
||||||
|
struct gl_renderbuffer *depth,
|
||||||
|
struct gl_renderbuffer *stencil);
|
||||||
|
|
||||||
|
|
||||||
|
extern void
|
||||||
|
_mesa_split_depth_stencil_buffer(GLcontext *ctx,
|
||||||
|
struct gl_renderbuffer *source,
|
||||||
|
struct gl_renderbuffer *depth,
|
||||||
|
struct gl_renderbuffer *stencil);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* DEPTHSTENCIL_H */
|
@@ -38,7 +38,6 @@
|
|||||||
#include "texstore.h"
|
#include "texstore.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* XXX temporarily here */
|
/* XXX temporarily here */
|
||||||
#define GL_READ_FRAMEBUFFER_EXT 0x90
|
#define GL_READ_FRAMEBUFFER_EXT 0x90
|
||||||
#define GL_DRAW_FRAMEBUFFER_EXT 0x9a
|
#define GL_DRAW_FRAMEBUFFER_EXT 0x9a
|
||||||
@@ -108,8 +107,9 @@ lookup_framebuffer(GLcontext *ctx, GLuint id)
|
|||||||
* Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
|
* Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
|
||||||
* gl_renderbuffer_attachment object.
|
* gl_renderbuffer_attachment object.
|
||||||
*/
|
*/
|
||||||
static struct gl_renderbuffer_attachment *
|
struct gl_renderbuffer_attachment *
|
||||||
get_attachment(GLcontext *ctx, struct gl_framebuffer *fb, GLenum attachment)
|
_mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||||
|
GLenum attachment)
|
||||||
{
|
{
|
||||||
GLuint i;
|
GLuint i;
|
||||||
|
|
||||||
@@ -232,15 +232,17 @@ _mesa_set_renderbuffer_attachment(GLcontext *ctx,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fallback for ctx->Driver.FramebufferRenderbuffer()
|
* Fallback for ctx->Driver.FramebufferRenderbuffer()
|
||||||
* Sets a framebuffer attachment to a particular renderbuffer.
|
* Attach a renderbuffer object to a framebuffer object.
|
||||||
* The framebuffer in question is ctx->DrawBuffer.
|
|
||||||
* \sa _mesa_renderbuffer_texture
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
_mesa_framebuffer_renderbuffer(GLcontext *ctx,
|
_mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||||
struct gl_renderbuffer_attachment *att,
|
GLenum attachment, struct gl_renderbuffer *rb)
|
||||||
struct gl_renderbuffer *rb)
|
|
||||||
{
|
{
|
||||||
|
struct gl_renderbuffer_attachment *att;
|
||||||
|
|
||||||
|
att = _mesa_get_attachment(ctx, fb, attachment);
|
||||||
|
ASSERT(att);
|
||||||
|
|
||||||
if (rb) {
|
if (rb) {
|
||||||
_mesa_set_renderbuffer_attachment(ctx, att, rb);
|
_mesa_set_renderbuffer_attachment(ctx, att, rb);
|
||||||
}
|
}
|
||||||
@@ -461,7 +463,7 @@ _mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb)
|
|||||||
for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
|
for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
|
||||||
if (fb->ColorDrawBuffer[i] != GL_NONE) {
|
if (fb->ColorDrawBuffer[i] != GL_NONE) {
|
||||||
const struct gl_renderbuffer_attachment *att
|
const struct gl_renderbuffer_attachment *att
|
||||||
= get_attachment(ctx, fb, fb->ColorDrawBuffer[i]);
|
= _mesa_get_attachment(ctx, fb, fb->ColorDrawBuffer[i]);
|
||||||
assert(att);
|
assert(att);
|
||||||
if (att->Type == GL_NONE) {
|
if (att->Type == GL_NONE) {
|
||||||
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
|
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
|
||||||
@@ -473,7 +475,7 @@ _mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb)
|
|||||||
/* Check that the ReadBuffer is present */
|
/* Check that the ReadBuffer is present */
|
||||||
if (fb->ColorReadBuffer != GL_NONE) {
|
if (fb->ColorReadBuffer != GL_NONE) {
|
||||||
const struct gl_renderbuffer_attachment *att
|
const struct gl_renderbuffer_attachment *att
|
||||||
= get_attachment(ctx, fb, fb->ColorReadBuffer);
|
= _mesa_get_attachment(ctx, fb, fb->ColorReadBuffer);
|
||||||
assert(att);
|
assert(att);
|
||||||
if (att->Type == GL_NONE) {
|
if (att->Type == GL_NONE) {
|
||||||
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
|
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
|
||||||
@@ -1151,7 +1153,7 @@ _mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
|
|||||||
ASSERT(textarget == GL_TEXTURE_1D);
|
ASSERT(textarget == GL_TEXTURE_1D);
|
||||||
|
|
||||||
/* XXX read blit */
|
/* XXX read blit */
|
||||||
att = get_attachment(ctx, ctx->DrawBuffer, attachment);
|
att = _mesa_get_attachment(ctx, ctx->DrawBuffer, attachment);
|
||||||
if (att == NULL) {
|
if (att == NULL) {
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||||
"glFramebufferTexture1DEXT(attachment)");
|
"glFramebufferTexture1DEXT(attachment)");
|
||||||
@@ -1200,7 +1202,7 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
|
|||||||
textarget == GL_TEXTURE_RECTANGLE_ARB ||
|
textarget == GL_TEXTURE_RECTANGLE_ARB ||
|
||||||
IS_CUBE_FACE(textarget));
|
IS_CUBE_FACE(textarget));
|
||||||
|
|
||||||
att = get_attachment(ctx, ctx->DrawBuffer, attachment);
|
att = _mesa_get_attachment(ctx, ctx->DrawBuffer, attachment);
|
||||||
if (att == NULL) {
|
if (att == NULL) {
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||||
"glFramebufferTexture2DEXT(attachment)");
|
"glFramebufferTexture2DEXT(attachment)");
|
||||||
@@ -1252,7 +1254,7 @@ _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
|
|||||||
|
|
||||||
ASSERT(textarget == GL_TEXTURE_3D);
|
ASSERT(textarget == GL_TEXTURE_3D);
|
||||||
|
|
||||||
att = get_attachment(ctx, ctx->DrawBuffer, attachment);
|
att = _mesa_get_attachment(ctx, ctx->DrawBuffer, attachment);
|
||||||
if (att == NULL) {
|
if (att == NULL) {
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||||
"glFramebufferTexture1DEXT(attachment)");
|
"glFramebufferTexture1DEXT(attachment)");
|
||||||
@@ -1342,7 +1344,7 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
att = get_attachment(ctx, fb, attachment);
|
att = _mesa_get_attachment(ctx, fb, attachment);
|
||||||
if (att == NULL) {
|
if (att == NULL) {
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||||
"glFramebufferRenderbufferEXT(attachment)");
|
"glFramebufferRenderbufferEXT(attachment)");
|
||||||
@@ -1365,7 +1367,7 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
|
|||||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||||
|
|
||||||
assert(ctx->Driver.FramebufferRenderbuffer);
|
assert(ctx->Driver.FramebufferRenderbuffer);
|
||||||
ctx->Driver.FramebufferRenderbuffer(ctx, att, rb);
|
ctx->Driver.FramebufferRenderbuffer(ctx, fb, attachment, rb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1413,7 +1415,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
att = get_attachment(ctx, buffer, attachment);
|
att = _mesa_get_attachment(ctx, buffer, attachment);
|
||||||
if (att == NULL) {
|
if (att == NULL) {
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||||
"glGetFramebufferAttachmentParameterivEXT(attachment)");
|
"glGetFramebufferAttachmentParameterivEXT(attachment)");
|
||||||
|
@@ -27,6 +27,11 @@
|
|||||||
#define FBOBJECT_H
|
#define FBOBJECT_H
|
||||||
|
|
||||||
|
|
||||||
|
extern struct gl_renderbuffer_attachment *
|
||||||
|
_mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||||
|
GLenum attachment);
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
_mesa_remove_attachment(GLcontext *ctx,
|
_mesa_remove_attachment(GLcontext *ctx,
|
||||||
struct gl_renderbuffer_attachment *att);
|
struct gl_renderbuffer_attachment *att);
|
||||||
@@ -43,9 +48,8 @@ _mesa_set_renderbuffer_attachment(GLcontext *ctx,
|
|||||||
struct gl_renderbuffer *rb);
|
struct gl_renderbuffer *rb);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
_mesa_framebuffer_renderbuffer(GLcontext *ctx,
|
_mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||||
struct gl_renderbuffer_attachment *att,
|
GLenum attachment, struct gl_renderbuffer *rb);
|
||||||
struct gl_renderbuffer *rb);
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
_mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb);
|
_mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb);
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
#include "glheader.h"
|
#include "glheader.h"
|
||||||
#include "imports.h"
|
#include "imports.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
#include "depthstencil.h"
|
||||||
#include "mtypes.h"
|
#include "mtypes.h"
|
||||||
#include "fbobject.h"
|
#include "fbobject.h"
|
||||||
#include "framebuffer.h"
|
#include "framebuffer.h"
|
||||||
@@ -159,7 +160,7 @@ _mesa_destroy_framebuffer(struct gl_framebuffer *fb)
|
|||||||
{
|
{
|
||||||
if (fb) {
|
if (fb) {
|
||||||
_mesa_free_framebuffer_data(fb);
|
_mesa_free_framebuffer_data(fb);
|
||||||
FREE(fb);
|
_mesa_free(fb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,6 +188,23 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
|
|||||||
att->Type = GL_NONE;
|
att->Type = GL_NONE;
|
||||||
att->Renderbuffer = NULL;
|
att->Renderbuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fb->_DepthBuffer) {
|
||||||
|
struct gl_renderbuffer *rb = fb->_DepthBuffer;
|
||||||
|
rb->RefCount--;
|
||||||
|
if (rb->RefCount <= 0) {
|
||||||
|
rb->Delete(rb);
|
||||||
|
}
|
||||||
|
fb->_DepthBuffer = NULL;
|
||||||
|
}
|
||||||
|
if (fb->_StencilBuffer) {
|
||||||
|
struct gl_renderbuffer *rb = fb->_StencilBuffer;
|
||||||
|
rb->RefCount--;
|
||||||
|
if (rb->RefCount <= 0) {
|
||||||
|
rb->Delete(rb);
|
||||||
|
}
|
||||||
|
fb->_StencilBuffer = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -194,7 +212,11 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
|
|||||||
* Resize the given framebuffer's renderbuffers to the new width and height.
|
* Resize the given framebuffer's renderbuffers to the new width and height.
|
||||||
* This should only be used for window-system framebuffers, not
|
* This should only be used for window-system framebuffers, not
|
||||||
* user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object).
|
* user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object).
|
||||||
* This will typically be called via ctx->Driver.ResizeBuffers()
|
* This will typically be called via ctx->Driver.ResizeBuffers() or directly
|
||||||
|
* from a device driver.
|
||||||
|
*
|
||||||
|
* \note it's possible for ctx to be null since a window can be resized
|
||||||
|
* without a currently bound rendering context.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
_mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
_mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||||
@@ -377,6 +399,45 @@ _mesa_update_framebuffer_visual(struct gl_framebuffer *fb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for _mesa_update_framebuffer().
|
||||||
|
* Set the actual depth renderbuffer for the given framebuffer.
|
||||||
|
* Take care of reference counts, etc.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
set_depth_renderbuffer(struct gl_framebuffer *fb,
|
||||||
|
struct gl_renderbuffer *rb)
|
||||||
|
{
|
||||||
|
if (fb->_DepthBuffer) {
|
||||||
|
fb->_DepthBuffer->RefCount--;
|
||||||
|
if (fb->_DepthBuffer->RefCount <= 0) {
|
||||||
|
fb->_DepthBuffer->Delete(fb->_DepthBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fb->_DepthBuffer = rb;
|
||||||
|
if (rb)
|
||||||
|
rb->RefCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \sa set_depth_renderbuffer.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
set_stencil_renderbuffer(struct gl_framebuffer *fb,
|
||||||
|
struct gl_renderbuffer *rb)
|
||||||
|
{
|
||||||
|
if (fb->_StencilBuffer) {
|
||||||
|
fb->_StencilBuffer->RefCount--;
|
||||||
|
if (fb->_StencilBuffer->RefCount <= 0) {
|
||||||
|
fb->_StencilBuffer->Delete(fb->_StencilBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fb->_StencilBuffer = rb;
|
||||||
|
if (rb)
|
||||||
|
rb->RefCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update state related to the current draw/read framebuffers.
|
* Update state related to the current draw/read framebuffers.
|
||||||
* Specifically, update these framebuffer fields:
|
* Specifically, update these framebuffer fields:
|
||||||
@@ -440,5 +501,45 @@ _mesa_update_framebuffer(GLcontext *ctx)
|
|||||||
fb->_ColorReadBuffer
|
fb->_ColorReadBuffer
|
||||||
= fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
|
= fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deal with GL_DEPTH_STENCIL renderbuffer(s) attached to the depth
|
||||||
|
* and/or stencil attachment points.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *depthRb
|
||||||
|
= fb->Attachment[BUFFER_DEPTH].Renderbuffer;
|
||||||
|
struct gl_renderbuffer *stencilRb
|
||||||
|
= fb->Attachment[BUFFER_STENCIL].Renderbuffer;
|
||||||
|
|
||||||
|
if (depthRb && depthRb->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
|
||||||
|
if (!fb->_DepthBuffer || fb->_DepthBuffer->Wrapped != depthRb) {
|
||||||
|
/* need to update wrapper */
|
||||||
|
struct gl_renderbuffer *wrapper
|
||||||
|
= _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
|
||||||
|
set_depth_renderbuffer(fb, wrapper);
|
||||||
|
assert(fb->_DepthBuffer->Wrapped == depthRb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* depthRb may be null */
|
||||||
|
set_depth_renderbuffer(fb, depthRb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stencilRb && stencilRb->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
|
||||||
|
if (!fb->_StencilBuffer || fb->_StencilBuffer->Wrapped != stencilRb) {
|
||||||
|
/* need to update wrapper */
|
||||||
|
struct gl_renderbuffer *wrapper
|
||||||
|
= _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb);
|
||||||
|
set_stencil_renderbuffer(fb, wrapper);
|
||||||
|
assert(fb->_StencilBuffer->Wrapped == stencilRb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* stencilRb may be null */
|
||||||
|
set_stencil_renderbuffer(fb, stencilRb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
compute_depth_max(fb);
|
compute_depth_max(fb);
|
||||||
}
|
}
|
||||||
|
@@ -2243,6 +2243,11 @@ struct gl_framebuffer
|
|||||||
struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS][4];
|
struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS][4];
|
||||||
struct gl_renderbuffer *_ColorReadBuffer;
|
struct gl_renderbuffer *_ColorReadBuffer;
|
||||||
|
|
||||||
|
/** The Actual depth/stencil buffers to use. May be wrappers around the
|
||||||
|
* depth/stencil buffers attached above. */
|
||||||
|
struct gl_renderbuffer *_DepthBuffer;
|
||||||
|
struct gl_renderbuffer *_StencilBuffer;
|
||||||
|
|
||||||
/** Delete this framebuffer */
|
/** Delete this framebuffer */
|
||||||
void (*Delete)(struct gl_framebuffer *fb);
|
void (*Delete)(struct gl_framebuffer *fb);
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user