diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp index 706ab523f2..38c9a9302a 100644 --- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp +++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp @@ -761,34 +761,76 @@ namespace dawn_native { namespace d3d12 { if (CanUseCopyResource(copy->source, copy->destination, copy->copySize)) { commandList->CopyResource(destination->GetD3D12Resource(), source->GetD3D12Resource()); + } else if (source->GetDimension() == wgpu::TextureDimension::e3D && + destination->GetDimension() == wgpu::TextureDimension::e3D) { + for (Aspect aspect : IterateEnumMask(srcRange.aspects)) { + D3D12_TEXTURE_COPY_LOCATION srcLocation = + ComputeTextureCopyLocationForTexture(source, copy->source.mipLevel, + 0, aspect); + D3D12_TEXTURE_COPY_LOCATION dstLocation = + ComputeTextureCopyLocationForTexture( + destination, copy->destination.mipLevel, 0, aspect); + + D3D12_BOX sourceRegion = ComputeD3D12BoxFromOffsetAndSize( + copy->source.origin, copy->copySize); + + commandList->CopyTextureRegion(&dstLocation, copy->destination.origin.x, + copy->destination.origin.y, + copy->destination.origin.z, &srcLocation, + &sourceRegion); + } } else { // TODO(crbug.com/dawn/814): support copying with 1D. - ASSERT(source->GetDimension() == wgpu::TextureDimension::e2D && - destination->GetDimension() == wgpu::TextureDimension::e2D); + ASSERT(source->GetDimension() != wgpu::TextureDimension::e1D && + destination->GetDimension() != wgpu::TextureDimension::e1D); const dawn_native::Extent3D copyExtentOneSlice = { copy->copySize.width, copy->copySize.height, 1u}; for (Aspect aspect : IterateEnumMask(srcRange.aspects)) { - for (uint32_t layer = 0; layer < copy->copySize.depthOrArrayLayers; - ++layer) { + for (uint32_t z = 0; z < copy->copySize.depthOrArrayLayers; ++z) { + uint32_t sourceLayer = 0; + uint32_t sourceZ = 0; + switch (source->GetDimension()) { + case wgpu::TextureDimension::e2D: + sourceLayer = copy->source.origin.z + z; + break; + case wgpu::TextureDimension::e3D: + sourceZ = copy->source.origin.z + z; + break; + case wgpu::TextureDimension::e1D: + UNREACHABLE(); + } + + uint32_t destinationLayer = 0; + uint32_t destinationZ = 0; + switch (destination->GetDimension()) { + case wgpu::TextureDimension::e2D: + destinationLayer = copy->destination.origin.z + z; + break; + case wgpu::TextureDimension::e3D: + destinationZ = copy->destination.origin.z + z; + break; + case wgpu::TextureDimension::e1D: + UNREACHABLE(); + } D3D12_TEXTURE_COPY_LOCATION srcLocation = ComputeTextureCopyLocationForTexture( - source, copy->source.mipLevel, - copy->source.origin.z + layer, aspect); + source, copy->source.mipLevel, sourceLayer, aspect); D3D12_TEXTURE_COPY_LOCATION dstLocation = - ComputeTextureCopyLocationForTexture( - destination, copy->destination.mipLevel, - copy->destination.origin.z + layer, aspect); + ComputeTextureCopyLocationForTexture(destination, + copy->destination.mipLevel, + destinationLayer, aspect); Origin3D sourceOriginInSubresource = copy->source.origin; - sourceOriginInSubresource.z = 0; + sourceOriginInSubresource.z = sourceZ; D3D12_BOX sourceRegion = ComputeD3D12BoxFromOffsetAndSize( sourceOriginInSubresource, copyExtentOneSlice); commandList->CopyTextureRegion( &dstLocation, copy->destination.origin.x, - copy->destination.origin.y, 0, &srcLocation, &sourceRegion); + copy->destination.origin.y, destinationZ, &srcLocation, + &sourceRegion); } } } diff --git a/src/tests/end2end/CopyTests.cpp b/src/tests/end2end/CopyTests.cpp index 6218d1db4c..fd690fed9c 100644 --- a/src/tests/end2end/CopyTests.cpp +++ b/src/tests/end2end/CopyTests.cpp @@ -2135,8 +2135,6 @@ TEST_P(CopyTests_T2T, Texture3DFull) { // Test that copying whole 3D texture to a 2D array in one texture-to-texture-copy works. TEST_P(CopyTests_T2T, Texture3DTo2DArrayFull) { - DAWN_TEST_UNSUPPORTED_IF(IsD3D12()); // TODO(crbug.com/dawn/547): Implement on D3D12. - constexpr uint32_t kWidth = 256; constexpr uint32_t kHeight = 128; constexpr uint32_t kDepth = 6u; @@ -2150,8 +2148,6 @@ TEST_P(CopyTests_T2T, Texture3DTo2DArrayFull) { // Test that copying whole 2D array to a 3D texture in one texture-to-texture-copy works. TEST_P(CopyTests_T2T, Texture2DArrayTo3DFull) { - DAWN_TEST_UNSUPPORTED_IF(IsD3D12()); // TODO(crbug.com/dawn/547): Implement on D3D12. - constexpr uint32_t kWidth = 256; constexpr uint32_t kHeight = 128; constexpr uint32_t kDepth = 6u; @@ -2165,9 +2161,7 @@ TEST_P(CopyTests_T2T, Texture2DArrayTo3DFull) { // Test that copying subregion of a 3D texture in one texture-to-texture-copy works. TEST_P(CopyTests_T2T, Texture3DSubRegion) { - DAWN_TEST_UNSUPPORTED_IF(IsD3D12()); // TODO(crbug.com/dawn/547): Implement on D3D12. DAWN_TEST_UNSUPPORTED_IF(IsANGLE()); // TODO(crbug.com/angleproject/5967) - constexpr uint32_t kWidth = 256; constexpr uint32_t kHeight = 128; constexpr uint32_t kDepth = 6u; @@ -2181,8 +2175,6 @@ TEST_P(CopyTests_T2T, Texture3DSubRegion) { // Test that copying subregion of a 3D texture to a 2D array in one texture-to-texture-copy works. TEST_P(CopyTests_T2T, Texture3DTo2DArraySubRegion) { - DAWN_TEST_UNSUPPORTED_IF(IsD3D12()); // TODO(crbug.com/dawn/547): Implement on D3D12. - constexpr uint32_t kWidth = 256; constexpr uint32_t kHeight = 128; constexpr uint32_t kDepth = 6u; @@ -2197,9 +2189,7 @@ TEST_P(CopyTests_T2T, Texture3DTo2DArraySubRegion) { // Test that copying subregion of a 2D array to a 3D texture to in one texture-to-texture-copy // works. TEST_P(CopyTests_T2T, Texture2DArrayTo3DSubRegion) { - DAWN_TEST_UNSUPPORTED_IF(IsD3D12()); // TODO(crbug.com/dawn/547): Implement on D3D12. DAWN_TEST_UNSUPPORTED_IF(IsANGLE()); // TODO(crbug.com/angleproject/5967) - constexpr uint32_t kWidth = 256; constexpr uint32_t kHeight = 128; constexpr uint32_t kDepth = 6u;