mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-21 22:54:16 +01:00
[dxvk] Refactor sparse page allocation
Uses the new allocator directly.
This commit is contained in:
parent
af4a2f7973
commit
0f23a17d8f
@ -2683,7 +2683,7 @@ namespace dxvk {
|
|||||||
key.offset = pageInfo.buffer.offset;
|
key.offset = pageInfo.buffer.offset;
|
||||||
key.size = pageInfo.buffer.length;
|
key.size = pageInfo.buffer.length;
|
||||||
|
|
||||||
m_cmd->bindBufferMemory(key, mapping.getHandle());
|
m_cmd->bindBufferMemory(key, mapping.getMemoryInfo());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DxvkSparsePageType::Image: {
|
case DxvkSparsePageType::Image: {
|
||||||
@ -2693,7 +2693,7 @@ namespace dxvk {
|
|||||||
key.offset = pageInfo.image.offset;
|
key.offset = pageInfo.image.offset;
|
||||||
key.extent = pageInfo.image.extent;
|
key.extent = pageInfo.image.extent;
|
||||||
|
|
||||||
m_cmd->bindImageMemory(key, mapping.getHandle());
|
m_cmd->bindImageMemory(key, mapping.getMemoryInfo());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DxvkSparsePageType::ImageMipTail: {
|
case DxvkSparsePageType::ImageMipTail: {
|
||||||
@ -2703,7 +2703,7 @@ namespace dxvk {
|
|||||||
key.size = pageInfo.mipTail.resourceLength;
|
key.size = pageInfo.mipTail.resourceLength;
|
||||||
key.flags = 0;
|
key.flags = 0;
|
||||||
|
|
||||||
m_cmd->bindImageOpaqueMemory(key, mapping.getHandle());
|
m_cmd->bindImageOpaqueMemory(key, mapping.getMemoryInfo());
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -894,6 +894,26 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkResourceAllocation> DxvkMemoryAllocator::createSparsePage() {
|
||||||
|
VkMemoryRequirements requirements = { };
|
||||||
|
requirements.size = SparseMemoryPageSize;
|
||||||
|
requirements.alignment = SparseMemoryPageSize;
|
||||||
|
requirements.memoryTypeBits = m_sparseMemoryTypes;
|
||||||
|
|
||||||
|
// Try device memory first, fall back to system memory if that fails.
|
||||||
|
// We might get an allocation with a global buffer, just ignore that.
|
||||||
|
auto allocation = allocateMemory(requirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
|
if (!allocation)
|
||||||
|
allocation = allocateMemory(requirements, 0);
|
||||||
|
|
||||||
|
if (!allocation)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return allocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkLocalAllocationCache DxvkMemoryAllocator::createAllocationCache(
|
DxvkLocalAllocationCache DxvkMemoryAllocator::createAllocationCache(
|
||||||
VkBufferUsageFlags bufferUsage,
|
VkBufferUsageFlags bufferUsage,
|
||||||
VkMemoryPropertyFlags properties) {
|
VkMemoryPropertyFlags properties) {
|
||||||
|
@ -1067,14 +1067,6 @@ namespace dxvk {
|
|||||||
return m_device;
|
return m_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Memory type mask for sparse resources
|
|
||||||
* \returns Sparse resource memory types
|
|
||||||
*/
|
|
||||||
uint32_t getSparseMemoryTypes() const {
|
|
||||||
return m_sparseMemoryTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Allocates device memory
|
* \brief Allocates device memory
|
||||||
*
|
*
|
||||||
@ -1145,6 +1137,14 @@ namespace dxvk {
|
|||||||
VkMemoryPropertyFlags properties,
|
VkMemoryPropertyFlags properties,
|
||||||
const void* next);
|
const void* next);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Creates allocation for sparse binding
|
||||||
|
*
|
||||||
|
* Allocates a single page of memory for sparse binding.
|
||||||
|
* \returns Allocated memory region
|
||||||
|
*/
|
||||||
|
Rc<DxvkResourceAllocation> createSparsePage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Creates local allocation cache for buffer resources
|
* \brief Creates local allocation cache for buffer resources
|
||||||
*
|
*
|
||||||
|
@ -16,7 +16,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkSparseMapping::DxvkSparseMapping(
|
DxvkSparseMapping::DxvkSparseMapping(
|
||||||
Rc<DxvkSparsePageAllocator> allocator,
|
Rc<DxvkSparsePageAllocator> allocator,
|
||||||
Rc<DxvkSparsePage> page)
|
Rc<DxvkResourceAllocation> page)
|
||||||
: m_pool(std::move(allocator)),
|
: m_pool(std::move(allocator)),
|
||||||
m_page(std::move(page)) {
|
m_page(std::move(page)) {
|
||||||
|
|
||||||
@ -110,18 +110,18 @@ namespace dxvk {
|
|||||||
if (!m_useCount)
|
if (!m_useCount)
|
||||||
m_pages.resize(pageCount);
|
m_pages.resize(pageCount);
|
||||||
} else if (pageCount > m_pageCount) {
|
} else if (pageCount > m_pageCount) {
|
||||||
std::vector<Rc<DxvkSparsePage>> newPages;
|
std::vector<Rc<DxvkResourceAllocation>> newPages;
|
||||||
newPages.reserve(pageCount - m_pageCount);
|
newPages.reserve(pageCount - m_pageCount);
|
||||||
|
|
||||||
for (size_t i = 0; i < pageCount - m_pageCount; i++)
|
for (size_t i = 0; i < pageCount - m_pageCount; i++)
|
||||||
newPages.push_back(allocPage());
|
newPages.push_back(m_memory->createSparsePage());
|
||||||
|
|
||||||
// Sort page by memory and offset to enable more
|
// Sort page by memory and offset to enable more
|
||||||
// batching opportunities during page table updates
|
// batching opportunities during page table updates
|
||||||
std::sort(newPages.begin(), newPages.end(),
|
std::sort(newPages.begin(), newPages.end(),
|
||||||
[] (const Rc<DxvkSparsePage>& a, const Rc<DxvkSparsePage>& b) {
|
[] (const Rc<DxvkResourceAllocation>& a, const Rc<DxvkResourceAllocation>& b) {
|
||||||
auto aHandle = a->getHandle();
|
auto aHandle = a->getMemoryInfo();
|
||||||
auto bHandle = b->getHandle();
|
auto bHandle = b->getMemoryInfo();
|
||||||
|
|
||||||
// Ignore length here, the offsets cannot be the same anyway.
|
// Ignore length here, the offsets cannot be the same anyway.
|
||||||
if (aHandle.memory < bHandle.memory) return true;
|
if (aHandle.memory < bHandle.memory) return true;
|
||||||
@ -138,35 +138,15 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkSparsePage> DxvkSparsePageAllocator::allocPage() {
|
|
||||||
DxvkMemoryRequirements memoryRequirements = { };
|
|
||||||
memoryRequirements.tiling = VK_IMAGE_TILING_LINEAR;
|
|
||||||
memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 };
|
|
||||||
|
|
||||||
// We don't know what kind of resource the memory6
|
|
||||||
// might be bound to, so just guess the memory types
|
|
||||||
auto& core = memoryRequirements.core.memoryRequirements;
|
|
||||||
core.size = SparseMemoryPageSize;
|
|
||||||
core.alignment = SparseMemoryPageSize;
|
|
||||||
core.memoryTypeBits = m_memory->getSparseMemoryTypes();
|
|
||||||
|
|
||||||
DxvkMemoryProperties memoryProperties = { };
|
|
||||||
memoryProperties.flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
|
||||||
|
|
||||||
DxvkMemory memory = m_memory->alloc(memoryRequirements, memoryProperties);
|
|
||||||
return new DxvkSparsePage(std::move(memory));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DxvkSparsePageAllocator::acquirePage(
|
void DxvkSparsePageAllocator::acquirePage(
|
||||||
const Rc<DxvkSparsePage>& page) {
|
const Rc<DxvkResourceAllocation>& page) {
|
||||||
std::lock_guard lock(m_mutex);
|
std::lock_guard lock(m_mutex);
|
||||||
m_useCount += 1;
|
m_useCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkSparsePageAllocator::releasePage(
|
void DxvkSparsePageAllocator::releasePage(
|
||||||
const Rc<DxvkSparsePage>& page) {
|
const Rc<DxvkResourceAllocation>& page) {
|
||||||
std::lock_guard lock(m_mutex);
|
std::lock_guard lock(m_mutex);
|
||||||
m_useCount -= 1;
|
m_useCount -= 1;
|
||||||
|
|
||||||
|
@ -155,38 +155,6 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Sparse memory page
|
|
||||||
*
|
|
||||||
* Stores a single reference-counted page
|
|
||||||
* of memory. The page size is 64k.
|
|
||||||
*/
|
|
||||||
class DxvkSparsePage : public DxvkResource {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DxvkSparsePage(DxvkMemory&& memory)
|
|
||||||
: m_memory(std::move(memory)) { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Queries memory handle
|
|
||||||
* \returns Memory information
|
|
||||||
*/
|
|
||||||
DxvkResourceMemoryInfo getHandle() const {
|
|
||||||
DxvkResourceMemoryInfo result;
|
|
||||||
result.memory = m_memory.memory();
|
|
||||||
result.offset = m_memory.offset();
|
|
||||||
result.size = m_memory.length();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
DxvkMemory m_memory;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Sparse page mapping
|
* \brief Sparse page mapping
|
||||||
*
|
*
|
||||||
@ -213,11 +181,11 @@ namespace dxvk {
|
|||||||
* \brief Queries memory handle
|
* \brief Queries memory handle
|
||||||
* \returns Memory information
|
* \returns Memory information
|
||||||
*/
|
*/
|
||||||
DxvkResourceMemoryInfo getHandle() const {
|
DxvkResourceMemoryInfo getMemoryInfo() const {
|
||||||
if (m_page == nullptr)
|
if (!m_page)
|
||||||
return DxvkResourceMemoryInfo();
|
return DxvkResourceMemoryInfo();
|
||||||
|
|
||||||
return m_page->getHandle();
|
return m_page->getMemoryInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator == (const DxvkSparseMapping& other) const {
|
bool operator == (const DxvkSparseMapping& other) const {
|
||||||
@ -236,11 +204,11 @@ namespace dxvk {
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
Rc<DxvkSparsePageAllocator> m_pool;
|
Rc<DxvkSparsePageAllocator> m_pool;
|
||||||
Rc<DxvkSparsePage> m_page;
|
Rc<DxvkResourceAllocation> m_page;
|
||||||
|
|
||||||
DxvkSparseMapping(
|
DxvkSparseMapping(
|
||||||
Rc<DxvkSparsePageAllocator> allocator,
|
Rc<DxvkSparsePageAllocator> allocator,
|
||||||
Rc<DxvkSparsePage> page);
|
Rc<DxvkResourceAllocation> page);
|
||||||
|
|
||||||
void acquire() const;
|
void acquire() const;
|
||||||
|
|
||||||
@ -294,15 +262,13 @@ namespace dxvk {
|
|||||||
dxvk::mutex m_mutex;
|
dxvk::mutex m_mutex;
|
||||||
uint32_t m_pageCount = 0u;
|
uint32_t m_pageCount = 0u;
|
||||||
uint32_t m_useCount = 0u;
|
uint32_t m_useCount = 0u;
|
||||||
std::vector<Rc<DxvkSparsePage>> m_pages;
|
std::vector<Rc<DxvkResourceAllocation>> m_pages;
|
||||||
|
|
||||||
Rc<DxvkSparsePage> allocPage();
|
|
||||||
|
|
||||||
void acquirePage(
|
void acquirePage(
|
||||||
const Rc<DxvkSparsePage>& page);
|
const Rc<DxvkResourceAllocation>& page);
|
||||||
|
|
||||||
void releasePage(
|
void releasePage(
|
||||||
const Rc<DxvkSparsePage>& page);
|
const Rc<DxvkResourceAllocation>& page);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user