Refactor read pixel format/type validation. Bug swiftshader:38 Change-Id: I74c642b3c7346541d042acde78aa2e0213beb5f6 Reviewed-on: https://swiftshader-review.googlesource.com/9028 Tested-by: Nicolas Capens <capn@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp index 70ff932..f3c190d 100644 --- a/src/OpenGL/libGLESv2/utilities.cpp +++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -16,6 +16,7 @@ #include "utilities.h" +#include "Framebuffer.h" #include "main.h" #include "mathutil.h" #include "Context.h" @@ -596,82 +597,107 @@ return GL_NONE; } - bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, GLint clientVersion) + bool IsValidReadPixelsFormatType(const Framebuffer *framebuffer, GLenum format, GLenum type, GLint clientVersion) { - switch(format) + // GL_NV_read_depth + if(format == GL_DEPTH_COMPONENT) { - case GL_RGBA: - switch(type) - { - case GL_UNSIGNED_BYTE: - break; - case GL_UNSIGNED_INT_2_10_10_10_REV: - return (clientVersion >= 3) && (internalFormat == GL_RGB10_A2); - case GL_FLOAT: - return (clientVersion >= 3) && (internalType == GL_FLOAT); - default: - return false; - } - break; - case GL_RGBA_INTEGER: - if(clientVersion < 3) + Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); + + if(!depthbuffer) { return false; } - switch(type) - { - case GL_INT: - if(internalType != GL_INT) - { - return false; - } - break; - case GL_UNSIGNED_INT: - if(internalType != GL_UNSIGNED_INT) - { - return false; - } - break; - default: - return false; - } - break; - case GL_BGRA_EXT: - switch(type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - break; - default: - return false; - } - break; - case GL_RG_EXT: - case GL_RED_EXT: - return (clientVersion >= 3) && (type == GL_UNSIGNED_BYTE); - case GL_DEPTH_COMPONENT: - if(internalFormat != format) - { - return false; - } + switch(type) { case GL_UNSIGNED_SHORT: case GL_FLOAT: - if(internalType != type) - { - return false; - } - break; + return true; default: + UNIMPLEMENTED(); return false; } - break; - default: + } + + Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); + + if(!colorbuffer) + { return false; } - return true; + + sw::Format internalformat = colorbuffer->getInternalFormat(); + + if(sw::Surface::isNormalizedInteger(internalformat)) + { + // Combination always supported by normalized fixed-point rendering surfaces. + if(format == GL_RGBA && type == GL_UNSIGNED_BYTE) + { + return true; + } + } + else if(sw::Surface::isFloatFormat(internalformat)) + { + // Combination always supported by floating-point rendering surfaces. + // Supported in OpenGL ES 2.0 due to GL_EXT_color_buffer_half_float. + if(format == GL_RGBA && type == GL_FLOAT) + { + return true; + } + } + else if(sw::Surface::isSignedNonNormalizedInteger(internalformat)) + { + ASSERT(clientVersion >= 3); + + if(format == GL_RGBA_INTEGER && type == GL_INT) + { + return true; + } + } + else if(sw::Surface::isUnsignedNonNormalizedInteger(internalformat)) + { + ASSERT(clientVersion >= 3); + + if(format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT) + { + return true; + } + } + else UNREACHABLE(internalformat); + + // GL_IMPLEMENTATION_COLOR_READ_FORMAT / GL_IMPLEMENTATION_COLOR_READ_TYPE + GLenum implementationReadFormat = GL_NONE; + GLenum implementationReadType = GL_NONE; + switch(format) + { + default: + implementationReadFormat = framebuffer->getImplementationColorReadFormat(); + implementationReadType = framebuffer->getImplementationColorReadType(); + break; + case GL_DEPTH_COMPONENT: + implementationReadFormat = framebuffer->getDepthReadFormat(); + implementationReadType = framebuffer->getDepthReadType(); + break; + } + + if(format == implementationReadFormat && type == implementationReadType) + { + return true; + } + + // Additional third combination accepted by OpenGL ES 3.0. + if(internalformat == sw::FORMAT_A2B10G10R10) + { + ASSERT(clientVersion >= 3); + + if(format == GL_RGBA && type == GL_UNSIGNED_INT_2_10_10_10_REV) + { + return true; + } + } + + return false; } bool IsDepthTexture(GLenum format) @@ -1878,7 +1904,7 @@ return GL_SIGNED_NORMALIZED; default: UNREACHABLE(format); - return 0; + return GL_NONE; } case GL_DEPTH_ATTACHMENT: case GL_STENCIL_ATTACHMENT: @@ -1886,7 +1912,7 @@ return GL_FLOAT; default: UNREACHABLE(attachment); - return 0; + return GL_NONE; } }