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 #include <Windows.h>
19 #include <dxgi1_2.h>
20 #include <aclapi.h>
21 #include <algorithm>
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(__ANDROID__)
76 const char *vulkanLoaderLibraryName = "libvulkan.so";
77 #else
78 const char *vulkanLoaderLibraryName = "libvulkan.so.1";
79 #endif
80 #ifdef _WIN32
81 HINSTANCE hDLL;
82 hDLL = LoadLibrary(vulkanLoaderLibraryName);
83 if (hDLL == NULL)
84 {
85 throw std::runtime_error("LoadLibrary failed!");
86 }
87 vkGetInstanceProcAddr =
88 (PFN_vkGetInstanceProcAddr)LoadFunction(hDLL, "vkGetInstanceProcAddr");
89 #else
90 #if !defined(__APPLE__)
91 void *handle;
92 handle = dlopen(vulkanLoaderLibraryName, RTLD_LAZY);
93 if (!handle)
94 {
95 fputs(dlerror(), stderr);
96 throw std::runtime_error("dlopen failed !!!");
97 }
98 vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)LoadFunction(
99 handle, "vkGetInstanceProcAddr");
100 #endif
101 #endif
102 if ((unsigned long long)vkGetInstanceProcAddr == (unsigned long long)NULL)
103 {
104 throw std::runtime_error("vkGetInstanceProcAddr() not found!");
105 }
106 #define VK_GET_NULL_INSTANCE_PROC_ADDR(name) \
107 _##name = (PFN_##name)vkGetInstanceProcAddr(NULL, #name);
108
109 if ((unsigned long long)vkGetInstanceProcAddr == (unsigned long long)NULL)
110 {
111 throw std::runtime_error("Couldn't obtain address for function");
112 }
113 VK_GET_NULL_INSTANCE_PROC_ADDR(vkEnumerateInstanceExtensionProperties);
114 uint32_t instanceExtensionPropertiesCount;
115 VkResult vkStatus = VK_SUCCESS;
116 vkStatus = vkEnumerateInstanceExtensionProperties(
117 NULL, &instanceExtensionPropertiesCount, NULL);
118 // Something went wrong in vulkan initialization (most likely incompatible
119 // device/driver combination)
120 if (vkStatus == VK_ERROR_INCOMPATIBLE_DRIVER)
121 {
122 throw std::runtime_error(
123 "Waiving vulkan test because "
124 "vkEnumerateInstanceExtensionProperties failed.");
125 // return WAIVED;
126 }
127
128 VK_GET_NULL_INSTANCE_PROC_ADDR(vkEnumerateInstanceVersion);
129 VK_GET_NULL_INSTANCE_PROC_ADDR(vkEnumerateInstanceLayerProperties);
130 VK_GET_NULL_INSTANCE_PROC_ADDR(vkCreateInstance);
131 #undef VK_GET_NULL_INSTANCE_PROC_ADDR
132
133 VkApplicationInfo vkApplicationInfo = {};
134 vkApplicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
135 vkApplicationInfo.pNext = NULL;
136 vkApplicationInfo.pApplicationName = "Default app";
137 vkApplicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
138 vkApplicationInfo.pEngineName = "No engine";
139 vkApplicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
140 vkApplicationInfo.apiVersion = VK_API_VERSION_1_0;
141
142 std::vector<const char *> enabledExtensionNameList;
143 enabledExtensionNameList.push_back(
144 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
145 enabledExtensionNameList.push_back(
146 VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
147 enabledExtensionNameList.push_back(
148 VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
149
150 std::vector<VkExtensionProperties> vkExtensionPropertiesList(
151 instanceExtensionPropertiesCount);
152 vkEnumerateInstanceExtensionProperties(NULL,
153 &instanceExtensionPropertiesCount,
154 vkExtensionPropertiesList.data());
155
156 for (size_t eenIdx = 0; eenIdx < enabledExtensionNameList.size(); eenIdx++)
157 {
158 bool isSupported = false;
159 for (size_t epIdx = 0; epIdx < vkExtensionPropertiesList.size();
160 epIdx++)
161 {
162 if (!strcmp(enabledExtensionNameList[eenIdx],
163 vkExtensionPropertiesList[epIdx].extensionName))
164 {
165 isSupported = true;
166 break;
167 }
168 }
169 if (!isSupported)
170 {
171 return;
172 }
173 }
174
175 VkInstanceCreateInfo vkInstanceCreateInfo = {};
176 vkInstanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
177 vkInstanceCreateInfo.pNext = NULL;
178 vkInstanceCreateInfo.flags = 0;
179 vkInstanceCreateInfo.pApplicationInfo = &vkApplicationInfo;
180 vkInstanceCreateInfo.enabledLayerCount = 0;
181 vkInstanceCreateInfo.ppEnabledLayerNames = NULL;
182 vkInstanceCreateInfo.enabledExtensionCount =
183 (uint32_t)enabledExtensionNameList.size();
184 vkInstanceCreateInfo.ppEnabledExtensionNames =
185 enabledExtensionNameList.data();
186
187 vkCreateInstance(&vkInstanceCreateInfo, NULL, &m_vkInstance);
188
189 #define VK_FUNC_DECL(name) \
190 _##name = (PFN_##name)vkGetInstanceProcAddr(m_vkInstance, #name); \
191 // ASSERT_NEQ((unsigned long long)name, 0ULL) << "Couldn't obtain address
192 // for function" << #name;
193
194 VK_FUNC_LIST
195 #if defined(_WIN32) || defined(_WIN64)
196 VK_WINDOWS_FUNC_LIST
197 #endif
198 #undef VK_FUNC_DECL
199
200 uint32_t physicalDeviceCount = 0;
201 vkEnumeratePhysicalDevices(m_vkInstance, &physicalDeviceCount, NULL);
202 // CHECK_NEQ(physicalDeviceCount, uint32_t(0));
203
204 if (physicalDeviceCount == uint32_t(0))
205 {
206 std::cout << "failed to find GPUs with Vulkan support!\n";
207 return;
208 }
209
210 std::vector<VkPhysicalDevice> vkPhysicalDeviceList(physicalDeviceCount,
211 VK_NULL_HANDLE);
212 vkEnumeratePhysicalDevices(m_vkInstance, &physicalDeviceCount,
213 vkPhysicalDeviceList.data());
214
215 for (size_t ppdIdx = 0; ppdIdx < vkPhysicalDeviceList.size(); ppdIdx++)
216 {
217 VulkanPhysicalDevice *physicalDevice =
218 new VulkanPhysicalDevice(vkPhysicalDeviceList[ppdIdx]);
219 m_physicalDeviceList.add(*physicalDevice);
220 }
221 }
222
~VulkanInstance()223 VulkanInstance::~VulkanInstance()
224 {
225 for (size_t pdIdx = 0; pdIdx < m_physicalDeviceList.size(); pdIdx++)
226 {
227 const VulkanPhysicalDevice &physicalDevice =
228 m_physicalDeviceList[pdIdx];
229 delete &physicalDevice;
230 }
231 if (m_vkInstance)
232 {
233 vkDestroyInstance(m_vkInstance, NULL);
234 }
235 }
236
getPhysicalDeviceList() const237 const VulkanPhysicalDeviceList &VulkanInstance::getPhysicalDeviceList() const
238 {
239 return m_physicalDeviceList;
240 }
241
operator VkInstance() const242 VulkanInstance::operator VkInstance() const { return m_vkInstance; }
243
244 /////////////////////////////////////////
245 // VulkanPhysicalDevice implementation //
246 /////////////////////////////////////////
247
VulkanPhysicalDevice(const VulkanPhysicalDevice & physicalDevice)248 VulkanPhysicalDevice::VulkanPhysicalDevice(
249 const VulkanPhysicalDevice &physicalDevice)
250 : m_vkPhysicalDevice(physicalDevice.m_vkPhysicalDevice),
251 m_vkPhysicalDeviceProperties(physicalDevice.m_vkPhysicalDeviceProperties),
252 m_vkDeviceNodeMask(physicalDevice.m_vkDeviceNodeMask),
253 m_vkPhysicalDeviceFeatures(physicalDevice.m_vkPhysicalDeviceFeatures),
254 m_vkPhysicalDeviceMemoryProperties(
255 physicalDevice.m_vkPhysicalDeviceMemoryProperties),
256 m_queueFamilyList(physicalDevice.m_queueFamilyList)
257 {
258 memcpy(m_vkDeviceUUID, physicalDevice.m_vkDeviceUUID, VK_UUID_SIZE);
259 }
260
VulkanPhysicalDevice(VkPhysicalDevice vkPhysicalDevice)261 VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkPhysicalDevice)
262 : m_vkPhysicalDevice(vkPhysicalDevice)
263 {
264 if (m_vkPhysicalDevice == (VkPhysicalDevice)VK_NULL_HANDLE)
265 {
266 throw std::runtime_error("failed to find a suitable GPU!");
267 }
268
269 vkGetPhysicalDeviceProperties(m_vkPhysicalDevice,
270 &m_vkPhysicalDeviceProperties);
271 vkGetPhysicalDeviceFeatures(m_vkPhysicalDevice,
272 &m_vkPhysicalDeviceFeatures);
273
274 VkPhysicalDeviceIDPropertiesKHR vkPhysicalDeviceIDPropertiesKHR = {};
275 vkPhysicalDeviceIDPropertiesKHR.sType =
276 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR;
277 vkPhysicalDeviceIDPropertiesKHR.pNext = NULL;
278
279 VkPhysicalDeviceProperties2 vkPhysicalDeviceProperties2 = {};
280 vkPhysicalDeviceProperties2.sType =
281 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
282 vkPhysicalDeviceProperties2.pNext = &vkPhysicalDeviceIDPropertiesKHR;
283
284 vkGetPhysicalDeviceProperties2(m_vkPhysicalDevice,
285 &vkPhysicalDeviceProperties2);
286
287 memcpy(m_vkDeviceUUID, vkPhysicalDeviceIDPropertiesKHR.deviceUUID,
288 sizeof(m_vkDeviceUUID));
289 memcpy(m_vkDeviceLUID, vkPhysicalDeviceIDPropertiesKHR.deviceLUID,
290 sizeof(m_vkDeviceLUID));
291 m_vkDeviceNodeMask = vkPhysicalDeviceIDPropertiesKHR.deviceNodeMask;
292
293 uint32_t queueFamilyCount = 0;
294 vkGetPhysicalDeviceQueueFamilyProperties(m_vkPhysicalDevice,
295 &queueFamilyCount, NULL);
296
297 std::vector<VkQueueFamilyProperties> vkQueueFamilyPropertiesList(
298 queueFamilyCount);
299 vkGetPhysicalDeviceQueueFamilyProperties(
300 m_vkPhysicalDevice, &queueFamilyCount,
301 vkQueueFamilyPropertiesList.data());
302
303 for (size_t qfpIdx = 0; qfpIdx < vkQueueFamilyPropertiesList.size();
304 qfpIdx++)
305 {
306 VulkanQueueFamily *queueFamily = new VulkanQueueFamily(
307 uint32_t(qfpIdx), vkQueueFamilyPropertiesList[qfpIdx]);
308 m_queueFamilyList.add(*queueFamily);
309 }
310
311 vkGetPhysicalDeviceMemoryProperties(m_vkPhysicalDevice,
312 &m_vkPhysicalDeviceMemoryProperties);
313
314 for (uint32_t mhIdx = 0;
315 mhIdx < m_vkPhysicalDeviceMemoryProperties.memoryHeapCount; mhIdx++)
316 {
317 VulkanMemoryHeap *memoryHeap = new VulkanMemoryHeap(
318 mhIdx, m_vkPhysicalDeviceMemoryProperties.memoryHeaps[mhIdx].size,
319 (VulkanMemoryHeapFlag)m_vkPhysicalDeviceMemoryProperties
320 .memoryHeaps[mhIdx]
321 .flags);
322 m_memoryHeapList.add(*memoryHeap);
323 }
324
325 for (uint32_t mtIdx = 0;
326 mtIdx < m_vkPhysicalDeviceMemoryProperties.memoryTypeCount; mtIdx++)
327 {
328 const VulkanMemoryHeap &memoryHeap = m_memoryHeapList
329 [m_vkPhysicalDeviceMemoryProperties.memoryTypes[mtIdx].heapIndex];
330 VulkanMemoryType *memoryType = new VulkanMemoryType(
331 mtIdx,
332 (VulkanMemoryTypeProperty)m_vkPhysicalDeviceMemoryProperties
333 .memoryTypes[mtIdx]
334 .propertyFlags,
335 memoryHeap);
336 m_memoryTypeList.add(*memoryType);
337 }
338 }
339
~VulkanPhysicalDevice()340 VulkanPhysicalDevice::~VulkanPhysicalDevice()
341 {
342 for (size_t mtIdx = 0; mtIdx < m_memoryTypeList.size(); mtIdx++)
343 {
344 const VulkanMemoryType &memoryType = m_memoryTypeList[mtIdx];
345 delete &memoryType;
346 }
347
348 for (size_t mhIdx = 0; mhIdx < m_memoryHeapList.size(); mhIdx++)
349 {
350 const VulkanMemoryHeap &memoryHeap = m_memoryHeapList[mhIdx];
351 delete &memoryHeap;
352 }
353
354 for (size_t qfIdx = 0; qfIdx < m_queueFamilyList.size(); qfIdx++)
355 {
356 const VulkanQueueFamily &queueFamily = m_queueFamilyList[qfIdx];
357 delete &queueFamily;
358 }
359 }
360
361
getQueueFamilyList() const362 const VulkanQueueFamilyList &VulkanPhysicalDevice::getQueueFamilyList() const
363 {
364 return m_queueFamilyList;
365 }
366
getMemoryHeapList() const367 const VulkanMemoryHeapList &VulkanPhysicalDevice::getMemoryHeapList() const
368 {
369 return m_memoryHeapList;
370 }
371
getMemoryTypeList() const372 const VulkanMemoryTypeList &VulkanPhysicalDevice::getMemoryTypeList() const
373 {
374 return m_memoryTypeList;
375 }
376
getUUID() const377 const uint8_t *VulkanPhysicalDevice::getUUID() const { return m_vkDeviceUUID; }
378
getLUID() const379 const uint8_t *VulkanPhysicalDevice::getLUID() const { return m_vkDeviceLUID; }
380
getNodeMask() const381 uint32_t VulkanPhysicalDevice::getNodeMask() const
382 {
383 return m_vkDeviceNodeMask;
384 }
385
operator VkPhysicalDevice() const386 VulkanPhysicalDevice::operator VkPhysicalDevice() const
387 {
388 return m_vkPhysicalDevice;
389 }
390
operator <(const VulkanQueueFamily & queueFamilyA,const VulkanQueueFamily & queueFamilyB)391 bool operator<(const VulkanQueueFamily &queueFamilyA,
392 const VulkanQueueFamily &queueFamilyB)
393 {
394 return (uint32_t)queueFamilyA < (uint32_t)queueFamilyB;
395 }
396
397 /////////////////////////////////////
398 // VulkanMemoryHeap implementation //
399 /////////////////////////////////////
400
VulkanMemoryHeap(const VulkanMemoryHeap & memoryHeap)401 VulkanMemoryHeap::VulkanMemoryHeap(const VulkanMemoryHeap &memoryHeap)
402 : m_memoryHeapIndex(memoryHeap.m_memoryHeapIndex),
403 m_size(memoryHeap.m_size), m_memoryHeapFlag(memoryHeap.m_memoryHeapFlag)
404 {}
405
VulkanMemoryHeap(uint32_t memoryHeapIndex,uint64_t size,VulkanMemoryHeapFlag memoryHeapFlag)406 VulkanMemoryHeap::VulkanMemoryHeap(uint32_t memoryHeapIndex, uint64_t size,
407 VulkanMemoryHeapFlag memoryHeapFlag)
408 : m_memoryHeapIndex(memoryHeapIndex), m_size(size),
409 m_memoryHeapFlag(memoryHeapFlag)
410 {}
411
~VulkanMemoryHeap()412 VulkanMemoryHeap::~VulkanMemoryHeap() {}
413
getSize() const414 uint64_t VulkanMemoryHeap::getSize() const { return m_size; }
415
416
getMemoryHeapFlag() const417 VulkanMemoryHeapFlag VulkanMemoryHeap::getMemoryHeapFlag() const
418 {
419 return m_memoryHeapFlag;
420 }
421
operator uint32_t() const422 VulkanMemoryHeap::operator uint32_t() const { return m_memoryHeapIndex; }
423
424 /////////////////////////////////////
425 // VulkanMemoryType implementation //
426 /////////////////////////////////////
427
VulkanMemoryType(const VulkanMemoryType & memoryType)428 VulkanMemoryType::VulkanMemoryType(const VulkanMemoryType &memoryType)
429 : m_memoryTypeIndex(memoryType.m_memoryTypeIndex),
430 m_memoryTypeProperty(memoryType.m_memoryTypeProperty),
431 m_memoryHeap(memoryType.m_memoryHeap)
432 {}
433
VulkanMemoryType(uint32_t memoryTypeIndex,VulkanMemoryTypeProperty memoryTypeProperty,const VulkanMemoryHeap & memoryHeap)434 VulkanMemoryType::VulkanMemoryType(uint32_t memoryTypeIndex,
435 VulkanMemoryTypeProperty memoryTypeProperty,
436 const VulkanMemoryHeap &memoryHeap)
437 : m_memoryTypeIndex(memoryTypeIndex),
438 m_memoryTypeProperty(memoryTypeProperty), m_memoryHeap(memoryHeap)
439 {}
440
~VulkanMemoryType()441 VulkanMemoryType::~VulkanMemoryType() {}
442
getMemoryTypeProperty() const443 VulkanMemoryTypeProperty VulkanMemoryType::getMemoryTypeProperty() const
444 {
445 return m_memoryTypeProperty;
446 }
447
getMemoryHeap() const448 const VulkanMemoryHeap &VulkanMemoryType::getMemoryHeap() const
449 {
450 return m_memoryHeap;
451 }
452
operator uint32_t() const453 VulkanMemoryType::operator uint32_t() const { return m_memoryTypeIndex; }
454
455 //////////////////////////////////////
456 // VulkanQueueFamily implementation //
457 //////////////////////////////////////
458
VulkanQueueFamily(const VulkanQueueFamily & queueFamily)459 VulkanQueueFamily::VulkanQueueFamily(const VulkanQueueFamily &queueFamily)
460 : m_queueFamilyIndex(queueFamily.m_queueFamilyIndex),
461 m_vkQueueFamilyProperties(queueFamily.m_vkQueueFamilyProperties)
462 {}
463
VulkanQueueFamily(uint32_t queueFamilyIndex,VkQueueFamilyProperties vkQueueFamilyProperties)464 VulkanQueueFamily::VulkanQueueFamily(
465 uint32_t queueFamilyIndex, VkQueueFamilyProperties vkQueueFamilyProperties)
466 : m_queueFamilyIndex(queueFamilyIndex),
467 m_vkQueueFamilyProperties(vkQueueFamilyProperties)
468 {}
469
~VulkanQueueFamily()470 VulkanQueueFamily::~VulkanQueueFamily() {}
471
getQueueFlags() const472 uint32_t VulkanQueueFamily::getQueueFlags() const
473 {
474 return m_vkQueueFamilyProperties.queueFlags
475 & (uint32_t)VULKAN_QUEUE_FLAG_MASK_ALL;
476 }
477
getQueueCount() const478 uint32_t VulkanQueueFamily::getQueueCount() const
479 {
480 return m_vkQueueFamilyProperties.queueCount;
481 }
482
operator uint32_t() const483 VulkanQueueFamily::operator uint32_t() const { return m_queueFamilyIndex; }
484
485 /////////////////////////////////
486 // VulkanDevice implementation //
487 /////////////////////////////////
488
VulkanDevice(const VulkanDevice & device)489 VulkanDevice::VulkanDevice(const VulkanDevice &device)
490 : m_physicalDevice(device.m_physicalDevice), m_vkDevice(device.m_vkDevice)
491 {}
492
VulkanDevice(const VulkanPhysicalDevice & physicalDevice,const VulkanQueueFamilyToQueueCountMap & queueFamilyToQueueCountMap)493 VulkanDevice::VulkanDevice(
494 const VulkanPhysicalDevice &physicalDevice,
495 const VulkanQueueFamilyToQueueCountMap &queueFamilyToQueueCountMap)
496 : m_physicalDevice(physicalDevice), m_vkDevice(NULL)
497 {
498 uint32_t maxQueueCount = 0;
499 for (uint32_t qfIdx = 0;
500 qfIdx < (uint32_t)physicalDevice.getQueueFamilyList().size(); qfIdx++)
501 {
502 maxQueueCount =
503 std::max(maxQueueCount, queueFamilyToQueueCountMap[qfIdx]);
504 }
505
506 std::vector<VkDeviceQueueCreateInfo> vkDeviceQueueCreateInfoList;
507 std::vector<float> queuePriorities(maxQueueCount);
508 for (uint32_t qfIdx = 0;
509 qfIdx < (uint32_t)physicalDevice.getQueueFamilyList().size(); qfIdx++)
510 {
511 if (queueFamilyToQueueCountMap[qfIdx])
512 {
513 VkDeviceQueueCreateInfo vkDeviceQueueCreateInfo = {};
514 vkDeviceQueueCreateInfo.sType =
515 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
516 vkDeviceQueueCreateInfo.pNext = NULL;
517 vkDeviceQueueCreateInfo.flags = 0;
518 vkDeviceQueueCreateInfo.queueFamilyIndex = qfIdx;
519 vkDeviceQueueCreateInfo.queueCount =
520 queueFamilyToQueueCountMap[qfIdx];
521 vkDeviceQueueCreateInfo.pQueuePriorities = queuePriorities.data();
522
523 vkDeviceQueueCreateInfoList.push_back(vkDeviceQueueCreateInfo);
524 }
525 }
526
527 std::vector<const char *> enabledExtensionNameList;
528 enabledExtensionNameList.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
529 enabledExtensionNameList.push_back(
530 VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
531 #if defined(_WIN32) || defined(_WIN64)
532 enabledExtensionNameList.push_back(
533 VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
534 enabledExtensionNameList.push_back(
535 VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME);
536 #else
537 enabledExtensionNameList.push_back(
538 VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
539 enabledExtensionNameList.push_back(
540 VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
541 #endif
542
543
544 VkDeviceCreateInfo vkDeviceCreateInfo = {};
545 vkDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
546 vkDeviceCreateInfo.pNext = NULL;
547 vkDeviceCreateInfo.flags = 0;
548 vkDeviceCreateInfo.queueCreateInfoCount =
549 (uint32_t)vkDeviceQueueCreateInfoList.size();
550 vkDeviceCreateInfo.pQueueCreateInfos = vkDeviceQueueCreateInfoList.data();
551 vkDeviceCreateInfo.enabledLayerCount = 0;
552 vkDeviceCreateInfo.ppEnabledLayerNames = NULL;
553 vkDeviceCreateInfo.enabledExtensionCount =
554 (uint32_t)enabledExtensionNameList.size();
555 vkDeviceCreateInfo.ppEnabledExtensionNames =
556 enabledExtensionNameList.data();
557 vkDeviceCreateInfo.pEnabledFeatures = NULL;
558
559 vkCreateDevice(physicalDevice, &vkDeviceCreateInfo, NULL, &m_vkDevice);
560
561 for (uint32_t qfIdx = 0;
562 qfIdx < (uint32_t)m_physicalDevice.getQueueFamilyList().size();
563 qfIdx++)
564 {
565 VulkanQueueList *queueList = new VulkanQueueList();
566 m_queueFamilyIndexToQueueListMap.insert(qfIdx, *queueList);
567 for (uint32_t qIdx = 0; qIdx < queueFamilyToQueueCountMap[qfIdx];
568 qIdx++)
569 {
570 VkQueue vkQueue;
571 vkGetDeviceQueue(m_vkDevice, qfIdx, qIdx, &vkQueue);
572 VulkanQueue *queue = new VulkanQueue(vkQueue);
573 m_queueFamilyIndexToQueueListMap[qfIdx].add(*queue);
574 }
575 }
576 }
577
~VulkanDevice()578 VulkanDevice::~VulkanDevice()
579 {
580 for (uint32_t qfIdx = 0;
581 qfIdx < (uint32_t)m_physicalDevice.getQueueFamilyList().size();
582 qfIdx++)
583 {
584 for (size_t qIdx = 0;
585 qIdx < m_queueFamilyIndexToQueueListMap[qfIdx].size(); qIdx++)
586 {
587 VulkanQueue &queue = m_queueFamilyIndexToQueueListMap[qfIdx][qIdx];
588 delete &queue;
589 }
590 VulkanQueueList &queueList = m_queueFamilyIndexToQueueListMap[qfIdx];
591 delete &queueList;
592 }
593 vkDestroyDevice(m_vkDevice, NULL);
594 }
595
getPhysicalDevice() const596 const VulkanPhysicalDevice &VulkanDevice::getPhysicalDevice() const
597 {
598 return m_physicalDevice;
599 }
600
getQueue(const VulkanQueueFamily & queueFamily,uint32_t queueIndex)601 VulkanQueue &VulkanDevice::getQueue(const VulkanQueueFamily &queueFamily,
602 uint32_t queueIndex)
603 {
604 return m_queueFamilyIndexToQueueListMap[queueFamily][queueIndex];
605 }
606
operator VkDevice() const607 VulkanDevice::operator VkDevice() const { return m_vkDevice; }
608
609 ////////////////////////////////
610 // VulkanFence implementation //
611 ////////////////////////////////
612
VulkanFence(const VulkanDevice & vkDevice)613 VulkanFence::VulkanFence(const VulkanDevice &vkDevice)
614 {
615
616 device = vkDevice;
617
618 VkFenceCreateInfo fenceInfo{};
619 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
620 fenceInfo.pNext = nullptr;
621 fenceInfo.flags = 0;
622
623 VkResult vkStatus = vkCreateFence(device, &fenceInfo, nullptr, &fence);
624
625 if (vkStatus != VK_SUCCESS)
626 {
627 throw std::runtime_error("Error: Failed create fence.");
628 }
629 }
630
~VulkanFence()631 VulkanFence::~VulkanFence() { vkDestroyFence(device, fence, nullptr); }
632
reset()633 void VulkanFence::reset() { vkResetFences(device, 1, &fence); }
634
wait()635 void VulkanFence::wait()
636 {
637 vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);
638 }
639
640 ////////////////////////////////
641 // VulkanQueue implementation //
642 ////////////////////////////////
643
VulkanQueue(const VulkanQueue & queue)644 VulkanQueue::VulkanQueue(const VulkanQueue &queue): m_vkQueue(queue.m_vkQueue)
645 {}
646
VulkanQueue(VkQueue vkQueue)647 VulkanQueue::VulkanQueue(VkQueue vkQueue): m_vkQueue(vkQueue) {}
648
~VulkanQueue()649 VulkanQueue::~VulkanQueue() {}
650
submit(const VulkanCommandBuffer & commandBuffer,const std::shared_ptr<VulkanFence> & vkFence)651 void VulkanQueue::submit(const VulkanCommandBuffer &commandBuffer,
652 const std::shared_ptr<VulkanFence> &vkFence)
653 {
654 VulkanCommandBufferList commandBufferList;
655 commandBufferList.add(commandBuffer);
656
657 VkSubmitInfo vkSubmitInfo = {};
658 vkSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
659 vkSubmitInfo.pNext = NULL;
660 vkSubmitInfo.waitSemaphoreCount = (uint32_t)0;
661 vkSubmitInfo.commandBufferCount = (uint32_t)commandBufferList.size();
662 vkSubmitInfo.pCommandBuffers = commandBufferList();
663
664 vkQueueSubmit(m_vkQueue, 1, &vkSubmitInfo, vkFence->fence);
665 }
666
submit(const VulkanSemaphoreList & waitSemaphoreList,const VulkanCommandBufferList & commandBufferList,const VulkanSemaphoreList & signalSemaphoreList)667 void VulkanQueue::submit(const VulkanSemaphoreList &waitSemaphoreList,
668 const VulkanCommandBufferList &commandBufferList,
669 const VulkanSemaphoreList &signalSemaphoreList)
670 {
671 std::vector<VkPipelineStageFlags> vkPipelineStageFlagsList(
672 waitSemaphoreList.size(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
673
674 VkSubmitInfo vkSubmitInfo = {};
675 vkSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
676 vkSubmitInfo.pNext = NULL;
677 vkSubmitInfo.waitSemaphoreCount = (uint32_t)waitSemaphoreList.size();
678 vkSubmitInfo.pWaitSemaphores = waitSemaphoreList();
679 vkSubmitInfo.pWaitDstStageMask = vkPipelineStageFlagsList.data();
680 vkSubmitInfo.commandBufferCount = (uint32_t)commandBufferList.size();
681 vkSubmitInfo.pCommandBuffers = commandBufferList();
682 vkSubmitInfo.signalSemaphoreCount = (uint32_t)signalSemaphoreList.size();
683 vkSubmitInfo.pSignalSemaphores = signalSemaphoreList();
684
685 vkQueueSubmit(m_vkQueue, 1, &vkSubmitInfo, NULL);
686 }
687
submit(const VulkanSemaphore & waitSemaphore,const VulkanCommandBuffer & commandBuffer,const VulkanSemaphore & signalSemaphore)688 void VulkanQueue::submit(const VulkanSemaphore &waitSemaphore,
689 const VulkanCommandBuffer &commandBuffer,
690 const VulkanSemaphore &signalSemaphore)
691 {
692 VulkanSemaphoreList waitSemaphoreList;
693 VulkanCommandBufferList commandBufferList;
694 VulkanSemaphoreList signalSemaphoreList;
695
696 waitSemaphoreList.add(waitSemaphore);
697 commandBufferList.add(commandBuffer);
698 signalSemaphoreList.add(signalSemaphore);
699
700 submit(waitSemaphoreList, commandBufferList, signalSemaphoreList);
701 }
702
submit(const VulkanCommandBuffer & commandBuffer,const VulkanSemaphore & signalSemaphore)703 void VulkanQueue::submit(const VulkanCommandBuffer &commandBuffer,
704 const VulkanSemaphore &signalSemaphore)
705 {
706 VulkanSemaphoreList waitSemaphoreList;
707 VulkanCommandBufferList commandBufferList;
708 VulkanSemaphoreList signalSemaphoreList;
709
710 commandBufferList.add(commandBuffer);
711 signalSemaphoreList.add(signalSemaphore);
712
713 submit(waitSemaphoreList, commandBufferList, signalSemaphoreList);
714 }
715
submit(const VulkanCommandBuffer & commandBuffer)716 void VulkanQueue::submit(const VulkanCommandBuffer &commandBuffer)
717 {
718 VulkanSemaphoreList waitSemaphoreList;
719 VulkanCommandBufferList commandBufferList;
720 VulkanSemaphoreList signalSemaphoreList;
721
722 commandBufferList.add(commandBuffer);
723
724 submit(waitSemaphoreList, commandBufferList, signalSemaphoreList);
725 }
726
waitIdle()727 void VulkanQueue::waitIdle() { vkQueueWaitIdle(m_vkQueue); }
728
operator VkQueue() const729 VulkanQueue::operator VkQueue() const { return m_vkQueue; }
730
731 /////////////////////////////////////////////////////
732 // VulkanDescriptorSetLayoutBinding implementation //
733 /////////////////////////////////////////////////////
734
VulkanDescriptorSetLayoutBinding(const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding)735 VulkanDescriptorSetLayoutBinding::VulkanDescriptorSetLayoutBinding(
736 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding)
737 : m_vkDescriptorSetLayoutBinding(
738 descriptorSetLayoutBinding.m_vkDescriptorSetLayoutBinding)
739 {}
740
VulkanDescriptorSetLayoutBinding(uint32_t binding,VulkanDescriptorType descriptorType,uint32_t descriptorCount,VulkanShaderStage shaderStage)741 VulkanDescriptorSetLayoutBinding::VulkanDescriptorSetLayoutBinding(
742 uint32_t binding, VulkanDescriptorType descriptorType,
743 uint32_t descriptorCount, VulkanShaderStage shaderStage)
744 {
745 m_vkDescriptorSetLayoutBinding.binding = binding;
746 m_vkDescriptorSetLayoutBinding.descriptorType =
747 (VkDescriptorType)descriptorType;
748 m_vkDescriptorSetLayoutBinding.descriptorCount = descriptorCount;
749 m_vkDescriptorSetLayoutBinding.stageFlags =
750 (VkShaderStageFlags)(VkShaderStageFlagBits)shaderStage;
751 m_vkDescriptorSetLayoutBinding.pImmutableSamplers = NULL;
752 }
753
~VulkanDescriptorSetLayoutBinding()754 VulkanDescriptorSetLayoutBinding::~VulkanDescriptorSetLayoutBinding() {}
755
operator VkDescriptorSetLayoutBinding() const756 VulkanDescriptorSetLayoutBinding::operator VkDescriptorSetLayoutBinding() const
757 {
758 return m_vkDescriptorSetLayoutBinding;
759 }
760
761 //////////////////////////////////////////////
762 // VulkanDescriptorSetLayout implementation //
763 //////////////////////////////////////////////
764
VulkanDescriptorSetLayout(const VulkanDescriptorSetLayout & descriptorSetLayout)765 VulkanDescriptorSetLayout::VulkanDescriptorSetLayout(
766 const VulkanDescriptorSetLayout &descriptorSetLayout)
767 : m_device(descriptorSetLayout.m_device),
768 m_vkDescriptorSetLayout(descriptorSetLayout.m_vkDescriptorSetLayout)
769 {}
770
VulkanDescriptorSetLayoutCommon(const VulkanDescriptorSetLayoutBindingList & descriptorSetLayoutBindingList)771 void VulkanDescriptorSetLayout::VulkanDescriptorSetLayoutCommon(
772 const VulkanDescriptorSetLayoutBindingList &descriptorSetLayoutBindingList)
773 {
774 VkDescriptorSetLayoutCreateInfo vkDescriptorSetLayoutCreateInfo = {};
775 vkDescriptorSetLayoutCreateInfo.sType =
776 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
777 vkDescriptorSetLayoutCreateInfo.pNext = NULL;
778 vkDescriptorSetLayoutCreateInfo.flags = 0;
779 vkDescriptorSetLayoutCreateInfo.bindingCount =
780 (uint32_t)descriptorSetLayoutBindingList.size();
781 vkDescriptorSetLayoutCreateInfo.pBindings =
782 descriptorSetLayoutBindingList();
783
784 vkCreateDescriptorSetLayout(m_device, &vkDescriptorSetLayoutCreateInfo,
785 NULL, &m_vkDescriptorSetLayout);
786 }
787
VulkanDescriptorSetLayout(const VulkanDevice & device,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding)788 VulkanDescriptorSetLayout::VulkanDescriptorSetLayout(
789 const VulkanDevice &device,
790 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding)
791 : m_device(device), m_vkDescriptorSetLayout(VK_NULL_HANDLE)
792 {
793 VulkanDescriptorSetLayoutBindingList descriptorSetLayoutBindingList;
794 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding);
795
796 VulkanDescriptorSetLayoutCommon(descriptorSetLayoutBindingList);
797 }
798
VulkanDescriptorSetLayout(const VulkanDevice & device,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding0,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding1)799 VulkanDescriptorSetLayout::VulkanDescriptorSetLayout(
800 const VulkanDevice &device,
801 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding0,
802 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding1)
803 : m_device(device), m_vkDescriptorSetLayout(VK_NULL_HANDLE)
804 {
805 VulkanDescriptorSetLayoutBindingList descriptorSetLayoutBindingList;
806 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding0);
807 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding1);
808
809 VulkanDescriptorSetLayoutCommon(descriptorSetLayoutBindingList);
810 }
811
VulkanDescriptorSetLayout(const VulkanDevice & device,const VulkanDescriptorSetLayoutBindingList & descriptorSetLayoutBindingList)812 VulkanDescriptorSetLayout::VulkanDescriptorSetLayout(
813 const VulkanDevice &device,
814 const VulkanDescriptorSetLayoutBindingList &descriptorSetLayoutBindingList)
815 : m_device(device), m_vkDescriptorSetLayout(VK_NULL_HANDLE)
816 {
817 VulkanDescriptorSetLayoutCommon(descriptorSetLayoutBindingList);
818 }
819
~VulkanDescriptorSetLayout()820 VulkanDescriptorSetLayout::~VulkanDescriptorSetLayout()
821 {
822 if (m_vkDescriptorSetLayout != VK_NULL_HANDLE)
823 {
824 vkDestroyDescriptorSetLayout(m_device, m_vkDescriptorSetLayout, NULL);
825 }
826 }
827
operator VkDescriptorSetLayout() const828 VulkanDescriptorSetLayout::operator VkDescriptorSetLayout() const
829 {
830 return m_vkDescriptorSetLayout;
831 }
832
833 /////////////////////////////////////////
834 // VulkanPipelineLayout implementation //
835 /////////////////////////////////////////
836
VulkanPipelineLayout(const VulkanPipelineLayout & pipelineLayout)837 VulkanPipelineLayout::VulkanPipelineLayout(
838 const VulkanPipelineLayout &pipelineLayout)
839 : m_device(pipelineLayout.m_device),
840 m_vkPipelineLayout(pipelineLayout.m_vkPipelineLayout)
841 {}
842
VulkanPipelineLayoutCommon(const VulkanDescriptorSetLayoutList & descriptorSetLayoutList)843 void VulkanPipelineLayout::VulkanPipelineLayoutCommon(
844 const VulkanDescriptorSetLayoutList &descriptorSetLayoutList)
845 {
846 VkPipelineLayoutCreateInfo vkPipelineLayoutCreateInfo = {};
847 vkPipelineLayoutCreateInfo.sType =
848 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
849 vkPipelineLayoutCreateInfo.pNext = NULL;
850 vkPipelineLayoutCreateInfo.flags = 0;
851 vkPipelineLayoutCreateInfo.setLayoutCount =
852 (uint32_t)descriptorSetLayoutList.size();
853 vkPipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayoutList();
854 vkPipelineLayoutCreateInfo.pushConstantRangeCount = 0;
855 vkPipelineLayoutCreateInfo.pPushConstantRanges = NULL;
856
857 vkCreatePipelineLayout(m_device, &vkPipelineLayoutCreateInfo, NULL,
858 &m_vkPipelineLayout);
859 }
860
VulkanPipelineLayout(const VulkanDevice & device,const VulkanDescriptorSetLayout & descriptorSetLayout)861 VulkanPipelineLayout::VulkanPipelineLayout(
862 const VulkanDevice &device,
863 const VulkanDescriptorSetLayout &descriptorSetLayout)
864 : m_device(device), m_vkPipelineLayout(VK_NULL_HANDLE)
865 {
866 VulkanDescriptorSetLayoutList descriptorSetLayoutList;
867 descriptorSetLayoutList.add(descriptorSetLayout);
868
869 VulkanPipelineLayoutCommon(descriptorSetLayoutList);
870 }
871
VulkanPipelineLayout(const VulkanDevice & device,const VulkanDescriptorSetLayoutList & descriptorSetLayoutList)872 VulkanPipelineLayout::VulkanPipelineLayout(
873 const VulkanDevice &device,
874 const VulkanDescriptorSetLayoutList &descriptorSetLayoutList)
875 : m_device(device), m_vkPipelineLayout(VK_NULL_HANDLE)
876 {
877 VulkanPipelineLayoutCommon(descriptorSetLayoutList);
878 }
879
~VulkanPipelineLayout()880 VulkanPipelineLayout::~VulkanPipelineLayout()
881 {
882 vkDestroyPipelineLayout(m_device, m_vkPipelineLayout, NULL);
883 }
884
operator VkPipelineLayout() const885 VulkanPipelineLayout::operator VkPipelineLayout() const
886 {
887 return m_vkPipelineLayout;
888 }
889
890 ///////////////////////////////////////
891 // VulkanShaderModule implementation //
892 ///////////////////////////////////////
893
VulkanShaderModule(const VulkanShaderModule & shaderModule)894 VulkanShaderModule::VulkanShaderModule(const VulkanShaderModule &shaderModule)
895 : m_device(shaderModule.m_device),
896 m_vkShaderModule(shaderModule.m_vkShaderModule)
897 {}
898
VulkanShaderModule(const VulkanDevice & device,const std::vector<char> & code)899 VulkanShaderModule::VulkanShaderModule(const VulkanDevice &device,
900 const std::vector<char> &code)
901 : m_device(device)
902 {
903
904 VkShaderModuleCreateInfo vkShaderModuleCreateInfo = {};
905 vkShaderModuleCreateInfo.sType =
906 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
907 vkShaderModuleCreateInfo.pNext = NULL;
908 vkShaderModuleCreateInfo.flags = 0;
909 vkShaderModuleCreateInfo.codeSize = code.size();
910 vkShaderModuleCreateInfo.pCode =
911 reinterpret_cast<const uint32_t *>(code.data());
912
913 vkCreateShaderModule(m_device, &vkShaderModuleCreateInfo, NULL,
914 &m_vkShaderModule);
915 }
916
~VulkanShaderModule()917 VulkanShaderModule::~VulkanShaderModule()
918 {
919 vkDestroyShaderModule(m_device, m_vkShaderModule, NULL);
920 }
921
operator VkShaderModule() const922 VulkanShaderModule::operator VkShaderModule() const { return m_vkShaderModule; }
923
924 ///////////////////////////////////
925 // VulkanPipeline implementation //
926 ///////////////////////////////////
927
VulkanPipeline(const VulkanPipeline & pipeline)928 VulkanPipeline::VulkanPipeline(const VulkanPipeline &pipeline)
929 : m_device(pipeline.m_device), m_vkPipeline(pipeline.m_vkPipeline)
930 {}
931
VulkanPipeline(const VulkanDevice & device)932 VulkanPipeline::VulkanPipeline(const VulkanDevice &device)
933 : m_device(device), m_vkPipeline(VK_NULL_HANDLE)
934 {}
935
~VulkanPipeline()936 VulkanPipeline::~VulkanPipeline()
937 {
938 vkDestroyPipeline(m_device, m_vkPipeline, NULL);
939 }
940
operator VkPipeline() const941 VulkanPipeline::operator VkPipeline() const { return m_vkPipeline; }
942
943 //////////////////////////////////////////
944 // VulkanComputePipeline implementation //
945 //////////////////////////////////////////
946
VulkanComputePipeline(const VulkanComputePipeline & computePipeline)947 VulkanComputePipeline::VulkanComputePipeline(
948 const VulkanComputePipeline &computePipeline)
949 : VulkanPipeline(computePipeline)
950 {}
951
VulkanComputePipeline(const VulkanDevice & device,const VulkanPipelineLayout & pipelineLayout,const VulkanShaderModule & shaderModule,const std::string & entryFuncName)952 VulkanComputePipeline::VulkanComputePipeline(
953 const VulkanDevice &device, const VulkanPipelineLayout &pipelineLayout,
954 const VulkanShaderModule &shaderModule, const std::string &entryFuncName)
955 : VulkanPipeline(device)
956 {
957 VkPipelineShaderStageCreateInfo vkPipelineShaderStageCreateInfo = {};
958 vkPipelineShaderStageCreateInfo.sType =
959 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
960 vkPipelineShaderStageCreateInfo.pNext = NULL;
961 vkPipelineShaderStageCreateInfo.flags = 0;
962 vkPipelineShaderStageCreateInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT;
963 vkPipelineShaderStageCreateInfo.module = shaderModule;
964 vkPipelineShaderStageCreateInfo.pName = entryFuncName.c_str();
965 vkPipelineShaderStageCreateInfo.pSpecializationInfo = NULL;
966
967 VkComputePipelineCreateInfo vkComputePipelineCreateInfo = {};
968 vkComputePipelineCreateInfo.sType =
969 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
970 vkComputePipelineCreateInfo.pNext = NULL;
971 vkComputePipelineCreateInfo.flags = 0;
972 vkComputePipelineCreateInfo.stage = vkPipelineShaderStageCreateInfo;
973 vkComputePipelineCreateInfo.layout = pipelineLayout;
974 vkComputePipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
975 vkComputePipelineCreateInfo.basePipelineIndex = 0;
976
977 vkCreateComputePipelines(device, VK_NULL_HANDLE, 1,
978 &vkComputePipelineCreateInfo, NULL, &m_vkPipeline);
979 }
980
~VulkanComputePipeline()981 VulkanComputePipeline::~VulkanComputePipeline() {}
982
getPipelineBindPoint() const983 VulkanPipelineBindPoint VulkanComputePipeline::getPipelineBindPoint() const
984 {
985 return VULKAN_PIPELINE_BIND_POINT_COMPUTE;
986 }
987
988 /////////////////////////////////////////
989 // VulkanDescriptorPool implementation //
990 /////////////////////////////////////////
991
VulkanDescriptorPool(const VulkanDescriptorPool & descriptorPool)992 VulkanDescriptorPool::VulkanDescriptorPool(
993 const VulkanDescriptorPool &descriptorPool)
994 : m_device(descriptorPool.m_device),
995 m_vkDescriptorPool(descriptorPool.m_vkDescriptorPool)
996 {}
997
VulkanDescriptorPoolCommon(const VulkanDescriptorSetLayoutBindingList & descriptorSetLayoutBindingList)998 void VulkanDescriptorPool::VulkanDescriptorPoolCommon(
999 const VulkanDescriptorSetLayoutBindingList &descriptorSetLayoutBindingList)
1000 {
1001 if (descriptorSetLayoutBindingList.size())
1002 {
1003 std::map<VkDescriptorType, uint32_t>
1004 vkDescriptorTypeToDescriptorCountMap;
1005
1006 for (size_t dslbIdx = 0;
1007 dslbIdx < descriptorSetLayoutBindingList.size(); dslbIdx++)
1008 {
1009 VkDescriptorSetLayoutBinding vkDescriptorSetLayoutBinding =
1010 descriptorSetLayoutBindingList[dslbIdx];
1011 if (vkDescriptorTypeToDescriptorCountMap.find(
1012 vkDescriptorSetLayoutBinding.descriptorType)
1013 == vkDescriptorTypeToDescriptorCountMap.end())
1014 {
1015 vkDescriptorTypeToDescriptorCountMap
1016 [vkDescriptorSetLayoutBinding.descriptorType] =
1017 vkDescriptorSetLayoutBinding.descriptorCount;
1018 }
1019 else
1020 {
1021 vkDescriptorTypeToDescriptorCountMap
1022 [vkDescriptorSetLayoutBinding.descriptorType] +=
1023 vkDescriptorSetLayoutBinding.descriptorCount;
1024 }
1025 }
1026
1027 std::vector<VkDescriptorPoolSize> vkDescriptorPoolSizeList;
1028 std::map<VkDescriptorType, uint32_t>::iterator dtdcIt;
1029 for (dtdcIt = vkDescriptorTypeToDescriptorCountMap.begin();
1030 dtdcIt != vkDescriptorTypeToDescriptorCountMap.end(); ++dtdcIt)
1031 {
1032 VkDescriptorPoolSize vkDescriptorPoolSize = {};
1033 vkDescriptorPoolSize.type = dtdcIt->first;
1034 vkDescriptorPoolSize.descriptorCount = dtdcIt->second;
1035
1036 vkDescriptorPoolSizeList.push_back(vkDescriptorPoolSize);
1037 }
1038
1039 VkDescriptorPoolCreateInfo vkDescriptorPoolCreateInfo = {};
1040 vkDescriptorPoolCreateInfo.sType =
1041 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1042 vkDescriptorPoolCreateInfo.pNext = NULL;
1043 vkDescriptorPoolCreateInfo.flags =
1044 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1045 vkDescriptorPoolCreateInfo.maxSets = 1;
1046 vkDescriptorPoolCreateInfo.poolSizeCount =
1047 (uint32_t)vkDescriptorPoolSizeList.size();
1048 vkDescriptorPoolCreateInfo.pPoolSizes = vkDescriptorPoolSizeList.data();
1049
1050 vkCreateDescriptorPool(m_device, &vkDescriptorPoolCreateInfo, NULL,
1051 &m_vkDescriptorPool);
1052 }
1053 }
1054
VulkanDescriptorPool(const VulkanDevice & device,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding)1055 VulkanDescriptorPool::VulkanDescriptorPool(
1056 const VulkanDevice &device,
1057 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding)
1058 : m_device(device), m_vkDescriptorPool(VK_NULL_HANDLE)
1059 {
1060 VulkanDescriptorSetLayoutBindingList descriptorSetLayoutBindingList;
1061 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding);
1062
1063 VulkanDescriptorPoolCommon(descriptorSetLayoutBindingList);
1064 }
1065
VulkanDescriptorPool(const VulkanDevice & device,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding0,const VulkanDescriptorSetLayoutBinding & descriptorSetLayoutBinding1)1066 VulkanDescriptorPool::VulkanDescriptorPool(
1067 const VulkanDevice &device,
1068 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding0,
1069 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding1)
1070 : m_device(device), m_vkDescriptorPool(VK_NULL_HANDLE)
1071 {
1072 VulkanDescriptorSetLayoutBindingList descriptorSetLayoutBindingList;
1073 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding0);
1074 descriptorSetLayoutBindingList.add(descriptorSetLayoutBinding1);
1075
1076 VulkanDescriptorPoolCommon(descriptorSetLayoutBindingList);
1077 }
1078
VulkanDescriptorPool(const VulkanDevice & device,const VulkanDescriptorSetLayoutBindingList & descriptorSetLayoutBindingList)1079 VulkanDescriptorPool::VulkanDescriptorPool(
1080 const VulkanDevice &device,
1081 const VulkanDescriptorSetLayoutBindingList &descriptorSetLayoutBindingList)
1082 : m_device(device), m_vkDescriptorPool(VK_NULL_HANDLE)
1083 {
1084 VulkanDescriptorPoolCommon(descriptorSetLayoutBindingList);
1085 }
1086
~VulkanDescriptorPool()1087 VulkanDescriptorPool::~VulkanDescriptorPool()
1088 {
1089 if (m_vkDescriptorPool != VK_NULL_HANDLE)
1090 {
1091 vkDestroyDescriptorPool(m_device, m_vkDescriptorPool, NULL);
1092 }
1093 }
1094
operator VkDescriptorPool() const1095 VulkanDescriptorPool::operator VkDescriptorPool() const
1096 {
1097 return m_vkDescriptorPool;
1098 }
1099
1100 ////////////////////////////////////////
1101 // VulkanDescriptorSet implementation //
1102 ////////////////////////////////////////
1103
VulkanDescriptorSet(const VulkanDescriptorSet & descriptorSet)1104 VulkanDescriptorSet::VulkanDescriptorSet(
1105 const VulkanDescriptorSet &descriptorSet)
1106 : m_device(descriptorSet.m_device),
1107 m_descriptorPool(descriptorSet.m_descriptorPool),
1108 m_vkDescriptorSet(descriptorSet.m_vkDescriptorSet)
1109 {}
1110
VulkanDescriptorSet(const VulkanDevice & device,const VulkanDescriptorPool & descriptorPool,const VulkanDescriptorSetLayout & descriptorSetLayout)1111 VulkanDescriptorSet::VulkanDescriptorSet(
1112 const VulkanDevice &device, const VulkanDescriptorPool &descriptorPool,
1113 const VulkanDescriptorSetLayout &descriptorSetLayout)
1114 : m_device(device), m_descriptorPool(descriptorPool),
1115 m_vkDescriptorSet(VK_NULL_HANDLE)
1116 {
1117 VkDescriptorSetLayout vkDescriptorSetLayout = descriptorSetLayout;
1118
1119 if ((VkDescriptorPool)m_descriptorPool)
1120 {
1121 VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo = {};
1122 vkDescriptorSetAllocateInfo.sType =
1123 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
1124 vkDescriptorSetAllocateInfo.pNext = NULL;
1125 vkDescriptorSetAllocateInfo.descriptorPool = descriptorPool;
1126 vkDescriptorSetAllocateInfo.descriptorSetCount = 1;
1127 vkDescriptorSetAllocateInfo.pSetLayouts = &vkDescriptorSetLayout;
1128
1129 vkAllocateDescriptorSets(m_device, &vkDescriptorSetAllocateInfo,
1130 &m_vkDescriptorSet);
1131 }
1132 }
1133
~VulkanDescriptorSet()1134 VulkanDescriptorSet::~VulkanDescriptorSet()
1135 {
1136 if ((VkDescriptorPool)m_descriptorPool)
1137 {
1138 vkFreeDescriptorSets(m_device, m_descriptorPool, 1, &m_vkDescriptorSet);
1139 }
1140 }
1141
update(uint32_t binding,const VulkanBuffer & buffer)1142 void VulkanDescriptorSet::update(uint32_t binding, const VulkanBuffer &buffer)
1143 {
1144 VkDescriptorBufferInfo vkDescriptorBufferInfo = {};
1145 vkDescriptorBufferInfo.buffer = buffer;
1146 vkDescriptorBufferInfo.offset = 0;
1147 vkDescriptorBufferInfo.range = VK_WHOLE_SIZE;
1148
1149 VkWriteDescriptorSet vkWriteDescriptorSet = {};
1150 vkWriteDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1151 vkWriteDescriptorSet.pNext = NULL;
1152 vkWriteDescriptorSet.dstSet = m_vkDescriptorSet;
1153 vkWriteDescriptorSet.dstBinding = binding;
1154 vkWriteDescriptorSet.dstArrayElement = 0;
1155 vkWriteDescriptorSet.descriptorCount = 1;
1156 vkWriteDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1157 vkWriteDescriptorSet.pImageInfo = NULL;
1158 vkWriteDescriptorSet.pBufferInfo = &vkDescriptorBufferInfo;
1159 vkWriteDescriptorSet.pTexelBufferView = NULL;
1160
1161 vkUpdateDescriptorSets(m_device, 1, &vkWriteDescriptorSet, 0, NULL);
1162 }
1163
updateArray(uint32_t binding,unsigned numBuffers,const VulkanBufferList & buffers)1164 void VulkanDescriptorSet::updateArray(uint32_t binding, unsigned numBuffers,
1165 const VulkanBufferList &buffers)
1166 {
1167 VkDescriptorBufferInfo *vkDescriptorBufferInfo =
1168 (VkDescriptorBufferInfo *)calloc(numBuffers,
1169 sizeof(VkDescriptorBufferInfo));
1170 for (unsigned i = 0; i < numBuffers; i++)
1171 {
1172 vkDescriptorBufferInfo[i].buffer = buffers[i];
1173 vkDescriptorBufferInfo[i].offset = 0;
1174 vkDescriptorBufferInfo[i].range = VK_WHOLE_SIZE;
1175 }
1176
1177 VkWriteDescriptorSet vkWriteDescriptorSet = {};
1178 vkWriteDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1179 vkWriteDescriptorSet.pNext = NULL;
1180 vkWriteDescriptorSet.dstSet = m_vkDescriptorSet;
1181 vkWriteDescriptorSet.dstBinding = binding;
1182 vkWriteDescriptorSet.dstArrayElement = 0;
1183 vkWriteDescriptorSet.descriptorCount = numBuffers;
1184 vkWriteDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1185 vkWriteDescriptorSet.pImageInfo = NULL;
1186 vkWriteDescriptorSet.pBufferInfo = vkDescriptorBufferInfo;
1187 vkWriteDescriptorSet.pTexelBufferView = NULL;
1188
1189 vkUpdateDescriptorSets(m_device, 1, &vkWriteDescriptorSet, 0, NULL);
1190 free(vkDescriptorBufferInfo);
1191 }
1192
update(uint32_t binding,const VulkanImageView & imageView)1193 void VulkanDescriptorSet::update(uint32_t binding,
1194 const VulkanImageView &imageView)
1195 {
1196 VkDescriptorImageInfo vkDescriptorImageInfo = {};
1197 vkDescriptorImageInfo.sampler = VK_NULL_HANDLE;
1198 vkDescriptorImageInfo.imageView = imageView;
1199 vkDescriptorImageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
1200
1201 VkWriteDescriptorSet vkWriteDescriptorSet = {};
1202 vkWriteDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1203 vkWriteDescriptorSet.pNext = NULL;
1204 vkWriteDescriptorSet.dstSet = m_vkDescriptorSet;
1205 vkWriteDescriptorSet.dstBinding = binding;
1206 vkWriteDescriptorSet.dstArrayElement = 0;
1207 vkWriteDescriptorSet.descriptorCount = 1;
1208 vkWriteDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1209 vkWriteDescriptorSet.pImageInfo = &vkDescriptorImageInfo;
1210 vkWriteDescriptorSet.pBufferInfo = NULL;
1211 vkWriteDescriptorSet.pTexelBufferView = NULL;
1212
1213 vkUpdateDescriptorSets(m_device, 1, &vkWriteDescriptorSet, 0, NULL);
1214 }
1215
updateArray(uint32_t binding,const VulkanImageViewList & imageViewList)1216 void VulkanDescriptorSet::updateArray(uint32_t binding,
1217 const VulkanImageViewList &imageViewList)
1218 {
1219 VkDescriptorImageInfo *vkDescriptorImageInfo =
1220 new VkDescriptorImageInfo[imageViewList.size()];
1221 for (size_t i = 0; i < imageViewList.size(); i++)
1222 {
1223 vkDescriptorImageInfo[i].sampler = VK_NULL_HANDLE;
1224 vkDescriptorImageInfo[i].imageView = imageViewList[i];
1225 vkDescriptorImageInfo[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
1226 }
1227
1228 VkWriteDescriptorSet vkWriteDescriptorSet = {};
1229 vkWriteDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1230 vkWriteDescriptorSet.pNext = NULL;
1231 vkWriteDescriptorSet.dstSet = m_vkDescriptorSet;
1232 vkWriteDescriptorSet.dstBinding = binding;
1233 vkWriteDescriptorSet.dstArrayElement = 0;
1234 vkWriteDescriptorSet.descriptorCount = imageViewList.size();
1235 vkWriteDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1236 vkWriteDescriptorSet.pImageInfo = vkDescriptorImageInfo;
1237 vkWriteDescriptorSet.pBufferInfo = NULL;
1238 vkWriteDescriptorSet.pTexelBufferView = NULL;
1239
1240 vkUpdateDescriptorSets(m_device, 1, &vkWriteDescriptorSet, 0, NULL);
1241 delete[] vkDescriptorImageInfo;
1242 }
1243
operator VkDescriptorSet() const1244 VulkanDescriptorSet::operator VkDescriptorSet() const
1245 {
1246 return m_vkDescriptorSet;
1247 }
1248
1249 ///////////////////////////////////
1250 // VulkanOffset3D implementation //
1251 ///////////////////////////////////
1252
VulkanOffset3D(const VulkanOffset3D & offset3D)1253 VulkanOffset3D::VulkanOffset3D(const VulkanOffset3D &offset3D)
1254 : m_vkOffset3D(offset3D.m_vkOffset3D)
1255 {}
1256
VulkanOffset3D(uint32_t x,uint32_t y,uint32_t z)1257 VulkanOffset3D::VulkanOffset3D(uint32_t x, uint32_t y, uint32_t z)
1258 {
1259 m_vkOffset3D.x = x;
1260 m_vkOffset3D.y = y;
1261 m_vkOffset3D.z = z;
1262 }
1263
~VulkanOffset3D()1264 VulkanOffset3D::~VulkanOffset3D() {}
1265
getX() const1266 uint32_t VulkanOffset3D::getX() const { return m_vkOffset3D.x; }
1267
getY() const1268 uint32_t VulkanOffset3D::getY() const { return m_vkOffset3D.y; }
1269
getZ() const1270 uint32_t VulkanOffset3D::getZ() const { return m_vkOffset3D.z; }
1271
operator VkOffset3D() const1272 VulkanOffset3D::operator VkOffset3D() const { return m_vkOffset3D; }
1273
1274 ///////////////////////////////////
1275 // VulkanExtent3D implementation //
1276 ///////////////////////////////////
1277
VulkanExtent3D(const VulkanExtent3D & extent3D)1278 VulkanExtent3D::VulkanExtent3D(const VulkanExtent3D &extent3D)
1279 : m_vkExtent3D(extent3D.m_vkExtent3D)
1280 {}
1281
VulkanExtent3D(uint32_t width,uint32_t height,uint32_t depth)1282 VulkanExtent3D::VulkanExtent3D(uint32_t width, uint32_t height, uint32_t depth)
1283 {
1284 m_vkExtent3D.width = width;
1285 m_vkExtent3D.height = height;
1286 m_vkExtent3D.depth = depth;
1287 }
1288
~VulkanExtent3D()1289 VulkanExtent3D::~VulkanExtent3D() {}
1290
getWidth() const1291 uint32_t VulkanExtent3D::getWidth() const { return m_vkExtent3D.width; }
1292
getHeight() const1293 uint32_t VulkanExtent3D::getHeight() const { return m_vkExtent3D.height; }
1294
getDepth() const1295 uint32_t VulkanExtent3D::getDepth() const { return m_vkExtent3D.depth; }
1296
operator VkExtent3D() const1297 VulkanExtent3D::operator VkExtent3D() const { return m_vkExtent3D; }
1298
1299 //////////////////////////////////////
1300 // VulkanCommandPool implementation //
1301 //////////////////////////////////////
1302
VulkanCommandPool(const VulkanCommandPool & commandPool)1303 VulkanCommandPool::VulkanCommandPool(const VulkanCommandPool &commandPool)
1304 : m_device(commandPool.m_device),
1305 m_vkCommandPool(commandPool.m_vkCommandPool)
1306 {}
1307
VulkanCommandPool(const VulkanDevice & device,const VulkanQueueFamily & queueFamily)1308 VulkanCommandPool::VulkanCommandPool(const VulkanDevice &device,
1309 const VulkanQueueFamily &queueFamily)
1310 : m_device(device)
1311 {
1312 VkCommandPoolCreateInfo vkCommandPoolCreateInfo = {};
1313 vkCommandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1314 vkCommandPoolCreateInfo.pNext = NULL;
1315 vkCommandPoolCreateInfo.flags =
1316 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1317 vkCommandPoolCreateInfo.queueFamilyIndex = queueFamily;
1318
1319 vkCreateCommandPool(m_device, &vkCommandPoolCreateInfo, NULL,
1320 &m_vkCommandPool);
1321 }
1322
~VulkanCommandPool()1323 VulkanCommandPool::~VulkanCommandPool()
1324 {
1325 vkDestroyCommandPool(m_device, m_vkCommandPool, NULL);
1326 }
1327
operator VkCommandPool() const1328 VulkanCommandPool::operator VkCommandPool() const { return m_vkCommandPool; }
1329
1330 ////////////////////////////////////////
1331 // VulkanCommandBuffer implementation //
1332 ////////////////////////////////////////
1333
VulkanCommandBuffer(const VulkanCommandBuffer & commandBuffer)1334 VulkanCommandBuffer::VulkanCommandBuffer(
1335 const VulkanCommandBuffer &commandBuffer)
1336 : m_device(commandBuffer.m_device),
1337 m_commandPool(commandBuffer.m_commandPool),
1338 m_vkCommandBuffer(commandBuffer.m_vkCommandBuffer)
1339 {}
1340
VulkanCommandBuffer(const VulkanDevice & device,const VulkanCommandPool & commandPool)1341 VulkanCommandBuffer::VulkanCommandBuffer(const VulkanDevice &device,
1342 const VulkanCommandPool &commandPool)
1343 : m_device(device), m_commandPool(commandPool)
1344 {
1345 VkCommandBufferAllocateInfo vkCommandBufferAllocateInfo = {};
1346 vkCommandBufferAllocateInfo.sType =
1347 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1348 vkCommandBufferAllocateInfo.pNext = NULL;
1349 vkCommandBufferAllocateInfo.commandPool = commandPool;
1350 vkCommandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1351 vkCommandBufferAllocateInfo.commandBufferCount = 1;
1352
1353 vkAllocateCommandBuffers(m_device, &vkCommandBufferAllocateInfo,
1354 &m_vkCommandBuffer);
1355 }
1356
~VulkanCommandBuffer()1357 VulkanCommandBuffer::~VulkanCommandBuffer()
1358 {
1359 vkFreeCommandBuffers(m_device, m_commandPool, 1, &m_vkCommandBuffer);
1360 }
1361
begin()1362 void VulkanCommandBuffer::begin()
1363 {
1364 VkCommandBufferBeginInfo vkCommandBufferBeginInfo = {};
1365 vkCommandBufferBeginInfo.sType =
1366 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1367 vkCommandBufferBeginInfo.pNext = NULL;
1368 vkCommandBufferBeginInfo.flags =
1369 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
1370 vkCommandBufferBeginInfo.pInheritanceInfo = NULL;
1371
1372 vkBeginCommandBuffer(m_vkCommandBuffer, &vkCommandBufferBeginInfo);
1373 }
1374
bindPipeline(const VulkanPipeline & pipeline)1375 void VulkanCommandBuffer::bindPipeline(const VulkanPipeline &pipeline)
1376 {
1377 VkPipelineBindPoint vkPipelineBindPoint =
1378 (VkPipelineBindPoint)pipeline.getPipelineBindPoint();
1379
1380 vkCmdBindPipeline(m_vkCommandBuffer, vkPipelineBindPoint, pipeline);
1381 }
1382
bindDescriptorSets(const VulkanPipeline & pipeline,const VulkanPipelineLayout & pipelineLayout,const VulkanDescriptorSet & descriptorSet)1383 void VulkanCommandBuffer::bindDescriptorSets(
1384 const VulkanPipeline &pipeline, const VulkanPipelineLayout &pipelineLayout,
1385 const VulkanDescriptorSet &descriptorSet)
1386 {
1387 VkPipelineBindPoint vkPipelineBindPoint =
1388 (VkPipelineBindPoint)pipeline.getPipelineBindPoint();
1389 VkDescriptorSet vkDescriptorSet = descriptorSet;
1390
1391 vkCmdBindDescriptorSets(m_vkCommandBuffer, vkPipelineBindPoint,
1392 pipelineLayout, 0, 1, &vkDescriptorSet, 0, NULL);
1393 }
1394
pipelineBarrier(const VulkanImage2DList & image2DList,VulkanImageLayout oldImageLayout,VulkanImageLayout newImageLayout)1395 void VulkanCommandBuffer::pipelineBarrier(const VulkanImage2DList &image2DList,
1396 VulkanImageLayout oldImageLayout,
1397 VulkanImageLayout newImageLayout)
1398 {
1399 std::vector<VkImageMemoryBarrier> vkImageMemoryBarrierList;
1400 for (size_t i2DIdx = 0; i2DIdx < image2DList.size(); i2DIdx++)
1401 {
1402 VkImageSubresourceRange vkImageSubresourceRange = {};
1403 vkImageSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1404 vkImageSubresourceRange.baseMipLevel = 0;
1405 vkImageSubresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
1406 vkImageSubresourceRange.baseArrayLayer = 0;
1407 vkImageSubresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
1408
1409 VkImageMemoryBarrier vkImageMemoryBarrier = {};
1410 vkImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1411 vkImageMemoryBarrier.pNext = NULL;
1412 vkImageMemoryBarrier.srcAccessMask = 0;
1413 vkImageMemoryBarrier.dstAccessMask = 0;
1414 vkImageMemoryBarrier.oldLayout = (VkImageLayout)oldImageLayout;
1415 vkImageMemoryBarrier.newLayout = (VkImageLayout)newImageLayout;
1416 vkImageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1417 vkImageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1418 vkImageMemoryBarrier.image = image2DList[i2DIdx];
1419 vkImageMemoryBarrier.subresourceRange = vkImageSubresourceRange;
1420
1421 vkImageMemoryBarrierList.push_back(vkImageMemoryBarrier);
1422 }
1423
1424 vkCmdPipelineBarrier(m_vkCommandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
1425 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL, 0,
1426 NULL, (uint32_t)vkImageMemoryBarrierList.size(),
1427 vkImageMemoryBarrierList.data());
1428 }
1429
dispatch(uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)1430 void VulkanCommandBuffer::dispatch(uint32_t groupCountX, uint32_t groupCountY,
1431 uint32_t groupCountZ)
1432 {
1433 vkCmdDispatch(m_vkCommandBuffer, groupCountX, groupCountY, groupCountZ);
1434 }
1435
fillBuffer(const VulkanBuffer & buffer,uint32_t data,uint64_t offset,uint64_t size)1436 void VulkanCommandBuffer::fillBuffer(const VulkanBuffer &buffer, uint32_t data,
1437 uint64_t offset, uint64_t size)
1438 {
1439 vkCmdFillBuffer(m_vkCommandBuffer, buffer, offset, size, data);
1440 }
1441
updateBuffer(const VulkanBuffer & buffer,void * pdata,uint64_t offset,uint64_t size)1442 void VulkanCommandBuffer::updateBuffer(const VulkanBuffer &buffer, void *pdata,
1443 uint64_t offset, uint64_t size)
1444 {
1445 vkCmdUpdateBuffer(m_vkCommandBuffer, buffer, offset, size, pdata);
1446 }
1447
copyBufferToImage(const VulkanBuffer & buffer,const VulkanImage & image,VulkanImageLayout imageLayout)1448 void VulkanCommandBuffer::copyBufferToImage(const VulkanBuffer &buffer,
1449 const VulkanImage &image,
1450 VulkanImageLayout imageLayout)
1451 {
1452 VkDeviceSize bufferOffset = 0;
1453
1454 std::vector<VkBufferImageCopy> vkBufferImageCopyList;
1455 for (uint32_t mipLevel = 0; mipLevel < image.getNumMipLevels(); mipLevel++)
1456 {
1457 VulkanExtent3D extent3D = image.getExtent3D(mipLevel);
1458 size_t elementSize = getVulkanFormatElementSize(image.getFormat());
1459
1460 VkImageSubresourceLayers vkImageSubresourceLayers = {};
1461 vkImageSubresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1462 vkImageSubresourceLayers.mipLevel = mipLevel;
1463 vkImageSubresourceLayers.baseArrayLayer = 0;
1464 vkImageSubresourceLayers.layerCount = image.getNumLayers();
1465
1466 VkBufferImageCopy vkBufferImageCopy = {};
1467 vkBufferImageCopy.bufferOffset = bufferOffset;
1468 vkBufferImageCopy.bufferRowLength = 0;
1469 vkBufferImageCopy.bufferImageHeight = 0;
1470 vkBufferImageCopy.imageSubresource = vkImageSubresourceLayers;
1471 vkBufferImageCopy.imageOffset = VulkanOffset3D(0, 0, 0);
1472 vkBufferImageCopy.imageExtent = extent3D;
1473
1474 vkBufferImageCopyList.push_back(vkBufferImageCopy);
1475
1476 bufferOffset += extent3D.getWidth() * extent3D.getHeight()
1477 * extent3D.getDepth() * elementSize;
1478 bufferOffset =
1479 ROUND_UP(bufferOffset,
1480 std::max(elementSize,
1481 (size_t)VULKAN_MIN_BUFFER_OFFSET_COPY_ALIGNMENT));
1482 }
1483
1484 vkCmdCopyBufferToImage(
1485 m_vkCommandBuffer, buffer, image, (VkImageLayout)imageLayout,
1486 (uint32_t)vkBufferImageCopyList.size(), vkBufferImageCopyList.data());
1487 }
1488
copyBufferToImage(const VulkanBuffer & buffer,const VulkanImage & image,uint64_t bufferOffset,uint32_t mipLevel,uint32_t baseArrayLayer,uint32_t layerCount,VulkanOffset3D offset3D,VulkanExtent3D extent3D)1489 void VulkanCommandBuffer::copyBufferToImage(
1490 const VulkanBuffer &buffer, const VulkanImage &image, uint64_t bufferOffset,
1491 uint32_t mipLevel, uint32_t baseArrayLayer, uint32_t layerCount,
1492 VulkanOffset3D offset3D, VulkanExtent3D extent3D)
1493 {
1494 VkImageSubresourceLayers vkImageSubresourceLayers = {};
1495 vkImageSubresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1496 vkImageSubresourceLayers.mipLevel = mipLevel;
1497 vkImageSubresourceLayers.baseArrayLayer = baseArrayLayer;
1498 vkImageSubresourceLayers.layerCount = layerCount;
1499
1500 VkExtent3D vkExtent3D = extent3D;
1501 if ((extent3D.getWidth() == 0) && (extent3D.getHeight() == 0)
1502 && (extent3D.getDepth() == 0))
1503 {
1504 vkExtent3D = image.getExtent3D(mipLevel);
1505 }
1506
1507 VkBufferImageCopy vkBufferImageCopy = {};
1508 vkBufferImageCopy.bufferOffset = bufferOffset;
1509 vkBufferImageCopy.bufferRowLength = 0;
1510 vkBufferImageCopy.bufferImageHeight = 0;
1511 vkBufferImageCopy.imageSubresource = vkImageSubresourceLayers;
1512 vkBufferImageCopy.imageOffset = offset3D;
1513 vkBufferImageCopy.imageExtent = vkExtent3D;
1514
1515 vkCmdCopyBufferToImage(m_vkCommandBuffer, buffer, image,
1516 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
1517 &vkBufferImageCopy);
1518 }
1519
copyImageToBuffer(const VulkanImage & image,const VulkanBuffer & buffer,uint64_t bufferOffset,uint32_t mipLevel,uint32_t baseArrayLayer,uint32_t layerCount,VulkanOffset3D offset3D,VulkanExtent3D extent3D)1520 void VulkanCommandBuffer::copyImageToBuffer(
1521 const VulkanImage &image, const VulkanBuffer &buffer, uint64_t bufferOffset,
1522 uint32_t mipLevel, uint32_t baseArrayLayer, uint32_t layerCount,
1523 VulkanOffset3D offset3D, VulkanExtent3D extent3D)
1524 {
1525 VkImageSubresourceLayers vkImageSubresourceLayers = {};
1526 vkImageSubresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1527 vkImageSubresourceLayers.mipLevel = mipLevel;
1528 vkImageSubresourceLayers.baseArrayLayer = baseArrayLayer;
1529 vkImageSubresourceLayers.layerCount = layerCount;
1530
1531 VkExtent3D vkExtent3D = extent3D;
1532 if ((extent3D.getWidth() == 0) && (extent3D.getHeight() == 0)
1533 && (extent3D.getDepth() == 0))
1534 {
1535 vkExtent3D = image.getExtent3D(mipLevel);
1536 }
1537
1538 VkBufferImageCopy vkBufferImageCopy = {};
1539 vkBufferImageCopy.bufferOffset = bufferOffset;
1540 vkBufferImageCopy.bufferRowLength = 0;
1541 vkBufferImageCopy.bufferImageHeight = 0;
1542 vkBufferImageCopy.imageSubresource = vkImageSubresourceLayers;
1543 vkBufferImageCopy.imageOffset = offset3D;
1544 vkBufferImageCopy.imageExtent = vkExtent3D;
1545
1546 vkCmdCopyImageToBuffer(m_vkCommandBuffer, image, VK_IMAGE_LAYOUT_GENERAL,
1547 buffer, 1, &vkBufferImageCopy);
1548 }
1549
end()1550 void VulkanCommandBuffer::end() { vkEndCommandBuffer(m_vkCommandBuffer); }
1551
operator VkCommandBuffer() const1552 VulkanCommandBuffer::operator VkCommandBuffer() const
1553 {
1554 return m_vkCommandBuffer;
1555 }
1556
1557 /////////////////////////////////
1558 // VulkanBuffer implementation //
1559 /////////////////////////////////
1560
VulkanBuffer(const VulkanBuffer & buffer)1561 VulkanBuffer::VulkanBuffer(const VulkanBuffer &buffer)
1562 : m_device(buffer.m_device), m_vkBuffer(buffer.m_vkBuffer),
1563 m_size(buffer.m_size), m_alignment(buffer.m_alignment),
1564 m_memoryTypeList(buffer.m_memoryTypeList)
1565 {}
1566
isDedicated() const1567 bool VulkanBuffer::isDedicated() const { return m_dedicated; }
1568
VulkanBuffer(const VulkanDevice & device,uint64_t size,VulkanExternalMemoryHandleType externalMemoryHandleType,VulkanBufferUsage bufferUsage,VulkanSharingMode sharingMode,const VulkanQueueFamilyList & queueFamilyList)1569 VulkanBuffer::VulkanBuffer(
1570 const VulkanDevice &device, uint64_t size,
1571 VulkanExternalMemoryHandleType externalMemoryHandleType,
1572 VulkanBufferUsage bufferUsage, VulkanSharingMode sharingMode,
1573 const VulkanQueueFamilyList &queueFamilyList)
1574 : m_device(device), m_vkBuffer(VK_NULL_HANDLE), m_dedicated(false)
1575 {
1576 std::vector<uint32_t> queueFamilyIndexList;
1577 if (queueFamilyList.size() == 0)
1578 {
1579 for (size_t qfIdx = 0;
1580 qfIdx < device.getPhysicalDevice().getQueueFamilyList().size();
1581 qfIdx++)
1582 {
1583 queueFamilyIndexList.push_back(
1584 device.getPhysicalDevice().getQueueFamilyList()[qfIdx]);
1585 }
1586 }
1587 else
1588 {
1589 for (size_t qfIdx = 0; qfIdx < queueFamilyList.size(); qfIdx++)
1590 {
1591 queueFamilyIndexList.push_back(queueFamilyList[qfIdx]);
1592 }
1593 }
1594
1595 VkBufferCreateInfo vkBufferCreateInfo = {};
1596 vkBufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1597 vkBufferCreateInfo.pNext = NULL;
1598 vkBufferCreateInfo.flags = 0;
1599 vkBufferCreateInfo.size = (VkDeviceSize)size;
1600 vkBufferCreateInfo.usage = (VkBufferUsageFlags)bufferUsage;
1601 vkBufferCreateInfo.sharingMode = (VkSharingMode)sharingMode;
1602 vkBufferCreateInfo.queueFamilyIndexCount =
1603 (uint32_t)queueFamilyIndexList.size();
1604 vkBufferCreateInfo.pQueueFamilyIndices = queueFamilyIndexList.data();
1605
1606 VkExternalMemoryBufferCreateInfo vkExternalMemoryBufferCreateInfo = {};
1607 if (externalMemoryHandleType != VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE)
1608 {
1609 vkExternalMemoryBufferCreateInfo.sType =
1610 VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR;
1611 vkExternalMemoryBufferCreateInfo.pNext = NULL;
1612 vkExternalMemoryBufferCreateInfo.handleTypes =
1613 (VkExternalMemoryHandleTypeFlags)externalMemoryHandleType;
1614
1615 vkBufferCreateInfo.pNext = &vkExternalMemoryBufferCreateInfo;
1616 }
1617
1618 vkCreateBuffer(m_device, &vkBufferCreateInfo, NULL, &m_vkBuffer);
1619
1620 VkMemoryDedicatedRequirements vkMemoryDedicatedRequirements = {};
1621 vkMemoryDedicatedRequirements.sType =
1622 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
1623 vkMemoryDedicatedRequirements.pNext = NULL;
1624
1625 VkMemoryRequirements2 vkMemoryRequirements = {};
1626 vkMemoryRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
1627 vkMemoryRequirements.pNext = &vkMemoryDedicatedRequirements;
1628
1629 VkBufferMemoryRequirementsInfo2 vkMemoryRequirementsInfo = {};
1630
1631 vkMemoryRequirementsInfo.sType =
1632 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
1633 vkMemoryRequirementsInfo.buffer = m_vkBuffer;
1634 vkMemoryRequirementsInfo.pNext = NULL;
1635
1636 vkGetBufferMemoryRequirements2(m_device, &vkMemoryRequirementsInfo,
1637 &vkMemoryRequirements);
1638
1639 m_dedicated = vkMemoryDedicatedRequirements.requiresDedicatedAllocation;
1640
1641 m_size = vkMemoryRequirements.memoryRequirements.size;
1642 m_alignment = vkMemoryRequirements.memoryRequirements.alignment;
1643 const VulkanMemoryTypeList &memoryTypeList =
1644 m_device.getPhysicalDevice().getMemoryTypeList();
1645 for (size_t mtIdx = 0; mtIdx < memoryTypeList.size(); mtIdx++)
1646 {
1647 uint32_t memoryTypeIndex = memoryTypeList[mtIdx];
1648 if ((1 << memoryTypeIndex)
1649 & vkMemoryRequirements.memoryRequirements.memoryTypeBits)
1650 {
1651 m_memoryTypeList.add(memoryTypeList[mtIdx]);
1652 }
1653 }
1654 }
1655
~VulkanBuffer()1656 VulkanBuffer::~VulkanBuffer() { vkDestroyBuffer(m_device, m_vkBuffer, NULL); }
1657
getSize() const1658 uint64_t VulkanBuffer::getSize() const { return m_size; }
1659
getAlignment() const1660 uint64_t VulkanBuffer::getAlignment() const { return m_alignment; }
1661
getMemoryTypeList() const1662 const VulkanMemoryTypeList &VulkanBuffer::getMemoryTypeList() const
1663 {
1664 return m_memoryTypeList;
1665 }
1666
operator VkBuffer() const1667 VulkanBuffer::operator VkBuffer() const { return m_vkBuffer; }
1668
1669 ////////////////////////////////
1670 // VulkanImage implementation //
1671 ////////////////////////////////
1672
VulkanImage(const VulkanImage & image)1673 VulkanImage::VulkanImage(const VulkanImage &image)
1674 : m_device(image.m_device), m_imageType(image.m_imageType),
1675 m_extent3D(image.m_extent3D), m_format(image.m_format),
1676 m_numMipLevels(image.m_numMipLevels), m_numLayers(image.m_numLayers),
1677 m_vkImage(image.m_vkImage), m_size(image.m_size),
1678 m_alignment(image.m_alignment), m_memoryTypeList(image.m_memoryTypeList)
1679 {}
1680
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)1681 VulkanImage::VulkanImage(
1682 const VulkanDevice &device, VulkanImageType imageType, VulkanFormat format,
1683 const VulkanExtent3D &extent3D, uint32_t numMipLevels, uint32_t arrayLayers,
1684 VulkanExternalMemoryHandleType externalMemoryHandleType,
1685 VulkanImageCreateFlag imageCreateFlag, VulkanImageTiling imageTiling,
1686 VulkanImageUsage imageUsage, VulkanSharingMode sharingMode)
1687 : m_device(device), m_imageType(imageType), m_extent3D(extent3D),
1688 m_format(format), m_numMipLevels(numMipLevels), m_numLayers(arrayLayers),
1689 m_vkImage(VK_NULL_HANDLE)
1690 {
1691 VkImageCreateInfo vkImageCreateInfo = {};
1692 vkImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1693 vkImageCreateInfo.pNext = NULL;
1694 vkImageCreateInfo.flags = (VkImageCreateFlags)imageCreateFlag;
1695 vkImageCreateInfo.imageType = (VkImageType)imageType;
1696 vkImageCreateInfo.format = (VkFormat)format;
1697 vkImageCreateInfo.extent = extent3D;
1698 vkImageCreateInfo.mipLevels = numMipLevels;
1699 vkImageCreateInfo.arrayLayers = arrayLayers;
1700 vkImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1701 vkImageCreateInfo.tiling = (VkImageTiling)imageTiling;
1702 vkImageCreateInfo.usage = (VkImageUsageFlags)imageUsage;
1703 vkImageCreateInfo.sharingMode = (VkSharingMode)sharingMode;
1704 vkImageCreateInfo.queueFamilyIndexCount =
1705 (uint32_t)m_device.getPhysicalDevice().getQueueFamilyList().size();
1706 vkImageCreateInfo.pQueueFamilyIndices =
1707 m_device.getPhysicalDevice().getQueueFamilyList()();
1708 vkImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1709
1710 VkExternalMemoryImageCreateInfo vkExternalMemoryImageCreateInfo = {};
1711 if (externalMemoryHandleType != VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE)
1712 {
1713 vkExternalMemoryImageCreateInfo.sType =
1714 VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
1715 vkExternalMemoryImageCreateInfo.pNext = NULL;
1716 vkExternalMemoryImageCreateInfo.handleTypes =
1717 (VkExternalMemoryHandleTypeFlags)externalMemoryHandleType;
1718
1719 vkImageCreateInfo.pNext = &vkExternalMemoryImageCreateInfo;
1720 }
1721
1722 vkCreateImage(m_device, &vkImageCreateInfo, NULL, &m_vkImage);
1723 VulkanImageCreateInfo = vkImageCreateInfo;
1724
1725 VkMemoryDedicatedRequirements vkMemoryDedicatedRequirements = {};
1726 vkMemoryDedicatedRequirements.sType =
1727 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
1728 vkMemoryDedicatedRequirements.pNext = NULL;
1729
1730 VkMemoryRequirements2 vkMemoryRequirements = {};
1731 vkMemoryRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
1732 vkMemoryRequirements.pNext = &vkMemoryDedicatedRequirements;
1733
1734 VkImageMemoryRequirementsInfo2 vkMemoryRequirementsInfo = {};
1735
1736 vkMemoryRequirementsInfo.sType =
1737 VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
1738 vkMemoryRequirementsInfo.image = m_vkImage;
1739 vkMemoryRequirementsInfo.pNext = NULL;
1740
1741 vkGetImageMemoryRequirements2(m_device, &vkMemoryRequirementsInfo,
1742 &vkMemoryRequirements);
1743 m_size = vkMemoryRequirements.memoryRequirements.size;
1744 m_alignment = vkMemoryRequirements.memoryRequirements.alignment;
1745 m_dedicated = vkMemoryDedicatedRequirements.requiresDedicatedAllocation;
1746
1747 const VulkanMemoryTypeList &memoryTypeList =
1748 m_device.getPhysicalDevice().getMemoryTypeList();
1749 for (size_t mtIdx = 0; mtIdx < memoryTypeList.size(); mtIdx++)
1750 {
1751 uint32_t memoryTypeIndex = memoryTypeList[mtIdx];
1752 if ((1 << memoryTypeIndex)
1753 & vkMemoryRequirements.memoryRequirements.memoryTypeBits)
1754 {
1755 m_memoryTypeList.add(memoryTypeList[mtIdx]);
1756 }
1757 }
1758 }
1759
~VulkanImage()1760 VulkanImage::~VulkanImage() { vkDestroyImage(m_device, m_vkImage, NULL); }
1761
getExtent3D(uint32_t mipLevel) const1762 VulkanExtent3D VulkanImage::getExtent3D(uint32_t mipLevel) const
1763 {
1764 return VulkanExtent3D(0, 0, 0);
1765 }
1766
getFormat() const1767 VulkanFormat VulkanImage::getFormat() const { return m_format; }
1768
getVkImageCreateInfo() const1769 VkImageCreateInfo VulkanImage::getVkImageCreateInfo() const
1770 {
1771 return VulkanImageCreateInfo;
1772 }
1773
getNumMipLevels() const1774 uint32_t VulkanImage::getNumMipLevels() const { return m_numMipLevels; }
1775
getNumLayers() const1776 uint32_t VulkanImage::getNumLayers() const { return m_numLayers; }
1777
getSize() const1778 uint64_t VulkanImage::getSize() const { return m_size; }
1779
getAlignment() const1780 uint64_t VulkanImage::getAlignment() const { return m_alignment; }
1781
isDedicated() const1782 bool VulkanImage::isDedicated() const { return m_dedicated; }
1783
getMemoryTypeList() const1784 const VulkanMemoryTypeList &VulkanImage::getMemoryTypeList() const
1785 {
1786 return m_memoryTypeList;
1787 }
1788
operator VkImage() const1789 VulkanImage::operator VkImage() const { return m_vkImage; }
1790
1791 //////////////////////////////////
1792 // VulkanImage2D implementation //
1793 //////////////////////////////////
1794
VulkanImage2D(const VulkanImage2D & image2D)1795 VulkanImage2D::VulkanImage2D(const VulkanImage2D &image2D): VulkanImage(image2D)
1796 {}
1797
VulkanImage2D(const VulkanDevice & device,VulkanFormat format,uint32_t width,uint32_t height,VulkanImageTiling imageTiling,uint32_t numMipLevels,VulkanExternalMemoryHandleType externalMemoryHandleType,VulkanImageCreateFlag imageCreateFlag,VulkanImageUsage imageUsage,VulkanSharingMode sharingMode)1798 VulkanImage2D::VulkanImage2D(
1799 const VulkanDevice &device, VulkanFormat format, uint32_t width,
1800 uint32_t height, VulkanImageTiling imageTiling, uint32_t numMipLevels,
1801 VulkanExternalMemoryHandleType externalMemoryHandleType,
1802 VulkanImageCreateFlag imageCreateFlag, VulkanImageUsage imageUsage,
1803 VulkanSharingMode sharingMode)
1804 : VulkanImage(device, VULKAN_IMAGE_TYPE_2D, format,
1805 VulkanExtent3D(width, height, 1), numMipLevels, 1,
1806 externalMemoryHandleType, imageCreateFlag, imageTiling,
1807 imageUsage, sharingMode)
1808 {}
1809
~VulkanImage2D()1810 VulkanImage2D::~VulkanImage2D() {}
1811
getExtent3D(uint32_t mipLevel) const1812 VulkanExtent3D VulkanImage2D::getExtent3D(uint32_t mipLevel) const
1813 {
1814 uint32_t width = std::max(m_extent3D.getWidth() >> mipLevel, uint32_t(1));
1815 uint32_t height = std::max(m_extent3D.getHeight() >> mipLevel, uint32_t(1));
1816 uint32_t depth = 1;
1817
1818 return VulkanExtent3D(width, height, depth);
1819 }
1820
1821 ////////////////////////////////////
1822 // VulkanImageView implementation //
1823 ////////////////////////////////////
1824
VulkanImageView(const VulkanImageView & imageView)1825 VulkanImageView::VulkanImageView(const VulkanImageView &imageView)
1826 : m_device(imageView.m_device), m_vkImageView(imageView.m_vkImageView)
1827 {}
1828
VulkanImageView(const VulkanDevice & device,const VulkanImage & image,VulkanImageViewType imageViewType,uint32_t baseMipLevel,uint32_t levelCount,uint32_t baseArrayLayer,uint32_t layerCount)1829 VulkanImageView::VulkanImageView(const VulkanDevice &device,
1830 const VulkanImage &image,
1831 VulkanImageViewType imageViewType,
1832 uint32_t baseMipLevel, uint32_t levelCount,
1833 uint32_t baseArrayLayer, uint32_t layerCount)
1834 : m_device(device), m_vkImageView(VK_NULL_HANDLE)
1835 {
1836 VkComponentMapping vkComponentMapping = {};
1837 vkComponentMapping.r = VK_COMPONENT_SWIZZLE_IDENTITY;
1838 vkComponentMapping.g = VK_COMPONENT_SWIZZLE_IDENTITY;
1839 vkComponentMapping.b = VK_COMPONENT_SWIZZLE_IDENTITY;
1840 vkComponentMapping.a = VK_COMPONENT_SWIZZLE_IDENTITY;
1841
1842 VkImageSubresourceRange vkImageSubresourceRange = {};
1843 vkImageSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1844 vkImageSubresourceRange.baseMipLevel = baseMipLevel;
1845 vkImageSubresourceRange.levelCount = levelCount;
1846 vkImageSubresourceRange.baseArrayLayer = baseArrayLayer;
1847 vkImageSubresourceRange.layerCount = layerCount;
1848
1849 VkImageViewCreateInfo vkImageViewCreateInfo = {};
1850 vkImageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1851 vkImageViewCreateInfo.pNext = NULL;
1852 vkImageViewCreateInfo.flags = 0;
1853 vkImageViewCreateInfo.image = image;
1854 vkImageViewCreateInfo.viewType = (VkImageViewType)imageViewType;
1855 vkImageViewCreateInfo.format = (VkFormat)image.getFormat();
1856 vkImageViewCreateInfo.components = vkComponentMapping;
1857 vkImageViewCreateInfo.subresourceRange = vkImageSubresourceRange;
1858
1859 vkCreateImageView(m_device, &vkImageViewCreateInfo, NULL, &m_vkImageView);
1860 }
1861
~VulkanImageView()1862 VulkanImageView::~VulkanImageView()
1863 {
1864 vkDestroyImageView(m_device, m_vkImageView, NULL);
1865 }
1866
operator VkImageView() const1867 VulkanImageView::operator VkImageView() const { return m_vkImageView; }
1868
1869 ///////////////////////////////////////
1870 // VulkanDeviceMemory implementation //
1871 ///////////////////////////////////////
1872
1873 #if defined(_WIN32) || defined(_WIN64)
1874
1875 class WindowsSecurityAttributes {
1876 protected:
1877 SECURITY_ATTRIBUTES m_winSecurityAttributes;
1878 PSECURITY_DESCRIPTOR m_winPSecurityDescriptor;
1879
1880 public:
1881 WindowsSecurityAttributes();
1882 SECURITY_ATTRIBUTES *operator&();
1883 ~WindowsSecurityAttributes();
1884 };
1885
1886
WindowsSecurityAttributes()1887 WindowsSecurityAttributes::WindowsSecurityAttributes()
1888 {
1889 m_winPSecurityDescriptor = (PSECURITY_DESCRIPTOR)calloc(
1890 1, SECURITY_DESCRIPTOR_MIN_LENGTH + 2 * sizeof(void **));
1891 // CHECK_NEQ(m_winPSecurityDescriptor, (PSECURITY_DESCRIPTOR)NULL);
1892 PSID *ppSID = (PSID *)((PBYTE)m_winPSecurityDescriptor
1893 + SECURITY_DESCRIPTOR_MIN_LENGTH);
1894 PACL *ppACL = (PACL *)((PBYTE)ppSID + sizeof(PSID *));
1895 InitializeSecurityDescriptor(m_winPSecurityDescriptor,
1896 SECURITY_DESCRIPTOR_REVISION);
1897 SID_IDENTIFIER_AUTHORITY sidIdentifierAuthority =
1898 SECURITY_WORLD_SID_AUTHORITY;
1899 AllocateAndInitializeSid(&sidIdentifierAuthority, 1, SECURITY_WORLD_RID, 0,
1900 0, 0, 0, 0, 0, 0, ppSID);
1901 EXPLICIT_ACCESS explicitAccess;
1902 ZeroMemory(&explicitAccess, sizeof(EXPLICIT_ACCESS));
1903 explicitAccess.grfAccessPermissions =
1904 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1905 explicitAccess.grfAccessMode = SET_ACCESS;
1906 explicitAccess.grfInheritance = INHERIT_ONLY;
1907 explicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
1908 explicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
1909 explicitAccess.Trustee.ptstrName = (LPTSTR)*ppSID;
1910 SetEntriesInAcl(1, &explicitAccess, NULL, ppACL);
1911 SetSecurityDescriptorDacl(m_winPSecurityDescriptor, TRUE, *ppACL, FALSE);
1912 m_winSecurityAttributes.nLength = sizeof(m_winSecurityAttributes);
1913 m_winSecurityAttributes.lpSecurityDescriptor = m_winPSecurityDescriptor;
1914 m_winSecurityAttributes.bInheritHandle = TRUE;
1915 }
1916
operator &()1917 SECURITY_ATTRIBUTES *WindowsSecurityAttributes::operator&()
1918 {
1919 return &m_winSecurityAttributes;
1920 }
1921
~WindowsSecurityAttributes()1922 WindowsSecurityAttributes::~WindowsSecurityAttributes()
1923 {
1924 PSID *ppSID = (PSID *)((PBYTE)m_winPSecurityDescriptor
1925 + SECURITY_DESCRIPTOR_MIN_LENGTH);
1926 PACL *ppACL = (PACL *)((PBYTE)ppSID + sizeof(PSID *));
1927 if (*ppSID)
1928 {
1929 FreeSid(*ppSID);
1930 }
1931 if (*ppACL)
1932 {
1933 LocalFree(*ppACL);
1934 }
1935 free(m_winPSecurityDescriptor);
1936 }
1937
1938 #endif
1939
VulkanDeviceMemory(const VulkanDeviceMemory & deviceMemory)1940 VulkanDeviceMemory::VulkanDeviceMemory(const VulkanDeviceMemory &deviceMemory)
1941 : m_device(deviceMemory.m_device),
1942 m_vkDeviceMemory(deviceMemory.m_vkDeviceMemory),
1943 m_size(deviceMemory.m_size), m_isDedicated(deviceMemory.m_isDedicated)
1944 {}
1945
VulkanDeviceMemory(const VulkanDevice & device,uint64_t size,const VulkanMemoryType & memoryType,VulkanExternalMemoryHandleType externalMemoryHandleType,const void * name)1946 VulkanDeviceMemory::VulkanDeviceMemory(
1947 const VulkanDevice &device, uint64_t size,
1948 const VulkanMemoryType &memoryType,
1949 VulkanExternalMemoryHandleType externalMemoryHandleType, const void *name)
1950 : m_device(device), m_size(size), m_isDedicated(false)
1951 {
1952 #if defined(_WIN32) || defined(_WIN64)
1953 WindowsSecurityAttributes winSecurityAttributes;
1954
1955 VkExportMemoryWin32HandleInfoKHR vkExportMemoryWin32HandleInfoKHR = {};
1956 vkExportMemoryWin32HandleInfoKHR.sType =
1957 VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
1958 vkExportMemoryWin32HandleInfoKHR.pNext = NULL;
1959 vkExportMemoryWin32HandleInfoKHR.pAttributes = &winSecurityAttributes;
1960 vkExportMemoryWin32HandleInfoKHR.dwAccess =
1961 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE;
1962 vkExportMemoryWin32HandleInfoKHR.name = (LPCWSTR)name;
1963
1964 #endif
1965
1966 VkExportMemoryAllocateInfoKHR vkExportMemoryAllocateInfoKHR = {};
1967 vkExportMemoryAllocateInfoKHR.sType =
1968 VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;
1969 #if defined(_WIN32) || defined(_WIN64)
1970 vkExportMemoryAllocateInfoKHR.pNext = externalMemoryHandleType
1971 & VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT
1972 ? &vkExportMemoryWin32HandleInfoKHR
1973 : NULL;
1974 #else
1975 vkExportMemoryAllocateInfoKHR.pNext = NULL;
1976 #endif
1977 vkExportMemoryAllocateInfoKHR.handleTypes =
1978 (VkExternalMemoryHandleTypeFlagsKHR)externalMemoryHandleType;
1979
1980 VkMemoryAllocateInfo vkMemoryAllocateInfo = {};
1981 vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1982 vkMemoryAllocateInfo.pNext =
1983 externalMemoryHandleType ? &vkExportMemoryAllocateInfoKHR : NULL;
1984 vkMemoryAllocateInfo.allocationSize = m_size;
1985 vkMemoryAllocateInfo.memoryTypeIndex = (uint32_t)memoryType;
1986
1987 vkAllocateMemory(m_device, &vkMemoryAllocateInfo, NULL, &m_vkDeviceMemory);
1988 }
1989
VulkanDeviceMemory(const VulkanDevice & device,const VulkanImage & image,const VulkanMemoryType & memoryType,VulkanExternalMemoryHandleType externalMemoryHandleType,const void * name)1990 VulkanDeviceMemory::VulkanDeviceMemory(
1991 const VulkanDevice &device, const VulkanImage &image,
1992 const VulkanMemoryType &memoryType,
1993 VulkanExternalMemoryHandleType externalMemoryHandleType, const void *name)
1994 : m_device(device), m_size(image.getSize()),
1995 m_isDedicated(image.isDedicated())
1996 {
1997 #if defined(_WIN32) || defined(_WIN64)
1998 WindowsSecurityAttributes winSecurityAttributes;
1999
2000 VkExportMemoryWin32HandleInfoKHR vkExportMemoryWin32HandleInfoKHR = {};
2001 vkExportMemoryWin32HandleInfoKHR.sType =
2002 VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
2003 vkExportMemoryWin32HandleInfoKHR.pNext = NULL;
2004 vkExportMemoryWin32HandleInfoKHR.pAttributes = &winSecurityAttributes;
2005 vkExportMemoryWin32HandleInfoKHR.dwAccess =
2006 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE;
2007 vkExportMemoryWin32HandleInfoKHR.name = (LPCWSTR)name;
2008
2009 #endif
2010
2011 VkExportMemoryAllocateInfoKHR vkExportMemoryAllocateInfoKHR = {};
2012 vkExportMemoryAllocateInfoKHR.sType =
2013 VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;
2014 #if defined(_WIN32) || defined(_WIN64)
2015 vkExportMemoryAllocateInfoKHR.pNext = externalMemoryHandleType
2016 & VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT
2017 ? &vkExportMemoryWin32HandleInfoKHR
2018 : NULL;
2019 #else
2020 vkExportMemoryAllocateInfoKHR.pNext = NULL;
2021 #endif
2022 vkExportMemoryAllocateInfoKHR.handleTypes =
2023 (VkExternalMemoryHandleTypeFlagsKHR)externalMemoryHandleType;
2024
2025 VkMemoryDedicatedAllocateInfo vkMemoryDedicatedAllocateInfo = {};
2026 vkMemoryDedicatedAllocateInfo.sType =
2027 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
2028 vkMemoryDedicatedAllocateInfo.pNext = NULL;
2029 vkMemoryDedicatedAllocateInfo.image = image;
2030 vkMemoryDedicatedAllocateInfo.buffer = VK_NULL_HANDLE;
2031
2032 VkMemoryAllocateInfo vkMemoryAllocateInfo = {};
2033 vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2034 vkMemoryAllocateInfo.allocationSize = m_size;
2035 vkMemoryAllocateInfo.memoryTypeIndex = (uint32_t)memoryType;
2036
2037 if (m_isDedicated)
2038 {
2039 vkMemoryAllocateInfo.pNext = &vkMemoryDedicatedAllocateInfo;
2040 vkMemoryDedicatedAllocateInfo.pNext =
2041 externalMemoryHandleType ? &vkExportMemoryAllocateInfoKHR : NULL;
2042 }
2043 else
2044 {
2045 vkMemoryAllocateInfo.pNext =
2046 externalMemoryHandleType ? &vkExportMemoryAllocateInfoKHR : NULL;
2047 }
2048
2049 vkAllocateMemory(m_device, &vkMemoryAllocateInfo, NULL, &m_vkDeviceMemory);
2050 }
2051
VulkanDeviceMemory(const VulkanDevice & device,const VulkanBuffer & buffer,const VulkanMemoryType & memoryType,VulkanExternalMemoryHandleType externalMemoryHandleType,const void * name)2052 VulkanDeviceMemory::VulkanDeviceMemory(
2053 const VulkanDevice &device, const VulkanBuffer &buffer,
2054 const VulkanMemoryType &memoryType,
2055 VulkanExternalMemoryHandleType externalMemoryHandleType, const void *name)
2056 : m_device(device), m_size(buffer.getSize()),
2057 m_isDedicated(buffer.isDedicated())
2058 {
2059 #if defined(_WIN32) || defined(_WIN64)
2060 WindowsSecurityAttributes winSecurityAttributes;
2061
2062 VkExportMemoryWin32HandleInfoKHR vkExportMemoryWin32HandleInfoKHR = {};
2063 vkExportMemoryWin32HandleInfoKHR.sType =
2064 VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
2065 vkExportMemoryWin32HandleInfoKHR.pNext = NULL;
2066 vkExportMemoryWin32HandleInfoKHR.pAttributes = &winSecurityAttributes;
2067 vkExportMemoryWin32HandleInfoKHR.dwAccess =
2068 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE;
2069 vkExportMemoryWin32HandleInfoKHR.name = (LPCWSTR)name;
2070
2071 #endif
2072
2073 VkExportMemoryAllocateInfoKHR vkExportMemoryAllocateInfoKHR = {};
2074 vkExportMemoryAllocateInfoKHR.sType =
2075 VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;
2076 #if defined(_WIN32) || defined(_WIN64)
2077 vkExportMemoryAllocateInfoKHR.pNext = externalMemoryHandleType
2078 & VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT
2079 ? &vkExportMemoryWin32HandleInfoKHR
2080 : NULL;
2081 #else
2082 vkExportMemoryAllocateInfoKHR.pNext = NULL;
2083 #endif
2084 vkExportMemoryAllocateInfoKHR.handleTypes =
2085 (VkExternalMemoryHandleTypeFlagsKHR)externalMemoryHandleType;
2086
2087 VkMemoryDedicatedAllocateInfo vkMemoryDedicatedAllocateInfo = {};
2088 vkMemoryDedicatedAllocateInfo.sType =
2089 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
2090 vkMemoryDedicatedAllocateInfo.pNext = NULL;
2091 vkMemoryDedicatedAllocateInfo.image = VK_NULL_HANDLE;
2092 vkMemoryDedicatedAllocateInfo.buffer = buffer;
2093
2094 VkMemoryAllocateInfo vkMemoryAllocateInfo = {};
2095 vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2096 vkMemoryAllocateInfo.allocationSize = m_size;
2097 vkMemoryAllocateInfo.memoryTypeIndex = (uint32_t)memoryType;
2098
2099 if (m_isDedicated)
2100 {
2101 vkMemoryAllocateInfo.pNext = &vkMemoryDedicatedAllocateInfo;
2102 vkMemoryDedicatedAllocateInfo.pNext =
2103 externalMemoryHandleType ? &vkExportMemoryAllocateInfoKHR : NULL;
2104 }
2105 else
2106 {
2107 vkMemoryAllocateInfo.pNext =
2108 externalMemoryHandleType ? &vkExportMemoryAllocateInfoKHR : NULL;
2109 }
2110
2111
2112 VkResult res = vkAllocateMemory(m_device, &vkMemoryAllocateInfo, NULL,
2113 &m_vkDeviceMemory);
2114 ASSERT_SUCCESS(res, "Failed to allocate device memory");
2115 }
2116
~VulkanDeviceMemory()2117 VulkanDeviceMemory::~VulkanDeviceMemory()
2118 {
2119 vkFreeMemory(m_device, m_vkDeviceMemory, NULL);
2120 }
2121
getSize() const2122 uint64_t VulkanDeviceMemory::getSize() const { return m_size; }
2123
2124 #ifdef _WIN32
getHandle(VulkanExternalMemoryHandleType externalMemoryHandleType) const2125 HANDLE VulkanDeviceMemory::getHandle(
2126 VulkanExternalMemoryHandleType externalMemoryHandleType) const
2127 {
2128 HANDLE handle;
2129
2130 VkMemoryGetWin32HandleInfoKHR vkMemoryGetWin32HandleInfoKHR = {};
2131 vkMemoryGetWin32HandleInfoKHR.sType =
2132 VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
2133 vkMemoryGetWin32HandleInfoKHR.pNext = NULL;
2134 vkMemoryGetWin32HandleInfoKHR.memory = m_vkDeviceMemory;
2135 vkMemoryGetWin32HandleInfoKHR.handleType =
2136 (VkExternalMemoryHandleTypeFlagBitsKHR)externalMemoryHandleType;
2137
2138 vkGetMemoryWin32HandleKHR(m_device, &vkMemoryGetWin32HandleInfoKHR,
2139 &handle);
2140
2141 return handle;
2142 }
2143 #else
getHandle(VulkanExternalMemoryHandleType externalMemoryHandleType) const2144 int VulkanDeviceMemory::getHandle(
2145 VulkanExternalMemoryHandleType externalMemoryHandleType) const
2146 {
2147 if (externalMemoryHandleType
2148 == VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD)
2149 {
2150 int fd;
2151
2152 VkMemoryGetFdInfoKHR vkMemoryGetFdInfoKHR = {};
2153 vkMemoryGetFdInfoKHR.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
2154 vkMemoryGetFdInfoKHR.pNext = NULL;
2155 vkMemoryGetFdInfoKHR.memory = m_vkDeviceMemory;
2156 vkMemoryGetFdInfoKHR.handleType =
2157 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
2158
2159 vkGetMemoryFdKHR(m_device, &vkMemoryGetFdInfoKHR, &fd);
2160
2161 return fd;
2162 }
2163 return HANDLE_ERROR;
2164 }
2165 #endif
2166
isDedicated() const2167 bool VulkanDeviceMemory::isDedicated() const { return m_isDedicated; }
2168
map(size_t offset,size_t size)2169 void *VulkanDeviceMemory::map(size_t offset, size_t size)
2170 {
2171 void *pData;
2172
2173 vkMapMemory(m_device, m_vkDeviceMemory, (VkDeviceSize)offset,
2174 (VkDeviceSize)size, 0, &pData);
2175
2176 return pData;
2177 }
2178
unmap()2179 void VulkanDeviceMemory::unmap() { vkUnmapMemory(m_device, m_vkDeviceMemory); }
2180
bindBuffer(const VulkanBuffer & buffer,uint64_t offset)2181 void VulkanDeviceMemory::bindBuffer(const VulkanBuffer &buffer, uint64_t offset)
2182 {
2183 if (buffer.isDedicated() && !m_isDedicated)
2184 {
2185 throw std::runtime_error(
2186 "Buffer requires dedicated memory. Failed to bind");
2187 }
2188 vkBindBufferMemory(m_device, buffer, m_vkDeviceMemory, offset);
2189 }
2190
bindImage(const VulkanImage & image,uint64_t offset)2191 void VulkanDeviceMemory::bindImage(const VulkanImage &image, uint64_t offset)
2192 {
2193 if (image.isDedicated() && !m_isDedicated)
2194 {
2195 throw std::runtime_error(
2196 "Image requires dedicated memory. Failed to bind");
2197 }
2198 vkBindImageMemory(m_device, image, m_vkDeviceMemory, offset);
2199 }
2200
operator VkDeviceMemory() const2201 VulkanDeviceMemory::operator VkDeviceMemory() const { return m_vkDeviceMemory; }
2202
2203 ////////////////////////////////////
2204 // VulkanSemaphore implementation //
2205 ////////////////////////////////////
2206
VulkanSemaphore(const VulkanSemaphore & semaphore)2207 VulkanSemaphore::VulkanSemaphore(const VulkanSemaphore &semaphore)
2208 : m_device(semaphore.m_device), m_vkSemaphore(semaphore.m_vkSemaphore)
2209 {}
2210
VulkanSemaphore(const VulkanDevice & device,VulkanExternalSemaphoreHandleType externalSemaphoreHandleType,const std::wstring name)2211 VulkanSemaphore::VulkanSemaphore(
2212 const VulkanDevice &device,
2213 VulkanExternalSemaphoreHandleType externalSemaphoreHandleType,
2214 const std::wstring name)
2215 : m_device(device), m_name(name)
2216 {
2217 #if defined(_WIN32) || defined(_WIN64)
2218 WindowsSecurityAttributes winSecurityAttributes;
2219
2220 VkExportSemaphoreWin32HandleInfoKHR
2221 vkExportSemaphoreWin32HandleInfoKHR = {};
2222 vkExportSemaphoreWin32HandleInfoKHR.sType =
2223 VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR;
2224 vkExportSemaphoreWin32HandleInfoKHR.pNext = NULL;
2225 vkExportSemaphoreWin32HandleInfoKHR.pAttributes = &winSecurityAttributes;
2226 vkExportSemaphoreWin32HandleInfoKHR.dwAccess =
2227 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE;
2228 vkExportSemaphoreWin32HandleInfoKHR.name =
2229 m_name.size() ? (LPCWSTR)m_name.c_str() : NULL;
2230 #endif
2231
2232 VkExportSemaphoreCreateInfoKHR vkExportSemaphoreCreateInfoKHR = {};
2233 vkExportSemaphoreCreateInfoKHR.sType =
2234 VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR;
2235 #if defined(_WIN32) || defined(_WIN64)
2236 vkExportSemaphoreCreateInfoKHR.pNext =
2237 (externalSemaphoreHandleType
2238 & VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT)
2239 ? &vkExportSemaphoreWin32HandleInfoKHR
2240 : NULL;
2241 #else
2242 vkExportSemaphoreCreateInfoKHR.pNext = NULL;
2243 #endif
2244 vkExportSemaphoreCreateInfoKHR.handleTypes =
2245 (VkExternalSemaphoreHandleTypeFlagsKHR)externalSemaphoreHandleType;
2246
2247 VkSemaphoreCreateInfo vkSemaphoreCreateInfo = {};
2248 vkSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2249 vkSemaphoreCreateInfo.pNext =
2250 (externalSemaphoreHandleType
2251 != VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NONE)
2252 ? &vkExportSemaphoreCreateInfoKHR
2253 : NULL;
2254 vkSemaphoreCreateInfo.flags = 0;
2255
2256 vkCreateSemaphore(m_device, &vkSemaphoreCreateInfo, NULL, &m_vkSemaphore);
2257 }
2258
~VulkanSemaphore()2259 VulkanSemaphore::~VulkanSemaphore()
2260 {
2261 vkDestroySemaphore(m_device, m_vkSemaphore, NULL);
2262 }
2263
2264 #if defined(_WIN32) || defined(_WIN64)
getHandle(VulkanExternalSemaphoreHandleType externalSemaphoreHandleType) const2265 HANDLE VulkanSemaphore::getHandle(
2266 VulkanExternalSemaphoreHandleType externalSemaphoreHandleType) const
2267 {
2268 HANDLE handle;
2269
2270 VkSemaphoreGetWin32HandleInfoKHR vkSemaphoreGetWin32HandleInfoKHR = {};
2271 vkSemaphoreGetWin32HandleInfoKHR.sType =
2272 VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR;
2273 vkSemaphoreGetWin32HandleInfoKHR.pNext = NULL;
2274 vkSemaphoreGetWin32HandleInfoKHR.semaphore = m_vkSemaphore;
2275 vkSemaphoreGetWin32HandleInfoKHR.handleType =
2276 (VkExternalSemaphoreHandleTypeFlagBitsKHR)externalSemaphoreHandleType;
2277
2278 vkGetSemaphoreWin32HandleKHR(m_device, &vkSemaphoreGetWin32HandleInfoKHR,
2279 &handle);
2280
2281 return handle;
2282 }
2283 #else
getHandle(VulkanExternalSemaphoreHandleType externalSemaphoreHandleType) const2284 int VulkanSemaphore::getHandle(
2285 VulkanExternalSemaphoreHandleType externalSemaphoreHandleType) const
2286 {
2287 if (externalSemaphoreHandleType
2288 == VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD)
2289 {
2290 int fd;
2291
2292 VkSemaphoreGetFdInfoKHR vkSemaphoreGetFdInfoKHR = {};
2293 vkSemaphoreGetFdInfoKHR.sType =
2294 VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR;
2295 vkSemaphoreGetFdInfoKHR.pNext = NULL;
2296 vkSemaphoreGetFdInfoKHR.semaphore = m_vkSemaphore;
2297 vkSemaphoreGetFdInfoKHR.handleType =
2298 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
2299
2300 vkGetSemaphoreFdKHR(m_device, &vkSemaphoreGetFdInfoKHR, &fd);
2301
2302 return fd;
2303 }
2304 return HANDLE_ERROR;
2305 }
2306 #endif
2307
getName() const2308 const std::wstring &VulkanSemaphore::getName() const { return m_name; }
2309
operator VkSemaphore() const2310 VulkanSemaphore::operator VkSemaphore() const { return m_vkSemaphore; }
2311