Update checks for floating point renderability.
* Expose GL_CHROMIUM_color_buffer_float_rgb and
GL_CHROMIUM_color_buffer_float_rgba
* Fix many texture formats that were incorrectly checking the wrong
extension for support or renderability.
* Make all floating point texture extensions dynamically enableable.
BUG=angleproject:1958
BUG=angleproject:1715
Change-Id: Iefccc8b5ae5edd97623affa9de05b1d9af5c9598
Reviewed-on: https://chromium-review.googlesource.com/468450
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index e60768b..c281f17 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -8,6 +8,7 @@
#include "test_utils/ANGLETest.h"
+#include "common/mathutil.h"
#include "test_utils/gl_raii.h"
namespace
@@ -32,6 +33,20 @@
}
}
+// Extensions that affect the ability to use floating point textures
+constexpr const char *FloatingPointTextureExtensions[] = {
+ "",
+ "GL_EXT_texture_storage",
+ "GL_OES_texture_float",
+ "GL_OES_texture_float_linear",
+ "GL_OES_texture_half_float",
+ "GL_OES_texture_half_float_linear",
+ "GL_EXT_color_buffer_half_float",
+ "GL_EXT_color_buffer_float",
+ "GL_CHROMIUM_color_buffer_float_rgba",
+ "GL_CHROMIUM_color_buffer_float_rgb",
+};
+
} // namespace
namespace angle
@@ -58,6 +73,150 @@
eglGetProcAddress("glRequestExtensionANGLE"));
}
+ template <typename T>
+ void TestFloatTextureFormat(GLenum internalFormat,
+ GLenum format,
+ GLenum type,
+ bool texturingEnabled,
+ bool linearSamplingEnabled,
+ bool renderingEnabled,
+ const T textureData[4],
+ const float floatData[4])
+ {
+ ASSERT_GL_NO_ERROR();
+
+ const std::string samplingVs =
+ "attribute vec4 position;\n"
+ "varying vec2 texcoord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
+ " texcoord = (position.xy * 0.5) + 0.5;\n"
+ "}\n";
+
+ const std::string samplingFs =
+ "precision mediump float;\n"
+ "uniform sampler2D tex;\n"
+ "uniform vec4 subtractor;\n"
+ "varying vec2 texcoord;\n"
+ "void main()\n"
+ "{\n"
+ " vec4 color = texture2D(tex, texcoord);\n"
+ " if (abs(color.r - subtractor.r) +\n"
+ " abs(color.g - subtractor.g) +\n"
+ " abs(color.b - subtractor.b) +\n"
+ " abs(color.a - subtractor.a) < 8.0)\n"
+ " {\n"
+ " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
+ " }\n"
+ "}\n";
+
+ ANGLE_GL_PROGRAM(samplingProgram, samplingVs, samplingFs);
+ glUseProgram(samplingProgram.get());
+
+ GLRenderbuffer rbo;
+ glBindRenderbuffer(GL_RENDERBUFFER, rbo.get());
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
+
+ GLFramebuffer fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo.get());
+
+ GLTexture texture;
+ glBindTexture(GL_TEXTURE_2D, texture.get());
+
+ if (internalFormat == format)
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, textureData);
+ }
+ else
+ {
+ if (getClientMajorVersion() >= 3)
+ {
+ glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
+ }
+ else
+ {
+ ASSERT_TRUE(extensionEnabled("GL_EXT_texture_storage"));
+ glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
+ }
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, format, type, textureData);
+ }
+
+ if (!texturingEnabled)
+ {
+ // Depending on the entry point and client version, different errors may be generated
+ ASSERT_GLENUM_NE(GL_NO_ERROR, glGetError());
+
+ // Two errors may be generated in the glTexStorage + glTexSubImage case, clear the
+ // second error
+ glGetError();
+
+ return;
+ }
+ ASSERT_GL_NO_ERROR();
+
+ glUniform1i(glGetUniformLocation(samplingProgram.get(), "tex"), 0);
+ glUniform4fv(glGetUniformLocation(samplingProgram.get(), "subtractor"), 1, floatData);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ drawQuad(samplingProgram.get(), "position", 0.5f, 1.0f, true);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ drawQuad(samplingProgram.get(), "position", 0.5f, 1.0f, true);
+
+ if (linearSamplingEnabled)
+ {
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+ }
+ else
+ {
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+ }
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.get(),
+ 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ if (!renderingEnabled)
+ {
+ EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ glCheckFramebufferStatus(GL_FRAMEBUFFER));
+ return;
+ }
+ ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ const std::string renderingVs =
+ "attribute vec4 position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
+ "}\n";
+
+ const std::string renderingFs =
+ "precision mediump float;\n"
+ "uniform vec4 writeValue;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = writeValue;\n"
+ "}\n";
+
+ ANGLE_GL_PROGRAM(renderingProgram, renderingVs, renderingFs);
+ glUseProgram(renderingProgram.get());
+
+ glUniform4fv(glGetUniformLocation(renderingProgram.get(), "writeValue"), 1, floatData);
+
+ drawQuad(renderingProgram.get(), "position", 0.5f, 1.0f, true);
+
+ EXPECT_PIXEL_COLOR32F_NEAR(
+ 0, 0, GLColor32F(floatData[0], floatData[1], floatData[2], floatData[3]), 1.0f);
+ }
+
// Called from RenderingFeedbackLoopWithDrawBuffersEXT.
void drawBuffersEXTFeedbackLoop(GLuint program,
const std::array<GLenum, 2> &drawBuffers,
@@ -1341,6 +1500,447 @@
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
}
+TEST_P(WebGLCompatibilityTest, L32FTextures)
+{
+ constexpr float textureData[] = {15.1f, 0.0f, 0.0f, 0.0f};
+ constexpr float readPixelData[] = {textureData[0], textureData[0], textureData[0], 1.0f};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized L 32F
+ {
+ bool texture = extensionEnabled("GL_OES_texture_float");
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = false;
+ TestFloatTextureFormat(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT, texture, filter, render,
+ textureData, readPixelData);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized L 32F
+ bool texture = extensionEnabled("GL_OES_texture_float") &&
+ extensionEnabled("GL_EXT_texture_storage");
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = false;
+ TestFloatTextureFormat(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT, texture, filter,
+ render, textureData, readPixelData);
+ }
+ }
+}
+
+TEST_P(WebGLCompatibilityTest, A32FTextures)
+{
+ constexpr float textureData[] = {33.33f, 0.0f, 0.0f, 0.0f};
+ constexpr float readPixelData[] = {0.0f, 0.0f, 0.0f, textureData[0]};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized A 32F
+ {
+ bool texture = extensionEnabled("GL_OES_texture_float");
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = false;
+ TestFloatTextureFormat(GL_ALPHA, GL_ALPHA, GL_FLOAT, texture, filter, render,
+ textureData, readPixelData);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized A 32F
+ bool texture = extensionEnabled("GL_OES_texture_float") &&
+ extensionEnabled("GL_EXT_texture_storage");
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = false;
+ TestFloatTextureFormat(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT, texture, filter, render,
+ textureData, readPixelData);
+ }
+ }
+}
+
+TEST_P(WebGLCompatibilityTest, LA32FTextures)
+{
+ constexpr float textureData[] = {-0.21f, 15.1f, 0.0f, 0.0f};
+ constexpr float readPixelData[] = {textureData[0], textureData[0], textureData[0],
+ textureData[1]};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized LA 32F
+ {
+ bool texture = extensionEnabled("GL_OES_texture_float");
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = false;
+ TestFloatTextureFormat(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT, texture,
+ filter, render, textureData, readPixelData);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized LA 32F
+ bool texture = extensionEnabled("GL_OES_texture_float") &&
+ extensionEnabled("GL_EXT_texture_storage");
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = false;
+ TestFloatTextureFormat(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT, texture,
+ filter, render, textureData, readPixelData);
+ }
+ }
+}
+
+TEST_P(WebGLCompatibilityTest, R32FTextures)
+{
+ constexpr float data[] = {1000.0f, 0.0f, 0.0f, 1.0f};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized R 32F
+ {
+ bool texture =
+ extensionEnabled("GL_OES_texture_float") && extensionEnabled("GL_EXT_texture_rg");
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_float");
+ TestFloatTextureFormat(GL_RED, GL_RED, GL_FLOAT, texture, filter, render, data, data);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized R 32F
+ bool texture =
+ (getClientMajorVersion() >= 3) || (extensionEnabled("GL_OES_texture_float") &&
+ extensionEnabled("GL_EXT_texture_rg") &&
+ extensionEnabled("GL_EXT_texture_storage"));
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_float");
+ TestFloatTextureFormat(GL_R32F, GL_RED, GL_FLOAT, texture, filter, render, data, data);
+ }
+ }
+}
+
+TEST_P(WebGLCompatibilityTest, RG32FTextures)
+{
+ constexpr float data[] = {1000.0f, -0.001f, 0.0f, 1.0f};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized RG 32F
+ {
+ bool texture =
+ (extensionEnabled("GL_OES_texture_float") && extensionEnabled("GL_EXT_texture_rg"));
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_float");
+ TestFloatTextureFormat(GL_RG, GL_RG, GL_FLOAT, texture, filter, render, data, data);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized RG 32F
+ bool texture =
+ (getClientMajorVersion() >= 3) || (extensionEnabled("GL_OES_texture_float") &&
+ extensionEnabled("GL_EXT_texture_rg") &&
+ extensionEnabled("GL_EXT_texture_storage"));
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_float");
+ TestFloatTextureFormat(GL_RG32F, GL_RG, GL_FLOAT, texture, filter, render, data, data);
+ }
+ }
+}
+
+TEST_P(WebGLCompatibilityTest, RGB32FTextures)
+{
+ constexpr float data[] = {1000.0f, -500.0f, 10.0f, 1.0f};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized RGB 32F
+ {
+ bool texture = extensionEnabled("GL_OES_texture_float");
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = extensionEnabled("GL_CHROMIUM_color_buffer_float_rgb");
+ TestFloatTextureFormat(GL_RGB, GL_RGB, GL_FLOAT, texture, filter, render, data, data);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized RGBA 32F
+ bool texture =
+ (getClientMajorVersion() >= 3) || (extensionEnabled("GL_OES_texture_float") &&
+ extensionEnabled("GL_EXT_texture_storage"));
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = extensionEnabled("GL_CHROMIUM_color_buffer_float_rgb");
+ TestFloatTextureFormat(GL_RGB32F, GL_RGB, GL_FLOAT, texture, filter, render, data,
+ data);
+ }
+ }
+}
+
+TEST_P(WebGLCompatibilityTest, RGBA32FTextures)
+{
+ constexpr float data[] = {7000.0f, 100.0f, 33.0f, -1.0f};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized RGBA 32F
+ {
+ bool texture = extensionEnabled("GL_OES_texture_float");
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_float") ||
+ extensionEnabled("GL_CHROMIUM_color_buffer_float_rgba");
+ TestFloatTextureFormat(GL_RGBA, GL_RGBA, GL_FLOAT, texture, filter, render, data, data);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized RGBA 32F
+ bool texture =
+ (getClientMajorVersion() >= 3) || (extensionEnabled("GL_OES_texture_float") &&
+ extensionEnabled("GL_EXT_texture_storage"));
+ bool filter = extensionEnabled("GL_OES_texture_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_float") ||
+ extensionEnabled("GL_CHROMIUM_color_buffer_float_rgba");
+ TestFloatTextureFormat(GL_RGBA32F, GL_RGBA, GL_FLOAT, texture, filter, render, data,
+ data);
+ }
+ }
+}
+
+TEST_P(WebGLCompatibilityTest, R16FTextures)
+{
+ constexpr float readPixelsData[] = {-5000.0f, 0.0f, 0.0f, 1.0f};
+ const GLushort textureData[] = {
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized R 16F (OES)
+ {
+ bool texture = extensionEnabled("GL_OES_texture_half_float") &&
+ extensionEnabled("GL_EXT_texture_rg");
+ bool filter = getClientMajorVersion() >= 3 ||
+ extensionEnabled("GL_OES_texture_half_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_half_float");
+ TestFloatTextureFormat(GL_RED, GL_RED, GL_HALF_FLOAT_OES, texture, filter, render,
+ textureData, readPixelsData);
+ }
+
+ // Unsized R 16F
+ {
+ bool texture = false;
+ bool filter = false;
+ bool render = false;
+ TestFloatTextureFormat(GL_RED, GL_RED, GL_HALF_FLOAT, texture, filter, render,
+ textureData, readPixelsData);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized R 16F
+ bool texture = getClientMajorVersion() >= 3;
+ bool filter = getClientMajorVersion() >= 3 ||
+ extensionEnabled("GL_OES_texture_half_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_half_float") ||
+ extensionEnabled("GL_EXT_color_buffer_float");
+ TestFloatTextureFormat(GL_R16F, GL_RED, GL_HALF_FLOAT, texture, filter, render,
+ textureData, readPixelsData);
+ }
+ }
+}
+
+TEST_P(WebGLCompatibilityTest, RG16FTextures)
+{
+ constexpr float readPixelsData[] = {7108.0f, -10.0f, 0.0f, 1.0f};
+ const GLushort textureData[] = {
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized RG 16F (OES)
+ {
+ bool texture = extensionEnabled("GL_OES_texture_half_float") &&
+ extensionEnabled("GL_EXT_texture_rg");
+ bool filter = getClientMajorVersion() >= 3 ||
+ extensionEnabled("GL_OES_texture_half_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_half_float") &&
+ extensionEnabled("GL_EXT_texture_rg");
+ TestFloatTextureFormat(GL_RG, GL_RG, GL_HALF_FLOAT_OES, texture, filter, render,
+ textureData, readPixelsData);
+ }
+
+ // Unsized RG 16F
+ {
+ bool texture = false;
+ bool filter = false;
+ bool render = false;
+ TestFloatTextureFormat(GL_RG, GL_RG, GL_HALF_FLOAT, texture, filter, render,
+ textureData, readPixelsData);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized RG 16F
+ bool texture = getClientMajorVersion() >= 3;
+ bool filter = getClientMajorVersion() >= 3 ||
+ extensionEnabled("GL_OES_texture_half_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_half_float") ||
+ extensionEnabled("GL_EXT_color_buffer_float");
+ TestFloatTextureFormat(GL_RG16F, GL_RG, GL_HALF_FLOAT, texture, filter, render,
+ textureData, readPixelsData);
+ }
+ }
+}
+
+TEST_P(WebGLCompatibilityTest, RGB16FTextures)
+{
+ constexpr float readPixelsData[] = {7000.0f, 100.0f, 33.0f, 1.0f};
+ const GLushort textureData[] = {
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized RGB 16F (OES)
+ {
+ bool texture = extensionEnabled("GL_OES_texture_half_float");
+ bool filter = getClientMajorVersion() >= 3 ||
+ extensionEnabled("GL_OES_texture_half_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_half_float");
+ TestFloatTextureFormat(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES, texture, filter, render,
+ textureData, readPixelsData);
+ }
+
+ // Unsized RGB 16F
+ {
+ bool texture = false;
+ bool filter = false;
+ bool render = false;
+ TestFloatTextureFormat(GL_RGB, GL_RGB, GL_HALF_FLOAT, texture, filter, render,
+ textureData, readPixelsData);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized RGB 16F
+ bool texture = getClientMajorVersion() >= 3;
+ bool filter = getClientMajorVersion() >= 3 ||
+ extensionEnabled("GL_OES_texture_half_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_half_float");
+ TestFloatTextureFormat(GL_RGB16F, GL_RGB, GL_HALF_FLOAT, texture, filter, render,
+ textureData, readPixelsData);
+ }
+ }
+}
+
+TEST_P(WebGLCompatibilityTest, RGBA16FTextures)
+{
+ constexpr float readPixelsData[] = {7000.0f, 100.0f, 33.0f, -1.0f};
+ const GLushort textureData[] = {
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
+
+ for (auto extension : FloatingPointTextureExtensions)
+ {
+ if (strlen(extension) > 0 && extensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ // Unsized RGBA 16F (OES)
+ {
+ bool texture = extensionEnabled("GL_OES_texture_half_float");
+ bool filter = getClientMajorVersion() >= 3 ||
+ extensionEnabled("GL_OES_texture_half_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_half_float") ||
+ extensionEnabled("GL_EXT_color_buffer_float");
+ TestFloatTextureFormat(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES, texture, filter, render,
+ textureData, readPixelsData);
+ }
+
+ // Unsized RGBA 16F
+ {
+ bool texture = false;
+ bool filter = false;
+ bool render = false;
+ TestFloatTextureFormat(GL_RGBA, GL_RGBA, GL_HALF_FLOAT, texture, filter, render,
+ textureData, readPixelsData);
+ }
+
+ if (getClientMajorVersion() >= 3 || extensionEnabled("GL_EXT_texture_storage"))
+ {
+ // Sized RGBA 16F
+ bool texture = getClientMajorVersion() >= 3;
+ bool filter = getClientMajorVersion() >= 3 ||
+ extensionEnabled("GL_OES_texture_half_float_linear");
+ bool render = extensionEnabled("GL_EXT_color_buffer_half_float") ||
+ extensionEnabled("GL_EXT_color_buffer_float");
+ TestFloatTextureFormat(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, texture, filter, render,
+ textureData, readPixelsData);
+ }
+ }
+}
+
// This tests that rendering feedback loops works as expected with WebGL 2.
// Based on WebGL test conformance2/rendering/rendering-sampling-feedback-loop.html
TEST_P(WebGL2CompatibilityTest, RenderingFeedbackLoopWithDrawBuffers)
@@ -1608,20 +2208,28 @@
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
// Float buffer
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, nullptr);
- ASSERT_GL_NO_ERROR();
+ if (extensionRequestable("GL_EXT_color_buffer_float"))
+ {
+ glRequestExtensionANGLE("GL_EXT_color_buffer_float");
+ }
- glClearBufferfv(GL_COLOR, 0, clearFloat);
- EXPECT_GL_NO_ERROR();
+ if (extensionEnabled("GL_EXT_color_buffer_float"))
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, nullptr);
+ ASSERT_GL_NO_ERROR();
- glClearBufferiv(GL_COLOR, 0, clearInt);
- EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+ glClearBufferfv(GL_COLOR, 0, clearFloat);
+ EXPECT_GL_NO_ERROR();
- glClearBufferuiv(GL_COLOR, 0, clearUint);
- EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+ glClearBufferiv(GL_COLOR, 0, clearInt);
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
- glClear(GL_COLOR_BUFFER_BIT);
- EXPECT_GL_NO_ERROR();
+ glClearBufferuiv(GL_COLOR, 0, clearUint);
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_GL_NO_ERROR();
+ }
// Normalized uint buffer
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
@@ -1713,7 +2321,6 @@
ES2_D3D9(),
ES2_D3D11(),
ES3_D3D11(),
- ES2_D3D11_FL9_3(),
ES2_OPENGL(),
ES3_OPENGL(),
ES2_OPENGLES(),