aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main/fbobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main/fbobject.c')
-rw-r--r--mesalib/src/mesa/main/fbobject.c128
1 files changed, 119 insertions, 9 deletions
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 4370c7218..eb03b0918 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -38,8 +38,8 @@
#include "fbobject.h"
#include "formats.h"
#include "framebuffer.h"
+#include "glformats.h"
#include "hash.h"
-#include "image.h"
#include "macros.h"
#include "mfeatures.h"
#include "mtypes.h"
@@ -164,10 +164,10 @@ get_framebuffer_target(struct gl_context *ctx, GLenum target)
{
switch (target) {
case GL_DRAW_FRAMEBUFFER:
- return ctx->Extensions.EXT_framebuffer_blit && ctx->API == API_OPENGL
+ return ctx->Extensions.EXT_framebuffer_blit && _mesa_is_desktop_gl(ctx)
? ctx->DrawBuffer : NULL;
case GL_READ_FRAMEBUFFER:
- return ctx->Extensions.EXT_framebuffer_blit && ctx->API == API_OPENGL
+ return ctx->Extensions.EXT_framebuffer_blit && _mesa_is_desktop_gl(ctx)
? ctx->ReadBuffer : NULL;
case GL_FRAMEBUFFER_EXT:
return ctx->DrawBuffer;
@@ -221,7 +221,7 @@ _mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
}
return &fb->Attachment[BUFFER_COLOR0 + i];
case GL_DEPTH_STENCIL_ATTACHMENT:
- if (ctx->API != API_OPENGL)
+ if (!_mesa_is_desktop_gl(ctx))
return NULL;
/* fall-through */
case GL_DEPTH_ATTACHMENT_EXT:
@@ -817,7 +817,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
}
#if FEATURE_GL
- if (ctx->API == API_OPENGL && !ctx->Extensions.ARB_ES2_compatibility) {
+ if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) {
/* Check that all DrawBuffers are present */
for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) {
if (fb->ColorDrawBuffer[j] != GL_NONE) {
@@ -2289,7 +2289,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
ASSERT_OUTSIDE_BEGIN_END(ctx);
/* The error differs in GL and GLES. */
- err = ctx->API == API_OPENGL ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
+ err = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
buffer = get_framebuffer_target(ctx, target);
if (!buffer) {
@@ -2309,7 +2309,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
* OES_framebuffer_object spec refers to the EXT_framebuffer_object
* spec.
*/
- if (ctx->API != API_OPENGL || !ctx->Extensions.ARB_framebuffer_object) {
+ if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_framebuffer_object) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetFramebufferAttachmentParameteriv(bound FBO = 0)");
return;
@@ -2357,7 +2357,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
}
else {
assert(att->Type == GL_NONE);
- if (ctx->API == API_OPENGL) {
+ if (_mesa_is_desktop_gl(ctx)) {
*params = 0;
} else {
_mesa_error(ctx, GL_INVALID_ENUM,
@@ -2633,6 +2633,116 @@ compatible_color_datatypes(gl_format srcFormat, gl_format dstFormat)
/**
+ * Return the equivalent non-generic internal format.
+ * This is useful for comparing whether two internal formats are semantically
+ * equivalent.
+ */
+static GLenum
+get_nongeneric_internalformat(GLenum format)
+{
+ switch (format) {
+ /* GL 1.1 formats. */
+ case 4:
+ case GL_RGBA:
+ return GL_RGBA8;
+
+ case 3:
+ case GL_RGB:
+ return GL_RGB8;
+
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ return GL_LUMINANCE8_ALPHA8;
+
+ case 1:
+ case GL_LUMINANCE:
+ return GL_LUMINANCE8;
+
+ case GL_ALPHA:
+ return GL_ALPHA8;
+
+ case GL_INTENSITY:
+ return GL_INTENSITY8;
+
+ /* GL_ARB_texture_rg */
+ case GL_RED:
+ return GL_R8;
+
+ case GL_RG:
+ return GL_RG8;
+
+ /* GL_EXT_texture_sRGB */
+ case GL_SRGB:
+ return GL_SRGB8;
+
+ case GL_SRGB_ALPHA:
+ return GL_SRGB8_ALPHA8;
+
+ case GL_SLUMINANCE:
+ return GL_SLUMINANCE8;
+
+ case GL_SLUMINANCE_ALPHA:
+ return GL_SLUMINANCE8_ALPHA8;
+
+ /* GL_EXT_texture_snorm */
+ case GL_RGBA_SNORM:
+ return GL_RGBA8_SNORM;
+
+ case GL_RGB_SNORM:
+ return GL_RGB8_SNORM;
+
+ case GL_RG_SNORM:
+ return GL_RG8_SNORM;
+
+ case GL_RED_SNORM:
+ return GL_R8_SNORM;
+
+ case GL_LUMINANCE_ALPHA_SNORM:
+ return GL_LUMINANCE8_ALPHA8_SNORM;
+
+ case GL_LUMINANCE_SNORM:
+ return GL_LUMINANCE8_SNORM;
+
+ case GL_ALPHA_SNORM:
+ return GL_ALPHA8_SNORM;
+
+ case GL_INTENSITY_SNORM:
+ return GL_INTENSITY8_SNORM;
+
+ default:
+ return format;
+ }
+}
+
+
+static GLboolean
+compatible_resolve_formats(const struct gl_renderbuffer *colorReadRb,
+ const struct gl_renderbuffer *colorDrawRb)
+{
+ /* The simple case where we know the backing formats are the same.
+ */
+ if (colorReadRb->Format == colorDrawRb->Format) {
+ return GL_TRUE;
+ }
+
+ /* The Mesa formats are different, so we must check whether the internal
+ * formats are compatible.
+ *
+ * Under some circumstances, the user may request e.g. two GL_RGBA8
+ * textures and get two entirely different Mesa formats like RGBA8888 and
+ * ARGB8888. Drivers behaving like that should be able to cope with
+ * non-matching formats by themselves, because it's not the user's fault.
+ */
+ if (get_nongeneric_internalformat(colorReadRb->InternalFormat) ==
+ get_nongeneric_internalformat(colorDrawRb->InternalFormat)) {
+ return GL_TRUE;
+ }
+
+ return GL_FALSE;
+}
+
+
+/**
* Blit rectangular region, optionally from one framebuffer to another.
*
* Note, if the src buffer is multisampled and the dest is not, this is
@@ -2798,7 +2908,7 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
/* color formats must match */
if (colorReadRb &&
colorDrawRb &&
- colorReadRb->Format != colorDrawRb->Format) {
+ !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBlitFramebufferEXT(bad src/dst multisample pixel formats)");
return;