Skip to content

Commit 9c46050

Browse files
committed
fix(🐛): Route surfaces configured with viewFormats through the blit path
Added check for viewFormats in swapchain image usage validation.The Vulkan swapchain creates its images without VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT and wraps them in a texture descriptor that omits the configuration's viewFormats, so the first GetCurrentTexture() fails the viewFormats consistency DAWN_CHECK and aborts. Any non-empty viewFormats now sets needsBlit, like an unsupported extent or usage: the user-facing texture becomes the intermediate blit texture, a regular texture created from the full descriptor, which supports reinterpretation. Metal already builds the swapchain texture from the full descriptor and is unaffected. Adds a SurfaceTests end2end case; the file previously only exercised viewFormatCount = 0, which is why this went unnoticed. Change-Id: If09df3749bb4de9c9ed011bf924141ea1fbfe15b
1 parent 25eb865 commit 9c46050

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

src/dawn/native/vulkan/SwapChainVk.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,10 @@ ResultOrError<SwapChain::Config> SwapChain::ChooseConfig(
272272
VkImageUsageFlags targetUsages =
273273
VulkanImageUsage(GetDevice(), GetUsage(), GetDevice()->GetValidInternalFormat(GetFormat()));
274274
VkImageUsageFlags supportedUsages = surfaceInfo.capabilities.supportedUsageFlags;
275-
if (!IsSubset(targetUsages, supportedUsages)) {
275+
// The swapchain images are also unable to satisfy viewFormats: they are
276+
// created without VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, so they cannot be
277+
// reinterpreted. The blit texture is a regular texture and can.
278+
if (!IsSubset(targetUsages, supportedUsages) || !GetViewFormats().empty()) {
276279
config.needsBlit = true;
277280
} else {
278281
config.usage = targetUsages;

src/dawn/tests/end2end/SurfaceTests.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,34 @@ TEST_P(SurfaceTests, Storage) {
719719
ASSERT_EQ(wgpu::Status::Success, surface.Present());
720720
}
721721

722+
// Test acquiring a texture from a surface configured with viewFormats.
723+
TEST_P(SurfaceTests, ConfigureWithViewFormats) {
724+
wgpu::Surface surface = CreateTestSurface();
725+
wgpu::SurfaceConfiguration config = GetPreferredConfiguration(surface);
726+
727+
// Reinterpretation between a format and its srgb counterpart is always
728+
// allowed; pick the counterpart of whatever the surface prefers.
729+
wgpu::TextureFormat viewFormat;
730+
switch (config.format) {
731+
case wgpu::TextureFormat::BGRA8Unorm:
732+
viewFormat = wgpu::TextureFormat::BGRA8UnormSrgb;
733+
break;
734+
case wgpu::TextureFormat::RGBA8Unorm:
735+
viewFormat = wgpu::TextureFormat::RGBA8UnormSrgb;
736+
break;
737+
default:
738+
GTEST_SKIP() << "Preferred surface format has no srgb counterpart";
739+
}
740+
config.viewFormatCount = 1;
741+
config.viewFormats = &viewFormat;
742+
surface.Configure(&config);
743+
744+
wgpu::SurfaceTexture surfaceTexture;
745+
surface.GetCurrentTexture(&surfaceTexture); // aborts on Vulkan before the fix
746+
ClearTexture(surfaceTexture.texture, {1.0, 0.0, 0.0, 1.0});
747+
surface.Present();
748+
}
749+
722750
// TODO(crbug.com/465183957): Implement swap chain for WebGPUBackend.
723751
DAWN_INSTANTIATE_TEST(SurfaceTests,
724752
D3D11Backend(),

0 commit comments

Comments
 (0)