Skip to content
Snippets Groups Projects
Commit 10ef2441 authored by Sebastian Gaida's avatar Sebastian Gaida
Browse files

[#16] adjust to core class after merge-conflicts

adjusted swapchain and window class after the big mess of the core class :)
added temporarily utils functions to core class
parent b89e838e
No related branches found
No related tags found
4 merge requests!12Resolve "Swapchain Class",!7Resolve "Shader Program Class",!5Resolve "Pipeline State Object",!4Resolve "Renderpass Class"
Pipeline #24689 passed
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include "vkcv/Context.hpp" #include "vkcv/Context.hpp"
#include "vkcv/Handles.hpp" #include "vkcv/Handles.hpp"
#include <GLFW/glfw3.h>
namespace vkcv namespace vkcv
{ {
...@@ -97,4 +98,30 @@ namespace vkcv ...@@ -97,4 +98,30 @@ namespace vkcv
PipelineHandle createPipeline(const Pipeline &pipeline); PipelineHandle createPipeline(const Pipeline &pipeline);
}; };
/**
* initializes glfw once and increases the counter
*/
void initGLFW();
/**
* terminates glfw once, if it was initialized or decreases the counter
*/
void terminateGLFW();
/**
* gets the window width
* @param window glfwWindow
* @return int with window width
*/
[[nodiscard]]
int getWidth(GLFWwindow *window);
/**
* gets the window height
* @param window glfwWindow
* @return int with window height
*/
[[nodiscard]]
int getHeight(GLFWwindow *window);
} }
#pragma once #pragma once
#include "vulkan/vulkan.hpp" #include "vulkan/vulkan.hpp"
#include "Context.hpp" #include "Core.hpp"
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <iostream> #include <iostream>
...@@ -13,15 +13,9 @@ namespace vkcv { ...@@ -13,15 +13,9 @@ namespace vkcv {
private: private:
vk::SurfaceKHR m_surface; vk::SurfaceKHR m_surface;
const vkcv::Context* m_context; const vkcv::Core* m_core;
SwapChain(vk::SurfaceKHR surface, const vkcv::Context* context); SwapChain(vk::SurfaceKHR surface, const vkcv::Core* core);
static vk::SurfaceFormatKHR chooseSwapSurfaceFormat(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface);
static vk::PresentModeKHR choosePresentMode(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface);
static vk::Extent2D chooseSwapExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, GLFWwindow* window );
public: public:
// bin mir grade unsicher wegen der Mehrfachinstanziierung der Klasse // bin mir grade unsicher wegen der Mehrfachinstanziierung der Klasse
...@@ -29,8 +23,7 @@ namespace vkcv { ...@@ -29,8 +23,7 @@ namespace vkcv {
SwapChain(const SwapChain &other) = delete; SwapChain(const SwapChain &other) = delete;
SwapChain(SwapChain &&other) = default; SwapChain(SwapChain &&other) = default;
static SwapChain create(GLFWwindow *window, const vkcv::Context* Context); static SwapChain create(GLFWwindow *window, const vkcv::Core* core);
static vk::SurfaceKHR createSurface(GLFWwindow *window, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice);
virtual ~SwapChain(); virtual ~SwapChain();
}; };
......
...@@ -34,7 +34,7 @@ namespace vkcv { ...@@ -34,7 +34,7 @@ namespace vkcv {
* @param[in] resizable resize ability of the window (optional) * @param[in] resizable resize ability of the window (optional)
* @return Window class * @return Window class
*/ */
static Window create(const vkcv::Context& context, const char *windowTitle, int width = -1, int height = -1, bool resizable = false); static Window create(const vkcv::Core& core, const char *windowTitle, int width = -1, int height = -1, bool resizable = false);
/** /**
* checks if the window is still open, or the close event was called * checks if the window is still open, or the close event was called
* This function should be changed/removed later on * This function should be changed/removed later on
......
...@@ -20,7 +20,7 @@ int main(int argc, const char** argv) { ...@@ -20,7 +20,7 @@ int main(int argc, const char** argv) {
const vk::Device& device = context.getDevice(); const vk::Device& device = context.getDevice();
vkcv::Window window = vkcv::Window::create( vkcv::Window window = vkcv::Window::create(
context, core,
applicationName, applicationName,
800, 800,
600, 600,
......
...@@ -146,6 +146,38 @@ namespace vkcv ...@@ -146,6 +146,38 @@ namespace vkcv
return true; return true;
} }
std::vector<const char*> getRequiredExtensions() {
uint32_t glfwExtensionCount = 0;
const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
std::vector<const char*> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
#ifndef NDEBUG
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
#endif
return extensions;
}
/**
* @brief finds an queue family index that fits with the given queue flags to create a queue handle
* @param flag The given flag that specifies as which queue type the accessed queue should be treated
* @param createInfos The createInfos of the created queues depending on the logical device
* @param device The physical with which the queue families can be accessed
* @return a fitting queue family index
*/
int findQueueFamilyIndex(vk::QueueFlagBits flag, std::vector<vk::DeviceQueueCreateInfo> &createInfos, vk::PhysicalDevice &device){
std::vector<vk::QueueFamilyProperties> queueFamilyProperties = device.getQueueFamilyProperties();
for (auto i = createInfos.begin(); i != createInfos.end(); ++i ) {
auto createInfo = *i;
int index = createInfo.queueFamilyIndex;
if(static_cast<uint32_t>(queueFamilyProperties[index].queueFlags & flag) != 0){
return index;
}
}
return -1;
}
Core Core::create(const char *applicationName, Core Core::create(const char *applicationName,
uint32_t applicationVersion, uint32_t applicationVersion,
uint32_t queueCount, uint32_t queueCount,
...@@ -153,7 +185,7 @@ namespace vkcv ...@@ -153,7 +185,7 @@ namespace vkcv
std::vector<const char *> instanceExtensions, std::vector<const char *> instanceExtensions,
std::vector<const char *> deviceExtensions) std::vector<const char *> deviceExtensions)
{ {
vkcv::initGLFW();
// check for layer support // check for layer support
const std::vector<vk::LayerProperties>& layerProperties = vk::enumerateInstanceLayerProperties(); const std::vector<vk::LayerProperties>& layerProperties = vk::enumerateInstanceLayerProperties();
...@@ -190,9 +222,9 @@ namespace vkcv ...@@ -190,9 +222,9 @@ namespace vkcv
throw std::runtime_error("The requested instance extensions are not supported!"); throw std::runtime_error("The requested instance extensions are not supported!");
} }
#ifndef NDEBUG // for GLFW: get all required extensions
instanceExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); std::vector<const char*> requiredExtensions = getRequiredExtensions();
#endif instanceExtensions.insert(instanceExtensions.end(), requiredExtensions.begin(), requiredExtensions.end());
const vk::ApplicationInfo applicationInfo( const vk::ApplicationInfo applicationInfo(
applicationName, applicationName,
...@@ -256,7 +288,23 @@ namespace vkcv ...@@ -256,7 +288,23 @@ namespace vkcv
vk::Device device = physicalDevice.createDevice(deviceCreateInfo); vk::Device device = physicalDevice.createDevice(deviceCreateInfo);
// TODO: implement device.getQueue() to access the queues, if needed
uint32_t graphicsQueueFamilyIndex = findQueueFamilyIndex({vk::QueueFlagBits::eGraphics}, qCreateInfos, physicalDevice);
if(graphicsQueueFamilyIndex == -1){
throw std::runtime_error("It is not possible to access another queue as a graphics queue.");
}
uint32_t computeQueueFamilyIndex = findQueueFamilyIndex({vk::QueueFlagBits::eCompute}, qCreateInfos, physicalDevice);
if(computeQueueFamilyIndex == -1){
throw std::runtime_error("It is not possible to access another queue as a compute queue.");
}
uint32_t transferQueueFamilyIndex = findQueueFamilyIndex({vk::QueueFlagBits::eTransfer}, qCreateInfos, physicalDevice);
if(transferQueueFamilyIndex == -1){
throw std::runtime_error("It is not possible to access another queue as a transfer queue.");
}
vk::Queue graphicsQueue = device.getQueue( graphicsQueueFamilyIndex, 0 );
vk::Queue computeQueue = device.getQueue(computeQueueFamilyIndex,1);
vk::Queue transferQueue = device.getQueue(transferQueueFamilyIndex,2);
Context context(instance, physicalDevice, device); Context context(instance, physicalDevice, device);
return Core(std::move(context)); return Core(std::move(context));
...@@ -270,4 +318,37 @@ namespace vkcv ...@@ -270,4 +318,37 @@ namespace vkcv
Core::Core(Context &&context) noexcept : Core::Core(Context &&context) noexcept :
m_Context(std::move(context)) m_Context(std::move(context))
{} {}
int glfwCounter = 0;
void initGLFW() {
if (glfwCounter == 0) {
int glfwSuccess = glfwInit();
if (glfwSuccess == GLFW_FALSE) {
throw std::runtime_error("Could not initialize GLFW");
}
}
glfwCounter++;
}
void terminateGLFW() {
if (glfwCounter == 1) {
glfwTerminate();
}
glfwCounter--;
}
int getWidth(GLFWwindow *window) {
int width;
glfwGetWindowSize(window, &width, nullptr);
return width;
}
int getHeight(GLFWwindow *window) {
int height;
glfwGetWindowSize(window, nullptr, &height);
return height;
}
} }
#include "/vkcv/SwapChain.hpp"
#include <vkcv/SwapChain.hpp>
namespace vkcv { namespace vkcv {
SwapChain::SwapChain(vk::SurfaceKHR surface, const vkcv::Context* context) SwapChain::SwapChain(vk::SurfaceKHR surface, const vkcv::Core* core)
: m_surface(surface), m_context(context) : m_surface(surface), m_core(core)
{} {}
SwapChain SwapChain::create(GLFWwindow* window, const vkcv::Context* context){ vk::SurfaceKHR createSurface(GLFWwindow *window, const vk::Instance &instance, const vk::PhysicalDevice& physicalDevice) {
//create surface
const vk::Instance& instance = context->getInstance(); VkSurfaceKHR surface;
const vk::PhysicalDevice& physicalDevice = context->getPhysicalDevice(); // 0 means VK_SUCCESS
const vk::Device& device = context->getDevice(); //std::cout << "FAIL: " << glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &newSurface) << std::endl;
if(glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &surface) != VK_SUCCESS) {
vk::SurfaceKHR surface = createSurface(window,instance,physicalDevice); throw std::runtime_error("failed to create a window surface!");
}
vk::Extent2D extent2D = chooseSwapExtent(physicalDevice, surface, window); vk::Bool32 surfaceSupport = false;
vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(physicalDevice, surface); // ToDo: hierfuer brauchen wir jetzt den queuefamiliy Index -> siehe ToDo in Context.cpp
vk::PresentModeKHR presentMode = choosePresentMode(physicalDevice, surface); //if(physicalDevice.getSurfaceSupportKHR())
// vk::SwapchainCreateInfoKHR swapchainCreateInfo(
// vk::SwapchainCreateFlagBitsKHR()
// VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // VkStructureType sType
// nullptr, // const void *pNext
// 0, // VkSwapchainCreateFlagsKHR flags
// surface, // VkSurfaceKHR surface
// desired_number_of_images, // uint32_t minImageCount
// desired_format.format, // VkFormat imageFormat
// desired_format.colorSpace, // VkColorSpaceKHR imageColorSpace
// desired_extent, // VkExtent2D imageExtent
// 1, // uint32_t imageArrayLayers
// desired_usage, // VkImageUsageFlags imageUsage
// VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode
// 0, // uint32_t queueFamilyIndexCount
// nullptr, // const uint32_t *pQueueFamilyIndices
// desired_transform, // VkSurfaceTransformFlagBitsKHR preTransform
// VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha
// desired_present_mode, // VkPresentModeKHR presentMode
// VK_TRUE, // VkBool32 clipped
// old_swap_chain // VkSwapchainKHR oldSwapchain
// );
// vk::SwapchainCreateInfoKHR swapchainCreateInfo(
// vk::SwapchainCreateFlagsKHR(), //flags
// surface, // surface
// surfaceCapabilities.minImageCount, // minImageCount TODO: how many do we need for our application?? "must be less than or equal to the value returned in maxImageCount"
// vk::Format::eB8G8R8A8Unorm, // imageFormat TODO: what image format should be used?
// vk::ColorSpaceKHR::eSrgbNonlinear, // imageColorSpace TODO: which color space should be used?
// vk::Extent2D(width, height), // imageExtent
// 1, // imageArrayLayers TODO: should we only allow non-stereoscopic applications? yes -> 1, no -> ? "must be greater than 0, less or equal to maxImageArrayLayers"
// vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eDepthStencilAttachment, // imageUsage TODO: what attachments? only color? depth?
// vk::SharingMode::eExclusive, // imageSharingMode TODO: which sharing mode? "VK_SHARING_MODE_EXCLUSIV access exclusive to a single queue family, better performance", "VK_SHARING_MODE_CONCURRENT access from multiple queues"
// 0, // queueFamilyIndexCount, the number of queue families having access to the image(s) of the swapchain when imageSharingMode is VK_SHARING_MODE_CONCURRENT
// nullptr, // pQueueFamilyIndices, the pointer to an array of queue family indices having access to the images(s) of the swapchain when imageSharingMode is VK_SHARING_MODE_CONCURRENT
// vk::SurfaceTransformFlagBitsKHR::eIdentity, // preTransform, transformations applied onto the image before display
// vk::CompositeAlphaFlagBitsKHR::eOpaque, // compositeAlpha, TODO: how to handle transparent pixels? do we need transparency? If no -> opaque
// vk::PresentModeKHR::eFifo, // presentMode
// true, // clipped
// nullptr // oldSwapchain
// );
return SwapChain(surface, context);
}
vk::SurfaceKHR SwapChain::createSurface(GLFWwindow *window, const vk::Instance &instance, const vk::PhysicalDevice& physicalDevice) {
//create surface
VkSurfaceKHR surface;
// 0 means VK_SUCCESS
//std::cout << "FAIL: " << glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &newSurface) << std::endl;
if(glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &surface) != VK_SUCCESS) {
throw std::runtime_error("failed to create a window surface!");
}
vk::Bool32 surfaceSupport = false;
// ToDo: hierfuer brauchen wir jetzt den queuefamiliy Index -> siehe ToDo in Context.cpp
//if(physicalDevice.getSurfaceSupportKHR())
return vk::SurfaceKHR(surface); return vk::SurfaceKHR(surface);
} }
vk::Extent2D SwapChain::chooseSwapExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, GLFWwindow* window){ vk::Extent2D chooseSwapExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, GLFWwindow* window){
vk::SurfaceCapabilitiesKHR surfaceCapabilities; vk::SurfaceCapabilitiesKHR surfaceCapabilities;
if(physicalDevice.getSurfaceCapabilitiesKHR(surface,&surfaceCapabilities) != vk::Result::eSuccess){ if(physicalDevice.getSurfaceCapabilitiesKHR(surface,&surfaceCapabilities) != vk::Result::eSuccess){
throw std::runtime_error("cannot get surface capabilities. There is an issue with the surface."); throw std::runtime_error("cannot get surface capabilities. There is an issue with the surface.");
...@@ -100,7 +43,7 @@ namespace vkcv { ...@@ -100,7 +43,7 @@ namespace vkcv {
return extent2D; return extent2D;
} }
vk::SurfaceFormatKHR SwapChain::chooseSwapSurfaceFormat(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) { vk::SurfaceFormatKHR chooseSwapSurfaceFormat(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) {
uint32_t formatCount; uint32_t formatCount;
physicalDevice.getSurfaceFormatsKHR(surface, &formatCount, nullptr); physicalDevice.getSurfaceFormatsKHR(surface, &formatCount, nullptr);
std::vector<vk::SurfaceFormatKHR> availableFormats(formatCount); std::vector<vk::SurfaceFormatKHR> availableFormats(formatCount);
...@@ -116,7 +59,7 @@ namespace vkcv { ...@@ -116,7 +59,7 @@ namespace vkcv {
return availableFormats[0]; return availableFormats[0];
} }
vk::PresentModeKHR SwapChain::choosePresentMode(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) { vk::PresentModeKHR choosePresentMode(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) {
uint32_t modeCount; uint32_t modeCount;
physicalDevice.getSurfacePresentModesKHR( surface, &modeCount, nullptr ); physicalDevice.getSurfacePresentModesKHR( surface, &modeCount, nullptr );
std::vector<vk::PresentModeKHR> availablePresentModes(modeCount); std::vector<vk::PresentModeKHR> availablePresentModes(modeCount);
...@@ -132,9 +75,67 @@ namespace vkcv { ...@@ -132,9 +75,67 @@ namespace vkcv {
return vk::PresentModeKHR::eFifo; return vk::PresentModeKHR::eFifo;
} }
SwapChain SwapChain::create(GLFWwindow* window, const vkcv::Core* core){
const vk::Instance& instance = core->getContext().getInstance();
const vk::PhysicalDevice& physicalDevice = core->getContext().getPhysicalDevice();
const vk::Device& device = core->getContext().getDevice();
vk::SurfaceKHR surface = createSurface(window,instance,physicalDevice);
vk::Extent2D extent2D = chooseSwapExtent(physicalDevice, surface, window);
vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(physicalDevice, surface);
vk::PresentModeKHR presentMode = choosePresentMode(physicalDevice, surface);
// vk::SwapchainCreateInfoKHR swapchainCreateInfo(
// vk::SwapchainCreateFlagBitsKHR()
// VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // VkStructureType sType
// nullptr, // const void *pNext
// 0, // VkSwapchainCreateFlagsKHR flags
// surface, // VkSurfaceKHR surface
// desired_number_of_images, // uint32_t minImageCount
// desired_format.format, // VkFormat imageFormat
// desired_format.colorSpace, // VkColorSpaceKHR imageColorSpace
// desired_extent, // VkExtent2D imageExtent
// 1, // uint32_t imageArrayLayers
// desired_usage, // VkImageUsageFlags imageUsage
// VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode
// 0, // uint32_t queueFamilyIndexCount
// nullptr, // const uint32_t *pQueueFamilyIndices
// desired_transform, // VkSurfaceTransformFlagBitsKHR preTransform
// VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha
// desired_present_mode, // VkPresentModeKHR presentMode
// VK_TRUE, // VkBool32 clipped
// old_swap_chain // VkSwapchainKHR oldSwapchain
// );
// vk::SwapchainCreateInfoKHR swapchainCreateInfo(
// vk::SwapchainCreateFlagsKHR(), //flags
// surface, // surface
// surfaceCapabilities.minImageCount, // minImageCount TODO: how many do we need for our application?? "must be less than or equal to the value returned in maxImageCount"
// vk::Format::eB8G8R8A8Unorm, // imageFormat TODO: what image format should be used?
// vk::ColorSpaceKHR::eSrgbNonlinear, // imageColorSpace TODO: which color space should be used?
// vk::Extent2D(width, height), // imageExtent
// 1, // imageArrayLayers TODO: should we only allow non-stereoscopic applications? yes -> 1, no -> ? "must be greater than 0, less or equal to maxImageArrayLayers"
// vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eDepthStencilAttachment, // imageUsage TODO: what attachments? only color? depth?
// vk::SharingMode::eExclusive, // imageSharingMode TODO: which sharing mode? "VK_SHARING_MODE_EXCLUSIV access exclusive to a single queue family, better performance", "VK_SHARING_MODE_CONCURRENT access from multiple queues"
// 0, // queueFamilyIndexCount, the number of queue families having access to the image(s) of the swapchain when imageSharingMode is VK_SHARING_MODE_CONCURRENT
// nullptr, // pQueueFamilyIndices, the pointer to an array of queue family indices having access to the images(s) of the swapchain when imageSharingMode is VK_SHARING_MODE_CONCURRENT
// vk::SurfaceTransformFlagBitsKHR::eIdentity, // preTransform, transformations applied onto the image before display
// vk::CompositeAlphaFlagBitsKHR::eOpaque, // compositeAlpha, TODO: how to handle transparent pixels? do we need transparency? If no -> opaque
// vk::PresentModeKHR::eFifo, // presentMode
// true, // clipped
// nullptr // oldSwapchain
// );
return SwapChain(surface, core);
}
SwapChain::~SwapChain() { SwapChain::~SwapChain() {
// m_context->getDevice().destroySwapchainKHR( m_swapChain ); // m_context->getDevice().destroySwapchainKHR( m_swapChain );
m_context->getInstance().destroySurfaceKHR( m_surface ); m_core->getContext().getInstance().destroySurfaceKHR( m_surface );
} }
} }
...@@ -19,13 +19,11 @@ namespace vkcv { ...@@ -19,13 +19,11 @@ namespace vkcv {
glfwDestroyWindow(m_window); glfwDestroyWindow(m_window);
s_WindowCount--; s_WindowCount--;
if(s_WindowCount == 0) terminateGLFW();
glfwTerminate();
} }
Window Window::create(const char *windowTitle, int width, int height, bool resizable) { Window Window::create(const vkcv::Core& core, const char *windowTitle, int width, int height, bool resizable) {
if(s_WindowCount == 0) initGLFW();
glfwInit();
s_WindowCount++; s_WindowCount++;
...@@ -39,7 +37,7 @@ namespace vkcv { ...@@ -39,7 +37,7 @@ namespace vkcv {
const vkcv::SwapChain swapChain = vkcv::SwapChain::create( const vkcv::SwapChain swapChain = vkcv::SwapChain::create(
window, window,
&context); &core);
return Window(window, &swapChain); return Window(window, &swapChain);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment