d3d12: Start using a ring-like buffer for constants

This commit is contained in:
vlj 2015-06-01 22:48:30 +02:00 committed by Vincent Lejeune
parent c1abf80b40
commit e0cff6b0b4
3 changed files with 94 additions and 7 deletions

View File

@ -394,16 +394,15 @@ void D3D12GSRender::setScaleOffset()
scaleOffsetMat[3] /= RSXThread::m_width / RSXThread::m_width_scale;
scaleOffsetMat[7] /= RSXThread::m_height / RSXThread::m_height_scale;
size_t constantBuffersHeapOffset = m_perFrameStorage.m_constantsBuffersHeapFreeSpace;
// 65536 alignment
constantBuffersHeapOffset = (constantBuffersHeapOffset + 65536 - 1) & ~65535;
assert(m_constantsData.canAlloc(256));
size_t heapOffset = m_constantsData.alloc(256);
// Scale offset buffer
// Separate constant buffer
ID3D12Resource *scaleOffsetBuffer;
check(m_device->CreatePlacedResource(
m_perFrameStorage.m_constantsBuffersHeap,
constantBuffersHeapOffset,
m_constantsData.m_heap,
heapOffset,
&getBufferResourceDesc(256),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
@ -421,8 +420,7 @@ void D3D12GSRender::setScaleOffset()
D3D12_CPU_DESCRIPTOR_HANDLE Handle = m_perFrameStorage.m_scaleOffsetDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
Handle.ptr += m_perFrameStorage.m_currentScaleOffsetBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle);
m_perFrameStorage.m_constantsBuffersHeapFreeSpace = constantBuffersHeapOffset + 256;
m_perFrameStorage.m_inflightResources.push_back(scaleOffsetBuffer);
m_constantsData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, 256, scaleOffsetBuffer));
}
void D3D12GSRender::FillVertexShaderConstantsBuffer()

View File

@ -14,6 +14,66 @@ void SetGetD3DGSFrameCallback(GetGSFrameCb2 value)
GetGSFrame = value;
}
void DataHeap::Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type)
{
m_size = heapSize;
D3D12_HEAP_DESC heapDesc = {};
heapDesc.SizeInBytes = m_size;
heapDesc.Properties.Type = type;
heapDesc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
check(device->CreateHeap(&heapDesc, IID_PPV_ARGS(&m_heap)));
m_putPos = 0;
m_getPos = m_size - 1;
}
bool DataHeap::canAlloc(size_t size)
{
size_t putPos = m_putPos.load(), getPos = m_getPos.load();
size_t allocSize = powerOf2Align(size, 65536);
if (putPos + allocSize < m_size)
{
// range before get
if (putPos + allocSize < getPos)
return true;
// range after get
if (putPos > getPos)
return true;
return false;
}
else
{
// ..]....[..get..
if (putPos < getPos)
return false;
// ..get..]...[...
// Actually all resources extending beyond heap space starts at 0
if (allocSize > getPos)
return false;
return true;
}
}
size_t DataHeap::alloc(size_t size)
{
assert(canAlloc(size));
size_t putPos = m_putPos.load();
if (putPos + size < m_size)
{
m_putPos += powerOf2Align(size, 65536);
return putPos;
}
else
{
m_putPos.store(powerOf2Align(size, 65536));
return 0;
}
}
void DataHeap::Release()
{
}
void D3D12GSRender::ResourceStorage::Reset()
{
m_vertexIndexBuffersHeapFreeSpace = 0;
@ -334,10 +394,13 @@ D3D12GSRender::D3D12GSRender()
m_UAVHeap.m_getPos = 1024 * 1024 * 128 - 1;
m_rtts.Init(m_device);
m_constantsData.Init(m_device, 1024 * 1024, D3D12_HEAP_TYPE_UPLOAD);
}
D3D12GSRender::~D3D12GSRender()
{
m_constantsData.Release();
m_UAVHeap.m_heap->Release();
m_readbackResources.m_heap->Release();
m_texturesRTTs.clear();
@ -870,6 +933,13 @@ void D3D12GSRender::Flip()
m_texturesCache.clear();
m_texturesRTTs.clear();
for (auto tmp : m_constantsData.m_resourceStoredSinceLastSync)
{
std::get<2>(tmp)->Release();
m_constantsData.m_getPos.store(std::get<0>(tmp));
}
m_constantsData.m_resourceStoredSinceLastSync.clear();
m_frame->Flip(nullptr);
}

View File

@ -44,6 +44,23 @@ typedef GSFrameBase2*(*GetGSFrameCb2)();
void SetGetD3DGSFrameCallback(GetGSFrameCb2 value);
struct DataHeap
{
ID3D12Heap *m_heap;
size_t m_size;
std::atomic<size_t> m_putPos, // Start of free space
m_getPos; // End of free space
std::vector<std::tuple<size_t, size_t, ID3D12Resource *> > m_resourceStoredSinceLastSync;
void Init(ID3D12Device *, size_t, D3D12_HEAP_TYPE);
/**
* Does alloc cross get position ?
*/
bool canAlloc(size_t size);
size_t alloc(size_t size);
void Release();
};
class D3D12GSRender : public GSRender
{
private:
@ -96,6 +113,8 @@ private:
ResourceStorage m_perFrameStorage;
DataHeap m_constantsData;
struct UAVHeap
{
ID3D12Heap *m_heap;