summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-08-28 14:42:08 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-08-28 14:42:08 +0000
commitad97af5a953b8c158e0896ae25e72afe4d1c3a9e (patch)
treee76a9ef4dffa2d63ba2cf339918841b5effe6d6e /Graphics/GraphicsEngineD3D12
parentUpdated LockHelper to spin few times before yielding thread (diff)
downloadDiligentCore-ad97af5a953b8c158e0896ae25e72afe4d1c3a9e.tar.gz
DiligentCore-ad97af5a953b8c158e0896ae25e72afe4d1c3a9e.zip
Fixed https://github.com/DiligentGraphics/DiligentCore/issues/17 (Add support for Update Texture on DX12)
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
-rw-r--r--Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h27
-rw-r--r--Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp78
-rw-r--r--Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp14
4 files changed, 96 insertions, 25 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
index 3fd9c1f8..ae006d32 100644
--- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
+++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
@@ -109,13 +109,34 @@ public:
void UpdateBufferRegion(class BufferD3D12Impl *pBuffD3D12, struct DynamicAllocation& Allocation, Uint64 DstOffset, Uint64 NumBytes);
void UpdateBufferRegion(class BufferD3D12Impl *pBuffD3D12, const void *pData, Uint64 DstOffset, Uint64 NumBytes);
void CopyBufferRegion(class BufferD3D12Impl *pSrcBuffD3D12, class BufferD3D12Impl *pDstBuffD3D12, Uint64 SrcOffset, Uint64 DstOffset, Uint64 NumBytes);
- void CopyTextureRegion(class TextureD3D12Impl *pSrcTexture, Uint32 SrcSubResIndex, const D3D12_BOX *pD3D12SrcBox,
+ void CopyTextureRegion(class TextureD3D12Impl *pSrcTexture, Uint32 SrcSubResIndex, const D3D12_BOX* pD3D12SrcBox,
class TextureD3D12Impl *pDstTexture, Uint32 DstSubResIndex, Uint32 DstX, Uint32 DstY, Uint32 DstZ);
- void CopyTextureRegion(IBuffer *pSrcBuffer, Uint32 SrcStride, Uint32 SrcDepthStride, class TextureD3D12Impl *pTextureD3D12, Uint32 DstSubResIndex, const Box &DstBox);
+ void CopyTextureRegion(IBuffer* pSrcBuffer,
+ Uint32 SrcOffset,
+ Uint32 SrcStride,
+ Uint32 SrcDepthStride,
+ class TextureD3D12Impl* pTextureD3D12,
+ Uint32 DstSubResIndex,
+ const Box& DstBox);
+ void CopyTextureRegion(ID3D12Resource* pd3d12Buffer,
+ Uint32 SrcOffset,
+ Uint32 SrcStride,
+ Uint32 SrcDepthStride,
+ Uint32 BufferSize,
+ class TextureD3D12Impl* pTextureD3D12,
+ Uint32 DstSubResIndex,
+ const Box& DstBox);
+
+ void UpdateTextureRegion(const void* pSrcData,
+ Uint32 SrcStride,
+ Uint32 SrcDepthStride,
+ class TextureD3D12Impl* pTextureD3D12,
+ Uint32 DstSubResIndex,
+ const Box& DstBox);
void GenerateMips(class TextureViewD3D12Impl *pTexView);
- struct DynamicAllocation AllocateDynamicSpace(size_t NumBytes);
+ struct DynamicAllocation AllocateDynamicSpace(size_t NumBytes, size_t Alignment);
Uint32 GetContextId()const{return m_ContextId;}
diff --git a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp
index f0a9e4b3..92b734f4 100644
--- a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp
@@ -354,7 +354,7 @@ void BufferD3D12Impl :: Map(IDeviceContext* pContext, MAP_TYPE MapType, Uint32 M
auto ContextId = pDeviceContextD3D12->GetContextId();
if ((MapFlags & MAP_FLAG_DISCARD) != 0 || m_DynamicData[ContextId].CPUAddress == nullptr)
{
- m_DynamicData[ContextId] = pCtxD3D12->AllocateDynamicSpace(m_Desc.uiSizeInBytes);
+ m_DynamicData[ContextId] = pCtxD3D12->AllocateDynamicSpace(m_Desc.uiSizeInBytes, 0);
}
else
{
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index 66477281..70dddbcd 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -690,9 +690,9 @@ namespace Diligent
}
}
- DynamicAllocation DeviceContextD3D12Impl::AllocateDynamicSpace(size_t NumBytes)
+ DynamicAllocation DeviceContextD3D12Impl::AllocateDynamicSpace(size_t NumBytes, size_t Alignment)
{
- return m_pUploadHeap->Allocate(NumBytes);
+ return m_pUploadHeap->Allocate(NumBytes + Alignment);
}
void DeviceContextD3D12Impl::UpdateBufferRegion(class BufferD3D12Impl* pBuffD3D12, DynamicAllocation& Allocation, Uint64 DstOffset, Uint64 NumBytes)
@@ -754,12 +754,16 @@ namespace Diligent
++m_NumCommandsInCurCtx;
}
- void DeviceContextD3D12Impl::CopyTextureRegion(IBuffer* pSrcBuffer, Uint32 SrcStride, Uint32 SrcDepthStride, class TextureD3D12Impl* pTextureD3D12, Uint32 DstSubResIndex, const Box& DstBox)
+ void DeviceContextD3D12Impl::CopyTextureRegion(ID3D12Resource* pd3d12Buffer,
+ Uint32 SrcOffset,
+ Uint32 SrcStride,
+ Uint32 SrcDepthStride,
+ Uint32 BufferSize,
+ class TextureD3D12Impl* pTextureD3D12,
+ Uint32 DstSubResIndex,
+ const Box& DstBox)
{
- auto *pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(pSrcBuffer);
const auto& TexDesc = pTextureD3D12->GetDesc();
- VERIFY(pBufferD3D12->GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Staging buffer is expected to always be in D3D12_RESOURCE_STATE_GENERIC_READ state");
-
auto *pCmdCtx = RequestCmdContext();
auto *pCmdList = pCmdCtx->GetCommandList();
auto TextureState = pTextureD3D12->GetState();
@@ -781,16 +785,16 @@ namespace Diligent
D3D12_TEXTURE_COPY_LOCATION SrcLocation;
SrcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
- SrcLocation.pResource = pBufferD3D12->GetD3D12Resource();
+ SrcLocation.pResource = pd3d12Buffer;
D3D12_PLACED_SUBRESOURCE_FOOTPRINT &Footpring = SrcLocation.PlacedFootprint;
- Footpring.Offset = 0;
- Footpring.Footprint.Width = static_cast<UINT>(DstBox.MaxX - DstBox.MinX);
+ Footpring.Offset = SrcOffset;
+ Footpring.Footprint.Width = static_cast<UINT>(DstBox.MaxX - DstBox.MinX);
Footpring.Footprint.Height = static_cast<UINT>(DstBox.MaxY - DstBox.MinY);
- Footpring.Footprint.Depth = static_cast<UINT>(DstBox.MaxZ - DstBox.MinZ); // Depth cannot be 0
+ Footpring.Footprint.Depth = static_cast<UINT>(DstBox.MaxZ - DstBox.MinZ); // Depth cannot be 0
Footpring.Footprint.Format = TexFormatToDXGI_Format(TexDesc.Format);
Footpring.Footprint.RowPitch = static_cast<UINT>(SrcStride);
- VERIFY(Footpring.Footprint.RowPitch * Footpring.Footprint.Height * Footpring.Footprint.Depth <= pBufferD3D12->GetDesc().uiSizeInBytes, "Buffer is not large enough");
+ VERIFY(Footpring.Footprint.RowPitch * Footpring.Footprint.Height * Footpring.Footprint.Depth <= BufferSize, "Buffer is not large enough");
VERIFY(SrcDepthStride == 0 || static_cast<UINT>(SrcDepthStride) == Footpring.Footprint.RowPitch * Footpring.Footprint.Height, "Depth stride must be equal to the size 2D level");
D3D12_BOX D3D12SrcBox;
@@ -815,6 +819,58 @@ namespace Diligent
}
}
+ void DeviceContextD3D12Impl::CopyTextureRegion(IBuffer* pSrcBuffer,
+ Uint32 SrcOffset,
+ Uint32 SrcStride,
+ Uint32 SrcDepthStride,
+ class TextureD3D12Impl* pTextureD3D12,
+ Uint32 DstSubResIndex,
+ const Box& DstBox)
+ {
+ auto* pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(pSrcBuffer);
+ VERIFY(pBufferD3D12->GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Staging buffer is expected to always be in D3D12_RESOURCE_STATE_GENERIC_READ state");
+ CopyTextureRegion(pBufferD3D12->GetD3D12Resource(), SrcOffset, SrcStride, SrcDepthStride, pBufferD3D12->GetDesc().uiSizeInBytes, pTextureD3D12, DstSubResIndex, DstBox);
+ }
+
+ void DeviceContextD3D12Impl::UpdateTextureRegion(const void* pSrcData,
+ Uint32 SrcStride,
+ Uint32 SrcDepthStride,
+ TextureD3D12Impl* pTextureD3D12,
+ Uint32 DstSubResIndex,
+ const Box& DstBox)
+ {
+ const auto& TexDesc = pTextureD3D12->GetDesc();
+ const auto& FmtAttribs = GetTextureFormatAttribs(TexDesc.Format);
+ VERIFY_EXPR(DstBox.MaxX > DstBox.MinX && DstBox.MaxY > DstBox.MinY && DstBox.MaxZ > DstBox.MinZ);
+ auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX;
+ auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY;
+ auto UpdateRegionDepth = DstBox.MaxZ - DstBox.MinZ;
+ auto BufferDataStride = UpdateRegionWidth * FmtAttribs.ComponentSize * FmtAttribs.NumComponents;
+ auto BufferDataDepthStride = UpdateRegionHeight * BufferDataStride;
+ auto MemorySize = UpdateRegionDepth * BufferDataDepthStride;
+ auto UploadSpace = AllocateDynamicSpace(MemorySize, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
+ auto AlignedOffset = (UploadSpace.Offset + (D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT-1)) & ~(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT-1);
+
+ for(Uint32 slice = 0; slice < UpdateRegionDepth; ++slice)
+ {
+ for(Uint32 row = 0; row < UpdateRegionHeight; ++row)
+ {
+ const auto* pSrcPtr =
+ reinterpret_cast<const Uint8*>(pSrcData)
+ + row * SrcStride
+ + slice * SrcDepthStride;
+ auto* pDstPtr =
+ reinterpret_cast<Uint8*>(UploadSpace.CPUAddress)
+ + (AlignedOffset - UploadSpace.Offset)
+ + row * BufferDataStride
+ + slice * BufferDataDepthStride;
+
+ memcpy(pDstPtr, pSrcPtr, BufferDataStride);
+ }
+ }
+ CopyTextureRegion(UploadSpace.pBuffer, static_cast<Uint32>(AlignedOffset), BufferDataStride, BufferDataDepthStride, MemorySize, pTextureD3D12, DstSubResIndex, DstBox);
+ }
+
void DeviceContextD3D12Impl::GenerateMips(TextureViewD3D12Impl* pTexView)
{
auto *pCtx = RequestCmdContext();
diff --git a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
index bf01b26c..77d8894f 100644
--- a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
@@ -408,19 +408,13 @@ void TextureD3D12Impl::UpdateData( IDeviceContext* pContext,
const TextureSubResData& SubresData )
{
TTextureBase::UpdateData( pContext, MipLevel, Slice, DstBox, SubresData );
- if (SubresData.pSrcBuffer == nullptr)
- {
- LOG_ERROR("D3D12 does not allow updating texture subresource from CPU memory");
- return;
- }
-
- VERIFY( m_Desc.Usage == USAGE_DEFAULT, "Only default usage resiurces can be updated with UpdateData()" );
auto *pCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext);
-
auto DstSubResIndex = D3D12CalcSubresource(MipLevel, Slice, 0, m_Desc.MipLevels, m_Desc.ArraySize);
-
- pCtxD3D12->CopyTextureRegion(SubresData.pSrcBuffer, SubresData.Stride, SubresData.DepthStride, this, DstSubResIndex, DstBox);
+ if (SubresData.pSrcBuffer == nullptr)
+ pCtxD3D12->UpdateTextureRegion(SubresData.pData, SubresData.Stride, SubresData.DepthStride, this, DstSubResIndex, DstBox);
+ else
+ pCtxD3D12->CopyTextureRegion(SubresData.pSrcBuffer, 0, SubresData.Stride, SubresData.DepthStride, this, DstSubResIndex, DstBox);
}
void TextureD3D12Impl :: CopyData(IDeviceContext* pContext,