summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsTools
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-04-16 02:50:18 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-04-16 02:50:18 +0000
commit8add3f24c9843a80ddb4dc800dc3b3c942a6267d (patch)
treedd9f38a6d51ffa105d3d9319b05c52ee385e5ca1 /Graphics/GraphicsTools
parentFixed issue with buffer usage flags (diff)
downloadDiligentCore-8add3f24c9843a80ddb4dc800dc3b3c942a6267d.tar.gz
DiligentCore-8add3f24c9843a80ddb4dc800dc3b3c942a6267d.zip
Fixed grammatic error plus few minor updates
Diffstat (limited to 'Graphics/GraphicsTools')
-rw-r--r--Graphics/GraphicsTools/src/TextureUploaderD3D11.cpp459
-rw-r--r--Graphics/GraphicsTools/src/TextureUploaderGL.cpp387
2 files changed, 431 insertions, 415 deletions
diff --git a/Graphics/GraphicsTools/src/TextureUploaderD3D11.cpp b/Graphics/GraphicsTools/src/TextureUploaderD3D11.cpp
index dbee7022..17fffc39 100644
--- a/Graphics/GraphicsTools/src/TextureUploaderD3D11.cpp
+++ b/Graphics/GraphicsTools/src/TextureUploaderD3D11.cpp
@@ -39,290 +39,299 @@
namespace Diligent
{
- class UploadBufferD3D11 : public UploadBufferBase
- {
- public:
- UploadBufferD3D11(Diligent::IReferenceCounters *pRefCounters, const UploadBufferDesc &Desc, ID3D11Texture2D *pStagingTexture) :
- UploadBufferBase(pRefCounters, Desc),
- m_pStagingTexture(pStagingTexture)
- {}
- ~UploadBufferD3D11()
- {
- if (m_pStagingTexture)
- LOG_INFO_MESSAGE("UploadBufferD3D11: releasing ", m_Desc.Width, 'x', m_Desc.Height, " Fmt=", m_Desc.Format, " staging texture");
- }
- void SetDataPtr(void *pData, size_t RowStride, size_t DepthStride)
- {
- m_pData = pData;
- m_RowStride = RowStride;
- m_DepthStride = DepthStride;
- }
+namespace
+{
- // http://en.cppreference.com/w/cpp/thread/condition_variable
- void WaitForMap()
- {
- m_BufferMappedSignal.Wait();
- }
+class UploadBufferD3D11 : public UploadBufferBase
+{
+public:
+ UploadBufferD3D11(Diligent::IReferenceCounters *pRefCounters, const UploadBufferDesc &Desc, ID3D11Texture2D *pStagingTexture) :
+ UploadBufferBase(pRefCounters, Desc),
+ m_pStagingTexture(pStagingTexture)
+ {}
- void SignalMapped()
- {
- m_BufferMappedSignal.Trigger();
- }
+ ~UploadBufferD3D11()
+ {
+ if (m_pStagingTexture)
+ LOG_INFO_MESSAGE("UploadBufferD3D11: releasing ", m_Desc.Width, 'x', m_Desc.Height, " Fmt=", m_Desc.Format, " staging texture");
+ }
- void SignalCopyScheduled()
- {
- m_CopyScheduledSignal.Trigger();
- }
+ void SetDataPtr(void *pData, size_t RowStride, size_t DepthStride)
+ {
+ m_pData = pData;
+ m_RowStride = RowStride;
+ m_DepthStride = DepthStride;
+ }
- virtual void WaitForCopyScheduled()override final
- {
- m_CopyScheduledSignal.Wait();
- }
+ // http://en.cppreference.com/w/cpp/thread/condition_variable
+ void WaitForMap()
+ {
+ m_BufferMappedSignal.Wait();
+ }
- bool DbgIsCopyScheduled()
- {
- return m_CopyScheduledSignal.IsTriggered();
- }
+ void SignalMapped()
+ {
+ m_BufferMappedSignal.Trigger();
+ }
- bool DbgIsMapped()
- {
- return m_BufferMappedSignal.IsTriggered();
- }
+ void SignalCopyScheduled()
+ {
+ m_CopyScheduledSignal.Trigger();
+ }
- void Reset()
- {
- m_pData = nullptr;
- m_RowStride = 0;
- m_DepthStride = 0;
- m_BufferMappedSignal.Reset();
- m_CopyScheduledSignal.Reset();
- }
+ virtual void WaitForCopyScheduled()override final
+ {
+ m_CopyScheduledSignal.Wait();
+ }
- ID3D11Texture2D* GetStagingTex() { return m_pStagingTexture; }
- private:
- ThreadingTools::Signal m_BufferMappedSignal;
- ThreadingTools::Signal m_CopyScheduledSignal;
- CComPtr<ID3D11Texture2D> m_pStagingTexture;
- };
+ bool DbgIsCopyScheduled()
+ {
+ return m_CopyScheduledSignal.IsTriggered();
+ }
- struct TextureUploaderD3D11::InternalData
+ bool DbgIsMapped()
{
- struct PendingBufferOperation
- {
- enum Operation
- {
- Map,
- Copy,
- MapAndCache
- }operation;
- RefCntAutoPtr<UploadBufferD3D11> pUploadBuffer;
- CComPtr<ID3D11Resource> pd3d11NativeDstTexture;
- UINT DstSubresource = 0;
-
- PendingBufferOperation(Operation op, UploadBufferD3D11* pBuff) :
- operation(op),
- pUploadBuffer(pBuff)
- {}
- PendingBufferOperation(Operation op, UploadBufferD3D11* pBuff, ID3D11Resource *pd3d11DstTex, UINT dstSubres) :
- operation(op),
- pUploadBuffer(pBuff),
- pd3d11NativeDstTexture(pd3d11DstTex),
- DstSubresource(dstSubres)
- {}
- };
+ return m_BufferMappedSignal.IsTriggered();
+ }
- InternalData(IRenderDevice *pDevice)
- {
- RefCntAutoPtr<IRenderDeviceD3D11> pDeviceD3D11(pDevice, IID_RenderDeviceD3D11);
- m_pd3d11NativeDevice = pDeviceD3D11->GetD3D11Device();
- }
+ void Reset()
+ {
+ m_pData = nullptr;
+ m_RowStride = 0;
+ m_DepthStride = 0;
+ m_BufferMappedSignal.Reset();
+ m_CopyScheduledSignal.Reset();
+ }
- CComPtr<ID3D11Device> m_pd3d11NativeDevice;
+ ID3D11Texture2D* GetStagingTex() { return m_pStagingTexture; }
+private:
+ ThreadingTools::Signal m_BufferMappedSignal;
+ ThreadingTools::Signal m_CopyScheduledSignal;
+ CComPtr<ID3D11Texture2D> m_pStagingTexture;
+};
- void SwapMapQueues()
- {
- std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
- m_PendingOperations.swap(m_InWorkOperations);
- }
+} // namespace
- void EnqueCopy(UploadBufferD3D11 *pUploadBuffer, ID3D11Resource *pd3d11DstTex, UINT dstSubres)
- {
- std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
- m_PendingOperations.emplace_back(PendingBufferOperation::Operation::Copy, pUploadBuffer, pd3d11DstTex, dstSubres);
- }
- void EnqueMap(UploadBufferD3D11 *pUploadBuffer, PendingBufferOperation::Operation Op)
+struct TextureUploaderD3D11::InternalData
+{
+ struct PendingBufferOperation
+ {
+ enum Operation
{
- std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
- m_PendingOperations.emplace_back(Op, pUploadBuffer);
- }
+ Map,
+ Copy,
+ MapAndCache
+ }operation;
+ RefCntAutoPtr<UploadBufferD3D11> pUploadBuffer;
+ CComPtr<ID3D11Resource> pd3d11NativeDstTexture;
+ UINT DstSubresource = 0;
+
+ PendingBufferOperation(Operation op, UploadBufferD3D11* pBuff) :
+ operation(op),
+ pUploadBuffer(pBuff)
+ {}
+ PendingBufferOperation(Operation op, UploadBufferD3D11* pBuff, ID3D11Resource *pd3d11DstTex, UINT dstSubres) :
+ operation(op),
+ pUploadBuffer(pBuff),
+ pd3d11NativeDstTexture(pd3d11DstTex),
+ DstSubresource(dstSubres)
+ {}
+ };
- std::mutex m_PendingOperationsMtx;
- std::vector< PendingBufferOperation > m_PendingOperations;
- std::vector< PendingBufferOperation > m_InWorkOperations;
+ InternalData(IRenderDevice *pDevice)
+ {
+ RefCntAutoPtr<IRenderDeviceD3D11> pDeviceD3D11(pDevice, IID_RenderDeviceD3D11);
+ m_pd3d11NativeDevice = pDeviceD3D11->GetD3D11Device();
+ }
- std::mutex m_UploadBuffCacheMtx;
- std::unordered_map< UploadBufferDesc, std::deque< RefCntAutoPtr<UploadBufferD3D11> > > m_UploadBufferCache;
- };
+ CComPtr<ID3D11Device> m_pd3d11NativeDevice;
- TextureUploaderD3D11::TextureUploaderD3D11(IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const TextureUploaderDesc Desc) :
- TextureUploaderBase(pRefCounters, pDevice, Desc),
- m_pInternalData(new InternalData(pDevice))
+ void SwapMapQueues()
{
+ std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
+ m_PendingOperations.swap(m_InWorkOperations);
}
- TextureUploaderD3D11::~TextureUploaderD3D11()
+ void EnqueCopy(UploadBufferD3D11 *pUploadBuffer, ID3D11Resource *pd3d11DstTex, UINT dstSubres)
+ {
+ std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
+ m_PendingOperations.emplace_back(PendingBufferOperation::Operation::Copy, pUploadBuffer, pd3d11DstTex, dstSubres);
+ }
+
+ void EnqueMap(UploadBufferD3D11 *pUploadBuffer, PendingBufferOperation::Operation Op)
+ {
+ std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
+ m_PendingOperations.emplace_back(Op, pUploadBuffer);
+ }
+
+ std::mutex m_PendingOperationsMtx;
+ std::vector< PendingBufferOperation > m_PendingOperations;
+ std::vector< PendingBufferOperation > m_InWorkOperations;
+
+ std::mutex m_UploadBuffCacheMtx;
+ std::unordered_map< UploadBufferDesc, std::deque< RefCntAutoPtr<UploadBufferD3D11> > > m_UploadBufferCache;
+};
+
+TextureUploaderD3D11::TextureUploaderD3D11(IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const TextureUploaderDesc Desc) :
+ TextureUploaderBase(pRefCounters, pDevice, Desc),
+ m_pInternalData(new InternalData(pDevice))
+{
+}
+
+TextureUploaderD3D11::~TextureUploaderD3D11()
+{
+ for (auto BuffQueueIt : m_pInternalData->m_UploadBufferCache)
{
- for (auto BuffQueueIt : m_pInternalData->m_UploadBufferCache)
+ if (BuffQueueIt.second.size())
{
- if (BuffQueueIt.second.size())
- {
- const auto &desc = BuffQueueIt.first;
- auto &FmtInfo = m_pDevice->GetTextureFormatInfo(desc.Format);
- LOG_INFO_MESSAGE("TextureUploaderD3D11: releasing ", BuffQueueIt.second.size(), ' ', desc.Width, 'x', desc.Height, 'x', desc.Depth, ' ', FmtInfo.Name, " staging texture(s) ");
- }
+ const auto &desc = BuffQueueIt.first;
+ auto &FmtInfo = m_pDevice->GetTextureFormatInfo(desc.Format);
+ LOG_INFO_MESSAGE("TextureUploaderD3D11: releasing ", BuffQueueIt.second.size(), ' ', desc.Width, 'x', desc.Height, 'x', desc.Depth, ' ', FmtInfo.Name, " staging texture(s) ");
}
}
+}
- void TextureUploaderD3D11::RenderThreadUpdate(Diligent::IDeviceContext *pContext)
+void TextureUploaderD3D11::RenderThreadUpdate(Diligent::IDeviceContext *pContext)
+{
+ m_pInternalData->SwapMapQueues();
+ if (!m_pInternalData->m_InWorkOperations.empty())
{
- m_pInternalData->SwapMapQueues();
- if (!m_pInternalData->m_InWorkOperations.empty())
+ RefCntAutoPtr<IDeviceContextD3D11> pContextD3D11(pContext, IID_DeviceContextD3D11);
+ auto* pd3d11NativeCtx = pContextD3D11->GetD3D11DeviceContext();
+
+ for (auto &OperationInfo : m_pInternalData->m_InWorkOperations)
{
- RefCntAutoPtr<IDeviceContextD3D11> pContextD3D11(pContext, IID_DeviceContextD3D11);
- auto* pd3d11NativeCtx = pContextD3D11->GetD3D11DeviceContext();
+ auto &pBuffer = OperationInfo.pUploadBuffer;
- for (auto &OperationInfo : m_pInternalData->m_InWorkOperations)
+ switch (OperationInfo.operation)
{
- auto &pBuffer = OperationInfo.pUploadBuffer;
-
- switch (OperationInfo.operation)
+ case InternalData::PendingBufferOperation::MapAndCache:
+ case InternalData::PendingBufferOperation::Map:
{
- case InternalData::PendingBufferOperation::MapAndCache:
- case InternalData::PendingBufferOperation::Map:
+ D3D11_MAPPED_SUBRESOURCE MappedData;
+ auto hr = pd3d11NativeCtx->Map(pBuffer->GetStagingTex(), 0, D3D11_MAP_WRITE, D3D11_MAP_FLAG_DO_NOT_WAIT, &MappedData);
+ if (SUCCEEDED(hr))
+ {
+ pBuffer->SetDataPtr(MappedData.pData, MappedData.RowPitch, MappedData.DepthPitch);
+ pBuffer->SignalMapped();
+ if (OperationInfo.operation == InternalData::PendingBufferOperation::MapAndCache)
+ {
+ std::lock_guard<std::mutex> CacheLock(m_pInternalData->m_UploadBuffCacheMtx);
+ auto &Cache = m_pInternalData->m_UploadBufferCache;
+ Cache[pBuffer->GetDesc()].emplace_back( std::move(pBuffer) );
+ }
+ }
+ else
{
- D3D11_MAPPED_SUBRESOURCE MappedData;
- auto hr = pd3d11NativeCtx->Map(pBuffer->GetStagingTex(), 0, D3D11_MAP_WRITE, D3D11_MAP_FLAG_DO_NOT_WAIT, &MappedData);
- if (SUCCEEDED(hr))
+ if (hr == DXGI_ERROR_WAS_STILL_DRAWING)
{
- pBuffer->SetDataPtr(MappedData.pData, MappedData.RowPitch, MappedData.DepthPitch);
- pBuffer->SignalMapped();
- if (OperationInfo.operation == InternalData::PendingBufferOperation::MapAndCache)
- {
- std::lock_guard<std::mutex> CacheLock(m_pInternalData->m_UploadBuffCacheMtx);
- auto &Cache = m_pInternalData->m_UploadBufferCache;
- Cache[pBuffer->GetDesc()].emplace_back( std::move(pBuffer) );
- }
+ m_pInternalData->EnqueMap(pBuffer, OperationInfo.operation);
}
else
{
- if (hr == DXGI_ERROR_WAS_STILL_DRAWING)
- {
- m_pInternalData->EnqueMap(pBuffer, OperationInfo.operation);
- }
- else
- {
- LOG_ERROR("Unknown DX error when mapping staging texture: ", hr);
- }
+ LOG_ERROR("Unknown DX error when mapping staging texture: ", hr);
}
}
- break;
+ }
+ break;
- case InternalData::PendingBufferOperation::Copy:
- {
- VERIFY(pBuffer->DbgIsMapped(), "Upload buffer must be copied only after it has been mapped");
- pd3d11NativeCtx->Unmap(pBuffer->GetStagingTex(), 0);
- pd3d11NativeCtx->CopySubresourceRegion(OperationInfo.pd3d11NativeDstTexture, OperationInfo.DstSubresource,
- 0, 0, 0, // DstX, DstY, DstZ
- pBuffer->GetStagingTex(),
- 0, // SrcSubresource
- nullptr // pSrcBox
- );
- pBuffer->SignalCopyScheduled();
- }
- break;
+ case InternalData::PendingBufferOperation::Copy:
+ {
+ VERIFY(pBuffer->DbgIsMapped(), "Upload buffer must be copied only after it has been mapped");
+ pd3d11NativeCtx->Unmap(pBuffer->GetStagingTex(), 0);
+ pd3d11NativeCtx->CopySubresourceRegion(OperationInfo.pd3d11NativeDstTexture, OperationInfo.DstSubresource,
+ 0, 0, 0, // DstX, DstY, DstZ
+ pBuffer->GetStagingTex(),
+ 0, // SrcSubresource
+ nullptr // pSrcBox
+ );
+ pBuffer->SignalCopyScheduled();
}
+ break;
}
- m_pInternalData->m_InWorkOperations.clear();
}
+ m_pInternalData->m_InWorkOperations.clear();
}
+}
- void TextureUploaderD3D11::AllocateUploadBuffer(const UploadBufferDesc& Desc, bool IsRenderThread, IUploadBuffer **ppBuffer)
- {
- *ppBuffer = nullptr;
+void TextureUploaderD3D11::AllocateUploadBuffer(const UploadBufferDesc& Desc, bool IsRenderThread, IUploadBuffer **ppBuffer)
+{
+ *ppBuffer = nullptr;
+ {
+ std::lock_guard<std::mutex> CacheLock(m_pInternalData->m_UploadBuffCacheMtx);
+ auto &Cache = m_pInternalData->m_UploadBufferCache;
+ if (!Cache.empty())
{
- std::lock_guard<std::mutex> CacheLock(m_pInternalData->m_UploadBuffCacheMtx);
- auto &Cache = m_pInternalData->m_UploadBufferCache;
- if (!Cache.empty())
+ auto DequeIt = Cache.find(Desc);
+ if (DequeIt != Cache.end())
{
- auto DequeIt = Cache.find(Desc);
- if (DequeIt != Cache.end())
+ auto &Deque = DequeIt->second;
+ if (!Deque.empty())
{
- auto &Deque = DequeIt->second;
- if (!Deque.empty())
- {
- *ppBuffer = Deque.front().Detach();
- Deque.pop_front();
- }
+ *ppBuffer = Deque.front().Detach();
+ Deque.pop_front();
}
}
}
+ }
- if( *ppBuffer == nullptr )
+ if( *ppBuffer == nullptr )
+ {
+ D3D11_TEXTURE2D_DESC StagingTexDesc =
{
- D3D11_TEXTURE2D_DESC StagingTexDesc =
- {
- static_cast<UINT>(Desc.Width),
- static_cast<UINT>(Desc.Height),
- 1, // UINT MipLevels;
- 1, // UINT ArraySize;
- TexFormatToDXGI_Format(Desc.Format),
- {1, 0}, // DXGI_SAMPLE_DESC SampleDesc;
- D3D11_USAGE_STAGING,
- 0, // UINT BindFlags;
- D3D11_CPU_ACCESS_WRITE, // UINT CPUAccessFlags;
- 0, // UINT MiscFlags;
- };
-
- CComPtr<ID3D11Texture2D> pStagingTex;
- HRESULT hr = m_pInternalData->m_pd3d11NativeDevice->CreateTexture2D(&StagingTexDesc, nullptr, &pStagingTex);
- if (FAILED(hr))
- {
- LOG_ERROR_MESSAGE("Failed to allocate staging D3D11 texture");
- return;
- }
-
- LOG_INFO_MESSAGE("TextureUploaderD3D11: created ", Desc.Width, 'x', Desc.Height, ' ', m_pDevice->GetTextureFormatInfo(Desc.Format).Name, " staging texture");
+ static_cast<UINT>(Desc.Width),
+ static_cast<UINT>(Desc.Height),
+ 1, // UINT MipLevels;
+ 1, // UINT ArraySize;
+ TexFormatToDXGI_Format(Desc.Format),
+ {1, 0}, // DXGI_SAMPLE_DESC SampleDesc;
+ D3D11_USAGE_STAGING,
+ 0, // UINT BindFlags;
+ D3D11_CPU_ACCESS_WRITE, // UINT CPUAccessFlags;
+ 0, // UINT MiscFlags;
+ };
- RefCntAutoPtr<UploadBufferD3D11> pUploadBuffer(MakeNewRCObj<UploadBufferD3D11>()(Desc, pStagingTex));
- m_pInternalData->EnqueMap(pUploadBuffer, InternalData::PendingBufferOperation::Map);
- pUploadBuffer->WaitForMap();
- *ppBuffer = pUploadBuffer.Detach();
+ CComPtr<ID3D11Texture2D> pStagingTex;
+ HRESULT hr = m_pInternalData->m_pd3d11NativeDevice->CreateTexture2D(&StagingTexDesc, nullptr, &pStagingTex);
+ if (FAILED(hr))
+ {
+ LOG_ERROR_MESSAGE("Failed to allocate staging D3D11 texture");
+ return;
}
- }
- void TextureUploaderD3D11::ScheduleGPUCopy(Diligent::ITexture *pDstTexture,
- Uint32 ArraySlice,
- Uint32 MipLevel,
- IUploadBuffer *pUploadBuffer)
- {
- auto *pUploadBufferD3D11 = ValidatedCast<UploadBufferD3D11>(pUploadBuffer);
- RefCntAutoPtr<ITextureD3D11> pDstTexD3D11(pDstTexture, IID_TextureD3D11);
- auto *pd3d11NativeDstTex = pDstTexD3D11->GetD3D11Texture();
- const auto &DstTexDesc = pDstTexture->GetDesc();
- UINT DstSubres = D3D11CalcSubresource(static_cast<UINT>(MipLevel), static_cast<UINT>(ArraySlice), static_cast<UINT>(DstTexDesc.MipLevels));
- m_pInternalData->EnqueCopy(pUploadBufferD3D11, pd3d11NativeDstTex, DstSubres);
+ LOG_INFO_MESSAGE("TextureUploaderD3D11: created ", Desc.Width, 'x', Desc.Height, ' ', m_pDevice->GetTextureFormatInfo(Desc.Format).Name, " staging texture");
+
+ RefCntAutoPtr<UploadBufferD3D11> pUploadBuffer(MakeNewRCObj<UploadBufferD3D11>()(Desc, pStagingTex));
+ m_pInternalData->EnqueMap(pUploadBuffer, InternalData::PendingBufferOperation::Map);
+ pUploadBuffer->WaitForMap();
+ *ppBuffer = pUploadBuffer.Detach();
}
+}
- void TextureUploaderD3D11::RecycleBuffer(IUploadBuffer *pUploadBuffer)
- {
- auto *pUploadBufferD3D11 = ValidatedCast<UploadBufferD3D11>(pUploadBuffer);
- VERIFY(pUploadBufferD3D11->DbgIsCopyScheduled(), "Upload buffer must be recycled only after copy operation has been scheduled on the GPU");
- pUploadBufferD3D11->Reset();
+void TextureUploaderD3D11::ScheduleGPUCopy(Diligent::ITexture *pDstTexture,
+ Uint32 ArraySlice,
+ Uint32 MipLevel,
+ IUploadBuffer *pUploadBuffer)
+{
+ auto *pUploadBufferD3D11 = ValidatedCast<UploadBufferD3D11>(pUploadBuffer);
+ RefCntAutoPtr<ITextureD3D11> pDstTexD3D11(pDstTexture, IID_TextureD3D11);
+ auto *pd3d11NativeDstTex = pDstTexD3D11->GetD3D11Texture();
+ const auto &DstTexDesc = pDstTexture->GetDesc();
+ UINT DstSubres = D3D11CalcSubresource(static_cast<UINT>(MipLevel), static_cast<UINT>(ArraySlice), static_cast<UINT>(DstTexDesc.MipLevels));
+ m_pInternalData->EnqueCopy(pUploadBufferD3D11, pd3d11NativeDstTex, DstSubres);
+}
+
+void TextureUploaderD3D11::RecycleBuffer(IUploadBuffer *pUploadBuffer)
+{
+ auto *pUploadBufferD3D11 = ValidatedCast<UploadBufferD3D11>(pUploadBuffer);
+ VERIFY(pUploadBufferD3D11->DbgIsCopyScheduled(), "Upload buffer must be recycled only after copy operation has been scheduled on the GPU");
+ pUploadBufferD3D11->Reset();
- m_pInternalData->EnqueMap(pUploadBufferD3D11, InternalData::PendingBufferOperation::MapAndCache);
- }
-} \ No newline at end of file
+ m_pInternalData->EnqueMap(pUploadBufferD3D11, InternalData::PendingBufferOperation::MapAndCache);
+}
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsTools/src/TextureUploaderGL.cpp b/Graphics/GraphicsTools/src/TextureUploaderGL.cpp
index fa954d93..5b5f2f91 100644
--- a/Graphics/GraphicsTools/src/TextureUploaderGL.cpp
+++ b/Graphics/GraphicsTools/src/TextureUploaderGL.cpp
@@ -32,243 +32,250 @@
namespace Diligent
{
- class UploadBufferGL : public UploadBufferBase
+namespace
+{
+
+class UploadBufferGL : public UploadBufferBase
+{
+public:
+ UploadBufferGL(IReferenceCounters *pRefCounters, const UploadBufferDesc &Desc) :
+ UploadBufferBase(pRefCounters, Desc)
+ {}
+
+ void SetDataPtr(void *pData, size_t RowStride, size_t DepthStride)
{
- public:
- UploadBufferGL(IReferenceCounters *pRefCounters, const UploadBufferDesc &Desc) :
- UploadBufferBase(pRefCounters, Desc)
- {}
+ m_pData = pData;
+ m_RowStride = RowStride;
+ m_DepthStride = DepthStride;
+ }
- void SetDataPtr(void *pData, size_t RowStride, size_t DepthStride)
- {
- m_pData = pData;
- m_RowStride = RowStride;
- m_DepthStride = DepthStride;
- }
+ // http://en.cppreference.com/w/cpp/thread/condition_variable
+ void WaitForMap()
+ {
+ m_BufferMappedSignal.Wait();
+ }
- // http://en.cppreference.com/w/cpp/thread/condition_variable
- void WaitForMap()
- {
- m_BufferMappedSignal.Wait();
- }
+ void SignalMapped()
+ {
+ m_BufferMappedSignal.Trigger();
+ }
- void SignalMapped()
- {
- m_BufferMappedSignal.Trigger();
- }
+ void SignalCopyScheduled()
+ {
+ m_CopyScheduledSignal.Trigger();
+ }
- void SignalCopyScheduled()
- {
- m_CopyScheduledSignal.Trigger();
- }
+ virtual void WaitForCopyScheduled()override final
+ {
+ m_CopyScheduledSignal.Wait();
+ }
- virtual void WaitForCopyScheduled()override final
- {
- m_CopyScheduledSignal.Wait();
- }
+ bool DbgIsCopyScheduled()const { return m_CopyScheduledSignal.IsTriggered(); }
- bool DbgIsCopyScheduled()const { return m_CopyScheduledSignal.IsTriggered(); }
+ void Reset()
+ {
+ m_BufferMappedSignal.Reset();
+ m_CopyScheduledSignal.Reset();
+ m_pData = nullptr;
+ // Do not zero out strides
+ }
- void Reset()
- {
- m_BufferMappedSignal.Reset();
- m_CopyScheduledSignal.Reset();
- m_pData = nullptr;
- // Do not zero out strides
- }
+private:
+ friend class TextureUploaderGL;
+ ThreadingTools::Signal m_BufferMappedSignal;
+ ThreadingTools::Signal m_CopyScheduledSignal;
+ RefCntAutoPtr<IBuffer> m_pStagingBuffer;
+};
- private:
- friend class TextureUploaderGL;
- ThreadingTools::Signal m_BufferMappedSignal;
- ThreadingTools::Signal m_CopyScheduledSignal;
- RefCntAutoPtr<IBuffer> m_pStagingBuffer;
- };
+} // namespace
- struct TextureUploaderGL::InternalData
+
+struct TextureUploaderGL::InternalData
+{
+ void SwapMapQueues()
{
- void SwapMapQueues()
- {
- std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
- m_PendingOperations.swap(m_InWorkOperations);
- }
+ std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
+ m_PendingOperations.swap(m_InWorkOperations);
+ }
- void EnqueCopy(UploadBufferGL *pUploadBuffer, ITexture *pDstTexture, Uint32 dstSlice, Uint32 dstMip)
- {
- std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
- m_PendingOperations.emplace_back(PendingBufferOperation::Operation::Copy, pUploadBuffer, pDstTexture, dstSlice, dstMip);
- }
+ void EnqueCopy(UploadBufferGL *pUploadBuffer, ITexture *pDstTexture, Uint32 dstSlice, Uint32 dstMip)
+ {
+ std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
+ m_PendingOperations.emplace_back(PendingBufferOperation::Operation::Copy, pUploadBuffer, pDstTexture, dstSlice, dstMip);
+ }
- void EnqueMap(UploadBufferGL *pUploadBuffer)
- {
- std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
- m_PendingOperations.emplace_back(PendingBufferOperation::Operation::Map, pUploadBuffer);
- }
+ void EnqueMap(UploadBufferGL *pUploadBuffer)
+ {
+ std::lock_guard<std::mutex> QueueLock(m_PendingOperationsMtx);
+ m_PendingOperations.emplace_back(PendingBufferOperation::Operation::Map, pUploadBuffer);
+ }
- struct PendingBufferOperation
+ struct PendingBufferOperation
+ {
+ enum Operation
{
- enum Operation
- {
- Map,
- Copy
- }operation;
- RefCntAutoPtr<UploadBufferGL> pUploadBuffer;
- RefCntAutoPtr<ITexture> pDstTexture;
- Uint32 DstSlice = 0;
- Uint32 DstMip = 0;
-
- PendingBufferOperation(Operation op, UploadBufferGL* pBuff) :
- operation(op),
- pUploadBuffer(pBuff)
- {}
- PendingBufferOperation(Operation op, UploadBufferGL* pBuff, ITexture *pDstTex, Uint32 dstSlice, Uint32 dstMip) :
- operation(op),
- pUploadBuffer(pBuff),
- pDstTexture(pDstTex),
- DstSlice(dstSlice),
- DstMip(dstMip)
- {}
- };
-
- std::mutex m_PendingOperationsMtx;
- std::vector< PendingBufferOperation > m_PendingOperations;
- std::vector< PendingBufferOperation > m_InWorkOperations;
-
- std::mutex m_UploadBuffCacheMtx;
- std::unordered_map< UploadBufferDesc, std::deque<RefCntAutoPtr<UploadBufferGL> > > m_UploadBufferCache;
+ Map,
+ Copy
+ }operation;
+ RefCntAutoPtr<UploadBufferGL> pUploadBuffer;
+ RefCntAutoPtr<ITexture> pDstTexture;
+ Uint32 DstSlice = 0;
+ Uint32 DstMip = 0;
+
+ PendingBufferOperation(Operation op, UploadBufferGL* pBuff) :
+ operation(op),
+ pUploadBuffer(pBuff)
+ {}
+ PendingBufferOperation(Operation op, UploadBufferGL* pBuff, ITexture *pDstTex, Uint32 dstSlice, Uint32 dstMip) :
+ operation(op),
+ pUploadBuffer(pBuff),
+ pDstTexture(pDstTex),
+ DstSlice(dstSlice),
+ DstMip(dstMip)
+ {}
};
- TextureUploaderGL::TextureUploaderGL(IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const TextureUploaderDesc Desc) :
- TextureUploaderBase(pRefCounters, pDevice, Desc),
- m_pInternalData(new InternalData())
- {
- }
+ std::mutex m_PendingOperationsMtx;
+ std::vector< PendingBufferOperation > m_PendingOperations;
+ std::vector< PendingBufferOperation > m_InWorkOperations;
+
+ std::mutex m_UploadBuffCacheMtx;
+ std::unordered_map< UploadBufferDesc, std::deque<RefCntAutoPtr<UploadBufferGL> > > m_UploadBufferCache;
+};
+
+TextureUploaderGL::TextureUploaderGL(IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const TextureUploaderDesc Desc) :
+ TextureUploaderBase(pRefCounters, pDevice, Desc),
+ m_pInternalData(new InternalData())
+{
+}
- TextureUploaderGL::~TextureUploaderGL()
+TextureUploaderGL::~TextureUploaderGL()
+{
+ for (auto BuffQueueIt : m_pInternalData->m_UploadBufferCache)
{
- for (auto BuffQueueIt : m_pInternalData->m_UploadBufferCache)
+ if (BuffQueueIt.second.size())
{
- if (BuffQueueIt.second.size())
- {
- const auto &desc = BuffQueueIt.first;
- auto &FmtInfo = m_pDevice->GetTextureFormatInfo(desc.Format);
- LOG_INFO_MESSAGE("TextureUploaderGL: releasing ", BuffQueueIt.second.size(), ' ', desc.Width, 'x', desc.Height, 'x', desc.Depth, ' ', FmtInfo.Name, " upload buffer(s) ");
- }
+ const auto &desc = BuffQueueIt.first;
+ auto &FmtInfo = m_pDevice->GetTextureFormatInfo(desc.Format);
+ LOG_INFO_MESSAGE("TextureUploaderGL: releasing ", BuffQueueIt.second.size(), ' ', desc.Width, 'x', desc.Height, 'x', desc.Depth, ' ', FmtInfo.Name, " upload buffer(s) ");
}
}
+}
- void TextureUploaderGL::RenderThreadUpdate(IDeviceContext *pContext)
+void TextureUploaderGL::RenderThreadUpdate(IDeviceContext *pContext)
+{
+ m_pInternalData->SwapMapQueues();
+ if (!m_pInternalData->m_InWorkOperations.empty())
{
- m_pInternalData->SwapMapQueues();
- if (!m_pInternalData->m_InWorkOperations.empty())
+ for (auto &OperationInfo : m_pInternalData->m_InWorkOperations)
{
- for (auto &OperationInfo : m_pInternalData->m_InWorkOperations)
- {
- auto &pBuffer = OperationInfo.pUploadBuffer;
+ auto &pBuffer = OperationInfo.pUploadBuffer;
- switch (OperationInfo.operation)
+ switch (OperationInfo.operation)
+ {
+ case InternalData::PendingBufferOperation::Map:
{
- case InternalData::PendingBufferOperation::Map:
+ Uint32 RowStride = static_cast<Uint32>(pBuffer->GetRowStride());
+ if (pBuffer->m_pStagingBuffer == nullptr)
{
- Uint32 RowStride = static_cast<Uint32>(pBuffer->GetRowStride());
- if (pBuffer->m_pStagingBuffer == nullptr)
- {
- const auto &Desc = pBuffer->GetDesc();
- BufferDesc BuffDesc;
- BuffDesc.Name = "Staging buffer for UploadBufferGL";
- BuffDesc.CPUAccessFlags = CPU_ACCESS_WRITE;
- BuffDesc.Usage = USAGE_STAGING;
-
- const auto &TexFmtInfo = m_pDevice->GetTextureFormatInfo(Desc.Format);
- RowStride = Desc.Width * Uint32{TexFmtInfo.ComponentSize} * Uint32{TexFmtInfo.NumComponents};
- const Uint32 Alignment = 16;
- const Uint32 AlignmentMask = Alignment-1;
- RowStride = (RowStride + AlignmentMask) & (~AlignmentMask);
-
- BuffDesc.uiSizeInBytes = Desc.Height * RowStride;
- RefCntAutoPtr<IBuffer> pStagingBuffer;
- m_pDevice->CreateBuffer(BuffDesc, nullptr, &pBuffer->m_pStagingBuffer);
- }
-
- PVoid CpuAddress = nullptr;
- pContext->MapBuffer(pBuffer->m_pStagingBuffer, MAP_WRITE, MAP_FLAG_DISCARD, CpuAddress);
- pBuffer->SetDataPtr(CpuAddress, RowStride, 0);
-
- pBuffer->SignalMapped();
+ const auto &Desc = pBuffer->GetDesc();
+ BufferDesc BuffDesc;
+ BuffDesc.Name = "Staging buffer for UploadBufferGL";
+ BuffDesc.CPUAccessFlags = CPU_ACCESS_WRITE;
+ BuffDesc.Usage = USAGE_STAGING;
+
+ const auto &TexFmtInfo = m_pDevice->GetTextureFormatInfo(Desc.Format);
+ RowStride = Desc.Width * Uint32{TexFmtInfo.ComponentSize} * Uint32{TexFmtInfo.NumComponents};
+ const Uint32 Alignment = 16;
+ const Uint32 AlignmentMask = Alignment-1;
+ RowStride = (RowStride + AlignmentMask) & (~AlignmentMask);
+
+ BuffDesc.uiSizeInBytes = Desc.Height * RowStride;
+ RefCntAutoPtr<IBuffer> pStagingBuffer;
+ m_pDevice->CreateBuffer(BuffDesc, nullptr, &pBuffer->m_pStagingBuffer);
}
- break;
- case InternalData::PendingBufferOperation::Copy:
- {
- pContext->UnmapBuffer(pBuffer->m_pStagingBuffer, MAP_WRITE);
- TextureSubResData SubResData(pBuffer->m_pStagingBuffer, 0, static_cast<Uint32>(pBuffer->GetRowStride()));
- Box DstBox;
- const auto &TexDesc = OperationInfo.pDstTexture->GetDesc();
- DstBox.MaxX = TexDesc.Width;
- DstBox.MaxY = TexDesc.Height;
- pContext->UpdateTexture(OperationInfo.pDstTexture, OperationInfo.DstMip, OperationInfo.DstSlice, DstBox,
- SubResData, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
- pBuffer->SignalCopyScheduled();
- }
- break;
+ PVoid CpuAddress = nullptr;
+ pContext->MapBuffer(pBuffer->m_pStagingBuffer, MAP_WRITE, MAP_FLAG_DISCARD, CpuAddress);
+ pBuffer->SetDataPtr(CpuAddress, RowStride, 0);
+
+ pBuffer->SignalMapped();
}
+ break;
+
+ case InternalData::PendingBufferOperation::Copy:
+ {
+ pContext->UnmapBuffer(pBuffer->m_pStagingBuffer, MAP_WRITE);
+ TextureSubResData SubResData(pBuffer->m_pStagingBuffer, 0, static_cast<Uint32>(pBuffer->GetRowStride()));
+ Box DstBox;
+ const auto &TexDesc = OperationInfo.pDstTexture->GetDesc();
+ DstBox.MaxX = TexDesc.Width;
+ DstBox.MaxY = TexDesc.Height;
+ pContext->UpdateTexture(OperationInfo.pDstTexture, OperationInfo.DstMip, OperationInfo.DstSlice, DstBox,
+ SubResData, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
+ pBuffer->SignalCopyScheduled();
+ }
+ break;
}
- m_pInternalData->m_InWorkOperations.clear();
}
+ m_pInternalData->m_InWorkOperations.clear();
}
+}
- void TextureUploaderGL::AllocateUploadBuffer(const UploadBufferDesc& Desc, bool IsRenderThread, IUploadBuffer **ppBuffer)
- {
- *ppBuffer = nullptr;
- RefCntAutoPtr<UploadBufferGL> pUploadBuffer;
+void TextureUploaderGL::AllocateUploadBuffer(const UploadBufferDesc& Desc, bool IsRenderThread, IUploadBuffer **ppBuffer)
+{
+ *ppBuffer = nullptr;
+ RefCntAutoPtr<UploadBufferGL> pUploadBuffer;
+ {
+ std::lock_guard<std::mutex> CacheLock(m_pInternalData->m_UploadBuffCacheMtx);
+ auto &Cache = m_pInternalData->m_UploadBufferCache;
+ if (!Cache.empty())
{
- std::lock_guard<std::mutex> CacheLock(m_pInternalData->m_UploadBuffCacheMtx);
- auto &Cache = m_pInternalData->m_UploadBufferCache;
- if (!Cache.empty())
+ auto DequeIt = Cache.find(Desc);
+ if (DequeIt != Cache.end())
{
- auto DequeIt = Cache.find(Desc);
- if (DequeIt != Cache.end())
+ auto &Deque = DequeIt->second;
+ if (!Deque.empty())
{
- auto &Deque = DequeIt->second;
- if (!Deque.empty())
- {
- pUploadBuffer.Attach(Deque.front().Detach());
- Deque.pop_front();
- }
+ pUploadBuffer.Attach(Deque.front().Detach());
+ Deque.pop_front();
}
}
}
-
- if( !pUploadBuffer )
- {
- pUploadBuffer = MakeNewRCObj<UploadBufferGL>()(Desc);
- LOG_INFO_MESSAGE("TextureUploaderGL: created upload buffer for ", Desc.Width, 'x', Desc.Height, 'x', Desc.Depth, ' ', m_pDevice->GetTextureFormatInfo(Desc.Format).Name, " texture");
- }
-
- m_pInternalData->EnqueMap(pUploadBuffer);
- pUploadBuffer->WaitForMap();
- *ppBuffer = pUploadBuffer.Detach();
}
- void TextureUploaderGL::ScheduleGPUCopy(ITexture *pDstTexture,
- Uint32 ArraySlice,
- Uint32 MipLevel,
- IUploadBuffer *pUploadBuffer)
+ if( !pUploadBuffer )
{
- auto *pUploadBufferGL = ValidatedCast<UploadBufferGL>(pUploadBuffer);
- m_pInternalData->EnqueCopy(pUploadBufferGL, pDstTexture, ArraySlice, MipLevel);
+ pUploadBuffer = MakeNewRCObj<UploadBufferGL>()(Desc);
+ LOG_INFO_MESSAGE("TextureUploaderGL: created upload buffer for ", Desc.Width, 'x', Desc.Height, 'x', Desc.Depth, ' ', m_pDevice->GetTextureFormatInfo(Desc.Format).Name, " texture");
}
- void TextureUploaderGL::RecycleBuffer(IUploadBuffer *pUploadBuffer)
- {
- auto *pUploadBufferGL = ValidatedCast<UploadBufferGL>(pUploadBuffer);
- VERIFY(pUploadBufferGL->DbgIsCopyScheduled(), "Upload buffer must be recycled only after copy operation has been scheduled on the GPU");
- pUploadBufferGL->Reset();
+ m_pInternalData->EnqueMap(pUploadBuffer);
+ pUploadBuffer->WaitForMap();
+ *ppBuffer = pUploadBuffer.Detach();
+}
- std::lock_guard<std::mutex> CacheLock(m_pInternalData->m_UploadBuffCacheMtx);
- auto &Cache = m_pInternalData->m_UploadBufferCache;
- auto &Deque = Cache[pUploadBufferGL->GetDesc()];
- Deque.emplace_back( pUploadBufferGL );
- }
+void TextureUploaderGL::ScheduleGPUCopy(ITexture *pDstTexture,
+ Uint32 ArraySlice,
+ Uint32 MipLevel,
+ IUploadBuffer *pUploadBuffer)
+{
+ auto *pUploadBufferGL = ValidatedCast<UploadBufferGL>(pUploadBuffer);
+ m_pInternalData->EnqueCopy(pUploadBufferGL, pDstTexture, ArraySlice, MipLevel);
}
+
+void TextureUploaderGL::RecycleBuffer(IUploadBuffer *pUploadBuffer)
+{
+ auto *pUploadBufferGL = ValidatedCast<UploadBufferGL>(pUploadBuffer);
+ VERIFY(pUploadBufferGL->DbgIsCopyScheduled(), "Upload buffer must be recycled only after copy operation has been scheduled on the GPU");
+ pUploadBufferGL->Reset();
+
+ std::lock_guard<std::mutex> CacheLock(m_pInternalData->m_UploadBuffCacheMtx);
+ auto &Cache = m_pInternalData->m_UploadBufferCache;
+ auto &Deque = Cache[pUploadBufferGL->GetDesc()];
+ Deque.emplace_back( pUploadBufferGL );
+}
+
+} // namespace Diligent