Replace TextureCopyView::arrayLayer -> origin.z in backends

Also fix a misuse of VkBufferImageCopy that caused some Swiftshader
failures.

Bug: dawn:22
Change-Id: Ie812a590d70c7561dfcf2f78ce6c530187610e65
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23200
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
Corentin Wallez 2020-06-26 11:07:00 +00:00 committed by Commit Bot service account
parent 2a6cc4f8fb
commit ff90599cdf
11 changed files with 104 additions and 131 deletions

View File

@ -51,6 +51,17 @@ namespace dawn_native {
return false; return false;
} }
SubresourceRange GetSubresourcesAffectedByCopy(const TextureCopy& copy,
const Extent3D& copySize) {
switch (copy.texture->GetDimension()) {
case wgpu::TextureDimension::e2D:
return {copy.mipLevel, 1, copy.origin.z, copySize.depth};
default:
UNREACHABLE();
return {};
}
}
void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass) { void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass) {
for (uint32_t i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { for (uint32_t i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
auto& attachmentInfo = renderPass->colorAttachments[i]; auto& attachmentInfo = renderPass->colorAttachments[i];

View File

@ -20,10 +20,12 @@
#include "dawn_native/Forward.h" #include "dawn_native/Forward.h"
#include "dawn_native/ObjectBase.h" #include "dawn_native/ObjectBase.h"
#include "dawn_native/PassResourceUsage.h" #include "dawn_native/PassResourceUsage.h"
#include "dawn_native/Texture.h"
namespace dawn_native { namespace dawn_native {
struct BeginRenderPassCmd; struct BeginRenderPassCmd;
struct TextureCopy;
class CommandBufferBase : public ObjectBase { class CommandBufferBase : public ObjectBase {
public: public:
@ -37,9 +39,12 @@ namespace dawn_native {
CommandBufferResourceUsage mResourceUsages; CommandBufferResourceUsage mResourceUsages;
}; };
bool IsCompleteSubresourceCopiedTo(const TextureBase* texture, bool IsCompleteSubresourceCopiedTo(const TextureBase* texture,
const Extent3D copySize, const Extent3D copySize,
const uint32_t mipLevel); const uint32_t mipLevel);
SubresourceRange GetSubresourcesAffectedByCopy(const TextureCopy& copy,
const Extent3D& copySize);
void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass); void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass);

View File

@ -737,13 +737,8 @@ namespace dawn_native {
copy->source.rowsPerImage = defaultedRowsPerImage; copy->source.rowsPerImage = defaultedRowsPerImage;
copy->destination.texture = destination->texture; copy->destination.texture = destination->texture;
copy->destination.origin = destination->origin; copy->destination.origin = destination->origin;
copy->copySize = *copySize;
copy->destination.mipLevel = destination->mipLevel; copy->destination.mipLevel = destination->mipLevel;
copy->destination.arrayLayer = destination->arrayLayer; copy->copySize = *copySize;
// TODO(cwallez@chromium.org): Make backends use origin.z instead of arrayLayer
copy->destination.arrayLayer = copy->destination.origin.z;
copy->destination.origin.z = 0;
return {}; return {};
}); });
@ -803,17 +798,12 @@ namespace dawn_native {
allocator->Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer); allocator->Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
copy->source.texture = source->texture; copy->source.texture = source->texture;
copy->source.origin = source->origin; copy->source.origin = source->origin;
copy->copySize = *copySize;
copy->source.mipLevel = source->mipLevel; copy->source.mipLevel = source->mipLevel;
copy->source.arrayLayer = source->arrayLayer;
copy->destination.buffer = destination->buffer; copy->destination.buffer = destination->buffer;
copy->destination.offset = destination->offset; copy->destination.offset = destination->offset;
copy->destination.bytesPerRow = destination->bytesPerRow; copy->destination.bytesPerRow = destination->bytesPerRow;
copy->destination.rowsPerImage = defaultedRowsPerImage; copy->destination.rowsPerImage = defaultedRowsPerImage;
copy->copySize = *copySize;
// TODO(cwallez@chromium.org): Make backends use origin.z instead of arrayLayer
copy->source.arrayLayer = copy->source.origin.z;
copy->source.origin.z = 0;
return {}; return {};
}); });
@ -860,19 +850,11 @@ namespace dawn_native {
copy->source.texture = source->texture; copy->source.texture = source->texture;
copy->source.origin = source->origin; copy->source.origin = source->origin;
copy->source.mipLevel = source->mipLevel; copy->source.mipLevel = source->mipLevel;
copy->source.arrayLayer = source->arrayLayer;
copy->destination.texture = destination->texture; copy->destination.texture = destination->texture;
copy->destination.origin = destination->origin; copy->destination.origin = destination->origin;
copy->destination.mipLevel = destination->mipLevel; copy->destination.mipLevel = destination->mipLevel;
copy->destination.arrayLayer = destination->arrayLayer;
copy->copySize = *copySize; copy->copySize = *copySize;
// TODO(cwallez@chromium.org): Make backends use origin.z instead of arrayLayer
copy->source.arrayLayer = copy->source.origin.z;
copy->source.origin.z = 0;
copy->destination.arrayLayer = copy->destination.origin.z;
copy->destination.origin.z = 0;
return {}; return {};
}); });
} }

View File

@ -102,8 +102,7 @@ namespace dawn_native {
struct TextureCopy { struct TextureCopy {
Ref<TextureBase> texture; Ref<TextureBase> texture;
uint32_t mipLevel; uint32_t mipLevel;
uint32_t arrayLayer; Origin3D origin; // Texels / array layer
Origin3D origin; // Texels
}; };
struct CopyBufferToBufferCmd { struct CopyBufferToBufferCmd {

View File

@ -577,11 +577,8 @@ namespace dawn_native { namespace d3d12 {
Texture* texture = ToBackend(copy->destination.texture.Get()); Texture* texture = ToBackend(copy->destination.texture.Get());
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D); ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
// TODO(jiawei.shao@intel.com): use copy->destination.origin.z instead of
// copy->destination.arrayLayer once GPUTextureCopyView.arrayLayer to
// GPUTextureCopyView.origin.z is done.
SubresourceRange subresources = {copy->destination.mipLevel, 1, SubresourceRange subresources = {copy->destination.mipLevel, 1,
copy->destination.arrayLayer, copy->destination.origin.z,
copy->copySize.depth}; copy->copySize.depth};
if (IsCompleteSubresourceCopiedTo(texture, copy->copySize, if (IsCompleteSubresourceCopiedTo(texture, copy->copySize,
copy->destination.mipLevel)) { copy->destination.mipLevel)) {
@ -600,13 +597,15 @@ namespace dawn_native { namespace d3d12 {
const dawn_native::Extent3D copyOneLayerSize = {copy->copySize.width, const dawn_native::Extent3D copyOneLayerSize = {copy->copySize.width,
copy->copySize.height, 1}; copy->copySize.height, 1};
uint64_t bufferOffsetForNextSlice = 0; uint64_t bufferOffsetForNextSlice = 0;
for (uint32_t copySlice = copy->destination.arrayLayer; for (uint32_t copySlice = copy->destination.origin.z;
copySlice < copy->destination.arrayLayer + copy->copySize.depth; copySlice < copy->destination.origin.z + copy->copySize.depth;
++copySlice) { ++copySlice) {
// TODO(jiawei.shao@intel.com): compute copySplit once for all texture array // TODO(jiawei.shao@intel.com): compute copySplit once for all texture array
// layers when possible. // layers when possible.
Origin3D destinationOriginInSubresource = copy->destination.origin;
destinationOriginInSubresource.z = 0;
auto copySplit = ComputeTextureCopySplit( auto copySplit = ComputeTextureCopySplit(
copy->destination.origin, copyOneLayerSize, texture->GetFormat(), destinationOriginInSubresource, copyOneLayerSize, texture->GetFormat(),
bufferOffsetForNextSlice + copy->source.offset, bufferOffsetForNextSlice + copy->source.offset,
copy->source.bytesPerRow, copy->source.rowsPerImage); copy->source.bytesPerRow, copy->source.rowsPerImage);
@ -640,11 +639,8 @@ namespace dawn_native { namespace d3d12 {
Buffer* buffer = ToBackend(copy->destination.buffer.Get()); Buffer* buffer = ToBackend(copy->destination.buffer.Get());
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D); ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
// TODO(jiawei.shao@intel.com): use copy->destination.origin.z instead of
// copy->destination.arrayLayer once GPUTextureCopyView.arrayLayer to
// GPUTextureCopyView.origin.z is done.
SubresourceRange subresources = {copy->source.mipLevel, 1, SubresourceRange subresources = {copy->source.mipLevel, 1,
copy->source.arrayLayer, copy->copySize.depth}; copy->source.origin.z, copy->copySize.depth};
texture->EnsureSubresourceContentInitialized(commandContext, subresources); texture->EnsureSubresourceContentInitialized(commandContext, subresources);
texture->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc, texture->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc,
@ -657,12 +653,14 @@ namespace dawn_native { namespace d3d12 {
const dawn_native::Extent3D copyOneLayerSize = {copy->copySize.width, const dawn_native::Extent3D copyOneLayerSize = {copy->copySize.width,
copy->copySize.height, 1}; copy->copySize.height, 1};
uint64_t bufferOffsetForNextSlice = 0; uint64_t bufferOffsetForNextSlice = 0;
for (uint32_t copySlice = copy->source.arrayLayer; for (uint32_t copySlice = copy->source.origin.z;
copySlice < copy->source.arrayLayer + copy->copySize.depth; ++copySlice) { copySlice < copy->source.origin.z + copy->copySize.depth; ++copySlice) {
// TODO(jiawei.shao@intel.com): compute copySplit once for all texture array // TODO(jiawei.shao@intel.com): compute copySplit once for all texture array
// layers when possible. // layers when possible.
Origin3D sourceOriginInSubresource = copy->source.origin;
sourceOriginInSubresource.z = 0;
TextureCopySplit copySplit = ComputeTextureCopySplit( TextureCopySplit copySplit = ComputeTextureCopySplit(
copy->source.origin, copyOneLayerSize, texture->GetFormat(), sourceOriginInSubresource, copyOneLayerSize, texture->GetFormat(),
bufferOffsetForNextSlice + copy->destination.offset, bufferOffsetForNextSlice + copy->destination.offset,
copy->destination.bytesPerRow, copy->destination.rowsPerImage); copy->destination.bytesPerRow, copy->destination.rowsPerImage);
@ -697,11 +695,10 @@ namespace dawn_native { namespace d3d12 {
Texture* source = ToBackend(copy->source.texture.Get()); Texture* source = ToBackend(copy->source.texture.Get());
Texture* destination = ToBackend(copy->destination.texture.Get()); Texture* destination = ToBackend(copy->destination.texture.Get());
SubresourceRange srcRange = {copy->source.mipLevel, 1, copy->source.arrayLayer, SubresourceRange srcRange = {copy->source.mipLevel, 1, copy->source.origin.z,
copy->copySize.depth}; copy->copySize.depth};
SubresourceRange dstRange = {copy->destination.mipLevel, 1, SubresourceRange dstRange = {copy->destination.mipLevel, 1,
copy->destination.arrayLayer, copy->destination.origin.z, copy->copySize.depth};
copy->copySize.depth};
source->EnsureSubresourceContentInitialized(commandContext, srcRange); source->EnsureSubresourceContentInitialized(commandContext, srcRange);
if (IsCompleteSubresourceCopiedTo(destination, copy->copySize, if (IsCompleteSubresourceCopiedTo(destination, copy->copySize,
@ -717,8 +714,7 @@ namespace dawn_native { namespace d3d12 {
// subresources should all be COMMON instead of what we set now. Currently // subresources should all be COMMON instead of what we set now. Currently
// it is not allowed to copy with overlapped subresources, but we still // it is not allowed to copy with overlapped subresources, but we still
// add the ASSERT here as a reminder for this possible misuse. // add the ASSERT here as a reminder for this possible misuse.
ASSERT(!IsRangeOverlapped(copy->source.arrayLayer, ASSERT(!IsRangeOverlapped(copy->source.origin.z, copy->destination.origin.z,
copy->destination.arrayLayer,
copy->copySize.depth)); copy->copySize.depth));
} }
source->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc, source->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc,
@ -737,21 +733,22 @@ namespace dawn_native { namespace d3d12 {
copy->copySize.width, copy->copySize.height, 1u}; copy->copySize.width, copy->copySize.height, 1u};
for (uint32_t slice = 0; slice < copy->copySize.depth; ++slice) { for (uint32_t slice = 0; slice < copy->copySize.depth; ++slice) {
D3D12_TEXTURE_COPY_LOCATION srcLocation = D3D12_TEXTURE_COPY_LOCATION srcLocation =
ComputeTextureCopyLocationForTexture( ComputeTextureCopyLocationForTexture(source, copy->source.mipLevel,
source, copy->source.mipLevel, copy->source.arrayLayer + slice); copy->source.origin.z + slice);
D3D12_TEXTURE_COPY_LOCATION dstLocation = D3D12_TEXTURE_COPY_LOCATION dstLocation =
ComputeTextureCopyLocationForTexture( ComputeTextureCopyLocationForTexture(
destination, copy->destination.mipLevel, destination, copy->destination.mipLevel,
copy->destination.arrayLayer + slice); copy->destination.origin.z + slice);
Origin3D sourceOriginInSubresource = copy->source.origin;
sourceOriginInSubresource.z = 0;
D3D12_BOX sourceRegion = ComputeD3D12BoxFromOffsetAndSize( D3D12_BOX sourceRegion = ComputeD3D12BoxFromOffsetAndSize(
copy->source.origin, copyExtentOneSlice); sourceOriginInSubresource, copyExtentOneSlice);
commandList->CopyTextureRegion(&dstLocation, copy->destination.origin.x, commandList->CopyTextureRegion(&dstLocation, copy->destination.origin.x,
copy->destination.origin.y, copy->destination.origin.y, 0,
copy->destination.origin.z, &srcLocation, &srcLocation, &sourceRegion);
&sourceRegion);
} }
} }
break; break;

View File

@ -324,10 +324,6 @@ namespace dawn_native { namespace metal {
std::array<CopyInfo, kMaxTextureBufferCopyRegions> copies; std::array<CopyInfo, kMaxTextureBufferCopyRegions> copies;
}; };
MTLOrigin MakeMTLOrigin(Origin3D origin) {
return MTLOriginMake(origin.x, origin.y, origin.z);
}
TextureBufferCopySplit ComputeTextureBufferCopySplit(wgpu::TextureDimension dimension, TextureBufferCopySplit ComputeTextureBufferCopySplit(wgpu::TextureDimension dimension,
Origin3D origin, Origin3D origin,
Extent3D copyExtent, Extent3D copyExtent,
@ -444,18 +440,12 @@ namespace dawn_native { namespace metal {
return copy; return copy;
} }
void EnsureSourceTextureInitialized(Texture* texture,
const Extent3D& size,
const TextureCopy& src) {
texture->EnsureSubresourceContentInitialized(
{src.mipLevel, 1, src.arrayLayer, size.depth});
}
void EnsureDestinationTextureInitialized(Texture* texture, void EnsureDestinationTextureInitialized(Texture* texture,
const Extent3D& size, const TextureCopy& dst,
const TextureCopy& dst) { const Extent3D& size) {
SubresourceRange range = {dst.mipLevel, 1, dst.arrayLayer, size.depth}; ASSERT(texture == dst.texture.Get());
if (IsCompleteSubresourceCopiedTo(texture, size, dst.mipLevel)) { SubresourceRange range = GetSubresourcesAffectedByCopy(dst, size);
if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), size, dst.mipLevel)) {
texture->SetIsSubresourceContentInitialized(true, range); texture->SetIsSubresourceContentInitialized(true, range);
} else { } else {
texture->EnsureSubresourceContentInitialized(range); texture->EnsureSubresourceContentInitialized(range);
@ -748,15 +738,13 @@ namespace dawn_native { namespace metal {
Buffer* buffer = ToBackend(src.buffer.Get()); Buffer* buffer = ToBackend(src.buffer.Get());
Texture* texture = ToBackend(dst.texture.Get()); Texture* texture = ToBackend(dst.texture.Get());
EnsureDestinationTextureInitialized(texture, copy->copySize, copy->destination); EnsureDestinationTextureInitialized(texture, copy->destination, copy->copySize);
const Extent3D virtualSizeAtLevel = const Extent3D virtualSizeAtLevel =
texture->GetMipLevelVirtualSize(dst.mipLevel); texture->GetMipLevelVirtualSize(dst.mipLevel);
Origin3D copyOrigin = dst.origin;
copyOrigin.z = dst.arrayLayer;
TextureBufferCopySplit splitCopies = ComputeTextureBufferCopySplit( TextureBufferCopySplit splitCopies = ComputeTextureBufferCopySplit(
texture->GetDimension(), copyOrigin, copySize, texture->GetFormat(), texture->GetDimension(), dst.origin, copySize, texture->GetFormat(),
virtualSizeAtLevel, buffer->GetSize(), src.offset, src.bytesPerRow, virtualSizeAtLevel, buffer->GetSize(), src.offset, src.bytesPerRow,
src.rowsPerImage); src.rowsPerImage);
@ -797,13 +785,12 @@ namespace dawn_native { namespace metal {
Texture* texture = ToBackend(src.texture.Get()); Texture* texture = ToBackend(src.texture.Get());
Buffer* buffer = ToBackend(dst.buffer.Get()); Buffer* buffer = ToBackend(dst.buffer.Get());
EnsureSourceTextureInitialized(texture, copy->copySize, copy->source); texture->EnsureSubresourceContentInitialized(
GetSubresourcesAffectedByCopy(src, copySize));
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(src.mipLevel); Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(src.mipLevel);
Origin3D copyOrigin = src.origin;
copyOrigin.z = src.arrayLayer;
TextureBufferCopySplit splitCopies = ComputeTextureBufferCopySplit( TextureBufferCopySplit splitCopies = ComputeTextureBufferCopySplit(
texture->GetDimension(), copyOrigin, copySize, texture->GetFormat(), texture->GetDimension(), src.origin, copySize, texture->GetFormat(),
virtualSizeAtLevel, buffer->GetSize(), dst.offset, dst.bytesPerRow, virtualSizeAtLevel, buffer->GetSize(), dst.offset, dst.bytesPerRow,
dst.rowsPerImage); dst.rowsPerImage);
@ -842,28 +829,33 @@ namespace dawn_native { namespace metal {
Texture* srcTexture = ToBackend(copy->source.texture.Get()); Texture* srcTexture = ToBackend(copy->source.texture.Get());
Texture* dstTexture = ToBackend(copy->destination.texture.Get()); Texture* dstTexture = ToBackend(copy->destination.texture.Get());
EnsureSourceTextureInitialized(srcTexture, copy->copySize, copy->source); srcTexture->EnsureSubresourceContentInitialized(
EnsureDestinationTextureInitialized(dstTexture, copy->copySize, GetSubresourcesAffectedByCopy(copy->source, copy->copySize));
copy->destination); EnsureDestinationTextureInitialized(dstTexture, copy->destination,
copy->copySize);
// TODO(jiawei.shao@intel.com): support copies with 1D and 3D textures. // TODO(jiawei.shao@intel.com): support copies with 1D and 3D textures.
ASSERT(srcTexture->GetDimension() == wgpu::TextureDimension::e2D && ASSERT(srcTexture->GetDimension() == wgpu::TextureDimension::e2D &&
dstTexture->GetDimension() == wgpu::TextureDimension::e2D); dstTexture->GetDimension() == wgpu::TextureDimension::e2D);
const MTLSize mtlSizeOneLayer = const MTLSize sizeOneLayer =
MTLSizeMake(copy->copySize.width, copy->copySize.height, 1); MTLSizeMake(copy->copySize.width, copy->copySize.height, 1);
const MTLOrigin sourceOriginNoLayer =
MTLOriginMake(copy->source.origin.x, copy->source.origin.y, 0);
const MTLOrigin destinationOriginNoLayer =
MTLOriginMake(copy->destination.origin.x, copy->destination.origin.y, 0);
for (uint32_t slice = 0; slice < copy->copySize.depth; ++slice) { for (uint32_t slice = 0; slice < copy->copySize.depth; ++slice) {
[commandContext->EnsureBlit() [commandContext->EnsureBlit()
copyFromTexture:srcTexture->GetMTLTexture() copyFromTexture:srcTexture->GetMTLTexture()
sourceSlice:copy->source.arrayLayer + slice sourceSlice:copy->source.origin.z + slice
sourceLevel:copy->source.mipLevel sourceLevel:copy->source.mipLevel
sourceOrigin:MakeMTLOrigin(copy->source.origin) sourceOrigin:sourceOriginNoLayer
sourceSize:mtlSizeOneLayer sourceSize:sizeOneLayer
toTexture:dstTexture->GetMTLTexture() toTexture:dstTexture->GetMTLTexture()
destinationSlice:copy->destination.arrayLayer + slice destinationSlice:copy->destination.origin.z + slice
destinationLevel:copy->destination.mipLevel destinationLevel:copy->destination.mipLevel
destinationOrigin:MakeMTLOrigin(copy->destination.origin)]; destinationOrigin:destinationOriginNoLayer];
} }
break; break;
} }

View File

@ -515,10 +515,7 @@ namespace dawn_native { namespace opengl {
const GLFormat& format = texture->GetGLFormat(); const GLFormat& format = texture->GetGLFormat();
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D); ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
// TODO(jiawei.shao@intel.com): use copy->destination.origin.z instead of SubresourceRange subresources = {dst.mipLevel, 1, dst.origin.z,
// copy->destination.arrayLayer once GPUTextureCopyView.arrayLayer to
// GPUTextureCopyView.origin.z is done.
SubresourceRange subresources = {dst.mipLevel, 1, dst.arrayLayer,
copy->copySize.depth}; copy->copySize.depth};
if (IsCompleteSubresourceCopiedTo(texture, copySize, dst.mipLevel)) { if (IsCompleteSubresourceCopiedTo(texture, copySize, dst.mipLevel)) {
texture->SetIsSubresourceContentInitialized(true, subresources); texture->SetIsSubresourceContentInitialized(true, subresources);
@ -550,7 +547,7 @@ namespace dawn_native { namespace opengl {
if (texture->GetArrayLayers() > 1) { if (texture->GetArrayLayers() > 1) {
gl.CompressedTexSubImage3D( gl.CompressedTexSubImage3D(
target, dst.mipLevel, dst.origin.x, dst.origin.y, dst.arrayLayer, target, dst.mipLevel, dst.origin.x, dst.origin.y, dst.origin.z,
copyExtent.width, copyExtent.height, copyExtent.depth, copyExtent.width, copyExtent.height, copyExtent.depth,
format.internalFormat, copyDataSize, format.internalFormat, copyDataSize,
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset))); reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
@ -565,7 +562,7 @@ namespace dawn_native { namespace opengl {
case wgpu::TextureDimension::e2D: case wgpu::TextureDimension::e2D:
if (texture->GetArrayLayers() > 1) { if (texture->GetArrayLayers() > 1) {
gl.TexSubImage3D(target, dst.mipLevel, dst.origin.x, gl.TexSubImage3D(target, dst.mipLevel, dst.origin.x,
dst.origin.y, dst.arrayLayer, copySize.width, dst.origin.y, dst.origin.z, copySize.width,
copySize.height, copySize.depth, format.format, copySize.height, copySize.depth, format.format,
format.type, format.type,
reinterpret_cast<void*>( reinterpret_cast<void*>(
@ -609,7 +606,7 @@ namespace dawn_native { namespace opengl {
} }
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D); ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
SubresourceRange subresources = {src.mipLevel, 1, src.arrayLayer, SubresourceRange subresources = {src.mipLevel, 1, src.origin.z,
copy->copySize.depth}; copy->copySize.depth};
texture->EnsureSubresourceContentInitialized(subresources); texture->EnsureSubresourceContentInitialized(subresources);
// The only way to move data from a texture to a buffer in GL is via // The only way to move data from a texture to a buffer in GL is via
@ -660,7 +657,7 @@ namespace dawn_native { namespace opengl {
for (uint32_t layer = 0; layer < copySize.depth; ++layer) { for (uint32_t layer = 0; layer < copySize.depth; ++layer) {
gl.FramebufferTextureLayer(GL_READ_FRAMEBUFFER, glAttachment, gl.FramebufferTextureLayer(GL_READ_FRAMEBUFFER, glAttachment,
texture->GetHandle(), src.mipLevel, texture->GetHandle(), src.mipLevel,
src.arrayLayer + layer); src.origin.z + layer);
gl.ReadPixels(src.origin.x, src.origin.y, copySize.width, gl.ReadPixels(src.origin.x, src.origin.y, copySize.width,
copySize.height, glFormat.format, glFormat.type, copySize.height, glFormat.format, glFormat.type,
offset); offset);
@ -696,9 +693,9 @@ namespace dawn_native { namespace opengl {
Extent3D copySize = ComputeTextureCopyExtent(dst, copy->copySize); Extent3D copySize = ComputeTextureCopyExtent(dst, copy->copySize);
Texture* srcTexture = ToBackend(src.texture.Get()); Texture* srcTexture = ToBackend(src.texture.Get());
Texture* dstTexture = ToBackend(dst.texture.Get()); Texture* dstTexture = ToBackend(dst.texture.Get());
SubresourceRange srcRange = {src.mipLevel, 1, src.arrayLayer, SubresourceRange srcRange = {src.mipLevel, 1, src.origin.z,
copy->copySize.depth}; copy->copySize.depth};
SubresourceRange dstRange = {dst.mipLevel, 1, dst.arrayLayer, SubresourceRange dstRange = {dst.mipLevel, 1, dst.origin.z,
copy->copySize.depth}; copy->copySize.depth};
srcTexture->EnsureSubresourceContentInitialized(srcRange); srcTexture->EnsureSubresourceContentInitialized(srcRange);
@ -708,9 +705,9 @@ namespace dawn_native { namespace opengl {
dstTexture->EnsureSubresourceContentInitialized(dstRange); dstTexture->EnsureSubresourceContentInitialized(dstRange);
} }
gl.CopyImageSubData(srcTexture->GetHandle(), srcTexture->GetGLTarget(), gl.CopyImageSubData(srcTexture->GetHandle(), srcTexture->GetGLTarget(),
src.mipLevel, src.origin.x, src.origin.y, src.arrayLayer, src.mipLevel, src.origin.x, src.origin.y, src.origin.z,
dstTexture->GetHandle(), dstTexture->GetGLTarget(), dstTexture->GetHandle(), dstTexture->GetGLTarget(),
dst.mipLevel, dst.origin.x, dst.origin.y, dst.arrayLayer, dst.mipLevel, dst.origin.x, dst.origin.y, dst.origin.z,
copySize.width, copySize.height, copy->copySize.depth); copySize.width, copySize.height, copy->copySize.depth);
break; break;
} }

View File

@ -70,21 +70,21 @@ namespace dawn_native { namespace vulkan {
dstTexture->GetDimension() == wgpu::TextureDimension::e2D); dstTexture->GetDimension() == wgpu::TextureDimension::e2D);
region.srcSubresource.aspectMask = srcTexture->GetVkAspectMask(); region.srcSubresource.aspectMask = srcTexture->GetVkAspectMask();
region.srcSubresource.mipLevel = srcCopy.mipLevel; region.srcSubresource.mipLevel = srcCopy.mipLevel;
region.srcSubresource.baseArrayLayer = srcCopy.arrayLayer; region.srcSubresource.baseArrayLayer = srcCopy.origin.z;
region.srcSubresource.layerCount = copySize.depth; region.srcSubresource.layerCount = copySize.depth;
region.srcOffset.x = srcCopy.origin.x; region.srcOffset.x = srcCopy.origin.x;
region.srcOffset.y = srcCopy.origin.y; region.srcOffset.y = srcCopy.origin.y;
region.srcOffset.z = srcCopy.origin.z; region.srcOffset.z = 0;
region.dstSubresource.aspectMask = dstTexture->GetVkAspectMask(); region.dstSubresource.aspectMask = dstTexture->GetVkAspectMask();
region.dstSubresource.mipLevel = dstCopy.mipLevel; region.dstSubresource.mipLevel = dstCopy.mipLevel;
region.dstSubresource.baseArrayLayer = dstCopy.arrayLayer; region.dstSubresource.baseArrayLayer = dstCopy.origin.z;
region.dstSubresource.layerCount = copySize.depth; region.dstSubresource.layerCount = copySize.depth;
region.dstOffset.x = dstCopy.origin.x; region.dstOffset.x = dstCopy.origin.x;
region.dstOffset.y = dstCopy.origin.y; region.dstOffset.y = dstCopy.origin.y;
region.dstOffset.z = dstCopy.origin.z; region.dstOffset.z = 0;
ASSERT(HasSameTextureCopyExtent(srcCopy, dstCopy, copySize)); ASSERT(HasSameTextureCopyExtent(srcCopy, dstCopy, copySize));
Extent3D imageExtent = ComputeTextureCopyExtent(dstCopy, copySize); Extent3D imageExtent = ComputeTextureCopyExtent(dstCopy, copySize);
@ -507,10 +507,8 @@ namespace dawn_native { namespace vulkan {
mCommands.NextCommand<CopyTextureToTextureCmd>(); mCommands.NextCommand<CopyTextureToTextureCmd>();
TextureCopy& src = copy->source; TextureCopy& src = copy->source;
TextureCopy& dst = copy->destination; TextureCopy& dst = copy->destination;
SubresourceRange srcRange = {src.mipLevel, 1, src.arrayLayer, SubresourceRange srcRange = GetSubresourcesAffectedByCopy(src, copy->copySize);
copy->copySize.depth}; SubresourceRange dstRange = GetSubresourcesAffectedByCopy(dst, copy->copySize);
SubresourceRange dstRange = {dst.mipLevel, 1, dst.arrayLayer,
copy->copySize.depth};
ToBackend(src.texture) ToBackend(src.texture)
->EnsureSubresourceContentInitialized(recordingContext, srcRange); ->EnsureSubresourceContentInitialized(recordingContext, srcRange);
@ -528,10 +526,11 @@ namespace dawn_native { namespace vulkan {
// subresources should all be GENERAL instead of what we set now. Currently // subresources should all be GENERAL instead of what we set now. Currently
// it is not allowed to copy with overlapped subresources, but we still // it is not allowed to copy with overlapped subresources, but we still
// add the ASSERT here as a reminder for this possible misuse. // add the ASSERT here as a reminder for this possible misuse.
ASSERT(!IsRangeOverlapped(src.arrayLayer, dst.arrayLayer, ASSERT(
copy->copySize.depth)); !IsRangeOverlapped(src.origin.z, dst.origin.z, copy->copySize.depth));
} }
// TODO after Yunchao's CL
ToBackend(src.texture) ToBackend(src.texture)
->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopySrc, ->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopySrc,
srcRange); srcRange);

View File

@ -939,9 +939,8 @@ namespace dawn_native { namespace vulkan {
dawn_native::TextureCopy textureCopy; dawn_native::TextureCopy textureCopy;
textureCopy.texture = this; textureCopy.texture = this;
textureCopy.origin = {0, 0, 0}; textureCopy.origin = {0, 0, layer};
textureCopy.mipLevel = level; textureCopy.mipLevel = level;
textureCopy.arrayLayer = layer;
VkBufferImageCopy region = VkBufferImageCopy region =
ComputeBufferImageCopyRegion(bufferCopy, textureCopy, copySize); ComputeBufferImageCopyRegion(bufferCopy, textureCopy, copySize);

View File

@ -81,19 +81,27 @@ namespace dawn_native { namespace vulkan {
region.imageSubresource.aspectMask = texture->GetVkAspectMask(); region.imageSubresource.aspectMask = texture->GetVkAspectMask();
region.imageSubresource.mipLevel = textureCopy.mipLevel; region.imageSubresource.mipLevel = textureCopy.mipLevel;
region.imageSubresource.baseArrayLayer = textureCopy.arrayLayer;
switch (textureCopy.texture->GetDimension()) {
case wgpu::TextureDimension::e2D: {
region.imageOffset.x = textureCopy.origin.x; region.imageOffset.x = textureCopy.origin.x;
region.imageOffset.y = textureCopy.origin.y; region.imageOffset.y = textureCopy.origin.y;
region.imageOffset.z = textureCopy.origin.z; region.imageOffset.z = 0;
region.imageSubresource.baseArrayLayer = textureCopy.origin.z;
region.imageSubresource.layerCount = copySize.depth;
Extent3D imageExtent = ComputeTextureCopyExtent(textureCopy, copySize); Extent3D imageExtent = ComputeTextureCopyExtent(textureCopy, copySize);
region.imageExtent.width = imageExtent.width; region.imageExtent.width = imageExtent.width;
region.imageExtent.height = imageExtent.height; region.imageExtent.height = imageExtent.height;
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
region.imageSubresource.layerCount = copySize.depth;
region.imageExtent.depth = 1; region.imageExtent.depth = 1;
break;
}
default:
UNREACHABLE();
break;
}
return region; return region;
} }

View File

@ -669,10 +669,6 @@ TEST_P(CopyTests_T2B, RowPitchUnaligned) {
// Test that copying whole texture 2D array layers in one texture-to-buffer-copy works. // Test that copying whole texture 2D array layers in one texture-to-buffer-copy works.
TEST_P(CopyTests_T2B, Texture2DArrayRegion) { TEST_P(CopyTests_T2B, Texture2DArrayRegion) {
// TODO(jiawei.shao@intel.com): investigate why copies with multiple texture array layer fail
// with swiftshader.
DAWN_SKIP_TEST_IF(IsSwiftshader());
constexpr uint32_t kWidth = 256; constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128; constexpr uint32_t kHeight = 128;
constexpr uint32_t kLayers = 6u; constexpr uint32_t kLayers = 6u;
@ -687,10 +683,6 @@ TEST_P(CopyTests_T2B, Texture2DArrayRegion) {
// Test that copying a range of texture 2D array layers in one texture-to-buffer-copy works. // Test that copying a range of texture 2D array layers in one texture-to-buffer-copy works.
TEST_P(CopyTests_T2B, Texture2DArraySubRegion) { TEST_P(CopyTests_T2B, Texture2DArraySubRegion) {
// TODO(jiawei.shao@intel.com): investigate why copies with multiple texture array layer fail
// with swiftshader.
DAWN_SKIP_TEST_IF(IsSwiftshader());
constexpr uint32_t kWidth = 256; constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128; constexpr uint32_t kHeight = 128;
constexpr uint32_t kLayers = 6u; constexpr uint32_t kLayers = 6u;
@ -1044,10 +1036,6 @@ TEST_P(CopyTests_B2T, RowPitchUnaligned) {
// Test that copying whole texture 2D array layers in one texture-to-buffer-copy works. // Test that copying whole texture 2D array layers in one texture-to-buffer-copy works.
TEST_P(CopyTests_B2T, Texture2DArrayRegion) { TEST_P(CopyTests_B2T, Texture2DArrayRegion) {
// TODO(jiawei.shao@intel.com): investigate why copies with multiple texture array layers fail
// with swiftshader.
DAWN_SKIP_TEST_IF(IsSwiftshader());
constexpr uint32_t kWidth = 256; constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128; constexpr uint32_t kHeight = 128;
constexpr uint32_t kLayers = 6u; constexpr uint32_t kLayers = 6u;
@ -1062,10 +1050,6 @@ TEST_P(CopyTests_B2T, Texture2DArrayRegion) {
// Test that copying a range of texture 2D array layers in one texture-to-buffer-copy works. // Test that copying a range of texture 2D array layers in one texture-to-buffer-copy works.
TEST_P(CopyTests_B2T, Texture2DArraySubRegion) { TEST_P(CopyTests_B2T, Texture2DArraySubRegion) {
// TODO(jiawei.shao@intel.com): investigate why copies with multiple texture array layers fail
// with swiftshader.
DAWN_SKIP_TEST_IF(IsSwiftshader());
constexpr uint32_t kWidth = 256; constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128; constexpr uint32_t kHeight = 128;
constexpr uint32_t kLayers = 6u; constexpr uint32_t kLayers = 6u;