Validate depth/stencil texture formats in image copies

- Update block size of depth/stencil formats in TextureUtils.h
- Allow to copy depth aspect for Depth32FloatStencil8 and disallow it
for Depth24UnormStencil8 in copyTextureToBuffer()
- Add Depth24UnormStencil8, Depth32FloatStencil8 and other depth/stencil
  formats in CopyCommandsValidationTests.

Bug=dawn:690

Change-Id: I3f645b838b8a8cdafe0880bbd1e4e8d17d994510
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/71400
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Hao Li <hao.x.li@intel.com>
This commit is contained in:
Li Hao 2021-12-02 02:06:40 +00:00 committed by Dawn LUCI CQ
parent b17ecc3835
commit c871df0b19
4 changed files with 288 additions and 239 deletions

View File

@ -89,12 +89,14 @@ namespace dawn_native {
switch (src.texture->GetFormat().format) { switch (src.texture->GetFormat().format) {
case wgpu::TextureFormat::Depth24Plus: case wgpu::TextureFormat::Depth24Plus:
case wgpu::TextureFormat::Depth24PlusStencil8: case wgpu::TextureFormat::Depth24PlusStencil8:
case wgpu::TextureFormat::Depth24UnormStencil8:
return DAWN_FORMAT_VALIDATION_ERROR( return DAWN_FORMAT_VALIDATION_ERROR(
"The depth aspect of %s format %s cannot be selected in a texture to " "The depth aspect of %s format %s cannot be selected in a texture to "
"buffer copy.", "buffer copy.",
src.texture, src.texture->GetFormat().format); src.texture, src.texture->GetFormat().format);
case wgpu::TextureFormat::Depth32Float: case wgpu::TextureFormat::Depth32Float:
case wgpu::TextureFormat::Depth16Unorm: case wgpu::TextureFormat::Depth16Unorm:
case wgpu::TextureFormat::Depth32FloatStencil8:
break; break;
default: default:

View File

@ -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 a successfull B2T copy
TEST_F(CopyCommandTest_B2T, Success) { 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 B2T copies with incorrect buffer offset usage for depth-stencil texture
TEST_F(CopyCommandTest_B2T, IncorrectBufferOffsetForDepthStencilTexture) { 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. // are implemented, e.g. Stencil8 and depth16unorm.
std::array<std::tuple<wgpu::TextureFormat, wgpu::TextureAspect>, 1> params = { std::array<std::tuple<wgpu::TextureFormat, wgpu::TextureAspect>, 3> params = {
std::make_tuple(wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureAspect::StencilOnly), 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); uint64_t bufferSize = BufferSizeForTextureCopy(32, 32, 1);
@ -854,87 +865,51 @@ TEST_F(CopyCommandTest_B2T, CopyToMipmapOfNonSquareTexture) {
// Test it is invalid to copy to a depth texture // Test it is invalid to copy to a depth texture
TEST_F(CopyCommandTest_B2T, CopyToDepthAspect) { 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::Depth32Float);
{
uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::R32Float);
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc); wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
wgpu::Texture destination = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth32Float, for (wgpu::TextureFormat format : utils::kDepthFormats) {
wgpu::TextureUsage::CopyDst); wgpu::Texture destination =
Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopyDst);
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 16, destination, 0, {0, 0, 0},
{16, 16, 1}, wgpu::TextureAspect::All);
// 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}, TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 16, destination, 0, {0, 0, 0},
{16, 16, 1}, wgpu::TextureAspect::DepthOnly); {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 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);
} }
} }
// Test copy to only the stencil aspect of a texture // Test copy to only the stencil aspect of a texture
TEST_F(CopyCommandTest_B2T, CopyToStencilAspect) { 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); uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::R8Uint);
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc); wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
wgpu::Texture destination = Create2DTexture( for (wgpu::TextureFormat format : utils::kStencilFormats) {
16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopyDst); // 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);
// TODO(dawn:666): Test "all" of Stencil8 format when it's implemented.
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 16, destination, 0, {0, 0, 0}, TestB2TCopy(utils::Expectation::Success, source, 0, 256, 16, destination, 0, {0, 0, 0},
{16, 16, 1}, wgpu::TextureAspect::StencilOnly); {16, 16, 1}, wgpu::TextureAspect::StencilOnly);
// And that it fails if the buffer is one byte too small // And that it fails if the buffer is one byte too small
wgpu::Buffer sourceSmall = CreateBuffer(bufferSize - 1, wgpu::BufferUsage::CopySrc); wgpu::Buffer sourceSmall = CreateBuffer(bufferSize - 1, wgpu::BufferUsage::CopySrc);
TestB2TCopy(utils::Expectation::Failure, sourceSmall, 0, 256, 16, destination, 0, {0, 0, 0}, TestB2TCopy(utils::Expectation::Failure, sourceSmall, 0, 256, 16, destination, 0,
{16, 16, 1}, wgpu::TextureAspect::StencilOnly); {0, 0, 0}, {16, 16, 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);
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 16, destination, 0, {0, 0, 0},
{16, 16, 1}, wgpu::TextureAspect::StencilOnly);
}
// 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 // 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 = wgpu::Texture destination =
Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, Create2DTexture(16, 16, 1, 1, format,
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment); wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 15, destination, 0, {0, 0, 0}, TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 15, destination, 0, {0, 0, 0},
@ -951,7 +926,7 @@ TEST_F(CopyCommandTest_B2T, CopyToStencilAspect) {
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc); wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
wgpu::Texture destination = wgpu::Texture destination =
Create2DTexture(16, 16, 2, 1, wgpu::TextureFormat::Depth24PlusStencil8, Create2DTexture(16, 16, 2, 1, format,
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment); wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);
// Whole mip is success // Whole mip is success
@ -973,7 +948,7 @@ TEST_F(CopyCommandTest_B2T, CopyToStencilAspect) {
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc); wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
wgpu::Texture destination = wgpu::Texture destination =
Create2DTexture(17, 17, 2, 1, wgpu::TextureFormat::Depth24PlusStencil8, Create2DTexture(17, 17, 2, 1, format,
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment); wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);
// Whole mip is success // Whole mip is success
@ -989,6 +964,25 @@ TEST_F(CopyCommandTest_B2T, CopyToStencilAspect) {
} }
} }
// Test it is invalid to copy from a buffer into the stencil aspect of Depth24Plus (no stencil)
{
wgpu::Texture destination = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth24Plus,
wgpu::TextureUsage::CopyDst);
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 16, destination, 0, {0, 0, 0},
{16, 16, 1}, wgpu::TextureAspect::StencilOnly);
}
// Test it is invalid to copy from a buffer into the stencil aspect of a color texture
{
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);
}
}
// Test that CopyB2T throws an error when requiredBytesInCopy overflows uint64_t // Test that CopyB2T throws an error when requiredBytesInCopy overflows uint64_t
TEST_F(CopyCommandTest_B2T, RequiredBytesInCopyOverflow) { TEST_F(CopyCommandTest_B2T, RequiredBytesInCopyOverflow) {
wgpu::Buffer source = CreateBuffer(10000, wgpu::BufferUsage::CopySrc); wgpu::Buffer source = CreateBuffer(10000, wgpu::BufferUsage::CopySrc);
@ -1003,7 +997,14 @@ TEST_F(CopyCommandTest_B2T, RequiredBytesInCopyOverflow) {
{0, 0, 0}, {1, 1, 16}); {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 a successfull T2B copy
TEST_F(CopyCommandTest_T2B, Success) { 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 T2B copies with incorrect buffer offset usage for depth-stencil texture
TEST_F(CopyCommandTest_T2B, IncorrectBufferOffsetForDepthStencilTexture) { 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. // are implemented, e.g. Stencil8 and depth16unorm.
std::array<std::tuple<wgpu::TextureFormat, wgpu::TextureAspect>, 3> params = { std::array<std::tuple<wgpu::TextureFormat, wgpu::TextureAspect>, 6> params = {
std::make_tuple(wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureAspect::StencilOnly), 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::DepthOnly),
std::make_tuple(wgpu::TextureFormat::Depth32Float, wgpu::TextureAspect::All), 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); 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 copy from only the depth aspect of a texture
TEST_F(CopyCommandTest_T2B, CopyFromDepthAspect) { 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::Buffer destination = CreateBuffer(bufferSize, wgpu::BufferUsage::CopyDst);
{
wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth32Float,
wgpu::TextureUsage::CopySrc);
constexpr std::array<wgpu::TextureFormat, 3> 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 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. // 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, TestT2BCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, 256,
{16, 16, 1}, wgpu::TextureAspect::All); 16, {16, 16, 1}, wgpu::TextureAspect::All);
}
// 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);
} }
{
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 constexpr std::array<wgpu::TextureFormat, 3> 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 these depth/stencil texture
TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 16, TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 16,
{16, 16, 1}, wgpu::TextureAspect::DepthOnly); {16, 16, 1}, wgpu::TextureAspect::DepthOnly);
} }
{
wgpu::Texture source = Create2DTexture(
16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, 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);
} }
{ {
wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::R32Float, wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::R32Float,
wgpu::TextureUsage::CopySrc); wgpu::TextureUsage::CopySrc);
@ -1516,41 +1529,30 @@ TEST_F(CopyCommandTest_T2B, CopyFromDepthAspect) {
TEST_F(CopyCommandTest_T2B, CopyFromStencilAspect) { TEST_F(CopyCommandTest_T2B, CopyFromStencilAspect) {
uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::R8Uint); uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::R8Uint);
wgpu::Buffer destination = CreateBuffer(bufferSize, wgpu::BufferUsage::CopyDst); 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 for (wgpu::TextureFormat format : utils::kStencilFormats) {
{
wgpu::Texture source =
Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopySrc);
// 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, TestT2BCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, 256, 16,
{16, 16, 1}, wgpu::TextureAspect::StencilOnly); {16, 16, 1}, wgpu::TextureAspect::StencilOnly);
// Test it is invalid if the buffer is too small // Test it is invalid if the buffer is too small
wgpu::Buffer destinationSmall = CreateBuffer(bufferSize - 1, wgpu::BufferUsage::CopyDst); wgpu::Buffer destinationSmall =
TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destinationSmall, 0, 256, 16, CreateBuffer(bufferSize - 1, wgpu::BufferUsage::CopyDst);
{16, 16, 1}, wgpu::TextureAspect::StencilOnly); TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destinationSmall, 0, 256,
} 16, {16, 16, 1}, wgpu::TextureAspect::StencilOnly);
{
wgpu::Texture source =
Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::R8Uint, wgpu::TextureUsage::CopySrc);
// Test it is invalid to copy from the stencil aspect of a color texture
TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 16,
{16, 16, 1}, wgpu::TextureAspect::StencilOnly);
}
{
wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth24Plus,
wgpu::TextureUsage::CopySrc);
// Test it is invalid to copy from the stencil aspect of a depth-only texture
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 // A copy fails when using a depth/stencil texture, and the entire subresource isn't
// copied // copied
{ {
wgpu::Texture source = Create2DTexture( wgpu::Texture source =
16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopySrc);
TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 15, TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 15,
{15, 15, 1}, wgpu::TextureAspect::StencilOnly); {15, 15, 1}, wgpu::TextureAspect::StencilOnly);
@ -1562,8 +1564,8 @@ TEST_F(CopyCommandTest_T2B, CopyFromStencilAspect) {
// Non-zero mip: A copy fails when using a depth/stencil texture, and the entire // Non-zero mip: A copy fails when using a depth/stencil texture, and the entire
// subresource isn't copied // subresource isn't copied
{ {
wgpu::Texture source = Create2DTexture( wgpu::Texture source =
16, 16, 2, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); Create2DTexture(16, 16, 2, 1, format, wgpu::TextureUsage::CopySrc);
// Whole mip is success // Whole mip is success
TestT2BCopy(utils::Expectation::Success, source, 1, {0, 0, 0}, destination, 0, 256, 8, TestT2BCopy(utils::Expectation::Success, source, 1, {0, 0, 0}, destination, 0, 256, 8,
@ -1580,8 +1582,8 @@ TEST_F(CopyCommandTest_T2B, CopyFromStencilAspect) {
// Non-zero mip, non-pow-2: A copy fails when using a depth/stencil texture, and the // Non-zero mip, non-pow-2: A copy fails when using a depth/stencil texture, and the
// entire subresource isn't copied // entire subresource isn't copied
{ {
wgpu::Texture source = Create2DTexture( wgpu::Texture source =
17, 17, 2, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); Create2DTexture(17, 17, 2, 1, format, wgpu::TextureUsage::CopySrc);
// Whole mip is success // Whole mip is success
TestT2BCopy(utils::Expectation::Success, source, 1, {0, 0, 0}, destination, 0, 256, 8, TestT2BCopy(utils::Expectation::Success, source, 1, {0, 0, 0}, destination, 0, 256, 8,
@ -1596,6 +1598,24 @@ TEST_F(CopyCommandTest_T2B, CopyFromStencilAspect) {
} }
} }
{
wgpu::Texture source =
Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::R8Uint, wgpu::TextureUsage::CopySrc);
// Test it is invalid to copy from the stencil aspect of a color texture
TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 16,
{16, 16, 1}, wgpu::TextureAspect::StencilOnly);
}
{
wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth24Plus,
wgpu::TextureUsage::CopySrc);
// Test it is invalid to copy from the stencil aspect of a depth-only texture
TestT2BCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, 256, 16,
{16, 16, 1}, wgpu::TextureAspect::StencilOnly);
}
}
// Test that CopyT2B throws an error when requiredBytesInCopy overflows uint64_t // Test that CopyT2B throws an error when requiredBytesInCopy overflows uint64_t
TEST_F(CopyCommandTest_T2B, RequiredBytesInCopyOverflow) { TEST_F(CopyCommandTest_T2B, RequiredBytesInCopyOverflow) {
wgpu::Buffer destination = CreateBuffer(10000, wgpu::BufferUsage::CopyDst); wgpu::Buffer destination = CreateBuffer(10000, wgpu::BufferUsage::CopyDst);
@ -1610,7 +1630,14 @@ TEST_F(CopyCommandTest_T2B, RequiredBytesInCopyOverflow) {
(1 << 31), {1, 1, 16}); (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) { TEST_F(CopyCommandTest_T2T, Success) {
wgpu::Texture source = wgpu::Texture source =
@ -1752,11 +1779,11 @@ TEST_F(CopyCommandTest_T2T, OutOfBounds) {
} }
TEST_F(CopyCommandTest_T2T, 2DTextureDepthStencil) { TEST_F(CopyCommandTest_T2T, 2DTextureDepthStencil) {
wgpu::Texture source = Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, for (wgpu::TextureFormat format : utils::kDepthAndStencilFormats) {
wgpu::TextureUsage::CopySrc); wgpu::Texture source = Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopySrc);
wgpu::Texture destination = Create2DTexture( wgpu::Texture destination =
16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopyDst); Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopyDst);
// Success when entire depth stencil subresource is copied // Success when entire depth stencil subresource is copied
TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0}, TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0},
@ -1774,6 +1801,7 @@ TEST_F(CopyCommandTest_T2T, 2DTextureDepthStencil) {
TestT2TCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0}, TestT2TCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0},
{16, 16, 1}, wgpu::TextureAspect::StencilOnly); {16, 16, 1}, wgpu::TextureAspect::StencilOnly);
} }
}
TEST_F(CopyCommandTest_T2T, 2DTextureDepthOnly) { TEST_F(CopyCommandTest_T2T, 2DTextureDepthOnly) {
constexpr std::array<wgpu::TextureFormat, 2> kDepthOnlyFormats = { constexpr std::array<wgpu::TextureFormat, 2> kDepthOnlyFormats = {
@ -1804,41 +1832,43 @@ TEST_F(CopyCommandTest_T2T, 2DTextureDepthOnly) {
} }
TEST_F(CopyCommandTest_T2T, 2DTextureArrayDepthStencil) { TEST_F(CopyCommandTest_T2T, 2DTextureArrayDepthStencil) {
for (wgpu::TextureFormat format : utils::kDepthAndStencilFormats) {
{ {
wgpu::Texture source = Create2DTexture( wgpu::Texture source =
16, 16, 1, 3, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); Create2DTexture(16, 16, 1, 3, format, wgpu::TextureUsage::CopySrc);
wgpu::Texture destination = Create2DTexture( wgpu::Texture destination =
16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopyDst); Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopyDst);
// Success when entire depth stencil subresource (layer) is the copy source // 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}, TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 1}, destination, 0,
{16, 16, 1}); {0, 0, 0}, {16, 16, 1});
} }
{ {
wgpu::Texture source = Create2DTexture( wgpu::Texture source =
16, 16, 1, 1, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopySrc);
wgpu::Texture destination = Create2DTexture( wgpu::Texture destination =
16, 16, 1, 3, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopyDst); Create2DTexture(16, 16, 1, 3, format, wgpu::TextureUsage::CopyDst);
// Success when entire depth stencil subresource (layer) is the copy destination // 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}, TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
{16, 16, 1}); {0, 0, 1}, {16, 16, 1});
} }
{ {
wgpu::Texture source = Create2DTexture( wgpu::Texture source =
16, 16, 1, 3, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopySrc); Create2DTexture(16, 16, 1, 3, format, wgpu::TextureUsage::CopySrc);
wgpu::Texture destination = Create2DTexture( wgpu::Texture destination =
16, 16, 1, 3, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureUsage::CopyDst); Create2DTexture(16, 16, 1, 3, format, wgpu::TextureUsage::CopyDst);
// Success when src and dst are an entire depth stencil subresource (layer) // 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}, TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 2}, destination, 0,
{16, 16, 1}); {0, 0, 1}, {16, 16, 1});
// Success when src and dst are an array of entire depth stencil subresources // 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}, TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 1}, destination, 0,
{16, 16, 2}); {0, 0, 0}, {16, 16, 2});
}
} }
} }

View File

@ -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) { uint32_t GetTexelBlockSizeInBytes(wgpu::TextureFormat textureFormat) {
switch (textureFormat) { switch (textureFormat) {
case wgpu::TextureFormat::R8Unorm: case wgpu::TextureFormat::R8Unorm:
@ -134,7 +145,6 @@ namespace utils {
case wgpu::TextureFormat::RG8Snorm: case wgpu::TextureFormat::RG8Snorm:
case wgpu::TextureFormat::RG8Uint: case wgpu::TextureFormat::RG8Uint:
case wgpu::TextureFormat::RG8Sint: case wgpu::TextureFormat::RG8Sint:
case wgpu::TextureFormat::Depth16Unorm:
return 2u; return 2u;
case wgpu::TextureFormat::R32Float: case wgpu::TextureFormat::R32Float:
@ -153,7 +163,6 @@ namespace utils {
case wgpu::TextureFormat::RGB10A2Unorm: case wgpu::TextureFormat::RGB10A2Unorm:
case wgpu::TextureFormat::RG11B10Ufloat: case wgpu::TextureFormat::RG11B10Ufloat:
case wgpu::TextureFormat::RGB9E5Ufloat: case wgpu::TextureFormat::RGB9E5Ufloat:
case wgpu::TextureFormat::Depth32Float:
return 4u; return 4u;
case wgpu::TextureFormat::RG32Float: case wgpu::TextureFormat::RG32Float:
@ -169,6 +178,14 @@ namespace utils {
case wgpu::TextureFormat::RGBA32Sint: case wgpu::TextureFormat::RGBA32Sint:
return 16u; 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::BC1RGBAUnorm:
case wgpu::TextureFormat::BC1RGBAUnormSrgb: case wgpu::TextureFormat::BC1RGBAUnormSrgb:
case wgpu::TextureFormat::BC4RUnorm: case wgpu::TextureFormat::BC4RUnorm:
@ -231,9 +248,7 @@ namespace utils {
case wgpu::TextureFormat::ASTC12x12UnormSrgb: case wgpu::TextureFormat::ASTC12x12UnormSrgb:
return 16u; return 16u;
case wgpu::TextureFormat::Depth24Plus:
case wgpu::TextureFormat::Depth24PlusStencil8: case wgpu::TextureFormat::Depth24PlusStencil8:
case wgpu::TextureFormat::Depth24UnormStencil8:
case wgpu::TextureFormat::Depth32FloatStencil8: case wgpu::TextureFormat::Depth32FloatStencil8:
// Block size of a multi-planar format depends on aspect. // Block size of a multi-planar format depends on aspect.

View File

@ -206,6 +206,8 @@ namespace utils {
bool IsETC2TextureFormat(wgpu::TextureFormat textureFormat); bool IsETC2TextureFormat(wgpu::TextureFormat textureFormat);
bool IsASTCTextureFormat(wgpu::TextureFormat textureFormat); bool IsASTCTextureFormat(wgpu::TextureFormat textureFormat);
bool IsDepthOnlyFormat(wgpu::TextureFormat textureFormat);
uint32_t GetTexelBlockSizeInBytes(wgpu::TextureFormat textureFormat); uint32_t GetTexelBlockSizeInBytes(wgpu::TextureFormat textureFormat);
uint32_t GetTextureFormatBlockWidth(wgpu::TextureFormat textureFormat); uint32_t GetTextureFormatBlockWidth(wgpu::TextureFormat textureFormat);
uint32_t GetTextureFormatBlockHeight(wgpu::TextureFormat textureFormat); uint32_t GetTextureFormatBlockHeight(wgpu::TextureFormat textureFormat);