d3d: Map Depth24PlusStencil8 to DXGI_FORMAT_D24_UNORM_S8_UINT
WebGPU spec says that 24 bit depth can be mapped to a depth 24 unorm
format[1]. When depth/stencil formats were initially implemented, all
platforms defaulted to using D32_FLOAT_S8X24_UINT formats presumably due
to their universal availability, but D3D has supported D24_UNORM_S8_UINT
format since feature level 10.0[2] which covers all clients which we
would like Dawn to support. Still put it behind a toggle since there's
a difference in behavior with respect to clamping of the compare ref
value when sampling from unorm vs float depth components with D3D.
[1] https://www.w3.org/TR/webgpu/#24-bit-depth
[2] https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/format-support-for-direct3d-feature-level-10-0-hardware#dxgi_format_d24_unorm_s8_uintfcs-45
Bug: 337980338, 341254292
Change-Id: I9a64de8afaffe820f24c61bf925445d3e23bc22e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/188640
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Auto-Submit: Sunny Sachanandani <sunnyps@chromium.org>
diff --git a/src/dawn/native/Toggles.cpp b/src/dawn/native/Toggles.cpp
index ae42d83..2b373e7 100644
--- a/src/dawn/native/Toggles.cpp
+++ b/src/dawn/native/Toggles.cpp
@@ -542,6 +542,16 @@
"Only use shader model 6.5 or less for D3D12 backend, to workaround issues on some Intel "
"devices.",
"https://crbug.com/dawn/2470", ToggleStage::Adapter}},
+ {Toggle::UsePackedDepth24UnormStencil8Format,
+ {"use_packed_depth24_unorm_stencil8_format",
+ "Use a packed depth24_unorm_stencil8 format like DXGI_FORMAT_D24_UNORM_STENCIL8_UINT on D3D "
+ "for wgpu::TextureFormat::Depth24PlusStencil8.",
+ "https://crbug.com/341254292", ToggleStage::Device}},
+ {Toggle::D3D12ForceStencilComponentReplicateSwizzle,
+ {"d3d12_force_stencil_component_replicate_swizzle",
+ "Force a replicate swizzle for the stencil component i.e. (ssss) instead of (s001) to "
+ "workaround issues on certain Nvidia drivers on D3D12 with depth24_unorm_stencil8 format.",
+ "https://crbug.com/341254292", ToggleStage::Device}},
{Toggle::NoWorkaroundSampleMaskBecomesZeroForAllButLastColorTarget,
{"no_workaround_sample_mask_becomes_zero_for_all_but_last_color_target",
"MacOS 12.0+ Intel has a bug where the sample mask is only applied for the last color "
diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h
index 2c1909d..b5f35e6 100644
--- a/src/dawn/native/Toggles.h
+++ b/src/dawn/native/Toggles.h
@@ -132,6 +132,8 @@
EnableImmediateErrorHandling,
VulkanUseStorageInputOutput16,
D3D12DontUseShaderModel66OrHigher,
+ UsePackedDepth24UnormStencil8Format,
+ D3D12ForceStencilComponentReplicateSwizzle,
// Unresolved issues.
NoWorkaroundSampleMaskBecomesZeroForAllButLastColorTarget,
diff --git a/src/dawn/native/d3d/SwapChainD3D.cpp b/src/dawn/native/d3d/SwapChainD3D.cpp
index 83ccc28..43a575c 100644
--- a/src/dawn/native/d3d/SwapChainD3D.cpp
+++ b/src/dawn/native/d3d/SwapChainD3D.cpp
@@ -109,7 +109,7 @@
// Precompute the configuration parameters we want for the DXGI swapchain.
mConfig.bufferCount = PresentModeToBufferCount(GetPresentMode());
- mConfig.format = d3d::DXGITextureFormat(GetFormat());
+ mConfig.format = d3d::DXGITextureFormat(GetDevice(), GetFormat());
mConfig.swapChainFlags = PresentModeToSwapChainFlags(GetPresentMode());
mConfig.usage = ToDXGIUsage(GetUsage());
diff --git a/src/dawn/native/d3d/UtilsD3D.cpp b/src/dawn/native/d3d/UtilsD3D.cpp
index 9d0123a..2575637 100644
--- a/src/dawn/native/d3d/UtilsD3D.cpp
+++ b/src/dawn/native/d3d/UtilsD3D.cpp
@@ -29,6 +29,8 @@
#include <utility>
+#include "dawn/native/Device.h"
+
namespace dawn::native::d3d {
ResultOrError<std::wstring> ConvertStringToWstring(std::string_view s) {
@@ -97,7 +99,7 @@
return (majorVersion << 32) + minorVersion;
}
-DXGI_FORMAT DXGITypelessTextureFormat(wgpu::TextureFormat format) {
+DXGI_FORMAT DXGITypelessTextureFormat(const DeviceBase* device, wgpu::TextureFormat format) {
switch (format) {
case wgpu::TextureFormat::R8Unorm:
case wgpu::TextureFormat::R8Snorm:
@@ -176,7 +178,12 @@
// for which the typeless equivalent is DXGI_FORMAT_R24G8_TYPELESS.
case wgpu::TextureFormat::Stencil8:
return DXGI_FORMAT_R24G8_TYPELESS;
+
case wgpu::TextureFormat::Depth24PlusStencil8:
+ return device->IsToggleEnabled(Toggle::UsePackedDepth24UnormStencil8Format)
+ ? DXGI_FORMAT_R24G8_TYPELESS
+ : DXGI_FORMAT_R32G8X24_TYPELESS;
+
case wgpu::TextureFormat::Depth32FloatStencil8:
return DXGI_FORMAT_R32G8X24_TYPELESS;
@@ -313,7 +320,7 @@
X(wgpu::TextureFormat::R8BG8Biplanar420Unorm, DXGI_FORMAT_NV12) \
X(wgpu::TextureFormat::R10X6BG10X6Biplanar420Unorm, DXGI_FORMAT_P010)
-DXGI_FORMAT DXGITextureFormat(wgpu::TextureFormat format) {
+DXGI_FORMAT DXGITextureFormat(const DeviceBase* device, wgpu::TextureFormat format) {
switch (format) {
#define X(wgpuFormat, dxgiFormat) \
case wgpuFormat: \
@@ -330,6 +337,9 @@
case wgpu::TextureFormat::Stencil8:
return DXGI_FORMAT_D24_UNORM_S8_UINT;
case wgpu::TextureFormat::Depth24PlusStencil8:
+ return device->IsToggleEnabled(Toggle::UsePackedDepth24UnormStencil8Format)
+ ? DXGI_FORMAT_D24_UNORM_S8_UINT
+ : DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
case wgpu::TextureFormat::Depth32FloatStencil8:
return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
@@ -497,4 +507,61 @@
}
}
+DXGI_FORMAT D3DShaderResourceViewFormat(const DeviceBase* device,
+ const Format& textureFormat,
+ const Format& viewFormat,
+ Aspect aspects) {
+ DAWN_ASSERT(aspects != Aspect::None);
+ if (!HasZeroOrOneBits(aspects)) {
+ // A single aspect is not selected. The texture view must not be sampled.
+ return DXGI_FORMAT_UNKNOWN;
+ }
+ // Note that this will configure the SRV descriptor to reinterpret the texture allocated as
+ // TYPELESS as a single-plane shader-accessible view.
+ DXGI_FORMAT srvFormat = DXGITextureFormat(device, viewFormat.format);
+ if (textureFormat.HasDepthOrStencil()) {
+ // Depth-stencil formats must be mapped to compatible shader-accessible view format.
+ switch (DXGITextureFormat(device, textureFormat.format)) {
+ case DXGI_FORMAT_D32_FLOAT:
+ srvFormat = DXGI_FORMAT_R32_FLOAT;
+ break;
+ case DXGI_FORMAT_D16_UNORM:
+ srvFormat = DXGI_FORMAT_R16_UNORM;
+ break;
+ case DXGI_FORMAT_D24_UNORM_S8_UINT: {
+ switch (aspects) {
+ case Aspect::Depth:
+ srvFormat = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
+ break;
+ case Aspect::Stencil:
+ srvFormat = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
+ break;
+ default:
+ DAWN_UNREACHABLE();
+ break;
+ }
+ break;
+ }
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: {
+ switch (aspects) {
+ case Aspect::Depth:
+ srvFormat = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
+ break;
+ case Aspect::Stencil:
+ srvFormat = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
+ break;
+ default:
+ DAWN_UNREACHABLE();
+ break;
+ }
+ break;
+ }
+ default:
+ DAWN_UNREACHABLE();
+ break;
+ }
+ }
+ return srvFormat;
+}
+
} // namespace dawn::native::d3d
diff --git a/src/dawn/native/d3d/UtilsD3D.h b/src/dawn/native/d3d/UtilsD3D.h
index e78ed7b..3980640 100644
--- a/src/dawn/native/d3d/UtilsD3D.h
+++ b/src/dawn/native/d3d/UtilsD3D.h
@@ -43,13 +43,20 @@
uint64_t MakeDXCVersion(uint64_t majorVersion, uint64_t minorVersion);
-DXGI_FORMAT DXGITypelessTextureFormat(wgpu::TextureFormat format);
+DXGI_FORMAT DXGITypelessTextureFormat(const DeviceBase* device, wgpu::TextureFormat format);
+DXGI_FORMAT DXGITextureFormat(const DeviceBase* device, wgpu::TextureFormat format);
-DXGI_FORMAT DXGITextureFormat(wgpu::TextureFormat format);
ResultOrError<wgpu::TextureFormat> FromUncompressedColorDXGITextureFormat(DXGI_FORMAT format);
DXGI_FORMAT DXGIVertexFormat(wgpu::VertexFormat format);
+// Returns the DXGI format to use as the SRV format for a texture view. Returns
+// DXGI_FORMAT_UNKNOWN if a single aspect is not selected.
+DXGI_FORMAT D3DShaderResourceViewFormat(const DeviceBase* device,
+ const Format& textureFormat,
+ const Format& viewFormat,
+ Aspect aspects);
+
} // namespace dawn::native::d3d
#endif // SRC_DAWN_NATIVE_D3D_UTILSD3D_H_
diff --git a/src/dawn/native/d3d11/CommandBufferD3D11.cpp b/src/dawn/native/d3d11/CommandBufferD3D11.cpp
index 392f314..f5710d0 100644
--- a/src/dawn/native/d3d11/CommandBufferD3D11.cpp
+++ b/src/dawn/native/d3d11/CommandBufferD3D11.cpp
@@ -807,7 +807,8 @@
d3d11DeviceContext->ResolveSubresource(
resolveTexture->GetD3D11Resource(), dstSubresource,
colorTexture->GetD3D11Resource(), srcSubresource,
- d3d::DXGITextureFormat(attachment.resolveTarget->GetFormat().format));
+ d3d::DXGITextureFormat(GetDevice(),
+ attachment.resolveTarget->GetFormat().format));
}
return {};
diff --git a/src/dawn/native/d3d11/TextureD3D11.cpp b/src/dawn/native/d3d11/TextureD3D11.cpp
index 45cab9e..f31c305 100644
--- a/src/dawn/native/d3d11/TextureD3D11.cpp
+++ b/src/dawn/native/d3d11/TextureD3D11.cpp
@@ -236,9 +236,11 @@
// We need to use the typeless format if it's a staging texture for writting to depth-stencil
// textures.
needsTypelessFormat |=
- d3d::IsDepthStencil(d3d::DXGITextureFormat(GetFormat().format)) && mKind == Kind::Staging;
- desc.Format = needsTypelessFormat ? d3d::DXGITypelessTextureFormat(GetFormat().format)
- : d3d::DXGITextureFormat(GetFormat().format);
+ d3d::IsDepthStencil(d3d::DXGITextureFormat(GetDevice(), GetFormat().format)) &&
+ mKind == Kind::Staging;
+ desc.Format = needsTypelessFormat
+ ? d3d::DXGITypelessTextureFormat(GetDevice(), GetFormat().format)
+ : d3d::DXGITextureFormat(GetDevice(), GetFormat().format);
desc.Usage = mKind == Kind::Staging ? D3D11_USAGE_STAGING : D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11TextureBindFlags(GetInternalUsage(), GetFormat());
constexpr UINT kCPUReadWriteFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
@@ -348,7 +350,7 @@
uint32_t sliceCount,
uint32_t planeSlice) const {
D3D11_RENDER_TARGET_VIEW_DESC1 rtvDesc;
- rtvDesc.Format = d3d::DXGITextureFormat(format);
+ rtvDesc.Format = d3d::DXGITextureFormat(GetDevice(), format);
if (IsMultisampledTexture()) {
DAWN_ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
DAWN_ASSERT(GetNumMipLevels() == 1);
@@ -402,7 +404,7 @@
bool stencilReadOnly) const {
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
DAWN_ASSERT(singleLevelRange.levelCount == 1);
- dsvDesc.Format = d3d::DXGITextureFormat(GetFormat().format);
+ dsvDesc.Format = d3d::DXGITextureFormat(GetDevice(), GetFormat().format);
dsvDesc.Flags = 0;
if (depthReadOnly && singleLevelRange.aspects & Aspect::Depth) {
dsvDesc.Flags |= D3D11_DSV_READ_ONLY_DEPTH;
@@ -716,7 +718,7 @@
DAWN_ASSERT(size.width != 0 && size.height != 0 && size.depthOrArrayLayers != 0);
DAWN_ASSERT(subresources.levelCount == 1);
- if (d3d::IsDepthStencil(d3d::DXGITextureFormat(GetFormat().format))) {
+ if (d3d::IsDepthStencil(d3d::DXGITextureFormat(GetDevice(), GetFormat().format))) {
DAWN_TRY(WriteDepthStencilInternal(commandContext, subresources, origin, size, data,
bytesPerRow, rowsPerImage));
return {};
@@ -807,8 +809,8 @@
DAWN_TRY(Texture::CopyInternal(commandContext, ©Cmd));
}
- const auto aspectLayout =
- DepthStencilAspectLayout(d3d::DXGITextureFormat(GetFormat().format), subresources.aspects);
+ const auto aspectLayout = DepthStencilAspectLayout(
+ d3d::DXGITextureFormat(GetDevice(), GetFormat().format), subresources.aspects);
// Map and write to the staging texture.
D3D11_MAPPED_SUBRESOURCE mappedResource;
@@ -891,7 +893,7 @@
// We need to read texel by texel for depth-stencil formats.
std::vector<uint8_t> depthOrStencilData(size.width * blockInfo.byteSize);
const auto aspectLayout = DepthStencilAspectLayout(
- d3d::DXGITextureFormat(GetFormat().format), subresources.aspects);
+ d3d::DXGITextureFormat(GetDevice(), GetFormat().format), subresources.aspects);
DAWN_ASSERT(blockInfo.byteSize == aspectLayout.componentSize);
for (uint32_t y = 0; y < rowsPerImage; ++y) {
// Filter the depth/stencil data out.
@@ -1189,71 +1191,8 @@
Device* device = ToBackend(GetDevice());
D3D11_SHADER_RESOURCE_VIEW_DESC1 srvDesc;
- srvDesc.Format = d3d::DXGITextureFormat(GetFormat().format);
-
- const Format& textureFormat = GetTexture()->GetFormat();
- // TODO(dawn:1705): share below code with D3D12?
- if (textureFormat.HasDepthOrStencil()) {
- // Configure the SRV descriptor to reinterpret the texture allocated as
- // TYPELESS as a single-plane shader-accessible view.
- switch (textureFormat.format) {
- case wgpu::TextureFormat::Depth32Float:
- case wgpu::TextureFormat::Depth24Plus:
- srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
- break;
- case wgpu::TextureFormat::Depth16Unorm:
- srvDesc.Format = DXGI_FORMAT_R16_UNORM;
- break;
- case wgpu::TextureFormat::Stencil8: {
- Aspect aspects = GetAspects();
- DAWN_ASSERT(aspects != Aspect::None);
- if (!HasZeroOrOneBits(aspects)) {
- // A single aspect is not selected. The texture view must not be
- // sampled.
- srvDesc.Format = DXGI_FORMAT_UNKNOWN;
- break;
- }
- switch (aspects) {
- case Aspect::Depth:
- srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
- break;
- case Aspect::Stencil:
- srvDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
- break;
- default:
- DAWN_UNREACHABLE();
- break;
- }
- break;
- }
- case wgpu::TextureFormat::Depth24PlusStencil8:
- case wgpu::TextureFormat::Depth32FloatStencil8: {
- Aspect aspects = GetAspects();
- DAWN_ASSERT(aspects != Aspect::None);
- if (!HasZeroOrOneBits(aspects)) {
- // A single aspect is not selected. The texture view must not be
- // sampled.
- srvDesc.Format = DXGI_FORMAT_UNKNOWN;
- break;
- }
- switch (aspects) {
- case Aspect::Depth:
- srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
- break;
- case Aspect::Stencil:
- srvDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
- break;
- default:
- DAWN_UNREACHABLE();
- break;
- }
- break;
- }
- default:
- DAWN_UNREACHABLE();
- break;
- }
- }
+ srvDesc.Format = d3d::D3DShaderResourceViewFormat(GetDevice(), GetTexture()->GetFormat(),
+ GetFormat(), GetAspects());
// Currently we always use D3D11_TEX2D_ARRAY_SRV because we cannot specify base array
// layer and layer count in D3D11_TEX2D_SRV. For 2D texture views, we treat them as
@@ -1371,7 +1310,7 @@
}
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
- uavDesc.Format = d3d::DXGITextureFormat(GetFormat().format);
+ uavDesc.Format = d3d::DXGITextureFormat(GetDevice(), GetFormat().format);
DAWN_ASSERT(!GetTexture()->IsMultisampledTexture());
switch (GetDimension()) {
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
index 3fe92f1..95d0499 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
@@ -768,6 +768,10 @@
deviceToggles->Default(Toggle::DisableResourceSuballocation, true);
}
}
+
+ if (gpu_info::IsNvidia(vendorId)) {
+ deviceToggles->Default(Toggle::D3D12ForceStencilComponentReplicateSwizzle, true);
+ }
}
ResultOrError<Ref<DeviceBase>> PhysicalDevice::CreateDeviceImpl(
diff --git a/src/dawn/native/d3d12/RenderPipelineD3D12.cpp b/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
index 9c71063..0784d27 100644
--- a/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
+++ b/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
@@ -401,7 +401,7 @@
descriptorD3D12.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
if (HasDepthStencilAttachment()) {
- descriptorD3D12.DSVFormat = d3d::DXGITextureFormat(GetDepthStencilFormat());
+ descriptorD3D12.DSVFormat = d3d::DXGITextureFormat(device, GetDepthStencilFormat());
}
static_assert(kMaxColorAttachments == 8);
@@ -412,7 +412,7 @@
auto highestColorAttachmentIndexPlusOne = GetHighestBitIndexPlusOne(GetColorAttachmentsMask());
for (auto i : IterateBitSet(GetColorAttachmentsMask())) {
descriptorD3D12.RTVFormats[static_cast<uint8_t>(i)] =
- d3d::DXGITextureFormat(GetColorAttachmentFormat(i));
+ d3d::DXGITextureFormat(device, GetColorAttachmentFormat(i));
descriptorD3D12.BlendState.RenderTarget[static_cast<uint8_t>(i)] =
ComputeColorDesc(device, GetColorTargetState(i));
}
diff --git a/src/dawn/native/d3d12/TextureD3D12.cpp b/src/dawn/native/d3d12/TextureD3D12.cpp
index 17b386e..d8635b5 100644
--- a/src/dawn/native/d3d12/TextureD3D12.cpp
+++ b/src/dawn/native/d3d12/TextureD3D12.cpp
@@ -103,16 +103,18 @@
D3D12_RESOURCE_FLAGS D3D12ResourceFlags(wgpu::TextureUsage usage, const Format& format) {
D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE;
- if (usage & wgpu::TextureUsage::StorageBinding) {
- flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
- }
-
- if (usage & wgpu::TextureUsage::RenderAttachment) {
- if (format.HasDepthOrStencil()) {
- flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
- } else {
+ // Always set the depth stencil flags on depth stencil format textures since some formats like
+ // D24_UNORM_S8_UINT don't support copying for lazy clear. Also, setting depth stencil flags
+ // precludes setting other resource flags like render target or unordered access.
+ if (format.HasDepthOrStencil()) {
+ flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
+ } else {
+ if (usage & wgpu::TextureUsage::RenderAttachment) {
flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
}
+ if (usage & wgpu::TextureUsage::StorageBinding) {
+ flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
+ }
}
DAWN_ASSERT(!(flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) ||
@@ -246,8 +248,8 @@
(GetInternalUsage() & wgpu::TextureUsage::TextureBinding) != 0);
DXGI_FORMAT dxgiFormat = needsTypelessFormat
- ? d3d::DXGITypelessTextureFormat(GetFormat().format)
- : d3d::DXGITextureFormat(GetFormat().format);
+ ? d3d::DXGITypelessTextureFormat(device, GetFormat().format)
+ : d3d::DXGITextureFormat(device, GetFormat().format);
resourceDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels());
resourceDescriptor.Format = dxgiFormat;
@@ -343,7 +345,7 @@
}
DXGI_FORMAT Texture::GetD3D12Format() const {
- return d3d::DXGITextureFormat(GetFormat().format);
+ return d3d::DXGITextureFormat(GetDevice(), GetFormat().format);
}
ID3D12Resource* Texture::GetD3D12Resource() const {
@@ -357,12 +359,17 @@
DXGI_FORMAT Texture::GetD3D12CopyableSubresourceFormat(Aspect aspect) const {
DAWN_ASSERT(GetFormat().aspects & aspect);
- switch (GetFormat().format) {
+ wgpu::TextureFormat format = GetFormat().format;
+ switch (format) {
case wgpu::TextureFormat::Depth24PlusStencil8:
case wgpu::TextureFormat::Depth32FloatStencil8:
case wgpu::TextureFormat::Stencil8:
switch (aspect) {
case Aspect::Depth:
+ // The depth24 part of a D24_UNORM_S8_UINT texture cannot be copied with D3D and
+ // is also not supported by WebGPU.
+ // See https://gpuweb.github.io/gpuweb/#depth-formats
+ DAWN_ASSERT(format == wgpu::TextureFormat::Depth32FloatStencil8);
return DXGI_FORMAT_R32_FLOAT;
case Aspect::Stencil:
return DXGI_FORMAT_R8_UINT;
@@ -645,7 +652,7 @@
uint32_t sliceCount,
uint32_t planeSlice) const {
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = d3d::DXGITextureFormat(format.format);
+ rtvDesc.Format = d3d::DXGITextureFormat(GetDevice(), format.format);
if (IsMultisampledTexture()) {
DAWN_ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
DAWN_ASSERT(GetNumMipLevels() == 1);
@@ -905,167 +912,104 @@
TextureView::TextureView(TextureBase* texture, const UnpackedPtr<TextureViewDescriptor>& descriptor)
: TextureViewBase(texture, descriptor) {
- mSrvDesc.Format = d3d::DXGITextureFormat(descriptor->format);
- mSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
-
- UINT planeSlice = 0;
+ const Aspect aspects = GetAspects();
const Format& textureFormat = texture->GetFormat();
- if (textureFormat.HasDepthOrStencil()) {
- // Configure the SRV descriptor to reinterpret the texture allocated as
- // TYPELESS as a single-plane shader-accessible view.
- switch (textureFormat.format) {
- case wgpu::TextureFormat::Depth32Float:
- case wgpu::TextureFormat::Depth24Plus:
- mSrvDesc.Format = DXGI_FORMAT_R32_FLOAT;
- break;
- case wgpu::TextureFormat::Depth16Unorm:
- mSrvDesc.Format = DXGI_FORMAT_R16_UNORM;
- break;
- case wgpu::TextureFormat::Stencil8: {
- Aspect aspects = SelectFormatAspects(textureFormat, descriptor->aspect);
- DAWN_ASSERT(aspects != Aspect::None);
- if (!HasZeroOrOneBits(aspects)) {
- // A single aspect is not selected. The texture view must not be
- // sampled.
- mSrvDesc.Format = DXGI_FORMAT_UNKNOWN;
- break;
- }
- switch (aspects) {
- case Aspect::Depth:
- planeSlice = 0;
- mSrvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
- break;
- case Aspect::Stencil:
- planeSlice = 1;
- mSrvDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
- // Stencil is accessed using the .g component in the shader.
- // Map it to the zeroth component to match other APIs.
- mSrvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
- D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
- D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
- D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
- D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1);
- break;
- default:
- DAWN_UNREACHABLE();
- break;
- }
- break;
+
+ mSrvDesc.Format =
+ d3d::D3DShaderResourceViewFormat(GetDevice(), textureFormat, GetFormat(), aspects);
+ if (mSrvDesc.Format != DXGI_FORMAT_UNKNOWN) {
+ mSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+
+ // Stencil is accessed using the .g component in the shader. Map it to the zeroth component
+ // to match other APIs.
+ DXGI_FORMAT textureDxgiFormat = d3d::DXGITextureFormat(GetDevice(), textureFormat.format);
+ if (d3d::IsDepthStencil(textureDxgiFormat) && aspects == Aspect::Stencil) {
+ if (GetDevice()->IsToggleEnabled(Toggle::D3D12ForceStencilComponentReplicateSwizzle) &&
+ textureDxgiFormat == DXGI_FORMAT_D24_UNORM_S8_UINT) {
+ // Swizzle (ssss)
+ mSrvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
+ D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
+ D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
+ D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
+ D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1);
+ } else {
+ // Swizzle (s001)
+ mSrvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
+ D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
+ D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
+ D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
+ D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1);
}
- case wgpu::TextureFormat::Depth24PlusStencil8:
- case wgpu::TextureFormat::Depth32FloatStencil8: {
- Aspect aspects = SelectFormatAspects(textureFormat, descriptor->aspect);
- DAWN_ASSERT(aspects != Aspect::None);
- if (!HasZeroOrOneBits(aspects)) {
- // A single aspect is not selected. The texture view must not be
- // sampled.
- mSrvDesc.Format = DXGI_FORMAT_UNKNOWN;
+ }
+
+ // Currently we always use D3D12_TEX2D_ARRAY_SRV because we cannot specify base array layer
+ // and layer count in D3D12_TEX2D_SRV. For 2D texture views, we treat them as 1-layer 2D
+ // array textures.
+ // Multisampled textures may only be one array layer, so we use
+ // D3D12_SRV_DIMENSION_TEXTURE2DMS.
+ // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_srv
+ // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_array_srv
+ if (GetTexture()->IsMultisampledTexture()) {
+ switch (descriptor->dimension) {
+ case wgpu::TextureViewDimension::e2DArray:
+ DAWN_ASSERT(texture->GetArrayLayers() == 1);
+ [[fallthrough]];
+ case wgpu::TextureViewDimension::e2D:
+ DAWN_ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
+ mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS;
break;
- }
- switch (aspects) {
- case Aspect::Depth:
- planeSlice = 0;
- mSrvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
- break;
- case Aspect::Stencil:
- planeSlice = 1;
- mSrvDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
- // Stencil is accessed using the .g component in the shader.
- // Map it to the zeroth component to match other APIs.
- mSrvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
- D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
- D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
- D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
- D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1);
- break;
- default:
- DAWN_UNREACHABLE();
- break;
- }
- break;
+
+ default:
+ DAWN_UNREACHABLE();
}
- default:
- DAWN_UNREACHABLE();
- break;
- }
- }
+ } else {
+ switch (descriptor->dimension) {
+ case wgpu::TextureViewDimension::e1D:
+ mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
+ mSrvDesc.Texture1D.MipLevels = descriptor->mipLevelCount;
+ mSrvDesc.Texture1D.MostDetailedMip = descriptor->baseMipLevel;
+ mSrvDesc.Texture1D.ResourceMinLODClamp = 0;
+ break;
- // Per plane view formats must have the plane slice number be the index of the plane in the
- // array of textures.
- if (texture->GetFormat().IsMultiPlanar()) {
- const Aspect planeAspect = ConvertViewAspect(GetFormat(), descriptor->aspect);
- planeSlice = GetAspectIndex(planeAspect);
- mSrvDesc.Format =
- d3d::DXGITextureFormat(texture->GetFormat().GetAspectInfo(planeAspect).format);
- }
+ case wgpu::TextureViewDimension::e2D:
+ case wgpu::TextureViewDimension::e2DArray:
+ DAWN_ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
+ mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
+ mSrvDesc.Texture2DArray.ArraySize = descriptor->arrayLayerCount;
+ mSrvDesc.Texture2DArray.FirstArraySlice = descriptor->baseArrayLayer;
+ mSrvDesc.Texture2DArray.MipLevels = descriptor->mipLevelCount;
+ mSrvDesc.Texture2DArray.MostDetailedMip = descriptor->baseMipLevel;
+ mSrvDesc.Texture2DArray.PlaneSlice = GetAspectIndex(aspects);
+ mSrvDesc.Texture2DArray.ResourceMinLODClamp = 0;
+ break;
+ case wgpu::TextureViewDimension::Cube:
+ case wgpu::TextureViewDimension::CubeArray:
+ DAWN_ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
+ DAWN_ASSERT(descriptor->arrayLayerCount % 6 == 0);
+ mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
+ mSrvDesc.TextureCubeArray.First2DArrayFace = descriptor->baseArrayLayer;
+ mSrvDesc.TextureCubeArray.NumCubes = descriptor->arrayLayerCount / 6;
+ mSrvDesc.TextureCubeArray.MostDetailedMip = descriptor->baseMipLevel;
+ mSrvDesc.TextureCubeArray.MipLevels = descriptor->mipLevelCount;
+ mSrvDesc.TextureCubeArray.ResourceMinLODClamp = 0;
+ break;
+ case wgpu::TextureViewDimension::e3D:
+ DAWN_ASSERT(texture->GetDimension() == wgpu::TextureDimension::e3D);
+ mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
+ mSrvDesc.Texture3D.MostDetailedMip = descriptor->baseMipLevel;
+ mSrvDesc.Texture3D.MipLevels = descriptor->mipLevelCount;
+ mSrvDesc.Texture3D.ResourceMinLODClamp = 0;
+ break;
- // Currently we always use D3D12_TEX2D_ARRAY_SRV because we cannot specify base array layer
- // and layer count in D3D12_TEX2D_SRV. For 2D texture views, we treat them as 1-layer 2D
- // array textures.
- // Multisampled textures may only be one array layer, so we use
- // D3D12_SRV_DIMENSION_TEXTURE2DMS.
- // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_srv
- // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_array_srv
- if (GetTexture()->IsMultisampledTexture()) {
- switch (descriptor->dimension) {
- case wgpu::TextureViewDimension::e2DArray:
- DAWN_ASSERT(texture->GetArrayLayers() == 1);
- [[fallthrough]];
- case wgpu::TextureViewDimension::e2D:
- DAWN_ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
- mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS;
- break;
-
- default:
- DAWN_UNREACHABLE();
- }
- } else {
- switch (descriptor->dimension) {
- case wgpu::TextureViewDimension::e1D:
- mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
- mSrvDesc.Texture1D.MipLevels = descriptor->mipLevelCount;
- mSrvDesc.Texture1D.MostDetailedMip = descriptor->baseMipLevel;
- mSrvDesc.Texture1D.ResourceMinLODClamp = 0;
- break;
-
- case wgpu::TextureViewDimension::e2D:
- case wgpu::TextureViewDimension::e2DArray:
- DAWN_ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
- mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
- mSrvDesc.Texture2DArray.ArraySize = descriptor->arrayLayerCount;
- mSrvDesc.Texture2DArray.FirstArraySlice = descriptor->baseArrayLayer;
- mSrvDesc.Texture2DArray.MipLevels = descriptor->mipLevelCount;
- mSrvDesc.Texture2DArray.MostDetailedMip = descriptor->baseMipLevel;
- mSrvDesc.Texture2DArray.PlaneSlice = planeSlice;
- mSrvDesc.Texture2DArray.ResourceMinLODClamp = 0;
- break;
- case wgpu::TextureViewDimension::Cube:
- case wgpu::TextureViewDimension::CubeArray:
- DAWN_ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
- DAWN_ASSERT(descriptor->arrayLayerCount % 6 == 0);
- mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
- mSrvDesc.TextureCubeArray.First2DArrayFace = descriptor->baseArrayLayer;
- mSrvDesc.TextureCubeArray.NumCubes = descriptor->arrayLayerCount / 6;
- mSrvDesc.TextureCubeArray.MostDetailedMip = descriptor->baseMipLevel;
- mSrvDesc.TextureCubeArray.MipLevels = descriptor->mipLevelCount;
- mSrvDesc.TextureCubeArray.ResourceMinLODClamp = 0;
- break;
- case wgpu::TextureViewDimension::e3D:
- DAWN_ASSERT(texture->GetDimension() == wgpu::TextureDimension::e3D);
- mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
- mSrvDesc.Texture3D.MostDetailedMip = descriptor->baseMipLevel;
- mSrvDesc.Texture3D.MipLevels = descriptor->mipLevelCount;
- mSrvDesc.Texture3D.ResourceMinLODClamp = 0;
- break;
-
- case wgpu::TextureViewDimension::Undefined:
- DAWN_UNREACHABLE();
+ case wgpu::TextureViewDimension::Undefined:
+ DAWN_UNREACHABLE();
+ }
}
}
}
DXGI_FORMAT TextureView::GetD3D12Format() const {
- return d3d::DXGITextureFormat(GetFormat().format);
+ return d3d::DXGITextureFormat(GetDevice(), GetFormat().format);
}
const D3D12_SHADER_RESOURCE_VIEW_DESC& TextureView::GetSRVDescriptor() const {
diff --git a/src/dawn/tests/end2end/DepthBiasTests.cpp b/src/dawn/tests/end2end/DepthBiasTests.cpp
index e8a73e4..68b4ea3 100644
--- a/src/dawn/tests/end2end/DepthBiasTests.cpp
+++ b/src/dawn/tests/end2end/DepthBiasTests.cpp
@@ -50,6 +50,11 @@
int32_t bias,
float biasSlopeScale,
float biasClamp) {
+ // Skip formats other than Depth24PlusStencil8 if we're specifically testing with the packed
+ // depth24_unorm_stencil8 toggle.
+ DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("use_packed_depth24_unorm_stencil8_format") &&
+ depthFormat != wgpu::TextureFormat::Depth24PlusStencil8);
+
const char* vertexSource = nullptr;
switch (quadAngle) {
case QuadAngle::Flat:
diff --git a/src/dawn/tests/end2end/DepthStencilCopyTests.cpp b/src/dawn/tests/end2end/DepthStencilCopyTests.cpp
index 86d1080..7eb9960 100644
--- a/src/dawn/tests/end2end/DepthStencilCopyTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilCopyTests.cpp
@@ -129,6 +129,12 @@
DAWN_TEST_UNSUPPORTED_IF(!mIsFormatSupported);
+ // Skip formats other than Depth24PlusStencil8 if we're specifically testing with the packed
+ // depth24_unorm_stencil8 toggle.
+ DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("use_packed_depth24_unorm_stencil8_format") &&
+ GetParam().mTextureFormat !=
+ wgpu::TextureFormat::Depth24PlusStencil8);
+
// Draw a square in the bottom left quarter of the screen.
mVertexModule = utils::CreateShaderModule(device, R"(
@vertex
@@ -330,6 +336,11 @@
// Test copying both aspects in a T2T copy, then copying only stencil.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyStencil) {
+ // TODO(crbug.com/344949343): Test fails on Intel D3D11 with packed depth24_unorm_stencil8.
+ DAWN_SUPPRESS_TEST_IF(IsIntel() && IsD3D11() &&
+ GetParam().mTextureFormat == wgpu::TextureFormat::Depth24PlusStencil8 &&
+ HasToggleEnabled("use_packed_depth24_unorm_stencil8_format"));
+
constexpr uint32_t kWidth = 4;
constexpr uint32_t kHeight = 4;
@@ -351,6 +362,11 @@
// Test that part of a non-renderable stencil aspect can be copied. Notably,
// this test has different behavior on some platforms than T2TBothAspectsThenCopyStencil.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonRenderableStencil) {
+ // Test fails on D3D11 with Intel when using packed depth24_unorm_stencil8 format.
+ DAWN_SUPPRESS_TEST_IF(IsIntel() && IsD3D11() &&
+ GetParam().mTextureFormat == wgpu::TextureFormat::Depth24PlusStencil8 &&
+ HasToggleEnabled("use_packed_depth24_unorm_stencil8_format"));
+
constexpr uint32_t kWidth = 4;
constexpr uint32_t kHeight = 4;
@@ -371,6 +387,11 @@
// Test that part of a non-renderable, non-zero mip stencil aspect can be copied. Notably,
// this test has different behavior on some platforms than T2TBothAspectsThenCopyStencil.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonRenderableNonZeroMipStencil) {
+ // Test fails on D3D11 with Intel when using packed depth24_unorm_stencil8 format.
+ DAWN_SUPPRESS_TEST_IF(IsIntel() && IsD3D11() &&
+ GetParam().mTextureFormat == wgpu::TextureFormat::Depth24PlusStencil8 &&
+ HasToggleEnabled("use_packed_depth24_unorm_stencil8_format"));
+
wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
0.1f, 0.3f, 1u, 3u, 9, 9, wgpu::TextureUsage::CopySrc, 1);
@@ -1561,7 +1582,8 @@
DAWN_INSTANTIATE_TEST_P(
DepthStencilCopyTests,
- {D3D11Backend(), D3D12Backend(),
+ {D3D11Backend(), D3D11Backend({"use_packed_depth24_unorm_stencil8_format"}), D3D12Backend(),
+ D3D12Backend({"use_packed_depth24_unorm_stencil8_format"}),
D3D12Backend({"use_blit_for_depth_texture_to_texture_copy_to_nonzero_subresource"}),
MetalBackend(),
MetalBackend({"use_blit_for_depth_texture_to_texture_copy_to_nonzero_subresource"}),
@@ -1597,7 +1619,8 @@
DAWN_INSTANTIATE_TEST_P(
StencilCopyTests,
- {D3D11Backend(), D3D12Backend(),
+ {D3D11Backend(), D3D11Backend({"use_packed_depth24_unorm_stencil8_format"}), D3D12Backend(),
+ D3D12Backend({"use_packed_depth24_unorm_stencil8_format"}),
D3D12Backend({"d3d12_use_temp_buffer_in_depth_stencil_texture_and_buffer_"
"copy_with_non_zero_buffer_offset"}),
MetalBackend(), MetalBackend({"metal_use_combined_depth_stencil_format_for_stencil8"}),
diff --git a/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp b/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp
index 29c36b5..8c202e0 100644
--- a/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp
@@ -84,6 +84,11 @@
// Also depends on glTextureView which is not supported on ES.
DAWN_SUPPRESS_TEST_IF(IsOpenGL() || IsOpenGLES());
+ // Skip formats other than Depth24PlusStencil8 if we're specifically testing with the packed
+ // depth24_unorm_stencil8 toggle.
+ DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("use_packed_depth24_unorm_stencil8_format") &&
+ GetParam().mFormat != wgpu::TextureFormat::Depth24PlusStencil8);
+
wgpu::TextureDescriptor descriptor;
descriptor.size = {kRTSize, kRTSize};
descriptor.format = GetParam().mFormat;
@@ -436,8 +441,9 @@
}
DAWN_INSTANTIATE_TEST_P(DepthTextureClearTwiceTest,
- {D3D11Backend(), D3D12Backend(), MetalBackend(), OpenGLBackend(),
- OpenGLESBackend(), VulkanBackend()},
+ {D3D11Backend(), D3D11Backend({"use_packed_depth24_unorm_stencil8_format"}),
+ D3D12Backend(), D3D12Backend({"use_packed_depth24_unorm_stencil8_format"}),
+ MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
{wgpu::TextureFormat::Depth16Unorm, wgpu::TextureFormat::Depth24Plus,
wgpu::TextureFormat::Depth32Float,
wgpu::TextureFormat::Depth32FloatStencil8,
diff --git a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
index 8a75ed2..285003f 100644
--- a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
@@ -28,6 +28,7 @@
#include <utility>
#include <vector>
+#include "absl/strings/str_format.h"
#include "dawn/common/Assert.h"
#include "dawn/tests/DawnTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
@@ -68,6 +69,12 @@
DAWN_TEST_UNSUPPORTED_IF(!mIsFormatSupported);
+ // Skip formats other than Depth24PlusStencil8 if we're specifically testing with the packed
+ // depth24_unorm_stencil8 toggle.
+ DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("use_packed_depth24_unorm_stencil8_format") &&
+ GetParam().mTextureFormat !=
+ wgpu::TextureFormat::Depth24PlusStencil8);
+
wgpu::BufferDescriptor uniformBufferDesc;
uniformBufferDesc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst;
uniformBufferDesc.size = sizeof(float);
@@ -568,7 +575,9 @@
queue.Submit(1, &commands);
EXPECT_TEXTURE_EQ(CompareFunctionPasses(compareRef, compare, textureValue) ? 1.f : 0.f,
- outputTexture, {0, 0});
+ outputTexture, {0, 0})
+ << "compareRef=" << compareRef << " " << compare
+ << " textureValue=" << textureValue;
}
}
@@ -618,7 +627,9 @@
float* expected =
CompareFunctionPasses(compareRef, compare, textureValue) ? &float1 : &float0;
- EXPECT_BUFFER_U32_EQ(*reinterpret_cast<uint32_t*>(expected), outputBuffer, 0);
+ EXPECT_BUFFER_U32_EQ(*reinterpret_cast<uint32_t*>(expected), outputBuffer, 0)
+ << "compareRef=" << compareRef << " " << compare
+ << " textureValue=" << textureValue;
}
}
@@ -761,6 +772,10 @@
wgpu::TextureFormat format = GetParam().mTextureFormat;
+ // Depth24PlusStencil8 could be mapped to a depth24unorm format and ULP for 24-bit unorm is
+ // 1 / (2 ^ 24 - 1) whereas ULP for 32-bit float varies and can be smaller.
+ const float tolerance = format == wgpu::TextureFormat::Depth24PlusStencil8 ? 1e-6f : 0.0f;
+
wgpu::SamplerDescriptor samplerDesc;
wgpu::Sampler sampler = device.CreateSampler(&samplerDesc);
@@ -820,7 +835,7 @@
memcpy(&expectedDepth, &passDescriptor.cDepthStencilAttachmentInfo.depthClearValue,
sizeof(float));
EXPECT_BUFFER(depthOutput, 0, sizeof(float),
- new ::dawn::detail::ExpectEq<float>(expectedDepth));
+ new ::dawn::detail::ExpectEq<float>(expectedDepth, tolerance));
uint8_t expectedStencil = 0;
memcpy(&expectedStencil, &passDescriptor.cDepthStencilAttachmentInfo.stencilClearValue,
@@ -870,7 +885,7 @@
memcpy(&expectedDepth, &passDescriptor.cDepthStencilAttachmentInfo.depthClearValue,
sizeof(float));
EXPECT_BUFFER(depthOutput, 0, sizeof(float),
- new ::dawn::detail::ExpectEq<float>(expectedDepth));
+ new ::dawn::detail::ExpectEq<float>(expectedDepth, tolerance));
uint8_t expectedStencil = 0;
memcpy(&expectedStencil, &passDescriptor.cDepthStencilAttachmentInfo.stencilClearValue,
@@ -890,7 +905,14 @@
DAWN_SUPPRESS_TEST_IF(IsWindows() && IsIntelGen12() && IsANGLED3D11());
wgpu::TextureFormat format = GetParam().mTextureFormat;
- float tolerance = format == wgpu::TextureFormat::Depth16Unorm ? 0.001f : 0.0f;
+
+ // ULP for Depth16Unorm is 1 / (2 ^ 16 - 1). Similarly Depth24PlusStencil8 could be mapped to a
+ // depth24unorm format and ULP for 24-bit unorm is 1 / (2 ^ 24 - 1). But ULP for 32-bit float
+ // varies and can be smaller so set a tolerance (any value greater than unorm ULP is fine).
+ const float tolerance = (format == wgpu::TextureFormat::Depth16Unorm ||
+ format == wgpu::TextureFormat::Depth24PlusStencil8)
+ ? 1e-4f
+ : 0.0f;
// Test 0, between [0, 1], and 1.
DoSamplingTest(TestAspectAndSamplerType::DepthAsDepth,
@@ -917,13 +939,17 @@
DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsQualcomm());
wgpu::TextureFormat format = GetParam().mTextureFormat;
- // Test does not account for precision issues when comparison testing Depth16Unorm.
- DAWN_TEST_UNSUPPORTED_IF(format == wgpu::TextureFormat::Depth16Unorm);
-
wgpu::RenderPipeline pipeline = CreateComparisonRenderPipeline();
+ bool isDepthUnorm = format == wgpu::TextureFormat::Depth16Unorm ||
+ (format == wgpu::TextureFormat::Depth24PlusStencil8 &&
+ HasToggleEnabled("use_packed_depth24_unorm_stencil8_format"));
+
// Test a "normal" ref value between 0 and 1; as well as negative and > 1 refs.
for (float compareRef : kCompareRefs) {
+ if (isDepthUnorm) {
+ compareRef = std::clamp(compareRef, 0.0f, 1.0f);
+ }
// Test 0, below the ref, equal to, above the ref, and 1.
for (wgpu::CompareFunction f : kCompareFunctions) {
DoDepthCompareRefTest(pipeline, format, compareRef, f, kNormalizedTextureValues);
@@ -953,19 +979,21 @@
}
DAWN_INSTANTIATE_TEST_P(DepthStencilSamplingTest,
- {D3D11Backend(), D3D12Backend(), MetalBackend(), OpenGLBackend(),
- OpenGLESBackend(), VulkanBackend()},
+ {D3D11Backend(), D3D11Backend({"use_packed_depth24_unorm_stencil8_format"}),
+ D3D12Backend(), D3D12Backend({"use_packed_depth24_unorm_stencil8_format"}),
+ MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
std::vector<wgpu::TextureFormat>(utils::kDepthAndStencilFormats.begin(),
utils::kDepthAndStencilFormats.end()));
DAWN_INSTANTIATE_TEST_P(DepthSamplingTest,
- {D3D11Backend(), D3D12Backend(), MetalBackend(), OpenGLBackend(),
- OpenGLESBackend(), VulkanBackend()},
+ {D3D11Backend(), D3D11Backend({"use_packed_depth24_unorm_stencil8_format"}),
+ MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
std::vector<wgpu::TextureFormat>(utils::kDepthFormats.begin(),
utils::kDepthFormats.end()));
DAWN_INSTANTIATE_TEST_P(StencilSamplingTest,
- {D3D11Backend(), D3D12Backend(), MetalBackend(),
+ {D3D12Backend(), D3D12Backend({"use_packed_depth24_unorm_stencil8_format"}),
+ MetalBackend(),
MetalBackend({"metal_use_combined_depth_stencil_format_for_stencil8"}),
OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
std::vector<wgpu::TextureFormat>(utils::kStencilFormats.begin(),