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) {
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:

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_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<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::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<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::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<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 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<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 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});
}
}
}

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) {
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.

View File

@ -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);