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:
Brian Paul
2006-03-20 18:51:57 +00:00
parent 4991888fa0
commit 519b23b21f
7 changed files with 212 additions and 95 deletions

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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);

View File

@@ -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;

View File

@@ -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.

View File

@@ -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);
} }
} }

View File

@@ -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 */