mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
d3d12: Start using a ring-like buffer for constants
This commit is contained in:
parent
c1abf80b40
commit
e0cff6b0b4
@ -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()
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user