| 69 | } |
| 70 | |
| 71 | bool vulkan_buffer::create_internal(const bool copy_host_data, const device_queue& cqueue) { |
| 72 | const auto& vulkan_dev = vk_dev.device; |
| 73 | |
| 74 | // create the buffer |
| 75 | const auto is_sharing = has_flag<MEMORY_FLAG::VULKAN_SHARING>(flags); |
| 76 | const auto is_host_coherent = has_flag<MEMORY_FLAG::VULKAN_HOST_COHERENT>(flags); |
| 77 | const auto is_desc_buffer = has_flag<MEMORY_FLAG::VULKAN_DESCRIPTOR_BUFFER>(flags); |
| 78 | // set all the bits here, might need some better restrictions later on |
| 79 | // NOTE: not setting vertex bit here, b/c we're always using SSBOs |
| 80 | buffer_usage = (VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT | |
| 81 | VK_BUFFER_USAGE_2_TRANSFER_DST_BIT | |
| 82 | VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT | |
| 83 | VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT | |
| 84 | VK_BUFFER_USAGE_2_INDIRECT_BUFFER_BIT | |
| 85 | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT); |
| 86 | VkExternalMemoryBufferCreateInfo ext_create_info; |
| 87 | if (is_sharing) { |
| 88 | ext_create_info = { |
| 89 | .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, |
| 90 | .pNext = nullptr, |
| 91 | #if defined(__WINDOWS__) |
| 92 | .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, |
| 93 | #else |
| 94 | .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, |
| 95 | #endif |
| 96 | }; |
| 97 | } |
| 98 | if (is_desc_buffer) { |
| 99 | buffer_usage |= VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT; |
| 100 | } |
| 101 | const auto is_concurrent_sharing = (vk_dev.all_queue_family_index != vk_dev.compute_queue_family_index); |
| 102 | const VkBufferUsageFlags2CreateInfo buffer_usage_flags_info { |
| 103 | .sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO, |
| 104 | .pNext = (is_sharing ? &ext_create_info : nullptr), |
| 105 | .usage = buffer_usage, |
| 106 | }; |
| 107 | const VkBufferCreateInfo buffer_create_info { |
| 108 | .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, |
| 109 | .pNext = &buffer_usage_flags_info, |
| 110 | .flags = 0, |
| 111 | .size = size, |
| 112 | .usage = 0, |
| 113 | .sharingMode = (is_concurrent_sharing ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE), |
| 114 | .queueFamilyIndexCount = (is_concurrent_sharing ? uint32_t(vk_dev.queue_families.size()) : 0), |
| 115 | .pQueueFamilyIndices = (is_concurrent_sharing ? vk_dev.queue_families.data() : nullptr), |
| 116 | }; |
| 117 | |
| 118 | VkExportMemoryAllocateInfo export_alloc_info; |
| 119 | if (!is_heap_allocation) { |
| 120 | VK_CALL_RET(vkCreateBuffer(vulkan_dev, &buffer_create_info, nullptr, &buffer), |
| 121 | "buffer creation failed", false) |
| 122 | |
| 123 | // export memory alloc info (if sharing is enabled) |
| 124 | #if defined(__WINDOWS__) |
| 125 | VkExportMemoryWin32HandleInfoKHR export_mem_win32_info; |
| 126 | #endif |
| 127 | if (is_sharing) { |
| 128 | #if defined(__WINDOWS__) |