mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 04:29:15 +01:00
[dxvk] Clean up internal memory allocation API
This commit is contained in:
parent
5117210c93
commit
a2a21cb4d3
@ -65,25 +65,32 @@ namespace dxvk {
|
||||
|
||||
DxvkBufferHandle handle;
|
||||
|
||||
if (vkd->vkCreateBuffer(vkd->device(),
|
||||
&info, nullptr, &handle.buffer) != VK_SUCCESS) {
|
||||
if (vkd->vkCreateBuffer(vkd->device(), &info, nullptr, &handle.buffer)) {
|
||||
throw DxvkError(str::format(
|
||||
"DxvkBuffer: Failed to create buffer:"
|
||||
"\n size: ", info.size,
|
||||
"\n usage: ", info.usage));
|
||||
}
|
||||
|
||||
VkMemoryDedicatedRequirements dedicatedRequirements = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS };
|
||||
VkMemoryRequirements2 memReq = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &dedicatedRequirements };
|
||||
|
||||
VkBufferMemoryRequirementsInfo2 memReqInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 };
|
||||
memReqInfo.buffer = handle.buffer;
|
||||
|
||||
VkMemoryDedicatedAllocateInfo dedMemoryAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO };
|
||||
dedMemoryAllocInfo.buffer = handle.buffer;
|
||||
|
||||
vkd->vkGetBufferMemoryRequirements2(
|
||||
vkd->device(), &memReqInfo, &memReq);
|
||||
// Query memory requirements and whether to use a dedicated allocation
|
||||
DxvkMemoryRequirements memoryRequirements = { };
|
||||
memoryRequirements.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS };
|
||||
memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &memoryRequirements.dedicated };
|
||||
|
||||
VkBufferMemoryRequirementsInfo2 memoryRequirementInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 };
|
||||
memoryRequirementInfo.buffer = handle.buffer;
|
||||
|
||||
vkd->vkGetBufferMemoryRequirements2(vkd->device(),
|
||||
&memoryRequirementInfo, &memoryRequirements.core);
|
||||
|
||||
// Fill in desired memory properties
|
||||
DxvkMemoryProperties memoryProperties = { };
|
||||
memoryProperties.flags = m_memFlags;
|
||||
|
||||
if (memoryRequirements.dedicated.prefersDedicatedAllocation) {
|
||||
memoryProperties.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO };
|
||||
memoryProperties.dedicated.buffer = handle.buffer;
|
||||
}
|
||||
|
||||
// Use high memory priority for GPU-writable resources
|
||||
bool isGpuWritable = (m_info.access & (
|
||||
@ -102,9 +109,7 @@ namespace dxvk {
|
||||
&& (m_info.usage & VK_BUFFER_USAGE_TRANSFER_SRC_BIT))
|
||||
hints.set(DxvkMemoryFlag::Transient);
|
||||
|
||||
// Ask driver whether we should be using a dedicated allocation
|
||||
handle.memory = m_memAlloc->alloc(&memReq.memoryRequirements,
|
||||
dedicatedRequirements, dedMemoryAllocInfo, m_memFlags, hints);
|
||||
handle.memory = m_memAlloc->alloc(memoryRequirements, memoryProperties, hints);
|
||||
|
||||
if (vkd->vkBindBufferMemory(vkd->device(), handle.buffer,
|
||||
handle.memory.memory(), handle.memory.offset()) != VK_SUCCESS)
|
||||
|
@ -22,7 +22,10 @@ namespace dxvk {
|
||||
VkImageFormatListCreateInfo formatList = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO };
|
||||
formatList.viewFormatCount = createInfo.viewFormatCount;
|
||||
formatList.pViewFormats = createInfo.viewFormats;
|
||||
|
||||
|
||||
VkExternalMemoryImageCreateInfo externalInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO };
|
||||
externalInfo.handleTypes = createInfo.sharing.type;
|
||||
|
||||
VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, &formatList };
|
||||
info.flags = createInfo.flags;
|
||||
info.imageType = createInfo.type;
|
||||
@ -36,17 +39,10 @@ namespace dxvk {
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
info.initialLayout = createInfo.initialLayout;
|
||||
|
||||
m_shared = canShareImage(info, createInfo.sharing);
|
||||
|
||||
VkExternalMemoryImageCreateInfo externalInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO };
|
||||
|
||||
if (m_shared) {
|
||||
if ((m_shared = canShareImage(info, createInfo.sharing)))
|
||||
externalInfo.pNext = std::exchange(info.pNext, &externalInfo);
|
||||
externalInfo.handleTypes = createInfo.sharing.type;
|
||||
}
|
||||
|
||||
if (m_vkd->vkCreateImage(m_vkd->device(),
|
||||
&info, nullptr, &m_image.image) != VK_SUCCESS) {
|
||||
|
||||
if (m_vkd->vkCreateImage(m_vkd->device(), &info, nullptr, &m_image.image)) {
|
||||
throw DxvkError(str::format(
|
||||
"DxvkImage: Failed to create image:",
|
||||
"\n Type: ", info.imageType,
|
||||
@ -61,40 +57,52 @@ namespace dxvk {
|
||||
"\n Tiling: ", info.tiling));
|
||||
}
|
||||
|
||||
// Get memory requirements for the image. We may enforce strict
|
||||
// alignment on non-linear images in order not to violate the
|
||||
// bufferImageGranularity limit, which may be greater than the
|
||||
// required resource memory alignment on some GPUs.
|
||||
VkMemoryDedicatedRequirements dedicatedRequirements = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS };
|
||||
VkMemoryRequirements2 memReq = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &dedicatedRequirements };
|
||||
|
||||
VkImageMemoryRequirementsInfo2 memReqInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 };
|
||||
memReqInfo.image = m_image.image;
|
||||
// Get memory requirements for the image and ask driver
|
||||
// whether we need to use a dedicated allocation.
|
||||
DxvkMemoryRequirements memoryRequirements = { };
|
||||
memoryRequirements.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS };
|
||||
memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &memoryRequirements.dedicated };
|
||||
|
||||
VkMemoryDedicatedAllocateInfo dedMemoryAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO };
|
||||
dedMemoryAllocInfo.image = m_image.image;
|
||||
VkImageMemoryRequirementsInfo2 memoryRequirementInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 };
|
||||
memoryRequirementInfo.image = m_image.image;
|
||||
|
||||
VkExportMemoryAllocateInfo exportInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO };
|
||||
if (m_shared && createInfo.sharing.mode == DxvkSharedHandleMode::Export) {
|
||||
exportInfo.pNext = std::exchange(dedMemoryAllocInfo.pNext, &exportInfo);
|
||||
exportInfo.handleTypes = createInfo.sharing.type;
|
||||
m_vkd->vkGetImageMemoryRequirements2(m_vkd->device(),
|
||||
&memoryRequirementInfo, &memoryRequirements.core);
|
||||
|
||||
// Fill in desired memory properties
|
||||
DxvkMemoryProperties memoryProperties = { };
|
||||
memoryProperties.flags = m_memFlags;
|
||||
|
||||
if (m_shared) {
|
||||
memoryRequirements.dedicated.prefersDedicatedAllocation = VK_TRUE;
|
||||
memoryRequirements.dedicated.requiresDedicatedAllocation = VK_TRUE;
|
||||
|
||||
if (createInfo.sharing.mode == DxvkSharedHandleMode::Export) {
|
||||
memoryProperties.sharedExport = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO };
|
||||
memoryProperties.sharedExport.handleTypes = createInfo.sharing.type;
|
||||
}
|
||||
|
||||
if (createInfo.sharing.mode == DxvkSharedHandleMode::Import) {
|
||||
memoryProperties.sharedImportWin32 = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR };
|
||||
memoryProperties.sharedImportWin32.handleType = createInfo.sharing.type;
|
||||
memoryProperties.sharedImportWin32.handle = createInfo.sharing.handle;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
VkImportMemoryWin32HandleInfoKHR importInfo = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR };
|
||||
if (m_shared && createInfo.sharing.mode == DxvkSharedHandleMode::Import) {
|
||||
importInfo.pNext = std::exchange(dedMemoryAllocInfo.pNext, &importInfo);
|
||||
importInfo.handleType = createInfo.sharing.type;
|
||||
importInfo.handle = createInfo.sharing.handle;
|
||||
if (memoryRequirements.dedicated.prefersDedicatedAllocation) {
|
||||
memoryProperties.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO };
|
||||
memoryProperties.dedicated.image = m_image.image;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_vkd->vkGetImageMemoryRequirements2(
|
||||
m_vkd->device(), &memReqInfo, &memReq);
|
||||
// If there's a chance we won't create the image with a dedicated
|
||||
// allocation, enforce strict alignment for tiled images to not
|
||||
// violate the bufferImageGranularity requirement on some GPUs.
|
||||
if (info.tiling != VK_IMAGE_TILING_LINEAR && !memoryRequirements.dedicated.requiresDedicatedAllocation) {
|
||||
VkDeviceSize granularity = memAlloc.bufferImageGranularity();
|
||||
|
||||
if (info.tiling != VK_IMAGE_TILING_LINEAR && !dedicatedRequirements.prefersDedicatedAllocation) {
|
||||
memReq.memoryRequirements.size = align(memReq.memoryRequirements.size, memAlloc.bufferImageGranularity());
|
||||
memReq.memoryRequirements.alignment = align(memReq.memoryRequirements.alignment , memAlloc.bufferImageGranularity());
|
||||
auto& core = memoryRequirements.core.memoryRequirements;
|
||||
core.size = align(core.size, granularity);
|
||||
core.alignment = align(core.alignment, granularity);
|
||||
}
|
||||
|
||||
// Use high memory priority for GPU-writable resources
|
||||
@ -110,14 +118,7 @@ namespace dxvk {
|
||||
if (isGpuWritable)
|
||||
hints.set(DxvkMemoryFlag::GpuWritable);
|
||||
|
||||
if (m_shared) {
|
||||
dedicatedRequirements.prefersDedicatedAllocation = VK_TRUE;
|
||||
dedicatedRequirements.requiresDedicatedAllocation = VK_TRUE;
|
||||
}
|
||||
|
||||
// Ask driver whether we should be using a dedicated allocation
|
||||
m_image.memory = memAlloc.alloc(&memReq.memoryRequirements,
|
||||
dedicatedRequirements, dedMemoryAllocInfo, memFlags, hints);
|
||||
m_image.memory = memAlloc.alloc(memoryRequirements, memoryProperties, hints);
|
||||
|
||||
// Try to bind the allocated memory slice to the image
|
||||
if (m_vkd->vkBindImageMemory(m_vkd->device(), m_image.image,
|
||||
|
@ -211,63 +211,66 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxvkMemory DxvkMemoryAllocator::alloc(
|
||||
const VkMemoryRequirements* req,
|
||||
const VkMemoryDedicatedRequirements& dedAllocReq,
|
||||
const VkMemoryDedicatedAllocateInfo& dedAllocInfo,
|
||||
VkMemoryPropertyFlags flags,
|
||||
const DxvkMemoryRequirements& req,
|
||||
DxvkMemoryProperties info,
|
||||
DxvkMemoryFlags hints) {
|
||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
||||
|
||||
// Keep small allocations together to avoid fragmenting
|
||||
// chunks for larger resources with lots of small gaps,
|
||||
// as well as resources with potentially weird lifetimes
|
||||
if (req->size <= SmallAllocationThreshold) {
|
||||
if (req.core.memoryRequirements.size <= SmallAllocationThreshold) {
|
||||
hints.set(DxvkMemoryFlag::Small);
|
||||
hints.clr(DxvkMemoryFlag::GpuWritable, DxvkMemoryFlag::GpuReadable);
|
||||
}
|
||||
|
||||
// Ignore most hints for host-visible allocations since they
|
||||
// usually don't make much sense for those resources
|
||||
if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
|
||||
if (info.flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
|
||||
hints = hints & DxvkMemoryFlag::Transient;
|
||||
|
||||
// Try to allocate from a memory type which supports the given flags exactly
|
||||
auto dedAllocPtr = dedAllocReq.prefersDedicatedAllocation ? &dedAllocInfo : nullptr;
|
||||
DxvkMemory result = this->tryAlloc(req, dedAllocPtr, flags, hints);
|
||||
DxvkMemory result = this->tryAlloc(req, info, hints);
|
||||
|
||||
// If the first attempt failed, try ignoring the dedicated allocation
|
||||
if (!result && dedAllocPtr && !dedAllocReq.requiresDedicatedAllocation) {
|
||||
result = this->tryAlloc(req, nullptr, flags, hints);
|
||||
dedAllocPtr = nullptr;
|
||||
if (!result && !req.dedicated.requiresDedicatedAllocation) {
|
||||
// If that failed, try without a dedicated allocation
|
||||
if (info.dedicated.image || info.dedicated.buffer) {
|
||||
info.dedicated.image = VK_NULL_HANDLE;
|
||||
info.dedicated.buffer = VK_NULL_HANDLE;
|
||||
|
||||
result = this->tryAlloc(req, info, hints);
|
||||
}
|
||||
}
|
||||
|
||||
// Retry without the hint constraints
|
||||
if (!result) {
|
||||
// Retry without the hint constraints
|
||||
hints.set(DxvkMemoryFlag::IgnoreConstraints);
|
||||
result = this->tryAlloc(req, nullptr, flags, hints);
|
||||
result = this->tryAlloc(req, info, hints);
|
||||
}
|
||||
|
||||
// If that still didn't work, probe slower memory types as well
|
||||
VkMemoryPropertyFlags optFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
||||
VkMemoryPropertyFlags remFlags = 0;
|
||||
|
||||
while (!result && (flags & optFlags)) {
|
||||
remFlags |= optFlags & -optFlags;
|
||||
optFlags &= ~remFlags;
|
||||
if (!result) {
|
||||
// If that still didn't work, probe slower memory types as well
|
||||
VkMemoryPropertyFlags optFlags = info.flags & (
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
|
||||
|
||||
result = this->tryAlloc(req, dedAllocPtr, flags & ~remFlags, hints);
|
||||
while (!result && optFlags) {
|
||||
VkMemoryPropertyFlags bit = optFlags & -optFlags;
|
||||
optFlags &= ~bit;
|
||||
|
||||
info.flags &= ~bit;
|
||||
result = this->tryAlloc(req, info, hints);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!result) {
|
||||
DxvkAdapterMemoryInfo memHeapInfo = m_device->adapter()->getMemoryHeapInfo();
|
||||
|
||||
Logger::err(str::format(
|
||||
"DxvkMemoryAllocator: Memory allocation failed",
|
||||
"\n Size: ", req->size,
|
||||
"\n Alignment: ", req->alignment,
|
||||
"\n Mem flags: ", "0x", std::hex, flags,
|
||||
"\n Mem types: ", "0x", std::hex, req->memoryTypeBits));
|
||||
"\n Size: ", req.core.memoryRequirements.size,
|
||||
"\n Alignment: ", req.core.memoryRequirements.alignment,
|
||||
"\n Mem types: ", "0x", std::hex, req.core.memoryRequirements.memoryTypeBits));
|
||||
|
||||
for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) {
|
||||
Logger::err(str::format("Heap ", i, ": ",
|
||||
@ -290,19 +293,20 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxvkMemory DxvkMemoryAllocator::tryAlloc(
|
||||
const VkMemoryRequirements* req,
|
||||
const VkMemoryDedicatedAllocateInfo* dedAllocInfo,
|
||||
VkMemoryPropertyFlags flags,
|
||||
const DxvkMemoryRequirements& req,
|
||||
const DxvkMemoryProperties& info,
|
||||
DxvkMemoryFlags hints) {
|
||||
DxvkMemory result;
|
||||
|
||||
for (uint32_t i = 0; i < m_memProps.memoryTypeCount && !result; i++) {
|
||||
const bool supported = (req->memoryTypeBits & (1u << i)) != 0;
|
||||
const bool adequate = (m_memTypes[i].memType.propertyFlags & flags) == flags;
|
||||
const bool supported = (req.core.memoryRequirements.memoryTypeBits & (1u << i)) != 0;
|
||||
const bool adequate = (m_memTypes[i].memType.propertyFlags & info.flags) == info.flags;
|
||||
|
||||
if (supported && adequate) {
|
||||
result = this->tryAllocFromType(&m_memTypes[i],
|
||||
flags, req->size, req->alignment, hints, dedAllocInfo);
|
||||
req.core.memoryRequirements.size,
|
||||
req.core.memoryRequirements.alignment,
|
||||
info, hints);
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,27 +316,25 @@ namespace dxvk {
|
||||
|
||||
DxvkMemory DxvkMemoryAllocator::tryAllocFromType(
|
||||
DxvkMemoryType* type,
|
||||
VkMemoryPropertyFlags flags,
|
||||
VkDeviceSize size,
|
||||
VkDeviceSize align,
|
||||
DxvkMemoryFlags hints,
|
||||
const VkMemoryDedicatedAllocateInfo* dedAllocInfo) {
|
||||
const DxvkMemoryProperties& info,
|
||||
DxvkMemoryFlags hints) {
|
||||
VkDeviceSize chunkSize = pickChunkSize(type->memTypeId, hints);
|
||||
|
||||
DxvkMemory memory;
|
||||
|
||||
if (size >= chunkSize || dedAllocInfo) {
|
||||
if (size >= chunkSize || info.dedicated.buffer || info.dedicated.image) {
|
||||
if (this->shouldFreeEmptyChunks(type->heap, size))
|
||||
this->freeEmptyChunks(type->heap);
|
||||
|
||||
DxvkDeviceMemory devMem = this->tryAllocDeviceMemory(
|
||||
type, flags, size, hints, dedAllocInfo);
|
||||
DxvkDeviceMemory devMem = this->tryAllocDeviceMemory(type, size, info, hints);
|
||||
|
||||
if (devMem.memHandle != VK_NULL_HANDLE)
|
||||
memory = DxvkMemory(this, nullptr, type, devMem.memHandle, 0, size, devMem.memPointer);
|
||||
} else {
|
||||
for (uint32_t i = 0; i < type->chunks.size() && !memory; i++)
|
||||
memory = type->chunks[i]->alloc(flags, size, align, hints);
|
||||
memory = type->chunks[i]->alloc(info.flags, size, align, hints);
|
||||
|
||||
if (!memory) {
|
||||
DxvkDeviceMemory devMem;
|
||||
@ -341,11 +343,11 @@ namespace dxvk {
|
||||
this->freeEmptyChunks(type->heap);
|
||||
|
||||
for (uint32_t i = 0; i < 6 && (chunkSize >> i) >= size && !devMem.memHandle; i++)
|
||||
devMem = tryAllocDeviceMemory(type, flags, chunkSize >> i, hints, nullptr);
|
||||
devMem = tryAllocDeviceMemory(type, chunkSize >> i, info, hints);
|
||||
|
||||
if (devMem.memHandle) {
|
||||
Rc<DxvkMemoryChunk> chunk = new DxvkMemoryChunk(this, type, devMem, hints);
|
||||
memory = chunk->alloc(flags, size, align, hints);
|
||||
memory = chunk->alloc(info.flags, size, align, hints);
|
||||
|
||||
type->chunks.push_back(std::move(chunk));
|
||||
}
|
||||
@ -361,11 +363,10 @@ namespace dxvk {
|
||||
|
||||
DxvkDeviceMemory DxvkMemoryAllocator::tryAllocDeviceMemory(
|
||||
DxvkMemoryType* type,
|
||||
VkMemoryPropertyFlags flags,
|
||||
VkDeviceSize size,
|
||||
DxvkMemoryFlags hints,
|
||||
const VkMemoryDedicatedAllocateInfo* dedAllocInfo) {
|
||||
bool useMemoryPriority = (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
|
||||
DxvkMemoryProperties info,
|
||||
DxvkMemoryFlags hints) {
|
||||
bool useMemoryPriority = (info.flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
|
||||
&& (m_device->features().extMemoryPriority.memoryPriority);
|
||||
|
||||
if (type->heap->budget && type->heap->stats.memoryAllocated + size > type->heap->budget)
|
||||
@ -380,23 +381,32 @@ namespace dxvk {
|
||||
|
||||
DxvkDeviceMemory result;
|
||||
result.memSize = size;
|
||||
result.memFlags = flags;
|
||||
result.memFlags = info.flags;
|
||||
result.priority = priority;
|
||||
|
||||
VkMemoryPriorityAllocateInfoEXT prio = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT };
|
||||
prio.priority = priority;
|
||||
VkMemoryPriorityAllocateInfoEXT priorityInfo = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT };
|
||||
priorityInfo.priority = priority;
|
||||
|
||||
VkMemoryAllocateInfo info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, dedAllocInfo };
|
||||
info.allocationSize = size;
|
||||
info.memoryTypeIndex = type->memTypeId;
|
||||
VkMemoryAllocateInfo memoryInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||
memoryInfo.allocationSize = size;
|
||||
memoryInfo.memoryTypeIndex = type->memTypeId;
|
||||
|
||||
if (info.sharedExport.handleTypes)
|
||||
info.sharedExport.pNext = std::exchange(memoryInfo.pNext, &info.sharedExport);
|
||||
|
||||
if (info.sharedImportWin32.handleType)
|
||||
info.sharedImportWin32.pNext = std::exchange(memoryInfo.pNext, &info.sharedImportWin32);
|
||||
|
||||
if (info.dedicated.buffer || info.dedicated.image)
|
||||
info.dedicated.pNext = std::exchange(memoryInfo.pNext, &info.dedicated);
|
||||
|
||||
if (useMemoryPriority)
|
||||
prio.pNext = std::exchange(info.pNext, &prio);
|
||||
priorityInfo.pNext = std::exchange(memoryInfo.pNext, &priorityInfo);
|
||||
|
||||
if (m_vkd->vkAllocateMemory(m_vkd->device(), &info, nullptr, &result.memHandle) != VK_SUCCESS)
|
||||
if (m_vkd->vkAllocateMemory(m_vkd->device(), &memoryInfo, nullptr, &result.memHandle) != VK_SUCCESS)
|
||||
return DxvkDeviceMemory();
|
||||
|
||||
if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
|
||||
if (info.flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
|
||||
VkResult status = m_vkd->vkMapMemory(m_vkd->device(), result.memHandle, 0, VK_WHOLE_SIZE, 0, &result.memPointer);
|
||||
|
||||
if (status != VK_SUCCESS) {
|
||||
|
@ -271,8 +271,28 @@ namespace dxvk {
|
||||
bool checkHints(DxvkMemoryFlags hints) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \brief Memory requirement info
|
||||
*/
|
||||
struct DxvkMemoryRequirements {
|
||||
VkMemoryDedicatedRequirements dedicated;
|
||||
VkMemoryRequirements2 core;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Memory allocation info
|
||||
*/
|
||||
struct DxvkMemoryProperties {
|
||||
VkExportMemoryAllocateInfo sharedExport;
|
||||
VkImportMemoryWin32HandleInfoKHR sharedImportWin32;
|
||||
VkMemoryDedicatedAllocateInfo dedicated;
|
||||
VkMemoryPropertyFlags flags;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Memory allocator
|
||||
*
|
||||
@ -305,17 +325,13 @@ namespace dxvk {
|
||||
* \brief Allocates device memory
|
||||
*
|
||||
* \param [in] req Memory requirements
|
||||
* \param [in] dedAllocReq Dedicated allocation requirements
|
||||
* \param [in] dedAllocInfo Dedicated allocation info
|
||||
* \param [in] flags Memory type flags
|
||||
* \param [in] info Memory properties
|
||||
* \param [in] hints Memory hints
|
||||
* \returns Allocated memory slice
|
||||
*/
|
||||
DxvkMemory alloc(
|
||||
const VkMemoryRequirements* req,
|
||||
const VkMemoryDedicatedRequirements& dedAllocReq,
|
||||
const VkMemoryDedicatedAllocateInfo& dedAllocInfo,
|
||||
VkMemoryPropertyFlags flags,
|
||||
const DxvkMemoryRequirements& req,
|
||||
DxvkMemoryProperties info,
|
||||
DxvkMemoryFlags hints);
|
||||
|
||||
/**
|
||||
@ -342,25 +358,22 @@ namespace dxvk {
|
||||
std::array<DxvkMemoryType, VK_MAX_MEMORY_TYPES> m_memTypes;
|
||||
|
||||
DxvkMemory tryAlloc(
|
||||
const VkMemoryRequirements* req,
|
||||
const VkMemoryDedicatedAllocateInfo* dedAllocInfo,
|
||||
VkMemoryPropertyFlags flags,
|
||||
const DxvkMemoryRequirements& req,
|
||||
const DxvkMemoryProperties& info,
|
||||
DxvkMemoryFlags hints);
|
||||
|
||||
DxvkMemory tryAllocFromType(
|
||||
DxvkMemoryType* type,
|
||||
VkMemoryPropertyFlags flags,
|
||||
VkDeviceSize size,
|
||||
VkDeviceSize align,
|
||||
DxvkMemoryFlags hints,
|
||||
const VkMemoryDedicatedAllocateInfo* dedAllocInfo);
|
||||
const DxvkMemoryProperties& info,
|
||||
DxvkMemoryFlags hints);
|
||||
|
||||
DxvkDeviceMemory tryAllocDeviceMemory(
|
||||
DxvkMemoryType* type,
|
||||
VkMemoryPropertyFlags flags,
|
||||
VkDeviceSize size,
|
||||
DxvkMemoryFlags hints,
|
||||
const VkMemoryDedicatedAllocateInfo* dedAllocInfo);
|
||||
DxvkMemoryProperties info,
|
||||
DxvkMemoryFlags hints);
|
||||
|
||||
void free(
|
||||
const DxvkMemory& memory);
|
||||
|
Loading…
x
Reference in New Issue
Block a user