Vulkan: Add robust init for NULL texture image.

In gl::ReadPixels(), ValidateReadPixels() will try to
flush staged updates before readPixels. In the case
where a texture was initialized with null RGBA data,
no Framebuffer dirty bits are set, and thus the staged
clear would never be flushed from the staged updates.

1. Add robust init in TextureVk::initImage to ensure
image is initialized.

Test: ./angle_end2end_tests --gtest_filter=\
RobustResourceInitTest*_Vulkan_AllocateNonZeroMemory

2. Update stageSubresourceRobustClear() to
kEmulatedInitColorValue in the case where robust resource
was initialized without full RGBA format to update
init value of robust resource.

Test: texture-attachment-formats.html in
webgl_conformance_vulkan_passthrough_tests.

3. Revert "Suppress Vulkan RobustResourceInit tests."
Revert commit a8e6a46312.

Reason for revert: re-enable related robust tests.

Bug: angleproject:4255
Change-Id: I79f20e0c02c2f1b1cd68ab590f0f765229f9e780
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1985503
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Xiaoxuan Liu 2020-01-02 15:13:37 +08:00 коммит произвёл Commit Bot
Родитель 6c56c57980
Коммит b07816d62b
7 изменённых файлов: 19 добавлений и 44 удалений

Просмотреть файл

@ -169,6 +169,7 @@ Arm Ltd.
Fei Yang
Xinyi He
Sunny Sun
Xiaoxuan Liu
Broadcom Inc.
Gary Sweet

Просмотреть файл

@ -160,7 +160,7 @@ angle::Result RenderbufferVk::initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex)
{
// Note: stageSubresourceRobustClear only uses the intended format to count channels.
mImage->stageSubresourceRobustClear(imageIndex, mImage->getFormat().intendedFormat());
mImage->stageSubresourceRobustClear(imageIndex, mImage->getFormat());
return mImage->flushAllStagedUpdates(vk::GetImpl(context));
}

Просмотреть файл

@ -357,15 +357,15 @@ angle::Result OffscreenSurfaceVk::initializeContents(const gl::Context *context,
if (mColorAttachment.image.valid())
{
mColorAttachment.image.stageSubresourceRobustClear(
imageIndex, mColorAttachment.image.getFormat().intendedFormat());
mColorAttachment.image.stageSubresourceRobustClear(imageIndex,
mColorAttachment.image.getFormat());
ANGLE_TRY(mColorAttachment.image.flushAllStagedUpdates(contextVk));
}
if (mDepthStencilAttachment.image.valid())
{
mDepthStencilAttachment.image.stageSubresourceRobustClear(
imageIndex, mDepthStencilAttachment.image.getFormat().intendedFormat());
imageIndex, mDepthStencilAttachment.image.getFormat());
ANGLE_TRY(mDepthStencilAttachment.image.flushAllStagedUpdates(contextVk));
}
return angle::Result::Continue;
@ -1503,13 +1503,13 @@ angle::Result WindowSurfaceVk::initializeContents(const gl::Context *context,
vk::ImageHelper *image =
isMultiSampled() ? &mColorImageMS : &mSwapchainImages[mCurrentSwapchainImageIndex].image;
image->stageSubresourceRobustClear(imageIndex, image->getFormat().intendedFormat());
image->stageSubresourceRobustClear(imageIndex, image->getFormat());
ANGLE_TRY(image->flushAllStagedUpdates(contextVk));
if (mDepthStencilImage.valid())
{
mDepthStencilImage.stageSubresourceRobustClear(
gl::ImageIndex::Make2D(0), mDepthStencilImage.getFormat().intendedFormat());
mDepthStencilImage.stageSubresourceRobustClear(gl::ImageIndex::Make2D(0),
mDepthStencilImage.getFormat());
ANGLE_TRY(mDepthStencilImage.flushAllStagedUpdates(contextVk));
}

Просмотреть файл

@ -1550,7 +1550,7 @@ angle::Result TextureVk::initializeContents(const gl::Context *context,
const vk::Format &format =
vk::GetImpl(context)->getRenderer()->getFormat(desc.format.info->sizedInternalFormat);
mImage->stageSubresourceRobustClear(imageIndex, format.intendedFormat());
mImage->stageSubresourceRobustClear(imageIndex, format);
onStagingBufferChange();
// Note that we cannot ensure the image is initialized because we might be calling subImage
@ -1646,16 +1646,17 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
ANGLE_TRY(initImageViews(contextVk, format, sized, levelCount, layerCount));
// If the image has an emulated channel, always clear it. These channels will be masked out in
// future writes, and shouldn't contain uninitialized values.
if (format.hasEmulatedImageChannels())
// If the image has an emulated channel or robust resource init is enabled, always clear it.
// These channels will be masked out in future writes, and shouldn't contain uninitialized
// values.
if (contextVk->getState().isRobustResourceInitEnabled() || format.hasEmulatedImageChannels())
{
uint32_t levelCount = mImage->getLevelCount();
for (uint32_t level = 0; level < levelCount; ++level)
{
gl::ImageIndex index = gl::ImageIndex::Make2DArrayRange(level, 0, layerCount);
mImage->stageSubresourceEmulatedClear(index, format.intendedFormat());
mImage->stageSubresourceRobustClear(index, format);
onStagingBufferChange();
}
}

Просмотреть файл

@ -2861,10 +2861,11 @@ void ImageHelper::stageSubresourceUpdateFromImage(ImageHelper *image,
mSubresourceUpdates.emplace_back(image, copyToImage);
}
void ImageHelper::stageSubresourceRobustClear(const gl::ImageIndex &index,
const angle::Format &format)
void ImageHelper::stageSubresourceRobustClear(const gl::ImageIndex &index, const Format &format)
{
stageSubresourceClear(index, format, kWebGLInitColorValue, kWebGLInitDepthStencilValue);
VkClearColorValue initValue =
format.hasEmulatedImageChannels() ? kEmulatedInitColorValue : kWebGLInitColorValue;
stageSubresourceClear(index, format.intendedFormat(), initValue, kWebGLInitDepthStencilValue);
}
void ImageHelper::stageSubresourceEmulatedClear(const gl::ImageIndex &index,

Просмотреть файл

@ -814,7 +814,7 @@ class ImageHelper final : public Resource
const VkImageType imageType);
// Stage a clear operation to a clear value based on WebGL requirements.
void stageSubresourceRobustClear(const gl::ImageIndex &index, const angle::Format &format);
void stageSubresourceRobustClear(const gl::ImageIndex &index, const Format &format);
// Stage a clear operation to a clear value that initializes emulated channels to the desired
// values.

Просмотреть файл

@ -528,9 +528,6 @@ TEST_P(RobustResourceInitTest, ReadingUninitializedTexture)
{
ANGLE_SKIP_TEST_IF(!hasGLExtension());
// http://anglebug.com/4255
ANGLE_SKIP_TEST_IF(IsVulkan());
GLTexture tex;
setupTexture(&tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
@ -547,9 +544,6 @@ TEST_P(RobustResourceInitTest, ReuploadingClearsTexture)
// crbug.com/826576
ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA() && IsDesktopOpenGL());
// http://anglebug.com/4255
ANGLE_SKIP_TEST_IF(IsVulkan());
// Put some data into the texture
std::array<GLColor, kWidth * kHeight> data;
data.fill(GLColor::white);
@ -574,11 +568,7 @@ TEST_P(RobustResourceInitTest, TexImageThenSubImage)
// http://anglebug.com/2407, but only fails on Nexus devices
ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
// http://anglebug.com/4255
ANGLE_SKIP_TEST_IF(IsVulkan());
// Put some data into the texture
GLTexture tex;
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
@ -603,9 +593,6 @@ TEST_P(RobustResourceInitTestES3, ReadingUninitialized3DTexture)
{
ANGLE_SKIP_TEST_IF(!hasGLExtension());
// http://anglebug.com/4255
ANGLE_SKIP_TEST_IF(IsVulkan());
GLTexture tex;
setup3DTexture(&tex);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, kWidth, kHeight, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
@ -768,9 +755,6 @@ TEST_P(RobustResourceInitTest, UninitializedPartsOfCopied2DTexturesAreBlack)
{
ANGLE_SKIP_TEST_IF(!hasGLExtension());
// http://anglebug.com/4255
ANGLE_SKIP_TEST_IF(IsVulkan());
GLTexture tex;
setupTexture(&tex);
GLFramebuffer fbo;
@ -805,9 +789,6 @@ TEST_P(RobustResourceInitTestES3, ReadingOutOfBoundsCopiedTextureWithUnpackBuffe
// glCopyTextureCHROMIUM to copy GL_ALPHA into GL_RGBA
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"));
// http://anglebug.com/4255
ANGLE_SKIP_TEST_IF(IsVulkan());
GLFramebuffer fbo;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
GLRenderbuffer rbo;
@ -858,9 +839,6 @@ TEST_P(RobustResourceInitTest, ReadingOutOfBoundsCopiedTexture)
{
ANGLE_SKIP_TEST_IF(!hasGLExtension());
// http://anglebug.com/4255
ANGLE_SKIP_TEST_IF(IsVulkan());
GLTexture tex;
setupTexture(&tex);
GLFramebuffer fbo;
@ -946,9 +924,6 @@ TEST_P(RobustResourceInitTest, Texture)
// Flaky failure on Linux / NV / Vulkan when run in a sequence. http://anglebug.com/3416
ANGLE_SKIP_TEST_IF(IsVulkan() && IsNVIDIA() && IsLinux());
// http://anglebug.com/4255
ANGLE_SKIP_TEST_IF(IsVulkan());
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
@ -1635,9 +1610,6 @@ TEST_P(RobustResourceInitTestES3, Texture2DArray)
{
ANGLE_SKIP_TEST_IF(!hasGLExtension());
// http://anglebug.com/4255
ANGLE_SKIP_TEST_IF(IsVulkan());
constexpr int kSize = 1024;
constexpr int kLayers = 8;