| 49 | } |
| 50 | |
| 51 | VltPhysicalBuffer VltBuffer::allocBuffer(VkDeviceSize sliceCount) const |
| 52 | { |
| 53 | VkBufferCreateInfo info; |
| 54 | info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; |
| 55 | info.pNext = nullptr; |
| 56 | info.flags = 0; |
| 57 | info.size = m_physSliceStride * sliceCount; |
| 58 | info.usage = m_info.usage; |
| 59 | info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
| 60 | info.queueFamilyIndexCount = 0; |
| 61 | info.pQueueFamilyIndices = nullptr; |
| 62 | |
| 63 | VltPhysicalBuffer handle; |
| 64 | |
| 65 | if (vkCreateBuffer(m_device->handle(), |
| 66 | &info, nullptr, &handle.buffer) != VK_SUCCESS) |
| 67 | { |
| 68 | Logger::exception(util::str::formatex( |
| 69 | "DxvkBuffer: Failed to create buffer:" |
| 70 | "\n size: ", |
| 71 | info.size, |
| 72 | "\n usage: ", info.usage)); |
| 73 | } |
| 74 | |
| 75 | VkMemoryDedicatedRequirements dedicatedRequirements; |
| 76 | dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; |
| 77 | dedicatedRequirements.pNext = VK_NULL_HANDLE; |
| 78 | dedicatedRequirements.prefersDedicatedAllocation = VK_FALSE; |
| 79 | dedicatedRequirements.requiresDedicatedAllocation = VK_FALSE; |
| 80 | |
| 81 | VkMemoryRequirements2 memReq; |
| 82 | memReq.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; |
| 83 | memReq.pNext = &dedicatedRequirements; |
| 84 | |
| 85 | VkBufferMemoryRequirementsInfo2 memReqInfo; |
| 86 | memReqInfo.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2; |
| 87 | memReqInfo.buffer = handle.buffer; |
| 88 | memReqInfo.pNext = VK_NULL_HANDLE; |
| 89 | |
| 90 | VkMemoryDedicatedAllocateInfo dedMemoryAllocInfo; |
| 91 | dedMemoryAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; |
| 92 | dedMemoryAllocInfo.pNext = VK_NULL_HANDLE; |
| 93 | dedMemoryAllocInfo.buffer = handle.buffer; |
| 94 | dedMemoryAllocInfo.image = VK_NULL_HANDLE; |
| 95 | |
| 96 | vkGetBufferMemoryRequirements2( |
| 97 | m_device->handle(), &memReqInfo, &memReq); |
| 98 | |
| 99 | // Use high memory priority for GPU-writable resources |
| 100 | bool isGpuWritable = (m_info.access & (VK_ACCESS_SHADER_WRITE_BIT | |
| 101 | VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT)) != 0; |
| 102 | |
| 103 | VltMemoryFlags hints(VltMemoryFlag::GpuReadable); |
| 104 | |
| 105 | if (isGpuWritable) |
| 106 | hints.set(VltMemoryFlag::GpuWritable); |
| 107 | |
| 108 | // Staging buffers that can't even be used as a transfer destinations |