Implement 3D Texture copy for partial depth slices on D3D12
Note that a slice somehow means a subresource on D3D12. There are mip slice, array slice, and plane/aspect slice in D3D12. We reuse the term "slice" for multiple depth of a 3D texture, although one single depth slice of multiple depth slices is not a separate subresource of a 3D texture (all these depth slices for one mip are a separte subresource in 3D texture). For the reason above, this change also renames "slice" to "layer" in some functions if "slice" is a layer in that function. Because a layer is definitely a subresource but a slice may not be (like a single depth slice of a 3D texture). Bug: dawn:547 Change-Id: I88b8120ef7f73bfc261fc225f4242924da221654 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/49240 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Yunchao He <yunchao.he@intel.com>
This commit is contained in:
parent
74326fe2c8
commit
ef6a482fb2
|
@ -842,17 +842,17 @@ namespace dawn_native { namespace d3d12 {
|
||||||
copy->copySize.width, copy->copySize.height, 1u};
|
copy->copySize.width, copy->copySize.height, 1u};
|
||||||
|
|
||||||
for (Aspect aspect : IterateEnumMask(srcRange.aspects)) {
|
for (Aspect aspect : IterateEnumMask(srcRange.aspects)) {
|
||||||
for (uint32_t slice = 0; slice < copy->copySize.depthOrArrayLayers;
|
for (uint32_t layer = 0; layer < copy->copySize.depthOrArrayLayers;
|
||||||
++slice) {
|
++layer) {
|
||||||
D3D12_TEXTURE_COPY_LOCATION srcLocation =
|
D3D12_TEXTURE_COPY_LOCATION srcLocation =
|
||||||
ComputeTextureCopyLocationForTexture(
|
ComputeTextureCopyLocationForTexture(
|
||||||
source, copy->source.mipLevel,
|
source, copy->source.mipLevel,
|
||||||
copy->source.origin.z + slice, aspect);
|
copy->source.origin.z + layer, aspect);
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION dstLocation =
|
D3D12_TEXTURE_COPY_LOCATION dstLocation =
|
||||||
ComputeTextureCopyLocationForTexture(
|
ComputeTextureCopyLocationForTexture(
|
||||||
destination, copy->destination.mipLevel,
|
destination, copy->destination.mipLevel,
|
||||||
copy->destination.origin.z + slice, aspect);
|
copy->destination.origin.z + layer, aspect);
|
||||||
|
|
||||||
Origin3D sourceOriginInSubresource = copy->source.origin;
|
Origin3D sourceOriginInSubresource = copy->source.origin;
|
||||||
sourceOriginInSubresource.z = 0;
|
sourceOriginInSubresource.z = 0;
|
||||||
|
|
|
@ -68,12 +68,12 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION ComputeTextureCopyLocationForTexture(const Texture* texture,
|
D3D12_TEXTURE_COPY_LOCATION ComputeTextureCopyLocationForTexture(const Texture* texture,
|
||||||
uint32_t level,
|
uint32_t level,
|
||||||
uint32_t slice,
|
uint32_t layer,
|
||||||
Aspect aspect) {
|
Aspect aspect) {
|
||||||
D3D12_TEXTURE_COPY_LOCATION copyLocation;
|
D3D12_TEXTURE_COPY_LOCATION copyLocation;
|
||||||
copyLocation.pResource = texture->GetD3D12Resource();
|
copyLocation.pResource = texture->GetD3D12Resource();
|
||||||
copyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
copyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||||
copyLocation.SubresourceIndex = texture->GetSubresourceIndex(level, slice, aspect);
|
copyLocation.SubresourceIndex = texture->GetSubresourceIndex(level, layer, aspect);
|
||||||
|
|
||||||
return copyLocation;
|
return copyLocation;
|
||||||
}
|
}
|
||||||
|
@ -149,11 +149,11 @@ namespace dawn_native { namespace d3d12 {
|
||||||
uint64_t bufferBytesPerRow,
|
uint64_t bufferBytesPerRow,
|
||||||
Texture* texture,
|
Texture* texture,
|
||||||
uint32_t textureMiplevel,
|
uint32_t textureMiplevel,
|
||||||
uint32_t textureSlice,
|
uint32_t textureLayer,
|
||||||
Aspect aspect) {
|
Aspect aspect) {
|
||||||
ASSERT(HasOneBit(aspect));
|
ASSERT(HasOneBit(aspect));
|
||||||
const D3D12_TEXTURE_COPY_LOCATION textureLocation =
|
const D3D12_TEXTURE_COPY_LOCATION textureLocation =
|
||||||
ComputeTextureCopyLocationForTexture(texture, textureMiplevel, textureSlice, aspect);
|
ComputeTextureCopyLocationForTexture(texture, textureMiplevel, textureLayer, aspect);
|
||||||
|
|
||||||
const uint64_t offsetBytes = baseCopySplit.offset + baseOffset;
|
const uint64_t offsetBytes = baseCopySplit.offset + baseOffset;
|
||||||
|
|
||||||
|
@ -201,12 +201,12 @@ namespace dawn_native { namespace d3d12 {
|
||||||
std::array<uint64_t, TextureCopySplits::kMaxTextureCopySplits> bufferOffsetsForNextSlice = {
|
std::array<uint64_t, TextureCopySplits::kMaxTextureCopySplits> bufferOffsetsForNextSlice = {
|
||||||
{0u, 0u}};
|
{0u, 0u}};
|
||||||
|
|
||||||
for (uint32_t copySlice = 0; copySlice < copySize.depthOrArrayLayers; ++copySlice) {
|
for (uint32_t copyLayer = 0; copyLayer < copySize.depthOrArrayLayers; ++copyLayer) {
|
||||||
const uint32_t splitIndex = copySlice % copySplits.copies2D.size();
|
const uint32_t splitIndex = copyLayer % copySplits.copies2D.size();
|
||||||
|
|
||||||
const Texture2DCopySplit& copySplitPerLayerBase = copySplits.copies2D[splitIndex];
|
const Texture2DCopySplit& copySplitPerLayerBase = copySplits.copies2D[splitIndex];
|
||||||
const uint64_t bufferOffsetForNextSlice = bufferOffsetsForNextSlice[splitIndex];
|
const uint64_t bufferOffsetForNextSlice = bufferOffsetsForNextSlice[splitIndex];
|
||||||
const uint32_t copyTextureLayer = copySlice + textureCopy.origin.z;
|
const uint32_t copyTextureLayer = copyLayer + textureCopy.origin.z;
|
||||||
|
|
||||||
RecordCopyBufferToTextureFromTextureCopySplit(
|
RecordCopyBufferToTextureFromTextureCopySplit(
|
||||||
commandContext->GetCommandList(), copySplitPerLayerBase, bufferResource,
|
commandContext->GetCommandList(), copySplitPerLayerBase, bufferResource,
|
||||||
|
@ -234,7 +234,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
RecordCopyBufferToTextureFromTextureCopySplit(
|
RecordCopyBufferToTextureFromTextureCopySplit(
|
||||||
commandContext->GetCommandList(), copySplits.copies2D[0], bufferResource, 0,
|
commandContext->GetCommandList(), copySplits.copies2D[0], bufferResource, 0,
|
||||||
bytesPerRow, texture, textureCopy.mipLevel, textureCopy.origin.z, aspect);
|
bytesPerRow, texture, textureCopy.mipLevel, 0, aspect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordCopyBufferToTexture(CommandRecordingContext* commandContext,
|
void RecordCopyBufferToTexture(CommandRecordingContext* commandContext,
|
||||||
|
@ -267,10 +267,10 @@ namespace dawn_native { namespace d3d12 {
|
||||||
uint64_t bufferBytesPerRow,
|
uint64_t bufferBytesPerRow,
|
||||||
Texture* texture,
|
Texture* texture,
|
||||||
uint32_t textureMiplevel,
|
uint32_t textureMiplevel,
|
||||||
uint32_t textureSlice,
|
uint32_t textureLayer,
|
||||||
Aspect aspect) {
|
Aspect aspect) {
|
||||||
const D3D12_TEXTURE_COPY_LOCATION textureLocation =
|
const D3D12_TEXTURE_COPY_LOCATION textureLocation =
|
||||||
ComputeTextureCopyLocationForTexture(texture, textureMiplevel, textureSlice, aspect);
|
ComputeTextureCopyLocationForTexture(texture, textureMiplevel, textureLayer, aspect);
|
||||||
|
|
||||||
const uint64_t offset = baseCopySplit.offset + baseOffset;
|
const uint64_t offset = baseCopySplit.offset + baseOffset;
|
||||||
|
|
||||||
|
@ -318,12 +318,12 @@ namespace dawn_native { namespace d3d12 {
|
||||||
// that uses copySplits.copies2D[1].
|
// that uses copySplits.copies2D[1].
|
||||||
std::array<uint64_t, TextureCopySplits::kMaxTextureCopySplits> bufferOffsetsForNextSlice = {
|
std::array<uint64_t, TextureCopySplits::kMaxTextureCopySplits> bufferOffsetsForNextSlice = {
|
||||||
{0u, 0u}};
|
{0u, 0u}};
|
||||||
for (uint32_t copySlice = 0; copySlice < copySize.depthOrArrayLayers; ++copySlice) {
|
for (uint32_t copyLayer = 0; copyLayer < copySize.depthOrArrayLayers; ++copyLayer) {
|
||||||
const uint32_t splitIndex = copySlice % copySplits.copies2D.size();
|
const uint32_t splitIndex = copyLayer % copySplits.copies2D.size();
|
||||||
|
|
||||||
const Texture2DCopySplit& copySplitPerLayerBase = copySplits.copies2D[splitIndex];
|
const Texture2DCopySplit& copySplitPerLayerBase = copySplits.copies2D[splitIndex];
|
||||||
const uint64_t bufferOffsetForNextSlice = bufferOffsetsForNextSlice[splitIndex];
|
const uint64_t bufferOffsetForNextSlice = bufferOffsetsForNextSlice[splitIndex];
|
||||||
const uint32_t copyTextureLayer = copySlice + textureCopy.origin.z;
|
const uint32_t copyTextureLayer = copyLayer + textureCopy.origin.z;
|
||||||
|
|
||||||
RecordCopyTextureToBufferFromTextureCopySplit(
|
RecordCopyTextureToBufferFromTextureCopySplit(
|
||||||
commandList, copySplitPerLayerBase, buffer, bufferOffsetForNextSlice,
|
commandList, copySplitPerLayerBase, buffer, bufferOffsetForNextSlice,
|
||||||
|
@ -349,9 +349,9 @@ namespace dawn_native { namespace d3d12 {
|
||||||
ComputeTextureCopySplits(textureCopy.origin, copySize, blockInfo, bufferCopy.offset,
|
ComputeTextureCopySplits(textureCopy.origin, copySize, blockInfo, bufferCopy.offset,
|
||||||
bufferCopy.bytesPerRow, bufferCopy.rowsPerImage, true);
|
bufferCopy.bytesPerRow, bufferCopy.rowsPerImage, true);
|
||||||
|
|
||||||
RecordCopyTextureToBufferFromTextureCopySplit(
|
RecordCopyTextureToBufferFromTextureCopySplit(commandList, copySplits.copies2D[0], buffer,
|
||||||
commandList, copySplits.copies2D[0], buffer, 0, bufferCopy.bytesPerRow, texture,
|
0, bufferCopy.bytesPerRow, texture,
|
||||||
textureCopy.mipLevel, textureCopy.origin.z, textureCopy.aspect);
|
textureCopy.mipLevel, 0, textureCopy.aspect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordCopyTextureToBuffer(ID3D12GraphicsCommandList* commandList,
|
void RecordCopyTextureToBuffer(ID3D12GraphicsCommandList* commandList,
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION ComputeTextureCopyLocationForTexture(const Texture* texture,
|
D3D12_TEXTURE_COPY_LOCATION ComputeTextureCopyLocationForTexture(const Texture* texture,
|
||||||
uint32_t level,
|
uint32_t level,
|
||||||
uint32_t slice,
|
uint32_t layer,
|
||||||
Aspect aspect);
|
Aspect aspect);
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION ComputeBufferLocationForCopyTextureRegion(
|
D3D12_TEXTURE_COPY_LOCATION ComputeBufferLocationForCopyTextureRegion(
|
||||||
|
@ -51,7 +51,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
uint64_t bufferBytesPerRow,
|
uint64_t bufferBytesPerRow,
|
||||||
Texture* texture,
|
Texture* texture,
|
||||||
uint32_t textureMiplevel,
|
uint32_t textureMiplevel,
|
||||||
uint32_t textureSlice,
|
uint32_t textureLayer,
|
||||||
Aspect aspect);
|
Aspect aspect);
|
||||||
|
|
||||||
void RecordCopyBufferToTexture(CommandRecordingContext* commandContext,
|
void RecordCopyBufferToTexture(CommandRecordingContext* commandContext,
|
||||||
|
@ -71,7 +71,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
uint64_t bufferBytesPerRow,
|
uint64_t bufferBytesPerRow,
|
||||||
Texture* texture,
|
Texture* texture,
|
||||||
uint32_t textureMiplevel,
|
uint32_t textureMiplevel,
|
||||||
uint32_t textureSlice,
|
uint32_t textureLayer,
|
||||||
Aspect aspect);
|
Aspect aspect);
|
||||||
|
|
||||||
void RecordCopyTextureToBuffer(ID3D12GraphicsCommandList* commandList,
|
void RecordCopyTextureToBuffer(ID3D12GraphicsCommandList* commandList,
|
||||||
|
|
|
@ -962,6 +962,26 @@ TEST_P(CopyTests_T2B, Texture3DFull) {
|
||||||
wgpu::TextureDimension::e3D);
|
wgpu::TextureDimension::e3D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that copying a range of texture 3D depths in one texture-to-buffer-copy works.
|
||||||
|
TEST_P(CopyTests_T2B, Texture3DSubRegion) {
|
||||||
|
// TODO(yunchao.he@intel.com): implement 3D texture copy on Vulkan, Metal, OpenGL and OpenGLES
|
||||||
|
// backend.
|
||||||
|
DAWN_SKIP_TEST_IF(IsVulkan() || IsMetal() || IsOpenGL() || IsOpenGLES());
|
||||||
|
|
||||||
|
constexpr uint32_t kWidth = 256;
|
||||||
|
constexpr uint32_t kHeight = 128;
|
||||||
|
constexpr uint32_t kDepth = 6u;
|
||||||
|
constexpr uint32_t kBaseDepth = 2u;
|
||||||
|
constexpr uint32_t kCopyDepth = 3u;
|
||||||
|
|
||||||
|
TextureSpec textureSpec;
|
||||||
|
textureSpec.copyOrigin = {0, 0, kBaseDepth};
|
||||||
|
textureSpec.textureSize = {kWidth, kHeight, kDepth};
|
||||||
|
|
||||||
|
DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kCopyDepth),
|
||||||
|
{kWidth, kHeight, kCopyDepth}, wgpu::TextureDimension::e3D);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(yunchao.he@intel.com): add T2B tests for 3D textures, like RowPitch,
|
// TODO(yunchao.he@intel.com): add T2B tests for 3D textures, like RowPitch,
|
||||||
// RowsPerImage, buffer offset, partial depth range, non-zero level, etc.
|
// RowsPerImage, buffer offset, partial depth range, non-zero level, etc.
|
||||||
|
|
||||||
|
@ -1419,6 +1439,26 @@ TEST_P(CopyTests_B2T, Texture3DFull) {
|
||||||
wgpu::TextureDimension::e3D);
|
wgpu::TextureDimension::e3D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that copying a range of texture 3D Depths in one texture-to-buffer-copy works.
|
||||||
|
TEST_P(CopyTests_B2T, Texture3DSubRegion) {
|
||||||
|
// TODO(yunchao.he@intel.com): implement 3D texture copy on Vulkan, Metal, OpenGL and OpenGLES
|
||||||
|
// backend.
|
||||||
|
DAWN_SKIP_TEST_IF(IsVulkan() || IsMetal() || IsOpenGL() || IsOpenGLES());
|
||||||
|
|
||||||
|
constexpr uint32_t kWidth = 256;
|
||||||
|
constexpr uint32_t kHeight = 128;
|
||||||
|
constexpr uint32_t kDepth = 6u;
|
||||||
|
constexpr uint32_t kBaseDepth = 2u;
|
||||||
|
constexpr uint32_t kCopyDepth = 3u;
|
||||||
|
|
||||||
|
TextureSpec textureSpec;
|
||||||
|
textureSpec.copyOrigin = {0, 0, kBaseDepth};
|
||||||
|
textureSpec.textureSize = {kWidth, kHeight, kDepth};
|
||||||
|
|
||||||
|
DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kCopyDepth),
|
||||||
|
{kWidth, kHeight, kCopyDepth}, wgpu::TextureDimension::e3D);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(yunchao.he@intel.com): add more tests like RowPitch, RowsPerImage, buffer offset, partial
|
// TODO(yunchao.he@intel.com): add more tests like RowPitch, RowsPerImage, buffer offset, partial
|
||||||
// depth range, non-zero level, etc.
|
// depth range, non-zero level, etc.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue