Properly use VK_KHR_dedicated_allocation to make some drivers extra happy

This commit is contained in:
Henrik Rydgard authored and Henrik Rydgård committed 2019-02-05 18:07:18 +01:00
1 parent 8e1a5ef3d6
commit 32f37723f9
2 files changed
+79 -17

No files matched your search

+26 -2
View File
@@ -72,9 +72,27 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
}
VkMemoryRequirements mem_reqs{};
vkGetImageMemoryRequirements(vulkan_->GetDevice(), image_, &mem_reqs);
if (allocator_) {
bool dedicatedAllocation = false;
if (vulkan_->DeviceExtensions().KHR_dedicated_allocation) {
VkImageMemoryRequirementsInfo2KHR memReqInfo2{VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR};
memReqInfo2.image = image_;
VkMemoryRequirements2KHR memReq2 = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR};
VkMemoryDedicatedRequirementsKHR memDedicatedReq{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR};
memReq2.pNext = &memDedicatedReq;
vkGetImageMemoryRequirements2KHR(vulkan_->GetDevice(), &memReqInfo2, &memReq2);
mem_reqs = memReq2.memoryRequirements;
dedicatedAllocation =
(memDedicatedReq.requiresDedicatedAllocation != VK_FALSE) ||
(memDedicatedReq.prefersDedicatedAllocation != VK_FALSE);
} else {
vkGetImageMemoryRequirements(vulkan_->GetDevice(), image_, &mem_reqs);
}
if (allocator_ && !dedicatedAllocation) {
offset_ = allocator_->Allocate(mem_reqs, &mem_, Tag());
if (offset_ == VulkanDeviceAllocator::ALLOCATE_FAILED) {
ELOG("Image memory allocation failed (mem_reqs.size=%d, typebits=%08x", (int)mem_reqs.size, (int)mem_reqs.memoryTypeBits);
@@ -86,6 +104,12 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
mem_alloc.memoryTypeIndex = 0;
mem_alloc.allocationSize = mem_reqs.size;
VkMemoryDedicatedAllocateInfoKHR dedicatedAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR};
if (dedicatedAllocation) {
dedicatedAllocateInfo.image = image_;
mem_alloc.pNext = &dedicatedAllocateInfo;
}
// Find memory type - don't specify any mapping requirements
bool pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &mem_alloc.memoryTypeIndex);
_assert_(pass);
+53 -15
View File
@@ -42,24 +42,39 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int
vkCreateImage(vulkan->GetDevice(), &ici, nullptr, &img.image);
VkMemoryRequirements memreq;
vkGetImageMemoryRequirements(vulkan->GetDevice(), img.image, &memreq);
bool dedicatedAllocation = false;
if (vulkan->DeviceExtensions().KHR_dedicated_allocation) {
VkImageMemoryRequirementsInfo2KHR memReqInfo2{VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR};
memReqInfo2.image = img.image;
VkMemoryRequirements2KHR memReq2 = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR};
VkMemoryDedicatedRequirementsKHR memDedicatedReq{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR};
memReq2.pNext = &memDedicatedReq;
vkGetImageMemoryRequirements2KHR(vulkan->GetDevice(), &memReqInfo2, &memReq2);
memreq = memReq2.memoryRequirements;
dedicatedAllocation =
(memDedicatedReq.requiresDedicatedAllocation != VK_FALSE) ||
(memDedicatedReq.prefersDedicatedAllocation != VK_FALSE);
} else {
vkGetImageMemoryRequirements(vulkan->GetDevice(), img.image, &memreq);
}
VkMemoryAllocateInfo alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
alloc.allocationSize = memreq.size;
/*
// Hint to the driver that this allocation is image-specific. Some drivers benefit.
// We only bother supporting the KHR extension, not the old NV one.
VkMemoryDedicatedAllocateInfoKHR dedicated{ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR };
if (vulkan->DeviceExtensions().DEDICATED_ALLOCATION) {
alloc.pNext = &dedicated;
dedicated.image = img.image;
VkMemoryDedicatedAllocateInfoKHR dedicatedAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR};
if (dedicatedAllocation) {
dedicatedAllocateInfo.image = img.image;
alloc.pNext = &dedicatedAllocateInfo;
}
*/
vulkan->MemoryTypeFromProperties(memreq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &alloc.memoryTypeIndex);
VkResult res = vkAllocateMemory(vulkan->GetDevice(), &alloc, nullptr, &img.memory);
assert(res == VK_SUCCESS);
res = vkBindImageMemory(vulkan->GetDevice(), img.image, img.memory, 0);
assert(res == VK_SUCCESS);
@@ -554,10 +569,6 @@ bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) {
image_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
image_info.flags = 0;
VkMemoryAllocateInfo mem_alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
mem_alloc.allocationSize = 0;
mem_alloc.memoryTypeIndex = 0;
VkMemoryRequirements mem_reqs;
depth_.format = depth_format;
@@ -568,9 +579,36 @@ bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) {
if (res != VK_SUCCESS)
return false;
vkGetImageMemoryRequirements(device, depth_.image, &mem_reqs);
bool dedicatedAllocation = false;
if (vulkan_->DeviceExtensions().KHR_dedicated_allocation) {
VkImageMemoryRequirementsInfo2KHR memReqInfo2{VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR};
memReqInfo2.image = depth_.image;
VkMemoryRequirements2KHR memReq2 = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR};
VkMemoryDedicatedRequirementsKHR memDedicatedReq{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR};
memReq2.pNext = &memDedicatedReq;
vkGetImageMemoryRequirements2KHR(vulkan_->GetDevice(), &memReqInfo2, &memReq2);
mem_reqs = memReq2.memoryRequirements;
dedicatedAllocation =
(memDedicatedReq.requiresDedicatedAllocation != VK_FALSE) ||
(memDedicatedReq.prefersDedicatedAllocation != VK_FALSE);
} else {
vkGetImageMemoryRequirements(vulkan_->GetDevice(), depth_.image, &mem_reqs);
}
VkMemoryAllocateInfo mem_alloc = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
mem_alloc.allocationSize = mem_reqs.size;
mem_alloc.memoryTypeIndex = 0;
VkMemoryDedicatedAllocateInfoKHR dedicatedAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR};
if (dedicatedAllocation) {
dedicatedAllocateInfo.image = depth_.image;
mem_alloc.pNext = &dedicatedAllocateInfo;
}
// Use the memory properties to determine the type of memory required
pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits,
0, /* No requirements */