mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
d3d12: Use a commited resource for constant buffer
Since we rarely use more than 1k of constant data we waste space due to alignment requirement with heap so use a commited resource instead.
This commit is contained in:
parent
2f54482592
commit
d2c13bc4c1
4 changed files with 129 additions and 123 deletions
|
@ -192,7 +192,7 @@ std::vector<VertexBufferFormat> FormatVertexData(const RSXVertexData *m_vertex_d
|
|||
* Create a new vertex buffer with attributes from vbf using vertexIndexHeap as storage heap.
|
||||
*/
|
||||
static
|
||||
ID3D12Resource *createVertexBuffer(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, ID3D12Device *device, DataHeap &vertexIndexHeap)
|
||||
ID3D12Resource *createVertexBuffer(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, ID3D12Device *device, DataHeap<ID3D12Heap, 65536> &vertexIndexHeap)
|
||||
{
|
||||
size_t subBufferSize = vbf.range.second - vbf.range.first + 1;
|
||||
// Make multiple of stride
|
||||
|
@ -423,31 +423,23 @@ void D3D12GSRender::setScaleOffset()
|
|||
|
||||
// Scale offset buffer
|
||||
// Separate constant buffer
|
||||
ID3D12Resource *scaleOffsetBuffer;
|
||||
check(m_device->CreatePlacedResource(
|
||||
m_constantsData.m_heap,
|
||||
heapOffset,
|
||||
&getBufferResourceDesc(256),
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&scaleOffsetBuffer)
|
||||
));
|
||||
D3D12_RANGE range = { heapOffset, heapOffset + 256 };
|
||||
|
||||
void *scaleOffsetMap;
|
||||
check(scaleOffsetBuffer->Map(0, nullptr, &scaleOffsetMap));
|
||||
streamToBuffer(scaleOffsetMap, scaleOffsetMat, 16 * sizeof(float));
|
||||
check(m_constantsData.m_heap->Map(0, &range, &scaleOffsetMap));
|
||||
streamToBuffer((char*)scaleOffsetMap + heapOffset, scaleOffsetMat, 16 * sizeof(float));
|
||||
int isAlphaTested = m_set_alpha_test;
|
||||
streamToBuffer((char*)scaleOffsetMap + 16 * sizeof(float), &isAlphaTested, sizeof(int));
|
||||
streamToBuffer((char*)scaleOffsetMap + 17 * sizeof(float), &m_alpha_ref, sizeof(float));
|
||||
scaleOffsetBuffer->Unmap(0, nullptr);
|
||||
streamToBuffer((char*)scaleOffsetMap + heapOffset + 16 * sizeof(float), &isAlphaTested, sizeof(int));
|
||||
streamToBuffer((char*)scaleOffsetMap + heapOffset + 17 * sizeof(float), &m_alpha_ref, sizeof(float));
|
||||
m_constantsData.m_heap->Unmap(0, &range);
|
||||
|
||||
D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {};
|
||||
constantBufferViewDesc.BufferLocation = scaleOffsetBuffer->GetGPUVirtualAddress();
|
||||
constantBufferViewDesc.BufferLocation = m_constantsData.m_heap->GetGPUVirtualAddress() + heapOffset;
|
||||
constantBufferViewDesc.SizeInBytes = (UINT)256;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_scaleOffsetDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
Handle.ptr += getCurrentResourceStorage().m_currentScaleOffsetBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle);
|
||||
m_constantsData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, 256, scaleOffsetBuffer));
|
||||
// m_constantsData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, 256, scaleOffsetBuffer));
|
||||
}
|
||||
|
||||
void D3D12GSRender::FillVertexShaderConstantsBuffer()
|
||||
|
@ -464,28 +456,20 @@ void D3D12GSRender::FillVertexShaderConstantsBuffer()
|
|||
assert(m_constantsData.canAlloc(bufferSize));
|
||||
size_t heapOffset = m_constantsData.alloc(bufferSize);
|
||||
|
||||
ID3D12Resource *constantsBuffer;
|
||||
check(m_device->CreatePlacedResource(
|
||||
m_constantsData.m_heap,
|
||||
heapOffset,
|
||||
&getBufferResourceDesc(bufferSize),
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&constantsBuffer)
|
||||
));
|
||||
D3D12_RANGE range = { heapOffset, heapOffset + bufferSize };
|
||||
|
||||
void *constantsBufferMap;
|
||||
check(constantsBuffer->Map(0, nullptr, &constantsBufferMap));
|
||||
streamBuffer(constantsBufferMap, vertexConstantShadowCopy, bufferSize);
|
||||
constantsBuffer->Unmap(0, nullptr);
|
||||
check(m_constantsData.m_heap->Map(0, &range, &constantsBufferMap));
|
||||
streamBuffer((char*)constantsBufferMap + heapOffset, vertexConstantShadowCopy, bufferSize);
|
||||
m_constantsData.m_heap->Unmap(0, &range);
|
||||
|
||||
D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {};
|
||||
constantBufferViewDesc.BufferLocation = constantsBuffer->GetGPUVirtualAddress();
|
||||
constantBufferViewDesc.BufferLocation = m_constantsData.m_heap->GetGPUVirtualAddress() + heapOffset;
|
||||
constantBufferViewDesc.SizeInBytes = (UINT)bufferSize;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
Handle.ptr += getCurrentResourceStorage().m_constantsBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle);
|
||||
m_constantsData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, bufferSize, constantsBuffer));
|
||||
// m_constantsData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, bufferSize, constantsBuffer));
|
||||
}
|
||||
|
||||
void D3D12GSRender::FillPixelShaderConstantsBuffer()
|
||||
|
@ -499,19 +483,11 @@ void D3D12GSRender::FillPixelShaderConstantsBuffer()
|
|||
assert(m_constantsData.canAlloc(bufferSize));
|
||||
size_t heapOffset = m_constantsData.alloc(bufferSize);
|
||||
|
||||
ID3D12Resource *constantsBuffer;
|
||||
check(m_device->CreatePlacedResource(
|
||||
m_constantsData.m_heap,
|
||||
heapOffset,
|
||||
&getBufferResourceDesc(bufferSize),
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&constantsBuffer)
|
||||
));
|
||||
D3D12_RANGE range = { heapOffset, heapOffset + bufferSize };
|
||||
|
||||
size_t offset = 0;
|
||||
void *constantsBufferMap;
|
||||
check(constantsBuffer->Map(0, nullptr, &constantsBufferMap));
|
||||
check(m_constantsData.m_heap->Map(0, &range, &constantsBufferMap));
|
||||
for (size_t offsetInFP : fragmentOffset)
|
||||
{
|
||||
u32 vector[4];
|
||||
|
@ -546,19 +522,18 @@ void D3D12GSRender::FillPixelShaderConstantsBuffer()
|
|||
vector[3] = c3;
|
||||
}
|
||||
|
||||
streamToBuffer((char*)constantsBufferMap + offset, vector, 4 * sizeof(u32));
|
||||
streamToBuffer((char*)constantsBufferMap + heapOffset + offset, vector, 4 * sizeof(u32));
|
||||
offset += 4 * sizeof(u32);
|
||||
}
|
||||
|
||||
constantsBuffer->Unmap(0, nullptr);
|
||||
m_constantsData.m_heap->Unmap(0, &range);
|
||||
|
||||
D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {};
|
||||
constantBufferViewDesc.BufferLocation = constantsBuffer->GetGPUVirtualAddress();
|
||||
constantBufferViewDesc.BufferLocation = m_constantsData.m_heap->GetGPUVirtualAddress() + heapOffset;
|
||||
constantBufferViewDesc.SizeInBytes = (UINT)bufferSize;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
Handle.ptr += getCurrentResourceStorage().m_constantsBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle);
|
||||
m_constantsData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, bufferSize, constantsBuffer));
|
||||
// m_constantsData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, bufferSize, constantsBuffer));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,71 +14,6 @@ void SetGetD3DGSFrameCallback(GetGSFrameCb2 value)
|
|||
GetGSFrame = value;
|
||||
}
|
||||
|
||||
void DataHeap::Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
|
||||
{
|
||||
m_size = heapSize;
|
||||
D3D12_HEAP_DESC heapDesc = {};
|
||||
heapDesc.SizeInBytes = m_size;
|
||||
heapDesc.Properties.Type = type;
|
||||
heapDesc.Flags = flags;
|
||||
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, getPos = m_getPos;
|
||||
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;
|
||||
if (putPos + size < m_size)
|
||||
{
|
||||
m_putPos += powerOf2Align(size, 65536);
|
||||
return putPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_putPos = powerOf2Align(size, 65536);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DataHeap::Release()
|
||||
{
|
||||
m_heap->Release();
|
||||
for (auto tmp : m_resourceStoredSinceLastSync)
|
||||
{
|
||||
std::get<2>(tmp)->Release();
|
||||
}
|
||||
}
|
||||
|
||||
GarbageCollectionThread::GarbageCollectionThread()
|
||||
{
|
||||
m_worker = std::thread([this]() {
|
||||
|
@ -441,7 +376,7 @@ D3D12GSRender::D3D12GSRender()
|
|||
|
||||
m_rtts.Init(m_device);
|
||||
|
||||
m_constantsData.Init(m_device, 1024 * 1024 * 128, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
|
||||
m_constantsData.Init(m_device, 1024 * 1024 * 128, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE);
|
||||
m_vertexIndexData.Init(m_device, 1024 * 1024 * 128, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
|
||||
m_textureUploadData.Init(m_device, 1024 * 1024 * 256, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
|
||||
m_textureData.Init(m_device, 1024 * 1024 * 512, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES);
|
||||
|
|
|
@ -43,22 +43,118 @@ typedef GSFrameBase2*(*GetGSFrameCb2)();
|
|||
|
||||
void SetGetD3DGSFrameCallback(GetGSFrameCb2 value);
|
||||
|
||||
template<typename T>
|
||||
struct InitHeap
|
||||
{
|
||||
static T* Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct InitHeap<ID3D12Heap>
|
||||
{
|
||||
static ID3D12Heap* Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
|
||||
{
|
||||
ID3D12Heap *result;
|
||||
D3D12_HEAP_DESC heapDesc = {};
|
||||
heapDesc.SizeInBytes = heapSize;
|
||||
heapDesc.Properties.Type = type;
|
||||
heapDesc.Flags = flags;
|
||||
check(device->CreateHeap(&heapDesc, IID_PPV_ARGS(&result)));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct InitHeap<ID3D12Resource>
|
||||
{
|
||||
static ID3D12Resource* Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
|
||||
{
|
||||
ID3D12Resource *result;
|
||||
D3D12_HEAP_PROPERTIES heapProperties = {};
|
||||
heapProperties.Type = type;
|
||||
check(device->CreateCommittedResource(&heapProperties,
|
||||
flags,
|
||||
&getBufferResourceDesc(heapSize),
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&result))
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, size_t Alignment>
|
||||
struct DataHeap
|
||||
{
|
||||
ID3D12Heap *m_heap;
|
||||
T *m_heap;
|
||||
size_t m_size;
|
||||
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, D3D12_HEAP_FLAGS);
|
||||
void Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
|
||||
{
|
||||
m_size = heapSize;
|
||||
m_heap = InitHeap<T>::Init(device, heapSize, type, flags);
|
||||
m_putPos = 0;
|
||||
m_getPos = m_size - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does alloc cross get position ?
|
||||
*/
|
||||
bool canAlloc(size_t size);
|
||||
size_t alloc(size_t size);
|
||||
void Release();
|
||||
bool canAlloc(size_t size)
|
||||
{
|
||||
size_t putPos = m_putPos, getPos = m_getPos;
|
||||
size_t allocSize = powerOf2Align(size, Alignment);
|
||||
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 alloc(size_t size)
|
||||
{
|
||||
assert(canAlloc(size));
|
||||
size_t putPos = m_putPos;
|
||||
if (putPos + size < m_size)
|
||||
{
|
||||
m_putPos += powerOf2Align(size, Alignment);
|
||||
return putPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_putPos = powerOf2Align(size, Alignment);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
m_heap->Release();
|
||||
for (auto tmp : m_resourceStoredSinceLastSync)
|
||||
{
|
||||
std::get<2>(tmp)->Release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct GarbageCollectionThread
|
||||
|
@ -129,12 +225,12 @@ private:
|
|||
ResourceStorage &getNonCurrentResourceStorage();
|
||||
|
||||
// Constants storage
|
||||
DataHeap m_constantsData;
|
||||
DataHeap<ID3D12Resource, 256> m_constantsData;
|
||||
// Vertex storage
|
||||
DataHeap m_vertexIndexData;
|
||||
DataHeap<ID3D12Heap, 65536> m_vertexIndexData;
|
||||
// Texture storage
|
||||
DataHeap m_textureUploadData;
|
||||
DataHeap m_textureData;
|
||||
DataHeap<ID3D12Heap, 65536> m_textureUploadData;
|
||||
DataHeap<ID3D12Heap, 65536> m_textureData;
|
||||
|
||||
struct UAVHeap
|
||||
{
|
||||
|
|
|
@ -145,8 +145,8 @@ ID3D12Resource *uploadSingleTexture(
|
|||
const RSXTexture &texture,
|
||||
ID3D12Device *device,
|
||||
ID3D12GraphicsCommandList *commandList,
|
||||
DataHeap &textureBuffersHeap,
|
||||
DataHeap &textureHeap)
|
||||
DataHeap<ID3D12Heap, 65536> &textureBuffersHeap,
|
||||
DataHeap<ID3D12Heap, 65536> &textureHeap)
|
||||
{
|
||||
ID3D12Resource *vramTexture;
|
||||
size_t w = texture.GetWidth(), h = texture.GetHeight();
|
||||
|
|
Loading…
Add table
Reference in a new issue