diff --git a/config/Sources.cmake b/config/Sources.cmake index 0f2c2cf7019f07a44b5fd067f1b7fe38c4db5bc6..784562debdfb485b86e283dc765eca82d352d1b5 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -36,4 +36,10 @@ set(vkcv_sources ${vkcv_include}/vkcv/SyncResources.hpp ${vkcv_source}/vkcv/SyncResources.cpp + + ${vkcv_include}/vkcv/Queues.hpp + ${vkcv_source}/vkcv/Queues.cpp + + ${vkcv_source}/vkcv/Surface.hpp + ${vkcv_source}/vkcv/Surface.cpp ) diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 7cdb50fc50d437e1ec443f9df71621551cb2a553..57c28ee71ff2b1b547361189ecb5e8975abf3993 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -15,6 +15,7 @@ #include "vkcv/PipelineConfig.hpp" #include "CommandResources.hpp" #include "SyncResources.hpp" +#include "vkcv/Queues.hpp" namespace vkcv { @@ -35,7 +36,7 @@ namespace vkcv * @param context encapsulates various Vulkan objects */ Core(Context &&context, const Window &window, SwapChain swapChain, std::vector<vk::ImageView> imageViews, - const CommandResources& commandResources, const SyncResources& syncResources) noexcept; + const CommandResources& commandResources, const SyncResources& syncResources, const VulkanQueues &queues) noexcept; // explicit destruction of default constructor Core() = delete; @@ -53,6 +54,7 @@ namespace vkcv std::unique_ptr<PipelineManager> m_PipelineManager; CommandResources m_CommandResources; SyncResources m_SyncResources; + VulkanQueues m_Queues; public: /** * Destructor of #Core destroys the Vulkan objects contained in the core's context. @@ -139,5 +141,19 @@ namespace vkcv // TODO: BufferHandle createBuffer(const Buffer &buf); + /** + * @brief start recording command buffers and increment frame index + */ + void beginFrame(); + + /** + * @brief render a beautiful triangle + */ + void renderTriangle(); + + /** + * @brief end recording and present image + */ + void endFrame(); }; } diff --git a/include/vkcv/Queues.hpp b/include/vkcv/Queues.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9b6cbae005515eb0c5754d8df8b22038eb5a81b0 --- /dev/null +++ b/include/vkcv/Queues.hpp @@ -0,0 +1,26 @@ +#pragma once +#include <vulkan/vulkan.hpp> + +namespace vkcv { + struct VulkanQueues { + vk::Queue graphicsQueue; + vk::Queue computeQueue; + vk::Queue transferQueue; + vk::Queue presentQueue; + }; + + struct QueueFamilyIndices { + int graphicsIndex = -1; + int computeIndex = -1; + int transferIndex = -1; + int presentIndex = -1; + }; + + VulkanQueues getDeviceQueues(const vk::Device& device, const QueueFamilyIndices& familyIndices); + + QueueFamilyIndices getQueueFamilyIndices(const vk::PhysicalDevice& physicalDevice, const vk::SurfaceKHR surface); + + // TODO: try to use specialised queues + std::vector<vk::DeviceQueueCreateInfo> createDeviceQueueCreateInfo(const QueueFamilyIndices& indices); + +} diff --git a/include/vkcv/SwapChain.hpp b/include/vkcv/SwapChain.hpp index 15633badd4c6a3aef9766049317f3f5c8382bab8..91d2ccbbafdd30fb744a40231414782d4d9a9f1f 100644 --- a/include/vkcv/SwapChain.hpp +++ b/include/vkcv/SwapChain.hpp @@ -52,7 +52,7 @@ namespace vkcv { * @param context of the application * @return returns an object of swapChain */ - static SwapChain create(const Window &window, const Context &context); + static SwapChain create(const Window &window, const Context &context, const vk::SurfaceKHR surface); /** * Destructor of SwapChain diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index e725c83ae44c71cc9184f5c2b0f0779e7b562732..0e567db7233fe0f778412a2bd043ed399d4a2e97 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -87,11 +87,9 @@ int main(int argc, const char** argv) { while (window.isWindowOpen()) { - // core.beginFrame(); or something like that + core.beginFrame(); // core.execute(trianglePass, trianglePipeline, triangleModel); - // core.endFrame(); or something like that - - // TBD: synchronization + core.endFrame(); window.pollEvents(); } diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index e10c593b5753ff34c551807d6c21101cdf9bef07..30d5076908e5becd210c173c83efc1b8433e7468 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -7,6 +7,7 @@ #include "vkcv/Core.hpp" #include "PassManager.hpp" #include "PipelineManager.hpp" +#include "Surface.hpp" namespace vkcv { @@ -79,173 +80,6 @@ namespace vkcv return phyDevice; } - - /** - * Given the @p physicalDevice and the @p queuePriorities, the @p queueCreateInfos are computed. First, the requested - * queues are sorted by priority depending on the availability of queues in the queue families of the given - * @p physicalDevice. Then check, if all requested queues are creatable. If so, the @p queueCreateInfos will be computed. - * Furthermore, lists of index pairs (queueFamilyIndex, queueIndex) for later referencing of the separate queues will - * be computed. - * @param[in] physicalDevice The physical device - * @param[in] queuePriorities The queue priorities used for the computation of @p queueCreateInfos - * @param[in] queueFlags The queue flags requesting the queues - * @param[in,out] queueCreateInfos The queue create info structures to be created - * @param[in,out] queuePairsGraphics The list of index pairs (queueFamilyIndex, queueIndex) of queues of type - * vk::QueueFlagBits::eGraphics - * @param[in,out] queuePairsCompute The list of index pairs (queueFamilyIndex, queueIndex) of queues of type - * vk::QueueFlagBits::eCompute - * @param[in,out] queuePairsTransfer The list of index pairs (queueFamilyIndex, queueIndex) of queues of type - * vk::QueueFlagBits::eTransfer - * @throws std::runtime_error If the requested queues from @p queueFlags are not creatable due to insufficient availability. - */ - void queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice, - std::vector<float> &queuePriorities, - std::vector<vk::QueueFlagBits> &queueFlags, - std::vector<vk::DeviceQueueCreateInfo> &queueCreateInfos, - std::vector<std::pair<int, int>> &queuePairsGraphics, - std::vector<std::pair<int, int>> &queuePairsCompute, - std::vector<std::pair<int, int>> &queuePairsTransfer) - { - queueCreateInfos = {}; - queuePairsGraphics = {}; - queuePairsCompute = {}; - queuePairsTransfer = {}; - std::vector<vk::QueueFamilyProperties> qFamilyProperties = physicalDevice.getQueueFamilyProperties(); - - // DEBUG - std::cout << "Input queue flags:" << std::endl; - for (auto qFlag : queueFlags) { - std::cout << "\t" << to_string(qFlag) << std::endl; - } - - //check priorities of flags -> the lower prioCount the higher the priority - std::vector<int> prios; - for(auto flag: queueFlags){ - int prioCount = 0; - for (int i = 0; i < qFamilyProperties.size(); i++) { - prioCount += (static_cast<uint32_t>(flag & qFamilyProperties[i].queueFlags) != 0) * qFamilyProperties[i].queueCount; - } - prios.push_back(prioCount); - std::cout<< "prio Count: " << prioCount << std::endl; - } - //resort flags with heighest priority before allocating the queues - std::vector<vk::QueueFlagBits> newFlags; - for(int i = 0; i < prios.size(); i++){ - auto minElem = std::min_element(prios.begin(), prios.end()); - int index = minElem - prios.begin(); - std::cout << "index: "<< index << std::endl; - newFlags.push_back(queueFlags[index]); - prios[index] = std::numeric_limits<int>::max(); - } - - std::cout << "Sorted queue flags:" << std::endl; - for (auto qFlag : newFlags) { - std::cout << "\t" << to_string(qFlag) << std::endl; - } - - // create requested queues and check if more requested queues are supported - // herefore: create vector that updates available queues in each queue family - // structure: [qFamily_0, ..., qFamily_n] where - // - qFamily_i = [GraphicsCount, ComputeCount, TransferCount], 0 <= i <= n - std::vector<std::vector<int>> queueFamilyStatus, initialQueueFamilyStatus; - - for (auto qFamily : qFamilyProperties) { - int graphicsCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eGraphics) != 0) * qFamily.queueCount; - int computeCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eCompute) != 0) * qFamily.queueCount;; - int transferCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eTransfer) != 0) * qFamily.queueCount;; - queueFamilyStatus.push_back({graphicsCount, computeCount, transferCount}); - } - - initialQueueFamilyStatus = queueFamilyStatus; - - // check if every queue with the specified queue flag can be created - // this automatically checks for queue flag support! - for (auto qFlag : newFlags) { - bool found; - switch (qFlag) { - case vk::QueueFlagBits::eGraphics: - found = false; - for (int i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (queueFamilyStatus[i][0] > 0) { - queuePairsGraphics.push_back(std::pair(i, initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0])); - queueFamilyStatus[i][0]--; - queueFamilyStatus[i][1]--; - queueFamilyStatus[i][2]--; - std::cout << "Graphics queue available at queue family #" << i << std::endl; - found = true; - } - } - if (!found) { - throw std::runtime_error("Too many graphics queues were requested than being available!"); - } - break; - case vk::QueueFlagBits::eCompute: - found = false; - for (int i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (queueFamilyStatus[i][1] > 0) { - queuePairsCompute.push_back(std::pair(i, initialQueueFamilyStatus[i][1] - queueFamilyStatus[i][1])); - queueFamilyStatus[i][0]--; - queueFamilyStatus[i][1]--; - queueFamilyStatus[i][2]--; - std::cout << "Compute queue available at queue family #" << i << std::endl; - found = true; - } - } - if (!found) { - throw std::runtime_error("Too many compute queues were requested than being available!"); - } - break; - case vk::QueueFlagBits::eTransfer: - found = false; - for (int i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (queueFamilyStatus[i][2] > 0) { - queuePairsTransfer.push_back(std::pair(i, initialQueueFamilyStatus[i][2] - queueFamilyStatus[i][2])); - queueFamilyStatus[i][0]--; - queueFamilyStatus[i][1]--; - queueFamilyStatus[i][2]--; - std::cout << "Transfer queue available at queue family #" << i << std::endl; - found = true; - } - } - if (!found) { - throw std::runtime_error("Too many transfer queues were requested than being available!"); - } - break; - default: - throw std::runtime_error("Invalid input for queue flag bits. Valid inputs are 'vk::QueueFlagBits::eGraphics', 'vk::QueueFlagBits::eCompute' and 'vk::QueueFlagBits::eTransfer'."); - } - } - - std::cout << "Initial queue status:" << std::endl; - int x = 0; - for (std::vector<int> e : initialQueueFamilyStatus) { - std::cout << "#" << x << ":\t[" << e[0] << ", " << e[1] << ", " << e[2] << "]" << std::endl; - x++; - } - - std::cout << "Actual queue status:" << std::endl; - x = 0; - for (std::vector<int> e : queueFamilyStatus) { - std::cout << "#" << x << ":\t[" << e[0] << ", " << e[1] << ", " << e[2] << "]" << std::endl; - x++; - } - - // create all requested queues - for (int i = 0; i < qFamilyProperties.size(); i++) { - uint32_t create = std::abs(initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0]); - std::cout << "For Queue Family #" << i << " create " << create << " queues" << std::endl; - if (create > 0) { - vk::DeviceQueueCreateInfo qCreateInfo( - vk::DeviceQueueCreateFlags(), - i, - create, - queuePriorities.data() - ); - queueCreateInfos.push_back(qCreateInfo); - } - } - } - /** * @brief With the help of the reference "supported" all elements in "check" checked, * if they are supported by the physical device. @@ -282,22 +116,6 @@ namespace vkcv return extensions; } - /** - * Computes the queue handles from @p queuePairs - * @param queuePairs The queuePairs that were created separately for each queue type (e.g., vk::QueueFlagBits::eGraphics) - * @param device The device - * @return An array of queue handles based on the @p queuePairs - */ - std::vector<vk::Queue> getQueueHandles(const std::vector<std::pair<int, int>> queuePairs, const vk::Device device) { - std::vector<vk::Queue> queueHandles; - for (auto q : queuePairs) { - int queueFamilyIndex = q.first; // the queueIndex of the queue family - int queueIndex = q.second; // the queueIndex within a queue family - queueHandles.push_back(device.getQueue(queueFamilyIndex, queueIndex)); - } - return queueHandles; - } - Core Core::create(const Window &window, const char *applicationName, uint32_t applicationVersion, @@ -382,47 +200,34 @@ namespace vkcv throw std::runtime_error("The requested device extensions are not supported by the physical device!"); } - //vector to define the queue priorities - std::vector<float> qPriorities; - qPriorities.resize(queueFlags.size(), 1.f); // all queues have the same priorities + const vk::SurfaceKHR surface = createSurface(window.getWindow(), instance, physicalDevice); + const QueueFamilyIndices queueFamilyIndices = getQueueFamilyIndices(physicalDevice, surface); + const std::vector<vk::DeviceQueueCreateInfo> qCreateInfos = createDeviceQueueCreateInfo(queueFamilyIndices); + + vk::DeviceCreateInfo deviceCreateInfo( + vk::DeviceCreateFlags(), + qCreateInfos.size(), + qCreateInfos.data(), + 0, + nullptr, + deviceExtensions.size(), + deviceExtensions.data(), + nullptr // Should our device use some features??? If yes: TODO + ); - // create required queues - std::vector<vk::DeviceQueueCreateInfo> qCreateInfos; - std::vector<std::pair<int, int>> queuePairsGraphics, queuePairsCompute, queuePairsTransfer; - queueCreateInfosQueueHandles(physicalDevice, qPriorities, queueFlags, qCreateInfos, queuePairsGraphics, queuePairsCompute, queuePairsTransfer); - vk::DeviceCreateInfo deviceCreateInfo( - vk::DeviceCreateFlags(), - qCreateInfos.size(), - qCreateInfos.data(), - 0, - nullptr, - deviceExtensions.size(), - deviceExtensions.data(), - nullptr // Should our device use some features??? If yes: TODO - ); #ifndef NDEBUG deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size()); deviceCreateInfo.ppEnabledLayerNames = validationLayers.data(); #endif - vk::Device device = physicalDevice.createDevice(deviceCreateInfo); - - // maybe it can be useful to store these lists as member variable of Core - std::vector<vk::Queue> graphicsQueues = getQueueHandles(queuePairsGraphics, device); - std::vector<vk::Queue> computeQueues = getQueueHandles(queuePairsCompute, device); - std::vector<vk::Queue> transferQueues = getQueueHandles(queuePairsTransfer, device); - - // examples for accessing queues - vk::Queue graphicsQueue = graphicsQueues[0]; - vk::Queue computeQueue = computeQueues[0]; - vk::Queue transferQueue = transferQueues[0]; - Context context(instance, physicalDevice, device); - SwapChain swapChain = SwapChain::create(window, context); + const VulkanQueues queues = getDeviceQueues(device, queueFamilyIndices); + + SwapChain swapChain = SwapChain::create(window, context, surface); std::vector<vk::Image> swapChainImages = device.getSwapchainImagesKHR(swapChain.getSwapchain()); std::vector<vk::ImageView> imageViews; @@ -450,11 +255,11 @@ namespace vkcv imageViews.push_back( device.createImageView( imageViewCreateInfo ) ); } - const int graphicQueueFamilyIndex = queuePairsGraphics[0].first; + const int graphicQueueFamilyIndex = queueFamilyIndices.graphicsIndex; const auto defaultCommandResources = createDefaultCommandResources(context.getDevice(), graphicQueueFamilyIndex); const auto defaultSyncResources = createDefaultSyncResources(context.getDevice()); - return Core(std::move(context) , window, swapChain, imageViews, defaultCommandResources, defaultSyncResources); + return Core(std::move(context) , window, swapChain, imageViews, defaultCommandResources, defaultSyncResources, queues); } const Context &Core::getContext() const @@ -463,7 +268,7 @@ namespace vkcv } Core::Core(Context &&context, const Window &window , SwapChain swapChain, std::vector<vk::ImageView> imageViews, - const CommandResources& commandResources, const SyncResources& syncResources) noexcept : + const CommandResources& commandResources, const SyncResources& syncResources, const VulkanQueues& queues) noexcept : m_Context(std::move(context)), m_window(window), m_swapchain(swapChain), @@ -474,12 +279,11 @@ namespace vkcv m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)}, m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)}, m_CommandResources(commandResources), - m_SyncResources(syncResources) + m_SyncResources(syncResources), + m_Queues(queues) {} Core::~Core() noexcept { - std::cout << " Core " << std::endl; - for(const auto &layout : m_PipelineLayouts) { m_Context.m_Device.destroy(layout); @@ -517,4 +321,19 @@ namespace vkcv return m_PassManager->createPass(config); } + void Core::beginFrame() { + const vk::CommandBufferUsageFlags beginFlags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit; + const vk::CommandBufferBeginInfo beginInfos(beginFlags); + m_CommandResources.commandBuffer.begin(beginInfos); + } + + void Core::renderTriangle() { + + } + + void Core::endFrame() { + m_CommandResources.commandBuffer.end(); + //m_Context. + } + } diff --git a/src/vkcv/Queues.cpp b/src/vkcv/Queues.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0b7967f93574119cee39aa125f2c9ad856f4cb6 --- /dev/null +++ b/src/vkcv/Queues.cpp @@ -0,0 +1,67 @@ +#include "vkcv/Queues.hpp" +#include <unordered_set> + +namespace vkcv { + + VulkanQueues getDeviceQueues(const vk::Device& device, const QueueFamilyIndices& familyIndices) { + VulkanQueues queues; + queues.graphicsQueue = device.getQueue(familyIndices.graphicsIndex, 0); + queues.computeQueue = device.getQueue(familyIndices.computeIndex, 0); + queues.transferQueue = device.getQueue(familyIndices.transferIndex, 0); + queues.presentQueue = device.getQueue(familyIndices.presentIndex, 0); + return queues; + } + + QueueFamilyIndices getQueueFamilyIndices(const vk::PhysicalDevice& physicalDevice, const vk::SurfaceKHR surface) { + const std::vector<vk::QueueFamilyProperties> familyProps = physicalDevice.getQueueFamilyProperties(); + + QueueFamilyIndices indices; + + for (int i = 0; i < familyProps.size(); i++) { + const auto& property = familyProps[i]; + + const bool hasQueues = property.queueCount >= 1; + if (!hasQueues) { + continue; + } + + if (property.queueFlags & vk::QueueFlagBits::eGraphics) { + indices.graphicsIndex = i; + } + if (property.queueFlags & vk::QueueFlagBits::eCompute) { + indices.computeIndex = i; + } + if (property.queueFlags & vk::QueueFlagBits::eTransfer) { + indices.transferIndex = i; + } + if (physicalDevice.getSurfaceSupportKHR(i, surface)) { + indices.presentIndex = i; + } + } + assert(indices.graphicsIndex != -1); + assert(indices.computeIndex != -1); + assert(indices.transferIndex != -1); + assert(indices.presentIndex != -1); + return indices; + } + + std::vector<vk::DeviceQueueCreateInfo> createDeviceQueueCreateInfo(const QueueFamilyIndices& indices) { + + // use set to avoid duplicate queues + std::unordered_set<int> familyIndexSet; + familyIndexSet.insert(indices.graphicsIndex); + familyIndexSet.insert(indices.computeIndex); + familyIndexSet.insert(indices.transferIndex); + familyIndexSet.insert(indices.presentIndex); + + const vk::DeviceQueueCreateFlagBits flags = {}; + const float priority = 1.f; + std::vector<vk::DeviceQueueCreateInfo> createInfos; + + for (const auto index : familyIndexSet) { + const vk::DeviceQueueCreateInfo graphicsCreateInfo(flags, index, 1, &priority); + createInfos.push_back(graphicsCreateInfo); + } + return createInfos; + } +} \ No newline at end of file diff --git a/src/vkcv/Surface.cpp b/src/vkcv/Surface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..29b6c646dc212cba2cc31f32dca5c4fcc023cd03 --- /dev/null +++ b/src/vkcv/Surface.cpp @@ -0,0 +1,27 @@ +#include "Surface.hpp" + +#define GLFW_INCLUDE_VULKAN +#include <GLFW/glfw3.h> + +namespace vkcv { + /** + * creates surface and checks availability + * @param window current window for the surface + * @param instance Vulkan-Instance + * @param physicalDevice Vulkan-PhysicalDevice + * @return created surface + */ + vk::SurfaceKHR createSurface(GLFWwindow* window, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice) { + //create surface + VkSurfaceKHR surface; + if (glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &surface) != VK_SUCCESS) { + throw std::runtime_error("failed to create a window surface!"); + } + vk::Bool32 surfaceSupport = false; + if (physicalDevice.getSurfaceSupportKHR(0, vk::SurfaceKHR(surface), &surfaceSupport) != vk::Result::eSuccess && surfaceSupport != true) { + throw std::runtime_error("surface is not supported by the device!"); + } + + return vk::SurfaceKHR(surface); + } +} diff --git a/src/vkcv/Surface.hpp b/src/vkcv/Surface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..74aafeba821334767ac5e13cd33e1d9674e12f5b --- /dev/null +++ b/src/vkcv/Surface.hpp @@ -0,0 +1,8 @@ +#pragma once +#include <vulkan/vulkan.hpp> + +struct GLFWwindow; + +namespace vkcv { + vk::SurfaceKHR createSurface(GLFWwindow* window, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice); +} \ No newline at end of file diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp index 85f67b8d0fe252a2ab65d4e0d5baf388a7cfa862..a9aecceae02d6e909daebe8d6f0d9a6c555397fe 100644 --- a/src/vkcv/SwapChain.cpp +++ b/src/vkcv/SwapChain.cpp @@ -1,4 +1,3 @@ - #include <vkcv/SwapChain.hpp> namespace vkcv { @@ -27,27 +26,6 @@ namespace vkcv { return m_format; } - /** - * creates surface and checks availability - * @param window current window for the surface - * @param instance Vulkan-Instance - * @param physicalDevice Vulkan-PhysicalDevice - * @return created surface - */ - vk::SurfaceKHR createSurface(GLFWwindow *window, const vk::Instance &instance, const vk::PhysicalDevice& physicalDevice) { - //create surface - VkSurfaceKHR surface; - if (glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &surface) != VK_SUCCESS) { - throw std::runtime_error("failed to create a window surface!"); - } - vk::Bool32 surfaceSupport = false; - if (physicalDevice.getSurfaceSupportKHR(0, vk::SurfaceKHR(surface), &surfaceSupport) != vk::Result::eSuccess && surfaceSupport != true) { - throw std::runtime_error("surface is not supported by the device!"); - } - - return vk::SurfaceKHR(surface); - } - /** * chooses Extent and clapms values to the available * @param physicalDevice Vulkan-PhysicalDevice @@ -148,13 +126,11 @@ namespace vkcv { * @param context that keeps instance, physicalDevice and a device. * @return swapchain */ - SwapChain SwapChain::create(const Window &window, const Context &context) { + SwapChain SwapChain::create(const Window &window, const Context &context, const vk::SurfaceKHR surface) { const vk::Instance& instance = context.getInstance(); const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice(); const vk::Device& device = context.getDevice(); - vk::SurfaceKHR surface = createSurface(window.getWindow(),instance,physicalDevice); - vk::Extent2D extent2D = chooseSwapExtent(physicalDevice, surface, window); vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(physicalDevice, surface); vk::PresentModeKHR presentMode = choosePresentMode(physicalDevice, surface);