aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/VulkanDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VulkanDevice.cpp')
-rw-r--r--src/VulkanDevice.cpp361
1 files changed, 196 insertions, 165 deletions
diff --git a/src/VulkanDevice.cpp b/src/VulkanDevice.cpp
index 3b47253..16d5aae 100644
--- a/src/VulkanDevice.cpp
+++ b/src/VulkanDevice.cpp
@@ -1,214 +1,245 @@
#include "VulkanDevice.hpp"
+#include "macros.h"
+namespace vke {
-vks::VulkanDevice::VulkanDevice(vkPhyInfo phyInfos, const std::vector<const char*>& devLayers)
-{
- phy = phyInfos.phy;
+ device_t::device_t(vkPhyInfo *phyInfos, const std::vector<const char*>& devLayers)
+ {
+ phy = phyInfos->phy;
- properties = phyInfos.properties;
- memoryProperties = phyInfos.memProps;
- features = phyInfos.features;
+ properties = phyInfos->properties;
+ memoryProperties = phyInfos->memProps;
+ features = phyInfos->features;
- //affect priorities to qcis from vector
- for (uint i=0; i<phyInfos.pQueueInfos.size(); i++)
- phyInfos.pQueueInfos[i].pQueuePriorities = phyInfos.qPriorities[i].data();
+ //affect priorities to qcis from vector
+ for (uint i=0; i<phyInfos->pQueueInfos.size(); i++)
+ phyInfos->pQueueInfos[i].pQueuePriorities = phyInfos->qPriorities[i].data();
- std::vector<const char*> devExtentions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
+ std::vector<const char*> devExtentions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
- VkDeviceCreateInfo devInfo = {VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO};
- devInfo.queueCreateInfoCount = (uint32_t)phyInfos.pQueueInfos.size();
- devInfo.pQueueCreateInfos = phyInfos.pQueueInfos.data();
- devInfo.enabledExtensionCount = (uint32_t)devExtentions.size();
- devInfo.ppEnabledExtensionNames = devExtentions.data();
- devInfo.enabledLayerCount = (uint32_t)devLayers.size();
- devInfo.ppEnabledLayerNames = devLayers.data();
- devInfo.pEnabledFeatures = &enabledFeatures;
+ VkDeviceCreateInfo devInfo = {VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO};
+ devInfo.queueCreateInfoCount = (uint32_t)phyInfos->pQueueInfos.size();
+ devInfo.pQueueCreateInfos = phyInfos->pQueueInfos.data();
+ devInfo.enabledExtensionCount = (uint32_t)devExtentions.size();
+ devInfo.ppEnabledExtensionNames = devExtentions.data();
+ devInfo.enabledLayerCount = (uint32_t)devLayers.size();
+ devInfo.ppEnabledLayerNames = devLayers.data();
+ devInfo.pEnabledFeatures = &enabledFeatures;
- VK_CHECK_RESULT(vkCreateDevice (phyInfos.phy, &devInfo, nullptr, &dev));
+ VK_CHECK_RESULT(vkCreateDevice (phy, &devInfo, nullptr, &dev));
- commandPool = createCommandPool (phyInfos.gQueues[0]);
+ commandPool = createCommandPool (phyInfos->gQueues[0]);
- vkGetDeviceQueue(dev, phyInfos.gQueues[0], 0, &queue);
+ vkGetDeviceQueue(dev, phyInfos->gQueues[0], 0, &queue);
- //reload pipeline cache if it exists
- std::ifstream is ("pipeline.cache", std::ifstream::binary);
- char* buffer = nullptr;
- int length = 0;
- VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO};
- if (is) {
- is.seekg (0, is.end);
- length = is.tellg();
- if (length > 0) {
- is.seekg (0, is.beg);
- buffer = new char [length];
- is.read (buffer,length);
+ //reload pipeline cache if it exists
+ std::ifstream is ("pipeline.cache", std::ifstream::binary);
+ char* buffer = nullptr;
+ int length = 0;
+ VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO};
+ if (is) {
+ is.seekg (0, is.end);
+ length = is.tellg();
+ if (length > 0) {
+ is.seekg (0, is.beg);
+ buffer = new char [length];
+ is.read (buffer,length);
+ }
+ is.close();
+ pipelineCacheCreateInfo.initialDataSize = length;
+ pipelineCacheCreateInfo.pInitialData = buffer;
}
- is.close();
- pipelineCacheCreateInfo.initialDataSize = length;
- pipelineCacheCreateInfo.pInitialData = buffer;
- }
- VK_CHECK_RESULT(vkCreatePipelineCache (dev, &pipelineCacheCreateInfo, nullptr, &pipelineCache));
- delete[] buffer;
-}
+ VK_CHECK_RESULT(vkCreatePipelineCache (dev, &pipelineCacheCreateInfo, nullptr, &pipelineCache));
+ delete[] buffer;
+ }
-vks::VulkanDevice::~VulkanDevice()
-{
- if (pipelineCache){
- if (savePLCache){
- std::ofstream os("pipeline.cache", std::ofstream::binary);
- size_t plCacheSize = 0;
- char* plCache = nullptr;
- VK_CHECK_RESULT(vkGetPipelineCacheData(dev, pipelineCache, &plCacheSize, nullptr));
- plCache = new char [plCacheSize];
- VK_CHECK_RESULT(vkGetPipelineCacheData(dev, pipelineCache, &plCacheSize, plCache));
- os.write (plCache, plCacheSize);
- os.close();
- delete[] plCache;
+ vke::device_t::~device_t()
+ {
+ if (pipelineCache){
+ if (savePLCache){
+ std::ofstream os("pipeline.cache", std::ofstream::binary);
+ size_t plCacheSize = 0;
+ char* plCache = nullptr;
+ VK_CHECK_RESULT(vkGetPipelineCacheData(dev, pipelineCache, &plCacheSize, nullptr));
+ plCache = new char [plCacheSize];
+ VK_CHECK_RESULT(vkGetPipelineCacheData(dev, pipelineCache, &plCacheSize, plCache));
+ os.write (plCache, plCacheSize);
+ os.close();
+ delete[] plCache;
+ }
+ vkDestroyPipelineCache(dev, pipelineCache, nullptr);
}
- vkDestroyPipelineCache(dev, pipelineCache, nullptr);
+ if (commandPool)
+ vkDestroyCommandPool(dev, commandPool, nullptr);
+ if (dev)
+ vkDestroyDevice(dev, nullptr);
}
- if (commandPool)
- vkDestroyCommandPool(dev, commandPool, nullptr);
- if (dev)
- vkDestroyDevice(dev, nullptr);
-}
-uint32_t vks::VulkanDevice::getMemoryType(uint32_t typeBits, VkMemoryPropertyFlags properties, VkBool32 *memTypeFound)
-{
- for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) {
- if ((typeBits & 1) == 1) {
- if ((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties) {
- if (memTypeFound) {
- *memTypeFound = true;
+ uint32_t vke::device_t::getMemoryType(uint32_t typeBits, VkMemoryPropertyFlags properties, VkBool32 *memTypeFound)
+ {
+ for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) {
+ if ((typeBits & 1) == 1) {
+ if ((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties) {
+ if (memTypeFound) {
+ *memTypeFound = true;
+ }
+ return i;
}
- return i;
}
+ typeBits >>= 1;
}
- typeBits >>= 1;
- }
- if (memTypeFound) {
- *memTypeFound = false;
- return 0;
- } else {
- throw std::runtime_error("Could not find a matching memory type");
+ if (memTypeFound) {
+ *memTypeFound = false;
+ return 0;
+ } else {
+ throw std::runtime_error("Could not find a matching memory type");
+ }
}
-}
-VkFormat vks::VulkanDevice::getSuitableDepthFormat () {
- std::vector<VkFormat> depthFormats = { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM };
- for (auto& format : depthFormats) {
- VkFormatProperties formatProps;
- vkGetPhysicalDeviceFormatProperties(phy, format, &formatProps);
- if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
- return format;
+ VkFormat vke::device_t::getSuitableDepthFormat () {
+ std::vector<VkFormat> depthFormats = { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM };
+ for (auto& format : depthFormats) {
+ VkFormatProperties formatProps;
+ vkGetPhysicalDeviceFormatProperties(phy, format, &formatProps);
+ if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
+ return format;
+ }
+ std::cerr << "No suitable depth format found" << std::endl;
+ exit(-1);
}
- std::cerr << "No suitable depth format found" << std::endl;
- exit(-1);
-}
-uint32_t vks::VulkanDevice::getQueueFamilyIndex(VkQueueFlagBits queueFlags)
-{
- // Dedicated queue for compute
- // Try to find a queue family index that supports compute but not graphics
- if (queueFlags & VK_QUEUE_COMPUTE_BIT)
+ uint32_t vke::device_t::getQueueFamilyIndex(VkQueueFlagBits queueFlags)
{
+ // Dedicated queue for compute
+ // Try to find a queue family index that supports compute but not graphics
+ if (queueFlags & VK_QUEUE_COMPUTE_BIT)
+ {
+ for (uint32_t i = 0; i < static_cast<uint32_t>(queueFamilyProperties.size()); i++) {
+ if ((queueFamilyProperties[i].queueFlags & queueFlags) && ((queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)) {
+ return i;
+ break;
+ }
+ }
+ }
+
+ // For other queue types or if no separate compute queue is present, return the first one to support the requested flags
for (uint32_t i = 0; i < static_cast<uint32_t>(queueFamilyProperties.size()); i++) {
- if ((queueFamilyProperties[i].queueFlags & queueFlags) && ((queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)) {
+ if (queueFamilyProperties[i].queueFlags & queueFlags) {
return i;
break;
}
}
- }
- // For other queue types or if no separate compute queue is present, return the first one to support the requested flags
- for (uint32_t i = 0; i < static_cast<uint32_t>(queueFamilyProperties.size()); i++) {
- if (queueFamilyProperties[i].queueFlags & queueFlags) {
- return i;
- break;
- }
+ throw std::runtime_error("Could not find a matching queue family index");
}
- throw std::runtime_error("Could not find a matching queue family index");
-}
+ VkCommandPool vke::device_t::createCommandPool(uint32_t queueFamilyIndex, VkCommandPoolCreateFlags createFlags)
+ {
+ VkCommandPoolCreateInfo cmdPoolInfo = {};
+ cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ cmdPoolInfo.queueFamilyIndex = queueFamilyIndex;
+ cmdPoolInfo.flags = createFlags;
+ VkCommandPool cmdPool;
+ VK_CHECK_RESULT(vkCreateCommandPool(dev, &cmdPoolInfo, nullptr, &cmdPool));
+ return cmdPool;
+ }
-VkCommandPool vks::VulkanDevice::createCommandPool(uint32_t queueFamilyIndex, VkCommandPoolCreateFlags createFlags)
-{
- VkCommandPoolCreateInfo cmdPoolInfo = {};
- cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
- cmdPoolInfo.queueFamilyIndex = queueFamilyIndex;
- cmdPoolInfo.flags = createFlags;
- VkCommandPool cmdPool;
- VK_CHECK_RESULT(vkCreateCommandPool(dev, &cmdPoolInfo, nullptr, &cmdPool));
- return cmdPool;
-}
+ VkCommandBuffer vke::device_t::createCommandBuffer(VkCommandBufferLevel level, bool begin)
+ {
+ VkCommandBufferAllocateInfo cmdBufAllocateInfo{};
+ cmdBufAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ cmdBufAllocateInfo.commandPool = commandPool;
+ cmdBufAllocateInfo.level = level;
+ cmdBufAllocateInfo.commandBufferCount = 1;
-VkCommandBuffer vks::VulkanDevice::createCommandBuffer(VkCommandBufferLevel level, bool begin)
-{
- VkCommandBufferAllocateInfo cmdBufAllocateInfo{};
- cmdBufAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
- cmdBufAllocateInfo.commandPool = commandPool;
- cmdBufAllocateInfo.level = level;
- cmdBufAllocateInfo.commandBufferCount = 1;
+ VkCommandBuffer cmdBuffer;
+ VK_CHECK_RESULT(vkAllocateCommandBuffers(dev, &cmdBufAllocateInfo, &cmdBuffer));
- VkCommandBuffer cmdBuffer;
- VK_CHECK_RESULT(vkAllocateCommandBuffers(dev, &cmdBufAllocateInfo, &cmdBuffer));
+ // If requested, also start recording for the new command buffer
+ if (begin) {
+ VkCommandBufferBeginInfo cmdBufInfo{};
+ cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ VK_CHECK_RESULT(vkBeginCommandBuffer(cmdBuffer, &cmdBufInfo));
+ }
- // If requested, also start recording for the new command buffer
- if (begin) {
- VkCommandBufferBeginInfo cmdBufInfo{};
- cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- VK_CHECK_RESULT(vkBeginCommandBuffer(cmdBuffer, &cmdBufInfo));
+ return cmdBuffer;
}
- return cmdBuffer;
-}
+ void vke::device_t::flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, bool free)
+ {
+ VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer));
-void vks::VulkanDevice::flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, bool free)
-{
- VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer));
+ VkSubmitInfo submitInfo{};
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.commandBufferCount = 1;
+ submitInfo.pCommandBuffers = &commandBuffer;
- VkSubmitInfo submitInfo{};
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &commandBuffer;
+ // Create fence to ensure that the command buffer has finished executing
+ VkFenceCreateInfo fenceInfo{};
+ fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+ VkFence fence;
+ VK_CHECK_RESULT(vkCreateFence(dev, &fenceInfo, nullptr, &fence));
- // Create fence to ensure that the command buffer has finished executing
- VkFenceCreateInfo fenceInfo{};
- fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
- VkFence fence;
- VK_CHECK_RESULT(vkCreateFence(dev, &fenceInfo, nullptr, &fence));
+ // Submit to the queue
+ VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence));
+ // Wait for the fence to signal that command buffer has finished executing
+ VK_CHECK_RESULT(vkWaitForFences(dev, 1, &fence, VK_TRUE, 100000000000));
- // Submit to the queue
- VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence));
- // Wait for the fence to signal that command buffer has finished executing
- VK_CHECK_RESULT(vkWaitForFences(dev, 1, &fence, VK_TRUE, 100000000000));
+ vkDestroyFence(dev, fence, nullptr);
- vkDestroyFence(dev, fence, nullptr);
+ if (free) {
+ vkFreeCommandBuffers(dev, commandPool, 1, &commandBuffer);
+ }
+ }
+ VkSemaphore vke::device_t::createSemaphore ()
+ {
+ VkSemaphore sema = VK_NULL_HANDLE;
+ VkSemaphoreCreateInfo semaphoreCreateInfo {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
+ VK_CHECK_RESULT(vkCreateSemaphore (dev, &semaphoreCreateInfo, nullptr, &sema));
+ return sema;
+ }
+ VkFence vke::device_t::createFence (bool signaled) {
+ VkFence fence = VK_NULL_HANDLE;
+ VkFenceCreateInfo fenceCreateInfo {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, VK_NULL_HANDLE,
+ signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0};
+ VK_CHECK_RESULT(vkCreateFence (dev, &fenceCreateInfo, nullptr, &fence));
+ return fence;
+ }
+ void device_t::destroyFence (VkFence fence) {
+ vkDestroyFence (dev, fence, VK_NULL_HANDLE);
+ }
+ void device_t::destroySemaphore (VkSemaphore semaphore) {
+ vkDestroySemaphore (dev, semaphore, VK_NULL_HANDLE);
+ }
+ VkPipelineShaderStageCreateInfo device_t::loadShader(std::string filename, VkShaderStageFlagBits stage)
+ {
+ VkPipelineShaderStageCreateInfo shaderStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
+ shaderStage.stage = stage;
+ shaderStage.pName = "main";
+ std::ifstream is("shaders/" + filename, std::ios::binary | std::ios::in | std::ios::ate);
- if (free) {
- vkFreeCommandBuffers(dev, commandPool, 1, &commandBuffer);
+ if (is.is_open()) {
+ size_t size = is.tellg();
+ is.seekg(0, std::ios::beg);
+ char* shaderCode = new char[size];
+ is.read(shaderCode, size);
+ is.close();
+ assert(size > 0);
+ VkShaderModuleCreateInfo moduleCreateInfo{};
+ moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+ moduleCreateInfo.codeSize = size;
+ moduleCreateInfo.pCode = (uint32_t*)shaderCode;
+ vkCreateShaderModule(dev, &moduleCreateInfo, NULL, &shaderStage.module);
+ delete[] shaderCode;
+ }
+ else {
+ std::cerr << "Error: Could not open shader file \"" << filename << "\"" << std::endl;
+ shaderStage.module = VK_NULL_HANDLE;
+ }
+ assert(shaderStage.module != VK_NULL_HANDLE);
+ return shaderStage;
}
}
-VkSemaphore vks::VulkanDevice::createSemaphore ()
-{
- VkSemaphore sema = VK_NULL_HANDLE;
- VkSemaphoreCreateInfo semaphoreCreateInfo {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
- VK_CHECK_RESULT(vkCreateSemaphore (dev, &semaphoreCreateInfo, nullptr, &sema));
- return sema;
-}
-VkFence vks::VulkanDevice::createFence (bool signaled) {
- VkFence fence = VK_NULL_HANDLE;
- VkFenceCreateInfo fenceCreateInfo {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, VK_NULL_HANDLE,
- signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0};
- VK_CHECK_RESULT(vkCreateFence (dev, &fenceCreateInfo, nullptr, &fence));
- return fence;
-}
-void vks::VulkanDevice::destroyFence (VkFence fence) {
- vkDestroyFence (dev, fence, VK_NULL_HANDLE);
-}
-void vks::VulkanDevice::destroySemaphore (VkSemaphore semaphore) {
- vkDestroySemaphore (dev, semaphore, VK_NULL_HANDLE);
-}