Support reading of half-float formats. Bug swiftshader:104 Change-Id: I037fcb69131906b52e0c1919f36fea61b2e1c621 Reviewed-on: https://swiftshader-review.googlesource.com/19628 Tested-by: Nicolas Capens <nicolascapens@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp index 57fa354..7d21c63 100644 --- a/src/OpenGL/libGLESv2/Context.cpp +++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3349,6 +3349,8 @@ sw::SliceRectF sliceRect(rect); sw::SliceRect dstSliceRect(dstRect); device->blit(renderTarget, sliceRect, externalSurface, dstSliceRect, false, false, false); + externalSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC); + externalSurface->unlockExternal(); delete externalSurface; renderTarget->release();
diff --git a/src/OpenGL/libGLESv2/Framebuffer.cpp b/src/OpenGL/libGLESv2/Framebuffer.cpp index f466de4..4a9be7b 100644 --- a/src/OpenGL/libGLESv2/Framebuffer.cpp +++ b/src/OpenGL/libGLESv2/Framebuffer.cpp
@@ -621,11 +621,11 @@ case GL_RG32UI: return GL_UNSIGNED_INT; case GL_RGB32UI: return GL_UNSIGNED_INT; case GL_RGBA32UI: return GL_UNSIGNED_INT; - case GL_R16F: return GL_FLOAT; - case GL_RG16F: return GL_FLOAT; - case GL_R11F_G11F_B10F: return GL_FLOAT; - case GL_RGB16F: return GL_FLOAT; - case GL_RGBA16F: return GL_FLOAT; + case GL_R16F: return GL_HALF_FLOAT; + case GL_RG16F: return GL_HALF_FLOAT; + case GL_R11F_G11F_B10F: return GL_HALF_FLOAT; + case GL_RGB16F: return GL_HALF_FLOAT; + case GL_RGBA16F: return GL_HALF_FLOAT; case GL_R32F: return GL_FLOAT; case GL_RG32F: return GL_FLOAT; case GL_RGB32F: return GL_FLOAT;
diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp index c531b26..246b71c 100644 --- a/src/OpenGL/libGLESv2/utilities.cpp +++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -714,7 +714,9 @@ break; } - if(format == implementationReadFormat && type == implementationReadType) + GLenum coreType = (type == GL_HALF_FLOAT_OES) ? GL_HALF_FLOAT : type; + + if(format == implementationReadFormat && coreType == implementationReadType) { return true; }
diff --git a/tests/unittests/unittests.cpp b/tests/unittests/unittests.cpp index 037112d..371fce3 100644 --- a/tests/unittests/unittests.cpp +++ b/tests/unittests/unittests.cpp
@@ -30,6 +30,7 @@ #endif #include <string.h> +#include <cstdint> #define EXPECT_GLENUM_EQ(expected, actual) EXPECT_EQ(static_cast<GLenum>(expected), static_cast<GLenum>(actual)) @@ -587,6 +588,44 @@ Uninitialize(); } +// Tests reading of half-float textures. +TEST_F(SwiftShaderTest, ReadHalfFloat) +{ + Initialize(3, false); + + GLuint tex = 1; + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 256, 256, 0, GL_RGB, GL_HALF_FLOAT, nullptr); + EXPECT_GLENUM_EQ(GL_NONE, glGetError()); + + GLuint fbo = 1; + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + EXPECT_GLENUM_EQ(GL_NONE, glGetError()); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + const float clear_color[4] = { 1.0f, 32.0f, 0.5f, 1.0f }; + glClearColor(clear_color[0], clear_color[1], clear_color[2], 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GLENUM_EQ(GL_NONE, glGetError()); + + int16_t pixel[3] = { 0x1234, 0x3F80, 0xAAAA }; + GLint x = 6; + GLint y = 3; + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, 1, 1, GL_RGB, GL_HALF_FLOAT, pixel); + + // This relies on GL_HALF_FLOAT being a valid type for read-back, + // which isn't guaranteed by the spec but is supported by SwiftShader. + int16_t read_color[3] = { 0, 0, 0 }; + glReadPixels(x, y, 1, 1, GL_RGB, GL_HALF_FLOAT, &read_color); + EXPECT_GLENUM_EQ(GL_NONE, glGetError()); + EXPECT_EQ(read_color[0], pixel[0]); + EXPECT_EQ(read_color[1], pixel[1]); + EXPECT_EQ(read_color[2], pixel[2]); + + Uninitialize(); +} + // Tests construction of a structure containing a single matrix TEST_F(SwiftShaderTest, MatrixInStruct) {