X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ffbobject.c;h=48b9904642a8ba4177c3e1c9376c407aa23b71b1;hb=61ec20581696004acad516b14ca4a8a5ae9e6f1d;hp=7c442e390c2a3feaca8467f8e22f205b24299f1b;hpb=275c4bd3643d773210780cb8d578ca84f2604684;p=mesa.git diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 7c442e390c2..48b9904642a 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -147,6 +147,8 @@ invalidate_framebuffer(struct gl_framebuffer *fb) /** * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding * gl_renderbuffer_attachment object. + * This function is only used for user-created FB objects, not the + * default / window-system FB object. * If \p attachment is GL_DEPTH_STENCIL_ATTACHMENT, return a pointer to * the depth buffer attachment point. */ @@ -156,6 +158,8 @@ _mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb, { GLuint i; + assert(fb->Name > 0); + switch (attachment) { case GL_COLOR_ATTACHMENT0_EXT: case GL_COLOR_ATTACHMENT1_EXT: @@ -180,8 +184,50 @@ _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: + return NULL; + } +} + + +/** + * As above, but only used for getting attachments of the default / + * window-system framebuffer (not user-created framebuffer objects). + */ +static struct gl_renderbuffer_attachment * +_mesa_get_fb0_attachment(GLcontext *ctx, struct gl_framebuffer *fb, + GLenum attachment) +{ + assert(fb->Name == 0); + + switch (attachment) { + case GL_FRONT_LEFT: + return &fb->Attachment[BUFFER_FRONT_LEFT]; + case GL_FRONT_RIGHT: + return &fb->Attachment[BUFFER_FRONT_RIGHT]; + case GL_BACK_LEFT: + return &fb->Attachment[BUFFER_BACK_LEFT]; + case GL_BACK_RIGHT: + return &fb->Attachment[BUFFER_BACK_RIGHT]; + case GL_AUX0: + if (fb->Visual.numAuxBuffers == 1) { + return &fb->Attachment[BUFFER_AUX0]; + } + return NULL; + 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: @@ -190,6 +236,7 @@ _mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb, } + /** * Remove any texture or renderbuffer attached to the given attachment * point. Update reference counts, etc. @@ -389,7 +436,9 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format, if (format == GL_COLOR) { if (baseFormat != GL_RGB && - baseFormat != GL_RGBA) { + baseFormat != GL_RGBA && + (!ctx->Extensions.ARB_framebuffer_object || + baseFormat != GL_ALPHA)) { att_incomplete("bad format"); att->Complete = GL_FALSE; return; @@ -568,7 +617,8 @@ _mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb) f = texImg->_BaseFormat; numImages++; if (f != GL_RGB && f != GL_RGBA && f != GL_DEPTH_COMPONENT - && f != GL_DEPTH_STENCIL_EXT) { + && f != GL_DEPTH_STENCIL_EXT + && (!ctx->Extensions.ARB_framebuffer_object || f != GL_ALPHA)) { fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT; fbo_incomplete("texture attachment incomplete", -1); return; @@ -625,30 +675,32 @@ _mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb) } } -#ifndef FEATURE_OES_framebuffer_object - /* Check that all DrawBuffers are present */ - for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) { - if (fb->ColorDrawBuffer[j] != GL_NONE) { - const struct gl_renderbuffer_attachment *att - = _mesa_get_attachment(ctx, fb, fb->ColorDrawBuffer[j]); - assert(att); - if (att->Type == GL_NONE) { - fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT; - fbo_incomplete("missing drawbuffer", j); - return; - } +#if FEATURE_GL + if (ctx->API == API_OPENGL) { + /* Check that all DrawBuffers are present */ + for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) { + if (fb->ColorDrawBuffer[j] != GL_NONE) { + const struct gl_renderbuffer_attachment *att + = _mesa_get_attachment(ctx, fb, fb->ColorDrawBuffer[j]); + assert(att); + if (att->Type == GL_NONE) { + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT; + fbo_incomplete("missing drawbuffer", j); + return; + } + } } - } - /* Check that the ReadBuffer is present */ - if (fb->ColorReadBuffer != GL_NONE) { - const struct gl_renderbuffer_attachment *att - = _mesa_get_attachment(ctx, fb, fb->ColorReadBuffer); - assert(att); - if (att->Type == GL_NONE) { - fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT; + /* Check that the ReadBuffer is present */ + if (fb->ColorReadBuffer != GL_NONE) { + const struct gl_renderbuffer_attachment *att + = _mesa_get_attachment(ctx, fb, fb->ColorReadBuffer); + assert(att); + if (att->Type == GL_NONE) { + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT; fbo_incomplete("missing readbuffer", -1); - return; + return; + } } } #else @@ -883,6 +935,7 @@ _mesa_base_fbo_format(GLcontext *ctx, GLenum internalFormat) case GL_RGB10_A2: case GL_RGBA12: case GL_RGBA16: + case GL_RGBA16_SNORM: return GL_RGBA; case GL_STENCIL_INDEX: case GL_STENCIL_INDEX1_EXT: @@ -1008,22 +1061,31 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, */ } + #if FEATURE_OES_EGL_image void GLAPIENTRY -_mesa_EGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image) +_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"); + _mesa_error(ctx, GL_INVALID_ENUM, + "EGLImageTargetRenderbufferStorageOES"); return; } rb = ctx->CurrentRenderbuffer; if (!rb) { - _mesa_error(ctx, GL_INVALID_OPERATION, "EGLImageTargetRenderbufferStorageOES"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "EGLImageTargetRenderbufferStorageOES"); return; } @@ -1033,6 +1095,7 @@ _mesa_EGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image) } #endif + /** * Helper function for _mesa_GetRenderbufferParameterivEXT() and * _mesa_GetFramebufferAttachmentParameterivEXT() @@ -1101,6 +1164,26 @@ _mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples, } +/** + * OpenGL ES version of glRenderBufferStorage. + */ +void GLAPIENTRY +_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, + GLsizei width, GLsizei height) +{ + switch (internalFormat) { + case GL_RGB565: + /* XXX this confuses GL_RENDERBUFFER_INTERNAL_FORMAT_OES */ + /* choose a closest format */ + internalFormat = GL_RGB5; + break; + default: + break; + } + + renderbuffer_storage(target, internalFormat, width, height, 0); +} + void GLAPIENTRY _mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params) @@ -1774,10 +1857,10 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment, rb = NULL; } - if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT && + rb && rb->Format != MESA_FORMAT_NONE) { /* make sure the renderbuffer is a depth/stencil format */ - const GLenum baseFormat = - _mesa_get_format_base_format(att->Renderbuffer->Format); + const GLenum baseFormat = _mesa_get_format_base_format(rb->Format); if (baseFormat != GL_DEPTH_STENCIL) { _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT(renderbuffer" @@ -1838,12 +1921,14 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, } if (buffer->Name == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetFramebufferAttachmentParameterivEXT"); - return; + /* the default / window-system FBO */ + att = _mesa_get_fb0_attachment(ctx, buffer, attachment); + } + else { + /* user-created framebuffer FBO */ + att = _mesa_get_attachment(ctx, buffer, attachment); } - att = _mesa_get_attachment(ctx, buffer, attachment); if (att == NULL) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetFramebufferAttachmentParameterivEXT(attachment)");