Vulkan: Add GL_ANGLE_yuv_internal_format extension

1. Add a new extension to support creation of immutable textures with
   sized internal YUV formats
2. Rename YUV format enums from *_ANGLEX to *_ANGLE
3. Move YUV format enums from angleutils.h to glext_angle.h

Bug: angleproject:5773
Change-Id: Ibfe732f4c9a4a536be56481f33e4768f6227c212
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2820153
Commit-Queue: Mohan Maiya <m.maiya@samsung.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Mohan Maiya
2021-07-12 13:28:54 -07:00
committed by Angle LUCI CQ
parent cd73949c48
commit e66e334491
16 changed files with 238 additions and 31 deletions

View File

@@ -0,0 +1,117 @@
Name
ANGLE_yuv_internal_format
Name Strings
GL_ANGLE_yuv_internal_format
Contributors
Mohan Maiya, Samsung
Jamie Madill, Google
Contacts
Mohan Maiya, Samsung (m.maiya 'at' samsung 'dot' com)
Notice
Copyright (c) 2021 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Status
Draft.
Version
Version 5, June 23, 2021
Number
OpenGL ES Extension ###
Dependencies
OpenGL ES 3.0 is required.
Overview
This extension introduces a few sized internal YUV texture formats
that can be used to create immutable textures using the TexStorage2D API.
The only valid texture target supported is TEXTURE_2D, an INVALID_ENUM
error is generated otherwise. There is no mipmap support and only NEAREST
minification and magnification filters are supported.
Support for the extension only requires the support of the commonly used 8-bit
2-plane YUV format listed in the "New Tokens" section, refer to [fn1] for details
about the formats and layout. It is up to the implementation to extend support
for the other YUV formats.
[fn1] : https://www.fourcc.org/yuv.php
New Types
None.
New Procedures and Functions
None.
New Tokens
List of non-standard YUV internal formats
// 8-bit YUV formats
G8_B8R8_2PLANE_420_UNORM_ANGLE 0x96B1
G8_B8_R8_3PLANE_420_UNORM_ANGLE 0x96B2
// 10-bit YUV formats
G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE 0x96B3
G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE 0x96B4
// 12-bit YUV formats
G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE 0x96B5
G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE 0x96B6
// 16-bit YUV formats
G16_B16R16_2PLANE_420_UNORM_ANGLE 0x96B7
G16_B16_R16_3PLANE_420_UNORM_ANGLE 0x96B8
Issues
1. How was the new format list chosen?
Commonly used planar YUV formats across various platforms were surveyed,
including new platforms that support HDR content. A subset of those were
chosen to be required. It is up to the implementations to extend support
for the rest of the formats.
2. What is the colorspace of image data of a texture created with the new formats?
The texture or sampler parameter APIs can be expanded to indicate the colorspace
in a layered extension and is outside the scope of this extension. The colorspace
for textures with the above YUV formats is assumed to be ITU-R BT.601 with YUV
values in limited range. Refer to ITU-R BT.601 spec for further details.
Revision History
#5 - (June 23, 2021) Mohan Maiya
Renamed format enums from *_ANGLEX to *_ANGLE
#4 - (June 23, 2021) Mohan Maiya
Removed references to GL_OES_EGL_image_external
and restricted the spec to simply introducing new
sized internal YUV formats. Also updated enum values
#3 - (June 8, 2021) Mohan Maiya
Clarification regarding default colorspace
#2 - (May 10, 2021) Mohan Maiya
Update overview section to specify support for
immutable textures
#1 - (April 10, 2021) Mohan Maiya
Original draft

View File

@@ -20,4 +20,26 @@ typedef void *GLeglContext;
// clang-format on
#ifndef GL_ANGLE_yuv_internal_format
#define GL_ANGLE_yuv_internal_format
// YUV formats introduced by GL_ANGLE_yuv_internal_format
// 8-bit YUV formats
#define GL_G8_B8R8_2PLANE_420_UNORM_ANGLE 0x96B1
#define GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE 0x96B2
// 10-bit YUV formats
#define GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE 0x96B3
#define GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE 0x96B4
// 12-bit YUV formats
#define GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE 0x96B5
#define GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE 0x96B6
// 16-bit YUV formats
#define GL_G16_B16R16_2PLANE_420_UNORM_ANGLE 0x96B7
#define GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE 0x96B8
#endif /* GL_ANGLE_yuv_internal_format */
#endif // INCLUDE_GLES_GLEXT_ANGLE_H_

View File

@@ -2,13 +2,13 @@
"src/libANGLE/renderer/FormatID_autogen.h":
"14285e7bdfd0346aa99712b48ec63967",
"src/libANGLE/renderer/Format_table_autogen.cpp":
"da0b1b6dbbbb4ff1228c18c09c03827c",
"e59a50263c2a9825293bfbd2d68aa1a2",
"src/libANGLE/renderer/angle_format.py":
"74d6c9842128293118ccf128aeae896a",
"src/libANGLE/renderer/angle_format_data.json":
"10e2ee1ed8ee54226edb644de30f512d",
"src/libANGLE/renderer/angle_format_map.json":
"623bcd907ccba69766fbc17c4b9a5b9a",
"6606c1d7df94e6150ab51cfe96c6dcdc",
"src/libANGLE/renderer/gen_angle_format_table.py":
"70bdbceee30506d4b14bf52f2bbd8f2b"
}

View File

@@ -4,7 +4,7 @@
"src/libANGLE/renderer/gen_load_functions_table.py":
"c131c494e7e0b35b65a8a097b4b8e5ce",
"src/libANGLE/renderer/load_functions_data.json":
"d90e9a8fbcf22d30bb1b4ec19cf93992",
"47db3cb699f04d27745b95c55d31d4d5",
"src/libANGLE/renderer/load_functions_table_autogen.cpp":
"25a87a4f979bbdb3b080e7f6f9e631bd"
"11845b0df85283f9357d1aa0c31bed12"
}

View File

@@ -2,7 +2,7 @@
"src/libANGLE/renderer/angle_format.py":
"74d6c9842128293118ccf128aeae896a",
"src/libANGLE/renderer/angle_format_map.json":
"623bcd907ccba69766fbc17c4b9a5b9a",
"6606c1d7df94e6150ab51cfe96c6dcdc",
"src/libANGLE/renderer/dxgi_format_data.json":
"3428e4761ccd05f960adffd6ccbd86c5",
"src/libANGLE/renderer/dxgi_format_map_autogen.cpp":

View File

@@ -2,7 +2,7 @@
"src/libANGLE/renderer/angle_format.py":
"74d6c9842128293118ccf128aeae896a",
"src/libANGLE/renderer/angle_format_map.json":
"623bcd907ccba69766fbc17c4b9a5b9a",
"6606c1d7df94e6150ab51cfe96c6dcdc",
"src/libANGLE/renderer/gen_angle_format_table.py":
"70bdbceee30506d4b14bf52f2bbd8f2b",
"src/libANGLE/renderer/metal/shaders/blit.metal":
@@ -24,7 +24,7 @@
"src/libANGLE/renderer/metal/shaders/gen_mtl_internal_shaders.py":
"ba74ebbfa2ceb825f36e84f2985b3d3d",
"src/libANGLE/renderer/metal/shaders/mtl_default_shaders_src_autogen.inc":
"ef8d023e7fdf7fb39dc744ffaab830f4",
"bcd4405cceb86371a2fe3c4f97a2e1c3",
"src/libANGLE/renderer/metal/shaders/visibility.metal":
"b82aa740cf4b0aed606aacef1024beea"
}

View File

@@ -2,7 +2,7 @@
"src/libANGLE/renderer/angle_format.py":
"74d6c9842128293118ccf128aeae896a",
"src/libANGLE/renderer/angle_format_map.json":
"623bcd907ccba69766fbc17c4b9a5b9a",
"6606c1d7df94e6150ab51cfe96c6dcdc",
"src/libANGLE/renderer/metal/gen_mtl_format_table.py":
"4b9bc5e4c59175d30de4a42fd110c3b5",
"src/libANGLE/renderer/metal/mtl_format_map.json":

View File

@@ -2,11 +2,11 @@
"src/libANGLE/renderer/angle_format.py":
"74d6c9842128293118ccf128aeae896a",
"src/libANGLE/renderer/angle_format_map.json":
"623bcd907ccba69766fbc17c4b9a5b9a",
"6606c1d7df94e6150ab51cfe96c6dcdc",
"src/libANGLE/renderer/vulkan/gen_vk_format_table.py":
"ffeebc0e8ec8db860e472c7cf04cd880",
"src/libANGLE/renderer/vulkan/vk_format_map.json":
"b5e35a7c708d764ae66ac39bf2beb054",
"src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp":
"50a29ee869bbae62fca78d597aa695ee"
"a116ed4afe6cbbf3f714f60ae255f584"
}

View File

@@ -290,10 +290,6 @@ inline bool IsLittleEndian()
#define GL_X2_RGB10_UNORM_ANGLEX 0x6AF7
#define GL_X2_RGB10_SNORM_ANGLEX 0x6AF8
// YUV formats
#define GL_G8_B8_R8_3PLANE_420_UNORM_ANGLEX 0x6B00
#define GL_G8_B8R8_2PLANE_420_UNORM_ANGLEX 0x6B01
#define ANGLE_CHECK_GL_ALLOC(context, result) \
ANGLE_CHECK(context, result, "Failed to allocate host memory", GL_OUT_OF_MEMORY)

View File

@@ -127,8 +127,8 @@ const Format gFormatInfoTable[] = {
{ FormatID::ETC2_R8G8B8A8_UNORM_BLOCK, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 16, 0, true, false, false, false, false, gl::VertexAttribType::UnsignedByte },
{ FormatID::ETC2_R8G8B8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 8, 0, true, false, false, true, false, gl::VertexAttribType::Byte },
{ FormatID::ETC2_R8G8B8_UNORM_BLOCK, GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::UnsignedByte },
{ FormatID::G8_B8R8_2PLANE_420_UNORM, GL_G8_B8R8_2PLANE_420_UNORM_ANGLEX, GL_G8_B8R8_2PLANE_420_UNORM_ANGLEX, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, true, gl::VertexAttribType::UnsignedByte },
{ FormatID::G8_B8_R8_3PLANE_420_UNORM, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLEX, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLEX, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, true, gl::VertexAttribType::UnsignedByte },
{ FormatID::G8_B8R8_2PLANE_420_UNORM, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, true, gl::VertexAttribType::UnsignedByte },
{ FormatID::G8_B8_R8_3PLANE_420_UNORM, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, true, gl::VertexAttribType::UnsignedByte },
{ FormatID::L16A16_FLOAT, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA16F_EXT, GenerateMip<L16A16F>, NoCopyFunctions, ReadColor<L16A16F, GLfloat>, WriteColor<L16A16F, GLfloat>, GL_FLOAT, 0, 0, 0, 16, 16, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Float },
{ FormatID::L16_FLOAT, GL_LUMINANCE16F_EXT, GL_LUMINANCE16F_EXT, GenerateMip<L16F>, NoCopyFunctions, ReadColor<L16F, GLfloat>, WriteColor<L16F, GLfloat>, GL_FLOAT, 0, 0, 0, 0, 16, 0, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Float },
{ FormatID::L32A32_FLOAT, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA32F_EXT, GenerateMip<L32A32F>, NoCopyFunctions, ReadColor<L32A32F, GLfloat>, WriteColor<L32A32F, GLfloat>, GL_FLOAT, 0, 0, 0, 32, 32, 0, 0, 8, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Float },
@@ -473,9 +473,9 @@ FormatID Format::InternalFormatToID(GLenum internalFormat)
return FormatID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK;
case GL_ETC1_RGB8_OES:
return FormatID::ETC1_R8G8B8_UNORM_BLOCK;
case GL_G8_B8R8_2PLANE_420_UNORM_ANGLEX:
case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE:
return FormatID::G8_B8R8_2PLANE_420_UNORM;
case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLEX:
case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE:
return FormatID::G8_B8_R8_3PLANE_420_UNORM;
case GL_INT_10_10_10_2_OES:
return FormatID::A2R10G10B10_SINT_VERTEX;

View File

@@ -226,6 +226,6 @@
[ "GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT", "PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK" ],
[ "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT", "PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK" ],
[ "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT", "PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK" ],
[ "GL_G8_B8_R8_3PLANE_420_UNORM_ANGLEX", "G8_B8_R8_3PLANE_420_UNORM" ],
[ "GL_G8_B8R8_2PLANE_420_UNORM_ANGLEX", "G8_B8R8_2PLANE_420_UNORM" ]
[ "GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE", "G8_B8_R8_3PLANE_420_UNORM" ],
[ "GL_G8_B8R8_2PLANE_420_UNORM_ANGLE", "G8_B8R8_2PLANE_420_UNORM" ]
]

View File

@@ -1182,12 +1182,12 @@
"GL_UNSIGNED_BYTE": "LoadCompressedToNative<6, 6, 6, 16>"
}
},
"GL_G8_B8_R8_3PLANE_420_UNORM_ANGLEX": {
"GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE": {
"NONE": {
"GL_UNSIGNED_BYTE": "UnimplementedLoadFunction"
}
},
"GL_G8_B8R8_2PLANE_420_UNORM_ANGLEX": {
"GL_G8_B8R8_2PLANE_420_UNORM_ANGLE": {
"NONE": {
"GL_UNSIGNED_BYTE": "UnimplementedLoadFunction"
}

View File

@@ -1620,7 +1620,7 @@ LoadImageFunctionInfo ETC1_RGB8_OES_to_R8G8B8A8_UNORM(GLenum type)
}
}
LoadImageFunctionInfo G8_B8R8_2PLANE_420_UNORM_ANGLEX_to_default(GLenum type)
LoadImageFunctionInfo G8_B8R8_2PLANE_420_UNORM_ANGLE_to_default(GLenum type)
{
switch (type)
{
@@ -1632,7 +1632,7 @@ LoadImageFunctionInfo G8_B8R8_2PLANE_420_UNORM_ANGLEX_to_default(GLenum type)
}
}
LoadImageFunctionInfo G8_B8_R8_3PLANE_420_UNORM_ANGLEX_to_default(GLenum type)
LoadImageFunctionInfo G8_B8_R8_3PLANE_420_UNORM_ANGLE_to_default(GLenum type)
{
switch (type)
{
@@ -3740,10 +3740,10 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat)
}
break;
}
case GL_G8_B8R8_2PLANE_420_UNORM_ANGLEX:
return G8_B8R8_2PLANE_420_UNORM_ANGLEX_to_default;
case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLEX:
return G8_B8_R8_3PLANE_420_UNORM_ANGLEX_to_default;
case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE:
return G8_B8R8_2PLANE_420_UNORM_ANGLE_to_default;
case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE:
return G8_B8_R8_3PLANE_420_UNORM_ANGLE_to_default;
case GL_LUMINANCE:
{
switch (angleFormat)

View File

@@ -14,7 +14,7 @@ static char gDefaultMetallibSrc[] = R"(
# 1 "temp_master_source.metal"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 369 "<built-in>" 3
# 386 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "temp_master_source.metal" 2

View File

@@ -961,7 +961,7 @@ void Format::initialize(RendererVk *renderer, const angle::Format &angleFormat)
break;
case angle::FormatID::G8_B8R8_2PLANE_420_UNORM:
intendedGLFormat = GL_G8_B8R8_2PLANE_420_UNORM_ANGLEX;
intendedGLFormat = GL_G8_B8R8_2PLANE_420_UNORM_ANGLE;
actualImageFormatID = angle::FormatID::G8_B8R8_2PLANE_420_UNORM;
imageInitializerFunction = nullptr;
actualBufferFormatID = angle::FormatID::G8_B8R8_2PLANE_420_UNORM;
@@ -971,7 +971,7 @@ void Format::initialize(RendererVk *renderer, const angle::Format &angleFormat)
break;
case angle::FormatID::G8_B8_R8_3PLANE_420_UNORM:
intendedGLFormat = GL_G8_B8_R8_3PLANE_420_UNORM_ANGLEX;
intendedGLFormat = GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE;
actualImageFormatID = angle::FormatID::G8_B8_R8_3PLANE_420_UNORM;
imageInitializerFunction = nullptr;
actualBufferFormatID = angle::FormatID::G8_B8_R8_3PLANE_420_UNORM;

View File

@@ -412,6 +412,47 @@ class Texture2DTestES3 : public Texture2DTest
Texture2DTest::testSetUp();
setUpProgram();
}
void createImmutableTexture2D(GLuint texture,
size_t width,
size_t height,
GLenum format,
GLenum internalFormat,
GLenum type,
GLsizei levels,
GLubyte data[4])
{
// Support only 1 level for now
ASSERT(levels == 1);
glBindTexture(GL_TEXTURE_2D, texture);
glTexStorage2D(GL_TEXTURE_2D, levels, internalFormat, width, height);
ASSERT_GL_NO_ERROR();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, data);
ASSERT_GL_NO_ERROR();
// Disable mipmapping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ASSERT_GL_NO_ERROR();
}
void verifyResults2D(GLuint texture, GLubyte referenceColor[4])
{
// Draw a quad with the target texture
glUseProgram(mProgram);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(mTexture2DUniformLocation, 0);
drawQuad(mProgram, "position", 0.5f);
// Expect that the rendered quad's color is the same as the reference color with a tolerance
// of 1
EXPECT_PIXEL_NEAR(0, 0, referenceColor[0], referenceColor[1], referenceColor[2],
referenceColor[3], 1);
}
};
class Texture2DBaseMaxTestES3 : public ANGLETest
@@ -2834,6 +2875,37 @@ TEST_P(Texture2DTestES3, TexImageWithDepthStencilPBO)
EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
}
// Test functionality of GL_ANGLE_yuv_internal_format while cycling through RGB and YUV sources
TEST_P(Texture2DTestES3, TexStorage2DCycleThroughYuvAndRgbSources)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
// Create YUV texture
GLTexture yuvTexture;
GLubyte yuvColor[6] = {40, 40, 40, 40, 240, 109};
GLubyte expectedRgbColor[4] = {0, 0, 255, 255};
createImmutableTexture2D(yuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, yuvColor);
// Create RGBA texture
GLTexture rgbaTexture;
GLubyte rgbaColor[4] = {0, 0, 255, 255};
createImmutableTexture2D(rgbaTexture, 1, 1, GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE, 1, rgbaColor);
// Cycle through source textures
// RGBA source
verifyResults2D(rgbaTexture, rgbaColor);
ASSERT_GL_NO_ERROR();
// YUV source
verifyResults2D(yuvTexture, expectedRgbColor);
ASSERT_GL_NO_ERROR();
// RGBA source
verifyResults2D(rgbaTexture, rgbaColor);
ASSERT_GL_NO_ERROR();
}
// Tests CopySubImage for float formats
TEST_P(Texture2DTest, CopySubImageFloat_R_R)
{