Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • vulkan2021/vkcv-framework
1 result
Select Git revision
Show changes
Commits on Source (105)
Showing
with 570 additions and 44 deletions
# IDE specific files
.project
.cproject
.vs/
......@@ -5,6 +7,12 @@
.idea/
.editorconfig
# build directories
build/
cmake-build-debug/
cmake-build-release/
# VS build files and binaries
*.exe
*.ilk
*.pdb
stages:
- build
- deploy
build_ubuntu_gcc:
variables:
GIT_SUBMODULE_STRATEGY: recursive
stage: build
tags:
- ubuntu-gcc
variables:
GIT_SUBMODULE_STRATEGY: recursive
script:
- mkdir debug
- cd debug
- cmake -DCMAKE_BUILD_TYPE=Debug ..
- cmake --build .
artifacts:
name: "Documentation - $CI_PIPELINE_ID"
paths:
- doc/html
- doc/latex
expire_in: never
build_win10_msvc:
variables:
GIT_SUBMODULE_STRATEGY: recursive
stage: build
tags:
- win10-msvc
variables:
GIT_SUBMODULE_STRATEGY: recursive
script:
- cd 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\'
- .\Launch-VsDevShell.ps1
......@@ -23,4 +33,36 @@ build_win10_msvc:
- mkdir debug
- cd debug
- cmake -DCMAKE_BUILD_TYPE=Debug ..
- cmake --build .
\ No newline at end of file
- cmake --build .
deploy_doc_develop:
only:
refs:
- develop
stage: deploy
needs: ["build_ubuntu_gcc"]
dependencies:
- build_ubuntu_gcc
tags:
- webserver
variables:
GIT_STRATEGY: none
script:
- rsync -avh doc/html/ /var/www/html/develop --delete
- echo "Check it out at https://vkcv.de/develop"
deploy_doc_branch:
except:
refs:
- develop
stage: deploy
needs: ["build_ubuntu_gcc"]
dependencies:
- build_ubuntu_gcc
tags:
- webserver
variables:
GIT_STRATEGY: none
script:
- rsync -avh doc/html/ /var/www/html/branch/$CI_COMMIT_BRANCH --delete
- echo "Check it out at https://vkcv.de/branch/$CI_COMMIT_BRANCH"
\ No newline at end of file
......@@ -12,6 +12,11 @@ if (CMAKE_BUILD_TYPE)
endif()
message("-- Language: [ C++ " ${CMAKE_CXX_STANDARD} " ]")
message("-- Compiler: [ " ${CMAKE_CXX_COMPILER_ID} " " ${CMAKE_CXX_COMPILER_VERSION} " ]")
if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0.0"))
message(FATAL_ERROR "Upgrade your compiler! GCC 9.0+ is required!")
endif()
# setting up different paths
set(vkcv_config ${PROJECT_SOURCE_DIR}/config)
......@@ -36,17 +41,21 @@ if (vkcv_build_debug)
endif()
endif()
# add modules as targets
add_subdirectory(modules)
# add source files for compilation
include(${vkcv_config}/Sources.cmake)
# configure everything to use the required dependencies
include(${vkcv_config}/Libraries.cmake)
message("-- Libraries: [ ${vkcv_libraries} ]")
message("-- Flags: [ ${vkcv_flags} ]")
# set the compiler flags for the framework
set(CMAKE_CXX_FLAGS ${vkcv_flags})
message("-- Flags: [ ${CMAKE_CXX_FLAGS} ]")
# set the compile definitions aka preprocessor variables
add_compile_definitions(${vkcv_definitions})
......
......@@ -1545,7 +1545,7 @@ DISABLE_INDEX = NO
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = NO
GENERATE_TREEVIEW = YES
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
......@@ -2299,7 +2299,7 @@ EXTERNAL_PAGES = YES
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
CLASS_DIAGRAMS = NO
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
......@@ -2321,7 +2321,7 @@ HIDE_UNDOC_RELATIONS = YES
# set to NO
# The default value is: NO.
HAVE_DOT = NO
HAVE_DOT = YES
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of
......@@ -2460,7 +2460,7 @@ INCLUDED_BY_GRAPH = YES
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALL_GRAPH = NO
CALL_GRAPH = YES
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
# dependency graph for every global function or class method.
......@@ -2472,7 +2472,7 @@ CALL_GRAPH = NO
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALLER_GRAPH = NO
CALLER_GRAPH = YES
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
# hierarchy of all classes instead of a textual one.
......
......@@ -3,7 +3,7 @@ set(vkcv_config_lib ${vkcv_config}/lib)
set(vkcv_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_lib})
if(NOT WIN32)
set(vkcv_libraries stdc++fs)
set(vkcv_libraries stdc++fs)
# optimization for loading times
list(APPEND vkcv_flags -pthread)
......
......@@ -7,9 +7,45 @@ set(vkcv_sources
${vkcv_include}/vkcv/Core.hpp
${vkcv_source}/vkcv/Core.cpp
${vkcv_include}/vkcv/PassConfig.hpp
${vkcv_source}/vkcv/PassConfig.cpp
${vkcv_source}/vkcv/PassManager.hpp
${vkcv_source}/vkcv/PassManager.cpp
${vkcv_include}/vkcv/Handles.hpp
${vkcv_source}/vkcv/Handles.cpp
${vkcv_include}/vkcv/Window.hpp
${vkcv_source}/vkcv/Window.cpp
${vkcv_include}/vkcv/SwapChain.hpp
${vkcv_source}/vkcv/SwapChain.cpp
${vkcv_include}/vkcv/ShaderProgram.hpp
${vkcv_source}/vkcv/ShaderProgram.cpp
${vkcv_include}/vkcv/PipelineConfig.hpp
${vkcv_source}/vkcv/PipelineConfig.cpp
${vkcv_source}/vkcv/PipelineManager.hpp
${vkcv_source}/vkcv/PipelineManager.cpp
${vkcv_include}/vkcv/CommandResources.hpp
${vkcv_source}/vkcv/CommandResources.cpp
${vkcv_include}/vkcv/SyncResources.hpp
${vkcv_source}/vkcv/SyncResources.cpp
${vkcv_include}/vkcv/QueueManager.hpp
${vkcv_source}/vkcv/QueueManager.cpp
${vkcv_source}/vkcv/Surface.hpp
${vkcv_source}/vkcv/Surface.cpp
${vkcv_source}/vkcv/ImageLayoutTransitions.hpp
${vkcv_source}/vkcv/ImageLayoutTransitions.cpp
${vkcv_source}/vkcv/Framebuffer.hpp
${vkcv_source}/vkcv/Framebuffer.cpp
)
#pragma once
#include <vulkan/vulkan.hpp>
namespace vkcv {
struct CommandResources {
vk::CommandPool commandPool;
vk::CommandBuffer commandBuffer;
};
CommandResources createDefaultCommandResources(const vk::Device& device, const int graphicFamilyIndex);
void destroyCommandResources(const vk::Device& device, const CommandResources& resources);
}
\ No newline at end of file
......@@ -2,6 +2,8 @@
#include <vulkan/vulkan.hpp>
#include "QueueManager.hpp"
namespace vkcv
{
class Context
......@@ -21,10 +23,21 @@ namespace vkcv
[[nodiscard]]
const vk::Instance &getInstance() const;
[[nodiscard]]
const vk::PhysicalDevice &getPhysicalDevice() const;
[[nodiscard]]
const vk::Device &getDevice() const;
[[nodiscard]]
const QueueManager& getQueueManager() const;
static Context create(const char *applicationName,
uint32_t applicationVersion,
std::vector<vk::QueueFlagBits> queueFlags,
std::vector<const char *> instanceExtensions,
std::vector<const char *> deviceExtensions);
private:
/**
......@@ -34,9 +47,11 @@ namespace vkcv
* @param physicalDevice Vulkan-PhysicalDevice
* @param device Vulkan-Device
*/
Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device) noexcept;
Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device, QueueManager&& queueManager) noexcept;
vk::Instance m_Instance;
vk::PhysicalDevice m_PhysicalDevice;
vk::Device m_Device;
QueueManager m_QueueManager;
};
}
......@@ -4,16 +4,27 @@
* @brief Handling of global states regarding dependencies
*/
#include <memory>
#include <vulkan/vulkan.hpp>
#include "vkcv/Context.hpp"
#include "vkcv/SwapChain.hpp"
#include "vkcv/Window.hpp"
#include "vkcv/PassConfig.hpp"
#include "vkcv/Handles.hpp"
#include "vkcv/PipelineConfig.hpp"
#include "CommandResources.hpp"
#include "SyncResources.hpp"
#include "Result.hpp"
namespace vkcv
{
// TODO:
class Buffer;
class Renderpass;
class Pipeline;
// forward declarations
class PassManager;
class PipelineManager;
class Core final
{
......@@ -24,16 +35,31 @@ namespace vkcv
*
* @param context encapsulates various Vulkan objects
*/
explicit Core(Context &&context) noexcept;
Core(Context &&context, const Window &window, SwapChain swapChain, std::vector<vk::ImageView> imageViews,
const CommandResources& commandResources, const SyncResources& syncResources) noexcept;
// explicit destruction of default constructor
Core() = delete;
Result acquireSwapchainImage();
void destroyTemporaryFramebuffers();
Context m_Context;
SwapChain m_swapchain;
std::vector<vk::ImageView> m_swapchainImageViews;
const Window& m_window;
std::unique_ptr<PassManager> m_PassManager;
std::unique_ptr<PipelineManager> m_PipelineManager;
CommandResources m_CommandResources;
SyncResources m_SyncResources;
uint32_t m_currentSwapchainImageIndex;
std::vector<vk::Framebuffer> m_TemporaryFramebuffers;
public:
/**
* Destructor of #Core destroys the Vulkan objects contained in the core's context.
*/
~Core() noexcept = default;
~Core() noexcept;
/**
* Copy-constructor of #Core is deleted!
......@@ -78,23 +104,59 @@ namespace vkcv
*
* @param[in] applicationName Name of the application
* @param[in] applicationVersion Version of the application
* @param[in] queueCount (optional) Amount of queues which is requested
* @param[in] queueFlags (optional) Requested flags of queues
* @param[in] instanceExtensions (optional) Requested instance extensions
* @param[in] deviceExtensions (optional) Requested device extensions
* @return New instance of #Context
*/
static Core create(const char *applicationName,
static Core create(const Window &window,
const char *applicationName,
uint32_t applicationVersion,
uint32_t queueCount,
std::vector<vk::QueueFlagBits> queueFlags = {},
std::vector<const char*> instanceExtensions = {},
std::vector<const char*> deviceExtensions = {});
/**
* Creates a basic vulkan graphics pipeline using @p config from the pipeline config class and returns it using the @p handle.
* Fixed Functions for pipeline are set with standard values.
*
* @param config a pipeline config object from the pipeline config class
* @param handle a handle to return the created vulkan handle
* @return True if pipeline creation was successful, False if not
*/
[[nodiscard]]
PipelineHandle createGraphicsPipeline(const PipelineConfig &config);
/**
* Creates a basic vulkan render pass using @p config from the render pass config class and returns it using the @p handle.
* Fixed Functions for pipeline are set with standard values.
*
* @param config a render pass config object from the render pass config class
* @param handle a handle to return the created vulkan handle
* @return True if render pass creation was successful, False if not
*/
[[nodiscard]]
PassHandle createPass(const PassConfig &config);
// TODO:
BufferHandle createBuffer(const Buffer &buf);
PassHandle createRenderPass(const Renderpass &pass) ;
PipelineHandle createPipeline(const Pipeline &pipeline);
/**
* @brief start recording command buffers and increment frame index
*/
void beginFrame();
/**
* @brief render a beautiful triangle
*/
void renderTriangle(const PassHandle renderpassHandle, const PipelineHandle pipelineHandle,
const int width, const int height);
/**
* @brief end recording and present image
*/
void endFrame();
vk::Format getSwapchainImageFormat();
};
}
#pragma once
#include <vector>
#include <vulkan/vulkan.hpp>
namespace vkcv
{
enum class AttachmentLayout
{
UNDEFINED,
GENERAL,
COLOR_ATTACHMENT,
SHADER_READ_ONLY,
DEPTH_STENCIL_ATTACHMENT,
DEPTH_STENCIL_READ_ONLY,
TRANSFER_SRC,
TRANSFER_DST,
PRESENTATION
};
enum class AttachmentOperation
{
LOAD,
CLEAR,
STORE,
DONT_CARE
};
struct AttachmentDescription
{
AttachmentDescription() = delete;
AttachmentDescription(
AttachmentLayout initial,
AttachmentLayout in_pass,
AttachmentLayout final,
AttachmentOperation store_op,
AttachmentOperation load_op,
vk::Format format) noexcept;
AttachmentLayout layout_initial;
AttachmentLayout layout_in_pass;
AttachmentLayout layout_final;
AttachmentOperation store_operation;
AttachmentOperation load_operation;
vk::Format format;
};
struct PassConfig
{
PassConfig() = delete;
explicit PassConfig(std::vector<AttachmentDescription> attachments) noexcept;
std::vector<AttachmentDescription> attachments{};
};
}
\ No newline at end of file
/**
* @authors Mara Vogt, Mark Mints
* @file src/vkcv/Pipeline.hpp
* @brief Pipeline class to handle shader stages
*/
#ifndef VKCV_PIPELINECONFIG_HPP
#define VKCV_PIPELINECONFIG_HPP
#include <vector>
#include <cstdint>
#include "vkcv/Handles.hpp"
#include "ShaderProgram.hpp"
namespace vkcv {
class PipelineConfig {
public:
/**
* Default constructer is deleted!
*/
PipelineConfig() = delete;
/**
* Constructor for the pipeline. Creates a pipeline using @p vertexCode, @p fragmentCode as well as the
* dimensions of the application window @p width and @p height. A handle for the Render Pass is also needed, @p passHandle.
*
* @param shaderProgram shaders of the pipeline
* @param height height of the application window
* @param width width of the application window
* @param passHandle handle for Render Pass
*/
PipelineConfig(const ShaderProgram& shaderProgram, uint32_t width, uint32_t height, PassHandle &passHandle);
ShaderProgram m_ShaderProgram;
uint32_t m_Height;
uint32_t m_Width;
PassHandle m_PassHandle;
};
}
#endif //VKCV_PIPELINECONFIG_HPP
#pragma once
#include <vulkan/vulkan.hpp>
namespace vkcv {
struct Queue {
int familyIndex;
int queueIndex;
vk::Queue handle;
};
class QueueManager {
public:
static QueueManager create(vk::Device device,
std::vector<std::pair<int, int>> &queuePairsGraphics,
std::vector<std::pair<int, int>> &queuePairsCompute,
std::vector<std::pair<int, int>> &queuePairsTransfer);
[[nodiscard]]
const Queue &getPresentQueue() const;
[[nodiscard]]
const std::vector<Queue> &getGraphicsQueues() const;
[[nodiscard]]
const std::vector<Queue> &getComputeQueues() const;
[[nodiscard]]
const std::vector<Queue> &getTransferQueues() const;
static 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);
private:
std::vector<Queue> m_graphicsQueues;
std::vector<Queue> m_computeQueues;
std::vector<Queue> m_transferQueues;
size_t m_presentIndex;
QueueManager(std::vector<Queue>&& graphicsQueues, std::vector<Queue>&& computeQueues, std::vector<Queue>&& transferQueues, size_t presentIndex);
};
}
#pragma once
namespace vkcv {
enum class Result {
SUCCESS = 0,
ERROR = 1
};
}
#pragma once
/**
* @authors Simeon Hermann, Leonie Franken
* @file src/vkcv/ShaderProgram.hpp
* @brief ShaderProgram class to handle and prepare the shader stages for a graphics pipeline
*/
#include <unordered_map>
#include <fstream>
#include <iostream>
#include <filesystem>
#include <vulkan/vulkan.hpp>
namespace vkcv {
enum class ShaderStage
{
VERTEX,
TESS_CONTROL,
TESS_EVAL,
GEOMETRY,
FRAGMENT,
COMPUTE
};
struct Shader
{
std::vector<char> shaderCode;
ShaderStage shaderStage;
};
class ShaderProgram
{
public:
ShaderProgram() noexcept; // ctor
~ShaderProgram() = default; // dtor
/**
* Adds a shader into the shader program.
* The shader is only added if the shader program does not contain the particular shader stage already.
* Contains: (1) reading of the code, (2) creation of a shader module, (3) creation of a shader stage, (4) adding to the shader stage list, (5) destroying of the shader module
* @param[in] flag that signals the respective shaderStage (e.g. VK_SHADER_STAGE_VERTEX_BIT)
* @param[in] relative path to the shader code (e.g. "../../../../../shaders/vert.spv")
*/
bool addShader(ShaderStage shaderStage, const std::filesystem::path &shaderPath);
/**
* Returns the shader program's shader of the specified shader.
* Needed for the transfer to the pipeline.
* @return Shader object consisting of buffer with shader code and shader stage enum
*/
const Shader &getShader(ShaderStage shaderStage) const;
bool existsShader(ShaderStage shaderStage) const;
private:
std::unordered_map<ShaderStage, Shader> m_Shaders;
};
}
#pragma once
#include "vulkan/vulkan.hpp"
#include "Context.hpp"
#include "vkcv/Window.hpp"
namespace vkcv {
class SwapChain final {
private:
vk::SurfaceKHR m_surface;
vk::SwapchainKHR m_swapchain;
vk::SurfaceFormatKHR m_format;
uint32_t m_ImageCount;
/**
* Constructor of a SwapChain object
* glfw is not initialized in this class because ist must be sure that there exists a context first
* glfw is already initialized by the window class
* @param surface used by the swapchain
* @param swapchain to show images in the window
* @param format
*/
SwapChain(vk::SurfaceKHR surface, vk::SwapchainKHR swapchain, vk::SurfaceFormatKHR format, uint32_t imageCount);
public:
SwapChain(const SwapChain &other) = default;
SwapChain(SwapChain &&other) = default;
/**
* @return The swapchain linked with the #SwapChain class
* @note The reference to our Swapchain variable is needed for the recreation step
*/
[[nodiscard]]
const vk::SwapchainKHR& getSwapchain() const;
/**
* gets the current surface object
* @return current surface
*/
[[nodiscard]]
vk::SurfaceKHR getSurface();
/**
* gets the current surface format
* @return gets the surface format
*/
[[nodiscard]]
vk::SurfaceFormatKHR getSurfaceFormat();
/**
* creates a swap chain object out of the given window and the given context
* @param window a wrapper that represents a glfw window
* @param context of the application
* @return returns an object of swapChain
*/
static SwapChain create(const Window &window, const Context &context, const vk::SurfaceKHR surface);
/**
* Destructor of SwapChain
*/
virtual ~SwapChain();
/**
* @return number of images in swapchain
*/
uint32_t getImageCount();
};
}
#pragma once
#include <vulkan/vulkan.hpp>
namespace vkcv {
struct SyncResources {
vk::Semaphore renderFinished;
vk::Fence swapchainImageAcquired;
vk::Fence presentFinished;
};
SyncResources createDefaultSyncResources(const vk::Device& device);
void destroySyncResources(const vk::Device& device, const SyncResources& resources);
}
\ No newline at end of file
......@@ -5,18 +5,18 @@
* @brief Window class to handle a basic rendering surface and input
*/
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#define NOMINMAX
#include <algorithm>
namespace vkcv {
struct GLFWwindow;
namespace vkcv {
class Window final {
private:
GLFWwindow *m_window;
/**
*
* @param GLFWwindow of the class
......@@ -32,8 +32,7 @@ namespace vkcv {
* @param[in] resizable resize ability of the window (optional)
* @return Window class
*/
static Window create(const char *windowTitle, int width = -1, int height = -1, bool resizable = false);
static Window create( 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
* This function should be changed/removed later on
......@@ -54,20 +53,6 @@ namespace vkcv {
[[nodiscard]]
GLFWwindow *getWindow() const;
/**
* gets the current window width
* @return int with window width
*/
[[nodiscard]]
int getWidth() const;
/**
* gets the current window height
* @return int with window height
*/
[[nodiscard]]
int getHeight() const;
/**
* Copy-operator of #Window is deleted!
*
......@@ -84,10 +69,26 @@ namespace vkcv {
*/
Window &operator=(Window &&other) = default;
/**
* gets the window width
* @param window glfwWindow
* @return int with window width
*/
[[nodiscard]]
int getWidth() const;
/**
* gets the window height
* @param window glfwWindow
* @return int with window height
*/
[[nodiscard]]
int getHeight() const;
/**
* Destructor of #Window, terminates GLFW
*/
virtual ~Window();
};
}
\ No newline at end of file
# Add new modules here:
add_subdirectory(testing)
cmake_minimum_required(VERSION 3.16)
project(vkcv_testing)
# setting c++ standard for the project
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(vkcv_testing_source ${PROJECT_SOURCE_DIR}/src)
set(vkcv_testing_include ${PROJECT_SOURCE_DIR}/include)
set(vkcv_testing_sources
${vkcv_testing_include}/vkcv/testing/Test.hpp
${vkcv_testing_source}/vkcv/testing/Test.cpp
)
# adding source files to the project
add_library(vkcv_testing STATIC ${vkcv_testing_sources})
# add the own include directory for public headers
target_include_directories(vkcv_testing BEFORE PUBLIC ${vkcv_testing_include})
#pragma once
namespace vkcv::testing {
class Test {
private:
public:
void test(int test_value);
};
}