summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/teximage.c
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2006-03-20 18:51:57 +0000
committerBrian Paul <[email protected]>2006-03-20 18:51:57 +0000
commit519b23b21f9cd6945fd17cdb26e7a6f531cdeec0 (patch)
treecad1402052d00a0e4140454baa07746336019a75 /src/mesa/main/teximage.c
parent4991888fa0ea8e31e3cd2a0d87bb7e205ad1dccd (diff)
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.
Diffstat (limited to 'src/mesa/main/teximage.c')
-rw-r--r--src/mesa/main/teximage.c65
1 files changed, 58 insertions, 7 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index edfe82adcf7..15a12ee4dcc 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -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
* 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.
*/
@@ -2156,6 +2198,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+ const GLuint face = texture_face(target);
if (texture_error_check(ctx, target, level, internalFormat,
format, type, 1, postConvWidth, 1, 1, border)) {
@@ -2191,6 +2234,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
ASSERT(texImage->TexFormat);
+ update_fbo_texture(ctx, texObj, face, level);
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
@@ -2247,6 +2292,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+ const GLuint face = texture_face(target);
if (texture_error_check(ctx, target, level, internalFormat,
format, type, 2, postConvWidth, postConvHeight,
@@ -2280,14 +2326,10 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
width, height, border, format, type, pixels,
&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);
+ update_fbo_texture(ctx, texObj, face, level);
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
@@ -2337,10 +2379,11 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (target == GL_TEXTURE_3D) {
+ /* non-proxy target */
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- /* non-proxy target */
+ const GLuint face = texture_face(target);
if (texture_error_check(ctx, target, level, (GLint) internalFormat,
format, type, 3, width, height, depth, border)) {
@@ -2375,6 +2418,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
ASSERT(texImage->TexFormat);
+ update_fbo_texture(ctx, texObj, face, level);
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
@@ -2565,6 +2610,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width;
+ const GLuint face = texture_face(target);
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -2602,6 +2648,8 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
ASSERT(texImage->TexFormat);
+ update_fbo_texture(ctx, texObj, face, level);
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
@@ -2618,6 +2666,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width, postConvHeight = height;
+ const GLuint face = texture_face(target);
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -2656,6 +2705,8 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
ASSERT(texImage->TexFormat);
+ update_fbo_texture(ctx, texObj, face, level);
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;