Allow CopyBufferToTexture with Depth16Unorm
Removes the validation logic that was blocking this copy from being valid and update tests to ensure that it works properly. Copy logic worked with this format as-is, so no updates were necessary. Bug: dawn:1251 Change-Id: Id0ca503ed0f82e79e75f63ad6870389f7f647d22 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/81024 Reviewed-by: Shrek Shao <shrekshao@google.com> Reviewed-by: Loko Kung <lokokung@google.com> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
f607280a62
commit
39c2029063
|
@ -386,8 +386,17 @@ namespace dawn::native {
|
|||
MaybeError ValidateLinearToDepthStencilCopyRestrictions(const ImageCopyTexture& dst) {
|
||||
Aspect aspectUsed;
|
||||
DAWN_TRY_ASSIGN(aspectUsed, SingleAspectUsedByImageCopyTexture(dst));
|
||||
DAWN_INVALID_IF(aspectUsed == Aspect::Depth, "Cannot copy into the depth aspect of %s.",
|
||||
dst.texture);
|
||||
|
||||
const Format& format = dst.texture->GetFormat();
|
||||
switch (format.format) {
|
||||
case wgpu::TextureFormat::Depth16Unorm:
|
||||
return {};
|
||||
default:
|
||||
DAWN_INVALID_IF(aspectUsed == Aspect::Depth,
|
||||
"Cannot copy into the depth aspect of %s with format %s.",
|
||||
dst.texture, format.format);
|
||||
break;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -31,6 +31,10 @@ namespace {
|
|||
wgpu::TextureFormat::Depth32Float,
|
||||
wgpu::TextureFormat::Depth32FloatStencil8,
|
||||
};
|
||||
|
||||
constexpr std::array<wgpu::TextureFormat, 1> kValidDepthCopyFromBufferFormats = {
|
||||
wgpu::TextureFormat::Depth16Unorm,
|
||||
};
|
||||
} // namespace
|
||||
|
||||
class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestParams> {
|
||||
|
@ -240,6 +244,16 @@ class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestPara
|
|||
return dst;
|
||||
}
|
||||
|
||||
uint32_t BufferSizeForTextureCopy(
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t depth,
|
||||
wgpu::TextureFormat format = wgpu::TextureFormat::RGBA8Unorm) {
|
||||
uint32_t bytesPerPixel = utils::GetTexelBlockSizeInBytes(format);
|
||||
uint32_t bytesPerRow = Align(width * bytesPerPixel, kTextureBytesPerRowAlignment);
|
||||
return (bytesPerRow * (height - 1) + width * bytesPerPixel) * depth;
|
||||
}
|
||||
|
||||
wgpu::ShaderModule mVertexModule;
|
||||
|
||||
private:
|
||||
|
@ -522,6 +536,72 @@ TEST_P(DepthCopyTests, FromNonZeroMipDepthAspect) {
|
|||
}
|
||||
}
|
||||
|
||||
class DepthCopyFromBufferTests : public DepthStencilCopyTests {};
|
||||
|
||||
// Test copying the depth-only aspect from a buffer.
|
||||
TEST_P(DepthCopyFromBufferTests, BufferToDepthAspect) {
|
||||
// TODO(crbug.com/dawn/1237): Depth16Unorm test failed on OpenGL and OpenGLES which says
|
||||
// Invalid format and type combination in glReadPixels
|
||||
DAWN_TEST_UNSUPPORTED_IF(GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm &&
|
||||
(IsOpenGL() || IsOpenGLES()));
|
||||
|
||||
constexpr uint32_t kWidth = 8;
|
||||
constexpr uint32_t kHeight = 1;
|
||||
|
||||
wgpu::Texture destTexture =
|
||||
CreateTexture(kWidth, kHeight, wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc);
|
||||
|
||||
wgpu::BufferDescriptor descriptor;
|
||||
descriptor.size = BufferSizeForTextureCopy(kWidth, kHeight, 1, GetParam().mTextureFormat);
|
||||
descriptor.usage = wgpu::BufferUsage::CopySrc;
|
||||
descriptor.mappedAtCreation = true;
|
||||
wgpu::Buffer srcBuffer = device.CreateBuffer(&descriptor);
|
||||
|
||||
wgpu::ImageCopyBuffer imageCopyBuffer =
|
||||
utils::CreateImageCopyBuffer(srcBuffer, 0, 256, kHeight);
|
||||
wgpu::ImageCopyTexture imageCopyTexture =
|
||||
utils::CreateImageCopyTexture(destTexture, 0, {0, 0, 0}, wgpu::TextureAspect::DepthOnly);
|
||||
wgpu::Extent3D extent = {kWidth, kHeight, 1};
|
||||
|
||||
constexpr float kInitDepth = 0.2f;
|
||||
|
||||
// This expectation is the test as it performs the CopyTextureToBuffer.
|
||||
if (GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm) {
|
||||
uint16_t expected = FloatToUnorm<uint16_t>(kInitDepth);
|
||||
std::vector<uint16_t> expectedData = {
|
||||
0, 0, expected, expected, 0, 0, expected, expected,
|
||||
};
|
||||
size_t expectedSize = expectedData.size() * sizeof(uint16_t);
|
||||
|
||||
memcpy(srcBuffer.GetMappedRange(0, expectedSize), expectedData.data(), expectedSize);
|
||||
srcBuffer.Unmap();
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.CopyBufferToTexture(&imageCopyBuffer, &imageCopyTexture, &extent);
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
|
||||
EXPECT_TEXTURE_EQ(expectedData.data(), destTexture, {0, 0}, {kWidth, kHeight}, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
} else {
|
||||
std::vector<float> expectedData = {
|
||||
0.0, 0.0, kInitDepth, kInitDepth, 0.0, 0.0, kInitDepth, kInitDepth,
|
||||
};
|
||||
size_t expectedSize = expectedData.size() * sizeof(float);
|
||||
|
||||
memcpy(srcBuffer.GetMappedRange(0, expectedSize), expectedData.data(), expectedSize);
|
||||
srcBuffer.Unmap();
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.CopyBufferToTexture(&imageCopyBuffer, &imageCopyTexture, &extent);
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
|
||||
EXPECT_TEXTURE_EQ(expectedData.data(), destTexture, {0, 0}, {kWidth, kHeight}, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
}
|
||||
}
|
||||
|
||||
class StencilCopyTests : public DepthStencilCopyTests {};
|
||||
|
||||
// Test copying the stencil-only aspect into a buffer.
|
||||
|
@ -696,6 +776,12 @@ DAWN_INSTANTIATE_TEST_P(DepthCopyTests,
|
|||
std::vector<wgpu::TextureFormat>(kValidDepthCopyTextureFormats.begin(),
|
||||
kValidDepthCopyTextureFormats.end()));
|
||||
|
||||
DAWN_INSTANTIATE_TEST_P(DepthCopyFromBufferTests,
|
||||
{D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
|
||||
VulkanBackend()},
|
||||
std::vector<wgpu::TextureFormat>(kValidDepthCopyFromBufferFormats.begin(),
|
||||
kValidDepthCopyFromBufferFormats.end()));
|
||||
|
||||
DAWN_INSTANTIATE_TEST_P(StencilCopyTests,
|
||||
{D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
|
||||
VulkanBackend()},
|
||||
|
|
|
@ -715,8 +715,10 @@ 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): 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 = {
|
||||
// are implemented, e.g. Stencil8.
|
||||
std::array<std::tuple<wgpu::TextureFormat, wgpu::TextureAspect>, 5> params = {
|
||||
std::make_tuple(wgpu::TextureFormat::Depth16Unorm, wgpu::TextureAspect::DepthOnly),
|
||||
std::make_tuple(wgpu::TextureFormat::Depth16Unorm, wgpu::TextureAspect::All),
|
||||
std::make_tuple(wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureAspect::StencilOnly),
|
||||
std::make_tuple(wgpu::TextureFormat::Depth24UnormStencil8,
|
||||
wgpu::TextureAspect::StencilOnly),
|
||||
|
@ -866,12 +868,35 @@ TEST_F(CopyCommandTest_B2T, CopyToMipmapOfNonSquareTexture) {
|
|||
{0, 0, 0}, {2, 2, 1});
|
||||
}
|
||||
|
||||
// Test it is invalid to copy to a depth texture
|
||||
// Test whether or not it is valid to copy to a depth texture
|
||||
TEST_F(CopyCommandTest_B2T, CopyToDepthAspect) {
|
||||
uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1, wgpu::TextureFormat::Depth32Float);
|
||||
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
|
||||
|
||||
for (wgpu::TextureFormat format : utils::kDepthFormats) {
|
||||
constexpr std::array<wgpu::TextureFormat, 1> kAllowBufferToDepthCopyFormats = {
|
||||
wgpu::TextureFormat::Depth16Unorm};
|
||||
|
||||
for (wgpu::TextureFormat format : kAllowBufferToDepthCopyFormats) {
|
||||
wgpu::Texture destination =
|
||||
Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopyDst);
|
||||
|
||||
// Test it is valid to copy this format from a buffer into a depth texture
|
||||
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 16, 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::Success, source, 0, 256, 16, destination, 0, {0, 0, 0},
|
||||
{16, 16, 1}, wgpu::TextureAspect::All);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr std::array<wgpu::TextureFormat, 5> kDisallowBufferToDepthCopyFormats = {
|
||||
wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Depth24Plus,
|
||||
wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureFormat::Depth24UnormStencil8,
|
||||
wgpu::TextureFormat::Depth32FloatStencil8,
|
||||
};
|
||||
|
||||
for (wgpu::TextureFormat format : kDisallowBufferToDepthCopyFormats) {
|
||||
wgpu::Texture destination =
|
||||
Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopyDst);
|
||||
|
||||
|
@ -1325,8 +1350,10 @@ 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): List other valid parameters after missing texture formats
|
||||
// are implemented, e.g. Stencil8 and depth16unorm.
|
||||
std::array<std::tuple<wgpu::TextureFormat, wgpu::TextureAspect>, 6> params = {
|
||||
// are implemented, e.g. Stencil8.
|
||||
std::array<std::tuple<wgpu::TextureFormat, wgpu::TextureAspect>, 8> params = {
|
||||
std::make_tuple(wgpu::TextureFormat::Depth16Unorm, wgpu::TextureAspect::DepthOnly),
|
||||
std::make_tuple(wgpu::TextureFormat::Depth16Unorm, wgpu::TextureAspect::All),
|
||||
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),
|
||||
|
|
Loading…
Reference in New Issue