1 //
2 // Copyright (c) 2022 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #ifdef _WIN32
18 #define NOMINMAX
19 #include <Windows.h>
20 #include <dxgi1_2.h>
21 #include <aclapi.h>
22 #endif
23 #include <vulkan/vulkan.h>
24 #include "vulkan_wrapper.hpp"
25 #if defined(__linux__) && !defined(__ANDROID__)
26 #include <gnu/libc-version.h>
27 #include <dlfcn.h>
28 #elif defined(__ANDROID__)
29 #include <dlfcn.h>
30 #endif
31 #if defined _WIN32
32 #define LoadFunction GetProcAddress
33 #elif defined __linux
34 #define LoadFunction dlsym
35 #endif
36
37 extern "C" {
38 #define VK_FUNC_DECL(name) PFN_##name _##name = NULL;
39 VK_FUNC_LIST
40 #if defined(_WIN32) || defined(_WIN64)
41 VK_WINDOWS_FUNC_LIST
42 #endif
43 #undef VK_FUNC_DECL
44 }
45
46 #define WAIVED 2
47 #define HANDLE_ERROR -1
48
49 #define CHECK_VK(call) \
50 if (call != VK_SUCCESS) return call;
51 ///////////////////////////////////
52 // VulkanInstance implementation //
53 ///////////////////////////////////
54
VulkanInstance(const VulkanInstance & instance)55 VulkanInstance::VulkanInstance(const VulkanInstance &instance)
56 : m_vkInstance(instance.m_vkInstance),
57 m_physicalDeviceList(instance.m_physicalDeviceList)
58 {}
59
VulkanInstance()60 VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
61 {
62 #if defined(__linux__) && !defined(__ANDROID__)
63 char *glibcVersion = strdup(gnu_get_libc_version());
64 int majNum = (int)atoi(strtok(glibcVersion, "."));
65 int minNum = (int)atoi(strtok(NULL, "."));
66 free(glibcVersion);
67 if ((majNum < 2) || (majNum == 2 && minNum < 17))
68 {
69 // WAIVE_TEST() << "Insufficient GLIBC version. Test waived!";
70 }
71 #endif
72
73 #if defined(_WIN32) || defined(_WIN64)
74 const char *vulkanLoaderLibraryName = "vulkan-1.dll";
75 #elif defined(__linux__)
76 const char *vulkanLoaderLibraryName = "libvulkan.so.1";
77 #endif
78 #ifdef _WIN32
79 HINSTANCE hDLL;
80 hDLL = LoadLibrary(vulkanLoaderLibraryName);
81 if (hDLL == NULL)
82 {
83 throw std::runtime_error("LoadLibrary failed!");
84 }
85 vkGetInstanceProcAddr =
86 (PFN_vkGetInstanceProcAddr)LoadFunction(hDLL, "vkGetInstanceProcAddr");
87 #else
88 #if !defined(__APPLE__)
89 void *handle;
90 handle = dlopen(vulkanLoaderLibraryName, RTLD_LAZY);
91 if (!handle)
92 {
93 fputs(dlerror(), stderr);
94 throw std::runtime_error("dlopen failed !!!");
95 }
96 vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)LoadFunction(
97 handle, "vkGetInstanceProcAddr");
98 #endif
99 #endif
100 if ((unsigned long long)vkGetInstanceProcAddr == (unsigned long long)NULL)
101 {
102 throw std::runtime_error("vkGetInstanceProcAddr() not found!");
103 }
104 #define VK_GET_NULL_INSTANCE_PROC_ADDR(name) \
105 _##name = (PFN_##name)vkGetInstanceProcAddr(NULL, #name);
106
107 if ((unsigned long long)vkGetInstanceProcAddr == (unsigned long long)NULL)
108 {
109 throw std::runtime_error("Couldn't obtain address for function");
110 }
111 VK_GET_NULL_INSTANCE_PROC_ADDR(vkEnumerateInstanceExtensionProperties);
112 uint32_t instanceExtensionPropertiesCount;
113 VkResult vkStatus = VK_SUCCESS;
114 vkStatus = vkEnumerateInstanceExtensionProperties(
115 NULL, &instanceExtensionPropertiesCount, NULL);
116 // Something went wrong in vulkan initialization (most likely incompatible
117 // device/driver combination)
118 if (vkStatus == VK_ERROR_INCOMPATIBLE_DRIVER)
119 {
120 throw std::runtime_error(
121 "Waiving vulkan test because "
122 "vkEnumerateInstanceExtensionProperties failed.");
123 // return WAIVED;
124 }
125
126 VK_GET_NULL_INSTANCE_PROC_ADDR(vkEnumerateInstanceVersion);
127 VK_GET_NULL_INSTANCE_PROC_ADDR(vkEnumerateInstanceLayerProperties);
128 VK_GET_NULL_INSTANCE_PROC_ADDR(vkCreateInstance);
129 #undef VK_GET_NULL_INSTANCE_PROC_ADDR
130
131 VkApplicationInfo vkApplicationInfo = {};
132 vkApplicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
133 vkApplicationInfo.pNext = NULL;
134 vkApplicationInfo.pApplicationName = "Default app";
135 vkApplicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
136 vkApplicationInfo.pEngineName = "No engine";
137 vkApplicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
138 vkApplicationInfo.apiVersion = VK_API_VERSION_1_0;
139
140 std::vector<const char *> enabledExtensionNameList;
141 enabledExtensionNameList.push_back(
142 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
143 enabledExtensionNameList.push_back(
144 VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
145 enabledExtensionNameList.push_back(
146 VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
147
148 std::vector<VkExtensionProperties> vkExtensionPropertiesList(
149 instanceExtensionPropertiesCount);
150 vkEnumerateInstanceExtensionProperties(NULL,
151 &instanceExtensionPropertiesCount,
152 vkExtensionPropertiesList.data());
153
154 for (size_t eenIdx = 0; eenIdx < enabledExtensionNameList.size(); eenIdx++)
155 {
156 bool isSupported = false;
157 for (size_t epIdx = 0; epIdx < vkExtensionPropertiesList.size();
158 epIdx++)
159 {
160 if (!strcmp(enabledExtensionNameList[eenIdx],
161 vkExtensionPropertiesList[epIdx].extensionName))
162 {
163 isSupported = true;
164 break;
165 }
166 }
167 if (!isSupported)
168 {
169 return;
170 }
171 }
172
173 VkInstanceCreateInfo vkInstanceCreateInfo = {};
174 vkInstanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
175 vkInstanceCreateInfo.pNext = NULL;
176 vkInstanceCreateInfo.flags = 0;
177 vkInstanceCreateInfo.pApplicationInfo = &vkApplicationInfo;
178 vkInstanceCreateInfo.enabledLayerCount = 0;
179 vkInstanceCreateInfo.ppEnabledLayerNames = NULL;
180 vkInstanceCreateInfo.enabledExtensionCount =
181 (uint32_t)enabledExtensionNameList.size();
182 vkInstanceCreateInfo.ppEnabledExtensionNames =
183 enabledExtensionNameList.data();
184
185 vkCreateInstance(&vkInstanceCreateInfo, NULL, &m_vkInstance);
186
187 #define VK_FUNC_DECL(name) \
188 _##name = (PFN_##name)vkGetInstanceProcAddr(m_vkInstance, #name); \
189 // ASSERT_NEQ((unsigned long long)name, 0ULL) << "Couldn't obtain address
190 // for function" << #name;
191
192 VK_FUNC_LIST
193 #if defined(_WIN32) || defined(_WIN64)
194 VK_WINDOWS_FUNC_LIST
195 #endif
196 #undef VK_FUNC_DECL
197
198 uint32_t physicalDeviceCount = 0;
199 vkEnumeratePhysicalDevices(m_vkInstance, &physicalDeviceCount, NULL);
200 // CHECK_NEQ(physicalDeviceCount, uint32_t(0));
201
202 if (physicalDeviceCount == uint32_t(0))
203 {
204 std::cout << "failed to find GPUs with Vulkan support!\n";
205 return;
206 }
207
208 std::vector<VkPhysicalDevice> vkPhysicalDeviceList(physicalDeviceCount,
209 VK_NULL_HANDLE);
210 vkEnumeratePhysicalDevices(m_vkInstance, &physicalDeviceCount,
211 vkPhysicalDeviceList.data());
212
213 for (size_t ppdIdx = 0; ppdIdx < vkPhysicalDeviceList.size(); ppdIdx++)
214 {
215 VulkanPhysicalDevice *physicalDevice =
216 new VulkanPhysicalDevice(vkPhysicalDeviceList[ppdIdx]);
217 m_physicalDeviceList.add(*physicalDevice);
218 }
219 }
220
~VulkanInstance()221 VulkanInstance::~VulkanInstance()
222 {
223 for (size_t pdIdx = 0; pdIdx < m_physicalDeviceList.size(); pdIdx++)
224 {
225 const VulkanPhysicalDevice &physicalDevice =
226 m_physicalDeviceList[pdIdx];
227 delete &physicalDevice;
228 }
229 if (m_vkInstance)
230 {
231 vkDestroyInstance(m_vkInstance, NULL);
232 }
233 }
234
getPhysicalDeviceList() const235 const VulkanPhysicalDeviceList &VulkanInstance::getPhysicalDeviceList() const
236 {
237 return m_physicalDeviceList;
238 }
239
operator VkInstance() const240 VulkanInstance::operator VkInstance() const { return m_vkInstance; }
241
242 /////////////////////////////////////////
243 // VulkanPhysicalDevice implementation //
244 /////////////////////////////////////////
245
VulkanPhysicalDevice(const VulkanPhysicalDevice & physicalDevice)246 VulkanPhysicalDevice::VulkanPhysicalDevice(
247 const VulkanPhysicalDevice &physicalDevice)
248 : m_vkPhysicalDevice(physicalDevice.m_vkPhysicalDevice),
249 m_vkPhysicalDeviceProperties(physicalDevice.m_vkPhysicalDeviceProperties),
250 m_vkDeviceNodeMask(physicalDevice.m_vkDeviceNodeMask),
251 m_vkPhysicalDeviceFeatures(physicalDevice.m_vkPhysicalDeviceFeatures),
252 m_vkPhysicalDeviceMemoryProperties(
253 physicalDevice.m_vkPhysicalDeviceMemoryProperties),
254 m_queueFamilyList(physicalDevice.m_queueFamilyList)
255 {
256 memcpy(m_vkDeviceUUID, physicalDevice.m_vkDeviceUUID, VK_UUID_SIZE);
257 }
258
VulkanPhysicalDevice(VkPhysicalDevice vkPhysicalDevice)259 VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkPhysicalDevice)
260 : m_vkPhysicalDevice(vkPhysicalDevice)
261 {
262 if (m_vkPhysicalDevice == (VkPhysicalDevice)VK_NULL_HANDLE)
263 {
264 throw std::runtime_error("failed to find a suitable GPU!");
265 }
266
267 vkGetPhysicalDeviceProperties(m_vkPhysicalDevice,
268 &m_vkPhysicalDeviceProperties);
269 vkGetPhysicalDeviceFeatures(m_vkPhysicalDevice,
270 &m_vkPhysicalDeviceFeatures);
271
272 VkPhysicalDeviceIDPropertiesKHR vkPhysicalDeviceIDPropertiesKHR = {};
273 vkPhysicalDeviceIDPropertiesKHR.sType =
274 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR;
275 vkPhysicalDeviceIDPropertiesKHR.pNext = NULL;
276
277 VkPhysicalDeviceProperties2KHR vkPhysicalDeviceProperties2KHR = {};
278 vkPhysicalDeviceProperties2KHR.sType =
279 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
280 vkPhysicalDeviceProperties2KHR.pNext = &vkPhysicalDeviceIDPropertiesKHR;
281
282 vkGetPhysicalDeviceProperties2KHR(m_vkPhysicalDevice,
283 &vkPhysicalDeviceProperties2KHR);
284
285 memcpy(m_vkDeviceUUID, vkPhysicalDeviceIDPropertiesKHR.deviceUUID,
286 sizeof(m_vkDeviceUUID));
287 memcpy(m_vkDeviceLUID, vkPhysicalDeviceIDPropertiesKHR.deviceLUID,
288 sizeof(m_vkDeviceLUID));
289 m_vkDeviceNodeMask = vkPhysicalDeviceIDPropertiesKHR.deviceNodeMask;
290
291 uint32_t queueFamilyCount = 0;
292 vkGetPhysicalDeviceQueueFamilyProperties(m_vkPhysicalDevice,
293 &queueFamilyCount, NULL);
294
295 std::vector<VkQueueFamilyProperties> vkQueueFamilyPropertiesList(
296 queueFamilyCount);
297 vkGetPhysicalDeviceQueueFamilyProperties(
298 m_vkPhysicalDevice, &queueFamilyCount,
299 vkQueueFamilyPropertiesList.data());
300
301 for (size_t qfpIdx = 0; qfpIdx < vkQueueFamilyPropertiesList.size();
302 qfpIdx++)
303 {
304 VulkanQueueFamily *queueFamily = new VulkanQueueFamily(
305 uint32_t(qfpIdx), vkQueueFamilyPropertiesList[qfpIdx]);
306 m_queueFamilyList.add(*queueFamily);
307 }
308
309 vkGetPhysicalDeviceMemoryProperties(m_vkPhysicalDevice,
310 &m_vkPhysicalDeviceMemoryProperties);
311
312 for (uint32_t mhIdx = 0;
313 mhIdx < m_vkPhysicalDeviceMemoryProperties.memoryHeapCount; mhIdx++)
314 {
315 VulkanMemoryHeap *memoryHeap = new VulkanMemoryHeap(
316 mhIdx, m_vkPhysicalDeviceMemoryProperties.memoryHeaps[mhIdx].size,
317 (VulkanMemoryHeapFlag)m_vkPhysicalDeviceMemoryProperties
318 .memoryHeaps[mhIdx]
319 .flags);
320 m_memoryHeapList.add(*memoryHeap);
321 }
322
323 for (uint32_t mtIdx = 0;
324 mtIdx < m_vkPhysicalDeviceMemoryProperties.memoryTypeCount; mtIdx++)
325 {
326 const VulkanMemoryHeap &memoryHeap = m_memoryHeapList
327 [m_vkPhysicalDeviceMemoryProperties.memoryTypes[mtIdx].heapIndex];
328 VulkanMemoryType *memoryType = new VulkanMemoryType(
329 mtIdx,
330 (VulkanMemoryTypeProperty)m_vkPhysicalDeviceMemoryProperties
331 .memoryTypes[mtIdx]
332 .propertyFlags,
333 memoryHeap);
334 m_memoryTypeList.add(*memoryType);
335 }
336 }
337
~VulkanPhysicalDevice()338 VulkanPhysicalDevice::~VulkanPhysicalDevice()
339 {
340 for (size_t mtIdx = 0; mtIdx < m_memoryTypeList.size(); mtIdx++)
341 {
342 const VulkanMemoryType &memoryType = m_memoryTypeList[mtIdx];
343 delete &memoryType;
344 }
345
346 for (size_t mhIdx = 0; mhIdx < m_memoryHeapList.size(); mhIdx++)
347 {
348 const VulkanMemoryHeap &memoryHeap = m_memoryHeapList[mhIdx];
349 delete &memoryHeap;
350 }
351
352 for (size_t qfIdx = 0; qfIdx < m_queueFamilyList.size(); qfIdx++)
353 {
354 const VulkanQueueFamily &queueFamily = m_queueFamilyList[qfIdx];
355 delete &queueFamily;
356 }
357 }
358
359
getQueueFamilyList() const360 const VulkanQueueFamilyList &VulkanPhysicalDevice::getQueueFamilyList() const
361 {
362 return m_queueFamilyList;
363 }
364
getMemoryHeapList() const365 const VulkanMemoryHeapList &VulkanPhysicalDevice::getMemoryHeapList() const
366 {
367 return m_memoryHeapList;
368 }
369
getMemoryTypeList() const370 const VulkanMemoryTypeList &VulkanPhysicalDevice::getMemoryTypeList() const
371 {
372 return m_memoryTypeList;
373 }
374
getUUID() const375 const uint8_t *VulkanPhysicalDevice::getUUID() const { return m_vkDeviceUUID; }
376
getLUID() const377 const uint8_t *VulkanPhysicalDevice::getLUID() const { return m_vkDeviceLUID; }
378
getNodeMask() const379 uint32_t VulkanPhysicalDevice::getNodeMask() const
380 {
381 return m_vkDeviceNodeMask;
382 }
383
operator VkPhysicalDevice() const384 VulkanPhysicalDevice::operator VkPhysicalDevice() const
385 {
386 return m_vkPhysicalDevice;
387 }
388
operator <(const VulkanQueueFamily & queueFamilyA,const VulkanQueueFamily & queueFamilyB)389 bool operator<(const VulkanQueueFamily &queueFamilyA,
390 const VulkanQueueFamily &queueFamilyB)
391 {
392 return (uint32_t)queueFamilyA < (uint32_t)queueFamilyB;
393 }
394
395 /////////////////////////////////////
396 // VulkanMemoryHeap implementation //
397 /////////////////////////////////////
398
VulkanMemoryHeap(const VulkanMemoryHeap & memoryHeap)399 VulkanMemoryHeap::VulkanMemoryHeap(const VulkanMemoryHeap &memoryHeap)
400 : m_memoryHeapIndex(memoryHeap.m_memoryHeapIndex),
401 m_size(memoryHeap.m_size), m_memoryHeapFlag(memoryHeap.m_memoryHeapFlag)
402 {}
403
VulkanMemoryHeap(uint32_t memoryHeapIndex,uint64_t size,VulkanMemoryHeapFlag memoryHeapFlag)404 VulkanMemoryHeap::VulkanMemoryHeap(uint32_t memoryHeapIndex, uint64_t size,
405 VulkanMemoryHeapFlag memoryHeapFlag)
406 : m_memoryHeapIndex(memoryHeapIndex), m_size(size),
407 m_memoryHeapFlag(memoryHeapFlag)
408 {}
409
~VulkanMemoryHeap()410 VulkanMemoryHeap::~VulkanMemoryHeap() {}
411
getSize() const412 uint64_t VulkanMemoryHeap::getSize() const { return m_size; }
413
414
getMemoryHeapFlag() const415 VulkanMemoryHeapFlag VulkanMemoryHeap::getMemoryHeapFlag() const
416 {
417 return m_memoryHeapFlag;
418 }
419
operator uint32_t() const420 VulkanMemoryHeap::operator uint32_t() const { return m_memoryHeapIndex; }
421
422 /////////////////////////////////////
423 // VulkanMemoryType implementation //
424 /////////////////////////////////////
425
VulkanMemoryType(const VulkanMemoryType & memoryType)426 VulkanMemoryType::VulkanMemoryType(const VulkanMemoryType &memoryType)
427 : m_memoryTypeIndex(memoryType.m_memoryTypeIndex),
428 m_memoryTypeProperty(memoryType.m_memoryTypeProperty),
429 m_memoryHeap(memoryType.m_memoryHeap)
430 {}
431
VulkanMemoryType(uint32_t memoryTypeIndex,VulkanMemoryTypeProperty memoryTypeProperty,const VulkanMemoryHeap & memoryHeap)432 VulkanMemoryType::VulkanMemoryType(uint32_t memoryTypeIndex,
433 VulkanMemoryTypeProperty memoryTypeProperty,
434 const VulkanMemoryHeap &memoryHeap)
435 : m_memoryTypeIndex(memoryTypeIndex),
436 m_memoryTypeProperty(memoryTypeProperty), m_memoryHeap(memoryHeap)
437 {}
438
~VulkanMemoryType()439 VulkanMemoryType::~VulkanMemoryType() {}
440
getMemoryTypeProperty() const441 VulkanMemoryTypeProperty VulkanMemoryType::getMemoryTypeProperty() const
442 {
443 return m_memoryTypeProperty;
444 }
445
getMemoryHeap() const446 const VulkanMemoryHeap &VulkanMemoryType::getMemoryHeap() const
447 {
448 return m_memoryHeap;
449 }
450
operator uint32_t() const451 VulkanMemoryType::operator uint32_t() const { return m_memoryTypeIndex; }
452
453 //////////////////////////////////////
454 // VulkanQueueFamily implementation //
455 //////////////////////////////////////
456
VulkanQueueFamily(const VulkanQueueFamily & queueFamily)457 VulkanQueueFamily::VulkanQueueFamily(const VulkanQueueFamily &queueFamily)
458 : m_queueFamilyIndex(queueFamily.m_queueFamilyIndex),
459 m_vkQueueFamilyProperties(queueFamily.m_vkQueueFamilyProperties)
460 {}
461
VulkanQueueFamily(uint32_t queueFamilyIndex,VkQueueFamilyProperties vkQueueFamilyProperties)462 VulkanQueueFamily::VulkanQueueFamily(
463 uint32_t queueFamilyIndex, VkQueueFamilyProperties vkQueueFamilyProperties)
464 : m_queueFamilyIndex(queueFamilyIndex),
465 m_vkQueueFamilyProperties(vkQueueFamilyProperties)
466 {}
467
~VulkanQueueFamily()468 VulkanQueueFamily::~VulkanQueueFamily() {}
469
getQueueFlags() const470 uint32_t VulkanQueueFamily::getQueueFlags() const
471 {
472 return m_vkQueueFamilyProperties.queueFlags
473 & (uint32_t)VULKAN_QUEUE_FLAG_MASK_ALL;
474 }
475
getQueueCount() const476 uint32_t VulkanQueueFamily::getQueueCount() const
477 {
478 return m_vkQueueFamilyProperties.queueCount;
479 }
480
operator uint32_t() const481 VulkanQueueFamily::operator uint32_t() const { return m_queueFamilyIndex; }
482
483 /////////////////////////////////
484 // VulkanDevice implementation //
485 /////////////////////////////////
486
VulkanDevice(const VulkanDevice & device)487 VulkanDevice::VulkanDevice(const VulkanDevice &device)
488 : m_physicalDevice(device.m_physicalDevice), m_vkDevice(device.m_vkDevice)
489 {}
490
VulkanDevice(const VulkanPhysicalDevice & physicalDevice,const VulkanQueueFamilyToQueueCountMap & queueFamilyToQueueCountMap)491 VulkanDevice::VulkanDevice(
492 const VulkanPhysicalDevice &physicalDevice,
493 const VulkanQueueFamilyToQueueCountMap &queueFamilyToQueueCountMap)
494 : m_physicalDevice(physicalDevice), m_vkDevice(NULL)
495 {
496 uint32_t maxQueueCount = 0;
497 for (uint32_t qfIdx = 0;
498 qfIdx < (uint32_t)physicalDevice.getQueueFamilyList().size(); qfIdx++)
499 {
500 maxQueueCount =
501 std::max(maxQueueCount, queueFamilyToQueueCountMap[qfIdx]);
502 }
503
504 std::vector<VkDeviceQueueCreateInfo> vkDeviceQueueCreateInfoList;
505 std::vector<float> queuePriorities(maxQueueCount);
506 for (uint32_t qfIdx = 0;
507 qfIdx < (uint32_t)physicalDevice.getQueueFamilyList().size(); qfIdx++)
508 {
509 if (queueFamilyToQueueCountMap[qfIdx])
510 {
511 VkDeviceQueueCreateInfo vkDeviceQueueCreateInfo = {};
512 vkDeviceQueueCreateInfo.sType =
513 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
514 vkDeviceQueueCreateInfo.pNext = NULL;
515 vkDeviceQueueCreateInfo.flags = 0;
516 vkDeviceQueueCreateInfo.queueFamilyIndex = qfIdx;
517 vkDeviceQueueCreateInfo.queueCount =
518 queueFamilyToQueueCountMap[qfIdx];
519 vkDeviceQueueCreateInfo.pQueuePriorities = queuePriorities.data();
520
521 vkDeviceQueueCreateInfoList.push_back(vkDeviceQueueCreateInfo);
522 }
523 }
524
525 std::vector<const char *> enabledExtensionNameList;
526 enabledExtensionNameList.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
527 enabledExtensionNameList.push_back(
528 VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
529 #if defined(_WIN32) || defined(_WIN64)
530 enabledExtensionNameList.push_back(
531 VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
532 enabledExtensionNameList.push_back(
533 VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME);
534 #else
535 enabledExtensionNameList.push_back(
536 VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
537 enabledExtensionNameList.push_back(
538 VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
539 #endif
540
541
542 VkDeviceCreateInfo vkDeviceCreateInfo = {};
543 vkDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
544 vkDeviceCreateInfo.pNext = NULL;
545 vkDeviceCreateInfo.flags = 0;
546 vkDeviceCreateInfo.queueCreateInfoCount =
547 (uint32_t)vkDeviceQueueCreateInfoList.size();
548 vkDeviceCreateInfo.pQueueCreateInfos = vkDeviceQueueCreateInfoList.data();
549 vkDeviceCreateInfo.enabledLayerCount = 0;
550 vkDeviceCreateInfo.ppEnabledLayerNames = NULL;
551 vkDeviceCreateInfo.enabledExtensionCount =
552 (uint32_t)enabledExtensionNameList.size();
553 vkDeviceCreateInfo.ppEnabledExtensionNames =
554 enabledExtensionNameList.data();
555 vkDeviceCreateInfo.pEnabledFeatures = NULL;
556
557 vkCreateDevice(physicalDevice, &vkDeviceCreateInfo, NULL, &m_vkDevice);
558
559 for (uint32_t qfIdx = 0;
560 qfIdx < (uint32_t)m_physicalDevice.getQueueFamilyList().size();
561 qfIdx++)
562 {
563 VulkanQueueList *queueList = new VulkanQueueList();
564 m_queueFamilyIndexToQueueListMap.insert(qfIdx, *queueList);
565 for (uint32_t qIdx = 0; qIdx < queueFamilyToQueueCountMap[qfIdx];
566 qIdx++)
567 {
568 VkQueue vkQueue;
569 vkGetDeviceQueue(m_vkDevice, qfIdx, qIdx, &vkQueue);
570 VulkanQueue *queue = new VulkanQueue(vkQueue);
571 m_queueFamilyIndexToQueueListMap[qfIdx].add(*queue);
572 }
573 }
574 }
575
~VulkanDevice()576 VulkanDevice::~VulkanDevice()
577 {
578 for (uint32_t qfIdx = 0;
579 qfIdx < (uint32_t)m_physicalDevice.getQueueFamilyList().size();
580 qfIdx++)
581 {
582 for (size_t qIdx = 0;
583 qIdx < m_queueFamilyIndexToQueueListMap[qfIdx].size(); qIdx++)
584 {
585 VulkanQueue &queue = m_queueFamilyIndexToQueueListMap[qfIdx][qIdx];
586 delete &queue;
587 }
588 VulkanQueueList &queueList = m_queueFamilyIndexToQueueListMap[qfIdx];
589 delete &queueList;
590 }
591 vkDestroyDevice(m_vkDevice, NULL);
592 }
593
getPhysicalDevice() const594 const VulkanPhysicalDevice &VulkanDevice::getPhysicalDevice() const
595 {
596 return m_physicalDevice;
597 }
598
getQueue(const VulkanQueueFamily & queueFamily,uint32_t queueIndex)599 VulkanQueue &VulkanDevice::getQueue(const VulkanQueueFamily &queueFamily,
600 uint32_t queueIndex)
601 {
602 return m_queueFamilyIndexToQueueListMap[queueFamily][queueIndex];
603 }
604
operator VkDevice() const605 VulkanDevice::operator VkDevice() const { return m_vkDevice; }
606
607 ////////////////////////////////
608 // VulkanQueue implementation //
609 ////////////////////////////////
610
VulkanQueue(const VulkanQueue & queue)611 VulkanQueue::VulkanQueue(const VulkanQueue &queue): m_vkQueue(queue.m_vkQueue)
612 {}
613
VulkanQueue(VkQueue vkQueue)614 VulkanQueue::VulkanQueue(VkQueue vkQueue): m_vkQueue(vkQueue) {}
615
~VulkanQueue()616 VulkanQueue::~VulkanQueue() {}
617
submit(const VulkanSemaphoreList & waitSemaphoreList,const VulkanCommandBufferList & commandBufferList,const VulkanSemaphoreList & signalSemaphoreList)618 void VulkanQueue::submit(const VulkanSemaphoreList &waitSemaphoreList,
619 const VulkanCommandBufferList &commandBufferList,
620 const VulkanSemaphoreList &signalSemaphoreList)
621 {
622 std::vector<VkPipelineStageFlags> vkPipelineStageFlagsList(
623 waitSemaphoreList.size(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
624
625 VkSubmitInfo vkSubmitInfo = {};
626 vkSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
627 vkSubmitInfo.pNext = NULL;
628 vkSubmitInfo.waitSemaphoreCount = (uint32_t)waitSemaphoreList.size();
629 vkSubmitInfo.pWaitSemaphores = waitSemaphoreList();
630 vkSubmitInfo.pWaitDstStageMask = vkPipelineStageFlagsList.data();
631 vkSubmitInfo.commandBufferCount = (uint32_t)commandBufferList.size();
632 vkSubmitInfo.pCommandBuffers = commandBufferList();
633 vkSubmitInfo.signalSemaphoreCount = (uint32_t)signalSemaphoreList.size();
634 vkSubmitInfo.pSignalSemaphores = signalSemaphoreList();
635
636 vkQueueSubmit(m_vkQueue, 1, &vkSubmitInfo, NULL);
637 }
638
submit(const VulkanSemaphore & waitSemaphore,const VulkanCommandBuffer & commandBuffer,const VulkanSemaphore & signalSemaphore)639 void VulkanQueue::submit(const VulkanSemaphore &waitSemaphore,
640 const VulkanCommandBuffer &commandBuffer,
641 const VulkanSemaphore &signalSemaphore)
642 {
643 VulkanSemaphoreList waitSemaphoreList;
644 VulkanCommandBufferList commandBufferList;
645 VulkanSemaphoreList signalSemaphoreList;
646
647 waitSemaphoreList.add(waitSemaphore);
648 commandBufferList.add(commandBuffer);
649 signalSemaphoreList.add(signalSemaphore);
650
651 submit(waitSemaphoreList, commandBufferList, signalSemaphoreList);
652 }
653
submit(const VulkanCommandBuffer & commandBuffer,const VulkanSemaphore & signalSemaphore)654 void VulkanQueue::submit(const VulkanCommandBuffer &commandBuffer,
655 const VulkanSemaphore &signalSemaphore)
656 {
657 VulkanSemaphoreList waitSemaphoreList;
658 VulkanCommandBufferList commandBufferList;
659 VulkanSemaphoreList signalSemaphoreList;
660
661 commandBufferList.add(commandBuffer);
662 signalSemaphoreList.add(signalSemaphore);
663
664 submit(waitSemaphoreList, commandBufferList, signalSemaphoreList);
665 }
666
submit(const VulkanCommandBuffer & commandBuffer)667 void VulkanQueue::submit(const VulkanCommandBuffer &commandBuffer)
668 {
669 VulkanSemaphoreList waitSemaphoreList;
670 VulkanCommandBufferList commandBufferList;
671 VulkanSemaphoreList signalSemaphoreList;
672
673 commandBufferList.add(commandBuffer);
674
675 submit(waitSemaphoreList, commandBufferList, signalSemaphoreList);
676 }
677
waitIdle()678 void VulkanQueue::waitIdle() { vkQueueWaitIdle(m_vkQueue); }
679
operator VkQueue() const680 VulkanQueue::operator VkQueue() const { return m_vkQueue; }
681
682 /////////////////////////////////////////////////////
683 // VulkanDescriptorSetLayoutBinding implementation //
684 /////////////////////////////////////////////////////
685
VulkanDescriptorSetLayoutBinding(const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding)686 VulkanDescriptorSetLayoutBinding::VulkanDescriptorSetLayoutBinding(
687 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding)
688 : m_vkDescriptorSetLayoutBinding(
689 descriptorSetLayoutBinding.m_vkDescriptorSetLayoutBinding)
690 {}
691
VulkanDescriptorSetLayoutBinding(uint32_t binding,VulkanDescriptorType descriptorType,uint32_t descriptorCount,VulkanShaderStage shaderStage)692 VulkanDescriptorSetLayoutBinding::VulkanDescriptorSetLayoutBinding(
693 uint32_t binding, VulkanDescriptorType descriptorType,
694 uint32_t descriptorCount, VulkanShaderStage shaderStage)
695 {
696 m_vkDescriptorSetLayoutBinding.binding = binding;
697 m_vkDescriptorSetLayoutBinding.descriptorType =
698 (VkDescriptorType)descriptorType;
699 m_vkDescriptorSetLayoutBinding.descriptorCount = descriptorCount;
700 m_vkDescriptorSetLayoutBinding.stageFlags =
701 (VkShaderStageFlags)(VkShaderStageFlagBits)shaderStage;
702 m_vkDescriptorSetLayoutBinding.pImmutableSamplers = NULL;
703 }
704
~VulkanDescriptorSetLayoutBinding()705 VulkanDescriptorSetLayoutBinding::~VulkanDescriptorSetLayoutBinding() {}
706
operator VkDescriptorSetLayoutBinding() const707 VulkanDescriptorSetLayoutBinding::operator VkDescriptorSetLayoutBinding() const
708 {
709 return m_vkDescriptorSetLayoutBinding;
710 }
711
712 //////////////////////////////////////////////
713 // VulkanDescriptorSetLayout implementation //
714 //////////////////////////////////////////////
715
VulkanDescriptorSetLayout(const VulkanDescriptorSetLayout & descriptorSetLayout)716 VulkanDescriptorSetLayout::VulkanDescriptorSetLayout(
717 const VulkanDescriptorSetLayout &descriptorSetLayout)
718 : m_device(descriptorSetLayout.m_device),
719 m_vkDescriptorSetLayout(descriptorSetLayout.m_vkDescriptorSetLayout)
720 {}
721
VulkanDescriptorSetLayoutCommon(const VulkanDescriptorSetLayoutBindingList & descriptorSetLayoutBindingList)722 void VulkanDescriptorSetLayout::VulkanDescriptorSetLayoutCommon(
723 const VulkanDescriptorSetLayoutBindingList &descriptorSetLayoutBindingList)
724 {
725 VkDescriptorSetLayoutCreateInfo vkDescriptorSetLayoutCreateInfo = {};
726 vkDescriptorSetLayoutCreateInfo.sType =
727 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
728 vkDescriptorSetLayoutCreateInfo.pNext = NULL;
729 vkDescriptorSetLayoutCreateInfo.flags = 0;
730 vkDescriptorSetLayoutCreateInfo.bindingCount =
731 (uint32_t)descriptorSetLayoutBindingList.size();
732 vkDescriptorSetLayoutCreateInfo.pBindings =
733 descriptorSetLayoutBindingList();
734
735 vkCreateDescriptorSetLayout(m_device, &vkDescriptorSetLayoutCreateInfo,
736 NULL, &m_vkDescriptorSetLayout);
737 }
738
VulkanDescriptorSetLayout(const VulkanDevice & device,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding)739 VulkanDescriptorSetLayout::VulkanDescriptorSetLayout(
740 const VulkanDevice &device,
741 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding)
742 : m_device(device), m_vkDescriptorSetLayout(VK_NULL_HANDLE)
743 {
744 VulkanDescriptorSetLayoutBindingList descriptorSetLayoutBindingList;
745 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding);
746
747 VulkanDescriptorSetLayoutCommon(descriptorSetLayoutBindingList);
748 }
749
VulkanDescriptorSetLayout(const VulkanDevice & device,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding0,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding1)750 VulkanDescriptorSetLayout::VulkanDescriptorSetLayout(
751 const VulkanDevice &device,
752 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding0,
753 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding1)
754 : m_device(device), m_vkDescriptorSetLayout(VK_NULL_HANDLE)
755 {
756 VulkanDescriptorSetLayoutBindingList descriptorSetLayoutBindingList;
757 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding0);
758 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding1);
759
760 VulkanDescriptorSetLayoutCommon(descriptorSetLayoutBindingList);
761 }
762
VulkanDescriptorSetLayout(const VulkanDevice & device,const VulkanDescriptorSetLayoutBindingList & descriptorSetLayoutBindingList)763 VulkanDescriptorSetLayout::VulkanDescriptorSetLayout(
764 const VulkanDevice &device,
765 const VulkanDescriptorSetLayoutBindingList &descriptorSetLayoutBindingList)
766 : m_device(device), m_vkDescriptorSetLayout(VK_NULL_HANDLE)
767 {
768 VulkanDescriptorSetLayoutCommon(descriptorSetLayoutBindingList);
769 }
770
~VulkanDescriptorSetLayout()771 VulkanDescriptorSetLayout::~VulkanDescriptorSetLayout()
772 {
773 if (m_vkDescriptorSetLayout != VK_NULL_HANDLE)
774 {
775 vkDestroyDescriptorSetLayout(m_device, m_vkDescriptorSetLayout, NULL);
776 }
777 }
778
operator VkDescriptorSetLayout() const779 VulkanDescriptorSetLayout::operator VkDescriptorSetLayout() const
780 {
781 return m_vkDescriptorSetLayout;
782 }
783
784 /////////////////////////////////////////
785 // VulkanPipelineLayout implementation //
786 /////////////////////////////////////////
787
VulkanPipelineLayout(const VulkanPipelineLayout & pipelineLayout)788 VulkanPipelineLayout::VulkanPipelineLayout(
789 const VulkanPipelineLayout &pipelineLayout)
790 : m_device(pipelineLayout.m_device),
791 m_vkPipelineLayout(pipelineLayout.m_vkPipelineLayout)
792 {}
793
VulkanPipelineLayoutCommon(const VulkanDescriptorSetLayoutList & descriptorSetLayoutList)794 void VulkanPipelineLayout::VulkanPipelineLayoutCommon(
795 const VulkanDescriptorSetLayoutList &descriptorSetLayoutList)
796 {
797 VkPipelineLayoutCreateInfo vkPipelineLayoutCreateInfo = {};
798 vkPipelineLayoutCreateInfo.sType =
799 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
800 vkPipelineLayoutCreateInfo.pNext = NULL;
801 vkPipelineLayoutCreateInfo.flags = 0;
802 vkPipelineLayoutCreateInfo.setLayoutCount =
803 (uint32_t)descriptorSetLayoutList.size();
804 vkPipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayoutList();
805 vkPipelineLayoutCreateInfo.pushConstantRangeCount = 0;
806 vkPipelineLayoutCreateInfo.pPushConstantRanges = NULL;
807
808 vkCreatePipelineLayout(m_device, &vkPipelineLayoutCreateInfo, NULL,
809 &m_vkPipelineLayout);
810 }
811
VulkanPipelineLayout(const VulkanDevice & device,const VulkanDescriptorSetLayout & descriptorSetLayout)812 VulkanPipelineLayout::VulkanPipelineLayout(
813 const VulkanDevice &device,
814 const VulkanDescriptorSetLayout &descriptorSetLayout)
815 : m_device(device), m_vkPipelineLayout(VK_NULL_HANDLE)
816 {
817 VulkanDescriptorSetLayoutList descriptorSetLayoutList;
818 descriptorSetLayoutList.add(descriptorSetLayout);
819
820 VulkanPipelineLayoutCommon(descriptorSetLayoutList);
821 }
822
VulkanPipelineLayout(const VulkanDevice & device,const VulkanDescriptorSetLayoutList & descriptorSetLayoutList)823 VulkanPipelineLayout::VulkanPipelineLayout(
824 const VulkanDevice &device,
825 const VulkanDescriptorSetLayoutList &descriptorSetLayoutList)
826 : m_device(device), m_vkPipelineLayout(VK_NULL_HANDLE)
827 {
828 VulkanPipelineLayoutCommon(descriptorSetLayoutList);
829 }
830
~VulkanPipelineLayout()831 VulkanPipelineLayout::~VulkanPipelineLayout()
832 {
833 vkDestroyPipelineLayout(m_device, m_vkPipelineLayout, NULL);
834 }
835
operator VkPipelineLayout() const836 VulkanPipelineLayout::operator VkPipelineLayout() const
837 {
838 return m_vkPipelineLayout;
839 }
840
841 ///////////////////////////////////////
842 // VulkanShaderModule implementation //
843 ///////////////////////////////////////
844
VulkanShaderModule(const VulkanShaderModule & shaderModule)845 VulkanShaderModule::VulkanShaderModule(const VulkanShaderModule &shaderModule)
846 : m_device(shaderModule.m_device),
847 m_vkShaderModule(shaderModule.m_vkShaderModule)
848 {}
849
VulkanShaderModule(const VulkanDevice & device,const std::vector<char> & code)850 VulkanShaderModule::VulkanShaderModule(const VulkanDevice &device,
851 const std::vector<char> &code)
852 : m_device(device)
853 {
854
855 VkShaderModuleCreateInfo vkShaderModuleCreateInfo = {};
856 vkShaderModuleCreateInfo.sType =
857 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
858 vkShaderModuleCreateInfo.pNext = NULL;
859 vkShaderModuleCreateInfo.flags = 0;
860 vkShaderModuleCreateInfo.codeSize = code.size();
861 vkShaderModuleCreateInfo.pCode =
862 reinterpret_cast<const uint32_t *>(code.data());
863
864 vkCreateShaderModule(m_device, &vkShaderModuleCreateInfo, NULL,
865 &m_vkShaderModule);
866 }
867
~VulkanShaderModule()868 VulkanShaderModule::~VulkanShaderModule()
869 {
870 vkDestroyShaderModule(m_device, m_vkShaderModule, NULL);
871 }
872
operator VkShaderModule() const873 VulkanShaderModule::operator VkShaderModule() const { return m_vkShaderModule; }
874
875 ///////////////////////////////////
876 // VulkanPipeline implementation //
877 ///////////////////////////////////
878
VulkanPipeline(const VulkanPipeline & pipeline)879 VulkanPipeline::VulkanPipeline(const VulkanPipeline &pipeline)
880 : m_device(pipeline.m_device), m_vkPipeline(pipeline.m_vkPipeline)
881 {}
882
VulkanPipeline(const VulkanDevice & device)883 VulkanPipeline::VulkanPipeline(const VulkanDevice &device)
884 : m_device(device), m_vkPipeline(VK_NULL_HANDLE)
885 {}
886
~VulkanPipeline()887 VulkanPipeline::~VulkanPipeline()
888 {
889 vkDestroyPipeline(m_device, m_vkPipeline, NULL);
890 }
891
operator VkPipeline() const892 VulkanPipeline::operator VkPipeline() const { return m_vkPipeline; }
893
894 //////////////////////////////////////////
895 // VulkanComputePipeline implementation //
896 //////////////////////////////////////////
897
VulkanComputePipeline(const VulkanComputePipeline & computePipeline)898 VulkanComputePipeline::VulkanComputePipeline(
899 const VulkanComputePipeline &computePipeline)
900 : VulkanPipeline(computePipeline)
901 {}
902
VulkanComputePipeline(const VulkanDevice & device,const VulkanPipelineLayout & pipelineLayout,const VulkanShaderModule & shaderModule,const std::string & entryFuncName)903 VulkanComputePipeline::VulkanComputePipeline(
904 const VulkanDevice &device, const VulkanPipelineLayout &pipelineLayout,
905 const VulkanShaderModule &shaderModule, const std::string &entryFuncName)
906 : VulkanPipeline(device)
907 {
908 VkPipelineShaderStageCreateInfo vkPipelineShaderStageCreateInfo = {};
909 vkPipelineShaderStageCreateInfo.sType =
910 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
911 vkPipelineShaderStageCreateInfo.pNext = NULL;
912 vkPipelineShaderStageCreateInfo.flags = 0;
913 vkPipelineShaderStageCreateInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT;
914 vkPipelineShaderStageCreateInfo.module = shaderModule;
915 vkPipelineShaderStageCreateInfo.pName = entryFuncName.c_str();
916 vkPipelineShaderStageCreateInfo.pSpecializationInfo = NULL;
917
918 VkComputePipelineCreateInfo vkComputePipelineCreateInfo = {};
919 vkComputePipelineCreateInfo.sType =
920 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
921 vkComputePipelineCreateInfo.pNext = NULL;
922 vkComputePipelineCreateInfo.flags = 0;
923 vkComputePipelineCreateInfo.stage = vkPipelineShaderStageCreateInfo;
924 vkComputePipelineCreateInfo.layout = pipelineLayout;
925 vkComputePipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
926 vkComputePipelineCreateInfo.basePipelineIndex = 0;
927
928 vkCreateComputePipelines(device, VK_NULL_HANDLE, 1,
929 &vkComputePipelineCreateInfo, NULL, &m_vkPipeline);
930 }
931
~VulkanComputePipeline()932 VulkanComputePipeline::~VulkanComputePipeline() {}
933
getPipelineBindPoint() const934 VulkanPipelineBindPoint VulkanComputePipeline::getPipelineBindPoint() const
935 {
936 return VULKAN_PIPELINE_BIND_POINT_COMPUTE;
937 }
938
939 /////////////////////////////////////////
940 // VulkanDescriptorPool implementation //
941 /////////////////////////////////////////
942
VulkanDescriptorPool(const VulkanDescriptorPool & descriptorPool)943 VulkanDescriptorPool::VulkanDescriptorPool(
944 const VulkanDescriptorPool &descriptorPool)
945 : m_device(descriptorPool.m_device),
946 m_vkDescriptorPool(descriptorPool.m_vkDescriptorPool)
947 {}
948
VulkanDescriptorPoolCommon(const VulkanDescriptorSetLayoutBindingList & descriptorSetLayoutBindingList)949 void VulkanDescriptorPool::VulkanDescriptorPoolCommon(
950 const VulkanDescriptorSetLayoutBindingList &descriptorSetLayoutBindingList)
951 {
952 if (descriptorSetLayoutBindingList.size())
953 {
954 std::map<VkDescriptorType, uint32_t>
955 vkDescriptorTypeToDescriptorCountMap;
956
957 for (size_t dslbIdx = 0;
958 dslbIdx < descriptorSetLayoutBindingList.size(); dslbIdx++)
959 {
960 VkDescriptorSetLayoutBinding vkDescriptorSetLayoutBinding =
961 descriptorSetLayoutBindingList[dslbIdx];
962 if (vkDescriptorTypeToDescriptorCountMap.find(
963 vkDescriptorSetLayoutBinding.descriptorType)
964 == vkDescriptorTypeToDescriptorCountMap.end())
965 {
966 vkDescriptorTypeToDescriptorCountMap
967 [vkDescriptorSetLayoutBinding.descriptorType] = 1;
968 }
969 else
970 {
971 vkDescriptorTypeToDescriptorCountMap
972 [vkDescriptorSetLayoutBinding.descriptorType]++;
973 }
974 }
975
976 std::vector<VkDescriptorPoolSize> vkDescriptorPoolSizeList;
977 std::map<VkDescriptorType, uint32_t>::iterator dtdcIt;
978 for (dtdcIt = vkDescriptorTypeToDescriptorCountMap.begin();
979 dtdcIt != vkDescriptorTypeToDescriptorCountMap.end(); ++dtdcIt)
980 {
981 VkDescriptorPoolSize vkDescriptorPoolSize = {};
982 vkDescriptorPoolSize.type = dtdcIt->first;
983 vkDescriptorPoolSize.descriptorCount = dtdcIt->second;
984
985 vkDescriptorPoolSizeList.push_back(vkDescriptorPoolSize);
986 }
987
988 VkDescriptorPoolCreateInfo vkDescriptorPoolCreateInfo = {};
989 vkDescriptorPoolCreateInfo.sType =
990 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
991 vkDescriptorPoolCreateInfo.pNext = NULL;
992 vkDescriptorPoolCreateInfo.flags =
993 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
994 vkDescriptorPoolCreateInfo.maxSets = 1;
995 vkDescriptorPoolCreateInfo.poolSizeCount =
996 (uint32_t)vkDescriptorPoolSizeList.size();
997 vkDescriptorPoolCreateInfo.pPoolSizes = vkDescriptorPoolSizeList.data();
998
999 vkCreateDescriptorPool(m_device, &vkDescriptorPoolCreateInfo, NULL,
1000 &m_vkDescriptorPool);
1001 }
1002 }
1003
VulkanDescriptorPool(const VulkanDevice & device,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding)1004 VulkanDescriptorPool::VulkanDescriptorPool(
1005 const VulkanDevice &device,
1006 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding)
1007 : m_device(device), m_vkDescriptorPool(VK_NULL_HANDLE)
1008 {
1009 VulkanDescriptorSetLayoutBindingList descriptorSetLayoutBindingList;
1010 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding);
1011
1012 VulkanDescriptorPoolCommon(descriptorSetLayoutBindingList);
1013 }
1014
VulkanDescriptorPool(const VulkanDevice & device,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding0,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding1)1015 VulkanDescriptorPool::VulkanDescriptorPool(
1016 const VulkanDevice &device,
1017 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding0,
1018 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding1)
1019 : m_device(device), m_vkDescriptorPool(VK_NULL_HANDLE)
1020 {
1021 VulkanDescriptorSetLayoutBindingList descriptorSetLayoutBindingList;
1022 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding0);
1023 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding1);
1024
1025 VulkanDescriptorPoolCommon(descriptorSetLayoutBindingList);
1026 }
1027
VulkanDescriptorPool(const VulkanDevice & device,const VulkanDescriptorSetLayoutBindingList & descriptorSetLayoutBindingList)1028 VulkanDescriptorPool::VulkanDescriptorPool(
1029 const VulkanDevice &device,
1030 const VulkanDescriptorSetLayoutBindingList &descriptorSetLayoutBindingList)
1031 : m_device(device), m_vkDescriptorPool(VK_NULL_HANDLE)
1032 {
1033 VulkanDescriptorPoolCommon(descriptorSetLayoutBindingList);
1034 }
1035
~VulkanDescriptorPool()1036 VulkanDescriptorPool::~VulkanDescriptorPool()
1037 {
1038 if (m_vkDescriptorPool != VK_NULL_HANDLE)
1039 {
1040 vkDestroyDescriptorPool(m_device, m_vkDescriptorPool, NULL);
1041 }
1042 }
1043
operator VkDescriptorPool() const1044 VulkanDescriptorPool::operator VkDescriptorPool() const
1045 {
1046 return m_vkDescriptorPool;
1047 }
1048
1049 ////////////////////////////////////////
1050 // VulkanDescriptorSet implementation //
1051 ////////////////////////////////////////
1052
VulkanDescriptorSet(const VulkanDescriptorSet & descriptorSet)1053 VulkanDescriptorSet::VulkanDescriptorSet(
1054 const VulkanDescriptorSet &descriptorSet)
1055 : m_device(descriptorSet.m_device),
1056 m_descriptorPool(descriptorSet.m_descriptorPool),
1057 m_vkDescriptorSet(descriptorSet.m_vkDescriptorSet)
1058 {}
1059
VulkanDescriptorSet(const VulkanDevice & device,const VulkanDescriptorPool & descriptorPool,const VulkanDescriptorSetLayout & descriptorSetLayout)1060 VulkanDescriptorSet::VulkanDescriptorSet(
1061 const VulkanDevice &device, const VulkanDescriptorPool &descriptorPool,
1062 const VulkanDescriptorSetLayout &descriptorSetLayout)
1063 : m_device(device), m_descriptorPool(descriptorPool),
1064 m_vkDescriptorSet(VK_NULL_HANDLE)
1065 {
1066 VkDescriptorSetLayout vkDescriptorSetLayout = descriptorSetLayout;
1067
1068 if ((VkDescriptorPool)m_descriptorPool)
1069 {
1070 VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo = {};
1071 vkDescriptorSetAllocateInfo.sType =
1072 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
1073 vkDescriptorSetAllocateInfo.pNext = NULL;
1074 vkDescriptorSetAllocateInfo.descriptorPool = descriptorPool;
1075 vkDescriptorSetAllocateInfo.descriptorSetCount = 1;
1076 vkDescriptorSetAllocateInfo.pSetLayouts = &vkDescriptorSetLayout;
1077
1078 vkAllocateDescriptorSets(m_device, &vkDescriptorSetAllocateInfo,
1079 &m_vkDescriptorSet);
1080 }
1081 }
1082
~VulkanDescriptorSet()1083 VulkanDescriptorSet::~VulkanDescriptorSet()
1084 {
1085 if ((VkDescriptorPool)m_descriptorPool)
1086 {
1087 vkFreeDescriptorSets(m_device, m_descriptorPool, 1, &m_vkDescriptorSet);
1088 }
1089 }
1090
update(uint32_t binding,const VulkanBuffer & buffer)1091 void VulkanDescriptorSet::update(uint32_t binding, const VulkanBuffer &buffer)
1092 {
1093 VkDescriptorBufferInfo vkDescriptorBufferInfo = {};
1094 vkDescriptorBufferInfo.buffer = buffer;
1095 vkDescriptorBufferInfo.offset = 0;
1096 vkDescriptorBufferInfo.range = VK_WHOLE_SIZE;
1097
1098 VkWriteDescriptorSet vkWriteDescriptorSet = {};
1099 vkWriteDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1100 vkWriteDescriptorSet.pNext = NULL;
1101 vkWriteDescriptorSet.dstSet = m_vkDescriptorSet;
1102 vkWriteDescriptorSet.dstBinding = binding;
1103 vkWriteDescriptorSet.dstArrayElement = 0;
1104 vkWriteDescriptorSet.descriptorCount = 1;
1105 vkWriteDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1106 vkWriteDescriptorSet.pImageInfo = NULL;
1107 vkWriteDescriptorSet.pBufferInfo = &vkDescriptorBufferInfo;
1108 vkWriteDescriptorSet.pTexelBufferView = NULL;
1109
1110 vkUpdateDescriptorSets(m_device, 1, &vkWriteDescriptorSet, 0, NULL);
1111 }
1112
update(uint32_t binding,const VulkanImageView & imageView)1113 void VulkanDescriptorSet::update(uint32_t binding,
1114 const VulkanImageView &imageView)
1115 {
1116 VkDescriptorImageInfo vkDescriptorImageInfo = {};
1117 vkDescriptorImageInfo.sampler = VK_NULL_HANDLE;
1118 vkDescriptorImageInfo.imageView = imageView;
1119 vkDescriptorImageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
1120
1121 VkWriteDescriptorSet vkWriteDescriptorSet = {};
1122 vkWriteDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1123 vkWriteDescriptorSet.pNext = NULL;
1124 vkWriteDescriptorSet.dstSet = m_vkDescriptorSet;
1125 vkWriteDescriptorSet.dstBinding = binding;
1126 vkWriteDescriptorSet.dstArrayElement = 0;
1127 vkWriteDescriptorSet.descriptorCount = 1;
1128 vkWriteDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1129 vkWriteDescriptorSet.pImageInfo = &vkDescriptorImageInfo;
1130 vkWriteDescriptorSet.pBufferInfo = NULL;
1131 vkWriteDescriptorSet.pTexelBufferView = NULL;
1132
1133 vkUpdateDescriptorSets(m_device, 1, &vkWriteDescriptorSet, 0, NULL);
1134 }
1135
operator VkDescriptorSet() const1136 VulkanDescriptorSet::operator VkDescriptorSet() const
1137 {
1138 return m_vkDescriptorSet;
1139 }
1140
1141 ///////////////////////////////////
1142 // VulkanOffset3D implementation //
1143 ///////////////////////////////////
1144
VulkanOffset3D(const VulkanOffset3D & offset3D)1145 VulkanOffset3D::VulkanOffset3D(const VulkanOffset3D &offset3D)
1146 : m_vkOffset3D(offset3D.m_vkOffset3D)
1147 {}
1148
VulkanOffset3D(uint32_t x,uint32_t y,uint32_t z)1149 VulkanOffset3D::VulkanOffset3D(uint32_t x, uint32_t y, uint32_t z)
1150 {
1151 m_vkOffset3D.x = x;
1152 m_vkOffset3D.y = y;
1153 m_vkOffset3D.z = z;
1154 }
1155
~VulkanOffset3D()1156 VulkanOffset3D::~VulkanOffset3D() {}
1157
getX() const1158 uint32_t VulkanOffset3D::getX() const { return m_vkOffset3D.x; }
1159
getY() const1160 uint32_t VulkanOffset3D::getY() const { return m_vkOffset3D.y; }
1161
getZ() const1162 uint32_t VulkanOffset3D::getZ() const { return m_vkOffset3D.z; }
1163
operator VkOffset3D() const1164 VulkanOffset3D::operator VkOffset3D() const { return m_vkOffset3D; }
1165
1166 ///////////////////////////////////
1167 // VulkanExtent3D implementation //
1168 ///////////////////////////////////
1169
VulkanExtent3D(const VulkanExtent3D & extent3D)1170 VulkanExtent3D::VulkanExtent3D(const VulkanExtent3D &extent3D)
1171 : m_vkExtent3D(extent3D.m_vkExtent3D)
1172 {}
1173
VulkanExtent3D(uint32_t width,uint32_t height,uint32_t depth)1174 VulkanExtent3D::VulkanExtent3D(uint32_t width, uint32_t height, uint32_t depth)
1175 {
1176 m_vkExtent3D.width = width;
1177 m_vkExtent3D.height = height;
1178 m_vkExtent3D.depth = depth;
1179 }
1180
~VulkanExtent3D()1181 VulkanExtent3D::~VulkanExtent3D() {}
1182
getWidth() const1183 uint32_t VulkanExtent3D::getWidth() const { return m_vkExtent3D.width; }
1184
getHeight() const1185 uint32_t VulkanExtent3D::getHeight() const { return m_vkExtent3D.height; }
1186
getDepth() const1187 uint32_t VulkanExtent3D::getDepth() const { return m_vkExtent3D.depth; }
1188
operator VkExtent3D() const1189 VulkanExtent3D::operator VkExtent3D() const { return m_vkExtent3D; }
1190
1191 //////////////////////////////////////
1192 // VulkanCommandPool implementation //
1193 //////////////////////////////////////
1194
VulkanCommandPool(const VulkanCommandPool & commandPool)1195 VulkanCommandPool::VulkanCommandPool(const VulkanCommandPool &commandPool)
1196 : m_device(commandPool.m_device),
1197 m_vkCommandPool(commandPool.m_vkCommandPool)
1198 {}
1199
VulkanCommandPool(const VulkanDevice & device,const VulkanQueueFamily & queueFamily)1200 VulkanCommandPool::VulkanCommandPool(const VulkanDevice &device,
1201 const VulkanQueueFamily &queueFamily)
1202 : m_device(device)
1203 {
1204 VkCommandPoolCreateInfo vkCommandPoolCreateInfo = {};
1205 vkCommandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1206 vkCommandPoolCreateInfo.pNext = NULL;
1207 vkCommandPoolCreateInfo.flags =
1208 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1209 vkCommandPoolCreateInfo.queueFamilyIndex = queueFamily;
1210
1211 vkCreateCommandPool(m_device, &vkCommandPoolCreateInfo, NULL,
1212 &m_vkCommandPool);
1213 }
1214
~VulkanCommandPool()1215 VulkanCommandPool::~VulkanCommandPool()
1216 {
1217 vkDestroyCommandPool(m_device, m_vkCommandPool, NULL);
1218 }
1219
operator VkCommandPool() const1220 VulkanCommandPool::operator VkCommandPool() const { return m_vkCommandPool; }
1221
1222 ////////////////////////////////////////
1223 // VulkanCommandBuffer implementation //
1224 ////////////////////////////////////////
1225
VulkanCommandBuffer(const VulkanCommandBuffer & commandBuffer)1226 VulkanCommandBuffer::VulkanCommandBuffer(
1227 const VulkanCommandBuffer &commandBuffer)
1228 : m_device(commandBuffer.m_device),
1229 m_commandPool(commandBuffer.m_commandPool),
1230 m_vkCommandBuffer(commandBuffer.m_vkCommandBuffer)
1231 {}
1232
VulkanCommandBuffer(const VulkanDevice & device,const VulkanCommandPool & commandPool)1233 VulkanCommandBuffer::VulkanCommandBuffer(const VulkanDevice &device,
1234 const VulkanCommandPool &commandPool)
1235 : m_device(device), m_commandPool(commandPool)
1236 {
1237 VkCommandBufferAllocateInfo vkCommandBufferAllocateInfo = {};
1238 vkCommandBufferAllocateInfo.sType =
1239 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1240 vkCommandBufferAllocateInfo.pNext = NULL;
1241 vkCommandBufferAllocateInfo.commandPool = commandPool;
1242 vkCommandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1243 vkCommandBufferAllocateInfo.commandBufferCount = 1;
1244
1245 vkAllocateCommandBuffers(m_device, &vkCommandBufferAllocateInfo,
1246 &m_vkCommandBuffer);
1247 }
1248
~VulkanCommandBuffer()1249 VulkanCommandBuffer::~VulkanCommandBuffer()
1250 {
1251 vkFreeCommandBuffers(m_device, m_commandPool, 1, &m_vkCommandBuffer);
1252 }
1253
begin()1254 void VulkanCommandBuffer::begin()
1255 {
1256 VkCommandBufferBeginInfo vkCommandBufferBeginInfo = {};
1257 vkCommandBufferBeginInfo.sType =
1258 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1259 vkCommandBufferBeginInfo.pNext = NULL;
1260 vkCommandBufferBeginInfo.flags =
1261 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
1262 vkCommandBufferBeginInfo.pInheritanceInfo = NULL;
1263
1264 vkBeginCommandBuffer(m_vkCommandBuffer, &vkCommandBufferBeginInfo);
1265 }
1266
bindPipeline(const VulkanPipeline & pipeline)1267 void VulkanCommandBuffer::bindPipeline(const VulkanPipeline &pipeline)
1268 {
1269 VkPipelineBindPoint vkPipelineBindPoint =
1270 (VkPipelineBindPoint)pipeline.getPipelineBindPoint();
1271
1272 vkCmdBindPipeline(m_vkCommandBuffer, vkPipelineBindPoint, pipeline);
1273 }
1274
bindDescriptorSets(const VulkanPipeline & pipeline,const VulkanPipelineLayout & pipelineLayout,const VulkanDescriptorSet & descriptorSet)1275 void VulkanCommandBuffer::bindDescriptorSets(
1276 const VulkanPipeline &pipeline, const VulkanPipelineLayout &pipelineLayout,
1277 const VulkanDescriptorSet &descriptorSet)
1278 {
1279 VkPipelineBindPoint vkPipelineBindPoint =
1280 (VkPipelineBindPoint)pipeline.getPipelineBindPoint();
1281 VkDescriptorSet vkDescriptorSet = descriptorSet;
1282
1283 vkCmdBindDescriptorSets(m_vkCommandBuffer, vkPipelineBindPoint,
1284 pipelineLayout, 0, 1, &vkDescriptorSet, 0, NULL);
1285 }
1286
pipelineBarrier(const VulkanImage2DList & image2DList,VulkanImageLayout oldImageLayout,VulkanImageLayout newImageLayout)1287 void VulkanCommandBuffer::pipelineBarrier(const VulkanImage2DList &image2DList,
1288 VulkanImageLayout oldImageLayout,
1289 VulkanImageLayout newImageLayout)
1290 {
1291 std::vector<VkImageMemoryBarrier> vkImageMemoryBarrierList;
1292 for (size_t i2DIdx = 0; i2DIdx < image2DList.size(); i2DIdx++)
1293 {
1294 VkImageSubresourceRange vkImageSubresourceRange = {};
1295 vkImageSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1296 vkImageSubresourceRange.baseMipLevel = 0;
1297 vkImageSubresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
1298 vkImageSubresourceRange.baseArrayLayer = 0;
1299 vkImageSubresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
1300
1301 VkImageMemoryBarrier vkImageMemoryBarrier = {};
1302 vkImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1303 vkImageMemoryBarrier.pNext = NULL;
1304 vkImageMemoryBarrier.srcAccessMask = 0;
1305 vkImageMemoryBarrier.dstAccessMask = 0;
1306 vkImageMemoryBarrier.oldLayout = (VkImageLayout)oldImageLayout;
1307 vkImageMemoryBarrier.newLayout = (VkImageLayout)newImageLayout;
1308 vkImageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1309 vkImageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1310 vkImageMemoryBarrier.image = image2DList[i2DIdx];
1311 vkImageMemoryBarrier.subresourceRange = vkImageSubresourceRange;
1312
1313 vkImageMemoryBarrierList.push_back(vkImageMemoryBarrier);
1314 }
1315
1316 vkCmdPipelineBarrier(m_vkCommandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
1317 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL, 0,
1318 NULL, (uint32_t)vkImageMemoryBarrierList.size(),
1319 vkImageMemoryBarrierList.data());
1320 }
1321
dispatch(uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)1322 void VulkanCommandBuffer::dispatch(uint32_t groupCountX, uint32_t groupCountY,
1323 uint32_t groupCountZ)
1324 {
1325 vkCmdDispatch(m_vkCommandBuffer, groupCountX, groupCountY, groupCountZ);
1326 }
1327
fillBuffer(const VulkanBuffer & buffer,uint32_t data,uint64_t offset,uint64_t size)1328 void VulkanCommandBuffer::fillBuffer(const VulkanBuffer &buffer, uint32_t data,
1329 uint64_t offset, uint64_t size)
1330 {
1331 vkCmdFillBuffer(m_vkCommandBuffer, buffer, offset, size, data);
1332 }
1333
updateBuffer(const VulkanBuffer & buffer,void * pdata,uint64_t offset,uint64_t size)1334 void VulkanCommandBuffer::updateBuffer(const VulkanBuffer &buffer, void *pdata,
1335 uint64_t offset, uint64_t size)
1336 {
1337 vkCmdUpdateBuffer(m_vkCommandBuffer, buffer, offset, size, pdata);
1338 }
1339
copyBufferToImage(const VulkanBuffer & buffer,const VulkanImage & image,VulkanImageLayout imageLayout)1340 void VulkanCommandBuffer::copyBufferToImage(const VulkanBuffer &buffer,
1341 const VulkanImage &image,
1342 VulkanImageLayout imageLayout)
1343 {
1344 VkDeviceSize bufferOffset = 0;
1345
1346 std::vector<VkBufferImageCopy> vkBufferImageCopyList;
1347 for (uint32_t mipLevel = 0; mipLevel < image.getNumMipLevels(); mipLevel++)
1348 {
1349 VulkanExtent3D extent3D = image.getExtent3D(mipLevel);
1350 size_t elementSize = getVulkanFormatElementSize(image.getFormat());
1351
1352 VkImageSubresourceLayers vkImageSubresourceLayers = {};
1353 vkImageSubresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1354 vkImageSubresourceLayers.mipLevel = mipLevel;
1355 vkImageSubresourceLayers.baseArrayLayer = 0;
1356 vkImageSubresourceLayers.layerCount = image.getNumLayers();
1357
1358 VkBufferImageCopy vkBufferImageCopy = {};
1359 vkBufferImageCopy.bufferOffset = bufferOffset;
1360 vkBufferImageCopy.bufferRowLength = 0;
1361 vkBufferImageCopy.bufferImageHeight = 0;
1362 vkBufferImageCopy.imageSubresource = vkImageSubresourceLayers;
1363 vkBufferImageCopy.imageOffset = VulkanOffset3D(0, 0, 0);
1364 vkBufferImageCopy.imageExtent = extent3D;
1365
1366 vkBufferImageCopyList.push_back(vkBufferImageCopy);
1367
1368 bufferOffset += extent3D.getWidth() * extent3D.getHeight()
1369 * extent3D.getDepth() * elementSize;
1370 bufferOffset =
1371 ROUND_UP(bufferOffset,
1372 std::max(elementSize,
1373 (size_t)VULKAN_MIN_BUFFER_OFFSET_COPY_ALIGNMENT));
1374 }
1375
1376 vkCmdCopyBufferToImage(
1377 m_vkCommandBuffer, buffer, image, (VkImageLayout)imageLayout,
1378 (uint32_t)vkBufferImageCopyList.size(), vkBufferImageCopyList.data());
1379 }
1380
copyBufferToImage(const VulkanBuffer & buffer,const VulkanImage & image,uint64_t bufferOffset,uint32_t mipLevel,uint32_t baseArrayLayer,uint32_t layerCount,VulkanOffset3D offset3D,VulkanExtent3D extent3D)1381 void VulkanCommandBuffer::copyBufferToImage(
1382 const VulkanBuffer &buffer, const VulkanImage &image, uint64_t bufferOffset,
1383 uint32_t mipLevel, uint32_t baseArrayLayer, uint32_t layerCount,
1384 VulkanOffset3D offset3D, VulkanExtent3D extent3D)
1385 {
1386 VkImageSubresourceLayers vkImageSubresourceLayers = {};
1387 vkImageSubresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1388 vkImageSubresourceLayers.mipLevel = mipLevel;
1389 vkImageSubresourceLayers.baseArrayLayer = baseArrayLayer;
1390 vkImageSubresourceLayers.layerCount = layerCount;
1391
1392 VkExtent3D vkExtent3D = extent3D;
1393 if ((extent3D.getWidth() == 0) && (extent3D.getHeight() == 0)
1394 && (extent3D.getDepth() == 0))
1395 {
1396 vkExtent3D = image.getExtent3D(mipLevel);
1397 }
1398
1399 VkBufferImageCopy vkBufferImageCopy = {};
1400 vkBufferImageCopy.bufferOffset = bufferOffset;
1401 vkBufferImageCopy.bufferRowLength = 0;
1402 vkBufferImageCopy.bufferImageHeight = 0;
1403 vkBufferImageCopy.imageSubresource = vkImageSubresourceLayers;
1404 vkBufferImageCopy.imageOffset = offset3D;
1405 vkBufferImageCopy.imageExtent = vkExtent3D;
1406
1407 vkCmdCopyBufferToImage(m_vkCommandBuffer, buffer, image,
1408 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
1409 &vkBufferImageCopy);
1410 }
1411
copyImageToBuffer(const VulkanImage & image,const VulkanBuffer & buffer,uint64_t bufferOffset,uint32_t mipLevel,uint32_t baseArrayLayer,uint32_t layerCount,VulkanOffset3D offset3D,VulkanExtent3D extent3D)1412 void VulkanCommandBuffer::copyImageToBuffer(
1413 const VulkanImage &image, const VulkanBuffer &buffer, uint64_t bufferOffset,
1414 uint32_t mipLevel, uint32_t baseArrayLayer, uint32_t layerCount,
1415 VulkanOffset3D offset3D, VulkanExtent3D extent3D)
1416 {
1417 VkImageSubresourceLayers vkImageSubresourceLayers = {};
1418 vkImageSubresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1419 vkImageSubresourceLayers.mipLevel = mipLevel;
1420 vkImageSubresourceLayers.baseArrayLayer = baseArrayLayer;
1421 vkImageSubresourceLayers.layerCount = layerCount;
1422
1423 VkExtent3D vkExtent3D = extent3D;
1424 if ((extent3D.getWidth() == 0) && (extent3D.getHeight() == 0)
1425 && (extent3D.getDepth() == 0))
1426 {
1427 vkExtent3D = image.getExtent3D(mipLevel);
1428 }
1429
1430 VkBufferImageCopy vkBufferImageCopy = {};
1431 vkBufferImageCopy.bufferOffset = bufferOffset;
1432 vkBufferImageCopy.bufferRowLength = 0;
1433 vkBufferImageCopy.bufferImageHeight = 0;
1434 vkBufferImageCopy.imageSubresource = vkImageSubresourceLayers;
1435 vkBufferImageCopy.imageOffset = offset3D;
1436 vkBufferImageCopy.imageExtent = vkExtent3D;
1437
1438 vkCmdCopyImageToBuffer(m_vkCommandBuffer, image, VK_IMAGE_LAYOUT_GENERAL,
1439 buffer, 1, &vkBufferImageCopy);
1440 }
1441
end()1442 void VulkanCommandBuffer::end() { vkEndCommandBuffer(m_vkCommandBuffer); }
1443
operator VkCommandBuffer() const1444 VulkanCommandBuffer::operator VkCommandBuffer() const
1445 {
1446 return m_vkCommandBuffer;
1447 }
1448
1449 /////////////////////////////////
1450 // VulkanBuffer implementation //
1451 /////////////////////////////////
1452
VulkanBuffer(const VulkanBuffer & buffer)1453 VulkanBuffer::VulkanBuffer(const VulkanBuffer &buffer)
1454 : m_device(buffer.m_device), m_vkBuffer(buffer.m_vkBuffer),
1455 m_size(buffer.m_size), m_alignment(buffer.m_alignment),
1456 m_memoryTypeList(buffer.m_memoryTypeList)
1457 {}
1458
VulkanBuffer(const VulkanDevice & device,uint64_t size,VulkanExternalMemoryHandleType externalMemoryHandleType,VulkanBufferUsage bufferUsage,VulkanSharingMode sharingMode,const VulkanQueueFamilyList & queueFamilyList)1459 VulkanBuffer::VulkanBuffer(
1460 const VulkanDevice &device, uint64_t size,
1461 VulkanExternalMemoryHandleType externalMemoryHandleType,
1462 VulkanBufferUsage bufferUsage, VulkanSharingMode sharingMode,
1463 const VulkanQueueFamilyList &queueFamilyList)
1464 : m_device(device), m_vkBuffer(VK_NULL_HANDLE)
1465 {
1466 std::vector<uint32_t> queueFamilyIndexList;
1467 if (queueFamilyList.size() == 0)
1468 {
1469 for (size_t qfIdx = 0;
1470 qfIdx < device.getPhysicalDevice().getQueueFamilyList().size();
1471 qfIdx++)
1472 {
1473 queueFamilyIndexList.push_back(
1474 device.getPhysicalDevice().getQueueFamilyList()[qfIdx]);
1475 }
1476 }
1477 else
1478 {
1479 for (size_t qfIdx = 0; qfIdx < queueFamilyList.size(); qfIdx++)
1480 {
1481 queueFamilyIndexList.push_back(queueFamilyList[qfIdx]);
1482 }
1483 }
1484
1485 VkBufferCreateInfo vkBufferCreateInfo = {};
1486 vkBufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1487 vkBufferCreateInfo.pNext = NULL;
1488 vkBufferCreateInfo.flags = 0;
1489 vkBufferCreateInfo.size = (VkDeviceSize)size;
1490 vkBufferCreateInfo.usage = (VkBufferUsageFlags)bufferUsage;
1491 vkBufferCreateInfo.sharingMode = (VkSharingMode)sharingMode;
1492 vkBufferCreateInfo.queueFamilyIndexCount =
1493 (uint32_t)queueFamilyIndexList.size();
1494 vkBufferCreateInfo.pQueueFamilyIndices = queueFamilyIndexList.data();
1495
1496 VkExternalMemoryBufferCreateInfo vkExternalMemoryBufferCreateInfo = {};
1497 if (externalMemoryHandleType != VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE)
1498 {
1499 vkExternalMemoryBufferCreateInfo.sType =
1500 VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR;
1501 vkExternalMemoryBufferCreateInfo.pNext = NULL;
1502 vkExternalMemoryBufferCreateInfo.handleTypes =
1503 (VkExternalMemoryHandleTypeFlags)externalMemoryHandleType;
1504
1505 vkBufferCreateInfo.pNext = &vkExternalMemoryBufferCreateInfo;
1506 }
1507
1508 vkCreateBuffer(m_device, &vkBufferCreateInfo, NULL, &m_vkBuffer);
1509
1510 VkMemoryRequirements vkMemoryRequirements = {};
1511 vkGetBufferMemoryRequirements(m_device, m_vkBuffer, &vkMemoryRequirements);
1512 m_size = vkMemoryRequirements.size;
1513 m_alignment = vkMemoryRequirements.alignment;
1514 const VulkanMemoryTypeList &memoryTypeList =
1515 m_device.getPhysicalDevice().getMemoryTypeList();
1516 for (size_t mtIdx = 0; mtIdx < memoryTypeList.size(); mtIdx++)
1517 {
1518 uint32_t memoryTypeIndex = memoryTypeList[mtIdx];
1519 if ((1 << memoryTypeIndex) & vkMemoryRequirements.memoryTypeBits)
1520 {
1521 m_memoryTypeList.add(memoryTypeList[mtIdx]);
1522 }
1523 }
1524 }
1525
~VulkanBuffer()1526 VulkanBuffer::~VulkanBuffer() { vkDestroyBuffer(m_device, m_vkBuffer, NULL); }
1527
getSize() const1528 uint64_t VulkanBuffer::getSize() const { return m_size; }
1529
getAlignment() const1530 uint64_t VulkanBuffer::getAlignment() const { return m_alignment; }
1531
getMemoryTypeList() const1532 const VulkanMemoryTypeList &VulkanBuffer::getMemoryTypeList() const
1533 {
1534 return m_memoryTypeList;
1535 }
1536
operator VkBuffer() const1537 VulkanBuffer::operator VkBuffer() const { return m_vkBuffer; }
1538
1539 ////////////////////////////////
1540 // VulkanImage implementation //
1541 ////////////////////////////////
1542
VulkanImage(const VulkanImage & image)1543 VulkanImage::VulkanImage(const VulkanImage &image)
1544 : m_device(image.m_device), m_imageType(image.m_imageType),
1545 m_extent3D(image.m_extent3D), m_format(image.m_format),
1546 m_numMipLevels(image.m_numMipLevels), m_numLayers(image.m_numLayers),
1547 m_vkImage(image.m_vkImage), m_size(image.m_size),
1548 m_alignment(image.m_alignment), m_memoryTypeList(image.m_memoryTypeList)
1549 {}
1550
VulkanImage(const VulkanDevice & device,VulkanImageType imageType,VulkanFormat format,const VulkanExtent3D & extent3D,uint32_t numMipLevels,uint32_t arrayLayers,VulkanExternalMemoryHandleType externalMemoryHandleType,VulkanImageCreateFlag imageCreateFlag,VulkanImageTiling imageTiling,VulkanImageUsage imageUsage,VulkanSharingMode sharingMode)1551 VulkanImage::VulkanImage(
1552 const VulkanDevice &device, VulkanImageType imageType, VulkanFormat format,
1553 const VulkanExtent3D &extent3D, uint32_t numMipLevels, uint32_t arrayLayers,
1554 VulkanExternalMemoryHandleType externalMemoryHandleType,
1555 VulkanImageCreateFlag imageCreateFlag, VulkanImageTiling imageTiling,
1556 VulkanImageUsage imageUsage, VulkanSharingMode sharingMode)
1557 : m_device(device), m_imageType(imageType), m_extent3D(extent3D),
1558 m_format(format), m_numMipLevels(numMipLevels), m_numLayers(arrayLayers),
1559 m_vkImage(VK_NULL_HANDLE)
1560 {
1561 VkImageCreateInfo vkImageCreateInfo = {};
1562 vkImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1563 vkImageCreateInfo.pNext = NULL;
1564 vkImageCreateInfo.flags = (VkImageCreateFlags)imageCreateFlag;
1565 vkImageCreateInfo.imageType = (VkImageType)imageType;
1566 vkImageCreateInfo.format = (VkFormat)format;
1567 vkImageCreateInfo.extent = extent3D;
1568 vkImageCreateInfo.mipLevels = numMipLevels;
1569 vkImageCreateInfo.arrayLayers = arrayLayers;
1570 vkImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1571 vkImageCreateInfo.tiling = (VkImageTiling)imageTiling;
1572 vkImageCreateInfo.usage = (VkImageUsageFlags)imageUsage;
1573 vkImageCreateInfo.sharingMode = (VkSharingMode)sharingMode;
1574 vkImageCreateInfo.queueFamilyIndexCount =
1575 (uint32_t)m_device.getPhysicalDevice().getQueueFamilyList().size();
1576 vkImageCreateInfo.pQueueFamilyIndices =
1577 m_device.getPhysicalDevice().getQueueFamilyList()();
1578 vkImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1579
1580 VkExternalMemoryImageCreateInfo vkExternalMemoryImageCreateInfo = {};
1581 if (externalMemoryHandleType != VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE)
1582 {
1583 vkExternalMemoryImageCreateInfo.sType =
1584 VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
1585 vkExternalMemoryImageCreateInfo.pNext = NULL;
1586 vkExternalMemoryImageCreateInfo.handleTypes =
1587 (VkExternalMemoryHandleTypeFlags)externalMemoryHandleType;
1588
1589 vkImageCreateInfo.pNext = &vkExternalMemoryImageCreateInfo;
1590 }
1591
1592 vkCreateImage(m_device, &vkImageCreateInfo, NULL, &m_vkImage);
1593 VulkanImageCreateInfo = vkImageCreateInfo;
1594 VkMemoryRequirements vkMemoryRequirements = {};
1595 vkGetImageMemoryRequirements(m_device, m_vkImage, &vkMemoryRequirements);
1596 m_size = vkMemoryRequirements.size;
1597 m_alignment = vkMemoryRequirements.alignment;
1598 const VulkanMemoryTypeList &memoryTypeList =
1599 m_device.getPhysicalDevice().getMemoryTypeList();
1600 for (size_t mtIdx = 0; mtIdx < memoryTypeList.size(); mtIdx++)
1601 {
1602 uint32_t memoryTypeIndex = memoryTypeList[mtIdx];
1603 if ((1 << memoryTypeIndex) & vkMemoryRequirements.memoryTypeBits)
1604 {
1605 m_memoryTypeList.add(memoryTypeList[mtIdx]);
1606 }
1607 }
1608 }
1609
~VulkanImage()1610 VulkanImage::~VulkanImage() { vkDestroyImage(m_device, m_vkImage, NULL); }
1611
getExtent3D(uint32_t mipLevel) const1612 VulkanExtent3D VulkanImage::getExtent3D(uint32_t mipLevel) const
1613 {
1614 return VulkanExtent3D(0, 0, 0);
1615 }
1616
getFormat() const1617 VulkanFormat VulkanImage::getFormat() const { return m_format; }
1618
getVkImageCreateInfo() const1619 VkImageCreateInfo VulkanImage::getVkImageCreateInfo() const
1620 {
1621 return VulkanImageCreateInfo;
1622 }
1623
getNumMipLevels() const1624 uint32_t VulkanImage::getNumMipLevels() const { return m_numMipLevels; }
1625
getNumLayers() const1626 uint32_t VulkanImage::getNumLayers() const { return m_numLayers; }
1627
getSize() const1628 uint64_t VulkanImage::getSize() const { return m_size; }
1629
getAlignment() const1630 uint64_t VulkanImage::getAlignment() const { return m_alignment; }
1631
getMemoryTypeList() const1632 const VulkanMemoryTypeList &VulkanImage::getMemoryTypeList() const
1633 {
1634 return m_memoryTypeList;
1635 }
1636
operator VkImage() const1637 VulkanImage::operator VkImage() const { return m_vkImage; }
1638
1639 //////////////////////////////////
1640 // VulkanImage2D implementation //
1641 //////////////////////////////////
1642
VulkanImage2D(const VulkanImage2D & image2D)1643 VulkanImage2D::VulkanImage2D(const VulkanImage2D &image2D): VulkanImage(image2D)
1644 {}
1645
VulkanImage2D(const VulkanDevice & device,VulkanFormat format,uint32_t width,uint32_t height,uint32_t numMipLevels,VulkanExternalMemoryHandleType externalMemoryHandleType,VulkanImageCreateFlag imageCreateFlag,VulkanImageUsage imageUsage,VulkanSharingMode sharingMode)1646 VulkanImage2D::VulkanImage2D(
1647 const VulkanDevice &device, VulkanFormat format, uint32_t width,
1648 uint32_t height, uint32_t numMipLevels,
1649 VulkanExternalMemoryHandleType externalMemoryHandleType,
1650 VulkanImageCreateFlag imageCreateFlag, VulkanImageUsage imageUsage,
1651 VulkanSharingMode sharingMode)
1652 : VulkanImage(device, VULKAN_IMAGE_TYPE_2D, format,
1653 VulkanExtent3D(width, height, 1), numMipLevels, 1,
1654 externalMemoryHandleType, imageCreateFlag,
1655 VULKAN_IMAGE_TILING_OPTIMAL, imageUsage, sharingMode)
1656 {}
1657
~VulkanImage2D()1658 VulkanImage2D::~VulkanImage2D() {}
1659
getExtent3D(uint32_t mipLevel) const1660 VulkanExtent3D VulkanImage2D::getExtent3D(uint32_t mipLevel) const
1661 {
1662 uint32_t width = std::max(m_extent3D.getWidth() >> mipLevel, uint32_t(1));
1663 uint32_t height = std::max(m_extent3D.getHeight() >> mipLevel, uint32_t(1));
1664 uint32_t depth = 1;
1665
1666 return VulkanExtent3D(width, height, depth);
1667 }
1668
1669 ////////////////////////////////////
1670 // VulkanImageView implementation //
1671 ////////////////////////////////////
1672
VulkanImageView(const VulkanImageView & imageView)1673 VulkanImageView::VulkanImageView(const VulkanImageView &imageView)
1674 : m_device(imageView.m_device), m_vkImageView(imageView.m_vkImageView)
1675 {}
1676
VulkanImageView(const VulkanDevice & device,const VulkanImage & image,VulkanImageViewType imageViewType,uint32_t baseMipLevel,uint32_t levelCount,uint32_t baseArrayLayer,uint32_t layerCount)1677 VulkanImageView::VulkanImageView(const VulkanDevice &device,
1678 const VulkanImage &image,
1679 VulkanImageViewType imageViewType,
1680 uint32_t baseMipLevel, uint32_t levelCount,
1681 uint32_t baseArrayLayer, uint32_t layerCount)
1682 : m_device(device), m_vkImageView(VK_NULL_HANDLE)
1683 {
1684 VkComponentMapping vkComponentMapping = {};
1685 vkComponentMapping.r = VK_COMPONENT_SWIZZLE_IDENTITY;
1686 vkComponentMapping.g = VK_COMPONENT_SWIZZLE_IDENTITY;
1687 vkComponentMapping.b = VK_COMPONENT_SWIZZLE_IDENTITY;
1688 vkComponentMapping.a = VK_COMPONENT_SWIZZLE_IDENTITY;
1689
1690 VkImageSubresourceRange vkImageSubresourceRange = {};
1691 vkImageSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1692 vkImageSubresourceRange.baseMipLevel = baseMipLevel;
1693 vkImageSubresourceRange.levelCount = levelCount;
1694 vkImageSubresourceRange.baseArrayLayer = baseArrayLayer;
1695 vkImageSubresourceRange.layerCount = layerCount;
1696
1697 VkImageViewCreateInfo vkImageViewCreateInfo = {};
1698 vkImageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1699 vkImageViewCreateInfo.pNext = NULL;
1700 vkImageViewCreateInfo.flags = 0;
1701 vkImageViewCreateInfo.image = image;
1702 vkImageViewCreateInfo.viewType = (VkImageViewType)imageViewType;
1703 vkImageViewCreateInfo.format = (VkFormat)image.getFormat();
1704 vkImageViewCreateInfo.components = vkComponentMapping;
1705 vkImageViewCreateInfo.subresourceRange = vkImageSubresourceRange;
1706
1707 vkCreateImageView(m_device, &vkImageViewCreateInfo, NULL, &m_vkImageView);
1708 }
1709
~VulkanImageView()1710 VulkanImageView::~VulkanImageView()
1711 {
1712 vkDestroyImageView(m_device, m_vkImageView, NULL);
1713 }
1714
operator VkImageView() const1715 VulkanImageView::operator VkImageView() const { return m_vkImageView; }
1716
1717 ///////////////////////////////////////
1718 // VulkanDeviceMemory implementation //
1719 ///////////////////////////////////////
1720
1721 #if defined(_WIN32) || defined(_WIN64)
1722
1723 class WindowsSecurityAttributes {
1724 protected:
1725 SECURITY_ATTRIBUTES m_winSecurityAttributes;
1726 PSECURITY_DESCRIPTOR m_winPSecurityDescriptor;
1727
1728 public:
1729 WindowsSecurityAttributes();
1730 SECURITY_ATTRIBUTES *operator&();
1731 ~WindowsSecurityAttributes();
1732 };
1733
1734
WindowsSecurityAttributes()1735 WindowsSecurityAttributes::WindowsSecurityAttributes()
1736 {
1737 m_winPSecurityDescriptor = (PSECURITY_DESCRIPTOR)calloc(
1738 1, SECURITY_DESCRIPTOR_MIN_LENGTH + 2 * sizeof(void **));
1739 // CHECK_NEQ(m_winPSecurityDescriptor, (PSECURITY_DESCRIPTOR)NULL);
1740 PSID *ppSID = (PSID *)((PBYTE)m_winPSecurityDescriptor
1741 + SECURITY_DESCRIPTOR_MIN_LENGTH);
1742 PACL *ppACL = (PACL *)((PBYTE)ppSID + sizeof(PSID *));
1743 InitializeSecurityDescriptor(m_winPSecurityDescriptor,
1744 SECURITY_DESCRIPTOR_REVISION);
1745 SID_IDENTIFIER_AUTHORITY sidIdentifierAuthority =
1746 SECURITY_WORLD_SID_AUTHORITY;
1747 AllocateAndInitializeSid(&sidIdentifierAuthority, 1, SECURITY_WORLD_RID, 0,
1748 0, 0, 0, 0, 0, 0, ppSID);
1749 EXPLICIT_ACCESS explicitAccess;
1750 ZeroMemory(&explicitAccess, sizeof(EXPLICIT_ACCESS));
1751 explicitAccess.grfAccessPermissions =
1752 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1753 explicitAccess.grfAccessMode = SET_ACCESS;
1754 explicitAccess.grfInheritance = INHERIT_ONLY;
1755 explicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
1756 explicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
1757 explicitAccess.Trustee.ptstrName = (LPTSTR)*ppSID;
1758 SetEntriesInAcl(1, &explicitAccess, NULL, ppACL);
1759 SetSecurityDescriptorDacl(m_winPSecurityDescriptor, TRUE, *ppACL, FALSE);
1760 m_winSecurityAttributes.nLength = sizeof(m_winSecurityAttributes);
1761 m_winSecurityAttributes.lpSecurityDescriptor = m_winPSecurityDescriptor;
1762 m_winSecurityAttributes.bInheritHandle = TRUE;
1763 }
1764
operator &()1765 SECURITY_ATTRIBUTES *WindowsSecurityAttributes::operator&()
1766 {
1767 return &m_winSecurityAttributes;
1768 }
1769
~WindowsSecurityAttributes()1770 WindowsSecurityAttributes::~WindowsSecurityAttributes()
1771 {
1772 PSID *ppSID = (PSID *)((PBYTE)m_winPSecurityDescriptor
1773 + SECURITY_DESCRIPTOR_MIN_LENGTH);
1774 PACL *ppACL = (PACL *)((PBYTE)ppSID + sizeof(PSID *));
1775 if (*ppSID)
1776 {
1777 FreeSid(*ppSID);
1778 }
1779 if (*ppACL)
1780 {
1781 LocalFree(*ppACL);
1782 }
1783 free(m_winPSecurityDescriptor);
1784 }
1785
1786 #endif
1787
VulkanDeviceMemory(const VulkanDeviceMemory & deviceMemory)1788 VulkanDeviceMemory::VulkanDeviceMemory(const VulkanDeviceMemory &deviceMemory)
1789 : m_device(deviceMemory.m_device),
1790 m_vkDeviceMemory(deviceMemory.m_vkDeviceMemory),
1791 m_size(deviceMemory.m_size), m_isDedicated(deviceMemory.m_isDedicated)
1792 {}
1793
VulkanDeviceMemory(const VulkanDevice & device,uint64_t size,const VulkanMemoryType & memoryType,VulkanExternalMemoryHandleType externalMemoryHandleType,const void * name)1794 VulkanDeviceMemory::VulkanDeviceMemory(
1795 const VulkanDevice &device, uint64_t size,
1796 const VulkanMemoryType &memoryType,
1797 VulkanExternalMemoryHandleType externalMemoryHandleType, const void *name)
1798 : m_device(device), m_size(size), m_isDedicated(false)
1799 {
1800 #if defined(_WIN32) || defined(_WIN64)
1801 WindowsSecurityAttributes winSecurityAttributes;
1802
1803 VkExportMemoryWin32HandleInfoKHR vkExportMemoryWin32HandleInfoKHR = {};
1804 vkExportMemoryWin32HandleInfoKHR.sType =
1805 VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
1806 vkExportMemoryWin32HandleInfoKHR.pNext = NULL;
1807 vkExportMemoryWin32HandleInfoKHR.pAttributes = &winSecurityAttributes;
1808 vkExportMemoryWin32HandleInfoKHR.dwAccess =
1809 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE;
1810 vkExportMemoryWin32HandleInfoKHR.name = (LPCWSTR)name;
1811
1812 #endif
1813
1814 VkExportMemoryAllocateInfoKHR vkExportMemoryAllocateInfoKHR = {};
1815 vkExportMemoryAllocateInfoKHR.sType =
1816 VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;
1817 #if defined(_WIN32) || defined(_WIN64)
1818 vkExportMemoryAllocateInfoKHR.pNext = externalMemoryHandleType
1819 & VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT
1820 ? &vkExportMemoryWin32HandleInfoKHR
1821 : NULL;
1822 #else
1823 vkExportMemoryAllocateInfoKHR.pNext = NULL;
1824 #endif
1825 vkExportMemoryAllocateInfoKHR.handleTypes =
1826 (VkExternalMemoryHandleTypeFlagsKHR)externalMemoryHandleType;
1827
1828 VkMemoryAllocateInfo vkMemoryAllocateInfo = {};
1829 vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1830 vkMemoryAllocateInfo.pNext =
1831 externalMemoryHandleType ? &vkExportMemoryAllocateInfoKHR : NULL;
1832 vkMemoryAllocateInfo.allocationSize = m_size;
1833 vkMemoryAllocateInfo.memoryTypeIndex = (uint32_t)memoryType;
1834
1835 vkAllocateMemory(m_device, &vkMemoryAllocateInfo, NULL, &m_vkDeviceMemory);
1836 }
1837
VulkanDeviceMemory(const VulkanDevice & device,const VulkanImage & image,const VulkanMemoryType & memoryType,VulkanExternalMemoryHandleType externalMemoryHandleType,const void * name)1838 VulkanDeviceMemory::VulkanDeviceMemory(
1839 const VulkanDevice &device, const VulkanImage &image,
1840 const VulkanMemoryType &memoryType,
1841 VulkanExternalMemoryHandleType externalMemoryHandleType, const void *name)
1842 : m_device(device), m_size(image.getSize()), m_isDedicated(true)
1843 {
1844 #if defined(_WIN32) || defined(_WIN64)
1845 WindowsSecurityAttributes winSecurityAttributes;
1846
1847 VkExportMemoryWin32HandleInfoKHR vkExportMemoryWin32HandleInfoKHR = {};
1848 vkExportMemoryWin32HandleInfoKHR.sType =
1849 VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
1850 vkExportMemoryWin32HandleInfoKHR.pNext = NULL;
1851 vkExportMemoryWin32HandleInfoKHR.pAttributes = &winSecurityAttributes;
1852 vkExportMemoryWin32HandleInfoKHR.dwAccess =
1853 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE;
1854 vkExportMemoryWin32HandleInfoKHR.name = (LPCWSTR)name;
1855
1856 #endif
1857
1858 VkExportMemoryAllocateInfoKHR vkExportMemoryAllocateInfoKHR = {};
1859 vkExportMemoryAllocateInfoKHR.sType =
1860 VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;
1861 #if defined(_WIN32) || defined(_WIN64)
1862 vkExportMemoryAllocateInfoKHR.pNext = externalMemoryHandleType
1863 & VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT
1864 ? &vkExportMemoryWin32HandleInfoKHR
1865 : NULL;
1866 #else
1867 vkExportMemoryAllocateInfoKHR.pNext = NULL;
1868 #endif
1869 vkExportMemoryAllocateInfoKHR.handleTypes =
1870 (VkExternalMemoryHandleTypeFlagsKHR)externalMemoryHandleType;
1871
1872 VkMemoryDedicatedAllocateInfo vkMemoryDedicatedAllocateInfo = {};
1873 vkMemoryDedicatedAllocateInfo.sType =
1874 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
1875 vkMemoryDedicatedAllocateInfo.pNext =
1876 externalMemoryHandleType ? &vkExportMemoryAllocateInfoKHR : NULL;
1877 vkMemoryDedicatedAllocateInfo.image = image;
1878 vkMemoryDedicatedAllocateInfo.buffer = VK_NULL_HANDLE;
1879
1880 VkMemoryAllocateInfo vkMemoryAllocateInfo = {};
1881 vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1882 vkMemoryAllocateInfo.pNext = &vkMemoryDedicatedAllocateInfo;
1883 vkMemoryAllocateInfo.allocationSize = m_size;
1884 vkMemoryAllocateInfo.memoryTypeIndex = (uint32_t)memoryType;
1885
1886 vkAllocateMemory(m_device, &vkMemoryAllocateInfo, NULL, &m_vkDeviceMemory);
1887 }
1888
~VulkanDeviceMemory()1889 VulkanDeviceMemory::~VulkanDeviceMemory()
1890 {
1891 vkFreeMemory(m_device, m_vkDeviceMemory, NULL);
1892 }
1893
getSize() const1894 uint64_t VulkanDeviceMemory::getSize() const { return m_size; }
1895
1896 #ifdef _WIN32
getHandle(VulkanExternalMemoryHandleType externalMemoryHandleType) const1897 HANDLE VulkanDeviceMemory::getHandle(
1898 VulkanExternalMemoryHandleType externalMemoryHandleType) const
1899 {
1900 HANDLE handle;
1901
1902 VkMemoryGetWin32HandleInfoKHR vkMemoryGetWin32HandleInfoKHR = {};
1903 vkMemoryGetWin32HandleInfoKHR.sType =
1904 VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
1905 vkMemoryGetWin32HandleInfoKHR.pNext = NULL;
1906 vkMemoryGetWin32HandleInfoKHR.memory = m_vkDeviceMemory;
1907 vkMemoryGetWin32HandleInfoKHR.handleType =
1908 (VkExternalMemoryHandleTypeFlagBitsKHR)externalMemoryHandleType;
1909
1910 vkGetMemoryWin32HandleKHR(m_device, &vkMemoryGetWin32HandleInfoKHR,
1911 &handle);
1912
1913 return handle;
1914 }
1915 #else
getHandle(VulkanExternalMemoryHandleType externalMemoryHandleType) const1916 int VulkanDeviceMemory::getHandle(
1917 VulkanExternalMemoryHandleType externalMemoryHandleType) const
1918 {
1919 if (externalMemoryHandleType
1920 == VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD)
1921 {
1922 int fd;
1923
1924 VkMemoryGetFdInfoKHR vkMemoryGetFdInfoKHR = {};
1925 vkMemoryGetFdInfoKHR.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
1926 vkMemoryGetFdInfoKHR.pNext = NULL;
1927 vkMemoryGetFdInfoKHR.memory = m_vkDeviceMemory;
1928 vkMemoryGetFdInfoKHR.handleType =
1929 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
1930
1931 vkGetMemoryFdKHR(m_device, &vkMemoryGetFdInfoKHR, &fd);
1932
1933 return fd;
1934 }
1935 return HANDLE_ERROR;
1936 }
1937 #endif
1938
isDedicated() const1939 bool VulkanDeviceMemory::isDedicated() const { return m_isDedicated; }
1940
map(size_t offset,size_t size)1941 void *VulkanDeviceMemory::map(size_t offset, size_t size)
1942 {
1943 void *pData;
1944
1945 vkMapMemory(m_device, m_vkDeviceMemory, (VkDeviceSize)offset,
1946 (VkDeviceSize)size, 0, &pData);
1947
1948 return pData;
1949 }
1950
unmap()1951 void VulkanDeviceMemory::unmap() { vkUnmapMemory(m_device, m_vkDeviceMemory); }
1952
bindBuffer(const VulkanBuffer & buffer,uint64_t offset)1953 void VulkanDeviceMemory::bindBuffer(const VulkanBuffer &buffer, uint64_t offset)
1954 {
1955 vkBindBufferMemory(m_device, buffer, m_vkDeviceMemory, offset);
1956 }
1957
bindImage(const VulkanImage & image,uint64_t offset)1958 void VulkanDeviceMemory::bindImage(const VulkanImage &image, uint64_t offset)
1959 {
1960 vkBindImageMemory(m_device, image, m_vkDeviceMemory, offset);
1961 }
1962
operator VkDeviceMemory() const1963 VulkanDeviceMemory::operator VkDeviceMemory() const { return m_vkDeviceMemory; }
1964
1965 ////////////////////////////////////
1966 // VulkanSemaphore implementation //
1967 ////////////////////////////////////
1968
VulkanSemaphore(const VulkanSemaphore & semaphore)1969 VulkanSemaphore::VulkanSemaphore(const VulkanSemaphore &semaphore)
1970 : m_device(semaphore.m_device), m_vkSemaphore(semaphore.m_vkSemaphore)
1971 {}
1972
VulkanSemaphore(const VulkanDevice & device,VulkanExternalSemaphoreHandleType externalSemaphoreHandleType,const std::wstring name)1973 VulkanSemaphore::VulkanSemaphore(
1974 const VulkanDevice &device,
1975 VulkanExternalSemaphoreHandleType externalSemaphoreHandleType,
1976 const std::wstring name)
1977 : m_device(device), m_name(name)
1978 {
1979 #if defined(_WIN32) || defined(_WIN64)
1980 WindowsSecurityAttributes winSecurityAttributes;
1981
1982 VkExportSemaphoreWin32HandleInfoKHR
1983 vkExportSemaphoreWin32HandleInfoKHR = {};
1984 vkExportSemaphoreWin32HandleInfoKHR.sType =
1985 VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR;
1986 vkExportSemaphoreWin32HandleInfoKHR.pNext = NULL;
1987 vkExportSemaphoreWin32HandleInfoKHR.pAttributes = &winSecurityAttributes;
1988 vkExportSemaphoreWin32HandleInfoKHR.dwAccess =
1989 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE;
1990 vkExportSemaphoreWin32HandleInfoKHR.name =
1991 m_name.size() ? (LPCWSTR)m_name.c_str() : NULL;
1992 #endif
1993
1994 VkExportSemaphoreCreateInfoKHR vkExportSemaphoreCreateInfoKHR = {};
1995 vkExportSemaphoreCreateInfoKHR.sType =
1996 VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR;
1997 #if defined(_WIN32) || defined(_WIN64)
1998 vkExportSemaphoreCreateInfoKHR.pNext =
1999 (externalSemaphoreHandleType
2000 & VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT)
2001 ? &vkExportSemaphoreWin32HandleInfoKHR
2002 : NULL;
2003 #else
2004 vkExportSemaphoreCreateInfoKHR.pNext = NULL;
2005 #endif
2006 vkExportSemaphoreCreateInfoKHR.handleTypes =
2007 (VkExternalSemaphoreHandleTypeFlagsKHR)externalSemaphoreHandleType;
2008
2009 VkSemaphoreCreateInfo vkSemaphoreCreateInfo = {};
2010 vkSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2011 vkSemaphoreCreateInfo.pNext =
2012 (externalSemaphoreHandleType
2013 != VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NONE)
2014 ? &vkExportSemaphoreCreateInfoKHR
2015 : NULL;
2016 vkSemaphoreCreateInfo.flags = 0;
2017
2018 vkCreateSemaphore(m_device, &vkSemaphoreCreateInfo, NULL, &m_vkSemaphore);
2019 }
2020
~VulkanSemaphore()2021 VulkanSemaphore::~VulkanSemaphore()
2022 {
2023 vkDestroySemaphore(m_device, m_vkSemaphore, NULL);
2024 }
2025
2026 #if defined(_WIN32) || defined(_WIN64)
getHandle(VulkanExternalSemaphoreHandleType externalSemaphoreHandleType) const2027 HANDLE VulkanSemaphore::getHandle(
2028 VulkanExternalSemaphoreHandleType externalSemaphoreHandleType) const
2029 {
2030 HANDLE handle;
2031
2032 VkSemaphoreGetWin32HandleInfoKHR vkSemaphoreGetWin32HandleInfoKHR = {};
2033 vkSemaphoreGetWin32HandleInfoKHR.sType =
2034 VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR;
2035 vkSemaphoreGetWin32HandleInfoKHR.pNext = NULL;
2036 vkSemaphoreGetWin32HandleInfoKHR.semaphore = m_vkSemaphore;
2037 vkSemaphoreGetWin32HandleInfoKHR.handleType =
2038 (VkExternalSemaphoreHandleTypeFlagBitsKHR)externalSemaphoreHandleType;
2039
2040 vkGetSemaphoreWin32HandleKHR(m_device, &vkSemaphoreGetWin32HandleInfoKHR,
2041 &handle);
2042
2043 return handle;
2044 }
2045 #else
getHandle(VulkanExternalSemaphoreHandleType externalSemaphoreHandleType) const2046 int VulkanSemaphore::getHandle(
2047 VulkanExternalSemaphoreHandleType externalSemaphoreHandleType) const
2048 {
2049 if (externalSemaphoreHandleType
2050 == VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD)
2051 {
2052 int fd;
2053
2054 VkSemaphoreGetFdInfoKHR vkSemaphoreGetFdInfoKHR = {};
2055 vkSemaphoreGetFdInfoKHR.sType =
2056 VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR;
2057 vkSemaphoreGetFdInfoKHR.pNext = NULL;
2058 vkSemaphoreGetFdInfoKHR.semaphore = m_vkSemaphore;
2059 vkSemaphoreGetFdInfoKHR.handleType =
2060 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
2061
2062 vkGetSemaphoreFdKHR(m_device, &vkSemaphoreGetFdInfoKHR, &fd);
2063
2064 return fd;
2065 }
2066 return HANDLE_ERROR;
2067 }
2068 #endif
2069
getName() const2070 const std::wstring &VulkanSemaphore::getName() const { return m_name; }
2071
operator VkSemaphore() const2072 VulkanSemaphore::operator VkSemaphore() const { return m_vkSemaphore; }
2073