X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fframebuffer.c;h=039762a074aaba5f541d32a74a611eab0cd51a7d;hb=edd50828618ed2efe799013c2723d67c407d86b4;hp=f69dc6cb3e62017b38bf74c0416722423039b3d1;hpb=f96309753b7f5f4ea5e1942778087b3ace8eda9b;p=mesa.git diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index f69dc6cb3e6..039762a074a 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -44,6 +44,7 @@ #include "renderbuffer.h" #include "texobj.h" #include "glformats.h" +#include "state.h" @@ -250,13 +251,12 @@ _mesa_reference_framebuffer_(struct gl_framebuffer **ptr, oldFb->RefCount--; deleteFlag = (oldFb->RefCount == 0); mtx_unlock(&oldFb->Mutex); - + if (deleteFlag) oldFb->Delete(oldFb); *ptr = NULL; } - assert(!*ptr); if (fb) { mtx_lock(&fb->Mutex); @@ -320,43 +320,6 @@ _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb, } } -/** - * Examine all the framebuffer's renderbuffers to update the Width/Height - * fields of the framebuffer. If we have renderbuffers with different - * sizes, set the framebuffer's width and height to the min size. - * Note: this is only intended for user-created framebuffers, not - * window-system framebuffes. - */ -static void -update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb) -{ - GLuint minWidth = ~0, minHeight = ~0; - GLuint i; - - /* user-created framebuffers only */ - assert(_mesa_is_user_fbo(fb)); - - for (i = 0; i < BUFFER_COUNT; i++) { - struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; - const struct gl_renderbuffer *rb = att->Renderbuffer; - if (rb) { - minWidth = MIN2(minWidth, rb->Width); - minHeight = MIN2(minHeight, rb->Height); - } - } - - if (minWidth != ~0U) { - fb->Width = minWidth; - fb->Height = minHeight; - } - else { - fb->Width = 0; - fb->Height = 0; - } -} - - - /** * Given a bounding box, intersect the bounding box with the scissor of * a specified vieport. @@ -403,14 +366,14 @@ _mesa_intersect_scissor_bounding_box(const struct gl_context *ctx, * xmax, ymin, ymax. * * \warning This function assumes that the framebuffer dimensions are up to - * date (e.g., update_framebuffer_size has been recently called on \c buffer). + * date. * * \sa _mesa_clip_to_region */ -void -_mesa_scissor_bounding_box(const struct gl_context *ctx, - const struct gl_framebuffer *buffer, - unsigned idx, int *bbox) +static void +scissor_bounding_box(const struct gl_context *ctx, + const struct gl_framebuffer *buffer, + unsigned idx, int *bbox) { bbox[0] = 0; bbox[2] = 0; @@ -438,13 +401,8 @@ _mesa_update_draw_buffer_bounds(struct gl_context *ctx, if (!buffer) return; - if (_mesa_is_user_fbo(buffer)) { - /* user-created framebuffer size depends on the renderbuffers */ - update_framebuffer_size(ctx, buffer); - } - /* Default to the first scissor as that's always valid */ - _mesa_scissor_bounding_box(ctx, buffer, 0, bbox); + scissor_bounding_box(ctx, buffer, 0, bbox); buffer->_Xmin = bbox[0]; buffer->_Ymin = bbox[2]; buffer->_Xmax = bbox[1]; @@ -474,13 +432,6 @@ _mesa_update_framebuffer_visual(struct gl_context *ctx, memset(&fb->Visual, 0, sizeof(fb->Visual)); fb->Visual.rgbMode = GL_TRUE; /* assume this */ -#if 0 /* this _might_ be needed */ - if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { - /* leave visual fields zero'd */ - return; - } -#endif - /* find first RGB renderbuffer */ for (i = 0; i < BUFFER_COUNT; i++) { if (fb->Attachment[i].Renderbuffer) { @@ -631,7 +582,7 @@ static void update_color_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb) { (void) ctx; - if (fb->_ColorReadBufferIndex == -1 || + if (fb->_ColorReadBufferIndex == BUFFER_NONE || fb->DeletePending || fb->Width == 0 || fb->Height == 0) { @@ -836,28 +787,62 @@ _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format) /** - * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES query. + * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES queries (using + * GetIntegerv, GetFramebufferParameteriv, etc) + * + * If @fb is NULL, the method returns the value for the current bound + * framebuffer. */ GLenum -_mesa_get_color_read_format(struct gl_context *ctx) +_mesa_get_color_read_format(struct gl_context *ctx, + struct gl_framebuffer *fb, + const char *caller) { - if (!ctx->ReadBuffer || !ctx->ReadBuffer->_ColorReadBuffer) { - /* The spec is unclear how to handle this case, but NVIDIA's - * driver generates GL_INVALID_OPERATION. + if (ctx->NewState) + _mesa_update_state(ctx); + + if (fb == NULL) + fb = ctx->ReadBuffer; + + if (!fb || !fb->_ColorReadBuffer) { + /* + * From OpenGL 4.5 spec, section 18.2.2 "ReadPixels": + * + * "An INVALID_OPERATION error is generated by GetIntegerv if pname + * is IMPLEMENTATION_COLOR_READ_FORMAT or IMPLEMENTATION_COLOR_- + * READ_TYPE and any of: + * * the read framebuffer is not framebuffer complete. + * * the read framebuffer is a framebuffer object, and the selected + * read buffer (see section 18.2.1) has no image attached. + * * the selected read buffer is NONE." + * + * There is not equivalent quote for GetFramebufferParameteriv or + * GetNamedFramebufferParameteriv, but from section 9.2.3 "Framebuffer + * Object Queries": + * + * "Values of framebuffer-dependent state are identical to those that + * would be obtained were the framebuffer object bound and queried + * using the simple state queries in that table." + * + * Where "using the simple state queries" refer to use GetIntegerv. So + * we will assume that on that situation the same error should be + * triggered too. */ _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT: " - "no GL_READ_BUFFER)"); + "%s(GL_IMPLEMENTATION_COLOR_READ_FORMAT: no GL_READ_BUFFER)", + caller); return GL_NONE; } else { - const GLenum format = ctx->ReadBuffer->_ColorReadBuffer->Format; + const mesa_format format = fb->_ColorReadBuffer->Format; const GLenum data_type = _mesa_get_format_datatype(format); if (format == MESA_FORMAT_B8G8R8A8_UNORM) return GL_BGRA; else if (format == MESA_FORMAT_B5G6R5_UNORM) - return GL_BGR; + return GL_RGB; + else if (format == MESA_FORMAT_R_UNORM8) + return GL_RED; switch (data_type) { case GL_UNSIGNED_INT: @@ -871,26 +856,38 @@ _mesa_get_color_read_format(struct gl_context *ctx) /** - * Used to answer the GL_IMPLEMENTATION_COLOR_READ_TYPE_OES query. + * Used to answer the GL_IMPLEMENTATION_COLOR_READ_TYPE_OES queries (using + * GetIntegerv, GetFramebufferParameteriv, etc) + * + * If @fb is NULL, the method returns the value for the current bound + * framebuffer. */ GLenum -_mesa_get_color_read_type(struct gl_context *ctx) +_mesa_get_color_read_type(struct gl_context *ctx, + struct gl_framebuffer *fb, + const char *caller) { - if (!ctx->ReadBuffer || !ctx->ReadBuffer->_ColorReadBuffer) { - /* The spec is unclear how to handle this case, but NVIDIA's - * driver generates GL_INVALID_OPERATION. + if (ctx->NewState) + _mesa_update_state(ctx); + + if (fb == NULL) + fb = ctx->ReadBuffer; + + if (!fb || !fb->_ColorReadBuffer) { + /* + * See comment on _mesa_get_color_read_format */ _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE: " - "no GL_READ_BUFFER)"); + "%s(GL_IMPLEMENTATION_COLOR_READ_TYPE: no GL_READ_BUFFER)", + caller); return GL_NONE; } else { - const GLenum format = ctx->ReadBuffer->_ColorReadBuffer->Format; + const GLenum format = fb->_ColorReadBuffer->Format; const GLenum data_type = _mesa_get_format_datatype(format); if (format == MESA_FORMAT_B5G6R5_UNORM) - return GL_UNSIGNED_SHORT_5_6_5_REV; + return GL_UNSIGNED_SHORT_5_6_5; switch (data_type) { case GL_SIGNED_NORMALIZED: @@ -992,7 +989,8 @@ _mesa_geometric_nonvalidated_samples(const struct gl_framebuffer *buffer) buffer->DefaultGeometry.NumSamples; } -bool _mesa_is_multisample_enabled(const struct gl_context *ctx) +bool +_mesa_is_multisample_enabled(const struct gl_context *ctx) { /* The sample count may not be validated by the driver, but when it is set, * we know that is in a valid range and no driver should ever validate a @@ -1000,5 +998,29 @@ bool _mesa_is_multisample_enabled(const struct gl_context *ctx) */ return ctx->Multisample.Enabled && ctx->DrawBuffer && - _mesa_geometric_nonvalidated_samples(ctx->DrawBuffer) > 1; + _mesa_geometric_nonvalidated_samples(ctx->DrawBuffer) >= 1; +} + +/** + * Is alpha testing enabled and applicable to the currently bound + * framebuffer? + */ +bool +_mesa_is_alpha_test_enabled(const struct gl_context *ctx) +{ + bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1; + return (ctx->Color.AlphaEnabled && !buffer0_is_integer); +} + +/** + * Is alpha to coverage enabled and applicable to the currently bound + * framebuffer? + */ +bool +_mesa_is_alpha_to_coverage_enabled(const struct gl_context *ctx) +{ + bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1; + return (ctx->Multisample.SampleAlphaToCoverage && + _mesa_is_multisample_enabled(ctx) && + !buffer0_is_integer); }