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
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <cstdlib>
|
||||
#include <fmt/format.h>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
|
||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "fmt/base.h"
|
||||
#include "util/magic_enum.hpp"
|
||||
#include "util/types.h"
|
||||
|
||||
namespace vk {
|
||||
|
@ -28,7 +30,7 @@ constexpr bool enableValidationLayers = true;
|
|||
|
||||
class VulkanApp {
|
||||
public:
|
||||
void run() {
|
||||
fn run() -> void {
|
||||
initWindow();
|
||||
initVulkan();
|
||||
mainLoop();
|
||||
|
@ -44,14 +46,21 @@ class VulkanApp {
|
|||
vk::DispatchLoaderDynamic mLoader;
|
||||
|
||||
vk::PhysicalDevice mPhysicalDevice;
|
||||
vk::UniqueDevice mDevice;
|
||||
|
||||
vk::Queue mGraphicsQueue;
|
||||
vk::Queue mPresentQueue;
|
||||
|
||||
vk::UniqueSurfaceKHR mSurface;
|
||||
|
||||
struct QueueFamilyIndices {
|
||||
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();
|
||||
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
|
@ -60,17 +69,19 @@ class VulkanApp {
|
|||
mWindow = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
|
||||
}
|
||||
|
||||
void initVulkan() {
|
||||
fn initVulkan() -> void {
|
||||
createInstance();
|
||||
setupDebugMessenger();
|
||||
createSurface();
|
||||
pickPhysicalDevice();
|
||||
createLogicalDevice();
|
||||
}
|
||||
|
||||
void mainLoop() {
|
||||
fn mainLoop() -> void {
|
||||
while (!glfwWindowShouldClose(mWindow)) { glfwPollEvents(); }
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
fn cleanup() -> void {
|
||||
glfwDestroyWindow(mWindow);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
@ -114,7 +125,7 @@ class VulkanApp {
|
|||
}
|
||||
}
|
||||
|
||||
void setupDebugMessenger() {
|
||||
fn setupDebugMessenger() -> void {
|
||||
if (!enableValidationLayers)
|
||||
return;
|
||||
|
||||
|
@ -131,6 +142,20 @@ class VulkanApp {
|
|||
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 {
|
||||
std::vector<vk::PhysicalDevice> devices = mInstance->enumeratePhysicalDevices();
|
||||
|
||||
|
@ -157,13 +182,42 @@ class VulkanApp {
|
|||
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);
|
||||
|
||||
return indices.isComplete();
|
||||
}
|
||||
|
||||
static fn findQueueFamilies(vk::PhysicalDevice device) -> QueueFamilyIndices {
|
||||
fn findQueueFamilies(vk::PhysicalDevice device) -> QueueFamilyIndices {
|
||||
QueueFamilyIndices indices;
|
||||
|
||||
std::vector<vk::QueueFamilyProperties> queueFamilies = device.getQueueFamilyProperties();
|
||||
|
@ -172,6 +226,11 @@ class VulkanApp {
|
|||
if (queueFamilies[i].queueFlags & vk::QueueFlagBits::eGraphics)
|
||||
indices.graphics_family = i;
|
||||
|
||||
vk::Bool32 presentSupport = device.getSurfaceSupportKHR(i, mSurface.get());
|
||||
|
||||
if (presentSupport)
|
||||
indices.present_family = i;
|
||||
|
||||
if (indices.isComplete())
|
||||
break;
|
||||
}
|
||||
|
@ -221,7 +280,7 @@ class VulkanApp {
|
|||
VkDebugUtilsMessageTypeFlagsEXT /*messageType*/,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* /*pUserData*/
|
||||
) -> VkBool32 {
|
||||
) -> vk::Bool32 {
|
||||
fmt::println("Validation layer: {}", pCallbackData->pMessage);
|
||||
|
||||
return VK_FALSE;
|
||||
|
|
Loading…
Reference in a new issue