forked from pupbrained/vulkan-test
ughehgehgge
This commit is contained in:
parent
a4c78acebf
commit
329eeb76c7
81
src/main.cpp
81
src/main.cpp
|
@ -2,13 +2,15 @@
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <fmt/format.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <set>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
#include "fmt/base.h"
|
#include "util/magic_enum.hpp"
|
||||||
#include "util/types.h"
|
#include "util/types.h"
|
||||||
|
|
||||||
namespace vk {
|
namespace vk {
|
||||||
|
@ -28,7 +30,7 @@ constexpr bool enableValidationLayers = true;
|
||||||
|
|
||||||
class VulkanApp {
|
class VulkanApp {
|
||||||
public:
|
public:
|
||||||
void run() {
|
fn run() -> void {
|
||||||
initWindow();
|
initWindow();
|
||||||
initVulkan();
|
initVulkan();
|
||||||
mainLoop();
|
mainLoop();
|
||||||
|
@ -44,14 +46,21 @@ class VulkanApp {
|
||||||
vk::DispatchLoaderDynamic mLoader;
|
vk::DispatchLoaderDynamic mLoader;
|
||||||
|
|
||||||
vk::PhysicalDevice mPhysicalDevice;
|
vk::PhysicalDevice mPhysicalDevice;
|
||||||
|
vk::UniqueDevice mDevice;
|
||||||
|
|
||||||
|
vk::Queue mGraphicsQueue;
|
||||||
|
vk::Queue mPresentQueue;
|
||||||
|
|
||||||
|
vk::UniqueSurfaceKHR mSurface;
|
||||||
|
|
||||||
struct QueueFamilyIndices {
|
struct QueueFamilyIndices {
|
||||||
std::optional<u32> graphics_family;
|
std::optional<u32> graphics_family;
|
||||||
|
std::optional<u32> present_family;
|
||||||
|
|
||||||
fn isComplete() -> bool { return graphics_family.has_value(); }
|
fn isComplete() -> bool { return graphics_family.has_value() && present_family.has_value(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
void initWindow() {
|
fn initWindow() -> void {
|
||||||
glfwInit();
|
glfwInit();
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
|
@ -60,17 +69,19 @@ class VulkanApp {
|
||||||
mWindow = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
|
mWindow = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initVulkan() {
|
fn initVulkan() -> void {
|
||||||
createInstance();
|
createInstance();
|
||||||
setupDebugMessenger();
|
setupDebugMessenger();
|
||||||
|
createSurface();
|
||||||
pickPhysicalDevice();
|
pickPhysicalDevice();
|
||||||
|
createLogicalDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mainLoop() {
|
fn mainLoop() -> void {
|
||||||
while (!glfwWindowShouldClose(mWindow)) { glfwPollEvents(); }
|
while (!glfwWindowShouldClose(mWindow)) { glfwPollEvents(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup() {
|
fn cleanup() -> void {
|
||||||
glfwDestroyWindow(mWindow);
|
glfwDestroyWindow(mWindow);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
|
@ -114,7 +125,7 @@ class VulkanApp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupDebugMessenger() {
|
fn setupDebugMessenger() -> void {
|
||||||
if (!enableValidationLayers)
|
if (!enableValidationLayers)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -131,6 +142,20 @@ class VulkanApp {
|
||||||
mDebugMessenger = mInstance->createDebugUtilsMessengerEXTUnique(messengerCreateInfo, nullptr, mLoader);
|
mDebugMessenger = mInstance->createDebugUtilsMessengerEXTUnique(messengerCreateInfo, nullptr, mLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn createSurface() -> void {
|
||||||
|
VkSurfaceKHR surface = nullptr;
|
||||||
|
|
||||||
|
// FIXME: This is failing on macOS for some reason
|
||||||
|
VkResult result = glfwCreateWindowSurface(mInstance.get(), mWindow, nullptr, &surface);
|
||||||
|
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Failed to create window surface! Error code: " + string(magic_enum::enum_name(result))
|
||||||
|
);
|
||||||
|
|
||||||
|
mSurface = vk::UniqueSurfaceKHR(surface, mInstance.get());
|
||||||
|
}
|
||||||
|
|
||||||
fn pickPhysicalDevice() -> void {
|
fn pickPhysicalDevice() -> void {
|
||||||
std::vector<vk::PhysicalDevice> devices = mInstance->enumeratePhysicalDevices();
|
std::vector<vk::PhysicalDevice> devices = mInstance->enumeratePhysicalDevices();
|
||||||
|
|
||||||
|
@ -157,13 +182,42 @@ class VulkanApp {
|
||||||
throw std::runtime_error("Failed to find a suitable GPU!");
|
throw std::runtime_error("Failed to find a suitable GPU!");
|
||||||
}
|
}
|
||||||
|
|
||||||
static fn isDeviceSuitable(vk::PhysicalDevice device) -> bool {
|
fn createLogicalDevice() -> void {
|
||||||
|
QueueFamilyIndices indices = findQueueFamilies(mPhysicalDevice);
|
||||||
|
|
||||||
|
std::vector<vk::DeviceQueueCreateInfo> queueCreateInfos;
|
||||||
|
std::set<u32> uniqueQueueFamilies = { indices.graphics_family.value(), indices.present_family.value() };
|
||||||
|
|
||||||
|
f32 queuePriority = 1.0F;
|
||||||
|
|
||||||
|
for (u32 queueFamily : uniqueQueueFamilies) {
|
||||||
|
vk::DeviceQueueCreateInfo queueCreateInfo { .queueFamilyIndex = queueFamily,
|
||||||
|
.queueCount = 1,
|
||||||
|
.pQueuePriorities = &queuePriority };
|
||||||
|
|
||||||
|
queueCreateInfos.push_back(queueCreateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::PhysicalDeviceFeatures deviceFeatures;
|
||||||
|
|
||||||
|
vk::DeviceCreateInfo createInfo { .queueCreateInfoCount = static_cast<u32>(queueCreateInfos.size()),
|
||||||
|
.pQueueCreateInfos = queueCreateInfos.data(),
|
||||||
|
.enabledExtensionCount = 0,
|
||||||
|
.ppEnabledExtensionNames = nullptr,
|
||||||
|
.pEnabledFeatures = &deviceFeatures };
|
||||||
|
|
||||||
|
mDevice = mPhysicalDevice.createDeviceUnique(createInfo);
|
||||||
|
|
||||||
|
mGraphicsQueue = mDevice->getQueue(indices.graphics_family.value(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn isDeviceSuitable(vk::PhysicalDevice device) -> bool {
|
||||||
QueueFamilyIndices indices = findQueueFamilies(device);
|
QueueFamilyIndices indices = findQueueFamilies(device);
|
||||||
|
|
||||||
return indices.isComplete();
|
return indices.isComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
static fn findQueueFamilies(vk::PhysicalDevice device) -> QueueFamilyIndices {
|
fn findQueueFamilies(vk::PhysicalDevice device) -> QueueFamilyIndices {
|
||||||
QueueFamilyIndices indices;
|
QueueFamilyIndices indices;
|
||||||
|
|
||||||
std::vector<vk::QueueFamilyProperties> queueFamilies = device.getQueueFamilyProperties();
|
std::vector<vk::QueueFamilyProperties> queueFamilies = device.getQueueFamilyProperties();
|
||||||
|
@ -172,6 +226,11 @@ class VulkanApp {
|
||||||
if (queueFamilies[i].queueFlags & vk::QueueFlagBits::eGraphics)
|
if (queueFamilies[i].queueFlags & vk::QueueFlagBits::eGraphics)
|
||||||
indices.graphics_family = i;
|
indices.graphics_family = i;
|
||||||
|
|
||||||
|
vk::Bool32 presentSupport = device.getSurfaceSupportKHR(i, mSurface.get());
|
||||||
|
|
||||||
|
if (presentSupport)
|
||||||
|
indices.present_family = i;
|
||||||
|
|
||||||
if (indices.isComplete())
|
if (indices.isComplete())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +280,7 @@ class VulkanApp {
|
||||||
VkDebugUtilsMessageTypeFlagsEXT /*messageType*/,
|
VkDebugUtilsMessageTypeFlagsEXT /*messageType*/,
|
||||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||||
void* /*pUserData*/
|
void* /*pUserData*/
|
||||||
) -> VkBool32 {
|
) -> vk::Bool32 {
|
||||||
fmt::println("Validation layer: {}", pCallbackData->pMessage);
|
fmt::println("Validation layer: {}", pCallbackData->pMessage);
|
||||||
|
|
||||||
return VK_FALSE;
|
return VK_FALSE;
|
||||||
|
|
Loading…
Reference in a new issue