Remove VDeleter garbage, and add working release target build config
This commit is contained in:
parent
7c2ba102a3
commit
868c4a0975
3 changed files with 114 additions and 95 deletions
|
@ -61,8 +61,12 @@
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<IncludePath>D:\Code\GLFW3\include;C:\VulkanSDK\1.0.46.0\Include;$(IncludePath)</IncludePath>
|
<IncludePath>D:\Code\GLFW3\include;C:\VulkanSDK\1.1.70.1\Include;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>C:\VulkanSDK\1.0.46.0\Lib;D:\Code\GLFW3\win64\lib-vc2015;$(LibraryPath)</LibraryPath>
|
<LibraryPath>C:\VulkanSDK\1.1.70.1\Lib;D:\Code\GLFW3\win64\lib-vc2015;$(LibraryPath)</LibraryPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<IncludePath>D:\Code\GLFW3\include;C:\VulkanSDK\1.1.70.1\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
||||||
|
<LibraryPath>C:\VulkanSDK\1.1.70.1\Lib;D:\Code\GLFW3\win64\lib-vc2015;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
|
142
main.cpp
142
main.cpp
|
@ -61,26 +61,26 @@ public:
|
||||||
private:
|
private:
|
||||||
// Instance variables:
|
// Instance variables:
|
||||||
GLFWwindow* window;
|
GLFWwindow* window;
|
||||||
VDeleter<VkInstance> instance {vkDestroyInstance};
|
VkInstance instance;
|
||||||
VDeleter<VkDebugReportCallbackEXT> callback {instance, DestroyDebugReportCallbackEXT};
|
VkDebugReportCallbackEXT callback;
|
||||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||||
VkQueue graphicsQueue;
|
VkQueue graphicsQueue;
|
||||||
VDeleter<VkDevice> device {vkDestroyDevice};
|
VkDevice device;
|
||||||
VDeleter<VkSurfaceKHR> surface {instance, vkDestroySurfaceKHR};
|
VkSurfaceKHR surface;
|
||||||
VkQueue presentQueue;
|
VkQueue presentQueue;
|
||||||
VDeleter<VkSwapchainKHR> swapChain {device, vkDestroySwapchainKHR};
|
VkSwapchainKHR swapChain;
|
||||||
std::vector<VkImage> swapChainImages;
|
std::vector<VkImage> swapChainImages;
|
||||||
VkFormat swapChainImageFormat;
|
VkFormat swapChainImageFormat;
|
||||||
VkExtent2D swapChainExtent;
|
VkExtent2D swapChainExtent;
|
||||||
std::vector<VDeleter<VkImageView>> swapChainImageViews;
|
std::vector<VkImageView> swapChainImageViews;
|
||||||
VDeleter<VkRenderPass> renderPass {device, vkDestroyRenderPass};
|
VkRenderPass renderPass;
|
||||||
VDeleter<VkPipelineLayout> pipelineLayout {device, vkDestroyPipelineLayout};
|
VkPipelineLayout pipelineLayout;
|
||||||
VDeleter<VkPipeline> graphicsPipeline {device, vkDestroyPipeline};
|
VkPipeline graphicsPipeline;
|
||||||
std::vector<VDeleter<VkFramebuffer>> swapChainFramebuffers;
|
std::vector<VkFramebuffer> swapChainFramebuffers;
|
||||||
VDeleter<VkCommandPool> commandPool {device, vkDestroyCommandPool};
|
VkCommandPool commandPool;
|
||||||
std::vector<VkCommandBuffer> commandBuffers;
|
std::vector<VkCommandBuffer> commandBuffers;
|
||||||
VDeleter<VkSemaphore> imageAvailableSemaphore {device, vkDestroySemaphore};
|
VkSemaphore imageAvailableSemaphore;
|
||||||
VDeleter<VkSemaphore> renderFinishedSemaphore {device, vkDestroySemaphore};
|
VkSemaphore renderFinishedSemaphore;
|
||||||
|
|
||||||
|
|
||||||
// Initialize our GLFW window.
|
// Initialize our GLFW window.
|
||||||
|
@ -175,7 +175,7 @@ private:
|
||||||
createInfo.enabledExtensionCount = reqExtensions.size();
|
createInfo.enabledExtensionCount = reqExtensions.size();
|
||||||
createInfo.ppEnabledExtensionNames = reqExtensions.data();
|
createInfo.ppEnabledExtensionNames = reqExtensions.data();
|
||||||
|
|
||||||
if(vkCreateInstance(&createInfo, nullptr, instance.replace()) != VK_SUCCESS) {
|
if(vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create Vulkan instance!");
|
throw std::runtime_error("failed to create Vulkan instance!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +192,10 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyInstance() {
|
||||||
|
vkDestroyInstance(instance, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the validation layers are supported.s
|
// Check if the validation layers are supported.s
|
||||||
bool checkValidationLayerSupport() {
|
bool checkValidationLayerSupport() {
|
||||||
uint32_t layerCount;
|
uint32_t layerCount;
|
||||||
|
@ -227,11 +231,17 @@ private:
|
||||||
createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
|
createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
|
||||||
createInfo.pfnCallback = debugCallback;
|
createInfo.pfnCallback = debugCallback;
|
||||||
|
|
||||||
if(CreateDebugReportCallbackEXT(instance, &createInfo, nullptr, callback.replace()) != VK_SUCCESS) {
|
if(CreateDebugReportCallbackEXT(instance, &createInfo, nullptr, &callback) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to setup debug callback!");
|
throw std::runtime_error("failed to setup debug callback!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cleanupDebugCallback() {
|
||||||
|
if (!enableValidationLayers) return;
|
||||||
|
|
||||||
|
DestroyDebugReportCallbackEXT(instance, callback, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
// Pick the first suitable physical device, using isDeviceSuitable(VkPhysicalDevice)
|
// Pick the first suitable physical device, using isDeviceSuitable(VkPhysicalDevice)
|
||||||
void pickPhysicalDevice() {
|
void pickPhysicalDevice() {
|
||||||
uint32_t deviceCount = 0;
|
uint32_t deviceCount = 0;
|
||||||
|
@ -368,7 +378,7 @@ private:
|
||||||
createInfo.enabledLayerCount = 0;
|
createInfo.enabledLayerCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vkCreateDevice(physicalDevice, &createInfo, nullptr, device.replace()) != VK_SUCCESS) {
|
if(vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create logical device!");
|
throw std::runtime_error("failed to create logical device!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,14 +386,22 @@ private:
|
||||||
vkGetDeviceQueue(device, indices.presentFamily, 0, &presentQueue);
|
vkGetDeviceQueue(device, indices.presentFamily, 0, &presentQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyLogicalDevice() {
|
||||||
|
vkDestroyDevice(device, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
// Have GLFW create a surface for us, this lets us not be concerned with the platform-specifics
|
// Have GLFW create a surface for us, this lets us not be concerned with the platform-specifics
|
||||||
// involved in surfaces.
|
// involved in surfaces.
|
||||||
void createSurface() {
|
void createSurface() {
|
||||||
if(glfwCreateWindowSurface(instance, window, nullptr, surface.replace()) != VK_SUCCESS) {
|
if(glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create window surface!");
|
throw std::runtime_error("failed to create window surface!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroySurface() {
|
||||||
|
vkDestroySurfaceKHR(instance, surface, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
// Find out what formats and present modes the physical device supports.
|
// Find out what formats and present modes the physical device supports.
|
||||||
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device) {
|
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device) {
|
||||||
SwapChainSupportDetails details;
|
SwapChainSupportDetails details;
|
||||||
|
@ -457,7 +475,7 @@ private:
|
||||||
|
|
||||||
// Create the swap chain that will be used to submit completed frames to
|
// Create the swap chain that will be used to submit completed frames to
|
||||||
void createSwapChain() {
|
void createSwapChain() {
|
||||||
SwapChainSupportDetails swapChainSupport= querySwapChainSupport(physicalDevice);
|
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);
|
||||||
|
|
||||||
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
|
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
|
||||||
VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes);
|
VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes);
|
||||||
|
@ -532,8 +550,12 @@ private:
|
||||||
swapChainExtent = extent;
|
swapChainExtent = extent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroySwapChain() {
|
||||||
|
vkDestroySwapchainKHR(device, swapChain, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void createImageViews() {
|
void createImageViews() {
|
||||||
swapChainImageViews.resize(swapChainImages.size(), VDeleter<VkImageView>{device, vkDestroyImageView});
|
swapChainImageViews.resize(swapChainImages.size(), VkImageView{});
|
||||||
|
|
||||||
// For each image in the swap chain create a VkImageView
|
// For each image in the swap chain create a VkImageView
|
||||||
for(uint32_t i = 0; i < swapChainImages.size(); i++) {
|
for(uint32_t i = 0; i < swapChainImages.size(); i++) {
|
||||||
|
@ -556,22 +578,28 @@ private:
|
||||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
createInfo.subresourceRange.layerCount = 1;
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
if(vkCreateImageView(device, &createInfo, nullptr, swapChainImageViews[i].replace()) != VK_SUCCESS) {
|
if(vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create image views!");
|
throw std::runtime_error("failed to create image views!");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyImageViews() {
|
||||||
|
for (uint32_t i = 0; i < swapChainImages.size(); i++) {
|
||||||
|
vkDestroyImageView(device, swapChainImageViews[i], nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void createGraphicsPipeline() {
|
void createGraphicsPipeline() {
|
||||||
auto vertShaderCode = readFile("shaders/vert.spv");
|
auto vertShaderCode = readFile("shaders/vert.spv");
|
||||||
auto fragShaderCode = readFile("shaders/frag.spv");
|
auto fragShaderCode = readFile("shaders/frag.spv");
|
||||||
|
|
||||||
VDeleter<VkShaderModule> vertShaderModule{device, vkDestroyShaderModule};
|
VkShaderModule vertShaderModule;
|
||||||
VDeleter<VkShaderModule> fragShaderModule{device, vkDestroyShaderModule};
|
VkShaderModule fragShaderModule;
|
||||||
|
|
||||||
createShaderModule(vertShaderCode, vertShaderModule);
|
createShaderModule(vertShaderCode, &vertShaderModule);
|
||||||
createShaderModule(fragShaderCode, fragShaderModule);
|
createShaderModule(fragShaderCode, &fragShaderModule);
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
|
VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
|
||||||
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
@ -670,7 +698,7 @@ private:
|
||||||
pipelineLayoutInfo.setLayoutCount = 0;
|
pipelineLayoutInfo.setLayoutCount = 0;
|
||||||
pipelineLayoutInfo.pSetLayouts = nullptr;
|
pipelineLayoutInfo.pSetLayouts = nullptr;
|
||||||
|
|
||||||
if(vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, pipelineLayout.replace()) != VK_SUCCESS) {
|
if(vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create pipeline layout!");
|
throw std::runtime_error("failed to create pipeline layout!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,11 +724,16 @@ private:
|
||||||
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
|
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||||
pipelineInfo.basePipelineIndex = -1;
|
pipelineInfo.basePipelineIndex = -1;
|
||||||
|
|
||||||
if(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, graphicsPipeline.replace()) != VK_SUCCESS) {
|
if(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create graphics pipeline!");
|
throw std::runtime_error("failed to create graphics pipeline!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyGraphicsPipeline() {
|
||||||
|
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
||||||
|
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
static std::vector<char> readFile(const std::string& filename) {
|
static std::vector<char> readFile(const std::string& filename) {
|
||||||
// Start reading at end of the file, as binary.
|
// Start reading at end of the file, as binary.
|
||||||
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
||||||
|
@ -718,13 +751,13 @@ private:
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createShaderModule(const std::vector<char>& code, VDeleter<VkShaderModule>& shaderModule) {
|
void createShaderModule(const std::vector<char>& code, VkShaderModule* shaderModule) {
|
||||||
VkShaderModuleCreateInfo createInfo = {};
|
VkShaderModuleCreateInfo createInfo = {};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
createInfo.codeSize = code.size();
|
createInfo.codeSize = code.size();
|
||||||
createInfo.pCode = (uint32_t*) code.data();
|
createInfo.pCode = (uint32_t*) code.data();
|
||||||
|
|
||||||
if(vkCreateShaderModule(device, &createInfo, nullptr, shaderModule.replace()) != VK_SUCCESS) {
|
if(vkCreateShaderModule(device, &createInfo, nullptr, shaderModule) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create shader module!");
|
throw std::runtime_error("failed to create shader module!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -770,13 +803,17 @@ private:
|
||||||
renderPassInfo.dependencyCount = 1;
|
renderPassInfo.dependencyCount = 1;
|
||||||
renderPassInfo.pDependencies = &dependency;
|
renderPassInfo.pDependencies = &dependency;
|
||||||
|
|
||||||
if(vkCreateRenderPass(device, &renderPassInfo, nullptr, renderPass.replace()) != VK_SUCCESS) {
|
if(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create render pass!");
|
throw std::runtime_error("failed to create render pass!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyRenderPass() {
|
||||||
|
vkDestroyRenderPass(device, renderPass, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void createFramebuffers() {
|
void createFramebuffers() {
|
||||||
swapChainFramebuffers.resize(swapChainImageViews.size(), VDeleter<VkFramebuffer> {device, vkDestroyFramebuffer});
|
swapChainFramebuffers.resize(swapChainImageViews.size(), VkFramebuffer{});
|
||||||
|
|
||||||
for(size_t i = 0; i < swapChainImageViews.size(); i++) {
|
for(size_t i = 0; i < swapChainImageViews.size(); i++) {
|
||||||
VkImageView attachments[] = { swapChainImageViews[i] };
|
VkImageView attachments[] = { swapChainImageViews[i] };
|
||||||
|
@ -790,13 +827,19 @@ private:
|
||||||
framebufferInfo.height = swapChainExtent.height;
|
framebufferInfo.height = swapChainExtent.height;
|
||||||
framebufferInfo.layers = 1;
|
framebufferInfo.layers = 1;
|
||||||
|
|
||||||
if(vkCreateFramebuffer(device, &framebufferInfo, nullptr, swapChainFramebuffers[i].replace()) != VK_SUCCESS) {
|
if(vkCreateFramebuffer(device, &framebufferInfo, nullptr, &swapChainFramebuffers[i]) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create framebuffer!");
|
throw std::runtime_error("failed to create framebuffer!");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyFramebuffers() {
|
||||||
|
for (size_t i = 0; i < swapChainImageViews.size(); i++) {
|
||||||
|
vkDestroyFramebuffer(device, swapChainFramebuffers[i], nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void createCommandPool() {
|
void createCommandPool() {
|
||||||
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);
|
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);
|
||||||
|
|
||||||
|
@ -805,11 +848,15 @@ private:
|
||||||
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily;
|
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily;
|
||||||
poolInfo.flags = 0;
|
poolInfo.flags = 0;
|
||||||
|
|
||||||
if(vkCreateCommandPool(device, &poolInfo, nullptr, commandPool.replace()) != VK_SUCCESS) {
|
if(vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create command pool!");
|
throw std::runtime_error("failed to create command pool!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyCommandPool() {
|
||||||
|
vkDestroyCommandPool(device, commandPool, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void createCommandBuffers() {
|
void createCommandBuffers() {
|
||||||
if(commandBuffers.size() > 0) {
|
if(commandBuffers.size() > 0) {
|
||||||
vkFreeCommandBuffers(device, commandPool, commandBuffers.size(), commandBuffers.data());
|
vkFreeCommandBuffers(device, commandPool, commandBuffers.size(), commandBuffers.data());
|
||||||
|
@ -859,17 +906,28 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyCommandBuffers() {
|
||||||
|
if (commandBuffers.size() > 0) {
|
||||||
|
vkFreeCommandBuffers(device, commandPool, commandBuffers.size(), commandBuffers.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void createSemaphores() {
|
void createSemaphores() {
|
||||||
VkSemaphoreCreateInfo semaphoreInfo = {};
|
VkSemaphoreCreateInfo semaphoreInfo = {};
|
||||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
|
||||||
if(vkCreateSemaphore(device, &semaphoreInfo, nullptr, imageAvailableSemaphore.replace()) != VK_SUCCESS ||
|
if(vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore) != VK_SUCCESS ||
|
||||||
vkCreateSemaphore(device, &semaphoreInfo, nullptr, renderFinishedSemaphore.replace()) != VK_SUCCESS) {
|
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create semaphores!");
|
throw std::runtime_error("failed to create semaphores!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroySemaphores() {
|
||||||
|
vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
|
||||||
|
vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void mainLoop() {
|
void mainLoop() {
|
||||||
// While we shouldn't close, have glfw poll for events
|
// While we shouldn't close, have glfw poll for events
|
||||||
while(!glfwWindowShouldClose(window)) {
|
while(!glfwWindowShouldClose(window)) {
|
||||||
|
@ -878,6 +936,22 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
vkDeviceWaitIdle(device);
|
vkDeviceWaitIdle(device);
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup() {
|
||||||
|
destroySemaphores();
|
||||||
|
destroyCommandBuffers();
|
||||||
|
destroyCommandPool();
|
||||||
|
destroyFramebuffers();
|
||||||
|
destroyGraphicsPipeline();
|
||||||
|
destroyRenderPass();
|
||||||
|
destroyImageViews();
|
||||||
|
destroySwapChain();
|
||||||
|
destroyLogicalDevice();
|
||||||
|
destroySurface();
|
||||||
|
cleanupDebugCallback();
|
||||||
|
destroyInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawFrame() {
|
void drawFrame() {
|
||||||
|
|
59
main.h
59
main.h
|
@ -16,65 +16,6 @@ void DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// VDeleter utility class that automatically destroys objects when they fall out of scope.
|
|
||||||
template <typename T>
|
|
||||||
class VDeleter {
|
|
||||||
public:
|
|
||||||
VDeleter() : VDeleter([](T, VkAllocationCallbacks*) {}) {}
|
|
||||||
|
|
||||||
VDeleter(std::function<void(T, VkAllocationCallbacks*)> deletef) {
|
|
||||||
this->deleter = [=](T obj) { deletef(obj, nullptr); };
|
|
||||||
}
|
|
||||||
|
|
||||||
VDeleter(const VDeleter<VkInstance>& instance, std::function<void(VkInstance, T, VkAllocationCallbacks*)> deletef) {
|
|
||||||
this->deleter = [&instance, deletef](T obj) { deletef(instance, obj, nullptr); };
|
|
||||||
}
|
|
||||||
|
|
||||||
VDeleter(const VDeleter<VkDevice>& device, std::function<void(VkDevice, T, VkAllocationCallbacks*)> deletef) {
|
|
||||||
this->deleter = [&device, deletef](T obj) { deletef(device, obj, nullptr); };
|
|
||||||
}
|
|
||||||
|
|
||||||
~VDeleter() {
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
const T* operator &() const {
|
|
||||||
return &object;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* replace() {
|
|
||||||
cleanup();
|
|
||||||
return &object;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator T() const {
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator=(T rhs) {
|
|
||||||
if (rhs != object) {
|
|
||||||
cleanup();
|
|
||||||
object = rhs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename V>
|
|
||||||
bool operator==(V rhs) {
|
|
||||||
return object == T(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T object{VK_NULL_HANDLE};
|
|
||||||
std::function<void(T)> deleter;
|
|
||||||
|
|
||||||
void cleanup() {
|
|
||||||
if (object != VK_NULL_HANDLE) {
|
|
||||||
deleter(object);
|
|
||||||
}
|
|
||||||
object = VK_NULL_HANDLE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QueueFamilyIndices {
|
struct QueueFamilyIndices {
|
||||||
int graphicsFamily = -1;
|
int graphicsFamily = -1;
|
||||||
int presentFamily = -1;
|
int presentFamily = -1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue