mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 02:52:10 +01:00
[dxvk] Use multiple free lists for physical buffer slices
Reduces lock contention and slightly improves performance in games that rely heavily on the buffer renaming mechanism if the lock protecting the original free list was contested.
This commit is contained in:
parent
c6251d28fc
commit
f762811af0
@ -31,16 +31,22 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxvkPhysicalBufferSlice DxvkBuffer::allocPhysicalSlice() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
std::unique_lock<std::mutex> freeLock(m_freeMutex);
|
||||
|
||||
// If necessary, create a new buffer
|
||||
// that we'll allocate slices from.
|
||||
if (m_slices.size() == 0) {
|
||||
// If no slices are available, swap the two free lists.
|
||||
if (m_freeSlices.size() == 0) {
|
||||
std::unique_lock<std::mutex> swapLock(m_swapMutex);
|
||||
std::swap(m_freeSlices, m_nextSlices);
|
||||
}
|
||||
|
||||
// If there are still no slices available, create a new
|
||||
// physical buffer and add all slices to the free list.
|
||||
if (m_freeSlices.size() == 0) {
|
||||
const Rc<DxvkPhysicalBuffer> buffer
|
||||
= this->allocPhysicalBuffer(m_physSliceCount);
|
||||
|
||||
for (uint32_t i = 0; i < m_physSliceCount; i++) {
|
||||
m_slices.push_back(buffer->slice(
|
||||
m_freeSlices.push_back(buffer->slice(
|
||||
m_physSliceStride * i,
|
||||
m_physSliceLength));
|
||||
}
|
||||
@ -49,15 +55,16 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
// Take the first slice from the queue
|
||||
DxvkPhysicalBufferSlice result = std::move(m_slices.back());
|
||||
m_slices.pop_back();
|
||||
DxvkPhysicalBufferSlice result = std::move(m_freeSlices.back());
|
||||
m_freeSlices.pop_back();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DxvkBuffer::freePhysicalSlice(const DxvkPhysicalBufferSlice& slice) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_slices.push_back(slice);
|
||||
// Add slice to a separate free list to reduce lock contention.
|
||||
std::unique_lock<std::mutex> swapLock(m_swapMutex);
|
||||
m_nextSlices.push_back(slice);
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,8 +140,11 @@ namespace dxvk {
|
||||
DxvkPhysicalBufferSlice m_physSlice;
|
||||
uint32_t m_revision = 0;
|
||||
|
||||
std::mutex m_mutex;
|
||||
std::vector<DxvkPhysicalBufferSlice> m_slices;
|
||||
std::mutex m_freeMutex;
|
||||
std::mutex m_swapMutex;
|
||||
|
||||
std::vector<DxvkPhysicalBufferSlice> m_freeSlices;
|
||||
std::vector<DxvkPhysicalBufferSlice> m_nextSlices;
|
||||
|
||||
VkDeviceSize m_physSliceLength = 0;
|
||||
VkDeviceSize m_physSliceStride = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user