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 (112)
Showing
with 606 additions and 163 deletions
*.blend filter=lfs diff=lfs merge=lfs -text
*.blend1 filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.glb filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.tif filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.gltf filter=lfs diff=lfs merge=lfs
<<<<<<< HEAD
=======
>>>>>>> develop
# IDE specific files # IDE specific files
.project .project
.cproject .cproject
......
variables:
RUN:
value: "all"
description: "The tests that should run. Possible values: ubuntu, win, all."
GIT_DEPTH: 1
stages: stages:
- build - build
- deploy - deploy
build_ubuntu_gcc: build_ubuntu_gcc:
only:
variables:
- $RUN =~ /\bubuntu.*/i || $RUN =~ /\ball.*/i
stage: build stage: build
tags: tags:
- ubuntu-gcc - ubuntu-gcc
variables: variables:
GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_STRATEGY: recursive
timeout: 10m
retry: 1
script: script:
- mkdir debug - mkdir debug
- cd debug - cd debug
...@@ -21,11 +32,16 @@ build_ubuntu_gcc: ...@@ -21,11 +32,16 @@ build_ubuntu_gcc:
expire_in: never expire_in: never
build_win10_msvc: build_win10_msvc:
only:
variables:
- $RUN =~ /\bwin.*/i || $RUN =~ /\ball.*/i
stage: build stage: build
tags: tags:
- win10-msvc - win10-msvc
variables: variables:
GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_STRATEGY: recursive
timeout: 10m
retry: 1
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\'
- .\Launch-VsDevShell.ps1 - .\Launch-VsDevShell.ps1
...@@ -37,6 +53,8 @@ build_win10_msvc: ...@@ -37,6 +53,8 @@ build_win10_msvc:
deploy_doc_develop: deploy_doc_develop:
only: only:
variables:
- $RUN =~ /\bubuntu.*/i || $RUN =~ /\ball.*/i
refs: refs:
- develop - develop
stage: deploy stage: deploy
...@@ -52,6 +70,9 @@ deploy_doc_develop: ...@@ -52,6 +70,9 @@ deploy_doc_develop:
- echo "Check it out at https://vkcv.de/develop" - echo "Check it out at https://vkcv.de/develop"
deploy_doc_branch: deploy_doc_branch:
only:
variables:
- $RUN =~ /\bubuntu.*/i || $RUN =~ /\ball.*/i
except: except:
refs: refs:
- develop - develop
......
[submodule "lib/glfw"] [submodule "lib/glfw"]
path = lib/glfw path = lib/glfw
url = https://github.com/glfw/glfw.git url = https://github.com/glfw/glfw.git
[submodule "modules/asset_loader/lib/fx-gltf"]
path = modules/asset_loader/lib/fx-gltf
url = https://github.com/jessey-git/fx-gltf.git
[submodule "modules/asset_loader/lib/json"]
path = modules/asset_loader/lib/json
url = https://github.com/nlohmann/json.git
[submodule "modules/asset_loader/lib/stb"]
path = modules/asset_loader/lib/stb
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
...@@ -72,12 +72,15 @@ endif() ...@@ -72,12 +72,15 @@ endif()
# add include directories from dependencies as system includes # add include directories from dependencies as system includes
target_include_directories(vkcv SYSTEM BEFORE PRIVATE ${vkcv_includes}) target_include_directories(vkcv SYSTEM BEFORE PRIVATE ${vkcv_includes})
message(STATUS ${vkcv_includes})
# add the own include directory for public headers # add the own include directory for public headers
target_include_directories(vkcv BEFORE PUBLIC ${vkcv_include}) target_include_directories(vkcv BEFORE PUBLIC ${vkcv_include})
message(STATUS ${vkcv_include})
# link the framework using all required libraries # link the framework using all required libraries
target_link_libraries(vkcv ${vkcv_libraries}) target_link_libraries(vkcv ${vkcv_libraries})
message(STATUS ${vkcv_libraries})
# add sub-projects/examples as targets # add sub-projects/examples as targets
add_subdirectory(projects) add_subdirectory(projects)
......
...@@ -3,7 +3,25 @@ ...@@ -3,7 +3,25 @@
![Vulkan-Chan](https://gitlab.uni-koblenz.de/uploads/-/system/project/avatar/3712/VulkanChan.jpg) ![Vulkan-Chan](https://gitlab.uni-koblenz.de/uploads/-/system/project/avatar/3712/VulkanChan.jpg)
## Repository
Git LFS is used for bigger resource files like meshes and textures. So you need to install Git LFS and use `git lfs install` after cloning.
More information about Git LFS [here](https://git-lfs.github.com/).
## Build ## Build
[![pipeline status](https://gitlab.uni-koblenz.de/vulkan2021/vkcv-framework/badges/develop/pipeline.svg)](https://gitlab.uni-koblenz.de/vulkan2021/vkcv-framework/-/commits/develop)
Git submodules are used for libraries. Git submodules are used for libraries.
To download the submodules either clone using `git clone --recurse-submodules` or after `git clone` use `git submodule init` and `git submodule update`. To download the submodules either clone using `git clone --recurse-submodules` or after `git clone` use `git submodule init` and `git submodule update`.
## Documentation
The documentation for the develop-branch can be found here:
https://vkcv.de/develop/
The documentation concerning the respective merge request is listed here:
https://vkcv.de/branch/
It is automatically generated and uploaded using the CI pipeline.
...@@ -20,7 +20,9 @@ set(vkcv_sources ...@@ -20,7 +20,9 @@ set(vkcv_sources
${vkcv_source}/vkcv/Window.cpp ${vkcv_source}/vkcv/Window.cpp
${vkcv_include}/vkcv/Buffer.hpp ${vkcv_include}/vkcv/Buffer.hpp
${vkcv_source}/vkcv/Buffer.cpp
${vkcv_include}/vkcv/BufferManager.hpp
${vkcv_source}/vkcv/BufferManager.cpp
${vkcv_include}/vkcv/SwapChain.hpp ${vkcv_include}/vkcv/SwapChain.hpp
${vkcv_source}/vkcv/SwapChain.cpp ${vkcv_source}/vkcv/SwapChain.cpp
...@@ -51,4 +53,12 @@ set(vkcv_sources ...@@ -51,4 +53,12 @@ set(vkcv_sources
${vkcv_source}/vkcv/Framebuffer.hpp ${vkcv_source}/vkcv/Framebuffer.hpp
${vkcv_source}/vkcv/Framebuffer.cpp ${vkcv_source}/vkcv/Framebuffer.cpp
${vkcv_include}/vkcv/Event.hpp
${vkcv_source}/vkcv/DescriptorManager.hpp
${vkcv_source}/vkcv/DescriptorManager.cpp
${vkcv_include}/vkcv/DescriptorConfig.hpp
${vkcv_source}/vkcv/DescriptorConfig.cpp
) )
#pragma once #pragma once
/** /**
* @authors Lars Hoerttrich * @authors Lars Hoerttrich, Tobias Frisch
* @file include/vkcv/Buffer.hpp * @file vkcv/Buffer.hpp
* @brief template buffer class, template for type security, implemented here because template classes can't be written in .cpp * @brief template buffer class, template for type security, implemented here because template classes can't be written in .cpp
*/ */
#include "vkcv/Handles.hpp" #include "Handles.hpp"
#include <vulkan/vulkan.hpp> #include "BufferManager.hpp"
#include "vkcv/Context.hpp"
namespace vkcv { namespace vkcv {
//Enum of buffertypes
enum BufferType { VERTEX, UNIFORM, STORAGE };
//Functions outsourced to Buffer.cpp file:
void outsourcedDestructor(vk::Device device, vk::DeviceMemory bufferMemory, vk::Buffer buffer);
vk::Buffer outsourcedCreateBuffer(vk::Device device, BufferType type, size_t size);
vk::DeviceMemory outsourcedAllocateMemory(vk::Device device, vk::PhysicalDevice physicalDevice, vk::MemoryRequirements memoryRequirements);
template<typename T> template<typename T>
class Buffer { class Buffer {
friend class Core;
public: public:
//future bufferHandle struct
struct Handle {
uint64_t id;
};
// explicit destruction of default constructor // explicit destruction of default constructor
Buffer<T>() = delete; Buffer<T>() = delete;
// is never called directly
~Buffer<T>() noexcept { [[nodiscard]]
outsourcedDestructor(m_Device, m_BufferMemory, m_Buffer); const BufferHandle& getHandle() const {
return m_handle;
} }
Buffer<T>(const Buffer<T>& other) = delete; // copy-ctor
Buffer<T>(Buffer<T>&& other) noexcept :
m_Buffer(other.m_Buffer),
m_BufferMemory(other.m_BufferMemory),
m_Device(other.m_Device),
m_Type(other.m_Type),
m_Size(other.m_Size),
m_DataP(other.m_DataP)
{
other.m_Buffer = nullptr;
other.m_BufferMemory = nullptr;
other.m_Device = nullptr;
other.m_Type = vkcv::VERTEX; //set to 0
other.m_Size = 0;
other.m_DataP = nullptr;
} // move-ctor
Buffer<T>& operator=(const Buffer<T>& other) = delete; // copy assignment
Buffer<T>& operator=(Buffer<T>&& other) noexcept {
m_Buffer = other.m_Buffer;
m_BufferMemory = other.m_BufferMemory;
m_Device = other.m_Device;
m_Type = other.m_Type;
m_Size = other.m_Size;
m_DataP = other.m_DataP;
other.m_Buffer = nullptr;
other.m_BufferMemory = nullptr;
other.m_Device = nullptr;
other.m_Type = vkcv::VERTEX; //set to 0
other.m_Size = 0;
other.m_DataP = nullptr;
}// move assignment
BufferType getType() { return m_Type; };
size_t getSize() { return m_Size; };
/** [[nodiscard]]
* Maps this buffers Memory, fills this buffer with @p data of type T and count @p count BufferType getType() const {
* unmaps afterwards. return m_type;
* @p data Pointer to data
* @p count Amount of data of type T
*/
// TODO: we will probably need staging-buffer here later (possible add in BufferManager later?)
void fill(T* data, size_t count) {
const vk::MemoryRequirements requirements = m_Device.getBufferMemoryRequirements(m_Buffer);
// TODO: check if mapped already
m_DataP = static_cast<uint8_t*>(m_Device.mapMemory(m_BufferMemory, 0, requirements.size));
memcpy(m_DataP, data, sizeof(T) * count);
m_Device.unmapMemory(m_BufferMemory);
}; };
T* map() { [[nodiscard]]
const vk::MemoryRequirements requirements = m_Device.getBufferMemoryRequirements(m_Buffer); size_t getCount() const {
return m_count;
m_DataP = static_cast<uint8_t*>(m_Device.mapMemory(m_BufferMemory, 0, requirements.size)); }
// TODO: make sure to unmap before deallocation
return reinterpret_cast<T*>(m_DataP);
};
void unmap() { [[nodiscard]]
m_Device.unmapMemory(m_BufferMemory); size_t getSize() const {
// TODO: mark m_DataP as invalid? return m_count * sizeof(T);
}; }
/** void fill(T* data, size_t count = 0, size_t offset = 0) {
* * Create function of #Buffer requires a @p device, a @p physicalDevice, a @p buffer type and a @p size. * m_manager->fillBuffer(m_handle, data, count * sizeof(T), offset * sizeof(T));
* @param device Vulkan-Device }
* @param physicalDevice Vulkan-PhysicalDevice
* @param type Enum type of possible vkcv::BufferType [[nodiscard]]
* @param Size size of data T* map(size_t offset = 0, size_t count = 0) {
*/ return reinterpret_cast<T*>(m_manager->mapBuffer(m_handle, offset * sizeof(T), count * sizeof(T)));
static Buffer<T> create(vk::Device device, vk::PhysicalDevice physicalDevice, BufferType type, size_t size) { }
vk::Buffer buffer = nullptr;
buffer = outsourcedCreateBuffer(device, type, sizeof(T) * size); void unmap() {
m_manager->unmapBuffer(m_handle);
if (!buffer) {
//TODO: potential issue
}
//get requirements for allocation
const vk::MemoryRequirements requirements = device.getBufferMemoryRequirements(buffer);
vk::DeviceMemory memory= outsourcedAllocateMemory(device, physicalDevice, requirements);
if (!memory) {
//TODO: other potential issue
}
device.bindBufferMemory(buffer, memory, 0);
return Buffer<T>(buffer, memory, device, type, size);
} }
private: private:
vk::Buffer m_Buffer; BufferManager* const m_manager;
vk::DeviceMemory m_BufferMemory; const BufferHandle m_handle;
vk::Device m_Device; const BufferType m_type;
BufferType m_Type; const size_t m_count;
size_t m_Size=0; const BufferMemoryType m_memoryType;
uint8_t* m_DataP;
Buffer<T>(BufferManager* manager, BufferHandle handle, BufferType type, size_t count, BufferMemoryType memoryType) :
/** m_manager(manager),
* * Constructor of #Buffer requires a @p buffer, a @p memory, @p device, @ requirement, a @p buffer type and a @p size. m_handle(handle),
* @param buffer Vulkan-Buffer m_type(type),
* @param memory Vulkan-DeviceMemory m_count(count),
* @param device Vulkan-Device m_memoryType(memoryType)
* @param requirement Vulkan-MemoryRequirements {}
* @param type Enum type of possible vkcv::BufferType
* @param Size size of data [[nodiscard]]
*/ static Buffer<T> create(BufferManager* manager, BufferType type, size_t count, BufferMemoryType memoryType) {
Buffer<T>(vk::Buffer buffer, vk::DeviceMemory memory, vk::Device device, BufferType type, size_t size) : return Buffer<T>(manager, manager->createBuffer(type, count * sizeof(T), memoryType), type, count, memoryType);
m_Buffer(buffer), }
m_BufferMemory(memory),
m_Device(device),
m_Type(type),
m_Size(size),
m_DataP(nullptr)
{}
}; };
} }
#pragma once
#include <vector>
#include <vulkan/vulkan.hpp>
#include "Handles.hpp"
namespace vkcv
{
enum class BufferType {
INDEX,
VERTEX,
UNIFORM,
STORAGE,
STAGING
};
enum class BufferMemoryType {
DEVICE_LOCAL,
HOST_VISIBLE
};
class Core;
class BufferManager
{
friend class Core;
private:
struct Buffer
{
vk::Buffer m_handle;
vk::DeviceMemory m_memory;
size_t m_size;
void* m_mapped = nullptr;
bool m_mappable;
};
Core* m_core;
std::vector<Buffer> m_buffers;
BufferHandle m_stagingBuffer;
BufferManager() noexcept;
void init();
public:
~BufferManager() noexcept;
BufferManager(BufferManager&& other) = delete;
BufferManager(const BufferManager& other) = delete;
BufferManager& operator=(BufferManager&& other) = delete;
BufferManager& operator=(const BufferManager& other) = delete;
/**
* Creates and allocates a new buffer and returns its
* unique buffer handle id.
*
* @param type Type of buffer
* @param size Size of buffer in bytes
* @param memoryType Type of buffers memory
* @return New buffer handle
*/
BufferHandle createBuffer(BufferType type, size_t size, BufferMemoryType memoryType);
/**
* Returns the Vulkan buffer handle of a buffer
* represented by a given buffer handle id.
*
* @param handle Buffer handle
* @return Vulkan buffer handle
*/
[[nodiscard]]
vk::Buffer getBuffer(const BufferHandle& handle) const;
/**
* Returns the Vulkan device memory handle of a buffer
* represented by a given buffer handle id.
*
* @param handle Buffer handle
* @return Vulkan device memory handle
*/
[[nodiscard]]
vk::DeviceMemory getDeviceMemory(const BufferHandle& handle) const;
/**
* Fills a buffer represented by a given buffer
* handle id with custom data.
*
* @param handle Buffer handle
* @param data Pointer to data
* @param size Size of data in bytes
* @param offset Offset to fill in data in bytes
*/
void fillBuffer(const BufferHandle& handle, void* data, size_t size, size_t offset);
/**
* Maps memory to a buffer represented by a given
* buffer handle id and returns it.
*
* @param handle Buffer handle
* @param offset Offset of mapping in bytes
* @param size Size of mapping in bytes
* @return Pointer to mapped memory
*/
void* mapBuffer(const BufferHandle& handle, size_t offset, size_t size);
/**
* Unmaps memory from a buffer represented by a given
* buffer handle id.
*
* @param handle Buffer handle
*/
void unmapBuffer(const BufferHandle& handle);
/**
* Destroys and deallocates buffer represented by a given
* buffer handle id.
*
* @param handle Buffer handle
*/
void destroyBuffer(const BufferHandle& handle);
};
}
#pragma once #pragma once
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include <unordered_set>
#include "QueueManager.hpp"
namespace vkcv { namespace vkcv {
struct CommandResources { struct CommandResources {
vk::CommandPool commandPool; std::vector<vk::CommandPool> cmdPoolPerQueueFamily;
vk::CommandBuffer commandBuffer;
}; };
CommandResources createDefaultCommandResources(const vk::Device& device, const int graphicFamilyIndex); std::unordered_set<int> generateQueueFamilyIndexSet(const QueueManager& queueManager);
void destroyCommandResources(const vk::Device& device, const CommandResources& resources); CommandResources createCommandResources(const vk::Device& device, const std::unordered_set<int> &familyIndexSet);
void destroyCommandResources(const vk::Device& device, const CommandResources& resources);
vk::CommandBuffer allocateCommandBuffer(const vk::Device& device, const vk::CommandPool cmdPool);
vk::CommandPool chooseCmdPool(const Queue &queue, const CommandResources &cmdResources);
Queue getQueueForSubmit(const QueueType type, const QueueManager &queueManager);
void beginCommandBuffer(const vk::CommandBuffer cmdBuffer, const vk::CommandBufferUsageFlags flags);
void submitCommandBufferToQueue(
const vk::Queue queue,
const vk::CommandBuffer cmdBuffer,
const vk::Fence fence,
const std::vector<vk::Semaphore>& waitSemaphores,
const std::vector<vk::Semaphore>& signalSemaphores);
} }
\ No newline at end of file
...@@ -17,12 +17,24 @@ ...@@ -17,12 +17,24 @@
#include "CommandResources.hpp" #include "CommandResources.hpp"
#include "SyncResources.hpp" #include "SyncResources.hpp"
#include "Result.hpp" #include "Result.hpp"
#include "vkcv/DescriptorConfig.hpp"
namespace vkcv namespace vkcv
{ {
// forward declarations // forward declarations
class PassManager; class PassManager;
class PipelineManager; class PipelineManager;
class DescriptorManager;
class BufferManager;
struct SubmitInfo {
QueueType queueType;
std::vector<vk::Semaphore> waitSemaphores;
std::vector<vk::Semaphore> signalSemaphores;
};
typedef std::function<void(const vk::CommandBuffer& cmdBuffer)> RecordCommandFunction;
typedef std::function<void(void)> FinishCommandFunction;
class Core final class Core final
{ {
...@@ -33,7 +45,7 @@ namespace vkcv ...@@ -33,7 +45,7 @@ namespace vkcv
* *
* @param context encapsulates various Vulkan objects * @param context encapsulates various Vulkan objects
*/ */
Core(Context &&context, const Window &window, SwapChain swapChain, std::vector<vk::ImageView> imageViews, Core(Context &&context, Window &window, SwapChain swapChain, std::vector<vk::ImageView> imageViews,
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;
...@@ -49,10 +61,21 @@ namespace vkcv ...@@ -49,10 +61,21 @@ namespace vkcv
std::unique_ptr<PassManager> m_PassManager; std::unique_ptr<PassManager> m_PassManager;
std::unique_ptr<PipelineManager> m_PipelineManager; std::unique_ptr<PipelineManager> m_PipelineManager;
std::unique_ptr<DescriptorManager> m_DescriptorManager;
std::unique_ptr<BufferManager> m_BufferManager;
CommandResources m_CommandResources; CommandResources m_CommandResources;
SyncResources m_SyncResources; SyncResources m_SyncResources;
uint32_t m_currentSwapchainImageIndex; uint32_t m_currentSwapchainImageIndex;
std::vector<vk::Framebuffer> m_TemporaryFramebuffers; std::vector<vk::Framebuffer> m_TemporaryFramebuffers;
/**
* recreates the swapchain
* @param[in] width new window width
* @param[in] height new window hight
*/
static void recreateSwapchain(int width, int height);
public: public:
/** /**
* Destructor of #Core destroys the Vulkan objects contained in the core's context. * Destructor of #Core destroys the Vulkan objects contained in the core's context.
...@@ -107,7 +130,7 @@ namespace vkcv ...@@ -107,7 +130,7 @@ 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(const Window &window, static Core create(Window &window,
const char *applicationName, const char *applicationName,
uint32_t applicationVersion, uint32_t applicationVersion,
std::vector<vk::QueueFlagBits> queueFlags = {}, std::vector<vk::QueueFlagBits> queueFlags = {},
...@@ -138,15 +161,23 @@ namespace vkcv ...@@ -138,15 +161,23 @@ namespace vkcv
/** /**
* Creates a #Buffer with data-type T and @p bufferType * Creates a #Buffer with data-type T and @p bufferType
* @param bufferType Type of Buffer created * @param type Type of Buffer created
* @param size Amount of Data of type T * @param count Count of elements of type T
* @param memoryType Type of Buffers memory
* return Buffer-Object * return Buffer-Object
*/ */
template<typename T> template<typename T>
Buffer<T> createBuffer(vkcv::BufferType bufferType,size_t size) { Buffer<T> createBuffer(vkcv::BufferType type, size_t count, BufferMemoryType memoryType = BufferMemoryType::DEVICE_LOCAL) {
return Buffer<T>::create(m_Context.getDevice(), m_Context.getPhysicalDevice(), bufferType, size); return Buffer<T>::create(m_BufferManager.get(), type, count, memoryType);
} }
/** TODO:
* @param setDescriptions
* @return
*/
[[nodiscard]]
ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> &descriptorSets);
/** /**
* @brief start recording command buffers and increment frame index * @brief start recording command buffers and increment frame index
*/ */
...@@ -156,7 +187,7 @@ namespace vkcv ...@@ -156,7 +187,7 @@ namespace vkcv
* @brief render a beautiful triangle * @brief render a beautiful triangle
*/ */
void renderTriangle(const PassHandle renderpassHandle, const PipelineHandle pipelineHandle, void renderTriangle(const PassHandle renderpassHandle, const PipelineHandle pipelineHandle,
const int width, const int height); const int width, const int height, const size_t pushConstantSize, const void* pushConstantData);
/** /**
* @brief end recording and present image * @brief end recording and present image
...@@ -164,5 +195,16 @@ namespace vkcv ...@@ -164,5 +195,16 @@ namespace vkcv
void endFrame(); void endFrame();
vk::Format getSwapchainImageFormat(); 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
* will be called.
*
* @param submitInfo Submit information
* @param record Record-command-function
* @param finish Finish-command-function or nullptr
*/
void submitCommands(const SubmitInfo &submitInfo, const RecordCommandFunction& record, const FinishCommandFunction& finish);
}; };
} }
#pragma once
#include <vkcv/ShaderProgram.hpp>
namespace vkcv
{
/*
* All the types of descriptors (resources) that can be retrieved by the shaders
*/
enum class DescriptorType
{
UNIFORM_BUFFER,
STORAGE_BUFFER,
SAMPLER,
IMAGE
};
/*
* One binding for a descriptor set
* @param[in] a unique binding ID
* @param[in] a descriptor type
* @param[in] the number of descriptors of this type (arrays of the same type possible)
* @param[in] the shader stage where the descriptor is supposed to be retrieved
*/
struct DescriptorBinding
{
DescriptorBinding() = delete;
DescriptorBinding(
DescriptorType descriptorType,
uint32_t descriptorCount,
ShaderStage shaderStage
) noexcept;
DescriptorType descriptorType;
uint32_t descriptorCount;
ShaderStage shaderStage;
};
/*
* One descriptor set struct that contains all the necessary information for the actual creation.
* @param[in] a number of bindings that were created beforehand
* @param[in] the number of (identical) sets that should be created from the attached bindings
*/
struct DescriptorSet
{
DescriptorSet() = delete;
explicit DescriptorSet(std::vector<DescriptorBinding> bindings) noexcept;
std::vector<DescriptorBinding> bindings;
};
}
#pragma once
#include <functional>
namespace vkcv {
template<typename... T>
struct event_function {
typedef std::function<void(T...)> type;
};
/**
* template for event handling
* @tparam T parameter list
*/
template<typename... T>
struct event {
private:
std::vector<typename event_function<T...>::type> m_handles;
public:
/**
* calls all function handles with the given arguments
* @param arguments of the given function
*/
void operator()(T... arguments) {
for (auto &handle : this->m_handles) {
handle(arguments...);
}
}
/**
* adds a function handle to the event to be called
* @param handle of the function
*/
typename event_function<T...>::type add(typename event_function<T...>::type handle) {
this->m_handles.push_back(handle);
return 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()
);
}
event() = default;
event(const event &other) = delete;
event(event &&other) = delete;
~event() = default;
event &operator=(const event &other) = delete;
event &operator=(event &&other) = delete;
};
}
...@@ -5,12 +5,63 @@ ...@@ -5,12 +5,63 @@
* @brief Central header file for all possible handles that the framework will hand out. * @brief Central header file for all possible handles that the framework will hand out.
*/ */
#include <cstdint> #include <iostream>
namespace vkcv namespace vkcv
{ {
class Handle {
friend std::ostream& operator << (std::ostream& out, const Handle& handle);
private:
uint64_t m_id;
protected:
Handle();
explicit Handle(uint64_t id);
[[nodiscard]]
uint64_t getId() const;
public:
virtual ~Handle() = default;
Handle(const Handle& other) = default;
Handle(Handle&& other) = default;
Handle& operator=(const Handle& other) = default;
Handle& operator=(Handle&& other) = default;
explicit operator bool() const;
bool operator!() const;
};
std::ostream& operator << (std::ostream& out, const Handle& handle);
// Handle returned for any buffer created with the core/context objects // Handle returned for any buffer created with the core/context objects
struct BufferHandle {uint64_t id;}; class BufferHandle : public Handle {
struct PassHandle {uint64_t id;}; friend class BufferManager;
struct PipelineHandle {uint64_t id;}; private:
using Handle::Handle;
};
class PassHandle : public Handle {
friend class PassManager;
private:
using Handle::Handle;
};
class PipelineHandle : public Handle {
friend class PipelineManager;
private:
using Handle::Handle;
};
class ResourcesHandle : public Handle {
friend class DescriptorManager;
private:
using Handle::Handle;
};
} }
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
namespace vkcv { namespace vkcv {
enum class QueueType { Compute, Transfer, Graphics, Present };
struct Queue { struct Queue {
int familyIndex; int familyIndex;
int queueIndex; int queueIndex;
......
...@@ -3,11 +3,13 @@ ...@@ -3,11 +3,13 @@
namespace vkcv { namespace vkcv {
struct SyncResources { struct SyncResources {
vk::Semaphore renderFinished; vk::Semaphore renderFinished;
vk::Fence swapchainImageAcquired; vk::Semaphore swapchainImageAcquired;
vk::Fence presentFinished; vk::Fence presentFinished;
}; };
SyncResources createDefaultSyncResources(const vk::Device& device); SyncResources createSyncResources(const vk::Device &device);
void destroySyncResources(const vk::Device& device, const SyncResources& resources); void destroySyncResources(const vk::Device &device, const SyncResources &resources);
vk::Fence createFence(const vk::Device &device);
void waitForFence(const vk::Device& device, const vk::Fence fence);
} }
\ No newline at end of file
...@@ -7,11 +7,12 @@ ...@@ -7,11 +7,12 @@
#define NOMINMAX #define NOMINMAX
#include <algorithm> #include <algorithm>
#include "Event.hpp"
struct GLFWwindow; struct GLFWwindow;
namespace vkcv { namespace vkcv {
class Window final { class Window final {
private: private:
GLFWwindow *m_window; GLFWwindow *m_window;
...@@ -23,6 +24,42 @@ namespace vkcv { ...@@ -23,6 +24,42 @@ namespace vkcv {
*/ */
explicit Window(GLFWwindow *window); explicit Window(GLFWwindow *window);
/**
* mouse callback for moving the mouse on the screen
* @param[in] window The window that received the event.
* @param[in] xpos The new cursor x-coordinate, relative to the left edge of the content area.
* @param[in] ypos The new cursor y-coordinate, relative to the top edge of the content area.
*/
static void onMouseMoveEvent(GLFWwindow *window, double x, double y);
/**
* mouseButton callback for mouse buttons
* @param[in] button The [mouse button](@ref buttons) that was pressed or released.
* @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`. Future releases may add more actions.
* @param[in] mods Bit field describing which [modifier keys](@ref mods) were held down.
*/
static void onMouseButtonEvent(GLFWwindow *callbackWindow, int button, int action, int mods);
static void onMouseScrollEvent(GLFWwindow *callbackWindow, double xoffset, double yoffset);
/**
* resize callback for the resize option of the window
* @param[in] window The window that was resized.
* @param[in] width The new width, in screen coordinates, of the window.
* @param[in] height The new height, in screen coordinates, of the window.
*/
static void onResize(GLFWwindow *callbackWindow, int width, int height);
/**
* key callback for the pressed key
* @param[in] window The window that received the event.
* @param[in] key The [keyboard key](@ref keys) that was pressed or released.
* @param[in] scancode The system-specific scancode of the key.
* @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
* @param[in] mods Bit field describing which [modifier keys](@ref mods) were held down.
*/
static void onKeyEvent(GLFWwindow *callbackWindow, int key, int scancode, int action, int mods);
public: public:
/** /**
* creates a GLFWwindow with the parameters in the function * creates a GLFWwindow with the parameters in the function
...@@ -41,11 +78,25 @@ namespace vkcv { ...@@ -41,11 +78,25 @@ namespace vkcv {
[[nodiscard]] [[nodiscard]]
bool isWindowOpen() const; bool isWindowOpen() const;
/**
* binds windowEvents to lambda events
*/
void initEvents();
/** /**
* polls all events on the GLFWwindow * polls all events on the GLFWwindow
*/ */
static void pollEvents(); static void pollEvents();
/**
* basic events of the window
*/
event< int, int, int> e_mouseButton;
event< double, double > e_mouseMove;
event< double, double > e_mouseScroll;
event< int, int > e_resize;
event< int, int, int, int > e_key;
/** /**
* returns the current window * returns the current window
* @return window handle * @return window handle
...@@ -90,5 +141,5 @@ namespace vkcv { ...@@ -90,5 +141,5 @@ namespace vkcv {
*/ */
virtual ~Window(); virtual ~Window();
}; };
} }
\ No newline at end of file
# Add new modules here: # Add new modules here:
add_subdirectory(asset_loader)
add_subdirectory(camera)
add_subdirectory(testing) add_subdirectory(testing)
cmake_minimum_required(VERSION 3.16)
project(vkcv_asset_loader)
# setting c++ standard for the module
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(vkcv_asset_loader_source ${PROJECT_SOURCE_DIR}/src)
set(vkcv_asset_loader_include ${PROJECT_SOURCE_DIR}/include)
# Add source and header files to the module
set(vkcv_asset_loader_sources
${vkcv_asset_loader_include}/vkcv/asset/asset_loader.hpp
${vkcv_asset_loader_source}/vkcv/asset/asset_loader.cpp
)
# adding source files to the module
add_library(vkcv_asset_loader STATIC ${vkcv_asset_loader_sources})
# Setup some path variables to load libraries
set(vkcv_asset_loader_lib lib)
set(vkcv_asset_loader_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_asset_loader_lib})
# Check and load NLOHMANN_JSON
include(config/NLOHMANN_JSON.cmake)
# Check and load FX-GLTF
include(config/FX_GLTF.cmake)
# Check and load STB
include(config/STB.cmake)
# link the required libraries to the module
target_link_libraries(vkcv_asset_loader ${vkcv_asset_loader_libraries})
# including headers of dependencies and the VkCV framework
target_include_directories(vkcv_asset_loader SYSTEM BEFORE PRIVATE ${vkcv_asset_loader_includes})
# add the own include directory for public headers
target_include_directories(vkcv_asset_loader BEFORE PUBLIC ${vkcv_asset_loader_include})
if (EXISTS "${vkcv_asset_loader_lib_path}/fx-gltf")
set(FX_GLTF_INSTALL OFF CACHE INTERNAL "")
set(FX_GLTF_USE_INSTALLED_DEPS OFF CACHE INTERNAL "")
set(BUILD_TESTING OFF CACHE INTERNAL "")
add_subdirectory(${vkcv_asset_loader_lib}/fx-gltf)
list(APPEND vkcv_asset_loader_libraries fx-gltf)
else()
message(WARNING "FX-GLTF is required..! Update the submodules!")
endif ()