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:
parent
93f88af15b
commit
1cad258869
|
@ -677,22 +677,35 @@ 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) {
|
||||
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(),
|
||||
device->fn.CmdClearDepthStencilImage(recordingContext->commandBuffer,
|
||||
GetHandle(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
clearDepthStencilValue, 1, &range);
|
||||
} else {
|
||||
|
@ -702,6 +715,8 @@ namespace dawn_native { namespace vulkan {
|
|||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
&clearColorValue, 1, &range);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// TODO(natlee@microsoft.com): test compressed textures are cleared
|
||||
// create temp buffer with clear color to copy to the texture image
|
||||
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue