diff --git a/.gitmodules b/.gitmodules index 1902397c4be138a3219453d01082c9b42c59e1bc..0f788015915ea014037a674cd19deccaea0279f2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,7 +8,7 @@ branch = main [submodule "modules/asset_loader/lib/fx-gltf"] path = modules/asset_loader/lib/fx-gltf - url = https://github.com/jessey-git/fx-gltf.git + url = https://github.com/TheJackiMonster/fx-gltf.git branch = master [submodule "modules/asset_loader/lib/json"] path = modules/asset_loader/lib/json @@ -48,8 +48,8 @@ branch = main [submodule "lib/VulkanMemoryAllocator-Hpp"] path = lib/VulkanMemoryAllocator-Hpp - url = https://github.com/TheJackiMonster/VulkanMemoryAllocator-Hpp.git - branch = fix + url = https://github.com/YaaZ/VulkanMemoryAllocator-Hpp.git + branch = master [submodule "modules/algorithm/lib/FidelityFX-SPD"] path = modules/algorithm/lib/FidelityFX-SPD url = https://github.com/GPUOpen-Effects/FidelityFX-SPD.git diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 5939988c3dc41f4ea4c640ed1bb30795fec8a36c..b97cf4eea750cbcc038e06c1a38df2d1aaa96e8e 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -73,10 +73,6 @@ namespace vkcv { Context m_Context; - std::unique_ptr<PassManager> m_PassManager; - std::unique_ptr<GraphicsPipelineManager> m_GraphicsPipelineManager; - std::unique_ptr<ComputePipelineManager> m_ComputePipelineManager; - std::unique_ptr<RayTracingPipelineManager> m_RayTracingPipelineManager; std::unique_ptr<DescriptorSetLayoutManager> m_DescriptorSetLayoutManager; std::unique_ptr<DescriptorSetManager> m_DescriptorSetManager; std::unique_ptr<BufferManager> m_BufferManager; @@ -86,11 +82,16 @@ namespace vkcv { std::unique_ptr<CommandStreamManager> m_CommandStreamManager; std::unique_ptr<WindowManager> m_WindowManager; std::unique_ptr<SwapchainManager> m_SwapchainManager; + std::unique_ptr<PassManager> m_PassManager; + std::unique_ptr<GraphicsPipelineManager> m_GraphicsPipelineManager; + std::unique_ptr<ComputePipelineManager> m_ComputePipelineManager; + std::unique_ptr<RayTracingPipelineManager> m_RayTracingPipelineManager; Vector<vk::CommandPool> m_CommandPools; vk::Semaphore m_RenderFinished; - vk::Semaphore m_SwapchainImageAcquired; + std::vector<vk::Semaphore> m_SwapchainImagesAcquired; uint32_t m_currentSwapchainImageIndex; + uint32_t m_currentSwapchainSemaphoreIndex; std::unique_ptr<Downsampler> m_downsampler; diff --git a/include/vkcv/Event.hpp b/include/vkcv/Event.hpp index 328b0e51ff4b3c78c3926083b71dbdcb6b98afa0..cb508d0c3fa7c739865348c4f7b25a2ab13ceeeb 100644 --- a/include/vkcv/Event.hpp +++ b/include/vkcv/Event.hpp @@ -5,6 +5,7 @@ * @brief Template event struct to synchronize callbacks. */ +#include <algorithm> #include <functional> #ifndef __MINGW32__ diff --git a/include/vkcv/Handles.hpp b/include/vkcv/Handles.hpp index c338cac3b0ff9052f832229d4ee04cf0c629ec96..f35eeaa32b903ae65756635ffa34fe16919537a6 100644 --- a/include/vkcv/Handles.hpp +++ b/include/vkcv/Handles.hpp @@ -28,6 +28,11 @@ namespace vkcv { HandleDestroyFunction m_destroy; + /** + * @brief Private internal method to destroy handle. + */ + void destroy(); + protected: /** * @brief Constructor of an invalid handle diff --git a/modules/gui/src/vkcv/gui/GUI.cpp b/modules/gui/src/vkcv/gui/GUI.cpp index 15a1b049aa5496bdcb9ecb81c00f82b66ad86d71..7978b10a4a515b022868fb357b6aa3f123a3d7e0 100644 --- a/modules/gui/src/vkcv/gui/GUI.cpp +++ b/modules/gui/src/vkcv/gui/GUI.cpp @@ -90,7 +90,7 @@ namespace vkcv::gui { init_info.MinImageCount = swapchainImageCount; init_info.ImageCount = swapchainImageCount; init_info.CheckVkResultFn = checkVulkanResult; - + const vk::AttachmentDescription attachment ( vk::AttachmentDescriptionFlags(), m_core.getSwapchainFormat(swapchainHandle), @@ -141,19 +141,13 @@ namespace vkcv::gui { &dependency ); - m_render_pass = m_context.getDevice().createRenderPass(passCreateInfo); - - ImGui_ImplVulkan_Init(&init_info, static_cast<VkRenderPass>(m_render_pass)); + init_info.RenderPass = m_context.getDevice().createRenderPass(passCreateInfo); - auto stream = m_core.createCommandStream(QueueType::Graphics); - - m_core.recordCommandsToStream(stream, [](const vk::CommandBuffer& commandBuffer) { - ImGui_ImplVulkan_CreateFontsTexture(static_cast<VkCommandBuffer>(commandBuffer)); - }, []() { - ImGui_ImplVulkan_DestroyFontUploadObjects(); - }); - - m_core.submitCommandStream(stream, false); + ImGui_ImplVulkan_Init(&init_info); + ImGui_ImplVulkan_CreateFontsTexture(); + + m_render_pass = init_info.RenderPass; + m_context.getDevice().waitIdle(); } @@ -161,6 +155,7 @@ namespace vkcv::gui { m_context.getDevice().waitIdle(); Window& window = m_core.getWindow(m_windowHandle); + ImGui_ImplVulkan_DestroyFontsTexture(); ImGui_ImplVulkan_Shutdown(); m_context.getDevice().destroyRenderPass(m_render_pass); @@ -188,6 +183,7 @@ namespace vkcv::gui { ImGui_ImplVulkan_NewFrame(); ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); } diff --git a/modules/shader_compiler/config/JSON-C.cmake b/modules/shader_compiler/config/JSON-C.cmake index 498b933cafb5d8bd84faed49cf51e6eef9c7503b..eb8b6ab74a2614b80db033fd399ca10324ed0615 100644 --- a/modules/shader_compiler/config/JSON-C.cmake +++ b/modules/shader_compiler/config/JSON-C.cmake @@ -3,6 +3,8 @@ use_git_submodule("${vkcv_shader_compiler_lib_path}/json-c" json_c_status) if (${json_c_status}) add_subdirectory(${vkcv_shader_compiler_lib}/json-c) + + set(JSON_C_INCLUDE_DIR ${vkcv_shader_compiler_lib_path}) list(APPEND vkcv_shader_compiler_libraries json-c) list(APPEND vkcv_shader_compiler_includes ${vkcv_shader_compiler_lib}) diff --git a/modules/shader_compiler/config/Shady.cmake b/modules/shader_compiler/config/Shady.cmake index b5d3bf6ca2a04209806b571da740efd9ca5e0cdc..56da131a23e3680e487c678260de6af2c9c3aba6 100644 --- a/modules/shader_compiler/config/Shady.cmake +++ b/modules/shader_compiler/config/Shady.cmake @@ -6,6 +6,11 @@ if (${shady_status}) set(EXTERNAL_SPIRV_HEADERS ON CACHE INTERNAL "") set(EXTERNAL_MURMUR3 ON CACHE INTERNAL "") + set(EXTERNAL_JSON_C_INCLUDE ${JSON_C_INCLUDE_DIR} CACHE INTERNAL "") + + set(BUILD_RUNTIME OFF CACHE INTERNAL "") + set(BUILD_SAMPLES OFF CACHE INTERNAL "") + add_subdirectory(${vkcv_shader_compiler_lib}/shady) if (vkcv_build_attribute EQUAL "SHARED") diff --git a/modules/shader_compiler/src/vkcv/shader/GlslangCompiler.cpp b/modules/shader_compiler/src/vkcv/shader/GlslangCompiler.cpp index 6a16e2eba9db00d45c0802f865525875edd33123..2a2847ada699364c025f957b204b58b3190a8ed2 100644 --- a/modules/shader_compiler/src/vkcv/shader/GlslangCompiler.cpp +++ b/modules/shader_compiler/src/vkcv/shader/GlslangCompiler.cpp @@ -4,7 +4,8 @@ #include <vkcv/File.hpp> #include <vkcv/Logger.hpp> -#include <glslang/Public/ShaderLang.h> +#include <glslang/SPIRV/GlslangToSpv.h> +#include <glslang/glslang/Public/ShaderLang.h> namespace vkcv::shader { diff --git a/modules/shader_compiler/src/vkcv/shader/LLVMCompiler.cpp b/modules/shader_compiler/src/vkcv/shader/LLVMCompiler.cpp index c53904d402efd7117b6fc73356284624445c4f5c..e415e19a70729e5288ce64f15a1e386cd7b963ca 100644 --- a/modules/shader_compiler/src/vkcv/shader/LLVMCompiler.cpp +++ b/modules/shader_compiler/src/vkcv/shader/LLVMCompiler.cpp @@ -47,7 +47,7 @@ namespace vkcv::shader { DriverConfig config = default_driver_config(); config.target = TgtSPV; - config.output_filename = tmp_path.c_str(); + config.output_filename = tmp_path.string().c_str(); codes = driver_compile(&config, module); destroy_driver_config(&config); diff --git a/modules/shader_compiler/src/vkcv/shader/SlimCompiler.cpp b/modules/shader_compiler/src/vkcv/shader/SlimCompiler.cpp index 475d867b883d82a5c811e7ea1081b8fc45dfa0c6..028d0618940d27cf00af920653e87d89f3ff7025 100644 --- a/modules/shader_compiler/src/vkcv/shader/SlimCompiler.cpp +++ b/modules/shader_compiler/src/vkcv/shader/SlimCompiler.cpp @@ -47,7 +47,7 @@ namespace vkcv::shader { DriverConfig config = default_driver_config(); config.target = TgtSPV; - config.output_filename = tmp_path.c_str(); + config.output_filename = tmp_path.string().c_str(); codes = driver_compile(&config, module); destroy_driver_config(&config); diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index f98b6209cca74011ec8170236f0eb1d20c0c83ef..e01949c8bf89573983f188cb715ac0a8d9bdb6db 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -53,17 +53,15 @@ int main(int argc, const char** argv) { // recreate copies of the bindings and the handles (to check whether they are properly reused instead of actually recreated) const vkcv::DescriptorBindings& set0Bindings = firstMeshProgram.getReflectedDescriptors().at(0); - vkcv::DescriptorSetLayoutHandle setLayoutHandle = core.createDescriptorSetLayout(set0Bindings); - vkcv::DescriptorSetLayoutHandle setLayoutHandleCopy = core.createDescriptorSetLayout(set0Bindings); - - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(setLayoutHandle); + vkcv::DescriptorSetLayoutHandle descriptorSetLayout = core.createDescriptorSetLayout(set0Bindings); + vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout); vkcv::GraphicsPipelineHandle firstMeshPipeline = core.createGraphicsPipeline( vkcv::GraphicsPipelineConfig( firstMeshProgram, firstMeshPass, { firstMeshLayout }, - { setLayoutHandle } + { descriptorSetLayout } ) ); diff --git a/projects/indirect_draw/src/main.cpp b/projects/indirect_draw/src/main.cpp index 424f2e0708a38d60426aff78a61d4ea0af7bad5f..c24dd260812b7837742089eeedb8d3b3de2a42af 100644 --- a/projects/indirect_draw/src/main.cpp +++ b/projects/indirect_draw/src/main.cpp @@ -279,7 +279,6 @@ int main(int argc, const char** argv) { }); features.requireExtension(VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME); - features.requireExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); features.requireExtensionFeature<vk::PhysicalDeviceDescriptorIndexingFeatures>( VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, [](vk::PhysicalDeviceDescriptorIndexingFeatures &features) { // features.setShaderInputAttachmentArrayDynamicIndexing(true); diff --git a/projects/mesh_shader/assets/shaders/shader.task b/projects/mesh_shader/assets/shaders/shader.task index 5a104fd9803826cb52087039f3f1f72de577299d..58698733439c3987fb46a13e56b4df6255f0516d 100644 --- a/projects/mesh_shader/assets/shaders/shader.task +++ b/projects/mesh_shader/assets/shaders/shader.task @@ -14,8 +14,7 @@ layout( push_constant ) uniform constants { uint matrixIndex; }; -// TODO: reuse mesh stage binding at location 2 after required fix in framework -layout(std430, set=0, binding = 5) readonly buffer meshletBuffer { +layout(std430, set=0, binding = 2) readonly buffer meshletBuffer { Meshlet meshlets[]; }; diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp index 72b15e3176a9a5e3614a9238fefe618a19070ba0..c248ac1c575613b273baf231d722253c731f9277 100644 --- a/projects/mesh_shader/src/main.cpp +++ b/projects/mesh_shader/src/main.cpp @@ -302,15 +302,13 @@ int main(int argc, const char** argv) { 2, meshletBuffer.getHandle() ).writeStorageBuffer( 4, matrixBuffer.getHandle() - ).writeStorageBuffer( - 5, meshletBuffer.getHandle() ); meshShaderWrites.writeUniformBuffer(3, cameraPlaneBuffer.getHandle()); - core.writeDescriptorSet( meshShaderDescriptorSet, meshShaderWrites); + core.writeDescriptorSet( meshShaderDescriptorSet, meshShaderWrites); - vkcv::ImageHandle depthBuffer; + vkcv::ImageHandle depthBuffer; vkcv::ImageHandle swapchainImageHandle = vkcv::ImageHandle::createSwapchainImageHandle(); vkcv::VertexData vertexData (vertexBufferBindings); diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp index 09cb702809f9f7c48105d8b95b4f398f2bbeb014..3411cdf6cb107d9e3cf371e6a581a368e4e48f27 100644 --- a/projects/particle_simulation/src/main.cpp +++ b/projects/particle_simulation/src/main.cpp @@ -16,12 +16,15 @@ int main(int argc, const char **argv) { uint32_t windowWidth = 800; uint32_t windowHeight = 600; + + vkcv::Features features; + features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); vkcv::Core core = vkcv::Core::create( applicationName, VK_MAKE_VERSION(0, 0, 1), {vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute}, - { VK_KHR_SWAPCHAIN_EXTENSION_NAME } + features ); vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); vkcv::Window& window = core.getWindow(windowHandle); diff --git a/projects/path_tracer/src/main.cpp b/projects/path_tracer/src/main.cpp index 1a87015e58aee80feebb4bc5fafac0a482da5743..21d83a689a442c90bf434597890e7e910767ca70 100644 --- a/projects/path_tracer/src/main.cpp +++ b/projects/path_tracer/src/main.cpp @@ -47,11 +47,14 @@ int main(int argc, const char** argv) { const std::string applicationName = "Path Tracer"; + vkcv::Features features; + features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + vkcv::Core core = vkcv::Core::create( applicationName, VK_MAKE_VERSION(0, 0, 1), { vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, - { "VK_KHR_swapchain" } + features ); const int initialWidth = 1280; diff --git a/projects/ray_tracer/src/main.cpp b/projects/ray_tracer/src/main.cpp index 1a906d5d8141148acbbf767163fb173f8053d466..a920c3a55907f0587290b91cae64263a0f87c3b0 100644 --- a/projects/ray_tracer/src/main.cpp +++ b/projects/ray_tracer/src/main.cpp @@ -35,11 +35,14 @@ int main(int argc, const char** argv) { const int windowWidth = 800; const int windowHeight = 600; + vkcv::Features features; + features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + vkcv::Core core = vkcv::Core::create( applicationName, VK_MAKE_VERSION(0, 0, 1), { vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, - { "VK_KHR_swapchain" } + features ); vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); diff --git a/projects/sph/src/main.cpp b/projects/sph/src/main.cpp index 3d8cf07842e542036125c26a2f95f298ec043343..ac02278046260215f3ad2b1077c750f5d6961dd0 100644 --- a/projects/sph/src/main.cpp +++ b/projects/sph/src/main.cpp @@ -16,12 +16,15 @@ int main(int argc, const char **argv) { const std::string applicationName = "SPH"; + vkcv::Features features; + features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + // creating core object that will handle all vulkan objects vkcv::Core core = vkcv::Core::create( applicationName, VK_MAKE_VERSION(0, 0, 1), { vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, - { VK_KHR_SWAPCHAIN_EXTENSION_NAME } + features ); vkcv::WindowHandle windowHandle = core.createWindow(applicationName, 1280, 720, true); diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index 9a6492b80febb61e38ee3a90f29921d5ca7ed9ba..835bbf27f64e286ba1c097ecf137703fb73cb8b2 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -37,6 +37,7 @@ int main(int argc, const char** argv) { VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, [](vk::PhysicalDeviceDescriptorIndexingFeatures& features) { features.setDescriptorBindingPartiallyBound(true); + features.setDescriptorBindingVariableDescriptorCount(true); } ); diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 9f1274b2532fbea3da59466bf42360d83c9a0ec0..3cefdab895e1f5fb4fc34c2c1f4332f62e86464b 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -6,6 +6,9 @@ #include <GLFW/glfw3.h> #include <cmath> +#include <cstdint> +#include <limits> +#include <vkcv/Logger.hpp> #include "AccelerationStructureManager.hpp" #include "BufferManager.hpp" @@ -91,10 +94,7 @@ namespace vkcv { } Core::Core(Context &&context) noexcept : - m_Context(std::move(context)), m_PassManager(std::make_unique<PassManager>()), - m_GraphicsPipelineManager(std::make_unique<GraphicsPipelineManager>()), - m_ComputePipelineManager(std::make_unique<ComputePipelineManager>()), - m_RayTracingPipelineManager(std::make_unique<RayTracingPipelineManager>()), + m_Context(std::move(context)), m_DescriptorSetLayoutManager(std::make_unique<DescriptorSetLayoutManager>()), m_DescriptorSetManager(std::make_unique<DescriptorSetManager>()), m_BufferManager(std::make_unique<BufferManager>()), @@ -103,18 +103,22 @@ namespace vkcv { m_AccelerationStructureManager(std::make_unique<AccelerationStructureManager>()), m_CommandStreamManager { std::make_unique<CommandStreamManager>() }, m_WindowManager(std::make_unique<WindowManager>()), - m_SwapchainManager(std::make_unique<SwapchainManager>()), m_CommandPools(), - m_RenderFinished(), m_SwapchainImageAcquired(), m_downsampler(nullptr) { + m_SwapchainManager(std::make_unique<SwapchainManager>()), + m_PassManager(std::make_unique<PassManager>()), + m_GraphicsPipelineManager(std::make_unique<GraphicsPipelineManager>()), + m_ComputePipelineManager(std::make_unique<ComputePipelineManager>()), + m_RayTracingPipelineManager(std::make_unique<RayTracingPipelineManager>()), + m_CommandPools(), + m_RenderFinished(), + m_SwapchainImagesAcquired(), + m_currentSwapchainImageIndex(std::numeric_limits<uint32_t>::max()), + m_currentSwapchainSemaphoreIndex(0), + m_downsampler(nullptr) { m_CommandPools = createCommandPools( m_Context.getDevice(), generateQueueFamilyIndexSet(m_Context.getQueueManager())); m_RenderFinished = m_Context.getDevice().createSemaphore({}); - m_SwapchainImageAcquired = m_Context.getDevice().createSemaphore({}); - m_PassManager->init(*this); - m_GraphicsPipelineManager->init(*this); - m_ComputePipelineManager->init(*this); - m_RayTracingPipelineManager->init(*this); m_DescriptorSetLayoutManager->init(*this); m_DescriptorSetManager->init(*this, *m_DescriptorSetLayoutManager); m_BufferManager->init(*this); @@ -123,6 +127,10 @@ namespace vkcv { m_AccelerationStructureManager->init(*this, *m_BufferManager); m_CommandStreamManager->init(*this); m_SwapchainManager->init(*this); + m_PassManager->init(*this); + m_GraphicsPipelineManager->init(*this); + m_ComputePipelineManager->init(*this); + m_RayTracingPipelineManager->init(*this); m_downsampler = std::unique_ptr<Downsampler>(new BlitDownsampler(*this, *m_ImageManager)); } @@ -134,7 +142,10 @@ namespace vkcv { } m_Context.getDevice().destroySemaphore(m_RenderFinished); - m_Context.getDevice().destroySemaphore(m_SwapchainImageAcquired); + + for (auto& semaphore : m_SwapchainImagesAcquired) { + m_Context.getDevice().destroySemaphore(semaphore); + } } GraphicsPipelineHandle Core::createGraphicsPipeline(const GraphicsPipelineConfig &config) { @@ -219,14 +230,25 @@ namespace vkcv { } Result Core::acquireSwapchainImage(const SwapchainHandle &swapchainHandle) { - uint32_t imageIndex; + uint32_t imageIndex, semaphoreIndex; vk::Result result; + if (m_SwapchainImagesAcquired.size() <= 0) { + vkcv_log(LogLevel::ERROR, "Semaphores not available"); + return Result::ERROR; + } + + semaphoreIndex = m_currentSwapchainSemaphoreIndex % m_SwapchainImagesAcquired.size(); + try { result = m_Context.getDevice().acquireNextImageKHR( m_SwapchainManager->getSwapchain(swapchainHandle).m_Swapchain, - std::numeric_limits<uint64_t>::max(), m_SwapchainImageAcquired, nullptr, - &imageIndex, {}); + std::numeric_limits<uint64_t>::max(), + m_SwapchainImagesAcquired[semaphoreIndex], + nullptr, + &imageIndex, + {} + ); } catch (const vk::OutOfDateKHRError &e) { result = vk::Result::eErrorOutOfDateKHR; } catch (const vk::DeviceLostError &e) { @@ -261,6 +283,17 @@ namespace vkcv { setSwapchainImages(swapchainHandle); } + const uint32_t count = m_SwapchainManager->getImageCount(swapchainHandle); + const uint32_t initialized = m_SwapchainImagesAcquired.size(); + + if (count > initialized) { + m_SwapchainImagesAcquired.resize(count); + + for (uint32_t i = initialized; i < count; i++) { + m_SwapchainImagesAcquired[i] = m_Context.getDevice().createSemaphore({}); + } + } + const auto &extent = m_SwapchainManager->getExtent(swapchainHandle); width = extent.width; @@ -276,9 +309,6 @@ namespace vkcv { m_currentSwapchainImageIndex = std::numeric_limits<uint32_t>::max(); } - m_Context.getDevice().waitIdle(); // TODO: this is a sin against graphics programming, but - // its getting late - Alex - m_ImageManager->setCurrentSwapchainImageIndex(m_currentSwapchainImageIndex); return (m_currentSwapchainImageIndex != std::numeric_limits<uint32_t>::max()); @@ -286,8 +316,8 @@ namespace vkcv { static std::array<uint32_t, 2> getWidthHeightFromRenderTargets(const Vector<ImageHandle> &renderTargets, - const vk::Extent2D &swapchainExtent, - const ImageManager &imageManager) { + const vk::Extent2D &swapchainExtent, + const ImageManager &imageManager) { std::array<uint32_t, 2> widthHeight; @@ -831,17 +861,26 @@ namespace vkcv { void Core::endFrame(const WindowHandle &windowHandle) { SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchain(); - if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) { + if ((m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) || + (m_SwapchainImagesAcquired.size() <= 0)) { return; } - const std::array<vk::Semaphore, 2> waitSemaphores { m_RenderFinished, - m_SwapchainImageAcquired }; + const uint32_t semaphoreIndex = m_currentSwapchainSemaphoreIndex % m_SwapchainImagesAcquired.size(); + m_currentSwapchainSemaphoreIndex = (m_currentSwapchainSemaphoreIndex + 1) % m_SwapchainImagesAcquired.size(); + + const std::array<vk::Semaphore, 2> waitSemaphores { + m_RenderFinished, + m_SwapchainImagesAcquired[semaphoreIndex] + }; const vk::SwapchainKHR &swapchain = m_SwapchainManager->getSwapchain(swapchainHandle).m_Swapchain; - const vk::PresentInfoKHR presentInfo(waitSemaphores, swapchain, - m_currentSwapchainImageIndex); + const vk::PresentInfoKHR presentInfo( + waitSemaphores, + swapchain, + m_currentSwapchainImageIndex + ); vk::Result result; diff --git a/src/vkcv/DescriptorSetLayoutManager.cpp b/src/vkcv/DescriptorSetLayoutManager.cpp index 6bbdb099ffbfe63bfaa6cead742d815202720b88..b0ed1064359e989236dfe4473be4e8b70c43adbb 100644 --- a/src/vkcv/DescriptorSetLayoutManager.cpp +++ b/src/vkcv/DescriptorSetLayoutManager.cpp @@ -34,8 +34,8 @@ namespace vkcv { DescriptorSetLayoutManager::~DescriptorSetLayoutManager() noexcept { for (uint64_t id = 0; id < getCount(); id++) { - // Resets the usage count to zero for destruction. - getById(id).layoutUsageCount = 0; + // Resets the usage count to one for destruction. + getById(id).layoutUsageCount = 1; } clear(); diff --git a/src/vkcv/DescriptorSetManager.cpp b/src/vkcv/DescriptorSetManager.cpp index 4a3d4f5bbc1a785d4977ede468172ef7c5a54af1..d4ffce7480853bbd907ef3dc61ed317ae04e9220 100644 --- a/src/vkcv/DescriptorSetManager.cpp +++ b/src/vkcv/DescriptorSetManager.cpp @@ -1,6 +1,7 @@ #include "DescriptorSetManager.hpp" #include "vkcv/Core.hpp" +#include <vulkan/vulkan_core.h> namespace vkcv { @@ -16,27 +17,48 @@ namespace vkcv { m_DescriptorSetLayoutManager = &descriptorSetLayoutManager; + const auto& featureManager = core.getContext().getFeatureManager(); + /** * Allocate the set size for the descriptor pools, namely 1000 units of each descriptor type * below. Finally, create an initial pool. */ m_PoolSizes.clear(); m_PoolSizes.emplace_back(vk::DescriptorType::eSampler, 1000); + m_PoolSizes.emplace_back(vk::DescriptorType::eCombinedImageSampler, 1000); m_PoolSizes.emplace_back(vk::DescriptorType::eSampledImage, 1000); + m_PoolSizes.emplace_back(vk::DescriptorType::eStorageImage, 1000); + m_PoolSizes.emplace_back(vk::DescriptorType::eUniformTexelBuffer, 1000); + m_PoolSizes.emplace_back(vk::DescriptorType::eStorageTexelBuffer, 1000); m_PoolSizes.emplace_back(vk::DescriptorType::eUniformBuffer, 1000); m_PoolSizes.emplace_back(vk::DescriptorType::eStorageBuffer, 1000); m_PoolSizes.emplace_back(vk::DescriptorType::eUniformBufferDynamic, 1000); m_PoolSizes.emplace_back(vk::DescriptorType::eStorageBufferDynamic, 1000); + m_PoolSizes.emplace_back(vk::DescriptorType::eInputAttachment, 1000); + + if (featureManager.isExtensionActive(VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME)) { + m_PoolSizes.emplace_back(vk::DescriptorType::eInlineUniformBlock, 1000); + } - if (core.getContext().getFeatureManager().isExtensionActive(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME)) { + if (featureManager.isExtensionActive(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME)) { m_PoolSizes.emplace_back(vk::DescriptorType::eAccelerationStructureKHR, 1000); } m_PoolInfo = vk::DescriptorPoolCreateInfo( - vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1000, - static_cast<uint32_t>(m_PoolSizes.size()), m_PoolSizes.data() + vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, + 1000, + static_cast<uint32_t>(m_PoolSizes.size()), + m_PoolSizes.data() ); + if (featureManager.isExtensionActive(VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME)) { + m_InlineUniformBlockInfo = vk::DescriptorPoolInlineUniformBlockCreateInfo( + 1000 + ); + + m_PoolInfo.setPNext(&m_InlineUniformBlockInfo); + } + return allocateDescriptorPool(); } @@ -50,19 +72,27 @@ namespace vkcv { } void DescriptorSetManager::destroyById(uint64_t id) { + const auto& device = getCore().getContext().getDevice(); auto &set = getById(id); if (set.vulkanHandle) { - getCore().getContext().getDevice().freeDescriptorSets(m_Pools [set.poolIndex], 1, - &(set.vulkanHandle)); - set.setLayoutHandle = DescriptorSetLayoutHandle(); + device.freeDescriptorSets( + m_Pools[set.poolIndex], + 1, + &(set.vulkanHandle) + ); + set.vulkanHandle = nullptr; } + + set.setLayoutHandle = DescriptorSetLayoutHandle(); } bool DescriptorSetManager::allocateDescriptorPool() { + const auto& device = getCore().getContext().getDevice(); + vk::DescriptorPool pool; - if (getCore().getContext().getDevice().createDescriptorPool(&m_PoolInfo, nullptr, &pool) + if (device.createDescriptorPool(&m_PoolInfo, nullptr, &pool) != vk::Result::eSuccess) { vkcv_log(LogLevel::WARNING, "Failed to allocate descriptor pool"); return false; @@ -76,11 +106,13 @@ namespace vkcv { HandleManager<DescriptorSetEntry, DescriptorSetHandle>() {} DescriptorSetManager::~DescriptorSetManager() noexcept { + const auto& device = getCore().getContext().getDevice(); + clear(); for (const auto &pool : m_Pools) { if (pool) { - getCore().getContext().getDevice().destroy(pool); + device.destroy(pool); } } } @@ -89,9 +121,15 @@ namespace vkcv { DescriptorSetManager::createDescriptorSet(const DescriptorSetLayoutHandle &layout) { // create and allocate the set based on the layout provided const auto &setLayout = m_DescriptorSetLayoutManager->getDescriptorSetLayout(layout); + const auto &device = getCore().getContext().getDevice(); + vk::DescriptorSet vulkanHandle; - vk::DescriptorSetAllocateInfo allocInfo(m_Pools.back(), 1, &setLayout.vulkanHandle); + vk::DescriptorSetAllocateInfo allocInfo( + m_Pools.back(), + 1, + &setLayout.vulkanHandle + ); uint32_t sumVariableDescriptorCounts = 0; for (auto bindingElem : setLayout.descriptorBindings) { @@ -108,15 +146,21 @@ namespace vkcv { allocInfo.setPNext(&variableAllocInfo); } - auto result = - getCore().getContext().getDevice().allocateDescriptorSets(&allocInfo, &vulkanHandle); + auto result = device.allocateDescriptorSets( + &allocInfo, + &vulkanHandle + ); + if (result != vk::Result::eSuccess) { // create a new descriptor pool if the previous one ran out of memory - if (result == vk::Result::eErrorOutOfPoolMemory) { - allocateDescriptorPool(); + if ((result == vk::Result::eErrorOutOfPoolMemory) && + (allocateDescriptorPool())) { allocInfo.setDescriptorPool(m_Pools.back()); - result = getCore().getContext().getDevice().allocateDescriptorSets(&allocInfo, - &vulkanHandle); + + result = device.allocateDescriptorSets( + &allocInfo, + &vulkanHandle + ); } if (result != vk::Result::eSuccess) { diff --git a/src/vkcv/DescriptorSetManager.hpp b/src/vkcv/DescriptorSetManager.hpp index 74cf75d9efd145132732fde03ca50d2f46baaded..6236cf9c37bee4a5a1973ae8baee5aa5ff642586 100644 --- a/src/vkcv/DescriptorSetManager.hpp +++ b/src/vkcv/DescriptorSetManager.hpp @@ -38,6 +38,7 @@ namespace vkcv { Vector<vk::DescriptorPool> m_Pools; Vector<vk::DescriptorPoolSize> m_PoolSizes; vk::DescriptorPoolCreateInfo m_PoolInfo; + vk::DescriptorPoolInlineUniformBlockCreateInfo m_InlineUniformBlockInfo; bool init(Core &core) override; bool init(Core &core, DescriptorSetLayoutManager &descriptorSetLayoutManager); diff --git a/src/vkcv/Handles.cpp b/src/vkcv/Handles.cpp index 64ab3080f5e6a649fa4fb0d8f772872713cb0140..578e467623830b8a1e6a612533011a8aa9bfc977 100644 --- a/src/vkcv/Handles.cpp +++ b/src/vkcv/Handles.cpp @@ -5,12 +5,7 @@ namespace vkcv { - Handle::Handle() : m_id(std::numeric_limits<uint64_t>::max()), m_rc(nullptr), m_destroy(nullptr) {} - - Handle::Handle(uint64_t id, const HandleDestroyFunction &destroy) : - m_id(id), m_rc(new uint64_t(1)), m_destroy(destroy) {} - - Handle::~Handle() { + void Handle::destroy() { if ((m_rc) && (*m_rc > 0) && (--(*m_rc) == 0)) { if (m_destroy) { m_destroy(m_id); @@ -20,6 +15,15 @@ namespace vkcv { } } + Handle::Handle() : m_id(std::numeric_limits<uint64_t>::max()), m_rc(nullptr), m_destroy(nullptr) {} + + Handle::Handle(uint64_t id, const HandleDestroyFunction &destroy) : + m_id(id), m_rc(new uint64_t(1)), m_destroy(destroy) {} + + Handle::~Handle() { + destroy(); + } + Handle::Handle(const Handle &other) : m_id(other.m_id), m_rc(other.m_rc), m_destroy(other.m_destroy) { if (m_rc) { @@ -38,6 +42,8 @@ namespace vkcv { return *this; } + destroy(); + m_id = other.m_id; m_rc = other.m_rc; m_destroy = other.m_destroy; @@ -50,6 +56,8 @@ namespace vkcv { } Handle &Handle::operator=(Handle &&other) noexcept { + destroy(); + m_id = other.m_id; m_rc = other.m_rc; m_destroy = other.m_destroy; diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp index 619f16585ebbd0c5d4680e83e7b6ab5bf058d01b..79e18ade1978fa3c5f680822b413d1d930920c26 100644 --- a/src/vkcv/ImageManager.cpp +++ b/src/vkcv/ImageManager.cpp @@ -516,7 +516,7 @@ namespace vkcv { } void ImageManager::switchImageLayoutImmediate(const ImageHandle &handle, - vk::ImageLayout newLayout) { + vk::ImageLayout newLayout) { auto &image = (*this) [handle]; const auto transitionBarriers = createImageLayoutTransitionBarriers(image, 0, 0, newLayout, false); @@ -540,7 +540,7 @@ namespace vkcv { ); if (vk::Result::eSuccess != result) { - // TODO: warning? + vkcv_log(LogLevel::WARNING, "Transition to new layout failed"); break; } } diff --git a/src/vkcv/ShaderProgram.cpp b/src/vkcv/ShaderProgram.cpp index 2deeeb813ad51e60b98a0c74f78b0cb0afa73039..bc478788855705d985c163f101008d321498fae6 100644 --- a/src/vkcv/ShaderProgram.cpp +++ b/src/vkcv/ShaderProgram.cpp @@ -8,6 +8,9 @@ #include "vkcv/File.hpp" #include "vkcv/Logger.hpp" +#include <cstddef> +#include <cstdint> +#include <limits> namespace vkcv { @@ -79,164 +82,71 @@ namespace vkcv { return true; } - void ShaderProgram::reflectShader(ShaderStage shaderStage) { - auto shaderCode = m_Shaders.at(shaderStage); - - spirv_cross::Compiler comp(shaderCode); - spirv_cross::ShaderResources resources = comp.get_shader_resources(); - - // reflect vertex input - if (shaderStage == ShaderStage::VERTEX) { - // spirv-cross API (hopefully) returns the stage_inputs in order - for (uint32_t i = 0; i < resources.stage_inputs.size(); i++) { - // spirv-cross specific objects - auto &stage_input = resources.stage_inputs [i]; - const spirv_cross::SPIRType &base_type = comp.get_type(stage_input.base_type_id); - - // vertex input location - const uint32_t attachment_loc = - comp.get_decoration(stage_input.id, spv::DecorationLocation); - // vertex input name - const std::string attachment_name = stage_input.name; - // vertex input format (implies its size) - const VertexAttachmentFormat attachment_format = - convertFormat(base_type.basetype, base_type.vecsize); - - m_VertexAttachments.push_back( - { attachment_loc, attachment_name, attachment_format, 0 }); - } + static void reflectShaderDescriptorSets(Dictionary<uint32_t, DescriptorBindings> &descriptorSets, + ShaderStage shaderStage, + DescriptorType descriptorType, + const spirv_cross::Compiler &comp, + const spirv_cross::ShaderResources &resources) { + const spirv_cross::SmallVector<spirv_cross::Resource> *res = nullptr; + + switch (descriptorType) { + case DescriptorType::UNIFORM_BUFFER: + res = &(resources.uniform_buffers); + break; + case DescriptorType::STORAGE_BUFFER: + res = &(resources.storage_buffers); + break; + case DescriptorType::SAMPLER: + res = &(resources.separate_samplers); + break; + case DescriptorType::IMAGE_SAMPLED: + res = &(resources.separate_images); + break; + case DescriptorType::IMAGE_STORAGE: + res = &(resources.storage_images); + break; + case DescriptorType::UNIFORM_BUFFER_DYNAMIC: + res = &(resources.uniform_buffers); + break; + case DescriptorType::STORAGE_BUFFER_DYNAMIC: + res = &(resources.storage_buffers); + break; + case DescriptorType::ACCELERATION_STRUCTURE_KHR: + res = &(resources.acceleration_structures); + break; + default: + break; } - // reflect descriptor sets (uniform buffer, storage buffer, sampler, sampled image, storage - // image) - Vector<std::pair<uint32_t, DescriptorBinding>> bindings; - - for (uint32_t i = 0; i < resources.uniform_buffers.size(); i++) { - auto &u = resources.uniform_buffers [i]; - const spirv_cross::SPIRType &base_type = comp.get_type(u.base_type_id); - const spirv_cross::SPIRType &type = comp.get_type(u.type_id); - - uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); - uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); - - uint32_t descriptorCount = base_type.vecsize; - bool variableCount = false; - // query whether reflected resources are qualified as one-dimensional array - if (type.array_size_literal [0]) { - descriptorCount = type.array [0]; - if (type.array [0] == 0) - variableCount = true; - } - - DescriptorBinding binding { - bindingID, DescriptorType::UNIFORM_BUFFER, descriptorCount, shaderStage, - variableCount, - variableCount // partialBinding == variableCount - }; - - auto insertionResult = - m_DescriptorSets [setID].insert(std::make_pair(bindingID, binding)); - if (!insertionResult.second) { - insertionResult.first->second.shaderStages |= shaderStage; - - vkcv_log(LogLevel::WARNING, - "Attempting to overwrite already existing binding %u at set ID %u.", - bindingID, setID); - } + if (nullptr == res) { + return; } - for (uint32_t i = 0; i < resources.storage_buffers.size(); i++) { - auto &u = resources.storage_buffers [i]; + for (uint32_t i = 0; i < res->size(); i++) { + const spirv_cross::Resource &u = (*res)[i]; const spirv_cross::SPIRType &base_type = comp.get_type(u.base_type_id); - const spirv_cross::SPIRType &type = comp.get_type(u.type_id); uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); uint32_t descriptorCount = base_type.vecsize; - bool variableCount = false; - // query whether reflected resources are qualified as one-dimensional array - if (type.array_size_literal [0]) { - descriptorCount = type.array [0]; - if (type.array [0] == 0) - variableCount = true; - } - - DescriptorBinding binding { - bindingID, DescriptorType::STORAGE_BUFFER, descriptorCount, shaderStage, - variableCount, - variableCount // partialBinding == variableCount - }; - - auto insertionResult = - m_DescriptorSets [setID].insert(std::make_pair(bindingID, binding)); - if (!insertionResult.second) { - insertionResult.first->second.shaderStages |= shaderStage; - - vkcv_log(LogLevel::WARNING, - "Attempting to overwrite already existing binding %u at set ID %u.", - bindingID, setID); - } - } - - for (uint32_t i = 0; i < resources.separate_samplers.size(); i++) { - auto &u = resources.separate_samplers [i]; - const spirv_cross::SPIRType &base_type = comp.get_type(u.base_type_id); - const spirv_cross::SPIRType &type = comp.get_type(u.type_id); - uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); - uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); - - uint32_t descriptorCount = base_type.vecsize; bool variableCount = false; // query whether reflected resources are qualified as one-dimensional array - if (type.array_size_literal [0]) { - descriptorCount = type.array [0]; - if (type.array [0] == 0) - variableCount = true; + if (descriptorCount == 0) { + variableCount = true; } DescriptorBinding binding { - bindingID, DescriptorType::SAMPLER, descriptorCount, shaderStage, variableCount, - variableCount // partialBinding == variableCount - }; - - auto insertionResult = - m_DescriptorSets [setID].insert(std::make_pair(bindingID, binding)); - if (!insertionResult.second) { - insertionResult.first->second.shaderStages |= shaderStage; - - vkcv_log(LogLevel::WARNING, - "Attempting to overwrite already existing binding %u at set ID %u.", - bindingID, setID); - } - } - - for (uint32_t i = 0; i < resources.separate_images.size(); i++) { - auto &u = resources.separate_images [i]; - const spirv_cross::SPIRType &base_type = comp.get_type(u.base_type_id); - const spirv_cross::SPIRType &type = comp.get_type(u.type_id); - - uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); - uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); - - uint32_t descriptorCount = base_type.vecsize; - bool variableCount = false; - // query whether reflected resources are qualified as one-dimensional array - if (type.array_size_literal [0]) { - descriptorCount = type.array [0]; - if (type.array [0] == 0) - variableCount = true; - } - - DescriptorBinding binding { - bindingID, DescriptorType::IMAGE_SAMPLED, descriptorCount, shaderStage, + bindingID, + descriptorType, + descriptorCount, + shaderStage, variableCount, variableCount // partialBinding == variableCount }; - auto insertionResult = - m_DescriptorSets [setID].insert(std::make_pair(bindingID, binding)); + auto insertionResult = descriptorSets[setID].insert(std::make_pair(bindingID, binding)); if (!insertionResult.second) { insertionResult.first->second.shaderStages |= shaderStage; @@ -245,63 +155,96 @@ namespace vkcv { bindingID, setID); } } + } - for (uint32_t i = 0; i < resources.storage_images.size(); i++) { - auto &u = resources.storage_images [i]; - const spirv_cross::SPIRType &base_type = comp.get_type(u.base_type_id); - const spirv_cross::SPIRType &type = comp.get_type(u.type_id); + void ShaderProgram::reflectShader(ShaderStage shaderStage) { + auto shaderCode = m_Shaders.at(shaderStage); - uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); - uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); + spirv_cross::Compiler comp(shaderCode); + spirv_cross::ShaderResources resources = comp.get_shader_resources(); - uint32_t descriptorCount = base_type.vecsize; - bool variableCount = false; - // query whether reflected resources are qualified as one-dimensional array - if (type.array_size_literal [0]) { - descriptorCount = type.array [0]; - if (type.array [0] == 0) - variableCount = true; - } + // reflect vertex input + if (shaderStage == ShaderStage::VERTEX) { + // spirv-cross API (hopefully) returns the stage_inputs in order + for (uint32_t i = 0; i < resources.stage_inputs.size(); i++) { + // spirv-cross specific objects + auto &stage_input = resources.stage_inputs [i]; + const spirv_cross::SPIRType &base_type = comp.get_type(stage_input.base_type_id); - DescriptorBinding binding { - bindingID, DescriptorType::IMAGE_STORAGE, descriptorCount, shaderStage, - variableCount, - variableCount // partialBinding == variableCount - }; + // vertex input location + const uint32_t attachment_loc = + comp.get_decoration(stage_input.id, spv::DecorationLocation); + // vertex input name + const std::string attachment_name = stage_input.name; + // vertex input format (implies its size) + const VertexAttachmentFormat attachment_format = + convertFormat(base_type.basetype, base_type.vecsize); - auto insertionResult = - m_DescriptorSets [setID].insert(std::make_pair(bindingID, binding)); - if (!insertionResult.second) { - insertionResult.first->second.shaderStages |= shaderStage; - - vkcv_log(LogLevel::WARNING, - "Attempting to overwrite already existing binding %u at set ID %u.", - bindingID, setID); + m_VertexAttachments.push_back( + { attachment_loc, attachment_name, attachment_format, 0 }); } } - // Used to reflect acceleration structure bindings for RTX. - for (uint32_t i = 0; i < resources.acceleration_structures.size(); i++) { - auto &u = resources.acceleration_structures [i]; - const spirv_cross::SPIRType &base_type = comp.get_type(u.base_type_id); + reflectShaderDescriptorSets( + m_DescriptorSets, + shaderStage, + DescriptorType::UNIFORM_BUFFER, + comp, + resources + ); + + reflectShaderDescriptorSets( + m_DescriptorSets, + shaderStage, + DescriptorType::STORAGE_BUFFER, + comp, + resources + ); + + reflectShaderDescriptorSets( + m_DescriptorSets, + shaderStage, + DescriptorType::SAMPLER, + comp, + resources + ); + + reflectShaderDescriptorSets( + m_DescriptorSets, + shaderStage, + DescriptorType::IMAGE_SAMPLED, + comp, + resources + ); + + reflectShaderDescriptorSets( + m_DescriptorSets, + shaderStage, + DescriptorType::IMAGE_STORAGE, + comp, + resources + ); + + reflectShaderDescriptorSets( + m_DescriptorSets, + shaderStage, + DescriptorType::ACCELERATION_STRUCTURE_KHR, + comp, + resources + ); + + for (auto &descriptorSet : m_DescriptorSets) { + uint32_t maxVariableBindingID = 0; + + for (const auto &binding : descriptorSet.second) { + maxVariableBindingID = std::max(maxVariableBindingID, binding.first); + } - uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); - uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); - auto binding = DescriptorBinding { bindingID, - DescriptorType::ACCELERATION_STRUCTURE_KHR, - base_type.vecsize, - shaderStage, - false, - false }; - - auto insertionResult = - m_DescriptorSets [setID].insert(std::make_pair(bindingID, binding)); - if (!insertionResult.second) { - insertionResult.first->second.shaderStages |= shaderStage; - - vkcv_log(LogLevel::WARNING, - "Attempting to overwrite already existing binding %u at set ID %u.", - bindingID, setID); + for (auto &binding : descriptorSet.second) { + if (binding.first < maxVariableBindingID) { + binding.second.variableCount &= false; + binding.second.partialBinding &= false; + } } } diff --git a/src/vkcv/SwapchainManager.cpp b/src/vkcv/SwapchainManager.cpp index c89845302c408faf05d38bc356f648ce822f2cd3..03dbdc0175b393565bc4235e99f5cb02dd176db5 100644 --- a/src/vkcv/SwapchainManager.cpp +++ b/src/vkcv/SwapchainManager.cpp @@ -207,7 +207,7 @@ namespace vkcv { vk::CompositeAlphaFlagBitsKHR::eOpaque, chosenPresentMode, true, entry.m_Swapchain); entry.m_Swapchain = device.createSwapchainKHR(swapchainCreateInfo); - return true; + return entry.m_Swapchain? true : false; } SwapchainHandle SwapchainManager::createSwapchain(Window &window) { diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp index 78afe0f2175e6b3c7355e5f7863ae425069adacd..d710766014f21671a32b720421c734ddf12a317f 100644 --- a/src/vkcv/Window.cpp +++ b/src/vkcv/Window.cpp @@ -122,6 +122,9 @@ namespace vkcv { Window::e_char.unlock(); Window::e_gamepad.unlock(); Window::e_resize.remove(m_resizeHandle); + + m_swapchainHandle = SwapchainHandle(); + if (m_window) { s_Windows.erase(std::find(s_Windows.begin(), s_Windows.end(), m_window)); glfwDestroyWindow(m_window);