Verified Commit 60755124 authored by Tobias Frisch's avatar Tobias Frisch
Browse files

Merge branch 'develop' into 43-multi-threading

parents 8ea8f76b eab9f823
Pipeline #26187 passed with stages
in 3 minutes and 45 seconds
<<<<<<< HEAD
=======
>>>>>>> develop
# IDE specific files
.project
.cproject
......@@ -19,3 +15,6 @@ cmake-build-release/
*.exe
*.ilk
*.pdb
# GUI configuration files
imgui.ini
......@@ -14,7 +14,7 @@ build_ubuntu_gcc:
- $RUN =~ /\bubuntu.*/i || $RUN =~ /\ball.*/i
stage: build
tags:
- ubuntu-gcc
- ubuntu-gcc-cached
variables:
GIT_SUBMODULE_STRATEGY: recursive
timeout: 10m
......@@ -37,11 +37,11 @@ build_win10_msvc:
- $RUN =~ /\bwin.*/i || $RUN =~ /\ball.*/i
stage: build
tags:
- win10-msvc
- win10-msvc-cached
variables:
GIT_SUBMODULE_STRATEGY: recursive
timeout: 10m
retry: 1
retry: 0
script:
- cd 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\'
- .\Launch-VsDevShell.ps1
......
......@@ -15,4 +15,10 @@
url = https://github.com/nothings/stb.git
[submodule "modules/camera/lib/glm"]
path = modules/camera/lib/glm
url = https://github.com/g-truc/glm.git
\ No newline at end of file
url = https://github.com/g-truc/glm.git
[submodule "modules/shader_compiler/lib/glslang"]
path = modules/shader_compiler/lib/glslang
url = https://github.com/KhronosGroup/glslang.git
[submodule "modules/gui/lib/imgui"]
path = modules/gui/lib/imgui
url = https://github.com/ocornut/imgui.git
......@@ -41,24 +41,24 @@ if (vkcv_build_debug)
endif()
endif()
# configure everything to use the required dependencies
include(${vkcv_config}/Libraries.cmake)
# set the compile definitions aka preprocessor variables
add_compile_definitions(${vkcv_definitions})
# 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})
# set the compile definitions aka preprocessor variables
add_compile_definitions(${vkcv_definitions})
# create VkCV framework as static library using all source files
add_library(vkcv STATIC ${vkcv_sources})
......
......@@ -865,7 +865,8 @@ WARN_LOGFILE =
# Note: If this tag is empty the current directory is searched.
INPUT = src \
include
include \
modules
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
......@@ -953,7 +954,7 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE =
EXCLUDE = lib
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
......@@ -969,7 +970,7 @@ EXCLUDE_SYMLINKS = NO
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
EXCLUDE_PATTERNS =
EXCLUDE_PATTERNS = */lib/*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
......
......@@ -10,6 +10,8 @@ if(NOT WIN32)
list(APPEND vkcv_flags -fopenmp)
endif()
list(APPEND vkcv_definitions _USE_MATH_DEFINES)
# some formatted printing
set(vkcv_config_msg " - Library: ")
......
......@@ -32,8 +32,8 @@ set(vkcv_sources
${vkcv_include}/vkcv/Logger.hpp
${vkcv_include}/vkcv/SwapChain.hpp
${vkcv_source}/vkcv/SwapChain.cpp
${vkcv_include}/vkcv/Swapchain.hpp
${vkcv_source}/vkcv/Swapchain.cpp
${vkcv_include}/vkcv/ShaderStage.hpp
......@@ -41,7 +41,6 @@ set(vkcv_sources
${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
......@@ -81,4 +80,7 @@ set(vkcv_sources
${vkcv_source}/vkcv/CommandStreamManager.cpp
${vkcv_include}/vkcv/CommandRecordingFunctionTypes.hpp
${vkcv_include}/vkcv/ImageConfig.hpp
${vkcv_source}/vkcv/ImageConfig.cpp
)
......@@ -132,6 +132,9 @@ namespace vkcv
*/
void unmapBuffer(const BufferHandle& handle);
void recordBufferMemoryBarrier(
const BufferHandle& handle,
vk::CommandBuffer cmdBuffer);
};
}
......@@ -8,7 +8,7 @@
#include <vulkan/vulkan.hpp>
#include "vkcv/Context.hpp"
#include "vkcv/SwapChain.hpp"
#include "vkcv/Swapchain.hpp"
#include "vkcv/Window.hpp"
#include "vkcv/PassConfig.hpp"
#include "vkcv/Handles.hpp"
......@@ -52,7 +52,7 @@ namespace vkcv
*
* @param context encapsulates various Vulkan objects
*/
Core(Context &&context, Window &window, const SwapChain& swapChain, std::vector<vk::ImageView> imageViews,
Core(Context &&context, Window &window, const Swapchain& swapChain, std::vector<vk::ImageView> imageViews,
const CommandResources& commandResources, const SyncResources& syncResources) noexcept;
// explicit destruction of default constructor
Core() = delete;
......@@ -61,11 +61,8 @@ namespace vkcv
Context m_Context;
SwapChain m_swapchain;
std::vector<vk::ImageView> m_swapchainImageViews;
std::vector<vk::Image> m_swapchainImages;
std::vector<vk::ImageLayout> m_swapchainImageLayouts;
const Window& m_window;
Swapchain m_swapchain;
Window& m_window;
std::unique_ptr<PassManager> m_PassManager;
std::unique_ptr<PipelineManager> m_PipelineManager;
......@@ -79,11 +76,7 @@ namespace vkcv
SyncResources m_SyncResources;
uint32_t m_currentSwapchainImageIndex;
std::function<void(int, int)> e_resizeHandle;
static std::vector<vk::ImageView> createImageViews( Context &context, SwapChain& swapChain);
void recordSwapchainImageLayoutTransition(vk::CommandBuffer cmdBuffer, vk::ImageLayout newLayout);
event_handle<int,int> e_resizeHandle;
public:
/**
......@@ -123,6 +116,9 @@ namespace vkcv
[[nodiscard]]
const Context &getContext() const;
[[nodiscard]]
const Swapchain& getSwapchain() const;
/**
* Creates a #Core with given @p applicationName and @p applicationVersion for your application.
......@@ -216,7 +212,20 @@ namespace vkcv
* @return Image-Object
*/
[[nodiscard]]
Image createImage(vk::Format format, uint32_t width, uint32_t height, uint32_t depth = 1);
Image createImage(
vk::Format format,
uint32_t width,
uint32_t height,
uint32_t depth = 1,
bool createMipChain = false,
bool supportStorage = false,
bool supportColorAttachment = false,
Multisampling multisampling = Multisampling::None);
[[nodiscard]]
const uint32_t getImageWidth(ImageHandle imageHandle);
[[nodiscard]]
const uint32_t getImageHeight(ImageHandle imageHandle);
/** TODO:
* @param setDescriptions
......@@ -253,8 +262,6 @@ namespace vkcv
*/
void endFrame();
vk::Format getSwapchainImageFormat();
/**
* Submit a command buffer to any queue of selected type. The recording can be customized by a
* custom record-command-function. If the command submission has finished, an optional finish-function
......@@ -264,7 +271,7 @@ namespace vkcv
* @param record Record-command-function
* @param finish Finish-command-function or nullptr
*/
void recordAndSubmitCommands(
void recordAndSubmitCommandsImmediate(
const SubmitInfo &submitInfo,
const RecordCommandFunction &record,
const FinishCommandFunction &finish);
......@@ -279,5 +286,12 @@ namespace vkcv
void submitCommandStream(const CommandStreamHandle handle);
void prepareSwapchainImageForPresent(const CommandStreamHandle handle);
void prepareImageForSampling(const CommandStreamHandle cmdStream, const ImageHandle image);
void prepareImageForStorage(const CommandStreamHandle cmdStream, const ImageHandle image);
void recordImageMemoryBarrier(const CommandStreamHandle cmdStream, const ImageHandle image);
void recordBufferMemoryBarrier(const CommandStreamHandle cmdStream, const BufferHandle buffer);
void resolveMSAAImage(CommandStreamHandle cmdStream, ImageHandle src, ImageHandle dst);
vk::ImageView getSwapchainImageView() const;
};
}
......@@ -4,15 +4,20 @@
namespace vkcv {
struct SampledImageDescriptorWrite {
inline SampledImageDescriptorWrite(uint32_t binding, ImageHandle image) : binding(binding), image(image) {};
inline SampledImageDescriptorWrite(uint32_t binding, ImageHandle image, uint32_t mipLevel = 0, bool useGeneralLayout = false)
: binding(binding), image(image), mipLevel(mipLevel), useGeneralLayout(useGeneralLayout) {};
uint32_t binding;
ImageHandle image;
uint32_t mipLevel;
bool useGeneralLayout;
};
struct StorageImageDescriptorWrite {
inline StorageImageDescriptorWrite(uint32_t binding, ImageHandle image) : binding(binding), image(image) {};
inline StorageImageDescriptorWrite(uint32_t binding, ImageHandle image, uint32_t mipLevel = 0)
: binding(binding), image(image), mipLevel(mipLevel) {};
uint32_t binding;
ImageHandle image;
uint32_t mipLevel;
};
struct UniformBufferDescriptorWrite {
......@@ -36,8 +41,8 @@ namespace vkcv {
struct DescriptorWrites {
std::vector<SampledImageDescriptorWrite> sampledImageWrites;
std::vector<StorageImageDescriptorWrite> storageImageWrites;
std::vector<UniformBufferDescriptorWrite> uniformBufferWrites;
std::vector<StorageBufferDescriptorWrite> storageBufferWrites;
std::vector<SamplerDescriptorWrite> samplerWrites;
std::vector<UniformBufferDescriptorWrite> uniformBufferWrites;
std::vector<StorageBufferDescriptorWrite> storageBufferWrites;
std::vector<SamplerDescriptorWrite> samplerWrites;
};
}
\ No newline at end of file
......@@ -37,11 +37,12 @@ namespace vkcv {
};
struct DrawcallInfo {
inline DrawcallInfo(const Mesh& mesh, const std::vector<DescriptorSetUsage>& descriptorSets)
: mesh(mesh), descriptorSets(descriptorSets) {}
inline DrawcallInfo(const Mesh& mesh, const std::vector<DescriptorSetUsage>& descriptorSets, const uint32_t instanceCount = 1)
: mesh(mesh), descriptorSets(descriptorSets), instanceCount(instanceCount){}
Mesh mesh;
std::vector<DescriptorSetUsage> descriptorSets;
uint32_t instanceCount;
};
void recordDrawcall(
......
......@@ -4,10 +4,18 @@
#include <mutex>
namespace vkcv {
template<typename... T>
struct event_handle {
uint32_t id;
};
template<typename... T>
struct event_function {
typedef std::function<void(T...)> type;
event_handle<T...> handle;
type callback;
};
/**
......@@ -17,8 +25,9 @@ namespace vkcv {
template<typename... T>
struct event {
private:
std::vector<typename event_function<T...>::type> m_handles;
std::mutex m_mutex;
std::vector< event_function<T...> > m_functions;
uint32_t m_id_counter;
std::mutex m_mutex;
public:
......@@ -28,31 +37,37 @@ namespace vkcv {
*/
void operator()(T... arguments) {
lock();
for (auto &handle : this->m_handles) {
handle(arguments...);
}
for (auto &function : this->m_functions) {
function.callback(arguments...);
}
unlock();
}
/**
* adds a function handle to the event to be called
* @param handle of the function
* @param callback of the function
* @return handle of the function
*/
typename event_function<T...>::type add(typename event_function<T...>::type handle) {
this->m_handles.push_back(handle);
return handle;
event_handle<T...> add(typename event_function<T...>::type callback) {
event_function<T...> function;
function.handle = { m_id_counter++ };
function.callback = callback;
this->m_functions.push_back(function);
return function.handle;
}
/**
* removes a function handle of the event
* @param handle of the function
*/
void remove(typename event_function<T...>::type handle) {
this->m_handles.erase(
remove(this->m_handles.begin(), this->m_handles.end(), handle),
this->m_handles.end()
void remove(event_handle<T...> handle) {
this->m_functions.erase(
std::remove_if(this->m_functions.begin(), this->m_functions.end(), [&handle](auto function){
return (handle.id == function.handle.id);
}),
this->m_functions.end()
);
}
......@@ -60,17 +75,21 @@ namespace vkcv {
* locks the event so its function handles won't be called
*/
void lock() {
m_mutex.lock();
m_mutex.lock();
}
/**
* unlocks the event so its function handles can be called after locking
*/
void unlock() {
m_mutex.unlock();
m_mutex.unlock();
}
event() = default;
explicit event(bool locked = false) {
if (locked) {
lock();
}
}
event(const event &other) = delete;
......
......@@ -7,11 +7,11 @@
#include "vulkan/vulkan.hpp"
#include "Handles.hpp"
#include "vkcv/ImageConfig.hpp"
namespace vkcv {
// forward declares
class ImageManager;
class ImageManager;
bool isDepthFormat(const vk::Format format);
......@@ -29,24 +29,37 @@ namespace vkcv {
[[nodiscard]]
uint32_t getDepth() const;
[[nodiscard]]
vk::ImageLayout getLayout() const;
[[nodiscard]]
vkcv::ImageHandle getHandle() const;
[[nodiscard]]
uint32_t getMipCount() const;
void switchLayout(vk::ImageLayout newLayout);
void fill(void* data, size_t size = SIZE_MAX);
void generateMipChainImmediate();
void recordMipChainGeneration(const vkcv::CommandStreamHandle& cmdStream);
private:
ImageManager* const m_manager;
const ImageHandle m_handle;
// TODO: const qualifier removed, very hacky!!!
// Else you cannot recreate an image. Pls fix.
ImageManager* m_manager;
ImageHandle m_handle;
Image(ImageManager* manager, const ImageHandle& handle);
static Image create(ImageManager* manager, vk::Format format, uint32_t width, uint32_t height, uint32_t depth);
static Image create(
ImageManager* manager,
vk::Format format,
uint32_t width,
uint32_t height,
uint32_t depth,
uint32_t mipCount,
bool supportStorage,
bool supportColorAttachment,
Multisampling msaa);
};
}
#pragma once
#include <vulkan/vulkan.hpp>
namespace vkcv {
enum class Multisampling { None, MSAA2X, MSAA4X, MSAA8X };
vk::SampleCountFlagBits msaaToVkSampleCountFlag(Multisampling msaa);
uint32_t msaaToSampleCount(Multisampling msaa);
}
#pragma once
#include <iostream>
#include <stdio.h>
namespace vkcv {
......@@ -45,12 +45,12 @@ namespace vkcv {
char output_message [ \
VKCV_DEBUG_MESSAGE_LEN \
]; \
std::snprintf( \
snprintf( \
output_message, \
VKCV_DEBUG_MESSAGE_LEN, \
__VA_ARGS__ \
); \
std::fprintf( \
fprintf( \
getLogOutput(level), \
"[%s]: %s [%s, line %d: %s]\n", \
vkcv::getLogName(level), \
......
......@@ -2,6 +2,7 @@
#include <vector>
#include <vulkan/vulkan.hpp>
#include "ImageConfig.hpp"
namespace vkcv
{
......@@ -45,7 +46,8 @@ namespace vkcv
struct PassConfig
{
explicit PassConfig(std::vector<AttachmentDescription> attachments) noexcept;
explicit PassConfig(std::vector<AttachmentDescription> attachments, Multisampling msaa = Multisampling::None) noexcept;
std::vector<AttachmentDescription> attachments{};
Multisampling msaa;
};
}
\ No newline at end of file
......@@ -10,37 +10,35 @@
#include "Handles.hpp"
#include "ShaderProgram.hpp"
#include "VertexLayout.hpp"
#include "ImageConfig.hpp"
namespace vkcv {
struct PipelineConfig {
/**
* 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
* @param vertexLayout layout of vertex buffer, comprised of its bindings and the bindings' attachments
*/
PipelineConfig(
const ShaderProgram& shaderProgram,
uint32_t width,
uint32_t height,
const PassHandle &passHandle,
const VertexLayout &vertexLayouts,
const std::vector<vk::DescriptorSetLayout> &descriptorLayouts,
bool useDynamicViewport);
enum class PrimitiveTopology{PointList, LineList, TriangleList };
enum class CullMode{ None, Front, Back };
enum class DepthTest { None, Less, LessEqual, Greater, GreatherEqual, Equal };
ShaderProgram m_ShaderProgram;
uint32_t m_Height;
uint32_t m_Width;
PassHandle m_PassHandle;
VertexLayout m_VertexLayout;
std::vector<vk::DescriptorSetLayout> m_DescriptorLayouts;
bool m_UseDynamicViewport;
// add more as needed
// alternatively we could expose the blend factors directly
enum class BlendMode{ None, Additive };
struct PipelineConfig {
ShaderProgram m_ShaderProgram;
uint32_t m_Width;
uint32_t m_Height;
PassHandle m_PassHandle;
VertexLayout m_VertexLayout;
std::vector<vk::DescriptorSetLayout> m_DescriptorLayouts;
bool m_UseDynamicViewport;
bool m_UseConservativeRasterization = false;
PrimitiveTopology m_PrimitiveTopology = PrimitiveTopology::TriangleList;
BlendMode m_blendMode = BlendMode::None;
bool m_EnableDepthClamping = false;
Multisampling m_multisampling = Multisampling::None;
CullMode m_culling = CullMode::None;
DepthTest m_depthTest = DepthTest::LessEqual;
bool m_depthWrite = true;
bool m_alphaToCoverage = false;
};
}
\ No newline at end of file
......@@ -51,7 +51,7 @@ namespace vkcv {
const std::vector<VertexAttachment> &getVertexAttachments() const;
size_t getPushConstantSize() const;
const std::vector<std::vector<DescriptorBinding>> &getReflectedDescriptors() const;
const std::vector<std::vector<DescriptorBinding>>& getReflectedDescriptors() const;
private:
/**
......
......@@ -7,8 +7,12 @@
namespace vkcv
{
class SwapChain final {
const uint32_t MIN_SWAPCHAIN_SIZE = 2;
class Swapchain final {
private:
friend class Core;
struct Surface
{
......@@ -21,10 +25,10 @@ namespace vkcv
Surface m_Surface;
vk::SwapchainKHR m_Swapchain;
vk::Format m_SwapchainFormat;
vk::ColorSpaceKHR m_SwapchainColorSpace;
vk::PresentModeKHR m_SwapchainPresentMode;
uint32_t m_SwapchainImageCount;
vk::Format m_Format;
vk::ColorSpaceKHR m_ColorSpace;
vk::PresentModeKHR m_PresentMode;
uint32_t m_ImageCount;