mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 05:52:11 +01:00
[dxvk] Optimize buffer renaming
Small reduction in CPU overhead by using spinlocks instead of a full mutex for the two buffer free lists.
This commit is contained in:
parent
88cda20746
commit
19f74a89cd
@ -21,28 +21,19 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkPhysicalBufferSlice DxvkBuffer::rename(const DxvkPhysicalBufferSlice& slice) {
|
|
||||||
DxvkPhysicalBufferSlice prevSlice = std::move(m_physSlice);
|
|
||||||
|
|
||||||
m_physSlice = slice;
|
|
||||||
m_revision += 1;
|
|
||||||
return prevSlice;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkPhysicalBufferSlice DxvkBuffer::allocPhysicalSlice() {
|
DxvkPhysicalBufferSlice DxvkBuffer::allocPhysicalSlice() {
|
||||||
std::unique_lock<std::mutex> freeLock(m_freeMutex);
|
std::unique_lock<sync::Spinlock> freeLock(m_freeMutex);
|
||||||
|
|
||||||
// If no slices are available, swap the two free lists.
|
// If no slices are available, swap the two free lists.
|
||||||
if (m_freeSlices.size() == 0) {
|
if (m_freeSlices.size() == 0) {
|
||||||
std::unique_lock<std::mutex> swapLock(m_swapMutex);
|
std::unique_lock<sync::Spinlock> swapLock(m_swapMutex);
|
||||||
std::swap(m_freeSlices, m_nextSlices);
|
std::swap(m_freeSlices, m_nextSlices);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are still no slices available, create a new
|
// If there are still no slices available, create a new
|
||||||
// physical buffer and add all slices to the free list.
|
// physical buffer and add all slices to the free list.
|
||||||
if (m_freeSlices.size() == 0) {
|
if (m_freeSlices.size() == 0) {
|
||||||
std::unique_lock<std::mutex> swapLock(m_swapMutex);
|
std::unique_lock<sync::Spinlock> swapLock(m_swapMutex);
|
||||||
m_physBuffer = this->allocPhysicalBuffer(m_physSliceCount);
|
m_physBuffer = this->allocPhysicalBuffer(m_physSliceCount);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < m_physSliceCount; i++) {
|
for (uint32_t i = 0; i < m_physSliceCount; i++) {
|
||||||
@ -63,7 +54,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
void DxvkBuffer::freePhysicalSlice(const DxvkPhysicalBufferSlice& slice) {
|
void DxvkBuffer::freePhysicalSlice(const DxvkPhysicalBufferSlice& slice) {
|
||||||
// Add slice to a separate free list to reduce lock contention.
|
// Add slice to a separate free list to reduce lock contention.
|
||||||
std::unique_lock<std::mutex> swapLock(m_swapMutex);
|
std::unique_lock<sync::Spinlock> swapLock(m_swapMutex);
|
||||||
|
|
||||||
// Discard slices allocated from other physical buffers.
|
// Discard slices allocated from other physical buffers.
|
||||||
// This may make descriptor set binding more efficient.
|
// This may make descriptor set binding more efficient.
|
||||||
|
@ -111,8 +111,12 @@ namespace dxvk {
|
|||||||
* \param [in] slice The new backing resource
|
* \param [in] slice The new backing resource
|
||||||
* \returns Previous buffer slice
|
* \returns Previous buffer slice
|
||||||
*/
|
*/
|
||||||
DxvkPhysicalBufferSlice rename(
|
DxvkPhysicalBufferSlice rename(const DxvkPhysicalBufferSlice& slice) {
|
||||||
const DxvkPhysicalBufferSlice& slice);
|
DxvkPhysicalBufferSlice prevSlice = std::move(m_physSlice);
|
||||||
|
m_physSlice = slice;
|
||||||
|
m_revision += 1;
|
||||||
|
return prevSlice;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Allocates new physical resource
|
* \brief Allocates new physical resource
|
||||||
@ -140,8 +144,8 @@ namespace dxvk {
|
|||||||
DxvkPhysicalBufferSlice m_physSlice;
|
DxvkPhysicalBufferSlice m_physSlice;
|
||||||
uint32_t m_revision = 0;
|
uint32_t m_revision = 0;
|
||||||
|
|
||||||
std::mutex m_freeMutex;
|
sync::Spinlock m_freeMutex;
|
||||||
std::mutex m_swapMutex;
|
sync::Spinlock m_swapMutex;
|
||||||
|
|
||||||
std::vector<DxvkPhysicalBufferSlice> m_freeSlices;
|
std::vector<DxvkPhysicalBufferSlice> m_freeSlices;
|
||||||
std::vector<DxvkPhysicalBufferSlice> m_nextSlices;
|
std::vector<DxvkPhysicalBufferSlice> m_nextSlices;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user