mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-11 01:08:39 +12:00
d3d12: Use big buffer instead of placed resource for vertex index storage
Increase perf in Disgaea 3
This commit is contained in:
parent
8ba74a7f7d
commit
37721d6b8a
3 changed files with 17 additions and 55 deletions
|
@ -206,10 +206,10 @@ std::vector<VertexBufferFormat> FormatVertexData(const RSXVertexData *m_vertex_d
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new vertex buffer with attributes from vbf using vertexIndexHeap as storage heap.
|
* Suballocate a new vertex buffer with attributes from vbf using vertexIndexHeap as storage heap.
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
ComPtr<ID3D12Resource> createVertexBuffer(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, size_t baseOffset, ID3D12Device *device, DataHeap<ID3D12Heap, 65536> &vertexIndexHeap)
|
D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, size_t baseOffset, ID3D12Device *device, DataHeap<ID3D12Resource, 65536> &vertexIndexHeap)
|
||||||
{
|
{
|
||||||
size_t subBufferSize = vbf.range.second - vbf.range.first + 1;
|
size_t subBufferSize = vbf.range.second - vbf.range.first + 1;
|
||||||
// Make multiple of stride
|
// Make multiple of stride
|
||||||
|
@ -218,17 +218,9 @@ ComPtr<ID3D12Resource> createVertexBuffer(const VertexBufferFormat &vbf, const R
|
||||||
assert(vertexIndexHeap.canAlloc(subBufferSize));
|
assert(vertexIndexHeap.canAlloc(subBufferSize));
|
||||||
size_t heapOffset = vertexIndexHeap.alloc(subBufferSize);
|
size_t heapOffset = vertexIndexHeap.alloc(subBufferSize);
|
||||||
|
|
||||||
ComPtr<ID3D12Resource> vertexBuffer;
|
void *buffer;
|
||||||
ThrowIfFailed(device->CreatePlacedResource(
|
ThrowIfFailed(vertexIndexHeap.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer));
|
||||||
vertexIndexHeap.m_heap,
|
void *bufferMap = (char*)buffer + heapOffset;
|
||||||
heapOffset,
|
|
||||||
&CD3DX12_RESOURCE_DESC::Buffer(subBufferSize),
|
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
|
||||||
nullptr,
|
|
||||||
IID_PPV_ARGS(vertexBuffer.GetAddressOf())
|
|
||||||
));
|
|
||||||
void *bufferMap;
|
|
||||||
ThrowIfFailed(vertexBuffer->Map(0, nullptr, (void**)&bufferMap));
|
|
||||||
for (int vertex = 0; vertex < vbf.elementCount; vertex++)
|
for (int vertex = 0; vertex < vbf.elementCount; vertex++)
|
||||||
{
|
{
|
||||||
for (size_t attributeId : vbf.attributeId)
|
for (size_t attributeId : vbf.attributeId)
|
||||||
|
@ -271,8 +263,8 @@ ComPtr<ID3D12Resource> createVertexBuffer(const VertexBufferFormat &vbf, const R
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexBuffer->Unmap(0, nullptr);
|
vertexIndexHeap.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize));
|
||||||
return vertexBuffer;
|
return vertexIndexHeap.m_heap->GetGPUVirtualAddress() + heapOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -302,26 +294,11 @@ std::vector<D3D12_VERTEX_BUFFER_VIEW> D3D12GSRender::UploadVertexBuffers(bool in
|
||||||
if (vbf.stride)
|
if (vbf.stride)
|
||||||
subBufferSize = ((subBufferSize + vbf.stride - 1) / vbf.stride) * vbf.stride;
|
subBufferSize = ((subBufferSize + vbf.stride - 1) / vbf.stride) * vbf.stride;
|
||||||
|
|
||||||
u64 key = vbf.range.first;
|
D3D12_GPU_VIRTUAL_ADDRESS virtualAddress = createVertexBuffer(vbf, m_vertex_data, m_vertex_data_base_offset, m_device.Get(), m_vertexIndexData);
|
||||||
key = key << 32;
|
m_timers.m_bufferUploadSize += subBufferSize;
|
||||||
key = key | vbf.range.second;
|
|
||||||
auto It = m_vertexCache.find(key);
|
|
||||||
|
|
||||||
ID3D12Resource *vertexBuffer;
|
|
||||||
if (vbf.range.first != 0 && // Attribute is stored in a buffer, not inline in command buffer
|
|
||||||
It != m_vertexCache.end())
|
|
||||||
vertexBuffer = It->second;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ComPtr<ID3D12Resource> newVertexBuffer = createVertexBuffer(vbf, m_vertex_data, m_vertex_data_base_offset, m_device.Get(), m_vertexIndexData);
|
|
||||||
m_timers.m_bufferUploadSize += subBufferSize;
|
|
||||||
vertexBuffer = newVertexBuffer.Get();
|
|
||||||
m_vertexCache[key] = newVertexBuffer.Get();
|
|
||||||
getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(newVertexBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {};
|
D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {};
|
||||||
vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress();
|
vertexBufferView.BufferLocation = virtualAddress;
|
||||||
vertexBufferView.SizeInBytes = (UINT)subBufferSize;
|
vertexBufferView.SizeInBytes = (UINT)subBufferSize;
|
||||||
vertexBufferView.StrideInBytes = (UINT)vbf.stride;
|
vertexBufferView.StrideInBytes = (UINT)vbf.stride;
|
||||||
result.push_back(vertexBufferView);
|
result.push_back(vertexBufferView);
|
||||||
|
@ -428,18 +405,9 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw)
|
||||||
assert(m_vertexIndexData.canAlloc(subBufferSize));
|
assert(m_vertexIndexData.canAlloc(subBufferSize));
|
||||||
size_t heapOffset = m_vertexIndexData.alloc(subBufferSize);
|
size_t heapOffset = m_vertexIndexData.alloc(subBufferSize);
|
||||||
|
|
||||||
ComPtr<ID3D12Resource> indexBuffer;
|
void *buffer;
|
||||||
ThrowIfFailed(m_device->CreatePlacedResource(
|
ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer));
|
||||||
m_vertexIndexData.m_heap,
|
void *bufferMap = (char*)buffer + heapOffset;
|
||||||
heapOffset,
|
|
||||||
&CD3DX12_RESOURCE_DESC::Buffer(subBufferSize),
|
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
|
||||||
nullptr,
|
|
||||||
IID_PPV_ARGS(indexBuffer.GetAddressOf())
|
|
||||||
));
|
|
||||||
|
|
||||||
void *bufferMap;
|
|
||||||
ThrowIfFailed(indexBuffer->Map(0, nullptr, (void**)&bufferMap));
|
|
||||||
if (indexed_draw && !forcedIndexBuffer)
|
if (indexed_draw && !forcedIndexBuffer)
|
||||||
streamBuffer(bufferMap, m_indexed_array.m_data.data(), subBufferSize);
|
streamBuffer(bufferMap, m_indexed_array.m_data.data(), subBufferSize);
|
||||||
else if (indexed_draw && forcedIndexBuffer)
|
else if (indexed_draw && forcedIndexBuffer)
|
||||||
|
@ -500,13 +468,12 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
indexBuffer->Unmap(0, nullptr);
|
m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize));
|
||||||
getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(indexBuffer);
|
|
||||||
|
|
||||||
m_timers.m_bufferUploadSize += subBufferSize;
|
m_timers.m_bufferUploadSize += subBufferSize;
|
||||||
|
|
||||||
indexBufferView.SizeInBytes = (UINT)subBufferSize;
|
indexBufferView.SizeInBytes = (UINT)subBufferSize;
|
||||||
indexBufferView.BufferLocation = indexBuffer->GetGPUVirtualAddress();
|
indexBufferView.BufferLocation = m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heapOffset;
|
||||||
return indexBufferView;
|
return indexBufferView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,7 @@ D3D12GSRender::D3D12GSRender()
|
||||||
m_rtts.Init(m_device.Get());
|
m_rtts.Init(m_device.Get());
|
||||||
|
|
||||||
m_constantsData.Init(m_device.Get(), 1024 * 1024 * 64, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE);
|
m_constantsData.Init(m_device.Get(), 1024 * 1024 * 64, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE);
|
||||||
m_vertexIndexData.Init(m_device.Get(), 1024 * 1024 * 384, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
|
m_vertexIndexData.Init(m_device.Get(), 1024 * 1024 * 384, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE);
|
||||||
m_textureUploadData.Init(m_device.Get(), 1024 * 1024 * 256, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
|
m_textureUploadData.Init(m_device.Get(), 1024 * 1024 * 256, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
|
||||||
|
|
||||||
if (Ini.GSOverlay.GetValue())
|
if (Ini.GSOverlay.GetValue())
|
||||||
|
@ -884,7 +884,6 @@ void D3D12GSRender::Flip()
|
||||||
|
|
||||||
// Flush
|
// Flush
|
||||||
m_texturesRTTs.clear();
|
m_texturesRTTs.clear();
|
||||||
m_vertexCache.clear();
|
|
||||||
m_vertexConstants.clear();
|
m_vertexConstants.clear();
|
||||||
|
|
||||||
// Now get ready for next frame
|
// Now get ready for next frame
|
||||||
|
|
|
@ -229,10 +229,6 @@ private:
|
||||||
std::unordered_map<u32, ID3D12Resource*> m_texturesCache;
|
std::unordered_map<u32, ID3D12Resource*> m_texturesCache;
|
||||||
// std::vector<PostDrawObj> m_post_draw_objs;
|
// std::vector<PostDrawObj> m_post_draw_objs;
|
||||||
|
|
||||||
// TODO: Use a tree structure to parse more efficiently
|
|
||||||
// Key is begin << 32 | end
|
|
||||||
std::unordered_map<u64, ID3D12Resource *> m_vertexCache;
|
|
||||||
|
|
||||||
PipelineStateObjectCache m_cachePSO;
|
PipelineStateObjectCache m_cachePSO;
|
||||||
std::pair<ID3D12PipelineState *, size_t> *m_PSO;
|
std::pair<ID3D12PipelineState *, size_t> *m_PSO;
|
||||||
|
|
||||||
|
@ -334,7 +330,7 @@ private:
|
||||||
// Constants storage
|
// Constants storage
|
||||||
DataHeap<ID3D12Resource, 256> m_constantsData;
|
DataHeap<ID3D12Resource, 256> m_constantsData;
|
||||||
// Vertex storage
|
// Vertex storage
|
||||||
DataHeap<ID3D12Heap, 65536> m_vertexIndexData;
|
DataHeap<ID3D12Resource, 65536> m_vertexIndexData;
|
||||||
// Texture storage
|
// Texture storage
|
||||||
DataHeap<ID3D12Heap, 65536> m_textureUploadData;
|
DataHeap<ID3D12Heap, 65536> m_textureUploadData;
|
||||||
DataHeap<ID3D12Heap, 65536> m_UAVHeap;
|
DataHeap<ID3D12Heap, 65536> m_UAVHeap;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue