Update depth-stencil copy validation

Depth/stencil copies of partial subresources is disallowed in
WebGPU because this is a D3D12 restriction. This restriction
need also to be enforced on B2T, T2B and WriteTexture.

This CL also fixes the subresource whole size calucation to use
the mip level. Previously, the 0th level size was always used.

This CL updates the validation to be correct and adds tests.
The DepthStencilCopy tests are factored into smaller helpers to
reduce code duplication.

Bug: dawn:439
Change-Id: I45d4836f6be1707c5171bddef875e535e935f7f4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/26660
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Austin Eng
2020-09-01 18:40:18 +00:00
committed by Commit Bot service account
parent ccda6a0009
commit f114a68b8f
10 changed files with 708 additions and 253 deletions

View File

@@ -792,6 +792,66 @@ TEST_F(CopyCommandTest_B2T, CopyToStencilAspect) {
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, {0, 0, 0},
{16, 16, 1}, wgpu::TextureAspect::StencilOnly);
}
// A copy fails when using a depth/stencil texture, and the entire subresource isn't copied
{
uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::R8Uint);
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
wgpu::Texture destination =
Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8,
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::OutputAttachment);
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, {0, 0, 0},
{15, 15, 1}, wgpu::TextureAspect::StencilOnly);
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, {0, 0, 0},
{1, 1, 1}, wgpu::TextureAspect::StencilOnly);
}
// Non-zero mip: A copy fails when using a depth/stencil texture, and the entire subresource
// isn't copied
{
uint64_t bufferSize = BufferSizeForTextureCopy(8, 8, 1, wgpu::TextureFormat::R8Uint);
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
wgpu::Texture destination =
Create2DTexture(16, 16, 2, 1, wgpu::TextureFormat::Depth24PlusStencil8,
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::OutputAttachment);
// Whole mip is success
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 1, {0, 0, 0},
{8, 8, 1}, wgpu::TextureAspect::StencilOnly);
// Partial mip fails
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 1, {0, 0, 0},
{7, 7, 1}, wgpu::TextureAspect::StencilOnly);
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 1, {0, 0, 0},
{1, 1, 1}, wgpu::TextureAspect::StencilOnly);
}
// Non-zero mip, non-pow-2: A copy fails when using a depth/stencil texture, and the entire
// subresource isn't copied
{
uint64_t bufferSize = BufferSizeForTextureCopy(8, 8, 1, wgpu::TextureFormat::R8Uint);
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
wgpu::Texture destination =
Create2DTexture(17, 17, 2, 1, wgpu::TextureFormat::Depth24PlusStencil8,
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::OutputAttachment);
// Whole mip is success
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 1, {0, 0, 0},
{8, 8, 1}, wgpu::TextureAspect::StencilOnly);
// Partial mip fails
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 1, {0, 0, 0},
{7, 7, 1}, wgpu::TextureAspect::StencilOnly);
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 1, {0, 0, 0},
{1, 1, 1}, wgpu::TextureAspect::StencilOnly);
}
}
// Test that CopyB2T throws an error when requiredBytesInCopy overflows uint64_t
@@ -1240,6 +1300,55 @@ TEST_F(CopyCommandTest_T2B, CopyFromStencilAspect) {
TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 0,
{16, 16, 1}, wgpu::TextureAspect::StencilOnly);
}
// A copy fails when using a depth/stencil texture, and the entire subresource isn't
// copied
{
wgpu::Texture source = Create2DTexture(
16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc);
TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 0,
{15, 15, 1}, wgpu::TextureAspect::StencilOnly);
TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 0,
{1, 1, 1}, wgpu::TextureAspect::StencilOnly);
}
// Non-zero mip: A copy fails when using a depth/stencil texture, and the entire
// subresource isn't copied
{
wgpu::Texture source = Create2DTexture(
16, 16, 2, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc);
// Whole mip is success
TestT2BCopy(utils::Expectation::Success, source, 1, {0, 0, 0}, destination, 0, 256, 0,
{8, 8, 1}, wgpu::TextureAspect::StencilOnly);
// Partial mip fails
TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 0,
{7, 7, 1}, wgpu::TextureAspect::StencilOnly);
TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 0,
{1, 1, 1}, wgpu::TextureAspect::StencilOnly);
}
// Non-zero mip, non-pow-2: A copy fails when using a depth/stencil texture, and the
// entire subresource isn't copied
{
wgpu::Texture source = Create2DTexture(
17, 17, 2, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc);
// Whole mip is success
TestT2BCopy(utils::Expectation::Success, source, 1, {0, 0, 0}, destination, 0, 256, 0,
{8, 8, 1}, wgpu::TextureAspect::StencilOnly);
// Partial mip fails
TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 0,
{7, 7, 1}, wgpu::TextureAspect::StencilOnly);
TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 0,
{1, 1, 1}, wgpu::TextureAspect::StencilOnly);
}
}
// Test that CopyT2B throws an error when requiredBytesInCopy overflows uint64_t
@@ -1400,6 +1509,7 @@ TEST_F(CopyCommandTest_T2T, OutOfBounds) {
TEST_F(CopyCommandTest_T2T, 2DTextureDepthStencil) {
wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8,
wgpu::TextureUsage::CopySrc);
wgpu::Texture destination = Create2DTexture(
16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopyDst);

View File

@@ -499,6 +499,11 @@ namespace {
ASSERT_DEVICE_ERROR(TestWriteTexture(dataSize - 1, 0, bytesPerRow, 0, destination, 0,
{0, 0, 0}, {4, 4, 1},
wgpu::TextureAspect::StencilOnly));
// It is invalid to write just part of the subresource size
ASSERT_DEVICE_ERROR(TestWriteTexture(dataSize, 0, bytesPerRow, 0, destination, 0,
{0, 0, 0}, {3, 3, 1},
wgpu::TextureAspect::StencilOnly));
}
// It is invalid to write into the stencil aspect of depth24plus (no stencil)