Boy this is messy, but for the love of god let surface config from the vulkan tutorial be over.

This commit is contained in:
Warwick 2024-05-02 15:54:48 +01:00
parent 11887dae98
commit ce1d58b086
5 changed files with 60 additions and 34 deletions

View file

@ -1,12 +1,10 @@
#include "application.hpp"
#include "yave_vulkan_instance.hpp"
#include "yave_vulkan_surface.hpp"
namespace yave {
void Application::run() {
YaveVulkanInstance VI = YaveVulkanInstance();
YaveVulkanSurface VS = YaveVulkanSurface(VI, yaveWindow);
YaveVulkanInstance VI = YaveVulkanInstance(&yaveWindow);
while (!yaveWindow.shouldClose()) {
glfwPollEvents();

View file

@ -1,16 +1,19 @@
#include "yave_vulkan_instance.hpp"
#include <cstdint>
#include <set>
#include <vulkan/vulkan_core.h>
namespace yave {
YaveVulkanInstance::YaveVulkanInstance() {
YaveVulkanInstance::YaveVulkanInstance(YaveWindow *window) : window(window) {
createInstance();
surface = new YaveVulkanSurface(*this, window);
pickPhysicalDevice();
createLogicalDevice();
}
YaveVulkanInstance::~YaveVulkanInstance() {
destroyLogicalDevice();
delete surface;
destroyInstance();
}
@ -142,41 +145,55 @@ YaveVulkanInstance::findQueueFamilies(VkPhysicalDevice device) {
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
indices.graphicsFamily = i;
}
VkBool32 presentSupport = false;
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, *surface->getVkSurface(),
&presentSupport);
if (presentSupport) {
indices.presentFamily = i;
}
// If we know we have support we don't need to look for anything more
if (indices.isComplete()) {
break;
}
i++;
}
return indices;
}
void YaveVulkanInstance::createLogicalDevice() {
QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
// Only need a single queue as we can feed it with multiple threads and
// trigger it from the main thread to start off with.
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 = indices.graphicsFamily.value();
queueCreateInfo.queueFamilyIndex = queueFamily;
queueCreateInfo.queueCount = 1;
// Since we only have one queue it has all the priority.
float queuePriority = 1.0f;
queueCreateInfo.pQueuePriorities = &queuePriority;
queueCreateInfos.push_back(queueCreateInfo);
}
// TODO: set up device with interesting features as we use them
VkPhysicalDeviceFeatures deviceFeatures{};
// Create logical device.
VkDeviceCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.pQueueCreateInfos = &queueCreateInfo;
createInfo.queueCreateInfoCount = 1;
createInfo.queueCreateInfoCount =
static_cast<uint32_t>(queueCreateInfos.size());
createInfo.pQueueCreateInfos = queueCreateInfos.data();
createInfo.pEnabledFeatures = &deviceFeatures;
// TODO: Require specific features when we need some
// Device specific create information
createInfo.enabledExtensionCount = 0;
if (enableValidationLayers) {
createInfo.enabledLayerCount =
static_cast<uint32_t>(validationLayers.size());
@ -185,14 +202,13 @@ void YaveVulkanInstance::createLogicalDevice() {
createInfo.enabledLayerCount = 0;
}
// Create logical device
if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) !=
VK_SUCCESS) {
throw std::runtime_error("failed to create logical device!");
}
// Whilst we're here we might as well set up our queue
vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
}
void YaveVulkanInstance::destroyLogicalDevice() {

View file

@ -1,5 +1,7 @@
#pragma once
#include "yave_vulkan_surface.hpp"
#include "yave_window.hpp"
#include <cstring>
#include <optional>
#include <stdexcept>
@ -13,8 +15,11 @@ namespace yave {
struct QueueFamilyIndices {
std::optional<uint32_t> graphicsFamily;
std::optional<uint32_t> presentFamily;
bool isComplete() { return graphicsFamily.has_value(); }
bool isComplete() {
return graphicsFamily.has_value() && presentFamily.has_value();
}
};
class YaveVulkanInstance {
@ -24,6 +29,9 @@ private:
VkPhysicalDevice physicalDevice;
VkDevice device;
VkQueue graphicsQueue;
YaveVulkanSurface *surface;
YaveWindow *window;
VkQueue presentQueue;
// Vulkan instance
void createInstance();
@ -56,8 +64,8 @@ public:
YaveVulkanInstance(const YaveVulkanInstance &) = delete;
YaveVulkanInstance &operator=(const YaveVulkanInstance &) = delete;
VkInstance *getVkInstance(){return &instance;}
YaveVulkanInstance();
VkInstance *getVkInstance() { return &instance; }
YaveVulkanInstance(YaveWindow *window);
~YaveVulkanInstance();
};
} // namespace yave

View file

@ -7,16 +7,18 @@
namespace yave {
YaveVulkanSurface::YaveVulkanSurface(YaveVulkanInstance &yaveVulkanInstance,
YaveWindow &window) {
this->instance = yaveVulkanInstance.getVkInstance();
if (glfwCreateWindowSurface(*instance, window.getGLFWWindow(), nullptr,
&surface)) {
YaveWindow *window)
: instance(yaveVulkanInstance) {
if (glfwCreateWindowSurface(*instance.getVkInstance(),
window->getGLFWWindow(), nullptr, &surface)) {
throw std::runtime_error("failed to create window surface!");
}
}
VkSurfaceKHR *YaveVulkanSurface::getVkSurface() { return &this->surface; }
YaveVulkanSurface::~YaveVulkanSurface() {
vkDestroySurfaceKHR(*instance, surface, nullptr);
vkDestroySurfaceKHR(*instance.getVkInstance(), surface, nullptr);
}
} // namespace yave

View file

@ -1,26 +1,28 @@
#pragma once
#include "yave_vulkan_instance.hpp"
#include "yave_window.hpp"
#include <vulkan/vulkan_core.h>
#include <vulkan/vulkan_core.h>
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
namespace yave {
class YaveVulkanInstance;
class YaveVulkanSurface {
private:
// Keep reference to instance this surface is attached to
VkInstance *instance;
YaveVulkanInstance &instance;
VkSurfaceKHR surface;
public:
YaveVulkanSurface(YaveVulkanInstance &yaveVulkanInstance, YaveWindow &window);
YaveVulkanSurface(YaveVulkanInstance &yaveVulkanInstance, YaveWindow *window);
~YaveVulkanSurface();
//
VkSurfaceKHR *getVkSurface();
// Delete Copy constructors
// This class should match one to one with vulkan instances
YaveVulkanSurface(const YaveVulkanSurface &) = delete;