X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ffbobject.c;h=8d44246618702de05c6eca96c694ffb224bf6806;hb=dff50ff592da7cb1d784fae794dd1647a5445bca;hp=5896f1b95f7dbc954939ce83f34b73be619e516b;hpb=e6f60d30375c637c0823a9aade8098a45f70d6a7;p=mesa.git diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 5896f1b95f7..8d442466187 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -40,13 +40,10 @@ #include "framebuffer.h" #include "hash.h" #include "macros.h" -#include "mipmap.h" #include "renderbuffer.h" #include "state.h" #include "teximage.h" #include "texobj.h" -#include "texstore.h" -#include "texstate.h" /** Set this to 1 to help debug FBO incompleteness problems */ @@ -183,8 +180,12 @@ _mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb, return &fb->Attachment[BUFFER_COLOR0 + i]; case GL_DEPTH_STENCIL_ATTACHMENT: /* fall-through */ + case GL_DEPTH_BUFFER: + /* fall-through / new in GL 3.0 */ case GL_DEPTH_ATTACHMENT_EXT: return &fb->Attachment[BUFFER_DEPTH]; + case GL_STENCIL_BUFFER: + /* fall-through / new in GL 3.0 */ case GL_STENCIL_ATTACHMENT_EXT: return &fb->Attachment[BUFFER_STENCIL]; default: @@ -377,8 +378,8 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format, } if (texImage->Width < 1 || texImage->Height < 1) { att_incomplete("teximage width/height=0"); - _mesa_printf("texobj = %u\n", texObj->Name); - _mesa_printf("level = %d\n", att->TextureLevel); + printf("texobj = %u\n", texObj->Name); + printf("level = %d\n", att->TextureLevel); att->Complete = GL_FALSE; return; } @@ -628,7 +629,7 @@ _mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb) } } -#ifndef FEATURE_OES_framebuffer_object +#if !FEATURE_OES_framebuffer_object /* Check that all DrawBuffers are present */ for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) { if (fb->ColorDrawBuffer[j] != GL_NONE) { @@ -861,6 +862,9 @@ _mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers) * * \return one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT * GL_DEPTH_STENCIL_EXT or zero if error. + * + * XXX in the future when we support red-only and red-green formats + * we'll also return GL_RED and GL_RG. */ GLenum _mesa_base_fbo_format(GLcontext *ctx, GLenum internalFormat) @@ -954,7 +958,7 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, /* NumSamples == 0 indicates non-multisampling */ samples = 0; } - else if (samples > ctx->Const.MaxSamples) { + else if (samples > (GLsizei) ctx->Const.MaxSamples) { /* note: driver may choose to use more samples than what's requested */ _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples)", func); return; @@ -987,7 +991,7 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, assert(rb->Width == (GLuint) width); assert(rb->Height == (GLuint) height); rb->InternalFormat = internalFormat; - rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); + rb->_BaseFormat = baseFormat; assert(rb->_BaseFormat != 0); } else { @@ -1008,6 +1012,36 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, */ } +#if FEATURE_OES_EGL_image +void GLAPIENTRY +_mesa_EGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image) +{ + struct gl_renderbuffer *rb; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!ctx->Extensions.OES_EGL_image) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glEGLImageTargetRenderbufferStorageOES(unsupported)"); + return; + } + + if (target != GL_RENDERBUFFER) { + _mesa_error(ctx, GL_INVALID_ENUM, "EGLImageTargetRenderbufferStorageOES"); + return; + } + + rb = ctx->CurrentRenderbuffer; + if (!rb) { + _mesa_error(ctx, GL_INVALID_OPERATION, "EGLImageTargetRenderbufferStorageOES"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_BUFFERS); + + ctx->Driver.EGLImageTargetRenderbufferStorage(ctx, rb, image); +} +#endif /** * Helper function for _mesa_GetRenderbufferParameterivEXT() and @@ -1159,6 +1193,10 @@ check_begin_texture_render(GLcontext *ctx, struct gl_framebuffer *fb) { GLuint i; ASSERT(ctx->Driver.RenderTexture); + + if (fb->Name == 0) + return; /* can't render to texture with winsys framebuffers */ + for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = fb->Attachment + i; struct gl_texture_object *texObj = att->Texture; @@ -1178,6 +1216,9 @@ check_begin_texture_render(GLcontext *ctx, struct gl_framebuffer *fb) static void check_end_texture_render(GLcontext *ctx, struct gl_framebuffer *fb) { + if (fb->Name == 0) + return; /* can't render to texture with winsys framebuffers */ + if (ctx->Driver.FinishRenderTexture) { GLuint i; for (i = 0; i < BUFFER_COUNT; i++) { @@ -1194,6 +1235,7 @@ void GLAPIENTRY _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) { struct gl_framebuffer *newDrawFb, *newReadFb; + struct gl_framebuffer *oldDrawFb, *oldReadFb; GLboolean bindReadBuf, bindDrawBuf; GET_CURRENT_CONTEXT(ctx); @@ -1275,36 +1317,51 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) ASSERT(newDrawFb); ASSERT(newDrawFb != &DummyFramebuffer); + /* save pointers to current/old framebuffers */ + oldDrawFb = ctx->DrawBuffer; + oldReadFb = ctx->ReadBuffer; + + /* check if really changing bindings */ + if (oldDrawFb == newDrawFb) + bindDrawBuf = GL_FALSE; + if (oldReadFb == newReadFb) + bindReadBuf = GL_FALSE; + /* * OK, now bind the new Draw/Read framebuffers, if they're changing. + * + * We also check if we're beginning and/or ending render-to-texture. + * When a framebuffer with texture attachments is unbound, call + * ctx->Driver.FinishRenderTexture(). + * When a framebuffer with texture attachments is bound, call + * ctx->Driver.RenderTexture(). + * + * Note that if the ReadBuffer has texture attachments we don't consider + * that a render-to-texture case. */ if (bindReadBuf) { - if (ctx->ReadBuffer == newReadFb) { - bindReadBuf = GL_FALSE; /* no change */ - } - else { - FLUSH_VERTICES(ctx, _NEW_BUFFERS); - _mesa_reference_framebuffer(&ctx->ReadBuffer, newReadFb); - } + FLUSH_VERTICES(ctx, _NEW_BUFFERS); + + /* check if old readbuffer was render-to-texture */ + check_end_texture_render(ctx, oldReadFb); + + _mesa_reference_framebuffer(&ctx->ReadBuffer, newReadFb); } if (bindDrawBuf) { - if (ctx->DrawBuffer->Name != 0) { - check_end_texture_render(ctx, ctx->DrawBuffer); - } + FLUSH_VERTICES(ctx, _NEW_BUFFERS); - if (ctx->DrawBuffer == newDrawFb) { - bindDrawBuf = GL_FALSE; /* no change */ - } - else { - FLUSH_VERTICES(ctx, _NEW_BUFFERS); - _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb); - } + /* check if old read/draw buffers were render-to-texture */ + if (!bindReadBuf) + check_end_texture_render(ctx, oldReadFb); - if (newDrawFb->Name != 0) { - /* check if newly bound framebuffer has any texture attachments */ - check_begin_texture_render(ctx, newDrawFb); - } + if (oldDrawFb != oldReadFb) + check_end_texture_render(ctx, oldDrawFb); + + /* check if newly bound framebuffer has any texture attachments */ + check_begin_texture_render(ctx, newDrawFb); + + _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb); } if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) { @@ -1330,15 +1387,26 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers) ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]); /* check if deleting currently bound framebuffer object */ - if (fb == ctx->DrawBuffer) { - /* bind default */ - ASSERT(fb->RefCount >= 2); - _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + if (ctx->Extensions.EXT_framebuffer_blit) { + /* separate draw/read binding points */ + if (fb == ctx->DrawBuffer) { + /* bind default */ + ASSERT(fb->RefCount >= 2); + _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + } + if (fb == ctx->ReadBuffer) { + /* bind default */ + ASSERT(fb->RefCount >= 2); + _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + } } - if (fb == ctx->ReadBuffer) { - /* bind default */ - ASSERT(fb->RefCount >= 2); - _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + else { + /* only one binding point for read/draw buffers */ + if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer) { + /* bind default */ + ASSERT(fb->RefCount >= 2); + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } } /* remove from hash table immediately, to free the ID */ @@ -1491,6 +1559,7 @@ framebuffer_texture(GLcontext *ctx, const char *caller, GLenum target, texObj = _mesa_lookup_texture(ctx, texture); if (texObj != NULL) { if (textarget == 0) { + /* XXX what's the purpose of this? */ err = (texObj->Target != GL_TEXTURE_3D) && (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) && (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT); @@ -1501,6 +1570,13 @@ framebuffer_texture(GLcontext *ctx, const char *caller, GLenum target, : (texObj->Target != textarget); } } + else { + /* can't render to a non-existant texture */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glFramebufferTexture%sEXT(non existant texture)", + caller); + return; + } if (err) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -1919,7 +1995,6 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, void GLAPIENTRY _mesa_GenerateMipmapEXT(GLenum target) { - struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); @@ -1938,8 +2013,12 @@ _mesa_GenerateMipmapEXT(GLenum target) return; } - texUnit = _mesa_get_current_tex_unit(ctx); - texObj = _mesa_select_tex_object(ctx, texUnit, target); + texObj = _mesa_get_current_tex_object(ctx, target); + + if (texObj->BaseLevel >= texObj->MaxLevel) { + /* nothing to do */ + return; + } _mesa_lock_texture(ctx, texObj); if (target == GL_TEXTURE_CUBE_MAP) { @@ -2102,39 +2181,39 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, /* Debug code */ if (DEBUG_BLIT) { - _mesa_printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d," - " 0x%x, 0x%x)\n", - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); + printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d," + " 0x%x, 0x%x)\n", + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); if (colorReadRb) { const struct gl_renderbuffer_attachment *att; att = find_attachment(readFb, colorReadRb); - _mesa_printf(" Src FBO %u RB %u (%dx%d) ", - readFb->Name, colorReadRb->Name, - colorReadRb->Width, colorReadRb->Height); + printf(" Src FBO %u RB %u (%dx%d) ", + readFb->Name, colorReadRb->Name, + colorReadRb->Width, colorReadRb->Height); if (att && att->Texture) { - _mesa_printf("Tex %u tgt 0x%x level %u face %u", - att->Texture->Name, - att->Texture->Target, - att->TextureLevel, - att->CubeMapFace); + printf("Tex %u tgt 0x%x level %u face %u", + att->Texture->Name, + att->Texture->Target, + att->TextureLevel, + att->CubeMapFace); } - _mesa_printf("\n"); + printf("\n"); att = find_attachment(drawFb, colorDrawRb); - _mesa_printf(" Dst FBO %u RB %u (%dx%d) ", - drawFb->Name, colorDrawRb->Name, - colorDrawRb->Width, colorDrawRb->Height); + printf(" Dst FBO %u RB %u (%dx%d) ", + drawFb->Name, colorDrawRb->Name, + colorDrawRb->Width, colorDrawRb->Height); if (att && att->Texture) { - _mesa_printf("Tex %u tgt 0x%x level %u face %u", - att->Texture->Name, - att->Texture->Target, - att->TextureLevel, - att->CubeMapFace); + printf("Tex %u tgt 0x%x level %u face %u", + att->Texture->Name, + att->Texture->Target, + att->TextureLevel, + att->CubeMapFace); } - _mesa_printf("\n"); + printf("\n"); } }