Commit baf64903 by Tim Van Patten Committed by Commit Bot

Allow small compressed mip level copies

Update ValidateCopyImageSubDataBase() to take into consideration if the entire mip level is being written, even if the size of the mip level is smaller than the compressed block size. This also uncovered a bug in ImageHelper::initializeNonZeroMemory() where the image extents are not at least as large as the compressed format block size: VUID-vkCmdCopyBufferToImage-imageExtent-00207 This CL adds isAllocateNonZeroMemoryEnabled() to allow skipping the test when that feature is enabled while that bug is chased. Bug: angleproject:5592 Bug: angleproject:5634 Bug: angleproject:5643 Test: Texture2DTestES3.CopyCompressedImageMipMaps Change-Id: I0381e0d3490fb148604b61dc3bae8f96ba8b5f8e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2673069 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent a9de5d99
......@@ -2965,16 +2965,15 @@ bool ValidateCompressedRegion(const Context *context,
GLsizei width,
GLsizei height)
{
if (formatInfo.compressed)
ASSERT(formatInfo.compressed);
// INVALID_VALUE is generated if the image format is compressed and the dimensions of the
// subregion fail to meet the alignment constraints of the format.
if ((width % formatInfo.compressedBlockWidth != 0) ||
(height % formatInfo.compressedBlockHeight != 0))
{
// INVALID_VALUE is generated if the image format is compressed and the dimensions of the
// subregion fail to meet the alignment constraints of the format.
if ((width % formatInfo.compressedBlockWidth != 0) ||
(height % formatInfo.compressedBlockHeight != 0))
{
context->validationError(GL_INVALID_VALUE, kInvalidCompressedRegionSize);
return false;
}
context->validationError(GL_INVALID_VALUE, kInvalidCompressedRegionSize);
return false;
}
return true;
......@@ -3355,12 +3354,27 @@ bool ValidateCopyImageSubDataBase(const Context *context,
return false;
}
if (!ValidateCompressedRegion(context, srcFormatInfo, srcWidth, srcHeight))
bool fillsEntireMip = false;
gl::Texture *dstTexture = context->getTexture({dstName});
gl::TextureTarget dstTargetPacked = gl::PackParam<gl::TextureTarget>(dstTarget);
// TODO(http://anglebug.com/5643): Some targets (e.g., GL_TEXTURE_CUBE_MAP, GL_RENDERBUFFER) are
// unsupported when used with compressed formats due to gl::PackParam() returning
// TextureTarget::InvalidEnum.
if (dstTargetPacked != gl::TextureTarget::InvalidEnum)
{
const gl::Extents &dstExtents = dstTexture->getExtents(dstTargetPacked, dstLevel);
fillsEntireMip = dstX == 0 && dstY == 0 && dstZ == 0 && srcWidth == dstExtents.width &&
srcHeight == dstExtents.height && srcDepth == dstExtents.depth;
}
if (srcFormatInfo.compressed && !fillsEntireMip &&
!ValidateCompressedRegion(context, srcFormatInfo, srcWidth, srcHeight))
{
return false;
}
if (!ValidateCompressedRegion(context, dstFormatInfo, dstWidth, dstHeight))
if (dstFormatInfo.compressed && !fillsEntireMip &&
!ValidateCompressedRegion(context, dstFormatInfo, dstWidth, dstHeight))
{
return false;
}
......
......@@ -3870,6 +3870,47 @@ TEST_P(Texture2DTestES3, CopyImage)
EXPECT_PIXEL_RECT_EQ(0, 0, 2, 4, GLColor::red);
}
// Test GL_EXT_copy_image compressed texture copy with mipmaps smaller than the block size
TEST_P(Texture2DTestES3, CopyCompressedImageMipMaps)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
// TODO(http://anglebug.com/5634): Fix calls to vkCmdCopyBufferToImage() with images smaller
// than the compressed format block size.
ANGLE_SKIP_TEST_IF(isAllocateNonZeroMemoryEnabled());
constexpr uint32_t kSize = 4;
constexpr size_t kNumLevels = 3;
const uint8_t CompressedImageETC1[8] = {0x0, 0x0, 0xf8, 0x2, 0xff, 0xff, 0x0, 0x0};
GLTexture srcTexture;
glBindTexture(GL_TEXTURE_2D, srcTexture);
for (size_t level = 0; level < kNumLevels; ++level)
{
glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_ETC1_RGB8_OES, kSize >> level,
kSize >> level, 0, 8, CompressedImageETC1);
EXPECT_GL_NO_ERROR();
}
GLTexture destTexture;
glBindTexture(GL_TEXTURE_2D, destTexture);
for (size_t level = 0; level < kNumLevels; ++level)
{
glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_ETC1_RGB8_OES, kSize >> level,
kSize >> level, 0, 8, nullptr);
EXPECT_GL_NO_ERROR();
}
glBindTexture(GL_TEXTURE_2D, 0);
// copy
for (size_t level = 0; level < kNumLevels; ++level)
{
glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, level, 0, 0, 0, destTexture, GL_TEXTURE_2D,
level, 0, 0, 0, kSize >> level, kSize >> level, 1);
EXPECT_GL_NO_ERROR();
}
}
// Test GL_EXT_copy_image copy with a non-zero base level
TEST_P(Texture2DTestES3, CopyImageBaseLevel1)
{
......
......@@ -524,6 +524,11 @@ class ANGLETestBase
bool platformSupportsMultithreading() const;
bool isAllocateNonZeroMemoryEnabled() const
{
return mCurrentParams->getAllocateNonZeroMemoryFeature() == EGL_TRUE;
}
private:
void checkD3D11SDKLayersMessages();
......
......@@ -49,6 +49,11 @@ bool PlatformParameters::isSwiftshader() const
return eglParameters.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;
}
EGLint PlatformParameters::getAllocateNonZeroMemoryFeature() const
{
return eglParameters.allocateNonZeroMemoryFeature;
}
void PlatformParameters::initDefaultParameters()
{
// Default debug layers to enabled in tests.
......
......@@ -34,6 +34,7 @@ struct PlatformParameters
EGLint getRenderer() const;
EGLint getDeviceType() const;
bool isSwiftshader() const;
EGLint getAllocateNonZeroMemoryFeature() const;
void initDefaultParameters();
......
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