source: opengl-game/vulkan-utils.hpp@ 8aa4888

feature/imgui-sdl
Last change on this file since 8aa4888 was c074f81, checked in by Dmitry Portnoy <dportnoy@…>, 3 years ago

Change VulkanUtils::copyDataToMemory() to always require a size and to optionally flush the memory. Also add a VulkanUtils::copyDataToMappedMemory function that does the same thing, but assumes the data is already mapped.

  • Property mode set to 100644
File size: 10.6 KB
RevLine 
[cb01aff]1#ifndef _VULKAN_UTILS_H
2#define _VULKAN_UTILS_H
3
[90a424f]4#include <optional>
[8b823e7]5#include <sstream>
6#include <stdexcept>
[b794178]7#include <string>
[cb01aff]8#include <vector>
9
10#include <vulkan/vulkan.h>
11
[7f60b28]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
[b794178]14#include <SDL2/SDL.h>
15#include <SDL2/SDL_vulkan.h>
16
[cb01aff]17using namespace std;
18
[90a424f]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
[b794178]28struct VulkanImage {
29 VkImage image;
30 VkDeviceMemory imageMemory;
31 VkImageView imageView;
32};
33
[cb01aff]34class VulkanUtils {
35 public:
[8b823e7]36 static string resultString(VkResult result);
37
[cb01aff]38 static bool checkValidationLayerSupport(const vector<const char*> &validationLayers);
39
40 static VkResult createDebugUtilsMessengerEXT(VkInstance instance,
[e8445f0]41 const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
42 const VkAllocationCallbacks* pAllocator,
43 VkDebugUtilsMessengerEXT* pDebugMessenger);
[cb01aff]44
45 static void destroyDebugUtilsMessengerEXT(VkInstance instance,
[e8445f0]46 VkDebugUtilsMessengerEXT debugMessenger,
47 const VkAllocationCallbacks* pAllocator);
[90a424f]48
[fe5c3ba]49 static QueueFamilyIndices findQueueFamilies(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface);
[b794178]50 static bool checkDeviceExtensionSupport(VkPhysicalDevice physicalDevice,
[e8445f0]51 const vector<const char*>& deviceExtensions);
[7f60b28]52 static VkSurfaceCapabilitiesKHR querySwapChainCapabilities(VkPhysicalDevice physicalDevice,
[e8445f0]53 VkSurfaceKHR surface);
[7f60b28]54 static vector<VkSurfaceFormatKHR> querySwapChainFormats(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface);
55 static vector<VkPresentModeKHR> querySwapChainPresentModes(VkPhysicalDevice physicalDevice,
[e8445f0]56 VkSurfaceKHR surface);
[7f60b28]57 static VkSurfaceFormatKHR chooseSwapSurfaceFormat(const vector<VkSurfaceFormatKHR>& availableFormats,
[e8445f0]58 const vector<VkFormat>& requestedFormats, VkColorSpaceKHR requestedColorSpace);
[7f60b28]59 static VkPresentModeKHR chooseSwapPresentMode(const vector<VkPresentModeKHR>& availablePresentModes,
[e8445f0]60 const vector<VkPresentModeKHR>& requestedPresentModes);
[502bd0b]61 static VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, int width, int height);
[b794178]62 static VkImageView createImageView(VkDevice device, VkImage image, VkFormat format,
[e8445f0]63 VkImageAspectFlags aspectFlags);
[6fc24c7]64 static VkFormat findSupportedFormat(VkPhysicalDevice physicalDevice, const vector<VkFormat>& candidates,
[e8445f0]65 VkImageTiling tiling, VkFormatFeatureFlags features);
[b794178]66 static void createBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkDeviceSize size,
[e8445f0]67 VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer,
68 VkDeviceMemory& bufferMemory);
[b794178]69 static uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter,
[e8445f0]70 VkMemoryPropertyFlags properties);
[b794178]71
72 static void createVulkanImageFromFile(VkDevice device, VkPhysicalDevice physicalDevice,
[e8445f0]73 VkCommandPool commandPool, string filename, VulkanImage& image,
74 VkQueue graphicsQueue);
[b794178]75 static void createVulkanImageFromSDLTexture(VkDevice device, VkPhysicalDevice physicalDevice,
[e8445f0]76 SDL_Texture* texture, VulkanImage& image);
[d2d9286]77 static void populateVulkanImageFromSDLTexture(VkDevice device, VkPhysicalDevice physicalDevice,
[e8445f0]78 VkCommandPool commandPool, SDL_Texture* texture,
79 SDL_Renderer* renderer, VulkanImage& image, VkQueue graphicsQueue);
[603b5bc]80 static void createDepthImage(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool,
[e8445f0]81 VkFormat depthFormat, VkExtent2D extent, VulkanImage& image, VkQueue graphicsQueue);
[b794178]82 static void createImage(VkDevice device, VkPhysicalDevice physicalDevice, uint32_t width, uint32_t height,
[e8445f0]83 VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage,
84 VkMemoryPropertyFlags properties, VulkanImage& image);
[b794178]85
86 static void transitionImageLayout(VkDevice device, VkCommandPool commandPool, VkImage image,
[e8445f0]87 VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout,
88 VkQueue graphicsQueue);
[b794178]89 static VkCommandBuffer beginSingleTimeCommands(VkDevice device, VkCommandPool commandPool);
90 static void endSingleTimeCommands(VkDevice device, VkCommandPool commandPool,
[e8445f0]91 VkCommandBuffer commandBuffer, VkQueue graphicsQueue);
[b794178]92 static void copyBufferToImage(VkDevice device, VkCommandPool commandPool, VkBuffer buffer, VkImage image,
[e8445f0]93 uint32_t width, uint32_t height, VkQueue graphicsQueue);
[b794178]94
[e3bef3a]95 template<class DataType>
96 static void copyDataToBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool,
[e8445f0]97 const vector<DataType>& srcData, VkBuffer dstBuffer, size_t dstVertexOffset,
98 VkQueue graphicsQueue);
[e3bef3a]99
[87c8f1a]100 static void copyBuffer(VkDevice device, VkCommandPool commandPool, VkBuffer srcBuffer, VkBuffer dstBuffer,
[e8445f0]101 VkDeviceSize srcOffset, VkDeviceSize dstOffset, VkDeviceSize size,
102 VkQueue graphicsQueue);
[87c8f1a]103
[8e02b6b]104 template<class DataType>
[c074f81]105 static void copyDataToMemory(VkDevice device, DataType* srcData, VkDeviceMemory bufferMemory,
106 VkDeviceSize offset, VkDeviceSize size, bool flush);
[e8445f0]107
108 template<class DataType>
[c074f81]109 static void copyDataToMappedMemory(VkDevice device, DataType* srcData, void* mappedData,
110 VkDeviceMemory bufferMemory, VkDeviceSize size, bool flush);
[8e02b6b]111
[b794178]112 static bool hasStencilComponent(VkFormat format);
[e83b155]113
114 static void destroyVulkanImage(VkDevice& device, VulkanImage& image);
[cb01aff]115};
116
[e3bef3a]117template<class DataType>
118void VulkanUtils::copyDataToBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool,
[996dd3e]119 const vector<DataType>& srcData, VkBuffer dstBuffer, size_t dstVertexOffset,
120 VkQueue graphicsQueue) {
[e3bef3a]121 VkDeviceSize srcDataSize = srcData.size() * sizeof(DataType);
122
123 VkBuffer stagingBuffer;
124 VkDeviceMemory stagingBufferMemory;
125 createBuffer(device, physicalDevice, srcDataSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
126 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
127 stagingBuffer, stagingBufferMemory);
128
129 void* data;
130 vkMapMemory(device, stagingBufferMemory, 0, srcDataSize, 0, &data);
131 memcpy(data, srcData.data(), (size_t)srcDataSize);
132 vkUnmapMemory(device, stagingBufferMemory);
133
134 copyBuffer(device, commandPool, stagingBuffer, dstBuffer, 0, dstVertexOffset * sizeof(DataType), srcDataSize,
135 graphicsQueue);
136
137 vkDestroyBuffer(device, stagingBuffer, nullptr);
138 vkFreeMemory(device, stagingBufferMemory, nullptr);
139}
140
[8e02b6b]141template<class DataType>
[c074f81]142void VulkanUtils::copyDataToMemory(VkDevice device, DataType* srcData, VkDeviceMemory bufferMemory,
143 VkDeviceSize offset, VkDeviceSize size, bool flush) {
[8e02b6b]144 void* data;
[5a1ace0]145
[e8445f0]146 vkMapMemory(device, bufferMemory, offset, size, 0, &data);
[c074f81]147
148 memcpy(data, srcData, size);
149
150 if (flush) {
151 VkMappedMemoryRange memoryRange{};
152 memoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
153 memoryRange.memory = bufferMemory;
154 memoryRange.size = size;
155
156 vkFlushMappedMemoryRanges(device, 1, &memoryRange);
157 }
158
[8e02b6b]159 vkUnmapMemory(device, bufferMemory);
160}
161
[c074f81]162template<class DataType>
163void VulkanUtils::copyDataToMappedMemory(VkDevice device, DataType* srcData, void* mappedData,
164 VkDeviceMemory bufferMemory, VkDeviceSize size, bool flush) {
165 memcpy(mappedData, srcData, size);
166
167 if (flush) {
168 VkMappedMemoryRange memoryRange{};
169 memoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
170 memoryRange.memory = bufferMemory;
171 memoryRange.size = size;
172
173 vkFlushMappedMemoryRanges(device, 1, &memoryRange);
174 }
175}
176
[e8445f0]177// TODO: Use this in vulkan-utils itself as well
[8b823e7]178#define VKUTIL_CHECK_RESULT(f, msg) { \
179 VkResult res = (f); \
180 \
181 if (res != VK_SUCCESS) { \
182 ostringstream oss; \
183 oss << msg << " VkResult is \"" << VulkanUtils::resultString(res) << "\" in " << __FILE__ << " at line " << __LINE__;\
184 \
185 if (res < 0) { \
186 throw runtime_error("Fatal: " + oss.str()); \
187 } else { \
188 cerr << oss.str(); \
189 } \
190 } \
191}
192
[cb01aff]193#endif // _VULKAN_UTILS_H
Note: See TracBrowser for help on using the repository browser.