use hash table for pool buffers

This commit is contained in:
Jack Andersen 2016-12-10 20:18:41 -10:00
parent 25fadc7348
commit c057068e64
8 changed files with 118 additions and 45 deletions

View File

@ -26,6 +26,7 @@ class GLDataFactory : public IGraphicsDataFactory
void destroyPool(IGraphicsBufferPool*); void destroyPool(IGraphicsBufferPool*);
IGraphicsBufferD* newPoolBuffer(IGraphicsBufferPool* pool, BufferUse use, IGraphicsBufferD* newPoolBuffer(IGraphicsBufferPool* pool, BufferUse use,
size_t stride, size_t count); size_t stride, size_t count);
void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf);
public: public:
GLDataFactory(IGraphicsContext* parent, uint32_t drawSamples); GLDataFactory(IGraphicsContext* parent, uint32_t drawSamples);
~GLDataFactory() {destroyAllData();} ~GLDataFactory() {destroyAllData();}

View File

@ -266,6 +266,7 @@ private:
virtual void destroyPool(IGraphicsBufferPool*)=0; virtual void destroyPool(IGraphicsBufferPool*)=0;
virtual IGraphicsBufferD* newPoolBuffer(IGraphicsBufferPool* pool, BufferUse use, virtual IGraphicsBufferD* newPoolBuffer(IGraphicsBufferPool* pool, BufferUse use,
size_t stride, size_t count)=0; size_t stride, size_t count)=0;
virtual void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf)=0;
}; };
using FactoryCommitFunc = std::function<bool(IGraphicsDataFactory::Context& ctx)>; using FactoryCommitFunc = std::function<bool(IGraphicsDataFactory::Context& ctx)>;
@ -368,6 +369,11 @@ public:
{ {
return m_factory->newPoolBuffer(m_pool, use, stride, count); return m_factory->newPoolBuffer(m_pool, use, stride, count);
} }
void deletePoolBuffer(IGraphicsBufferD* buf)
{
m_factory->deletePoolBuffer(m_pool, buf);
}
}; };
} }

View File

@ -97,6 +97,7 @@ class VulkanDataFactory : public IGraphicsDataFactory
void destroyAllData(); void destroyAllData();
IGraphicsBufferD* newPoolBuffer(IGraphicsBufferPool *pool, BufferUse use, IGraphicsBufferD* newPoolBuffer(IGraphicsBufferPool *pool, BufferUse use,
size_t stride, size_t count); size_t stride, size_t count);
void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf);
public: public:
VulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx, uint32_t drawSamples); VulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx, uint32_t drawSamples);
~VulkanDataFactory() {destroyAllData();} ~VulkanDataFactory() {destroyAllData();}

View File

@ -59,22 +59,37 @@ struct D3D11Data : IGraphicsData
} }
}; };
class D3D11GraphicsBufferD;
struct D3D11Pool : IGraphicsBufferPool struct D3D11Pool : IGraphicsBufferPool
{ {
size_t m_deleteCountdown = 4; struct Buffer
std::vector<std::unique_ptr<class D3D11GraphicsBufferD>> m_DBufs;
bool decref()
{ {
if (!m_deleteCountdown) size_t m_deleteCountdown = 4;
Log.report(logvisor::Fatal, "Can't decrement 0-data"); std::unique_ptr<D3D11GraphicsBufferD> m_buf;
--m_deleteCountdown; Buffer(D3D11GraphicsBufferD* buf) : m_buf(buf) {}
if (!m_deleteCountdown)
bool decref()
{ {
delete this; if (!m_deleteCountdown)
return true; Log.report(logvisor::Fatal, "Can't decrement 0-data");
--m_deleteCountdown;
if (!m_deleteCountdown)
{
delete this;
return true;
}
return false;
} }
return false; };
std::unordered_map<D3D11GraphicsBufferD*, Buffer*> m_DBufs;
void destroyPool(std::unordered_set<D3D11Pool::Buffer*>& delsOut)
{
for (auto& b : m_DBufs)
delsOut.emplace(b.second);
m_DBufs.clear();
} }
}; };
@ -1060,9 +1075,11 @@ void D3D11GraphicsBufferD::update(ID3D11DeviceContext* ctx, int b)
{ {
ID3D11Buffer* res = m_bufs[b].Get(); ID3D11Buffer* res = m_bufs[b].Get();
D3D11_MAPPED_SUBRESOURCE d; D3D11_MAPPED_SUBRESOURCE d;
ctx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d); if (SUCCEEDED(ctx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d)))
memcpy(d.pData, m_cpuBuf.get(), m_cpuSz); {
ctx->Unmap(res, 0); memcpy(d.pData, m_cpuBuf.get(), m_cpuSz);
ctx->Unmap(res, 0);
}
m_validSlots |= slot; m_validSlots |= slot;
} }
} }
@ -1129,7 +1146,7 @@ class D3D11DataFactory : public ID3DDataFactory
std::unordered_set<D3D11Pool*> m_committedPools; std::unordered_set<D3D11Pool*> m_committedPools;
std::mutex m_committedMutex; std::mutex m_committedMutex;
std::unordered_set<D3D11Data*> m_deletedData; std::unordered_set<D3D11Data*> m_deletedData;
std::unordered_set<D3D11Pool*> m_deletedPools; std::unordered_set<D3D11Pool::Buffer*> m_deletedPoolBufs;
uint32_t m_sampleCount; uint32_t m_sampleCount;
void destroyData(IGraphicsData* d) void destroyData(IGraphicsData* d)
@ -1146,7 +1163,7 @@ class D3D11DataFactory : public ID3DDataFactory
for (IGraphicsData* data : m_committedData) for (IGraphicsData* data : m_committedData)
m_deletedData.insert(static_cast<D3D11Data*>(data)); m_deletedData.insert(static_cast<D3D11Data*>(data));
for (IGraphicsBufferPool* pool : m_committedPools) for (IGraphicsBufferPool* pool : m_committedPools)
m_deletedPools.insert(static_cast<D3D11Pool*>(pool)); static_cast<D3D11Pool*>(pool)->destroyPool(m_deletedPoolBufs);
m_committedData.clear(); m_committedData.clear();
m_committedPools.clear(); m_committedPools.clear();
} }
@ -1156,7 +1173,7 @@ class D3D11DataFactory : public ID3DDataFactory
std::unique_lock<std::mutex> lk(m_committedMutex); std::unique_lock<std::mutex> lk(m_committedMutex);
D3D11Pool* pool = static_cast<D3D11Pool*>(p); D3D11Pool* pool = static_cast<D3D11Pool*>(p);
m_committedPools.erase(pool); m_committedPools.erase(pool);
m_deletedPools.insert(pool); pool->destroyPool(m_deletedPoolBufs);
} }
void procDeletes() void procDeletes()
@ -1171,12 +1188,12 @@ class D3D11DataFactory : public ID3DDataFactory
} }
++it; ++it;
} }
for (auto it = m_deletedPools.begin(); it != m_deletedPools.end();) for (auto it = m_deletedPoolBufs.begin(); it != m_deletedPoolBufs.end();)
{ {
D3D11Pool* cpool = static_cast<D3D11Pool*>(*it); D3D11Pool::Buffer* cpool = *it;
if (cpool->decref()) if (cpool->decref())
{ {
it = m_deletedPools.erase(it); it = m_deletedPoolBufs.erase(it);
continue; continue;
} }
++it; ++it;
@ -1189,10 +1206,21 @@ class D3D11DataFactory : public ID3DDataFactory
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue()); D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue());
D3D11Pool* pool = static_cast<D3D11Pool*>(p); D3D11Pool* pool = static_cast<D3D11Pool*>(p);
D3D11GraphicsBufferD* retval = new D3D11GraphicsBufferD(q, use, m_ctx, stride, count); D3D11GraphicsBufferD* retval = new D3D11GraphicsBufferD(q, use, m_ctx, stride, count);
pool->m_DBufs.emplace_back(retval); pool->m_DBufs.emplace(std::make_pair(retval, new D3D11Pool::Buffer(retval)));
return retval; return retval;
} }
void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf)
{
D3D11Pool* pool = static_cast<D3D11Pool*>(p);
auto search = pool->m_DBufs.find(static_cast<D3D11GraphicsBufferD*>(buf));
if (search != pool->m_DBufs.end())
{
m_deletedPoolBufs.emplace(search->second);
pool->m_DBufs.erase(search);
}
}
public: public:
D3D11DataFactory(IGraphicsContext* parent, D3D11Context* ctx, uint32_t sampleCount) D3D11DataFactory(IGraphicsContext* parent, D3D11Context* ctx, uint32_t sampleCount)
: m_parent(parent), m_ctx(ctx), m_sampleCount(sampleCount) : m_parent(parent), m_ctx(ctx), m_sampleCount(sampleCount)
@ -1404,8 +1432,8 @@ void D3D11CommandQueue::ProcessDynamicLoads(ID3D11DeviceContext* ctx)
} }
for (D3D11Pool* p : gfxF->m_committedPools) for (D3D11Pool* p : gfxF->m_committedPools)
{ {
for (std::unique_ptr<D3D11GraphicsBufferD>& b : p->m_DBufs) for (auto& b : p->m_DBufs)
b->update(ctx, m_drawBuf); b.second->m_buf->update(ctx, m_drawBuf);
} }
} }

View File

@ -64,7 +64,7 @@ struct D3D12Pool : IGraphicsBufferPool
Buffer(ComPtr<ID3D12Heap>&& heap, class D3D12GraphicsBufferD* buf) Buffer(ComPtr<ID3D12Heap>&& heap, class D3D12GraphicsBufferD* buf)
: m_bufHeap(std::move(heap)), m_buf(buf) {} : m_bufHeap(std::move(heap)), m_buf(buf) {}
}; };
std::vector<Buffer> m_DBufs; std::unordered_map<class D3D12GraphicsBufferD*, Buffer> m_DBufs;
}; };
static const D3D12_RESOURCE_STATES USE_TABLE[] = static const D3D12_RESOURCE_STATES USE_TABLE[] =
@ -1586,10 +1586,16 @@ class D3D12DataFactory : public ID3DDataFactory
/* Place resources */ /* Place resources */
PlaceBufferForGPU(retval, m_ctx, bufHeap.Get(), 0); PlaceBufferForGPU(retval, m_ctx, bufHeap.Get(), 0);
pool->m_DBufs.emplace_back(std::move(bufHeap), retval); pool->m_DBufs.emplace(std::make_pair(retval, D3D12Pool::Buffer{std::move(bufHeap), retval}));
return retval; return retval;
} }
void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf)
{
D3D12Pool* pool = static_cast<D3D12Pool*>(p);
pool->m_DBufs.erase(static_cast<D3D12GraphicsBufferD*>(buf));
}
public: public:
D3D12DataFactory(IGraphicsContext* parent, D3D12Context* ctx, uint32_t sampleCount) D3D12DataFactory(IGraphicsContext* parent, D3D12Context* ctx, uint32_t sampleCount)
: m_parent(parent), m_ctx(ctx), m_sampleCount(sampleCount) : m_parent(parent), m_ctx(ctx), m_sampleCount(sampleCount)
@ -1893,8 +1899,8 @@ void D3D12CommandQueue::execute()
} }
for (D3D12Pool* p : gfxF->m_committedPools) for (D3D12Pool* p : gfxF->m_committedPools)
{ {
for (D3D12Pool::Buffer& b : p->m_DBufs) for (auto& b : p->m_DBufs)
b.m_buf->update(m_fillBuf); b.second.m_buf->update(m_fillBuf);
} }
datalk.unlock(); datalk.unlock();

View File

@ -6,6 +6,7 @@
#include <mutex> #include <mutex>
#include <condition_variable> #include <condition_variable>
#include <array> #include <array>
#include <unordered_map>
#include "logvisor/logvisor.hpp" #include "logvisor/logvisor.hpp"
@ -32,7 +33,7 @@ struct GLData : IGraphicsData
struct GLPool : IGraphicsBufferPool struct GLPool : IGraphicsBufferPool
{ {
std::vector<std::unique_ptr<class GLGraphicsBufferD>> m_DBufs; std::unordered_map<class GLGraphicsBufferD*, std::unique_ptr<class GLGraphicsBufferD>> m_DBufs;
}; };
static const GLenum USE_TABLE[] = static const GLenum USE_TABLE[] =
@ -738,10 +739,16 @@ IGraphicsBufferD* GLDataFactory::newPoolBuffer(IGraphicsBufferPool* p, BufferUse
{ {
GLPool* pool = static_cast<GLPool*>(p); GLPool* pool = static_cast<GLPool*>(p);
GLGraphicsBufferD* retval = new GLGraphicsBufferD(use, stride * count); GLGraphicsBufferD* retval = new GLGraphicsBufferD(use, stride * count);
pool->m_DBufs.emplace_back(retval); pool->m_DBufs.emplace(std::make_pair(retval, retval));
return retval; return retval;
} }
void GLDataFactory::deletePoolBuffer(IGraphicsBufferPool *p, IGraphicsBufferD *buf)
{
GLPool* pool = static_cast<GLPool*>(p);
pool->m_DBufs.erase(static_cast<GLGraphicsBufferD*>(buf));
}
static const GLint SEMANTIC_COUNT_TABLE[] = static const GLint SEMANTIC_COUNT_TABLE[] =
{ {
0, 0,
@ -1297,8 +1304,8 @@ struct GLCommandQueue : IGraphicsCommandQueue
} }
for (GLPool* p : gfxF->m_committedPools) for (GLPool* p : gfxF->m_committedPools)
{ {
for (std::unique_ptr<GLGraphicsBufferD>& b : p->m_DBufs) for (auto& b : p->m_DBufs)
b->update(m_completeBuf); b.second->update(m_completeBuf);
} }
datalk.unlock(); datalk.unlock();
glFlush(); glFlush();

View File

@ -687,14 +687,14 @@ struct VulkanPool : IGraphicsBufferPool
Buffer(VkDeviceMemory mem, class VulkanGraphicsBufferD* buf) Buffer(VkDeviceMemory mem, class VulkanGraphicsBufferD* buf)
: m_bufMem(mem), m_buffer(buf) {} : m_bufMem(mem), m_buffer(buf) {}
}; };
std::vector<Buffer> m_DBufs; std::unordered_map<class VulkanGraphicsBufferD*, Buffer> m_DBufs;
bool m_dead = false; bool m_dead = false;
VulkanPool(VulkanContext* ctx) : m_ctx(ctx) {} VulkanPool(VulkanContext* ctx) : m_ctx(ctx) {}
~VulkanPool() ~VulkanPool()
{ {
for (Buffer& buf : m_DBufs) for (auto& buf : m_DBufs)
if (buf.m_bufMem) if (buf.second.m_bufMem)
vk::FreeMemory(m_ctx->m_dev, buf.m_bufMem, nullptr); vk::FreeMemory(m_ctx->m_dev, buf.second.m_bufMem, nullptr);
} }
}; };
@ -3221,10 +3221,16 @@ IGraphicsBufferD* VulkanDataFactory::newPoolBuffer(IGraphicsBufferPool* p, Buffe
retval->placeForGPU(m_ctx, bufMem); retval->placeForGPU(m_ctx, bufMem);
} }
pool->m_DBufs.emplace_back(bufMem, retval); pool->m_DBufs.emplace(std::make_pair(retval, VulkanPool::Buffer{bufMem, retval}));
return retval; return retval;
} }
void VulkanDataFactory::deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf)
{
VulkanPool* pool = static_cast<VulkanPool*>(p);
pool->m_DBufs.erase(static_cast<VulkanGraphicsBufferD*>(buf));
}
GraphicsBufferPoolToken VulkanDataFactory::newBufferPool() GraphicsBufferPoolToken VulkanDataFactory::newBufferPool()
{ {
std::unique_lock<std::mutex> lk(m_committedMutex); std::unique_lock<std::mutex> lk(m_committedMutex);
@ -3252,8 +3258,8 @@ void VulkanCommandQueue::execute()
} }
for (VulkanPool* p : gfxF->m_committedPools) for (VulkanPool* p : gfxF->m_committedPools)
{ {
for (VulkanPool::Buffer& b : p->m_DBufs) for (auto& b : p->m_DBufs)
b.m_buffer->update(m_fillBuf); b.second.m_buffer->update(m_fillBuf);
} }
datalk.unlock(); datalk.unlock();

View File

@ -142,7 +142,7 @@ public:
#if _WIN32_WINNT_WIN10 #if _WIN32_WINNT_WIN10
HMODULE d3d12lib = LoadLibraryW(L"D3D12.dll"); HMODULE d3d12lib = LoadLibraryW(L"D3D12.dll");
if (!no12 && !noD3d && d3d12lib) if (!no12 && !noD3d && d3d12lib)
{ {
#if _DEBUG #if _DEBUG
{ {
PFN_D3D12_GET_DEBUG_INTERFACE MyD3D12GetDebugInterface = PFN_D3D12_GET_DEBUG_INTERFACE MyD3D12GetDebugInterface =
@ -165,15 +165,32 @@ public:
if (!MyD3D12CreateDevice) if (!MyD3D12CreateDevice)
Log.report(logvisor::Fatal, "unable to find D3D12CreateDevice in D3D12.dll"); Log.report(logvisor::Fatal, "unable to find D3D12CreateDevice in D3D12.dll");
/* Obtain DXGI Factory */
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx12.m_dxFactory);
if (FAILED(hr))
Log.report(logvisor::Fatal, "unable to create DXGI factory");
/* Adapter */
ComPtr<IDXGIAdapter1> ppAdapter;
for (UINT adapterIndex = 0; ; ++adapterIndex)
{
ComPtr<IDXGIAdapter1> pAdapter;
if (DXGI_ERROR_NOT_FOUND == m_3dCtx.m_ctx12.m_dxFactory->EnumAdapters1(adapterIndex, &pAdapter))
break;
// Check to see if the adapter supports Direct3D 12, but don't create the
// actual device yet.
if (SUCCEEDED(MyD3D12CreateDevice(pAdapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
{
ppAdapter = std::move(pAdapter);
break;
}
}
/* Create device */ /* Create device */
HRESULT hr = MyD3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), &m_3dCtx.m_ctx12.m_dev); hr = ppAdapter ? MyD3D12CreateDevice(ppAdapter.Get(), D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), &m_3dCtx.m_ctx12.m_dev) : E_FAIL;
if (!FAILED(hr)) if (!FAILED(hr))
{ {
/* Obtain DXGI Factory */
hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx12.m_dxFactory);
if (FAILED(hr))
Log.report(logvisor::Fatal, "unable to create DXGI factory");
/* Establish loader objects */ /* Establish loader objects */
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
__uuidof(ID3D12CommandAllocator), &m_3dCtx.m_ctx12.m_loadqalloc))) __uuidof(ID3D12CommandAllocator), &m_3dCtx.m_ctx12.m_loadqalloc)))
@ -204,6 +221,7 @@ public:
{ {
/* Some Win10 client HW doesn't support D3D12 (despite being supposedly HW-agnostic) */ /* Some Win10 client HW doesn't support D3D12 (despite being supposedly HW-agnostic) */
m_3dCtx.m_ctx12.m_dev.Reset(); m_3dCtx.m_ctx12.m_dev.Reset();
m_3dCtx.m_ctx12.m_dxFactory.Reset();
} }
} }
#endif #endif