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)
{