d3d12: Use big buffer instead of placed resource for vertex index storage

Increase perf in Disgaea 3
This commit is contained in:
Vincent Lejeune 2015-09-25 16:46:29 +02:00
parent 8ba74a7f7d
commit 37721d6b8a
3 changed files with 17 additions and 55 deletions

View file

@ -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;
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; 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;
} }

View file

@ -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

View file

@ -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;