Vulkan: Choose D32S8 or D24S8 depending on availability
The Vulkan spec mandates support for only one or the other, which is
why we have the concept of a depth24plus format. This also adds a Toggle
to test both formats in DepthStencilStateTests.
Finally this renames ForceWorkarounds to ForceToggles because toggles
can be more than just workarounds.
BUG=dawn:286
Change-Id: I5b5dc582ffd4ee61c51e3e75563aec815c580511
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14103
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: David Turner <digit@google.com>
diff --git a/src/dawn_native/Toggles.cpp b/src/dawn_native/Toggles.cpp
index b46c9ef..34c4692 100644
--- a/src/dawn_native/Toggles.cpp
+++ b/src/dawn_native/Toggles.cpp
@@ -96,6 +96,12 @@
"Enable usage of spvc's internal parsing and IR generation code, instead of "
"spirv_cross's.",
"https://crbug.com/dawn/288"}},
+ {Toggle::VulkanUseD32S8,
+ {"vulkan_use_d32s8",
+ "Vulkan mandates support of either D32_FLOAT_S8 or D24_UNORM_S8. When available the "
+ "backend will use D32S8 (toggle to on) but setting the toggle to off will make it"
+ "use the D24S8 format when possible.",
+ "https://crbug.com/dawn/286"}},
}};
} // anonymous namespace
diff --git a/src/dawn_native/Toggles.h b/src/dawn_native/Toggles.h
index aa5c4f9..e97a273 100644
--- a/src/dawn_native/Toggles.h
+++ b/src/dawn_native/Toggles.h
@@ -35,6 +35,7 @@
SkipValidation,
UseSpvc,
UseSpvcIRGen,
+ VulkanUseD32S8,
EnumCount,
InvalidEnum = EnumCount,
diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp
index a5f7788..232d9b8 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -79,6 +79,10 @@
DAWN_TRY(PrepareRecordingContext());
+ // The environment can request to use D32S8 or D24S8 when it's not available. Override
+ // the decision if it is not applicable.
+ ApplyDepth24PlusS8Toggle();
+
return {};
}
@@ -459,6 +463,40 @@
// TODO(jiawei.shao@intel.com): tighten this workaround when this issue is fixed in both
// Vulkan SPEC and drivers.
SetToggle(Toggle::UseTemporaryBufferInCompressedTextureToTextureCopy, true);
+
+ // By default try to use D32S8 for Depth24PlusStencil8
+ SetToggle(Toggle::VulkanUseD32S8, true);
+ }
+
+ void Device::ApplyDepth24PlusS8Toggle() {
+ VkPhysicalDevice physicalDevice = ToBackend(GetAdapter())->GetPhysicalDevice();
+
+ bool supportsD32s8 = false;
+ {
+ VkFormatProperties properties;
+ fn.GetPhysicalDeviceFormatProperties(physicalDevice, VK_FORMAT_D32_SFLOAT_S8_UINT,
+ &properties);
+ supportsD32s8 =
+ properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ }
+
+ bool supportsD24s8 = false;
+ {
+ VkFormatProperties properties;
+ fn.GetPhysicalDeviceFormatProperties(physicalDevice, VK_FORMAT_D24_UNORM_S8_UINT,
+ &properties);
+ supportsD24s8 =
+ properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ }
+
+ ASSERT(supportsD32s8 || supportsD24s8);
+
+ if (!supportsD24s8) {
+ SetToggle(Toggle::VulkanUseD32S8, true);
+ }
+ if (!supportsD32s8) {
+ SetToggle(Toggle::VulkanUseD32S8, false);
+ }
}
VulkanFunctions* Device::GetMutableFunctions() {
@@ -616,7 +654,7 @@
return DAWN_VALIDATION_ERROR("External semaphore usage not supported");
}
if (!mExternalMemoryService->SupportsImportMemory(
- VulkanImageFormat(textureDescriptor->format), VK_IMAGE_TYPE_2D,
+ VulkanImageFormat(this, textureDescriptor->format), VK_IMAGE_TYPE_2D,
VK_IMAGE_TILING_OPTIMAL,
VulkanImageUsage(textureDescriptor->usage,
GetValidInternalFormat(textureDescriptor->format)),
diff --git a/src/dawn_native/vulkan/DeviceVk.h b/src/dawn_native/vulkan/DeviceVk.h
index e5210d6..13eb152 100644
--- a/src/dawn_native/vulkan/DeviceVk.h
+++ b/src/dawn_native/vulkan/DeviceVk.h
@@ -68,6 +68,8 @@
Serial GetPendingCommandSerial() const override;
MaybeError SubmitPendingCommands();
+ // Dawn Native API
+
TextureBase* CreateTextureWrappingVulkanImage(
const ExternalImageDescriptor* descriptor,
ExternalMemoryHandle memoryHandle,
@@ -126,6 +128,7 @@
void GatherQueueFromDevice();
void InitTogglesFromDriver();
+ void ApplyDepth24PlusS8Toggle();
// To make it easier to use fn it is a public const member. However
// the Device is allowed to mutate them through these private methods.
diff --git a/src/dawn_native/vulkan/RenderPassCache.cpp b/src/dawn_native/vulkan/RenderPassCache.cpp
index 1f3f940..8742458 100644
--- a/src/dawn_native/vulkan/RenderPassCache.cpp
+++ b/src/dawn_native/vulkan/RenderPassCache.cpp
@@ -108,7 +108,7 @@
attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDesc.flags = 0;
- attachmentDesc.format = VulkanImageFormat(query.colorFormats[i]);
+ attachmentDesc.format = VulkanImageFormat(mDevice, query.colorFormats[i]);
attachmentDesc.samples = vkSampleCount;
attachmentDesc.loadOp = VulkanAttachmentLoadOp(query.colorLoadOp[i]);
attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
@@ -129,7 +129,7 @@
depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachmentDesc.flags = 0;
- attachmentDesc.format = VulkanImageFormat(query.depthStencilFormat);
+ attachmentDesc.format = VulkanImageFormat(mDevice, query.depthStencilFormat);
attachmentDesc.samples = vkSampleCount;
attachmentDesc.loadOp = VulkanAttachmentLoadOp(query.depthLoadOp);
attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
@@ -150,7 +150,7 @@
attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDesc.flags = 0;
- attachmentDesc.format = VulkanImageFormat(query.colorFormats[i]);
+ attachmentDesc.format = VulkanImageFormat(mDevice, query.colorFormats[i]);
attachmentDesc.samples = VK_SAMPLE_COUNT_1_BIT;
attachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp
index 5d11976..1594417 100644
--- a/src/dawn_native/vulkan/TextureVk.cpp
+++ b/src/dawn_native/vulkan/TextureVk.cpp
@@ -203,7 +203,7 @@
} // namespace
// Converts Dawn texture format to Vulkan formats.
- VkFormat VulkanImageFormat(wgpu::TextureFormat format) {
+ VkFormat VulkanImageFormat(const Device* device, wgpu::TextureFormat format) {
switch (format) {
case wgpu::TextureFormat::R8Unorm:
return VK_FORMAT_R8_UNORM;
@@ -285,7 +285,15 @@
case wgpu::TextureFormat::Depth24Plus:
return VK_FORMAT_D32_SFLOAT;
case wgpu::TextureFormat::Depth24PlusStencil8:
- return VK_FORMAT_D32_SFLOAT_S8_UINT;
+ // Depth24PlusStencil8 maps to either of these two formats because only requires
+ // that one of the two be present. The VulkanUseD32S8 toggle combines the wish of
+ // the environment, default to using D32S8, and availability information so we know
+ // that the format is available.
+ if (device->IsToggleEnabled(Toggle::VulkanUseD32S8)) {
+ return VK_FORMAT_D32_SFLOAT_S8_UINT;
+ } else {
+ return VK_FORMAT_D24_UNORM_S8_UINT;
+ }
case wgpu::TextureFormat::BC1RGBAUnorm:
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
@@ -428,7 +436,7 @@
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.imageType = VulkanImageType(GetDimension());
- createInfo.format = VulkanImageFormat(GetFormat().format);
+ createInfo.format = VulkanImageFormat(device, GetFormat().format);
createInfo.extent = VulkanExtent3D(GetSize());
createInfo.mipLevels = GetNumMipLevels();
createInfo.arrayLayers = GetArrayLayers();
@@ -484,7 +492,7 @@
// Internally managed, but imported from external handle
MaybeError Texture::InitializeFromExternal(const ExternalImageDescriptor* descriptor,
external_memory::Service* externalMemoryService) {
- VkFormat format = VulkanImageFormat(GetFormat().format);
+ VkFormat format = VulkanImageFormat(ToBackend(GetDevice()), GetFormat().format);
VkImageUsageFlags usage = VulkanImageUsage(GetUsage(), GetFormat());
if (!externalMemoryService->SupportsCreateImage(descriptor, format, usage)) {
return DAWN_VALIDATION_ERROR("Creating an image from external memory is not supported");
@@ -790,7 +798,7 @@
createInfo.flags = 0;
createInfo.image = ToBackend(GetTexture())->GetHandle();
createInfo.viewType = VulkanImageViewType(descriptor->dimension);
- createInfo.format = VulkanImageFormat(descriptor->format);
+ createInfo.format = VulkanImageFormat(device, descriptor->format);
createInfo.components = VkComponentMapping{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
createInfo.subresourceRange.aspectMask = VulkanAspectMask(GetFormat());
diff --git a/src/dawn_native/vulkan/TextureVk.h b/src/dawn_native/vulkan/TextureVk.h
index 82366ae..f904452 100644
--- a/src/dawn_native/vulkan/TextureVk.h
+++ b/src/dawn_native/vulkan/TextureVk.h
@@ -28,7 +28,7 @@
class Device;
struct ExternalImageDescriptor;
- VkFormat VulkanImageFormat(wgpu::TextureFormat format);
+ VkFormat VulkanImageFormat(const Device* device, wgpu::TextureFormat format);
VkImageUsageFlags VulkanImageUsage(wgpu::TextureUsage usage, const Format& format);
VkSampleCountFlagBits VulkanSampleCount(uint32_t sampleCount);
diff --git a/src/tests/DawnTest.cpp b/src/tests/DawnTest.cpp
index 29ffcce..5c3ca29 100644
--- a/src/tests/DawnTest.cpp
+++ b/src/tests/DawnTest.cpp
@@ -93,9 +93,9 @@
const DawnTestParam OpenGLBackend(dawn_native::BackendType::OpenGL);
const DawnTestParam VulkanBackend(dawn_native::BackendType::Vulkan);
-DawnTestParam ForceWorkarounds(const DawnTestParam& originParam,
- std::initializer_list<const char*> forceEnabledWorkarounds,
- std::initializer_list<const char*> forceDisabledWorkarounds) {
+DawnTestParam ForceToggles(const DawnTestParam& originParam,
+ std::initializer_list<const char*> forceEnabledWorkarounds,
+ std::initializer_list<const char*> forceDisabledWorkarounds) {
DawnTestParam newTestParam = originParam;
newTestParam.forceEnabledWorkarounds = forceEnabledWorkarounds;
newTestParam.forceDisabledWorkarounds = forceDisabledWorkarounds;
diff --git a/src/tests/DawnTest.h b/src/tests/DawnTest.h
index e65e148..73fe149 100644
--- a/src/tests/DawnTest.h
+++ b/src/tests/DawnTest.h
@@ -104,9 +104,9 @@
extern const DawnTestParam OpenGLBackend;
extern const DawnTestParam VulkanBackend;
-DawnTestParam ForceWorkarounds(const DawnTestParam& originParam,
- std::initializer_list<const char*> forceEnabledWorkarounds,
- std::initializer_list<const char*> forceDisabledWorkarounds = {});
+DawnTestParam ForceToggles(const DawnTestParam& originParam,
+ std::initializer_list<const char*> forceEnabledWorkarounds,
+ std::initializer_list<const char*> forceDisabledWorkarounds = {});
namespace utils {
class TerribleCommandBuffer;
diff --git a/src/tests/end2end/BufferTests.cpp b/src/tests/end2end/BufferTests.cpp
index e75863e..09640fa 100644
--- a/src/tests/end2end/BufferTests.cpp
+++ b/src/tests/end2end/BufferTests.cpp
@@ -746,7 +746,7 @@
DAWN_INSTANTIATE_TEST(CreateBufferMappedTests,
D3D12Backend,
- ForceWorkarounds(D3D12Backend, {}, {"use_d3d12_resource_heap_tier2"}),
+ ForceToggles(D3D12Backend, {}, {"use_d3d12_resource_heap_tier2"}),
MetalBackend,
OpenGLBackend,
VulkanBackend);
diff --git a/src/tests/end2end/CompressedTextureFormatTests.cpp b/src/tests/end2end/CompressedTextureFormatTests.cpp
index 4a6b627..c720462 100644
--- a/src/tests/end2end/CompressedTextureFormatTests.cpp
+++ b/src/tests/end2end/CompressedTextureFormatTests.cpp
@@ -1054,5 +1054,5 @@
MetalBackend,
OpenGLBackend,
VulkanBackend,
- ForceWorkarounds(VulkanBackend,
- {"use_temporary_buffer_in_texture_to_texture_copy"}));
+ ForceToggles(VulkanBackend,
+ {"use_temporary_buffer_in_texture_to_texture_copy"}));
diff --git a/src/tests/end2end/DepthStencilStateTests.cpp b/src/tests/end2end/DepthStencilStateTests.cpp
index 1692172..d485004 100644
--- a/src/tests/end2end/DepthStencilStateTests.cpp
+++ b/src/tests/end2end/DepthStencilStateTests.cpp
@@ -682,7 +682,8 @@
}
DAWN_INSTANTIATE_TEST(DepthStencilStateTest,
- D3D12Backend,
- MetalBackend,
- OpenGLBackend,
- VulkanBackend);
+ D3D12Backend,
+ MetalBackend,
+ OpenGLBackend,
+ ForceToggles(VulkanBackend, {"vulkan_use_d32s8"}, {}),
+ ForceToggles(VulkanBackend, {}, {"vulkan_use_d32s8"}));
diff --git a/src/tests/end2end/MultisampledRenderingTests.cpp b/src/tests/end2end/MultisampledRenderingTests.cpp
index 6c9d644..80db464 100644
--- a/src/tests/end2end/MultisampledRenderingTests.cpp
+++ b/src/tests/end2end/MultisampledRenderingTests.cpp
@@ -497,13 +497,13 @@
DAWN_INSTANTIATE_TEST(MultisampledRenderingTest,
D3D12Backend,
- ForceWorkarounds(D3D12Backend, {}, {"use_d3d12_resource_heap_tier2"}),
- ForceWorkarounds(D3D12Backend, {}, {"use_d3d12_render_pass"}),
+ ForceToggles(D3D12Backend, {}, {"use_d3d12_resource_heap_tier2"}),
+ ForceToggles(D3D12Backend, {}, {"use_d3d12_render_pass"}),
MetalBackend,
OpenGLBackend,
VulkanBackend,
- ForceWorkarounds(MetalBackend, {"emulate_store_and_msaa_resolve"}),
- ForceWorkarounds(MetalBackend, {"always_resolve_into_zero_level_and_layer"}),
- ForceWorkarounds(MetalBackend,
- {"always_resolve_into_zero_level_and_layer",
- "emulate_store_and_msaa_resolve"}));
+ ForceToggles(MetalBackend, {"emulate_store_and_msaa_resolve"}),
+ ForceToggles(MetalBackend, {"always_resolve_into_zero_level_and_layer"}),
+ ForceToggles(MetalBackend,
+ {"always_resolve_into_zero_level_and_layer",
+ "emulate_store_and_msaa_resolve"}));
diff --git a/src/tests/end2end/NonzeroTextureCreationTests.cpp b/src/tests/end2end/NonzeroTextureCreationTests.cpp
index 2313f3f..405a09f 100644
--- a/src/tests/end2end/NonzeroTextureCreationTests.cpp
+++ b/src/tests/end2end/NonzeroTextureCreationTests.cpp
@@ -166,12 +166,12 @@
}
DAWN_INSTANTIATE_TEST(NonzeroTextureCreationTests,
- ForceWorkarounds(D3D12Backend,
- {"nonzero_clear_resources_on_creation_for_testing"},
- {"lazy_clear_resource_on_first_use"}),
- ForceWorkarounds(OpenGLBackend,
- {"nonzero_clear_resources_on_creation_for_testing"},
- {"lazy_clear_resource_on_first_use"}),
- ForceWorkarounds(VulkanBackend,
- {"nonzero_clear_resources_on_creation_for_testing"},
- {"lazy_clear_resource_on_first_use"}));
+ ForceToggles(D3D12Backend,
+ {"nonzero_clear_resources_on_creation_for_testing"},
+ {"lazy_clear_resource_on_first_use"}),
+ ForceToggles(OpenGLBackend,
+ {"nonzero_clear_resources_on_creation_for_testing"},
+ {"lazy_clear_resource_on_first_use"}),
+ ForceToggles(VulkanBackend,
+ {"nonzero_clear_resources_on_creation_for_testing"},
+ {"lazy_clear_resource_on_first_use"}));
diff --git a/src/tests/end2end/RenderPassTests.cpp b/src/tests/end2end/RenderPassTests.cpp
index 223d99b..6d8aa31 100644
--- a/src/tests/end2end/RenderPassTests.cpp
+++ b/src/tests/end2end/RenderPassTests.cpp
@@ -167,7 +167,7 @@
DAWN_INSTANTIATE_TEST(RenderPassTest,
D3D12Backend,
- ForceWorkarounds(D3D12Backend, {}, {"use_d3d12_render_pass"}),
+ ForceToggles(D3D12Backend, {}, {"use_d3d12_render_pass"}),
MetalBackend,
OpenGLBackend,
VulkanBackend);
diff --git a/src/tests/end2end/TextureZeroInitTests.cpp b/src/tests/end2end/TextureZeroInitTests.cpp
index 13f1d9e..b31f2b7 100644
--- a/src/tests/end2end/TextureZeroInitTests.cpp
+++ b/src/tests/end2end/TextureZeroInitTests.cpp
@@ -762,9 +762,9 @@
DAWN_INSTANTIATE_TEST(
TextureZeroInitTest,
- ForceWorkarounds(D3D12Backend, {"nonzero_clear_resources_on_creation_for_testing"}),
- ForceWorkarounds(D3D12Backend,
- {"nonzero_clear_resources_on_creation_for_testing"},
- {"use_d3d12_render_pass"}),
- ForceWorkarounds(OpenGLBackend, {"nonzero_clear_resources_on_creation_for_testing"}),
- ForceWorkarounds(VulkanBackend, {"nonzero_clear_resources_on_creation_for_testing"}));
+ ForceToggles(D3D12Backend, {"nonzero_clear_resources_on_creation_for_testing"}),
+ ForceToggles(D3D12Backend,
+ {"nonzero_clear_resources_on_creation_for_testing"},
+ {"use_d3d12_render_pass"}),
+ ForceToggles(OpenGLBackend, {"nonzero_clear_resources_on_creation_for_testing"}),
+ ForceToggles(VulkanBackend, {"nonzero_clear_resources_on_creation_for_testing"}));
diff --git a/src/tests/perf_tests/DrawCallPerf.cpp b/src/tests/perf_tests/DrawCallPerf.cpp
index 50b54f1..2a1eba7 100644
--- a/src/tests/perf_tests/DrawCallPerf.cpp
+++ b/src/tests/perf_tests/DrawCallPerf.cpp
@@ -607,7 +607,7 @@
DAWN_INSTANTIATE_PERF_TEST_SUITE_P(
DrawCallPerf,
{D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend,
- ForceWorkarounds(VulkanBackend, {"skip_validation"})},
+ ForceToggles(VulkanBackend, {"skip_validation"})},
{
// Baseline
MakeParam(),