diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 63fda17212cf97f2857ac1891dfad9dd052cbe6a..0000000000000000000000000000000000000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,125 +0,0 @@ -variables: - RUN: - value: "all" - description: "The tests that should run. Possible values: ubuntu, win-msvc, win-mingw, mac, all." - GIT_DEPTH: 15 - -stages: - - build - - deploy - -build_ubuntu_gcc: - only: - variables: - - $RUN =~ /\bubuntu.*/i || $RUN =~ /\ball.*/i - stage: build - tags: - - ubuntu-gcc-cached - variables: - GIT_SUBMODULE_STRATEGY: recursive - timeout: 15m - retry: 1 - script: - - mkdir debug - - cd debug - - cmake -DCMAKE_BUILD_TYPE=Debug .. - - cmake --build . -j 4 - artifacts: - name: "Documentation - $CI_PIPELINE_ID" - paths: - - doc/html - - doc/latex - expire_in: never - -build_win10_msvc: - only: - variables: - - $RUN =~ /\bwin-msvc.*/i || $RUN =~ /\ball.*/i - stage: build - tags: - - win10-msvc-cached - variables: - GIT_SUBMODULE_STRATEGY: recursive - timeout: 15m - retry: 0 - script: - - cd 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\' - - .\Launch-VsDevShell.ps1 - - cd $CI_PROJECT_DIR - - mkdir debug - - cd debug - - cmake -DCMAKE_BUILD_TYPE=Debug .. - - cmake --build . -j 4 - -build_win10_mingw: - only: - variables: - - $RUN =~ /\bwin-mingw.*/i || $RUN =~ /\ball.*/i - stage: build - tags: - - win10-mingw-cached - variables: - GIT_SUBMODULE_STRATEGY: recursive - timeout: 15m - retry: 0 - script: - - mkdir debug - - cd debug - - cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=C:\msys64\mingw64\bin\x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++.exe .. -G "Unix Makefiles" - - cmake --build . -j 4 - -build_mac_clang: - only: - variables: - - $RUN =~ /\bmac.*/i || $RUN =~ /\ball.*/i - stage: build - tags: - - catalina-clang-cached - variables: - GIT_SUBMODULE_STRATEGY: recursive - timeout: 15m - retry: 1 - script: - - mkdir debug - - cd debug - - export LDFLAGS="-L/usr/local/opt/llvm/lib" - - export CPPFLAGS="-I/usr/local/opt/llvm/include" - - cmake -DCMAKE_C_COMPILER="/usr/local/opt/llvm/bin/clang" -DCMAKE_CXX_COMPILER="/usr/local/opt/llvm/bin/clang++" -DCMAKE_BUILD_TYPE=Debug .. - - cmake --build . -j 4 - -deploy_doc_develop: - only: - variables: - - $RUN =~ /\bubuntu.*/i || $RUN =~ /\ball.*/i - refs: - - develop - stage: deploy - needs: ["build_ubuntu_gcc"] - dependencies: - - build_ubuntu_gcc - tags: - - webserver - variables: - GIT_STRATEGY: none - script: - - rsync -avh doc/html/ /var/www/html/develop --delete - - echo "Check it out at https://vkcv.de/develop" - -deploy_doc_branch: - only: - variables: - - $RUN =~ /\bubuntu.*/i || $RUN =~ /\ball.*/i - except: - refs: - - develop - stage: deploy - needs: ["build_ubuntu_gcc"] - dependencies: - - build_ubuntu_gcc - tags: - - webserver - variables: - GIT_STRATEGY: none - script: - - rsync -avh doc/html/ /var/www/html/branch/$CI_COMMIT_BRANCH --delete - - echo "Check it out at https://vkcv.de/branch/$CI_COMMIT_BRANCH" \ No newline at end of file diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 1e036f799d6769a88e4350afdf182ef397400907..77370fb39b1a5a300614fe9cfb0b505e5ef2dd67 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -207,7 +207,7 @@ namespace vkcv [[nodiscard]] SamplerHandle createSampler(SamplerFilterType magFilter, SamplerFilterType minFilter, SamplerMipmapMode mipmapMode, SamplerAddressMode addressMode, - float mipLodBias = 0.0f); + float mipLodBias = 0.0f, SamplerBorderColor borderColor = SamplerBorderColor::INT_ZERO_OPAQUE); /** * Creates an #Image with a given format, width, height and depth. diff --git a/include/vkcv/DrawcallRecording.hpp b/include/vkcv/DrawcallRecording.hpp index 77e2a2e13bee3248e424d1d9c3d4cad7aaecd34b..70b23107c4605e6ac01aa80fa4a431c62d7a7219 100644 --- a/include/vkcv/DrawcallRecording.hpp +++ b/include/vkcv/DrawcallRecording.hpp @@ -1,11 +1,12 @@ #pragma once #include <vulkan/vulkan.hpp> -#include <vkcv/Handles.hpp> -#include <vkcv/DescriptorConfig.hpp> -#include <vkcv/PushConstants.hpp> +#include "vkcv/Handles.hpp" +#include "vkcv/DescriptorConfig.hpp" +#include "vkcv/PushConstants.hpp" #include "Buffer.hpp" namespace vkcv { + struct VertexBufferBinding { inline VertexBufferBinding(vk::DeviceSize offset, vk::Buffer buffer) noexcept : offset(offset), buffer(buffer) {} @@ -20,12 +21,12 @@ namespace vkcv { }; struct DescriptorSetUsage { - inline DescriptorSetUsage(uint32_t setLocation, vk::DescriptorSet vulkanHandle, + inline DescriptorSetUsage(uint32_t setLocation, DescriptorSetHandle descriptorSet, const std::vector<uint32_t>& dynamicOffsets = {}) noexcept - : setLocation(setLocation), vulkanHandle(vulkanHandle), dynamicOffsets(dynamicOffsets) {} + : setLocation(setLocation), descriptorSet(descriptorSet), dynamicOffsets(dynamicOffsets) {} const uint32_t setLocation; - const vk::DescriptorSet vulkanHandle; + const DescriptorSetHandle descriptorSet; const std::vector<uint32_t> dynamicOffsets; }; @@ -51,8 +52,6 @@ namespace vkcv { }; - vk::IndexType getIndexType(IndexBitCount indexByteCount); - struct DrawcallInfo { inline DrawcallInfo(const Mesh& mesh, const std::vector<DescriptorSetUsage>& descriptorSets, const uint32_t instanceCount = 1) : mesh(mesh), descriptorSets(descriptorSets), instanceCount(instanceCount){} @@ -62,22 +61,6 @@ namespace vkcv { uint32_t instanceCount; }; - void recordDrawcall( - const DrawcallInfo &drawcall, - vk::CommandBuffer cmdBuffer, - vk::PipelineLayout pipelineLayout, - const PushConstants &pushConstants, - const size_t drawcallIndex); - - void recordIndirectDrawcall( - const DrawcallInfo &drawcall, - vk::CommandBuffer cmdBuffer, - const vkcv::Buffer<vk::DrawIndexedIndirectCommand> &drawBuffer, - const uint32_t drawCount, - vk::PipelineLayout pipelineLayout, - const PushConstants &pushConstants, - const size_t drawcallIndex); - void InitMeshShaderDrawFunctions(vk::Device device); struct MeshShaderDrawcall { @@ -89,9 +72,10 @@ namespace vkcv { }; void recordMeshShaderDrawcall( + const Core& core, vk::CommandBuffer cmdBuffer, vk::PipelineLayout pipelineLayout, - const PushConstants& pushConstantData, + const PushConstants& pushConstantData, const uint32_t pushConstantOffset, const MeshShaderDrawcall& drawcall, const uint32_t firstTask); diff --git a/include/vkcv/FeatureManager.hpp b/include/vkcv/FeatureManager.hpp index 2f932f6e25c12e80f42d762f82a73f9a5265b793..5d5a2e9a7ca839c1cbd2cfa53d0f61d042ac3b2a 100644 --- a/include/vkcv/FeatureManager.hpp +++ b/include/vkcv/FeatureManager.hpp @@ -79,6 +79,12 @@ namespace vkcv { [[nodiscard]] bool checkSupport(const vk::PhysicalDeviceMeshShaderFeaturesNV& features, bool required) const; + [[nodiscard]] + bool checkSupport(const vk::PhysicalDeviceShaderAtomicFloatFeaturesEXT& features, bool required) const; + + [[nodiscard]] + bool checkSupport(const vk::PhysicalDeviceShaderAtomicFloat2FeaturesEXT& features, bool required) const; + /** * @brief Currently used for RTX. Checks support of the @p vk::PhysicalDeviceVulkan12Features. * @param features The features. diff --git a/include/vkcv/Sampler.hpp b/include/vkcv/Sampler.hpp index 007ed5ae4737275ddacbc5881a2c4c202b8806a4..e4f10cd9d3f1dd60021e62842acaa07d2aefb5ce 100644 --- a/include/vkcv/Sampler.hpp +++ b/include/vkcv/Sampler.hpp @@ -16,7 +16,19 @@ namespace vkcv { REPEAT = 1, MIRRORED_REPEAT = 2, CLAMP_TO_EDGE = 3, - MIRROR_CLAMP_TO_EDGE = 4 + MIRROR_CLAMP_TO_EDGE = 4, + CLAMP_TO_BORDER = 5 + }; + + enum class SamplerBorderColor { + INT_ZERO_OPAQUE = 1, + INT_ZERO_TRANSPARENT = 2, + + FLOAT_ZERO_OPAQUE = 3, + FLOAT_ZERO_TRANSPARENT = 4, + + INT_ONE_OPAQUE = 5, + FLOAT_ONE_OPAQUE = 6 }; } diff --git a/modules/scene/src/vkcv/scene/MeshPart.cpp b/modules/scene/src/vkcv/scene/MeshPart.cpp index 46e79897719d5422151ec31837a41f7e58324a71..4aa450da4c11b23d686a2836f815d2c03c3675f7 100644 --- a/modules/scene/src/vkcv/scene/MeshPart.cpp +++ b/modules/scene/src/vkcv/scene/MeshPart.cpp @@ -70,11 +70,10 @@ namespace vkcv::scene { if (*this) { const auto& material = getMaterial(); - const auto& descriptorSet = core.getDescriptorSet(material.getDescriptorSet()); drawcalls.push_back(DrawcallInfo( vkcv::Mesh(m_vertexBindings, indexBuffer.getVulkanHandle(), m_indexCount), - { DescriptorSetUsage(0, descriptorSet.vulkanHandle) } + { DescriptorSetUsage(0, material.getDescriptorSet()) } )); } } diff --git a/modules/shader_compiler/include/vkcv/shader/Compiler.hpp b/modules/shader_compiler/include/vkcv/shader/Compiler.hpp index 5b119ca5c68f997bacfbea6c60d5c965f9a7a54e..d4be7384dfffeeb068a13660004be138e62722a1 100644 --- a/modules/shader_compiler/include/vkcv/shader/Compiler.hpp +++ b/modules/shader_compiler/include/vkcv/shader/Compiler.hpp @@ -6,10 +6,12 @@ #include <vkcv/Event.hpp> #include <vkcv/ShaderStage.hpp> +#include <vkcv/ShaderProgram.hpp> namespace vkcv::shader { typedef typename event_function<ShaderStage, const std::filesystem::path&>::type ShaderCompiledFunction; + typedef typename event_function<ShaderProgram&>::type ShaderProgramCompiledFunction; class Compiler { private: @@ -25,6 +27,11 @@ namespace vkcv::shader { const ShaderCompiledFunction& compiled, const std::filesystem::path& includePath, bool update) = 0; + void compileProgram(ShaderProgram& program, + const std::unordered_map<ShaderStage, const std::filesystem::path>& stages, + const ShaderProgramCompiledFunction& compiled, + const std::filesystem::path& includePath = "", bool update = false); + std::string getDefine(const std::string& name) const; void setDefine(const std::string& name, const std::string& value); diff --git a/modules/shader_compiler/src/vkcv/shader/Compiler.cpp b/modules/shader_compiler/src/vkcv/shader/Compiler.cpp index f5ec0435ca8b82dc5f328921f43a39338d1be456..1467bf22616764e00399ada69d5f866b929416d5 100644 --- a/modules/shader_compiler/src/vkcv/shader/Compiler.cpp +++ b/modules/shader_compiler/src/vkcv/shader/Compiler.cpp @@ -3,6 +3,27 @@ namespace vkcv::shader { + void Compiler::compileProgram(ShaderProgram& program, + const std::unordered_map<ShaderStage, const std::filesystem::path>& stages, + const ShaderProgramCompiledFunction& compiled, + const std::filesystem::path& includePath, bool update) { + for (const auto& stage : stages) { + compile( + stage.first, + stage.second, + [&program](ShaderStage shaderStage, const std::filesystem::path& path) { + program.addShader(shaderStage, path); + }, + includePath, + update + ); + } + + if (compiled) { + compiled(program); + } + } + std::string Compiler::getDefine(const std::string &name) const { return m_defines.at(name); } diff --git a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp index 2045db9ea216d6810ec439114e93e06949c45cc0..0f6dfcdeaa3b1efc6f58c1c2d0eb61bbd2090a80 100644 --- a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp +++ b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp @@ -344,9 +344,7 @@ namespace vkcv::upscaling { cmdStream, m_easuPipeline, dispatch, - {DescriptorSetUsage(0, m_core.getDescriptorSet( - m_easuDescriptorSet - ).vulkanHandle, { 0 })}, + {DescriptorSetUsage(0, m_easuDescriptorSet, { 0 })}, PushConstants(0) ); @@ -366,9 +364,7 @@ namespace vkcv::upscaling { cmdStream, m_rcasPipeline, dispatch, - {DescriptorSetUsage(0, m_core.getDescriptorSet( - m_rcasDescriptorSet - ).vulkanHandle, { 0 })}, + {DescriptorSetUsage(0,m_rcasDescriptorSet, { 0 })}, PushConstants(0) ); @@ -386,9 +382,7 @@ namespace vkcv::upscaling { cmdStream, m_easuPipeline, dispatch, - {DescriptorSetUsage(0, m_core.getDescriptorSet( - m_easuDescriptorSet - ).vulkanHandle, { 0 })}, + {DescriptorSetUsage(0, m_easuDescriptorSet, { 0 })}, PushConstants(0) ); } diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index 621371fd4e20f942a775ac73300861ba2e15dd45..ffe8546c961697869354993539697b118fa8d6be 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -14,4 +14,5 @@ add_subdirectory(indirect_draw) add_subdirectory(bindless_textures) add_subdirectory(saf_r) add_subdirectory(indirect_dispatch) -add_subdirectory(path_tracer) \ No newline at end of file +add_subdirectory(path_tracer) +add_subdirectory(wobble_bobble) \ No newline at end of file diff --git a/projects/bindless_textures/src/main.cpp b/projects/bindless_textures/src/main.cpp index 0ad6c1250c8a6e01838ae1b52fd52a6dd24fbbe3..6aa0a9d6106dd06c08dd5219c9570430b49ce229 100644 --- a/projects/bindless_textures/src/main.cpp +++ b/projects/bindless_textures/src/main.cpp @@ -123,18 +123,12 @@ int main(int argc, const char** argv) { vkcv::ShaderProgram firstMeshProgram; vkcv::shader::GLSLCompiler compiler; - compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/shader.vert"), - [&firstMeshProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - firstMeshProgram.addShader(shaderStage, path); - }); - - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/shader.frag"), - [&firstMeshProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - firstMeshProgram.addShader(shaderStage, path); - }); + compiler.compileProgram(firstMeshProgram, { + { vkcv::ShaderStage::VERTEX, "resources/shaders/shader.vert" }, + { vkcv::ShaderStage::FRAGMENT, "resources/shaders/shader.frag" } + }, nullptr); auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes; - std::sort(attributes.begin(), attributes.end(), [](const vkcv::asset::VertexAttribute& x, const vkcv::asset::VertexAttribute& y) { return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); @@ -218,7 +212,7 @@ int main(int argc, const char** argv) { const vkcv::Mesh renderMesh(vertexBufferBindings, indexBuffer.getVulkanHandle(), mesh.vertexGroups[0].numIndices); - vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); + vkcv::DescriptorSetUsage descriptorUsage(0, descriptorSet); vkcv::DrawcallInfo drawcall(renderMesh, { descriptorUsage },1); vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index 55278b703b6a7c70d7d12e8b86ca5eea2b76cdf8..3f4378a6a2187ba33b7965fd6d008577541f7351 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -73,18 +73,12 @@ int main(int argc, const char** argv) { vkcv::ShaderProgram firstMeshProgram; vkcv::shader::GLSLCompiler compiler; - compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("assets/shaders/shader.vert"), - [&firstMeshProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - firstMeshProgram.addShader(shaderStage, path); - }); - - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("assets/shaders/shader.frag"), - [&firstMeshProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - firstMeshProgram.addShader(shaderStage, path); - }); + compiler.compileProgram(firstMeshProgram, { + { vkcv::ShaderStage::VERTEX, "assets/shaders/shader.vert" }, + { vkcv::ShaderStage::FRAGMENT, "assets/shaders/shader.frag" } + }, nullptr); auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes; - std::sort(attributes.begin(), attributes.end(), [](const vkcv::asset::VertexAttribute& x, const vkcv::asset::VertexAttribute& y) { return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); @@ -167,7 +161,7 @@ int main(int argc, const char** argv) { const vkcv::Mesh renderMesh(vertexBufferBindings, indexBuffer.getVulkanHandle(), mesh.vertexGroups[0].numIndices); - vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); + vkcv::DescriptorSetUsage descriptorUsage(0, descriptorSet); vkcv::DrawcallInfo drawcall(renderMesh, { descriptorUsage },1); vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp index 3ec5b9764f70efa8911d8e772d6287e5efc8f056..3dd6fc40d516c6f1ae3358d60c02fc4ed219245a 100644 --- a/projects/first_scene/src/main.cpp +++ b/projects/first_scene/src/main.cpp @@ -61,15 +61,10 @@ int main(int argc, const char** argv) { vkcv::ShaderProgram sceneShaderProgram; vkcv::shader::GLSLCompiler compiler; - compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("assets/shaders/shader.vert"), - [&sceneShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - sceneShaderProgram.addShader(shaderStage, path); - }); - - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("assets/shaders/shader.frag"), - [&sceneShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - sceneShaderProgram.addShader(shaderStage, path); - }); + compiler.compileProgram(sceneShaderProgram, { + { vkcv::ShaderStage::VERTEX, "assets/shaders/shader.vert" }, + { vkcv::ShaderStage::FRAGMENT, "assets/shaders/shader.frag" } + }, nullptr); const std::vector<vkcv::VertexAttachment> vertexAttachments = sceneShaderProgram.getVertexAttachments(); std::vector<vkcv::VertexBinding> bindings; diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index 1725b5c84dea931fe785880e3cd423cbb5f04a46..b4ba9046e07ecd3534844b493642098aa5847307 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -47,15 +47,10 @@ int main(int argc, const char** argv) { vkcv::ShaderProgram triangleShaderProgram; vkcv::shader::GLSLCompiler compiler; - compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("shaders/shader.vert"), - [&triangleShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - triangleShaderProgram.addShader(shaderStage, path); - }); - - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("shaders/shader.frag"), - [&triangleShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - triangleShaderProgram.addShader(shaderStage, path); - }); + compiler.compileProgram(triangleShaderProgram, { + {vkcv::ShaderStage::VERTEX, "shaders/shader.vert"}, + { vkcv::ShaderStage::FRAGMENT, "shaders/shader.frag" } + }, nullptr); const auto swapchainExtent = core.getSwapchain(windowHandle).getExtent(); diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp index 532cef11db5b2bb8b5d741f6505507ff23fa4163..cc897e68651de65c7122188b52598535e6637335 100644 --- a/projects/indirect_dispatch/src/App.cpp +++ b/projects/indirect_dispatch/src/App.cpp @@ -261,7 +261,7 @@ void App::run() { for (const Object& obj : sceneObjects) { forwardSceneDrawcalls.push_back(vkcv::DrawcallInfo( obj.meshResources.mesh, - { vkcv::DescriptorSetUsage(0, m_core.getDescriptorSet(m_meshPass.descriptorSet).vulkanHandle) })); + { vkcv::DescriptorSetUsage(0, m_meshPass.descriptorSet) })); } m_core.recordDrawcallsToCmdStream( @@ -338,7 +338,7 @@ void App::run() { cmdStream, m_gammaCorrectionPass.pipeline, fullScreenImageDispatch, - { vkcv::DescriptorSetUsage(0, m_core.getDescriptorSet(m_gammaCorrectionPass.descriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_gammaCorrectionPass.descriptorSet) }, vkcv::PushConstants(0)); m_core.prepareSwapchainImageForPresent(cmdStream); diff --git a/projects/indirect_dispatch/src/MotionBlur.cpp b/projects/indirect_dispatch/src/MotionBlur.cpp index fea5b1d6f726851ad1d88e71301bffb0f6d71f4a..30116c84b79ae71c683ee865dbf93dd1a37923e9 100644 --- a/projects/indirect_dispatch/src/MotionBlur.cpp +++ b/projects/indirect_dispatch/src/MotionBlur.cpp @@ -120,7 +120,7 @@ vkcv::ImageHandle MotionBlur::render( cmdStream, m_tileResetPass.pipeline, dispatchSizeOne, - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_tileResetPass.descriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_tileResetPass.descriptorSet) }, vkcv::PushConstants(0)); m_core->recordBufferMemoryBarrier(cmdStream, m_fullPathWorkTileBuffer); @@ -166,7 +166,7 @@ vkcv::ImageHandle MotionBlur::render( cmdStream, m_tileClassificationPass.pipeline, tileClassificationDispatch.data(), - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_tileClassificationPass.descriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_tileClassificationPass.descriptorSet) }, classificationPushConstants); m_core->recordBufferMemoryBarrier(cmdStream, m_fullPathWorkTileBuffer); @@ -254,7 +254,7 @@ vkcv::ImageHandle MotionBlur::render( m_motionBlurPass.pipeline, m_fullPathWorkTileBuffer, 0, - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_motionBlurPass.descriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_motionBlurPass.descriptorSet) }, motionBlurPushConstants); m_core->recordComputeIndirectDispatchToCmdStream( @@ -262,7 +262,7 @@ vkcv::ImageHandle MotionBlur::render( m_colorCopyPass.pipeline, m_copyPathWorkTileBuffer, 0, - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_colorCopyPass.descriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_colorCopyPass.descriptorSet) }, vkcv::PushConstants(0)); m_core->recordComputeIndirectDispatchToCmdStream( @@ -270,7 +270,7 @@ vkcv::ImageHandle MotionBlur::render( m_motionBlurFastPathPass.pipeline, m_fastPathWorkTileBuffer, 0, - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_motionBlurFastPathPass.descriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_motionBlurFastPathPass.descriptorSet) }, fastPathPushConstants); } else if(mode == eMotionBlurMode::Disabled) { @@ -305,7 +305,7 @@ vkcv::ImageHandle MotionBlur::render( cmdStream, m_tileVisualisationPass.pipeline, dispatchCounts, - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_tileVisualisationPass.descriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_tileVisualisationPass.descriptorSet) }, vkcv::PushConstants(0)); } else { @@ -371,7 +371,7 @@ vkcv::ImageHandle MotionBlur::renderMotionVectorVisualisation( cmdStream, m_motionVectorVisualisationPass.pipeline, dispatchSizes.data(), - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_motionVectorVisualisationPass.descriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_motionVectorVisualisationPass.descriptorSet) }, motionVectorVisualisationPushConstants); return m_renderTargets.outputColor; @@ -406,7 +406,7 @@ void MotionBlur::computeMotionTiles( cmdStream, m_motionVectorMinMaxPass.pipeline, motionTileDispatchCounts.data(), - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_motionVectorMinMaxPass.descriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_motionVectorMinMaxPass.descriptorSet) }, vkcv::PushConstants(0)); // motion vector min max neighbourhood @@ -432,6 +432,6 @@ void MotionBlur::computeMotionTiles( cmdStream, m_motionVectorMinMaxNeighbourhoodPass.pipeline, motionTileDispatchCounts.data(), - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_motionVectorMinMaxNeighbourhoodPass.descriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_motionVectorMinMaxNeighbourhoodPass.descriptorSet) }, vkcv::PushConstants(0)); } \ No newline at end of file diff --git a/projects/indirect_draw/src/main.cpp b/projects/indirect_draw/src/main.cpp index 4841743a8e1462bfba572960986a3aba6ea355ab..9b062ab56245c44e5021f164b9e06fed8edd15c3 100644 --- a/projects/indirect_draw/src/main.cpp +++ b/projects/indirect_draw/src/main.cpp @@ -536,7 +536,7 @@ int main(int argc, const char** argv) { const uint32_t dispatchCount[3] = {static_cast<uint32_t>(ceiledDispatchCount), 1, 1}; - vkcv::DescriptorSetUsage cullingUsage(0, core.getDescriptorSet(cullingDescSet).vulkanHandle, {}); + vkcv::DescriptorSetUsage cullingUsage(0, cullingDescSet, {}); vkcv::PushConstants emptyPushConstant(0); bool updateFrustumPlanes = true; diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp index dc7ca7caae5362e74fac82558b530cdce0357bb0..0a9914abf0a28f82eee06c5d2a67067faaff4109 100644 --- a/projects/mesh_shader/src/main.cpp +++ b/projects/mesh_shader/src/main.cpp @@ -354,7 +354,7 @@ int main(int argc, const char** argv) { if (useMeshShader) { - vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(meshShaderDescriptorSet).vulkanHandle); + vkcv::DescriptorSetUsage descriptorUsage(0, meshShaderDescriptorSet); const uint32_t taskCount = (meshShaderModelData.meshlets.size() + 31) / 32; core.recordMeshShaderDrawcalls( @@ -368,7 +368,7 @@ int main(int argc, const char** argv) { } else { - vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(vertexShaderDescriptorSet).vulkanHandle); + vkcv::DescriptorSetUsage descriptorUsage(0, vertexShaderDescriptorSet); core.recordDrawcallsToCmdStream( cmdStream, diff --git a/projects/particle_simulation/src/BloomAndFlares.cpp b/projects/particle_simulation/src/BloomAndFlares.cpp index a437afac25490e35547d53f432f7994d8e02717d..6ab0a8deff3d5fe906567562cb86d75a1cc2c09b 100644 --- a/projects/particle_simulation/src/BloomAndFlares.cpp +++ b/projects/particle_simulation/src/BloomAndFlares.cpp @@ -118,7 +118,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre cmdStream, m_DownsamplePipe, initialDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[0]).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_DownsampleDescSets[0])}, vkcv::PushConstants(0)); // downsample dispatches of blur buffer's mip maps @@ -153,7 +153,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre cmdStream, m_DownsamplePipe, mipDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[mipLevel]).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_DownsampleDescSets[mipLevel])}, vkcv::PushConstants(0)); // image barrier between mips @@ -198,7 +198,7 @@ void BloomAndFlares::execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream cmdStream, m_UpsamplePipe, upsampleDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_UpsampleDescSets[mipLevel]).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_UpsampleDescSets[mipLevel])}, vkcv::PushConstants(0) ); // image barrier between mips @@ -230,7 +230,7 @@ void BloomAndFlares::execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStr cmdStream, m_LensFlarePipe, lensFeatureDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_LensFlareDescSet).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_LensFlareDescSet)}, vkcv::PushConstants(0)); } @@ -263,7 +263,7 @@ void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStrea cmdStream, m_CompositePipe, compositeDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_CompositeDescSet).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_CompositeDescSet)}, vkcv::PushConstants(0)); } diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp index 291b97f2fde4719530dcb26eb4baeb197f9b2a74..6637041e5ea9c8f1dd3dadf0303049d2a3b749e9 100644 --- a/projects/particle_simulation/src/main.cpp +++ b/projects/particle_simulation/src/main.cpp @@ -180,7 +180,7 @@ int main(int argc, const char **argv) { const vkcv::Mesh renderMesh({vertexBufferBindings}, particleIndexBuffer.getVulkanHandle(), particleIndexBuffer.getCount()); - vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); + vkcv::DescriptorSetUsage descriptorUsage(0, descriptorSet); auto pos = glm::vec2(0.f); auto spawnPosition = glm::vec3(0.f); @@ -283,7 +283,7 @@ int main(int argc, const char **argv) { core.recordComputeDispatchToCmdStream(cmdStream, computePipeline, computeDispatchCount, - {vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, computeDescriptorSet)}, pushConstantsCompute); core.recordBufferMemoryBarrier(cmdStream, particleBuffer.getHandle()); @@ -321,7 +321,7 @@ int main(int argc, const char **argv) { cmdStream, tonemappingPipe, tonemappingDispatchCount, - {vkcv::DescriptorSetUsage(0, core.getDescriptorSet(tonemappingDescriptor).vulkanHandle) }, + {vkcv::DescriptorSetUsage(0, tonemappingDescriptor) }, vkcv::PushConstants(0)); core.prepareSwapchainImageForPresent(cmdStream); diff --git a/projects/path_tracer/src/main.cpp b/projects/path_tracer/src/main.cpp index db25f239fd5845d2bd2ac69243ceb48b0b80a6ce..b7c495c070bd354dd58c0fad3f857489ad7408e7 100644 --- a/projects/path_tracer/src/main.cpp +++ b/projects/path_tracer/src/main.cpp @@ -342,7 +342,7 @@ int main(int argc, const char** argv) { core.recordComputeDispatchToCmdStream(cmdStream, imageClearPipeline, fullscreenDispatchCount, - { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(imageClearDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, imageClearDescriptorSet) }, vkcv::PushConstants(0)); clearMeanImage = false; @@ -377,7 +377,7 @@ int main(int argc, const char** argv) { core.recordComputeDispatchToCmdStream(cmdStream, tracePipeline, traceDispatchCount, - { vkcv::DescriptorSetUsage(0,core.getDescriptorSet(traceDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, traceDescriptorSet) }, pushConstantsCompute); core.prepareImageForStorage(cmdStream, meanImage); @@ -387,7 +387,7 @@ int main(int argc, const char** argv) { core.recordComputeDispatchToCmdStream(cmdStream, imageCombinePipeline, fullscreenDispatchCount, - { vkcv::DescriptorSetUsage(0,core.getDescriptorSet(imageCombineDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, imageCombineDescriptorSet) }, vkcv::PushConstants(0)); core.recordImageMemoryBarrier(cmdStream, meanImage); @@ -406,7 +406,7 @@ int main(int argc, const char** argv) { core.recordComputeDispatchToCmdStream(cmdStream, presentPipeline, fullscreenDispatchCount, - { vkcv::DescriptorSetUsage(0,core.getDescriptorSet(presentDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, presentDescriptorSet) }, vkcv::PushConstants(0)); core.prepareSwapchainImageForPresent(cmdStream); diff --git a/projects/rtx_ambient_occlusion/src/main.cpp b/projects/rtx_ambient_occlusion/src/main.cpp index bac1fe367031e43cf2fc53d4be23c208f4fb682d..d4c8ec2cac8e26f70da346738da04de16a766a26 100644 --- a/projects/rtx_ambient_occlusion/src/main.cpp +++ b/projects/rtx_ambient_occlusion/src/main.cpp @@ -148,7 +148,7 @@ int main(int argc, const char** argv) { rtxRegions.rmissRegion, rtxRegions.rchitRegion, rtxRegions.rcallRegion, - { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(rtxShaderDescriptorSet).vulkanHandle)}, + { vkcv::DescriptorSetUsage(0, rtxShaderDescriptorSet)}, pushConstantsRTX, windowHandle); diff --git a/projects/saf_r/src/main.cpp b/projects/saf_r/src/main.cpp index 9ffd2845e1081d56e6026a10f19abd36e82d5828..a188c33d63f8c5d190ee02ce4aaef5adc2a8b967 100644 --- a/projects/saf_r/src/main.cpp +++ b/projects/saf_r/src/main.cpp @@ -198,7 +198,7 @@ int main(int argc, const char** argv) { auto start = std::chrono::system_clock::now(); const vkcv::Mesh renderMesh({}, safrIndexBuffer.getVulkanHandle(), 3); - vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); + vkcv::DescriptorSetUsage descriptorUsage(0, descriptorSet); vkcv::DrawcallInfo drawcall(renderMesh, { descriptorUsage }, 1); //create the camera @@ -280,7 +280,7 @@ int main(int argc, const char** argv) { core.recordComputeDispatchToCmdStream(cmdStream, computePipeline, computeDispatchCount, - { vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, computeDescriptorSet) }, pushConstantsCompute); core.recordBufferMemoryBarrier(cmdStream, lightsBuffer.getHandle()); diff --git a/projects/sph/shaders/force.comp b/projects/sph/shaders/force.comp index 9830a42f11a527e570bc77bc2f5a65b347e35819..694ddbdf7009d4e493a5f8dd8ba462e42d1e8b68 100644 --- a/projects/sph/shaders/force.comp +++ b/projects/sph/shaders/force.comp @@ -67,25 +67,29 @@ shared ParticleData particle_data [256]; void main() { uint id = gl_GlobalInvocationID.x; - if(id >= int(particleCount)) - { - return; + if (id >= int(particleCount)) { + particle_data[gl_LocalInvocationIndex].position = vec3(0.0f); + particle_data[gl_LocalInvocationIndex].density = 0.0f; + particle_data[gl_LocalInvocationIndex].velocity = vec3(0.0f); + particle_data[gl_LocalInvocationIndex].pressure = 0.0f; + } else { + particle_data[gl_LocalInvocationIndex].position = inParticle[id].position; + particle_data[gl_LocalInvocationIndex].density = inParticle[id].density; + particle_data[gl_LocalInvocationIndex].velocity = inParticle[id].velocity; + particle_data[gl_LocalInvocationIndex].pressure = inParticle[id].pressure; } uint index_offset = gl_WorkGroupID.x * gl_WorkGroupSize.x; - - particle_data[gl_LocalInvocationIndex].position = inParticle[id].position; - particle_data[gl_LocalInvocationIndex].density = inParticle[id].density; - particle_data[gl_LocalInvocationIndex].velocity = inParticle[id].velocity; - particle_data[gl_LocalInvocationIndex].pressure = inParticle[id].pressure; + uint group_size = min(index_offset + gl_WorkGroupSize.x, int(particleCount)) - index_offset; memoryBarrierShared(); + barrier(); const float h6 = pow(h, 6); externalForce = particle_data[gl_LocalInvocationIndex].density * gravity * vec3(-gravityDir.x,gravityDir.y,gravityDir.z); - for(uint j = 1; j < gl_WorkGroupSize.x; j++) { - uint i = (gl_LocalInvocationIndex + j) % gl_WorkGroupSize.x; + for(uint j = 1; j < group_size; j++) { + uint i = (gl_LocalInvocationIndex + j) % group_size; vec3 dir = particle_data[gl_LocalInvocationIndex].position - particle_data[i].position; float dist = length(dir); @@ -119,7 +123,7 @@ void main() { } } - for(uint i = index_offset + gl_WorkGroupSize.x; i < int(particleCount); i++) + for(uint i = index_offset + group_size; i < int(particleCount); i++) { vec3 dir = particle_data[gl_LocalInvocationIndex].position - inParticle[i].position; float dist = length(dir); @@ -138,9 +142,11 @@ void main() { viscosityForce *= viscosity; - outParticle[id].force = externalForce + pressureForce + viscosityForce; - outParticle[id].density = particle_data[gl_LocalInvocationIndex].density; - outParticle[id].pressure = particle_data[gl_LocalInvocationIndex].pressure; - outParticle[id].position = particle_data[gl_LocalInvocationIndex].position; - outParticle[id].velocity = particle_data[gl_LocalInvocationIndex].velocity; + if (id < int(particleCount)) { + outParticle[id].force = externalForce + pressureForce + viscosityForce; + outParticle[id].density = particle_data[gl_LocalInvocationIndex].density; + outParticle[id].pressure = particle_data[gl_LocalInvocationIndex].pressure; + outParticle[id].position = particle_data[gl_LocalInvocationIndex].position; + outParticle[id].velocity = particle_data[gl_LocalInvocationIndex].velocity; + } } diff --git a/projects/sph/shaders/pressure.comp b/projects/sph/shaders/pressure.comp index eb2029e35760d732ac8b4095d0ef41819a256736..8fa2e4762bddb3b9b28d8a3c184ceaaf7ab4421c 100644 --- a/projects/sph/shaders/pressure.comp +++ b/projects/sph/shaders/pressure.comp @@ -53,19 +53,20 @@ void main() { uint id = gl_GlobalInvocationID.x; - if(id >= int(particleCount)) - { - return; + if (id >= int(particleCount)) { + position_data[gl_LocalInvocationIndex] = vec3(0.0f); + } else { + position_data[gl_LocalInvocationIndex] = inParticle[id].position; } uint index_offset = gl_WorkGroupID.x * gl_WorkGroupSize.x; - - position_data[gl_LocalInvocationIndex] = inParticle[id].position; + uint group_size = min(index_offset + gl_WorkGroupSize.x, int(particleCount)) - index_offset; memoryBarrierShared(); + barrier(); - for(uint j = 1; j < gl_WorkGroupSize.x; j++) { - uint i = (gl_LocalInvocationIndex + j) % gl_WorkGroupSize.x; + for(uint j = 1; j < group_size; j++) { + uint i = (gl_LocalInvocationIndex + j) % group_size; float dist = distance(position_data[gl_LocalInvocationIndex], position_data[i]); densitySum += mass * poly6(dist); @@ -77,15 +78,17 @@ void main() { densitySum += mass * poly6(dist); } - for(uint i = index_offset + gl_WorkGroupSize.x; i < int(particleCount); i++) + for(uint i = index_offset + group_size; i < int(particleCount); i++) { float dist = distance(position_data[gl_LocalInvocationIndex], inParticle[i].position); densitySum += mass * poly6(dist); } - outParticle[id].density = max(densitySum,0.0000001f); - outParticle[id].pressure = max((densitySum - offset), 0.0000001f) * gasConstant; - outParticle[id].position = position_data[gl_LocalInvocationIndex]; - outParticle[id].velocity = inParticle[id].velocity; - outParticle[id].force = inParticle[id].force; + if (id < int(particleCount)) { + outParticle[id].density = max(densitySum, 0.0000001f); + outParticle[id].pressure = max((densitySum - offset), 0.0000001f) * gasConstant; + outParticle[id].position = position_data[gl_LocalInvocationIndex]; + outParticle[id].velocity = inParticle[id].velocity; + outParticle[id].force = inParticle[id].force; + } } diff --git a/projects/sph/src/BloomAndFlares.cpp b/projects/sph/src/BloomAndFlares.cpp index 0af3bf8cc132db891e070a0068183a702061ee1d..200c0dea16a0b1483a8b20786902b38a43b5f825 100644 --- a/projects/sph/src/BloomAndFlares.cpp +++ b/projects/sph/src/BloomAndFlares.cpp @@ -114,7 +114,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre cmdStream, m_DownsamplePipe, initialDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[0]).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_DownsampleDescSets[0])}, vkcv::PushConstants(0)); // downsample dispatches of blur buffer's mip maps @@ -149,7 +149,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre cmdStream, m_DownsamplePipe, mipDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[mipLevel]).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_DownsampleDescSets[mipLevel])}, vkcv::PushConstants(0)); // image barrier between mips @@ -194,7 +194,7 @@ void BloomAndFlares::execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream cmdStream, m_UpsamplePipe, upsampleDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_UpsampleDescSets[mipLevel]).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_UpsampleDescSets[mipLevel])}, vkcv::PushConstants(0) ); // image barrier between mips @@ -226,7 +226,7 @@ void BloomAndFlares::execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStr cmdStream, m_LensFlarePipe, lensFeatureDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_LensFlareDescSet).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_LensFlareDescSet)}, vkcv::PushConstants(0)); } @@ -259,7 +259,7 @@ void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStrea cmdStream, m_CompositePipe, compositeDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_CompositeDescSet).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_CompositeDescSet)}, vkcv::PushConstants(0)); } diff --git a/projects/sph/src/main.cpp b/projects/sph/src/main.cpp index 96968776a6aea9aaa12abfea1bbc966a43548491..44d38850a134327e1bd4733d45e9e2aed295f8b3 100644 --- a/projects/sph/src/main.cpp +++ b/projects/sph/src/main.cpp @@ -204,7 +204,7 @@ int main(int argc, const char **argv) { const vkcv::Mesh renderMesh({vertexBufferBindings}, particleIndexBuffer.getVulkanHandle(), particleIndexBuffer.getCount()); - vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); + vkcv::DescriptorSetUsage descriptorUsage(0, descriptorSet); auto pos = glm::vec2(0.f); @@ -329,7 +329,7 @@ int main(int argc, const char **argv) { core.recordComputeDispatchToCmdStream(cmdStream, computePipeline1, computeDispatchCount, - {vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet1).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, computeDescriptorSet1)}, pushConstantsCompute); core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle()); @@ -338,7 +338,7 @@ int main(int argc, const char **argv) { core.recordComputeDispatchToCmdStream(cmdStream, computePipeline2, computeDispatchCount, - {vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet2).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, computeDescriptorSet2)}, pushConstantsCompute); core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle()); @@ -347,7 +347,7 @@ int main(int argc, const char **argv) { core.recordComputeDispatchToCmdStream(cmdStream, computePipeline3, computeDispatchCount, - { vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet3).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, computeDescriptorSet3) }, pushConstantsCompute); core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle()); @@ -356,7 +356,7 @@ int main(int argc, const char **argv) { core.recordComputeDispatchToCmdStream(cmdStream, computePipeline4, computeDispatchCount, - { vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet4).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, computeDescriptorSet4) }, pushConstantsCompute); core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle()); @@ -397,7 +397,7 @@ int main(int argc, const char **argv) { cmdStream, tonemappingPipe, tonemappingDispatchCount, - {vkcv::DescriptorSetUsage(0, core.getDescriptorSet(tonemappingDescriptor).vulkanHandle) }, + {vkcv::DescriptorSetUsage(0, tonemappingDescriptor) }, vkcv::PushConstants(0)); core.prepareSwapchainImageForPresent(cmdStream); diff --git a/projects/voxelization/src/BloomAndFlares.cpp b/projects/voxelization/src/BloomAndFlares.cpp index a7ac2904c173d84d45ffec1d03f3c37fef20c76a..ddb1326ae83c8bd596ce61dc1c47b81b5ddb17be 100644 --- a/projects/voxelization/src/BloomAndFlares.cpp +++ b/projects/voxelization/src/BloomAndFlares.cpp @@ -145,7 +145,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre cmdStream, m_DownsamplePipe, initialDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[0]).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_DownsampleDescSets[0])}, vkcv::PushConstants(0)); // downsample dispatches of blur buffer's mip maps @@ -180,7 +180,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre cmdStream, m_DownsamplePipe, mipDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[mipLevel]).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_DownsampleDescSets[mipLevel])}, vkcv::PushConstants(0)); // image barrier between mips @@ -229,7 +229,7 @@ void BloomAndFlares::execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream cmdStream, m_UpsamplePipe, upsampleDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_UpsampleDescSets[mipLevel]).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_UpsampleDescSets[mipLevel])}, vkcv::PushConstants(0) ); // image barrier between mips @@ -268,7 +268,7 @@ void BloomAndFlares::execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStr cmdStream, m_LensFlarePipe, lensFeatureDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_LensFlareDescSet).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_LensFlareDescSet)}, vkcv::PushConstants(0)); // upsample dispatch @@ -301,7 +301,7 @@ void BloomAndFlares::execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStr cmdStream, m_UpsamplePipe, upsampleDispatchCount, - { vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_UpsampleLensFlareDescSets[i]).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_UpsampleLensFlareDescSets[i]) }, vkcv::PushConstants(0) ); // image barrier between mips @@ -348,7 +348,7 @@ void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStrea cmdStream, m_CompositePipe, compositeDispatchCount, - {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_CompositeDescSet).vulkanHandle)}, + {vkcv::DescriptorSetUsage(0, m_CompositeDescSet)}, pushConstants); p_Core->recordEndDebugLabel(cmdStream); diff --git a/projects/voxelization/src/ShadowMapping.cpp b/projects/voxelization/src/ShadowMapping.cpp index c2e1631098146c8ee82586995a5a9d21e6d85252..5ae7eb6047200b2cdb7a3ac38ce8512cdcaa3d53 100644 --- a/projects/voxelization/src/ShadowMapping.cpp +++ b/projects/voxelization/src/ShadowMapping.cpp @@ -296,7 +296,7 @@ void ShadowMapping::recordShadowMapRendering( cmdStream, m_depthToMomentsPipe, dispatchCount, - { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_depthToMomentsDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_depthToMomentsDescriptorSet) }, msaaPushConstants); m_corePtr->prepareImageForSampling(cmdStream, m_shadowMap.getHandle()); m_corePtr->recordEndDebugLabel(cmdStream); @@ -309,7 +309,7 @@ void ShadowMapping::recordShadowMapRendering( cmdStream, m_shadowBlurXPipe, dispatchCount, - { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_shadowBlurXDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_shadowBlurXDescriptorSet) }, vkcv::PushConstants(0)); m_corePtr->prepareImageForSampling(cmdStream, m_shadowMapIntermediate.getHandle()); @@ -319,7 +319,7 @@ void ShadowMapping::recordShadowMapRendering( cmdStream, m_shadowBlurYPipe, dispatchCount, - { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_shadowBlurYDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_shadowBlurYDescriptorSet) }, vkcv::PushConstants(0)); m_shadowMap.recordMipChainGeneration(cmdStream); m_corePtr->prepareImageForSampling(cmdStream, m_shadowMap.getHandle()); diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp index c5d48fb350226896546c1e9ae23bc5bff656aca4..faa03d38127d5a23c931fdef0470c1e24131d206 100644 --- a/projects/voxelization/src/Voxelization.cpp +++ b/projects/voxelization/src/Voxelization.cpp @@ -168,7 +168,7 @@ Voxelization::Voxelization( voxelIndexData.push_back(static_cast<uint16_t>(i)); } - const vkcv::DescriptorSetUsage voxelizationDescriptorUsage(0, m_corePtr->getDescriptorSet(m_visualisationDescriptorSet).vulkanHandle); + const vkcv::DescriptorSetUsage voxelizationDescriptorUsage(0, m_visualisationDescriptorSet); vkcv::ShaderProgram resetVoxelShader = loadVoxelResetShader(); @@ -259,7 +259,7 @@ void Voxelization::voxelizeMeshes( cmdStream, m_voxelResetPipe, resetVoxelDispatchCount, - { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_voxelResetDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_voxelResetDescriptorSet) }, voxelCountPushConstants); m_corePtr->recordBufferMemoryBarrier(cmdStream, m_voxelBuffer.getHandle()); m_corePtr->recordEndDebugLabel(cmdStream); @@ -270,8 +270,8 @@ void Voxelization::voxelizeMeshes( drawcalls.push_back(vkcv::DrawcallInfo( meshes[i], { - vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_voxelizationDescriptorSet).vulkanHandle), - vkcv::DescriptorSetUsage(1, m_corePtr->getDescriptorSet(perMeshDescriptorSets[i]).vulkanHandle) + vkcv::DescriptorSetUsage(0, m_voxelizationDescriptorSet), + vkcv::DescriptorSetUsage(1, perMeshDescriptorSets[i]) },1)); } @@ -299,7 +299,7 @@ void Voxelization::voxelizeMeshes( cmdStream, m_bufferToImagePipe, bufferToImageDispatchCount, - { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_bufferToImageDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_bufferToImageDescriptorSet) }, vkcv::PushConstants(0)); m_corePtr->recordImageMemoryBarrier(cmdStream, m_voxelImageIntermediate.getHandle()); @@ -318,7 +318,7 @@ void Voxelization::voxelizeMeshes( cmdStream, m_secondaryBouncePipe, bufferToImageDispatchCount, - { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_secondaryBounceDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, m_secondaryBounceDescriptorSet) }, vkcv::PushConstants(0)); m_voxelImage.recordMipChainGeneration(cmdStream); m_corePtr->recordImageMemoryBarrier(cmdStream, m_voxelImage.getHandle()); @@ -355,7 +355,7 @@ void Voxelization::renderVoxelVisualisation( const auto drawcall = vkcv::DrawcallInfo( vkcv::Mesh({}, nullptr, drawVoxelCount), - { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_visualisationDescriptorSet).vulkanHandle) },1); + { vkcv::DescriptorSetUsage(0, m_visualisationDescriptorSet) },1); m_corePtr->recordBeginDebugLabel(cmdStream, "Voxel visualisation", { 1, 1, 1, 1 }); m_corePtr->prepareImageForStorage(cmdStream, m_voxelImage.getHandle()); diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index 7157d2f625d5d86d0f916dc3c1d6e4f4c596b546..2245419f87d196e913ba27e8e78ffff73aab04b6 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -527,11 +527,11 @@ int main(int argc, const char** argv) { for (size_t i = 0; i < meshes.size(); i++) { drawcalls.push_back(vkcv::DrawcallInfo(meshes[i], { - vkcv::DescriptorSetUsage(0, core.getDescriptorSet(forwardShadingDescriptorSet).vulkanHandle), - vkcv::DescriptorSetUsage(1, core.getDescriptorSet(perMeshDescriptorSets[i]).vulkanHandle) })); + vkcv::DescriptorSetUsage(0, forwardShadingDescriptorSet), + vkcv::DescriptorSetUsage(1, perMeshDescriptorSets[i]) })); prepassDrawcalls.push_back(vkcv::DrawcallInfo(meshes[i], { - vkcv::DescriptorSetUsage(0, core.getDescriptorSet(prepassDescriptorSet).vulkanHandle), - vkcv::DescriptorSetUsage(1, core.getDescriptorSet(perMeshDescriptorSets[i]).vulkanHandle) })); + vkcv::DescriptorSetUsage(0, prepassDescriptorSet), + vkcv::DescriptorSetUsage(1, perMeshDescriptorSets[i]) })); } vkcv::SamplerHandle voxelSampler = core.createSampler( @@ -859,7 +859,7 @@ int main(int argc, const char** argv) { cmdStream, resolvePipeline, fulsscreenDispatchCount, - { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(resolveDescriptorSet).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, resolveDescriptorSet) }, vkcv::PushConstants(0)); core.recordImageMemoryBarrier(cmdStream, resolvedColorBuffer); @@ -882,9 +882,7 @@ int main(int argc, const char** argv) { cmdStream, tonemappingPipeline, fulsscreenDispatchCount, - { vkcv::DescriptorSetUsage(0, core.getDescriptorSet( - tonemappingDescriptorSet - ).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, tonemappingDescriptorSet) }, vkcv::PushConstants(0) ); @@ -920,9 +918,7 @@ int main(int argc, const char** argv) { cmdStream, postEffectsPipeline, fulsscreenDispatchCount, - { vkcv::DescriptorSetUsage(0, core.getDescriptorSet( - postEffectsDescriptorSet - ).vulkanHandle) }, + { vkcv::DescriptorSetUsage(0, postEffectsDescriptorSet) }, timePushConstants ); core.recordEndDebugLabel(cmdStream); diff --git a/projects/wobble_bobble/.gitignore b/projects/wobble_bobble/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7ed07ed409373206a95d74e6dbdc27a4cb391fea --- /dev/null +++ b/projects/wobble_bobble/.gitignore @@ -0,0 +1 @@ +wobble_bobble diff --git a/projects/wobble_bobble/CMakeLists.txt b/projects/wobble_bobble/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..9842b13b1038d61414de5c2cf2a9107604b6fe16 --- /dev/null +++ b/projects/wobble_bobble/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.16) +project(wobble_bobble) + +# setting c++ standard for the project +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# this should fix the execution path to load local files from the project +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +# adding source files to the project +add_executable(wobble_bobble + src/main.cpp) + +fix_project(wobble_bobble) + +# including headers of dependencies and the VkCV framework +target_include_directories(wobble_bobble SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_camera_include} ${vkcv_gui_include} ${vkcv_shader_compiler_include}) + +# linking with libraries from all dependencies and the VkCV framework +target_link_libraries(wobble_bobble vkcv vkcv_camera vkcv_gui vkcv_shader_compiler) diff --git a/projects/wobble_bobble/shaders/.gitignore b/projects/wobble_bobble/shaders/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/projects/wobble_bobble/shaders/grid.frag b/projects/wobble_bobble/shaders/grid.frag new file mode 100644 index 0000000000000000000000000000000000000000..8eb2fbc2173bbddb5bdc44c52ce81d2e5d52d389 --- /dev/null +++ b/projects/wobble_bobble/shaders/grid.frag @@ -0,0 +1,30 @@ +#version 450 + +layout(location = 0) in vec2 passPos; +layout(location = 1) in vec3 passVelocity; +layout(location = 2) in float passMass; + +layout(location = 0) out vec3 outColor; + +void main() { + if (passMass <= 0.0f) { + discard; + } + + const float value = length(passPos); + + float z = sqrt(0.25 - value * value); + + if (value < 0.5f) { + vec3 surface = vec3(passPos.x + 0.5f, passPos.y + 0.5f, z * 2.0f); + vec3 velocity = vec3(0.5f); + + if (length(passVelocity) > 0.0f) { + velocity = vec3(0.5f) + 0.5f * normalize(passVelocity.xyz); + } + + outColor = velocity; + } else { + discard; + } +} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/grid.vert b/projects/wobble_bobble/shaders/grid.vert new file mode 100644 index 0000000000000000000000000000000000000000..54de3f3e1da43e3ea3d018e5c54003b83e055c4c --- /dev/null +++ b/projects/wobble_bobble/shaders/grid.vert @@ -0,0 +1,58 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable + +#include "particle.inc" + +layout(set=0, binding=0) uniform texture3D gridImage; +layout(set=0, binding=1) uniform sampler gridSampler; + +layout(set=0, binding=2) uniform simulationBlock { + Simulation simulation; +}; + +layout(location = 0) in vec2 vertexPos; + +layout(location = 0) out vec2 passPos; +layout(location = 1) out vec3 passVelocity; +layout(location = 2) out float passMass; + +layout( push_constant ) uniform constants{ + mat4 mvp; +}; + +ivec3 actual_mod(ivec3 x, ivec3 y) { + return x - y * (x/y); +} + +void main() { + ivec3 gridResolution = textureSize(sampler3D(gridImage, gridSampler), 0); + + ivec3 gridID = ivec3( + gl_InstanceIndex, + gl_InstanceIndex / gridResolution.x, + gl_InstanceIndex / gridResolution.x / gridResolution.y + ); + + gridID = actual_mod(gridID, gridResolution); + + vec3 position = (vec3(gridID) + vec3(0.5f)) / gridResolution; + + vec3 size = vec3(1.0f) / vec3(gridResolution); + float volume = size.x * size.y * size.z; + float radius = cube_radius(volume); + + vec4 gridData = texture(sampler3D(gridImage, gridSampler), position); + + float mass = gridData.w; + float density = mass / volume; + + float alpha = clamp(density / simulation.density, 0.0f, 1.0f); + + passPos = vertexPos; + passVelocity = gridData.xyz; + passMass = mass; + + // align voxel to face camera + gl_Position = mvp * vec4(position, 1); // transform position into projected view space + gl_Position.xy += vertexPos * (radius * 2.0f) * alpha; // move position directly in view space +} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/init_particle_weights.comp b/projects/wobble_bobble/shaders/init_particle_weights.comp new file mode 100644 index 0000000000000000000000000000000000000000..9b821e88fc7cc3fcea87b7eb6de0f8f6d629d911 --- /dev/null +++ b/projects/wobble_bobble/shaders/init_particle_weights.comp @@ -0,0 +1,43 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable + +layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; + +#include "particle.inc" + +layout(set=0, binding=0, std430) restrict buffer particleBuffer { + Particle particles []; +}; + +layout(set=1, binding=0) uniform texture3D gridImage; +layout(set=1, binding=1) uniform sampler gridSampler; + +void main() { + if (gl_GlobalInvocationID.x < particles.length()) { + ParticleMinimal minimal = particles[gl_GlobalInvocationID.x].minimal; + + minimal.weight_sum = 1.0f; + + ivec3 gridResolution = textureSize(sampler3D(gridImage, gridSampler), 0); + ivec3 gridWindow = ivec3(minimal.size * 2.0f * gridResolution); + + float weight_sum = 0.0f; + + int i, j, k; + + for (i = -gridWindow.x; i <= gridWindow.x; i++) { + for (j = -gridWindow.y; j <= gridWindow.y; j++) { + for (k = -gridWindow.z; k <= gridWindow.z; k++) { + vec3 offset = vec3(i, j, k) / gridResolution; + vec3 voxel = minimal.position + offset; + + weight_sum += voxel_particle_weight(voxel, minimal); + } + } + } + + if (weight_sum > 0.0f) { + particles[gl_GlobalInvocationID.x].minimal.weight_sum = weight_sum; + } + } +} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/lines.frag b/projects/wobble_bobble/shaders/lines.frag new file mode 100644 index 0000000000000000000000000000000000000000..37d79d30d2ce751a59b1b467764b2fe464aa5c17 --- /dev/null +++ b/projects/wobble_bobble/shaders/lines.frag @@ -0,0 +1,7 @@ +#version 450 + +layout(location = 0) out vec3 outColor; + +void main() { + outColor = vec3(1.0f); +} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/lines.vert b/projects/wobble_bobble/shaders/lines.vert new file mode 100644 index 0000000000000000000000000000000000000000..b8e3b01c67986156ad980899697ffea05409b752 --- /dev/null +++ b/projects/wobble_bobble/shaders/lines.vert @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) in vec3 vertexPos; + +layout( push_constant ) uniform constants{ + mat4 mvp; +}; + +void main() { + gl_Position = mvp * vec4(vertexPos, 1); +} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/particle.frag b/projects/wobble_bobble/shaders/particle.frag new file mode 100644 index 0000000000000000000000000000000000000000..81c0a3594359e816a28b5e3f0301b47ce74a3cd7 --- /dev/null +++ b/projects/wobble_bobble/shaders/particle.frag @@ -0,0 +1,18 @@ +#version 450 + +layout(location = 0) in vec2 passPos; +layout(location = 1) in float passMass; + +layout(location = 0) out vec3 outColor; + +void main() { + const float value = length(passPos); + + float z = sqrt(0.25 - value * value); + + if (value < 0.5f) { + outColor = vec3(passPos.x + 0.5f, passPos.y + 0.5f, z * 2.0f); + } else { + discard; + } +} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/particle.inc b/projects/wobble_bobble/shaders/particle.inc new file mode 100644 index 0000000000000000000000000000000000000000..a622485eab5bbcafdc51c030281e53b1cc1c5f11 --- /dev/null +++ b/projects/wobble_bobble/shaders/particle.inc @@ -0,0 +1,118 @@ +#ifndef PARTICLE_INC +#define PARTICLE_INC + +#define EPSILON 0.00000001f + +struct ParticleMinimal { + vec3 position; + float size; + vec3 velocity; + float mass; + + vec3 pad; + float weight_sum; +}; + +struct Particle { + ParticleMinimal minimal; + mat4 deformation; + mat4 mls; +}; + +#define SIM_FORM_SPHERE 0 +#define SIM_FORM_CUBE 1 + +#define SIM_TYPE_HYPERELASTIC 0 +#define SIM_TYPE_FLUID 1 + +#define SIM_MODE_RANDOM 0 +#define SIM_MODE_ORDERED 1 + +struct Simulation { + float density; + float size; + float lame1; + float lame2; + + int form; + int type; + float K; + float E; + + float gamma; + int mode; + float gravity; + int count; +}; + +const float PI = 3.1415926535897932384626433832795; + +float sphere_volume(float radius) { + return 4.0f * (radius * radius * radius) * PI / 3.0f; +} + +float sphere_radius(float volume) { + return pow(volume * 3.0f / 4.0f / PI, 1.0f / 3.0f); +} + +float cube_volume(float radius) { + return 8.0f * (radius * radius * radius); +} + +float cube_radius(float volume) { + return pow(volume / 8.0f, 1.0f / 3.0f); +} + +float weight_A(float x) { + return max(1.0f - x, 0.0f); +} + +float weight_B(float x) { + if (x < 0.5f) { + return 0.75f - x * x; + } else + if (x < 1.5f) { + float y = (1.5f - x); + return 0.5f * y * y; + } else { + return 0.0f; + } +} + +float weight_C(float x) { + if (x < 1.0f) { + return (0.5f * x - 1.0f) * x*x + 2.0f / 3.0f; + } else + if (x < 2.0f) { + float y = (2.0f - x); + return 0.5f / 3.0f * y * y * y; + } else { + return 0.0f; + } +} + +float voxel_particle_weight(vec3 voxel, ParticleMinimal particle) { + vec3 delta = abs(particle.position - voxel) / particle.size; + + if (any(isnan(delta)) || any(isinf(delta))) { + return 0.0f; + } + + vec3 weight = vec3( + weight_C(delta.x), + weight_C(delta.y), + weight_C(delta.z) + ); + + float result = ( + weight.x * weight.y * weight.z + ) / particle.weight_sum; + + if ((isnan(result)) || (isinf(result))) { + return 0.0f; + } else { + return result; + } +} + +#endif // PARTICLE_INC \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/particle.vert b/projects/wobble_bobble/shaders/particle.vert new file mode 100644 index 0000000000000000000000000000000000000000..a8f697e79eacba361d80b5858405add675e761bb --- /dev/null +++ b/projects/wobble_bobble/shaders/particle.vert @@ -0,0 +1,31 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable + +#include "particle.inc" + +layout(set=0, binding=0, std430) readonly buffer particleBuffer { + Particle particles []; +}; + +layout(location = 0) in vec2 vertexPos; + +layout(location = 0) out vec2 passPos; +layout(location = 1) out float passMass; + +layout( push_constant ) uniform constants{ + mat4 mvp; +}; + +void main() { + vec3 position = particles[gl_InstanceIndex].minimal.position; + float size = particles[gl_InstanceIndex].minimal.size; + + float mass = particles[gl_InstanceIndex].minimal.mass; + + passPos = vertexPos; + passMass = mass; + + // align particle to face camera + gl_Position = mvp * vec4(position, 1); // transform position into projected view space + gl_Position.xy += vertexPos * size * 2.0f; // move position directly in view space +} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/transform_particles_to_grid.comp b/projects/wobble_bobble/shaders/transform_particles_to_grid.comp new file mode 100644 index 0000000000000000000000000000000000000000..1be18c41303ab2208c8cb4a8c33f41b350315d63 --- /dev/null +++ b/projects/wobble_bobble/shaders/transform_particles_to_grid.comp @@ -0,0 +1,101 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable + +layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; + +#include "particle.inc" + +layout(set=0, binding=0, std430) readonly buffer particleBuffer { + Particle particles []; +}; + +layout(set=1, binding=0) uniform simulationBlock { + Simulation simulation; +}; + +layout(set=2, binding=0, rgba16f) restrict writeonly uniform image3D gridImage; + +layout( push_constant ) uniform constants { + float t; + float dt; + float speedfactor; +}; + +#define SHARED_PARTICLES_BATCH_SIZE 64 + +shared ParticleMinimal shared_particles [SHARED_PARTICLES_BATCH_SIZE]; + +void main() { + const vec3 position = (vec3(gl_GlobalInvocationID) + vec3(0.5f)) / imageSize(gridImage); + + float dts = dt * speedfactor; + + vec4 gridValue = vec4(0.0f); + + uint offset = 0; + + for (offset = 0; offset < particles.length(); offset += SHARED_PARTICLES_BATCH_SIZE) { + uint localOffset = offset + gl_LocalInvocationIndex; + + if (localOffset < particles.length()) { + shared_particles[gl_LocalInvocationIndex] = particles[localOffset].minimal; + + shared_particles[gl_LocalInvocationIndex].pad = ( + mat3(particles[localOffset].mls) * + (position - shared_particles[gl_LocalInvocationIndex].position) + ) + ( + shared_particles[gl_LocalInvocationIndex].velocity * + shared_particles[gl_LocalInvocationIndex].mass + ); + } else { + shared_particles[gl_LocalInvocationIndex].position = vec3(0.0f); + shared_particles[gl_LocalInvocationIndex].size = 0.0f; + shared_particles[gl_LocalInvocationIndex].velocity = vec3(0.0f); + shared_particles[gl_LocalInvocationIndex].mass = 0.0f; + + shared_particles[gl_LocalInvocationIndex].pad = vec3(0.0f); + shared_particles[gl_LocalInvocationIndex].weight_sum = 1.0f; + } + + barrier(); + memoryBarrierShared(); + + for (uint i = 0; i < SHARED_PARTICLES_BATCH_SIZE; i++) { + float weight = voxel_particle_weight(position, shared_particles[i]); + + gridValue += vec4( + shared_particles[i].pad * weight, + shared_particles[i].mass * weight + ); + } + + barrier(); + memoryBarrierShared(); + } + + if (any(isnan(gridValue.xyz)) || any(isinf(gridValue.xyz))) { + gridValue.xyz = vec3(0.0f); + } + + gridValue.xyz += vec3(0.0f, -simulation.gravity * dts * gridValue.w, 0.0f); + + bvec3 lowerID = lessThanEqual(gl_GlobalInvocationID, ivec3(0)); + bvec3 negativeVelocity = lessThan(gridValue.xyz, vec3(0.0f)); + + bvec3 greaterID = greaterThanEqual(gl_GlobalInvocationID + ivec3(1), imageSize(gridImage)); + bvec3 positiveVelocity = greaterThan(gridValue.xyz, vec3(0.0f)); + + bvec3 collision = bvec3( + (lowerID.x && negativeVelocity.x) || (greaterID.x && positiveVelocity.x), + (lowerID.y && negativeVelocity.y) || (greaterID.y && positiveVelocity.y), + (lowerID.z && negativeVelocity.z) || (greaterID.z && positiveVelocity.z) + ); + + gridValue.xyz = mix(gridValue.xyz, -gridValue.xyz, collision); + + imageStore( + gridImage, + ivec3(gl_GlobalInvocationID), + gridValue + ); +} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/update_particle_velocities.comp b/projects/wobble_bobble/shaders/update_particle_velocities.comp new file mode 100644 index 0000000000000000000000000000000000000000..4420bc9575bcde4d04d7d4f5531d0091362285c2 --- /dev/null +++ b/projects/wobble_bobble/shaders/update_particle_velocities.comp @@ -0,0 +1,161 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_control_flow_attributes : enable + +layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; + +#include "particle.inc" + +layout(set=0, binding=0, std430) restrict buffer particleBuffer { + Particle particles []; +}; + +layout(set=1, binding=0) uniform simulationBlock { + Simulation simulation; +}; + +layout(set=2, binding=0) uniform texture3D gridImage; +layout(set=2, binding=1) uniform sampler gridSampler; + +layout( push_constant ) uniform constants { + float t; + float dt; + float speedfactor; +}; + +void main() { + float dts = dt * speedfactor; + + if (gl_GlobalInvocationID.x < particles.length()) { + Particle particle = particles[gl_GlobalInvocationID.x]; + + vec3 position = particle.minimal.position; + float size = particle.minimal.size; + float mass = particle.minimal.mass; + + ivec3 gridResolution = textureSize(sampler3D(gridImage, gridSampler), 0); + ivec3 gridWindow = ivec3(size * 2.0f * gridResolution); + + mat3 affine_D = mat3(0.0f); + mat3 affine_B = mat3(0.0f); + + vec3 velocity_pic = vec3(0.0f); + vec3 velocity_flip = vec3(particle.minimal.velocity); + + int i, j, k; + + for (i = -gridWindow.x; i <= gridWindow.x; i++) { + for (j = -gridWindow.y; j <= gridWindow.y; j++) { + for (k = -gridWindow.z; k <= gridWindow.z; k++) { + vec3 offset = vec3(i, j, k) / gridResolution; + vec3 voxel = position + offset; + + vec4 gridSample = texture(sampler3D(gridImage, gridSampler), voxel); + + float weight = voxel_particle_weight(voxel, particle.minimal); + vec3 velocity = gridSample.xyz * weight / gridSample.w; + + if (any(isnan(velocity)) || any(isinf(velocity))) { + velocity = vec3(0.0f); + } + + affine_D += outerProduct(weight * offset, offset); + affine_B += outerProduct(velocity, offset); + + velocity_pic += velocity; + } + } + } + + mat3 mls_Q = mat3(0.0f); + mat3 affine_C = mat3(0.0f); + + mat3 F = mat3(particle.deformation); + + mat3 D_inv = inverse(affine_D); + float D_det = determinant(D_inv); + + if ((isnan(D_det)) || (isinf(D_det))) { + D_inv = mat3(0.0f); + } else { + D_inv *= min(abs(D_det), 1.0f / EPSILON) / abs(D_det); + } + + float J = max(determinant(F), EPSILON); + float volume = sphere_volume(size); + + mat3 stress = mat3(0.0f); + + switch (simulation.type) { + case SIM_TYPE_HYPERELASTIC: + mat3 F_T = transpose(F); + mat3 F_T_inv = inverse(F_T); + + mat3 P_term_0 = simulation.lame2 * (F - F_T_inv); + mat3 P_term_1 = simulation.lame1 * log(J) * F_T_inv; + + mat3 P = P_term_0 + P_term_1; + + stress = P * F_T; + break; + case SIM_TYPE_FLUID: + float pressure = simulation.K * (1.0f / pow(J, simulation.gamma) - 1.0f); + + stress = mat3(-pressure * J); + break; + default: + break; + } + + mls_Q -= dts * volume * stress * D_inv; + + affine_C = affine_B * D_inv; + mls_Q += affine_C * mass; + + F = (mat3(1.0f) + dts * affine_C) * F; + + position = position + velocity_pic * dts; + + const float gridRange = (1.0f - 2.0f * size); + + for (uint i = 0; i < 3; i++) { + if (position[i] - size < 0.0f) { + float a = (size - position[i]) / gridRange; + int b = int(floor(a)); + + a = (a - b) * gridRange; + + if (b % 2 == 0) { + position[i] = size + a; + } else { + position[i] = 1.0f - size - a; + } + + if ((velocity_pic[i] < 0.0f) == (b % 2 == 0)) { + velocity_pic[i] *= -1.0f; + } + } else + if (position[i] + size > 1.0f) { + float a = (position[i] + size - 1.0f) / gridRange; + int b = int(floor(a)); + + a = (a - b) * gridRange; + + if (b % 2 == 0) { + position[i] = 1.0f - size - a; + } else { + position[i] = size + a; + } + + if ((velocity_pic[i] > 0.0f) == (b % 2 == 0)) { + velocity_pic[i] *= -1.0f; + } + } + } + + particles[gl_GlobalInvocationID.x].minimal.position = position; + particles[gl_GlobalInvocationID.x].minimal.velocity = velocity_pic; + particles[gl_GlobalInvocationID.x].deformation = mat4(F); + particles[gl_GlobalInvocationID.x].mls = mat4(mls_Q); + } +} \ No newline at end of file diff --git a/projects/wobble_bobble/src/main.cpp b/projects/wobble_bobble/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..96c367f2f8e22ac65bf6ccf6a5c09eb238b5604d --- /dev/null +++ b/projects/wobble_bobble/src/main.cpp @@ -0,0 +1,905 @@ + +#include <vkcv/Core.hpp> +#include <vkcv/camera/CameraManager.hpp> +#include <vkcv/gui/GUI.hpp> +#include <vkcv/shader/GLSLCompiler.hpp> + +#include <random> + +struct Particle { + glm::vec3 position; + float size; + glm::vec3 velocity; + float mass; + + glm::vec3 pad; + float weight_sum; + + glm::mat4 deformation; + glm::mat4 mls; +}; + +#define SIM_FORM_SPHERE 0 +#define SIM_FORM_CUBE 1 + +#define SIM_TYPE_HYPERELASTIC 0 +#define SIM_TYPE_FLUID 1 + +#define SIM_MODE_RANDOM 0 +#define SIM_MODE_ORDERED 1 + +struct Simulation { + float density; + float size; + float lame1; + float lame2; + + int form; + int type; + float K; + float E; + + float gamma; + int mode; + float gravity; + int count; +}; + +struct Physics { + float t; + float dt; + float speedfactor; +}; + +float sphere_volume(float radius) { + return 4.0f * (radius * radius * radius) * M_PI / 3.0f; +} + +float sphere_radius(float volume) { + return std::pow(volume * 3.0f / 4.0f / M_PI, 1.0f / 3.0f); +} + +float cube_volume(float radius) { + return 8.0f * (radius * radius * radius); +} + +float cube_radius(float volume) { + return std::pow(volume / 8.0f, 1.0f / 3.0f); +} + +std::random_device random_dev; +std::uniform_int_distribution<int> dist(0, RAND_MAX); + +float randomFloat(float min, float max) { + return min + (max - min) * dist(random_dev) / static_cast<float>(RAND_MAX); +} + +float mod(float x, float y) { + return x - std::floor(x / y) * y; +} + +void distributeParticlesCube(Particle *particles, size_t count, const glm::vec3& center, float radius, + float mass, const glm::vec3& velocity, bool random) { + const float side = cube_radius(static_cast<float>(count)) * 2.0f; + + float volume = 0.0f; + + for (size_t i = 0; i < count; i++) { + glm::vec3 offset; + + if (random) { + offset.x = randomFloat(-1.0f, +1.0f); + offset.y = randomFloat(-1.0f, +1.0f); + offset.z = randomFloat(-1.0f, +1.0f); + } else { + const float s = static_cast<float>(i) + 0.5f; + + offset.x = 2.0f * mod(s, side) / side - 1.0f; + offset.y = 2.0f * mod(s / side, side) / side - 1.0f; + offset.z = 2.0f * mod(s / side / side, side) / side - 1.0f; + } + + offset *= radius; + + float size = 0.0f; + + if (random) { + const float ax = std::abs(offset.x); + const float ay = std::abs(offset.y); + const float az = std::abs(offset.z); + + const float a = std::max(std::max(ax, ay), az); + + size = (radius - a); + } else { + size = 2.0f * radius / side; + } + + particles[i].position = center + offset; + particles[i].size = size; + particles[i].velocity = velocity; + + volume += cube_volume(size); + } + + for (size_t i = 0; i < count; i++) { + particles[i].mass = (mass * cube_volume(particles[i].size) / volume); + particles[i].deformation = glm::mat4(1.0f); + + particles[i].pad = glm::vec3(0.0f); + particles[i].weight_sum = 1.0f; + + particles[i].mls = glm::mat4(0.0f); + } +} + +void distributeParticlesSphere(Particle *particles, size_t count, const glm::vec3& center, float radius, + float mass, const glm::vec3& velocity, bool random) { + const float side = sphere_radius(static_cast<float>(count)) * 2.0f; + + float volume = 0.0f; + + for (size_t i = 0; i < count; i++) { + glm::vec3 offset; + + if (random) { + offset.x = randomFloat(-1.0f, +1.0f); + offset.y = randomFloat(-1.0f, +1.0f); + offset.z = randomFloat(-1.0f, +1.0f); + + if (glm::length(offset) > 0.0f) + offset = glm::normalize(offset); + + offset *= randomFloat(0.0f, 1.0f); + } else { + const float range = 0.5f * side; + const float s = static_cast<float>(i) + 0.5f; + + float a = mod(s, range) / range; + float b = mod(s / range, M_PI * range); + float c = mod(s / range / M_PI / range, M_PI * range * 2.0f); + + offset.x = a * std::sin(c) * std::sin(b); + offset.y = a * std::cos(b); + offset.z = a * std::cos(c) * std::sin(b); + } + + offset *= radius; + + float size = 0.0f; + + if (random) { + size = (radius - glm::length(offset)); + } else { + size = 2.0f * radius / side; + } + + particles[i].position = center + offset; + particles[i].size = size; + particles[i].velocity = velocity; + + volume += sphere_volume(size); + } + + // Keep the same densitiy as planned! + mass *= (volume / sphere_volume(radius)); + + for (size_t i = 0; i < count; i++) { + particles[i].mass = (mass * sphere_volume(particles[i].size) / volume); + particles[i].deformation = glm::mat4(1.0f); + + particles[i].pad = glm::vec3(0.0f); + particles[i].weight_sum = 1.0f; + + particles[i].mls = glm::mat4(0.0f); + } +} + +vkcv::ComputePipelineHandle createComputePipeline(vkcv::Core& core, vkcv::shader::GLSLCompiler& compiler, + const std::string& path, + std::vector<vkcv::DescriptorSetHandle>& descriptorSets) { + vkcv::ShaderProgram shaderProgram; + + compiler.compile( + vkcv::ShaderStage::COMPUTE, + path, + [&shaderProgram](vkcv::ShaderStage stage, const std::filesystem::path& path) { + shaderProgram.addShader(stage, path); + } + ); + + const auto& descriptors = shaderProgram.getReflectedDescriptors(); + + size_t count = 0; + + for (const auto& descriptor : descriptors) { + if (descriptor.first >= count) { + count = (descriptor.first + 1); + } + } + + std::vector<vkcv::DescriptorSetLayoutHandle> descriptorSetLayouts; + + descriptorSetLayouts.resize(count); + descriptorSets.resize(count); + + for (const auto& descriptor : descriptors) { + descriptorSetLayouts[descriptor.first] = core.createDescriptorSetLayout(descriptor.second); + descriptorSets[descriptor.first] = core.createDescriptorSet(descriptorSetLayouts[descriptor.first]); + } + + vkcv::ComputePipelineConfig config { + shaderProgram, + descriptorSetLayouts + }; + + return core.createComputePipeline(config); +} + +vkcv::BufferHandle resetParticles(vkcv::Core& core, size_t count, const glm::vec3& velocity, + float density, float size, int form, int mode) { + vkcv::Buffer<Particle> particles = core.createBuffer<Particle>( + vkcv::BufferType::STORAGE, + count + ); + + std::vector<Particle> particles_vec (particles.getCount()); + + switch (form) { + case SIM_FORM_SPHERE: + distributeParticlesSphere( + particles_vec.data(), + particles_vec.size(), + glm::vec3(0.5f), + size, + density * sphere_volume(size), + velocity, + (mode == 0) + ); + break; + case SIM_FORM_CUBE: + distributeParticlesCube( + particles_vec.data(), + particles_vec.size(), + glm::vec3(0.5f), + size, + density * sphere_volume(size), + velocity, + (mode == 0) + ); + break; + default: + break; + } + + particles.fill(particles_vec); + return particles.getHandle(); +} + +int main(int argc, const char **argv) { + const char* applicationName = "Wobble Bobble"; + + 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}, + features + ); + vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); + vkcv::Window& window = core.getWindow(windowHandle); + vkcv::camera::CameraManager cameraManager(window); + + vkcv::gui::GUI gui (core, windowHandle); + + uint32_t trackballIdx = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); + cameraManager.getCamera(trackballIdx).setCenter(glm::vec3(0.5f, 0.5f, 0.5f)); // set camera to look at the center of the particle volume + cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); + + auto swapchainExtent = core.getSwapchain(windowHandle).getExtent(); + + vkcv::ImageHandle depthBuffer = core.createImage( + vk::Format::eD32Sfloat, + swapchainExtent.width, + swapchainExtent.height + ).getHandle(); + + vkcv::Image grid = core.createImage( + vk::Format::eR16G16B16A16Sfloat, + 32, + 32, + 32, + false, + true + ); + + vkcv::SamplerHandle gridSampler = core.createSampler( + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerMipmapMode::NEAREST, + vkcv::SamplerAddressMode::CLAMP_TO_BORDER, + 0.0f, + vkcv::SamplerBorderColor::FLOAT_ZERO_TRANSPARENT + ); + + vkcv::Buffer<Simulation> simulation = core.createBuffer<Simulation>( + vkcv::BufferType::UNIFORM, 1, vkcv::BufferMemoryType::HOST_VISIBLE + ); + + Simulation* sim = simulation.map(); + + glm::vec3 initialVelocity (0.0f, 0.1f, 0.0f); + + sim->density = 2500.0f; + sim->size = 0.1f; + sim->lame1 = 10.0f; + sim->lame2 = 20.0f; + sim->form = SIM_FORM_SPHERE; + sim->type = SIM_TYPE_HYPERELASTIC; + sim->K = 2.2f; + sim->E = 35.0f; + sim->gamma = 1.330f; + sim->mode = SIM_MODE_RANDOM; + sim->gravity = 9.81f; + sim->count = 1024; + + vkcv::BufferHandle particlesHandle = resetParticles( + core, + sim->count, + initialVelocity, + sim->density, + sim->size, + sim->form, + sim->mode + ); + + vkcv::shader::GLSLCompiler compiler; + + std::vector<vkcv::DescriptorSetHandle> initParticleWeightsSets; + vkcv::ComputePipelineHandle initParticleWeightsPipeline = createComputePipeline( + core, compiler, + "shaders/init_particle_weights.comp", + initParticleWeightsSets + ); + + { + vkcv::DescriptorWrites writes; + writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particlesHandle)); + core.writeDescriptorSet(initParticleWeightsSets[0], writes); + } + + { + vkcv::DescriptorWrites writes; + writes.sampledImageWrites.push_back(vkcv::SampledImageDescriptorWrite(0, grid.getHandle())); + writes.samplerWrites.push_back(vkcv::SamplerDescriptorWrite(1, gridSampler)); + core.writeDescriptorSet(initParticleWeightsSets[1], writes); + } + + std::vector<vkcv::DescriptorSetHandle> transformParticlesToGridSets; + vkcv::ComputePipelineHandle transformParticlesToGridPipeline = createComputePipeline( + core, compiler, + "shaders/transform_particles_to_grid.comp", + transformParticlesToGridSets + ); + + { + vkcv::DescriptorWrites writes; + writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particlesHandle)); + core.writeDescriptorSet(transformParticlesToGridSets[0], writes); + } + + { + vkcv::DescriptorWrites writes; + writes.uniformBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, simulation.getHandle())); + core.writeDescriptorSet(transformParticlesToGridSets[1], writes); + } + + { + vkcv::DescriptorWrites writes; + writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(0, grid.getHandle())); + core.writeDescriptorSet(transformParticlesToGridSets[2], writes); + } + + std::vector<vkcv::DescriptorSetHandle> updateParticleVelocitiesSets; + vkcv::ComputePipelineHandle updateParticleVelocitiesPipeline = createComputePipeline( + core, compiler, + "shaders/update_particle_velocities.comp", + updateParticleVelocitiesSets + ); + + { + vkcv::DescriptorWrites writes; + writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particlesHandle)); + core.writeDescriptorSet(updateParticleVelocitiesSets[0], writes); + } + + { + vkcv::DescriptorWrites writes; + writes.uniformBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, simulation.getHandle())); + core.writeDescriptorSet(updateParticleVelocitiesSets[1], writes); + } + + { + vkcv::DescriptorWrites writes; + writes.sampledImageWrites.push_back(vkcv::SampledImageDescriptorWrite(0, grid.getHandle())); + writes.samplerWrites.push_back(vkcv::SamplerDescriptorWrite(1, gridSampler)); + core.writeDescriptorSet(updateParticleVelocitiesSets[2], writes); + } + + vkcv::ShaderProgram gfxProgramGrid; + + compiler.compileProgram(gfxProgramGrid, { + { vkcv::ShaderStage::VERTEX, "shaders/grid.vert" }, + { vkcv::ShaderStage::FRAGMENT, "shaders/grid.frag" } + }, nullptr); + + vkcv::ShaderProgram gfxProgramParticles; + + compiler.compileProgram(gfxProgramParticles, { + { vkcv::ShaderStage::VERTEX, "shaders/particle.vert" }, + { vkcv::ShaderStage::FRAGMENT, "shaders/particle.frag" } + }, nullptr); + + vkcv::ShaderProgram gfxProgramLines; + + compiler.compileProgram(gfxProgramLines, { + { vkcv::ShaderStage::VERTEX, "shaders/lines.vert" }, + { vkcv::ShaderStage::FRAGMENT, "shaders/lines.frag" } + }, nullptr); + + vkcv::PassConfig passConfigGrid ({ + vkcv::AttachmentDescription( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + core.getSwapchain(windowHandle).getFormat() + ), + vkcv::AttachmentDescription( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + vk::Format::eD32Sfloat + ) + }); + + vkcv::PassConfig passConfigParticles ({ + vkcv::AttachmentDescription( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + core.getSwapchain(windowHandle).getFormat() + ), + vkcv::AttachmentDescription( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + vk::Format::eD32Sfloat + ) + }); + + vkcv::PassConfig passConfigLines ({ + vkcv::AttachmentDescription( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::LOAD, + core.getSwapchain(windowHandle).getFormat() + ), + vkcv::AttachmentDescription( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::LOAD, + vk::Format::eD32Sfloat + ) + }); + + vkcv::DescriptorSetLayoutHandle gfxSetLayoutGrid = core.createDescriptorSetLayout( + gfxProgramGrid.getReflectedDescriptors().at(0) + ); + + vkcv::DescriptorSetHandle gfxSetGrid = core.createDescriptorSet(gfxSetLayoutGrid); + + { + vkcv::DescriptorWrites writes; + writes.sampledImageWrites.push_back(vkcv::SampledImageDescriptorWrite(0, grid.getHandle())); + writes.samplerWrites.push_back(vkcv::SamplerDescriptorWrite(1, gridSampler)); + writes.uniformBufferWrites.push_back(vkcv::BufferDescriptorWrite(2, simulation.getHandle())); + core.writeDescriptorSet(gfxSetGrid, writes); + } + + vkcv::DescriptorSetLayoutHandle gfxSetLayoutParticles = core.createDescriptorSetLayout( + gfxProgramParticles.getReflectedDescriptors().at(0) + ); + + vkcv::DescriptorSetHandle gfxSetParticles = core.createDescriptorSet(gfxSetLayoutParticles); + + { + vkcv::DescriptorWrites writes; + writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particlesHandle)); + core.writeDescriptorSet(gfxSetParticles, writes); + } + + vkcv::PassHandle gfxPassGrid = core.createPass(passConfigGrid); + vkcv::PassHandle gfxPassParticles = core.createPass(passConfigParticles); + vkcv::PassHandle gfxPassLines = core.createPass(passConfigLines); + + vkcv::VertexLayout vertexLayoutGrid ({ + vkcv::VertexBinding(0, gfxProgramGrid.getVertexAttachments()) + }); + + vkcv::GraphicsPipelineConfig gfxPipelineConfigGrid; + gfxPipelineConfigGrid.m_ShaderProgram = gfxProgramGrid; + gfxPipelineConfigGrid.m_Width = windowWidth; + gfxPipelineConfigGrid.m_Height = windowHeight; + gfxPipelineConfigGrid.m_PassHandle = gfxPassGrid; + gfxPipelineConfigGrid.m_VertexLayout = vertexLayoutGrid; + gfxPipelineConfigGrid.m_DescriptorLayouts = { gfxSetLayoutGrid }; + gfxPipelineConfigGrid.m_UseDynamicViewport = true; + + vkcv::VertexLayout vertexLayoutParticles ({ + vkcv::VertexBinding(0, gfxProgramParticles.getVertexAttachments()) + }); + + vkcv::GraphicsPipelineConfig gfxPipelineConfigParticles; + gfxPipelineConfigParticles.m_ShaderProgram = gfxProgramParticles; + gfxPipelineConfigParticles.m_Width = windowWidth; + gfxPipelineConfigParticles.m_Height = windowHeight; + gfxPipelineConfigParticles.m_PassHandle = gfxPassParticles; + gfxPipelineConfigParticles.m_VertexLayout = vertexLayoutParticles; + gfxPipelineConfigParticles.m_DescriptorLayouts = { gfxSetLayoutParticles }; + gfxPipelineConfigParticles.m_UseDynamicViewport = true; + + vkcv::VertexLayout vertexLayoutLines ({ + vkcv::VertexBinding(0, gfxProgramLines.getVertexAttachments()) + }); + + vkcv::GraphicsPipelineConfig gfxPipelineConfigLines; + gfxPipelineConfigLines.m_ShaderProgram = gfxProgramLines; + gfxPipelineConfigLines.m_Width = windowWidth; + gfxPipelineConfigLines.m_Height = windowHeight; + gfxPipelineConfigLines.m_PassHandle = gfxPassLines; + gfxPipelineConfigLines.m_VertexLayout = vertexLayoutLines; + gfxPipelineConfigLines.m_DescriptorLayouts = {}; + gfxPipelineConfigLines.m_UseDynamicViewport = true; + gfxPipelineConfigLines.m_PrimitiveTopology = vkcv::PrimitiveTopology::LineList; + + vkcv::GraphicsPipelineHandle gfxPipelineGrid = core.createGraphicsPipeline(gfxPipelineConfigGrid); + vkcv::GraphicsPipelineHandle gfxPipelineParticles = core.createGraphicsPipeline(gfxPipelineConfigParticles); + vkcv::GraphicsPipelineHandle gfxPipelineLines = core.createGraphicsPipeline(gfxPipelineConfigLines); + + vkcv::Buffer<glm::vec2> trianglePositions = core.createBuffer<glm::vec2>(vkcv::BufferType::VERTEX, 3); + trianglePositions.fill({ + glm::vec2(-1.0f, -1.0f), + glm::vec2(+0.0f, +1.5f), + glm::vec2(+1.0f, -1.0f) + }); + + vkcv::Buffer<uint16_t> triangleIndices = core.createBuffer<uint16_t>(vkcv::BufferType::INDEX, 3); + triangleIndices.fill({ + 0, 1, 2 + }); + + vkcv::Mesh triangleMesh ( + { vkcv::VertexBufferBinding(0, trianglePositions.getVulkanHandle()) }, + triangleIndices.getVulkanHandle(), + triangleIndices.getCount() + ); + + vkcv::Buffer<glm::vec3> linesPositions = core.createBuffer<glm::vec3>(vkcv::BufferType::VERTEX, 8); + linesPositions.fill({ + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(1.0f, 0.0f, 0.0f), + glm::vec3(0.0f, 1.0f, 0.0f), + glm::vec3(1.0f, 1.0f, 0.0f), + glm::vec3(0.0f, 0.0f, 1.0f), + glm::vec3(1.0f, 0.0f, +1.0f), + glm::vec3(0.0f, 1.0f, 1.0f), + glm::vec3(1.0f, 1.0f, 1.0f) + }); + + vkcv::Buffer<uint16_t> linesIndices = core.createBuffer<uint16_t>(vkcv::BufferType::INDEX, 24); + linesIndices.fill({ + 0, 1, + 1, 3, + 3, 2, + 2, 0, + + 4, 5, + 5, 7, + 7, 6, + 6, 4, + + 0, 4, + 1, 5, + 2, 6, + 3, 7 + }); + + vkcv::Mesh linesMesh ( + { vkcv::VertexBufferBinding(0, linesPositions.getVulkanHandle()) }, + linesIndices.getVulkanHandle(), + linesIndices.getCount() + ); + + std::vector<vkcv::DrawcallInfo> drawcallsGrid; + + drawcallsGrid.push_back(vkcv::DrawcallInfo( + triangleMesh, + { vkcv::DescriptorSetUsage(0, gfxSetGrid) }, + grid.getWidth() * grid.getHeight() * grid.getDepth() + )); + + std::vector<vkcv::DrawcallInfo> drawcallsParticles; + + drawcallsParticles.push_back(vkcv::DrawcallInfo( + triangleMesh, + { vkcv::DescriptorSetUsage(0, gfxSetParticles) }, + sim->count + )); + + std::vector<vkcv::DrawcallInfo> drawcallsLines; + + drawcallsLines.push_back(vkcv::DrawcallInfo( + linesMesh, + {}, + 1 + )); + + bool renderGrid = true; + + float speed_factor = 1.0f; + + auto start = std::chrono::system_clock::now(); + auto current = start; + + while (vkcv::Window::hasOpenWindow()) { + vkcv::Window::pollEvents(); + + if (window.getHeight() == 0 || window.getWidth() == 0) + continue; + + uint32_t swapchainWidth, swapchainHeight; + if (!core.beginFrame(swapchainWidth, swapchainHeight, windowHandle)) { + continue; + } + + if ((swapchainWidth != swapchainExtent.width) || ((swapchainHeight != swapchainExtent.height))) { + depthBuffer = core.createImage( + vk::Format::eD32Sfloat, + swapchainWidth, + swapchainHeight + ).getHandle(); + + swapchainExtent.width = swapchainWidth; + swapchainExtent.height = swapchainHeight; + } + + auto next = std::chrono::system_clock::now(); + + auto time = std::chrono::duration_cast<std::chrono::microseconds>(next - start); + auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(next - current); + + current = next; + + Physics physics; + physics.t = static_cast<float>(0.000001 * static_cast<double>(time.count())); + physics.dt = static_cast<float>(0.000001 * static_cast<double>(deltatime.count())); + physics.speedfactor = speed_factor; + + vkcv::PushConstants physicsPushConstants(sizeof(physics)); + physicsPushConstants.appendDrawcall(physics); + + cameraManager.update(physics.dt); + + glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); + vkcv::PushConstants cameraPushConstants(sizeof(glm::mat4)); + cameraPushConstants.appendDrawcall(mvp); + + auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); + + const uint32_t dispatchSizeGrid[3] = {grid.getWidth() / 4, grid.getHeight() / 4, grid.getDepth() / 4}; + const uint32_t dispatchSizeParticles[3] = {static_cast<uint32_t>(sim->count + 63) / 64, 1, 1}; + + for (int step = 0; step < 1; step++) { + core.recordBeginDebugLabel(cmdStream, "INIT PARTICLE WEIGHTS", {0.78f, 0.89f, 0.94f, 1.0f}); + core.recordBufferMemoryBarrier(cmdStream, particlesHandle); + core.prepareImageForSampling(cmdStream, grid.getHandle()); + + core.recordComputeDispatchToCmdStream( + cmdStream, + initParticleWeightsPipeline, + dispatchSizeParticles, + { + vkcv::DescriptorSetUsage( + 0, initParticleWeightsSets[0] + ), + vkcv::DescriptorSetUsage( + 1, initParticleWeightsSets[1] + ) + }, + vkcv::PushConstants(0) + ); + + core.recordBufferMemoryBarrier(cmdStream, particlesHandle); + core.recordEndDebugLabel(cmdStream); + + core.recordBeginDebugLabel(cmdStream, "TRANSFORM PARTICLES TO GRID", {0.47f, 0.77f, 0.85f, 1.0f}); + core.recordBufferMemoryBarrier(cmdStream, particlesHandle); + core.prepareImageForStorage(cmdStream, grid.getHandle()); + + core.recordComputeDispatchToCmdStream( + cmdStream, + transformParticlesToGridPipeline, + dispatchSizeGrid, + { + vkcv::DescriptorSetUsage( + 0, transformParticlesToGridSets[0] + ), + vkcv::DescriptorSetUsage( + 1, transformParticlesToGridSets[1] + ), + vkcv::DescriptorSetUsage( + 2, transformParticlesToGridSets[2] + ) + }, + physicsPushConstants + ); + + core.recordImageMemoryBarrier(cmdStream, grid.getHandle()); + core.recordEndDebugLabel(cmdStream); + + core.recordBeginDebugLabel(cmdStream, "UPDATE PARTICLE VELOCITIES", {0.78f, 0.89f, 0.94f, 1.0f}); + core.recordBufferMemoryBarrier(cmdStream, particlesHandle); + core.recordBufferMemoryBarrier(cmdStream, simulation.getHandle()); + core.prepareImageForSampling(cmdStream, grid.getHandle()); + + core.recordComputeDispatchToCmdStream( + cmdStream, + updateParticleVelocitiesPipeline, + dispatchSizeParticles, + { + vkcv::DescriptorSetUsage( + 0, updateParticleVelocitiesSets[0] + ), + vkcv::DescriptorSetUsage( + 1, updateParticleVelocitiesSets[1] + ), + vkcv::DescriptorSetUsage( + 2, updateParticleVelocitiesSets[2] + ) + }, + physicsPushConstants + ); + + core.recordBufferMemoryBarrier(cmdStream, particlesHandle); + core.recordEndDebugLabel(cmdStream); + } + + std::vector<vkcv::ImageHandle> renderTargets { + vkcv::ImageHandle::createSwapchainImageHandle(), + depthBuffer + }; + + if (renderGrid) { + core.recordBeginDebugLabel(cmdStream, "RENDER GRID", { 0.13f, 0.20f, 0.22f, 1.0f }); + core.recordBufferMemoryBarrier(cmdStream, simulation.getHandle()); + core.prepareImageForSampling(cmdStream, grid.getHandle()); + + core.recordDrawcallsToCmdStream( + cmdStream, + gfxPassGrid, + gfxPipelineGrid, + cameraPushConstants, + drawcallsGrid, + renderTargets, + windowHandle + ); + + core.recordEndDebugLabel(cmdStream); + } else { + core.recordBeginDebugLabel(cmdStream, "RENDER PARTICLES", { 0.13f, 0.20f, 0.22f, 1.0f }); + core.recordBufferMemoryBarrier(cmdStream, particlesHandle); + + core.recordDrawcallsToCmdStream( + cmdStream, + gfxPassParticles, + gfxPipelineParticles, + cameraPushConstants, + drawcallsParticles, + renderTargets, + windowHandle + ); + + core.recordEndDebugLabel(cmdStream); + } + + core.recordBeginDebugLabel(cmdStream, "RENDER LINES", { 0.13f, 0.20f, 0.22f, 1.0f }); + + core.recordDrawcallsToCmdStream( + cmdStream, + gfxPassLines, + gfxPipelineLines, + cameraPushConstants, + drawcallsLines, + renderTargets, + windowHandle + ); + + core.recordEndDebugLabel(cmdStream); + + core.prepareSwapchainImageForPresent(cmdStream); + core.submitCommandStream(cmdStream); + + gui.beginGUI(); + ImGui::Begin("Settings"); + + ImGui::BeginGroup(); + ImGui::Combo("Mode", &(sim->mode), "Random\0Ordered", 2); + ImGui::Combo("Form", &(sim->form), "Sphere\0Cube", 2); + ImGui::Combo("Type", &(sim->type), "Hyperelastic\0Fluid", 2); + ImGui::EndGroup(); + + ImGui::Spacing(); + + ImGui::SliderInt("Particle Count", &(sim->count), 1, 100000); + ImGui::SliderFloat("Density", &(sim->density), std::numeric_limits<float>::epsilon(), 5000.0f); + ImGui::SameLine(0.0f, 10.0f); + if (ImGui::SmallButton("Reset##density")) { + sim->density = 2500.0f; + } + + ImGui::SliderFloat("Radius", &(sim->size), 0.0f, 0.5f); + ImGui::SameLine(0.0f, 10.0f); + if (ImGui::SmallButton("Reset##radius")) { + sim->size = 0.1f; + } + + ImGui::Spacing(); + + ImGui::BeginGroup(); + ImGui::SliderFloat("Bulk Modulus", &(sim->K), 0.0f, 1000.0f); + ImGui::SliderFloat("Young's Modulus", &(sim->E), 0.0f, 1000.0f); + ImGui::SliderFloat("Heat Capacity Ratio", &(sim->gamma), 1.0f, 2.0f); + ImGui::SliderFloat("Lame1", &(sim->lame1), 0.0f, 1000.0f); + ImGui::SliderFloat("Lame2", &(sim->lame2), 0.0f, 1000.0f); + ImGui::EndGroup(); + + ImGui::Spacing(); + + ImGui::SliderFloat("Simulation Speed", &speed_factor, 0.0f, 2.0f); + + ImGui::Spacing(); + ImGui::Checkbox("Render Grid", &renderGrid); + + ImGui::DragFloat3("Initial Velocity", reinterpret_cast<float*>(&initialVelocity), 0.001f); + ImGui::SameLine(0.0f, 10.0f); + if (ImGui::Button("Reset##particle_velocity")) { + particlesHandle = resetParticles( + core, + sim->count, + initialVelocity, + sim->density, + sim->size, + sim->form, + sim->mode + ); + + vkcv::DescriptorWrites writes; + writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particlesHandle)); + + core.writeDescriptorSet(initParticleWeightsSets[0], writes); + core.writeDescriptorSet(transformParticlesToGridSets[0], writes); + core.writeDescriptorSet(updateParticleVelocitiesSets[0], writes); + + core.writeDescriptorSet(gfxSetParticles, writes); + } + + ImGui::SliderFloat("Gravity", &(sim->gravity), 0.0f, 10.0f); + + ImGui::End(); + gui.endGUI(); + + core.endFrame(windowHandle); + } + + simulation.unmap(); + return 0; +} diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 12d2090de47e5d002734c9a44773affdb4f99b3e..ba69cab5fcd2a1ce78e5a3491e24ab7f273e0474 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -268,6 +268,56 @@ namespace vkcv cmdBuffer.setViewport(0, 1, &dynamicViewport); cmdBuffer.setScissor(0, 1, &dynamicScissor); } + + vk::IndexType getIndexType(IndexBitCount indexByteCount){ + switch (indexByteCount) { + case IndexBitCount::Bit16: return vk::IndexType::eUint16; + case IndexBitCount::Bit32: return vk::IndexType::eUint32; + default: + vkcv_log(LogLevel::ERROR, "unknown Enum"); + return vk::IndexType::eUint16; + } + } + + void recordDrawcall( + const Core &core, + const DrawcallInfo &drawcall, + vk::CommandBuffer cmdBuffer, + vk::PipelineLayout pipelineLayout, + const PushConstants &pushConstants, + const size_t drawcallIndex) { + + for (uint32_t i = 0; i < drawcall.mesh.vertexBufferBindings.size(); i++) { + const auto& vertexBinding = drawcall.mesh.vertexBufferBindings[i]; + cmdBuffer.bindVertexBuffers(i, vertexBinding.buffer, vertexBinding.offset); + } + + for (const auto& descriptorUsage : drawcall.descriptorSets) { + cmdBuffer.bindDescriptorSets( + vk::PipelineBindPoint::eGraphics, + pipelineLayout, + descriptorUsage.setLocation, + core.getDescriptorSet(descriptorUsage.descriptorSet).vulkanHandle, + nullptr); + } + + if (pushConstants.getSizePerDrawcall() > 0) { + cmdBuffer.pushConstants( + pipelineLayout, + vk::ShaderStageFlagBits::eAll, + 0, + pushConstants.getSizePerDrawcall(), + pushConstants.getDrawcallData(drawcallIndex)); + } + + if (drawcall.mesh.indexBuffer) { + cmdBuffer.bindIndexBuffer(drawcall.mesh.indexBuffer, 0, getIndexType(drawcall.mesh.indexBitCount)); + cmdBuffer.drawIndexed(drawcall.mesh.indexCount, drawcall.instanceCount, 0, 0, {}); + } + else { + cmdBuffer.draw(drawcall.mesh.indexCount, drawcall.instanceCount, 0, 0, {}); + } + } void Core::recordDrawcallsToCmdStream( const CommandStreamHandle& cmdStreamHandle, @@ -323,7 +373,7 @@ namespace vkcv } for (size_t i = 0; i < drawcalls.size(); i++) { - recordDrawcall(drawcalls[i], cmdBuffer, pipelineLayout, pushConstantData, i); + recordDrawcall(*this, drawcalls[i], cmdBuffer, pipelineLayout, pushConstantData, i); } cmdBuffer.endRenderPass(); @@ -490,6 +540,7 @@ namespace vkcv for (size_t i = 0; i < drawcalls.size(); i++) { const uint32_t pushConstantOffset = i * pushConstantData.getSizePerDrawcall(); recordMeshShaderDrawcall( + *this, cmdBuffer, pipelineLayout, pushConstantData, @@ -529,7 +580,7 @@ namespace vkcv vk::PipelineBindPoint::eRayTracingKHR, rtxPipelineLayout, usage.setLocation, - { usage.vulkanHandle }, + { getDescriptorSet(usage.descriptorSet).vulkanHandle }, usage.dynamicOffsets ); } @@ -570,7 +621,7 @@ namespace vkcv vk::PipelineBindPoint::eCompute, pipelineLayout, usage.setLocation, - { usage.vulkanHandle }, + { getDescriptorSet(usage.descriptorSet).vulkanHandle }, usage.dynamicOffsets ); } @@ -649,7 +700,7 @@ namespace vkcv vk::PipelineBindPoint::eCompute, pipelineLayout, usage.setLocation, - { usage.vulkanHandle }, + { getDescriptorSet(usage.descriptorSet).vulkanHandle }, usage.dynamicOffsets ); } @@ -763,8 +814,8 @@ namespace vkcv SamplerHandle Core::createSampler(SamplerFilterType magFilter, SamplerFilterType minFilter, SamplerMipmapMode mipmapMode, SamplerAddressMode addressMode, - float mipLodBias) { - return m_SamplerManager->createSampler(magFilter, minFilter, mipmapMode, addressMode, mipLodBias); + float mipLodBias, SamplerBorderColor borderColor) { + return m_SamplerManager->createSampler(magFilter, minFilter, mipmapMode, addressMode, mipLodBias, borderColor); } Image Core::createImage( diff --git a/src/vkcv/DrawcallRecording.cpp b/src/vkcv/DrawcallRecording.cpp index 638df388178f79f680c3b9f797d9d435e752fe10..e13b4d24148e9d76d8be4ad7fd3db0db87249c59 100644 --- a/src/vkcv/DrawcallRecording.cpp +++ b/src/vkcv/DrawcallRecording.cpp @@ -1,67 +1,9 @@ -#include <vkcv/DrawcallRecording.hpp> -#include <vkcv/Logger.hpp> -namespace vkcv { - - vk::IndexType getIndexType(IndexBitCount indexByteCount){ - switch (indexByteCount) { - case IndexBitCount::Bit16: return vk::IndexType::eUint16; - case IndexBitCount::Bit32: return vk::IndexType::eUint32; - default: - vkcv_log(LogLevel::ERROR, "unknown Enum"); - return vk::IndexType::eUint16; - } - } - - void recordDrawcall( - const DrawcallInfo &drawcall, - vk::CommandBuffer cmdBuffer, - vk::PipelineLayout pipelineLayout, - const PushConstants &pushConstants, - const size_t drawcallIndex) { - - for (uint32_t i = 0; i < drawcall.mesh.vertexBufferBindings.size(); i++) { - const auto& vertexBinding = drawcall.mesh.vertexBufferBindings[i]; - cmdBuffer.bindVertexBuffers(i, vertexBinding.buffer, vertexBinding.offset); - } +#include "vkcv/DrawcallRecording.hpp" +#include "vkcv/Logger.hpp" +#include "vkcv/Core.hpp" - for (const auto& descriptorUsage : drawcall.descriptorSets) { - cmdBuffer.bindDescriptorSets( - vk::PipelineBindPoint::eGraphics, - pipelineLayout, - descriptorUsage.setLocation, - descriptorUsage.vulkanHandle, - nullptr); - } - - if (pushConstants.getSizePerDrawcall() > 0) { - cmdBuffer.pushConstants( - pipelineLayout, - vk::ShaderStageFlagBits::eAll, - 0, - pushConstants.getSizePerDrawcall(), - pushConstants.getDrawcallData(drawcallIndex)); - } - - if (drawcall.mesh.indexBuffer) { - cmdBuffer.bindIndexBuffer(drawcall.mesh.indexBuffer, 0, getIndexType(drawcall.mesh.indexBitCount)); - cmdBuffer.drawIndexed(drawcall.mesh.indexCount, drawcall.instanceCount, 0, 0, {}); - } - else { - cmdBuffer.draw(drawcall.mesh.indexCount, drawcall.instanceCount, 0, 0, {}); - } - } - - void recordIndirectDrawcall( - const DrawcallInfo &drawcall, - vk::CommandBuffer cmdBuffer, - const Buffer <vk::DrawIndexedIndirectCommand> &drawBuffer, - const uint32_t drawCount, - vk::PipelineLayout pipelineLayout, - const PushConstants &pushConstants, - const size_t drawcallIndex) { - return; - } +namespace vkcv { struct MeshShaderFunctions { @@ -78,6 +20,7 @@ namespace vkcv { } void recordMeshShaderDrawcall( + const Core& core, vk::CommandBuffer cmdBuffer, vk::PipelineLayout pipelineLayout, const PushConstants& pushConstantData, @@ -90,7 +33,7 @@ namespace vkcv { vk::PipelineBindPoint::eGraphics, pipelineLayout, descriptorUsage.setLocation, - descriptorUsage.vulkanHandle, + core.getDescriptorSet(descriptorUsage.descriptorSet).vulkanHandle, nullptr); } diff --git a/src/vkcv/FeatureManager.cpp b/src/vkcv/FeatureManager.cpp index c25745fcdd007df86316e0f72bc3d654377baa70..f89eb0717b82e40b10f98673e6d42fc07e67a8fd 100644 --- a/src/vkcv/FeatureManager.cpp +++ b/src/vkcv/FeatureManager.cpp @@ -293,6 +293,44 @@ m_physicalDevice.getFeatures2(&query) return true; } + bool FeatureManager::checkSupport(const vk::PhysicalDeviceShaderAtomicFloatFeaturesEXT& features, bool required) const { + vkcv_check_init_features2(vk::PhysicalDeviceShaderAtomicFloatFeaturesEXT); + + vkcv_check_feature(shaderBufferFloat32Atomics); + vkcv_check_feature(shaderBufferFloat32AtomicAdd); + vkcv_check_feature(shaderBufferFloat64Atomics); + vkcv_check_feature(shaderBufferFloat64AtomicAdd); + vkcv_check_feature(shaderSharedFloat32Atomics); + vkcv_check_feature(shaderSharedFloat32AtomicAdd); + vkcv_check_feature(shaderSharedFloat64Atomics); + vkcv_check_feature(shaderSharedFloat64AtomicAdd); + vkcv_check_feature(shaderImageFloat32Atomics); + vkcv_check_feature(shaderImageFloat32AtomicAdd); + vkcv_check_feature(sparseImageFloat32Atomics); + vkcv_check_feature(sparseImageFloat32AtomicAdd); + + return true; + } + + bool FeatureManager::checkSupport(const vk::PhysicalDeviceShaderAtomicFloat2FeaturesEXT& features, bool required) const { + vkcv_check_init_features2(vk::PhysicalDeviceShaderAtomicFloat2FeaturesEXT); + + vkcv_check_feature(shaderBufferFloat16Atomics); + vkcv_check_feature(shaderBufferFloat16AtomicAdd); + vkcv_check_feature(shaderBufferFloat16AtomicMinMax); + vkcv_check_feature(shaderBufferFloat32AtomicMinMax); + vkcv_check_feature(shaderBufferFloat64AtomicMinMax); + vkcv_check_feature(shaderSharedFloat16Atomics); + vkcv_check_feature(shaderSharedFloat16AtomicAdd); + vkcv_check_feature(shaderSharedFloat16AtomicMinMax); + vkcv_check_feature(shaderSharedFloat32AtomicMinMax); + vkcv_check_feature(shaderSharedFloat64AtomicMinMax); + vkcv_check_feature(shaderImageFloat32AtomicMinMax); + vkcv_check_feature(sparseImageFloat32AtomicMinMax); + + return true; + } + bool FeatureManager::checkSupport(const vk::PhysicalDeviceVulkan12Features &features, bool required) const { vkcv_check_init_features2(vk::PhysicalDeviceVulkan12Features); diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp index bde020498e19e3f9bf0667c7182ca13d11f9044f..bfee504f599d941e625e6ef5c6045805c33a29a1 100644 --- a/src/vkcv/ImageManager.cpp +++ b/src/vkcv/ImageManager.cpp @@ -345,7 +345,7 @@ namespace vkcv { recordImageBarrier(cmdBuffer, transitionBarrier); } - constexpr uint32_t getChannelsByFormat(vk::Format format) { + constexpr uint32_t getBytesPerPixel(vk::Format format) { switch (format) { case vk::Format::eR8Unorm: return 1; @@ -353,6 +353,10 @@ namespace vkcv { return 4; case vk::Format::eR8G8B8A8Unorm: return 4; + case vk::Format::eR16G16B16A16Sfloat: + return 8; + case vk::Format::eR32G32B32A32Sfloat: + return 16; default: std::cerr << "Unknown image format" << std::endl; return 4; @@ -379,15 +383,15 @@ namespace vkcv { handle, vk::ImageLayout::eTransferDstOptimal); - uint32_t channels = getChannelsByFormat(image.m_format); const size_t image_size = ( - image.m_width * image.m_height * image.m_depth * channels + image.m_width * image.m_height * image.m_depth * + getBytesPerPixel(image.m_format) ); const size_t max_size = std::min(size, image_size); BufferHandle bufferHandle = m_bufferManager.createBuffer( - BufferType::STAGING, max_size, BufferMemoryType::HOST_VISIBLE, false + BufferType::STAGING, max_size, BufferMemoryType::DEVICE_LOCAL, false ); m_bufferManager.fillBuffer(bufferHandle, data, max_size, 0); diff --git a/src/vkcv/PassConfig.cpp b/src/vkcv/PassConfig.cpp index 78bd5808b63fee7333243db4fca640047f76eae9..b203fab4f02afcc8f51b468ab4504480a8e60e4e 100644 --- a/src/vkcv/PassConfig.cpp +++ b/src/vkcv/PassConfig.cpp @@ -11,7 +11,7 @@ namespace vkcv store_operation{store_op}, load_operation{load_op}, format(format) - {}; + {} PassConfig::PassConfig(std::vector<AttachmentDescription> attachments, Multisampling msaa) noexcept : attachments{std::move(attachments) }, msaa(msaa) diff --git a/src/vkcv/SamplerManager.cpp b/src/vkcv/SamplerManager.cpp index 792e6f16b4a05af41a164a1eda9dd7423594857e..9a80635744e5a3dd0b6bd8db476cec841b1c317d 100644 --- a/src/vkcv/SamplerManager.cpp +++ b/src/vkcv/SamplerManager.cpp @@ -18,11 +18,13 @@ namespace vkcv { SamplerFilterType minFilter, SamplerMipmapMode mipmapMode, SamplerAddressMode addressMode, - float mipLodBias) { + float mipLodBias, + SamplerBorderColor borderColor) { vk::Filter vkMagFilter; vk::Filter vkMinFilter; vk::SamplerMipmapMode vkMipmapMode; vk::SamplerAddressMode vkAddressMode; + vk::BorderColor vkBorderColor; switch (magFilter) { case SamplerFilterType::NEAREST: @@ -70,6 +72,32 @@ namespace vkcv { case SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: vkAddressMode = vk::SamplerAddressMode::eMirrorClampToEdge; break; + case SamplerAddressMode::CLAMP_TO_BORDER: + vkAddressMode = vk::SamplerAddressMode::eClampToBorder; + break; + default: + return SamplerHandle(); + } + + switch (borderColor) { + case SamplerBorderColor::INT_ZERO_OPAQUE: + vkBorderColor = vk::BorderColor::eIntOpaqueBlack; + break; + case SamplerBorderColor::INT_ZERO_TRANSPARENT: + vkBorderColor = vk::BorderColor::eIntTransparentBlack; + break; + case SamplerBorderColor::FLOAT_ZERO_OPAQUE: + vkBorderColor = vk::BorderColor::eFloatOpaqueBlack; + break; + case SamplerBorderColor::FLOAT_ZERO_TRANSPARENT: + vkBorderColor = vk::BorderColor::eFloatTransparentBlack; + break; + case SamplerBorderColor::INT_ONE_OPAQUE: + vkBorderColor = vk::BorderColor::eIntOpaqueWhite; + break; + case SamplerBorderColor::FLOAT_ONE_OPAQUE: + vkBorderColor = vk::BorderColor::eFloatOpaqueWhite; + break; default: return SamplerHandle(); } @@ -89,7 +117,7 @@ namespace vkcv { vk::CompareOp::eAlways, -1000.0f, 1000.0f, - vk::BorderColor::eIntOpaqueBlack, + vkBorderColor, false ); diff --git a/src/vkcv/SamplerManager.hpp b/src/vkcv/SamplerManager.hpp index aea47a03714b417314a09dfc0be855df31fbb557..128faa711993ac052cf774a1d31144d19362658f 100644 --- a/src/vkcv/SamplerManager.hpp +++ b/src/vkcv/SamplerManager.hpp @@ -30,10 +30,11 @@ namespace vkcv { SamplerManager& operator=(SamplerManager&& other) = delete; SamplerHandle createSampler(SamplerFilterType magFilter, - SamplerFilterType minFilter, - SamplerMipmapMode mipmapMode, - SamplerAddressMode addressMode, - float mipLodBias); + SamplerFilterType minFilter, + SamplerMipmapMode mipmapMode, + SamplerAddressMode addressMode, + float mipLodBias, + SamplerBorderColor borderColor); [[nodiscard]] vk::Sampler getVulkanSampler(const SamplerHandle& handle) const;