| // |
| // Copyright 2019 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // GetImageTest: |
| // Tests for the ANGLE_get_image extension. |
| // |
| |
| #include "test_utils/ANGLETest.h" |
| #include "test_utils/gl_raii.h" |
| |
| using namespace angle; |
| |
| namespace |
| { |
| constexpr uint32_t kSize = 32; |
| constexpr char kExtensionName[] = "GL_ANGLE_get_image"; |
| |
| class GetImageTest : public ANGLETest |
| { |
| public: |
| GetImageTest() |
| { |
| setWindowWidth(kSize); |
| setWindowHeight(kSize); |
| setConfigRedBits(8); |
| setConfigGreenBits(8); |
| setConfigBlueBits(8); |
| setConfigAlphaBits(8); |
| } |
| }; |
| |
| class GetImageTestNoExtensions : public ANGLETest |
| { |
| public: |
| GetImageTestNoExtensions() { setExtensionsEnabled(false); } |
| }; |
| |
| GLTexture InitSimpleTexture() |
| { |
| std::vector<GLColor> pixelData(kSize * kSize, GLColor::red); |
| |
| // Create a simple texture. |
| GLTexture tex; |
| glBindTexture(GL_TEXTURE_2D, tex); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| pixelData.data()); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| |
| return tex; |
| } |
| |
| GLRenderbuffer InitSimpleRenderbuffer() |
| { |
| // Create a simple renderbuffer. |
| GLRenderbuffer renderbuf; |
| glBindRenderbuffer(GL_RENDERBUFFER, renderbuf); |
| glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, kSize, kSize); |
| |
| return renderbuf; |
| } |
| |
| // Test validation for the extension functions. |
| TEST_P(GetImageTest, NegativeAPI) |
| { |
| // Verify the extension is enabled. |
| ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName)); |
| |
| // Draw once with simple texture. |
| GLTexture tex = InitSimpleTexture(); |
| ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D()); |
| drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true); |
| EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); |
| ASSERT_GL_NO_ERROR(); |
| |
| // Pack pixels tightly. |
| glPixelStorei(GL_PACK_ALIGNMENT, 1); |
| |
| // Verify GetTexImage can work with correct parameters. |
| std::vector<GLColor> buffer(kSize * kSize); |
| glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_NO_ERROR(); |
| |
| // Test invalid texture target. |
| glGetTexImageANGLE(GL_TEXTURE_CUBE_MAP, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_ENUM); |
| |
| // Test invalid texture level. |
| glGetTexImageANGLE(GL_TEXTURE_2D, -1, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_VALUE); |
| glGetTexImageANGLE(GL_TEXTURE_2D, 2000, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_VALUE); |
| |
| // Test invalid format and type. |
| glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_NONE, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_ENUM); |
| glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_NONE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_ENUM); |
| |
| // Create a simple renderbuffer. |
| GLRenderbuffer renderbuf = InitSimpleRenderbuffer(); |
| ASSERT_GL_NO_ERROR(); |
| |
| // Verify GetRenderbufferImage can work with correct parameters. |
| glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_NO_ERROR(); |
| |
| // Test invalid renderbuffer target. |
| glGetRenderbufferImageANGLE(GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_ENUM); |
| |
| // Test invalid renderbuffer format/type. |
| glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_NONE, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_ENUM); |
| glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_NONE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_ENUM); |
| |
| // Pack buffer tests. Requires ES 3+ or extension. |
| if (getClientMajorVersion() >= 3 || IsGLExtensionEnabled("GL_NV_pixel_buffer_object")) |
| { |
| // Test valid pack buffer. |
| GLBuffer packBuffer; |
| glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer); |
| glBufferData(GL_PIXEL_PACK_BUFFER, kSize * kSize * sizeof(GLColor), nullptr, |
| GL_STATIC_DRAW); |
| glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_OPERATION); |
| glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_OPERATION); |
| |
| // Test too small pack buffer. |
| glBufferData(GL_PIXEL_PACK_BUFFER, kSize, nullptr, GL_STATIC_DRAW); |
| glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_OPERATION); |
| glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_OPERATION); |
| } |
| } |
| |
| // Verifies that the extension enums and entry points are invalid when the extension is disabled. |
| TEST_P(GetImageTestNoExtensions, EntryPointsInactive) |
| { |
| // Verify the extension is not enabled. |
| ASSERT_FALSE(IsGLExtensionEnabled(kExtensionName)); |
| |
| // Draw once with simple texture. |
| GLTexture tex = InitSimpleTexture(); |
| ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D()); |
| drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true); |
| EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); |
| ASSERT_GL_NO_ERROR(); |
| |
| // Query implementation format and type. Should give invalid enum. |
| GLint param; |
| glGetTexParameteriv(GL_TEXTURE_2D, GL_IMPLEMENTATION_COLOR_READ_FORMAT, ¶m); |
| EXPECT_GL_ERROR(GL_INVALID_ENUM); |
| |
| glGetTexParameteriv(GL_TEXTURE_2D, GL_IMPLEMENTATION_COLOR_READ_TYPE, ¶m); |
| EXPECT_GL_ERROR(GL_INVALID_ENUM); |
| |
| // Verify calling GetTexImage produces an error. |
| std::vector<GLColor> buffer(kSize * kSize, 0); |
| glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_OPERATION); |
| |
| // Create a simple renderbuffer. |
| GLRenderbuffer renderbuf = InitSimpleRenderbuffer(); |
| ASSERT_GL_NO_ERROR(); |
| |
| // Query implementation format and type. Should give invalid enum. |
| glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, ¶m); |
| EXPECT_GL_ERROR(GL_INVALID_ENUM); |
| |
| glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, ¶m); |
| EXPECT_GL_ERROR(GL_INVALID_ENUM); |
| |
| // Verify calling GetRenderbufferImage produces an error. |
| glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); |
| EXPECT_GL_ERROR(GL_INVALID_OPERATION); |
| } |
| |
| ANGLE_INSTANTIATE_TEST(GetImageTest, ES2_VULKAN(), ES3_VULKAN()); |
| ANGLE_INSTANTIATE_TEST(GetImageTestNoExtensions, ES2_VULKAN(), ES3_VULKAN()); |
| } // namespace |