Support depth-only/stencil-only copies on D3D12
Bug: dawn:439 Change-Id: I919a5e7bcb46f1817f9b15aaf49a1a72680aa47a Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/24960 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
11c0f579b1
commit
37f547456c
|
@ -118,7 +118,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
const D3D12_TEXTURE_COPY_LOCATION bufferLocation =
|
const D3D12_TEXTURE_COPY_LOCATION bufferLocation =
|
||||||
ComputeBufferLocationForCopyTextureRegion(texture, buffer->GetD3D12Resource(),
|
ComputeBufferLocationForCopyTextureRegion(texture, buffer->GetD3D12Resource(),
|
||||||
info.bufferSize, offset,
|
info.bufferSize, offset,
|
||||||
bufferBytesPerRow);
|
bufferBytesPerRow, aspect);
|
||||||
const D3D12_BOX sourceRegion =
|
const D3D12_BOX sourceRegion =
|
||||||
ComputeD3D12BoxFromOffsetAndSize(info.textureOffset, info.copySize);
|
ComputeD3D12BoxFromOffsetAndSize(info.textureOffset, info.copySize);
|
||||||
|
|
||||||
|
@ -706,15 +706,17 @@ namespace dawn_native { namespace d3d12 {
|
||||||
subresources);
|
subresources);
|
||||||
buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopyDst);
|
buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopyDst);
|
||||||
|
|
||||||
|
const TexelBlockInfo& blockInfo =
|
||||||
|
texture->GetFormat().GetTexelBlockInfo(copy->source.aspect);
|
||||||
|
|
||||||
// See comments around ComputeTextureCopySplits() for more details.
|
// See comments around ComputeTextureCopySplits() for more details.
|
||||||
const TextureCopySplits copySplits = ComputeTextureCopySplits(
|
const TextureCopySplits copySplits = ComputeTextureCopySplits(
|
||||||
copy->source.origin, copy->copySize, texture->GetFormat(),
|
copy->source.origin, copy->copySize, blockInfo, copy->destination.offset,
|
||||||
copy->destination.offset, copy->destination.bytesPerRow,
|
copy->destination.bytesPerRow, copy->destination.rowsPerImage);
|
||||||
copy->destination.rowsPerImage);
|
|
||||||
|
|
||||||
const uint64_t bytesPerSlice =
|
const uint64_t bytesPerSlice =
|
||||||
copy->destination.bytesPerRow *
|
copy->destination.bytesPerRow *
|
||||||
(copy->destination.rowsPerImage / texture->GetFormat().blockHeight);
|
(copy->destination.rowsPerImage / blockInfo.blockHeight);
|
||||||
|
|
||||||
// copySplits.copies2D[1] is always calculated for the second copy slice with
|
// copySplits.copies2D[1] is always calculated for the second copy slice with
|
||||||
// extra "bytesPerSlice" copy offset compared with the first copy slice. So
|
// extra "bytesPerSlice" copy offset compared with the first copy slice. So
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "common/Assert.h"
|
#include "common/Assert.h"
|
||||||
#include "dawn_native/BackendConnection.h"
|
#include "dawn_native/BackendConnection.h"
|
||||||
#include "dawn_native/ErrorData.h"
|
#include "dawn_native/ErrorData.h"
|
||||||
|
#include "dawn_native/Format.h"
|
||||||
#include "dawn_native/Instance.h"
|
#include "dawn_native/Instance.h"
|
||||||
#include "dawn_native/d3d12/AdapterD3D12.h"
|
#include "dawn_native/d3d12/AdapterD3D12.h"
|
||||||
#include "dawn_native/d3d12/BackendD3D12.h"
|
#include "dawn_native/d3d12/BackendD3D12.h"
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
namespace dawn_native { namespace d3d12 {
|
namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
Origin3D ComputeTexelOffsets(const Format& format,
|
Origin3D ComputeTexelOffsets(const TexelBlockInfo& blockInfo,
|
||||||
uint32_t offset,
|
uint32_t offset,
|
||||||
uint32_t bytesPerRow,
|
uint32_t bytesPerRow,
|
||||||
uint32_t slicePitch) {
|
uint32_t slicePitch) {
|
||||||
|
@ -32,20 +32,20 @@ namespace dawn_native { namespace d3d12 {
|
||||||
uint32_t byteOffsetY = offset % slicePitch;
|
uint32_t byteOffsetY = offset % slicePitch;
|
||||||
uint32_t byteOffsetZ = offset - byteOffsetY;
|
uint32_t byteOffsetZ = offset - byteOffsetY;
|
||||||
|
|
||||||
return {byteOffsetX / format.blockByteSize * format.blockWidth,
|
return {byteOffsetX / blockInfo.blockByteSize * blockInfo.blockWidth,
|
||||||
byteOffsetY / bytesPerRow * format.blockHeight, byteOffsetZ / slicePitch};
|
byteOffsetY / bytesPerRow * blockInfo.blockHeight, byteOffsetZ / slicePitch};
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Texture2DCopySplit ComputeTextureCopySplit(Origin3D origin,
|
Texture2DCopySplit ComputeTextureCopySplit(Origin3D origin,
|
||||||
Extent3D copySize,
|
Extent3D copySize,
|
||||||
const Format& format,
|
const TexelBlockInfo& blockInfo,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
uint32_t bytesPerRow,
|
uint32_t bytesPerRow,
|
||||||
uint32_t rowsPerImage) {
|
uint32_t rowsPerImage) {
|
||||||
Texture2DCopySplit copy;
|
Texture2DCopySplit copy;
|
||||||
|
|
||||||
ASSERT(bytesPerRow % format.blockByteSize == 0);
|
ASSERT(bytesPerRow % blockInfo.blockByteSize == 0);
|
||||||
|
|
||||||
uint64_t alignedOffset =
|
uint64_t alignedOffset =
|
||||||
offset & ~static_cast<uint64_t>(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1);
|
offset & ~static_cast<uint64_t>(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1);
|
||||||
|
@ -71,12 +71,14 @@ namespace dawn_native { namespace d3d12 {
|
||||||
ASSERT(alignedOffset < offset);
|
ASSERT(alignedOffset < offset);
|
||||||
ASSERT(offset - alignedOffset < D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
|
ASSERT(offset - alignedOffset < D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
|
||||||
|
|
||||||
uint32_t slicePitch = bytesPerRow * (rowsPerImage / format.blockHeight);
|
uint32_t slicePitch = bytesPerRow * (rowsPerImage / blockInfo.blockHeight);
|
||||||
Origin3D texelOffset = ComputeTexelOffsets(
|
Origin3D texelOffset = ComputeTexelOffsets(
|
||||||
format, static_cast<uint32_t>(offset - alignedOffset), bytesPerRow, slicePitch);
|
blockInfo, static_cast<uint32_t>(offset - alignedOffset), bytesPerRow, slicePitch);
|
||||||
|
|
||||||
uint32_t copyBytesPerRowPitch = copySize.width / format.blockWidth * format.blockByteSize;
|
uint32_t copyBytesPerRowPitch =
|
||||||
uint32_t byteOffsetInRowPitch = texelOffset.x / format.blockWidth * format.blockByteSize;
|
copySize.width / blockInfo.blockWidth * blockInfo.blockByteSize;
|
||||||
|
uint32_t byteOffsetInRowPitch =
|
||||||
|
texelOffset.x / blockInfo.blockWidth * blockInfo.blockByteSize;
|
||||||
if (copyBytesPerRowPitch + byteOffsetInRowPitch <= bytesPerRow) {
|
if (copyBytesPerRowPitch + byteOffsetInRowPitch <= bytesPerRow) {
|
||||||
// The region's rows fit inside the bytes per row. In this case, extend the width of the
|
// The region's rows fit inside the bytes per row. In this case, extend the width of the
|
||||||
// PlacedFootprint and copy the buffer with an offset location
|
// PlacedFootprint and copy the buffer with an offset location
|
||||||
|
@ -154,7 +156,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
copy.copies[0].textureOffset = origin;
|
copy.copies[0].textureOffset = origin;
|
||||||
|
|
||||||
ASSERT(bytesPerRow > byteOffsetInRowPitch);
|
ASSERT(bytesPerRow > byteOffsetInRowPitch);
|
||||||
uint32_t texelsPerRow = bytesPerRow / format.blockByteSize * format.blockWidth;
|
uint32_t texelsPerRow = bytesPerRow / blockInfo.blockByteSize * blockInfo.blockWidth;
|
||||||
copy.copies[0].copySize.width = texelsPerRow - texelOffset.x;
|
copy.copies[0].copySize.width = texelsPerRow - texelOffset.x;
|
||||||
copy.copies[0].copySize.height = copySize.height;
|
copy.copies[0].copySize.height = copySize.height;
|
||||||
copy.copies[0].copySize.depth = copySize.depth;
|
copy.copies[0].copySize.depth = copySize.depth;
|
||||||
|
@ -174,10 +176,10 @@ namespace dawn_native { namespace d3d12 {
|
||||||
copy.copies[1].copySize.depth = copySize.depth;
|
copy.copies[1].copySize.depth = copySize.depth;
|
||||||
|
|
||||||
copy.copies[1].bufferOffset.x = 0;
|
copy.copies[1].bufferOffset.x = 0;
|
||||||
copy.copies[1].bufferOffset.y = texelOffset.y + format.blockHeight;
|
copy.copies[1].bufferOffset.y = texelOffset.y + blockInfo.blockHeight;
|
||||||
copy.copies[1].bufferOffset.z = texelOffset.z;
|
copy.copies[1].bufferOffset.z = texelOffset.z;
|
||||||
copy.copies[1].bufferSize.width = copy.copies[1].copySize.width;
|
copy.copies[1].bufferSize.width = copy.copies[1].copySize.width;
|
||||||
copy.copies[1].bufferSize.height = rowsPerImage + texelOffset.y + format.blockHeight;
|
copy.copies[1].bufferSize.height = rowsPerImage + texelOffset.y + blockInfo.blockHeight;
|
||||||
copy.copies[1].bufferSize.depth = copySize.depth + texelOffset.z;
|
copy.copies[1].bufferSize.depth = copySize.depth + texelOffset.z;
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
|
@ -185,13 +187,13 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
TextureCopySplits ComputeTextureCopySplits(Origin3D origin,
|
TextureCopySplits ComputeTextureCopySplits(Origin3D origin,
|
||||||
Extent3D copySize,
|
Extent3D copySize,
|
||||||
const Format& format,
|
const TexelBlockInfo& blockInfo,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
uint32_t bytesPerRow,
|
uint32_t bytesPerRow,
|
||||||
uint32_t rowsPerImage) {
|
uint32_t rowsPerImage) {
|
||||||
TextureCopySplits copies;
|
TextureCopySplits copies;
|
||||||
|
|
||||||
const uint64_t bytesPerSlice = bytesPerRow * (rowsPerImage / format.blockHeight);
|
const uint64_t bytesPerSlice = bytesPerRow * (rowsPerImage / blockInfo.blockHeight);
|
||||||
|
|
||||||
// The function ComputeTextureCopySplit() decides how to split the copy based on:
|
// The function ComputeTextureCopySplit() decides how to split the copy based on:
|
||||||
// - the alignment of the buffer offset with D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT (512)
|
// - the alignment of the buffer offset with D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT (512)
|
||||||
|
@ -207,8 +209,8 @@ namespace dawn_native { namespace d3d12 {
|
||||||
const dawn_native::Extent3D copyOneLayerSize = {copySize.width, copySize.height, 1};
|
const dawn_native::Extent3D copyOneLayerSize = {copySize.width, copySize.height, 1};
|
||||||
const dawn_native::Origin3D copyFirstLayerOrigin = {origin.x, origin.y, 0};
|
const dawn_native::Origin3D copyFirstLayerOrigin = {origin.x, origin.y, 0};
|
||||||
|
|
||||||
copies.copies2D[0] = ComputeTextureCopySplit(copyFirstLayerOrigin, copyOneLayerSize, format,
|
copies.copies2D[0] = ComputeTextureCopySplit(copyFirstLayerOrigin, copyOneLayerSize,
|
||||||
offset, bytesPerRow, rowsPerImage);
|
blockInfo, offset, bytesPerRow, rowsPerImage);
|
||||||
|
|
||||||
// When the copy only refers one texture 2D array layer copies.copies2D[1] will never be
|
// When the copy only refers one texture 2D array layer copies.copies2D[1] will never be
|
||||||
// used so we can safely early return here.
|
// used so we can safely early return here.
|
||||||
|
@ -222,7 +224,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
} else {
|
} else {
|
||||||
const uint64_t bufferOffsetNextLayer = offset + bytesPerSlice;
|
const uint64_t bufferOffsetNextLayer = offset + bytesPerSlice;
|
||||||
copies.copies2D[1] =
|
copies.copies2D[1] =
|
||||||
ComputeTextureCopySplit(copyFirstLayerOrigin, copyOneLayerSize, format,
|
ComputeTextureCopySplit(copyFirstLayerOrigin, copyOneLayerSize, blockInfo,
|
||||||
bufferOffsetNextLayer, bytesPerRow, rowsPerImage);
|
bufferOffsetNextLayer, bytesPerRow, rowsPerImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
|
|
||||||
struct Format;
|
struct TexelBlockInfo;
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
|
||||||
|
@ -51,14 +51,14 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
Texture2DCopySplit ComputeTextureCopySplit(Origin3D origin,
|
Texture2DCopySplit ComputeTextureCopySplit(Origin3D origin,
|
||||||
Extent3D copySize,
|
Extent3D copySize,
|
||||||
const Format& format,
|
const TexelBlockInfo& blockInfo,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
uint32_t bytesPerRow,
|
uint32_t bytesPerRow,
|
||||||
uint32_t rowsPerImage);
|
uint32_t rowsPerImage);
|
||||||
|
|
||||||
TextureCopySplits ComputeTextureCopySplits(Origin3D origin,
|
TextureCopySplits ComputeTextureCopySplits(Origin3D origin,
|
||||||
Extent3D copySize,
|
Extent3D copySize,
|
||||||
const Format& format,
|
const TexelBlockInfo& blockInfo,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
uint32_t bytesPerRow,
|
uint32_t bytesPerRow,
|
||||||
uint32_t rowsPerImage);
|
uint32_t rowsPerImage);
|
||||||
|
|
|
@ -548,6 +548,26 @@ namespace dawn_native { namespace d3d12 {
|
||||||
return mResourceAllocation.GetD3D12Resource();
|
return mResourceAllocation.GetD3D12Resource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DXGI_FORMAT Texture::GetD3D12CopyableSubresourceFormat(Aspect aspect) const {
|
||||||
|
ASSERT(GetFormat().aspects & aspect);
|
||||||
|
|
||||||
|
switch (GetFormat().format) {
|
||||||
|
case wgpu::TextureFormat::Depth24PlusStencil8:
|
||||||
|
switch (aspect) {
|
||||||
|
case Aspect::Depth:
|
||||||
|
return DXGI_FORMAT_R32_FLOAT;
|
||||||
|
case Aspect::Stencil:
|
||||||
|
return DXGI_FORMAT_R8_UINT;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return GetD3D12Format();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ASSERT(HasOneBit(GetFormat().aspects));
|
||||||
|
return GetD3D12Format();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
|
void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
|
||||||
wgpu::TextureUsage usage,
|
wgpu::TextureUsage usage,
|
||||||
const SubresourceRange& range) {
|
const SubresourceRange& range) {
|
||||||
|
@ -967,7 +987,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
D3D12_TEXTURE_COPY_LOCATION bufferLocation =
|
D3D12_TEXTURE_COPY_LOCATION bufferLocation =
|
||||||
ComputeBufferLocationForCopyTextureRegion(
|
ComputeBufferLocationForCopyTextureRegion(
|
||||||
this, ToBackend(uploadHandle.stagingBuffer)->GetResource(),
|
this, ToBackend(uploadHandle.stagingBuffer)->GetResource(),
|
||||||
info.bufferSize, copySplit.offset, bytesPerRow);
|
info.bufferSize, copySplit.offset, bytesPerRow, Aspect::Color);
|
||||||
D3D12_BOX sourceRegion =
|
D3D12_BOX sourceRegion =
|
||||||
ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize);
|
ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize);
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
DXGI_FORMAT GetD3D12Format() const;
|
DXGI_FORMAT GetD3D12Format() const;
|
||||||
ID3D12Resource* GetD3D12Resource() const;
|
ID3D12Resource* GetD3D12Resource() const;
|
||||||
|
DXGI_FORMAT GetD3D12CopyableSubresourceFormat(Aspect aspect) const;
|
||||||
|
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor(uint32_t mipLevel,
|
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor(uint32_t mipLevel,
|
||||||
uint32_t baseArrayLayer,
|
uint32_t baseArrayLayer,
|
||||||
|
|
|
@ -68,7 +68,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 slice,
|
||||||
const 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;
|
||||||
|
@ -82,12 +82,14 @@ namespace dawn_native { namespace d3d12 {
|
||||||
ID3D12Resource* bufferResource,
|
ID3D12Resource* bufferResource,
|
||||||
const Extent3D& bufferSize,
|
const Extent3D& bufferSize,
|
||||||
const uint64_t offset,
|
const uint64_t offset,
|
||||||
const uint32_t rowPitch) {
|
const uint32_t rowPitch,
|
||||||
|
Aspect aspect) {
|
||||||
D3D12_TEXTURE_COPY_LOCATION bufferLocation;
|
D3D12_TEXTURE_COPY_LOCATION bufferLocation;
|
||||||
bufferLocation.pResource = bufferResource;
|
bufferLocation.pResource = bufferResource;
|
||||||
bufferLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
bufferLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||||
bufferLocation.PlacedFootprint.Offset = offset;
|
bufferLocation.PlacedFootprint.Offset = offset;
|
||||||
bufferLocation.PlacedFootprint.Footprint.Format = texture->GetD3D12Format();
|
bufferLocation.PlacedFootprint.Footprint.Format =
|
||||||
|
texture->GetD3D12CopyableSubresourceFormat(aspect);
|
||||||
bufferLocation.PlacedFootprint.Footprint.Width = bufferSize.width;
|
bufferLocation.PlacedFootprint.Footprint.Width = bufferSize.width;
|
||||||
bufferLocation.PlacedFootprint.Footprint.Height = bufferSize.height;
|
bufferLocation.PlacedFootprint.Footprint.Height = bufferSize.height;
|
||||||
bufferLocation.PlacedFootprint.Footprint.Depth = bufferSize.depth;
|
bufferLocation.PlacedFootprint.Footprint.Depth = bufferSize.depth;
|
||||||
|
@ -147,7 +149,8 @@ namespace dawn_native { namespace d3d12 {
|
||||||
Texture* texture,
|
Texture* texture,
|
||||||
uint32_t textureMiplevel,
|
uint32_t textureMiplevel,
|
||||||
uint32_t textureSlice,
|
uint32_t textureSlice,
|
||||||
const Aspect& aspect) {
|
Aspect aspect) {
|
||||||
|
ASSERT(HasOneBit(aspect));
|
||||||
const D3D12_TEXTURE_COPY_LOCATION textureLocation =
|
const D3D12_TEXTURE_COPY_LOCATION textureLocation =
|
||||||
ComputeTextureCopyLocationForTexture(texture, textureMiplevel, textureSlice, aspect);
|
ComputeTextureCopyLocationForTexture(texture, textureMiplevel, textureSlice, aspect);
|
||||||
|
|
||||||
|
@ -160,7 +163,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
// members in Texture2DCopySplit::CopyInfo.
|
// members in Texture2DCopySplit::CopyInfo.
|
||||||
const D3D12_TEXTURE_COPY_LOCATION bufferLocation =
|
const D3D12_TEXTURE_COPY_LOCATION bufferLocation =
|
||||||
ComputeBufferLocationForCopyTextureRegion(texture, bufferResource, info.bufferSize,
|
ComputeBufferLocationForCopyTextureRegion(texture, bufferResource, info.bufferSize,
|
||||||
offsetBytes, bufferBytesPerRow);
|
offsetBytes, bufferBytesPerRow, aspect);
|
||||||
const D3D12_BOX sourceRegion =
|
const D3D12_BOX sourceRegion =
|
||||||
ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize);
|
ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize);
|
||||||
|
|
||||||
|
@ -178,14 +181,14 @@ namespace dawn_native { namespace d3d12 {
|
||||||
const uint64_t offsetBytes,
|
const uint64_t offsetBytes,
|
||||||
const uint32_t bytesPerRow,
|
const uint32_t bytesPerRow,
|
||||||
const uint32_t rowsPerImage,
|
const uint32_t rowsPerImage,
|
||||||
const Aspect& aspects) {
|
Aspect aspect) {
|
||||||
|
ASSERT(HasOneBit(aspect));
|
||||||
// See comments in ComputeTextureCopySplits() for more details.
|
// See comments in ComputeTextureCopySplits() for more details.
|
||||||
const TextureCopySplits copySplits =
|
const TexelBlockInfo& blockInfo = texture->GetFormat().GetTexelBlockInfo(aspect);
|
||||||
ComputeTextureCopySplits(textureCopy.origin, copySize, texture->GetFormat(),
|
const TextureCopySplits copySplits = ComputeTextureCopySplits(
|
||||||
offsetBytes, bytesPerRow, rowsPerImage);
|
textureCopy.origin, copySize, blockInfo, offsetBytes, bytesPerRow, rowsPerImage);
|
||||||
|
|
||||||
const uint64_t bytesPerSlice =
|
const uint64_t bytesPerSlice = bytesPerRow * (rowsPerImage / blockInfo.blockHeight);
|
||||||
bytesPerRow * (rowsPerImage / texture->GetFormat().blockHeight);
|
|
||||||
|
|
||||||
// copySplits.copies2D[1] is always calculated for the second copy slice with
|
// copySplits.copies2D[1] is always calculated for the second copy slice with
|
||||||
// extra "bytesPerSlice" copy offset compared with the first copy slice. So
|
// extra "bytesPerSlice" copy offset compared with the first copy slice. So
|
||||||
|
@ -207,7 +210,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
RecordCopyBufferToTextureFromTextureCopySplit(
|
RecordCopyBufferToTextureFromTextureCopySplit(
|
||||||
commandContext->GetCommandList(), copySplitPerLayerBase, bufferResource,
|
commandContext->GetCommandList(), copySplitPerLayerBase, bufferResource,
|
||||||
bufferOffsetForNextSlice, bytesPerRow, texture, textureCopy.mipLevel,
|
bufferOffsetForNextSlice, bytesPerRow, texture, textureCopy.mipLevel,
|
||||||
copyTextureLayer, aspects);
|
copyTextureLayer, aspect);
|
||||||
|
|
||||||
bufferOffsetsForNextSlice[splitIndex] += bytesPerSlice * copySplits.copies2D.size();
|
bufferOffsetsForNextSlice[splitIndex] += bytesPerSlice * copySplits.copies2D.size();
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,14 +31,15 @@ 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 slice,
|
||||||
const Aspect& aspect);
|
Aspect aspect);
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION ComputeBufferLocationForCopyTextureRegion(
|
D3D12_TEXTURE_COPY_LOCATION ComputeBufferLocationForCopyTextureRegion(
|
||||||
const Texture* texture,
|
const Texture* texture,
|
||||||
ID3D12Resource* bufferResource,
|
ID3D12Resource* bufferResource,
|
||||||
const Extent3D& bufferSize,
|
const Extent3D& bufferSize,
|
||||||
const uint64_t offset,
|
const uint64_t offset,
|
||||||
const uint32_t rowPitch);
|
const uint32_t rowPitch,
|
||||||
|
Aspect aspect);
|
||||||
D3D12_BOX ComputeD3D12BoxFromOffsetAndSize(const Origin3D& offset, const Extent3D& copySize);
|
D3D12_BOX ComputeD3D12BoxFromOffsetAndSize(const Origin3D& offset, const Extent3D& copySize);
|
||||||
|
|
||||||
bool IsTypeless(DXGI_FORMAT format);
|
bool IsTypeless(DXGI_FORMAT format);
|
||||||
|
@ -51,7 +52,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
Texture* texture,
|
Texture* texture,
|
||||||
uint32_t textureMiplevel,
|
uint32_t textureMiplevel,
|
||||||
uint32_t textureSlice,
|
uint32_t textureSlice,
|
||||||
const Aspect& aspect);
|
Aspect aspect);
|
||||||
|
|
||||||
void CopyBufferToTextureWithCopySplit(CommandRecordingContext* commandContext,
|
void CopyBufferToTextureWithCopySplit(CommandRecordingContext* commandContext,
|
||||||
const TextureCopy& textureCopy,
|
const TextureCopy& textureCopy,
|
||||||
|
@ -61,7 +62,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
const uint64_t offset,
|
const uint64_t offset,
|
||||||
const uint32_t bytesPerRow,
|
const uint32_t bytesPerRow,
|
||||||
const uint32_t rowsPerImage,
|
const uint32_t rowsPerImage,
|
||||||
const Aspect& aspect);
|
Aspect aspect);
|
||||||
|
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
|
||||||
|
|
|
@ -320,4 +320,4 @@ TEST_P(DepthStencilCopyTests, ToStencilAspect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(DepthStencilCopyTests, MetalBackend(), VulkanBackend());
|
DAWN_INSTANTIATE_TEST(DepthStencilCopyTests, D3D12Backend(), MetalBackend(), VulkanBackend());
|
||||||
|
|
|
@ -651,10 +651,12 @@ TEST_P(TextureZeroInitTest, IndependentDepthStencilLoadAfterDiscard) {
|
||||||
depthStencilTexture.Get(), 0, 1, 0, 1, WGPUTextureAspect_StencilOnly));
|
depthStencilTexture.Get(), 0, 1, 0, 1, WGPUTextureAspect_StencilOnly));
|
||||||
|
|
||||||
// TODO(crbug.com/dawn/439): Implement stencil copies on other platforms
|
// TODO(crbug.com/dawn/439): Implement stencil copies on other platforms
|
||||||
if (IsMetal() || IsVulkan()) {
|
if (IsMetal() || IsVulkan() || IsD3D12()) {
|
||||||
// Check by copy that the stencil data is 2.
|
// Check by copy that the stencil data is 2.
|
||||||
EXPECT_LAZY_CLEAR(0u, EXPECT_TEXTURE_EQ(uint8_t(2), depthStencilTexture, 0, 0, 0, 0,
|
std::vector<uint8_t> expected(kSize * kSize, 2);
|
||||||
wgpu::TextureAspect::StencilOnly));
|
EXPECT_LAZY_CLEAR(
|
||||||
|
0u, EXPECT_TEXTURE_EQ(expected.data(), depthStencilTexture, 0, 0, kSize, kSize, 0,
|
||||||
|
0, wgpu::TextureAspect::StencilOnly));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -722,10 +724,12 @@ TEST_P(TextureZeroInitTest, IndependentDepthStencilLoadAfterDiscard) {
|
||||||
depthStencilTexture.Get(), 0, 1, 0, 1, WGPUTextureAspect_StencilOnly));
|
depthStencilTexture.Get(), 0, 1, 0, 1, WGPUTextureAspect_StencilOnly));
|
||||||
|
|
||||||
// TODO(crbug.com/dawn/439): Implement stencil copies on other platforms
|
// TODO(crbug.com/dawn/439): Implement stencil copies on other platforms
|
||||||
if (IsMetal() || IsVulkan()) {
|
if (IsMetal() || IsVulkan() || IsD3D12()) {
|
||||||
// Check by copy that the stencil data is 0.
|
// Check by copy that the stencil data is 0.
|
||||||
EXPECT_LAZY_CLEAR(0u, EXPECT_TEXTURE_EQ(uint8_t(0), depthStencilTexture, 0, 0, 0, 0,
|
std::vector<uint8_t> expected(kSize * kSize, 0);
|
||||||
wgpu::TextureAspect::StencilOnly));
|
EXPECT_LAZY_CLEAR(
|
||||||
|
0u, EXPECT_TEXTURE_EQ(expected.data(), depthStencilTexture, 0, 0, kSize, kSize, 0,
|
||||||
|
0, wgpu::TextureAspect::StencilOnly));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -734,7 +738,7 @@ TEST_P(TextureZeroInitTest, IndependentDepthStencilLoadAfterDiscard) {
|
||||||
// Lazy clear of the stencil aspect via copy should not touch depth.
|
// Lazy clear of the stencil aspect via copy should not touch depth.
|
||||||
TEST_P(TextureZeroInitTest, IndependentDepthStencilCopyAfterDiscard) {
|
TEST_P(TextureZeroInitTest, IndependentDepthStencilCopyAfterDiscard) {
|
||||||
// TODO(crbug.com/dawn/439): Implement stencil copies on other platforms
|
// TODO(crbug.com/dawn/439): Implement stencil copies on other platforms
|
||||||
DAWN_SKIP_TEST_IF(!(IsMetal() || IsVulkan()));
|
DAWN_SKIP_TEST_IF(!(IsMetal() || IsVulkan() || IsD3D12()));
|
||||||
|
|
||||||
// TODO(enga): Figure out why this fails on Metal Intel.
|
// TODO(enga): Figure out why this fails on Metal Intel.
|
||||||
DAWN_SKIP_TEST_IF(IsMetal() && IsIntel());
|
DAWN_SKIP_TEST_IF(IsMetal() && IsIntel());
|
||||||
|
@ -767,8 +771,9 @@ TEST_P(TextureZeroInitTest, IndependentDepthStencilCopyAfterDiscard) {
|
||||||
depthStencilTexture.Get(), 0, 1, 0, 1, WGPUTextureAspect_StencilOnly));
|
depthStencilTexture.Get(), 0, 1, 0, 1, WGPUTextureAspect_StencilOnly));
|
||||||
|
|
||||||
// Check by copy that the stencil data is lazily cleared to 0.
|
// Check by copy that the stencil data is lazily cleared to 0.
|
||||||
EXPECT_LAZY_CLEAR(1u, EXPECT_TEXTURE_EQ(uint8_t(0), depthStencilTexture, 0, 0, 0, 0,
|
std::vector<uint8_t> expected(kSize * kSize, 0);
|
||||||
wgpu::TextureAspect::StencilOnly));
|
EXPECT_LAZY_CLEAR(1u, EXPECT_TEXTURE_EQ(expected.data(), depthStencilTexture, 0, 0, kSize,
|
||||||
|
kSize, 0, 0, wgpu::TextureAspect::StencilOnly));
|
||||||
|
|
||||||
// Everything is initialized now
|
// Everything is initialized now
|
||||||
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(depthStencilTexture.Get(), 0, 1, 0,
|
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(depthStencilTexture.Get(), 0, 1, 0,
|
||||||
|
|
Loading…
Reference in New Issue