Lots of changes/fixes for rendering to framebuffer objects.
- When deleting texture objects, unbind from FBOs if necessary. - Changed driver hooks for starting/ending render to texture. - Now properly handle case where gl[Copy]TexImage() is called after glFramebufferTexture[123]D(). That didn't work before.
This commit is contained in:
@@ -808,12 +808,10 @@ struct dd_function_table {
|
|||||||
GLenum attachment,
|
GLenum attachment,
|
||||||
struct gl_renderbuffer *rb);
|
struct gl_renderbuffer *rb);
|
||||||
void (*RenderbufferTexture)(GLcontext *ctx,
|
void (*RenderbufferTexture)(GLcontext *ctx,
|
||||||
struct gl_renderbuffer_attachment *att,
|
struct gl_framebuffer *fb,
|
||||||
struct gl_texture_object *texObj,
|
struct gl_renderbuffer_attachment *att);
|
||||||
GLenum texTarget, GLuint level, GLuint zoffset);
|
|
||||||
void (*FinishRenderTexture)(GLcontext *ctx,
|
void (*FinishRenderTexture)(GLcontext *ctx,
|
||||||
struct gl_texture_object *texObj,
|
struct gl_renderbuffer_attachment *att);
|
||||||
GLuint face, GLuint level);
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
#endif
|
#endif
|
||||||
#if FEATURE_EXT_framebuffer_blit
|
#if FEATURE_EXT_framebuffer_blit
|
||||||
|
@@ -155,9 +155,7 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
|
|||||||
else {
|
else {
|
||||||
/* tell driver that we're done rendering to this texture. */
|
/* tell driver that we're done rendering to this texture. */
|
||||||
if (ctx->Driver.FinishRenderTexture) {
|
if (ctx->Driver.FinishRenderTexture) {
|
||||||
ctx->Driver.FinishRenderTexture(ctx, att->Texture,
|
ctx->Driver.FinishRenderTexture(ctx, att);
|
||||||
att->CubeMapFace,
|
|
||||||
att->TextureLevel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
att->Texture = NULL;
|
att->Texture = NULL;
|
||||||
@@ -182,6 +180,7 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
_mesa_set_texture_attachment(GLcontext *ctx,
|
_mesa_set_texture_attachment(GLcontext *ctx,
|
||||||
|
struct gl_framebuffer *fb,
|
||||||
struct gl_renderbuffer_attachment *att,
|
struct gl_renderbuffer_attachment *att,
|
||||||
struct gl_texture_object *texObj,
|
struct gl_texture_object *texObj,
|
||||||
GLenum texTarget, GLuint level, GLuint zoffset)
|
GLenum texTarget, GLuint level, GLuint zoffset)
|
||||||
@@ -208,6 +207,10 @@ _mesa_set_texture_attachment(GLcontext *ctx,
|
|||||||
}
|
}
|
||||||
att->Zoffset = zoffset;
|
att->Zoffset = zoffset;
|
||||||
att->Complete = GL_FALSE;
|
att->Complete = GL_FALSE;
|
||||||
|
|
||||||
|
if (att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {
|
||||||
|
ctx->Driver.RenderbufferTexture(ctx, fb, att);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -903,8 +906,7 @@ check_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
|
|||||||
struct gl_renderbuffer_attachment *att = fb->Attachment + i;
|
struct gl_renderbuffer_attachment *att = fb->Attachment + i;
|
||||||
struct gl_texture_object *texObj = att->Texture;
|
struct gl_texture_object *texObj = att->Texture;
|
||||||
if (texObj) {
|
if (texObj) {
|
||||||
ctx->Driver.FinishRenderTexture(ctx, texObj, att->CubeMapFace,
|
ctx->Driver.FinishRenderTexture(ctx, att);
|
||||||
att->TextureLevel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1178,12 +1180,15 @@ error_check_framebuffer_texture(GLcontext *ctx, GLuint dims,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XXX The code in _mesa_FramebufferTexture1/2/3DEXT could be probably
|
||||||
|
* be combined into one function.
|
||||||
|
*/
|
||||||
void GLAPIENTRY
|
void GLAPIENTRY
|
||||||
_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
|
_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
|
||||||
GLenum textarget, GLuint texture, GLint level)
|
GLenum textarget, GLuint texture, GLint level)
|
||||||
{
|
{
|
||||||
struct gl_renderbuffer_attachment *att;
|
struct gl_renderbuffer_attachment *att;
|
||||||
struct gl_texture_object *texObj;
|
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
|
|
||||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||||
@@ -1205,7 +1210,7 @@ _mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
|
|||||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||||
|
|
||||||
if (texture) {
|
if (texture) {
|
||||||
texObj = (struct gl_texture_object *)
|
struct gl_texture_object *texObj = (struct gl_texture_object *)
|
||||||
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
||||||
if (!texObj) {
|
if (!texObj) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
@@ -1217,12 +1222,12 @@ _mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
|
|||||||
"glFramebufferTexture1DEXT(texture target)");
|
"glFramebufferTexture1DEXT(texture target)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_mesa_set_texture_attachment(ctx, ctx->DrawBuffer, att,
|
||||||
|
texObj, textarget, level, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* remove texture attachment */
|
_mesa_remove_attachment(ctx, att);
|
||||||
texObj = NULL;
|
|
||||||
}
|
}
|
||||||
ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget, level, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1231,7 +1236,6 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
|
|||||||
GLenum textarget, GLuint texture, GLint level)
|
GLenum textarget, GLuint texture, GLint level)
|
||||||
{
|
{
|
||||||
struct gl_renderbuffer_attachment *att;
|
struct gl_renderbuffer_attachment *att;
|
||||||
struct gl_texture_object *texObj;
|
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
|
|
||||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||||
@@ -1254,7 +1258,7 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
|
|||||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||||
|
|
||||||
if (texture) {
|
if (texture) {
|
||||||
texObj = (struct gl_texture_object *)
|
struct gl_texture_object *texObj = (struct gl_texture_object *)
|
||||||
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
||||||
if (!texObj) {
|
if (!texObj) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
@@ -1270,12 +1274,12 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
|
|||||||
"glFramebufferTexture2DEXT(texture target)");
|
"glFramebufferTexture2DEXT(texture target)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_mesa_set_texture_attachment(ctx, ctx->DrawBuffer, att,
|
||||||
|
texObj, textarget, level, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* remove texture attachment */
|
_mesa_remove_attachment(ctx, att);
|
||||||
texObj = NULL;
|
|
||||||
}
|
}
|
||||||
ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget, level, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1285,7 +1289,6 @@ _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
|
|||||||
GLint level, GLint zoffset)
|
GLint level, GLint zoffset)
|
||||||
{
|
{
|
||||||
struct gl_renderbuffer_attachment *att;
|
struct gl_renderbuffer_attachment *att;
|
||||||
struct gl_texture_object *texObj;
|
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
|
|
||||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||||
@@ -1307,7 +1310,7 @@ _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
|
|||||||
|
|
||||||
if (texture) {
|
if (texture) {
|
||||||
const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
|
const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
|
||||||
texObj = (struct gl_texture_object *)
|
struct gl_texture_object *texObj = (struct gl_texture_object *)
|
||||||
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
||||||
if (!texObj) {
|
if (!texObj) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
@@ -1324,13 +1327,12 @@ _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
|
|||||||
"glFramebufferTexture3DEXT(zoffset)");
|
"glFramebufferTexture3DEXT(zoffset)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_mesa_set_texture_attachment(ctx, ctx->DrawBuffer, att,
|
||||||
|
texObj, textarget, level,zoffset);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* remove texture attachment */
|
_mesa_remove_attachment(ctx, att);
|
||||||
texObj = NULL;
|
|
||||||
}
|
}
|
||||||
ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget,
|
|
||||||
level, zoffset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -38,6 +38,7 @@ _mesa_remove_attachment(GLcontext *ctx,
|
|||||||
|
|
||||||
extern void
|
extern void
|
||||||
_mesa_set_texture_attachment(GLcontext *ctx,
|
_mesa_set_texture_attachment(GLcontext *ctx,
|
||||||
|
struct gl_framebuffer *fb,
|
||||||
struct gl_renderbuffer_attachment *att,
|
struct gl_renderbuffer_attachment *att,
|
||||||
struct gl_texture_object *texObj,
|
struct gl_texture_object *texObj,
|
||||||
GLenum texTarget, GLuint level, GLuint zoffset);
|
GLenum texTarget, GLuint level, GLuint zoffset);
|
||||||
|
@@ -551,6 +551,18 @@ is_compressed_format(GLcontext *ctx, GLenum internalFormat)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GLuint
|
||||||
|
texture_face(GLenum target)
|
||||||
|
{
|
||||||
|
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
||||||
|
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
|
||||||
|
return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a gl_texture_image pointer in a gl_texture_object structure
|
* Store a gl_texture_image pointer in a gl_texture_object structure
|
||||||
* according to the target and level parameters.
|
* according to the target and level parameters.
|
||||||
@@ -2135,6 +2147,36 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given texture image is bound to any framebuffer objects
|
||||||
|
* and update/invalidate them.
|
||||||
|
* XXX We're only checking the currently bound framebuffer object for now.
|
||||||
|
* In the future, perhaps struct gl_texture_image should have a pointer (or
|
||||||
|
* list of pointers (yikes)) to the gl_framebuffer(s) which it's bound to.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
update_fbo_texture(GLcontext *ctx, struct gl_texture_object *texObj,
|
||||||
|
GLuint face, GLuint level)
|
||||||
|
{
|
||||||
|
if (ctx->DrawBuffer->Name) {
|
||||||
|
GLuint i;
|
||||||
|
for (i = 0; i < BUFFER_COUNT; i++) {
|
||||||
|
struct gl_renderbuffer_attachment *att =
|
||||||
|
ctx->DrawBuffer->Attachment + i;
|
||||||
|
if (att->Type == GL_TEXTURE &&
|
||||||
|
att->Texture == texObj &&
|
||||||
|
att->TextureLevel == level &&
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called from the API. Note that width includes the border.
|
* Called from the API. Note that width includes the border.
|
||||||
*/
|
*/
|
||||||
@@ -2156,6 +2198,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
|
|||||||
struct gl_texture_unit *texUnit;
|
struct gl_texture_unit *texUnit;
|
||||||
struct gl_texture_object *texObj;
|
struct gl_texture_object *texObj;
|
||||||
struct gl_texture_image *texImage;
|
struct gl_texture_image *texImage;
|
||||||
|
const GLuint face = texture_face(target);
|
||||||
|
|
||||||
if (texture_error_check(ctx, target, level, internalFormat,
|
if (texture_error_check(ctx, target, level, internalFormat,
|
||||||
format, type, 1, postConvWidth, 1, 1, border)) {
|
format, type, 1, postConvWidth, 1, 1, border)) {
|
||||||
@@ -2191,6 +2234,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
|
|||||||
|
|
||||||
ASSERT(texImage->TexFormat);
|
ASSERT(texImage->TexFormat);
|
||||||
|
|
||||||
|
update_fbo_texture(ctx, texObj, face, level);
|
||||||
|
|
||||||
/* state update */
|
/* state update */
|
||||||
texObj->Complete = GL_FALSE;
|
texObj->Complete = GL_FALSE;
|
||||||
ctx->NewState |= _NEW_TEXTURE;
|
ctx->NewState |= _NEW_TEXTURE;
|
||||||
@@ -2247,6 +2292,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
|
|||||||
struct gl_texture_unit *texUnit;
|
struct gl_texture_unit *texUnit;
|
||||||
struct gl_texture_object *texObj;
|
struct gl_texture_object *texObj;
|
||||||
struct gl_texture_image *texImage;
|
struct gl_texture_image *texImage;
|
||||||
|
const GLuint face = texture_face(target);
|
||||||
|
|
||||||
if (texture_error_check(ctx, target, level, internalFormat,
|
if (texture_error_check(ctx, target, level, internalFormat,
|
||||||
format, type, 2, postConvWidth, postConvHeight,
|
format, type, 2, postConvWidth, postConvHeight,
|
||||||
@@ -2280,14 +2326,10 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
|
|||||||
width, height, border, format, type, pixels,
|
width, height, border, format, type, pixels,
|
||||||
&ctx->Unpack, texObj, texImage);
|
&ctx->Unpack, texObj, texImage);
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX if this texture image is currently bound to a user-created
|
|
||||||
* framebuffer object, we have to invalidate that framebuffer's
|
|
||||||
* completeness state.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ASSERT(texImage->TexFormat);
|
ASSERT(texImage->TexFormat);
|
||||||
|
|
||||||
|
update_fbo_texture(ctx, texObj, face, level);
|
||||||
|
|
||||||
/* state update */
|
/* state update */
|
||||||
texObj->Complete = GL_FALSE;
|
texObj->Complete = GL_FALSE;
|
||||||
ctx->NewState |= _NEW_TEXTURE;
|
ctx->NewState |= _NEW_TEXTURE;
|
||||||
@@ -2337,10 +2379,11 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
|
|||||||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
||||||
|
|
||||||
if (target == GL_TEXTURE_3D) {
|
if (target == GL_TEXTURE_3D) {
|
||||||
|
/* non-proxy target */
|
||||||
struct gl_texture_unit *texUnit;
|
struct gl_texture_unit *texUnit;
|
||||||
struct gl_texture_object *texObj;
|
struct gl_texture_object *texObj;
|
||||||
struct gl_texture_image *texImage;
|
struct gl_texture_image *texImage;
|
||||||
/* non-proxy target */
|
const GLuint face = texture_face(target);
|
||||||
|
|
||||||
if (texture_error_check(ctx, target, level, (GLint) internalFormat,
|
if (texture_error_check(ctx, target, level, (GLint) internalFormat,
|
||||||
format, type, 3, width, height, depth, border)) {
|
format, type, 3, width, height, depth, border)) {
|
||||||
@@ -2375,6 +2418,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
|
|||||||
|
|
||||||
ASSERT(texImage->TexFormat);
|
ASSERT(texImage->TexFormat);
|
||||||
|
|
||||||
|
update_fbo_texture(ctx, texObj, face, level);
|
||||||
|
|
||||||
/* state update */
|
/* state update */
|
||||||
texObj->Complete = GL_FALSE;
|
texObj->Complete = GL_FALSE;
|
||||||
ctx->NewState |= _NEW_TEXTURE;
|
ctx->NewState |= _NEW_TEXTURE;
|
||||||
@@ -2565,6 +2610,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
|
|||||||
struct gl_texture_object *texObj;
|
struct gl_texture_object *texObj;
|
||||||
struct gl_texture_image *texImage;
|
struct gl_texture_image *texImage;
|
||||||
GLsizei postConvWidth = width;
|
GLsizei postConvWidth = width;
|
||||||
|
const GLuint face = texture_face(target);
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
||||||
|
|
||||||
@@ -2602,6 +2648,8 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
|
|||||||
|
|
||||||
ASSERT(texImage->TexFormat);
|
ASSERT(texImage->TexFormat);
|
||||||
|
|
||||||
|
update_fbo_texture(ctx, texObj, face, level);
|
||||||
|
|
||||||
/* state update */
|
/* state update */
|
||||||
texObj->Complete = GL_FALSE;
|
texObj->Complete = GL_FALSE;
|
||||||
ctx->NewState |= _NEW_TEXTURE;
|
ctx->NewState |= _NEW_TEXTURE;
|
||||||
@@ -2618,6 +2666,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
|
|||||||
struct gl_texture_object *texObj;
|
struct gl_texture_object *texObj;
|
||||||
struct gl_texture_image *texImage;
|
struct gl_texture_image *texImage;
|
||||||
GLsizei postConvWidth = width, postConvHeight = height;
|
GLsizei postConvWidth = width, postConvHeight = height;
|
||||||
|
const GLuint face = texture_face(target);
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
||||||
|
|
||||||
@@ -2656,6 +2705,8 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
|
|||||||
|
|
||||||
ASSERT(texImage->TexFormat);
|
ASSERT(texImage->TexFormat);
|
||||||
|
|
||||||
|
update_fbo_texture(ctx, texObj, face, level);
|
||||||
|
|
||||||
/* state update */
|
/* state update */
|
||||||
texObj->Complete = GL_FALSE;
|
texObj->Complete = GL_FALSE;
|
||||||
ctx->NewState |= _NEW_TEXTURE;
|
ctx->NewState |= _NEW_TEXTURE;
|
||||||
|
@@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
* Version: 6.3
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "colortab.h"
|
#include "colortab.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
|
#include "fbobject.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "imports.h"
|
#include "imports.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
#include "texobj.h"
|
#include "texobj.h"
|
||||||
#include "mtypes.h"
|
#include "mtypes.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __VMS
|
#ifdef __VMS
|
||||||
#define _mesa_sprintf sprintf
|
#define _mesa_sprintf sprintf
|
||||||
#endif
|
#endif
|
||||||
@@ -578,6 +580,82 @@ _mesa_GenTextures( GLsizei n, GLuint *textures )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given texture object is bound to the current draw or
|
||||||
|
* read framebuffer. If so, Unbind it.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
unbind_texobj_from_fbo(GLcontext *ctx, struct gl_texture_object *texObj)
|
||||||
|
{
|
||||||
|
const GLuint n = (ctx->DrawBuffer == ctx->ReadBuffer) ? 1 : 2;
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer;
|
||||||
|
if (fb->Name) {
|
||||||
|
GLuint j;
|
||||||
|
for (j = 0; j < BUFFER_COUNT; j++) {
|
||||||
|
if (fb->Attachment[j].Type == GL_TEXTURE &&
|
||||||
|
fb->Attachment[j].Texture == texObj) {
|
||||||
|
_mesa_remove_attachment(ctx, fb->Attachment + j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given texture object is bound to any texture image units and
|
||||||
|
* unbind it if so.
|
||||||
|
* XXX all RefCount accesses should be protected by a mutex.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
|
||||||
|
{
|
||||||
|
GLuint u;
|
||||||
|
|
||||||
|
for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
|
||||||
|
struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
|
||||||
|
if (texObj == unit->Current1D) {
|
||||||
|
unit->Current1D = ctx->Shared->Default1D;
|
||||||
|
ctx->Shared->Default1D->RefCount++;
|
||||||
|
texObj->RefCount--;
|
||||||
|
if (texObj == unit->_Current)
|
||||||
|
unit->_Current = unit->Current1D;
|
||||||
|
}
|
||||||
|
else if (texObj == unit->Current2D) {
|
||||||
|
unit->Current2D = ctx->Shared->Default2D;
|
||||||
|
ctx->Shared->Default2D->RefCount++;
|
||||||
|
texObj->RefCount--;
|
||||||
|
if (texObj == unit->_Current)
|
||||||
|
unit->_Current = unit->Current2D;
|
||||||
|
}
|
||||||
|
else if (texObj == unit->Current3D) {
|
||||||
|
unit->Current3D = ctx->Shared->Default3D;
|
||||||
|
ctx->Shared->Default3D->RefCount++;
|
||||||
|
texObj->RefCount--;
|
||||||
|
if (texObj == unit->_Current)
|
||||||
|
unit->_Current = unit->Current3D;
|
||||||
|
}
|
||||||
|
else if (texObj == unit->CurrentCubeMap) {
|
||||||
|
unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
|
||||||
|
ctx->Shared->DefaultCubeMap->RefCount++;
|
||||||
|
texObj->RefCount--;
|
||||||
|
if (texObj == unit->_Current)
|
||||||
|
unit->_Current = unit->CurrentCubeMap;
|
||||||
|
}
|
||||||
|
else if (texObj == unit->CurrentRect) {
|
||||||
|
unit->CurrentRect = ctx->Shared->DefaultRect;
|
||||||
|
ctx->Shared->DefaultRect->RefCount++;
|
||||||
|
texObj->RefCount--;
|
||||||
|
if (texObj == unit->_Current)
|
||||||
|
unit->_Current = unit->CurrentRect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete named textures.
|
* Delete named textures.
|
||||||
*
|
*
|
||||||
@@ -607,49 +685,18 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
|
|||||||
struct gl_texture_object *delObj = (struct gl_texture_object *)
|
struct gl_texture_object *delObj = (struct gl_texture_object *)
|
||||||
_mesa_HashLookup(ctx->Shared->TexObjects, textures[i]);
|
_mesa_HashLookup(ctx->Shared->TexObjects, textures[i]);
|
||||||
if (delObj) {
|
if (delObj) {
|
||||||
/* First check if this texture is currently bound.
|
|
||||||
* If so, unbind it and decrement the reference count.
|
/* Check if texture is bound to any framebuffer objects.
|
||||||
* XXX all RefCount accesses should be protected by a mutex.
|
* If so, unbind.
|
||||||
|
* See section 4.4.2.3 of GL_EXT_framebuffer_object.
|
||||||
*/
|
*/
|
||||||
GLuint u;
|
unbind_texobj_from_fbo(ctx, delObj);
|
||||||
for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
|
|
||||||
struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
|
/* Check if this texture is currently bound to any texture units.
|
||||||
if (delObj == unit->Current1D) {
|
* If so, unbind it and decrement the reference count.
|
||||||
unit->Current1D = ctx->Shared->Default1D;
|
*/
|
||||||
ctx->Shared->Default1D->RefCount++;
|
unbind_texobj_from_texunits(ctx, delObj);
|
||||||
delObj->RefCount--;
|
|
||||||
if (delObj == unit->_Current)
|
|
||||||
unit->_Current = unit->Current1D;
|
|
||||||
}
|
|
||||||
else if (delObj == unit->Current2D) {
|
|
||||||
unit->Current2D = ctx->Shared->Default2D;
|
|
||||||
ctx->Shared->Default2D->RefCount++;
|
|
||||||
delObj->RefCount--;
|
|
||||||
if (delObj == unit->_Current)
|
|
||||||
unit->_Current = unit->Current2D;
|
|
||||||
}
|
|
||||||
else if (delObj == unit->Current3D) {
|
|
||||||
unit->Current3D = ctx->Shared->Default3D;
|
|
||||||
ctx->Shared->Default3D->RefCount++;
|
|
||||||
delObj->RefCount--;
|
|
||||||
if (delObj == unit->_Current)
|
|
||||||
unit->_Current = unit->Current3D;
|
|
||||||
}
|
|
||||||
else if (delObj == unit->CurrentCubeMap) {
|
|
||||||
unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
|
|
||||||
ctx->Shared->DefaultCubeMap->RefCount++;
|
|
||||||
delObj->RefCount--;
|
|
||||||
if (delObj == unit->_Current)
|
|
||||||
unit->_Current = unit->CurrentCubeMap;
|
|
||||||
}
|
|
||||||
else if (delObj == unit->CurrentRect) {
|
|
||||||
unit->CurrentRect = ctx->Shared->DefaultRect;
|
|
||||||
ctx->Shared->DefaultRect->RefCount++;
|
|
||||||
delObj->RefCount--;
|
|
||||||
if (delObj == unit->_Current)
|
|
||||||
unit->_Current = unit->CurrentRect;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx->NewState |= _NEW_TEXTURE;
|
ctx->NewState |= _NEW_TEXTURE;
|
||||||
|
|
||||||
/* The texture _name_ is now free for re-use.
|
/* The texture _name_ is now free for re-use.
|
||||||
|
@@ -200,25 +200,44 @@ wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Software fallback for ctx->Driver.RenderbufferTexture.
|
* Called when rendering to a texture image begins.
|
||||||
* This is called via the glRenderbufferTexture1D/2D/3D() functions.
|
* This is a fallback routine for software render-to-texture.
|
||||||
* If we're unbinding a texture, texObj will be NULL.
|
*
|
||||||
* The framebuffer of interest is ctx->DrawBuffer.
|
* Called via the glRenderbufferTexture1D/2D/3D() functions
|
||||||
|
* and elsewhere (such as glTexImage2D).
|
||||||
|
*
|
||||||
|
* The image we're rendering into is
|
||||||
|
* att->Texture->Image[att->CubeMapFace][att->TextureLevel];
|
||||||
|
* It'll never be NULL.
|
||||||
|
*
|
||||||
|
* \param fb the framebuffer object the texture is being bound to
|
||||||
|
* \param att the fb attachment point of the texture
|
||||||
|
*
|
||||||
* \sa _mesa_framebuffer_renderbuffer
|
* \sa _mesa_framebuffer_renderbuffer
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
_mesa_renderbuffer_texture(GLcontext *ctx,
|
_mesa_renderbuffer_texture(GLcontext *ctx,
|
||||||
struct gl_renderbuffer_attachment *att,
|
struct gl_framebuffer *fb,
|
||||||
struct gl_texture_object *texObj,
|
struct gl_renderbuffer_attachment *att)
|
||||||
GLenum texTarget, GLuint level, GLuint zoffset)
|
|
||||||
{
|
{
|
||||||
if (texObj) {
|
struct gl_texture_image *newImage
|
||||||
_mesa_set_texture_attachment(ctx, att, texObj,
|
= att->Texture->Image[att->CubeMapFace][att->TextureLevel];
|
||||||
texTarget, level, zoffset);
|
struct texture_renderbuffer *trb
|
||||||
if (!att->Renderbuffer)
|
= (struct texture_renderbuffer *) att->Renderbuffer;
|
||||||
wrap_texture(ctx, att);
|
struct gl_texture_image *oldImage = trb ? trb->TexImage : NULL;
|
||||||
}
|
|
||||||
else {
|
(void) fb;
|
||||||
_mesa_remove_attachment(ctx, att);
|
|
||||||
|
ASSERT(newImage);
|
||||||
|
|
||||||
|
if (oldImage != newImage) {
|
||||||
|
if (trb) {
|
||||||
|
/* get rid of old wrapper */
|
||||||
|
/* XXX also if Zoffset changes? */
|
||||||
|
trb->Base.Delete(&trb->Base);
|
||||||
|
}
|
||||||
|
wrap_texture(ctx, att);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -4,9 +4,8 @@
|
|||||||
|
|
||||||
extern void
|
extern void
|
||||||
_mesa_renderbuffer_texture(GLcontext *ctx,
|
_mesa_renderbuffer_texture(GLcontext *ctx,
|
||||||
struct gl_renderbuffer_attachment *att,
|
struct gl_framebuffer *fb,
|
||||||
struct gl_texture_object *texObj,
|
struct gl_renderbuffer_attachment *att);
|
||||||
GLenum texTarget, GLuint level, GLuint zoffset);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* TEXRENDER_H */
|
#endif /* TEXRENDER_H */
|
||||||
|
Reference in New Issue
Block a user