summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-07-21 15:16:15 +0200
committerMarek Olšák <[email protected]>2012-07-23 19:23:52 +0200
commit592722757648efc723663d6c9dbe874c7475e95c (patch)
tree9a419132b812fd0a3da68dcaa3414ebdb38be61d /src/mesa
parentc30bf68946433d26f672c741a763bba4712aada7 (diff)
mesa: fix format checking when doing a multisample resolve
v2: make it more bullet-proof Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/fbobject.c112
1 files changed, 111 insertions, 1 deletions
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 4370c7218c8..ca43f810553 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -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;