mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +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.size = pageInfo.buffer.length;
|
||||
|
||||
m_cmd->bindBufferMemory(key, mapping.getHandle());
|
||||
m_cmd->bindBufferMemory(key, mapping.getMemoryInfo());
|
||||
} break;
|
||||
|
||||
case DxvkSparsePageType::Image: {
|
||||
@ -2693,7 +2693,7 @@ namespace dxvk {
|
||||
key.offset = pageInfo.image.offset;
|
||||
key.extent = pageInfo.image.extent;
|
||||
|
||||
m_cmd->bindImageMemory(key, mapping.getHandle());
|
||||
m_cmd->bindImageMemory(key, mapping.getMemoryInfo());
|
||||
} break;
|
||||
|
||||
case DxvkSparsePageType::ImageMipTail: {
|
||||
@ -2703,7 +2703,7 @@ namespace dxvk {
|
||||
key.size = pageInfo.mipTail.resourceLength;
|
||||
key.flags = 0;
|
||||
|
||||
m_cmd->bindImageOpaqueMemory(key, mapping.getHandle());
|
||||
m_cmd->bindImageOpaqueMemory(key, mapping.getMemoryInfo());
|
||||
} 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(
|
||||
VkBufferUsageFlags bufferUsage,
|
||||
VkMemoryPropertyFlags properties) {
|
||||
|
@ -1067,14 +1067,6 @@ namespace dxvk {
|
||||
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
|
||||
*
|
||||
@ -1145,6 +1137,14 @@ namespace dxvk {
|
||||
VkMemoryPropertyFlags properties,
|
||||
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
|
||||
*
|
||||
|
@ -16,7 +16,7 @@ namespace dxvk {
|
||||
|
||||
DxvkSparseMapping::DxvkSparseMapping(
|
||||
Rc<DxvkSparsePageAllocator> allocator,
|
||||
Rc<DxvkSparsePage> page)
|
||||
Rc<DxvkResourceAllocation> page)
|
||||
: m_pool(std::move(allocator)),
|
||||
m_page(std::move(page)) {
|
||||
|
||||
@ -110,18 +110,18 @@ namespace dxvk {
|
||||
if (!m_useCount)
|
||||
m_pages.resize(pageCount);
|
||||
} else if (pageCount > m_pageCount) {
|
||||
std::vector<Rc<DxvkSparsePage>> newPages;
|
||||
std::vector<Rc<DxvkResourceAllocation>> newPages;
|
||||
newPages.reserve(pageCount - m_pageCount);
|
||||
|
||||
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
|
||||
// batching opportunities during page table updates
|
||||
std::sort(newPages.begin(), newPages.end(),
|
||||
[] (const Rc<DxvkSparsePage>& a, const Rc<DxvkSparsePage>& b) {
|
||||
auto aHandle = a->getHandle();
|
||||
auto bHandle = b->getHandle();
|
||||
[] (const Rc<DxvkResourceAllocation>& a, const Rc<DxvkResourceAllocation>& b) {
|
||||
auto aHandle = a->getMemoryInfo();
|
||||
auto bHandle = b->getMemoryInfo();
|
||||
|
||||
// Ignore length here, the offsets cannot be the same anyway.
|
||||
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(
|
||||
const Rc<DxvkSparsePage>& page) {
|
||||
const Rc<DxvkResourceAllocation>& page) {
|
||||
std::lock_guard lock(m_mutex);
|
||||
m_useCount += 1;
|
||||
}
|
||||
|
||||
|
||||
void DxvkSparsePageAllocator::releasePage(
|
||||
const Rc<DxvkSparsePage>& page) {
|
||||
const Rc<DxvkResourceAllocation>& page) {
|
||||
std::lock_guard lock(m_mutex);
|
||||
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
|
||||
*
|
||||
@ -213,11 +181,11 @@ namespace dxvk {
|
||||
* \brief Queries memory handle
|
||||
* \returns Memory information
|
||||
*/
|
||||
DxvkResourceMemoryInfo getHandle() const {
|
||||
if (m_page == nullptr)
|
||||
DxvkResourceMemoryInfo getMemoryInfo() const {
|
||||
if (!m_page)
|
||||
return DxvkResourceMemoryInfo();
|
||||
|
||||
return m_page->getHandle();
|
||||
return m_page->getMemoryInfo();
|
||||
}
|
||||
|
||||
bool operator == (const DxvkSparseMapping& other) const {
|
||||
@ -236,11 +204,11 @@ namespace dxvk {
|
||||
private:
|
||||
|
||||
Rc<DxvkSparsePageAllocator> m_pool;
|
||||
Rc<DxvkSparsePage> m_page;
|
||||
Rc<DxvkResourceAllocation> m_page;
|
||||
|
||||
DxvkSparseMapping(
|
||||
Rc<DxvkSparsePageAllocator> allocator,
|
||||
Rc<DxvkSparsePage> page);
|
||||
Rc<DxvkResourceAllocation> page);
|
||||
|
||||
void acquire() const;
|
||||
|
||||
@ -294,15 +262,13 @@ namespace dxvk {
|
||||
dxvk::mutex m_mutex;
|
||||
uint32_t m_pageCount = 0u;
|
||||
uint32_t m_useCount = 0u;
|
||||
std::vector<Rc<DxvkSparsePage>> m_pages;
|
||||
|
||||
Rc<DxvkSparsePage> allocPage();
|
||||
std::vector<Rc<DxvkResourceAllocation>> m_pages;
|
||||
|
||||
void acquirePage(
|
||||
const Rc<DxvkSparsePage>& page);
|
||||
const Rc<DxvkResourceAllocation>& page);
|
||||
|
||||
void releasePage(
|
||||
const Rc<DxvkSparsePage>& page);
|
||||
const Rc<DxvkResourceAllocation>& page);
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user