Fix Vulkan over-eager lazy zero initialization for textures

Bug: dawn:145, dawn:348
Change-Id: I10f7bcd324799b783d8dfdc8aaae52033236b695
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16981
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Austin Eng 2020-03-17 01:14:36 +00:00 committed by Commit Bot service account
parent 93f88af15b
commit 1cad258869
3 changed files with 46 additions and 25 deletions

View File

@ -677,30 +677,45 @@ namespace dawn_native { namespace vulkan {
uint32_t layerCount,
TextureBase::ClearValue clearValue) {
Device* device = ToBackend(GetDevice());
VkImageSubresourceRange range = {};
range.aspectMask = GetVkAspectMask();
range.baseMipLevel = baseMipLevel;
range.levelCount = levelCount;
range.baseArrayLayer = baseArrayLayer;
range.layerCount = layerCount;
uint8_t clearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0 : 1;
float fClearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0.f : 1.f;
TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopyDst);
if (GetFormat().isRenderable) {
if (GetFormat().HasDepthOrStencil()) {
VkClearDepthStencilValue clearDepthStencilValue[1];
clearDepthStencilValue[0].depth = fClearColor;
clearDepthStencilValue[0].stencil = clearColor;
device->fn.CmdClearDepthStencilImage(recordingContext->commandBuffer, GetHandle(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
clearDepthStencilValue, 1, &range);
} else {
VkClearColorValue clearColorValue = {
{fClearColor, fClearColor, fClearColor, fClearColor}};
device->fn.CmdClearColorImage(recordingContext->commandBuffer, GetHandle(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
&clearColorValue, 1, &range);
VkImageSubresourceRange range = {};
range.aspectMask = GetVkAspectMask();
range.levelCount = 1;
range.layerCount = 1;
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) {
range.baseMipLevel = level;
for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount;
++layer) {
if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, layer, 1)) {
// Skip lazy clears if already initialized.
continue;
}
range.baseArrayLayer = layer;
if (GetFormat().HasDepthOrStencil()) {
VkClearDepthStencilValue clearDepthStencilValue[1];
clearDepthStencilValue[0].depth = fClearColor;
clearDepthStencilValue[0].stencil = clearColor;
device->fn.CmdClearDepthStencilImage(recordingContext->commandBuffer,
GetHandle(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
clearDepthStencilValue, 1, &range);
} else {
VkClearColorValue clearColorValue = {
{fClearColor, fClearColor, fClearColor, fClearColor}};
device->fn.CmdClearColorImage(recordingContext->commandBuffer, GetHandle(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
&clearColorValue, 1, &range);
}
}
}
} else {
// TODO(natlee@microsoft.com): test compressed textures are cleared
@ -725,11 +740,17 @@ namespace dawn_native { namespace vulkan {
bufferCopy.offset = uploadHandle.startOffset;
bufferCopy.rowPitch = rowPitch;
Extent3D copySize = {GetSize().width, GetSize().height, 1};
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) {
Extent3D copySize = GetMipLevelVirtualSize(level);
for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount;
++layer) {
if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, layer, 1)) {
// Skip lazy clears if already initialized.
continue;
}
dawn_native::TextureCopy textureCopy;
textureCopy.texture = this;
textureCopy.origin = {0, 0, 0};

View File

@ -195,7 +195,7 @@ TEST_P(NonzeroTextureCreationTests, NonRenderableTextureClearWithMultiArrayLayer
// Test that all subresources of a renderable texture are filled because the toggle is enabled.
TEST_P(NonzeroTextureCreationTests, AllSubresourcesFilled) {
// TODO(crbug.com/dawn/145): Implement on other platforms.
DAWN_SKIP_TEST_IF(!IsMetal() && !IsD3D12());
DAWN_SKIP_TEST_IF(!IsMetal() && !IsD3D12() && !IsVulkan());
wgpu::TextureDescriptor baseDescriptor;
baseDescriptor.dimension = wgpu::TextureDimension::e2D;
@ -251,7 +251,7 @@ TEST_P(NonzeroTextureCreationTests, AllSubresourcesFilled) {
// Test that all subresources of a nonrenderable texture are filled because the toggle is enabled.
TEST_P(NonzeroTextureCreationTests, NonRenderableAllSubresourcesFilled) {
// TODO(crbug.com/dawn/145): Implement on other platforms.
DAWN_SKIP_TEST_IF(!IsMetal() && !IsD3D12());
DAWN_SKIP_TEST_IF(!IsMetal() && !IsD3D12() && !IsVulkan());
wgpu::TextureDescriptor baseDescriptor;
baseDescriptor.dimension = wgpu::TextureDimension::e2D;

View File

@ -872,7 +872,7 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencilStoreOpClear) {
// uninitialized mip does not clear the initialized mip.
TEST_P(TextureZeroInitTest, PreservesInitializedMip) {
// TODO(crbug.com/dawn/145): Fix this on other backends
DAWN_SKIP_TEST_IF(!IsMetal() && !IsD3D12());
DAWN_SKIP_TEST_IF(!IsMetal() && !IsD3D12() && !IsVulkan());
wgpu::TextureDescriptor sampleTextureDescriptor = CreateTextureDescriptor(
2, 1,
@ -953,7 +953,7 @@ TEST_P(TextureZeroInitTest, PreservesInitializedMip) {
// the uninitialized layer does not clear the initialized layer.
TEST_P(TextureZeroInitTest, PreservesInitializedArrayLayer) {
// TODO(crbug.com/dawn/145): Fix this on other backends
DAWN_SKIP_TEST_IF(!IsMetal() && !IsD3D12());
DAWN_SKIP_TEST_IF(!IsMetal() && !IsD3D12() && !IsVulkan());
wgpu::TextureDescriptor sampleTextureDescriptor = CreateTextureDescriptor(
1, 2,