aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/VulkanDevice.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VulkanDevice.hpp')
-rw-r--r--src/VulkanDevice.hpp152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/VulkanDevice.hpp b/src/VulkanDevice.hpp
new file mode 100644
index 0000000..fa9f5f4
--- /dev/null
+++ b/src/VulkanDevice.hpp
@@ -0,0 +1,152 @@
+/*
+* Vulkan device class
+*
+* Encapsulates a physical Vulkan device and it's logical representation
+*
+* Copyright (C) 2016-2018 by Sascha Willems - www.saschawillems.de
+*
+* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+*/
+
+#pragma once
+
+#include "vke.h"
+
+//#include "VulkanBuffer.hpp"
+
+namespace vks
+{
+ struct vkPhyInfo{
+ VkPhysicalDevice phy;
+ VkPhysicalDeviceMemoryProperties memProps;
+ VkPhysicalDeviceProperties properties;
+ VkPhysicalDeviceFeatures features;
+ VkPhysicalDeviceFeatures enabledFeatures;
+ VkQueueFamilyProperties* queues;
+ uint32_t queueCount;
+ std::vector<int> cQueues;//compute, dedicated first
+ std::vector<int> gQueues;//graphic, idem
+ std::vector<int> tQueues;//transfer, idem
+ int pQueue;//presentation
+
+ std::vector<VkDeviceQueueCreateInfo> pQueueInfos;
+ std::vector<std::vector<float>> qPriorities;
+
+ vkPhyInfo (){}
+ vkPhyInfo (VkPhysicalDevice _phy, VkSurfaceKHR surface = VK_NULL_HANDLE) {
+ phy = _phy;
+// cQueues.clear();
+// gQueues.clear();
+// tQueues.clear();
+ pQueue = -1;
+// pQueueInfos.clear();
+// qPriorities.clear();
+
+ vkGetPhysicalDeviceProperties (phy, &properties);
+ vkGetPhysicalDeviceMemoryProperties (phy, &memProps);
+ vkGetPhysicalDeviceFeatures (phy, &features);
+
+ vkGetPhysicalDeviceQueueFamilyProperties (phy, &queueCount, NULL);
+ queues = (VkQueueFamilyProperties*)malloc(queueCount * sizeof(VkQueueFamilyProperties));
+ vkGetPhysicalDeviceQueueFamilyProperties (phy, &queueCount, queues);
+
+ //identify dedicated queues
+ //try to find dedicated queues first
+ VkBool32 present = VK_FALSE;
+ for (uint j=0; j<queueCount; j++){
+ switch (queues[j].queueFlags) {
+ case VK_QUEUE_GRAPHICS_BIT:
+ if (surface){
+ vkGetPhysicalDeviceSurfaceSupportKHR(phy, j, surface, &present);
+ if (present && pQueue<0)
+ pQueue = j;
+ }
+ gQueues.push_back (j);
+ break;
+ case VK_QUEUE_COMPUTE_BIT:
+ cQueues.push_back (j);
+ break;
+ case VK_QUEUE_TRANSFER_BIT:
+ tQueues.push_back (j);
+ break;
+ }
+ }
+ //add queues that include flag
+ for (uint j=0; j<queueCount; j++){
+ if (queues[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+ if (surface) {
+ vkGetPhysicalDeviceSurfaceSupportKHR(phy, j, surface, &present);
+ if (present && pQueue<0)
+ pQueue = j;
+ }
+ if (std::find(gQueues.begin(), gQueues.end(), j) == gQueues.end())
+ gQueues.push_back(j);
+ }
+ if (queues[j].queueFlags & VK_QUEUE_COMPUTE_BIT){
+ if (std::find(cQueues.begin(), cQueues.end(), j) == cQueues.end())
+ cQueues.push_back(j);
+ }
+ if (queues[j].queueFlags & VK_QUEUE_TRANSFER_BIT){
+ if (std::find(tQueues.begin(), tQueues.end(), j) == tQueues.end())
+ tQueues.push_back(j);
+ }
+ }
+ }
+
+ void selectQueue (int qIndex, float priority = 0.f) {
+ auto it = find_if(pQueueInfos.begin(), pQueueInfos.end(), [&qIndex](const VkDeviceQueueCreateInfo& qci)
+ {return qci.queueFamilyIndex == qIndex;});
+ if (it == pQueueInfos.end()) {
+ VkDeviceQueueCreateInfo dqci = {VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO};
+ dqci.queueCount = 1;
+ dqci.queueFamilyIndex = qIndex;
+ pQueueInfos.push_back (dqci);
+ qPriorities.push_back ({priority});
+ return;
+ }
+
+ int qciIdx = std::distance(pQueueInfos.begin(), it);
+ pQueueInfos[qciIdx].queueCount ++;
+ qPriorities[qciIdx].push_back(priority);
+ }
+
+ };
+ struct VulkanDevice
+ {
+ VkPhysicalDevice phy;
+ VkDevice dev;
+ VkPhysicalDeviceProperties properties;
+ VkPhysicalDeviceFeatures features;
+ VkPhysicalDeviceFeatures enabledFeatures;
+ VkPhysicalDeviceMemoryProperties memoryProperties;
+ std::vector<VkQueueFamilyProperties>queueFamilyProperties;
+
+ VkCommandPool commandPool = VK_NULL_HANDLE;
+ VkPipelineCache pipelineCache = VK_NULL_HANDLE;
+ bool savePLCache = true;
+
+ VkQueue queue;
+
+ struct {
+ uint32_t graphics;
+ uint32_t compute;
+ } queueFamilyIndices;
+
+ VulkanDevice(vkPhyInfo phyInfos, const std::vector<const char *> &devLayers);
+ ~VulkanDevice();
+
+ uint32_t getMemoryType(uint32_t typeBits, VkMemoryPropertyFlags properties, VkBool32 *memTypeFound = nullptr);
+ VkFormat getSuitableDepthFormat ();
+ uint32_t getQueueFamilyIndex(VkQueueFlagBits queueFlags);
+
+ VkCommandPool createCommandPool(uint32_t queueFamilyIndex,
+ VkCommandPoolCreateFlags createFlags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
+ VkCommandBuffer createCommandBuffer(VkCommandBufferLevel level, bool begin = false);
+
+ void flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, bool free = true);
+ VkSemaphore createSemaphore ();
+ VkFence createFence (bool signaled = false);
+ void destroyFence (VkFence fence);
+ void destroySemaphore (VkSemaphore semaphore);
+ };
+}