diff --git a/config/Sources.cmake b/config/Sources.cmake index f0fd0ed758ee8b7f4d8ce0940babf0e1142e6b60..ffbe38d67217ef515c89a5e6a26661441b22491d 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 ca826ea52e9bcee72c14c26496c99937c27fb775..e02e5e6995c9aa563cf24d2e1fe68f879b006a8e 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 0000000000000000000000000000000000000000..64d0f1db09f4e2321d527c832b49464e64099179 --- /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 d022fbed739255bac4fec06136d873c08cae380a..40ac830cd894736b76c5d220118377d02e9bb1b5 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 c8e51fe9716af0304687d6ae60fc0bea2a5d2cc6..d0872f19f52f0e17914c3e760d47b055063636e6 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 811e1162588fa699b4d74045504dc9c3d4de4f4c..fdef23f8537edeca665a4d4d9994e53af649e989 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 fa671a5507a7621586497048128e8959f72cdf08..b84834cda37ef87eb6893ad201a230cbea422d20 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 c2d8bf817dd1d6b2c7cc069f2037ee090abc4415..81330c39c37b24d928e4c34958b8fd3a4dfda10e 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 e6885b8e7dfa71c00335dbb2cee5c5994ce4eccc..e327ba8200532c022804c90be2b6082aa2b8c65c 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 c9345684225e64f792a13ade2e5d11297ab7c444..7f3e8ae8a5deeb55539762554f7b4736331ae499 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 26f523958e9704d7fc090ceba818591d904a2e92..e9d50c468ad33746b57400edaeb0c36f9d6b38e2 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 a74561ca07f7a052fe71c9e1d1efc751c2ab258c..56a8d827e25c15508717bc8d0dd685156969ed54 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 db538796201ee4c1cf5830bfd82036f16a82e693..f13fb8e07addd1c5b6090adb8d43257d47039bc3 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 670986fff81d4f308aa063e6275f41872bc8e878..4eb3a6490cb61a791f56e280f4160193caa5e7c6 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 e1bfd2231bc8047f12ba7d71e6a176f1fd85d92c..4ce5b2b5b023f45a32b96db40f1f8aa2c4006132 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 68bc546ded40e7f45454d62bfc4e8cd7227da4b7..b9b290e2d324a8d550a4ffc41e0afe344d90a7db 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 a4b967b33f47110df42ca02849fbeb06b4a024f8..8b8fd8bd87f5349372233111c06917075406ffb7 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 b30d8a7fa1e9cb56158903de4b11c24ddc503b94..99e82ce7520fb54b3bbfcc625467261bef1bf741 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 fe096114ead0b66a6d919a4d49baa791debc4897..b2101b1dc436d66c441c0a453a7498577578c9d3 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 7c865fac55cc9c4a7185006b3b74b205f9ac9105..4cbca35f10ed9f88f25051bb7bc9b8e4d71c235b 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 0000000000000000000000000000000000000000..5492ba2e93df1eeceaf70a8dcca4841f6243cc43 --- /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 0000000000000000000000000000000000000000..06e566a13f287051db8fbe55a20a06bfa3e559c2 --- /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; + } + +}