diff --git a/include/vkcv/BufferManager.hpp b/include/vkcv/BufferManager.hpp index 7bec33d8c4fa752be2487a849c16eaeeea0e6237..e4e1e4019f982908ad592466f342b84d3ef52d9a 100644 --- a/include/vkcv/BufferManager.hpp +++ b/include/vkcv/BufferManager.hpp @@ -13,7 +13,8 @@ namespace vkcv VERTEX, UNIFORM, STORAGE, - STAGING + STAGING, + INDIRECT }; enum class BufferMemoryType { diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 028f8bcc10c3483c417462bc9382e45ae24e74d6..b89dbae2f9af909ab2f1319994e9bb00fb87f98e 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -331,6 +331,18 @@ namespace vkcv const std::vector<ImageHandle> &renderTargets, const WindowHandle &windowHandle); + void recordIndexedIndirectDrawcallsToCmdStream( + const CommandStreamHandle cmdStreamHandle, + const PassHandle renderpassHandle, + const GraphicsPipelineHandle &pipelineHandle, + const PushConstants &pushConstantData, + const vkcv::DescriptorSetHandle &compiledDescriptorSet, + const vkcv::Mesh &compiledMesh, + const std::vector<ImageHandle> &renderTargets, + const vkcv::Buffer<vk::DrawIndexedIndirectCommand> &indirectBuffer, + const uint32_t drawCount, + const WindowHandle &windowHandle); + void recordMeshShaderDrawcalls( const CommandStreamHandle& cmdStreamHandle, const PassHandle& renderpassHandle, diff --git a/include/vkcv/DescriptorConfig.hpp b/include/vkcv/DescriptorConfig.hpp index 735f973777a6ef41951c7ef52350f9ddc5b1200c..becdb9f843aa254fed6f05dec0c18686fac497d6 100644 --- a/include/vkcv/DescriptorConfig.hpp +++ b/include/vkcv/DescriptorConfig.hpp @@ -61,17 +61,11 @@ namespace vkcv */ struct DescriptorBinding { - DescriptorBinding( - uint32_t bindingID, - DescriptorType descriptorType, - uint32_t descriptorCount, - ShaderStages shaderStages - ) noexcept; - uint32_t bindingID; DescriptorType descriptorType; uint32_t descriptorCount; ShaderStages shaderStages; + bool variableCount; bool operator ==(const DescriptorBinding &other) const; }; diff --git a/include/vkcv/DescriptorWrites.hpp b/include/vkcv/DescriptorWrites.hpp index 457e8952d0fcb2dbe0ad281f6f8018575c4f4ede..f4f9729a193c9da4cfc4ccc869337314e8a71ccb 100644 --- a/include/vkcv/DescriptorWrites.hpp +++ b/include/vkcv/DescriptorWrites.hpp @@ -4,12 +4,13 @@ namespace vkcv { struct SampledImageDescriptorWrite { - inline SampledImageDescriptorWrite(uint32_t binding, ImageHandle image, uint32_t mipLevel = 0, bool useGeneralLayout = false) - : binding(binding), image(image), mipLevel(mipLevel), useGeneralLayout(useGeneralLayout) {}; + inline SampledImageDescriptorWrite(uint32_t binding, ImageHandle image, uint32_t mipLevel = 0, bool useGeneralLayout = false, uint32_t arrayIndex = 0) + : binding(binding), image(image), mipLevel(mipLevel), useGeneralLayout(useGeneralLayout), arrayIndex(arrayIndex) {}; uint32_t binding; ImageHandle image; uint32_t mipLevel; bool useGeneralLayout; + uint32_t arrayIndex; }; struct StorageImageDescriptorWrite { diff --git a/include/vkcv/DrawcallRecording.hpp b/include/vkcv/DrawcallRecording.hpp index 37cf02d9102fcab5abd10ada711f67b721bcb52b..77e2a2e13bee3248e424d1d9c3d4cad7aaecd34b 100644 --- a/include/vkcv/DrawcallRecording.hpp +++ b/include/vkcv/DrawcallRecording.hpp @@ -3,6 +3,7 @@ #include <vkcv/Handles.hpp> #include <vkcv/DescriptorConfig.hpp> #include <vkcv/PushConstants.hpp> +#include "Buffer.hpp" namespace vkcv { struct VertexBufferBinding { @@ -50,6 +51,8 @@ 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){} @@ -66,6 +69,15 @@ namespace vkcv { 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 { diff --git a/include/vkcv/FeatureManager.hpp b/include/vkcv/FeatureManager.hpp index e9abd69009da1120284aefeb375dd380abd20201..2f932f6e25c12e80f42d762f82a73f9a5265b793 100644 --- a/include/vkcv/FeatureManager.hpp +++ b/include/vkcv/FeatureManager.hpp @@ -78,7 +78,7 @@ namespace vkcv { [[nodiscard]] bool checkSupport(const vk::PhysicalDeviceMeshShaderFeaturesNV& features, bool required) const; - + /** * @brief Currently used for RTX. Checks support of the @p vk::PhysicalDeviceVulkan12Features. * @param features The features. diff --git a/modules/camera/include/vkcv/camera/Camera.hpp b/modules/camera/include/vkcv/camera/Camera.hpp index 8a8c5df5d74cf1402bd8810172657ba77ddb2d56..6ccafe4ebe65f4e50747f1341ed1306948fef242 100644 --- a/modules/camera/include/vkcv/camera/Camera.hpp +++ b/modules/camera/include/vkcv/camera/Camera.hpp @@ -4,6 +4,7 @@ #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_access.hpp> #include <glm/vec3.hpp> +#include <glm/gtc/type_ptr.hpp> #include <glm/mat4x4.hpp> namespace vkcv::camera { diff --git a/modules/material/src/vkcv/material/Material.cpp b/modules/material/src/vkcv/material/Material.cpp index 43a72e4cb6c936457f3723e32dc2715d9788ce08..bd26733b878634e3caf5b927e8c0307432279212 100644 --- a/modules/material/src/vkcv/material/Material.cpp +++ b/modules/material/src/vkcv/material/Material.cpp @@ -36,16 +36,36 @@ namespace vkcv::material { case MaterialType::PBR_MATERIAL: if (pbr_bindings.empty()) { - pbr_bindings.insert(std::make_pair(0, DescriptorBinding(0, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT))); - pbr_bindings.insert(std::make_pair(1, DescriptorBinding(1, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT))); - pbr_bindings.insert(std::make_pair(2, DescriptorBinding(2, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT))); - pbr_bindings.insert(std::make_pair(3, DescriptorBinding(3, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT))); - pbr_bindings.insert(std::make_pair(4, DescriptorBinding(4, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT))); - pbr_bindings.insert(std::make_pair(5, DescriptorBinding(5, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT))); - pbr_bindings.insert(std::make_pair(6, DescriptorBinding(6, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT))); - pbr_bindings.insert(std::make_pair(7, DescriptorBinding(7, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT))); - pbr_bindings.insert(std::make_pair(8, DescriptorBinding(8, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT))); - pbr_bindings.insert(std::make_pair(9, DescriptorBinding(9, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT))); + pbr_bindings.insert(std::make_pair(0, DescriptorBinding { + 0, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT, false + })); + pbr_bindings.insert(std::make_pair(1, DescriptorBinding { + 1, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT, false + })); + pbr_bindings.insert(std::make_pair(2, DescriptorBinding { + 2, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT, false + })); + pbr_bindings.insert(std::make_pair(3, DescriptorBinding { + 3, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT, false + })); + pbr_bindings.insert(std::make_pair(4, DescriptorBinding { + 4, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT, false + })); + pbr_bindings.insert(std::make_pair(5, DescriptorBinding { + 5, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT, false + })); + pbr_bindings.insert(std::make_pair(6, DescriptorBinding { + 6, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT, false + })); + pbr_bindings.insert(std::make_pair(7, DescriptorBinding { + 7, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT, false + })); + pbr_bindings.insert(std::make_pair(8, DescriptorBinding { + 8, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT, false + })); + pbr_bindings.insert(std::make_pair(9, DescriptorBinding { + 9, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT, false + })); } return pbr_bindings; diff --git a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp index e4aae60b595d50d7e859199079714e91f5e5a694..f7cf0b4a1e68e46a784723d13366deac899f9963 100644 --- a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp +++ b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp @@ -67,33 +67,36 @@ namespace vkcv::upscaling { static DescriptorBindings getDescriptorBindings() { DescriptorBindings descriptorBindings = {}; - auto binding_0 = DescriptorBinding( + auto binding_0 = DescriptorBinding { 0, DescriptorType::UNIFORM_BUFFER_DYNAMIC, 1, - ShaderStage::COMPUTE - ); + ShaderStage::COMPUTE, + false + }; - auto binding_1 = DescriptorBinding( - 1, - DescriptorType::IMAGE_SAMPLED, - 1, - ShaderStage::COMPUTE - ); + auto binding_1 = DescriptorBinding { + 1, + DescriptorType::IMAGE_SAMPLED, + 1, + ShaderStage::COMPUTE, + false + }; - auto binding_2 = DescriptorBinding( - 2, - DescriptorType::IMAGE_STORAGE, - 1, - ShaderStage::COMPUTE - ); + auto binding_2 = DescriptorBinding{ + 2, + DescriptorType::IMAGE_STORAGE, + 1, + ShaderStage::COMPUTE, + false + }; - auto binding_3 = DescriptorBinding( - 3, - DescriptorType::SAMPLER, - 1, - ShaderStage::COMPUTE - ); + auto binding_3 = DescriptorBinding{ + 3, + DescriptorType::SAMPLER, + 1, + ShaderStage::COMPUTE + }; descriptorBindings.insert(std::make_pair(0, binding_0)); descriptorBindings.insert(std::make_pair(1, binding_1)); diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index 52d4a4a21f001b9feaab917fcdac4d52c6bf7e63..9cf1ff1c9327114d28871f11694a2fb88bc00735 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -8,6 +8,8 @@ add_subdirectory(rtx_ambient_occlusion) add_subdirectory(sph) add_subdirectory(voxelization) add_subdirectory(mesh_shader) +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 diff --git a/projects/bindless_textures/.gitignore b/projects/bindless_textures/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..cd45650aee8ab49ad568556452dde2d9d51d5f13 --- /dev/null +++ b/projects/bindless_textures/.gitignore @@ -0,0 +1 @@ +bindless_textures \ No newline at end of file diff --git a/projects/bindless_textures/CMakeLists.txt b/projects/bindless_textures/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..08cc636af2495afa3bb69cc7b652cc20eb4fa117 --- /dev/null +++ b/projects/bindless_textures/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.16) +project(bindless_textures) + +# setting c++ standard for the project +set(CMAKE_CXX_STANDARD 17) +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(bindless_textures src/main.cpp) + +# this should fix the execution path to load local files from the project (for MSVC) +if(MSVC) + set_target_properties(bindless_textures PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + set_target_properties(bindless_textures PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + + # in addition to setting the output directory, the working directory has to be set + # by default visual studio sets the working directory to the build directory, when using the debugger + set_target_properties(bindless_textures PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +endif() + +# including headers of dependencies and the VkCV framework +target_include_directories(bindless_textures SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include}) + +# linking with libraries from all dependencies and the VkCV framework +target_link_libraries(bindless_textures vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_shader_compiler) diff --git a/projects/bindless_textures/resources/Szene/Szene.bin b/projects/bindless_textures/resources/Szene/Szene.bin new file mode 100644 index 0000000000000000000000000000000000000000..c87d27637516b0bbf864251dd162773f5cc53e06 --- /dev/null +++ b/projects/bindless_textures/resources/Szene/Szene.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee4742718f720d589a2a03f5d879f8c50ba9057718d191a43b046eaa9071080d +size 70328 diff --git a/projects/bindless_textures/resources/Szene/Szene.gltf b/projects/bindless_textures/resources/Szene/Szene.gltf new file mode 100644 index 0000000000000000000000000000000000000000..e5a32b29af5d0a2ac5f497e60b4b92c1873e1df9 --- /dev/null +++ b/projects/bindless_textures/resources/Szene/Szene.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75ba834118792ebbacf528a1690c7d04df4b4c8122b9f99a9aa9a9d075d2c86a +size 7421 diff --git a/projects/bindless_textures/resources/Szene/boards2_vcyc.jpg b/projects/bindless_textures/resources/Szene/boards2_vcyc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/bindless_textures/resources/Szene/boards2_vcyc.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/bindless_textures/resources/Szene/boards2_vcyc_jpg.jpg b/projects/bindless_textures/resources/Szene/boards2_vcyc_jpg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/bindless_textures/resources/Szene/boards2_vcyc_jpg.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/bindless_textures/resources/cube/Grass001_1K_AmbientOcclusion.jpg b/projects/bindless_textures/resources/cube/Grass001_1K_AmbientOcclusion.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2217fb53744f9166232a40b78ee9518e04b0ded5 --- /dev/null +++ b/projects/bindless_textures/resources/cube/Grass001_1K_AmbientOcclusion.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6c88f8f3facd9e91f8dd160bd8c4a602e433872ed18e08015a9fa9dfff889de +size 901465 diff --git a/projects/bindless_textures/resources/cube/Grass001_1K_Color.jpg b/projects/bindless_textures/resources/cube/Grass001_1K_Color.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b8aa1533ae5a023a5fc8457f30ed60efe3bda32d --- /dev/null +++ b/projects/bindless_textures/resources/cube/Grass001_1K_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:878b8fe4747d9ce693220edea1915de550e8f14d402d26a0915f162d40f84e91 +size 1763328 diff --git a/projects/bindless_textures/resources/cube/Grass001_1K_Displacement.jpg b/projects/bindless_textures/resources/cube/Grass001_1K_Displacement.jpg new file mode 100644 index 0000000000000000000000000000000000000000..89789cba150eea7c7abbdc1851090f6021af978a --- /dev/null +++ b/projects/bindless_textures/resources/cube/Grass001_1K_Displacement.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e8300e1107bee7e681059d9da0a7e3ca422977e8b6f496e16452a4c94b3d385 +size 912347 diff --git a/projects/bindless_textures/resources/cube/Grass001_1K_Normal.jpg b/projects/bindless_textures/resources/cube/Grass001_1K_Normal.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3163d6391592ace10446cb71141a2192e63e9660 --- /dev/null +++ b/projects/bindless_textures/resources/cube/Grass001_1K_Normal.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:684426b49e841e267f12f06dc955b5b1d01b3ba3659bea0c5d73be889700929f +size 2336471 diff --git a/projects/bindless_textures/resources/cube/Grass001_1K_Roughness.jpg b/projects/bindless_textures/resources/cube/Grass001_1K_Roughness.jpg new file mode 100644 index 0000000000000000000000000000000000000000..10e6ac33badf2a4795766a66546a62c67eb8b558 --- /dev/null +++ b/projects/bindless_textures/resources/cube/Grass001_1K_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d952ffb098faf9ac5eb25134eabac08f0c65d927a448b5e7b4f9c72510cfcbe0 +size 822659 diff --git a/projects/bindless_textures/resources/cube/boards2_vcyc_jpg.jpg b/projects/bindless_textures/resources/cube/boards2_vcyc_jpg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/bindless_textures/resources/cube/boards2_vcyc_jpg.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/bindless_textures/resources/cube/cube.bin b/projects/bindless_textures/resources/cube/cube.bin new file mode 100644 index 0000000000000000000000000000000000000000..3303cd8635848bee18e10ab8754d5e4e7218db92 --- /dev/null +++ b/projects/bindless_textures/resources/cube/cube.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bb9b6b8bbe50a0aaa517057f245ee844f80afa7426dacb2aed4128f71629ce4 +size 840 diff --git a/projects/bindless_textures/resources/cube/cube.blend b/projects/bindless_textures/resources/cube/cube.blend new file mode 100644 index 0000000000000000000000000000000000000000..62ccb2c742094bcfb5ed194ab905bffae86bfd65 --- /dev/null +++ b/projects/bindless_textures/resources/cube/cube.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6c1e245f259c610528c9485db6688928faac0ab2addee9e3c2dde7740e4dd09 +size 774920 diff --git a/projects/bindless_textures/resources/cube/cube.blend1 b/projects/bindless_textures/resources/cube/cube.blend1 new file mode 100644 index 0000000000000000000000000000000000000000..13f21dcca218d7bc7a07a8a9682b5e1d9e607736 --- /dev/null +++ b/projects/bindless_textures/resources/cube/cube.blend1 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4496f423569b8ca81f3b3a55fad00f925557e0193fb9dbe6cdce7e71fb48f7b +size 774920 diff --git a/projects/bindless_textures/resources/cube/cube.glb b/projects/bindless_textures/resources/cube/cube.glb new file mode 100644 index 0000000000000000000000000000000000000000..66a42c65e71dcf375e04cc378256024dd3c7834d --- /dev/null +++ b/projects/bindless_textures/resources/cube/cube.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:198568b715f397d78f7c358c0f709a419e7fd677e54cdec7c19f71b5ed264897 +size 1194508 diff --git a/projects/bindless_textures/resources/cube/cube.gltf b/projects/bindless_textures/resources/cube/cube.gltf new file mode 100644 index 0000000000000000000000000000000000000000..428176144843dd06c78fe1d11a6392a0ea02b22d --- /dev/null +++ b/projects/bindless_textures/resources/cube/cube.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f82f455647a84ca6242882ae26a79a499d3ce594f8de317ab89488c5b79721ac +size 2823 diff --git a/projects/bindless_textures/resources/shaders/shader.frag b/projects/bindless_textures/resources/shaders/shader.frag new file mode 100644 index 0000000000000000000000000000000000000000..c855eb407944c415dc4055716aa64a531c830ef3 --- /dev/null +++ b/projects/bindless_textures/resources/shaders/shader.frag @@ -0,0 +1,16 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_EXT_nonuniform_qualifier : enable + +layout(location = 0) in vec3 passNormal; +layout(location = 1) in vec2 passUV; +layout(location = 2) in flat int passTextureIndex; + +layout(location = 0) out vec3 outColor; + +layout(set=0, binding=0) uniform sampler textureSampler; +layout(set=0, binding=1) uniform texture2D materialTextures[]; + +void main() { + outColor = texture(sampler2D(materialTextures[nonuniformEXT(passTextureIndex)], textureSampler), passUV).rgb; +} \ No newline at end of file diff --git a/projects/bindless_textures/resources/shaders/shader.vert b/projects/bindless_textures/resources/shaders/shader.vert new file mode 100644 index 0000000000000000000000000000000000000000..6bc918c6a186dcfb965719cd1e08cb448a49b44e --- /dev/null +++ b/projects/bindless_textures/resources/shaders/shader.vert @@ -0,0 +1,43 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inNormal; +layout(location = 2) in vec2 inUV; + +layout(location = 0) out vec3 passNormal; +layout(location = 1) out vec2 passUV; +layout(location = 2) out flat int passTextureIndex; + +layout( push_constant ) uniform constants{ + mat4 mvp; +}; + +void main() +{ + gl_Position = mvp * vec4(inPosition, 1.0); + passNormal = inNormal; + passUV = inUV; + + passTextureIndex = (gl_VertexIndex / 4); + + /* + if(inNormal.x > 0.9) + passTextureIndex = 0; + + if(inNormal.x < -0.9) + passTextureIndex = 1; + + if(inNormal.y > 0.9) + passTextureIndex = 2; + + if(inNormal.y < -0.9) + passTextureIndex = 3; + + if(inNormal.z > 0.9) + passTextureIndex = 4; + + if(inNormal.z < -0.9) + passTextureIndex = 5; + */ +} \ No newline at end of file diff --git a/projects/bindless_textures/resources/triangle/Triangle.bin b/projects/bindless_textures/resources/triangle/Triangle.bin new file mode 100644 index 0000000000000000000000000000000000000000..57f26ad96592b64377e6aa93823d96a94e6c5022 --- /dev/null +++ b/projects/bindless_textures/resources/triangle/Triangle.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:412ebd5f7242c266b4957e7e26be13aa331dbcb7bbb854ab334a2437ae8ed959 +size 104 diff --git a/projects/bindless_textures/resources/triangle/Triangle.blend b/projects/bindless_textures/resources/triangle/Triangle.blend new file mode 100644 index 0000000000000000000000000000000000000000..2421dc5e1bb029d73a9ec09cc4530c5196851fd7 --- /dev/null +++ b/projects/bindless_textures/resources/triangle/Triangle.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:387e544df173219fbf292a64a6656d1d782bbf71a5a9e9fdef0a308f47b05477 +size 758144 diff --git a/projects/bindless_textures/resources/triangle/Triangle.glb b/projects/bindless_textures/resources/triangle/Triangle.glb new file mode 100644 index 0000000000000000000000000000000000000000..4148620cd6af0dadbc791aa1c52bb5431a40884b --- /dev/null +++ b/projects/bindless_textures/resources/triangle/Triangle.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4be087a605212d139416b5352a018283b26b99260cbcddb7013a1beeb331227 +size 980 diff --git a/projects/bindless_textures/resources/triangle/Triangle.gltf b/projects/bindless_textures/resources/triangle/Triangle.gltf new file mode 100644 index 0000000000000000000000000000000000000000..a188e6ee16a5e8486cf307c7bda8cfd99bdbeea6 --- /dev/null +++ b/projects/bindless_textures/resources/triangle/Triangle.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5fc354e040f79cff329e919677b194c75e3a522c6406f75c1108ad9575f12ec +size 2202 diff --git a/projects/bindless_textures/src/main.cpp b/projects/bindless_textures/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a2e9ff5eed65d44f329c8986b64d6d8588a92d30 --- /dev/null +++ b/projects/bindless_textures/src/main.cpp @@ -0,0 +1,277 @@ +#include <iostream> +#include <vkcv/Core.hpp> +#include <GLFW/glfw3.h> +#include <vkcv/camera/CameraManager.hpp> +#include <chrono> +#include <vkcv/asset/asset_loader.hpp> +#include <vkcv/shader/GLSLCompiler.hpp> + +int main(int argc, const char** argv) { + const char* applicationName = "First Mesh"; + + uint32_t windowWidth = 800; + uint32_t windowHeight = 600; + + vkcv::Features features; + features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + features.requireExtensionFeature<vk::PhysicalDeviceDescriptorIndexingFeatures>( + VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, [](vk::PhysicalDeviceDescriptorIndexingFeatures &features) { + features.setShaderInputAttachmentArrayDynamicIndexing(true); + features.setShaderUniformTexelBufferArrayDynamicIndexing(true); + features.setShaderStorageTexelBufferArrayDynamicIndexing(true); + features.setShaderUniformBufferArrayNonUniformIndexing(true); + features.setShaderSampledImageArrayNonUniformIndexing(true); + features.setShaderStorageBufferArrayNonUniformIndexing(true); + features.setShaderStorageImageArrayNonUniformIndexing(true); + features.setShaderInputAttachmentArrayNonUniformIndexing(true); + features.setShaderUniformTexelBufferArrayNonUniformIndexing(true); + features.setShaderStorageTexelBufferArrayNonUniformIndexing(true); + + features.setDescriptorBindingUniformBufferUpdateAfterBind(true); + features.setDescriptorBindingSampledImageUpdateAfterBind(true); + features.setDescriptorBindingStorageImageUpdateAfterBind(true); + features.setDescriptorBindingStorageBufferUpdateAfterBind(true); + features.setDescriptorBindingUniformTexelBufferUpdateAfterBind(true); + features.setDescriptorBindingStorageTexelBufferUpdateAfterBind(true); + + features.setDescriptorBindingUpdateUnusedWhilePending(true); + features.setDescriptorBindingPartiallyBound(true); + features.setDescriptorBindingVariableDescriptorCount(true); + features.setRuntimeDescriptorArray(true); + } + ); + + vkcv::Core core = vkcv::Core::create( + applicationName, + VK_MAKE_VERSION(0, 0, 1), + { vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer }, + features + ); + + vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth,windowHeight,false); + + vkcv::asset::Scene mesh; + + // TEST DATA + std::vector<vkcv::Image> texturesArray; + const std::string grassPaths[5] = { "resources/cube/Grass001_1K_AmbientOcclusion.jpg", + "resources/cube/Grass001_1K_Color.jpg", + "resources/cube/Grass001_1K_Displacement.jpg", + "resources/cube/Grass001_1K_Normal.jpg", + "resources/cube/Grass001_1K_Roughness.jpg" }; + for(uint32_t i = 0; i < 5; i++) + { + std::filesystem::path grassPath(grassPaths[i]); + vkcv::asset::Texture grassTexture = vkcv::asset::loadTexture(grassPath); + + vkcv::Image texture = core.createImage(vk::Format::eR8G8B8A8Srgb, grassTexture.width, grassTexture.height); + texture.fill(grassTexture.data.data()); + texture.generateMipChainImmediate(); + texture.switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal); + + texturesArray.push_back(texture); + } + + const char* path = argc > 1 ? argv[1] : "resources/cube/cube.gltf"; + int result = vkcv::asset::loadScene(path, mesh); + + if (result == 1) { + std::cout << "Mesh loading successful!" << std::endl; + } else { + std::cerr << "Mesh loading failed: " << result << std::endl; + return 1; + } + + assert(!mesh.vertexGroups.empty()); + auto vertexBuffer = core.createBuffer<uint8_t>( + vkcv::BufferType::VERTEX, + mesh.vertexGroups[0].vertexBuffer.data.size(), + vkcv::BufferMemoryType::DEVICE_LOCAL + ); + + vertexBuffer.fill(mesh.vertexGroups[0].vertexBuffer.data); + + auto indexBuffer = core.createBuffer<uint8_t>( + vkcv::BufferType::INDEX, + mesh.vertexGroups[0].indexBuffer.data.size(), + vkcv::BufferMemoryType::DEVICE_LOCAL + ); + + indexBuffer.fill(mesh.vertexGroups[0].indexBuffer.data); + + // an example attachment for passes that output to the window + const vkcv::AttachmentDescription present_color_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + core.getSwapchain(windowHandle).getFormat() + ); + + const vkcv::AttachmentDescription depth_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + vk::Format::eD32Sfloat + ); + + vkcv::PassConfig firstMeshPassDefinition({ present_color_attachment, depth_attachment }); + vkcv::PassHandle firstMeshPass = core.createPass(firstMeshPassDefinition); + + if (!firstMeshPass) { + std::cerr << "Error. Could not create renderpass. Exiting." << std::endl; + return EXIT_FAILURE; + } + + 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); + }); + + 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); + }); + + const std::vector<vkcv::VertexAttachment> vertexAttachments = firstMeshProgram.getVertexAttachments(); + std::vector<vkcv::VertexBinding> bindings; + for (size_t i = 0; i < vertexAttachments.size(); i++) { + bindings.push_back(vkcv::VertexBinding(i, { vertexAttachments[i] })); + } + + const vkcv::VertexLayout firstMeshLayout (bindings); + + const std::unordered_map<uint32_t, vkcv::DescriptorBinding> &descriptorBindings = firstMeshProgram.getReflectedDescriptors().at(0); + + std::unordered_map<uint32_t, vkcv::DescriptorBinding> adjustedBindings = descriptorBindings; + adjustedBindings[1].descriptorCount = 6; + + vkcv::DescriptorSetLayoutHandle descriptorSetLayout = core.createDescriptorSetLayout(adjustedBindings); + vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout); + + const vkcv::GraphicsPipelineConfig firstMeshPipelineConfig { + firstMeshProgram, + UINT32_MAX, + UINT32_MAX, + firstMeshPass, + {firstMeshLayout}, + { core.getDescriptorSetLayout(descriptorSetLayout).vulkanHandle }, + true + }; + vkcv::GraphicsPipelineHandle firstMeshPipeline = core.createGraphicsPipeline(firstMeshPipelineConfig); + + if (!firstMeshPipeline) { + std::cerr << "Error. Could not create graphics pipeline. Exiting." << std::endl; + return EXIT_FAILURE; + } + + if (mesh.textures.empty()) { + std::cerr << "Error. No textures found. Exiting." << std::endl; + return EXIT_FAILURE; + } + + vkcv::asset::Texture &tex = mesh.textures[0]; + vkcv::Image texture = core.createImage(vk::Format::eR8G8B8A8Srgb, tex.w, tex.h); + texture.fill(tex.data.data()); + texture.generateMipChainImmediate(); + texture.switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal); + texturesArray.push_back(texture); + + vkcv::SamplerHandle sampler = core.createSampler( + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerMipmapMode::LINEAR, + vkcv::SamplerAddressMode::REPEAT + ); + + const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[0].offset), vertexBuffer.getVulkanHandle()), + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[1].offset), vertexBuffer.getVulkanHandle()), + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle()) }; + + vkcv::DescriptorWrites setWrites; + std::vector<vkcv::SampledImageDescriptorWrite> texturesArrayWrites; + for(uint32_t i = 0; i < 6; i++) + { + texturesArrayWrites.push_back(vkcv::SampledImageDescriptorWrite(1, + texturesArray[i].getHandle(), + 0, + false, + i)); + } + + setWrites.sampledImageWrites = texturesArrayWrites; + setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(0, sampler) }; + + core.writeDescriptorSet(descriptorSet, setWrites); + + vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight, 1, false).getHandle(); + + const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); + + const vkcv::Mesh renderMesh(vertexBufferBindings, indexBuffer.getVulkanHandle(), mesh.vertexGroups[0].numIndices); + + vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); + vkcv::DrawcallInfo drawcall(renderMesh, { descriptorUsage },1); + + vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); + uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); + uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); + + cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -3)); + + auto start = std::chrono::system_clock::now(); + + while (vkcv::Window::hasOpenWindow()) { + vkcv::Window::pollEvents(); + + if(core.getWindow(windowHandle).getHeight() == 0 || core.getWindow(windowHandle).getWidth() == 0) + continue; + + uint32_t swapchainWidth, swapchainHeight; + if (!core.beginFrame(swapchainWidth, swapchainHeight,windowHandle)) { + continue; + } + + if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) { + depthBuffer = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight).getHandle(); + + windowWidth = swapchainWidth; + windowHeight = swapchainHeight; + } + + auto end = std::chrono::system_clock::now(); + auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(end - start); + + start = end; + cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); + glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); + + vkcv::PushConstants pushConstants (sizeof(glm::mat4)); + pushConstants.appendDrawcall(mvp); + + const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; + auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); + + core.recordDrawcallsToCmdStream( + cmdStream, + firstMeshPass, + firstMeshPipeline, + pushConstants, + { drawcall }, + renderTargets, + windowHandle); + core.prepareSwapchainImageForPresent(cmdStream); + core.submitCommandStream(cmdStream); + core.endFrame(windowHandle); + } + + return 0; +} diff --git a/projects/first_scene/CMakeLists.txt b/projects/first_scene/CMakeLists.txt index ba2f7b1a7ae4845a12b9701269361a0a3f8affb7..21d6857e3b0086e31cc941659c7e8b3c57440922 100644 --- a/projects/first_scene/CMakeLists.txt +++ b/projects/first_scene/CMakeLists.txt @@ -22,7 +22,7 @@ if(MSVC) endif() # including headers of dependencies and the VkCV framework -target_include_directories(first_scene SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_scene_include} ${vkcv_shader_compiler_include}) +target_include_directories(first_scene SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_scene_include} ${vkcv_shader_compiler_include} ${vkcv_gui_include}) # linking with libraries from all dependencies and the VkCV framework -target_link_libraries(first_scene vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_scene vkcv_shader_compiler) +target_link_libraries(first_scene vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_scene vkcv_shader_compiler vkcv_gui) diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp index 4891fecbf8e0fc5dee3f9930b477aa03115916d2..a078776eb4b7688f51d45cecb7e08d5ba9d0d973 100644 --- a/projects/first_scene/src/main.cpp +++ b/projects/first_scene/src/main.cpp @@ -2,6 +2,7 @@ #include <vkcv/Core.hpp> #include <GLFW/glfw3.h> #include <vkcv/camera/CameraManager.hpp> +#include <vkcv/gui/GUI.hpp> #include <chrono> #include <vkcv/asset/asset_loader.hpp> #include <vkcv/shader/GLSLCompiler.hpp> @@ -23,7 +24,9 @@ int main(int argc, const char** argv) { vkcv::Window& window = core.getWindow(windowHandle); vkcv::camera::CameraManager cameraManager(window); - uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); + vkcv::gui::GUI gui (core, windowHandle); + + uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); cameraManager.getCamera(camIndex0).setPosition(glm::vec3(-8, 1, -0.5)); @@ -148,6 +151,18 @@ int main(int argc, const char** argv) { core.prepareSwapchainImageForPresent(cmdStream); core.submitCommandStream(cmdStream); + + auto stop = std::chrono::system_clock::now(); + auto kektime = std::chrono::duration_cast<std::chrono::microseconds>(stop - start); + + gui.beginGUI(); + + ImGui::Begin("Settings"); + ImGui::Text("Deltatime %fms, %f", 0.001 * static_cast<double>(kektime.count()), 1/(0.000001 * static_cast<double>(kektime.count()))); + ImGui::End(); + + gui.endGUI(); + core.endFrame(windowHandle); } diff --git a/projects/indirect_draw/.gitignore b/projects/indirect_draw/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..92714f6a3381225d29daff0d99efe51e12b40970 --- /dev/null +++ b/projects/indirect_draw/.gitignore @@ -0,0 +1 @@ +indirect_draw \ No newline at end of file diff --git a/projects/indirect_draw/CMakeLists.txt b/projects/indirect_draw/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a1bc8073a4105b291f0b3177cb6d252f8ce9e9a4 --- /dev/null +++ b/projects/indirect_draw/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.16) +project(indirect_draw) + +# setting c++ standard for the project +set(CMAKE_CXX_STANDARD 17) +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(indirect_draw src/main.cpp) + +# this should fix the execution path to load local files from the project (for MSVC) +if(MSVC) + set_target_properties(indirect_draw PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + set_target_properties(indirect_draw PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + + # in addition to setting the output directory, the working directory has to be set + # by default visual studio sets the working directory to the build directory, when using the debugger + set_target_properties(indirect_draw PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +endif() + +# including headers of dependencies and the VkCV framework +target_include_directories(indirect_draw SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include} ${vkcv_gui_include}) + +# linking with libraries from all dependencies and the VkCV framework +target_link_libraries(indirect_draw vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_shader_compiler vkcv_gui) diff --git a/projects/indirect_draw/resources/Sponza/Sponza.bin b/projects/indirect_draw/resources/Sponza/Sponza.bin new file mode 100644 index 0000000000000000000000000000000000000000..cfedd26ca5a67b6d0a47d44d13a75e14a141717a --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/Sponza.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b809f7a17687dc99e6f41ca1ea32c06eded8779bf34d16f1f565d750b0ffd68 +size 6347696 diff --git a/projects/indirect_draw/resources/Sponza/Sponza.gltf b/projects/indirect_draw/resources/Sponza/Sponza.gltf new file mode 100644 index 0000000000000000000000000000000000000000..172ea07e21c94465211c860cd805355704cef230 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/Sponza.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cc0ecad5c4694088ff820e663619c370421afc1323ac487406e8e9b4735d787 +size 713962 diff --git a/projects/indirect_draw/resources/Sponza/SponzaFloor.bin b/projects/indirect_draw/resources/Sponza/SponzaFloor.bin new file mode 100644 index 0000000000000000000000000000000000000000..684251288f35070d2e7d244877fd844cc00ca632 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/SponzaFloor.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:678455aca641cb1f449aa1a5054a7cae132be81c2b333aac283053967da66df0 +size 512 diff --git a/projects/indirect_draw/resources/Sponza/SponzaFloor.gltf b/projects/indirect_draw/resources/Sponza/SponzaFloor.gltf new file mode 100644 index 0000000000000000000000000000000000000000..b45f1c55ef85f2aa1d4bff01df3d9625aa38c809 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/SponzaFloor.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6deb75441b1138b50a6b0eec05e60df276fe8fb6d58118fdfce2090b6fbe734 +size 3139 diff --git a/projects/indirect_draw/resources/Sponza/background.png b/projects/indirect_draw/resources/Sponza/background.png new file mode 100644 index 0000000000000000000000000000000000000000..b64def129da38f4e23d89e21b4af1039008a4327 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/background.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5b5f900ff8ed83a31750ec8e428b5b91273794ddcbfc4e4b8a6a7e781f8c686 +size 1417666 diff --git a/projects/indirect_draw/resources/Sponza/chain_texture.png b/projects/indirect_draw/resources/Sponza/chain_texture.png new file mode 100644 index 0000000000000000000000000000000000000000..c1e1768cff78e0614ad707eca8602a4c4edab5e5 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/chain_texture.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8362cfd472880daeaea37439326a4651d1338680ae69bb2513fc6b17c8de7d4 +size 490895 diff --git a/projects/indirect_draw/resources/Sponza/lion.png b/projects/indirect_draw/resources/Sponza/lion.png new file mode 100644 index 0000000000000000000000000000000000000000..c49c7f0ed31e762e19284d0d3624fbc47664e56b --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/lion.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f882f746c3a9cd51a9c6eedc1189b97668721d91a3fe49232036e789912c652 +size 2088728 diff --git a/projects/indirect_draw/resources/Sponza/spnza_bricks_a_diff.png b/projects/indirect_draw/resources/Sponza/spnza_bricks_a_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..cde4c7a6511e9a5f03c63ad996437fcdba3ce2df --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/spnza_bricks_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b94219c2f5f943f3f4715c74e7d1038bf0ab3b3b3216a758eaee67f875df0851 +size 1928829 diff --git a/projects/indirect_draw/resources/Sponza/sponza_arch_diff.png b/projects/indirect_draw/resources/Sponza/sponza_arch_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..bcd9bda2918d226039f9e2d03902d377b706fab6 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_arch_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0df2c8a01b2843b1c792b494f7173cdbc4f834840fc2177af3e5d690fceda57 +size 1596151 diff --git a/projects/indirect_draw/resources/Sponza/sponza_ceiling_a_diff.png b/projects/indirect_draw/resources/Sponza/sponza_ceiling_a_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..59de631ffac4414cabf69b2dc794c46fc187d6cb --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_ceiling_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab6c187a81aa68f4eba30119e17fce2e4882a9ec320f70c90482dbe9da82b1c6 +size 1872074 diff --git a/projects/indirect_draw/resources/Sponza/sponza_column_a_diff.png b/projects/indirect_draw/resources/Sponza/sponza_column_a_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..01a82432d3f9939bbefe850bdb900f1ff9a3f6db --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_column_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c291507e2808bb83e160ab4b020689817df273baad3713a9ad19ac15fac6826 +size 1840992 diff --git a/projects/indirect_draw/resources/Sponza/sponza_column_b_diff.png b/projects/indirect_draw/resources/Sponza/sponza_column_b_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..10a660cce2a5a9b8997772c746058ce23e7d45d7 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_column_b_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2820b0267c4289c6cedbb42721792a57ef244ec2d0935941011c2a7d3fe88a9b +size 2170433 diff --git a/projects/indirect_draw/resources/Sponza/sponza_column_c_diff.png b/projects/indirect_draw/resources/Sponza/sponza_column_c_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..bc46fd979044a938d3adca7601689e71504e48bf --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_column_c_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0bc993ff59865468ef4530798930c7dfefb07482d71db45bc2a520986b27735 +size 2066950 diff --git a/projects/indirect_draw/resources/Sponza/sponza_curtain_blue_diff.png b/projects/indirect_draw/resources/Sponza/sponza_curtain_blue_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..384c8c2c051160d530eb3ac8b05c9c60752a2d2b --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_curtain_blue_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b85c6bb3cd5105f48d3812ec8e7a1068521ce69e917300d79e136e19d45422fb +size 9510905 diff --git a/projects/indirect_draw/resources/Sponza/sponza_curtain_diff.png b/projects/indirect_draw/resources/Sponza/sponza_curtain_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..af842e9f5fe18c1f609875e00899a6770fa4488b --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_curtain_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:563c56bdbbee395a6ef7f0c51c8ac9223c162e517b4cdba0d4654e8de27c98d8 +size 9189263 diff --git a/projects/indirect_draw/resources/Sponza/sponza_curtain_green_diff.png b/projects/indirect_draw/resources/Sponza/sponza_curtain_green_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..6c9b6391a199407637fa71033d79fb58b8b4f0d7 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_curtain_green_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:238fe1c7f481388d1c1d578c2da8d411b99e8f0030ab62060a306db333124476 +size 8785458 diff --git a/projects/indirect_draw/resources/Sponza/sponza_details_diff.png b/projects/indirect_draw/resources/Sponza/sponza_details_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..12656686362c3e0a297e060491f33bd7351551f9 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_details_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb1223b3bb82f8757e7df25a6891f1239cdd7ec59990340e952fb2d6b7ea570c +size 1522643 diff --git a/projects/indirect_draw/resources/Sponza/sponza_fabric_blue_diff.png b/projects/indirect_draw/resources/Sponza/sponza_fabric_blue_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..879d16ef84722a4fc13e83a771778de326e4bc54 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_fabric_blue_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:467d290bf5d4b2a017da140ba9e244ed8a8a9be5418a9ac9bcb4ad572ae2d7ab +size 2229440 diff --git a/projects/indirect_draw/resources/Sponza/sponza_fabric_diff.png b/projects/indirect_draw/resources/Sponza/sponza_fabric_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..3311287a219d2148620b87fe428fea071688d051 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_fabric_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1594f59cc2848db26add47361f4e665e3d8afa147760ed915d839fea42b20287 +size 2267382 diff --git a/projects/indirect_draw/resources/Sponza/sponza_fabric_green_diff.png b/projects/indirect_draw/resources/Sponza/sponza_fabric_green_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..de110f369004388dae4cd5067c63428db3a07834 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_fabric_green_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:902b87faab221173bf370cea7c74cb9060b4d870ac6316b190dafded1cb12993 +size 2258220 diff --git a/projects/indirect_draw/resources/Sponza/sponza_flagpole_diff.png b/projects/indirect_draw/resources/Sponza/sponza_flagpole_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..5f6e0812a0df80346318baa3cb50a6888afc58f8 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_flagpole_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfffb62e770959c725d0f3db6dc7dbdd46a380ec55ef884dab94d44ca017b438 +size 1425673 diff --git a/projects/indirect_draw/resources/Sponza/sponza_floor_a_diff.png b/projects/indirect_draw/resources/Sponza/sponza_floor_a_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..788ed764f79ba724f04a2d603076a5b85013e188 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_floor_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a16f9230fa91f9f31dfca6216ce205f1ef132d44f3b012fbf6efc0fba69770ab +size 1996838 diff --git a/projects/indirect_draw/resources/Sponza/sponza_roof_diff.png b/projects/indirect_draw/resources/Sponza/sponza_roof_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..c5b84261fdd1cc776a94b3ce398c7806b895f9a3 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_roof_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fc412138c20da19f8173e53545e771f4652558dff624d4dc67143e40efe562b +size 2320533 diff --git a/projects/indirect_draw/resources/Sponza/sponza_thorn_diff.png b/projects/indirect_draw/resources/Sponza/sponza_thorn_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..7a9142674a7d4a6f94a48c5152cf0300743b597a --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/sponza_thorn_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a73a17c883cd0d0d67cfda2dc4118400a916366c05b9a5ac465f0c8b30fd9c8e +size 635001 diff --git a/projects/indirect_draw/resources/Sponza/vase_dif.png b/projects/indirect_draw/resources/Sponza/vase_dif.png new file mode 100644 index 0000000000000000000000000000000000000000..61236a81cb324af8797b05099cd264cefe189e56 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/vase_dif.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53d06f52bf9e59df4cf00237707cca76c4f692bda61a62b06a30d321311d6dd9 +size 1842101 diff --git a/projects/indirect_draw/resources/Sponza/vase_hanging.png b/projects/indirect_draw/resources/Sponza/vase_hanging.png new file mode 100644 index 0000000000000000000000000000000000000000..36a3cee71d8213225090c74f8c0dce33b9d44378 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/vase_hanging.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9d10b4f27a3c9a78d5bac882fdd4b6a6987c262f48fa490670fe5e235951e31 +size 1432804 diff --git a/projects/indirect_draw/resources/Sponza/vase_plant.png b/projects/indirect_draw/resources/Sponza/vase_plant.png new file mode 100644 index 0000000000000000000000000000000000000000..7ad95e702e229f1ebd803e5203a266d15f2c07b9 --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/vase_plant.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2087371ff02212fb7014b6daefa191cf5676d2227193fff261a5d02f554cb8e +size 998089 diff --git a/projects/indirect_draw/resources/Sponza/vase_round.png b/projects/indirect_draw/resources/Sponza/vase_round.png new file mode 100644 index 0000000000000000000000000000000000000000..c17953abc000c44b8991e23c136c2b67348f3d1b --- /dev/null +++ b/projects/indirect_draw/resources/Sponza/vase_round.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa23d48d492d5d4ada2ddb27d1ef22952b214e6eb3b301c65f9d88442723d20a +size 1871399 diff --git a/projects/indirect_draw/resources/Szene/Szene.bin b/projects/indirect_draw/resources/Szene/Szene.bin new file mode 100644 index 0000000000000000000000000000000000000000..c87d27637516b0bbf864251dd162773f5cc53e06 --- /dev/null +++ b/projects/indirect_draw/resources/Szene/Szene.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee4742718f720d589a2a03f5d879f8c50ba9057718d191a43b046eaa9071080d +size 70328 diff --git a/projects/indirect_draw/resources/Szene/Szene.gltf b/projects/indirect_draw/resources/Szene/Szene.gltf new file mode 100644 index 0000000000000000000000000000000000000000..e5a32b29af5d0a2ac5f497e60b4b92c1873e1df9 --- /dev/null +++ b/projects/indirect_draw/resources/Szene/Szene.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75ba834118792ebbacf528a1690c7d04df4b4c8122b9f99a9aa9a9d075d2c86a +size 7421 diff --git a/projects/indirect_draw/resources/Szene/boards2_vcyc.jpg b/projects/indirect_draw/resources/Szene/boards2_vcyc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/indirect_draw/resources/Szene/boards2_vcyc.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/indirect_draw/resources/Szene/boards2_vcyc_jpg.jpg b/projects/indirect_draw/resources/Szene/boards2_vcyc_jpg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/indirect_draw/resources/Szene/boards2_vcyc_jpg.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/indirect_draw/resources/cube/Grass001_1K_AmbientOcclusion.jpg b/projects/indirect_draw/resources/cube/Grass001_1K_AmbientOcclusion.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2217fb53744f9166232a40b78ee9518e04b0ded5 --- /dev/null +++ b/projects/indirect_draw/resources/cube/Grass001_1K_AmbientOcclusion.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6c88f8f3facd9e91f8dd160bd8c4a602e433872ed18e08015a9fa9dfff889de +size 901465 diff --git a/projects/indirect_draw/resources/cube/Grass001_1K_Color.jpg b/projects/indirect_draw/resources/cube/Grass001_1K_Color.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b8aa1533ae5a023a5fc8457f30ed60efe3bda32d --- /dev/null +++ b/projects/indirect_draw/resources/cube/Grass001_1K_Color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:878b8fe4747d9ce693220edea1915de550e8f14d402d26a0915f162d40f84e91 +size 1763328 diff --git a/projects/indirect_draw/resources/cube/Grass001_1K_Displacement.jpg b/projects/indirect_draw/resources/cube/Grass001_1K_Displacement.jpg new file mode 100644 index 0000000000000000000000000000000000000000..89789cba150eea7c7abbdc1851090f6021af978a --- /dev/null +++ b/projects/indirect_draw/resources/cube/Grass001_1K_Displacement.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e8300e1107bee7e681059d9da0a7e3ca422977e8b6f496e16452a4c94b3d385 +size 912347 diff --git a/projects/indirect_draw/resources/cube/Grass001_1K_Normal.jpg b/projects/indirect_draw/resources/cube/Grass001_1K_Normal.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3163d6391592ace10446cb71141a2192e63e9660 --- /dev/null +++ b/projects/indirect_draw/resources/cube/Grass001_1K_Normal.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:684426b49e841e267f12f06dc955b5b1d01b3ba3659bea0c5d73be889700929f +size 2336471 diff --git a/projects/indirect_draw/resources/cube/Grass001_1K_Roughness.jpg b/projects/indirect_draw/resources/cube/Grass001_1K_Roughness.jpg new file mode 100644 index 0000000000000000000000000000000000000000..10e6ac33badf2a4795766a66546a62c67eb8b558 --- /dev/null +++ b/projects/indirect_draw/resources/cube/Grass001_1K_Roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d952ffb098faf9ac5eb25134eabac08f0c65d927a448b5e7b4f9c72510cfcbe0 +size 822659 diff --git a/projects/indirect_draw/resources/cube/boards2_vcyc_jpg.jpg b/projects/indirect_draw/resources/cube/boards2_vcyc_jpg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/indirect_draw/resources/cube/boards2_vcyc_jpg.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/indirect_draw/resources/cube/cube.bin b/projects/indirect_draw/resources/cube/cube.bin new file mode 100644 index 0000000000000000000000000000000000000000..3303cd8635848bee18e10ab8754d5e4e7218db92 --- /dev/null +++ b/projects/indirect_draw/resources/cube/cube.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bb9b6b8bbe50a0aaa517057f245ee844f80afa7426dacb2aed4128f71629ce4 +size 840 diff --git a/projects/indirect_draw/resources/cube/cube.blend b/projects/indirect_draw/resources/cube/cube.blend new file mode 100644 index 0000000000000000000000000000000000000000..62ccb2c742094bcfb5ed194ab905bffae86bfd65 --- /dev/null +++ b/projects/indirect_draw/resources/cube/cube.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6c1e245f259c610528c9485db6688928faac0ab2addee9e3c2dde7740e4dd09 +size 774920 diff --git a/projects/indirect_draw/resources/cube/cube.blend1 b/projects/indirect_draw/resources/cube/cube.blend1 new file mode 100644 index 0000000000000000000000000000000000000000..13f21dcca218d7bc7a07a8a9682b5e1d9e607736 --- /dev/null +++ b/projects/indirect_draw/resources/cube/cube.blend1 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4496f423569b8ca81f3b3a55fad00f925557e0193fb9dbe6cdce7e71fb48f7b +size 774920 diff --git a/projects/indirect_draw/resources/cube/cube.glb b/projects/indirect_draw/resources/cube/cube.glb new file mode 100644 index 0000000000000000000000000000000000000000..66a42c65e71dcf375e04cc378256024dd3c7834d --- /dev/null +++ b/projects/indirect_draw/resources/cube/cube.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:198568b715f397d78f7c358c0f709a419e7fd677e54cdec7c19f71b5ed264897 +size 1194508 diff --git a/projects/indirect_draw/resources/cube/cube.gltf b/projects/indirect_draw/resources/cube/cube.gltf new file mode 100644 index 0000000000000000000000000000000000000000..428176144843dd06c78fe1d11a6392a0ea02b22d --- /dev/null +++ b/projects/indirect_draw/resources/cube/cube.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f82f455647a84ca6242882ae26a79a499d3ce594f8de317ab89488c5b79721ac +size 2823 diff --git a/projects/indirect_draw/resources/shaders/culling.comp b/projects/indirect_draw/resources/shaders/culling.comp new file mode 100644 index 0000000000000000000000000000000000000000..5d5884b9e494baf56ab32576f094f34584b163b3 --- /dev/null +++ b/projects/indirect_draw/resources/shaders/culling.comp @@ -0,0 +1,58 @@ +#version 460 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_EXT_nonuniform_qualifier : enable + +layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; + +struct Plane{ + vec3 pointOnPlane; + float padding0; + vec3 normal; + float padding1; +}; + +struct DrawCommand{ + uint indexCount; + uint instanceCount; + uint firstIndex; + int vertexOffset; + uint firstInstance; +}; + +layout(set=0, binding=0, std140) readonly uniform cameraPlaneBuffer{ + Plane cameraPlanes[6]; +}; + +layout(set=0, binding=1, std430) buffer DrawCommandsBuffer{ + DrawCommand commands[]; +}; + +layout(set=0, binding=2, std430) readonly buffer boundingBoxBuffer{ + // x,y,z for meanPosition; + // w for boundingSphereRadius + vec4 boundingBoxes[]; +}; + +bool isSphereInsideFrustum(vec3 spherePos, float sphereRadius){ + bool isInside = true; + for(int i = 0; i < 6; i++){ + Plane p = cameraPlanes[i]; + isInside = isInside && dot(p.normal, spherePos - p.pointOnPlane) - sphereRadius < 0; + } + return isInside; +} + +void main(){ + if(gl_GlobalInvocationID.x > commands.length()){ + return; + } + + vec4 bbox = boundingBoxes[gl_GlobalInvocationID.x]; + if (isSphereInsideFrustum(bbox.xyz, bbox.w)){ + commands[gl_GlobalInvocationID.x].instanceCount = 1; + } + else{ + commands[gl_GlobalInvocationID.x].instanceCount = 0; + } +} + diff --git a/projects/indirect_draw/resources/shaders/shader.frag b/projects/indirect_draw/resources/shaders/shader.frag new file mode 100644 index 0000000000000000000000000000000000000000..f0a0b49314926ef9195d9a145b805b55d17b8807 --- /dev/null +++ b/projects/indirect_draw/resources/shaders/shader.frag @@ -0,0 +1,18 @@ +#version 460 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_EXT_nonuniform_qualifier : enable + +layout(location = 0) in vec3 passNormal; +layout(location = 1) in vec2 passUV; +layout(location = 2) in flat uint passDrawIndex; + +layout(location = 0) out vec3 outColor; + +layout(set=0, binding=0) uniform sampler standardSampler; +layout(set=0, binding=2) uniform texture2D baseColorTex[]; + + +void main() +{ + outColor = texture(sampler2D(baseColorTex[nonuniformEXT(passDrawIndex)], standardSampler), passUV).rgb; +} \ No newline at end of file diff --git a/projects/indirect_draw/resources/shaders/shader.vert b/projects/indirect_draw/resources/shaders/shader.vert new file mode 100644 index 0000000000000000000000000000000000000000..10b250761437dce6eea01dd195e1248fc9c0bd90 --- /dev/null +++ b/projects/indirect_draw/resources/shaders/shader.vert @@ -0,0 +1,27 @@ +#version 460 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shader_draw_parameters : enable + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inNormal; +layout(location = 2) in vec2 inUV; + +layout(std430, binding=1) readonly buffer uModel { + mat4 modelMatrix[]; +}; + +layout(location = 0) out vec3 passNormal; +layout(location = 1) out vec2 passUV; +layout(location = 2) out flat uint passDrawIndex; + +layout( push_constant ) uniform constants{ + mat4 vp; +}; + +void main() +{ + gl_Position = vp * modelMatrix[gl_DrawID] * vec4(inPosition, 1.0); + passNormal = inNormal; + passUV = inUV; + passDrawIndex = gl_DrawID; +} \ No newline at end of file diff --git a/projects/indirect_draw/resources/triangle/Triangle.bin b/projects/indirect_draw/resources/triangle/Triangle.bin new file mode 100644 index 0000000000000000000000000000000000000000..57f26ad96592b64377e6aa93823d96a94e6c5022 --- /dev/null +++ b/projects/indirect_draw/resources/triangle/Triangle.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:412ebd5f7242c266b4957e7e26be13aa331dbcb7bbb854ab334a2437ae8ed959 +size 104 diff --git a/projects/indirect_draw/resources/triangle/Triangle.blend b/projects/indirect_draw/resources/triangle/Triangle.blend new file mode 100644 index 0000000000000000000000000000000000000000..2421dc5e1bb029d73a9ec09cc4530c5196851fd7 --- /dev/null +++ b/projects/indirect_draw/resources/triangle/Triangle.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:387e544df173219fbf292a64a6656d1d782bbf71a5a9e9fdef0a308f47b05477 +size 758144 diff --git a/projects/indirect_draw/resources/triangle/Triangle.glb b/projects/indirect_draw/resources/triangle/Triangle.glb new file mode 100644 index 0000000000000000000000000000000000000000..4148620cd6af0dadbc791aa1c52bb5431a40884b --- /dev/null +++ b/projects/indirect_draw/resources/triangle/Triangle.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4be087a605212d139416b5352a018283b26b99260cbcddb7013a1beeb331227 +size 980 diff --git a/projects/indirect_draw/resources/triangle/Triangle.gltf b/projects/indirect_draw/resources/triangle/Triangle.gltf new file mode 100644 index 0000000000000000000000000000000000000000..a188e6ee16a5e8486cf307c7bda8cfd99bdbeea6 --- /dev/null +++ b/projects/indirect_draw/resources/triangle/Triangle.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5fc354e040f79cff329e919677b194c75e3a522c6406f75c1108ad9575f12ec +size 2202 diff --git a/projects/indirect_draw/src/main.cpp b/projects/indirect_draw/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..88e7005f2912bb448980bd4c1219245481f1559a --- /dev/null +++ b/projects/indirect_draw/src/main.cpp @@ -0,0 +1,619 @@ +#include <iostream> +#include <vkcv/Core.hpp> +#include <vkcv/camera/CameraManager.hpp> +#include <chrono> +#include <vkcv/gui/GUI.hpp> +#include <vkcv/asset/asset_loader.hpp> +#include <vkcv/shader/GLSLCompiler.hpp> + +struct Plane { + glm::vec3 pointOnPlane; + float padding0; + glm::vec3 normal; + float padding1; +}; + +struct CameraPlanes { + Plane planes[6]; +}; + +CameraPlanes computeCameraPlanes(const vkcv::camera::Camera& camera) { + const float fov = camera.getFov(); + const glm::vec3 pos = camera.getPosition(); + const float ratio = camera.getRatio(); + const glm::vec3 forward = glm::normalize(camera.getFront()); + float near; + float far; + camera.getNearFar(near, far); + + glm::vec3 up = glm::vec3(0, -1, 0); + glm::vec3 right = glm::normalize(glm::cross(forward, up)); + up = glm::cross(forward, right); + + const glm::vec3 nearCenter = pos + forward * near; + const glm::vec3 farCenter = pos + forward * far; + + const float tanFovHalf = glm::tan(fov / 2); + + const glm::vec3 nearUpCenter = nearCenter + up * tanFovHalf * near; + const glm::vec3 nearDownCenter = nearCenter - up * tanFovHalf * near; + const glm::vec3 nearRightCenter = nearCenter + right * tanFovHalf * near * ratio; + const glm::vec3 nearLeftCenter = nearCenter - right * tanFovHalf * near * ratio; + + const glm::vec3 farUpCenter = farCenter + up * tanFovHalf * far; + const glm::vec3 farDownCenter = farCenter - up * tanFovHalf * far; + const glm::vec3 farRightCenter = farCenter + right * tanFovHalf * far * ratio; + const glm::vec3 farLeftCenter = farCenter - right * tanFovHalf * far * ratio; + + CameraPlanes cameraPlanes; + // near + cameraPlanes.planes[0].pointOnPlane = nearCenter; + cameraPlanes.planes[0].normal = -forward; + // far + cameraPlanes.planes[1].pointOnPlane = farCenter; + cameraPlanes.planes[1].normal = forward; + + // top + cameraPlanes.planes[2].pointOnPlane = nearUpCenter; + cameraPlanes.planes[2].normal = glm::normalize(glm::cross(farUpCenter - nearUpCenter, right)); + // bot + cameraPlanes.planes[3].pointOnPlane = nearDownCenter; + cameraPlanes.planes[3].normal = glm::normalize(glm::cross(right, farDownCenter - nearDownCenter)); + + // right + cameraPlanes.planes[4].pointOnPlane = nearRightCenter; + cameraPlanes.planes[4].normal = glm::normalize(glm::cross(up, farRightCenter - nearRightCenter)); + // left + cameraPlanes.planes[5].pointOnPlane = nearLeftCenter; + cameraPlanes.planes[5].normal = glm::normalize(glm::cross(farLeftCenter - nearLeftCenter, up)); + + return cameraPlanes; +} + +struct Vertex +{ + glm::vec3 position; + glm::vec3 normal; + glm::vec2 uv; +}; + +struct CompiledMaterial +{ + std::vector<vkcv::Image> baseColor; + std::vector<vkcv::Image> metalRough; + std::vector<vkcv::Image> normal; + std::vector<vkcv::Image> occlusion; +}; + +void interleaveScene(vkcv::asset::Scene scene, + std::vector<std::vector<Vertex>> &interleavedVertexBuffers, + std::vector<glm::vec4> &boundingBoxBuffers) +{ + for(const auto &mesh : scene.meshes) + { + for(auto vertexGroupIndex : mesh.vertexGroups) + { + // Sort attributes to fix it! + auto& attributes = scene.vertexGroups[vertexGroupIndex].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); + }); + + const auto &vertexGroup = scene.vertexGroups[vertexGroupIndex]; + + const vkcv::asset::VertexAttribute positionAttribute = vertexGroup.vertexBuffer.attributes[0]; + const vkcv::asset::VertexAttribute normalAttribute = vertexGroup.vertexBuffer.attributes[1]; + const vkcv::asset::VertexAttribute uvAttribute = vertexGroup.vertexBuffer.attributes[2]; + + assert(positionAttribute.type == vkcv::asset::PrimitiveType::POSITION); + assert(normalAttribute.type == vkcv::asset::PrimitiveType::NORMAL); + assert(uvAttribute.type == vkcv::asset::PrimitiveType::TEXCOORD_0); + + const uint64_t &verticesCount = vertexGroup.numVertices; + const std::vector<uint8_t> &vertexData = vertexGroup.vertexBuffer.data; + + std::vector<Vertex> vertices; + vertices.reserve(verticesCount); + + const size_t positionStride = positionAttribute.stride == 0 ? sizeof(glm::vec3) : positionAttribute.stride; + const size_t normalStride = normalAttribute.stride == 0 ? sizeof(glm::vec3) : normalAttribute.stride; + const size_t uvStride = uvAttribute.stride == 0 ? sizeof(glm::vec2) : uvAttribute.stride; + + glm::vec3 max_pos(-std::numeric_limits<float>::max()); + glm::vec3 min_pos(std::numeric_limits<float>::max()); + + for(size_t i = 0; i < verticesCount; i++) + { + const size_t positionOffset = positionAttribute.offset + positionStride * i; + const size_t normalOffset = normalAttribute.offset + normalStride * i; + const size_t uvOffset = uvAttribute.offset + uvStride * i; + + Vertex v; + + v.position = *reinterpret_cast<const glm::vec3*>(&(vertexData[positionOffset])); + v.normal = *reinterpret_cast<const glm::vec3*>(&(vertexData[normalOffset])); + v.uv = *reinterpret_cast<const glm::vec3*>(&(vertexData[uvOffset])); + + glm::vec3 posWorld = glm::make_mat4(mesh.modelMatrix.data()) * glm::vec4(v.position, 1); + + max_pos.x = glm::max(max_pos.x, posWorld.x); + max_pos.y = glm::max(max_pos.y, posWorld.y); + max_pos.z = glm::max(max_pos.z, posWorld.z); + + min_pos.x = glm::min(min_pos.x, posWorld.x); + min_pos.y = glm::min(min_pos.y, posWorld.y); + min_pos.z = glm::min(min_pos.z, posWorld.z); + + vertices.push_back(v); + } + + const glm::vec3 boundingPosition = (max_pos + min_pos) / 2.0f; + const float radius = glm::distance(max_pos, min_pos) / 2.0f; + + boundingBoxBuffers.emplace_back(boundingPosition.x, + boundingPosition.y, + boundingPosition.z, + radius); + + interleavedVertexBuffers.push_back(vertices); + } + } +} + +// Assumes the meshes use index buffers +void compileMeshForIndirectDraw(vkcv::Core &core, + const vkcv::asset::Scene &scene, + std::vector<uint8_t> &compiledVertexBuffer, + std::vector<uint8_t> &compiledIndexBuffer, + CompiledMaterial &compiledMat, + std::vector<vk::DrawIndexedIndirectCommand> &indexedIndirectCommands) +{ + vkcv::Image pseudoImg = core.createImage(vk::Format::eR8G8B8A8Srgb, 2, 2); + std::vector<uint8_t> pseudoData = {0, 0, 0, 0}; + pseudoImg.fill(pseudoData.data()); + pseudoImg.switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal); + + uint32_t vertexOffset = 0; + for (const auto &mesh : scene.meshes) + { + for(auto &vertexGroupIndex : mesh.vertexGroups) + { + auto &vertexGroup = scene.vertexGroups[vertexGroupIndex]; + + auto &material = scene.materials[vertexGroup.materialIndex]; + + if(material.baseColor == -1) + { + std::cout << "baseColor is -1! Pushing pseudo-texture!" << std::endl; + compiledMat.baseColor.push_back(pseudoImg); + } + else + { + auto &baseColor = scene.textures[material.baseColor]; + + vkcv::Image baseColorImg = core.createImage(vk::Format::eR8G8B8A8Srgb, baseColor.w, baseColor.h); + baseColorImg.fill(baseColor.data.data()); + baseColorImg.generateMipChainImmediate(); + baseColorImg.switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal); + + compiledMat.baseColor.push_back(baseColorImg); + } + + indexedIndirectCommands.emplace_back(static_cast<uint32_t>(vertexGroup.numIndices), + 1, + static_cast<uint32_t>(compiledIndexBuffer.size() / 4), + vertexOffset, + static_cast<uint32_t>(indexedIndirectCommands.size())); + + vertexOffset += vertexGroup.numVertices; + + compiledVertexBuffer.insert(compiledVertexBuffer.end(), + vertexGroup.vertexBuffer.data.begin(), + vertexGroup.vertexBuffer.data.end()); + + if(vertexGroup.indexBuffer.type == vkcv::asset::IndexType::UINT8) + { + for(auto index : vertexGroup.indexBuffer.data) + { + uint32_t index32 = static_cast<uint32_t>(index); + uint8_t firstByte = index32; + uint8_t secondByte = index32 >> 8; + uint8_t thirdByte = index32 >> 16; + uint8_t fourthByte = index32 >> 24; + + compiledIndexBuffer.push_back(firstByte); + compiledIndexBuffer.push_back(secondByte); + compiledIndexBuffer.push_back(thirdByte); + compiledIndexBuffer.push_back(fourthByte); + } + } + else if(vertexGroup.indexBuffer.type == vkcv::asset::IndexType::UINT16) + { + for (size_t i = 0; i < vertexGroup.indexBuffer.data.size(); i += 2) + { + uint16_t index16 = *reinterpret_cast<const uint16_t*>(&vertexGroup.indexBuffer.data[i]); + uint32_t index32 = static_cast<uint32_t>(index16); + + uint8_t firstByte = index32; + uint8_t secondByte = index32 >> 8; + uint8_t thirdByte = index32 >> 16; + uint8_t fourthByte = index32 >> 24; + + compiledIndexBuffer.push_back(firstByte); + compiledIndexBuffer.push_back(secondByte); + compiledIndexBuffer.push_back(thirdByte); + compiledIndexBuffer.push_back(fourthByte); + } + } + else + { + compiledIndexBuffer.insert(compiledIndexBuffer.end(), + vertexGroup.indexBuffer.data.begin(), + vertexGroup.indexBuffer.data.end()); + } + } + } +} + +int main(int argc, const char** argv) { + const char* applicationName = "Indirect draw"; + + uint32_t windowWidth = 800; + uint32_t windowHeight = 600; + + vkcv::Features features; + features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + features.requireFeature([](vk::PhysicalDeviceFeatures &features){ + features.setMultiDrawIndirect(true); + }); + + features.requireExtension(VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME); + features.requireExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); + features.requireExtensionFeature<vk::PhysicalDeviceDescriptorIndexingFeatures>( + VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, [](vk::PhysicalDeviceDescriptorIndexingFeatures &features) { + // features.setShaderInputAttachmentArrayDynamicIndexing(true); + features.setShaderUniformTexelBufferArrayDynamicIndexing(true); + features.setShaderStorageTexelBufferArrayDynamicIndexing(true); + features.setShaderUniformBufferArrayNonUniformIndexing(true); + features.setShaderSampledImageArrayNonUniformIndexing(true); + features.setShaderStorageBufferArrayNonUniformIndexing(true); + features.setShaderStorageImageArrayNonUniformIndexing(true); + // features.setShaderInputAttachmentArrayNonUniformIndexing(true); + features.setShaderUniformTexelBufferArrayNonUniformIndexing(true); + features.setShaderStorageTexelBufferArrayNonUniformIndexing(true); + + features.setDescriptorBindingUniformBufferUpdateAfterBind(true); + features.setDescriptorBindingSampledImageUpdateAfterBind(true); + features.setDescriptorBindingStorageImageUpdateAfterBind(true); + features.setDescriptorBindingStorageBufferUpdateAfterBind(true); + features.setDescriptorBindingUniformTexelBufferUpdateAfterBind(true); + features.setDescriptorBindingStorageTexelBufferUpdateAfterBind(true); + + features.setDescriptorBindingUpdateUnusedWhilePending(true); + features.setDescriptorBindingPartiallyBound(true); + features.setDescriptorBindingVariableDescriptorCount(true); + features.setRuntimeDescriptorArray(true); + } + ); + + + vkcv::Core core = vkcv::Core::create( + applicationName, + VK_MAKE_VERSION(0, 0, 1), + { vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer }, + features + ); + + vkcv::WindowHandle windowHandle = core.createWindow(applicationName,windowWidth,windowHeight,false); + + vkcv::gui::GUI gui (core, windowHandle); + + vkcv::asset::Scene asset_scene; + const char* path = argc > 1 ? argv[1] : "resources/Sponza/Sponza.gltf"; + int result = vkcv::asset::loadScene(path, asset_scene); + + if (result == 1) { + std::cout << "Loading Sponza successful!" << std::endl; + } else { + std::cerr << "Loading Sponza failed: " << result << std::endl; + return 1; + } + assert(!asset_scene.vertexGroups.empty()); + if (asset_scene.textures.empty()) + { + std::cerr << "Error. No textures found. Exiting." << std::endl; + return EXIT_FAILURE; + } + + const vkcv::AttachmentDescription present_color_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + core.getSwapchain(windowHandle).getFormat() + ); + const vkcv::AttachmentDescription depth_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + vk::Format::eD32Sfloat + ); + + vkcv::PassConfig passDefinition({ present_color_attachment, depth_attachment }); + vkcv::PassHandle passHandle = core.createPass(passDefinition); + if (!passHandle) { + std::cerr << "Error. Could not create renderpass. Exiting." << std::endl; + return EXIT_FAILURE; + } + + + vkcv::ShaderProgram sponzaProgram; + vkcv::shader::GLSLCompiler compiler; + compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/shader.vert"), + [&sponzaProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + sponzaProgram.addShader(shaderStage, path); + }); + compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/shader.frag"), + [&sponzaProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + sponzaProgram.addShader(shaderStage, path); + }); + + vkcv::ShaderProgram cullingProgram; + compiler.compile(vkcv::ShaderStage::COMPUTE, std::filesystem::path("resources/shaders/culling.comp"), + [&cullingProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + cullingProgram.addShader(shaderStage, path); + }); + + // vertex layout for the pipeline. (assumed to be) used by all sponza meshes. + const std::vector<vkcv::VertexAttachment> vertexAttachments = sponzaProgram.getVertexAttachments(); + const vkcv::VertexLayout sponzaVertexLayout({ vkcv::VertexBinding(0, { vertexAttachments }) }); + + std::vector<uint8_t> compiledVertexBuffer; // IGNORED, since the vertex buffer is not interleaved! + + std::vector<uint8_t> compiledIndexBuffer; + CompiledMaterial compiledMaterial; + std::vector<vk::DrawIndexedIndirectCommand> indexedIndirectCommands; + + compileMeshForIndirectDraw(core, + asset_scene, + compiledVertexBuffer, + compiledIndexBuffer, + compiledMaterial, + indexedIndirectCommands); + + std::vector<std::vector<Vertex>> interleavedVertices; + std::vector<glm::vec4> compiledBoundingBoxBuffer; + interleaveScene(asset_scene, + interleavedVertices, + compiledBoundingBoxBuffer); + + std::vector<Vertex> compiledInterleavedVertexBuffer; + for(auto& vertexGroup : interleavedVertices ) + { + compiledInterleavedVertexBuffer.insert(compiledInterleavedVertexBuffer.end(),vertexGroup.begin(),vertexGroup.end()); + } + + auto vkCompiledVertexBuffer = core.createBuffer<Vertex>( + vkcv::BufferType::VERTEX, + compiledInterleavedVertexBuffer.size(), + vkcv::BufferMemoryType::DEVICE_LOCAL + ); + vkCompiledVertexBuffer.fill(compiledInterleavedVertexBuffer.data()); + + auto vkCompiledIndexBuffer = core.createBuffer<uint8_t>( + vkcv::BufferType::INDEX, + compiledIndexBuffer.size(), + vkcv::BufferMemoryType::DEVICE_LOCAL); + vkCompiledIndexBuffer.fill(compiledIndexBuffer.data()); + + vkcv::Buffer<vk::DrawIndexedIndirectCommand> indirectBuffer = core.createBuffer<vk::DrawIndexedIndirectCommand>( + vkcv::BufferType::INDIRECT, + indexedIndirectCommands.size(), + vkcv::BufferMemoryType::DEVICE_LOCAL); + indirectBuffer.fill(indexedIndirectCommands); + + auto boundingBoxBuffer = core.createBuffer<glm::vec4>( + vkcv::BufferType::STORAGE, + compiledBoundingBoxBuffer.size()); + boundingBoxBuffer.fill(compiledBoundingBoxBuffer); + + std::vector<glm::mat4> modelMatrix; + for( auto& mesh : asset_scene.meshes) + { + modelMatrix.push_back(glm::make_mat4(mesh.modelMatrix.data())); + } + vkcv::Buffer<glm::mat4> modelBuffer = core.createBuffer<glm::mat4>( + vkcv::BufferType::STORAGE, + modelMatrix.size(), + vkcv::BufferMemoryType::DEVICE_LOCAL + ); + modelBuffer.fill(modelMatrix); + + const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize> (0), vkCompiledVertexBuffer.getVulkanHandle() ) + }; + + const vkcv::Mesh compiledMesh(vertexBufferBindings, vkCompiledIndexBuffer.getVulkanHandle(), 0, vkcv::IndexBitCount::Bit32); + + //assert(compiledMaterial.baseColor.size() == compiledMaterial.metalRough.size()); + + vkcv::DescriptorBindings descriptorBindings = sponzaProgram.getReflectedDescriptors().at(0); + descriptorBindings[2].descriptorCount = compiledMaterial.baseColor.size(); + + vkcv::DescriptorSetLayoutHandle descriptorSetLayout = core.createDescriptorSetLayout(descriptorBindings); + vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout); + + vkcv::SamplerHandle standardSampler = core.createSampler( + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerMipmapMode::LINEAR, + vkcv::SamplerAddressMode::REPEAT + ); + + std::vector<vkcv::SampledImageDescriptorWrite> textureArrayWrites; + for(uint32_t i = 0; i < compiledMaterial.baseColor.size(); i++) + { + vkcv::SampledImageDescriptorWrite baseColorWrite(2, compiledMaterial.baseColor[i].getHandle(), 0, false, i); + textureArrayWrites.push_back(baseColorWrite); + } + + vkcv::DescriptorWrites setWrites; + setWrites.sampledImageWrites = textureArrayWrites; + setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(0, standardSampler) }; + setWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(1, modelBuffer.getHandle())}; + core.writeDescriptorSet(descriptorSet, setWrites); + + const vkcv::GraphicsPipelineConfig sponzaPipelineConfig { + sponzaProgram, + UINT32_MAX, + UINT32_MAX, + passHandle, + {sponzaVertexLayout}, + { core.getDescriptorSetLayout(descriptorSetLayout).vulkanHandle }, + true + }; + vkcv::GraphicsPipelineHandle sponzaPipelineHandle = core.createGraphicsPipeline(sponzaPipelineConfig); + if (!sponzaPipelineHandle) { + std::cerr << "Error. Could not create graphics pipeline. Exiting." << std::endl; + return EXIT_FAILURE; + } + + vkcv::DescriptorBindings cullingBindings = cullingProgram.getReflectedDescriptors().at(0); + vkcv::DescriptorSetLayoutHandle cullingSetLayout = core.createDescriptorSetLayout(cullingBindings); + vkcv::DescriptorSetHandle cullingDescSet = core.createDescriptorSet(cullingSetLayout); + + vkcv::Buffer<CameraPlanes> cameraPlaneBuffer = core.createBuffer<CameraPlanes>( + vkcv::BufferType::UNIFORM, + 1); + + //Plane dummyPlane{}; + //dummyPlane.pointOnPlane = glm::vec3(0.0f); + //dummyPlane.padding0 = 0.0f; + //dummyPlane.normal = glm::vec3(0.0f); + //dummyPlane.padding1 = 0.0f; + + //CameraPlanes dummyCameraPlane{}; + //dummyCameraPlane.planes[0] = dummyPlane; + //dummyCameraPlane.planes[1] = dummyPlane; + //dummyCameraPlane.planes[2] = dummyPlane; + //dummyCameraPlane.planes[3] = dummyPlane; + //dummyCameraPlane.planes[4] = dummyPlane; + //dummyCameraPlane.planes[5] = dummyPlane; + + //cameraPlaneBuffer.fill(&dummyCameraPlane); + + vkcv::BufferDescriptorWrite cameraPlaneWrite(0, cameraPlaneBuffer.getHandle()); + vkcv::BufferDescriptorWrite drawCommandsWrite(1, indirectBuffer.getHandle()); + vkcv::BufferDescriptorWrite boundingBoxWrite(2, boundingBoxBuffer.getHandle()); + + vkcv::DescriptorWrites cullingWrites; + cullingWrites.storageBufferWrites = {drawCommandsWrite, boundingBoxWrite}; + cullingWrites.uniformBufferWrites = {cameraPlaneWrite}; + core.writeDescriptorSet(cullingDescSet, cullingWrites); + + + const vkcv::ComputePipelineConfig computeCullingConfig { + cullingProgram, + {core.getDescriptorSetLayout(cullingSetLayout).vulkanHandle} + }; + vkcv::ComputePipelineHandle cullingPipelineHandle = core.createComputePipeline(computeCullingConfig); + if (!cullingPipelineHandle) { + std::cerr << "Error. Could not create culling pipeline. Exiting." << std::endl; + return EXIT_FAILURE; + } + + vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); + uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); + + cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -3)); + cameraManager.getCamera(camIndex0).setNearFar(0.1f, 20.f); + + vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight, 1, false).getHandle(); + const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); + + auto start = std::chrono::system_clock::now(); + + float ceiledDispatchCount = static_cast<float>(indexedIndirectCommands.size()) / 64.0f; + ceiledDispatchCount = std::ceil(ceiledDispatchCount); + const uint32_t dispatchCount[3] = {static_cast<uint32_t>(ceiledDispatchCount), 1, 1}; + + + vkcv::DescriptorSetUsage cullingUsage(0, core.getDescriptorSet(cullingDescSet).vulkanHandle, {}); + vkcv::PushConstants emptyPushConstant(0); + + bool updateFrustumPlanes = true; + + while (vkcv::Window::hasOpenWindow()) { + vkcv::Window::pollEvents(); + + if(core.getWindow(windowHandle).getHeight() == 0 || core.getWindow(windowHandle).getWidth() == 0) + continue; + + uint32_t swapchainWidth, swapchainHeight; + if (!core.beginFrame(swapchainWidth, swapchainHeight, windowHandle)) { + continue; + } + + if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) { + depthBuffer = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight).getHandle(); + + windowWidth = swapchainWidth; + windowHeight = swapchainHeight; + } + + auto end = std::chrono::system_clock::now(); + auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(end - start); + + start = end; + cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); + vkcv::camera::Camera cam = cameraManager.getActiveCamera(); + vkcv::PushConstants pushConstants(sizeof(glm::mat4)); + pushConstants.appendDrawcall(cam.getProjection() * cam.getView()); + + if(updateFrustumPlanes) + { + const CameraPlanes cameraPlanes = computeCameraPlanes(cam); + cameraPlaneBuffer.fill({ cameraPlanes }); + } + + const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; + auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); + + core.recordComputeDispatchToCmdStream(cmdStream, + cullingPipelineHandle, + dispatchCount, + {cullingUsage}, + emptyPushConstant); + + core.recordBufferMemoryBarrier(cmdStream, indirectBuffer.getHandle()); + + core.recordIndexedIndirectDrawcallsToCmdStream( + cmdStream, + passHandle, + sponzaPipelineHandle, + pushConstants, + descriptorSet, + compiledMesh, + renderTargets, + indirectBuffer, + indexedIndirectCommands.size(), + windowHandle); + + core.prepareSwapchainImageForPresent(cmdStream); + core.submitCommandStream(cmdStream); + + auto stop = std::chrono::system_clock::now(); + auto kektime = std::chrono::duration_cast<std::chrono::microseconds>(stop - start); + gui.beginGUI(); + + ImGui::Begin("Settings"); + ImGui::Checkbox("Update frustum culling", &updateFrustumPlanes); + ImGui::Text("Deltatime %fms, %f", 0.001 * static_cast<double>(kektime.count()), 1/(0.000001 * static_cast<double>(kektime.count()))); + + ImGui::End(); + + gui.endGUI(); + + core.endFrame(windowHandle); + } + + return 0; +} diff --git a/projects/path_tracer/.gitignore b/projects/path_tracer/.gitignore index ff3dff30031efafa24269a9ac0ef93f64f63ded1..24a57cda822232aa24d513fab3901ff7db36adb1 100644 --- a/projects/path_tracer/.gitignore +++ b/projects/path_tracer/.gitignore @@ -1 +1 @@ -saf_r \ No newline at end of file +path_tracer \ No newline at end of file diff --git a/projects/sph/.gitignore b/projects/sph/.gitignore index 4964f89e973f38358aa57f564f56d3d4b0c328a9..3968dc30067c92efde65779bc5eebecf167dfc75 100644 --- a/projects/sph/.gitignore +++ b/projects/sph/.gitignore @@ -1 +1 @@ -particle_simulation \ No newline at end of file +sph \ No newline at end of file diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp index 9bb9e67166013a8d1c2f7eb22a2ea867ddc9da32..52915ff04800ef3b6cb1e6caefdb3f25f6568aac 100644 --- a/src/vkcv/BufferManager.cpp +++ b/src/vkcv/BufferManager.cpp @@ -48,7 +48,10 @@ namespace vkcv { case BufferType::INDEX: usageFlags = vk::BufferUsageFlagBits::eIndexBuffer; break; - default: + case BufferType::INDIRECT: + usageFlags = vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndirectBuffer ; + break; + default: vkcv_log(LogLevel::WARNING, "Unknown buffer type"); break; } diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp index 60ee35629dd54c16f40762861667de5054defc12..2f3453f3ff97bd778df8fcfd36d79cc901c867ba 100644 --- a/src/vkcv/Context.cpp +++ b/src/vkcv/Context.cpp @@ -154,11 +154,10 @@ namespace vkcv } /** - * @brief With the help of the reference "supported" all elements in "check" checked, - * if they are supported by the physical device. - * @param supported The reference that can be used to check "check" - * @param check The elements to be checked - * @return True, if all elements in "check" are supported + * @brief Check whether all string occurrences in "check" are contained in "supported" + * @param supported The const vector const char* reference used to compare entries in "check" + * @param check The const vector const char* reference elements to be checked by "supported" + * @return True, if all elements in "check" are supported (contained in supported) */ bool checkSupport(const std::vector<const char*>& supported, const std::vector<const char*>& check) { @@ -185,7 +184,7 @@ namespace vkcv return extensions; } - + Context Context::create(const char *applicationName, uint32_t applicationVersion, const std::vector<vk::QueueFlagBits>& queueFlags, @@ -213,7 +212,7 @@ namespace vkcv } #endif - // check for extension support + // check for instance extension support std::vector<vk::ExtensionProperties> instanceExtensionProperties = vk::enumerateInstanceExtensionProperties(); std::vector<const char*> supportedExtensions; @@ -260,7 +259,7 @@ namespace vkcv #endif vk::Instance instance = vk::createInstance(instanceCreateInfo); - + std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices(); vk::PhysicalDevice physicalDevice; @@ -273,6 +272,21 @@ namespace vkcv #ifdef __APPLE__ featureManager.useExtension("VK_KHR_portability_subset", true); #endif + + if (featureManager.useExtension(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false)) { + featureManager.useFeatures<vk::PhysicalDeviceShaderFloat16Int8Features>( + [](vk::PhysicalDeviceShaderFloat16Int8Features& features) { + features.setShaderFloat16(true); + }, false); + } + + if (featureManager.useExtension(VK_KHR_16BIT_STORAGE_EXTENSION_NAME, false)) { + featureManager.useFeatures<vk::PhysicalDevice16BitStorageFeatures>( + [](vk::PhysicalDevice16BitStorageFeatures& features) { + features.setStorageBuffer16BitAccess(true); + }, false); + } + featureManager.useFeatures([](vk::PhysicalDeviceFeatures& features) { features.setFragmentStoresAndAtomics(true); features.setGeometryShader(true); @@ -285,10 +299,8 @@ namespace vkcv } const auto& extensions = featureManager.getActiveExtensions(); - + std::vector<vk::DeviceQueueCreateInfo> qCreateInfos; - - // create required queues std::vector<float> qPriorities; qPriorities.resize(queueFlags.size(), 1.f); std::vector<std::pair<int, int>> queuePairsGraphics, queuePairsCompute, queuePairsTransfer; @@ -310,7 +322,7 @@ namespace vkcv deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size()); deviceCreateInfo.ppEnabledLayerNames = validationLayers.data(); #endif - + deviceCreateInfo.setPNext(&(featureManager.getFeatures())); vk::Device device = physicalDevice.createDevice(deviceCreateInfo); diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index efba11ec2a95d8b08c9c9ddc646ec471f4f7adce..99d27496ba134c75dc555dca18fc26410005ed23 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -330,6 +330,103 @@ namespace vkcv recordCommandsToStream(cmdStreamHandle, submitFunction, finishFunction); } + void Core::recordIndexedIndirectDrawcallsToCmdStream( + const CommandStreamHandle cmdStreamHandle, + const PassHandle renderpassHandle, + const GraphicsPipelineHandle &pipelineHandle, + const PushConstants &pushConstantData, + const vkcv::DescriptorSetHandle &compiledDescriptorSet, + const vkcv::Mesh &compiledMesh, + const std::vector<ImageHandle> &renderTargets, + const vkcv::Buffer<vk::DrawIndexedIndirectCommand> &indirectBuffer, + const uint32_t drawCount, + const WindowHandle &windowHandle) { + + if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) { + return; + } + SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchainHandle(); + const std::array<uint32_t, 2> widthHeight = getWidthHeightFromRenderTargets(renderTargets, m_SwapchainManager->getSwapchain(swapchainHandle), + *m_ImageManager); + const auto width = widthHeight[0]; + const auto height = widthHeight[1]; + + const vk::RenderPass renderpass = m_PassManager->getVkPass(renderpassHandle); + const PassConfig passConfig = m_PassManager->getPassConfig(renderpassHandle); + + const vk::Pipeline pipeline = m_PipelineManager->getVkPipeline(pipelineHandle); + const vk::PipelineLayout pipelineLayout = m_PipelineManager->getVkPipelineLayout(pipelineHandle); + const vk::Rect2D renderArea(vk::Offset2D(0, 0), vk::Extent2D(width, height)); + + vk::CommandBuffer cmdBuffer = m_CommandStreamManager->getStreamCommandBuffer(cmdStreamHandle); + transitionRendertargetsToAttachmentLayout(renderTargets, *m_ImageManager, cmdBuffer); + + const vk::Framebuffer framebuffer = createFramebuffer(renderTargets, *m_ImageManager, m_SwapchainManager->getSwapchain(swapchainHandle), renderpass, + m_Context.m_Device); + + if (!framebuffer) { + vkcv_log(LogLevel::ERROR, "Failed to create temporary framebuffer"); + return; + } + + SubmitInfo submitInfo; + submitInfo.queueType = QueueType::Graphics; + submitInfo.signalSemaphores = {m_SyncResources.renderFinished}; + + auto submitFunction = [&](const vk::CommandBuffer &cmdBuffer) { + + const std::vector<vk::ClearValue> clearValues = createAttachmentClearValues(passConfig.attachments); + + const vk::RenderPassBeginInfo beginInfo(renderpass, framebuffer, renderArea, clearValues.size(), + clearValues.data()); + cmdBuffer.beginRenderPass(beginInfo, {}, {}); + + cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline, {}); + + const GraphicsPipelineConfig &pipeConfig = m_PipelineManager->getPipelineConfig(pipelineHandle); + if (pipeConfig.m_UseDynamicViewport) { + recordDynamicViewport(cmdBuffer, width, height); + } + + if (pushConstantData.getSizePerDrawcall() > 0) + { + cmdBuffer.pushConstants( + pipelineLayout, + vk::ShaderStageFlagBits::eAll, + 0, + pushConstantData.getSizePerDrawcall(), + pushConstantData.getDrawcallData(0)); + } + + vkcv::DescriptorSet descSet = m_DescriptorManager->getDescriptorSet(compiledDescriptorSet); + + cmdBuffer.bindDescriptorSets( + vk::PipelineBindPoint::eGraphics, + pipelineLayout, + 0, + descSet.vulkanHandle, + nullptr); + + vk::DeviceSize deviceSize = 0; + cmdBuffer.bindVertexBuffers(0, 1, &compiledMesh.vertexBufferBindings[0].buffer,&deviceSize); + cmdBuffer.bindIndexBuffer(compiledMesh.indexBuffer, 0, getIndexType(compiledMesh.indexBitCount)); + + cmdBuffer.drawIndexedIndirect( + indirectBuffer.getVulkanHandle(), + 0, + drawCount, + sizeof(vk::DrawIndexedIndirectCommand)); + + cmdBuffer.endRenderPass(); + }; + + auto finishFunction = [framebuffer, this]() { + m_Context.m_Device.destroy(framebuffer); + }; + + recordCommandsToStream(cmdStreamHandle, submitFunction, finishFunction); + } + void Core::recordMeshShaderDrawcalls( const CommandStreamHandle& cmdStreamHandle, const PassHandle& renderpassHandle, diff --git a/src/vkcv/DescriptorConfig.cpp b/src/vkcv/DescriptorConfig.cpp index 91a9c24dc1819b69223b6befa9b6d64409698c35..15bb05fd9cb3e5430b2a9909a682c468dfcde342 100644 --- a/src/vkcv/DescriptorConfig.cpp +++ b/src/vkcv/DescriptorConfig.cpp @@ -2,22 +2,12 @@ namespace vkcv { - DescriptorBinding::DescriptorBinding( - uint32_t bindingID, - DescriptorType descriptorType, - uint32_t descriptorCount, - ShaderStages shaderStages) noexcept: - bindingID(bindingID), - descriptorType(descriptorType), - descriptorCount(descriptorCount), - shaderStages(shaderStages) - {} - bool DescriptorBinding::operator==(const DescriptorBinding &other) const { return (this->bindingID == other.bindingID) && (this->descriptorType == other.descriptorType) && (this->descriptorCount == other.descriptorCount) && - (this->shaderStages == other.shaderStages); + (this->shaderStages == other.shaderStages) && + (this->variableCount == other.variableCount); } } diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index 7480289b1f2a0b1db194db3a06c52f7050888afe..f273e958b12892d6f2c9cc92a4ca07de3f6b29c7 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -61,27 +61,42 @@ namespace vkcv } } - //create the descriptor set's layout by iterating over its bindings + //create the descriptor set's layout and binding flags by iterating over its bindings std::vector<vk::DescriptorSetLayoutBinding> bindingsVector = {}; + std::vector<vk::DescriptorBindingFlags> bindingsFlags = {}; + for (auto bindingElem : setBindingsMap) { DescriptorBinding binding = bindingElem.second; uint32_t bindingID = bindingElem.first; - - vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding( - bindingID, - getVkDescriptorType(binding.descriptorType), - binding.descriptorCount, - getShaderStageFlags(binding.shaderStages), - nullptr - ); - - bindingsVector.push_back(descriptorSetLayoutBinding); + + bindingsVector.emplace_back( + bindingID, + getVkDescriptorType(binding.descriptorType), + binding.descriptorCount, + getShaderStageFlags(binding.shaderStages), + nullptr + ); + + if (binding.variableCount) { + bindingsFlags.push_back( + vk::DescriptorBindingFlagBits::eVariableDescriptorCount | + vk::DescriptorBindingFlagBits::ePartiallyBound + ); + } else { + bindingsFlags.emplace_back(); + } } + + vk::DescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo ( + bindingsFlags.size(), bindingsFlags.data() + ); //create the descriptor set's layout from the binding data gathered above vk::DescriptorSetLayout vulkanHandle; - vk::DescriptorSetLayoutCreateInfo layoutInfo({}, bindingsVector); + vk::DescriptorSetLayoutCreateInfo layoutInfo(vk::DescriptorSetLayoutCreateFlags(), bindingsVector); + layoutInfo.setPNext(&bindingFlagsInfo); + auto result = m_Device.createDescriptorSetLayout(&layoutInfo, nullptr, &vulkanHandle); if (result != vk::Result::eSuccess) { vkcv_log(LogLevel::ERROR, "Failed to create descriptor set layout"); @@ -99,6 +114,23 @@ namespace vkcv DescriptorSetLayout setLayout = m_DescriptorSetLayouts[setLayoutHandle.getId()]; vk::DescriptorSet vulkanHandle; vk::DescriptorSetAllocateInfo allocInfo(m_Pools.back(), 1, &setLayout.vulkanHandle); + + uint32_t sumVariableDescriptorCounts = 0; + for (auto bindingElem : setLayout.descriptorBindings) + { + DescriptorBinding binding = bindingElem.second; + uint32_t bindingID = bindingElem.first; + + if(binding.variableCount) + sumVariableDescriptorCounts += binding.descriptorCount; + } + + vk::DescriptorSetVariableDescriptorCountAllocateInfo variableAllocInfo(1, &sumVariableDescriptorCounts); + + if (sumVariableDescriptorCounts > 0) { + allocInfo.setPNext(&variableAllocInfo); + } + auto result = m_Device.allocateDescriptorSets(&allocInfo, &vulkanHandle); if(result != vk::Result::eSuccess) { @@ -126,6 +158,7 @@ namespace vkcv size_t imageInfoIndex; size_t bufferInfoIndex; uint32_t binding; + uint32_t arrayElementIndex; vk::DescriptorType type; }; @@ -142,7 +175,8 @@ namespace vkcv std::vector<WriteDescriptorSetInfo> writeInfos; - for (const auto& write : writes.sampledImageWrites) { + for (const auto& write : writes.sampledImageWrites) + { vk::ImageLayout layout = write.useGeneralLayout ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal; const vk::DescriptorImageInfo imageInfo( nullptr, @@ -156,6 +190,7 @@ namespace vkcv imageInfos.size(), 0, write.binding, + write.arrayIndex, vk::DescriptorType::eSampledImage, }; @@ -175,6 +210,7 @@ namespace vkcv imageInfos.size(), 0, write.binding, + 0, vk::DescriptorType::eStorageImage }; @@ -199,6 +235,7 @@ namespace vkcv 0, bufferInfos.size(), write.binding, + 0, write.dynamic? vk::DescriptorType::eUniformBufferDynamic : vk::DescriptorType::eUniformBuffer @@ -225,6 +262,7 @@ namespace vkcv 0, bufferInfos.size(), write.binding, + 0, write.dynamic? vk::DescriptorType::eStorageBufferDynamic : vk::DescriptorType::eStorageBuffer @@ -248,6 +286,7 @@ namespace vkcv imageInfos.size(), 0, write.binding, + 0, vk::DescriptorType::eSampler }; @@ -260,7 +299,7 @@ namespace vkcv vk::WriteDescriptorSet vulkanWrite( set, write.binding, - static_cast<uint32_t>(0), + write.arrayElementIndex, 1, write.type, (write.imageInfoIndex > 0? &(imageInfos[write.imageInfoIndex - 1]) : nullptr), @@ -289,6 +328,7 @@ namespace vkcv } auto& set = m_DescriptorSets[id]; + if (set.vulkanHandle) { m_Device.freeDescriptorSets(m_Pools[set.poolIndex], 1, &(set.vulkanHandle)); set.setLayoutHandle = DescriptorSetLayoutHandle(); @@ -303,6 +343,7 @@ namespace vkcv } auto& layout = m_DescriptorSetLayouts[id]; + if (layout.vulkanHandle){ m_Device.destroy(layout.vulkanHandle); layout.vulkanHandle = nullptr; @@ -321,4 +362,4 @@ namespace vkcv return pool; } -} \ No newline at end of file +} diff --git a/src/vkcv/DrawcallRecording.cpp b/src/vkcv/DrawcallRecording.cpp index ca8b248a06d06c7aed6f8d0e9760645b727a5993..638df388178f79f680c3b9f797d9d435e752fe10 100644 --- a/src/vkcv/DrawcallRecording.cpp +++ b/src/vkcv/DrawcallRecording.cpp @@ -52,6 +52,17 @@ namespace vkcv { } } + 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; + } + struct MeshShaderFunctions { PFN_vkCmdDrawMeshTasksNV cmdDrawMeshTasks = nullptr; diff --git a/src/vkcv/FeatureManager.cpp b/src/vkcv/FeatureManager.cpp index 2dd5585d0f3b01c9741e8e52da6a7b45b24d37e5..c25745fcdd007df86316e0f72bc3d654377baa70 100644 --- a/src/vkcv/FeatureManager.cpp +++ b/src/vkcv/FeatureManager.cpp @@ -87,6 +87,7 @@ m_physicalDevice.getFeatures2(&query) vkcv_check_feature(variableMultisampleRate); vkcv_check_feature(vertexPipelineStoresAndAtomics); vkcv_check_feature(wideLines); + vkcv_check_feature(multiDrawIndirect); return true; } @@ -291,7 +292,7 @@ m_physicalDevice.getFeatures2(&query) return true; } - + bool FeatureManager::checkSupport(const vk::PhysicalDeviceVulkan12Features &features, bool required) const { vkcv_check_init_features2(vk::PhysicalDeviceVulkan12Features); @@ -534,5 +535,4 @@ m_physicalDevice.getFeatures2(&query) const vk::PhysicalDeviceFeatures2& FeatureManager::getFeatures() const { return m_featuresBase; } - } diff --git a/src/vkcv/ShaderProgram.cpp b/src/vkcv/ShaderProgram.cpp index 4d2165aa22eb5f53dcc3067273721543edd309e4..504d8fcdbd84935db339370b15c31ccefe26e02b 100644 --- a/src/vkcv/ShaderProgram.cpp +++ b/src/vkcv/ShaderProgram.cpp @@ -146,14 +146,26 @@ namespace vkcv { { auto& u = resources.uniform_buffers[i]; const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); + const spirv_cross::SPIRType &type = comp.get_type(u.type_id); uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); - auto binding = DescriptorBinding( - bindingID, - DescriptorType::UNIFORM_BUFFER, - base_type.vecsize, - shaderStage); + + uint32_t descriptorCount = base_type.vecsize; + bool variableCount = false; + // query whether reflected resources are qualified as one-dimensional array + if(type.array_size_literal[0]) + { + descriptorCount = type.array[0]; + if(type.array[0] == 0) + variableCount = true; + } + + DescriptorBinding binding{bindingID, + DescriptorType::UNIFORM_BUFFER, + descriptorCount, + shaderStage, + variableCount}; auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); if(!insertionResult.second) @@ -169,14 +181,27 @@ namespace vkcv { { auto& u = resources.storage_buffers[i]; const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); + const spirv_cross::SPIRType &type = comp.get_type(u.type_id); uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); - auto binding = DescriptorBinding( - bindingID, - DescriptorType::STORAGE_BUFFER, - base_type.vecsize, - shaderStage); + + uint32_t descriptorCount = base_type.vecsize; + bool variableCount = false; + // query whether reflected resources are qualified as one-dimensional array + if(type.array_size_literal[0]) + { + descriptorCount = type.array[0]; + if(type.array[0] == 0) + variableCount = true; + } + + DescriptorBinding binding{bindingID, + DescriptorType::STORAGE_BUFFER, + descriptorCount, + shaderStage, + variableCount}; + auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); if(!insertionResult.second) @@ -191,14 +216,26 @@ namespace vkcv { for (uint32_t i = 0; i < resources.separate_samplers.size(); i++) { auto& u = resources.separate_samplers[i]; const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); + const spirv_cross::SPIRType &type = comp.get_type(u.type_id); uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); - auto binding = DescriptorBinding( - bindingID, - DescriptorType::SAMPLER, - base_type.vecsize, - shaderStage); + + uint32_t descriptorCount = base_type.vecsize; + bool variableCount = false; + // query whether reflected resources are qualified as one-dimensional array + if(type.array_size_literal[0]) + { + descriptorCount = type.array[0]; + if(type.array[0] == 0) + variableCount = true; + } + + DescriptorBinding binding {bindingID, + DescriptorType::SAMPLER, + descriptorCount, + shaderStage, + variableCount}; auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); if(!insertionResult.second) @@ -212,15 +249,27 @@ namespace vkcv { for (uint32_t i = 0; i < resources.separate_images.size(); i++) { auto& u = resources.separate_images[i]; - const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); + const spirv_cross::SPIRType &base_type = comp.get_type(u.base_type_id); + const spirv_cross::SPIRType &type = comp.get_type(u.type_id); uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); - auto binding = DescriptorBinding( - bindingID, - DescriptorType::IMAGE_SAMPLED, - base_type.vecsize, - shaderStage); + + uint32_t descriptorCount = base_type.vecsize; + bool variableCount = false; + // query whether reflected resources are qualified as one-dimensional array + if(type.array_size_literal[0]) + { + descriptorCount = type.array[0]; + if(type.array[0] == 0) + variableCount = true; + } + + DescriptorBinding binding {bindingID, + DescriptorType::IMAGE_SAMPLED, + descriptorCount, + shaderStage, + variableCount}; auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); if(!insertionResult.second) @@ -235,14 +284,26 @@ namespace vkcv { for (uint32_t i = 0; i < resources.storage_images.size(); i++) { auto& u = resources.storage_images[i]; const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); + const spirv_cross::SPIRType &type = comp.get_type(u.type_id); uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); - auto binding = DescriptorBinding( - bindingID, - DescriptorType::IMAGE_STORAGE, - base_type.vecsize, - shaderStage); + + uint32_t descriptorCount = base_type.vecsize; + bool variableCount = false; + // query whether reflected resources are qualified as one-dimensional array + if(type.array_size_literal[0]) + { + descriptorCount = type.array[0]; + if(type.array[0] == 0) + variableCount = true; + } + + DescriptorBinding binding {bindingID, + DescriptorType::IMAGE_STORAGE, + descriptorCount, + shaderStage, + variableCount}; auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); if(!insertionResult.second) @@ -261,11 +322,13 @@ namespace vkcv { uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); - auto binding = DescriptorBinding( + auto binding = DescriptorBinding { bindingID, DescriptorType::ACCELERATION_STRUCTURE_KHR, base_type.vecsize, - shaderStage); + shaderStage, + false + }; auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); if (!insertionResult.second) diff --git a/src/vkcv/VertexLayout.cpp b/src/vkcv/VertexLayout.cpp index fa079a3264ae47b32461bda26485adb97b0be280..0edced571502bbaf0e89ff6d45d338ca38b229ca 100644 --- a/src/vkcv/VertexLayout.cpp +++ b/src/vkcv/VertexLayout.cpp @@ -46,8 +46,8 @@ namespace vkcv { uint32_t offset = 0; for (auto &attachment : vertexAttachments) { - offset += getFormatSize(attachment.format); attachment.offset = offset; + offset += getFormatSize(attachment.format); } stride = offset; }