merge from texman branch
This commit is contained in:
@@ -206,7 +206,8 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
|
||||
#if FEATURE_EXT_framebuffer_object
|
||||
driver->NewFramebuffer = _mesa_new_framebuffer;
|
||||
driver->NewRenderbuffer = _mesa_new_soft_renderbuffer;
|
||||
driver->RenderbufferTexture = _mesa_renderbuffer_texture;
|
||||
driver->RenderTexture = _mesa_render_texture;
|
||||
driver->FinishRenderTexture = _mesa_finish_render_texture;
|
||||
driver->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer;
|
||||
#endif
|
||||
|
||||
|
@@ -89,7 +89,7 @@ $(LIB_DIR)/$(LIBNAME): $(LIBNAME)
|
||||
depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
|
||||
touch depend
|
||||
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(C_SOURCES) $(ASM_SOURCES) \
|
||||
> /dev/null
|
||||
>& /dev/null
|
||||
|
||||
|
||||
# Emacs tags
|
||||
|
@@ -831,7 +831,7 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv
|
||||
(void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
|
||||
(void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
|
||||
_mesa_free(psp->pDevPriv);
|
||||
(void)drmClose(psp->fd);
|
||||
(void)drmCloseOnce(psp->fd);
|
||||
if ( psp->modes != NULL ) {
|
||||
(*dri_interface->destroyContextModes)( psp->modes );
|
||||
}
|
||||
|
@@ -56,6 +56,8 @@ driNewRenderbuffer(GLenum format, GLvoid *addr,
|
||||
driRenderbuffer *drb;
|
||||
|
||||
assert(format == GL_RGBA ||
|
||||
format == GL_RGB5 ||
|
||||
format == GL_RGBA8 ||
|
||||
format == GL_DEPTH_COMPONENT16 ||
|
||||
format == GL_DEPTH_COMPONENT24 ||
|
||||
format == GL_DEPTH_COMPONENT32 ||
|
||||
@@ -75,7 +77,7 @@ driNewRenderbuffer(GLenum format, GLvoid *addr,
|
||||
|
||||
drb->Base.InternalFormat = format;
|
||||
|
||||
if (format == GL_RGBA) {
|
||||
if (format == GL_RGBA || format == GL_RGB5 || format == GL_RGBA8) {
|
||||
/* Color */
|
||||
drb->Base._BaseFormat = GL_RGBA;
|
||||
drb->Base.DataType = GL_UNSIGNED_BYTE;
|
||||
|
@@ -300,8 +300,8 @@ struct dd_function_table {
|
||||
*/
|
||||
void (*GetTexImage)( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLenum format, GLenum type, GLvoid *pixels,
|
||||
const struct gl_texture_object *texObj,
|
||||
const struct gl_texture_image *texImage );
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage );
|
||||
|
||||
/**
|
||||
* Called by glCopyTexImage1D().
|
||||
@@ -807,9 +807,9 @@ struct dd_function_table {
|
||||
struct gl_framebuffer *fb,
|
||||
GLenum attachment,
|
||||
struct gl_renderbuffer *rb);
|
||||
void (*RenderbufferTexture)(GLcontext *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer_attachment *att);
|
||||
void (*RenderTexture)(GLcontext *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer_attachment *att);
|
||||
void (*FinishRenderTexture)(GLcontext *ctx,
|
||||
struct gl_renderbuffer_attachment *att);
|
||||
/*@}*/
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
|
||||
* 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"),
|
||||
@@ -53,15 +53,15 @@ nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
|
||||
|
||||
|
||||
/**
|
||||
* Delete a depth or stencil renderbuffer.
|
||||
* Delete a depth or stencil wrapper 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);
|
||||
ASSERT(dsrb);
|
||||
ASSERT(rb->_ActualFormat == GL_DEPTH_COMPONENT24 ||
|
||||
rb->_ActualFormat == GL_STENCIL_INDEX8_EXT);
|
||||
/* decrement refcount on the wrapped buffer and delete it if necessary */
|
||||
dsrb->RefCount--;
|
||||
if (dsrb->RefCount <= 0) {
|
||||
@@ -71,6 +71,30 @@ delete_wrapper(struct gl_renderbuffer *rb)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Realloc storage for wrapper.
|
||||
*/
|
||||
static GLboolean
|
||||
alloc_wrapper_storage(GLcontext *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;
|
||||
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
|
||||
retVal = dsrb->AllocStorage(ctx, dsrb, dsrb->InternalFormat, width, height);
|
||||
if (retVal) {
|
||||
rb->Width = width;
|
||||
rb->Height = height;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*======================================================================
|
||||
* Depth wrapper around depth/stencil renderbuffer
|
||||
*/
|
||||
@@ -84,6 +108,7 @@ get_row_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
|
||||
GLuint *dst = (GLuint *) values;
|
||||
const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
|
||||
ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
if (!src) {
|
||||
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
|
||||
@@ -102,6 +127,7 @@ get_values_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
|
||||
GLuint temp[MAX_WIDTH], i;
|
||||
GLuint *dst = (GLuint *) values;
|
||||
ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
ASSERT(count <= MAX_WIDTH);
|
||||
/* don't bother trying direct access */
|
||||
@@ -119,6 +145,7 @@ put_row_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
|
||||
const GLuint *src = (const GLuint *) values;
|
||||
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
|
||||
ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
if (dst) {
|
||||
/* direct access */
|
||||
@@ -150,6 +177,7 @@ put_mono_row_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
|
||||
const GLuint shiftedVal = *((GLuint *) value) << 8;
|
||||
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
|
||||
ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
if (dst) {
|
||||
/* direct access */
|
||||
@@ -181,6 +209,7 @@ put_values_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
|
||||
struct gl_renderbuffer *dsrb = z24rb->Wrapped;
|
||||
const GLubyte *src = (const GLubyte *) values;
|
||||
ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
|
||||
/* direct access */
|
||||
@@ -235,7 +264,7 @@ _mesa_new_z24_renderbuffer_wrapper(GLcontext *ctx,
|
||||
{
|
||||
struct gl_renderbuffer *z24rb;
|
||||
|
||||
ASSERT(dsrb->_BaseFormat == GL_DEPTH_STENCIL_EXT);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
|
||||
z24rb = _mesa_new_renderbuffer(ctx, 0);
|
||||
@@ -248,11 +277,13 @@ _mesa_new_z24_renderbuffer_wrapper(GLcontext *ctx,
|
||||
z24rb->Width = dsrb->Width;
|
||||
z24rb->Height = dsrb->Height;
|
||||
z24rb->InternalFormat = GL_DEPTH_COMPONENT24_ARB;
|
||||
z24rb->_ActualFormat = 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->AllocStorage = alloc_wrapper_storage;
|
||||
z24rb->GetPointer = nop_get_pointer;
|
||||
z24rb->GetRow = get_row_z24;
|
||||
z24rb->GetValues = get_values_z24;
|
||||
@@ -279,6 +310,7 @@ get_row_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
|
||||
GLubyte *dst = (GLubyte *) values;
|
||||
const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
|
||||
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
if (!src) {
|
||||
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
|
||||
@@ -297,6 +329,7 @@ get_values_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
|
||||
GLuint temp[MAX_WIDTH], i;
|
||||
GLubyte *dst = (GLubyte *) values;
|
||||
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
ASSERT(count <= MAX_WIDTH);
|
||||
/* don't bother trying direct access */
|
||||
@@ -314,6 +347,7 @@ put_row_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
|
||||
const GLubyte *src = (const GLubyte *) values;
|
||||
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
|
||||
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
if (dst) {
|
||||
/* direct access */
|
||||
@@ -345,6 +379,7 @@ put_mono_row_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
|
||||
const GLubyte val = *((GLubyte *) value);
|
||||
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
|
||||
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
if (dst) {
|
||||
/* direct access */
|
||||
@@ -376,6 +411,7 @@ put_values_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
|
||||
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
|
||||
const GLubyte *src = (const GLubyte *) values;
|
||||
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
|
||||
/* direct access */
|
||||
@@ -429,7 +465,7 @@ _mesa_new_s8_renderbuffer_wrapper(GLcontext *ctx, struct gl_renderbuffer *dsrb)
|
||||
{
|
||||
struct gl_renderbuffer *s8rb;
|
||||
|
||||
ASSERT(dsrb->_BaseFormat == GL_DEPTH_STENCIL_EXT);
|
||||
ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
|
||||
s8rb = _mesa_new_renderbuffer(ctx, 0);
|
||||
@@ -442,11 +478,13 @@ _mesa_new_s8_renderbuffer_wrapper(GLcontext *ctx, struct gl_renderbuffer *dsrb)
|
||||
s8rb->Width = dsrb->Width;
|
||||
s8rb->Height = dsrb->Height;
|
||||
s8rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
|
||||
s8rb->_ActualFormat = 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->AllocStorage = alloc_wrapper_storage;
|
||||
s8rb->GetPointer = nop_get_pointer;
|
||||
s8rb->GetRow = get_row_s8;
|
||||
s8rb->GetValues = get_values_s8;
|
||||
@@ -460,90 +498,158 @@ _mesa_new_s8_renderbuffer_wrapper(GLcontext *ctx, struct gl_renderbuffer *dsrb)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Merge data from a depth renderbuffer and a stencil renderbuffer into a
|
||||
* combined depth/stencil renderbuffer.
|
||||
** The following functions are useful for hardware drivers that only
|
||||
** implement combined depth/stencil buffers.
|
||||
** The GL_EXT_framebuffer_object extension allows indepedent depth and
|
||||
** stencil buffers to be used in any combination.
|
||||
** Therefore, we sometimes have to merge separate depth and stencil
|
||||
** renderbuffers into a single depth+stencil renderbuffer. And sometimes
|
||||
** we have to split combined depth+stencil renderbuffers into separate
|
||||
** renderbuffers.
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* Extract stencil values from the combined depth/stencil renderbuffer, storing
|
||||
* the values into a separate stencil renderbuffer.
|
||||
* \param dsRb the source depth/stencil renderbuffer
|
||||
* \param stencilRb the destination stencil renderbuffer
|
||||
* (either 8-bit or 32-bit)
|
||||
*/
|
||||
void
|
||||
_mesa_merge_depth_stencil_buffers(GLcontext *ctx,
|
||||
struct gl_renderbuffer *dest,
|
||||
struct gl_renderbuffer *depth,
|
||||
struct gl_renderbuffer *stencil)
|
||||
_mesa_extract_stencil(GLcontext *ctx,
|
||||
struct gl_renderbuffer *dsRb,
|
||||
struct gl_renderbuffer *stencilRb)
|
||||
{
|
||||
GLuint depthVals[MAX_WIDTH];
|
||||
GLubyte stencilVals[MAX_WIDTH];
|
||||
GLuint combined[MAX_WIDTH];
|
||||
GLuint row, width;
|
||||
GLuint row, width, height;
|
||||
|
||||
ASSERT(dest);
|
||||
ASSERT(depth);
|
||||
ASSERT(stencil);
|
||||
ASSERT(dsRb);
|
||||
ASSERT(stencilRb);
|
||||
|
||||
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(dsRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
ASSERT(stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT ||
|
||||
stencilRb->_ActualFormat == GL_STENCIL_INDEX8_EXT);
|
||||
ASSERT(dsRb->Width == stencilRb->Width);
|
||||
ASSERT(dsRb->Height == stencilRb->Height);
|
||||
|
||||
ASSERT(dest->Width == depth->Width);
|
||||
ASSERT(dest->Height == depth->Height);
|
||||
ASSERT(dest->Width == stencil->Width);
|
||||
ASSERT(dest->Height == stencil->Height);
|
||||
width = dsRb->Width;
|
||||
height = dsRb->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];
|
||||
for (row = 0; row < height; row++) {
|
||||
GLuint depthStencil[MAX_WIDTH];
|
||||
dsRb->GetRow(ctx, dsRb, width, 0, row, depthStencil);
|
||||
if (stencilRb->_ActualFormat == GL_STENCIL_INDEX8_EXT) {
|
||||
/* 8bpp stencil */
|
||||
GLubyte stencil[MAX_WIDTH];
|
||||
GLuint i;
|
||||
for (i = 0; i < width; i++) {
|
||||
stencil[i] = depthStencil[i] & 0xff;
|
||||
}
|
||||
stencilRb->PutRow(ctx, stencilRb, width, 0, row, stencil, NULL);
|
||||
}
|
||||
else {
|
||||
/* 32bpp stencil */
|
||||
/* the 24 depth bits will be ignored */
|
||||
ASSERT(stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
stencilRb->PutRow(ctx, stencilRb, width, 0, row, depthStencil, NULL);
|
||||
}
|
||||
dest->PutRow(ctx, dest, width, 0, row, combined, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Split combined depth/stencil renderbuffer data into separate depth/stencil
|
||||
* buffers.
|
||||
* Copy stencil values from a stencil renderbuffer into a combined
|
||||
* depth/stencil renderbuffer.
|
||||
* \param dsRb the destination depth/stencil renderbuffer
|
||||
* \param stencilRb the source stencil buffer (either 8-bit or 32-bit)
|
||||
*/
|
||||
void
|
||||
_mesa_split_depth_stencil_buffer(GLcontext *ctx,
|
||||
struct gl_renderbuffer *source,
|
||||
struct gl_renderbuffer *depth,
|
||||
struct gl_renderbuffer *stencil)
|
||||
_mesa_insert_stencil(GLcontext *ctx,
|
||||
struct gl_renderbuffer *dsRb,
|
||||
struct gl_renderbuffer *stencilRb)
|
||||
{
|
||||
GLuint depthVals[MAX_WIDTH];
|
||||
GLubyte stencilVals[MAX_WIDTH];
|
||||
GLuint combined[MAX_WIDTH];
|
||||
GLuint row, width;
|
||||
GLuint row, width, height;
|
||||
|
||||
ASSERT(source);
|
||||
ASSERT(depth);
|
||||
ASSERT(stencil);
|
||||
ASSERT(dsRb);
|
||||
ASSERT(stencilRb);
|
||||
|
||||
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(dsRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(dsRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
ASSERT(stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT ||
|
||||
stencilRb->_ActualFormat == GL_STENCIL_INDEX8_EXT);
|
||||
|
||||
ASSERT(source->Width == depth->Width);
|
||||
ASSERT(source->Height == depth->Height);
|
||||
ASSERT(source->Width == stencil->Width);
|
||||
ASSERT(source->Height == stencil->Height);
|
||||
ASSERT(dsRb->Width == stencilRb->Width);
|
||||
ASSERT(dsRb->Height == stencilRb->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;
|
||||
width = dsRb->Width;
|
||||
height = dsRb->Height;
|
||||
|
||||
for (row = 0; row < height; row++) {
|
||||
GLuint depthStencil[MAX_WIDTH];
|
||||
|
||||
dsRb->GetRow(ctx, dsRb, width, 0, row, depthStencil);
|
||||
|
||||
if (stencilRb->_ActualFormat == GL_STENCIL_INDEX8_EXT) {
|
||||
/* 8bpp stencil */
|
||||
GLubyte stencil[MAX_WIDTH];
|
||||
GLuint i;
|
||||
stencilRb->GetRow(ctx, stencilRb, width, 0, row, stencil);
|
||||
for (i = 0; i < width; i++) {
|
||||
depthStencil[i] = (depthStencil[i] & 0xffffff00) | stencil[i];
|
||||
}
|
||||
}
|
||||
depth->PutRow(ctx, depth, width, 0, row, depthVals, NULL);
|
||||
stencil->PutRow(ctx, stencil, width, 0, row, stencilVals, NULL);
|
||||
else {
|
||||
/* 32bpp stencil buffer */
|
||||
GLuint stencil[MAX_WIDTH], i;
|
||||
ASSERT(stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
|
||||
ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
stencilRb->GetRow(ctx, stencilRb, width, 0, row, stencil);
|
||||
for (i = 0; i < width; i++) {
|
||||
depthStencil[i]
|
||||
= (depthStencil[i] & 0xffffff00) | (stencil[i] & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
dsRb->PutRow(ctx, dsRb, width, 0, row, depthStencil, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert the stencil buffer from 8bpp to 32bpp depth/stencil.
|
||||
* \param stencilRb the stencil renderbuffer to promote
|
||||
*/
|
||||
void
|
||||
_mesa_promote_stencil(GLcontext *ctx, struct gl_renderbuffer *stencilRb)
|
||||
{
|
||||
const GLsizei width = stencilRb->Width;
|
||||
const GLsizei height = stencilRb->Height;
|
||||
GLubyte *data;
|
||||
GLint i, j, k;
|
||||
|
||||
ASSERT(stencilRb->_ActualFormat == GL_STENCIL_INDEX8_EXT);
|
||||
ASSERT(stencilRb->Data);
|
||||
|
||||
data = (GLubyte *) stencilRb->Data;
|
||||
stencilRb->Data = NULL;
|
||||
stencilRb->AllocStorage(ctx, stencilRb, GL_DEPTH24_STENCIL8_EXT,
|
||||
width, height);
|
||||
|
||||
ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < height; i++) {
|
||||
GLuint depthStencil[MAX_WIDTH];
|
||||
for (j = 0; j < width; j++) {
|
||||
depthStencil[j] = data[k++];
|
||||
}
|
||||
stencilRb->PutRow(ctx, stencilRb, width, 0, i, depthStencil, NULL);
|
||||
}
|
||||
_mesa_free(data);
|
||||
|
||||
stencilRb->_BaseFormat = GL_DEPTH_STENCIL_EXT;
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
|
||||
* 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"),
|
||||
@@ -38,18 +38,19 @@ _mesa_new_s8_renderbuffer_wrapper(GLcontext *ctx,
|
||||
|
||||
|
||||
extern void
|
||||
_mesa_merge_depth_stencil_buffers(GLcontext *ctx,
|
||||
struct gl_renderbuffer *dest,
|
||||
struct gl_renderbuffer *depth,
|
||||
struct gl_renderbuffer *stencil);
|
||||
_mesa_extract_stencil(GLcontext *ctx,
|
||||
struct gl_renderbuffer *dsRb,
|
||||
struct gl_renderbuffer *stencilRb);
|
||||
|
||||
|
||||
extern void
|
||||
_mesa_split_depth_stencil_buffer(GLcontext *ctx,
|
||||
struct gl_renderbuffer *source,
|
||||
struct gl_renderbuffer *depth,
|
||||
struct gl_renderbuffer *stencil);
|
||||
_mesa_insert_stencil(GLcontext *ctx,
|
||||
struct gl_renderbuffer *dsRb,
|
||||
struct gl_renderbuffer *stencilRb);
|
||||
|
||||
|
||||
extern void
|
||||
_mesa_promote_stencil(GLcontext *ctx, struct gl_renderbuffer *stencilRb);
|
||||
|
||||
|
||||
#endif /* DEPTHSTENCIL_H */
|
||||
|
@@ -149,12 +149,6 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
||||
|
||||
if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glDrawPixels (invalid fragment program)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (width < 0 || height < 0) {
|
||||
_mesa_error( ctx, GL_INVALID_VALUE, "glDrawPixels(width or height < 0" );
|
||||
return;
|
||||
@@ -164,6 +158,12 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
|
||||
_mesa_update_state(ctx);
|
||||
}
|
||||
|
||||
if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glDrawPixels (invalid fragment program)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (error_check_format_type(ctx, format, type, GL_TRUE)) {
|
||||
/* found an error */
|
||||
return;
|
||||
@@ -315,12 +315,6 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
||||
|
||||
if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glBitmap (invalid fragment program)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (width < 0 || height < 0) {
|
||||
_mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
|
||||
return;
|
||||
@@ -334,6 +328,12 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
|
||||
_mesa_update_state(ctx);
|
||||
}
|
||||
|
||||
if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glBitmap (invalid fragment program)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
|
||||
_mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
|
||||
"glBitmap(incomplete framebuffer)");
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "renderbuffer.h"
|
||||
#include "state.h"
|
||||
#include "teximage.h"
|
||||
#include "texobj.h"
|
||||
#include "texstore.h"
|
||||
|
||||
|
||||
@@ -66,8 +67,8 @@ static struct gl_renderbuffer DummyRenderbuffer;
|
||||
/**
|
||||
* Helper routine for getting a gl_renderbuffer.
|
||||
*/
|
||||
static struct gl_renderbuffer *
|
||||
lookup_renderbuffer(GLcontext *ctx, GLuint id)
|
||||
struct gl_renderbuffer *
|
||||
_mesa_lookup_renderbuffer(GLcontext *ctx, GLuint id)
|
||||
{
|
||||
struct gl_renderbuffer *rb;
|
||||
|
||||
@@ -83,8 +84,8 @@ lookup_renderbuffer(GLcontext *ctx, GLuint id)
|
||||
/**
|
||||
* Helper routine for getting a gl_framebuffer.
|
||||
*/
|
||||
static struct gl_framebuffer *
|
||||
lookup_framebuffer(GLcontext *ctx, GLuint id)
|
||||
struct gl_framebuffer *
|
||||
_mesa_lookup_framebuffer(GLcontext *ctx, GLuint id)
|
||||
{
|
||||
struct gl_framebuffer *fb;
|
||||
|
||||
@@ -209,7 +210,7 @@ _mesa_set_texture_attachment(GLcontext *ctx,
|
||||
att->Complete = GL_FALSE;
|
||||
|
||||
if (att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {
|
||||
ctx->Driver.RenderbufferTexture(ctx, fb, att);
|
||||
ctx->Driver.RenderTexture(ctx, fb, att);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,6 +224,7 @@ _mesa_set_renderbuffer_attachment(GLcontext *ctx,
|
||||
struct gl_renderbuffer_attachment *att,
|
||||
struct gl_renderbuffer *rb)
|
||||
{
|
||||
/* XXX check if re-doing same attachment, exit early */
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
att->Type = GL_RENDERBUFFER_EXT;
|
||||
att->Renderbuffer = rb;
|
||||
@@ -242,6 +244,10 @@ _mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
{
|
||||
struct gl_renderbuffer_attachment *att;
|
||||
|
||||
_glthread_LOCK_MUTEX(fb->Mutex);
|
||||
if (rb)
|
||||
_glthread_LOCK_MUTEX(rb->Mutex);
|
||||
|
||||
att = _mesa_get_attachment(ctx, fb, attachment);
|
||||
ASSERT(att);
|
||||
|
||||
@@ -251,6 +257,10 @@ _mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
else {
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
}
|
||||
|
||||
if (rb)
|
||||
_glthread_UNLOCK_MUTEX(rb->Mutex);
|
||||
_glthread_UNLOCK_MUTEX(fb->Mutex);
|
||||
}
|
||||
|
||||
|
||||
@@ -554,7 +564,7 @@ _mesa_IsRenderbufferEXT(GLuint renderbuffer)
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
|
||||
if (renderbuffer) {
|
||||
struct gl_renderbuffer *rb = lookup_renderbuffer(ctx, renderbuffer);
|
||||
struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
|
||||
if (rb != NULL && rb != &DummyRenderbuffer)
|
||||
return GL_TRUE;
|
||||
}
|
||||
@@ -579,7 +589,7 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
|
||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||
|
||||
if (renderbuffer) {
|
||||
newRb = lookup_renderbuffer(ctx, renderbuffer);
|
||||
newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
|
||||
if (newRb == &DummyRenderbuffer) {
|
||||
/* ID was reserved, but no real renderbuffer object made yet */
|
||||
newRb = NULL;
|
||||
@@ -626,7 +636,7 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
|
||||
for (i = 0; i < n; i++) {
|
||||
if (renderbuffers[i] > 0) {
|
||||
struct gl_renderbuffer *rb;
|
||||
rb = lookup_renderbuffer(ctx, renderbuffers[i]);
|
||||
rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]);
|
||||
if (rb) {
|
||||
/* check if deleting currently bound renderbuffer object */
|
||||
if (rb == ctx->CurrentRenderbuffer) {
|
||||
@@ -786,15 +796,26 @@ _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
|
||||
return;
|
||||
}
|
||||
|
||||
/* These MUST get set by the AllocStorage func */
|
||||
rb->_ActualFormat = 0;
|
||||
rb->RedBits =
|
||||
rb->GreenBits =
|
||||
rb->BlueBits =
|
||||
rb->AlphaBits =
|
||||
rb->IndexBits =
|
||||
rb->DepthBits =
|
||||
rb->StencilBits = 0;
|
||||
|
||||
/* Now allocate the storage */
|
||||
ASSERT(rb->AllocStorage);
|
||||
if (rb->AllocStorage(ctx, rb, internalFormat, width, height)) {
|
||||
/* No error - check/set fields now */
|
||||
assert(rb->_ActualFormat);
|
||||
assert(rb->Width == width);
|
||||
assert(rb->Height == height);
|
||||
assert(rb->InternalFormat);
|
||||
assert(rb->RedBits || rb->GreenBits || rb->BlueBits || rb->AlphaBits ||
|
||||
rb->DepthBits || rb->StencilBits || rb->IndexBits);
|
||||
rb->InternalFormat = internalFormat;
|
||||
rb->_BaseFormat = baseFormat;
|
||||
}
|
||||
else {
|
||||
@@ -802,6 +823,7 @@ _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
|
||||
rb->Width = 0;
|
||||
rb->Height = 0;
|
||||
rb->InternalFormat = GL_NONE;
|
||||
rb->_ActualFormat = GL_NONE;
|
||||
rb->_BaseFormat = GL_NONE;
|
||||
rb->RedBits =
|
||||
rb->GreenBits =
|
||||
@@ -884,7 +906,7 @@ _mesa_IsFramebufferEXT(GLuint framebuffer)
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
|
||||
if (framebuffer) {
|
||||
struct gl_framebuffer *rb = lookup_framebuffer(ctx, framebuffer);
|
||||
struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, framebuffer);
|
||||
if (rb != NULL && rb != &DummyFramebuffer)
|
||||
return GL_TRUE;
|
||||
}
|
||||
@@ -892,13 +914,28 @@ _mesa_IsFramebufferEXT(GLuint framebuffer)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
check_begin_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
{
|
||||
GLuint i;
|
||||
ASSERT(ctx->Driver.RenderTexture);
|
||||
for (i = 0; i < BUFFER_COUNT; i++) {
|
||||
struct gl_renderbuffer_attachment *att = fb->Attachment + i;
|
||||
struct gl_texture_object *texObj = att->Texture;
|
||||
if (texObj) {
|
||||
ctx->Driver.RenderTexture(ctx, fb, att);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Examine all the framebuffer's attachments to see if any are textures.
|
||||
* If so, call ctx->Driver.FinishRenderTexture() for each texture to
|
||||
* notify the device driver that the texture image may have changed.
|
||||
*/
|
||||
static void
|
||||
check_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
check_end_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
{
|
||||
if (ctx->Driver.FinishRenderTexture) {
|
||||
GLuint i;
|
||||
@@ -922,6 +959,12 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (!ctx->Extensions.EXT_framebuffer_object) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glBindFramebufferEXT(unsupported)");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (target) {
|
||||
#if FEATURE_EXT_framebuffer_blit
|
||||
case GL_DRAW_FRAMEBUFFER_EXT:
|
||||
@@ -954,7 +997,7 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
|
||||
if (framebuffer) {
|
||||
/* Binding a user-created framebuffer object */
|
||||
newFb = lookup_framebuffer(ctx, framebuffer);
|
||||
newFb = _mesa_lookup_framebuffer(ctx, framebuffer);
|
||||
if (newFb == &DummyFramebuffer) {
|
||||
/* ID was reserved, but no real framebuffer object made yet */
|
||||
newFb = NULL;
|
||||
@@ -968,10 +1011,12 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
}
|
||||
_mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newFb);
|
||||
}
|
||||
_glthread_LOCK_MUTEX(newFb->Mutex);
|
||||
if (bindReadBuf)
|
||||
newFb->RefCount++;
|
||||
if (bindDrawBuf)
|
||||
newFb->RefCount++;
|
||||
_glthread_UNLOCK_MUTEX(newFb->Mutex);
|
||||
}
|
||||
else {
|
||||
/* Binding the window system framebuffer (which was originally set
|
||||
@@ -980,12 +1025,19 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
newFb = ctx->WinSysDrawBuffer;
|
||||
}
|
||||
|
||||
ASSERT(newFb);
|
||||
ASSERT(newFb != &DummyFramebuffer);
|
||||
|
||||
/*
|
||||
* XXX check if re-binding same buffer and skip some of this code.
|
||||
*/
|
||||
|
||||
if (bindReadBuf) {
|
||||
oldFb = ctx->ReadBuffer;
|
||||
if (oldFb && oldFb->Name != 0) {
|
||||
_glthread_LOCK_MUTEX(oldFb->Mutex);
|
||||
oldFb->RefCount--;
|
||||
_glthread_UNLOCK_MUTEX(oldFb->Mutex);
|
||||
if (oldFb->RefCount == 0) {
|
||||
oldFb->Delete(oldFb);
|
||||
}
|
||||
@@ -997,16 +1049,20 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
oldFb = ctx->DrawBuffer;
|
||||
if (oldFb && oldFb->Name != 0) {
|
||||
/* check if old FB had any texture attachments */
|
||||
if (ctx->Driver.FinishRenderTexture) {
|
||||
check_texture_render(ctx, oldFb);
|
||||
}
|
||||
check_end_texture_render(ctx, oldFb);
|
||||
/* check if time to delete this framebuffer */
|
||||
_glthread_LOCK_MUTEX(oldFb->Mutex);
|
||||
oldFb->RefCount--;
|
||||
if (oldFb->RefCount == 0) {
|
||||
oldFb->Delete(oldFb);
|
||||
}
|
||||
_glthread_UNLOCK_MUTEX(oldFb->Mutex);
|
||||
}
|
||||
ctx->DrawBuffer = newFb;
|
||||
if (newFb->Name != 0) {
|
||||
/* check if newly bound framebuffer has any texture attachments */
|
||||
check_begin_texture_render(ctx, newFb);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->Driver.BindFramebuffer) {
|
||||
@@ -1027,7 +1083,7 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
|
||||
for (i = 0; i < n; i++) {
|
||||
if (framebuffers[i] > 0) {
|
||||
struct gl_framebuffer *fb;
|
||||
fb = lookup_framebuffer(ctx, framebuffers[i]);
|
||||
fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]);
|
||||
if (fb) {
|
||||
ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);
|
||||
|
||||
@@ -1045,7 +1101,9 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
|
||||
/* But the object will not be freed until it's no longer
|
||||
* bound in any context.
|
||||
*/
|
||||
_glthread_LOCK_MUTEX(fb->Mutex);
|
||||
fb->RefCount--;
|
||||
_glthread_UNLOCK_MUTEX(fb->Mutex);
|
||||
if (fb->RefCount == 0) {
|
||||
fb->Delete(fb);
|
||||
}
|
||||
@@ -1134,100 +1192,134 @@ _mesa_CheckFramebufferStatusEXT(GLenum target)
|
||||
|
||||
|
||||
/**
|
||||
* Do error checking common to glFramebufferTexture1D/2D/3DEXT.
|
||||
* \return GL_TRUE if any error, GL_FALSE otherwise
|
||||
* Common code called by glFramebufferTexture1D/2D/3DEXT().
|
||||
*/
|
||||
static GLboolean
|
||||
error_check_framebuffer_texture(GLcontext *ctx, GLuint dims,
|
||||
GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture, GLint level)
|
||||
{
|
||||
ASSERT(dims >= 1 && dims <= 3);
|
||||
|
||||
if (target != GL_FRAMEBUFFER_EXT) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture%dDEXT(target)", dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* check framebuffer binding */
|
||||
if (ctx->DrawBuffer->Name == 0) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferTexture%dDEXT", dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* only check textarget, level if texture ID is non-zero */
|
||||
if (texture) {
|
||||
if ((dims == 1 && textarget != GL_TEXTURE_1D) ||
|
||||
(dims == 3 && textarget != GL_TEXTURE_3D) ||
|
||||
(dims == 2 && textarget != GL_TEXTURE_2D &&
|
||||
textarget != GL_TEXTURE_RECTANGLE_ARB &&
|
||||
!IS_CUBE_FACE(textarget))) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture%dDEXT(textarget)", dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
if ((level < 0) || level >= _mesa_max_texture_levels(ctx, textarget)) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture%dDEXT(level)", dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* XXX The code in _mesa_FramebufferTexture1/2/3DEXT could be probably
|
||||
* be combined into one function.
|
||||
*/
|
||||
void GLAPIENTRY
|
||||
_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture, GLint level)
|
||||
static void
|
||||
framebuffer_texture(GLuint dims, GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture,
|
||||
GLint level, GLint zoffset)
|
||||
{
|
||||
struct gl_renderbuffer_attachment *att;
|
||||
struct gl_texture_object *texObj = NULL;
|
||||
struct gl_framebuffer *fb;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (error_check_framebuffer_texture(ctx, 1, target, attachment,
|
||||
textarget, texture, level))
|
||||
if (target != GL_FRAMEBUFFER_EXT) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture%dDEXT(target)", dims);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(textarget == GL_TEXTURE_1D);
|
||||
fb = ctx->DrawBuffer;
|
||||
ASSERT(fb);
|
||||
|
||||
/* XXX read blit */
|
||||
att = _mesa_get_attachment(ctx, ctx->DrawBuffer, attachment);
|
||||
/* check framebuffer binding */
|
||||
if (fb->Name == 0) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferTexture%dDEXT", dims);
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
texObj = _mesa_lookup_texture(ctx, texture);
|
||||
}
|
||||
|
||||
/* Check dimension-dependent things */
|
||||
switch (dims) {
|
||||
case 1:
|
||||
if (textarget != GL_TEXTURE_1D) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture1DEXT(textarget)");
|
||||
return;
|
||||
}
|
||||
if (texObj && texObj->Target != GL_TEXTURE_1D) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferTexture1DEXT(texture target mismatch)");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (textarget != GL_TEXTURE_2D &&
|
||||
textarget != GL_TEXTURE_RECTANGLE_ARB &&
|
||||
!IS_CUBE_FACE(textarget)) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture2DEXT(textarget)");
|
||||
return;
|
||||
}
|
||||
if (texObj) {
|
||||
if ((texObj->Target == GL_TEXTURE_2D && textarget != GL_TEXTURE_2D) ||
|
||||
(texObj->Target == GL_TEXTURE_RECTANGLE_ARB
|
||||
&& textarget != GL_TEXTURE_RECTANGLE_ARB) ||
|
||||
(texObj->Target == GL_TEXTURE_CUBE_MAP
|
||||
&& !IS_CUBE_FACE(textarget))) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferTexture1DEXT(texture target mismatch)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (textarget != GL_TEXTURE_3D) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture3DEXT(textarget)");
|
||||
return;
|
||||
}
|
||||
if (texObj && texObj->Target != GL_TEXTURE_3D) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferTexture3DEXT(texture target mismatch)");
|
||||
return;
|
||||
}
|
||||
{
|
||||
const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
|
||||
if (zoffset < 0 || zoffset >= maxSize) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture3DEXT(zoffset)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(ctx, "Unexpected dims in error_check_framebuffer_texture");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((level < 0) || level >= _mesa_max_texture_levels(ctx, textarget)) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture%dDEXT(level)", dims);
|
||||
return;
|
||||
}
|
||||
|
||||
att = _mesa_get_attachment(ctx, fb, attachment);
|
||||
if (att == NULL) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture1DEXT(attachment)");
|
||||
"glFramebufferTexture%dDEXT(attachment)", dims);
|
||||
return;
|
||||
}
|
||||
|
||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||
|
||||
if (texture) {
|
||||
struct gl_texture_object *texObj = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
||||
if (!texObj) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture1DEXT(texture)");
|
||||
return;
|
||||
}
|
||||
if (texObj->Target != textarget) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
|
||||
"glFramebufferTexture1DEXT(texture target)");
|
||||
return;
|
||||
}
|
||||
_mesa_set_texture_attachment(ctx, ctx->DrawBuffer, att,
|
||||
texObj, textarget, level, 0);
|
||||
_glthread_LOCK_MUTEX(fb->Mutex);
|
||||
if (texObj) {
|
||||
_mesa_set_texture_attachment(ctx, fb, att, texObj, textarget,
|
||||
level, zoffset);
|
||||
}
|
||||
else {
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
}
|
||||
_glthread_UNLOCK_MUTEX(fb->Mutex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture, GLint level)
|
||||
{
|
||||
const GLint zoffset = 0;
|
||||
framebuffer_texture(1, target, attachment, textarget, texture,
|
||||
level, zoffset);
|
||||
}
|
||||
|
||||
|
||||
@@ -1235,51 +1327,9 @@ void GLAPIENTRY
|
||||
_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture, GLint level)
|
||||
{
|
||||
struct gl_renderbuffer_attachment *att;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (error_check_framebuffer_texture(ctx, 2, target, attachment,
|
||||
textarget, texture, level))
|
||||
return;
|
||||
|
||||
ASSERT(textarget == GL_TEXTURE_2D ||
|
||||
textarget == GL_TEXTURE_RECTANGLE_ARB ||
|
||||
IS_CUBE_FACE(textarget));
|
||||
|
||||
att = _mesa_get_attachment(ctx, ctx->DrawBuffer, attachment);
|
||||
if (att == NULL) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture2DEXT(attachment)");
|
||||
return;
|
||||
}
|
||||
|
||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||
|
||||
if (texture) {
|
||||
struct gl_texture_object *texObj = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
||||
if (!texObj) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture2DEXT(texture)");
|
||||
return;
|
||||
}
|
||||
if ((texObj->Target == GL_TEXTURE_2D && textarget != GL_TEXTURE_2D) ||
|
||||
(texObj->Target == GL_TEXTURE_RECTANGLE_ARB
|
||||
&& textarget != GL_TEXTURE_RECTANGLE_ARB) ||
|
||||
(texObj->Target == GL_TEXTURE_CUBE_MAP
|
||||
&& !IS_CUBE_FACE(textarget))) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
|
||||
"glFramebufferTexture2DEXT(texture target)");
|
||||
return;
|
||||
}
|
||||
_mesa_set_texture_attachment(ctx, ctx->DrawBuffer, att,
|
||||
texObj, textarget, level, 0);
|
||||
}
|
||||
else {
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
}
|
||||
const GLint zoffset = 0;
|
||||
framebuffer_texture(2, target, attachment, textarget, texture,
|
||||
level, zoffset);
|
||||
}
|
||||
|
||||
|
||||
@@ -1288,54 +1338,12 @@ _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture,
|
||||
GLint level, GLint zoffset)
|
||||
{
|
||||
struct gl_renderbuffer_attachment *att;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (error_check_framebuffer_texture(ctx, 3, target, attachment,
|
||||
textarget, texture, level))
|
||||
return;
|
||||
|
||||
ASSERT(textarget == GL_TEXTURE_3D);
|
||||
|
||||
att = _mesa_get_attachment(ctx, ctx->DrawBuffer, attachment);
|
||||
if (att == NULL) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture1DEXT(attachment)");
|
||||
return;
|
||||
}
|
||||
|
||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||
|
||||
if (texture) {
|
||||
const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
|
||||
struct gl_texture_object *texObj = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
||||
if (!texObj) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture3DEXT(texture)");
|
||||
return;
|
||||
}
|
||||
if (texObj->Target != textarget) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
|
||||
"glFramebufferTexture3DEXT(texture target)");
|
||||
return;
|
||||
}
|
||||
if (zoffset < 0 || zoffset >= maxSize) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture3DEXT(zoffset)");
|
||||
return;
|
||||
}
|
||||
_mesa_set_texture_attachment(ctx, ctx->DrawBuffer, att,
|
||||
texObj, textarget, level,zoffset);
|
||||
}
|
||||
else {
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
}
|
||||
framebuffer_texture(3, target, attachment, textarget, texture,
|
||||
level, zoffset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
|
||||
GLenum renderbufferTarget,
|
||||
@@ -1396,7 +1404,7 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
|
||||
}
|
||||
|
||||
if (renderbuffer) {
|
||||
rb = lookup_renderbuffer(ctx, renderbuffer);
|
||||
rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
|
||||
if (!rb) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferRenderbufferEXT(renderbuffer)");
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
|
||||
* 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"),
|
||||
@@ -27,6 +27,12 @@
|
||||
#define FBOBJECT_H
|
||||
|
||||
|
||||
extern struct gl_renderbuffer *
|
||||
_mesa_lookup_renderbuffer(GLcontext *ctx, GLuint id);
|
||||
|
||||
extern struct gl_framebuffer *
|
||||
_mesa_lookup_framebuffer(GLcontext *ctx, GLuint id);
|
||||
|
||||
extern struct gl_renderbuffer_attachment *
|
||||
_mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
GLenum attachment);
|
||||
|
@@ -69,6 +69,48 @@ compute_depth_max(struct gl_framebuffer *fb)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the framebuffer's _DepthBuffer field, taking 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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the framebuffer's _StencilBuffer field, taking care of
|
||||
* reference counts, etc.
|
||||
*/
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create and initialize a gl_framebuffer object.
|
||||
* This is intended for creating _window_system_ framebuffers, not generic
|
||||
@@ -127,6 +169,8 @@ _mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual)
|
||||
|
||||
_mesa_bzero(fb, sizeof(struct gl_framebuffer));
|
||||
|
||||
_glthread_INIT_MUTEX(fb->Mutex);
|
||||
|
||||
/* save the visual */
|
||||
fb->Visual = *visual;
|
||||
|
||||
@@ -159,6 +203,7 @@ void
|
||||
_mesa_destroy_framebuffer(struct gl_framebuffer *fb)
|
||||
{
|
||||
if (fb) {
|
||||
_glthread_DESTROY_MUTEX(fb->Mutex);
|
||||
_mesa_free_framebuffer_data(fb);
|
||||
_mesa_free(fb);
|
||||
}
|
||||
@@ -180,7 +225,9 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
|
||||
struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
|
||||
if (att->Renderbuffer) {
|
||||
struct gl_renderbuffer *rb = att->Renderbuffer;
|
||||
_glthread_LOCK_MUTEX(rb->Mutex);
|
||||
rb->RefCount--;
|
||||
_glthread_UNLOCK_MUTEX(rb->Mutex);
|
||||
if (rb->RefCount == 0) {
|
||||
rb->Delete(rb);
|
||||
}
|
||||
@@ -189,22 +236,9 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
|
||||
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;
|
||||
}
|
||||
/* unbind depth/stencil to decr ref counts */
|
||||
set_depth_renderbuffer(fb, NULL);
|
||||
set_stencil_renderbuffer(fb, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -224,6 +258,10 @@ _mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
/* XXX I think we could check if the size is not changing
|
||||
* and return early.
|
||||
*/
|
||||
|
||||
/* For window system framebuffers, Name is zero */
|
||||
assert(fb->Name == 0);
|
||||
|
||||
@@ -233,23 +271,42 @@ _mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer *rb = att->Renderbuffer;
|
||||
/* only resize if size is changing */
|
||||
if (rb->Width != width || rb->Height != height) {
|
||||
/* could just as well pass rb->_ActualFormat here */
|
||||
if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
|
||||
rb->Width = width;
|
||||
rb->Height = height;
|
||||
ASSERT(rb->Width == width);
|
||||
ASSERT(rb->Height == height);
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
|
||||
/* no return */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fb->_DepthBuffer) {
|
||||
struct gl_renderbuffer *rb = fb->_DepthBuffer;
|
||||
if (rb->Width != width || rb->Height != height) {
|
||||
if (!rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fb->_StencilBuffer) {
|
||||
struct gl_renderbuffer *rb = fb->_StencilBuffer;
|
||||
if (rb->Width != width || rb->Height != height) {
|
||||
if (!rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fb->Width = width;
|
||||
fb->Height = height;
|
||||
|
||||
/* to update scissor / window bounds */
|
||||
if (ctx)
|
||||
ctx->NewState |= _NEW_BUFFERS;
|
||||
_mesa_update_draw_buffer_bounds(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -400,41 +457,139 @@ _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.
|
||||
* 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
|
||||
* \param attIndex indicates the renderbuffer to possibly wrap
|
||||
*/
|
||||
static void
|
||||
set_depth_renderbuffer(struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer *rb)
|
||||
void
|
||||
_mesa_update_depth_buffer(GLcontext *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
GLuint attIndex)
|
||||
{
|
||||
if (fb->_DepthBuffer) {
|
||||
fb->_DepthBuffer->RefCount--;
|
||||
if (fb->_DepthBuffer->RefCount <= 0) {
|
||||
fb->_DepthBuffer->Delete(fb->_DepthBuffer);
|
||||
struct gl_renderbuffer *depthRb;
|
||||
|
||||
/* only one possiblity for now */
|
||||
ASSERT(attIndex == BUFFER_DEPTH);
|
||||
|
||||
depthRb = fb->Attachment[attIndex].Renderbuffer;
|
||||
|
||||
if (depthRb && depthRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
|
||||
/* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */
|
||||
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);
|
||||
}
|
||||
}
|
||||
fb->_DepthBuffer = rb;
|
||||
if (rb)
|
||||
rb->RefCount++;
|
||||
else {
|
||||
/* depthRb may be null */
|
||||
set_depth_renderbuffer(fb, depthRb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \sa set_depth_renderbuffer.
|
||||
* 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
|
||||
* \param attIndex indicates the renderbuffer to possibly wrap
|
||||
*/
|
||||
static void
|
||||
set_stencil_renderbuffer(struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer *rb)
|
||||
void
|
||||
_mesa_update_stencil_buffer(GLcontext *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
GLuint attIndex)
|
||||
{
|
||||
if (fb->_StencilBuffer) {
|
||||
fb->_StencilBuffer->RefCount--;
|
||||
if (fb->_StencilBuffer->RefCount <= 0) {
|
||||
fb->_StencilBuffer->Delete(fb->_StencilBuffer);
|
||||
struct gl_renderbuffer *stencilRb;
|
||||
|
||||
ASSERT(attIndex == BUFFER_DEPTH ||
|
||||
attIndex == BUFFER_STENCIL);
|
||||
|
||||
stencilRb = fb->Attachment[attIndex].Renderbuffer;
|
||||
|
||||
if (stencilRb && stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
|
||||
/* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */
|
||||
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);
|
||||
}
|
||||
}
|
||||
fb->_StencilBuffer = rb;
|
||||
if (rb)
|
||||
rb->RefCount++;
|
||||
else {
|
||||
/* stencilRb may be null */
|
||||
set_stencil_renderbuffer(fb, stencilRb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the list of color drawing renderbuffer pointers.
|
||||
* Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
|
||||
* writing colors.
|
||||
*/
|
||||
static void
|
||||
update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
{
|
||||
GLuint output;
|
||||
|
||||
/*
|
||||
* Fragment programs can write to multiple colorbuffers with
|
||||
* the GL_ARB_draw_buffers extension.
|
||||
*/
|
||||
for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
|
||||
GLbitfield bufferMask = fb->_ColorDrawBufferMask[output];
|
||||
GLuint count = 0;
|
||||
GLuint i;
|
||||
/* We need the inner loop here because glDrawBuffer(GL_FRONT_AND_BACK)
|
||||
* can specify writing to two or four color buffers (for example).
|
||||
*/
|
||||
for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
|
||||
const GLuint bufferBit = 1 << i;
|
||||
if (bufferBit & bufferMask) {
|
||||
struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
|
||||
if (rb) {
|
||||
fb->_ColorDrawBuffers[output][count] = rb;
|
||||
count++;
|
||||
}
|
||||
else {
|
||||
/*_mesa_warning(ctx, "DrawBuffer names a missing buffer!\n");*/
|
||||
}
|
||||
bufferMask &= ~bufferBit;
|
||||
}
|
||||
}
|
||||
fb->_NumColorDrawBuffers[output] = count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the color read renderbuffer pointer.
|
||||
* Unlike the DrawBuffer, we can only read from one (or zero) color buffers.
|
||||
*/
|
||||
static void
|
||||
update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
{
|
||||
if (fb->_ColorReadBufferIndex == -1) {
|
||||
fb->_ColorReadBuffer = NULL; /* legal! */
|
||||
}
|
||||
else {
|
||||
ASSERT(fb->_ColorReadBufferIndex >= 0);
|
||||
ASSERT(fb->_ColorReadBufferIndex < BUFFER_COUNT);
|
||||
fb->_ColorReadBuffer
|
||||
= fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -455,7 +610,6 @@ void
|
||||
_mesa_update_framebuffer(GLcontext *ctx)
|
||||
{
|
||||
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||
GLuint output;
|
||||
|
||||
/* Completeness only matters for user-created framebuffers */
|
||||
if (fb->Name != 0) {
|
||||
@@ -463,90 +617,10 @@ _mesa_update_framebuffer(GLcontext *ctx)
|
||||
_mesa_update_framebuffer_visual(fb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the list of color drawing renderbuffer pointers.
|
||||
* Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
|
||||
* writing colors. We need the inner loop here because
|
||||
* glDrawBuffer(GL_FRONT_AND_BACK) can specify writing to two or four
|
||||
* color buffers (for example).
|
||||
*/
|
||||
for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
|
||||
GLbitfield bufferMask = fb->_ColorDrawBufferMask[output];
|
||||
GLuint count = 0;
|
||||
GLuint i;
|
||||
for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
|
||||
const GLuint bufferBit = 1 << i;
|
||||
if (bufferBit & bufferMask) {
|
||||
struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
|
||||
if (rb) {
|
||||
fb->_ColorDrawBuffers[output][count] = rb;
|
||||
count++;
|
||||
}
|
||||
else {
|
||||
/*_mesa_warning(ctx, "DrawBuffer names a missing buffer!\n");*/
|
||||
}
|
||||
bufferMask &= ~bufferBit;
|
||||
}
|
||||
}
|
||||
fb->_NumColorDrawBuffers[output] = count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the color read renderbuffer pointer.
|
||||
* Unlike the DrawBuffer, we can only read from one (or zero) color buffers.
|
||||
*/
|
||||
if (fb->_ColorReadBufferIndex == -1) {
|
||||
fb->_ColorReadBuffer = NULL; /* legal! */
|
||||
}
|
||||
else {
|
||||
ASSERT(fb->_ColorReadBufferIndex >= 0);
|
||||
ASSERT(fb->_ColorReadBufferIndex < BUFFER_COUNT);
|
||||
fb->_ColorReadBuffer
|
||||
= fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deal with GL_DEPTH_STENCIL renderbuffer(s) attached to the depth
|
||||
* and/or stencil attachment points. If either of the DEPTH or STENCIL
|
||||
* renderbuffer attachments are GL_DEPTH_STENCIL buffers, we need to set
|
||||
* up depth/stencil renderbuffer wrappers.
|
||||
*/
|
||||
{
|
||||
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) {
|
||||
/* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */
|
||||
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) {
|
||||
/* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */
|
||||
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);
|
||||
}
|
||||
}
|
||||
update_color_draw_buffers(ctx, fb);
|
||||
update_color_read_buffer(ctx, fb);
|
||||
_mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH);
|
||||
_mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL);
|
||||
|
||||
compute_depth_max(fb);
|
||||
}
|
||||
|
@@ -52,6 +52,14 @@ _mesa_update_draw_buffer_bounds(GLcontext *ctx);
|
||||
extern void
|
||||
_mesa_update_framebuffer_visual(struct gl_framebuffer *fb);
|
||||
|
||||
extern void
|
||||
_mesa_update_depth_buffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
GLuint attIndex);
|
||||
|
||||
extern void
|
||||
_mesa_update_stencil_buffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
GLuint attIndex);
|
||||
|
||||
extern void
|
||||
_mesa_update_framebuffer(GLcontext *ctx);
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
|
||||
* 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"),
|
||||
@@ -4312,3 +4312,43 @@ _mesa_clip_readpixels(const GLcontext *ctx,
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clip the rectangle defined by (x, y, width, height) against the bounds
|
||||
* specified by [xmin, xmax) and [ymin, ymax).
|
||||
* \return GL_FALSE if rect is totally clipped, GL_TRUE otherwise.
|
||||
*/
|
||||
GLboolean
|
||||
_mesa_clip_to_region(GLint xmin, GLint ymin,
|
||||
GLint xmax, GLint ymax,
|
||||
GLint *x, GLint *y,
|
||||
GLsizei *width, GLsizei *height )
|
||||
{
|
||||
/* left clipping */
|
||||
if (*x < xmin) {
|
||||
*width -= (xmin - *x);
|
||||
*x = xmin;
|
||||
}
|
||||
|
||||
/* right clipping */
|
||||
if (*x + *width > xmax)
|
||||
*width -= (*x + *width - xmax - 1);
|
||||
|
||||
if (*width <= 0)
|
||||
return GL_FALSE;
|
||||
|
||||
/* bottom (or top) clipping */
|
||||
if (*y < ymin) {
|
||||
*height -= (ymin - *y);
|
||||
*y = ymin;
|
||||
}
|
||||
|
||||
/* top (or bottom) clipping */
|
||||
if (*y + *height > ymax)
|
||||
*height -= (*y + *height - ymax - 1);
|
||||
|
||||
if (*height <= 0)
|
||||
return GL_FALSE;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
|
||||
* 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"),
|
||||
@@ -216,5 +216,10 @@ _mesa_clip_readpixels(const GLcontext *ctx,
|
||||
GLsizei *width, GLsizei *height,
|
||||
struct gl_pixelstore_attrib *pack);
|
||||
|
||||
extern GLboolean
|
||||
_mesa_clip_to_region(GLint xmin, GLint ymin,
|
||||
GLint xmax, GLint ymax,
|
||||
GLint *x, GLint *y,
|
||||
GLsizei *width, GLsizei *height );
|
||||
|
||||
#endif
|
||||
|
@@ -319,6 +319,28 @@ enum {
|
||||
#define BUFFER_BIT_COLOR6 (1 << BUFFER_COLOR6)
|
||||
#define BUFFER_BIT_COLOR7 (1 << BUFFER_COLOR7)
|
||||
|
||||
/**
|
||||
* Mask of all the color buffer bits (but not accum).
|
||||
*/
|
||||
#define BUFFER_BITS_COLOR (BUFFER_BIT_FRONT_LEFT | \
|
||||
BUFFER_BIT_BACK_LEFT | \
|
||||
BUFFER_BIT_FRONT_RIGHT | \
|
||||
BUFFER_BIT_BACK_RIGHT | \
|
||||
BUFFER_BIT_AUX0 | \
|
||||
BUFFER_BIT_AUX1 | \
|
||||
BUFFER_BIT_AUX2 | \
|
||||
BUFFER_BIT_AUX3 | \
|
||||
BUFFER_BIT_COLOR0 | \
|
||||
BUFFER_BIT_COLOR1 | \
|
||||
BUFFER_BIT_COLOR2 | \
|
||||
BUFFER_BIT_COLOR3 | \
|
||||
BUFFER_BIT_COLOR4 | \
|
||||
BUFFER_BIT_COLOR5 | \
|
||||
BUFFER_BIT_COLOR6 | \
|
||||
BUFFER_BIT_COLOR7)
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Data structure for color tables
|
||||
@@ -1232,6 +1254,7 @@ struct gl_texture_image
|
||||
GLuint Height; /**< = 2^HeightLog2 + 2*Border */
|
||||
GLuint Depth; /**< = 2^DepthLog2 + 2*Border */
|
||||
GLuint RowStride; /**< == Width unless IsClientData and padded */
|
||||
GLuint ImageStride; /**< Stride between images, in texels */
|
||||
GLuint Width2; /**< = Width - 2*Border */
|
||||
GLuint Height2; /**< = Height - 2*Border */
|
||||
GLuint Depth2; /**< = Depth - 2*Border */
|
||||
@@ -2024,14 +2047,17 @@ struct gl_shared_state
|
||||
*/
|
||||
struct gl_renderbuffer
|
||||
{
|
||||
_glthread_Mutex Mutex; /**< for thread safety */
|
||||
GLuint ClassID; /**< Useful for drivers */
|
||||
GLuint Name;
|
||||
GLint RefCount;
|
||||
GLuint Width, Height;
|
||||
GLenum InternalFormat; /* The user-specified value */
|
||||
GLenum _BaseFormat; /* Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or */
|
||||
/* GL_STENCIL_INDEX. */
|
||||
GLenum DataType; /* Type of values passed to the Get/Put functions */
|
||||
GLubyte RedBits; /**< Bits per image component */
|
||||
GLenum InternalFormat; /**< The user-specified format */
|
||||
GLenum _ActualFormat; /**< The driver-chosen format */
|
||||
GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or
|
||||
GL_STENCIL_INDEX. */
|
||||
GLenum DataType; /**< Type of values passed to the Get/Put functions */
|
||||
GLubyte RedBits; /**< Bits of red per pixel */
|
||||
GLubyte GreenBits;
|
||||
GLubyte BlueBits;
|
||||
GLubyte AlphaBits;
|
||||
@@ -2139,6 +2165,7 @@ struct gl_renderbuffer_attachment
|
||||
*/
|
||||
struct gl_framebuffer
|
||||
{
|
||||
_glthread_Mutex Mutex; /**< for thread safety */
|
||||
GLuint Name; /* if zero, this is a window system framebuffer */
|
||||
GLint RefCount;
|
||||
|
||||
|
@@ -70,6 +70,9 @@ get_pointer_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
if (!rb->Data)
|
||||
return NULL;
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
/* Can't assert _ActualFormat since these funcs may be used for serveral
|
||||
* different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
|
||||
*/
|
||||
return (GLubyte *) rb->Data + y * rb->Width + x;
|
||||
}
|
||||
|
||||
@@ -90,7 +93,7 @@ get_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
{
|
||||
GLubyte *dst = (GLubyte *) values;
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
for (i = 0; i < count; i++) {
|
||||
const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
|
||||
dst[i] = *src;
|
||||
@@ -104,7 +107,7 @@ put_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
{
|
||||
const GLubyte *src = (const GLubyte *) values;
|
||||
GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
if (mask) {
|
||||
GLuint i;
|
||||
for (i = 0; i < count; i++) {
|
||||
@@ -125,7 +128,7 @@ put_mono_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
{
|
||||
const GLubyte val = *((const GLubyte *) value);
|
||||
GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
if (mask) {
|
||||
GLuint i;
|
||||
for (i = 0; i < count; i++) {
|
||||
@@ -150,7 +153,7 @@ put_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
{
|
||||
const GLubyte *src = (const GLubyte *) values;
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!mask || mask[i]) {
|
||||
GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
|
||||
@@ -167,7 +170,7 @@ put_mono_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
{
|
||||
const GLubyte val = *((const GLubyte *) value);
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!mask || mask[i]) {
|
||||
GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
|
||||
@@ -443,6 +446,7 @@ static void *
|
||||
get_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
GLint x, GLint y)
|
||||
{
|
||||
ASSERT(rb->_ActualFormat == GL_RGB8);
|
||||
/* No direct access since this buffer is RGB but caller will be
|
||||
* treating it as if it were RGBA.
|
||||
*/
|
||||
@@ -457,6 +461,7 @@ get_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x);
|
||||
GLubyte *dst = (GLubyte *) values;
|
||||
GLuint i;
|
||||
ASSERT(rb->_ActualFormat == GL_RGB8);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
for (i = 0; i < count; i++) {
|
||||
dst[i * 4 + 0] = src[i * 3 + 0];
|
||||
@@ -473,7 +478,8 @@ get_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
{
|
||||
GLubyte *dst = (GLubyte *) values;
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGB8);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
for (i = 0; i < count; i++) {
|
||||
const GLubyte *src
|
||||
= (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
|
||||
@@ -493,7 +499,8 @@ put_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
const GLubyte *src = (const GLubyte *) values;
|
||||
GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGB8);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!mask || mask[i]) {
|
||||
dst[i * 3 + 0] = src[i * 4 + 0];
|
||||
@@ -512,7 +519,8 @@ put_row_rgb_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
const GLubyte *src = (const GLubyte *) values;
|
||||
GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGB8);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!mask || mask[i]) {
|
||||
dst[i * 3 + 0] = src[i * 3 + 0];
|
||||
@@ -532,7 +540,8 @@ put_mono_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
const GLubyte val1 = ((const GLubyte *) value)[1];
|
||||
const GLubyte val2 = ((const GLubyte *) value)[2];
|
||||
GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGB8);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
if (!mask && val0 == val1 && val1 == val2) {
|
||||
/* optimized case */
|
||||
_mesa_memset(dst, val0, 3 * count);
|
||||
@@ -558,7 +567,8 @@ put_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
/* note: incoming values are RGB+A! */
|
||||
const GLubyte *src = (const GLubyte *) values;
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGB8);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!mask || mask[i]) {
|
||||
GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
|
||||
@@ -580,7 +590,8 @@ put_mono_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
const GLubyte val1 = ((const GLubyte *) value)[1];
|
||||
const GLubyte val2 = ((const GLubyte *) value)[2];
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGB8);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!mask || mask[i]) {
|
||||
GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
|
||||
@@ -604,6 +615,7 @@ get_pointer_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
if (!rb->Data)
|
||||
return NULL;
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGBA8);
|
||||
return (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
|
||||
}
|
||||
|
||||
@@ -614,6 +626,7 @@ get_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
{
|
||||
const GLbyte *src = (const GLbyte *) rb->Data + 4 * (y * rb->Width + x);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGBA8);
|
||||
_mesa_memcpy(values, src, 4 * count * sizeof(GLbyte));
|
||||
}
|
||||
|
||||
@@ -625,7 +638,8 @@ get_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
/* treat 4*GLubyte as 1*GLuint */
|
||||
GLuint *dst = (GLuint *) values;
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGBA8);
|
||||
for (i = 0; i < count; i++) {
|
||||
const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
|
||||
dst[i] = *src;
|
||||
@@ -640,7 +654,8 @@ put_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
/* treat 4*GLubyte as 1*GLuint */
|
||||
const GLuint *src = (const GLuint *) values;
|
||||
GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGBA8);
|
||||
if (mask) {
|
||||
GLuint i;
|
||||
for (i = 0; i < count; i++) {
|
||||
@@ -663,7 +678,8 @@ put_row_rgb_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
const GLubyte *src = (const GLubyte *) values;
|
||||
GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGBA8);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!mask || mask[i]) {
|
||||
dst[i * 4 + 0] = src[i * 3 + 0];
|
||||
@@ -682,7 +698,8 @@ put_mono_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
/* treat 4*GLubyte as 1*GLuint */
|
||||
const GLuint val = *((const GLuint *) value);
|
||||
GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGBA8);
|
||||
if (!mask && val == 0) {
|
||||
/* common case */
|
||||
_mesa_bzero(dst, count * 4 * sizeof(GLubyte));
|
||||
@@ -715,7 +732,8 @@ put_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
|
||||
/* treat 4*GLubyte as 1*GLuint */
|
||||
const GLuint *src = (const GLuint *) values;
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGBA8);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!mask || mask[i]) {
|
||||
GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
|
||||
@@ -733,7 +751,8 @@ put_mono_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
/* treat 4*GLubyte as 1*GLuint */
|
||||
const GLuint val = *((const GLuint *) value);
|
||||
GLuint i;
|
||||
assert(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
|
||||
ASSERT(rb->_ActualFormat == GL_RGBA8);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!mask || mask[i]) {
|
||||
GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
|
||||
@@ -919,9 +938,10 @@ put_mono_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
* This function also plugs in the appropriate GetPointer, Get/PutRow and
|
||||
* Get/PutValues functions.
|
||||
*/
|
||||
static GLboolean
|
||||
soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
GLenum internalFormat, GLuint width, GLuint height)
|
||||
GLboolean
|
||||
_mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
GLenum internalFormat,
|
||||
GLuint width, GLuint height)
|
||||
{
|
||||
GLuint pixelSize;
|
||||
|
||||
@@ -943,6 +963,7 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
case GL_RGB10:
|
||||
case GL_RGB12:
|
||||
case GL_RGB16:
|
||||
rb->_ActualFormat = GL_RGB8;
|
||||
rb->_BaseFormat = GL_RGB;
|
||||
rb->DataType = GL_UNSIGNED_BYTE;
|
||||
rb->GetPointer = get_pointer_ubyte3;
|
||||
@@ -964,6 +985,7 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
case GL_RGBA4:
|
||||
case GL_RGB5_A1:
|
||||
case GL_RGBA8:
|
||||
rb->_ActualFormat = GL_RGBA8;
|
||||
rb->_BaseFormat = GL_RGBA;
|
||||
rb->DataType = GL_UNSIGNED_BYTE;
|
||||
rb->GetPointer = get_pointer_ubyte4;
|
||||
@@ -983,6 +1005,7 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
case GL_RGB10_A2:
|
||||
case GL_RGBA12:
|
||||
case GL_RGBA16:
|
||||
rb->_ActualFormat = GL_RGBA16;
|
||||
rb->_BaseFormat = GL_RGBA;
|
||||
rb->DataType = GL_UNSIGNED_SHORT;
|
||||
rb->GetPointer = get_pointer_ushort4;
|
||||
@@ -1000,7 +1023,8 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
pixelSize = 4 * sizeof(GLushort);
|
||||
break;
|
||||
#if 00
|
||||
case ALPHA8:
|
||||
case GL_ALPHA8:
|
||||
rb->_ActualFormat = GL_ALPHA8;
|
||||
rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */
|
||||
rb->DataType = GL_UNSIGNED_BYTE;
|
||||
rb->GetPointer = get_pointer_alpha8;
|
||||
@@ -1022,6 +1046,7 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
case GL_STENCIL_INDEX1_EXT:
|
||||
case GL_STENCIL_INDEX4_EXT:
|
||||
case GL_STENCIL_INDEX8_EXT:
|
||||
rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
|
||||
rb->_BaseFormat = GL_STENCIL_INDEX;
|
||||
rb->DataType = GL_UNSIGNED_BYTE;
|
||||
rb->GetPointer = get_pointer_ubyte;
|
||||
@@ -1036,6 +1061,7 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
pixelSize = sizeof(GLubyte);
|
||||
break;
|
||||
case GL_STENCIL_INDEX16_EXT:
|
||||
rb->_ActualFormat = GL_STENCIL_INDEX16_EXT;
|
||||
rb->_BaseFormat = GL_STENCIL_INDEX;
|
||||
rb->DataType = GL_UNSIGNED_SHORT;
|
||||
rb->GetPointer = get_pointer_ushort;
|
||||
@@ -1051,6 +1077,7 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
break;
|
||||
case GL_DEPTH_COMPONENT:
|
||||
case GL_DEPTH_COMPONENT16:
|
||||
rb->_ActualFormat = GL_DEPTH_COMPONENT16;
|
||||
rb->_BaseFormat = GL_DEPTH_COMPONENT;
|
||||
rb->DataType = GL_UNSIGNED_SHORT;
|
||||
rb->GetPointer = get_pointer_ushort;
|
||||
@@ -1076,14 +1103,19 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
rb->PutMonoRow = put_mono_row_uint;
|
||||
rb->PutValues = put_values_uint;
|
||||
rb->PutMonoValues = put_mono_values_uint;
|
||||
if (internalFormat == GL_DEPTH_COMPONENT24)
|
||||
if (internalFormat == GL_DEPTH_COMPONENT24) {
|
||||
rb->_ActualFormat = GL_DEPTH_COMPONENT24;
|
||||
rb->DepthBits = 24;
|
||||
else
|
||||
}
|
||||
else {
|
||||
rb->_ActualFormat = GL_DEPTH_COMPONENT32;
|
||||
rb->DepthBits = 32;
|
||||
}
|
||||
pixelSize = sizeof(GLuint);
|
||||
break;
|
||||
case GL_DEPTH_STENCIL_EXT:
|
||||
case GL_DEPTH24_STENCIL8_EXT:
|
||||
rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
|
||||
rb->_BaseFormat = GL_DEPTH_STENCIL_EXT;
|
||||
rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
|
||||
rb->GetPointer = get_pointer_uint;
|
||||
@@ -1099,6 +1131,7 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
pixelSize = sizeof(GLuint);
|
||||
break;
|
||||
case GL_COLOR_INDEX8_EXT:
|
||||
rb->_ActualFormat = GL_COLOR_INDEX8_EXT;
|
||||
rb->_BaseFormat = GL_COLOR_INDEX;
|
||||
rb->DataType = GL_UNSIGNED_BYTE;
|
||||
rb->GetPointer = get_pointer_ubyte;
|
||||
@@ -1113,6 +1146,7 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
pixelSize = sizeof(GLubyte);
|
||||
break;
|
||||
case GL_COLOR_INDEX16_EXT:
|
||||
rb->_ActualFormat = GL_COLOR_INDEX16_EXT;
|
||||
rb->_BaseFormat = GL_COLOR_INDEX;
|
||||
rb->DataType = GL_UNSIGNED_SHORT;
|
||||
rb->GetPointer = get_pointer_ushort;
|
||||
@@ -1127,6 +1161,7 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
pixelSize = sizeof(GLushort);
|
||||
break;
|
||||
case COLOR_INDEX32:
|
||||
rb->_ActualFormat = COLOR_INDEX32;
|
||||
rb->_BaseFormat = GL_COLOR_INDEX;
|
||||
rb->DataType = GL_UNSIGNED_INT;
|
||||
rb->GetPointer = get_pointer_uint;
|
||||
@@ -1141,7 +1176,7 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
pixelSize = sizeof(GLuint);
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(ctx, "Bad internalFormat in soft_renderbuffer_storage");
|
||||
_mesa_problem(ctx, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
@@ -1171,7 +1206,6 @@ soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
|
||||
rb->Width = width;
|
||||
rb->Height = height;
|
||||
rb->InternalFormat = internalFormat;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
@@ -1198,6 +1232,7 @@ alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
|
||||
GLenum internalFormat, GLuint width, GLuint height)
|
||||
{
|
||||
ASSERT(arb != arb->Wrapped);
|
||||
ASSERT(arb->_ActualFormat == GL_ALPHA8);
|
||||
|
||||
/* first, pass the call to the wrapped RGB buffer */
|
||||
if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat,
|
||||
@@ -1220,7 +1255,6 @@ alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
|
||||
|
||||
arb->Width = width;
|
||||
arb->Height = height;
|
||||
arb->InternalFormat = internalFormat;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
@@ -1418,6 +1452,9 @@ nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
|
||||
void
|
||||
_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
|
||||
{
|
||||
_glthread_INIT_MUTEX(rb->Mutex);
|
||||
|
||||
rb->ClassID = 0;
|
||||
rb->Name = name;
|
||||
rb->RefCount = 1;
|
||||
rb->Delete = _mesa_delete_renderbuffer;
|
||||
@@ -1430,6 +1467,7 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
|
||||
rb->Width = 0;
|
||||
rb->Height = 0;
|
||||
rb->InternalFormat = GL_NONE;
|
||||
rb->_ActualFormat = GL_NONE;
|
||||
rb->_BaseFormat = GL_NONE;
|
||||
rb->DataType = GL_NONE;
|
||||
rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = 0;
|
||||
@@ -1479,6 +1517,7 @@ _mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
|
||||
if (rb->Data) {
|
||||
_mesa_free(rb->Data);
|
||||
}
|
||||
_glthread_INIT_MUTEX(rb->Mutex);
|
||||
_mesa_free(rb);
|
||||
}
|
||||
|
||||
@@ -1494,9 +1533,9 @@ _mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name)
|
||||
{
|
||||
struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
|
||||
if (rb) {
|
||||
rb->AllocStorage = soft_renderbuffer_storage;
|
||||
rb->AllocStorage = _mesa_soft_renderbuffer_storage;
|
||||
/* Normally, one would setup the PutRow, GetRow, etc functions here.
|
||||
* But we're doing that in the soft_renderbuffer_storage() function
|
||||
* But we're doing that in the _mesa_soft_renderbuffer_storage() function
|
||||
* instead.
|
||||
*/
|
||||
}
|
||||
@@ -1550,19 +1589,20 @@ _mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
|
||||
if (rgbBits <= 8) {
|
||||
if (alphaBits)
|
||||
rb->InternalFormat = GL_RGBA8;
|
||||
rb->_ActualFormat = GL_RGBA8;
|
||||
else
|
||||
rb->InternalFormat = GL_RGB8;
|
||||
rb->_ActualFormat = GL_RGB8;
|
||||
}
|
||||
else {
|
||||
assert(rgbBits <= 16);
|
||||
if (alphaBits)
|
||||
rb->InternalFormat = GL_RGBA16;
|
||||
rb->_ActualFormat = GL_RGBA16;
|
||||
else
|
||||
rb->InternalFormat = GL_RGBA16; /* don't really have RGB16 yet */
|
||||
rb->_ActualFormat = GL_RGBA16; /* don't really have RGB16 yet */
|
||||
}
|
||||
rb->InternalFormat = rb->_ActualFormat;
|
||||
|
||||
rb->AllocStorage = soft_renderbuffer_storage;
|
||||
rb->AllocStorage = _mesa_soft_renderbuffer_storage;
|
||||
_mesa_add_renderbuffer(fb, b, rb);
|
||||
}
|
||||
|
||||
@@ -1617,12 +1657,14 @@ _mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
if (indexBits <= 8) {
|
||||
/* only support GLuint for now */
|
||||
/*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
|
||||
rb->InternalFormat = COLOR_INDEX32;
|
||||
rb->_ActualFormat = COLOR_INDEX32;
|
||||
}
|
||||
else {
|
||||
rb->InternalFormat = COLOR_INDEX32;
|
||||
rb->_ActualFormat = COLOR_INDEX32;
|
||||
}
|
||||
rb->AllocStorage = soft_renderbuffer_storage;
|
||||
rb->InternalFormat = rb->_ActualFormat;
|
||||
|
||||
rb->AllocStorage = _mesa_soft_renderbuffer_storage;
|
||||
_mesa_add_renderbuffer(fb, b, rb);
|
||||
}
|
||||
|
||||
@@ -1693,6 +1735,7 @@ _mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
* values.
|
||||
*/
|
||||
arb->InternalFormat = arb->Wrapped->InternalFormat;
|
||||
arb->_ActualFormat = GL_ALPHA8;
|
||||
arb->_BaseFormat = arb->Wrapped->_BaseFormat;
|
||||
arb->DataType = arb->Wrapped->DataType;
|
||||
arb->AllocStorage = alloc_storage_alpha8;
|
||||
@@ -1746,16 +1789,17 @@ _mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
}
|
||||
|
||||
if (depthBits <= 16) {
|
||||
rb->InternalFormat = GL_DEPTH_COMPONENT16;
|
||||
rb->_ActualFormat = GL_DEPTH_COMPONENT16;
|
||||
}
|
||||
else if (depthBits <= 24) {
|
||||
rb->InternalFormat = GL_DEPTH_COMPONENT24;
|
||||
rb->_ActualFormat = GL_DEPTH_COMPONENT24;
|
||||
}
|
||||
else {
|
||||
rb->InternalFormat = GL_DEPTH_COMPONENT32;
|
||||
rb->_ActualFormat = GL_DEPTH_COMPONENT32;
|
||||
}
|
||||
rb->InternalFormat = rb->_ActualFormat;
|
||||
|
||||
rb->AllocStorage = soft_renderbuffer_storage;
|
||||
rb->AllocStorage = _mesa_soft_renderbuffer_storage;
|
||||
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
|
||||
|
||||
return GL_TRUE;
|
||||
@@ -1791,14 +1835,15 @@ _mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
}
|
||||
|
||||
if (stencilBits <= 8) {
|
||||
rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
|
||||
rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
|
||||
}
|
||||
else {
|
||||
/* not really supported (see s_stencil.c code) */
|
||||
rb->InternalFormat = GL_STENCIL_INDEX16_EXT;
|
||||
rb->_ActualFormat = GL_STENCIL_INDEX16_EXT;
|
||||
}
|
||||
rb->InternalFormat = rb->_ActualFormat;
|
||||
|
||||
rb->AllocStorage = soft_renderbuffer_storage;
|
||||
rb->AllocStorage = _mesa_soft_renderbuffer_storage;
|
||||
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
|
||||
|
||||
return GL_TRUE;
|
||||
@@ -1834,8 +1879,9 @@ _mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
rb->_ActualFormat = GL_RGBA16;
|
||||
rb->InternalFormat = GL_RGBA16;
|
||||
rb->AllocStorage = soft_renderbuffer_storage;
|
||||
rb->AllocStorage = _mesa_soft_renderbuffer_storage;
|
||||
_mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
|
||||
|
||||
return GL_TRUE;
|
||||
@@ -1878,13 +1924,14 @@ _mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
}
|
||||
|
||||
if (colorBits <= 8) {
|
||||
rb->InternalFormat = GL_RGBA8;
|
||||
rb->_ActualFormat = GL_RGBA8;
|
||||
}
|
||||
else {
|
||||
rb->InternalFormat = GL_RGBA16;
|
||||
rb->_ActualFormat = GL_RGBA16;
|
||||
}
|
||||
rb->InternalFormat = rb->_ActualFormat;
|
||||
|
||||
rb->AllocStorage = soft_renderbuffer_storage;
|
||||
rb->AllocStorage = _mesa_soft_renderbuffer_storage;
|
||||
_mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
|
||||
}
|
||||
return GL_TRUE;
|
||||
@@ -2018,7 +2065,8 @@ _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name)
|
||||
|
||||
/* init fields not covered by _mesa_new_renderbuffer() */
|
||||
dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT;
|
||||
dsrb->AllocStorage = soft_renderbuffer_storage;
|
||||
dsrb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
|
||||
dsrb->AllocStorage = _mesa_soft_renderbuffer_storage;
|
||||
|
||||
return dsrb;
|
||||
}
|
||||
|
@@ -41,6 +41,11 @@ extern struct gl_renderbuffer *
|
||||
_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name);
|
||||
|
||||
|
||||
extern GLboolean
|
||||
_mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
GLenum internalFormat,
|
||||
GLuint width, GLuint height);
|
||||
|
||||
extern GLboolean
|
||||
_mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
GLuint rgbBits, GLuint alphaBits,
|
||||
|
@@ -117,6 +117,7 @@ static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img)
|
||||
_mesa_printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]);
|
||||
data += (img->RowStride - img->Width) * c;
|
||||
}
|
||||
/* XXX use img->ImageStride here */
|
||||
_mesa_printf("\n");
|
||||
}
|
||||
#endif
|
||||
@@ -1052,6 +1053,7 @@ clear_teximage_fields(struct gl_texture_image *img)
|
||||
img->Height = 0;
|
||||
img->Depth = 0;
|
||||
img->RowStride = 0;
|
||||
img->ImageStride = 0;
|
||||
img->Width2 = 0;
|
||||
img->Height2 = 0;
|
||||
img->Depth2 = 0;
|
||||
@@ -1097,6 +1099,7 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
|
||||
img->Height = height;
|
||||
img->Depth = depth;
|
||||
img->RowStride = width;
|
||||
img->ImageStride = width * height;
|
||||
img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */
|
||||
img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
|
||||
img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */
|
||||
@@ -2049,8 +2052,8 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
|
||||
GLenum type, GLvoid *pixels )
|
||||
{
|
||||
const struct gl_texture_unit *texUnit;
|
||||
const struct gl_texture_object *texObj;
|
||||
const struct gl_texture_image *texImage;
|
||||
struct gl_texture_object *texObj;
|
||||
struct gl_texture_image *texImage;
|
||||
GLint maxLevels = 0;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
||||
@@ -2169,7 +2172,7 @@ update_fbo_texture(GLcontext *ctx, struct gl_texture_object *texObj,
|
||||
att->CubeMapFace == face) {
|
||||
ASSERT(att->Texture->Image[att->CubeMapFace][att->TextureLevel]);
|
||||
/* Tell driver about the new renderbuffer texture */
|
||||
ctx->Driver.RenderbufferTexture(ctx, ctx->DrawBuffer, att);
|
||||
ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -50,6 +50,19 @@
|
||||
/** \name Internal functions */
|
||||
/*@{*/
|
||||
|
||||
|
||||
/**
|
||||
* Return the gl_texture_object for a given ID.
|
||||
*/
|
||||
struct gl_texture_object *
|
||||
_mesa_lookup_texture(GLcontext *ctx, GLuint id)
|
||||
{
|
||||
return (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new texture object. But don't put it into the
|
||||
* texture object hash table.
|
||||
@@ -682,8 +695,8 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (textures[i] > 0) {
|
||||
struct gl_texture_object *delObj = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, textures[i]);
|
||||
struct gl_texture_object *delObj
|
||||
= _mesa_lookup_texture(ctx, textures[i]);
|
||||
if (delObj) {
|
||||
|
||||
/* Check if texture is bound to any framebuffer objects.
|
||||
@@ -817,8 +830,7 @@ _mesa_BindTexture( GLenum target, GLuint texName )
|
||||
}
|
||||
else {
|
||||
/* non-default texture object */
|
||||
const struct _mesa_HashTable *hash = ctx->Shared->TexObjects;
|
||||
newTexObj = (struct gl_texture_object *) _mesa_HashLookup(hash, texName);
|
||||
newTexObj = _mesa_lookup_texture(ctx, texName);
|
||||
if (newTexObj) {
|
||||
/* error checking */
|
||||
if (newTexObj->Target != 0 && newTexObj->Target != target) {
|
||||
@@ -935,8 +947,7 @@ _mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (texName[i] > 0) {
|
||||
struct gl_texture_object *t = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, texName[i]);
|
||||
struct gl_texture_object *t = _mesa_lookup_texture(ctx, texName[i]);
|
||||
if (t) {
|
||||
t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );
|
||||
if (ctx->Driver.PrioritizeTexture)
|
||||
@@ -985,8 +996,7 @@ _mesa_AreTexturesResident(GLsizei n, const GLuint *texName,
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
|
||||
return GL_FALSE;
|
||||
}
|
||||
t = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, texName[i]);
|
||||
t = _mesa_lookup_texture(ctx, texName[i]);
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
|
||||
return GL_FALSE;
|
||||
@@ -1033,8 +1043,7 @@ _mesa_IsTexture( GLuint texture )
|
||||
if (!texture)
|
||||
return GL_FALSE;
|
||||
|
||||
t = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
||||
t = _mesa_lookup_texture(ctx, texture);
|
||||
|
||||
/* IsTexture is true only after object has been bound once. */
|
||||
return t && t->Target;
|
||||
|
@@ -5,9 +5,9 @@
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 4.1
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
|
||||
* 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"),
|
||||
@@ -40,6 +40,9 @@
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
extern struct gl_texture_object *
|
||||
_mesa_lookup_texture(GLcontext *ctx, GLuint id);
|
||||
|
||||
extern struct gl_texture_object *
|
||||
_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target );
|
||||
|
||||
|
@@ -163,7 +163,6 @@ wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
|
||||
|
||||
trb->Zoffset = att->Zoffset;
|
||||
|
||||
trb->Base.RefCount = 1;
|
||||
trb->Base.Width = trb->TexImage->Width;
|
||||
trb->Base.Height = trb->TexImage->Height;
|
||||
trb->Base.InternalFormat = trb->TexImage->InternalFormat; /* XXX fix? */
|
||||
@@ -195,12 +194,14 @@ wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
|
||||
trb->Base.DepthBits = trb->TexImage->TexFormat->DepthBits;
|
||||
|
||||
att->Renderbuffer = &(trb->Base);
|
||||
trb->Base.RefCount++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Called when rendering to a texture image begins.
|
||||
* Called when rendering to a texture image begins, or when changing
|
||||
* the dest mipmap level, cube face, etc.
|
||||
* This is a fallback routine for software render-to-texture.
|
||||
*
|
||||
* Called via the glRenderbufferTexture1D/2D/3D() functions
|
||||
@@ -216,9 +217,9 @@ wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
|
||||
* \sa _mesa_framebuffer_renderbuffer
|
||||
*/
|
||||
void
|
||||
_mesa_renderbuffer_texture(GLcontext *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer_attachment *att)
|
||||
_mesa_render_texture(GLcontext *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer_attachment *att)
|
||||
{
|
||||
struct gl_texture_image *newImage
|
||||
= att->Texture->Image[att->CubeMapFace][att->TextureLevel];
|
||||
@@ -241,3 +242,12 @@ _mesa_renderbuffer_texture(GLcontext *ctx,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_mesa_finish_render_texture(GLcontext *ctx,
|
||||
struct gl_renderbuffer_attachment *att)
|
||||
{
|
||||
/* do nothing */
|
||||
/* The renderbuffer texture wrapper will get deleted by the
|
||||
* normal mechanism for deleting renderbuffers.
|
||||
*/
|
||||
}
|
||||
|
@@ -3,9 +3,13 @@
|
||||
|
||||
|
||||
extern void
|
||||
_mesa_renderbuffer_texture(GLcontext *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer_attachment *att);
|
||||
_mesa_render_texture(GLcontext *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer_attachment *att);
|
||||
|
||||
extern void
|
||||
_mesa_finish_render_texture(GLcontext *ctx,
|
||||
struct gl_renderbuffer_attachment *att);
|
||||
|
||||
|
||||
#endif /* TEXRENDER_H */
|
||||
|
@@ -1222,6 +1222,43 @@ _mesa_texstore_argb8888(STORE_PARAMS)
|
||||
dstImage += dstImageStride;
|
||||
}
|
||||
}
|
||||
else if (!ctx->_ImageTransferState &&
|
||||
!srcPacking->SwapBytes &&
|
||||
dstFormat == &_mesa_texformat_argb8888 &&
|
||||
srcFormat == GL_RGBA &&
|
||||
(srcType == GL_UNSIGNED_BYTE && littleEndian)) {
|
||||
|
||||
int img, row, col;
|
||||
GLubyte *dstImage = (GLubyte *) dstAddr
|
||||
+ dstZoffset * dstImageStride
|
||||
+ dstYoffset * dstRowStride
|
||||
+ dstXoffset * dstFormat->TexelBytes;
|
||||
|
||||
/* For some reason, streaming copies to write-combined regions
|
||||
* are extremely sensitive to the characteristics of how the
|
||||
* source data is retrieved. By reordering the source reads to
|
||||
* be in-order, the speed of this operation increases by half.
|
||||
* Strangely the same isn't required for the RGB path, above.
|
||||
*/
|
||||
for (img = 0; img < srcDepth; img++) {
|
||||
const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
|
||||
srcWidth, srcFormat, srcType);
|
||||
GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
|
||||
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
|
||||
GLubyte *dstRow = dstImage;
|
||||
for (row = 0; row < srcHeight; row++) {
|
||||
for (col = 0; col < srcWidth; col++) {
|
||||
*(GLuint *)(dstRow + col * 4) = (srcRow[col * 4 + RCOMP] << 16 |
|
||||
srcRow[col * 4 + GCOMP] << 8 |
|
||||
srcRow[col * 4 + BCOMP] << 0 |
|
||||
srcRow[col * 4 + ACOMP] << 24);
|
||||
}
|
||||
dstRow += dstRowStride;
|
||||
srcRow += srcRowStride;
|
||||
}
|
||||
dstImage += dstImageStride;
|
||||
}
|
||||
}
|
||||
else if (!ctx->_ImageTransferState &&
|
||||
!srcPacking->SwapBytes &&
|
||||
dstFormat == &_mesa_texformat_argb8888 &&
|
||||
@@ -4039,8 +4076,8 @@ _mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
|
||||
void
|
||||
_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
|
||||
GLenum format, GLenum type, GLvoid *pixels,
|
||||
const struct gl_texture_object *texObj,
|
||||
const struct gl_texture_image *texImage)
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage)
|
||||
{
|
||||
GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
|
||||
|
||||
|
@@ -231,8 +231,8 @@ _mesa_upscale_teximage2d(GLsizei inWidth, GLsizei inHeight,
|
||||
extern void
|
||||
_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
|
||||
GLenum format, GLenum type, GLvoid *pixels,
|
||||
const struct gl_texture_object *texObj,
|
||||
const struct gl_texture_image *texImage);
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage);
|
||||
|
||||
|
||||
extern void
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "colormac.h"
|
||||
#include "mtypes.h"
|
||||
#include "program.h"
|
||||
#include "teximage.h"
|
||||
#include "swrast.h"
|
||||
#include "s_blend.h"
|
||||
#include "s_context.h"
|
||||
@@ -372,6 +373,83 @@ _swrast_validate_blend_func( GLcontext *ctx, GLuint n,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make sure we have texture image data for all the textures we may need
|
||||
* for subsequent rendering.
|
||||
*/
|
||||
static void
|
||||
_swrast_validate_texture_images(GLcontext *ctx)
|
||||
{
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
GLuint u;
|
||||
|
||||
if (!swrast->ValidateTextureImage || !ctx->Texture._EnabledUnits) {
|
||||
/* no textures enabled, or no way to validate images! */
|
||||
return;
|
||||
}
|
||||
|
||||
for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) {
|
||||
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
||||
struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current;
|
||||
ASSERT(texObj);
|
||||
if (texObj) {
|
||||
GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||
GLuint face;
|
||||
for (face = 0; face < numFaces; face++) {
|
||||
GLuint lvl;
|
||||
for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) {
|
||||
struct gl_texture_image *texImg = texObj->Image[face][lvl];
|
||||
if (texImg && !texImg->Data) {
|
||||
swrast->ValidateTextureImage(ctx, texObj, face, lvl);
|
||||
ASSERT(texObj->Image[face][lvl]->Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free the texture image data attached to all currently enabled
|
||||
* textures. Meant to be called by device drivers when transitioning
|
||||
* from software to hardware rendering.
|
||||
*/
|
||||
void
|
||||
_swrast_eject_texture_images(GLcontext *ctx)
|
||||
{
|
||||
GLuint u;
|
||||
|
||||
if (!ctx->Texture._EnabledUnits) {
|
||||
/* no textures enabled */
|
||||
return;
|
||||
}
|
||||
|
||||
for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) {
|
||||
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
||||
struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current;
|
||||
ASSERT(texObj);
|
||||
if (texObj) {
|
||||
GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||
GLuint face;
|
||||
for (face = 0; face < numFaces; face++) {
|
||||
GLuint lvl;
|
||||
for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) {
|
||||
struct gl_texture_image *texImg = texObj->Image[face][lvl];
|
||||
if (texImg && texImg->Data) {
|
||||
_mesa_free_texmemory(texImg->Data);
|
||||
texImg->Data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
_swrast_sleep( GLcontext *ctx, GLbitfield new_state )
|
||||
{
|
||||
@@ -456,6 +534,9 @@ _swrast_validate_derived( GLcontext *ctx )
|
||||
if (swrast->NewState & _NEW_TEXTURE)
|
||||
_swrast_update_texture_samplers( ctx );
|
||||
|
||||
if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
|
||||
_swrast_validate_texture_images( ctx );
|
||||
|
||||
swrast->NewState = 0;
|
||||
swrast->StateChanges = 0;
|
||||
swrast->InvalidateState = _swrast_invalidate_state;
|
||||
|
@@ -226,6 +226,11 @@ typedef void (*swrast_tri_func)( GLcontext *ctx, const SWvertex *,
|
||||
const SWvertex *, const SWvertex *);
|
||||
|
||||
|
||||
typedef void (*validate_texture_image_func)(GLcontext *ctx,
|
||||
struct gl_texture_object *texObj,
|
||||
GLuint face, GLuint level);
|
||||
|
||||
|
||||
/** \defgroup Bitmasks
|
||||
* Bitmasks to indicate which rasterization options are enabled
|
||||
* (RasterMask)
|
||||
@@ -363,6 +368,8 @@ typedef struct
|
||||
*/
|
||||
GLchan *TexelBuffer;
|
||||
|
||||
validate_texture_image_func ValidateTextureImage;
|
||||
|
||||
} SWcontext;
|
||||
|
||||
|
||||
|
@@ -250,6 +250,10 @@ _swrast_copy_texsubimage3d(GLcontext *ctx,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
|
||||
|
||||
extern void
|
||||
_swrast_eject_texture_images(GLcontext *ctx);
|
||||
|
||||
|
||||
/**
|
||||
* The driver interface for the software rasterizer.
|
||||
* XXX this may go away.
|
||||
|
Reference in New Issue
Block a user