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 (312)
Showing
with 440 additions and 129 deletions
<<<<<<< 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: ")
......
......@@ -29,15 +29,18 @@ set(vkcv_sources
${vkcv_source}/vkcv/ImageManager.hpp
${vkcv_source}/vkcv/ImageManager.cpp
${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
${vkcv_include}/vkcv/ShaderProgram.hpp
${vkcv_source}/vkcv/ShaderProgram.cpp
${vkcv_include}/vkcv/PipelineConfig.hpp
${vkcv_source}/vkcv/PipelineConfig.cpp
${vkcv_source}/vkcv/PipelineManager.hpp
${vkcv_source}/vkcv/PipelineManager.cpp
......@@ -50,10 +53,7 @@ set(vkcv_sources
${vkcv_include}/vkcv/QueueManager.hpp
${vkcv_source}/vkcv/QueueManager.cpp
${vkcv_source}/vkcv/Surface.hpp
${vkcv_source}/vkcv/Surface.cpp
${vkcv_source}/vkcv/ImageLayoutTransitions.hpp
${vkcv_source}/vkcv/ImageLayoutTransitions.cpp
......@@ -72,4 +72,12 @@ set(vkcv_sources
${vkcv_source}/vkcv/SamplerManager.cpp
${vkcv_include}/vkcv/DescriptorWrites.hpp
${vkcv_include}/vkcv/DrawcallRecording.hpp
${vkcv_source}/vkcv/DrawcallRecording.cpp
${vkcv_include}/vkcv/CommandStreamManager.hpp
${vkcv_source}/vkcv/CommandStreamManager.cpp
${vkcv_include}/vkcv/CommandRecordingFunctionTypes.hpp
)
......@@ -6,9 +6,20 @@ if (spirv-cross_FOUND)
message(${vkcv_config_msg} " SPIRV Cross - " ${SPIRV_CROSS_VERSION})
else()
if (EXISTS "${vkcv_lib_path}/SPIRV-Cross")
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS OFF CACHE INTERNAL "")
set(SPIRV_CROSS_SHARED OFF CACHE INTERNAL "")
set(SPIRV_CROSS_STATIC ON CACHE INTERNAL "")
set(SPIRV_CROSS_CLI OFF CACHE INTERNAL "")
set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE INTERNAL "")
set(SPIRV_CROSS_ENABLE_GLSL ON CACHE INTERNAL "")
set(SPIRV_CROSS_ENABLE_HLSL OFF CACHE INTERNAL "")
set(SPIRV_CROSS_ENABLE_MSL OFF CACHE INTERNAL "")
set(SPIRV_CROSS_ENABLE_CPP ON CACHE INTERNAL "")
set(SPIRV_CROSS_ENABLE_REFLECT OFF CACHE INTERNAL "")
set(SPIRV_CROSS_ENABLE_C_API OFF CACHE INTERNAL "")
set(SPIRV_CROSS_ENABLE_UTIL OFF CACHE INTERNAL "")
set(SPIRV_CROSS_SKIP_INSTALL ON CACHE INTERNAL "")
add_subdirectory(${vkcv_lib}/SPIRV-Cross)
......
......@@ -37,6 +37,11 @@ namespace vkcv {
size_t getSize() const {
return m_count * sizeof(T);
}
[[nodiscard]]
const vk::Buffer getVulkanHandle() const {
return m_manager->getBuffer(m_handle);
}
void fill(const T* data, size_t count = 0, size_t offset = 0) {
m_manager->fillBuffer(m_handle, data, count * sizeof(T), offset * sizeof(T));
......
......@@ -132,6 +132,9 @@ namespace vkcv
*/
void unmapBuffer(const BufferHandle& handle);
void recordBufferMemoryBarrier(
const BufferHandle& handle,
vk::CommandBuffer cmdBuffer);
};
}
#pragma once
#include "vkcv/Event.hpp"
#include <vulkan/vulkan.hpp>
namespace vkcv {
typedef typename event_function<const vk::CommandBuffer&>::type RecordCommandFunction;
typedef typename event_function<>::type FinishCommandFunction;
}
\ No newline at end of file
#pragma once
#include <vulkan/vulkan.hpp>
#include <vector>
#include "vkcv/Event.hpp"
#include "vkcv/Handles.hpp"
#include "vkcv/CommandRecordingFunctionTypes.hpp"
namespace vkcv {
class Core;
class CommandStreamManager
{
friend class Core;
private:
struct CommandStream {
inline CommandStream(vk::CommandBuffer cmdBuffer, vk::Queue queue, vk::CommandPool cmdPool)
: cmdBuffer(cmdBuffer), cmdPool(cmdPool), queue(queue) {};
vk::CommandBuffer cmdBuffer;
vk::CommandPool cmdPool;
vk::Queue queue;
std::vector<FinishCommandFunction> callbacks;
};
Core* m_core;
std::vector<CommandStream> m_commandStreams;
CommandStreamManager() noexcept;
void init(Core* core);
public:
~CommandStreamManager() noexcept;
CommandStreamManager(CommandStreamManager&& other) = delete;
CommandStreamManager(const CommandStreamManager& other) = delete;
CommandStreamManager& operator=(CommandStreamManager&& other) = delete;
CommandStreamManager& operator=(const CommandStreamManager& other) = delete;
CommandStreamHandle createCommandStream(
const vk::Queue queue,
vk::CommandPool cmdPool);
void recordCommandsToStream(const CommandStreamHandle handle, const RecordCommandFunction record);
void addFinishCallbackToStream(const CommandStreamHandle handle, const FinishCommandFunction finish);
void submitCommandStreamSynchronous(
const CommandStreamHandle handle,
std::vector<vk::Semaphore> &waitSemaphores,
std::vector<vk::Semaphore> &signalSemaphores);
vk::CommandBuffer getStreamCommandBuffer(const CommandStreamHandle handle);
};
}
\ No newline at end of file
......@@ -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"
......@@ -22,13 +22,11 @@
#include "Sampler.hpp"
#include "DescriptorWrites.hpp"
#include "Event.hpp"
#include "DrawcallRecording.hpp"
#include "CommandRecordingFunctionTypes.hpp"
namespace vkcv
{
struct VertexBufferBinding {
vk::DeviceSize offset;
BufferHandle buffer;
};
// forward declarations
class PassManager;
......@@ -37,15 +35,13 @@ namespace vkcv
class BufferManager;
class SamplerManager;
class ImageManager;
class CommandStreamManager;
struct SubmitInfo {
QueueType queueType;
std::vector<vk::Semaphore> waitSemaphores;
std::vector<vk::Semaphore> signalSemaphores;
};
typedef typename event_function<const vk::CommandBuffer&>::type RecordCommandFunction;
typedef typename event_function<>::type FinishCommandFunction;
class Core final
{
......@@ -56,40 +52,33 @@ namespace vkcv
*
* @param context encapsulates various Vulkan objects
*/
Core(Context &&context, Window &window, 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;
Result acquireSwapchainImage();
void destroyTemporaryFramebuffers();
Context m_Context;
SwapChain m_swapchain;
std::vector<vk::ImageView> m_swapchainImageViews;
const Window& m_window;
std::unique_ptr<PassManager> m_PassManager;
std::unique_ptr<PipelineManager> m_PipelineManager;
std::unique_ptr<DescriptorManager> m_DescriptorManager;
std::unique_ptr<BufferManager> m_BufferManager;
std::unique_ptr<SamplerManager> m_SamplerManager;
std::unique_ptr<ImageManager> m_ImageManager;
CommandResources m_CommandResources;
SyncResources m_SyncResources;
uint32_t m_currentSwapchainImageIndex;
std::vector<vk::Framebuffer> m_TemporaryFramebuffers;
ImageHandle m_DepthImage;
Swapchain m_swapchain;
Window& m_window;
/**
* recreates the swapchain
* @param[in] width new window width
* @param[in] height new window hight
*/
static void recreateSwapchain(int width, int height);
std::unique_ptr<PassManager> m_PassManager;
std::unique_ptr<PipelineManager> m_PipelineManager;
std::unique_ptr<DescriptorManager> m_DescriptorManager;
std::unique_ptr<BufferManager> m_BufferManager;
std::unique_ptr<SamplerManager> m_SamplerManager;
std::unique_ptr<ImageManager> m_ImageManager;
std::unique_ptr<CommandStreamManager> m_CommandStreamManager;
CommandResources m_CommandResources;
SyncResources m_SyncResources;
uint32_t m_currentSwapchainImageIndex;
event_handle<int,int> e_resizeHandle;
static std::vector<vk::ImageView> createSwapchainImageViews( Context &context, Swapchain& swapChain);
public:
/**
......@@ -129,6 +118,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.
......@@ -163,6 +155,19 @@ namespace vkcv
[[nodiscard]]
PipelineHandle createGraphicsPipeline(const PipelineConfig &config);
/**
* 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.
*
* @param shader program that hold the compiles compute shader
* @param handle a handle to return the created vulkan handle
* @return True if pipeline creation was successful, False if not
*/
[[nodiscard]]
PipelineHandle createComputePipeline(
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.
* Fixed Functions for pipeline are set with standard values.
......@@ -209,46 +214,50 @@ 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);
/** TODO:
* @param setDescriptions
* @return
*/
[[nodiscard]]
ResourcesHandle createResourceDescription(const std::vector<DescriptorSetConfig> &descriptorSets);
void writeResourceDescription(ResourcesHandle handle, size_t setIndex, const DescriptorWrites& writes);
DescriptorSetHandle createDescriptorSet(const std::vector<DescriptorBinding> &bindings);
void writeDescriptorSet(DescriptorSetHandle handle, const DescriptorWrites& writes);
vk::DescriptorSetLayout getDescriptorSetLayout(ResourcesHandle handle, size_t setIndex);
DescriptorSet getDescriptorSet(const DescriptorSetHandle handle) const;
/**
* @brief start recording command buffers and increment frame index
*/
void beginFrame();
bool beginFrame(uint32_t& width, uint32_t& height);
/**
* @brief render a beautiful triangle
*/
void renderMesh(
const PassHandle renderpassHandle,
const PipelineHandle pipelineHandle,
const uint32_t width,
const uint32_t height,
const size_t pushConstantSize,
const void* pushConstantData,
const std::vector<VertexBufferBinding> &vertexBufferBindings,
const BufferHandle indexBuffer,
const size_t indexCount,
const vkcv::ResourcesHandle resourceHandle,
const size_t resourceDescriptorSetIndex);
void recordDrawcallsToCmdStream(
const CommandStreamHandle cmdStreamHandle,
const PassHandle renderpassHandle,
const PipelineHandle pipelineHandle,
const PushConstantData &pushConstantData,
const std::vector<DrawcallInfo> &drawcalls,
const std::vector<ImageHandle> &renderTargets);
void recordComputeDispatchToCmdStream(
CommandStreamHandle cmdStream,
PipelineHandle computePipeline,
const uint32_t dispatchCount[3],
const std::vector<DescriptorSetUsage> &descriptorSetUsages,
const PushConstantData& pushConstantData);
/**
* @brief end recording and present image
*/
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
......@@ -258,6 +267,26 @@ namespace vkcv
* @param record Record-command-function
* @param finish Finish-command-function or nullptr
*/
void submitCommands(const SubmitInfo &submitInfo, const RecordCommandFunction& record, const FinishCommandFunction& finish);
void recordAndSubmitCommandsImmediate(
const SubmitInfo &submitInfo,
const RecordCommandFunction &record,
const FinishCommandFunction &finish);
CommandStreamHandle createCommandStream(QueueType queueType);
void recordCommandsToStream(
const CommandStreamHandle cmdStreamHandle,
const RecordCommandFunction &record,
const FinishCommandFunction &finish);
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);
vk::ImageView getSwapchainImageView() const;
};
}
#pragma once
#include <vkcv/ShaderProgram.hpp>
#include <vulkan/vulkan.hpp>
#include "vkcv/Handles.hpp"
#include "vkcv/ShaderStage.hpp"
namespace vkcv
{
struct DescriptorSet
{
vk::DescriptorSet vulkanHandle;
vk::DescriptorSetLayout layout;
};
/*
* All the types of descriptors (resources) that can be retrieved by the shaders
*/
......@@ -24,27 +34,16 @@ namespace vkcv
*/
struct DescriptorBinding
{
DescriptorBinding() = delete;
DescriptorBinding(
uint32_t bindingID,
DescriptorType descriptorType,
uint32_t descriptorCount,
ShaderStage shaderStage
) noexcept;
uint32_t bindingID;
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 DescriptorSetConfig
{
explicit DescriptorSetConfig(std::vector<DescriptorBinding> bindings) noexcept;
std::vector<DescriptorBinding> bindings;
};
}
......@@ -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
#pragma once
#include <vulkan/vulkan.hpp>
#include <vkcv/Handles.hpp>
#include <vkcv/DescriptorConfig.hpp>
namespace vkcv {
struct VertexBufferBinding {
inline VertexBufferBinding(vk::DeviceSize offset, vk::Buffer buffer) noexcept
: offset(offset), buffer(buffer) {}
vk::DeviceSize offset;
vk::Buffer buffer;
};
struct DescriptorSetUsage {
inline DescriptorSetUsage(uint32_t setLocation, vk::DescriptorSet vulkanHandle) noexcept
: setLocation(setLocation), vulkanHandle(vulkanHandle) {}
const uint32_t setLocation;
const vk::DescriptorSet vulkanHandle;
};
struct Mesh {
inline Mesh(std::vector<VertexBufferBinding> vertexBufferBindings, vk::Buffer indexBuffer, size_t indexCount) noexcept
: vertexBufferBindings(vertexBufferBindings), indexBuffer(indexBuffer), indexCount(indexCount){}
std::vector<VertexBufferBinding> vertexBufferBindings;
vk::Buffer indexBuffer;
size_t indexCount;
};
struct PushConstantData {
inline PushConstantData(void* data, size_t sizePerDrawcall) : data(data), sizePerDrawcall(sizePerDrawcall) {}
void* data;
size_t sizePerDrawcall;
};
struct DrawcallInfo {
inline DrawcallInfo(const Mesh& mesh, const std::vector<DescriptorSetUsage>& descriptorSets)
: mesh(mesh), descriptorSets(descriptorSets) {}
Mesh mesh;
std::vector<DescriptorSetUsage> descriptorSets;
};
void recordDrawcall(
const DrawcallInfo &drawcall,
vk::CommandBuffer cmdBuffer,
vk::PipelineLayout pipelineLayout,
const PushConstantData &pushConstantData,
const size_t drawcallIndex);
}
\ No newline at end of file
#pragma once
#include <functional>
#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;
};
/**
......@@ -16,7 +25,9 @@ namespace vkcv {
template<typename... T>
struct event {
private:
std::vector<typename event_function<T...>::type> m_handles;
std::vector< event_function<T...> > m_functions;
uint32_t m_id_counter;
std::mutex m_mutex;
public:
......@@ -25,32 +36,60 @@ namespace vkcv {
* @param arguments of the given function
*/
void operator()(T... arguments) {
for (auto &handle : this->m_handles) {
handle(arguments...);
}
lock();
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()
);
}
/**
* locks the event so its function handles won't be called
*/
void lock() {
m_mutex.lock();
}
/**
* unlocks the event so its function handles can be called after locking
*/
void unlock() {
m_mutex.unlock();
}
event() = default;
explicit event(bool locked = false) {
if (locked) {
lock();
}
}
event(const event &other) = delete;
......
......@@ -79,7 +79,7 @@ namespace vkcv
using Handle::Handle;
};
class ResourcesHandle : public Handle {
class DescriptorSetHandle : public Handle {
friend class DescriptorManager;
private:
using Handle::Handle;
......@@ -93,14 +93,19 @@ namespace vkcv
class ImageHandle : public Handle {
friend class ImageManager;
private:
using Handle::Handle;
public:
[[nodiscard]]
bool isSwapchainImage() const;
static ImageHandle createSwapchainImageHandle(const HandleDestroyFunction& destroy = nullptr);
};
class CommandStreamHandle : public Handle {
friend class CommandStreamManager;
private:
using Handle::Handle;
};
}
......@@ -9,8 +9,12 @@
#include "Handles.hpp"
namespace vkcv {
class ImageManager;
// forward declares
class ImageManager;
bool isDepthFormat(const vk::Format format);
class Image {
friend class Core;
public:
......@@ -25,25 +29,35 @@ 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;
const vk::Format m_format;
vk::ImageLayout m_layout;
// 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, vk::Format format);
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);
};
......
#pragma once
#include <stdio.h>
namespace vkcv {
enum class LogLevel {
INFO,
WARNING,
ERROR
};
constexpr auto getLogOutput(LogLevel level) {
switch (level) {
case LogLevel::INFO:
return stdout;
default:
return stderr;
}
}
constexpr const char* getLogName(LogLevel level) {
switch (level) {
case LogLevel::INFO:
return "INFO";
case LogLevel::WARNING:
return "WARNING";
case LogLevel::ERROR:
return "ERROR";
default:
return "UNKNOWN";
}
}
#ifndef NDEBUG
#ifndef VKCV_DEBUG_MESSAGE_LEN
#define VKCV_DEBUG_MESSAGE_LEN 1024
#endif
#ifdef _MSC_VER
#define __PRETTY_FUNCTION__ __FUNCSIG__
#endif
#define vkcv_log(level, ...) { \
char output_message [ \
VKCV_DEBUG_MESSAGE_LEN \
]; \
snprintf( \
output_message, \
VKCV_DEBUG_MESSAGE_LEN, \
__VA_ARGS__ \
); \
fprintf( \
getLogOutput(level), \
"[%s]: %s [%s, line %d: %s]\n", \
vkcv::getLogName(level), \
output_message, \
__FILE__, \
__LINE__, \
__PRETTY_FUNCTION__ \
); \
}
#else
#define vkcv_log(level, ...) {}
#endif
}