mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-21 13:54:18 +01:00
[dxvk] Add concept of disabled chunks to allocator
This commit is contained in:
parent
bfcfcab60f
commit
a9bcb40655
@ -32,6 +32,13 @@ namespace dxvk {
|
|||||||
while (index--) {
|
while (index--) {
|
||||||
PageRange entry = m_freeList[index];
|
PageRange entry = m_freeList[index];
|
||||||
|
|
||||||
|
// The chunk index is the same regardless of alignment.
|
||||||
|
// Skip chunk if it does not accept new allocations.
|
||||||
|
uint32_t chunkIndex = entry.index >> ChunkPageBits;
|
||||||
|
|
||||||
|
if (unlikely(m_chunks[chunkIndex].disabled))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (likely(!(entry.index & (alignment - 1u)))) {
|
if (likely(!(entry.index & (alignment - 1u)))) {
|
||||||
// If the current free range is sufficiently aligned, we can use
|
// If the current free range is sufficiently aligned, we can use
|
||||||
// it as-is and simply modify the remaining free list entry.
|
// it as-is and simply modify the remaining free list entry.
|
||||||
@ -42,7 +49,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
insertFreeRange(entry, index);
|
insertFreeRange(entry, index);
|
||||||
|
|
||||||
uint32_t chunkIndex = pageIndex >> ChunkPageBits;
|
|
||||||
m_chunks[chunkIndex].pagesUsed += count;
|
m_chunks[chunkIndex].pagesUsed += count;
|
||||||
return pageIndex;
|
return pageIndex;
|
||||||
} else {
|
} else {
|
||||||
@ -68,7 +74,6 @@ namespace dxvk {
|
|||||||
if (nextRange.count)
|
if (nextRange.count)
|
||||||
insertFreeRange(nextRange, -1);
|
insertFreeRange(nextRange, -1);
|
||||||
|
|
||||||
uint32_t chunkIndex = pageIndex >> ChunkPageBits;
|
|
||||||
m_chunks[chunkIndex].pagesUsed += count;
|
m_chunks[chunkIndex].pagesUsed += count;
|
||||||
|
|
||||||
return pageIndex;
|
return pageIndex;
|
||||||
@ -163,6 +168,7 @@ namespace dxvk {
|
|||||||
chunk.pageCount = size / PageSize;
|
chunk.pageCount = size / PageSize;
|
||||||
chunk.pagesUsed = 0u;
|
chunk.pagesUsed = 0u;
|
||||||
chunk.nextChunk = -1;
|
chunk.nextChunk = -1;
|
||||||
|
chunk.disabled = false;
|
||||||
|
|
||||||
PageRange pageRange = { };
|
PageRange pageRange = { };
|
||||||
pageRange.index = uint32_t(chunkIndex) << ChunkPageBits;
|
pageRange.index = uint32_t(chunkIndex) << ChunkPageBits;
|
||||||
@ -179,6 +185,7 @@ namespace dxvk {
|
|||||||
chunk.pageCount = 0u;
|
chunk.pageCount = 0u;
|
||||||
chunk.pagesUsed = 0u;
|
chunk.pagesUsed = 0u;
|
||||||
chunk.nextChunk = std::exchange(m_freeChunk, int32_t(chunkIndex));
|
chunk.nextChunk = std::exchange(m_freeChunk, int32_t(chunkIndex));
|
||||||
|
chunk.disabled = true;
|
||||||
|
|
||||||
uint32_t pageIndex = chunkIndex << ChunkPageBits;
|
uint32_t pageIndex = chunkIndex << ChunkPageBits;
|
||||||
|
|
||||||
@ -190,6 +197,30 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkPageAllocator::killChunk(uint32_t chunkIndex) {
|
||||||
|
m_chunks[chunkIndex].disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkPageAllocator::reviveChunk(uint32_t chunkIndex) {
|
||||||
|
m_chunks[chunkIndex].disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t DxvkPageAllocator::reviveChunks() {
|
||||||
|
uint32_t count = 0u;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < m_chunks.size(); i++) {
|
||||||
|
if (m_chunks[i].pageCount && m_chunks[i].disabled) {
|
||||||
|
m_chunks[i].disabled = false;
|
||||||
|
count += 1u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkPageAllocator::getPageAllocationMask(uint32_t chunkIndex, uint32_t* pageMask) const {
|
void DxvkPageAllocator::getPageAllocationMask(uint32_t chunkIndex, uint32_t* pageMask) const {
|
||||||
// Initialize bit mask with all ones
|
// Initialize bit mask with all ones
|
||||||
const auto& chunk = m_chunks[chunkIndex];
|
const auto& chunk = m_chunks[chunkIndex];
|
||||||
|
@ -75,6 +75,16 @@ namespace dxvk {
|
|||||||
return m_chunks.at(chunkIndex).pagesUsed;
|
return m_chunks.at(chunkIndex).pagesUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checks whether a chunk is alive
|
||||||
|
*
|
||||||
|
* \param [in] chunkIndex Chunk index
|
||||||
|
* \returns \c true if chunk can be used
|
||||||
|
*/
|
||||||
|
bool chunkIsAvailable(uint32_t chunkIndex) const {
|
||||||
|
return !m_chunks.at(chunkIndex).disabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Allocates given number of bytes from the pool
|
* \brief Allocates given number of bytes from the pool
|
||||||
*
|
*
|
||||||
@ -131,6 +141,31 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
void removeChunk(uint32_t chunkIndex);
|
void removeChunk(uint32_t chunkIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Disables a chunk
|
||||||
|
*
|
||||||
|
* Makes an entire chunk unavailable for subsequent allocations.
|
||||||
|
* This can be useful when moving allocations out of that chunk
|
||||||
|
* in an attempt to free some memory.
|
||||||
|
* \param [in] chunkIndex Chunk index
|
||||||
|
*/
|
||||||
|
void killChunk(uint32_t chunkIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Re-enables a chunk
|
||||||
|
*
|
||||||
|
* Makes all disabled chunks available for allocations again.
|
||||||
|
* Should be used before allocating new chunk memory.
|
||||||
|
* \param [in] chunkIndex Chunk index
|
||||||
|
*/
|
||||||
|
void reviveChunk(uint32_t chunkIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Re-enables all disabled chunks
|
||||||
|
* \returns Number of chunks re-enabled
|
||||||
|
*/
|
||||||
|
uint32_t reviveChunks();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Queries page allocation mask
|
* \brief Queries page allocation mask
|
||||||
*
|
*
|
||||||
@ -149,6 +184,7 @@ namespace dxvk {
|
|||||||
uint32_t pageCount = 0u;
|
uint32_t pageCount = 0u;
|
||||||
uint32_t pagesUsed = 0u;
|
uint32_t pagesUsed = 0u;
|
||||||
int32_t nextChunk = -1;
|
int32_t nextChunk = -1;
|
||||||
|
bool disabled = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PageRange {
|
struct PageRange {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user