diff --git a/config/Sources.cmake b/config/Sources.cmake index 54bb3485ed975669668d987787975f019aa6358b..7ae106e2538c66179ab1ed50408551c43b785bc3 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -21,6 +21,8 @@ set(vkcv_sources ${vkcv_include}/vkcv/Buffer.hpp + ${vkcv_include}/vkcv/PushConstants.hpp + ${vkcv_include}/vkcv/BufferManager.hpp ${vkcv_source}/vkcv/BufferManager.cpp diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index cbbe1e908cdb74891ab9bfe4416c03e487e76b26..9f4ebb665ac0ee10bd228a880c12ef3345a5e60c 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -246,7 +246,7 @@ namespace vkcv const CommandStreamHandle cmdStreamHandle, const PassHandle renderpassHandle, const PipelineHandle pipelineHandle, - const PushConstantData &pushConstantData, + const PushConstants &pushConstants, const std::vector<DrawcallInfo> &drawcalls, const std::vector<ImageHandle> &renderTargets); @@ -255,7 +255,7 @@ namespace vkcv PipelineHandle computePipeline, const uint32_t dispatchCount[3], const std::vector<DescriptorSetUsage> &descriptorSetUsages, - const PushConstantData& pushConstantData); + const PushConstants& pushConstants); /** * @brief end recording and present image diff --git a/include/vkcv/DrawcallRecording.hpp b/include/vkcv/DrawcallRecording.hpp index 9f162a499a38d5633703f70eec8a8682e3328d72..572fc2b6b51735bdcd7eb77c1dd9d4a3482a1640 100644 --- a/include/vkcv/DrawcallRecording.hpp +++ b/include/vkcv/DrawcallRecording.hpp @@ -2,6 +2,7 @@ #include <vulkan/vulkan.hpp> #include <vkcv/Handles.hpp> #include <vkcv/DescriptorConfig.hpp> +#include <vkcv/PushConstants.hpp> namespace vkcv { struct VertexBufferBinding { @@ -29,13 +30,6 @@ namespace vkcv { size_t indexCount; }; - struct PushConstantData { - inline PushConstantData(void* data, size_t sizePerDrawcall) : data(data), sizePerDrawcall(sizePerDrawcall) {} - - void* data; - size_t sizePerDrawcall; - }; - struct DrawcallInfo { inline DrawcallInfo(const Mesh& mesh, const std::vector<DescriptorSetUsage>& descriptorSets, const uint32_t instanceCount = 1) : mesh(mesh), descriptorSets(descriptorSets), instanceCount(instanceCount){} @@ -49,7 +43,7 @@ namespace vkcv { const DrawcallInfo &drawcall, vk::CommandBuffer cmdBuffer, vk::PipelineLayout pipelineLayout, - const PushConstantData &pushConstantData, + const PushConstants &pushConstants, const size_t drawcallIndex); } \ No newline at end of file diff --git a/include/vkcv/PushConstants.hpp b/include/vkcv/PushConstants.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b433d214d5319634a7498c9f0b87f97eeb58b063 --- /dev/null +++ b/include/vkcv/PushConstants.hpp @@ -0,0 +1,89 @@ +#pragma once + +#include <vector> +#include <vulkan/vulkan.hpp> + +namespace vkcv { + + class PushConstants { + private: + std::vector<uint8_t> m_data; + size_t m_sizePerDrawcall; + + public: + template<typename T> + PushConstants() : PushConstants(sizeof(T)) {} + + explicit PushConstants(size_t sizePerDrawcall) : + m_data(), + m_sizePerDrawcall(sizePerDrawcall) {} + + PushConstants(const PushConstants& other) = default; + PushConstants(PushConstants&& other) = default; + + ~PushConstants() = default; + + PushConstants& operator=(const PushConstants& other) = default; + PushConstants& operator=(PushConstants&& other) = default; + + [[nodiscard]] + size_t getSizePerDrawcall() const { + return m_sizePerDrawcall; + } + + [[nodiscard]] + size_t getFullSize() const { + return m_data.size(); + } + + [[nodiscard]] + size_t getDrawcallCount() const { + return (m_data.size() / m_sizePerDrawcall); + } + + void clear() { + m_data.clear(); + } + + template<typename T = uint8_t> + bool appendDrawcall(const T& value) { + if (sizeof(T) != m_sizePerDrawcall) { + return false; + } + + const size_t offset = m_data.size(); + m_data.resize(offset + sizeof(value)); + std::memcpy(m_data.data() + offset, &value, sizeof(value)); + return true; + } + + template<typename T = uint8_t> + T& getDrawcall(size_t index) { + const size_t offset = (index * m_sizePerDrawcall); + return *reinterpret_cast<T*>(m_data.data() + offset); + } + + template<typename T = uint8_t> + const T& getDrawcall(size_t index) const { + const size_t offset = (index * m_sizePerDrawcall); + return *reinterpret_cast<const T*>(m_data.data() + offset); + } + + [[nodiscard]] + const void* getDrawcallData(size_t index) const { + const size_t offset = (index * m_sizePerDrawcall); + return reinterpret_cast<const void*>(m_data.data() + offset); + } + + [[nodiscard]] + const void* getData() const { + if (m_data.empty()) { + return nullptr; + } else { + return m_data.data(); + } + } + + }; + +} diff --git a/modules/scene/include/vkcv/scene/Mesh.hpp b/modules/scene/include/vkcv/scene/Mesh.hpp index 899e5e0ce11589b6021d6554cda1f7f32f356e37..bc82af4bfabed5e8bfc286bc53cd7b89791726fc 100644 --- a/modules/scene/include/vkcv/scene/Mesh.hpp +++ b/modules/scene/include/vkcv/scene/Mesh.hpp @@ -8,6 +8,8 @@ namespace vkcv::scene { + typedef typename event_function<const glm::mat4&, const glm::mat4&, PushConstants&, vkcv::DrawcallInfo&>::type RecordMeshDrawcallFunction; + class Node; class Mesh { @@ -26,8 +28,9 @@ namespace vkcv::scene { const asset::Mesh& mesh); void recordDrawcalls(const glm::mat4& viewProjection, - std::vector<glm::mat4>& matrices, - std::vector<DrawcallInfo>& drawcalls); + PushConstants& pushConstants, + std::vector<DrawcallInfo>& drawcalls, + const RecordMeshDrawcallFunction& record); [[nodiscard]] size_t getDrawcallCount() const; diff --git a/modules/scene/include/vkcv/scene/Node.hpp b/modules/scene/include/vkcv/scene/Node.hpp index 0772172d67f80772360d411bd6a1a18b02725bff..1fcca5b9cbecf1064070d7737d008d2b108371db 100644 --- a/modules/scene/include/vkcv/scene/Node.hpp +++ b/modules/scene/include/vkcv/scene/Node.hpp @@ -28,8 +28,9 @@ namespace vkcv::scene { void loadMesh(const asset::Scene& asset_scene, const asset::Mesh& asset_mesh); void recordDrawcalls(const glm::mat4& viewProjection, - std::vector<glm::mat4>& matrices, - std::vector<DrawcallInfo>& drawcalls); + PushConstants& pushConstants, + std::vector<DrawcallInfo>& drawcalls, + const RecordMeshDrawcallFunction& record); void splitMeshesToSubNodes(size_t maxMeshesPerNode); diff --git a/modules/scene/include/vkcv/scene/Scene.hpp b/modules/scene/include/vkcv/scene/Scene.hpp index d9104ab40f2f633b5f7d14cb95a1a202cfeb7c32..429c0bcf729f9afb7dd76cdd58c54931862e1a4a 100644 --- a/modules/scene/include/vkcv/scene/Scene.hpp +++ b/modules/scene/include/vkcv/scene/Scene.hpp @@ -4,6 +4,7 @@ #include <mutex> #include <vkcv/Core.hpp> +#include <vkcv/Event.hpp> #include <vkcv/camera/Camera.hpp> #include <vkcv/material/Material.hpp> @@ -54,11 +55,13 @@ namespace vkcv::scene { [[nodiscard]] const material::Material& getMaterial(size_t index) const; - void recordDrawcalls(CommandStreamHandle &cmdStream, - const camera::Camera &camera, - const PassHandle &pass, - const PipelineHandle &pipeline, - const std::vector<ImageHandle> &renderTargets); + void recordDrawcalls(CommandStreamHandle &cmdStream, + const camera::Camera &camera, + const PassHandle &pass, + const PipelineHandle &pipeline, + size_t pushConstantsSizePerDrawcall, + const RecordMeshDrawcallFunction &record, + const std::vector<ImageHandle> &renderTargets); static Scene create(Core& core); diff --git a/modules/scene/src/vkcv/scene/Mesh.cpp b/modules/scene/src/vkcv/scene/Mesh.cpp index ff93029e7883aaa2103a28415c0caeead4c3ad57..53fb81713ed7e14049a21cb91c771d67f2f7086c 100644 --- a/modules/scene/src/vkcv/scene/Mesh.cpp +++ b/modules/scene/src/vkcv/scene/Mesh.cpp @@ -89,8 +89,9 @@ namespace vkcv::scene { } void Mesh::recordDrawcalls(const glm::mat4& viewProjection, - std::vector<glm::mat4>& matrices, - std::vector<DrawcallInfo>& drawcalls) { + PushConstants& pushConstants, + std::vector<DrawcallInfo>& drawcalls, + const RecordMeshDrawcallFunction& record) { const glm::mat4 transform = viewProjection * m_transform; if (!checkFrustum(viewProjection, m_bounds)) { @@ -98,8 +99,11 @@ namespace vkcv::scene { } if (m_drawcalls.size() == 1) { - matrices.push_back(transform); drawcalls.push_back(m_drawcalls[0]); + + if (record) { + record(transform, m_transform, pushConstants, drawcalls.back()); + } } else { for (size_t i = 0; i < m_parts.size(); i++) { const MeshPart& part = m_parts[i]; @@ -108,8 +112,11 @@ namespace vkcv::scene { continue; } - matrices.push_back(transform); drawcalls.push_back(m_drawcalls[i]); + + if (record) { + record(transform, m_transform, pushConstants, drawcalls.back()); + } } } } diff --git a/modules/scene/src/vkcv/scene/Node.cpp b/modules/scene/src/vkcv/scene/Node.cpp index 906e00e8a96504849f9b8baaf82d630e4450ed56..32230099b2f693362bab69d8172a4dee56c4e304 100644 --- a/modules/scene/src/vkcv/scene/Node.cpp +++ b/modules/scene/src/vkcv/scene/Node.cpp @@ -91,18 +91,19 @@ namespace vkcv::scene { } void Node::recordDrawcalls(const glm::mat4& viewProjection, - std::vector<glm::mat4>& matrices, - std::vector<DrawcallInfo>& drawcalls) { + PushConstants& pushConstants, + std::vector<DrawcallInfo>& drawcalls, + const RecordMeshDrawcallFunction& record) { if (!checkFrustum(viewProjection, m_bounds)) { return; } for (auto& mesh : m_meshes) { - mesh.recordDrawcalls(viewProjection, matrices, drawcalls); + mesh.recordDrawcalls(viewProjection, pushConstants, drawcalls, record); } for (auto& node : m_nodes) { - node.recordDrawcalls(viewProjection, matrices, drawcalls); + node.recordDrawcalls(viewProjection, pushConstants, drawcalls, record); } } diff --git a/modules/scene/src/vkcv/scene/Scene.cpp b/modules/scene/src/vkcv/scene/Scene.cpp index 1a5f76e5d0bb4d64db11791b7e8d84ba8d0a764a..b050f67ff352296db6155247beebbb5682e542c2 100644 --- a/modules/scene/src/vkcv/scene/Scene.cpp +++ b/modules/scene/src/vkcv/scene/Scene.cpp @@ -109,12 +109,14 @@ namespace vkcv::scene { return m_materials[index].m_data; } - void Scene::recordDrawcalls(CommandStreamHandle &cmdStream, - const camera::Camera &camera, - const PassHandle &pass, - const PipelineHandle &pipeline, - const std::vector<ImageHandle> &renderTargets) { - std::vector<glm::mat4> matrices; + void Scene::recordDrawcalls(CommandStreamHandle &cmdStream, + const camera::Camera &camera, + const PassHandle &pass, + const PipelineHandle &pipeline, + size_t pushConstantsSizePerDrawcall, + const RecordMeshDrawcallFunction &record, + const std::vector<ImageHandle> &renderTargets) { + PushConstants pushConstants (pushConstantsSizePerDrawcall); std::vector<DrawcallInfo> drawcalls; size_t count = 0; @@ -122,18 +124,16 @@ namespace vkcv::scene { for (auto& node : m_nodes) { count += node.getDrawcallCount(); - node.recordDrawcalls(viewProjection, matrices, drawcalls); + node.recordDrawcalls(viewProjection, pushConstants, drawcalls, record); } vkcv_log(LogLevel::RAW_INFO, "Frustum culling: %lu / %lu", drawcalls.size(), count); - PushConstantData pushConstantData (matrices.data(), sizeof(glm::mat4)); - m_core->recordDrawcallsToCmdStream( cmdStream, pass, pipeline, - pushConstantData, + pushConstants, drawcalls, renderTargets ); diff --git a/projects/bloom/src/BloomAndFlares.cpp b/projects/bloom/src/BloomAndFlares.cpp index 6f26db9de0f2c8334b6dd7e5dd6cf4b6f48baedc..7529dcf0ca1e1d164c33658d7e90c105b88edc49 100644 --- a/projects/bloom/src/BloomAndFlares.cpp +++ b/projects/bloom/src/BloomAndFlares.cpp @@ -104,7 +104,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre m_DownsamplePipe, initialDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[0]).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); // downsample dispatches of blur buffer's mip maps float mipDispatchCountX = dispatchCountX; @@ -139,7 +139,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre m_DownsamplePipe, mipDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[mipLevel]).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); // image barrier between mips p_Core->recordImageMemoryBarrier(cmdStream, m_Blur.getHandle()); @@ -184,7 +184,7 @@ void BloomAndFlares::execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream m_UpsamplePipe, upsampleDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_UpsampleDescSets[mipLevel]).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0) + vkcv::PushConstants(0) ); // image barrier between mips p_Core->recordImageMemoryBarrier(cmdStream, m_Blur.getHandle()); @@ -216,7 +216,7 @@ void BloomAndFlares::execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStr m_LensFlarePipe, lensFeatureDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_LensFlareDescSet).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); } void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStream, @@ -249,7 +249,7 @@ void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStrea m_CompositePipe, compositeDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_CompositeDescSet).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); } void BloomAndFlares::execWholePipeline(const vkcv::CommandStreamHandle &cmdStream, diff --git a/projects/bloom/src/main.cpp b/projects/bloom/src/main.cpp index 7a17a51f1c7d638575c0b5aafcdca49b589533ef..95435a69032bf64b4aa704830162ae1e096849f5 100644 --- a/projects/bloom/src/main.cpp +++ b/projects/bloom/src/main.cpp @@ -252,9 +252,6 @@ int main(int argc, const char** argv) { }; const vkcv::PipelineHandle shadowPipe = core.createGraphicsPipeline(shadowPipeConfig); - std::vector<std::array<glm::mat4, 2>> mainPassMatrices; - std::vector<glm::mat4> mvpLight; - // gamma correction compute shader vkcv::ShaderProgram gammaCorrectionProgram; compiler.compile(vkcv::ShaderStage::COMPUTE, "resources/shaders/gammaCorrection.comp", @@ -348,18 +345,19 @@ int main(int argc, const char** argv) { lightBuffer.fill({ lightInfo }); const glm::mat4 viewProjectionCamera = cameraManager.getActiveCamera().getMVP(); - - mainPassMatrices.clear(); - mvpLight.clear(); + + vkcv::PushConstants pushConstants (2 * sizeof(glm::mat4)); + vkcv::PushConstants shadowPushConstants (sizeof(glm::mat4)); + for (const auto& m : modelMatrices) { - mainPassMatrices.push_back({ viewProjectionCamera * m, m }); - mvpLight.push_back(lightInfo.lightMatrix * m); + pushConstants.appendDrawcall(std::array<glm::mat4, 2>{ viewProjectionCamera * m, m }); + shadowPushConstants.appendDrawcall(lightInfo.lightMatrix * m); } - vkcv::PushConstantData pushConstantData((void*)mainPassMatrices.data(), 2 * sizeof(glm::mat4)); + const std::vector<vkcv::ImageHandle> renderTargets = { colorBuffer, depthBuffer }; - const vkcv::PushConstantData shadowPushConstantData((void*)mvpLight.data(), sizeof(glm::mat4)); + const auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); @@ -368,7 +366,7 @@ int main(int argc, const char** argv) { cmdStream, shadowPass, shadowPipe, - shadowPushConstantData, + shadowPushConstants, shadowDrawcalls, { shadowMap.getHandle() }); core.prepareImageForSampling(cmdStream, shadowMap.getHandle()); @@ -378,7 +376,7 @@ int main(int argc, const char** argv) { cmdStream, forwardPass, forwardPipeline, - pushConstantData, + pushConstants, drawcalls, renderTargets); @@ -406,7 +404,7 @@ int main(int argc, const char** argv) { gammaCorrectionPipeline, gammaCorrectionDispatchCount, { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(gammaCorrectionDescriptorSet).vulkanHandle) }, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); // present and end core.prepareSwapchainImageForPresent(cmdStream); diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index e7546fc3a143b3638cceb36869c519336ebec751..6eaf429c9f769792ccf2435ee41bcb52973701e3 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -185,7 +185,8 @@ int main(int argc, const char** argv) { cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - vkcv::PushConstantData pushConstantData((void*)&mvp, sizeof(glm::mat4)); + vkcv::PushConstants pushConstants (sizeof(glm::mat4)); + pushConstants.appendDrawcall(mvp); const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); @@ -194,7 +195,7 @@ int main(int argc, const char** argv) { cmdStream, firstMeshPass, firstMeshPipeline, - pushConstantData, + pushConstants, { drawcall }, renderTargets); core.prepareSwapchainImageForPresent(cmdStream); diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp index 0f81990bdddfffb4c6a59541311a7ee5e19837e9..486b21343926e1b922b73ba8ffb29428de6ea9a7 100644 --- a/projects/first_scene/src/main.cpp +++ b/projects/first_scene/src/main.cpp @@ -125,10 +125,18 @@ int main(int argc, const char** argv) { const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); + auto recordMesh = [](const glm::mat4& MVP, const glm::mat4& M, + vkcv::PushConstants &pushConstants, + vkcv::DrawcallInfo& drawcallInfo) { + pushConstants.appendDrawcall(MVP); + }; + scene.recordDrawcalls(cmdStream, cameraManager.getActiveCamera(), scenePass, scenePipeline, + sizeof(glm::mat4), + recordMesh, renderTargets); core.prepareSwapchainImageForPresent(cmdStream); diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index 5bdd55a263f4d81d8f424c056d7d6c0b54ccb1ca..db175a801b75535343cfa468af90ce490a670938 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -195,26 +195,31 @@ int main(int argc, const char** argv) { cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - vkcv::PushConstantData pushConstantData((void*)&mvp, sizeof(glm::mat4)); + vkcv::PushConstants pushConstants (sizeof(glm::mat4)); + pushConstants.appendDrawcall(mvp); + auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); core.recordDrawcallsToCmdStream( cmdStream, trianglePass, trianglePipeline, - pushConstantData, + pushConstants, { drawcall }, { swapchainInput }); const uint32_t dispatchSize[3] = { 2, 1, 1 }; const float theMeaningOfLife = 42; + + vkcv::PushConstants pushConstantsCompute (sizeof(theMeaningOfLife)); + pushConstantsCompute.appendDrawcall(theMeaningOfLife); core.recordComputeDispatchToCmdStream( cmdStream, computePipeline, dispatchSize, { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(computeDescriptorSet).vulkanHandle) }, - vkcv::PushConstantData((void*)&theMeaningOfLife, sizeof(theMeaningOfLife))); + pushConstantsCompute); core.prepareSwapchainImageForPresent(cmdStream); core.submitCommandStream(cmdStream); diff --git a/projects/particle_simulation/src/BloomAndFlares.cpp b/projects/particle_simulation/src/BloomAndFlares.cpp index 23ace2bc35a2e421613718c62380f9161a408f70..98d53c2a1a2c08d40473858b47aacf34da30f7ed 100644 --- a/projects/particle_simulation/src/BloomAndFlares.cpp +++ b/projects/particle_simulation/src/BloomAndFlares.cpp @@ -104,7 +104,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre m_DownsamplePipe, initialDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[0]).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); // downsample dispatches of blur buffer's mip maps float mipDispatchCountX = dispatchCountX; @@ -139,7 +139,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre m_DownsamplePipe, mipDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[mipLevel]).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); // image barrier between mips p_Core->recordImageMemoryBarrier(cmdStream, m_Blur.getHandle()); @@ -184,7 +184,7 @@ void BloomAndFlares::execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream m_UpsamplePipe, upsampleDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_UpsampleDescSets[mipLevel]).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0) + vkcv::PushConstants(0) ); // image barrier between mips p_Core->recordImageMemoryBarrier(cmdStream, m_Blur.getHandle()); @@ -216,7 +216,7 @@ void BloomAndFlares::execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStr m_LensFlarePipe, lensFeatureDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_LensFlareDescSet).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); } void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStream, @@ -249,7 +249,7 @@ void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStrea m_CompositePipe, compositeDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_CompositeDescSet).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); } void BloomAndFlares::execWholePipeline(const vkcv::CommandStreamHandle &cmdStream, diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp index a22044f0d2588a43a5e7a0f6cba25d9c7460be9f..ad02c651486e0f1b693a348d016a6f59d0f73eb4 100644 --- a/projects/particle_simulation/src/main.cpp +++ b/projects/particle_simulation/src/main.cpp @@ -260,30 +260,38 @@ int main(int argc, const char **argv) { cameraManager.update(deltatime); // split view and projection to allow for easy billboarding in shader - glm::mat4 renderingMatrices[2]; - renderingMatrices[0] = cameraManager.getActiveCamera().getView(); - renderingMatrices[1] = cameraManager.getActiveCamera().getProjection(); + struct { + glm::mat4 view; + glm::mat4 projection; + } renderingMatrices; + + renderingMatrices.view = cameraManager.getActiveCamera().getView(); + renderingMatrices.projection = cameraManager.getActiveCamera().getProjection(); auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); float random = rdm(rdmEngine); glm::vec2 pushData = glm::vec2(deltatime, random); - vkcv::PushConstantData pushConstantDataCompute( &pushData, sizeof(glm::vec2)); + vkcv::PushConstants pushConstantsCompute (sizeof(glm::vec2)); + pushConstantsCompute.appendDrawcall(pushData); + uint32_t computeDispatchCount[3] = {static_cast<uint32_t> (std::ceil(particleSystem.getParticles().size()/256.f)),1,1}; core.recordComputeDispatchToCmdStream(cmdStream, computePipeline, computeDispatchCount, {vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet).vulkanHandle)}, - pushConstantDataCompute); + pushConstantsCompute); core.recordBufferMemoryBarrier(cmdStream, particleBuffer.getHandle()); - vkcv::PushConstantData pushConstantDataDraw((void *) &renderingMatrices[0], 2 * sizeof(glm::mat4)); + vkcv::PushConstants pushConstantsDraw (sizeof(renderingMatrices)); + pushConstantsDraw.appendDrawcall(renderingMatrices); + core.recordDrawcallsToCmdStream( cmdStream, particlePass, particlePipeline, - pushConstantDataDraw, + pushConstantsDraw, {drawcalls}, { colorBuffer }); @@ -309,7 +317,7 @@ int main(int argc, const char **argv) { tonemappingPipe, tonemappingDispatchCount, {vkcv::DescriptorSetUsage(0, core.getDescriptorSet(tonemappingDescriptor).vulkanHandle) }, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); core.prepareSwapchainImageForPresent(cmdStream); core.submitCommandStream(cmdStream); diff --git a/projects/voxelization/src/BloomAndFlares.cpp b/projects/voxelization/src/BloomAndFlares.cpp index fac57735a6544c197f880f78e1f512382607d048..6cb02e9035daf7abebc047d26137d0ba973bb4f1 100644 --- a/projects/voxelization/src/BloomAndFlares.cpp +++ b/projects/voxelization/src/BloomAndFlares.cpp @@ -128,7 +128,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre m_DownsamplePipe, initialDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[0]).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); // downsample dispatches of blur buffer's mip maps float mipDispatchCountX = dispatchCountX; @@ -163,7 +163,7 @@ void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStre m_DownsamplePipe, mipDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[mipLevel]).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); // image barrier between mips p_Core->recordImageMemoryBarrier(cmdStream, m_Blur.getHandle()); @@ -208,7 +208,7 @@ void BloomAndFlares::execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream m_UpsamplePipe, upsampleDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_UpsampleDescSets[mipLevel]).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0) + vkcv::PushConstants(0) ); // image barrier between mips p_Core->recordImageMemoryBarrier(cmdStream, m_Blur.getHandle()); @@ -243,7 +243,7 @@ void BloomAndFlares::execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStr m_LensFlarePipe, lensFeatureDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_LensFlareDescSet).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); // upsample dispatch p_Core->prepareImageForStorage(cmdStream, m_LensFeatures.getHandle()); @@ -276,7 +276,7 @@ void BloomAndFlares::execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStr m_UpsamplePipe, upsampleDispatchCount, { vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_UpsampleLensFlareDescSets[i]).vulkanHandle) }, - vkcv::PushConstantData(nullptr, 0) + vkcv::PushConstants(0) ); // image barrier between mips p_Core->recordImageMemoryBarrier(cmdStream, m_LensFeatures.getHandle()); @@ -309,6 +309,9 @@ void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStrea static_cast<uint32_t>(glm::ceil(dispatchCountY)), 1 }; + + vkcv::PushConstants pushConstants (sizeof(cameraForward)); + pushConstants.appendDrawcall(cameraForward); // bloom composite dispatch p_Core->recordComputeDispatchToCmdStream( @@ -316,7 +319,7 @@ void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStrea m_CompositePipe, compositeDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_CompositeDescSet).vulkanHandle)}, - vkcv::PushConstantData((void*)&cameraForward, sizeof(cameraForward))); + pushConstants); } void BloomAndFlares::execWholePipeline(const vkcv::CommandStreamHandle &cmdStream, const vkcv::ImageHandle &colorAttachment, diff --git a/projects/voxelization/src/ShadowMapping.cpp b/projects/voxelization/src/ShadowMapping.cpp index a330394b7bd7ff2a4b8c347bd79e676dbc70f846..32dd5457541f8f09f4d2711ea831e3c78de2303a 100644 --- a/projects/voxelization/src/ShadowMapping.cpp +++ b/projects/voxelization/src/ShadowMapping.cpp @@ -248,12 +248,13 @@ void ShadowMapping::recordShadowMapRendering( voxelVolumeOffset, voxelVolumeExtent); m_lightInfoBuffer.fill({ lightInfo }); - - std::vector<glm::mat4> mvpLight; + + vkcv::PushConstants shadowPushConstants (sizeof(glm::mat4)); + for (const auto& m : modelMatrices) { - mvpLight.push_back(lightInfo.lightMatrix * m); + shadowPushConstants.appendDrawcall(lightInfo.lightMatrix * m); } - const vkcv::PushConstantData shadowPushConstantData((void*)mvpLight.data(), sizeof(glm::mat4)); + std::vector<vkcv::DrawcallInfo> drawcalls; for (const auto& mesh : meshes) { @@ -264,7 +265,7 @@ void ShadowMapping::recordShadowMapRendering( cmdStream, m_shadowMapPass, m_shadowMapPipe, - shadowPushConstantData, + shadowPushConstants, drawcalls, { m_shadowMapDepth.getHandle() }); m_corePtr->prepareImageForSampling(cmdStream, m_shadowMapDepth.getHandle()); @@ -276,6 +277,9 @@ void ShadowMapping::recordShadowMapRendering( dispatchCount[2] = 1; const uint32_t msaaSampleCount = msaaToSampleCount(msaa); + + vkcv::PushConstants msaaPushConstants (sizeof(msaaSampleCount)); + msaaPushConstants.appendDrawcall(msaaSampleCount); m_corePtr->prepareImageForStorage(cmdStream, m_shadowMap.getHandle()); m_corePtr->recordComputeDispatchToCmdStream( @@ -283,7 +287,7 @@ void ShadowMapping::recordShadowMapRendering( m_depthToMomentsPipe, dispatchCount, { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_depthToMomentsDescriptorSet).vulkanHandle) }, - vkcv::PushConstantData((void*)&msaaSampleCount, sizeof(msaaSampleCount))); + msaaPushConstants); m_corePtr->prepareImageForSampling(cmdStream, m_shadowMap.getHandle()); // blur X @@ -293,7 +297,7 @@ void ShadowMapping::recordShadowMapRendering( m_shadowBlurXPipe, dispatchCount, { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_shadowBlurXDescriptorSet).vulkanHandle) }, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); m_corePtr->prepareImageForSampling(cmdStream, m_shadowMapIntermediate.getHandle()); // blur Y @@ -303,7 +307,7 @@ void ShadowMapping::recordShadowMapRendering( m_shadowBlurYPipe, dispatchCount, { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_shadowBlurYDescriptorSet).vulkanHandle) }, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); m_shadowMap.recordMipChainGeneration(cmdStream); m_corePtr->prepareImageForSampling(cmdStream, m_shadowMap.getHandle()); } diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp index c117b4b9e6b896fbf51aae83343f30281061be9f..1f1888d5c0ed30effc4c93c02efddb370ce8ad21 100644 --- a/projects/voxelization/src/Voxelization.cpp +++ b/projects/voxelization/src/Voxelization.cpp @@ -232,34 +232,36 @@ void Voxelization::voxelizeMeshes( const glm::mat4 voxelizationView = glm::translate(glm::mat4(1.f), -m_voxelInfo.offset); const glm::mat4 voxelizationViewProjection = voxelizationProjection * voxelizationView; - - std::vector<std::array<glm::mat4, 2>> voxelizationMatrices; + + vkcv::PushConstants voxelizationPushConstants (2 * sizeof(glm::mat4)); + for (const auto& m : modelMatrices) { - voxelizationMatrices.push_back({ voxelizationViewProjection * m, m }); + voxelizationPushConstants.appendDrawcall(std::array<glm::mat4, 2>{ voxelizationViewProjection * m, m }); } - const vkcv::PushConstantData voxelizationPushConstantData((void*)voxelizationMatrices.data(), 2 * sizeof(glm::mat4)); - // reset voxels const uint32_t resetVoxelGroupSize = 64; uint32_t resetVoxelDispatchCount[3]; resetVoxelDispatchCount[0] = glm::ceil(voxelCount / float(resetVoxelGroupSize)); resetVoxelDispatchCount[1] = 1; resetVoxelDispatchCount[2] = 1; + + vkcv::PushConstants voxelCountPushConstants (sizeof(voxelCount)); + voxelCountPushConstants.appendDrawcall(voxelCount); m_corePtr->recordComputeDispatchToCmdStream( cmdStream, m_voxelResetPipe, resetVoxelDispatchCount, { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_voxelResetDescriptorSet).vulkanHandle) }, - vkcv::PushConstantData(&voxelCount, sizeof(voxelCount))); + voxelCountPushConstants); m_corePtr->recordBufferMemoryBarrier(cmdStream, m_voxelBuffer.getHandle()); // voxelization std::vector<vkcv::DrawcallInfo> drawcalls; for (int i = 0; i < meshes.size(); i++) { drawcalls.push_back(vkcv::DrawcallInfo( - meshes[i], + meshes[i], { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_voxelizationDescriptorSet).vulkanHandle), vkcv::DescriptorSetUsage(1, m_corePtr->getDescriptorSet(perMeshDescriptorSets[i]).vulkanHandle) @@ -271,7 +273,7 @@ void Voxelization::voxelizeMeshes( cmdStream, m_voxelizationPass, m_voxelizationPipe, - voxelizationPushConstantData, + voxelizationPushConstants, drawcalls, { m_dummyRenderTarget.getHandle() }); @@ -287,7 +289,7 @@ void Voxelization::voxelizeMeshes( m_bufferToImagePipe, bufferToImageDispatchCount, { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_bufferToImageDescriptorSet).vulkanHandle) }, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); m_corePtr->recordImageMemoryBarrier(cmdStream, m_voxelImageIntermediate.getHandle()); @@ -303,7 +305,7 @@ void Voxelization::voxelizeMeshes( m_secondaryBouncePipe, bufferToImageDispatchCount, { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_secondaryBounceDescriptorSet).vulkanHandle) }, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); m_voxelImage.recordMipChainGeneration(cmdStream); m_corePtr->recordImageMemoryBarrier(cmdStream, m_voxelImage.getHandle()); @@ -319,7 +321,8 @@ void Voxelization::renderVoxelVisualisation( const std::vector<vkcv::ImageHandle>& renderTargets, uint32_t mipLevel) { - const vkcv::PushConstantData voxelVisualisationPushConstantData((void*)&viewProjectin, sizeof(glm::mat4)); + vkcv::PushConstants voxelVisualisationPushConstants (sizeof(glm::mat4)); + voxelVisualisationPushConstants.appendDrawcall(viewProjectin); mipLevel = std::clamp(mipLevel, (uint32_t)0, m_voxelImage.getMipCount()-1); @@ -342,7 +345,7 @@ void Voxelization::renderVoxelVisualisation( cmdStream, m_visualisationPass, m_visualisationPipe, - voxelVisualisationPushConstantData, + voxelVisualisationPushConstants, { drawcall }, renderTargets); } diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index edc50c554b6c73bd2f06914eba6dd7adf9e43483..68018ef80f801b797eca30078ca6fadf897da4ad 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -618,29 +618,32 @@ int main(int argc, const char** argv) { // depth prepass const glm::mat4 viewProjectionCamera = cameraManager.getActiveCamera().getMVP(); - + + vkcv::PushConstants prepassPushConstants (sizeof(glm::mat4)); + std::vector<glm::mat4> prepassMatrices; for (const auto& m : modelMatrices) { - prepassMatrices.push_back(viewProjectionCamera * m); + prepassPushConstants.appendDrawcall(viewProjectionCamera * m); } - const vkcv::PushConstantData prepassPushConstantData((void*)prepassMatrices.data(), sizeof(glm::mat4)); + const std::vector<vkcv::ImageHandle> prepassRenderTargets = { depthBuffer }; core.recordDrawcallsToCmdStream( cmdStream, prepassPass, prepassPipeline, - prepassPushConstantData, + prepassPushConstants, prepassDrawcalls, prepassRenderTargets); core.recordImageMemoryBarrier(cmdStream, depthBuffer); - + + vkcv::PushConstants pushConstants (2 * sizeof(glm::mat4)); + // main pass - std::vector<std::array<glm::mat4, 2>> mainPassMatrices; for (const auto& m : modelMatrices) { - mainPassMatrices.push_back({ viewProjectionCamera * m, m }); + pushConstants.appendDrawcall(std::array<glm::mat4, 2>{ viewProjectionCamera * m, m }); } VolumetricSettings volumeSettings; @@ -648,28 +651,30 @@ int main(int argc, const char** argv) { volumeSettings.absorptionCoefficient = absorptionColor * absorptionDensity; volumeSettings.ambientLight = volumetricAmbient; volumetricSettingsBuffer.fill({ volumeSettings }); - - const vkcv::PushConstantData pushConstantData((void*)mainPassMatrices.data(), 2 * sizeof(glm::mat4)); + const std::vector<vkcv::ImageHandle> renderTargets = { colorBuffer, depthBuffer }; core.recordDrawcallsToCmdStream( cmdStream, forwardPass, forwardPipeline, - pushConstantData, + pushConstants, drawcalls, renderTargets); if (renderVoxelVis) { voxelization.renderVoxelVisualisation(cmdStream, viewProjectionCamera, renderTargets, voxelVisualisationMip); } + + vkcv::PushConstants skySettingsPushConstants (sizeof(skySettings)); + skySettingsPushConstants.appendDrawcall(skySettings); // sky core.recordDrawcallsToCmdStream( cmdStream, skyPass, skyPipe, - vkcv::PushConstantData((void*)&skySettings, sizeof(skySettings)), + skySettingsPushConstants, { vkcv::DrawcallInfo(vkcv::Mesh({}, nullptr, 3), {}) }, renderTargets); @@ -692,7 +697,7 @@ int main(int argc, const char** argv) { resolvePipeline, fulsscreenDispatchCount, { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(resolveDescriptorSet).vulkanHandle) }, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstants(0)); core.recordImageMemoryBarrier(cmdStream, resolvedColorBuffer); } @@ -710,12 +715,15 @@ int main(int argc, const char** argv) { auto timeSinceStart = std::chrono::duration_cast<std::chrono::microseconds>(end - appStartTime); float timeF = static_cast<float>(timeSinceStart.count()) * 0.01; + vkcv::PushConstants timePushConstants (sizeof(timeF)); + timePushConstants.appendDrawcall(timeF); + core.recordComputeDispatchToCmdStream( cmdStream, tonemappingPipeline, fulsscreenDispatchCount, { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(tonemappingDescriptorSet).vulkanHandle) }, - vkcv::PushConstantData(&timeF, sizeof(timeF))); + timePushConstants); // present and end core.prepareSwapchainImageForPresent(cmdStream); diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 352a1cf62eabe55ce1bbf2f53a6b5a4bd6e91753..3af359e7fa302e01e5c42664911ab90c9e9247cc 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -232,7 +232,7 @@ namespace vkcv const CommandStreamHandle cmdStreamHandle, const PassHandle renderpassHandle, const PipelineHandle pipelineHandle, - const PushConstantData &pushConstantData, + const PushConstants &pushConstants, const std::vector<DrawcallInfo> &drawcalls, const std::vector<ImageHandle> &renderTargets) { @@ -345,7 +345,7 @@ namespace vkcv } for (int i = 0; i < drawcalls.size(); i++) { - recordDrawcall(drawcalls[i], cmdBuffer, pipelineLayout, pushConstantData, i); + recordDrawcall(drawcalls[i], cmdBuffer, pipelineLayout, pushConstants, i); } cmdBuffer.endRenderPass(); @@ -364,7 +364,7 @@ namespace vkcv PipelineHandle computePipeline, const uint32_t dispatchCount[3], const std::vector<DescriptorSetUsage>& descriptorSetUsages, - const PushConstantData& pushConstantData) { + const PushConstants& pushConstants) { auto submitFunction = [&](const vk::CommandBuffer& cmdBuffer) { @@ -379,13 +379,13 @@ namespace vkcv { usage.vulkanHandle }, {}); } - if (pushConstantData.sizePerDrawcall > 0) { + if (pushConstants.getSizePerDrawcall() > 0) { cmdBuffer.pushConstants( pipelineLayout, vk::ShaderStageFlagBits::eCompute, 0, - pushConstantData.sizePerDrawcall, - pushConstantData.data); + pushConstants.getSizePerDrawcall(), + pushConstants.getData()); } cmdBuffer.dispatch(dispatchCount[0], dispatchCount[1], dispatchCount[2]); }; diff --git a/src/vkcv/DrawcallRecording.cpp b/src/vkcv/DrawcallRecording.cpp index e6ea18588c251b5e49f454618a5ac9962cc8a264..cae0b3226e5e6bc424123d5bfa21b98a73cb3951 100644 --- a/src/vkcv/DrawcallRecording.cpp +++ b/src/vkcv/DrawcallRecording.cpp @@ -6,7 +6,7 @@ namespace vkcv { const DrawcallInfo &drawcall, vk::CommandBuffer cmdBuffer, vk::PipelineLayout pipelineLayout, - const PushConstantData &pushConstantData, + const PushConstants &pushConstants, const size_t drawcallIndex) { for (uint32_t i = 0; i < drawcall.mesh.vertexBufferBindings.size(); i++) { @@ -23,17 +23,15 @@ namespace vkcv { nullptr); } - const size_t drawcallPushConstantOffset = drawcallIndex * pushConstantData.sizePerDrawcall; - // char* cast because void* does not support pointer arithmetic - const void* drawcallPushConstantData = drawcallPushConstantOffset + (char*)pushConstantData.data; + const size_t drawcallPushConstantOffset = drawcallIndex * pushConstants.getSizePerDrawcall(); - if (pushConstantData.data && pushConstantData.sizePerDrawcall > 0) { + if (pushConstants.getSizePerDrawcall() > 0) { cmdBuffer.pushConstants( pipelineLayout, vk::ShaderStageFlagBits::eAll, 0, - pushConstantData.sizePerDrawcall, - drawcallPushConstantData); + pushConstants.getSizePerDrawcall(), + pushConstants.getDrawcallData(drawcallIndex)); } if (drawcall.mesh.indexBuffer) {