Add more supported swapchain texture usages.
Adds the CopySrc and CopyDst usages to swapchain textures when available in backends so that the wgpu::Texture returned from GetCurrentTexture can be used in copies. Also adds a swapchain tests to check that these usages indeed work. Bug: dawn:1551 Change-Id: I8495075b0bfb5b8dd953a7811a9d75a76096b143 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/133464 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
bcf4174c06
commit
1b48cc0d6f
|
@ -48,8 +48,9 @@ void Device::DestroyImpl() {
|
|||
|
||||
ResultOrError<wgpu::TextureUsage> Device::GetSupportedSurfaceUsageImpl(
|
||||
const Surface* surface) const {
|
||||
wgpu::TextureUsage usages =
|
||||
wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding;
|
||||
wgpu::TextureUsage usages = wgpu::TextureUsage::RenderAttachment |
|
||||
wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc |
|
||||
wgpu::TextureUsage::CopyDst;
|
||||
return usages;
|
||||
}
|
||||
|
||||
|
|
|
@ -243,8 +243,9 @@ void Device::InitializeRenderPipelineAsyncImpl(Ref<RenderPipelineBase> renderPip
|
|||
|
||||
ResultOrError<wgpu::TextureUsage> Device::GetSupportedSurfaceUsageImpl(
|
||||
const Surface* surface) const {
|
||||
wgpu::TextureUsage usages =
|
||||
wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding;
|
||||
wgpu::TextureUsage usages = wgpu::TextureUsage::RenderAttachment |
|
||||
wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc |
|
||||
wgpu::TextureUsage::CopyDst;
|
||||
return usages;
|
||||
}
|
||||
|
||||
|
|
|
@ -255,8 +255,9 @@ ResultOrError<Ref<TextureViewBase>> Device::CreateTextureViewImpl(
|
|||
|
||||
ResultOrError<wgpu::TextureUsage> Device::GetSupportedSurfaceUsageImpl(
|
||||
const Surface* surface) const {
|
||||
wgpu::TextureUsage usages =
|
||||
wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding;
|
||||
wgpu::TextureUsage usages = wgpu::TextureUsage::RenderAttachment |
|
||||
wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc |
|
||||
wgpu::TextureUsage::CopyDst;
|
||||
return usages;
|
||||
}
|
||||
|
||||
|
|
|
@ -223,8 +223,16 @@ ResultOrError<wgpu::TextureUsage> SwapChain::GetSupportedSurfaceUsage(const Devi
|
|||
fn.GetPhysicalDeviceSurfaceCapabilitiesKHR(vkPhysicalDevice, surfaceVk, &surfaceCapsVk),
|
||||
"GetPhysicalDeviceSurfaceCapabilitiesKHR"));
|
||||
|
||||
wgpu::TextureUsage supportedUsages = wgpu::TextureUsage::RenderAttachment;
|
||||
|
||||
wgpu::TextureUsage supportedUsages = wgpu::TextureUsage::None;
|
||||
if (surfaceCapsVk.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
|
||||
supportedUsages |= wgpu::TextureUsage::CopySrc;
|
||||
}
|
||||
if (surfaceCapsVk.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
|
||||
supportedUsages |= wgpu::TextureUsage::CopyDst;
|
||||
}
|
||||
if (surfaceCapsVk.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
supportedUsages |= wgpu::TextureUsage::RenderAttachment;
|
||||
}
|
||||
if (surfaceCapsVk.supportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) {
|
||||
supportedUsages |= wgpu::TextureUsage::TextureBinding;
|
||||
}
|
||||
|
|
|
@ -69,8 +69,8 @@ class SwapChainTests : public DawnTest {
|
|||
DawnTest::TearDown();
|
||||
}
|
||||
|
||||
void ClearTexture(wgpu::TextureView view, wgpu::Color color) {
|
||||
utils::ComboRenderPassDescriptor desc({view});
|
||||
void ClearTexture(wgpu::Texture texture, wgpu::Color color) {
|
||||
utils::ComboRenderPassDescriptor desc({texture.CreateView()});
|
||||
desc.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
|
||||
desc.cColorAttachments[0].clearValue = color;
|
||||
|
||||
|
@ -92,35 +92,35 @@ class SwapChainTests : public DawnTest {
|
|||
// Basic test for creating a swapchain and presenting one frame.
|
||||
TEST_P(SwapChainTests, Basic) {
|
||||
wgpu::SwapChain swapchain = device.CreateSwapChain(surface, &baseDescriptor);
|
||||
ClearTexture(swapchain.GetCurrentTextureView(), {1.0, 0.0, 0.0, 1.0});
|
||||
ClearTexture(swapchain.GetCurrentTexture(), {1.0, 0.0, 0.0, 1.0});
|
||||
swapchain.Present();
|
||||
}
|
||||
|
||||
// Test replacing the swapchain
|
||||
TEST_P(SwapChainTests, ReplaceBasic) {
|
||||
wgpu::SwapChain swapchain1 = device.CreateSwapChain(surface, &baseDescriptor);
|
||||
ClearTexture(swapchain1.GetCurrentTextureView(), {1.0, 0.0, 0.0, 1.0});
|
||||
ClearTexture(swapchain1.GetCurrentTexture(), {1.0, 0.0, 0.0, 1.0});
|
||||
swapchain1.Present();
|
||||
|
||||
wgpu::SwapChain swapchain2 = device.CreateSwapChain(surface, &baseDescriptor);
|
||||
ClearTexture(swapchain2.GetCurrentTextureView(), {0.0, 1.0, 0.0, 1.0});
|
||||
ClearTexture(swapchain2.GetCurrentTexture(), {0.0, 1.0, 0.0, 1.0});
|
||||
swapchain2.Present();
|
||||
}
|
||||
|
||||
// Test replacing the swapchain after GetCurrentTextureView
|
||||
// Test replacing the swapchain after GetCurrentTexture
|
||||
TEST_P(SwapChainTests, ReplaceAfterGet) {
|
||||
wgpu::SwapChain swapchain1 = device.CreateSwapChain(surface, &baseDescriptor);
|
||||
ClearTexture(swapchain1.GetCurrentTextureView(), {1.0, 0.0, 0.0, 1.0});
|
||||
ClearTexture(swapchain1.GetCurrentTexture(), {1.0, 0.0, 0.0, 1.0});
|
||||
|
||||
wgpu::SwapChain swapchain2 = device.CreateSwapChain(surface, &baseDescriptor);
|
||||
ClearTexture(swapchain2.GetCurrentTextureView(), {0.0, 1.0, 0.0, 1.0});
|
||||
ClearTexture(swapchain2.GetCurrentTexture(), {0.0, 1.0, 0.0, 1.0});
|
||||
swapchain2.Present();
|
||||
}
|
||||
|
||||
// Test destroying the swapchain after GetCurrentTextureView
|
||||
// Test destroying the swapchain after GetCurrentTexture
|
||||
TEST_P(SwapChainTests, DestroyAfterGet) {
|
||||
wgpu::SwapChain swapchain = device.CreateSwapChain(surface, &baseDescriptor);
|
||||
ClearTexture(swapchain.GetCurrentTextureView(), {1.0, 0.0, 0.0, 1.0});
|
||||
ClearTexture(swapchain.GetCurrentTexture(), {1.0, 0.0, 0.0, 1.0});
|
||||
}
|
||||
|
||||
// Test destroying the surface before the swapchain
|
||||
|
@ -129,10 +129,10 @@ TEST_P(SwapChainTests, DestroySurface) {
|
|||
surface = nullptr;
|
||||
}
|
||||
|
||||
// Test destroying the surface before the swapchain but after GetCurrentTextureView
|
||||
// Test destroying the surface before the swapchain but after GetCurrentTexture
|
||||
TEST_P(SwapChainTests, DestroySurfaceAfterGet) {
|
||||
wgpu::SwapChain swapchain = device.CreateSwapChain(surface, &baseDescriptor);
|
||||
ClearTexture(swapchain.GetCurrentTextureView(), {1.0, 0.0, 0.0, 1.0});
|
||||
ClearTexture(swapchain.GetCurrentTexture(), {1.0, 0.0, 0.0, 1.0});
|
||||
surface = nullptr;
|
||||
}
|
||||
|
||||
|
@ -158,12 +158,12 @@ TEST_P(SwapChainTests, SwitchPresentMode) {
|
|||
|
||||
desc.presentMode = mode1;
|
||||
wgpu::SwapChain swapchain1 = device.CreateSwapChain(surface, &desc);
|
||||
ClearTexture(swapchain1.GetCurrentTextureView(), {0.0, 0.0, 0.0, 1.0});
|
||||
ClearTexture(swapchain1.GetCurrentTexture(), {0.0, 0.0, 0.0, 1.0});
|
||||
swapchain1.Present();
|
||||
|
||||
desc.presentMode = mode2;
|
||||
wgpu::SwapChain swapchain2 = device.CreateSwapChain(surface, &desc);
|
||||
ClearTexture(swapchain2.GetCurrentTextureView(), {0.0, 0.0, 0.0, 1.0});
|
||||
ClearTexture(swapchain2.GetCurrentTexture(), {0.0, 0.0, 0.0, 1.0});
|
||||
swapchain2.Present();
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ TEST_P(SwapChainTests, ResizingSwapChainOnly) {
|
|||
desc.height -= i * 10;
|
||||
|
||||
wgpu::SwapChain swapchain = device.CreateSwapChain(surface, &desc);
|
||||
ClearTexture(swapchain.GetCurrentTextureView(), {0.05f * i, 0.0f, 0.0f, 1.0f});
|
||||
ClearTexture(swapchain.GetCurrentTexture(), {0.05f * i, 0.0f, 0.0f, 1.0f});
|
||||
swapchain.Present();
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ TEST_P(SwapChainTests, ResizingWindowOnly) {
|
|||
glfwSetWindowSize(window, 400 - 10 * i, 400 + 10 * i);
|
||||
glfwPollEvents();
|
||||
|
||||
ClearTexture(swapchain.GetCurrentTextureView(), {0.05f * i, 0.0f, 0.0f, 1.0f});
|
||||
ClearTexture(swapchain.GetCurrentTexture(), {0.05f * i, 0.0f, 0.0f, 1.0f});
|
||||
swapchain.Present();
|
||||
}
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ TEST_P(SwapChainTests, ResizingWindowAndSwapChain) {
|
|||
desc.height = height;
|
||||
|
||||
wgpu::SwapChain swapchain = device.CreateSwapChain(surface, &desc);
|
||||
ClearTexture(swapchain.GetCurrentTextureView(), {0.05f * i, 0.0f, 0.0f, 1.0f});
|
||||
ClearTexture(swapchain.GetCurrentTexture(), {0.05f * i, 0.0f, 0.0f, 1.0f});
|
||||
swapchain.Present();
|
||||
}
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ TEST_P(SwapChainTests, SwitchingDevice) {
|
|||
}
|
||||
|
||||
wgpu::SwapChain swapchain = deviceToUse.CreateSwapChain(surface, &baseDescriptor);
|
||||
swapchain.GetCurrentTextureView();
|
||||
swapchain.GetCurrentTexture();
|
||||
swapchain.Present();
|
||||
}
|
||||
}
|
||||
|
@ -281,15 +281,16 @@ class SwapChainWithAdditionalUsageTests : public SwapChainTests {
|
|||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
// TODO(dawn:1551): Reenable on D3D11 after suppressing the D3D11 debug layer warning for
|
||||
// setting the same private data multiple times.
|
||||
DAWN_SUPPRESS_TEST_IF(IsD3D11());
|
||||
|
||||
DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::SurfaceCapabilities}));
|
||||
}
|
||||
|
||||
void SampleTexture(wgpu::TextureView view,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
utils::RGBA8 expectedColor) {
|
||||
void SampleTexture(wgpu::Texture texture, utils::RGBA8 expectedColor) {
|
||||
wgpu::TextureDescriptor texDescriptor;
|
||||
texDescriptor.size = {width, height, 1};
|
||||
texDescriptor.size = {texture.GetWidth(), texture.GetHeight(), 1};
|
||||
texDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||
texDescriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc |
|
||||
wgpu::TextureUsage::CopyDst;
|
||||
|
@ -329,8 +330,8 @@ class SwapChainWithAdditionalUsageTests : public SwapChainTests {
|
|||
{
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDesc);
|
||||
|
||||
wgpu::BindGroup bindGroup =
|
||||
utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, view}});
|
||||
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
|
||||
{{0, texture.CreateView()}});
|
||||
|
||||
utils::ComboRenderPassDescriptor renderPassInfo({dstView});
|
||||
|
||||
|
@ -345,7 +346,16 @@ class SwapChainWithAdditionalUsageTests : public SwapChainTests {
|
|||
queue.Submit(1, &commands);
|
||||
|
||||
EXPECT_TEXTURE_EQ(expectedColor, dstTexture, {0, 0});
|
||||
EXPECT_TEXTURE_EQ(expectedColor, dstTexture, {width - 1, height - 1});
|
||||
EXPECT_TEXTURE_EQ(expectedColor, dstTexture,
|
||||
{texture.GetWidth() - 1, texture.GetHeight() - 1});
|
||||
}
|
||||
|
||||
void WriteTexture(wgpu::Texture texture, const utils::RGBA8& data) {
|
||||
wgpu::Extent3D writeSize = {1, 1, 1};
|
||||
wgpu::ImageCopyTexture dest = {};
|
||||
dest.texture = texture;
|
||||
wgpu::TextureDataLayout dataLayout = {};
|
||||
queue.WriteTexture(&dest, &data, sizeof(utils::RGBA8), &dataLayout, &writeSize);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -356,22 +366,17 @@ TEST_P(SwapChainWithAdditionalUsageTests, GetSurfaceSupportedUsage) {
|
|||
|
||||
// Test that sampling from swapchain is supported.
|
||||
TEST_P(SwapChainWithAdditionalUsageTests, SamplingFromSwapChain) {
|
||||
// TODO(dawn:1551): Reenable on D3D11 after suppressing the D3D11 debug layer warning for
|
||||
// setting the same private data multiple times.
|
||||
DAWN_SUPPRESS_TEST_IF(IsD3D11());
|
||||
|
||||
// Skip all tests if readable surface doesn't support texture binding
|
||||
DAWN_TEST_UNSUPPORTED_IF(
|
||||
(device.GetSupportedSurfaceUsage(surface) & wgpu::TextureUsage::TextureBinding) == 0);
|
||||
!(device.GetSupportedSurfaceUsage(surface) & wgpu::TextureUsage::TextureBinding));
|
||||
|
||||
auto desc = baseDescriptor;
|
||||
desc.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment;
|
||||
|
||||
wgpu::SwapChain swapchain = device.CreateSwapChain(surface, &desc);
|
||||
ClearTexture(swapchain.GetCurrentTextureView(), {1.0, 0.0, 0.0, 1.0});
|
||||
ClearTexture(swapchain.GetCurrentTexture(), {1.0, 0.0, 0.0, 1.0});
|
||||
|
||||
SampleTexture(swapchain.GetCurrentTextureView(), baseDescriptor.width, baseDescriptor.height,
|
||||
utils::RGBA8::kRed);
|
||||
SampleTexture(swapchain.GetCurrentTexture(), utils::RGBA8::kRed);
|
||||
|
||||
swapchain.Present();
|
||||
}
|
||||
|
@ -383,7 +388,7 @@ TEST_P(SwapChainWithAdditionalUsageTests, ErrorIncludeUnsupportedUsage) {
|
|||
auto supportedUsage = device.GetSupportedSurfaceUsage(surface);
|
||||
|
||||
// Assuming StorageBinding is not supported.
|
||||
DAWN_TEST_UNSUPPORTED_IF((supportedUsage & wgpu::TextureUsage::StorageBinding) != 0);
|
||||
DAWN_TEST_UNSUPPORTED_IF(supportedUsage & wgpu::TextureUsage::StorageBinding);
|
||||
|
||||
auto desc = baseDescriptor;
|
||||
desc.usage = supportedUsage | wgpu::TextureUsage::StorageBinding;
|
||||
|
@ -392,6 +397,48 @@ TEST_P(SwapChainWithAdditionalUsageTests, ErrorIncludeUnsupportedUsage) {
|
|||
testing::HasSubstr("is not supported"));
|
||||
}
|
||||
|
||||
// Test copying to a swapchain texture when it is supported.
|
||||
TEST_P(SwapChainWithAdditionalUsageTests, CopyingToSwapChain) {
|
||||
wgpu::TextureUsage supportedUsages = device.GetSupportedSurfaceUsage(surface);
|
||||
// We need the swapchain to support copying to the texture and at least one readback method.
|
||||
DAWN_TEST_UNSUPPORTED_IF(!(supportedUsages & wgpu::TextureUsage::CopyDst));
|
||||
DAWN_TEST_UNSUPPORTED_IF(
|
||||
!(supportedUsages & (wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding)));
|
||||
|
||||
wgpu::SwapChainDescriptor desc = baseDescriptor;
|
||||
desc.usage |= supportedUsages;
|
||||
desc.width = 1;
|
||||
desc.height = 1;
|
||||
|
||||
wgpu::SwapChain swapchain = device.CreateSwapChain(surface, &desc);
|
||||
wgpu::Texture texture = swapchain.GetCurrentTexture();
|
||||
WriteTexture(texture, utils::RGBA8::kRed);
|
||||
|
||||
if (supportedUsages & wgpu::TextureUsage::CopySrc) {
|
||||
EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8::kRed, swapchain.GetCurrentTexture(), 0, 0);
|
||||
} else {
|
||||
// kBlue because the texture is actually BGRA
|
||||
SampleTexture(texture, utils::RGBA8::kBlue);
|
||||
}
|
||||
}
|
||||
|
||||
// Test copying from a swapchain texture when it is supported.
|
||||
TEST_P(SwapChainWithAdditionalUsageTests, CopyingFromSwapChain) {
|
||||
// We need the swapchain to support copying from the texture
|
||||
DAWN_TEST_UNSUPPORTED_IF(
|
||||
!(device.GetSupportedSurfaceUsage(surface) & wgpu::TextureUsage::CopySrc));
|
||||
|
||||
wgpu::SwapChainDescriptor desc = baseDescriptor;
|
||||
desc.usage |= wgpu::TextureUsage::CopySrc;
|
||||
|
||||
wgpu::SwapChain swapchain = device.CreateSwapChain(surface, &desc);
|
||||
wgpu::Texture texture = swapchain.GetCurrentTexture();
|
||||
|
||||
ClearTexture(swapchain.GetCurrentTexture(), {1.0, 0.0, 0.0, 1.0});
|
||||
// kBlue because the texture is actually BGRA8
|
||||
EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8::kBlue, swapchain.GetCurrentTexture(), 0, 0);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(SwapChainTests, MetalBackend(), VulkanBackend());
|
||||
DAWN_INSTANTIATE_TEST(SwapChainWithAdditionalUsageTests,
|
||||
D3D11Backend(),
|
||||
|
|
Loading…
Reference in New Issue