Add workaround to blit depth to depth
Fixes T2T depth copies on Mac Intel where the destination subresource is a non-zero mip/layer. Fixed: dawn:1083 Change-Id: If344b46c3fd436d857906850fc0ac5ccb4b93e1d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/117592 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
7f523b4e7c
commit
e60a579c19
|
@ -201,6 +201,8 @@ source_set("sources") {
|
|||
"BindingInfo.h",
|
||||
"BlitBufferToDepthStencil.cpp",
|
||||
"BlitBufferToDepthStencil.h",
|
||||
"BlitDepthToDepth.cpp",
|
||||
"BlitDepthToDepth.h",
|
||||
"Blob.cpp",
|
||||
"Blob.h",
|
||||
"BlobCache.cpp",
|
||||
|
|
|
@ -0,0 +1,227 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "dawn/native/BlitDepthToDepth.h"
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "dawn/common/Assert.h"
|
||||
#include "dawn/native/BindGroup.h"
|
||||
#include "dawn/native/CommandEncoder.h"
|
||||
#include "dawn/native/Device.h"
|
||||
#include "dawn/native/InternalPipelineStore.h"
|
||||
#include "dawn/native/RenderPassEncoder.h"
|
||||
#include "dawn/native/RenderPipeline.h"
|
||||
|
||||
namespace dawn::native {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kBlitToDepthShaders[] = R"(
|
||||
|
||||
@vertex fn vert_fullscreen_quad(
|
||||
@builtin(vertex_index) vertex_index : u32,
|
||||
) -> @builtin(position) vec4<f32> {
|
||||
const pos = array<vec2<f32>, 3>(
|
||||
vec2<f32>(-1.0, -1.0),
|
||||
vec2<f32>( 3.0, -1.0),
|
||||
vec2<f32>(-1.0, 3.0));
|
||||
return vec4<f32>(pos[vertex_index], 0.0, 1.0);
|
||||
}
|
||||
|
||||
@group(0) @binding(0) var src_tex : texture_depth_2d;
|
||||
|
||||
// Load the depth value and return it as the frag_depth.
|
||||
@fragment fn blit_to_depth(@builtin(position) position : vec4<f32>) -> @builtin(frag_depth) f32 {
|
||||
return textureLoad(src_tex, vec2<u32>(position.xy), 0);
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
ResultOrError<Ref<RenderPipelineBase>> GetOrCreateDepthBlitPipeline(DeviceBase* device,
|
||||
wgpu::TextureFormat format) {
|
||||
InternalPipelineStore* store = device->GetInternalPipelineStore();
|
||||
{
|
||||
auto it = store->depthBlitPipelines.find(format);
|
||||
if (it != store->depthBlitPipelines.end()) {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderModuleWGSLDescriptor wgslDesc = {};
|
||||
ShaderModuleDescriptor shaderModuleDesc = {};
|
||||
shaderModuleDesc.nextInChain = &wgslDesc;
|
||||
wgslDesc.source = kBlitToDepthShaders;
|
||||
|
||||
Ref<ShaderModuleBase> shaderModule;
|
||||
DAWN_TRY_ASSIGN(shaderModule, device->CreateShaderModule(&shaderModuleDesc));
|
||||
|
||||
FragmentState fragmentState = {};
|
||||
fragmentState.module = shaderModule.Get();
|
||||
fragmentState.entryPoint = "blit_to_depth";
|
||||
|
||||
DepthStencilState dsState = {};
|
||||
dsState.format = format;
|
||||
dsState.depthWriteEnabled = true;
|
||||
|
||||
RenderPipelineDescriptor renderPipelineDesc = {};
|
||||
renderPipelineDesc.vertex.module = shaderModule.Get();
|
||||
renderPipelineDesc.vertex.entryPoint = "vert_fullscreen_quad";
|
||||
renderPipelineDesc.depthStencil = &dsState;
|
||||
renderPipelineDesc.fragment = &fragmentState;
|
||||
|
||||
Ref<RenderPipelineBase> pipeline;
|
||||
DAWN_TRY_ASSIGN(pipeline, device->CreateRenderPipeline(&renderPipelineDesc));
|
||||
|
||||
store->depthBlitPipelines[format] = pipeline;
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MaybeError BlitDepthToDepth(DeviceBase* device,
|
||||
CommandEncoder* commandEncoder,
|
||||
const TextureCopy& src,
|
||||
const TextureCopy& dst,
|
||||
const Extent3D& copyExtent) {
|
||||
// ASSERT that the texture have depth and are not multisampled.
|
||||
ASSERT(src.texture->GetFormat().HasDepth());
|
||||
ASSERT(dst.texture->GetFormat().HasDepth());
|
||||
ASSERT(src.texture->GetSampleCount() == 1u);
|
||||
ASSERT(dst.texture->GetSampleCount() == 1u);
|
||||
|
||||
// Note: because depth texture subresources must be copied in full, this blit
|
||||
// does not need to handle copy subrects.
|
||||
|
||||
// Allow internal usages since we need to use the source as a texture binding, and
|
||||
// the destination as a render attachment.
|
||||
auto scope = commandEncoder->MakeInternalUsageScope();
|
||||
|
||||
Ref<RenderPipelineBase> pipeline;
|
||||
DAWN_TRY_ASSIGN(pipeline,
|
||||
GetOrCreateDepthBlitPipeline(device, dst.texture->GetFormat().format));
|
||||
|
||||
Ref<BindGroupLayoutBase> bgl;
|
||||
DAWN_TRY_ASSIGN(bgl, pipeline->GetBindGroupLayout(0));
|
||||
|
||||
// TODO(crbug.com/dawn/838)
|
||||
// Metal Intel drivers incorrectly create texture views starting at a nonzero array layer. They
|
||||
// also don't textureLoad in the shader at a non-zero array index correctly. Workaround this
|
||||
// issue by copying the non-zero array slices to a single-layer texture. That texture will be be
|
||||
// sampled as the source instead.
|
||||
std::vector<Ref<TextureViewBase>> srcViews;
|
||||
srcViews.reserve(copyExtent.depthOrArrayLayers);
|
||||
for (uint32_t z = 0; z < copyExtent.depthOrArrayLayers; ++z) {
|
||||
uint32_t layer = src.origin.z + z;
|
||||
Ref<TextureViewBase> srcView;
|
||||
if (layer == 0u) {
|
||||
// The zero'th slice. We can use the original texture.
|
||||
TextureViewDescriptor viewDesc = {};
|
||||
viewDesc.aspect = wgpu::TextureAspect::DepthOnly;
|
||||
viewDesc.dimension = wgpu::TextureViewDimension::e2D;
|
||||
viewDesc.baseMipLevel = src.mipLevel;
|
||||
viewDesc.mipLevelCount = 1u;
|
||||
DAWN_TRY_ASSIGN(srcView, src.texture->CreateView(&viewDesc));
|
||||
} else {
|
||||
// Create a single-layer intermediate texture to use as the texture source.
|
||||
TextureDescriptor intermediateTexDesc = {};
|
||||
intermediateTexDesc.format = src.texture->GetFormat().format;
|
||||
intermediateTexDesc.usage =
|
||||
wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst;
|
||||
intermediateTexDesc.size = {copyExtent.width, copyExtent.height};
|
||||
|
||||
Ref<TextureBase> intermediateTexture;
|
||||
DAWN_TRY_ASSIGN(intermediateTexture, device->CreateTexture(&intermediateTexDesc));
|
||||
|
||||
// Copy from the original texture source into the intermediate.
|
||||
{
|
||||
ImageCopyTexture intermediateSrc;
|
||||
intermediateSrc.texture = src.texture.Get();
|
||||
intermediateSrc.mipLevel = src.mipLevel;
|
||||
intermediateSrc.origin = {0, 0, layer};
|
||||
intermediateSrc.aspect = wgpu::TextureAspect::All;
|
||||
|
||||
ImageCopyTexture intermediateDst;
|
||||
intermediateDst.texture = intermediateTexture.Get();
|
||||
intermediateDst.mipLevel = 0u;
|
||||
intermediateDst.origin = {0, 0, 0};
|
||||
intermediateDst.aspect = wgpu::TextureAspect::All;
|
||||
|
||||
// Note: This does not recurse infinitely because the workaround to
|
||||
// blit depth is not needed if the destination level and layer is 0,
|
||||
// and the copy depth is 1.
|
||||
commandEncoder->APICopyTextureToTexture(&intermediateSrc, &intermediateDst,
|
||||
&intermediateTexDesc.size);
|
||||
}
|
||||
|
||||
// Create a texture view pointing to the intermediate texture.
|
||||
TextureViewDescriptor viewDesc = {};
|
||||
viewDesc.aspect = wgpu::TextureAspect::DepthOnly;
|
||||
DAWN_TRY_ASSIGN(srcView, intermediateTexture->CreateView(&viewDesc));
|
||||
}
|
||||
srcViews.push_back(std::move(srcView));
|
||||
}
|
||||
|
||||
// For each copied layer, blit from the source into the destination.
|
||||
for (uint32_t z = 0; z < copyExtent.depthOrArrayLayers; ++z) {
|
||||
Ref<BindGroupBase> bindGroup;
|
||||
{
|
||||
BindGroupEntry bgEntry = {};
|
||||
bgEntry.binding = 0;
|
||||
bgEntry.textureView = srcViews[z].Get();
|
||||
|
||||
BindGroupDescriptor bgDesc = {};
|
||||
bgDesc.layout = bgl.Get();
|
||||
bgDesc.entryCount = 1;
|
||||
bgDesc.entries = &bgEntry;
|
||||
DAWN_TRY_ASSIGN(bindGroup,
|
||||
device->CreateBindGroup(&bgDesc, UsageValidationMode::Internal));
|
||||
}
|
||||
|
||||
Ref<TextureViewBase> dstView;
|
||||
{
|
||||
TextureViewDescriptor viewDesc = {};
|
||||
viewDesc.dimension = wgpu::TextureViewDimension::e2D;
|
||||
viewDesc.baseArrayLayer = dst.origin.z + z;
|
||||
viewDesc.arrayLayerCount = 1;
|
||||
viewDesc.baseMipLevel = dst.mipLevel;
|
||||
viewDesc.mipLevelCount = 1;
|
||||
DAWN_TRY_ASSIGN(dstView, dst.texture->CreateView(&viewDesc));
|
||||
}
|
||||
|
||||
RenderPassDepthStencilAttachment dsAttachment = {};
|
||||
dsAttachment.view = dstView.Get();
|
||||
dsAttachment.depthLoadOp = wgpu::LoadOp::Load;
|
||||
dsAttachment.depthStoreOp = wgpu::StoreOp::Store;
|
||||
if (dst.texture->GetFormat().HasStencil()) {
|
||||
dsAttachment.stencilLoadOp = wgpu::LoadOp::Load;
|
||||
dsAttachment.stencilStoreOp = wgpu::StoreOp::Store;
|
||||
}
|
||||
|
||||
RenderPassDescriptor rpDesc = {};
|
||||
rpDesc.depthStencilAttachment = &dsAttachment;
|
||||
|
||||
// Draw to perform the blit.
|
||||
Ref<RenderPassEncoder> pass = AcquireRef(commandEncoder->APIBeginRenderPass(&rpDesc));
|
||||
pass->APISetBindGroup(0, bindGroup.Get());
|
||||
pass->APISetPipeline(pipeline.Get());
|
||||
pass->APIDraw(3, 1, 0, 0);
|
||||
pass->APIEnd();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace dawn::native
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_DAWN_NATIVE_BLITDEPTHTODEPTH_H_
|
||||
#define SRC_DAWN_NATIVE_BLITDEPTHTODEPTH_H_
|
||||
|
||||
#include "dawn/native/Error.h"
|
||||
|
||||
namespace dawn::native {
|
||||
|
||||
class DeviceBase;
|
||||
class CommandEncoder;
|
||||
struct TextureCopy;
|
||||
struct Extent3D;
|
||||
|
||||
MaybeError BlitDepthToDepth(DeviceBase* device,
|
||||
CommandEncoder* commandEncoder,
|
||||
const TextureCopy& src,
|
||||
const TextureCopy& dst,
|
||||
const Extent3D& copyExtent);
|
||||
|
||||
} // namespace dawn::native
|
||||
|
||||
#endif // SRC_DAWN_NATIVE_BLITDEPTHTODEPTH_H_
|
|
@ -49,6 +49,8 @@ target_sources(dawn_native PRIVATE
|
|||
"BindingInfo.h"
|
||||
"BlitBufferToDepthStencil.cpp"
|
||||
"BlitBufferToDepthStencil.h"
|
||||
"BlitDepthToDepth.cpp"
|
||||
"BlitDepthToDepth.h"
|
||||
"Blob.cpp"
|
||||
"Blob.h"
|
||||
"BlobCache.cpp"
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "dawn/native/ApplyClearColorValueWithDrawHelper.h"
|
||||
#include "dawn/native/BindGroup.h"
|
||||
#include "dawn/native/BlitBufferToDepthStencil.h"
|
||||
#include "dawn/native/BlitDepthToDepth.h"
|
||||
#include "dawn/native/Buffer.h"
|
||||
#include "dawn/native/ChainUtils_autogen.h"
|
||||
#include "dawn/native/CommandBuffer.h"
|
||||
|
@ -1368,18 +1369,44 @@ void CommandEncoder::APICopyTextureToTextureHelper(const ImageCopyTexture* sourc
|
|||
mTopLevelTextures.insert(source->texture);
|
||||
mTopLevelTextures.insert(destination->texture);
|
||||
|
||||
CopyTextureToTextureCmd* copy =
|
||||
allocator->Allocate<CopyTextureToTextureCmd>(Command::CopyTextureToTexture);
|
||||
copy->source.texture = source->texture;
|
||||
copy->source.origin = source->origin;
|
||||
copy->source.mipLevel = source->mipLevel;
|
||||
copy->source.aspect = ConvertAspect(source->texture->GetFormat(), source->aspect);
|
||||
copy->destination.texture = destination->texture;
|
||||
copy->destination.origin = destination->origin;
|
||||
copy->destination.mipLevel = destination->mipLevel;
|
||||
copy->destination.aspect =
|
||||
ConvertAspect(destination->texture->GetFormat(), destination->aspect);
|
||||
copy->copySize = *copySize;
|
||||
Aspect aspect = ConvertAspect(source->texture->GetFormat(), source->aspect);
|
||||
ASSERT(aspect == ConvertAspect(destination->texture->GetFormat(), destination->aspect));
|
||||
|
||||
TextureCopy src;
|
||||
src.texture = source->texture;
|
||||
src.origin = source->origin;
|
||||
src.mipLevel = source->mipLevel;
|
||||
src.aspect = aspect;
|
||||
|
||||
TextureCopy dst;
|
||||
dst.texture = destination->texture;
|
||||
dst.origin = destination->origin;
|
||||
dst.mipLevel = destination->mipLevel;
|
||||
dst.aspect = aspect;
|
||||
|
||||
const bool blitDepth =
|
||||
(aspect & Aspect::Depth) &&
|
||||
GetDevice()->IsToggleEnabled(
|
||||
Toggle::UseBlitForDepthTextureToTextureCopyToNonzeroSubresource) &&
|
||||
(dst.mipLevel > 0 || dst.origin.z > 0 || copySize->depthOrArrayLayers > 1);
|
||||
|
||||
// If we're not using a blit, or there are aspects other than depth,
|
||||
// issue the copy. This is because if there's also stencil, we still need the copy
|
||||
// command to copy the stencil portion.
|
||||
if (!blitDepth || aspect != Aspect::Depth) {
|
||||
CopyTextureToTextureCmd* copy =
|
||||
allocator->Allocate<CopyTextureToTextureCmd>(Command::CopyTextureToTexture);
|
||||
copy->source = src;
|
||||
copy->destination = dst;
|
||||
copy->copySize = *copySize;
|
||||
}
|
||||
|
||||
// Use a blit to copy the depth aspect.
|
||||
if (blitDepth) {
|
||||
DAWN_TRY_CONTEXT(BlitDepthToDepth(GetDevice(), this, src, dst, *copySize),
|
||||
"copying depth aspect from %s to %s using blit workaround.",
|
||||
source->texture, destination->texture);
|
||||
}
|
||||
|
||||
return {};
|
||||
},
|
||||
|
|
|
@ -65,6 +65,8 @@ struct InternalPipelineStore {
|
|||
std::array<Ref<RenderPipelineBase>, 8> setStencilPipelines;
|
||||
};
|
||||
std::unordered_map<wgpu::TextureFormat, BlitR8ToStencilPipelines> blitR8ToStencilPipelines;
|
||||
|
||||
std::unordered_map<wgpu::TextureFormat, Ref<RenderPipelineBase>> depthBlitPipelines;
|
||||
};
|
||||
|
||||
} // namespace dawn::native
|
||||
|
|
|
@ -575,6 +575,15 @@ TextureBase::TextureBase(DeviceBase* device,
|
|||
// in a render pass.
|
||||
AddInternalUsage(wgpu::TextureUsage::RenderAttachment);
|
||||
}
|
||||
if (mFormat.HasDepth() &&
|
||||
device->IsToggleEnabled(Toggle::UseBlitForDepthTextureToTextureCopyToNonzeroSubresource)) {
|
||||
if (mInternalUsage & wgpu::TextureUsage::CopySrc) {
|
||||
AddInternalUsage(wgpu::TextureUsage::TextureBinding);
|
||||
}
|
||||
if (mInternalUsage & wgpu::TextureUsage::CopyDst) {
|
||||
AddInternalUsage(wgpu::TextureUsage::RenderAttachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextureBase::~TextureBase() = default;
|
||||
|
|
|
@ -354,6 +354,11 @@ static constexpr ToggleEnumAndInfoList kToggleNameAndInfoList = {{
|
|||
"texture. Works around an issue where stencil writes by copy commands are not visible "
|
||||
"to a render or compute pass.",
|
||||
"https://crbug.com/dawn/1389"}},
|
||||
{Toggle::UseBlitForDepthTextureToTextureCopyToNonzeroSubresource,
|
||||
{"use_blit_for_depth_texture_to_texture_copy_to_nonzero_subresource",
|
||||
"Use a blit to copy from a depth texture to the nonzero subresource of a depth texture. "
|
||||
"Works around an issue where nonzero layers are not written.",
|
||||
"https://crbug.com/dawn/1083"}},
|
||||
{Toggle::DisallowDeprecatedAPIs,
|
||||
{"disallow_deprecated_apis",
|
||||
"Disallow all deprecated paths by changing the deprecation warnings to validation error for "
|
||||
|
|
|
@ -86,6 +86,7 @@ enum class Toggle {
|
|||
MetalUseBothDepthAndStencilAttachmentsForCombinedDepthStencilFormats,
|
||||
UseBlitForBufferToDepthTextureCopy,
|
||||
UseBlitForBufferToStencilTextureCopy,
|
||||
UseBlitForDepthTextureToTextureCopyToNonzeroSubresource,
|
||||
DisallowDeprecatedAPIs,
|
||||
|
||||
// Unresolved issues.
|
||||
|
|
|
@ -263,6 +263,7 @@ void Device::InitTogglesFromDriver() {
|
|||
true);
|
||||
SetToggle(Toggle::UseBlitForBufferToStencilTextureCopy, true);
|
||||
SetToggle(Toggle::UseBlitForBufferToDepthTextureCopy, true);
|
||||
SetToggle(Toggle::UseBlitForDepthTextureToTextureCopyToNonzeroSubresource, true);
|
||||
|
||||
if ([NSProcessInfo.processInfo
|
||||
isOperatingSystemAtLeastVersion:NSOperatingSystemVersion{12, 0, 0}]) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -130,7 +131,8 @@ class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestPara
|
|||
float regionDepth,
|
||||
uint8_t clearStencil,
|
||||
uint8_t regionStencil,
|
||||
uint32_t mipLevel = 0) {
|
||||
uint32_t mipLevel = 0,
|
||||
uint32_t arrayLayer = 0) {
|
||||
wgpu::TextureFormat format = GetParam().mTextureFormat;
|
||||
// Create the render pass used for the initialization.
|
||||
utils::ComboRenderPipelineDescriptor renderPipelineDesc;
|
||||
|
@ -162,6 +164,8 @@ class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestPara
|
|||
wgpu::TextureViewDescriptor viewDesc = {};
|
||||
viewDesc.baseMipLevel = mipLevel;
|
||||
viewDesc.mipLevelCount = 1;
|
||||
viewDesc.baseArrayLayer = arrayLayer;
|
||||
viewDesc.arrayLayerCount = 1;
|
||||
|
||||
utils::ComboRenderPassDescriptor renderPassDesc({}, texture.CreateView(&viewDesc));
|
||||
renderPassDesc.UnsetDepthStencilLoadStoreOpsForFormat(format);
|
||||
|
@ -916,24 +920,142 @@ TEST_P(StencilCopyTests, CopyNonzeroMipThenReadWithStencilTest) {
|
|||
kWidth >> kMipLevel, kWidth >> kMipLevel, 0u, kMipLevel, 7u);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST_P(DepthStencilCopyTests,
|
||||
{D3D12Backend(), MetalBackend(),
|
||||
MetalBackend({"use_blit_for_buffer_to_depth_texture_copy",
|
||||
"use_blit_for_buffer_to_stencil_texture_copy"}),
|
||||
OpenGLBackend(), OpenGLESBackend(),
|
||||
// Test with the vulkan_use_s8 toggle forced on and off.
|
||||
VulkanBackend({"vulkan_use_s8"}, {}),
|
||||
VulkanBackend({}, {"vulkan_use_s8"})},
|
||||
std::vector<wgpu::TextureFormat>(utils::kDepthAndStencilFormats.begin(),
|
||||
utils::kDepthAndStencilFormats.end()));
|
||||
class DepthStencilCopyTests_RegressionDawn1083 : public DepthStencilCopyTests {};
|
||||
|
||||
DAWN_INSTANTIATE_TEST_P(DepthCopyTests,
|
||||
{D3D12Backend(),
|
||||
D3D12Backend({"d3d12_use_temp_buffer_in_depth_stencil_texture_and_buffer_"
|
||||
"copy_with_non_zero_buffer_offset"}),
|
||||
MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
|
||||
std::vector<wgpu::TextureFormat>(kValidDepthCopyTextureFormats.begin(),
|
||||
kValidDepthCopyTextureFormats.end()));
|
||||
// Regression test for crbug.com/dawn/1083. Checks that T2T copies with
|
||||
// various mip/layer counts/offsets works.
|
||||
TEST_P(DepthStencilCopyTests_RegressionDawn1083, Run) {
|
||||
// TODO(crbug.com/dawn/1648): Diagnose failure on NVIDIA GLES.
|
||||
DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsNvidia());
|
||||
|
||||
uint32_t mipLevelCount = 3;
|
||||
uint32_t arrayLayerCount = 3;
|
||||
wgpu::TextureDescriptor texDesc = {};
|
||||
texDesc.size = {8, 8, arrayLayerCount};
|
||||
texDesc.format = GetParam().mTextureFormat;
|
||||
texDesc.mipLevelCount = mipLevelCount;
|
||||
|
||||
for (uint32_t mipLevel = 0; mipLevel < mipLevelCount; ++mipLevel) {
|
||||
uint32_t mipWidth = texDesc.size.width >> mipLevel;
|
||||
uint32_t mipHeight = texDesc.size.height >> mipLevel;
|
||||
for (uint32_t srcArrayLayer = 0; srcArrayLayer < arrayLayerCount; ++srcArrayLayer) {
|
||||
for (uint32_t dstArrayLayer = 0; dstArrayLayer < arrayLayerCount; ++dstArrayLayer) {
|
||||
// Test copying 1 layer, and all possible layers.
|
||||
for (uint32_t layerCount :
|
||||
{1u, arrayLayerCount - std::max(srcArrayLayer, dstArrayLayer)}) {
|
||||
texDesc.usage =
|
||||
wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
|
||||
wgpu::Texture src = device.CreateTexture(&texDesc);
|
||||
|
||||
texDesc.usage =
|
||||
wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopyDst;
|
||||
wgpu::Texture dst = device.CreateTexture(&texDesc);
|
||||
|
||||
// Initialize texture data.
|
||||
uint8_t stencilValue = 42;
|
||||
float d1 = 0.1;
|
||||
float d2 = 0.01;
|
||||
for (uint32_t z = 0; z < layerCount; ++z) {
|
||||
InitializeDepthStencilTextureRegion(src, d1, d2, stencilValue, stencilValue,
|
||||
mipLevel, srcArrayLayer + z);
|
||||
}
|
||||
|
||||
// Perform a T2T copy
|
||||
{
|
||||
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
|
||||
wgpu::ImageCopyTexture srcView =
|
||||
utils::CreateImageCopyTexture(src, mipLevel, {0, 0, srcArrayLayer});
|
||||
wgpu::ImageCopyTexture dstView =
|
||||
utils::CreateImageCopyTexture(dst, mipLevel, {0, 0, dstArrayLayer});
|
||||
wgpu::Extent3D copySize = {mipWidth, mipHeight, layerCount};
|
||||
commandEncoder.CopyTextureToTexture(&srcView, &dstView, ©Size);
|
||||
|
||||
wgpu::CommandBuffer commands = commandEncoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
}
|
||||
|
||||
// Helper to compute expected depth data.
|
||||
auto GetExpectedDepthData = [&](uint32_t mipLevel) -> std::vector<float> {
|
||||
if (mipLevel == 0) {
|
||||
return {
|
||||
d1, d1, d1, d1, d1, d1, d1, d1, //
|
||||
d1, d1, d1, d1, d1, d1, d1, d1, //
|
||||
d1, d1, d1, d1, d1, d1, d1, d1, //
|
||||
d1, d1, d1, d1, d1, d1, d1, d1, //
|
||||
d2, d2, d2, d2, d1, d1, d1, d1, //
|
||||
d2, d2, d2, d2, d1, d1, d1, d1, //
|
||||
d2, d2, d2, d2, d1, d1, d1, d1, //
|
||||
d2, d2, d2, d2, d1, d1, d1, d1, //
|
||||
};
|
||||
} else if (mipLevel == 1) {
|
||||
return {
|
||||
d1, d1, d1, d1, //
|
||||
d1, d1, d1, d1, //
|
||||
d2, d2, d1, d1, //
|
||||
d2, d2, d1, d1, //
|
||||
};
|
||||
} else if (mipLevel == 2) {
|
||||
return {
|
||||
d1, d1, //
|
||||
d2, d1, //
|
||||
};
|
||||
}
|
||||
UNREACHABLE();
|
||||
};
|
||||
|
||||
// Check the depth
|
||||
for (uint32_t z = 0; z < layerCount; ++z) {
|
||||
ExpectAttachmentDepthTestData(dst, GetParam().mTextureFormat, mipWidth,
|
||||
mipHeight, dstArrayLayer + z, mipLevel,
|
||||
GetExpectedDepthData(mipLevel))
|
||||
<< "depth aspect"
|
||||
<< "\nmipLevelCount: " << mipLevelCount
|
||||
<< "\narrayLayerCount: " << arrayLayerCount
|
||||
<< "\nmipLevel: " << mipLevel
|
||||
<< "\nsrcArrayLayer: " << srcArrayLayer + z
|
||||
<< "\ndstArrayLayer: " << dstArrayLayer + z;
|
||||
|
||||
// Check the stencil
|
||||
if (!utils::IsDepthOnlyFormat(GetParam().mTextureFormat)) {
|
||||
ExpectAttachmentStencilTestData(dst, GetParam().mTextureFormat,
|
||||
mipWidth, mipHeight, dstArrayLayer + z,
|
||||
mipLevel, stencilValue)
|
||||
<< "stencil aspect"
|
||||
<< "\nmipLevelCount: " << mipLevelCount
|
||||
<< "\narrayLayerCount: " << arrayLayerCount
|
||||
<< "\nmipLevel: " << mipLevel
|
||||
<< "\nsrcArrayLayer: " << srcArrayLayer + z
|
||||
<< "\ndstArrayLayer: " << dstArrayLayer + z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST_P(
|
||||
DepthStencilCopyTests,
|
||||
{D3D12Backend(), MetalBackend(),
|
||||
MetalBackend({"use_blit_for_depth_texture_to_texture_copy_to_nonzero_subresource"}),
|
||||
MetalBackend({"use_blit_for_buffer_to_depth_texture_copy",
|
||||
"use_blit_for_buffer_to_stencil_texture_copy"}),
|
||||
OpenGLBackend(), OpenGLESBackend(),
|
||||
// Test with the vulkan_use_s8 toggle forced on and off.
|
||||
VulkanBackend({"vulkan_use_s8"}, {}), VulkanBackend({}, {"vulkan_use_s8"})},
|
||||
std::vector<wgpu::TextureFormat>(utils::kDepthAndStencilFormats.begin(),
|
||||
utils::kDepthAndStencilFormats.end()));
|
||||
|
||||
DAWN_INSTANTIATE_TEST_P(
|
||||
DepthCopyTests,
|
||||
{D3D12Backend(),
|
||||
D3D12Backend({"d3d12_use_temp_buffer_in_depth_stencil_texture_and_buffer_"
|
||||
"copy_with_non_zero_buffer_offset"}),
|
||||
MetalBackend(),
|
||||
MetalBackend({"use_blit_for_depth_texture_to_texture_copy_to_nonzero_subresource"}),
|
||||
OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
|
||||
std::vector<wgpu::TextureFormat>(kValidDepthCopyTextureFormats.begin(),
|
||||
kValidDepthCopyTextureFormats.end()));
|
||||
|
||||
DAWN_INSTANTIATE_TEST_P(DepthCopyFromBufferTests,
|
||||
{D3D12Backend(),
|
||||
|
@ -958,3 +1080,12 @@ DAWN_INSTANTIATE_TEST_P(
|
|||
// Test with the vulkan_use_s8 toggle forced on and off.
|
||||
VulkanBackend({"vulkan_use_s8"}, {}), VulkanBackend({}, {"vulkan_use_s8"})},
|
||||
std::vector<wgpu::TextureFormat>(utils::kStencilFormats.begin(), utils::kStencilFormats.end()));
|
||||
|
||||
DAWN_INSTANTIATE_TEST_P(
|
||||
DepthStencilCopyTests_RegressionDawn1083,
|
||||
{D3D12Backend(), MetalBackend(),
|
||||
MetalBackend({"use_blit_for_depth_texture_to_texture_copy_to_nonzero_subresource"}),
|
||||
OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
|
||||
std::vector<wgpu::TextureFormat>{wgpu::TextureFormat::Depth16Unorm,
|
||||
wgpu::TextureFormat::Depth32FloatStencil8,
|
||||
wgpu::TextureFormat::Depth24Plus});
|
||||
|
|
|
@ -299,15 +299,6 @@ crbug.com/tint/1771 [ ubuntu ] webgpu:api,validation,compute_pipeline:overrides,
|
|||
crbug.com/tint/1771 [ win10 ] webgpu:api,validation,compute_pipeline:overrides,workgroup_size,limits,* [ Failure ]
|
||||
crbug.com/tint/1805 webgpu:shader,validation,parse,align:align_required_alignment:* [ Failure ]
|
||||
|
||||
################################################################################
|
||||
# Failures with depth/stencil textures on Intel Mac
|
||||
################################################################################
|
||||
crbug.com/dawn/1083 [ monterey ] webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth16unorm" [ Failure ]
|
||||
crbug.com/dawn/1083 [ monterey ] webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth24plus" [ Failure ]
|
||||
crbug.com/dawn/1083 [ monterey ] webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth24plus-stencil8" [ Failure ]
|
||||
crbug.com/dawn/1083 [ monterey ] webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth32float" [ Failure ]
|
||||
crbug.com/dawn/1083 [ monterey ] webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth32float-stencil8" [ Failure ]
|
||||
|
||||
############################################################################
|
||||
# Flaky on Intel Mac
|
||||
# KEEP
|
||||
|
|
Loading…
Reference in New Issue