mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
Added FinishRenderTexture() device driver function to indicate when
rendering to a texture has likely completed. Fixed refcount issue in texture renderbuffer wrapper.
This commit is contained in:
parent
cf2702e3db
commit
0e31e02aef
3 changed files with 65 additions and 19 deletions
|
|
@ -809,6 +809,9 @@ struct dd_function_table {
|
|||
struct gl_renderbuffer_attachment *att,
|
||||
struct gl_texture_object *texObj,
|
||||
GLenum texTarget, GLuint level, GLuint zoffset);
|
||||
void (*FinishRenderTexture)(GLcontext *ctx,
|
||||
struct gl_texture_object *texObj,
|
||||
GLuint face, GLuint level);
|
||||
/*@}*/
|
||||
#endif
|
||||
#if FEATURE_EXT_framebuffer_blit
|
||||
|
|
|
|||
|
|
@ -154,19 +154,21 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
|
|||
{
|
||||
if (att->Type == GL_TEXTURE) {
|
||||
ASSERT(att->Texture);
|
||||
if (att->Renderbuffer) {
|
||||
/* delete/remove the 'wrapper' renderbuffer */
|
||||
/* XXX do we really want to do this??? */
|
||||
att->Renderbuffer->Delete(att->Renderbuffer);
|
||||
att->Renderbuffer = NULL;
|
||||
}
|
||||
att->Texture->RefCount--;
|
||||
if (att->Texture->RefCount == 0) {
|
||||
ctx->Driver.DeleteTexture(ctx, att->Texture);
|
||||
}
|
||||
else {
|
||||
/* tell driver that we're done rendering to this texture. */
|
||||
if (ctx->Driver.FinishRenderTexture) {
|
||||
ctx->Driver.FinishRenderTexture(ctx, att->Texture,
|
||||
att->CubeMapFace,
|
||||
att->TextureLevel);
|
||||
}
|
||||
}
|
||||
att->Texture = NULL;
|
||||
}
|
||||
else if (att->Type == GL_RENDERBUFFER_EXT) {
|
||||
if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
|
||||
ASSERT(att->Renderbuffer);
|
||||
ASSERT(!att->Texture);
|
||||
att->Renderbuffer->RefCount--;
|
||||
|
|
@ -190,9 +192,19 @@ _mesa_set_texture_attachment(GLcontext *ctx,
|
|||
struct gl_texture_object *texObj,
|
||||
GLenum texTarget, GLuint level, GLuint zoffset)
|
||||
{
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
att->Type = GL_TEXTURE;
|
||||
att->Texture = texObj;
|
||||
if (att->Texture == texObj) {
|
||||
/* re-attaching same texture */
|
||||
ASSERT(att->Type == GL_TEXTURE);
|
||||
}
|
||||
else {
|
||||
/* new attachment */
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
att->Type = GL_TEXTURE;
|
||||
att->Texture = texObj;
|
||||
texObj->RefCount++;
|
||||
}
|
||||
|
||||
/* always update these fields */
|
||||
att->TextureLevel = level;
|
||||
if (IS_CUBE_FACE(texTarget)) {
|
||||
att->CubeMapFace = texTarget - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
|
|
@ -202,13 +214,6 @@ _mesa_set_texture_attachment(GLcontext *ctx,
|
|||
}
|
||||
att->Zoffset = zoffset;
|
||||
att->Complete = GL_FALSE;
|
||||
|
||||
texObj->RefCount++;
|
||||
|
||||
/* XXX when we attach to a texture, we should probably set the
|
||||
* att->Renderbuffer pointer to a "wrapper renderbuffer" which
|
||||
* makes the texture image look like renderbuffer.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -758,6 +763,8 @@ _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
|
|||
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->_BaseFormat = baseFormat;
|
||||
}
|
||||
else {
|
||||
|
|
@ -766,6 +773,13 @@ _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
|
|||
rb->Height = 0;
|
||||
rb->InternalFormat = GL_NONE;
|
||||
rb->_BaseFormat = GL_NONE;
|
||||
rb->RedBits =
|
||||
rb->GreenBits =
|
||||
rb->BlueBits =
|
||||
rb->AlphaBits =
|
||||
rb->IndexBits =
|
||||
rb->DepthBits =
|
||||
rb->StencilBits = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -848,6 +862,28 @@ _mesa_IsFramebufferEXT(GLuint framebuffer)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if (ctx->Driver.FinishRenderTexture) {
|
||||
GLuint i;
|
||||
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.FinishRenderTexture(ctx, texObj, att->CubeMapFace,
|
||||
att->TextureLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
{
|
||||
|
|
@ -931,6 +967,11 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
|||
if (bindDrawBuf) {
|
||||
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 if time to delete this framebuffer */
|
||||
oldFb->RefCount--;
|
||||
if (oldFb->RefCount == 0) {
|
||||
oldFb->Delete(oldFb);
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ texture_put_mono_values(GLcontext *ctx, struct gl_renderbuffer *rb,
|
|||
static void
|
||||
delete_texture_wrapper(struct gl_renderbuffer *rb)
|
||||
{
|
||||
ASSERT(rb->RefCount == 0);
|
||||
_mesa_free(rb);
|
||||
}
|
||||
|
||||
|
|
@ -162,6 +163,7 @@ 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? */
|
||||
|
|
@ -213,8 +215,8 @@ _mesa_renderbuffer_texture(GLcontext *ctx,
|
|||
if (texObj) {
|
||||
_mesa_set_texture_attachment(ctx, att, texObj,
|
||||
texTarget, level, zoffset);
|
||||
|
||||
wrap_texture(ctx, att);
|
||||
if (!att->Renderbuffer)
|
||||
wrap_texture(ctx, att);
|
||||
}
|
||||
else {
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue