Commit 5850c748 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Emulated RGB copies in compute

The copy between emulated RGB formats can take a number of paths: - Sample from src (reinterpreted as UINT), output to dst - Sample from src, output to temp buffer, copy to dst - Copy src to temp buffer, output to dst - Copy src to temp buffer, convert to another temp buffer, copy to dst While directly sampling from src and outputting to dst is more efficient, these are not always possible. The former may not have SAMPLED_IMAGE usage bit for the reinterpreted UINT format, and the latter may not have STORAGE_IMAGE usage at all. This change takes the universal approach of using two temp buffers. The ConvertVertex shader is used to transform between RGB and RGBA when copying from the first temp buffer to the second. Bug: angleproject:5278 Change-Id: I63d916cfdb4c389f5b817d89cd7348fdea703ce5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2556467 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarBrandon Schade <b.schade@samsung.com>
parent 113b7e63
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
// unsupported formats to their fallbacks. // unsupported formats to their fallbacks.
// - Image clear: Used by FramebufferVk::clearWithDraw(). // - Image clear: Used by FramebufferVk::clearWithDraw().
// - Image copy: Used by TextureVk::copySubImageImplWithDraw(). // - Image copy: Used by TextureVk::copySubImageImplWithDraw().
// - Image copy bits: Used by ImageHelper::CopyImageSubData() to perform bitwise copies between
// RGB formats where at least one of src and dest use RGBA as fallback.
// - Color blit/resolve: Used by FramebufferVk::blit() to implement blit or multisample resolve // - Color blit/resolve: Used by FramebufferVk::blit() to implement blit or multisample resolve
// on color images. // on color images.
// - Depth/Stencil blit/resolve: Used by FramebufferVk::blit() to implement blit or multisample // - Depth/Stencil blit/resolve: Used by FramebufferVk::blit() to implement blit or multisample
...@@ -141,6 +143,15 @@ class UtilsVk : angle::NonCopyable ...@@ -141,6 +143,15 @@ class UtilsVk : angle::NonCopyable
SurfaceRotation srcRotation; SurfaceRotation srcRotation;
}; };
struct CopyImageBitsParameters
{
int srcOffset[3];
gl::LevelIndex srcLevel;
int dstOffset[3];
gl::LevelIndex dstLevel;
uint32_t copyExtents[3];
};
struct OverlayCullParameters struct OverlayCullParameters
{ {
uint32_t subgroupSize[2]; uint32_t subgroupSize[2];
...@@ -236,6 +247,11 @@ class UtilsVk : angle::NonCopyable ...@@ -236,6 +247,11 @@ class UtilsVk : angle::NonCopyable
const vk::ImageView *srcView, const vk::ImageView *srcView,
const CopyImageParameters &params); const CopyImageParameters &params);
angle::Result copyImageBits(ContextVk *contextVk,
vk::ImageHelper *dest,
vk::ImageHelper *src,
const CopyImageBitsParameters &params);
using GenerateMipmapDestLevelViews = using GenerateMipmapDestLevelViews =
std::array<const vk::ImageView *, kGenerateMipmapMaxLevels>; std::array<const vk::ImageView *, kGenerateMipmapMaxLevels>;
angle::Result generateMipmap(ContextVk *contextVk, angle::Result generateMipmap(ContextVk *contextVk,
...@@ -496,6 +512,14 @@ class UtilsVk : angle::NonCopyable ...@@ -496,6 +512,14 @@ class UtilsVk : angle::NonCopyable
const gl::Rectangle &renderArea, const gl::Rectangle &renderArea,
vk::CommandBuffer **commandBufferOut); vk::CommandBuffer **commandBufferOut);
// Set up descriptor set and call dispatch.
angle::Result convertVertexBufferImpl(ContextVk *contextVk,
vk::BufferHelper *dest,
vk::BufferHelper *src,
uint32_t flags,
vk::CommandBuffer *commandBuffer,
const ConvertVertexShaderParams &shaderParams);
// Blits or resolves either color or depth/stencil, based on which view is given. // Blits or resolves either color or depth/stencil, based on which view is given.
angle::Result blitResolveImpl(ContextVk *contextVk, angle::Result blitResolveImpl(ContextVk *contextVk,
FramebufferVk *framebuffer, FramebufferVk *framebuffer,
......
...@@ -639,11 +639,15 @@ bool CanCopyWithTransferForCopyImage(RendererVk *renderer, ...@@ -639,11 +639,15 @@ bool CanCopyWithTransferForCopyImage(RendererVk *renderer,
const vk::Format &destFormat, const vk::Format &destFormat,
VkImageTiling destTilingMode) VkImageTiling destTilingMode)
{ {
// Transfers for copy image must have the source and destination formats be size compatible // Neither source nor destination formats can be emulated for copy image through transfer,
const angle::Format &srcFormatActual = srcFormat.actualImageFormat(); // unless they are emualted with the same format!
const angle::Format &destFormatActual = destFormat.actualImageFormat(); bool isFormatCompatible =
(!srcFormat.hasEmulatedImageFormat() && !destFormat.hasEmulatedImageFormat()) ||
srcFormat.actualImageFormatID == destFormat.actualImageFormatID;
bool isFormatCompatible = srcFormatActual.pixelBytes == destFormatActual.pixelBytes; // If neither formats are emulated, GL validation ensures that pixelBytes is the same for both.
ASSERT(!isFormatCompatible ||
srcFormat.actualImageFormat().pixelBytes == destFormat.actualImageFormat().pixelBytes);
return isFormatCompatible && return isFormatCompatible &&
CanCopyWithTransfer(renderer, srcFormat, srcTilingMode, destFormat, destTilingMode); CanCopyWithTransfer(renderer, srcFormat, srcTilingMode, destFormat, destTilingMode);
...@@ -3923,7 +3927,7 @@ angle::Result ImageHelper::initLayerImageViewImpl( ...@@ -3923,7 +3927,7 @@ angle::Result ImageHelper::initLayerImageViewImpl(
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result ImageHelper::initAliasedLayerImageView(Context *context, angle::Result ImageHelper::initReinterpretedLayerImageView(Context *context,
gl::TextureType textureType, gl::TextureType textureType,
VkImageAspectFlags aspectMask, VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap, const gl::SwizzleState &swizzleMap,
...@@ -4466,13 +4470,14 @@ angle::Result ImageHelper::CopyImageSubData(const gl::Context *context, ...@@ -4466,13 +4470,14 @@ angle::Result ImageHelper::CopyImageSubData(const gl::Context *context,
const vk::Format &destVkFormat = dstImage->getFormat(); const vk::Format &destVkFormat = dstImage->getFormat();
VkImageTiling destTilingMode = dstImage->getTilingMode(); VkImageTiling destTilingMode = dstImage->getTilingMode();
const gl::LevelIndex srcLevelGL = gl::LevelIndex(srcLevel);
const gl::LevelIndex dstLevelGL = gl::LevelIndex(dstLevel);
if (CanCopyWithTransferForCopyImage(contextVk->getRenderer(), sourceVkFormat, srcTilingMode, if (CanCopyWithTransferForCopyImage(contextVk->getRenderer(), sourceVkFormat, srcTilingMode,
destVkFormat, destTilingMode)) destVkFormat, destTilingMode))
{ {
bool isSrc3D = (srcImage->getType() == VK_IMAGE_TYPE_3D); bool isSrc3D = srcImage->getType() == VK_IMAGE_TYPE_3D;
bool isDst3D = (dstImage->getType() == VK_IMAGE_TYPE_3D); bool isDst3D = dstImage->getType() == VK_IMAGE_TYPE_3D;
const gl::LevelIndex srcLevelGL = gl::LevelIndex(srcLevel);
const gl::LevelIndex dstLevelGL = gl::LevelIndex(dstLevel);
srcImage->retain(&contextVk->getResourceUseList()); srcImage->retain(&contextVk->getResourceUseList());
dstImage->retain(&contextVk->getResourceUseList()); dstImage->retain(&contextVk->getResourceUseList());
...@@ -4515,12 +4520,30 @@ angle::Result ImageHelper::CopyImageSubData(const gl::Context *context, ...@@ -4515,12 +4520,30 @@ angle::Result ImageHelper::CopyImageSubData(const gl::Context *context,
commandBuffer->copyImage(srcImage->getImage(), srcImage->getCurrentLayout(), commandBuffer->copyImage(srcImage->getImage(), srcImage->getCurrentLayout(),
dstImage->getImage(), dstImage->getCurrentLayout(), 1, &region); dstImage->getImage(), dstImage->getCurrentLayout(), 1, &region);
} }
else if (!sourceVkFormat.intendedFormat().isBlock && !destVkFormat.intendedFormat().isBlock)
{
// The source and destination image formats may be using a fallback in the case of RGB
// images. A compute shader is used in such a case to perform the copy.
UtilsVk &utilsVk = contextVk->getUtils();
UtilsVk::CopyImageBitsParameters params;
params.srcOffset[0] = srcX;
params.srcOffset[1] = srcY;
params.srcOffset[2] = srcZ;
params.srcLevel = srcLevelGL;
params.dstOffset[0] = dstX;
params.dstOffset[1] = dstY;
params.dstOffset[2] = dstZ;
params.dstLevel = dstLevelGL;
params.copyExtents[0] = srcWidth;
params.copyExtents[1] = srcHeight;
params.copyExtents[2] = srcDepth;
ANGLE_TRY(utilsVk.copyImageBits(contextVk, dstImage, srcImage, params));
}
else else
{ {
// TODO (anglebug.com/5278) - implement fallback path // No support for emulated compressed formats.
// There is a possibility for the underlying source and destination VK image formats to be
// incompatible. An example scenario would be if the source image (RGB8UI) falls back
// to an emulated format(RGBA8UI) but the destination image is natively supported(RGB8I).
UNIMPLEMENTED(); UNIMPLEMENTED();
ANGLE_VK_CHECK(contextVk, false, VK_ERROR_FEATURE_NOT_PRESENT); ANGLE_VK_CHECK(contextVk, false, VK_ERROR_FEATURE_NOT_PRESENT);
} }
...@@ -6604,7 +6627,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk, ...@@ -6604,7 +6627,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk,
if (!mPerLevelLinearReadImageViews[mCurrentMaxLevel.get()].valid()) if (!mPerLevelLinearReadImageViews[mCurrentMaxLevel.get()].valid())
{ {
ANGLE_TRY(image.initAliasedLayerImageView( ANGLE_TRY(image.initReinterpretedLayerImageView(
contextVk, viewType, aspectFlags, readSwizzle, contextVk, viewType, aspectFlags, readSwizzle,
&mPerLevelLinearReadImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount, &mPerLevelLinearReadImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount,
baseLayer, layerCount, imageUsageFlags, linearFormat)); baseLayer, layerCount, imageUsageFlags, linearFormat));
...@@ -6612,7 +6635,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk, ...@@ -6612,7 +6635,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk,
if (srgbOverrideFormat != VK_FORMAT_UNDEFINED && if (srgbOverrideFormat != VK_FORMAT_UNDEFINED &&
!mPerLevelSRGBReadImageViews[mCurrentMaxLevel.get()].valid()) !mPerLevelSRGBReadImageViews[mCurrentMaxLevel.get()].valid())
{ {
ANGLE_TRY(image.initAliasedLayerImageView( ANGLE_TRY(image.initReinterpretedLayerImageView(
contextVk, viewType, aspectFlags, readSwizzle, contextVk, viewType, aspectFlags, readSwizzle,
&mPerLevelSRGBReadImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount, baseLayer, &mPerLevelSRGBReadImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount, baseLayer,
layerCount, imageUsageFlags, srgbOverrideFormat)); layerCount, imageUsageFlags, srgbOverrideFormat));
...@@ -6628,7 +6651,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk, ...@@ -6628,7 +6651,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk,
if (!mPerLevelLinearFetchImageViews[mCurrentMaxLevel.get()].valid()) if (!mPerLevelLinearFetchImageViews[mCurrentMaxLevel.get()].valid())
{ {
ANGLE_TRY(image.initAliasedLayerImageView( ANGLE_TRY(image.initReinterpretedLayerImageView(
contextVk, fetchType, aspectFlags, readSwizzle, contextVk, fetchType, aspectFlags, readSwizzle,
&mPerLevelLinearFetchImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount, &mPerLevelLinearFetchImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount,
baseLayer, layerCount, imageUsageFlags, linearFormat)); baseLayer, layerCount, imageUsageFlags, linearFormat));
...@@ -6636,7 +6659,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk, ...@@ -6636,7 +6659,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk,
if (srgbOverrideFormat != VK_FORMAT_UNDEFINED && if (srgbOverrideFormat != VK_FORMAT_UNDEFINED &&
!mPerLevelSRGBFetchImageViews[mCurrentMaxLevel.get()].valid()) !mPerLevelSRGBFetchImageViews[mCurrentMaxLevel.get()].valid())
{ {
ANGLE_TRY(image.initAliasedLayerImageView( ANGLE_TRY(image.initReinterpretedLayerImageView(
contextVk, fetchType, aspectFlags, readSwizzle, contextVk, fetchType, aspectFlags, readSwizzle,
&mPerLevelSRGBFetchImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount, &mPerLevelSRGBFetchImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount,
baseLayer, layerCount, imageUsageFlags, srgbOverrideFormat)); baseLayer, layerCount, imageUsageFlags, srgbOverrideFormat));
...@@ -6645,7 +6668,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk, ...@@ -6645,7 +6668,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk,
if (!mPerLevelLinearCopyImageViews[mCurrentMaxLevel.get()].valid()) if (!mPerLevelLinearCopyImageViews[mCurrentMaxLevel.get()].valid())
{ {
ANGLE_TRY(image.initAliasedLayerImageView( ANGLE_TRY(image.initReinterpretedLayerImageView(
contextVk, fetchType, aspectFlags, formatSwizzle, contextVk, fetchType, aspectFlags, formatSwizzle,
&mPerLevelLinearCopyImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount, &mPerLevelLinearCopyImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount,
baseLayer, layerCount, imageUsageFlags, linearFormat)); baseLayer, layerCount, imageUsageFlags, linearFormat));
...@@ -6653,7 +6676,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk, ...@@ -6653,7 +6676,7 @@ angle::Result ImageViewHelper::initSRGBReadViewsImpl(ContextVk *contextVk,
if (srgbOverrideFormat != VK_FORMAT_UNDEFINED && if (srgbOverrideFormat != VK_FORMAT_UNDEFINED &&
!mPerLevelSRGBCopyImageViews[mCurrentMaxLevel.get()].valid()) !mPerLevelSRGBCopyImageViews[mCurrentMaxLevel.get()].valid())
{ {
ANGLE_TRY(image.initAliasedLayerImageView( ANGLE_TRY(image.initReinterpretedLayerImageView(
contextVk, fetchType, aspectFlags, formatSwizzle, contextVk, fetchType, aspectFlags, formatSwizzle,
&mPerLevelSRGBCopyImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount, baseLayer, &mPerLevelSRGBCopyImageViews[mCurrentMaxLevel.get()], baseLevel, levelCount, baseLayer,
layerCount, imageUsageFlags, srgbOverrideFormat)); layerCount, imageUsageFlags, srgbOverrideFormat));
...@@ -6685,9 +6708,9 @@ angle::Result ImageViewHelper::getLevelStorageImageView(ContextVk *contextVk, ...@@ -6685,9 +6708,9 @@ angle::Result ImageViewHelper::getLevelStorageImageView(ContextVk *contextVk,
} }
// Create the view. Note that storage images are not affected by swizzle parameters. // Create the view. Note that storage images are not affected by swizzle parameters.
return image.initAliasedLayerImageView(contextVk, viewType, image.getAspectFlags(), return image.initReinterpretedLayerImageView(
gl::SwizzleState(), imageView, levelVk, 1, layer, contextVk, viewType, image.getAspectFlags(), gl::SwizzleState(), imageView, levelVk, 1,
image.getLayerCount(), imageUsageFlags, vkImageFormat); layer, image.getLayerCount(), imageUsageFlags, vkImageFormat);
} }
angle::Result ImageViewHelper::getLevelLayerStorageImageView(ContextVk *contextVk, angle::Result ImageViewHelper::getLevelLayerStorageImageView(ContextVk *contextVk,
...@@ -6716,9 +6739,9 @@ angle::Result ImageViewHelper::getLevelLayerStorageImageView(ContextVk *contextV ...@@ -6716,9 +6739,9 @@ angle::Result ImageViewHelper::getLevelLayerStorageImageView(ContextVk *contextV
// Create the view. Note that storage images are not affected by swizzle parameters. // Create the view. Note that storage images are not affected by swizzle parameters.
gl::TextureType viewType = Get2DTextureType(1, image.getSamples()); gl::TextureType viewType = Get2DTextureType(1, image.getSamples());
return image.initAliasedLayerImageView(contextVk, viewType, image.getAspectFlags(), return image.initReinterpretedLayerImageView(contextVk, viewType, image.getAspectFlags(),
gl::SwizzleState(), imageView, levelVk, 1, layer, 1, gl::SwizzleState(), imageView, levelVk, 1, layer,
imageUsageFlags, vkImageFormat); 1, imageUsageFlags, vkImageFormat);
} }
angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk, angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
......
...@@ -1339,7 +1339,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1339,7 +1339,7 @@ class ImageHelper final : public Resource, public angle::Subject
uint32_t levelCount, uint32_t levelCount,
uint32_t baseArrayLayer, uint32_t baseArrayLayer,
uint32_t layerCount) const; uint32_t layerCount) const;
angle::Result initAliasedLayerImageView(Context *context, angle::Result initReinterpretedLayerImageView(Context *context,
gl::TextureType textureType, gl::TextureType textureType,
VkImageAspectFlags aspectMask, VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap, const gl::SwizzleState &swizzleMap,
......
...@@ -8619,6 +8619,79 @@ TEST_P(TextureBufferTestES31, QueryWidthAfterBufferResize) ...@@ -8619,6 +8619,79 @@ TEST_P(TextureBufferTestES31, QueryWidthAfterBufferResize)
} }
} }
class CopyImageTestES31 : public ANGLETest
{
protected:
CopyImageTestES31() {}
};
// Test that copies between RGB formats doesn't affect the emulated alpha channel, if any.
TEST_P(CopyImageTestES31, PreserveEmulatedAlpha)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
constexpr GLsizei kSize = 1;
GLTexture src, dst;
// Set up the textures
glBindTexture(GL_TEXTURE_2D, src);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, kSize, kSize);
const GLColor kInitColor(50, 100, 150, 200);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGB, GL_UNSIGNED_BYTE, &kInitColor);
glBindTexture(GL_TEXTURE_2D, dst);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8UI, kSize, kSize);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Copy from src to dst
glCopyImageSubDataEXT(src, GL_TEXTURE_2D, 0, 0, 0, 0, dst, GL_TEXTURE_2D, 0, 0, 0, 0, kSize,
kSize, 1);
// Bind dst as image
glBindImageTexture(0, dst, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI);
// Create a buffer for output
constexpr GLsizei kBufferSize = kSize * kSize * sizeof(uint32_t) * 4;
GLBuffer buffer;
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, buffer);
constexpr char kCS[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(rgba8ui, binding = 0) readonly uniform highp uimage2D imageIn;
layout(std140, binding = 1) buffer dataOut {
uvec4 data[];
};
void main()
{
uvec4 color = imageLoad(imageIn, ivec2(0));
data[0] = color;
})";
ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
glUseProgram(program);
glDispatchCompute(1, 1, 1);
EXPECT_GL_NO_ERROR();
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
const uint32_t *ptr = reinterpret_cast<uint32_t *>(
glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
EXPECT_EQ(ptr[0], kInitColor.R);
EXPECT_EQ(ptr[1], kInitColor.G);
EXPECT_EQ(ptr[2], kInitColor.B);
// Expect alpha to be 1, even if the RGB format is emulated with RGBA.
EXPECT_EQ(ptr[3], 1u);
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
#define ES2_EMULATE_COPY_TEX_IMAGE() \ #define ES2_EMULATE_COPY_TEX_IMAGE() \
...@@ -8673,5 +8746,6 @@ ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest); ...@@ -8673,5 +8746,6 @@ ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest); ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest); ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
ANGLE_INSTANTIATE_TEST_ES31(TextureBufferTestES31); ANGLE_INSTANTIATE_TEST_ES31(TextureBufferTestES31);
ANGLE_INSTANTIATE_TEST_ES31(CopyImageTestES31);
} // anonymous namespace } // anonymous namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment