From 9a74f55b2e902e4b5b051d832fe3c7b6c2c67b13 Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Tue, 5 Jul 2022 02:26:32 +0200 Subject: [PATCH] Added proper type guard for push constants Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- config/Sources.cmake | 4 + include/vkcv/PushConstants.hpp | 55 +++------ include/vkcv/TypeGuard.hpp | 78 +++++++++++++ .../vkcv/algorithm/SinglePassDownsampler.cpp | 5 +- .../src/vkcv/effects/BloomAndFlaresEffect.cpp | 2 +- projects/bindless_textures/src/main.cpp | 2 +- projects/first_mesh/src/main.cpp | 2 +- projects/first_triangle/src/main.cpp | 3 +- projects/indirect_dispatch/src/App.cpp | 2 +- projects/indirect_dispatch/src/MotionBlur.cpp | 8 +- projects/indirect_draw/src/main.cpp | 2 +- projects/mesh_shader/src/main.cpp | 2 +- projects/particle_simulation/src/main.cpp | 2 +- projects/path_tracer/src/main.cpp | 2 +- projects/rtx_ambient_occlusion/src/main.cpp | 2 +- projects/saf_r/src/main.cpp | 2 +- projects/voxelization/src/ShadowMapping.cpp | 4 +- projects/voxelization/src/Voxelization.cpp | 4 +- projects/voxelization/src/main.cpp | 7 +- projects/wobble_bobble/src/main.cpp | 4 +- src/vkcv/PushConstants.cpp | 44 +++++++ src/vkcv/TypeGuard.cpp | 109 ++++++++++++++++++ 22 files changed, 282 insertions(+), 63 deletions(-) create mode 100644 include/vkcv/TypeGuard.hpp create mode 100644 src/vkcv/PushConstants.cpp create mode 100644 src/vkcv/TypeGuard.cpp diff --git a/config/Sources.cmake b/config/Sources.cmake index f0fd0ed7..ffbe38d6 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -30,6 +30,7 @@ set(vkcv_sources ${vkcv_include}/vkcv/Buffer.hpp ${vkcv_include}/vkcv/PushConstants.hpp + ${vkcv_source}/vkcv/PushConstants.cpp ${vkcv_include}/vkcv/BufferManager.hpp ${vkcv_source}/vkcv/BufferManager.cpp @@ -75,6 +76,9 @@ set(vkcv_sources ${vkcv_source}/vkcv/VertexLayout.cpp ${vkcv_include}/vkcv/Event.hpp + + ${vkcv_include}/vkcv/TypeGuard.hpp + ${vkcv_source}/vkcv/TypeGuard.cpp ${vkcv_source}/vkcv/DescriptorManager.hpp ${vkcv_source}/vkcv/DescriptorManager.cpp diff --git a/include/vkcv/PushConstants.hpp b/include/vkcv/PushConstants.hpp index ca826ea5..e02e5e69 100644 --- a/include/vkcv/PushConstants.hpp +++ b/include/vkcv/PushConstants.hpp @@ -9,24 +9,21 @@ #include <vulkan/vulkan.hpp> #include "Logger.hpp" +#include "TypeGuard.hpp" namespace vkcv { /** * @brief Class to handle push constants data per drawcall. */ - class PushConstants { + class PushConstants final { private: + TypeGuard m_typeGuard; 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) {} + explicit PushConstants(size_t sizePerDrawcall); + explicit PushConstants(const TypeGuard &guard); PushConstants(const PushConstants& other) = default; PushConstants(PushConstants&& other) = default; @@ -43,9 +40,7 @@ namespace vkcv { * @return Size of data per drawcall */ [[nodiscard]] - size_t getSizePerDrawcall() const { - return m_sizePerDrawcall; - } + size_t getSizePerDrawcall() const; /** * @brief Returns the size of total data stored for @@ -54,9 +49,7 @@ namespace vkcv { * @return Total size of data */ [[nodiscard]] - size_t getFullSize() const { - return m_data.size(); - } + size_t getFullSize() const; /** * @brief Returns the number of drawcalls that data @@ -65,17 +58,13 @@ namespace vkcv { * @return Number of drawcalls */ [[nodiscard]] - size_t getDrawcallCount() const { - return (m_data.size() / m_sizePerDrawcall); - } + size_t getDrawcallCount() const; /** * @brief Clears the data for all drawcalls currently. * stored. */ - void clear() { - m_data.clear(); - } + void clear(); /** * @brief Appends data for a single drawcall to the @@ -87,9 +76,7 @@ namespace vkcv { */ template<typename T = uint8_t> bool appendDrawcall(const T& value) { - if (sizeof(T) != m_sizePerDrawcall) { - vkcv_log(LogLevel::WARNING, "Size (%lu) of value does not match the specified size per drawcall (%lu)", - sizeof(value), m_sizePerDrawcall); + if (!m_typeGuard.template check<T>()) { return false; } @@ -109,7 +96,7 @@ namespace vkcv { */ template<typename T = uint8_t> T& getDrawcall(size_t index) { - const size_t offset = (index * m_sizePerDrawcall); + const size_t offset = (index * getSizePerDrawcall()); return *reinterpret_cast<T*>(m_data.data() + offset); } @@ -123,7 +110,7 @@ namespace vkcv { */ template<typename T = uint8_t> const T& getDrawcall(size_t index) const { - const size_t offset = (index * m_sizePerDrawcall); + const size_t offset = (index * getSizePerDrawcall()); return *reinterpret_cast<const T*>(m_data.data() + offset); } @@ -135,10 +122,7 @@ namespace vkcv { * @return Drawcall data */ [[nodiscard]] - const void* getDrawcallData(size_t index) const { - const size_t offset = (index * m_sizePerDrawcall); - return reinterpret_cast<const void*>(m_data.data() + offset); - } + const void* getDrawcallData(size_t index) const; /** * @brief Returns the pointer to the entire drawcall data which @@ -147,14 +131,13 @@ namespace vkcv { * @return Pointer to the data */ [[nodiscard]] - const void* getData() const { - if (m_data.empty()) { - return nullptr; - } else { - return m_data.data(); - } - } + const void* getData() const; }; + template<typename T> + PushConstants pushConstants() { + return PushConstants(typeGuard<T>()); + } + } diff --git a/include/vkcv/TypeGuard.hpp b/include/vkcv/TypeGuard.hpp new file mode 100644 index 00000000..64d0f1db --- /dev/null +++ b/include/vkcv/TypeGuard.hpp @@ -0,0 +1,78 @@ +#pragma once +/** + * @authors Tobias Frisch + * @file vkcv/TypeGuard.hpp + * @brief Support type safety for classes in debug compilation. + */ + +#include <stdlib.h> +#include <typeinfo> + +namespace vkcv { + + class TypeGuard { + private: +#ifndef NDEBUG + const char* m_typeName; + size_t m_typeHash; + + [[nodiscard]] + bool checkType(const char* name, size_t hash, size_t size) const; +#endif + size_t m_typeSize; + + [[nodiscard]] + bool checkTypeSize(size_t size) const; + + public: + explicit TypeGuard(size_t size = 0); + TypeGuard(const std::type_info &info, size_t size); + + TypeGuard(const TypeGuard &other) = default; + TypeGuard(TypeGuard &&other) noexcept; + + ~TypeGuard() = default; + + TypeGuard& operator=(const TypeGuard &other) = default; + TypeGuard& operator=(TypeGuard &&other) noexcept; + + bool operator==(const TypeGuard &other) const; + bool operator!=(const TypeGuard &other) const; + + template<typename T> + [[nodiscard]] + bool check() const { +#ifndef NDEBUG + return checkType(typeid(T).name(), typeid(T).hash_code(), sizeof(T)); +#else + return checkTypeSize(sizeof(T)); +#endif + } + + [[nodiscard]] + size_t typeSize() const; + + }; + + template<typename T> + TypeGuard typeGuard() { + static TypeGuard guard (typeid(T), sizeof(T)); + return guard; + } + + template<typename T> + TypeGuard typeGuard(T) { + return typeGuard<T>(); + } + + template<typename T> + TypeGuard typeGuard(const T&) { + return typeGuard<T>(); + } + + template<typename T> + TypeGuard typeGuard(T&&) { + return typeGuard<T>(); + } + +} diff --git a/modules/algorithm/src/vkcv/algorithm/SinglePassDownsampler.cpp b/modules/algorithm/src/vkcv/algorithm/SinglePassDownsampler.cpp index d022fbed..40ac830c 100644 --- a/modules/algorithm/src/vkcv/algorithm/SinglePassDownsampler.cpp +++ b/modules/algorithm/src/vkcv/algorithm/SinglePassDownsampler.cpp @@ -310,7 +310,10 @@ namespace vkcv::algorithm { dispatch[1] = dispatchThreadGroupCountXY[1]; dispatch[2] = m_core.getImageArrayLayers(image); - vkcv::PushConstants pushConstants (m_sampler? sizeof(SPDConstantsSampler) : sizeof(SPDConstants)); + vkcv::PushConstants pushConstants = (m_sampler? + vkcv::pushConstants<SPDConstantsSampler>() : + vkcv::pushConstants<SPDConstants>() + ); if (m_sampler) { SPDConstantsSampler data; diff --git a/modules/effects/src/vkcv/effects/BloomAndFlaresEffect.cpp b/modules/effects/src/vkcv/effects/BloomAndFlaresEffect.cpp index c8e51fe9..d0872f19 100644 --- a/modules/effects/src/vkcv/effects/BloomAndFlaresEffect.cpp +++ b/modules/effects/src/vkcv/effects/BloomAndFlaresEffect.cpp @@ -456,7 +456,7 @@ namespace vkcv::effects { dispatch[1] = calcDispatchSize(sampleHeight, threadGroupWorkRegionDim); dispatch[2] = 1; - PushConstants pushConstants (sizeof(m_cameraDirection)); + PushConstants pushConstants = vkcv::pushConstants<glm::vec3>(); pushConstants.appendDrawcall(m_cameraDirection); // bloom composite dispatch diff --git a/projects/bindless_textures/src/main.cpp b/projects/bindless_textures/src/main.cpp index 811e1162..fdef23f8 100644 --- a/projects/bindless_textures/src/main.cpp +++ b/projects/bindless_textures/src/main.cpp @@ -256,7 +256,7 @@ int main(int argc, const char** argv) { cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - vkcv::PushConstants pushConstants (sizeof(glm::mat4)); + vkcv::PushConstants pushConstants = vkcv::pushConstants<glm::mat4>(); pushConstants.appendDrawcall(mvp); const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index fa671a55..b84834cd 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -196,7 +196,7 @@ int main(int argc, const char** argv) { cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - vkcv::PushConstants pushConstants (sizeof(glm::mat4)); + vkcv::PushConstants pushConstants = vkcv::pushConstants<glm::mat4>(); pushConstants.appendDrawcall(mvp); const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index c2d8bf81..81330c39 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -78,7 +78,6 @@ int main(int argc, const char** argv) { vkcv::DrawcallInfo drawcall(renderMesh, {},1); const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - core.setDebugLabel(swapchainInput, "Swapchain Image"); vkcv::camera::CameraManager cameraManager(window); uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); @@ -104,7 +103,7 @@ int main(int argc, const char** argv) { cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - vkcv::PushConstants pushConstants (sizeof(glm::mat4)); + vkcv::PushConstants pushConstants = vkcv::pushConstants<glm::mat4>(); pushConstants.appendDrawcall(mvp); auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp index e6885b8e..e327ba82 100644 --- a/projects/indirect_dispatch/src/App.cpp +++ b/projects/indirect_dispatch/src/App.cpp @@ -274,7 +274,7 @@ void App::run() { m_windowHandle); // sky - vkcv::PushConstants skyPushConstants(sizeof(glm::mat4)); + vkcv::PushConstants skyPushConstants = vkcv::pushConstants<glm::mat4>(); skyPushConstants.appendDrawcall(viewProjection); m_core.recordDrawcallsToCmdStream( diff --git a/projects/indirect_dispatch/src/MotionBlur.cpp b/projects/indirect_dispatch/src/MotionBlur.cpp index c9345684..7f3e8ae8 100644 --- a/projects/indirect_dispatch/src/MotionBlur.cpp +++ b/projects/indirect_dispatch/src/MotionBlur.cpp @@ -163,7 +163,7 @@ vkcv::ImageHandle MotionBlur::render( classificationConstants.height = m_core->getImageHeight(m_renderTargets.outputColor); classificationConstants.fastPathThreshold = fastPathThreshold; - vkcv::PushConstants classificationPushConstants(sizeof(ClassificationConstants)); + vkcv::PushConstants classificationPushConstants = vkcv::pushConstants<ClassificationConstants>(); classificationPushConstants.appendDrawcall(classificationConstants); m_core->prepareImageForSampling(cmdStream, m_renderTargets.motionMaxNeighbourhood); @@ -235,7 +235,7 @@ vkcv::ImageHandle MotionBlur::render( motionBlurConstantData.cameraFarPlane = cameraFar; motionBlurConstantData.motionTileOffsetLength = motionTileOffsetLength; - vkcv::PushConstants motionBlurPushConstants(sizeof(motionBlurConstantData)); + vkcv::PushConstants motionBlurPushConstants = vkcv::pushConstants<MotionBlurConstantData>(); motionBlurPushConstants.appendDrawcall(motionBlurConstantData); struct FastPathConstants { @@ -244,7 +244,7 @@ vkcv::ImageHandle MotionBlur::render( FastPathConstants fastPathConstants; fastPathConstants.motionFactor = motionBlurConstantData.motionFactor; - vkcv::PushConstants fastPathPushConstants(sizeof(FastPathConstants)); + vkcv::PushConstants fastPathPushConstants = vkcv::pushConstants<FastPathConstants>(); fastPathPushConstants.appendDrawcall(fastPathConstants); m_core->prepareImageForStorage(cmdStream, m_renderTargets.outputColor); @@ -361,7 +361,7 @@ vkcv::ImageHandle MotionBlur::renderMotionVectorVisualisation( m_core->prepareImageForSampling(cmdStream, visualisationInput); m_core->prepareImageForStorage(cmdStream, m_renderTargets.outputColor); - vkcv::PushConstants motionVectorVisualisationPushConstants(sizeof(float)); + vkcv::PushConstants motionVectorVisualisationPushConstants = vkcv::pushConstants<float>(); motionVectorVisualisationPushConstants.appendDrawcall(velocityRange); const auto dispatchSizes = computeFullscreenDispatchSize( diff --git a/projects/indirect_draw/src/main.cpp b/projects/indirect_draw/src/main.cpp index 26f52395..e9d50c46 100644 --- a/projects/indirect_draw/src/main.cpp +++ b/projects/indirect_draw/src/main.cpp @@ -547,7 +547,7 @@ int main(int argc, const char** argv) { start = end; cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); vkcv::camera::Camera cam = cameraManager.getActiveCamera(); - vkcv::PushConstants pushConstants(sizeof(glm::mat4)); + vkcv::PushConstants pushConstants = vkcv::pushConstants<glm::mat4>(); pushConstants.appendDrawcall(cam.getProjection() * cam.getView()); if(updateFrustumPlanes) diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp index a74561ca..56a8d827 100644 --- a/projects/mesh_shader/src/main.cpp +++ b/projects/mesh_shader/src/main.cpp @@ -356,7 +356,7 @@ int main(int argc, const char** argv) { const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - vkcv::PushConstants pushConstantData(sizeof(pushConstants)); + vkcv::PushConstants pushConstantData = vkcv::pushConstants<PushConstants>(); pushConstantData.appendDrawcall(pushConstants); if (useMeshShader) { diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp index db538796..f13fb8e0 100644 --- a/projects/particle_simulation/src/main.cpp +++ b/projects/particle_simulation/src/main.cpp @@ -277,7 +277,7 @@ int main(int argc, const char **argv) { float random = rdm(rdmEngine); glm::vec2 pushData = glm::vec2(deltatime, random); - vkcv::PushConstants pushConstantsCompute (sizeof(glm::vec2)); + vkcv::PushConstants pushConstantsCompute = vkcv::pushConstants<glm::vec2>(); pushConstantsCompute.appendDrawcall(pushData); uint32_t computeDispatchCount[3] = {static_cast<uint32_t> (std::ceil(particleSystem.getParticles().size()/256.f)),1,1}; diff --git a/projects/path_tracer/src/main.cpp b/projects/path_tracer/src/main.cpp index 670986ff..4eb3a649 100644 --- a/projects/path_tracer/src/main.cpp +++ b/projects/path_tracer/src/main.cpp @@ -362,7 +362,7 @@ int main(int argc, const char** argv) { raytracingPushData.planeCount = planes.size(); raytracingPushData.frameIndex = frameIndex; - vkcv::PushConstants pushConstantsCompute(sizeof(RaytracingPushConstantData)); + vkcv::PushConstants pushConstantsCompute = vkcv::pushConstants<RaytracingPushConstantData>(); pushConstantsCompute.appendDrawcall(raytracingPushData); uint32_t traceDispatchCount[3] = { diff --git a/projects/rtx_ambient_occlusion/src/main.cpp b/projects/rtx_ambient_occlusion/src/main.cpp index e1bfd223..4ce5b2b5 100644 --- a/projects/rtx_ambient_occlusion/src/main.cpp +++ b/projects/rtx_ambient_occlusion/src/main.cpp @@ -130,7 +130,7 @@ int main(int argc, const char** argv) { raytracingPushData.camera_up = glm::vec4(cameraManager.getActiveCamera().getUp(),0); raytracingPushData.camera_forward = glm::vec4(cameraManager.getActiveCamera().getFront(),0); - vkcv::PushConstants pushConstantsRTX(sizeof(RaytracingPushConstantData)); + vkcv::PushConstants pushConstantsRTX = vkcv::pushConstants<RaytracingPushConstantData>(); pushConstantsRTX.appendDrawcall(raytracingPushData); auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); diff --git a/projects/saf_r/src/main.cpp b/projects/saf_r/src/main.cpp index 68bc546d..b9b290e2 100644 --- a/projects/saf_r/src/main.cpp +++ b/projects/saf_r/src/main.cpp @@ -273,7 +273,7 @@ int main(int argc, const char** argv) { raytracingPushData.sphereCount = spheres.size(); raytracingPushData.viewToWorld = glm::inverse(cameraManager.getActiveCamera().getView()); - vkcv::PushConstants pushConstantsCompute(sizeof(RaytracingPushConstantData)); + vkcv::PushConstants pushConstantsCompute = vkcv::pushConstants<RaytracingPushConstantData>(); pushConstantsCompute.appendDrawcall(raytracingPushData); //dispatch compute shader diff --git a/projects/voxelization/src/ShadowMapping.cpp b/projects/voxelization/src/ShadowMapping.cpp index a4b967b3..8b8fd8bd 100644 --- a/projects/voxelization/src/ShadowMapping.cpp +++ b/projects/voxelization/src/ShadowMapping.cpp @@ -255,7 +255,7 @@ void ShadowMapping::recordShadowMapRendering( voxelVolumeExtent); m_lightInfoBuffer.fill({ lightInfo }); - vkcv::PushConstants shadowPushConstants (sizeof(glm::mat4)); + vkcv::PushConstants shadowPushConstants = vkcv::pushConstants<glm::mat4>(); for (const auto& m : modelMatrices) { shadowPushConstants.appendDrawcall(lightInfo.lightMatrix * m); @@ -286,7 +286,7 @@ void ShadowMapping::recordShadowMapRendering( const uint32_t msaaSampleCount = msaaToSampleCount(msaa); - vkcv::PushConstants msaaPushConstants (sizeof(msaaSampleCount)); + vkcv::PushConstants msaaPushConstants = vkcv::pushConstants<uint32_t>(); msaaPushConstants.appendDrawcall(msaaSampleCount); m_corePtr->recordBeginDebugLabel(cmdStream, "Depth to moments", { 1, 1, 1, 1 }); diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp index b30d8a7f..99e82ce7 100644 --- a/projects/voxelization/src/Voxelization.cpp +++ b/projects/voxelization/src/Voxelization.cpp @@ -259,7 +259,7 @@ void Voxelization::voxelizeMeshes( resetVoxelDispatchCount[1] = 1; resetVoxelDispatchCount[2] = 1; - vkcv::PushConstants voxelCountPushConstants (sizeof(voxelCount)); + vkcv::PushConstants voxelCountPushConstants = vkcv::pushConstants<uint32_t>(); voxelCountPushConstants.appendDrawcall(voxelCount); m_corePtr->recordBeginDebugLabel(cmdStream, "Voxel reset", { 1, 1, 1, 1 }); @@ -343,7 +343,7 @@ void Voxelization::renderVoxelVisualisation( uint32_t mipLevel, const vkcv::WindowHandle& windowHandle) { - vkcv::PushConstants voxelVisualisationPushConstants (sizeof(glm::mat4)); + vkcv::PushConstants voxelVisualisationPushConstants = vkcv::pushConstants<glm::mat4>(); voxelVisualisationPushConstants.appendDrawcall(viewProjectin); mipLevel = std::clamp(mipLevel, (uint32_t)0, m_voxelImage.getMipCount()-1); diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index fe096114..b2101b1d 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -259,7 +259,6 @@ int main(int argc, const char** argv) { std::vector<vkcv::Image> sceneImages; vkcv::algorithm::SinglePassDownsampler spdDownsampler (core, colorSampler); - vkcv::Downsampler &downsampler = core.getDownsampler(); auto mipStream = core.createCommandStream(vkcv::QueueType::Graphics); @@ -800,7 +799,7 @@ int main(int argc, const char** argv) { // depth prepass const glm::mat4 viewProjectionCamera = cameraManager.getActiveCamera().getMVP(); - vkcv::PushConstants prepassPushConstants (sizeof(glm::mat4)); + vkcv::PushConstants prepassPushConstants = vkcv::pushConstants<glm::mat4>(); std::vector<glm::mat4> prepassMatrices; for (const auto& m : modelMatrices) { @@ -853,7 +852,7 @@ int main(int argc, const char** argv) { voxelization.renderVoxelVisualisation(cmdStream, viewProjectionCamera, renderTargets, voxelVisualisationMip, windowHandle); } - vkcv::PushConstants skySettingsPushConstants (sizeof(skySettings)); + vkcv::PushConstants skySettingsPushConstants = vkcv::pushConstants<SkySettings>(); skySettingsPushConstants.appendDrawcall(skySettings); // sky @@ -943,7 +942,7 @@ 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.01f; - vkcv::PushConstants timePushConstants (sizeof(timeF)); + vkcv::PushConstants timePushConstants = vkcv::pushConstants<float>(); timePushConstants.appendDrawcall(timeF); fulsscreenDispatchCount[0] = static_cast<uint32_t>( diff --git a/projects/wobble_bobble/src/main.cpp b/projects/wobble_bobble/src/main.cpp index 7c865fac..4cbca35f 100644 --- a/projects/wobble_bobble/src/main.cpp +++ b/projects/wobble_bobble/src/main.cpp @@ -684,13 +684,13 @@ int main(int argc, const char **argv) { physics.dt = static_cast<float>(0.000001 * static_cast<double>(deltatime.count())); physics.speedfactor = speed_factor; - vkcv::PushConstants physicsPushConstants(sizeof(physics)); + vkcv::PushConstants physicsPushConstants = vkcv::pushConstants<Physics>(); physicsPushConstants.appendDrawcall(physics); cameraManager.update(physics.dt); glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - vkcv::PushConstants cameraPushConstants(sizeof(glm::mat4)); + vkcv::PushConstants cameraPushConstants = vkcv::pushConstants<glm::mat4>(); cameraPushConstants.appendDrawcall(mvp); auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); diff --git a/src/vkcv/PushConstants.cpp b/src/vkcv/PushConstants.cpp new file mode 100644 index 00000000..5492ba2e --- /dev/null +++ b/src/vkcv/PushConstants.cpp @@ -0,0 +1,44 @@ +#include <vkcv/PushConstants.hpp> + +namespace vkcv { + + PushConstants::PushConstants(size_t sizePerDrawcall) : + m_typeGuard(sizePerDrawcall), + m_data() + {} + + PushConstants::PushConstants(const TypeGuard &guard) : + m_typeGuard(guard), + m_data() + {} + + size_t PushConstants::getSizePerDrawcall() const { + return m_typeGuard.typeSize(); + } + + size_t PushConstants::getFullSize() const { + return m_data.size(); + } + + size_t PushConstants::getDrawcallCount() const { + return getFullSize() / getSizePerDrawcall(); + } + + void PushConstants::clear() { + m_data.clear(); + } + + const void* PushConstants::getDrawcallData(size_t index) const { + const size_t offset = (index * getSizePerDrawcall()); + return reinterpret_cast<const void*>(m_data.data() + offset); + } + + const void* PushConstants::getData() const { + if (m_data.empty()) { + return nullptr; + } else { + return m_data.data(); + } + } + +} diff --git a/src/vkcv/TypeGuard.cpp b/src/vkcv/TypeGuard.cpp new file mode 100644 index 00000000..06e566a1 --- /dev/null +++ b/src/vkcv/TypeGuard.cpp @@ -0,0 +1,109 @@ +#include <vkcv/TypeGuard.hpp> + +#include <vkcv/Logger.hpp> +#include <string.h> + +namespace vkcv { + +#ifndef NDEBUG + bool TypeGuard::checkType(const char* name, size_t hash, size_t size) const { + if (!checkTypeSize(size)) { + return false; + } + + if ((!m_typeName) || (!name)) { + return true; + } + + if (m_typeHash != hash) { + vkcv_log( + LogLevel::WARNING, + "Hash (%lu) does not match the specified hash of the type guard (%lu)", + hash, + m_typeHash + ); + + return false; + } + + if (strcmp(m_typeName, name) != 0) { + vkcv_log( + LogLevel::WARNING, + "Name (%s) does not match the specified name of the type guard (%s)", + name, + m_typeName + ); + + return false; + } else { + return true; + } + } +#endif + + bool TypeGuard::checkTypeSize(size_t size) const { + if (m_typeSize != size) { + vkcv_log( + LogLevel::WARNING, + "Size (%lu) does not match the specified size of the type guard (%lu)", + size, + m_typeSize + ); + + return false; + } else { + return true; + } + } + + TypeGuard::TypeGuard(size_t size) : +#ifndef NDEBUG + m_typeName(nullptr), m_typeHash(0), +#endif + m_typeSize(size) + {} + + TypeGuard::TypeGuard(const std::type_info &info, size_t size) : +#ifndef NDEBUG + m_typeName(info.name()), m_typeHash(info.hash_code()), +#endif + m_typeSize(size) + {} + + TypeGuard::TypeGuard(TypeGuard &&other) noexcept : +#ifndef NDEBUG + m_typeName(other.m_typeName), m_typeHash(other.m_typeHash), +#endif + m_typeSize(other.m_typeSize) + {} + + TypeGuard& TypeGuard::operator=(TypeGuard &&other) noexcept { +#ifndef NDEBUG + m_typeName = other.m_typeName; + m_typeHash = other.m_typeHash; +#endif + m_typeSize = other.m_typeSize; + return *this; + } + + bool TypeGuard::operator==(const TypeGuard &other) const { +#ifndef NDEBUG + return checkType(other.m_typeName, other.m_typeHash, other.m_typeSize); +#else + return checkTypeSize(other.m_typeSize); +#endif + } + + bool TypeGuard::operator!=(const TypeGuard &other) const { +#ifndef NDEBUG + return !checkType(other.m_typeName, other.m_typeHash, other.m_typeSize); +#else + return !checkTypeSize(other.m_typeSize); +#endif + } + + size_t TypeGuard::typeSize() const { + return m_typeSize; + } + +} -- GitLab