feat: refactor to separate files
This commit is contained in:
@@ -7,21 +7,14 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "debugLayers.h"
|
|
||||||
#include "queues.h"
|
#include "queues.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
const std::vector<const char *> deviceExtensions = {
|
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkShaderModule HelloTriangleApplication::createShaderModule(const std::vector<char> &code) {
|
VkShaderModule HelloTriangleApplication::createShaderModule(const std::vector<char> &code) {
|
||||||
VkShaderModuleCreateInfo createInfo{};
|
VkShaderModuleCreateInfo createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
@@ -29,148 +22,24 @@ VkShaderModule HelloTriangleApplication::createShaderModule(const std::vector<ch
|
|||||||
createInfo.pCode = reinterpret_cast<const uint32_t *>(code.data());
|
createInfo.pCode = reinterpret_cast<const uint32_t *>(code.data());
|
||||||
|
|
||||||
VkShaderModule shaderModule;
|
VkShaderModule shaderModule;
|
||||||
if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
|
if (vkCreateShaderModule(myVkInstance->device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create shader module");
|
throw std::runtime_error("Failed to create shader module");
|
||||||
}
|
}
|
||||||
return shaderModule;
|
return shaderModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSuitableDevice(VkPhysicalDevice device, VkSurfaceKHR surface) {
|
|
||||||
VkPhysicalDeviceProperties deviceProperties;
|
|
||||||
VkPhysicalDeviceFeatures features;
|
|
||||||
QueueFamilyIndices indices;
|
|
||||||
|
|
||||||
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
|
||||||
vkGetPhysicalDeviceFeatures(device, &features);
|
|
||||||
indices = findQueueFamilies(device, surface);
|
|
||||||
|
|
||||||
bool extensionSupport = checkDeviceExtensionSupport(device, deviceExtensions);
|
|
||||||
bool swapChainAdequate = false;
|
|
||||||
if (extensionSupport) {
|
|
||||||
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device, surface);
|
|
||||||
swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
return deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
|
|
||||||
features.geometryShader &&
|
|
||||||
indices.isComplete() &&
|
|
||||||
extensionSupport &&
|
|
||||||
swapChainAdequate;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HelloTriangleApplication::run() {
|
void HelloTriangleApplication::run() {
|
||||||
initWindow();
|
this->myVkInstance = new MyVkInstance();
|
||||||
|
this->myVkInstance->init();
|
||||||
initVulkan();
|
initVulkan();
|
||||||
mainLoop();
|
mainLoop();
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
this->myVkInstance->cleanup();
|
||||||
|
|
||||||
void HelloTriangleApplication::initWindow() {
|
|
||||||
glfwInit();
|
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
|
||||||
|
|
||||||
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HelloTriangleApplication::createInstance() {
|
|
||||||
#ifdef WITH_VALIDATION_LAYERS
|
|
||||||
if (!checkValidationLayerSupport()) {
|
|
||||||
throw std::runtime_error("validation layer support required");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
VkApplicationInfo appInfo{};
|
|
||||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
|
||||||
appInfo.pApplicationName = "Hello Triangle";
|
|
||||||
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
|
|
||||||
appInfo.pEngineName = "No Engine";
|
|
||||||
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
|
|
||||||
appInfo.apiVersion = VK_API_VERSION_1_0;
|
|
||||||
|
|
||||||
VkInstanceCreateInfo createInfo{};
|
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
|
||||||
createInfo.pApplicationInfo = &appInfo;
|
|
||||||
|
|
||||||
auto extensions = getRequiredExtensions();
|
|
||||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
|
||||||
createInfo.ppEnabledExtensionNames = extensions.data();
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef WITH_VALIDATION_LAYERS
|
|
||||||
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
|
|
||||||
createInfo.ppEnabledLayerNames = validationLayers.data();
|
|
||||||
#else
|
|
||||||
createInfo.enabledLayerCount = 0;
|
|
||||||
createInfo.ppEnabledLayerNames = nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
|
|
||||||
throw std::runtime_error("Failed to create instance!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HelloTriangleApplication::createSurface() {
|
|
||||||
if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) {
|
|
||||||
throw std::runtime_error("Failed to create surface");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HelloTriangleApplication::pickPhysicalDevice() {
|
|
||||||
uint32_t deviceCount = 0;
|
|
||||||
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
|
|
||||||
if (deviceCount == 0) {
|
|
||||||
throw std::runtime_error("No devices available");
|
|
||||||
}
|
|
||||||
std::vector<VkPhysicalDevice> devices(deviceCount);
|
|
||||||
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
|
|
||||||
for (const auto &device: devices) {
|
|
||||||
if (isSuitableDevice(device, surface)) {
|
|
||||||
physicalDevice = device;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (physicalDevice == VK_NULL_HANDLE) {
|
|
||||||
throw std::runtime_error("No suitable device found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HelloTriangleApplication::createLogicalDevice() {
|
|
||||||
QueueFamilyIndices indices = findQueueFamilies(physicalDevice, surface);
|
|
||||||
|
|
||||||
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
|
|
||||||
std::set<uint32_t> uniqueQueueFamilies = {indices.graphicsFamily.value(), indices.presentFamily.value()};
|
|
||||||
float queuePriority = 1.0f;
|
|
||||||
for (uint32_t queueFamily : uniqueQueueFamilies) {
|
|
||||||
VkDeviceQueueCreateInfo queueCreateInfo{};
|
|
||||||
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
|
||||||
queueCreateInfo.queueFamilyIndex = queueFamily;
|
|
||||||
queueCreateInfo.queueCount = 1;
|
|
||||||
queueCreateInfo.pQueuePriorities = &queuePriority;
|
|
||||||
queueCreateInfos.push_back(queueCreateInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures deviceFeatures{};
|
|
||||||
|
|
||||||
VkDeviceCreateInfo createInfo{};
|
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
|
||||||
createInfo.pQueueCreateInfos = queueCreateInfos.data();
|
|
||||||
createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
|
|
||||||
createInfo.pEnabledFeatures = &deviceFeatures;
|
|
||||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
|
|
||||||
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
|
|
||||||
createInfo.enabledLayerCount = 0;
|
|
||||||
|
|
||||||
if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
|
|
||||||
throw std::runtime_error("Failed to create logical device");
|
|
||||||
}
|
|
||||||
vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
|
|
||||||
vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HelloTriangleApplication::createSwapChain() {
|
void HelloTriangleApplication::createSwapChain() {
|
||||||
QueueFamilyIndices indices = findQueueFamilies(physicalDevice, surface);
|
uint32_t queueFamilyIndices[] = {myVkInstance->indices.graphicsFamily.value(), myVkInstance->indices.presentFamily.value()};
|
||||||
uint32_t queueFamilyIndices[] = {indices.graphicsFamily.value(), indices.presentFamily.value()};
|
SwapChainSupportDetails swapChainSupportDetails = querySwapChainSupport(myVkInstance->physicalDevice, myVkInstance->surface);
|
||||||
SwapChainSupportDetails swapChainSupportDetails = querySwapChainSupport(physicalDevice, surface);
|
|
||||||
|
|
||||||
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupportDetails.formats);
|
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupportDetails.formats);
|
||||||
VkPresentModeKHR presentMode = chooseSwapChainPresentMode(swapChainSupportDetails.presentModes);
|
VkPresentModeKHR presentMode = chooseSwapChainPresentMode(swapChainSupportDetails.presentModes);
|
||||||
@@ -182,14 +51,14 @@ void HelloTriangleApplication::createSwapChain() {
|
|||||||
}
|
}
|
||||||
VkSwapchainCreateInfoKHR createInfo{};
|
VkSwapchainCreateInfoKHR createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
createInfo.surface = surface;
|
createInfo.surface = myVkInstance->surface;
|
||||||
createInfo.minImageCount = imageCount;
|
createInfo.minImageCount = imageCount;
|
||||||
createInfo.imageFormat = surfaceFormat.format;
|
createInfo.imageFormat = surfaceFormat.format;
|
||||||
createInfo.imageColorSpace = surfaceFormat.colorSpace;
|
createInfo.imageColorSpace = surfaceFormat.colorSpace;
|
||||||
createInfo.imageExtent = extent;
|
createInfo.imageExtent = extent;
|
||||||
createInfo.imageArrayLayers = 1;
|
createInfo.imageArrayLayers = 1;
|
||||||
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
if (indices.graphicsFamily != indices.presentFamily) {
|
if (myVkInstance->indices.graphicsFamily != myVkInstance->indices.presentFamily) {
|
||||||
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
createInfo.queueFamilyIndexCount = 2;
|
createInfo.queueFamilyIndexCount = 2;
|
||||||
createInfo.pQueueFamilyIndices = queueFamilyIndices;
|
createInfo.pQueueFamilyIndices = queueFamilyIndices;
|
||||||
@@ -204,12 +73,12 @@ void HelloTriangleApplication::createSwapChain() {
|
|||||||
createInfo.clipped = VK_TRUE;
|
createInfo.clipped = VK_TRUE;
|
||||||
createInfo.oldSwapchain = VK_NULL_HANDLE;
|
createInfo.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
|
if (vkCreateSwapchainKHR(myVkInstance->device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create swapChain");
|
throw std::runtime_error("Failed to create swapChain");
|
||||||
}
|
}
|
||||||
vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr);
|
vkGetSwapchainImagesKHR(myVkInstance->device, swapChain, &imageCount, nullptr);
|
||||||
swapChainImages.resize(imageCount);
|
swapChainImages.resize(imageCount);
|
||||||
vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());
|
vkGetSwapchainImagesKHR(myVkInstance->device, swapChain, &imageCount, swapChainImages.data());
|
||||||
swapChainImageFormat = surfaceFormat.format;
|
swapChainImageFormat = surfaceFormat.format;
|
||||||
swapChainExtent = extent;
|
swapChainExtent = extent;
|
||||||
}
|
}
|
||||||
@@ -232,7 +101,7 @@ void HelloTriangleApplication::createImageViews() {
|
|||||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
createInfo.subresourceRange.layerCount = 1;
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
if (vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
|
if (vkCreateImageView(myVkInstance->device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create image view");
|
throw std::runtime_error("Failed to create image view");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -276,7 +145,7 @@ void HelloTriangleApplication::createRenderPass() {
|
|||||||
.pDependencies = &dependency,
|
.pDependencies = &dependency,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (vkCreateRenderPass(device, &renderPassCreateInfo, nullptr, &renderPass) != VK_SUCCESS) {
|
if (vkCreateRenderPass(myVkInstance->device, &renderPassCreateInfo, nullptr, &renderPass) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create render pass");
|
throw std::runtime_error("Failed to create render pass");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -414,7 +283,7 @@ void HelloTriangleApplication::createGraphicsPipeline() {
|
|||||||
.pPushConstantRanges = nullptr,
|
.pPushConstantRanges = nullptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
|
if (vkCreatePipelineLayout(myVkInstance->device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create pipeline layout");
|
throw std::runtime_error("failed to create pipeline layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,12 +306,12 @@ void HelloTriangleApplication::createGraphicsPipeline() {
|
|||||||
.basePipelineIndex = -1,
|
.basePipelineIndex = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS) {
|
if (vkCreateGraphicsPipelines(myVkInstance->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");
|
||||||
}
|
}
|
||||||
|
|
||||||
vkDestroyShaderModule(device, fragShaderModule, nullptr);
|
vkDestroyShaderModule(myVkInstance->device, fragShaderModule, nullptr);
|
||||||
vkDestroyShaderModule(device, vertShaderModule, nullptr);
|
vkDestroyShaderModule(myVkInstance->device, vertShaderModule, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HelloTriangleApplication::createFrameBuffers() {
|
void HelloTriangleApplication::createFrameBuffers() {
|
||||||
@@ -460,22 +329,20 @@ void HelloTriangleApplication::createFrameBuffers() {
|
|||||||
.height = swapChainExtent.height,
|
.height = swapChainExtent.height,
|
||||||
.layers = 1
|
.layers = 1
|
||||||
};
|
};
|
||||||
if (vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &swapChainFrameBuffers[i]) != VK_SUCCESS) {
|
if (vkCreateFramebuffer(myVkInstance->device, &framebufferCreateInfo, nullptr, &swapChainFrameBuffers[i]) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create frame buffer");
|
throw std::runtime_error("Failed to create frame buffer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HelloTriangleApplication::createCommandPool() {
|
void HelloTriangleApplication::createCommandPool() {
|
||||||
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice, surface);
|
|
||||||
|
|
||||||
VkCommandPoolCreateInfo poolInfo{
|
VkCommandPoolCreateInfo poolInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value(),
|
.queueFamilyIndex = myVkInstance->indices.graphicsFamily.value(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
|
if (vkCreateCommandPool(myVkInstance->device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create command pool");
|
throw std::runtime_error("Failed to create command pool");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -490,7 +357,7 @@ void HelloTriangleApplication::createCommandBuffers() {
|
|||||||
.commandBufferCount = (uint32_t) commandBuffers.size(),
|
.commandBufferCount = (uint32_t) commandBuffers.size(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (vkAllocateCommandBuffers(device, &allocateInfo, commandBuffers.data()) != VK_SUCCESS) {
|
if (vkAllocateCommandBuffers(myVkInstance->device, &allocateInfo, commandBuffers.data()) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to allocate command buffers");
|
throw std::runtime_error("Failed to allocate command buffers");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,22 +405,15 @@ void HelloTriangleApplication::createSyncObjects() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
|
for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
|
||||||
if (vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &imageAvailableSemaphores[i]) != VK_SUCCESS ||
|
if (vkCreateSemaphore(myVkInstance->device, &semaphoreCreateInfo, nullptr, &imageAvailableSemaphores[i]) != VK_SUCCESS ||
|
||||||
vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &renderFinishedSemaphores[i]) != VK_SUCCESS ||
|
vkCreateSemaphore(myVkInstance->device, &semaphoreCreateInfo, nullptr, &renderFinishedSemaphores[i]) != VK_SUCCESS ||
|
||||||
vkCreateFence(device, &fenceInfo, nullptr, &inFlightFences[i])) {
|
vkCreateFence(myVkInstance->device, &fenceInfo, nullptr, &inFlightFences[i])) {
|
||||||
throw std::runtime_error("failed to create semaphore");
|
throw std::runtime_error("failed to create semaphore");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HelloTriangleApplication::initVulkan() {
|
void HelloTriangleApplication::initVulkan() {
|
||||||
createInstance();
|
|
||||||
#ifdef WITH_VALIDATION_LAYERS
|
|
||||||
setupDebugMessenger(instance, &debugMessenger);
|
|
||||||
#endif
|
|
||||||
createSurface();
|
|
||||||
pickPhysicalDevice();
|
|
||||||
createLogicalDevice();
|
|
||||||
createSwapChain();
|
createSwapChain();
|
||||||
createImageViews();
|
createImageViews();
|
||||||
createRenderPass();
|
createRenderPass();
|
||||||
@@ -565,20 +425,20 @@ void HelloTriangleApplication::initVulkan() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HelloTriangleApplication::mainLoop() {
|
void HelloTriangleApplication::mainLoop() {
|
||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(myVkInstance->window)) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
drawFrame();
|
drawFrame();
|
||||||
}
|
}
|
||||||
vkDeviceWaitIdle(device);
|
vkDeviceWaitIdle(myVkInstance->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HelloTriangleApplication::drawFrame() {
|
void HelloTriangleApplication::drawFrame() {
|
||||||
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
vkWaitForFences(myVkInstance->device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||||
uint32_t imageIndex;
|
uint32_t imageIndex;
|
||||||
vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
vkAcquireNextImageKHR(myVkInstance->device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
||||||
|
|
||||||
if (imagesInFlight[currentFrame] != VK_NULL_HANDLE) {
|
if (imagesInFlight[currentFrame] != VK_NULL_HANDLE) {
|
||||||
vkWaitForFences(device, 1, &imagesInFlight[currentFrame], VK_TRUE, UINT64_MAX);
|
vkWaitForFences(myVkInstance->device, 1, &imagesInFlight[currentFrame], VK_TRUE, UINT64_MAX);
|
||||||
}
|
}
|
||||||
imagesInFlight[currentFrame] = inFlightFences[currentFrame];
|
imagesInFlight[currentFrame] = inFlightFences[currentFrame];
|
||||||
|
|
||||||
@@ -596,9 +456,9 @@ void HelloTriangleApplication::drawFrame() {
|
|||||||
.pSignalSemaphores = signalSemaphores,
|
.pSignalSemaphores = signalSemaphores,
|
||||||
};
|
};
|
||||||
|
|
||||||
vkResetFences(device, 1, &inFlightFences[currentFrame]);
|
vkResetFences(myVkInstance->device, 1, &inFlightFences[currentFrame]);
|
||||||
|
|
||||||
if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) {
|
if (vkQueueSubmit(myVkInstance->graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to submit draw command");
|
throw std::runtime_error("Failed to submit draw command");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,7 +473,7 @@ void HelloTriangleApplication::drawFrame() {
|
|||||||
.pResults = nullptr,
|
.pResults = nullptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
vkQueuePresentKHR(presentQueue, &presentInfo);
|
vkQueuePresentKHR(myVkInstance->presentQueue, &presentInfo);
|
||||||
|
|
||||||
// vkQueueWaitIdle(presentQueue);
|
// vkQueueWaitIdle(presentQueue);
|
||||||
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||||
@@ -621,41 +481,19 @@ void HelloTriangleApplication::drawFrame() {
|
|||||||
|
|
||||||
void HelloTriangleApplication::cleanup() {
|
void HelloTriangleApplication::cleanup() {
|
||||||
for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
|
for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
|
||||||
vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
|
vkDestroySemaphore(myVkInstance->device, renderFinishedSemaphores[i], nullptr);
|
||||||
vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
|
vkDestroySemaphore(myVkInstance->device, imageAvailableSemaphores[i], nullptr);
|
||||||
vkDestroyFence(device, inFlightFences[i], nullptr);
|
vkDestroyFence(myVkInstance->device, inFlightFences[i], nullptr);
|
||||||
}
|
}
|
||||||
vkDestroyCommandPool(device, commandPool, nullptr);
|
vkDestroyCommandPool(myVkInstance->device, commandPool, nullptr);
|
||||||
for (auto frameBuffer : swapChainFrameBuffers) {
|
for (auto frameBuffer : swapChainFrameBuffers) {
|
||||||
vkDestroyFramebuffer(device, frameBuffer, nullptr);
|
vkDestroyFramebuffer(myVkInstance->device, frameBuffer, nullptr);
|
||||||
}
|
}
|
||||||
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
vkDestroyPipeline(myVkInstance->device, graphicsPipeline, nullptr);
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
vkDestroyPipelineLayout(myVkInstance->device, pipelineLayout, nullptr);
|
||||||
vkDestroyRenderPass(device, renderPass, nullptr);
|
vkDestroyRenderPass(myVkInstance->device, renderPass, nullptr);
|
||||||
for (auto imageView : swapChainImageViews) {
|
for (auto imageView : swapChainImageViews) {
|
||||||
vkDestroyImageView(device, imageView, nullptr);
|
vkDestroyImageView(myVkInstance->device, imageView, nullptr);
|
||||||
}
|
}
|
||||||
vkDestroySwapchainKHR(device, swapChain, nullptr);
|
vkDestroySwapchainKHR(myVkInstance->device, swapChain, nullptr);
|
||||||
vkDestroyDevice(device, nullptr);
|
|
||||||
vkDestroySurfaceKHR(instance, surface, nullptr);
|
|
||||||
#ifdef WITH_VALIDATION_LAYERS
|
|
||||||
DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
|
|
||||||
#endif
|
|
||||||
vkDestroyInstance(instance, nullptr);
|
|
||||||
glfwDestroyWindow(window);
|
|
||||||
glfwTerminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const char *> HelloTriangleApplication::getRequiredExtensions() {
|
|
||||||
uint32_t glfwExtensionCount;
|
|
||||||
const char **glfwExtensions;
|
|
||||||
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
|
|
||||||
|
|
||||||
std::vector<const char *> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
|
|
||||||
|
|
||||||
#ifdef WITH_VALIDATION_LAYERS
|
|
||||||
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return extensions;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#ifndef VULKANTEST_HELLOTRIANGLEAPPLICATION_H
|
#ifndef VULKANTEST_HELLOTRIANGLEAPPLICATION_H
|
||||||
#define VULKANTEST_HELLOTRIANGLEAPPLICATION_H
|
#define VULKANTEST_HELLOTRIANGLEAPPLICATION_H
|
||||||
|
|
||||||
|
#include "MyVkInstance.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
@@ -20,14 +22,7 @@ public:
|
|||||||
void run();
|
void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLFWwindow* window;
|
MyVkInstance *myVkInstance;
|
||||||
VkInstance instance;
|
|
||||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
|
||||||
VkDevice device;
|
|
||||||
VkQueue graphicsQueue;
|
|
||||||
VkQueue presentQueue;
|
|
||||||
VkSurfaceKHR surface;
|
|
||||||
VkDebugUtilsMessengerEXT debugMessenger;
|
|
||||||
VkSwapchainKHR swapChain;
|
VkSwapchainKHR swapChain;
|
||||||
std::vector<VkImage> swapChainImages;
|
std::vector<VkImage> swapChainImages;
|
||||||
std::vector<VkImageView> swapChainImageViews;
|
std::vector<VkImageView> swapChainImageViews;
|
||||||
@@ -47,13 +42,7 @@ private:
|
|||||||
|
|
||||||
int currentFrame = 0;
|
int currentFrame = 0;
|
||||||
|
|
||||||
// window creation
|
|
||||||
void initWindow();
|
|
||||||
|
|
||||||
// Vulkan initialisation
|
// Vulkan initialisation
|
||||||
void createInstance();
|
|
||||||
void pickPhysicalDevice();
|
|
||||||
void createLogicalDevice();
|
|
||||||
void createSurface();
|
void createSurface();
|
||||||
void createSwapChain();
|
void createSwapChain();
|
||||||
void createImageViews();
|
void createImageViews();
|
||||||
|
|||||||
199
src/MyVkInstance.cpp
Normal file
199
src/MyVkInstance.cpp
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 30-05-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "MyVkInstance.h"
|
||||||
|
#include "debugLayers.h"
|
||||||
|
#include "queues.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
const int DEFAULT_WIDTH = 600;
|
||||||
|
const int DEFAULT_HEIGHT = 300;
|
||||||
|
const char* DEFAULT_TITLE = "Vulkan";
|
||||||
|
|
||||||
|
const char* deviceExtensions[] = {
|
||||||
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<const char *> getRequiredExtensions() {
|
||||||
|
uint32_t glfwExtensionCount;
|
||||||
|
const char **glfwExtensions;
|
||||||
|
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
|
||||||
|
|
||||||
|
std::vector<const char *> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
|
||||||
|
|
||||||
|
#ifdef WITH_VALIDATION_LAYERS
|
||||||
|
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSuitableDevice(VkPhysicalDevice device, VkSurfaceKHR surface) {
|
||||||
|
VkPhysicalDeviceProperties deviceProperties;
|
||||||
|
VkPhysicalDeviceFeatures features;
|
||||||
|
QueueFamilyIndices indices;
|
||||||
|
|
||||||
|
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
||||||
|
vkGetPhysicalDeviceFeatures(device, &features);
|
||||||
|
indices = findQueueFamilies(device, surface);
|
||||||
|
|
||||||
|
bool extensionSupport = checkDeviceExtensionSupport(device, deviceExtensions, sizeof(deviceExtensions) / sizeof(void*));
|
||||||
|
bool swapChainAdequate = false;
|
||||||
|
if (extensionSupport) {
|
||||||
|
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device, surface);
|
||||||
|
swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
|
||||||
|
features.geometryShader &&
|
||||||
|
indices.isComplete() &&
|
||||||
|
extensionSupport &&
|
||||||
|
swapChainAdequate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MyVkInstance::MyVkInstance(){
|
||||||
|
new (this) MyVkInstance(DEFAULT_WIDTH, DEFAULT_HEIGHT, const_cast<char *&>(DEFAULT_TITLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
MyVkInstance::MyVkInstance(int width, int height, char* &title) {
|
||||||
|
this->width = width;
|
||||||
|
this->height = height;
|
||||||
|
this->title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyVkInstance::init() {
|
||||||
|
this->initWindow();
|
||||||
|
this->initVulkan();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyVkInstance::initWindow() {
|
||||||
|
glfwInit();
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
||||||
|
|
||||||
|
window = glfwCreateWindow(this->width, this->height, this->title.c_str(), nullptr, nullptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyVkInstance::initVulkan() {
|
||||||
|
createInstance();
|
||||||
|
#ifdef WITH_VALIDATION_LAYERS
|
||||||
|
setupDebugMessenger(instance, &debugMessenger);
|
||||||
|
#endif
|
||||||
|
createSurface();
|
||||||
|
pickPhysicalDevice();
|
||||||
|
createLogicalDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyVkInstance::createInstance() {
|
||||||
|
|
||||||
|
#ifdef WITH_VALIDATION_LAYERS
|
||||||
|
if (!checkValidationLayerSupport()) {
|
||||||
|
throw std::runtime_error("validation layer support required");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
VkApplicationInfo appInfo{};
|
||||||
|
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
|
appInfo.pApplicationName = "Hello Triangle";
|
||||||
|
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||||
|
appInfo.pEngineName = "No Engine";
|
||||||
|
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||||
|
appInfo.apiVersion = VK_API_VERSION_1_0;
|
||||||
|
|
||||||
|
VkInstanceCreateInfo createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
createInfo.pApplicationInfo = &appInfo;
|
||||||
|
|
||||||
|
auto extensions = getRequiredExtensions();
|
||||||
|
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
||||||
|
createInfo.ppEnabledExtensionNames = extensions.data();
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WITH_VALIDATION_LAYERS
|
||||||
|
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
|
||||||
|
createInfo.ppEnabledLayerNames = validationLayers.data();
|
||||||
|
#else
|
||||||
|
createInfo.enabledLayerCount = 0;
|
||||||
|
createInfo.ppEnabledLayerNames = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("Failed to create instance!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyVkInstance::createSurface() {
|
||||||
|
if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("Failed to create surface");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyVkInstance::pickPhysicalDevice() {
|
||||||
|
uint32_t deviceCount = 0;
|
||||||
|
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
|
||||||
|
if (deviceCount == 0) {
|
||||||
|
throw std::runtime_error("No devices available");
|
||||||
|
}
|
||||||
|
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||||
|
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
|
||||||
|
for (const auto &pPhysicalDeviceT: devices) {
|
||||||
|
if (isSuitableDevice(pPhysicalDeviceT, surface)) {
|
||||||
|
physicalDevice = pPhysicalDeviceT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (physicalDevice == VK_NULL_HANDLE) {
|
||||||
|
throw std::runtime_error("No suitable device found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyVkInstance::createLogicalDevice() {
|
||||||
|
this->indices = findQueueFamilies(physicalDevice, surface);
|
||||||
|
|
||||||
|
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
|
||||||
|
std::set<uint32_t> uniqueQueueFamilies = {this->indices.graphicsFamily.value(), this->indices.presentFamily.value()};
|
||||||
|
float queuePriority = 1.0f;
|
||||||
|
for (uint32_t queueFamily : uniqueQueueFamilies) {
|
||||||
|
VkDeviceQueueCreateInfo queueCreateInfo{};
|
||||||
|
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
queueCreateInfo.queueFamilyIndex = queueFamily;
|
||||||
|
queueCreateInfo.queueCount = 1;
|
||||||
|
queueCreateInfo.pQueuePriorities = &queuePriority;
|
||||||
|
queueCreateInfos.push_back(queueCreateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPhysicalDeviceFeatures deviceFeatures{};
|
||||||
|
|
||||||
|
int numel = sizeof(deviceExtensions) / sizeof(void*);
|
||||||
|
|
||||||
|
VkDeviceCreateInfo createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
createInfo.pQueueCreateInfos = queueCreateInfos.data();
|
||||||
|
createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
|
||||||
|
createInfo.pEnabledFeatures = &deviceFeatures;
|
||||||
|
createInfo.enabledExtensionCount = static_cast<uint32_t>(numel);
|
||||||
|
createInfo.ppEnabledExtensionNames = deviceExtensions;
|
||||||
|
createInfo.enabledLayerCount = 0;
|
||||||
|
|
||||||
|
if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("Failed to create logical device");
|
||||||
|
}
|
||||||
|
vkGetDeviceQueue(device, this->indices.graphicsFamily.value(), 0, &graphicsQueue);
|
||||||
|
vkGetDeviceQueue(device, this->indices.presentFamily.value(), 0, &presentQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyVkInstance::cleanup() {
|
||||||
|
vkDestroyDevice(device, nullptr);
|
||||||
|
vkDestroySurfaceKHR(instance, surface, nullptr);
|
||||||
|
#ifdef WITH_VALIDATION_LAYERS
|
||||||
|
DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
|
||||||
|
#endif
|
||||||
|
vkDestroyInstance(instance, nullptr);
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
glfwTerminate();
|
||||||
|
}
|
||||||
53
src/MyVkInstance.h
Normal file
53
src/MyVkInstance.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 30-05-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef VULKANTEST_MYVKINSTANCE_H
|
||||||
|
#define VULKANTEST_MYVKINSTANCE_H
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define GLFW_INCLUDE_VULKAN
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include "queues.h"
|
||||||
|
|
||||||
|
|
||||||
|
class MyVkInstance {
|
||||||
|
public:
|
||||||
|
MyVkInstance();
|
||||||
|
MyVkInstance(int width, int height, char* &title);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
VkInstance instance{};
|
||||||
|
VkDevice device{};
|
||||||
|
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||||
|
VkSurfaceKHR surface;
|
||||||
|
VkQueue graphicsQueue;
|
||||||
|
VkQueue presentQueue;
|
||||||
|
GLFWwindow* window{};
|
||||||
|
|
||||||
|
QueueFamilyIndices indices;
|
||||||
|
private:
|
||||||
|
int width{};
|
||||||
|
int height{};
|
||||||
|
std::string title;
|
||||||
|
|
||||||
|
#ifdef WITH_VALIDATION_LAYERS
|
||||||
|
VkDebugUtilsMessengerEXT debugMessenger;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// window creation
|
||||||
|
void initWindow();
|
||||||
|
|
||||||
|
// init vulkan
|
||||||
|
void initVulkan();
|
||||||
|
void createInstance();
|
||||||
|
void createSurface();
|
||||||
|
void pickPhysicalDevice();
|
||||||
|
void createLogicalDevice();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //VULKANTEST_MYVKINSTANCE_H
|
||||||
@@ -6,14 +6,14 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
bool checkDeviceExtensionSupport(VkPhysicalDevice device, std::vector<const char*> deviceExtensions) {
|
bool checkDeviceExtensionSupport(VkPhysicalDevice device, const char** deviceExtensions, int count) {
|
||||||
uint32_t extensionCount;
|
uint32_t extensionCount;
|
||||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
|
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
|
||||||
|
|
||||||
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
|
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
|
||||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
|
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
|
||||||
|
|
||||||
std::set<std::string> requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());
|
std::set<std::string> requiredExtensions(deviceExtensions, deviceExtensions + count);
|
||||||
for (const auto& extension : availableExtensions) {
|
for (const auto& extension : availableExtensions) {
|
||||||
requiredExtensions.erase(extension.extensionName);
|
requiredExtensions.erase(extension.extensionName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ struct SwapChainSupportDetails {
|
|||||||
std::vector<VkPresentModeKHR> presentModes;
|
std::vector<VkPresentModeKHR> presentModes;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool checkDeviceExtensionSupport(VkPhysicalDevice device, std::vector<const char*> deviceExtensions);
|
bool checkDeviceExtensionSupport(VkPhysicalDevice device, const char** deviceExtensions, int size);
|
||||||
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface);
|
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface);
|
||||||
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device, VkSurfaceKHR surface);
|
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device, VkSurfaceKHR surface);
|
||||||
VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
||||||
|
|||||||
Reference in New Issue
Block a user