Boy this is messy, but for the love of god let surface config from the vulkan tutorial be over.
This commit is contained in:
parent
11887dae98
commit
ce1d58b086
5 changed files with 60 additions and 34 deletions
|
|
@ -1,12 +1,10 @@
|
||||||
#include "application.hpp"
|
#include "application.hpp"
|
||||||
#include "yave_vulkan_instance.hpp"
|
#include "yave_vulkan_instance.hpp"
|
||||||
#include "yave_vulkan_surface.hpp"
|
|
||||||
|
|
||||||
namespace yave {
|
namespace yave {
|
||||||
|
|
||||||
void Application::run() {
|
void Application::run() {
|
||||||
YaveVulkanInstance VI = YaveVulkanInstance();
|
YaveVulkanInstance VI = YaveVulkanInstance(&yaveWindow);
|
||||||
YaveVulkanSurface VS = YaveVulkanSurface(VI, yaveWindow);
|
|
||||||
|
|
||||||
while (!yaveWindow.shouldClose()) {
|
while (!yaveWindow.shouldClose()) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
#include "yave_vulkan_instance.hpp"
|
#include "yave_vulkan_instance.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <set>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
namespace yave {
|
namespace yave {
|
||||||
|
|
||||||
YaveVulkanInstance::YaveVulkanInstance() {
|
YaveVulkanInstance::YaveVulkanInstance(YaveWindow *window) : window(window) {
|
||||||
createInstance();
|
createInstance();
|
||||||
|
surface = new YaveVulkanSurface(*this, window);
|
||||||
pickPhysicalDevice();
|
pickPhysicalDevice();
|
||||||
createLogicalDevice();
|
createLogicalDevice();
|
||||||
}
|
}
|
||||||
YaveVulkanInstance::~YaveVulkanInstance() {
|
YaveVulkanInstance::~YaveVulkanInstance() {
|
||||||
destroyLogicalDevice();
|
destroyLogicalDevice();
|
||||||
|
delete surface;
|
||||||
destroyInstance();
|
destroyInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,41 +145,55 @@ YaveVulkanInstance::findQueueFamilies(VkPhysicalDevice device) {
|
||||||
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||||
indices.graphicsFamily = i;
|
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 we know we have support we don't need to look for anything more
|
||||||
if (indices.isComplete()) {
|
if (indices.isComplete()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return indices;
|
return indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void YaveVulkanInstance::createLogicalDevice() {
|
void YaveVulkanInstance::createLogicalDevice() {
|
||||||
QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
|
QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
|
||||||
|
|
||||||
// Only need a single queue as we can feed it with multiple threads and
|
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
|
||||||
// trigger it from the main thread to start off with.
|
std::set<uint32_t> uniqueQueueFamilies = {indices.graphicsFamily.value(),
|
||||||
|
indices.presentFamily.value()};
|
||||||
|
|
||||||
|
float queuePriority = 1.0f;
|
||||||
|
for (uint32_t queueFamily : uniqueQueueFamilies) {
|
||||||
VkDeviceQueueCreateInfo queueCreateInfo{};
|
VkDeviceQueueCreateInfo queueCreateInfo{};
|
||||||
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
queueCreateInfo.queueFamilyIndex = indices.graphicsFamily.value();
|
queueCreateInfo.queueFamilyIndex = queueFamily;
|
||||||
queueCreateInfo.queueCount = 1;
|
queueCreateInfo.queueCount = 1;
|
||||||
// Since we only have one queue it has all the priority.
|
|
||||||
float queuePriority = 1.0f;
|
|
||||||
queueCreateInfo.pQueuePriorities = &queuePriority;
|
queueCreateInfo.pQueuePriorities = &queuePriority;
|
||||||
|
queueCreateInfos.push_back(queueCreateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: set up device with interesting features as we use them
|
|
||||||
VkPhysicalDeviceFeatures deviceFeatures{};
|
VkPhysicalDeviceFeatures deviceFeatures{};
|
||||||
|
|
||||||
// Create logical device.
|
|
||||||
VkDeviceCreateInfo createInfo{};
|
VkDeviceCreateInfo createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
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;
|
createInfo.pEnabledFeatures = &deviceFeatures;
|
||||||
|
|
||||||
// TODO: Require specific features when we need some
|
|
||||||
// Device specific create information
|
|
||||||
createInfo.enabledExtensionCount = 0;
|
createInfo.enabledExtensionCount = 0;
|
||||||
|
|
||||||
if (enableValidationLayers) {
|
if (enableValidationLayers) {
|
||||||
createInfo.enabledLayerCount =
|
createInfo.enabledLayerCount =
|
||||||
static_cast<uint32_t>(validationLayers.size());
|
static_cast<uint32_t>(validationLayers.size());
|
||||||
|
|
@ -185,14 +202,13 @@ void YaveVulkanInstance::createLogicalDevice() {
|
||||||
createInfo.enabledLayerCount = 0;
|
createInfo.enabledLayerCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create logical device
|
|
||||||
if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) !=
|
if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) !=
|
||||||
VK_SUCCESS) {
|
VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create logical device!");
|
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.graphicsFamily.value(), 0, &graphicsQueue);
|
||||||
|
vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void YaveVulkanInstance::destroyLogicalDevice() {
|
void YaveVulkanInstance::destroyLogicalDevice() {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "yave_vulkan_surface.hpp"
|
||||||
|
#include "yave_window.hpp"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
@ -13,8 +15,11 @@ namespace yave {
|
||||||
|
|
||||||
struct QueueFamilyIndices {
|
struct QueueFamilyIndices {
|
||||||
std::optional<uint32_t> graphicsFamily;
|
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 {
|
class YaveVulkanInstance {
|
||||||
|
|
@ -24,6 +29,9 @@ private:
|
||||||
VkPhysicalDevice physicalDevice;
|
VkPhysicalDevice physicalDevice;
|
||||||
VkDevice device;
|
VkDevice device;
|
||||||
VkQueue graphicsQueue;
|
VkQueue graphicsQueue;
|
||||||
|
YaveVulkanSurface *surface;
|
||||||
|
YaveWindow *window;
|
||||||
|
VkQueue presentQueue;
|
||||||
|
|
||||||
// Vulkan instance
|
// Vulkan instance
|
||||||
void createInstance();
|
void createInstance();
|
||||||
|
|
@ -57,7 +65,7 @@ public:
|
||||||
YaveVulkanInstance &operator=(const YaveVulkanInstance &) = delete;
|
YaveVulkanInstance &operator=(const YaveVulkanInstance &) = delete;
|
||||||
|
|
||||||
VkInstance *getVkInstance() { return &instance; }
|
VkInstance *getVkInstance() { return &instance; }
|
||||||
YaveVulkanInstance();
|
YaveVulkanInstance(YaveWindow *window);
|
||||||
~YaveVulkanInstance();
|
~YaveVulkanInstance();
|
||||||
};
|
};
|
||||||
} // namespace yave
|
} // namespace yave
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,18 @@
|
||||||
namespace yave {
|
namespace yave {
|
||||||
|
|
||||||
YaveVulkanSurface::YaveVulkanSurface(YaveVulkanInstance &yaveVulkanInstance,
|
YaveVulkanSurface::YaveVulkanSurface(YaveVulkanInstance &yaveVulkanInstance,
|
||||||
YaveWindow &window) {
|
YaveWindow *window)
|
||||||
this->instance = yaveVulkanInstance.getVkInstance();
|
: instance(yaveVulkanInstance) {
|
||||||
if (glfwCreateWindowSurface(*instance, window.getGLFWWindow(), nullptr,
|
if (glfwCreateWindowSurface(*instance.getVkInstance(),
|
||||||
&surface)) {
|
window->getGLFWWindow(), nullptr, &surface)) {
|
||||||
throw std::runtime_error("failed to create window surface!");
|
throw std::runtime_error("failed to create window surface!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkSurfaceKHR *YaveVulkanSurface::getVkSurface() { return &this->surface; }
|
||||||
|
|
||||||
YaveVulkanSurface::~YaveVulkanSurface() {
|
YaveVulkanSurface::~YaveVulkanSurface() {
|
||||||
vkDestroySurfaceKHR(*instance, surface, nullptr);
|
vkDestroySurfaceKHR(*instance.getVkInstance(), surface, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace yave
|
} // namespace yave
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,28 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "yave_vulkan_instance.hpp"
|
|
||||||
#include "yave_window.hpp"
|
#include "yave_window.hpp"
|
||||||
#include <vulkan/vulkan_core.h>
|
|
||||||
|
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
namespace yave {
|
namespace yave {
|
||||||
|
|
||||||
|
class YaveVulkanInstance;
|
||||||
class YaveVulkanSurface {
|
class YaveVulkanSurface {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Keep reference to instance this surface is attached to
|
// Keep reference to instance this surface is attached to
|
||||||
VkInstance *instance;
|
YaveVulkanInstance &instance;
|
||||||
|
|
||||||
VkSurfaceKHR surface;
|
VkSurfaceKHR surface;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
YaveVulkanSurface(YaveVulkanInstance &yaveVulkanInstance, YaveWindow &window);
|
YaveVulkanSurface(YaveVulkanInstance &yaveVulkanInstance, YaveWindow *window);
|
||||||
~YaveVulkanSurface();
|
~YaveVulkanSurface();
|
||||||
//
|
|
||||||
|
VkSurfaceKHR *getVkSurface();
|
||||||
|
|
||||||
// Delete Copy constructors
|
// Delete Copy constructors
|
||||||
// This class should match one to one with vulkan instances
|
// This class should match one to one with vulkan instances
|
||||||
YaveVulkanSurface(const YaveVulkanSurface &) = delete;
|
YaveVulkanSurface(const YaveVulkanSurface &) = delete;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue