D3D12: Fix usage of CopyResource
CopyResource may only be used for resources that have exactly the same format, dimension, mips, layers. And it can only be used if the entire texture region is copied. Bug: dawn:353 Change-Id: Ia8f96cc10c88fe026e23bce2d0532624725b12e0 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16984 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
b988e03982
commit
83e138ca96
|
@ -53,18 +53,40 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
}
|
||||
|
||||
bool CanUseCopyResource(const uint32_t sourceNumMipLevels,
|
||||
const Extent3D& srcSize,
|
||||
const Extent3D& dstSize,
|
||||
const Extent3D& copySize) {
|
||||
if (sourceNumMipLevels == 1 && srcSize.width == dstSize.width &&
|
||||
srcSize.height == dstSize.height && srcSize.depth == dstSize.depth &&
|
||||
srcSize.width == copySize.width && srcSize.height == copySize.height &&
|
||||
srcSize.depth == copySize.depth) {
|
||||
return true;
|
||||
}
|
||||
bool CanUseCopyResource(const Texture* src, const Texture* dst, const Extent3D& copySize) {
|
||||
// Checked by validation
|
||||
ASSERT(src->GetSampleCount() == dst->GetSampleCount());
|
||||
ASSERT(src->GetFormat().format == dst->GetFormat().format);
|
||||
|
||||
return false;
|
||||
const Extent3D& srcSize = src->GetSize();
|
||||
const Extent3D& dstSize = dst->GetSize();
|
||||
|
||||
auto GetCopyDepth = [](const Texture* texture) {
|
||||
switch (texture->GetDimension()) {
|
||||
case wgpu::TextureDimension::e1D:
|
||||
return 1u;
|
||||
case wgpu::TextureDimension::e2D:
|
||||
return texture->GetArrayLayers();
|
||||
case wgpu::TextureDimension::e3D:
|
||||
return texture->GetSize().depth;
|
||||
}
|
||||
};
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12graphicscommandlist-copyresource
|
||||
// In order to use D3D12's copy resource, the textures must be the same dimensions, and
|
||||
// the copy must be of the entire resource.
|
||||
// TODO(dawn:129): Support 1D textures.
|
||||
return src->GetDimension() == dst->GetDimension() && //
|
||||
dst->GetNumMipLevels() == 1 && //
|
||||
src->GetNumMipLevels() == 1 && // A copy command is of a single mip, so if a
|
||||
// resource has more than one, we definitely
|
||||
// cannot use CopyResource.
|
||||
copySize.width == dstSize.width && //
|
||||
copySize.width == srcSize.width && //
|
||||
copySize.height == dstSize.height && //
|
||||
copySize.height == srcSize.height && //
|
||||
copySize.depth == GetCopyDepth(src) && //
|
||||
copySize.depth == GetCopyDepth(dst);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -669,8 +691,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
destination->TrackUsageAndTransitionNow(commandContext,
|
||||
wgpu::TextureUsage::CopyDst);
|
||||
|
||||
if (CanUseCopyResource(source->GetNumMipLevels(), source->GetSize(),
|
||||
destination->GetSize(), copy->copySize)) {
|
||||
if (CanUseCopyResource(source, destination, copy->copySize)) {
|
||||
commandList->CopyResource(destination->GetD3D12Resource(),
|
||||
source->GetD3D12Resource());
|
||||
} else {
|
||||
|
|
|
@ -729,6 +729,24 @@ TEST_P(CopyTests_T2T, TextureMip) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_P(CopyTests_T2T, SingleMipSrcMultipleMipDst) {
|
||||
constexpr uint32_t kWidth = 256;
|
||||
constexpr uint32_t kHeight = 128;
|
||||
for (unsigned int i = 1; i < 4; ++i) {
|
||||
DoTest({kWidth >> i, kHeight >> i, 0, 0, 0}, {kWidth, kHeight, 0, 0, i},
|
||||
{kWidth >> i, kHeight >> i});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(CopyTests_T2T, MultipleMipSrcSingleMipDst) {
|
||||
constexpr uint32_t kWidth = 256;
|
||||
constexpr uint32_t kHeight = 128;
|
||||
for (unsigned int i = 1; i < 4; ++i) {
|
||||
DoTest({kWidth, kHeight, 0, 0, i}, {kWidth >> i, kHeight >> i, 0, 0, 0},
|
||||
{kWidth >> i, kHeight >> i});
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(brandon1.jones@intel.com) Add test for ensuring blitCommandEncoder on Metal.
|
||||
|
||||
DAWN_INSTANTIATE_TEST(CopyTests_T2T, D3D12Backend(), MetalBackend(), OpenGLBackend(), VulkanBackend());
|
||||
|
|
Loading…
Reference in New Issue