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 (351)
Showing
with 743 additions and 118 deletions
...@@ -18,3 +18,8 @@ cmake-build-release/ ...@@ -18,3 +18,8 @@ cmake-build-release/
# GUI configuration files # GUI configuration files
imgui.ini imgui.ini
# Generated source and header files for shaders
*.hxx
*.cxx
variables: variables:
RUN: RUN:
value: "all" value: "all"
description: "The tests that should run. Possible values: ubuntu, win, all." description: "The tests that should run. Possible values: ubuntu, win-msvc, win-mingw, mac, all."
GIT_DEPTH: 1 GIT_DEPTH: 15
stages: stages:
- build - build
...@@ -17,13 +17,13 @@ build_ubuntu_gcc: ...@@ -17,13 +17,13 @@ build_ubuntu_gcc:
- ubuntu-gcc-cached - ubuntu-gcc-cached
variables: variables:
GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_STRATEGY: recursive
timeout: 10m timeout: 15m
retry: 1 retry: 1
script: script:
- mkdir debug - mkdir debug
- cd debug - cd debug
- cmake -DCMAKE_BUILD_TYPE=Debug .. - cmake -DCMAKE_BUILD_TYPE=Debug ..
- cmake --build . - cmake --build . -j 4
artifacts: artifacts:
name: "Documentation - $CI_PIPELINE_ID" name: "Documentation - $CI_PIPELINE_ID"
paths: paths:
...@@ -34,13 +34,13 @@ build_ubuntu_gcc: ...@@ -34,13 +34,13 @@ build_ubuntu_gcc:
build_win10_msvc: build_win10_msvc:
only: only:
variables: variables:
- $RUN =~ /\bwin.*/i || $RUN =~ /\ball.*/i - $RUN =~ /\bwin-msvc.*/i || $RUN =~ /\ball.*/i
stage: build stage: build
tags: tags:
- win10-msvc-cached - win10-msvc-cached
variables: variables:
GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_STRATEGY: recursive
timeout: 10m timeout: 15m
retry: 0 retry: 0
script: script:
- cd 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\' - cd 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\'
...@@ -49,7 +49,43 @@ build_win10_msvc: ...@@ -49,7 +49,43 @@ build_win10_msvc:
- mkdir debug - mkdir debug
- cd debug - cd debug
- cmake -DCMAKE_BUILD_TYPE=Debug .. - cmake -DCMAKE_BUILD_TYPE=Debug ..
- cmake --build . - cmake --build . -j 4
build_win10_mingw:
only:
variables:
- $RUN =~ /\bwin-mingw.*/i || $RUN =~ /\ball.*/i
stage: build
tags:
- win10-mingw-cached
variables:
GIT_SUBMODULE_STRATEGY: recursive
timeout: 15m
retry: 0
script:
- mkdir debug
- cd debug
- cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=C:\msys64\mingw64\bin\x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++.exe .. -G "Unix Makefiles"
- cmake --build . -j 4
build_mac_clang:
only:
variables:
- $RUN =~ /\bmac.*/i || $RUN =~ /\ball.*/i
stage: build
tags:
- catalina-clang-cached
variables:
GIT_SUBMODULE_STRATEGY: recursive
timeout: 15m
retry: 1
script:
- mkdir debug
- cd debug
- export LDFLAGS="-L/usr/local/opt/llvm/lib"
- export CPPFLAGS="-I/usr/local/opt/llvm/include"
- cmake -DCMAKE_C_COMPILER="/usr/local/opt/llvm/bin/clang" -DCMAKE_CXX_COMPILER="/usr/local/opt/llvm/bin/clang++" -DCMAKE_BUILD_TYPE=Debug ..
- cmake --build . -j 4
deploy_doc_develop: deploy_doc_develop:
only: only:
......
...@@ -22,9 +22,9 @@ ...@@ -22,9 +22,9 @@
[submodule "modules/gui/lib/imgui"] [submodule "modules/gui/lib/imgui"]
path = modules/gui/lib/imgui path = modules/gui/lib/imgui
url = https://github.com/ocornut/imgui.git url = https://github.com/ocornut/imgui.git
[submodule "lib/VulkanMemoryAllocator"]
path = lib/VulkanMemoryAllocator
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
[submodule "lib/VulkanMemoryAllocator-Hpp"] [submodule "lib/VulkanMemoryAllocator-Hpp"]
path = lib/VulkanMemoryAllocator-Hpp path = lib/VulkanMemoryAllocator-Hpp
url = https://github.com/malte-v/VulkanMemoryAllocator-Hpp.git url = https://github.com/malte-v/VulkanMemoryAllocator-Hpp.git
[submodule "modules/upscaling/lib/FidelityFX-FSR"]
path = modules/upscaling/lib/FidelityFX-FSR
url = https://github.com/GPUOpen-Effects/FidelityFX-FSR.git
...@@ -33,9 +33,10 @@ set(vkcv_flags ${CMAKE_CXX_FLAGS}) ...@@ -33,9 +33,10 @@ set(vkcv_flags ${CMAKE_CXX_FLAGS})
# enabling warnings in the debug build # enabling warnings in the debug build
if (vkcv_build_debug) if (vkcv_build_debug)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(vkcv_flags ${vkcv_flags} " -Weverything") #set(vkcv_flags ${vkcv_flags} " -Weverything")
set(vkcv_flags ${vkcv_flags} " -Wextra -Wall -Wno-unused-parameter")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(vkcv_flags ${vkcv_flags} " -Wextra -Wall -pedantic") set(vkcv_flags ${vkcv_flags} " -Wextra -Wall -pedantic -Wno-unused-parameter")
else() else()
set(vkcv_flags ${vkcv_flags} " -W4") set(vkcv_flags ${vkcv_flags} " -W4")
endif() endif()
...@@ -64,7 +65,7 @@ add_library(vkcv STATIC ${vkcv_sources}) ...@@ -64,7 +65,7 @@ add_library(vkcv STATIC ${vkcv_sources})
if(MSVC) if(MSVC)
#enable multicore compilation on visual studio #enable multicore compilation on visual studio
target_compile_options(vkcv PRIVATE "/MP" "/openmp") target_compile_options(vkcv PRIVATE "/MP" "/openmp" "/Zc:offsetof-")
#set source groups to create proper filters in visual studio #set source groups to create proper filters in visual studio
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${vkcv_sources}) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${vkcv_sources})
......
...@@ -3,7 +3,13 @@ set(vkcv_config_lib ${vkcv_config}/lib) ...@@ -3,7 +3,13 @@ set(vkcv_config_lib ${vkcv_config}/lib)
set(vkcv_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_lib}) set(vkcv_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_lib})
if(NOT WIN32) if(NOT WIN32)
set(vkcv_libraries stdc++fs) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(vkcv_libraries stdc++fs)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
list(APPEND vkcv_flags -Xpreprocessor)
endif()
# optimization for loading times # optimization for loading times
list(APPEND vkcv_flags -pthread) list(APPEND vkcv_flags -pthread)
...@@ -34,6 +40,9 @@ endif () ...@@ -34,6 +40,9 @@ endif ()
# fix dependencies for different Linux distros (looking at you Ubuntu) # fix dependencies for different Linux distros (looking at you Ubuntu)
include(${vkcv_config_ext}/CheckLibraries.cmake) include(${vkcv_config_ext}/CheckLibraries.cmake)
# add custom function to include a file like a shader as string
include(${vkcv_config_ext}/IncludeShader.cmake)
# cleanup of compiler definitions aka preprocessor variables # cleanup of compiler definitions aka preprocessor variables
if (vkcv_definitions) if (vkcv_definitions)
list(REMOVE_DUPLICATES vkcv_definitions) list(REMOVE_DUPLICATES vkcv_definitions)
......
# adding all source files and header files of the framework: # adding all source files and header files of the framework:
set(vkcv_sources set(vkcv_sources
${vkcv_include}/vkcv/Features.hpp
${vkcv_source}/vkcv/Features.cpp
${vkcv_include}/vkcv/FeatureManager.hpp
${vkcv_source}/vkcv/FeatureManager.cpp
${vkcv_include}/vkcv/Context.hpp ${vkcv_include}/vkcv/Context.hpp
${vkcv_source}/vkcv/Context.cpp ${vkcv_source}/vkcv/Context.cpp
${vkcv_include}/vkcv/Core.hpp ${vkcv_include}/vkcv/Core.hpp
${vkcv_source}/vkcv/Core.cpp ${vkcv_source}/vkcv/Core.cpp
${vkcv_include}/vkcv/File.hpp
${vkcv_source}/vkcv/File.cpp
${vkcv_include}/vkcv/PassConfig.hpp ${vkcv_include}/vkcv/PassConfig.hpp
${vkcv_source}/vkcv/PassConfig.cpp ${vkcv_source}/vkcv/PassConfig.cpp
...@@ -42,11 +51,15 @@ set(vkcv_sources ...@@ -42,11 +51,15 @@ set(vkcv_sources
${vkcv_include}/vkcv/ShaderProgram.hpp ${vkcv_include}/vkcv/ShaderProgram.hpp
${vkcv_source}/vkcv/ShaderProgram.cpp ${vkcv_source}/vkcv/ShaderProgram.cpp
${vkcv_include}/vkcv/PipelineConfig.hpp ${vkcv_include}/vkcv/GraphicsPipelineConfig.hpp
${vkcv_include}/vkcv/ComputePipelineConfig.hpp
${vkcv_source}/vkcv/ComputePipelineManager.hpp
${vkcv_source}/vkcv/ComputePipelineManager.cpp
${vkcv_source}/vkcv/GraphicsPipelineManager.hpp
${vkcv_source}/vkcv/GraphicsPipelineManager.cpp
${vkcv_source}/vkcv/PipelineManager.hpp
${vkcv_source}/vkcv/PipelineManager.cpp
${vkcv_include}/vkcv/CommandResources.hpp ${vkcv_include}/vkcv/CommandResources.hpp
${vkcv_source}/vkcv/CommandResources.cpp ${vkcv_source}/vkcv/CommandResources.cpp
...@@ -72,6 +85,12 @@ set(vkcv_sources ...@@ -72,6 +85,12 @@ set(vkcv_sources
${vkcv_source}/vkcv/SamplerManager.hpp ${vkcv_source}/vkcv/SamplerManager.hpp
${vkcv_source}/vkcv/SamplerManager.cpp ${vkcv_source}/vkcv/SamplerManager.cpp
${vkcv_source}/vkcv/WindowManager.hpp
${vkcv_source}/vkcv/WindowManager.cpp
${vkcv_source}/vkcv/SwapchainManager.hpp
${vkcv_source}/vkcv/SwapchainManager.cpp
${vkcv_include}/vkcv/DescriptorWrites.hpp ${vkcv_include}/vkcv/DescriptorWrites.hpp
......
function(include_shader shader include_dir source_dir)
if (NOT EXISTS ${shader})
message(WARNING "Shader file does not exist: ${shader}")
else()
get_filename_component(filename ${shader} NAME)
file(SIZE ${shader} filesize)
set(include_target_file ${include_dir}/${filename}.hxx)
set(source_target_file ${source_dir}/${filename}.cxx)
if ((EXISTS ${source_target_file}) AND (EXISTS ${include_target_file}))
file(TIMESTAMP ${shader} shader_timestamp "%Y-%m-%dT%H:%M:%S")
file(TIMESTAMP ${source_target_file} source_timestamp "%Y-%m-%dT%H:%M:%S")
string(COMPARE GREATER ${shader_timestamp} ${source_timestamp} shader_update)
else()
set(shader_update true)
endif()
if (shader_update)
string(TOUPPER ${filename} varname)
string(REPLACE "." "_" varname ${varname})
set(shader_header "#pragma once\n")
string(APPEND shader_header "// This file is auto-generated via cmake, so don't touch it!\n")
string(APPEND shader_header "extern unsigned char ${varname} [${filesize}]\;\n")
string(APPEND shader_header "extern unsigned int ${varname}_LEN\;\n")
string(APPEND shader_header "const std::string ${varname}_SHADER (reinterpret_cast<const char*>(${varname}), ${varname}_LEN)\;")
file(WRITE ${include_target_file} ${shader_header})
find_program(xxd_program "xxd")
if (EXISTS ${xxd_program})
get_filename_component(shader_directory ${shader} DIRECTORY)
add_custom_command(
OUTPUT ${source_target_file}
WORKING_DIRECTORY "${shader_directory}"
COMMAND xxd -i -C "${filename}" "${source_target_file}"
COMMENT "Processing shader into source files: ${shader}"
)
else()
set(shader_source "// This file is auto-generated via cmake, so don't touch it!\n")
string(APPEND shader_source "unsigned char ${varname}[] = {")
math(EXPR max_fileoffset "${filesize} - 1" OUTPUT_FORMAT DECIMAL)
message(STATUS "Processing shader into source files: ${shader}")
foreach(fileoffset RANGE ${max_fileoffset})
file(READ ${shader} shader_source_byte OFFSET ${fileoffset} LIMIT 1 HEX)
math(EXPR offset_modulo "${fileoffset} % 12" OUTPUT_FORMAT DECIMAL)
if (${offset_modulo} EQUAL 0)
string(APPEND shader_source "\n ")
endif()
if (${fileoffset} LESS ${max_fileoffset})
string(APPEND shader_source "0x${shader_source_byte}, ")
else()
string(APPEND shader_source "0x${shader_source_byte}\n")
endif()
endforeach()
string(APPEND shader_source "}\;\n")
string(APPEND shader_source "unsigned int ${varname}_LEN = ${filesize}\;")
file(WRITE ${source_target_file} ${shader_source})
endif()
endif()
endif()
endfunction()
...@@ -76,8 +76,8 @@ namespace vkcv { ...@@ -76,8 +76,8 @@ namespace vkcv {
{} {}
[[nodiscard]] [[nodiscard]]
static Buffer<T> create(BufferManager* manager, BufferType type, size_t count, BufferMemoryType memoryType) { static Buffer<T> create(BufferManager* manager, BufferType type, size_t count, BufferMemoryType memoryType, bool supportIndirect) {
return Buffer<T>(manager, manager->createBuffer(type, count * sizeof(T), memoryType), type, count, memoryType); return Buffer<T>(manager, manager->createBuffer(type, count * sizeof(T), memoryType, supportIndirect), type, count, memoryType);
} }
}; };
......
...@@ -70,7 +70,7 @@ namespace vkcv ...@@ -70,7 +70,7 @@ namespace vkcv
* @param memoryType Type of buffers memory * @param memoryType Type of buffers memory
* @return New buffer handle * @return New buffer handle
*/ */
BufferHandle createBuffer(BufferType type, size_t size, BufferMemoryType memoryType); BufferHandle createBuffer(BufferType type, size_t size, BufferMemoryType memoryType, bool supportIndirect);
/** /**
* Returns the Vulkan buffer handle of a buffer * Returns the Vulkan buffer handle of a buffer
......
#pragma once
/**
* @authors Mark Mints
* @file src/vkcv/ComputePipelineConfig.hpp
* @brief Compute Pipeline Config Struct to hand over required information to Pipeline Creation.
*/
#include <vector>
#include "ShaderProgram.hpp"
namespace vkcv
{
struct ComputePipelineConfig {
ShaderProgram& m_ShaderProgram;
std::vector<vk::DescriptorSetLayout> m_DescriptorSetLayouts;
};
}
\ No newline at end of file
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include <vk_mem_alloc.hpp> #include <vk_mem_alloc.hpp>
#include "QueueManager.hpp" #include "QueueManager.hpp"
#include "DrawcallRecording.hpp"
#include "Features.hpp"
namespace vkcv namespace vkcv
{ {
...@@ -31,6 +33,9 @@ namespace vkcv ...@@ -31,6 +33,9 @@ namespace vkcv
[[nodiscard]] [[nodiscard]]
const vk::Device &getDevice() const; const vk::Device &getDevice() const;
[[nodiscard]]
const FeatureManager& getFeatureManager() const;
[[nodiscard]] [[nodiscard]]
const QueueManager& getQueueManager() const; const QueueManager& getQueueManager() const;
...@@ -39,9 +44,9 @@ namespace vkcv ...@@ -39,9 +44,9 @@ namespace vkcv
static Context create(const char *applicationName, static Context create(const char *applicationName,
uint32_t applicationVersion, uint32_t applicationVersion,
std::vector<vk::QueueFlagBits> queueFlags, const std::vector<vk::QueueFlagBits>& queueFlags,
std::vector<const char *> instanceExtensions, const Features& features,
std::vector<const char *> deviceExtensions); const std::vector<const char*>& instanceExtensions = {});
private: private:
/** /**
...@@ -52,11 +57,12 @@ namespace vkcv ...@@ -52,11 +57,12 @@ namespace vkcv
* @param device Vulkan-Device * @param device Vulkan-Device
*/ */
Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device, Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device,
QueueManager&& queueManager, vma::Allocator&& allocator) noexcept; FeatureManager&& featureManager, QueueManager&& queueManager, vma::Allocator&& allocator) noexcept;
vk::Instance m_Instance; vk::Instance m_Instance;
vk::PhysicalDevice m_PhysicalDevice; vk::PhysicalDevice m_PhysicalDevice;
vk::Device m_Device; vk::Device m_Device;
FeatureManager m_FeatureManager;
QueueManager m_QueueManager; QueueManager m_QueueManager;
vma::Allocator m_Allocator; vma::Allocator m_Allocator;
......
...@@ -7,14 +7,15 @@ ...@@ -7,14 +7,15 @@
#include <memory> #include <memory>
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include "vkcv/Context.hpp" #include "Context.hpp"
#include "vkcv/Swapchain.hpp" #include "Swapchain.hpp"
#include "vkcv/Window.hpp" #include "Window.hpp"
#include "vkcv/PassConfig.hpp" #include "PassConfig.hpp"
#include "vkcv/Handles.hpp" #include "Handles.hpp"
#include "vkcv/Buffer.hpp" #include "Buffer.hpp"
#include "vkcv/Image.hpp" #include "Image.hpp"
#include "vkcv/PipelineConfig.hpp" #include "GraphicsPipelineConfig.hpp"
#include "ComputePipelineConfig.hpp"
#include "CommandResources.hpp" #include "CommandResources.hpp"
#include "SyncResources.hpp" #include "SyncResources.hpp"
#include "Result.hpp" #include "Result.hpp"
...@@ -24,18 +25,24 @@ ...@@ -24,18 +25,24 @@
#include "Event.hpp" #include "Event.hpp"
#include "DrawcallRecording.hpp" #include "DrawcallRecording.hpp"
#include "CommandRecordingFunctionTypes.hpp" #include "CommandRecordingFunctionTypes.hpp"
#include "../../src/vkcv/WindowManager.hpp"
#include "../../src/vkcv/SwapchainManager.hpp"
namespace vkcv namespace vkcv
{ {
// forward declarations // forward declarations
class PassManager; class PassManager;
class PipelineManager; class GraphicsPipelineManager;
class ComputePipelineManager;
class DescriptorManager; class DescriptorManager;
class BufferManager; class BufferManager;
class SamplerManager; class SamplerManager;
class ImageManager; class ImageManager;
class CommandStreamManager; class CommandStreamManager;
class WindowManager;
class SwapchainManager;
struct SubmitInfo { struct SubmitInfo {
QueueType queueType; QueueType queueType;
...@@ -52,31 +59,34 @@ namespace vkcv ...@@ -52,31 +59,34 @@ namespace vkcv
* *
* @param context encapsulates various Vulkan objects * @param context encapsulates various Vulkan objects
*/ */
Core(Context &&context, Window &window, const Swapchain& swapChain, std::vector<vk::ImageView> imageViews, Core(Context &&context, const CommandResources& commandResources, const SyncResources& syncResources) noexcept;
const CommandResources& commandResources, const SyncResources& syncResources) noexcept;
// explicit destruction of default constructor // explicit destruction of default constructor
Core() = delete; Core() = delete;
Result acquireSwapchainImage(); Result acquireSwapchainImage(const SwapchainHandle &swapchainHandle);
Context m_Context; Context m_Context;
Swapchain m_swapchain; std::unique_ptr<PassManager> m_PassManager;
Window& m_window; std::unique_ptr<GraphicsPipelineManager> m_PipelineManager;
std::unique_ptr<ComputePipelineManager> m_ComputePipelineManager;
std::unique_ptr<PassManager> m_PassManager; std::unique_ptr<DescriptorManager> m_DescriptorManager;
std::unique_ptr<PipelineManager> m_PipelineManager; std::unique_ptr<BufferManager> m_BufferManager;
std::unique_ptr<DescriptorManager> m_DescriptorManager; std::unique_ptr<SamplerManager> m_SamplerManager;
std::unique_ptr<BufferManager> m_BufferManager; std::unique_ptr<ImageManager> m_ImageManager;
std::unique_ptr<SamplerManager> m_SamplerManager; std::unique_ptr<CommandStreamManager> m_CommandStreamManager;
std::unique_ptr<ImageManager> m_ImageManager; std::unique_ptr<WindowManager> m_WindowManager;
std::unique_ptr<CommandStreamManager> m_CommandStreamManager; std::unique_ptr<SwapchainManager> m_SwapchainManager;
CommandResources m_CommandResources; CommandResources m_CommandResources;
SyncResources m_SyncResources; SyncResources m_SyncResources;
uint32_t m_currentSwapchainImageIndex; uint32_t m_currentSwapchainImageIndex;
event_handle<int,int> e_resizeHandle; /**
* sets up swapchain images
* @param swapchainHandles of swapchain
*/
void setSwapchainImages(SwapchainHandle handle);
public: public:
/** /**
...@@ -116,9 +126,6 @@ namespace vkcv ...@@ -116,9 +126,6 @@ namespace vkcv
[[nodiscard]] [[nodiscard]]
const Context &getContext() const; const Context &getContext() const;
[[nodiscard]]
const Swapchain& getSwapchain() const;
/** /**
* Creates a #Core with given @p applicationName and @p applicationVersion for your application. * Creates a #Core with given @p applicationName and @p applicationVersion for your application.
...@@ -135,12 +142,11 @@ namespace vkcv ...@@ -135,12 +142,11 @@ namespace vkcv
* @param[in] deviceExtensions (optional) Requested device extensions * @param[in] deviceExtensions (optional) Requested device extensions
* @return New instance of #Context * @return New instance of #Context
*/ */
static Core create(Window &window, static Core create(const char *applicationName,
const char *applicationName,
uint32_t applicationVersion, uint32_t applicationVersion,
std::vector<vk::QueueFlagBits> queueFlags = {}, const std::vector<vk::QueueFlagBits>& queueFlags = {},
std::vector<const char*> instanceExtensions = {}, const Features& features = {},
std::vector<const char*> deviceExtensions = {}); const std::vector<const char *>& instanceExtensions = {});
/** /**
* Creates a basic vulkan graphics pipeline using @p config from the pipeline config class and returns it using the @p handle. * Creates a basic vulkan graphics pipeline using @p config from the pipeline config class and returns it using the @p handle.
...@@ -151,20 +157,17 @@ namespace vkcv ...@@ -151,20 +157,17 @@ namespace vkcv
* @return True if pipeline creation was successful, False if not * @return True if pipeline creation was successful, False if not
*/ */
[[nodiscard]] [[nodiscard]]
PipelineHandle createGraphicsPipeline(const PipelineConfig &config); GraphicsPipelineHandle createGraphicsPipeline(const GraphicsPipelineConfig &config);
/** /**
* Creates a basic vulkan compute pipeline using @p shader program and returns it using the @p handle. * Creates a basic vulkan compute pipeline using @p shader program and returns it using the @p handle.
* Fixed Functions for pipeline are set with standard values. * Fixed Functions for pipeline are set with standard values.
* *
* @param shader program that hold the compiles compute shader * @param config Contains the compiles compute shader and the corresponding descriptor set layout
* @param handle a handle to return the created vulkan handle
* @return True if pipeline creation was successful, False if not * @return True if pipeline creation was successful, False if not
*/ */
[[nodiscard]] [[nodiscard]]
PipelineHandle createComputePipeline( ComputePipelineHandle createComputePipeline(const ComputePipelineConfig &config);
const ShaderProgram &config,
const std::vector<vk::DescriptorSetLayout> &descriptorSetLayouts);
/** /**
* Creates a basic vulkan render pass using @p config from the render pass config class and returns it using the @p handle. * Creates a basic vulkan render pass using @p config from the render pass config class and returns it using the @p handle.
...@@ -185,8 +188,8 @@ namespace vkcv ...@@ -185,8 +188,8 @@ namespace vkcv
* return Buffer-Object * return Buffer-Object
*/ */
template<typename T> template<typename T>
Buffer<T> createBuffer(vkcv::BufferType type, size_t count, BufferMemoryType memoryType = BufferMemoryType::DEVICE_LOCAL) { Buffer<T> createBuffer(vkcv::BufferType type, size_t count, BufferMemoryType memoryType = BufferMemoryType::DEVICE_LOCAL, bool supportIndirect = false) {
return Buffer<T>::create(m_BufferManager.get(), type, count, memoryType); return Buffer<T>::create(m_BufferManager.get(), type, count, memoryType, supportIndirect);
} }
/** /**
...@@ -196,11 +199,13 @@ namespace vkcv ...@@ -196,11 +199,13 @@ namespace vkcv
* @param minFilter Minimizing filter * @param minFilter Minimizing filter
* @param mipmapMode Mipmapping filter * @param mipmapMode Mipmapping filter
* @param addressMode Address mode * @param addressMode Address mode
* @param mipLodBias Mip level of detail bias
* @return Sampler handle * @return Sampler handle
*/ */
[[nodiscard]] [[nodiscard]]
SamplerHandle createSampler(SamplerFilterType magFilter, SamplerFilterType minFilter, SamplerHandle createSampler(SamplerFilterType magFilter, SamplerFilterType minFilter,
SamplerMipmapMode mipmapMode, SamplerAddressMode addressMode); SamplerMipmapMode mipmapMode, SamplerAddressMode addressMode,
float mipLodBias = 0.0f);
/** /**
* Creates an #Image with a given format, width, height and depth. * Creates an #Image with a given format, width, height and depth.
...@@ -222,45 +227,144 @@ namespace vkcv ...@@ -222,45 +227,144 @@ namespace vkcv
bool supportColorAttachment = false, bool supportColorAttachment = false,
Multisampling multisampling = Multisampling::None); Multisampling multisampling = Multisampling::None);
/**
* creates a new window and returns it's handle
* @param applicationName window name
* @param windowWidth
* @param windowHeight
* @param resizeable resizeability bool
* @return windowHandle
*/
[[nodiscard]]
WindowHandle createWindow(
const char *applicationName,
uint32_t windowWidth,
uint32_t windowHeight,
bool resizeable);
/**
* getter for window reference
* @param handle of the window
* @return the window
*/
[[nodiscard]]
Window& getWindow(const WindowHandle& handle );
/**
* gets the swapchain of the current focused window
* @return swapchain
*/
[[nodiscard]]
Swapchain& getSwapchainOfCurrentWindow();
/**
* returns the swapchain reference
* @param handle of the swapchain
* @return swapchain
*/
[[nodiscard]]
Swapchain& getSwapchain(const SwapchainHandle& handle);
/**
* gets the swapchain handle from the window
* @param handle of the window
* @return the swapchain from getSwapchain( SwapchainHandle )
*/
[[nodiscard]]
Swapchain& getSwapchain(const WindowHandle& handle);
/**
* returns the image width
* @param image handle
* @return imageWidth
*/
[[nodiscard]] [[nodiscard]]
uint32_t getImageWidth(ImageHandle imageHandle); uint32_t getImageWidth(const ImageHandle& image);
/**
* returns the image height
* @param image handle
* @return imageHeight
*/
[[nodiscard]] [[nodiscard]]
uint32_t getImageHeight(ImageHandle imageHandle); uint32_t getImageHeight(const ImageHandle& image);
/**
* returns the image format of the image
* @param image handle
* @return imageFormat
*/
[[nodiscard]]
vk::Format getImageFormat(const ImageHandle& image);
/** TODO:
* @param bindings
* @return
*/
[[nodiscard]]
DescriptorSetLayoutHandle createDescriptorSetLayout(const std::unordered_map<uint32_t, DescriptorBinding> &bindingsMap);
DescriptorSetLayout getDescriptorSetLayout(const DescriptorSetLayoutHandle handle) const;
// TODO: existsDescriptorSetLayout function that checks and returns fitting layout upon existence.
/** TODO: /** TODO:
* @param setDescriptions * @param setDescriptions
* @return * @return
*/ */
[[nodiscard]] [[nodiscard]]
DescriptorSetHandle createDescriptorSet(const std::vector<DescriptorBinding> &bindings); DescriptorSetHandle createDescriptorSet(const DescriptorSetLayoutHandle &layoutHandle);
void writeDescriptorSet(DescriptorSetHandle handle, const DescriptorWrites& writes); void writeDescriptorSet(DescriptorSetHandle handle, const DescriptorWrites& writes);
DescriptorSet getDescriptorSet(const DescriptorSetHandle handle) const; DescriptorSet getDescriptorSet(const DescriptorSetHandle handle) const;
/** /**
* @brief start recording command buffers and increment frame index * @brief start recording command buffers and increment frame index
*/ */
bool beginFrame(uint32_t& width, uint32_t& height); bool beginFrame(uint32_t& width, uint32_t& height, const WindowHandle &windowHandle);
void recordDrawcallsToCmdStream( void recordDrawcallsToCmdStream(
const CommandStreamHandle cmdStreamHandle, const CommandStreamHandle& cmdStreamHandle,
const PassHandle renderpassHandle, const PassHandle& renderpassHandle,
const PipelineHandle pipelineHandle, const GraphicsPipelineHandle &pipelineHandle,
const PushConstants &pushConstants, const PushConstants &pushConstants,
const std::vector<DrawcallInfo> &drawcalls, const std::vector<DrawcallInfo> &drawcalls,
const std::vector<ImageHandle> &renderTargets); const std::vector<ImageHandle> &renderTargets,
const WindowHandle &windowHandle);
void recordMeshShaderDrawcalls(
const CommandStreamHandle& cmdStreamHandle,
const PassHandle& renderpassHandle,
const GraphicsPipelineHandle &pipelineHandle,
const PushConstants& pushConstantData,
const std::vector<MeshShaderDrawcall>& drawcalls,
const std::vector<ImageHandle>& renderTargets,
const WindowHandle& windowHandle);
void recordComputeDispatchToCmdStream( void recordComputeDispatchToCmdStream(
CommandStreamHandle cmdStream, CommandStreamHandle cmdStream,
PipelineHandle computePipeline, ComputePipelineHandle computePipeline,
const uint32_t dispatchCount[3], const uint32_t dispatchCount[3],
const std::vector<DescriptorSetUsage> &descriptorSetUsages, const std::vector<DescriptorSetUsage> &descriptorSetUsages,
const PushConstants& pushConstants); const PushConstants& pushConstants);
void recordBeginDebugLabel(const CommandStreamHandle &cmdStream,
const std::string& label,
const std::array<float, 4>& color);
void recordEndDebugLabel(const CommandStreamHandle &cmdStream);
void recordComputeIndirectDispatchToCmdStream(
const CommandStreamHandle cmdStream,
const ComputePipelineHandle computePipeline,
const vkcv::BufferHandle buffer,
const size_t bufferArgOffset,
const std::vector<DescriptorSetUsage>& descriptorSetUsages,
const PushConstants& pushConstants);
/** /**
* @brief end recording and present image * @brief end recording and present image
*/ */
void endFrame(); void endFrame( const WindowHandle& windowHandle );
/** /**
* Submit a command buffer to any queue of selected type. The recording can be customized by a * Submit a command buffer to any queue of selected type. The recording can be customized by a
...@@ -283,15 +387,40 @@ namespace vkcv ...@@ -283,15 +387,40 @@ namespace vkcv
const RecordCommandFunction &record, const RecordCommandFunction &record,
const FinishCommandFunction &finish); const FinishCommandFunction &finish);
void submitCommandStream(const CommandStreamHandle handle); void submitCommandStream(const CommandStreamHandle& handle);
void prepareSwapchainImageForPresent(const CommandStreamHandle handle); void prepareSwapchainImageForPresent(const CommandStreamHandle& handle);
void prepareImageForSampling(const CommandStreamHandle cmdStream, const ImageHandle image); void prepareImageForSampling(const CommandStreamHandle& cmdStream, const ImageHandle& image);
void prepareImageForStorage(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); // normally layout transitions for attachments are handled by the core
void resolveMSAAImage(CommandStreamHandle cmdStream, ImageHandle src, ImageHandle dst); // however for manual vulkan use, e.g. ImGui integration, this function is exposed
// this is also why the command buffer is passed directly, instead of the command stream handle
void prepareImageForAttachmentManually(const vk::CommandBuffer& cmdBuffer, const ImageHandle& image);
// if manual vulkan work, e.g. ImGui integration, changes an image layout this function must be used
// to update the internal image state
void updateImageLayoutManual(const vkcv::ImageHandle& image, const vk::ImageLayout layout);
void recordImageMemoryBarrier(const CommandStreamHandle& cmdStream, const ImageHandle& image);
void recordBufferMemoryBarrier(const CommandStreamHandle& cmdStream, const BufferHandle& buffer);
void resolveMSAAImage(const CommandStreamHandle& cmdStream, const ImageHandle& src, const ImageHandle& dst);
[[nodiscard]]
vk::ImageView getSwapchainImageView() const; vk::ImageView getSwapchainImageView() const;
void recordMemoryBarrier(const CommandStreamHandle& cmdStream);
void recordBlitImage(const CommandStreamHandle& cmdStream, const ImageHandle& src, const ImageHandle& dst,
SamplerFilterType filterType);
void setDebugLabel(const BufferHandle &handle, const std::string &label);
void setDebugLabel(const PassHandle &handle, const std::string &label);
void setDebugLabel(const GraphicsPipelineHandle &handle, const std::string &label);
void setDebugLabel(const ComputePipelineHandle &handle, const std::string &label);
void setDebugLabel(const DescriptorSetHandle &handle, const std::string &label);
void setDebugLabel(const SamplerHandle &handle, const std::string &label);
void setDebugLabel(const ImageHandle &handle, const std::string &label);
void setDebugLabel(const CommandStreamHandle &handle, const std::string &label);
}; };
} }
#pragma once #pragma once
#include <vulkan/vulkan.hpp> #include <unordered_map>
#include "vkcv/Handles.hpp" #include "vkcv/Handles.hpp"
#include "vkcv/ShaderStage.hpp" #include "vkcv/ShaderStage.hpp"
#include "vkcv/Logger.hpp"
namespace vkcv namespace vkcv
{ {
struct DescriptorSet
{
vk::DescriptorSet vulkanHandle;
vk::DescriptorSetLayout layout;
size_t poolIndex;
};
/* /*
* All the types of descriptors (resources) that can be retrieved by the shaders * All the types of descriptors (resources) that can be retrieved by the shaders
*/ */
...@@ -23,9 +17,38 @@ namespace vkcv ...@@ -23,9 +17,38 @@ namespace vkcv
STORAGE_BUFFER, STORAGE_BUFFER,
SAMPLER, SAMPLER,
IMAGE_SAMPLED, IMAGE_SAMPLED,
IMAGE_STORAGE IMAGE_STORAGE,
UNIFORM_BUFFER_DYNAMIC,
STORAGE_BUFFER_DYNAMIC
}; };
/**
* Converts the descriptor types from VulkanCV (vkcv) to native Vulkan (vk).
* @param[in] vkcv DescriptorType
* @return vk DescriptorType
*/
constexpr vk::DescriptorType getVkDescriptorType(DescriptorType type) noexcept {
switch (type)
{
case DescriptorType::UNIFORM_BUFFER:
return vk::DescriptorType::eUniformBuffer;
case DescriptorType::UNIFORM_BUFFER_DYNAMIC:
return vk::DescriptorType::eUniformBufferDynamic;
case DescriptorType::STORAGE_BUFFER:
return vk::DescriptorType::eStorageBuffer;
case DescriptorType::STORAGE_BUFFER_DYNAMIC:
return vk::DescriptorType::eStorageBufferDynamic;
case DescriptorType::SAMPLER:
return vk::DescriptorType::eSampler;
case DescriptorType::IMAGE_SAMPLED:
return vk::DescriptorType::eSampledImage;
case DescriptorType::IMAGE_STORAGE:
return vk::DescriptorType::eStorageImage;
default:
return vk::DescriptorType::eMutableVALVE;
}
}
/* /*
* One binding for a descriptor set * One binding for a descriptor set
* @param[in] a unique binding ID * @param[in] a unique binding ID
...@@ -39,12 +62,29 @@ namespace vkcv ...@@ -39,12 +62,29 @@ namespace vkcv
uint32_t bindingID, uint32_t bindingID,
DescriptorType descriptorType, DescriptorType descriptorType,
uint32_t descriptorCount, uint32_t descriptorCount,
ShaderStage shaderStage ShaderStages shaderStages
) noexcept; ) noexcept;
uint32_t bindingID; uint32_t bindingID;
DescriptorType descriptorType; DescriptorType descriptorType;
uint32_t descriptorCount; uint32_t descriptorCount;
ShaderStage shaderStage; ShaderStages shaderStages;
bool operator ==(const DescriptorBinding &other) const;
};
typedef std::unordered_map<uint32_t, DescriptorBinding> DescriptorBindings;
struct DescriptorSetLayout
{
vk::DescriptorSetLayout vulkanHandle;
DescriptorBindings descriptorBindings;
};
struct DescriptorSet
{
vk::DescriptorSet vulkanHandle;
DescriptorSetLayoutHandle setLayoutHandle;
size_t poolIndex;
}; };
} }
...@@ -20,16 +20,15 @@ namespace vkcv { ...@@ -20,16 +20,15 @@ namespace vkcv {
uint32_t mipLevel; uint32_t mipLevel;
}; };
struct UniformBufferDescriptorWrite { struct BufferDescriptorWrite {
inline UniformBufferDescriptorWrite(uint32_t binding, BufferHandle buffer) : binding(binding), buffer(buffer) {}; inline BufferDescriptorWrite(uint32_t binding, BufferHandle buffer, bool dynamic = false,
uint32_t binding; uint32_t offset = 0, uint32_t size = 0) :
BufferHandle buffer; binding(binding), buffer(buffer), dynamic(dynamic), offset(offset), size(size) {};
};
struct StorageBufferDescriptorWrite {
inline StorageBufferDescriptorWrite(uint32_t binding, BufferHandle buffer) : binding(binding), buffer(buffer) {};
uint32_t binding; uint32_t binding;
BufferHandle buffer; BufferHandle buffer;
bool dynamic;
uint32_t offset;
uint32_t size;
}; };
struct SamplerDescriptorWrite { struct SamplerDescriptorWrite {
...@@ -41,8 +40,8 @@ namespace vkcv { ...@@ -41,8 +40,8 @@ namespace vkcv {
struct DescriptorWrites { struct DescriptorWrites {
std::vector<SampledImageDescriptorWrite> sampledImageWrites; std::vector<SampledImageDescriptorWrite> sampledImageWrites;
std::vector<StorageImageDescriptorWrite> storageImageWrites; std::vector<StorageImageDescriptorWrite> storageImageWrites;
std::vector<UniformBufferDescriptorWrite> uniformBufferWrites; std::vector<BufferDescriptorWrite> uniformBufferWrites;
std::vector<StorageBufferDescriptorWrite> storageBufferWrites; std::vector<BufferDescriptorWrite> storageBufferWrites;
std::vector<SamplerDescriptorWrite> samplerWrites; std::vector<SamplerDescriptorWrite> samplerWrites;
}; };
} }
\ No newline at end of file
...@@ -13,21 +13,41 @@ namespace vkcv { ...@@ -13,21 +13,41 @@ namespace vkcv {
vk::Buffer buffer; vk::Buffer buffer;
}; };
enum class IndexBitCount{
Bit16,
Bit32
};
struct DescriptorSetUsage { struct DescriptorSetUsage {
inline DescriptorSetUsage(uint32_t setLocation, vk::DescriptorSet vulkanHandle) noexcept inline DescriptorSetUsage(uint32_t setLocation, vk::DescriptorSet vulkanHandle,
: setLocation(setLocation), vulkanHandle(vulkanHandle) {} const std::vector<uint32_t>& dynamicOffsets = {}) noexcept
: setLocation(setLocation), vulkanHandle(vulkanHandle), dynamicOffsets(dynamicOffsets) {}
const uint32_t setLocation; const uint32_t setLocation;
const vk::DescriptorSet vulkanHandle; const vk::DescriptorSet vulkanHandle;
const std::vector<uint32_t> dynamicOffsets;
}; };
struct Mesh { struct Mesh {
inline Mesh(std::vector<VertexBufferBinding> vertexBufferBindings, vk::Buffer indexBuffer, size_t indexCount) noexcept
: vertexBufferBindings(vertexBufferBindings), indexBuffer(indexBuffer), indexCount(indexCount){} inline Mesh(){}
inline Mesh(
std::vector<VertexBufferBinding> vertexBufferBindings,
vk::Buffer indexBuffer,
size_t indexCount,
IndexBitCount indexBitCount = IndexBitCount::Bit16) noexcept
:
vertexBufferBindings(vertexBufferBindings),
indexBuffer(indexBuffer),
indexCount(indexCount),
indexBitCount(indexBitCount) {}
std::vector<VertexBufferBinding> vertexBufferBindings; std::vector<VertexBufferBinding> vertexBufferBindings;
vk::Buffer indexBuffer; vk::Buffer indexBuffer;
size_t indexCount; size_t indexCount;
IndexBitCount indexBitCount;
}; };
struct DrawcallInfo { struct DrawcallInfo {
...@@ -46,4 +66,21 @@ namespace vkcv { ...@@ -46,4 +66,21 @@ namespace vkcv {
const PushConstants &pushConstants, const PushConstants &pushConstants,
const size_t drawcallIndex); const size_t drawcallIndex);
} void InitMeshShaderDrawFunctions(vk::Device device);
\ No newline at end of file
struct MeshShaderDrawcall {
inline MeshShaderDrawcall(const std::vector<DescriptorSetUsage> descriptorSets, uint32_t taskCount)
: descriptorSets(descriptorSets), taskCount(taskCount) {}
std::vector<DescriptorSetUsage> descriptorSets;
uint32_t taskCount;
};
void recordMeshShaderDrawcall(
vk::CommandBuffer cmdBuffer,
vk::PipelineLayout pipelineLayout,
const PushConstants& pushConstantData,
const uint32_t pushConstantOffset,
const MeshShaderDrawcall& drawcall,
const uint32_t firstTask);
}
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <mutex> #include <mutex>
#endif #endif
#include <vector>
namespace vkcv { namespace vkcv {
template<typename... T> template<typename... T>
......
#pragma once
#include "Logger.hpp"
#include <functional>
#include <unordered_set>
#include <vector>
#include <vulkan/vulkan.hpp>
namespace vkcv {
class FeatureManager {
private:
vk::PhysicalDevice& m_physicalDevice;
std::vector<const char*> m_supportedExtensions;
std::vector<const char*> m_activeExtensions;
vk::PhysicalDeviceFeatures2 m_featuresBase;
std::vector<vk::BaseOutStructure*> m_featuresExtensions;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceFeatures& features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDevice16BitStorageFeatures& features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDevice8BitStorageFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceBufferDeviceAddressFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceDescriptorIndexingFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceHostQueryResetFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceImagelessFramebufferFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceMultiviewFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceProtectedMemoryFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceSamplerYcbcrConversionFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceScalarBlockLayoutFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceSeparateDepthStencilLayoutsFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceShaderAtomicInt64Features &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceShaderFloat16Int8Features& features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceShaderSubgroupExtendedTypesFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceTimelineSemaphoreFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceUniformBufferStandardLayoutFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceVariablePointersFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceVulkanMemoryModelFeatures &features, bool required) const;
[[nodiscard]]
bool checkSupport(const vk::PhysicalDeviceMeshShaderFeaturesNV& features, bool required) const;
vk::BaseOutStructure* findFeatureStructure(vk::StructureType type) const;
public:
explicit FeatureManager(vk::PhysicalDevice& physicalDevice);
FeatureManager(const FeatureManager& other) = delete;
FeatureManager(FeatureManager&& other) noexcept;
~FeatureManager();
FeatureManager& operator=(const FeatureManager& other) = delete;
FeatureManager& operator=(FeatureManager&& other) noexcept;
[[nodiscard]]
bool isExtensionSupported(const std::string& extension) const;
bool useExtension(const std::string& extension, bool required = true);
[[nodiscard]]
bool isExtensionActive(const std::string& extension) const;
[[nodiscard]]
const std::vector<const char*>& getActiveExtensions() const;
bool useFeatures(const std::function<void(vk::PhysicalDeviceFeatures&)>& featureFunction, bool required = true);
template<typename T>
bool useFeatures(const std::function<void(T&)>& featureFunction, bool required = true) {
T features;
T* features_ptr = reinterpret_cast<T*>(findFeatureStructure(features.sType));
if (features_ptr) {
features = *features_ptr;
}
featureFunction(features);
if (!checkSupport(features, required)) {
if (required) {
throw std::runtime_error("Required feature is not supported!");
}
return false;
}
if (features_ptr) {
*features_ptr = features;
return true;
}
features_ptr = new T(features);
if (m_featuresExtensions.empty()) {
m_featuresBase.setPNext(features_ptr);
} else {
m_featuresExtensions.back()->setPNext(
reinterpret_cast<vk::BaseOutStructure*>(features_ptr)
);
}
m_featuresExtensions.push_back(
reinterpret_cast<vk::BaseOutStructure*>(features_ptr)
);
return true;
}
[[nodiscard]]
const vk::PhysicalDeviceFeatures2& getFeatures() const;
};
}
#pragma once
#include <functional>
#include <vector>
#include <initializer_list>
#include "FeatureManager.hpp"
namespace vkcv {
typedef std::function<bool(FeatureManager&)> Feature;
class Features {
private:
std::vector<Feature> m_features;
public:
Features() = default;
Features(const std::initializer_list<std::string>& list);
Features(const Features& other) = default;
Features(Features&& other) = default;
~Features() = default;
Features& operator=(const Features& other) = default;
Features& operator=(Features&& other) = default;
void requireExtension(const std::string& extension);
void requireExtensionFeature(const std::string& extension,
const std::function<void(vk::PhysicalDeviceFeatures&)>& featureFunction);
template<typename T>
void requireExtensionFeature(const std::string& extension, const std::function<void(T&)>& featureFunction) {
m_features.emplace_back([extension, featureFunction](FeatureManager& featureManager) {
if (featureManager.useExtension(extension, true)) {
return featureManager.template useFeatures<T>(featureFunction, true);
} else {
return false;
}
});
}
void requireFeature(const std::function<void(vk::PhysicalDeviceFeatures&)>& featureFunction);
template<typename T>
void requireFeature(const std::function<void(T&)>& featureFunction) {
m_features.emplace_back([featureFunction](FeatureManager& featureManager) {
return featureManager.template useFeatures<T>(featureFunction, true);
});
}
void tryExtension(const std::string& extension);
void tryExtensionFeature(const std::string& extension,
const std::function<void(vk::PhysicalDeviceFeatures&)>& featureFunction);
template<typename T>
void tryExtensionFeature(const std::string& extension, const std::function<void(T&)>& featureFunction) {
m_features.emplace_back([extension, featureFunction](FeatureManager& featureManager) {
if (featureManager.useExtension(extension, false)) {
return featureManager.template useFeatures<T>(featureFunction, false);
} else {
return false;
}
});
}
void tryFeature(const std::function<void(vk::PhysicalDeviceFeatures&)>& featureFunction);
template<typename T>
void tryFeature(const std::function<void(T&)>& featureFunction) {
m_features.emplace_back([featureFunction](FeatureManager& featureManager) {
return featureManager.template useFeatures<T>(featureFunction, false);
});
}
[[nodiscard]]
const std::vector<Feature>& getList() const;
};
}
#pragma once
#include <filesystem>
namespace vkcv {
std::filesystem::path generateTemporaryFilePath();
std::filesystem::path generateTemporaryDirectoryPath();
}
#pragma once #pragma once
/** /**
* @authors Mara Vogt, Mark Mints * @authors Mara Vogt, Mark Mints
* @file src/vkcv/Pipeline.hpp * @file src/vkcv/PipelineConfig.hpp
* @brief Pipeline class to handle shader stages * @brief Graphics Pipeline Config Struct to hand over required information to Pipeline Creation
*/ */
#include <vector> #include <vector>
...@@ -22,7 +22,7 @@ namespace vkcv { ...@@ -22,7 +22,7 @@ namespace vkcv {
// alternatively we could expose the blend factors directly // alternatively we could expose the blend factors directly
enum class BlendMode{ None, Additive }; enum class BlendMode{ None, Additive };
struct PipelineConfig { struct GraphicsPipelineConfig {
ShaderProgram m_ShaderProgram; ShaderProgram m_ShaderProgram;
uint32_t m_Width; uint32_t m_Width;
uint32_t m_Height; uint32_t m_Height;
......