Validate the buffer offset in T2B and B2T for depth/stencil texture

This patch modifies the ValidateLinearTextureCopyOffset for T2B and B2T
commands to make sure that buffer offset is a multiple of 4 when the
texture is of a depth/stencil format. The unittests are also updated
to cover these cases.

Bug: dawn:721
Change-Id: I5cb9487e61e7f6ac7075157a092a1f3577844042
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/55720
Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Zhaoming Jiang 2021-06-24 05:38:00 +00:00 committed by Dawn LUCI CQ
parent 75c5067ed1
commit 1af81e3128
2 changed files with 77 additions and 10 deletions

View File

@ -69,11 +69,20 @@ namespace dawn_native {
} }
MaybeError ValidateLinearTextureCopyOffset(const TextureDataLayout& layout, MaybeError ValidateLinearTextureCopyOffset(const TextureDataLayout& layout,
const TexelBlockInfo& blockInfo) { const TexelBlockInfo& blockInfo,
const bool hasDepthOrStencil) {
if (hasDepthOrStencil) {
// For depth-stencil texture, buffer offset must be a multiple of 4.
if (layout.offset % 4 != 0) {
return DAWN_VALIDATION_ERROR(
"offset must be a multiple of 4 for depth/stencil texture.");
}
} else {
if (layout.offset % blockInfo.byteSize != 0) { if (layout.offset % blockInfo.byteSize != 0) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"offset must be a multiple of the texel block byte size."); "offset must be a multiple of the texel block byte size.");
} }
}
return {}; return {};
} }
@ -680,7 +689,8 @@ namespace dawn_native {
TextureDataLayout srcLayout = FixUpDeprecatedTextureDataLayoutOptions( TextureDataLayout srcLayout = FixUpDeprecatedTextureDataLayoutOptions(
GetDevice(), source->layout, blockInfo, *copySize); GetDevice(), source->layout, blockInfo, *copySize);
if (GetDevice()->IsValidationEnabled()) { if (GetDevice()->IsValidationEnabled()) {
DAWN_TRY(ValidateLinearTextureCopyOffset(srcLayout, blockInfo)); DAWN_TRY(ValidateLinearTextureCopyOffset(
srcLayout, blockInfo, destination->texture->GetFormat().HasDepthOrStencil()));
DAWN_TRY(ValidateLinearTextureData(srcLayout, source->buffer->GetSize(), blockInfo, DAWN_TRY(ValidateLinearTextureData(srcLayout, source->buffer->GetSize(), blockInfo,
*copySize)); *copySize));
@ -731,7 +741,8 @@ namespace dawn_native {
TextureDataLayout dstLayout = FixUpDeprecatedTextureDataLayoutOptions( TextureDataLayout dstLayout = FixUpDeprecatedTextureDataLayoutOptions(
GetDevice(), destination->layout, blockInfo, *copySize); GetDevice(), destination->layout, blockInfo, *copySize);
if (GetDevice()->IsValidationEnabled()) { if (GetDevice()->IsValidationEnabled()) {
DAWN_TRY(ValidateLinearTextureCopyOffset(dstLayout, blockInfo)); DAWN_TRY(ValidateLinearTextureCopyOffset(
dstLayout, blockInfo, source->texture->GetFormat().HasDepthOrStencil()));
DAWN_TRY(ValidateLinearTextureData(dstLayout, destination->buffer->GetSize(), DAWN_TRY(ValidateLinearTextureData(dstLayout, destination->buffer->GetSize(),
blockInfo, *copySize)); blockInfo, *copySize));

View File

@ -656,8 +656,8 @@ TEST_F(CopyCommandTest_B2T, RowsPerImageConstraints) {
{4, 4, 1}); {4, 4, 1});
} }
// Test B2T copies with incorrect buffer offset usage // Test B2T copies with incorrect buffer offset usage for color texture
TEST_F(CopyCommandTest_B2T, IncorrectBufferOffset) { TEST_F(CopyCommandTest_B2T, IncorrectBufferOffsetForColorTexture) {
uint64_t bufferSize = BufferSizeForTextureCopy(4, 4, 1); uint64_t bufferSize = BufferSizeForTextureCopy(4, 4, 1);
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc); wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
wgpu::Texture destination = wgpu::Texture destination =
@ -678,6 +678,33 @@ TEST_F(CopyCommandTest_B2T, IncorrectBufferOffset) {
} }
} }
// 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
// are implemented, e.g. Stencil8 and depth16unorm.
std::array<std::tuple<wgpu::TextureFormat, wgpu::TextureAspect>, 1> params = {
std::make_tuple(wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureAspect::StencilOnly),
};
uint64_t bufferSize = BufferSizeForTextureCopy(32, 32, 1);
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
for (auto param : params) {
wgpu::TextureFormat textureFormat = std::get<0>(param);
wgpu::TextureAspect textureAspect = std::get<1>(param);
wgpu::Texture destination =
Create2DTexture(16, 16, 5, 1, textureFormat, wgpu::TextureUsage::CopyDst);
for (uint64_t srcOffset = 0; srcOffset < 8; srcOffset++) {
utils::Expectation expectation =
(srcOffset % 4 == 0) ? utils::Expectation::Success : utils::Expectation::Failure;
TestB2TCopy(expectation, source, srcOffset, 256, 16, destination, 0, {0, 0, 0},
{16, 16, 1}, textureAspect);
}
}
}
// Test multisampled textures cannot be used in B2T copies. // Test multisampled textures cannot be used in B2T copies.
TEST_F(CopyCommandTest_B2T, CopyToMultisampledTexture) { TEST_F(CopyCommandTest_B2T, CopyToMultisampledTexture) {
uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1); uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1);
@ -1247,8 +1274,8 @@ TEST_F(CopyCommandTest_T2B, RowsPerImageConstraints) {
{4, 4, 1}); {4, 4, 1});
} }
// Test T2B copies with incorrect buffer offset usage // Test T2B copies with incorrect buffer offset usage for color texture
TEST_F(CopyCommandTest_T2B, IncorrectBufferOffset) { TEST_F(CopyCommandTest_T2B, IncorrectBufferOffsetForColorTexture) {
uint64_t bufferSize = BufferSizeForTextureCopy(128, 16, 1); uint64_t bufferSize = BufferSizeForTextureCopy(128, 16, 1);
wgpu::Texture source = Create2DTexture(128, 16, 5, 1, wgpu::TextureFormat::RGBA8Unorm, wgpu::Texture source = Create2DTexture(128, 16, 5, 1, wgpu::TextureFormat::RGBA8Unorm,
wgpu::TextureUsage::CopySrc); wgpu::TextureUsage::CopySrc);
@ -1267,6 +1294,35 @@ TEST_F(CopyCommandTest_T2B, IncorrectBufferOffset) {
1, {1, 1, 1}); 1, {1, 1, 1});
} }
// 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
// are implemented, e.g. Stencil8 and depth16unorm.
std::array<std::tuple<wgpu::TextureFormat, wgpu::TextureAspect>, 3> 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),
};
uint64_t bufferSize = BufferSizeForTextureCopy(32, 32, 1);
wgpu::Buffer destination = CreateBuffer(bufferSize, wgpu::BufferUsage::CopyDst);
for (auto param : params) {
wgpu::TextureFormat textureFormat = std::get<0>(param);
wgpu::TextureAspect textureAspect = std::get<1>(param);
wgpu::Texture source =
Create2DTexture(16, 16, 5, 1, textureFormat, wgpu::TextureUsage::CopySrc);
for (uint64_t dstOffset = 0; dstOffset < 8; dstOffset++) {
utils::Expectation expectation =
(dstOffset % 4 == 0) ? utils::Expectation::Success : utils::Expectation::Failure;
TestT2BCopy(expectation, source, 0, {0, 0, 0}, destination, dstOffset, 256, 16,
{16, 16, 1}, textureAspect);
}
}
}
// Test multisampled textures cannot be used in T2B copies. // Test multisampled textures cannot be used in T2B copies.
TEST_F(CopyCommandTest_T2B, CopyFromMultisampledTexture) { TEST_F(CopyCommandTest_T2B, CopyFromMultisampledTexture) {
wgpu::Texture source = Create2DTexture(2, 2, 1, 1, wgpu::TextureFormat::RGBA8Unorm, wgpu::Texture source = Create2DTexture(2, 2, 1, 1, wgpu::TextureFormat::RGBA8Unorm,