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
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;
// Make multiple of stride
@ -218,17 +218,9 @@ ComPtr<ID3D12Resource> createVertexBuffer(const VertexBufferFormat &vbf, const R
assert(vertexIndexHeap.canAlloc(subBufferSize));
size_t heapOffset = vertexIndexHeap.alloc(subBufferSize);
ComPtr<ID3D12Resource> vertexBuffer;
ThrowIfFailed(device->CreatePlacedResource(
vertexIndexHeap.m_heap,
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));
void *buffer;
ThrowIfFailed(vertexIndexHeap.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer));
void *bufferMap = (char*)buffer + heapOffset;
for (int vertex = 0; vertex < vbf.elementCount; vertex++)
{
for (size_t attributeId : vbf.attributeId)
@ -271,8 +263,8 @@ ComPtr<ID3D12Resource> createVertexBuffer(const VertexBufferFormat &vbf, const R
}
}
vertexBuffer->Unmap(0, nullptr);
return vertexBuffer;
vertexIndexHeap.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize));
return vertexIndexHeap.m_heap->GetGPUVirtualAddress() + heapOffset;
}
static bool
@ -302,26 +294,11 @@ std::vector<D3D12_VERTEX_BUFFER_VIEW> D3D12GSRender::UploadVertexBuffers(bool in
if (vbf.stride)
subBufferSize = ((subBufferSize + vbf.stride - 1) / vbf.stride) * vbf.stride;
u64 key = vbf.range.first;
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;
vertexBuffer = newVertexBuffer.Get();
m_vertexCache[key] = newVertexBuffer.Get();
getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(newVertexBuffer);
}
D3D12_GPU_VIRTUAL_ADDRESS virtualAddress = createVertexBuffer(vbf, m_vertex_data, m_vertex_data_base_offset, m_device.Get(), m_vertexIndexData);
m_timers.m_bufferUploadSize += subBufferSize;
D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {};
vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress();
vertexBufferView.BufferLocation = virtualAddress;
vertexBufferView.SizeInBytes = (UINT)subBufferSize;
vertexBufferView.StrideInBytes = (UINT)vbf.stride;
result.push_back(vertexBufferView);
@ -428,18 +405,9 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw)
assert(m_vertexIndexData.canAlloc(subBufferSize));
size_t heapOffset = m_vertexIndexData.alloc(subBufferSize);
ComPtr<ID3D12Resource> indexBuffer;
ThrowIfFailed(m_device->CreatePlacedResource(
m_vertexIndexData.m_heap,
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));
void *buffer;
ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer));
void *bufferMap = (char*)buffer + heapOffset;
if (indexed_draw && !forcedIndexBuffer)
streamBuffer(bufferMap, m_indexed_array.m_data.data(), subBufferSize);
else if (indexed_draw && forcedIndexBuffer)
@ -500,13 +468,12 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw)
}
}
indexBuffer->Unmap(0, nullptr);
getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(indexBuffer);
m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize));
m_timers.m_bufferUploadSize += subBufferSize;
indexBufferView.SizeInBytes = (UINT)subBufferSize;
indexBufferView.BufferLocation = indexBuffer->GetGPUVirtualAddress();
indexBufferView.BufferLocation = m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heapOffset;
return indexBufferView;
}

View File

@ -298,7 +298,7 @@ D3D12GSRender::D3D12GSRender()
m_rtts.Init(m_device.Get());
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);
if (Ini.GSOverlay.GetValue())
@ -884,7 +884,6 @@ void D3D12GSRender::Flip()
// Flush
m_texturesRTTs.clear();
m_vertexCache.clear();
m_vertexConstants.clear();
// Now get ready for next frame

View File

@ -229,10 +229,6 @@ private:
std::unordered_map<u32, ID3D12Resource*> m_texturesCache;
// 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;
std::pair<ID3D12PipelineState *, size_t> *m_PSO;
@ -334,7 +330,7 @@ private:
// Constants storage
DataHeap<ID3D12Resource, 256> m_constantsData;
// Vertex storage
DataHeap<ID3D12Heap, 65536> m_vertexIndexData;
DataHeap<ID3D12Resource, 65536> m_vertexIndexData;
// Texture storage
DataHeap<ID3D12Heap, 65536> m_textureUploadData;
DataHeap<ID3D12Heap, 65536> m_UAVHeap;