summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-11-25 20:08:42 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-11-25 20:08:42 +0000
commit3494f0538a108730f9bb25d79416136d2b329af4 (patch)
treec0e82cd48d811954f1cd722f113f8042561b6caf /Graphics/GraphicsEngineD3D12
parentMoved ITextureView::GenerateMips() to IDeviceContext::GenerateMips() (diff)
downloadDiligentCore-3494f0538a108730f9bb25d79416136d2b329af4.tar.gz
DiligentCore-3494f0538a108730f9bb25d79416136d2b329af4.zip
Renamed/moved IBuffer::Map() to IDeviceContext::MapBuffer()
Renamed/moved IBuffer::Unmap() to IDeviceContext::UnmapBuffer() Closed https://github.com/DiligentGraphics/DiligentCore/issues/30 (Removed map type, map flag parameters from IBuffer::Unmap function)
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
-rw-r--r--Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h8
-rw-r--r--Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h10
-rw-r--r--Graphics/GraphicsEngineD3D12/interface/BufferD3D12.h2
-rw-r--r--Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp121
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp121
5 files changed, 134 insertions, 128 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h
index 60bb6907..6d187b53 100644
--- a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h
+++ b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h
@@ -60,9 +60,6 @@ public:
virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override;
- virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override;
- virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags )override;
-
#ifdef DEVELOPMENT
void DvpVerifyDynamicAllocation(class DeviceContextD3D12Impl* pCtx)const;
#endif
@@ -92,12 +89,9 @@ private:
void CreateCBV( D3D12_CPU_DESCRIPTOR_HANDLE CBVDescriptor );
DescriptorHeapAllocation m_CBVDescriptorAllocation;
-#ifdef _DEBUG
- std::vector< std::pair<MAP_TYPE, Uint32>, STDAllocatorRawMem<std::pair<MAP_TYPE, Uint32>> > m_DbgMapType;
-#endif
-
friend class DeviceContextD3D12Impl;
// Array of dynamic allocations for every device context
+ // sizeof(D3D12DynamicAllocation) == 40 (x64)
std::vector<D3D12DynamicAllocation, STDAllocatorRawMem<D3D12DynamicAllocation> > m_DynamicData;
};
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
index 0af2b72a..8f36d9c0 100644
--- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
+++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
@@ -92,6 +92,10 @@ public:
virtual void CopyBuffer(IBuffer *pSrcBuffer, Uint32 SrcOffset, IBuffer *pDstBuffer, Uint32 DstOffset, Uint32 Size)override final;
+ virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, Uint32 MapFlags, PVoid& pMappedData)override final;
+
+ virtual void UnmapBuffer(IBuffer* pBuffer)override final;
+
virtual void UpdateTexture(ITexture* pTexture, Uint32 MipLevel, Uint32 Slice, const Box& DstBox, const TextureSubResData& SubresData)override final;
virtual void CopyTexture(ITexture* pSrcTexture,
@@ -255,6 +259,12 @@ private:
};
};
std::unordered_map<MappedTextureKey, TextureUploadSpace, MappedTextureKey::Hasher> m_MappedTextures;
+
+ struct MappedBufferInfo
+ {
+ MAP_TYPE MapType;
+ };
+ std::unordered_map<BufferD3D12Impl*, MappedBufferInfo> m_MappedBuffers;
};
}
diff --git a/Graphics/GraphicsEngineD3D12/interface/BufferD3D12.h b/Graphics/GraphicsEngineD3D12/interface/BufferD3D12.h
index d4741e01..cd33e740 100644
--- a/Graphics/GraphicsEngineD3D12/interface/BufferD3D12.h
+++ b/Graphics/GraphicsEngineD3D12/interface/BufferD3D12.h
@@ -31,6 +31,8 @@
namespace Diligent
{
+class IDeviceContext;
+
// {3E9B15ED-A289-48DC-8214-C6E3E6177378}
static constexpr INTERFACE_ID IID_BufferD3D12 =
{ 0x3e9b15ed, 0xa289, 0x48dc, { 0x82, 0x14, 0xc6, 0xe3, 0xe6, 0x17, 0x73, 0x78 } };
diff --git a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp
index 82a94489..af521f11 100644
--- a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp
@@ -48,14 +48,6 @@ BufferD3D12Impl :: BufferD3D12Impl(IReferenceCounters* pRefCounters,
BuffDesc,
false
},
-#ifdef _DEBUG
- m_DbgMapType
- {
- 1 + pRenderDeviceD3D12->GetNumDeferredContexts(),
- std::make_pair(static_cast<MAP_TYPE>(-1), static_cast<Uint32>(-1)),
- STD_ALLOCATOR_RAW_MEM(D3D12DynamicAllocation, GetRawAllocator(), "Allocator for vector<pair<MAP_TYPE,Uint32>>")
- },
-#endif
m_DynamicData
{
BuffDesc.Usage == USAGE_DYNAMIC ? (1 + pRenderDeviceD3D12->GetNumDeferredContexts()) : 0,
@@ -276,9 +268,6 @@ BufferD3D12Impl :: BufferD3D12Impl(IReferenceCounters* pRefCounters,
BufferDescFromD3D12Resource(BuffDesc, pd3d12Buffer),
false
},
-#ifdef _DEBUG
- m_DbgMapType(1 + pRenderDeviceD3D12->GetNumDeferredContexts(), std::make_pair(static_cast<MAP_TYPE>(-1), static_cast<Uint32>(-1)), STD_ALLOCATOR_RAW_MEM(D3D12DynamicAllocation, GetRawAllocator(), "Allocator for vector<pair<MAP_TYPE,Uint32>>")),
-#endif
m_DynamicData
{
BuffDesc.Usage == USAGE_DYNAMIC ? (1 + pRenderDeviceD3D12->GetNumDeferredContexts()) : 0,
@@ -305,116 +294,6 @@ BufferD3D12Impl :: ~BufferD3D12Impl()
IMPLEMENT_QUERY_INTERFACE( BufferD3D12Impl, IID_BufferD3D12, TBufferBase )
-void BufferD3D12Impl :: Map(IDeviceContext* pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData)
-{
- TBufferBase::Map( pContext, MapType, MapFlags, pMappedData );
- auto *pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext);
-#ifdef _DEBUG
- if(pDeviceContextD3D12 != nullptr)
- m_DbgMapType[pDeviceContextD3D12->GetContextId()] = std::make_pair(MapType, MapFlags);
-#endif
- if (MapType == MAP_READ )
- {
- LOG_WARNING_MESSAGE_ONCE("Mapping CPU buffer for reading on D3D12 currently requires flushing context and idling GPU");
- pDeviceContextD3D12->Flush();
- auto *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice());
- pDeviceD3D12->IdleGPU();
-
- VERIFY(m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Buffer must be created as USAGE_CPU_ACCESSIBLE to be mapped for reading");
- D3D12_RANGE MapRange;
- MapRange.Begin = 0;
- MapRange.End = m_Desc.uiSizeInBytes;
- m_pd3d12Resource->Map(0, &MapRange, &pMappedData);
- }
- else if(MapType == MAP_WRITE)
- {
- if (m_Desc.Usage == USAGE_CPU_ACCESSIBLE)
- {
- VERIFY(m_pd3d12Resource != nullptr, "USAGE_CPU_ACCESSIBLE buffer mapped for writing must intialize D3D12 resource");
- if (MapFlags & MAP_FLAG_DISCARD)
- {
-
- }
- m_pd3d12Resource->Map(0, nullptr, &pMappedData);
- }
- else if (m_Desc.Usage == USAGE_DYNAMIC)
- {
- VERIFY( (MapFlags & (MAP_FLAG_DISCARD | MAP_FLAG_DO_NOT_SYNCHRONIZE)) != 0, "D3D12 buffer must be mapped for writing with MAP_FLAG_DISCARD or MAP_FLAG_DO_NOT_SYNCHRONIZE flag");
-
- auto *pCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext);
- auto ContextId = pDeviceContextD3D12->GetContextId();
- if ((MapFlags & MAP_FLAG_DISCARD) != 0 || m_DynamicData[ContextId].CPUAddress == nullptr)
- {
- size_t Alignment = (m_Desc.BindFlags & BIND_UNIFORM_BUFFER) ? D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT : 16;
- m_DynamicData[ContextId] = pCtxD3D12->AllocateDynamicSpace(m_Desc.uiSizeInBytes, Alignment);
- }
- else
- {
- VERIFY_EXPR(MapFlags & MAP_FLAG_DO_NOT_SYNCHRONIZE);
- // Reuse previously mapped region
- }
- pMappedData = m_DynamicData[ContextId].CPUAddress;
- }
- else
- {
- LOG_ERROR("Only USAGE_DYNAMIC and USAGE_CPU_ACCESSIBLE D3D12 buffers can be mapped for writing");
- }
- }
- else if(MapType == MAP_READ_WRITE)
- {
- LOG_ERROR("MAP_READ_WRITE is not supported on D3D12");
- }
- else
- {
- LOG_ERROR("Only MAP_WRITE_DISCARD and MAP_READ are currently implemented in D3D12");
- }
-}
-
-void BufferD3D12Impl::Unmap( IDeviceContext* pContext, MAP_TYPE MapType, Uint32 MapFlags )
-{
- TBufferBase::Unmap( pContext, MapType, MapFlags );
- auto *pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext);
- Uint32 CtxId = pDeviceContextD3D12 != nullptr ? pDeviceContextD3D12->GetContextId() : static_cast<Uint32>(-1);
-#ifdef _DEBUG
- if (pDeviceContextD3D12 != nullptr)
- {
- VERIFY(m_DbgMapType[CtxId].first == MapType, "Map type does not match the type provided to Map()");
- VERIFY(m_DbgMapType[CtxId].second == MapFlags, "Map flags do not match the flags provided to Map()");
- }
-#endif
-
- if (MapType == MAP_READ )
- {
- D3D12_RANGE MapRange;
- // It is valid to specify the CPU didn't write any data by passing a range where End is less than or equal to Begin.
- MapRange.Begin = 1;
- MapRange.End = 0;
- m_pd3d12Resource->Unmap(0, &MapRange);
- }
- else if(MapType == MAP_WRITE)
- {
- if (m_Desc.Usage == USAGE_CPU_ACCESSIBLE)
- {
- VERIFY(m_pd3d12Resource != nullptr, "USAGE_CPU_ACCESSIBLE buffer mapped for writing must intialize D3D12 resource");
- m_pd3d12Resource->Unmap(0, nullptr);
- }
- else if (m_Desc.Usage == USAGE_DYNAMIC)
- {
- VERIFY(MapFlags & (MAP_FLAG_DISCARD | MAP_FLAG_DO_NOT_SYNCHRONIZE), "D3D12 buffer must be mapped for writing with MAP_FLAG_DISCARD or MAP_FLAG_DO_NOT_SYNCHRONIZE flag");
- // Copy data into the resource
- if (m_pd3d12Resource)
- {
- pDeviceContextD3D12->UpdateBufferRegion(this, m_DynamicData[CtxId], 0, m_Desc.uiSizeInBytes);
- }
- }
- }
-
-#ifdef _DEBUG
- if(pDeviceContextD3D12 != nullptr)
- m_DbgMapType[CtxId] = std::make_pair(static_cast<MAP_TYPE>(-1), static_cast<Uint32>(-1));
-#endif
-}
-
void BufferD3D12Impl::CreateViewInternal( const BufferViewDesc& OrigViewDesc, IBufferView** ppView, bool bIsDefaultView )
{
VERIFY( ppView != nullptr, "Null pointer provided" );
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index 629ed589..02b87b13 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -693,6 +693,16 @@ namespace Diligent
void DeviceContextD3D12Impl::FinishFrame()
{
+#ifdef DEVELOPMENT
+ for(const auto& MappedBuffIt : m_MappedBuffers)
+ {
+ const auto& BuffDesc = MappedBuffIt.first->GetDesc();
+ if (BuffDesc.Usage == USAGE_DYNAMIC)
+ {
+ LOG_WARNING_MESSAGE("Dynamic buffer '", BuffDesc.Name, "' is still mapped when finishing the frame. The contents of the buffer and mapped address will become invalid");
+ }
+ }
+#endif
if (GetNumCommandsInCtx() != 0)
{
LOG_ERROR_MESSAGE(m_bIsDeferred ?
@@ -937,6 +947,117 @@ namespace Diligent
++m_State.NumCommands;
}
+ void DeviceContextD3D12Impl::MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, Uint32 MapFlags, PVoid& pMappedData)
+ {
+ TDeviceContextBase::MapBuffer(pBuffer, MapType, MapFlags, pMappedData);
+ auto* pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(pBuffer);
+ const auto& BuffDesc = pBufferD3D12->GetDesc();
+ auto* pd3d12Resource = pBufferD3D12->m_pd3d12Resource.p;
+
+#ifdef DEVELOPMENT
+ if (m_MappedBuffers.find(pBufferD3D12) != m_MappedBuffers.end())
+ {
+ LOG_ERROR_MESSAGE("Buffer '", BuffDesc.Name, "' has already been mapped");
+ }
+#endif
+
+ if (MapType == MAP_READ)
+ {
+ LOG_WARNING_MESSAGE_ONCE("Mapping CPU buffer for reading on D3D12 currently requires flushing context and idling GPU");
+ Flush();
+ m_pDevice.RawPtr<RenderDeviceD3D12Impl>()->IdleGPU();
+ VERIFY(BuffDesc.Usage == USAGE_CPU_ACCESSIBLE, "Buffer must be created as USAGE_CPU_ACCESSIBLE to be mapped for reading");
+ D3D12_RANGE MapRange;
+ MapRange.Begin = 0;
+ MapRange.End = BuffDesc.uiSizeInBytes;
+ pd3d12Resource->Map(0, &MapRange, &pMappedData);
+ }
+ else if(MapType == MAP_WRITE)
+ {
+ if (BuffDesc.Usage == USAGE_CPU_ACCESSIBLE)
+ {
+ VERIFY(pd3d12Resource != nullptr, "USAGE_CPU_ACCESSIBLE buffer mapped for writing must intialize D3D12 resource");
+ if (MapFlags & MAP_FLAG_DISCARD)
+ {
+
+ }
+ pd3d12Resource->Map(0, nullptr, &pMappedData);
+ }
+ else if (BuffDesc.Usage == USAGE_DYNAMIC)
+ {
+ VERIFY( (MapFlags & (MAP_FLAG_DISCARD | MAP_FLAG_DO_NOT_SYNCHRONIZE)) != 0, "D3D12 buffer must be mapped for writing with MAP_FLAG_DISCARD or MAP_FLAG_DO_NOT_SYNCHRONIZE flag");
+ auto& DynamicData = pBufferD3D12->m_DynamicData[m_ContextId];
+ if ((MapFlags & MAP_FLAG_DISCARD) != 0 || DynamicData.CPUAddress == nullptr)
+ {
+ size_t Alignment = (BuffDesc.BindFlags & BIND_UNIFORM_BUFFER) ? D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT : 16;
+ DynamicData = AllocateDynamicSpace(BuffDesc.uiSizeInBytes, Alignment);
+ }
+ else
+ {
+ VERIFY_EXPR(MapFlags & MAP_FLAG_DO_NOT_SYNCHRONIZE);
+ // Reuse previously mapped region
+ }
+ pMappedData = DynamicData.CPUAddress;
+ }
+ else
+ {
+ LOG_ERROR("Only USAGE_DYNAMIC and USAGE_CPU_ACCESSIBLE D3D12 buffers can be mapped for writing");
+ }
+ }
+ else if(MapType == MAP_READ_WRITE)
+ {
+ LOG_ERROR("MAP_READ_WRITE is not supported in D3D12");
+ }
+ else
+ {
+ LOG_ERROR("Only MAP_WRITE_DISCARD and MAP_READ are currently implemented in D3D12");
+ }
+ m_MappedBuffers[pBufferD3D12] = MappedBufferInfo{MapType};
+ }
+
+ void DeviceContextD3D12Impl::UnmapBuffer(IBuffer* pBuffer)
+ {
+ TDeviceContextBase::UnmapBuffer(pBuffer);
+ auto* pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(pBuffer);
+ auto MappedBufferIt = m_MappedBuffers.find(pBufferD3D12);
+ if (MappedBufferIt == m_MappedBuffers.end())
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBufferD3D12->GetDesc().Name, "' has not been mapped.");
+ return;
+ }
+ const auto& MapInfo = MappedBufferIt->second;
+ const auto& BuffDesc = pBufferD3D12->GetDesc();
+ auto* pd3d12Resource = pBufferD3D12->m_pd3d12Resource.p;
+
+ auto MapType = MapInfo.MapType;
+ if (MapType == MAP_READ )
+ {
+ D3D12_RANGE MapRange;
+ // It is valid to specify the CPU didn't write any data by passing a range where End is less than or equal to Begin.
+ MapRange.Begin = 1;
+ MapRange.End = 0;
+ pd3d12Resource->Unmap(0, &MapRange);
+ }
+ else if(MapType == MAP_WRITE)
+ {
+ if (BuffDesc.Usage == USAGE_CPU_ACCESSIBLE)
+ {
+ VERIFY(pd3d12Resource != nullptr, "USAGE_CPU_ACCESSIBLE buffer mapped for writing must intialize D3D12 resource");
+ pd3d12Resource->Unmap(0, nullptr);
+ }
+ else if (BuffDesc.Usage == USAGE_DYNAMIC)
+ {
+ // Copy data into the resource
+ if (pd3d12Resource)
+ {
+ UpdateBufferRegion(pBufferD3D12, pBufferD3D12->m_DynamicData[m_ContextId], 0, BuffDesc.uiSizeInBytes);
+ }
+ }
+ }
+
+ m_MappedBuffers.erase(MappedBufferIt);
+ }
+
void DeviceContextD3D12Impl::UpdateTexture(ITexture* pTexture, Uint32 MipLevel, Uint32 Slice, const Box& DstBox, const TextureSubResData& SubresData)
{
TDeviceContextBase::UpdateTexture( pTexture, MipLevel, Slice, DstBox, SubresData );