diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp index 5f34fea89e..bb16bc428d 100644 --- a/src/dawn_native/CommandEncoder.cpp +++ b/src/dawn_native/CommandEncoder.cpp @@ -89,12 +89,14 @@ namespace dawn_native { switch (src.texture->GetFormat().format) { case wgpu::TextureFormat::Depth24Plus: case wgpu::TextureFormat::Depth24PlusStencil8: + case wgpu::TextureFormat::Depth24UnormStencil8: return DAWN_FORMAT_VALIDATION_ERROR( "The depth aspect of %s format %s cannot be selected in a texture to " "buffer copy.", src.texture, src.texture->GetFormat().format); case wgpu::TextureFormat::Depth32Float: case wgpu::TextureFormat::Depth16Unorm: + case wgpu::TextureFormat::Depth32FloatStencil8: break; default: diff --git a/src/tests/unittests/validation/CopyCommandsValidationTests.cpp b/src/tests/unittests/validation/CopyCommandsValidationTests.cpp index 7954fdc517..0fddddfc76 100644 --- a/src/tests/unittests/validation/CopyCommandsValidationTests.cpp +++ b/src/tests/unittests/validation/CopyCommandsValidationTests.cpp @@ -416,7 +416,14 @@ TEST_F(CopyCommandTest_B2B, CopyWithinSameBuffer) { } } -class CopyCommandTest_B2T : public CopyCommandTest {}; +class CopyCommandTest_B2T : public CopyCommandTest { + protected: + WGPUDevice CreateTestDevice() override { + dawn_native::DeviceDescriptor descriptor; + descriptor.requiredFeatures = {"depth24unorm-stencil8", "depth32float-stencil8"}; + return adapter.CreateDevice(&descriptor); + } +}; // Test a successfull B2T copy TEST_F(CopyCommandTest_B2T, Success) { @@ -704,10 +711,14 @@ TEST_F(CopyCommandTest_B2T, IncorrectBufferOffsetForColorTexture) { // Test B2T copies with incorrect buffer offset usage for depth-stencil texture TEST_F(CopyCommandTest_B2T, IncorrectBufferOffsetForDepthStencilTexture) { - // TODO(dawn:570, dawn:666, dawn:690): List other valid parameters after missing texture formats + // TODO(dawn:570, dawn:666): List other valid parameters after missing texture formats // are implemented, e.g. Stencil8 and depth16unorm. - std::array, 1> params = { + std::array, 3> params = { std::make_tuple(wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureAspect::StencilOnly), + std::make_tuple(wgpu::TextureFormat::Depth24UnormStencil8, + wgpu::TextureAspect::StencilOnly), + std::make_tuple(wgpu::TextureFormat::Depth32FloatStencil8, + wgpu::TextureAspect::StencilOnly), }; uint64_t bufferSize = BufferSizeForTextureCopy(32, 32, 1); @@ -854,61 +865,107 @@ TEST_F(CopyCommandTest_B2T, CopyToMipmapOfNonSquareTexture) { // Test it is invalid to copy to a depth texture TEST_F(CopyCommandTest_B2T, CopyToDepthAspect) { - // Test it is invalid to copy from a buffer into Depth32Float - { - uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::R32Float); - wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc); + uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::Depth32Float); + wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc); - wgpu::Texture destination = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth32Float, - wgpu::TextureUsage::CopyDst); - - TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 16, destination, 0, {0, 0, 0}, - {16, 16, 1}, wgpu::TextureAspect::All); + for (wgpu::TextureFormat format : utils::kDepthFormats) { + wgpu::Texture destination = + Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopyDst); + // Test it is invalid to copy from a buffer into a depth texture TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 16, destination, 0, {0, 0, 0}, {16, 16, 1}, wgpu::TextureAspect::DepthOnly); - } - // Test it is invalid to copy from a buffer into Depth24Plus - { - uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::R32Float); - wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc); - - wgpu::Texture destination = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth24Plus, - wgpu::TextureUsage::CopyDst); - - TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, {0, 0, 0}, - {16, 16, 1}, wgpu::TextureAspect::All); - - TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, {0, 0, 0}, - {16, 16, 1}, wgpu::TextureAspect::DepthOnly); + if (utils::IsDepthOnlyFormat(format)) { + // Test "all" of a depth texture which is only the depth aspect. + TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 16, destination, 0, {0, 0, 0}, + {16, 16, 1}, wgpu::TextureAspect::All); + } } } // Test copy to only the stencil aspect of a texture TEST_F(CopyCommandTest_B2T, CopyToStencilAspect) { - // Test it is valid to copy from a buffer into the stencil aspect of Depth24PlusStencil8 - { - uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::R8Uint); - wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc); + 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); + for (wgpu::TextureFormat format : utils::kStencilFormats) { + // Test it is valid to copy from a buffer into the stencil aspect of a depth/stencil texture + { + wgpu::Texture destination = + Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopyDst); - TestB2TCopy(utils::Expectation::Success, source, 0, 256, 16, destination, 0, {0, 0, 0}, - {16, 16, 1}, wgpu::TextureAspect::StencilOnly); + // TODO(dawn:666): Test "all" of Stencil8 format when it's implemented. - // And that it fails if the buffer is one byte too small - wgpu::Buffer sourceSmall = CreateBuffer(bufferSize - 1, wgpu::BufferUsage::CopySrc); - TestB2TCopy(utils::Expectation::Failure, sourceSmall, 0, 256, 16, destination, 0, {0, 0, 0}, - {16, 16, 1}, wgpu::TextureAspect::StencilOnly); + TestB2TCopy(utils::Expectation::Success, source, 0, 256, 16, destination, 0, {0, 0, 0}, + {16, 16, 1}, wgpu::TextureAspect::StencilOnly); + + // And that it fails if the buffer is one byte too small + wgpu::Buffer sourceSmall = CreateBuffer(bufferSize - 1, wgpu::BufferUsage::CopySrc); + TestB2TCopy(utils::Expectation::Failure, sourceSmall, 0, 256, 16, 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 + { + wgpu::Texture destination = + Create2DTexture(16, 16, 1, 1, format, + wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment); + + TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 15, destination, 0, {0, 0, 0}, + {15, 15, 1}, wgpu::TextureAspect::StencilOnly); + + TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 1, 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, format, + wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment); + + // Whole mip is success + TestB2TCopy(utils::Expectation::Success, source, 0, 256, 8, destination, 1, {0, 0, 0}, + {8, 8, 1}, wgpu::TextureAspect::StencilOnly); + + // Partial mip fails + TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 7, destination, 1, {0, 0, 0}, + {7, 7, 1}, wgpu::TextureAspect::StencilOnly); + + TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 1, 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, format, + wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment); + + // Whole mip is success + TestB2TCopy(utils::Expectation::Success, source, 0, 256, 8, destination, 1, {0, 0, 0}, + {8, 8, 1}, wgpu::TextureAspect::StencilOnly); + + // Partial mip fails + TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 7, destination, 1, {0, 0, 0}, + {7, 7, 1}, wgpu::TextureAspect::StencilOnly); + + TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 1, destination, 1, {0, 0, 0}, + {1, 1, 1}, wgpu::TextureAspect::StencilOnly); + } } // Test it is invalid to copy from a buffer into the stencil aspect of Depth24Plus (no stencil) { - 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::Depth24Plus, wgpu::TextureUsage::CopyDst); @@ -918,75 +975,12 @@ TEST_F(CopyCommandTest_B2T, CopyToStencilAspect) { // Test it is invalid to copy from a buffer into the stencil aspect of a color texture { - 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::RGBA8Uint, wgpu::TextureUsage::CopyDst); TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 16, 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::RenderAttachment); - - TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 15, destination, 0, {0, 0, 0}, - {15, 15, 1}, wgpu::TextureAspect::StencilOnly); - - TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 1, 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::RenderAttachment); - - // Whole mip is success - TestB2TCopy(utils::Expectation::Success, source, 0, 256, 8, destination, 1, {0, 0, 0}, - {8, 8, 1}, wgpu::TextureAspect::StencilOnly); - - // Partial mip fails - TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 7, destination, 1, {0, 0, 0}, - {7, 7, 1}, wgpu::TextureAspect::StencilOnly); - - TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 1, 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::RenderAttachment); - - // Whole mip is success - TestB2TCopy(utils::Expectation::Success, source, 0, 256, 8, destination, 1, {0, 0, 0}, - {8, 8, 1}, wgpu::TextureAspect::StencilOnly); - - // Partial mip fails - TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 7, destination, 1, {0, 0, 0}, - {7, 7, 1}, wgpu::TextureAspect::StencilOnly); - - TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 1, destination, 1, {0, 0, 0}, - {1, 1, 1}, wgpu::TextureAspect::StencilOnly); - } } // Test that CopyB2T throws an error when requiredBytesInCopy overflows uint64_t @@ -1003,7 +997,14 @@ TEST_F(CopyCommandTest_B2T, RequiredBytesInCopyOverflow) { {0, 0, 0}, {1, 1, 16}); } -class CopyCommandTest_T2B : public CopyCommandTest {}; +class CopyCommandTest_T2B : public CopyCommandTest { + protected: + WGPUDevice CreateTestDevice() override { + dawn_native::DeviceDescriptor descriptor; + descriptor.requiredFeatures = {"depth24unorm-stencil8", "depth32float-stencil8"}; + return adapter.CreateDevice(&descriptor); + } +}; // Test a successfull T2B copy TEST_F(CopyCommandTest_T2B, Success) { @@ -1317,12 +1318,17 @@ TEST_F(CopyCommandTest_T2B, IncorrectBufferOffsetForColorTexture) { // Test T2B copies with incorrect buffer offset usage for depth-stencil texture TEST_F(CopyCommandTest_T2B, IncorrectBufferOffsetForDepthStencilTexture) { - // TODO(dawn:570, dawn:666, dawn:690): List other valid parameters after missing texture formats + // TODO(dawn:570, dawn:666): List other valid parameters after missing texture formats // are implemented, e.g. Stencil8 and depth16unorm. - std::array, 3> params = { + std::array, 6> params = { std::make_tuple(wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureAspect::StencilOnly), std::make_tuple(wgpu::TextureFormat::Depth32Float, wgpu::TextureAspect::DepthOnly), std::make_tuple(wgpu::TextureFormat::Depth32Float, wgpu::TextureAspect::All), + std::make_tuple(wgpu::TextureFormat::Depth24UnormStencil8, + wgpu::TextureAspect::StencilOnly), + std::make_tuple(wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureAspect::DepthOnly), + std::make_tuple(wgpu::TextureFormat::Depth32FloatStencil8, + wgpu::TextureAspect::StencilOnly), }; uint64_t bufferSize = BufferSizeForTextureCopy(32, 32, 1); @@ -1472,36 +1478,43 @@ TEST_F(CopyCommandTest_T2B, CopyFromMipmapOfNonSquareTexture) { // Test copy from only the depth aspect of a texture TEST_F(CopyCommandTest_T2B, CopyFromDepthAspect) { - uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::R32Float); + uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::Depth32Float); wgpu::Buffer destination = CreateBuffer(bufferSize, wgpu::BufferUsage::CopyDst); - { - wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth32Float, - wgpu::TextureUsage::CopySrc); - // Test "all" of a depth texture which is only the depth aspect. - TestT2BCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, 256, 16, - {16, 16, 1}, wgpu::TextureAspect::All); + constexpr std::array kAllowDepthCopyFormats = { + wgpu::TextureFormat::Depth16Unorm, wgpu::TextureFormat::Depth32Float, + wgpu::TextureFormat::Depth32FloatStencil8}; + for (wgpu::TextureFormat format : kAllowDepthCopyFormats) { + { + wgpu::Texture source = + Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopySrc); - // Test it is valid to copy the depth aspect of a depth texture - TestT2BCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, 256, 16, - {16, 16, 1}, wgpu::TextureAspect::DepthOnly); + // Test it is valid to copy the depth aspect of these depth/stencil texture + TestT2BCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, 256, 16, + {16, 16, 1}, wgpu::TextureAspect::DepthOnly); + + if (utils::IsDepthOnlyFormat(format)) { + // Test "all" of a depth texture which is only the depth aspect. + TestT2BCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, 256, + 16, {16, 16, 1}, wgpu::TextureAspect::All); + } + } } - { - wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth24Plus, - wgpu::TextureUsage::CopySrc); - // Test it is invalid to copy from the depth aspect of depth24plus - TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 16, - {16, 16, 1}, wgpu::TextureAspect::DepthOnly); - } - { - wgpu::Texture source = Create2DTexture( - 16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); + constexpr std::array kDisallowDepthCopyFormats = { + wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Depth24PlusStencil8, + wgpu::TextureFormat::Depth24UnormStencil8}; + for (wgpu::TextureFormat format : kDisallowDepthCopyFormats) { + { + wgpu::Texture source = + Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopySrc); - // Test it is invalid to copy from the depth aspect of depth24plus-stencil8 - TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 16, - {16, 16, 1}, wgpu::TextureAspect::DepthOnly); + // Test it is invalid to copy from the depth aspect of these depth/stencil texture + TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 16, + {16, 16, 1}, wgpu::TextureAspect::DepthOnly); + } } + { wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::R32Float, wgpu::TextureUsage::CopySrc); @@ -1516,19 +1529,75 @@ TEST_F(CopyCommandTest_T2B, CopyFromDepthAspect) { TEST_F(CopyCommandTest_T2B, CopyFromStencilAspect) { uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::R8Uint); wgpu::Buffer destination = CreateBuffer(bufferSize, wgpu::BufferUsage::CopyDst); - { - wgpu::Texture source = Create2DTexture( - 16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); - // Test it is valid to copy from the stencil aspect of a depth24plus-stencil8 texture - TestT2BCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, 256, 16, - {16, 16, 1}, wgpu::TextureAspect::StencilOnly); + for (wgpu::TextureFormat format : utils::kStencilFormats) { + { + wgpu::Texture source = + Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopySrc); - // Test it is invalid if the buffer is too small - wgpu::Buffer destinationSmall = CreateBuffer(bufferSize - 1, wgpu::BufferUsage::CopyDst); - TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destinationSmall, 0, 256, 16, - {16, 16, 1}, wgpu::TextureAspect::StencilOnly); + // TODO(dawn:666): Test "all" of Stencil8 format when it's implemented + + // Test it is valid to copy from the stencil aspect of a depth/stencil texture + TestT2BCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, 256, 16, + {16, 16, 1}, wgpu::TextureAspect::StencilOnly); + + // Test it is invalid if the buffer is too small + wgpu::Buffer destinationSmall = + CreateBuffer(bufferSize - 1, wgpu::BufferUsage::CopyDst); + TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destinationSmall, 0, 256, + 16, {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, format, wgpu::TextureUsage::CopySrc); + + TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 15, + {15, 15, 1}, wgpu::TextureAspect::StencilOnly); + + TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 1, + {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, format, wgpu::TextureUsage::CopySrc); + + // Whole mip is success + TestT2BCopy(utils::Expectation::Success, source, 1, {0, 0, 0}, destination, 0, 256, 8, + {8, 8, 1}, wgpu::TextureAspect::StencilOnly); + + // Partial mip fails + TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 7, + {7, 7, 1}, wgpu::TextureAspect::StencilOnly); + + TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 1, + {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, format, wgpu::TextureUsage::CopySrc); + + // Whole mip is success + TestT2BCopy(utils::Expectation::Success, source, 1, {0, 0, 0}, destination, 0, 256, 8, + {8, 8, 1}, wgpu::TextureAspect::StencilOnly); + + // Partial mip fails + TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 7, + {7, 7, 1}, wgpu::TextureAspect::StencilOnly); + + TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 1, + {1, 1, 1}, wgpu::TextureAspect::StencilOnly); + } } + { wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::R8Uint, wgpu::TextureUsage::CopySrc); @@ -1545,55 +1614,6 @@ TEST_F(CopyCommandTest_T2B, CopyFromStencilAspect) { TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 16, {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, 15, - {15, 15, 1}, wgpu::TextureAspect::StencilOnly); - - TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 1, - {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, 8, - {8, 8, 1}, wgpu::TextureAspect::StencilOnly); - - // Partial mip fails - TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 7, - {7, 7, 1}, wgpu::TextureAspect::StencilOnly); - - TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 1, - {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, 8, - {8, 8, 1}, wgpu::TextureAspect::StencilOnly); - - // Partial mip fails - TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 7, - {7, 7, 1}, wgpu::TextureAspect::StencilOnly); - - TestT2BCopy(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0, 256, 1, - {1, 1, 1}, wgpu::TextureAspect::StencilOnly); - } } // Test that CopyT2B throws an error when requiredBytesInCopy overflows uint64_t @@ -1610,7 +1630,14 @@ TEST_F(CopyCommandTest_T2B, RequiredBytesInCopyOverflow) { (1 << 31), {1, 1, 16}); } -class CopyCommandTest_T2T : public CopyCommandTest {}; +class CopyCommandTest_T2T : public CopyCommandTest { + protected: + WGPUDevice CreateTestDevice() override { + dawn_native::DeviceDescriptor descriptor; + descriptor.requiredFeatures = {"depth24unorm-stencil8", "depth32float-stencil8"}; + return adapter.CreateDevice(&descriptor); + } +}; TEST_F(CopyCommandTest_T2T, Success) { wgpu::Texture source = @@ -1752,27 +1779,28 @@ TEST_F(CopyCommandTest_T2T, OutOfBounds) { } TEST_F(CopyCommandTest_T2T, 2DTextureDepthStencil) { - wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, - wgpu::TextureUsage::CopySrc); + for (wgpu::TextureFormat format : utils::kDepthAndStencilFormats) { + wgpu::Texture source = Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopySrc); - wgpu::Texture destination = Create2DTexture( - 16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopyDst); + wgpu::Texture destination = + Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopyDst); - // Success when entire depth stencil subresource is copied - TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0}, - {16, 16, 1}); + // Success when entire depth stencil subresource is copied + TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0}, + {16, 16, 1}); - // Failure when depth stencil subresource is partially copied - TestT2TCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0}, - {15, 15, 1}); + // Failure when depth stencil subresource is partially copied + TestT2TCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0}, + {15, 15, 1}); - // Failure when selecting the depth aspect (not all) - TestT2TCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0}, - {16, 16, 1}, wgpu::TextureAspect::DepthOnly); + // Failure when selecting the depth aspect (not all) + TestT2TCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0}, + {16, 16, 1}, wgpu::TextureAspect::DepthOnly); - // Failure when selecting the stencil aspect (not all) - TestT2TCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0}, - {16, 16, 1}, wgpu::TextureAspect::StencilOnly); + // Failure when selecting the stencil aspect (not all) + TestT2TCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0}, + {16, 16, 1}, wgpu::TextureAspect::StencilOnly); + } } TEST_F(CopyCommandTest_T2T, 2DTextureDepthOnly) { @@ -1804,41 +1832,43 @@ TEST_F(CopyCommandTest_T2T, 2DTextureDepthOnly) { } TEST_F(CopyCommandTest_T2T, 2DTextureArrayDepthStencil) { - { - wgpu::Texture source = Create2DTexture( - 16, 16, 1, 3, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); - wgpu::Texture destination = Create2DTexture( - 16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopyDst); + for (wgpu::TextureFormat format : utils::kDepthAndStencilFormats) { + { + wgpu::Texture source = + Create2DTexture(16, 16, 1, 3, format, wgpu::TextureUsage::CopySrc); + wgpu::Texture destination = + Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopyDst); - // Success when entire depth stencil subresource (layer) is the copy source - TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 1}, destination, 0, {0, 0, 0}, - {16, 16, 1}); - } + // Success when entire depth stencil subresource (layer) is the copy source + TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 1}, destination, 0, + {0, 0, 0}, {16, 16, 1}); + } - { - wgpu::Texture source = Create2DTexture( - 16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); - wgpu::Texture destination = Create2DTexture( - 16, 16, 1, 3, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopyDst); + { + wgpu::Texture source = + Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopySrc); + wgpu::Texture destination = + Create2DTexture(16, 16, 1, 3, format, wgpu::TextureUsage::CopyDst); - // Success when entire depth stencil subresource (layer) is the copy destination - TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, {0, 0, 1}, - {16, 16, 1}); - } + // Success when entire depth stencil subresource (layer) is the copy destination + TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, + {0, 0, 1}, {16, 16, 1}); + } - { - wgpu::Texture source = Create2DTexture( - 16, 16, 1, 3, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); - wgpu::Texture destination = Create2DTexture( - 16, 16, 1, 3, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopyDst); + { + wgpu::Texture source = + Create2DTexture(16, 16, 1, 3, format, wgpu::TextureUsage::CopySrc); + wgpu::Texture destination = + Create2DTexture(16, 16, 1, 3, format, wgpu::TextureUsage::CopyDst); - // Success when src and dst are an entire depth stencil subresource (layer) - TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 2}, destination, 0, {0, 0, 1}, - {16, 16, 1}); + // Success when src and dst are an entire depth stencil subresource (layer) + TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 2}, destination, 0, + {0, 0, 1}, {16, 16, 1}); - // Success when src and dst are an array of entire depth stencil subresources - TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 1}, destination, 0, {0, 0, 0}, - {16, 16, 2}); + // Success when src and dst are an array of entire depth stencil subresources + TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 1}, destination, 0, + {0, 0, 0}, {16, 16, 2}); + } } } diff --git a/src/utils/TextureUtils.cpp b/src/utils/TextureUtils.cpp index a56815a0ff..9f5277a9f0 100644 --- a/src/utils/TextureUtils.cpp +++ b/src/utils/TextureUtils.cpp @@ -119,6 +119,17 @@ namespace utils { } } + bool IsDepthOnlyFormat(wgpu::TextureFormat textureFormat) { + switch (textureFormat) { + case wgpu::TextureFormat::Depth16Unorm: + case wgpu::TextureFormat::Depth24Plus: + case wgpu::TextureFormat::Depth32Float: + return true; + default: + return false; + } + } + uint32_t GetTexelBlockSizeInBytes(wgpu::TextureFormat textureFormat) { switch (textureFormat) { case wgpu::TextureFormat::R8Unorm: @@ -134,7 +145,6 @@ namespace utils { case wgpu::TextureFormat::RG8Snorm: case wgpu::TextureFormat::RG8Uint: case wgpu::TextureFormat::RG8Sint: - case wgpu::TextureFormat::Depth16Unorm: return 2u; case wgpu::TextureFormat::R32Float: @@ -153,7 +163,6 @@ namespace utils { case wgpu::TextureFormat::RGB10A2Unorm: case wgpu::TextureFormat::RG11B10Ufloat: case wgpu::TextureFormat::RGB9E5Ufloat: - case wgpu::TextureFormat::Depth32Float: return 4u; case wgpu::TextureFormat::RG32Float: @@ -169,6 +178,14 @@ namespace utils { case wgpu::TextureFormat::RGBA32Sint: return 16u; + case wgpu::TextureFormat::Depth16Unorm: + return 2u; + + case wgpu::TextureFormat::Depth24Plus: + case wgpu::TextureFormat::Depth24UnormStencil8: + case wgpu::TextureFormat::Depth32Float: + return 4u; + case wgpu::TextureFormat::BC1RGBAUnorm: case wgpu::TextureFormat::BC1RGBAUnormSrgb: case wgpu::TextureFormat::BC4RUnorm: @@ -231,9 +248,7 @@ namespace utils { case wgpu::TextureFormat::ASTC12x12UnormSrgb: return 16u; - case wgpu::TextureFormat::Depth24Plus: case wgpu::TextureFormat::Depth24PlusStencil8: - case wgpu::TextureFormat::Depth24UnormStencil8: case wgpu::TextureFormat::Depth32FloatStencil8: // Block size of a multi-planar format depends on aspect. diff --git a/src/utils/TextureUtils.h b/src/utils/TextureUtils.h index be271ccd82..fac5552c58 100644 --- a/src/utils/TextureUtils.h +++ b/src/utils/TextureUtils.h @@ -206,6 +206,8 @@ namespace utils { bool IsETC2TextureFormat(wgpu::TextureFormat textureFormat); bool IsASTCTextureFormat(wgpu::TextureFormat textureFormat); + bool IsDepthOnlyFormat(wgpu::TextureFormat textureFormat); + uint32_t GetTexelBlockSizeInBytes(wgpu::TextureFormat textureFormat); uint32_t GetTextureFormatBlockWidth(wgpu::TextureFormat textureFormat); uint32_t GetTextureFormatBlockHeight(wgpu::TextureFormat textureFormat);