source: opengl-game/vulkan-utils.hpp@ 5081b9a

feature/imgui-sdl
Last change on this file since 5081b9a was 8b823e7, checked in by Dmitry Portnoy <dportnoy@…>, 4 years ago

Create an error-checking macro to check Vulkan function results, which will print a custom message, the error code, and the line number for all results besides VK_SUCCESS, and update the imgui error-checking callback with similar functionality.

  • Property mode set to 100644
File size: 8.4 KB
Line 
1#ifndef _VULKAN_UTILS_H
2#define _VULKAN_UTILS_H
3
4#include <optional>
5#include <sstream>
6#include <stdexcept>
7#include <string>
8#include <vector>
9
10#include <vulkan/vulkan.h>
11
12// TODO: Ideally, vulkan-utils should not have things speciic to windowing apis (glfw, sdl, sfml, etc.).
13// Check what these inclydes are for and if that functionality can be moved
14#include <SDL2/SDL.h>
15#include <SDL2/SDL_vulkan.h>
16
17using namespace std;
18
19struct QueueFamilyIndices {
20 optional<uint32_t> graphicsFamily;
21 optional<uint32_t> presentFamily;
22
23 bool isComplete() {
24 return graphicsFamily.has_value() && presentFamily.has_value();
25 }
26};
27
28struct VulkanImage {
29 VkImage image;
30 VkDeviceMemory imageMemory;
31 VkImageView imageView;
32};
33
34class VulkanUtils {
35 public:
36 static string resultString(VkResult result);
37
38 static bool checkValidationLayerSupport(const vector<const char*> &validationLayers);
39
40 static VkResult createDebugUtilsMessengerEXT(VkInstance instance,
41 const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
42 const VkAllocationCallbacks* pAllocator,
43 VkDebugUtilsMessengerEXT* pDebugMessenger);
44
45 static void destroyDebugUtilsMessengerEXT(VkInstance instance,
46 VkDebugUtilsMessengerEXT debugMessenger,
47 const VkAllocationCallbacks* pAllocator);
48
49 static QueueFamilyIndices findQueueFamilies(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface);
50 static bool checkDeviceExtensionSupport(VkPhysicalDevice physicalDevice,
51 const vector<const char*>& deviceExtensions);
52 static VkSurfaceCapabilitiesKHR querySwapChainCapabilities(VkPhysicalDevice physicalDevice,
53 VkSurfaceKHR surface);
54 static vector<VkSurfaceFormatKHR> querySwapChainFormats(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface);
55 static vector<VkPresentModeKHR> querySwapChainPresentModes(VkPhysicalDevice physicalDevice,
56 VkSurfaceKHR surface);
57 static VkSurfaceFormatKHR chooseSwapSurfaceFormat(const vector<VkSurfaceFormatKHR>& availableFormats,
58 const vector<VkFormat>& requestedFormats, VkColorSpaceKHR requestedColorSpace);
59 static VkPresentModeKHR chooseSwapPresentMode(const vector<VkPresentModeKHR>& availablePresentModes,
60 const vector<VkPresentModeKHR>& requestedPresentModes);
61 static VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, int width, int height);
62 static VkImageView createImageView(VkDevice device, VkImage image, VkFormat format,
63 VkImageAspectFlags aspectFlags);
64 static VkFormat findSupportedFormat(VkPhysicalDevice physicalDevice, const vector<VkFormat>& candidates,
65 VkImageTiling tiling, VkFormatFeatureFlags features);
66 static void createBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkDeviceSize size,
67 VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer,
68 VkDeviceMemory& bufferMemory);
69 static uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter,
70 VkMemoryPropertyFlags properties);
71
72 static void createVulkanImageFromFile(VkDevice device, VkPhysicalDevice physicalDevice,
73 VkCommandPool commandPool, string filename, VulkanImage& image, VkQueue graphicsQueue);
74 static void createVulkanImageFromSDLTexture(VkDevice device, VkPhysicalDevice physicalDevice,
75 SDL_Texture* texture, VulkanImage& image);
76 static void populateVulkanImageFromSDLTexture(VkDevice device, VkPhysicalDevice physicalDevice,
77 VkCommandPool commandPool, SDL_Texture* texture, SDL_Renderer* renderer, VulkanImage& image,
78 VkQueue graphicsQueue);
79 static void createDepthImage(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool,
80 VkFormat depthFormat, VkExtent2D extent, VulkanImage& image, VkQueue graphicsQueue);
81 static void createImage(VkDevice device, VkPhysicalDevice physicalDevice, uint32_t width, uint32_t height,
82 VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties,
83 VulkanImage& image);
84
85 static void transitionImageLayout(VkDevice device, VkCommandPool commandPool, VkImage image,
86 VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, VkQueue graphicsQueue);
87 static VkCommandBuffer beginSingleTimeCommands(VkDevice device, VkCommandPool commandPool);
88 static void endSingleTimeCommands(VkDevice device, VkCommandPool commandPool,
89 VkCommandBuffer commandBuffer, VkQueue graphicsQueue);
90 static void copyBufferToImage(VkDevice device, VkCommandPool commandPool, VkBuffer buffer, VkImage image,
91 uint32_t width, uint32_t height, VkQueue graphicsQueue);
92
93 template<class DataType>
94 static void copyDataToBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool,
95 const vector<DataType>& srcData, VkBuffer dstBuffer, size_t dstVertexOffset, VkQueue graphicsQueue);
96
97 static void copyBuffer(VkDevice device, VkCommandPool commandPool, VkBuffer srcBuffer, VkBuffer dstBuffer,
98 VkDeviceSize srcOffset, VkDeviceSize dstOffset, VkDeviceSize size, VkQueue graphicsQueue);
99
100 template<class DataType>
101 static void copyDataToMemory(VkDevice device, VkDeviceMemory bufferMemory, VkDeviceSize offset,
102 const DataType& srcData);
103
104 static bool hasStencilComponent(VkFormat format);
105
106 static void destroyVulkanImage(VkDevice& device, VulkanImage& image);
107};
108
109template<class DataType>
110void VulkanUtils::copyDataToBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool,
111 const vector<DataType>& srcData, VkBuffer dstBuffer, size_t dstVertexOffset, VkQueue graphicsQueue) {
112 VkDeviceSize srcDataSize = srcData.size() * sizeof(DataType);
113
114 VkBuffer stagingBuffer;
115 VkDeviceMemory stagingBufferMemory;
116 createBuffer(device, physicalDevice, srcDataSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
117 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
118 stagingBuffer, stagingBufferMemory);
119
120 void* data;
121 vkMapMemory(device, stagingBufferMemory, 0, srcDataSize, 0, &data);
122 memcpy(data, srcData.data(), (size_t)srcDataSize);
123 vkUnmapMemory(device, stagingBufferMemory);
124
125 copyBuffer(device, commandPool, stagingBuffer, dstBuffer, 0, dstVertexOffset * sizeof(DataType), srcDataSize,
126 graphicsQueue);
127
128 vkDestroyBuffer(device, stagingBuffer, nullptr);
129 vkFreeMemory(device, stagingBufferMemory, nullptr);
130}
131
132template<class DataType>
133void VulkanUtils::copyDataToMemory(VkDevice device, VkDeviceMemory bufferMemory, VkDeviceSize offset,
134 const DataType& srcData) {
135 void* data;
136
137 vkMapMemory(device, bufferMemory, offset * sizeof(DataType), sizeof(DataType), 0, &data);
138 memcpy(data, &srcData, sizeof(DataType));
139 vkUnmapMemory(device, bufferMemory);
140}
141
142#define VKUTIL_CHECK_RESULT(f, msg) { \
143 VkResult res = (f); \
144 \
145 if (res != VK_SUCCESS) { \
146 ostringstream oss; \
147 oss << msg << " VkResult is \"" << VulkanUtils::resultString(res) << "\" in " << __FILE__ << " at line " << __LINE__;\
148 \
149 if (res < 0) { \
150 throw runtime_error("Fatal: " + oss.str()); \
151 } else { \
152 cerr << oss.str(); \
153 } \
154 } \
155}
156
157#endif // _VULKAN_UTILS_H
Note: See TracBrowser for help on using the repository browser.