diff --git a/CMakeLists.txt b/CMakeLists.txt index b90990a300786467744d6b879265167c04f7eb9d..ce6dc32fd9e828478d7d449580d12790fc672a6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ add_subdirectory(libs) find_package(Vulkan REQUIRED) if(DEFINED ENV{RENDERDOC_PATH}) - set(RENDERDOC_PATH ENV{RENDERDOC_PATH}) + set(RENDERDOC_PATH $ENV{RENDERDOC_PATH}) elseif(WIN32) if(EXISTS "C:\\Program Files\\RenderDoc") set(RENDERDOC_PATH "C:\\Program Files\\RenderDoc") @@ -87,6 +87,9 @@ set(SOURCES add_compile_definitions(WORKING_DIR="${CMAKE_CURRENT_SOURCE_DIR}") add_executable(${PROJECT_NAME} ${SOURCES}) + +add_shader(${PROJECT_NAME} shaders/particle_simulation.comp) + add_shader(${PROJECT_NAME} shaders/particles.comp) add_shader(${PROJECT_NAME} shaders/white.frag) add_shader(${PROJECT_NAME} shaders/soup.vert) @@ -99,7 +102,6 @@ add_shader(${PROJECT_NAME} shaders/particle2d.frag) add_shader(${PROJECT_NAME} shaders/background2d.vert) add_shader(${PROJECT_NAME} shaders/background2d.frag) - add_shader(${PROJECT_NAME} shaders/spatial_lookup.write.comp) add_shader(${PROJECT_NAME} shaders/spatial_lookup.sort.comp) add_shader(${PROJECT_NAME} shaders/spatial_lookup.index.comp) diff --git a/include/camera.h b/include/camera.h index afb7595019b959b5c6992d4d90b7bfa5495fdfd7..55acd9ec16567815d92ad1e8f9f2496bb9c8b711 100644 --- a/include/camera.h +++ b/include/camera.h @@ -9,7 +9,7 @@ public: float fovy = 0.9, aspect = 1280.f / 720.f, near = 0.1, far = 100; Camera(Camera &other) = delete; - Camera(){ + Camera() { reset(); } diff --git a/include/colormaps.h b/include/colormaps.h index a91655c9b7c8881349f378f2fa3b22cb47918714..3a7a05c8b4913abb76cb010c4abd3e172fa26302 100644 --- a/include/colormaps.h +++ b/include/colormaps.h @@ -10,4 +10,4 @@ struct RGB_F32 { extern std::vector<RGB_F32> viridis; -} // namespace colormaps +}// namespace colormaps diff --git a/include/debug_image.h b/include/debug_image.h index 6230e9cba9c13f641cde37a0bbd0ad13d59e28a7..5d294c21952f6f4715cb0b27f526c12359aba5df 100644 --- a/include/debug_image.h +++ b/include/debug_image.h @@ -5,14 +5,14 @@ class DebugImage { vk::DescriptorImageInfo descriptorInfo; vk::DeviceMemory imageMemory; + public: explicit DebugImage(std::string name); ~DebugImage(); vk::Image image; vk::ImageView view; - void clear(vk::CommandBuffer cmd, std::array<float,4> color); + void clear(vk::CommandBuffer cmd, std::array<float, 4> color); vk::DescriptorSetLayoutBinding getLayout(uint32_t binding); vk::WriteDescriptorSet getWrite(vk::DescriptorSet set, uint32_t binding); }; - diff --git a/include/helper.h b/include/helper.h index cfc61d4437d0a2bb86452ee5d344a47a122dbcad..72c9a4b871cac6566c6fe81bab72c274a8ddb8e8 100644 --- a/include/helper.h +++ b/include/helper.h @@ -8,6 +8,6 @@ inline std::string workingDir = std::string("./"); #endif const static std::string shaderDir = workingDir + "build/shaders/"; -inline std::string shaderPath(const char* file) { +inline std::string shaderPath(const char *file) { return shaderDir + file + ".spv"; } diff --git a/include/imgui_ui.h b/include/imgui_ui.h index 6a8b66492dba57686ea68487fc950d636b9e619b..38c3d3d6260b647f076dd0b06941f933d5e0ddde 100644 --- a/include/imgui_ui.h +++ b/include/imgui_ui.h @@ -9,7 +9,7 @@ struct SimulationState; /** * Wrap Parameters and update flags in convenience struct. */ -struct UiBindings{ +struct UiBindings { uint32_t frameIndex; SimulationParameters &simulationParameters; RenderParameters &renderParameters; @@ -29,10 +29,10 @@ struct UiBindings{ */ inline UiBindings(uint32_t frameIndex, SimulationParameters &simulationParameters, RenderParameters &renderParameters, SimulationState *simulationState) : frameIndex(frameIndex), - simulationParameters(simulationParameters), - renderParameters(renderParameters), - simulationState(simulationState), - updateFlags() {} + simulationParameters(simulationParameters), + renderParameters(renderParameters), + simulationState(simulationState), + updateFlags() {} }; class ImguiUi { @@ -54,6 +54,3 @@ public: void drawUi(UiBindings &bindings); }; - - - diff --git a/include/initialization.h b/include/initialization.h index e287ae256f61f20f5f6b6e687f90aa84fc6da696..3b604c02f99777b3224e80f92c4ed9bb61196d9c 100644 --- a/include/initialization.h +++ b/include/initialization.h @@ -1,12 +1,12 @@ #pragma once +#include "task_common.h" #include "utils.h" -#include <vulkan/vulkan.hpp> #include <GLFW/glfw3.h> -#include <glm/glm.hpp> #include <cstring> +#include <glm/glm.hpp> #include <memory> -#include "task_common.h" +#include <vulkan/vulkan.hpp> VKAPI_ATTR VkBool32 VKAPI_CALL debugUtilsMessengerCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, @@ -32,4 +32,4 @@ void createSwapchain(AppResources &app); void printDeviceCapabilities(vk::PhysicalDevice &pDevice); -void initApp(AppResources &app, bool withWindow = false, const std::string& name = "GPGPU/GPU-C", int width = 800, int height = 600); +void initApp(AppResources &app, bool withWindow = false, const std::string &name = "GPGPU/GPU-C", int width = 800, int height = 600); diff --git a/include/particle_physics.h b/include/particle_physics.h index a1053054e56a4745f6bb899604ea8a22a19c73da..942dde113bb400c7210c0c6f07dafd31c404375f 100644 --- a/include/particle_physics.h +++ b/include/particle_physics.h @@ -1,9 +1,29 @@ #pragma once #include "initialization.h" +#include "simulation_state.h" +#include "task_common.h" + class ParticleSimulation { - vk::Pipeline simulationPipeline; public: - vk::CommandBuffer run(); + ParticleSimulation() = delete; + ParticleSimulation(const ParticleSimulation &particleSimulation) = delete; + explicit ParticleSimulation(const SimulationParameters ¶meters); + ~ParticleSimulation(); + vk::CommandBuffer run(const SimulationState &simulationState); + void updateCmd(const SimulationState &state); + +private: + const uint32_t workgroupSizeX = 128; + const uint32_t workgroupSizeY = 1; + TaskResources classResources; + SimulationParameters simulationParameters; + vk::CommandBuffer cmd; + struct PushStruct { + float gravity; + float deltaTime; + uint32_t numParticles; + float collisionDamping; + } pushStruct; }; \ No newline at end of file diff --git a/include/particle_renderer.h b/include/particle_renderer.h index 2f31871085d14709512f9afc9c2d7b07eb0cb6f7..3da3a16c90fc24f004093d98b8c055e8375159d3 100644 --- a/include/particle_renderer.h +++ b/include/particle_renderer.h @@ -1,7 +1,7 @@ #pragma once -#include "simulation_state.h" #include "colormaps.h" +#include "simulation_state.h" class ParticleRenderer { public: @@ -33,9 +33,7 @@ private: UniformBufferStruct() = default; UniformBufferStruct(const UniformBufferStruct &obj) = default; bool operator==(const UniformBufferStruct &obj) const { - return numParticles == obj.numParticles - && backgroundField == obj.backgroundField - && particleRadius == obj.particleRadius; + return numParticles == obj.numParticles && backgroundField == obj.backgroundField && particleRadius == obj.particleRadius; } } uniformBufferContent; diff --git a/include/project.h b/include/project.h index 486e4e4b98c837b9d412cc0a2d40361eff4b199f..1ae64d1bd8ca8c09f85f4890eb88bab7dca09a12 100644 --- a/include/project.h +++ b/include/project.h @@ -1,26 +1,26 @@ #pragma once -#include <iostream> #include <cstdlib> +#include <iostream> #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 #define GLM_FORCE_DEPTH_ZERO_TO_ONE #define GLM_FORCE_RADIANS #include <glm/glm.hpp> -#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/constants.hpp> +#include <glm/gtc/matrix_transform.hpp> -#include "tiny_obj_loader.h" -#include <vulkan/vulkan.hpp> -#include <fstream> -#include <vector> -#include <memory> +#include "helper.h" #include "initialization.h" -#include "utils.h" -#include "task_common.h" #include "render.h" -#include "helper.h" #include "simulation_parameters.h" +#include "task_common.h" +#include "tiny_obj_loader.h" +#include "utils.h" +#include <fstream> +#include <memory> +#include <vector> +#include <vulkan/vulkan.hpp> struct ProjectData { /** @@ -34,7 +34,7 @@ struct ProjectData { struct PushConstant { glm::mat4 mvp; glm::vec4 pos; - float dT; // timestep + float dT;// timestep }; PushConstant push; @@ -65,7 +65,7 @@ struct ProjectData { class ProjectSolution { public: - ProjectSolution(AppResources& app, ProjectData& datad, uint32_t workGroupSize_x, uint32_t triangleCacheSize); + ProjectSolution(AppResources &app, ProjectData &datad, uint32_t workGroupSize_x, uint32_t triangleCacheSize); void cleanup(); @@ -79,8 +79,8 @@ private: void makeSampler(); void initParticles(); - AppResources& app; - ProjectData& data; + AppResources &app; + ProjectData &data; uint32_t workGroupSize_x; uint32_t triangleCacheSize; // Local PPS Pipeline @@ -96,8 +96,8 @@ private: class ProjectRender { public: - AppResources& app; - Render& render; + AppResources &app; + Render &render; std::unique_ptr<ImguiUi> imguiUi = nullptr; vk::Pipeline opaquePipeline; @@ -107,12 +107,12 @@ public: bool renderForceLines = false; bool fPress = false; - ProjectRender(AppResources& app, Render& render): app(app), render(render) { + ProjectRender(AppResources &app, Render &render) : app(app), render(render) { imguiUi = std::make_unique<ImguiUi>(); }; - void createPipeline(vk::Pipeline& pipeline, ProjectData& data, const std::string& vertex, - const std::string& fragment, + void createPipeline(vk::Pipeline &pipeline, ProjectData &data, const std::string &vertex, + const std::string &fragment, vk::PrimitiveTopology primitiveType, vk::PolygonMode polygonMode, vk::PipelineColorBlendAttachmentState blendState, vk::CullModeFlagBits cullMode, unsigned int subpass, bool depthWrite) { @@ -124,107 +124,113 @@ public: // Put shader stage creation info in to array // Graphics Pipeline creation info requires array of shader stage creates vk::PipelineShaderStageCreateInfo shaderStageCI[] = { - {{}, vk::ShaderStageFlagBits::eVertex, vertexM, "main", nullptr}, - {{}, vk::ShaderStageFlagBits::eFragment, fragmentM, "main", nullptr}, + {{}, vk::ShaderStageFlagBits::eVertex, vertexM, "main", nullptr}, + {{}, vk::ShaderStageFlagBits::eFragment, fragmentM, "main", nullptr}, }; // Vertex input vk::PipelineVertexInputStateCreateInfo vertexInputSCI = { - {}, - 0, // Vertex binding description count - nullptr, // List of Vertex Binding Descriptions (data spacing/stride information) - 0, // Vertex attribute description count - nullptr // List of Vertex Attribute Descriptions (data format and where to bind to/from) + {}, + 0, // Vertex binding description count + nullptr,// List of Vertex Binding Descriptions (data spacing/stride information) + 0, // Vertex attribute description count + nullptr // List of Vertex Attribute Descriptions (data format and where to bind to/from) }; // Input assembly vk::PipelineInputAssemblyStateCreateInfo inputAssemblySCI = { - {}, - primitiveType, // Primitive type to assemble vertices as - false // Allow overriding of "strip" topology to start new primitives + {}, + primitiveType,// Primitive type to assemble vertices as + false // Allow overriding of "strip" topology to start new primitives }; // Viewport & Scissor vk::Viewport viewport = { - 0.f, // x start coordinate - (float)app.extent.height, // y start coordinate - (float)app.extent.width, // Width of viewport - -(float)app.extent.height, // Height of viewport - 0.f, // Min framebuffer depth, - 1.f // Max framebuffer depth + 0.f, // x start coordinate + (float) app.extent.height, // y start coordinate + (float) app.extent.width, // Width of viewport + -(float) app.extent.height,// Height of viewport + 0.f, // Min framebuffer depth, + 1.f // Max framebuffer depth }; vk::Rect2D scissor = { - {0, 0}, // Offset to use region from - app.extent // Extent to describe region to use, starting at offset + {0, 0}, // Offset to use region from + app.extent// Extent to describe region to use, starting at offset }; vk::PipelineViewportStateCreateInfo viewportSCI = { - {}, - 1, // Viewport count - &viewport, // Viewport used - 1, // Scissor count - &scissor // Scissor used + {}, + 1, // Viewport count + &viewport,// Viewport used + 1, // Scissor count + &scissor // Scissor used }; // Rasterizer vk::PipelineRasterizationStateCreateInfo rasterizationSCI = { - {}, - false, // Change if fragments beyond near/far planes are clipped (default) or clamped to plane - false, - // Whether to discard data and skip rasterizer. Never creates fragments, only suitable for pipeline without framebuffer output - polygonMode, // How to handle filling points between vertices - cullMode, // Which face of a tri to cull - vk::FrontFace::eCounterClockwise, // Winding to determine which side is front - false, // Whether to add depth bias to fragments (good for stopping "shadow acne" in shadow mapping) - 0.f, - 0.f, - 0.f, - 1.f // How thick lines should be when drawn + {}, + false,// Change if fragments beyond near/far planes are clipped (default) or clamped to plane + false, + // Whether to discard data and skip rasterizer. Never creates fragments, only suitable for pipeline without framebuffer output + polygonMode, // How to handle filling points between vertices + cullMode, // Which face of a tri to cull + vk::FrontFace::eCounterClockwise,// Winding to determine which side is front + false, // Whether to add depth bias to fragments (good for stopping "shadow acne" in shadow mapping) + 0.f, + 0.f, + 0.f, + 1.f// How thick lines should be when drawn }; vk::PipelineMultisampleStateCreateInfo multisampleSCI = { - {}, - vk::SampleCountFlagBits::e1, // Number of samples to use per fragment - false, // Enable multisample shading or not - 0.f, - nullptr, - false, - false - }; + {}, + vk::SampleCountFlagBits::e1,// Number of samples to use per fragment + false, // Enable multisample shading or not + 0.f, + nullptr, + false, + false}; // Depth stencil creation vk::PipelineDepthStencilStateCreateInfo depthStencilSCI = { - {}, true, depthWrite, vk::CompareOp::eLess, false, false, {}, {}, 0.f, 0.f - }; + {}, + true, + depthWrite, + vk::CompareOp::eLess, + false, + false, + {}, + {}, + 0.f, + 0.f}; // -- BLENDING -- // Blending decides how to blend a new colour being written to a fragment, with the old value // Blend Attachment State (how blending is handled) vk::PipelineColorBlendAttachmentState colorBlendAttachmentState = blendState; // Colours to apply blending to colorBlendAttachmentState.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | - vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA; + vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA; vk::PipelineColorBlendStateCreateInfo colorBlendSCI = { - {}, - false, //logicOpEnable - Alternative to calculations is to use logical operations - {}, - 1, - &colorBlendAttachmentState, //pAttachments - {} - }; + {}, + false,//logicOpEnable - Alternative to calculations is to use logical operations + {}, + 1, + &colorBlendAttachmentState,//pAttachments + {}}; // Graphics Pipeline Creation vk::GraphicsPipelineCreateInfo cI = { - {}, - 2, // Number of shader stages - &shaderStageCI[0], // List of shader stages - &vertexInputSCI, // All the fixed function pipeline states - &inputAssemblySCI, - nullptr, - &viewportSCI, - &rasterizationSCI, - &multisampleSCI, - &depthStencilSCI, - &colorBlendSCI, - nullptr, - data.layout, // Pipeline Layout pipeline should use - render.renderPass, // Render pass description the pipeline is compatible with - subpass, // Subpass of render pass to use with pipeline - // Pipeline Derivatives : Can create multiple pipelines that derive from one another for optimisation - {}, //basePipelineHandle - Existing pipeline to derive from... - 0 //basePipelineIndex - or index of pipeline being created to derive from (in case creating multiple at once) + {}, + 2, // Number of shader stages + &shaderStageCI[0],// List of shader stages + &vertexInputSCI, // All the fixed function pipeline states + &inputAssemblySCI, + nullptr, + &viewportSCI, + &rasterizationSCI, + &multisampleSCI, + &depthStencilSCI, + &colorBlendSCI, + nullptr, + data.layout, // Pipeline Layout pipeline should use + render.renderPass,// Render pass description the pipeline is compatible with + subpass, // Subpass of render pass to use with pipeline + // Pipeline Derivatives : Can create multiple pipelines that derive from one another for optimisation + {},//basePipelineHandle - Existing pipeline to derive from... + 0 //basePipelineIndex - or index of pipeline being created to derive from (in case creating multiple at once) }; // Create Graphics Pipeline @@ -238,7 +244,7 @@ public: app.device.destroyShaderModule(fragmentM); } - void prepare(ProjectData& data) { + void prepare(ProjectData &data) { imguiUi->initCommandBuffers(); { @@ -252,9 +258,8 @@ public: { // Transparent vk::PipelineColorBlendAttachmentState blendState = { - true, vk::BlendFactor::eOne, vk::BlendFactor::eOne, vk::BlendOp::eAdd, - vk::BlendFactor::eOne, vk::BlendFactor::eOne, vk::BlendOp::eAdd - }; + true, vk::BlendFactor::eOne, vk::BlendFactor::eOne, vk::BlendOp::eAdd, + vk::BlendFactor::eOne, vk::BlendFactor::eOne, vk::BlendOp::eAdd}; createPipeline(transparentPipeline, data, workingDir + "build/shaders/particle.vert.spv", workingDir + "build/shaders/white.frag.spv", vk::PrimitiveTopology::ePointList, @@ -263,9 +268,8 @@ public: { // Lines vk::PipelineColorBlendAttachmentState blendState = { - true, vk::BlendFactor::eOne, vk::BlendFactor::eOne, vk::BlendOp::eAdd, - vk::BlendFactor::eOne, vk::BlendFactor::eOne, vk::BlendOp::eAdd - }; + true, vk::BlendFactor::eOne, vk::BlendFactor::eOne, vk::BlendOp::eAdd, + vk::BlendFactor::eOne, vk::BlendFactor::eOne, vk::BlendOp::eAdd}; createPipeline(linesPipeline, data, workingDir + "build/shaders/lines.vert.spv", workingDir + "build/shaders/white.frag.spv", vk::PrimitiveTopology::eTriangleList, @@ -281,66 +285,62 @@ public: app.device.destroyPipeline(linesPipeline); } - void renderFrame(ProjectData& data) { + void renderFrame(ProjectData &data) { if (glfwGetKey(app.window, GLFW_KEY_F) == GLFW_PRESS) { if (!fPress) { renderForceLines = !renderForceLines; fPress = true; } - } - else if (fPress) fPress = false; + } else if (fPress) + fPress = false; render.renderFrame( - [&](vk::CommandBuffer& cb) { - cb.bindPipeline(vk::PipelineBindPoint::eGraphics, opaquePipeline); - ProjectData::PushConstant pC = { - render.camera->viewProjectionMatrix(), glm::vec4(render.camera->position, 0.f) - }; - cb.pushConstants(data.layout, vk::ShaderStageFlagBits::eAll, 0, sizeof(pC), &pC); - cb.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, data.layout, 0, 1, &data.descriptorSet, 0, - nullptr); - cb.draw(3 * data.triangleCount, 1, 0, 0); - }, - [&](vk::CommandBuffer& cb) { - { - cb.bindPipeline(vk::PipelineBindPoint::eGraphics, transparentPipeline); - ProjectData::PushConstant pC = { - render.camera->viewProjectionMatrix(), glm::vec4(render.camera->position, 0.f) - }; - cb.pushConstants(data.layout, vk::ShaderStageFlagBits::eAll, 0, sizeof(pC), &pC); - cb.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, data.layout, 0, 1, &data.descriptorSet, 0, - nullptr); - cb.draw(data.particleCount, 1, 0, 0); - } - if (renderForceLines) { - cb.bindPipeline(vk::PipelineBindPoint::eGraphics, linesPipeline); + [&](vk::CommandBuffer &cb) { + cb.bindPipeline(vk::PipelineBindPoint::eGraphics, opaquePipeline); ProjectData::PushConstant pC = { - render.camera->viewProjectionMatrix(), glm::vec4(render.camera->position, 0.f) - }; + render.camera->viewProjectionMatrix(), glm::vec4(render.camera->position, 0.f)}; cb.pushConstants(data.layout, vk::ShaderStageFlagBits::eAll, 0, sizeof(pC), &pC); cb.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, data.layout, 0, 1, &data.descriptorSet, 0, nullptr); - cb.draw(3 * 10 * 10 * 10, 1, 0, 0); - } - }, - [&](uint32_t index){ - return imguiUi->updateCommandBuffer(index, data.uiBindings); - } - ); + cb.draw(3 * data.triangleCount, 1, 0, 0); + }, + [&](vk::CommandBuffer &cb) { + { + cb.bindPipeline(vk::PipelineBindPoint::eGraphics, transparentPipeline); + ProjectData::PushConstant pC = { + render.camera->viewProjectionMatrix(), glm::vec4(render.camera->position, 0.f)}; + cb.pushConstants(data.layout, vk::ShaderStageFlagBits::eAll, 0, sizeof(pC), &pC); + cb.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, data.layout, 0, 1, &data.descriptorSet, 0, + nullptr); + cb.draw(data.particleCount, 1, 0, 0); + } + if (renderForceLines) { + cb.bindPipeline(vk::PipelineBindPoint::eGraphics, linesPipeline); + ProjectData::PushConstant pC = { + render.camera->viewProjectionMatrix(), glm::vec4(render.camera->position, 0.f)}; + cb.pushConstants(data.layout, vk::ShaderStageFlagBits::eAll, 0, sizeof(pC), &pC); + cb.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, data.layout, 0, 1, &data.descriptorSet, 0, + nullptr); + cb.draw(3 * 10 * 10 * 10, 1, 0, 0); + } + }, + [&](uint32_t index) { + return imguiUi->updateCommandBuffer(index, data.uiBindings); + }); } }; class Project { - AppResources& app; + AppResources &app; ProjectRender render; public: ProjectData data; - Project(AppResources& app, Render& render, uint32_t particleCount = 20, + Project(AppResources &app, Render &render, uint32_t particleCount = 20, std::string objName = workingDir + "Assets/cubeJump.obj"); - void loop(ProjectSolution& solution); + void loop(ProjectSolution &solution); void cleanup(); @@ -362,7 +362,7 @@ private: { // SCOPE : Read and Fill a vector - FILE* fin = fopen((workingDir + "Assets/helix_float.raw").c_str(), "rb"); + FILE *fin = fopen((workingDir + "Assets/helix_float.raw").c_str(), "rb"); if (!fin) { std::cout << "Unable to open volumetric data file." << std::endl; return; @@ -379,10 +379,10 @@ private: std::array<float, 4> pForce; fread(&pForce, sizeof(float), 3, fin); pForce[2] *= 2.f; - float scale = (1.f - (float)z / (float)data.V_RESz) * 1.f; + float scale = (1.f - (float) z / (float) data.V_RESz) * 1.f; pForce[0] *= scale; pForce[1] *= scale; - pForce[2] *= scale * (1.f - exp(-(float)z / (float)data.V_RESz * 5.f)); + pForce[2] *= scale * (1.f - exp(-(float) z / (float) data.V_RESz * 5.f)); pForce[3] = 0.f; //std::swap(pForce[1], pForce[2]); @@ -395,24 +395,24 @@ private: } fclose(fin); staging = createBuffer(app.pDevice, app.device, tex_size * sizeof(std::array<float, 4>), - vk::BufferUsageFlagBits::eTransferSrc, - vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible, - "staging_tex"); + vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible, + "staging_tex"); fillDeviceBuffer(app.device, staging.mem, pVolume); } - auto makeImage = [&](vk::Image& image, vk::ImageView& imageView, vk::DeviceMemory& img_mem) { - vk::ImageCreateInfo imgInfo(vk::ImageCreateFlags{}, vk::ImageType::e3D, // VkImageCreateFlags, VkImageType - vk::Format::eR32G32B32A32Sfloat, // VkImageFormat - vk::Extent3D(data.V_RESx, data.V_RESy, data.V_RESz), // w,h,depth - 1, 1, // mipLevels, arrayLayers, + auto makeImage = [&](vk::Image &image, vk::ImageView &imageView, vk::DeviceMemory &img_mem) { + vk::ImageCreateInfo imgInfo(vk::ImageCreateFlags {}, vk::ImageType::e3D, // VkImageCreateFlags, VkImageType + vk::Format::eR32G32B32A32Sfloat, // VkImageFormat + vk::Extent3D(data.V_RESx, data.V_RESy, data.V_RESz),// w,h,depth + 1, 1, // mipLevels, arrayLayers, vk::SampleCountFlagBits::e1, vk::ImageTiling::eOptimal, // VkSampleCountFlagBits, VkImageTiling - vk::ImageUsageFlagBits::eSampled | // VkImageUsageFlags - vk::ImageUsageFlagBits::eTransferDst, - vk::SharingMode::eExclusive, // VkSharingMode - 0, nullptr, // queueFamilyIndexCount, *pQueueFamilyIndices + vk::ImageUsageFlagBits::eSampled |// VkImageUsageFlags + vk::ImageUsageFlagBits::eTransferDst, + vk::SharingMode::eExclusive,// VkSharingMode + 0, nullptr, // queueFamilyIndexCount, *pQueueFamilyIndices vk::ImageLayout::eUndefined // VkImageLayout ); @@ -431,8 +431,8 @@ private: app.device.bindImageMemory(image, img_mem, 0); vk::ImageViewCreateInfo viewInfo( - {}, image, vk::ImageViewType::e3D, vk::Format::eR32G32B32A32Sfloat, - {{}, {}, {}, {}}, {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}); + {}, image, vk::ImageViewType::e3D, vk::Format::eR32G32B32A32Sfloat, + {{}, {}, {}, {}}, {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}); imageView = app.device.createImageView(viewInfo); }; @@ -443,30 +443,29 @@ private: setObjectName(app.device, data.textureImageMemory, "3DTexImageMemory"); transitionImageLayout( - app.device, app.transferCommandPool, app.transferQueue, - data.textureImage, vk::Format::eR32G32B32A32Sfloat, vk::ImageLayout::eUndefined, - vk::ImageLayout::eTransferDstOptimal); + app.device, app.transferCommandPool, app.transferQueue, + data.textureImage, vk::Format::eR32G32B32A32Sfloat, vk::ImageLayout::eUndefined, + vk::ImageLayout::eTransferDstOptimal); copyBufferToImage(app.device, app.transferCommandPool, app.transferQueue, staging.buf, data.textureImage, data.V_RESx, data.V_RESy, data.V_RESz); transitionImageLayout( - app.device, app.computeCommandPool, app.computeQueue, - data.textureImage, vk::Format::eR32G32B32A32Sfloat, vk::ImageLayout::eTransferDstOptimal, - vk::ImageLayout::eShaderReadOnlyOptimal); + app.device, app.computeCommandPool, app.computeQueue, + data.textureImage, vk::Format::eR32G32B32A32Sfloat, vk::ImageLayout::eTransferDstOptimal, + vk::ImageLayout::eShaderReadOnlyOptimal); app.device.destroyBuffer(staging.buf); app.device.freeMemory(staging.mem); } - void makeForceLines(std::vector<std::array<float, 4>>& pForce, uint32_t NUM_FORCE_LINES = 50) { + void makeForceLines(std::vector<std::array<float, 4>> &pForce, uint32_t NUM_FORCE_LINES = 50) { //scatter force field sampling points pForce.resize(NUM_FORCE_LINES * 2); for (int i = 0; i < NUM_FORCE_LINES; i++) { pForce[2 * i] = { - float(rand()) / float(RAND_MAX), - float(rand()) / float(RAND_MAX), - float(rand()) / float(RAND_MAX), - 0.0f - }; + float(rand()) / float(RAND_MAX), + float(rand()) / float(RAND_MAX), + float(rand()) / float(RAND_MAX), + 0.0f}; pForce[2 * i + 1] = pForce[2 * i]; pForce[2 * i + 1][3] = 1.f; @@ -476,20 +475,19 @@ private: void makeSampler() { vk::PhysicalDeviceProperties properties = app.pDevice.getProperties(); vk::SamplerCreateInfo samplerInfo( - vk::SamplerCreateFlags{}, - vk::Filter::eLinear, vk::Filter::eLinear, - vk::SamplerMipmapMode::eLinear, - vk::SamplerAddressMode::eRepeat, - vk::SamplerAddressMode::eRepeat, - vk::SamplerAddressMode::eRepeat, - 0.f, - vk::Bool32(false), - properties.limits.maxSamplerAnisotropy, - vk::Bool32(false), - vk::CompareOp::eAlways, 0.f, 0.f, - vk::BorderColor::eIntOpaqueBlack, - vk::Bool32(false) - ); + vk::SamplerCreateFlags {}, + vk::Filter::eLinear, vk::Filter::eLinear, + vk::SamplerMipmapMode::eLinear, + vk::SamplerAddressMode::eRepeat, + vk::SamplerAddressMode::eRepeat, + vk::SamplerAddressMode::eRepeat, + 0.f, + vk::Bool32(false), + properties.limits.maxSamplerAnisotropy, + vk::Bool32(false), + vk::CompareOp::eAlways, 0.f, 0.f, + vk::BorderColor::eIntOpaqueBlack, + vk::Bool32(false)); data.textureSampler = app.device.createSampler(samplerInfo); setObjectName(app.device, data.textureSampler, "3DTexSampler"); } @@ -517,8 +515,8 @@ private: pVelMass[i][2] = 0.f; pVelMass[i][3] = (1.f + float(rand()) / float(RAND_MAX)) * 1.5f; } - std::vector<uint32_t> pAlive(data.particleCount, 1); // init with 1 - pAlive.resize(2 * data.particleCount, 0); // fill rest with 0 + std::vector<uint32_t> pAlive(data.particleCount, 1);// init with 1 + pAlive.resize(2 * data.particleCount, 0); // fill rest with 0 fillDeviceWithStagingBuffer(app.pDevice, app.device, app.transferCommandPool, app.transferQueue, data.gVelMass, pVelMass); @@ -528,7 +526,7 @@ private: pAlive); } - std::vector<std::array<float, 4>> getTriangles(std::string dataFile, std::vector<std::array<float, 4>>& normals) { + std::vector<std::array<float, 4>> getTriangles(std::string dataFile, std::vector<std::array<float, 4>> &normals) { std::vector<std::array<float, 4>> triangleSoup; tinyobj::ObjReaderConfig reader_config; // reader_config.mtl_search_path = "./"; // Path to material files @@ -546,9 +544,9 @@ private: std::cout << "TinyObjReader: " << reader.Warning(); } - auto& attrib = reader.GetAttrib(); - auto& shapes = reader.GetShapes(); - auto& materials = reader.GetMaterials(); + auto &attrib = reader.GetAttrib(); + auto &shapes = reader.GetShapes(); + auto &materials = reader.GetMaterials(); triangleSoup.reserve(attrib.GetVertices().size()); normals.reserve(attrib.GetVertices().size()); // Loop over shapes diff --git a/include/render.h b/include/render.h index 1298b3ab884ff5d56f2dcde87135e0a788b65ae6..4fa96537ad6c5d98d5ddd35205d016f7fc802b25 100644 --- a/include/render.h +++ b/include/render.h @@ -2,9 +2,9 @@ #include <cmath> -#include "task_common.h" +#include "camera.h" #include "imgui_ui.h" -#include "Camera.h" +#include "task_common.h" class Simulation; @@ -91,7 +91,5 @@ void Render::renderFrame(O opaque, T transparent, U ui) { }; app.graphicsQueue.submit(submitInfos, fences[idx]); - vk::Result vr = app.graphicsQueue.presentKHR({ - 1, &completionSemaphores[idx], 1, &app.swapchain, &swapchainIndex - }); + vk::Result vr = app.graphicsQueue.presentKHR({1, &completionSemaphores[idx], 1, &app.swapchain, &swapchainIndex}); } diff --git a/include/renderdoc.h b/include/renderdoc.h index 91028f0eb2e3b83c673215951da16fc488bc57eb..c228ac79246dffd3f351daeb5fa7ff866ce0b5c8 100644 --- a/include/renderdoc.h +++ b/include/renderdoc.h @@ -1,7 +1,7 @@ #pragma once namespace renderdoc { - void initialize(); - void startCapture(); - void endCapture(); -} +void initialize(); +void startCapture(); +void endCapture(); +}// namespace renderdoc diff --git a/include/simulation.h b/include/simulation.h index 7713b6081fc9d445c3f8301322d95477853f3228..4d01e006560b9dc90a517306ad0a56ad3c8fed81 100644 --- a/include/simulation.h +++ b/include/simulation.h @@ -1,16 +1,16 @@ #pragma once -#include <vulkan/vulkan.hpp> #include <memory> +#include <vulkan/vulkan.hpp> -#include "simulation_state.h" #include "initialization.h" +#include "simulation_state.h" -#include "imgui_ui.h" #include "debug_image.h" +#include "imgui_ui.h" #include "particle_physics.h" -#include "spatial_lookup.h" #include "particle_renderer.h" +#include "spatial_lookup.h" // handles interop of the 3 parts, also copies rendered image to swapchain image class Simulation { @@ -53,7 +53,7 @@ private: UiBindings::UpdateFlags lastUpdate; - friend void Render::renderSimulationFrame(Simulation &simulation); // access stuff, kind of ugly to do it this way + friend void Render::renderSimulationFrame(Simulation &simulation);// access stuff, kind of ugly to do it this way public: std::unique_ptr<ParticleSimulation> particleSimulation; }; diff --git a/include/simulation_parameters.h b/include/simulation_parameters.h index de39ea8c664a27425359e0db442f7e5a45ebc398..8c3c5bdce9f6e151176390c42e9b72944b22b188 100644 --- a/include/simulation_parameters.h +++ b/include/simulation_parameters.h @@ -3,13 +3,13 @@ #include "utils.h" #include <string> -template <typename T> +template<typename T> using Mappings = std::initializer_list<std::pair<std::string, T>>; -template <typename T> -std::vector<const char*> imguiComboArray(const Mappings<T> mappings) { - std::vector<const char*> result { mappings.size() }; - for (const auto &[label, v] : mappings) { +template<typename T> +std::vector<const char *> imguiComboArray(const Mappings<T> mappings) { + std::vector<const char *> result {mappings.size()}; + for (const auto &[label, v]: mappings) { result[static_cast<size_t>(v)] = label.c_str(); } @@ -37,7 +37,10 @@ public: SceneType type = SceneType::SPH_BOX_2D; InitializationFunction initializationFunction = InitializationFunction::UNIFORM; uint32_t numParticles = 128; - uint32_t randomSeed = 0; // initialized with TRNG if omitted + uint32_t randomSeed = 0; // initialized with TRNG if omitted + float gravity = 9.81f; // Default Earth gravity + float deltaTime = 1.0f / 60.0f; // Default 60 FPS + float collisionDampingFactor = 0.8f;// Default 20% energy loss public: SimulationParameters() = default; diff --git a/include/simulation_state.h b/include/simulation_state.h index b023e0d08d061d036e417a655ee86a44f1acc2a9..742a39badb2385d178b958198ebd7935dd52f992 100644 --- a/include/simulation_state.h +++ b/include/simulation_state.h @@ -1,13 +1,14 @@ #pragma once -#include "simulation_parameters.h" #include "debug_image.h" #include "render.h" +#include "simulation_parameters.h" #include <random> struct Particle { glm::vec2 position; + glm::vec2 velocity; }; struct SpatialLookupEntry { @@ -29,12 +30,13 @@ struct SimulationTime { struct SimulationState { public: SimulationState() = delete; - SimulationState(const SimulationState &other) = delete; // don't accidentally copy + SimulationState(const SimulationState &other) = delete;// don't accidentally copy explicit SimulationState(const SimulationParameters ¶meters, std::shared_ptr<Camera> camera); ~SimulationState(); SimulationTime time; Buffer particleCoordinateBuffer; + Buffer particleVelocityBuffer; const SimulationParameters parameters; std::shared_ptr<Camera> camera; diff --git a/include/spatial_lookup.h b/include/spatial_lookup.h index 886954cdd96c52c37fdf878bad82baef39fb8a8c..dcbcf137e63d454badabf224328abeec0c540c24 100644 --- a/include/spatial_lookup.h +++ b/include/spatial_lookup.h @@ -23,6 +23,7 @@ class SpatialLookup { vk::Pipeline indexPipeline; vk::CommandBuffer cmd; + public: explicit SpatialLookup(const SimulationParameters ¶meters); ~SpatialLookup(); diff --git a/include/task_common.h b/include/task_common.h index 0d8809f58e45b3050e63560c212f6e966047bb47..5b04412e6636b2052b2c3dc39f9d4ccd36a04f1e 100644 --- a/include/task_common.h +++ b/include/task_common.h @@ -1,35 +1,34 @@ #pragma once -#include <iostream> #include <cstdlib> +#include <iostream> -#include <vulkan/vulkan.hpp> -#include <fstream> -#include <vector> #include "initialization.h" #include "utils.h" +#include <fstream> +#include <vector> +#include <vulkan/vulkan.hpp> namespace Cmn { void createDescriptorSetLayout(vk::Device &device, - std::vector<vk::DescriptorSetLayoutBinding> &bindings, vk::DescriptorSetLayout &descLayout); + std::vector<vk::DescriptorSetLayoutBinding> &bindings, vk::DescriptorSetLayout &descLayout); void addStorage(std::vector<vk::DescriptorSetLayoutBinding> &bindings, uint32_t binding); void addCombinedImageSampler(std::vector<vk::DescriptorSetLayoutBinding> &bindings, uint32_t binding); void allocateDescriptorSet(vk::Device &device, vk::DescriptorSet &descSet, vk::DescriptorPool &descPool, - vk::DescriptorSetLayout &descLayout); + vk::DescriptorSetLayout &descLayout); void bindCombinedImageSampler(vk::Device &device, vk::ImageView &view, vk::Sampler &sampler, vk::DescriptorSet &set, uint32_t binding); void bindBuffers(vk::Device &device, const vk::Buffer &b, vk::DescriptorSet &set, uint32_t binding, vk::DescriptorType type = vk::DescriptorType::eStorageBuffer); void createDescriptorPool(vk::Device &device, std::vector<vk::DescriptorSetLayoutBinding> &bindings, vk::DescriptorPool &descPool, uint32_t numDescriptorSets = 1); void createPipeline(vk::Device &device, vk::Pipeline &pipeline, - vk::PipelineLayout &pipLayout, vk::SpecializationInfo &specInfo, vk::ShaderModule &sModule); + vk::PipelineLayout &pipLayout, vk::SpecializationInfo &specInfo, vk::ShaderModule &sModule); void createShader(vk::Device &device, vk::ShaderModule &shaderModule, const std::string &filename); -} +}// namespace Cmn -struct TaskResources -{ +struct TaskResources { //std::vector<Buffer> buffers; move this to user code vk::ShaderModule cShader; @@ -42,5 +41,4 @@ struct TaskResources vk::PipelineLayout pipelineLayout; void destroy(vk::Device &device); - }; diff --git a/include/utils.h b/include/utils.h index f107cc88596e19f5a2c4b35e659d3ca23efff8d8..55d8c833896bfe247f50cae44ea4c80132f084ca 100644 --- a/include/utils.h +++ b/include/utils.h @@ -1,20 +1,19 @@ #pragma once -#include <vector> -#include <cstring> #include <cmath> +#include <cstring> #include <glm/glm.hpp> -#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/constants.hpp> +#include <glm/gtc/matrix_transform.hpp> #include <vulkan/vulkan.hpp> #include "GLFW/glfw3.h" #include "helper.h" +#include <vulkan/vulkan.hpp> -struct AppResources -{ +struct AppResources { vk::Instance instance; vk::DebugUtilsMessengerEXT dbgUtilsMgr; vk::PhysicalDevice pDevice; @@ -25,7 +24,7 @@ struct AppResources vk::CommandPool graphicsCommandPool, computeCommandPool, transferCommandPool; vk::QueryPool queryPool; - GLFWwindow* window; + GLFWwindow *window; vk::Extent2D extent; vk::SurfaceKHR surface; vk::SurfaceFormatKHR surfaceFormat; @@ -42,29 +41,26 @@ extern AppResources &resources; #define CAST(a) static_cast<uint32_t>(a.size()) -struct Buffer -{ - Buffer(Buffer &other) = delete; // copy disabled - Buffer& operator=(const Buffer&) = delete; // Copy assignment disabled +struct Buffer { + Buffer(Buffer &other) = delete; // copy disabled + Buffer &operator=(const Buffer &) = delete;// Copy assignment disabled Buffer() : buf(nullptr), mem(nullptr) {} Buffer(vk::Buffer buf, vk::DeviceMemory mem) : buf(buf), mem(mem) {} - Buffer(Buffer&& other) noexcept : buf(other.buf), mem(other.mem) - { + Buffer(Buffer &&other) noexcept : buf(other.buf), mem(other.mem) { other.buf = nullptr; other.mem = nullptr; } - Buffer& operator=(Buffer&& other) noexcept // move is allowed + Buffer &operator=(Buffer &&other) noexcept// move is allowed { - if (this != &other) - { + if (this != &other) { // Clean up existing resources - if (buf != nullptr){ + if (buf != nullptr) { resources.device.destroyBuffer(buf); } - if (mem != nullptr){ + if (mem != nullptr) { resources.device.freeMemory(mem); } buf = other.buf; @@ -78,11 +74,11 @@ struct Buffer vk::Buffer buf; vk::DeviceMemory mem; - ~Buffer(){ - if (nullptr != buf){ + ~Buffer() { + if (nullptr != buf) { resources.device.destroyBuffer(buf); } - if (nullptr != mem){ + if (nullptr != mem) { resources.device.freeMemory(mem); } } @@ -98,11 +94,11 @@ void copyBufferToImage(vk::Device &device, vk::CommandPool &pool, vk::Queue &que Buffer createDeviceLocalBuffer(const std::string &name, vk::DeviceSize size, vk::BufferUsageFlags additionalUsageBits = {}); Buffer createBuffer(vk::PhysicalDevice &pDevice, vk::Device &device, - const vk::DeviceSize &size, vk::BufferUsageFlags usage, - vk::MemoryPropertyFlags properties, std::string name); + const vk::DeviceSize &size, vk::BufferUsageFlags usage, + vk::MemoryPropertyFlags properties, std::string name); -void createImage(vk::PhysicalDevice &pDevice, vk::Device &device, vk::ImageCreateInfo createInfo,vk::MemoryPropertyFlags properties, - std::string name, vk::Image &image, vk::DeviceMemory &imageMemory); +void createImage(vk::PhysicalDevice &pDevice, vk::Device &device, vk::ImageCreateInfo createInfo, vk::MemoryPropertyFlags properties, + std::string name, vk::Image &image, vk::DeviceMemory &imageMemory); void copyBuffer(vk::Device &device, vk::Queue &q, vk::CommandPool &commandPool, const vk::Buffer &srcBuffer, const vk::Buffer &dstBuffer, vk::DeviceSize byteSize); @@ -115,65 +111,73 @@ Buffer addDeviceOnlyBuffer(vk::PhysicalDevice &pDevice, vk::Device &device, vk:: void writeFloatJpg(const std::string name, const std::vector<float> &inData, const int w, const int h); -template <typename T> -void fillDeviceBuffer(vk::Device &device, vk::DeviceMemory &mem, const std::vector<T> &input) -{ +template<typename T> +void fillDeviceBuffer(vk::Device &device, vk::DeviceMemory &mem, const std::vector<T> &input) { void *data = device.mapMemory(mem, 0, input.size() * sizeof(T), vk::MemoryMapFlags()); memcpy(data, input.data(), static_cast<size_t>(input.size() * sizeof(T))); device.unmapMemory(mem); } -template <typename T> -void fillHostBuffer(vk::Device &device, vk::DeviceMemory &mem, std::vector<T> &output) -{ +template<typename T> +void fillHostBuffer(vk::Device &device, vk::DeviceMemory &mem, std::vector<T> &output) { // copy memory from mem to output void *data = device.mapMemory(mem, 0, output.size() * sizeof(T), vk::MemoryMapFlags()); memcpy(output.data(), data, static_cast<size_t>(output.size() * sizeof(T))); device.unmapMemory(mem); } -template <typename T> +template<typename T> void fillImageWithStagingBuffer(vk::PhysicalDevice &pDevice, vk::Device &device, vk::CommandPool &commandPool, vk::Queue &q, vk::Image &image, vk::ImageLayout targetLayout, const vk::Extent3D &extent, const std::vector<T> &data) { vk::DeviceSize byteSize = data.size() * sizeof(T); - vk::ImageSubresourceRange subresourceRange {{ vk::ImageAspectFlagBits::eColor }, 0, 1, 0, 1}; + vk::ImageSubresourceRange subresourceRange {{vk::ImageAspectFlagBits::eColor}, 0, 1, 0, 1}; auto staging = createBuffer(pDevice, device, byteSize, vk::BufferUsageFlagBits::eTransferSrc, - vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible, "staging" - ); + vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible, "staging"); // V host -> staging V fillDeviceBuffer<T>(device, staging.mem, data); auto cb = beginSingleTimeCommands(device, commandPool); vk::ImageMemoryBarrier toTransferLayout { - {}, {}, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, {}, {}, image, subresourceRange - }; + {}, + {}, + vk::ImageLayout::eUndefined, + vk::ImageLayout::eTransferDstOptimal, + {}, + {}, + image, + subresourceRange}; cb.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, 0, nullptr, 0, nullptr, 1, &toTransferLayout); vk::BufferImageCopy bufferImageCopy { - 0, - 0, - 0, - {{ vk::ImageAspectFlagBits::eColor }, 0, 0, 1}, - { 0, 0, 0 }, - extent - }; + 0, + 0, + 0, + {{vk::ImageAspectFlagBits::eColor}, 0, 0, 1}, + {0, 0, 0}, + extent}; cb.copyBufferToImage(staging.buf, image, vk::ImageLayout::eTransferDstOptimal, 1, &bufferImageCopy); vk::ImageMemoryBarrier toTargetLayout { - {}, {}, vk::ImageLayout::eTransferDstOptimal, targetLayout, {}, {}, image, subresourceRange - }; + {}, + {}, + vk::ImageLayout::eTransferDstOptimal, + targetLayout, + {}, + {}, + image, + subresourceRange}; cb.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, 0, nullptr, 0, nullptr, 1, &toTargetLayout); endSingleTimeCommands(device, q, commandPool, cb); } -template <typename T> +template<typename T> void fillImageWithStagingBuffer(vk::Image &image, vk::ImageLayout targetLayout, const vk::Extent3D &extent, const std::vector<T> &data) { fillImageWithStagingBuffer(resources.pDevice, resources.device, resources.transferCommandPool, @@ -182,57 +186,52 @@ void fillImageWithStagingBuffer(vk::Image &image, vk::ImageLayout targetLayout, // C++ 17 allows using it like this: // fillDeviceWithStagingBuffer(arguments) -// instead of +// instead of // fillDeviceWithStagingBuffer<vectorType>(arguments) -template <typename T> +template<typename T> void fillDeviceWithStagingBuffer(vk::PhysicalDevice &pDevice, vk::Device &device, - vk::CommandPool &commandPool, vk::Queue &q, - Buffer &b, const std::vector<T> &data) -{ + vk::CommandPool &commandPool, vk::Queue &q, + Buffer &b, const std::vector<T> &data) { // Buffer b requires the eTransferSrc bit // data (host) -> staging (device) -> Buffer b (device) vk::DeviceSize byteSize = data.size() * sizeof(T); auto staging = createBuffer(pDevice, device, byteSize, vk::BufferUsageFlagBits::eTransferSrc, - vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible, "staging" - ); + vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible, "staging"); // V host -> staging V fillDeviceBuffer<T>(device, staging.mem, data); // V staging -> buffer V copyBuffer(device, q, commandPool, staging.buf, b.buf, byteSize); } -template <typename T> +template<typename T> void fillDeviceWithStagingBuffer(Buffer &b, const std::vector<T> &data) { fillDeviceWithStagingBuffer(resources.pDevice, resources.device, resources.transferCommandPool, resources.transferQueue, b, data); } -template <typename T> +template<typename T> void fillHostWithStagingBuffer(vk::PhysicalDevice &pDevice, vk::Device &device, - vk::CommandPool &commandPool, vk::Queue &q, - const Buffer &b, std::vector<T> &data) -{ + vk::CommandPool &commandPool, vk::Queue &q, + const Buffer &b, std::vector<T> &data) { // Buffer b requires the eTransferDst bit // Buffer b (device) -> staging (device) -> data (host) vk::DeviceSize byteSize = data.size() * sizeof(T); auto staging = createBuffer(pDevice, device, byteSize, vk::BufferUsageFlagBits::eTransferDst, - vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible, "staging" - ); + vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible, "staging"); // V buffer -> staging V copyBuffer(device, q, commandPool, b.buf, staging.buf, byteSize); // V staging -> host V fillHostBuffer<T>(device, staging.mem, data); } -template <typename T> +template<typename T> void fillHostWithStagingBuffer(Buffer &b, std::vector<T> &data) { fillHostWithStagingBuffer<T>(resources.pDevice, resources.device, resources.transferCommandPool, resources.transferQueue, b, data); } -template <typename T> -void setObjectName(vk::Device &device, T handle, std::string name) -{ +template<typename T> +void setObjectName(vk::Device &device, T handle, std::string name) { #ifndef NDEBUG vk::DebugUtilsObjectNameInfoEXT infoEXT(handle.objectType, uint64_t(static_cast<typename T::CType>(handle)), name.c_str()); device.setDebugUtilsObjectNameEXT(infoEXT); @@ -240,4 +239,3 @@ void setObjectName(vk::Device &device, T handle, std::string name) } void computeBarrier(vk::CommandBuffer &cmd); - diff --git a/scenes/default.yaml b/scenes/default.yaml index 2e89ea61c43eedfbb4b771a44dc5a5d95a5ed7c8..ba0751c7cd4cc86109eda708e1b613d3e8b602be 100644 --- a/scenes/default.yaml +++ b/scenes/default.yaml @@ -1,3 +1,6 @@ type: sph_box_2d initialization_function: uniform num_particles: 1024 +gravity: 9.81 +deltaTime: 0.016 +collisionDampingFactor: 0.8 diff --git a/shaders/particle_simulation.comp b/shaders/particle_simulation.comp new file mode 100644 index 0000000000000000000000000000000000000000..88bd5efb5a11783f2d9c2cb5377aabf7f6b3ae24 --- /dev/null +++ b/shaders/particle_simulation.comp @@ -0,0 +1,52 @@ +#version 450 + +layout(local_size_x_id = 0, local_size_y = 1, local_size_z = 1) in; + +layout(binding = 0) buffer positionBuffer { float positions[]; }; +layout(binding = 1) buffer velocityBuffer { float velocities[]; }; + +layout(push_constant) uniform PushStruct { + float gravity; + float deltaTime; + uint numParticles; + float collisionDampingFactor; +} +constants; + +void main() { + uint index = gl_GlobalInvocationID.x; + if (index >= constants.numParticles) return; + + vec2 position = vec2(positions[2 * index], positions[2 * index + 1]); + vec2 velocity = vec2(velocities[2 * index], velocities[2 * index + 1]); + + // Update velocity + velocity += vec2(0.0, constants.gravity) * constants.deltaTime; + // Update position + position += velocity * constants.deltaTime; + + + // Resolve collisions + if (position.x < 0.0) { + position.x = 0.0; + velocity *= -constants.collisionDampingFactor; + } else if (position.x > 1.0) { + position.x = 1.0; + velocity *= -constants.collisionDampingFactor; + } + if (position.y < 0.0) { + position.y = 0.0; + velocity *= -constants.collisionDampingFactor; + } else if (position.y > 1.0) { + position.y = 1.0; + velocity *= -constants.collisionDampingFactor; + } + + + //barrier(); + // Write back results + positions[2 * index] = position.x; + positions[2 * index + 1] = position.y; + velocities[2 * index] = velocity.x; + velocities[2 * index + 1] = velocity.y; +} \ No newline at end of file diff --git a/src/camera.cpp b/src/camera.cpp index a17c44dffb7c770483e2cc4c304164ce8f57fc18..936b5e4970a6ffabf31359bd0e32046cfe65c8c2 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -5,23 +5,21 @@ void Camera::reset() { position = glm::vec3(0.5, 2, 0.9); phi = glm::pi<float>(); theta = 0.4 * glm::pi<float>(); - aspect = (float)resources.extent.width/(float)resources.extent.height; + aspect = (float) resources.extent.width / (float) resources.extent.height; } glm::vec3 Camera::forwardDir() const { return { std::sin(phi) * std::sin(theta), std::cos(phi) * std::sin(theta), - -std::cos(theta) - }; + -std::cos(theta)}; } glm::vec3 Camera::tangentDir() const { return { std::cos(phi), -std::sin(phi), - 0.f - }; + 0.f}; } void Camera::rotateTheta(float radians) { @@ -57,4 +55,3 @@ glm::mat4 Camera::projectionMatrix() const { glm::mat4 Camera::viewProjectionMatrix() const { return projectionMatrix() * viewMatrix(); } - diff --git a/src/colormaps.cpp b/src/colormaps.cpp index 65535fd2640b525dd0198ad9b289f8ba2e9a4b1a..243a0fdf552fd9a16100459a9c0d0b0d9f4ef401 100644 --- a/src/colormaps.cpp +++ b/src/colormaps.cpp @@ -4,92 +4,261 @@ namespace colormaps { // copied from matplotlib.colormaps['viridis'].colors std::vector<RGB_F32> viridis { - { 0.267004, 0.004874, 0.329415 }, { 0.26851, 0.009605, 0.335427 }, { 0.269944, 0.014625, 0.341379 }, - { 0.271305, 0.019942, 0.347269 }, { 0.272594, 0.025563, 0.353093 }, { 0.273809, 0.031497, 0.358853 }, - { 0.274952, 0.037752, 0.364543 }, { 0.276022, 0.044167, 0.370164 }, { 0.277018, 0.050344, 0.375715 }, - { 0.277941, 0.056324, 0.381191 }, { 0.278791, 0.062145, 0.386592 }, { 0.279566, 0.067836, 0.391917 }, - { 0.280267, 0.073417, 0.397163 }, { 0.280894, 0.078907, 0.402329 }, { 0.281446, 0.08432, 0.407414 }, - { 0.281924, 0.089666, 0.412415 }, { 0.282327, 0.094955, 0.417331 }, { 0.282656, 0.100196, 0.42216 }, - { 0.28291, 0.105393, 0.426902 }, { 0.283091, 0.110553, 0.431554 }, { 0.283197, 0.11568, 0.436115 }, - { 0.283229, 0.120777, 0.440584 }, { 0.283187, 0.125848, 0.44496 }, { 0.283072, 0.130895, 0.449241 }, - { 0.282884, 0.13592, 0.453427 }, { 0.282623, 0.140926, 0.457517 }, { 0.28229, 0.145912, 0.46151 }, - { 0.281887, 0.150881, 0.465405 }, { 0.281412, 0.155834, 0.469201 }, { 0.280868, 0.160771, 0.472899 }, - { 0.280255, 0.165693, 0.476498 }, { 0.279574, 0.170599, 0.479997 }, { 0.278826, 0.17549, 0.483397 }, - { 0.278012, 0.180367, 0.486697 }, { 0.277134, 0.185228, 0.489898 }, { 0.276194, 0.190074, 0.493001 }, - { 0.275191, 0.194905, 0.496005 }, { 0.274128, 0.199721, 0.498911 }, { 0.273006, 0.20452, 0.501721 }, - { 0.271828, 0.209303, 0.504434 }, { 0.270595, 0.214069, 0.507052 }, { 0.269308, 0.218818, 0.509577 }, - { 0.267968, 0.223549, 0.512008 }, { 0.26658, 0.228262, 0.514349 }, { 0.265145, 0.232956, 0.516599 }, - { 0.263663, 0.237631, 0.518762 }, { 0.262138, 0.242286, 0.520837 }, { 0.260571, 0.246922, 0.522828 }, - { 0.258965, 0.251537, 0.524736 }, { 0.257322, 0.25613, 0.526563 }, { 0.255645, 0.260703, 0.528312 }, - { 0.253935, 0.265254, 0.529983 }, { 0.252194, 0.269783, 0.531579 }, { 0.250425, 0.27429, 0.533103 }, - { 0.248629, 0.278775, 0.534556 }, { 0.246811, 0.283237, 0.535941 }, { 0.244972, 0.287675, 0.53726 }, - { 0.243113, 0.292092, 0.538516 }, { 0.241237, 0.296485, 0.539709 }, { 0.239346, 0.300855, 0.540844 }, - { 0.237441, 0.305202, 0.541921 }, { 0.235526, 0.309527, 0.542944 }, { 0.233603, 0.313828, 0.543914 }, - { 0.231674, 0.318106, 0.544834 }, { 0.229739, 0.322361, 0.545706 }, { 0.227802, 0.326594, 0.546532 }, - { 0.225863, 0.330805, 0.547314 }, { 0.223925, 0.334994, 0.548053 }, { 0.221989, 0.339161, 0.548752 }, - { 0.220057, 0.343307, 0.549413 }, { 0.21813, 0.347432, 0.550038 }, { 0.21621, 0.351535, 0.550627 }, - { 0.214298, 0.355619, 0.551184 }, { 0.212395, 0.359683, 0.55171 }, { 0.210503, 0.363727, 0.552206 }, - { 0.208623, 0.367752, 0.552675 }, { 0.206756, 0.371758, 0.553117 }, { 0.204903, 0.375746, 0.553533 }, - { 0.203063, 0.379716, 0.553925 }, { 0.201239, 0.38367, 0.554294 }, { 0.19943, 0.387607, 0.554642 }, - { 0.197636, 0.391528, 0.554969 }, { 0.19586, 0.395433, 0.555276 }, { 0.1941, 0.399323, 0.555565 }, - { 0.192357, 0.403199, 0.555836 }, { 0.190631, 0.407061, 0.556089 }, { 0.188923, 0.41091, 0.556326 }, - { 0.187231, 0.414746, 0.556547 }, { 0.185556, 0.41857, 0.556753 }, { 0.183898, 0.422383, 0.556944 }, - { 0.182256, 0.426184, 0.55712 }, { 0.180629, 0.429975, 0.557282 }, { 0.179019, 0.433756, 0.55743 }, - { 0.177423, 0.437527, 0.557565 }, { 0.175841, 0.44129, 0.557685 }, { 0.174274, 0.445044, 0.557792 }, - { 0.172719, 0.448791, 0.557885 }, { 0.171176, 0.45253, 0.557965 }, { 0.169646, 0.456262, 0.55803 }, - { 0.168126, 0.459988, 0.558082 }, { 0.166617, 0.463708, 0.558119 }, { 0.165117, 0.467423, 0.558141 }, - { 0.163625, 0.471133, 0.558148 }, { 0.162142, 0.474838, 0.55814 }, { 0.160665, 0.47854, 0.558115 }, - { 0.159194, 0.482237, 0.558073 }, { 0.157729, 0.485932, 0.558013 }, { 0.15627, 0.489624, 0.557936 }, - { 0.154815, 0.493313, 0.55784 }, { 0.153364, 0.497, 0.557724 }, { 0.151918, 0.500685, 0.557587 }, - { 0.150476, 0.504369, 0.55743 }, { 0.149039, 0.508051, 0.55725 }, { 0.147607, 0.511733, 0.557049 }, - { 0.14618, 0.515413, 0.556823 }, { 0.144759, 0.519093, 0.556572 }, { 0.143343, 0.522773, 0.556295 }, - { 0.141935, 0.526453, 0.555991 }, { 0.140536, 0.530132, 0.555659 }, { 0.139147, 0.533812, 0.555298 }, - { 0.13777, 0.537492, 0.554906 }, { 0.136408, 0.541173, 0.554483 }, { 0.135066, 0.544853, 0.554029 }, - { 0.133743, 0.548535, 0.553541 }, { 0.132444, 0.552216, 0.553018 }, { 0.131172, 0.555899, 0.552459 }, - { 0.129933, 0.559582, 0.551864 }, { 0.128729, 0.563265, 0.551229 }, { 0.127568, 0.566949, 0.550556 }, - { 0.126453, 0.570633, 0.549841 }, { 0.125394, 0.574318, 0.549086 }, { 0.124395, 0.578002, 0.548287 }, - { 0.123463, 0.581687, 0.547445 }, { 0.122606, 0.585371, 0.546557 }, { 0.121831, 0.589055, 0.545623 }, - { 0.121148, 0.592739, 0.544641 }, { 0.120565, 0.596422, 0.543611 }, { 0.120092, 0.600104, 0.54253 }, - { 0.119738, 0.603785, 0.5414 }, { 0.119512, 0.607464, 0.540218 }, { 0.119423, 0.611141, 0.538982 }, - { 0.119483, 0.614817, 0.537692 }, { 0.119699, 0.61849, 0.536347 }, { 0.120081, 0.622161, 0.534946 }, - { 0.120638, 0.625828, 0.533488 }, { 0.12138, 0.629492, 0.531973 }, { 0.122312, 0.633153, 0.530398 }, - { 0.123444, 0.636809, 0.528763 }, { 0.12478, 0.640461, 0.527068 }, { 0.126326, 0.644107, 0.525311 }, - { 0.128087, 0.647749, 0.523491 }, { 0.130067, 0.651384, 0.521608 }, { 0.132268, 0.655014, 0.519661 }, - { 0.134692, 0.658636, 0.517649 }, { 0.137339, 0.662252, 0.515571 }, { 0.14021, 0.665859, 0.513427 }, - { 0.143303, 0.669459, 0.511215 }, { 0.146616, 0.67305, 0.508936 }, { 0.150148, 0.676631, 0.506589 }, - { 0.153894, 0.680203, 0.504172 }, { 0.157851, 0.683765, 0.501686 }, { 0.162016, 0.687316, 0.499129 }, - { 0.166383, 0.690856, 0.496502 }, { 0.170948, 0.694384, 0.493803 }, { 0.175707, 0.6979, 0.491033 }, - { 0.180653, 0.701402, 0.488189 }, { 0.185783, 0.704891, 0.485273 }, { 0.19109, 0.708366, 0.482284 }, - { 0.196571, 0.711827, 0.479221 }, { 0.202219, 0.715272, 0.476084 }, { 0.20803, 0.718701, 0.472873 }, - { 0.214, 0.722114, 0.469588 }, { 0.220124, 0.725509, 0.466226 }, { 0.226397, 0.728888, 0.462789 }, - { 0.232815, 0.732247, 0.459277 }, { 0.239374, 0.735588, 0.455688 }, { 0.24607, 0.73891, 0.452024 }, - { 0.252899, 0.742211, 0.448284 }, { 0.259857, 0.745492, 0.444467 }, { 0.266941, 0.748751, 0.440573 }, - { 0.274149, 0.751988, 0.436601 }, { 0.281477, 0.755203, 0.432552 }, { 0.288921, 0.758394, 0.428426 }, - { 0.296479, 0.761561, 0.424223 }, { 0.304148, 0.764704, 0.419943 }, { 0.311925, 0.767822, 0.415586 }, - { 0.319809, 0.770914, 0.411152 }, { 0.327796, 0.77398, 0.40664 }, { 0.335885, 0.777018, 0.402049 }, - { 0.344074, 0.780029, 0.397381 }, { 0.35236, 0.783011, 0.392636 }, { 0.360741, 0.785964, 0.387814 }, - { 0.369214, 0.788888, 0.382914 }, { 0.377779, 0.791781, 0.377939 }, { 0.386433, 0.794644, 0.372886 }, - { 0.395174, 0.797475, 0.367757 }, { 0.404001, 0.800275, 0.362552 }, { 0.412913, 0.803041, 0.357269 }, - { 0.421908, 0.805774, 0.35191 }, { 0.430983, 0.808473, 0.346476 }, { 0.440137, 0.811138, 0.340967 }, - { 0.449368, 0.813768, 0.335384 }, { 0.458674, 0.816363, 0.329727 }, { 0.468053, 0.818921, 0.323998 }, - { 0.477504, 0.821444, 0.318195 }, { 0.487026, 0.823929, 0.312321 }, { 0.496615, 0.826376, 0.306377 }, - { 0.506271, 0.828786, 0.300362 }, { 0.515992, 0.831158, 0.294279 }, { 0.525776, 0.833491, 0.288127 }, - { 0.535621, 0.835785, 0.281908 }, { 0.545524, 0.838039, 0.275626 }, { 0.555484, 0.840254, 0.269281 }, - { 0.565498, 0.84243, 0.262877 }, { 0.575563, 0.844566, 0.256415 }, { 0.585678, 0.846661, 0.249897 }, - { 0.595839, 0.848717, 0.243329 }, { 0.606045, 0.850733, 0.236712 }, { 0.616293, 0.852709, 0.230052 }, - { 0.626579, 0.854645, 0.223353 }, { 0.636902, 0.856542, 0.21662 }, { 0.647257, 0.8584, 0.209861 }, - { 0.657642, 0.860219, 0.203082 }, { 0.668054, 0.861999, 0.196293 }, { 0.678489, 0.863742, 0.189503 }, - { 0.688944, 0.865448, 0.182725 }, { 0.699415, 0.867117, 0.175971 }, { 0.709898, 0.868751, 0.169257 }, - { 0.720391, 0.87035, 0.162603 }, { 0.730889, 0.871916, 0.156029 }, { 0.741388, 0.873449, 0.149561 }, - { 0.751884, 0.874951, 0.143228 }, { 0.762373, 0.876424, 0.137064 }, { 0.772852, 0.877868, 0.131109 }, - { 0.783315, 0.879285, 0.125405 }, { 0.79376, 0.880678, 0.120005 }, { 0.804182, 0.882046, 0.114965 }, - { 0.814576, 0.883393, 0.110347 }, { 0.82494, 0.88472, 0.106217 }, { 0.83527, 0.886029, 0.102646 }, - { 0.845561, 0.887322, 0.099702 }, { 0.85581, 0.888601, 0.097452 }, { 0.866013, 0.889868, 0.095953 }, - { 0.876168, 0.891125, 0.09525 }, { 0.886271, 0.892374, 0.095374 }, { 0.89632, 0.893616, 0.096335 }, - { 0.906311, 0.894855, 0.098125 }, { 0.916242, 0.896091, 0.100717 }, { 0.926106, 0.89733, 0.104071 }, - { 0.935904, 0.89857, 0.108131 }, { 0.945636, 0.899815, 0.112838 }, { 0.9553, 0.901065, 0.118128 }, - { 0.964894, 0.902323, 0.123941 }, { 0.974417, 0.90359, 0.130215 }, { 0.983868, 0.904867, 0.136897 }, - { 0.993248, 0.906157, 0.143936 } -}; + {0.267004, 0.004874, 0.329415}, + {0.26851, 0.009605, 0.335427}, + {0.269944, 0.014625, 0.341379}, + {0.271305, 0.019942, 0.347269}, + {0.272594, 0.025563, 0.353093}, + {0.273809, 0.031497, 0.358853}, + {0.274952, 0.037752, 0.364543}, + {0.276022, 0.044167, 0.370164}, + {0.277018, 0.050344, 0.375715}, + {0.277941, 0.056324, 0.381191}, + {0.278791, 0.062145, 0.386592}, + {0.279566, 0.067836, 0.391917}, + {0.280267, 0.073417, 0.397163}, + {0.280894, 0.078907, 0.402329}, + {0.281446, 0.08432, 0.407414}, + {0.281924, 0.089666, 0.412415}, + {0.282327, 0.094955, 0.417331}, + {0.282656, 0.100196, 0.42216}, + {0.28291, 0.105393, 0.426902}, + {0.283091, 0.110553, 0.431554}, + {0.283197, 0.11568, 0.436115}, + {0.283229, 0.120777, 0.440584}, + {0.283187, 0.125848, 0.44496}, + {0.283072, 0.130895, 0.449241}, + {0.282884, 0.13592, 0.453427}, + {0.282623, 0.140926, 0.457517}, + {0.28229, 0.145912, 0.46151}, + {0.281887, 0.150881, 0.465405}, + {0.281412, 0.155834, 0.469201}, + {0.280868, 0.160771, 0.472899}, + {0.280255, 0.165693, 0.476498}, + {0.279574, 0.170599, 0.479997}, + {0.278826, 0.17549, 0.483397}, + {0.278012, 0.180367, 0.486697}, + {0.277134, 0.185228, 0.489898}, + {0.276194, 0.190074, 0.493001}, + {0.275191, 0.194905, 0.496005}, + {0.274128, 0.199721, 0.498911}, + {0.273006, 0.20452, 0.501721}, + {0.271828, 0.209303, 0.504434}, + {0.270595, 0.214069, 0.507052}, + {0.269308, 0.218818, 0.509577}, + {0.267968, 0.223549, 0.512008}, + {0.26658, 0.228262, 0.514349}, + {0.265145, 0.232956, 0.516599}, + {0.263663, 0.237631, 0.518762}, + {0.262138, 0.242286, 0.520837}, + {0.260571, 0.246922, 0.522828}, + {0.258965, 0.251537, 0.524736}, + {0.257322, 0.25613, 0.526563}, + {0.255645, 0.260703, 0.528312}, + {0.253935, 0.265254, 0.529983}, + {0.252194, 0.269783, 0.531579}, + {0.250425, 0.27429, 0.533103}, + {0.248629, 0.278775, 0.534556}, + {0.246811, 0.283237, 0.535941}, + {0.244972, 0.287675, 0.53726}, + {0.243113, 0.292092, 0.538516}, + {0.241237, 0.296485, 0.539709}, + {0.239346, 0.300855, 0.540844}, + {0.237441, 0.305202, 0.541921}, + {0.235526, 0.309527, 0.542944}, + {0.233603, 0.313828, 0.543914}, + {0.231674, 0.318106, 0.544834}, + {0.229739, 0.322361, 0.545706}, + {0.227802, 0.326594, 0.546532}, + {0.225863, 0.330805, 0.547314}, + {0.223925, 0.334994, 0.548053}, + {0.221989, 0.339161, 0.548752}, + {0.220057, 0.343307, 0.549413}, + {0.21813, 0.347432, 0.550038}, + {0.21621, 0.351535, 0.550627}, + {0.214298, 0.355619, 0.551184}, + {0.212395, 0.359683, 0.55171}, + {0.210503, 0.363727, 0.552206}, + {0.208623, 0.367752, 0.552675}, + {0.206756, 0.371758, 0.553117}, + {0.204903, 0.375746, 0.553533}, + {0.203063, 0.379716, 0.553925}, + {0.201239, 0.38367, 0.554294}, + {0.19943, 0.387607, 0.554642}, + {0.197636, 0.391528, 0.554969}, + {0.19586, 0.395433, 0.555276}, + {0.1941, 0.399323, 0.555565}, + {0.192357, 0.403199, 0.555836}, + {0.190631, 0.407061, 0.556089}, + {0.188923, 0.41091, 0.556326}, + {0.187231, 0.414746, 0.556547}, + {0.185556, 0.41857, 0.556753}, + {0.183898, 0.422383, 0.556944}, + {0.182256, 0.426184, 0.55712}, + {0.180629, 0.429975, 0.557282}, + {0.179019, 0.433756, 0.55743}, + {0.177423, 0.437527, 0.557565}, + {0.175841, 0.44129, 0.557685}, + {0.174274, 0.445044, 0.557792}, + {0.172719, 0.448791, 0.557885}, + {0.171176, 0.45253, 0.557965}, + {0.169646, 0.456262, 0.55803}, + {0.168126, 0.459988, 0.558082}, + {0.166617, 0.463708, 0.558119}, + {0.165117, 0.467423, 0.558141}, + {0.163625, 0.471133, 0.558148}, + {0.162142, 0.474838, 0.55814}, + {0.160665, 0.47854, 0.558115}, + {0.159194, 0.482237, 0.558073}, + {0.157729, 0.485932, 0.558013}, + {0.15627, 0.489624, 0.557936}, + {0.154815, 0.493313, 0.55784}, + {0.153364, 0.497, 0.557724}, + {0.151918, 0.500685, 0.557587}, + {0.150476, 0.504369, 0.55743}, + {0.149039, 0.508051, 0.55725}, + {0.147607, 0.511733, 0.557049}, + {0.14618, 0.515413, 0.556823}, + {0.144759, 0.519093, 0.556572}, + {0.143343, 0.522773, 0.556295}, + {0.141935, 0.526453, 0.555991}, + {0.140536, 0.530132, 0.555659}, + {0.139147, 0.533812, 0.555298}, + {0.13777, 0.537492, 0.554906}, + {0.136408, 0.541173, 0.554483}, + {0.135066, 0.544853, 0.554029}, + {0.133743, 0.548535, 0.553541}, + {0.132444, 0.552216, 0.553018}, + {0.131172, 0.555899, 0.552459}, + {0.129933, 0.559582, 0.551864}, + {0.128729, 0.563265, 0.551229}, + {0.127568, 0.566949, 0.550556}, + {0.126453, 0.570633, 0.549841}, + {0.125394, 0.574318, 0.549086}, + {0.124395, 0.578002, 0.548287}, + {0.123463, 0.581687, 0.547445}, + {0.122606, 0.585371, 0.546557}, + {0.121831, 0.589055, 0.545623}, + {0.121148, 0.592739, 0.544641}, + {0.120565, 0.596422, 0.543611}, + {0.120092, 0.600104, 0.54253}, + {0.119738, 0.603785, 0.5414}, + {0.119512, 0.607464, 0.540218}, + {0.119423, 0.611141, 0.538982}, + {0.119483, 0.614817, 0.537692}, + {0.119699, 0.61849, 0.536347}, + {0.120081, 0.622161, 0.534946}, + {0.120638, 0.625828, 0.533488}, + {0.12138, 0.629492, 0.531973}, + {0.122312, 0.633153, 0.530398}, + {0.123444, 0.636809, 0.528763}, + {0.12478, 0.640461, 0.527068}, + {0.126326, 0.644107, 0.525311}, + {0.128087, 0.647749, 0.523491}, + {0.130067, 0.651384, 0.521608}, + {0.132268, 0.655014, 0.519661}, + {0.134692, 0.658636, 0.517649}, + {0.137339, 0.662252, 0.515571}, + {0.14021, 0.665859, 0.513427}, + {0.143303, 0.669459, 0.511215}, + {0.146616, 0.67305, 0.508936}, + {0.150148, 0.676631, 0.506589}, + {0.153894, 0.680203, 0.504172}, + {0.157851, 0.683765, 0.501686}, + {0.162016, 0.687316, 0.499129}, + {0.166383, 0.690856, 0.496502}, + {0.170948, 0.694384, 0.493803}, + {0.175707, 0.6979, 0.491033}, + {0.180653, 0.701402, 0.488189}, + {0.185783, 0.704891, 0.485273}, + {0.19109, 0.708366, 0.482284}, + {0.196571, 0.711827, 0.479221}, + {0.202219, 0.715272, 0.476084}, + {0.20803, 0.718701, 0.472873}, + {0.214, 0.722114, 0.469588}, + {0.220124, 0.725509, 0.466226}, + {0.226397, 0.728888, 0.462789}, + {0.232815, 0.732247, 0.459277}, + {0.239374, 0.735588, 0.455688}, + {0.24607, 0.73891, 0.452024}, + {0.252899, 0.742211, 0.448284}, + {0.259857, 0.745492, 0.444467}, + {0.266941, 0.748751, 0.440573}, + {0.274149, 0.751988, 0.436601}, + {0.281477, 0.755203, 0.432552}, + {0.288921, 0.758394, 0.428426}, + {0.296479, 0.761561, 0.424223}, + {0.304148, 0.764704, 0.419943}, + {0.311925, 0.767822, 0.415586}, + {0.319809, 0.770914, 0.411152}, + {0.327796, 0.77398, 0.40664}, + {0.335885, 0.777018, 0.402049}, + {0.344074, 0.780029, 0.397381}, + {0.35236, 0.783011, 0.392636}, + {0.360741, 0.785964, 0.387814}, + {0.369214, 0.788888, 0.382914}, + {0.377779, 0.791781, 0.377939}, + {0.386433, 0.794644, 0.372886}, + {0.395174, 0.797475, 0.367757}, + {0.404001, 0.800275, 0.362552}, + {0.412913, 0.803041, 0.357269}, + {0.421908, 0.805774, 0.35191}, + {0.430983, 0.808473, 0.346476}, + {0.440137, 0.811138, 0.340967}, + {0.449368, 0.813768, 0.335384}, + {0.458674, 0.816363, 0.329727}, + {0.468053, 0.818921, 0.323998}, + {0.477504, 0.821444, 0.318195}, + {0.487026, 0.823929, 0.312321}, + {0.496615, 0.826376, 0.306377}, + {0.506271, 0.828786, 0.300362}, + {0.515992, 0.831158, 0.294279}, + {0.525776, 0.833491, 0.288127}, + {0.535621, 0.835785, 0.281908}, + {0.545524, 0.838039, 0.275626}, + {0.555484, 0.840254, 0.269281}, + {0.565498, 0.84243, 0.262877}, + {0.575563, 0.844566, 0.256415}, + {0.585678, 0.846661, 0.249897}, + {0.595839, 0.848717, 0.243329}, + {0.606045, 0.850733, 0.236712}, + {0.616293, 0.852709, 0.230052}, + {0.626579, 0.854645, 0.223353}, + {0.636902, 0.856542, 0.21662}, + {0.647257, 0.8584, 0.209861}, + {0.657642, 0.860219, 0.203082}, + {0.668054, 0.861999, 0.196293}, + {0.678489, 0.863742, 0.189503}, + {0.688944, 0.865448, 0.182725}, + {0.699415, 0.867117, 0.175971}, + {0.709898, 0.868751, 0.169257}, + {0.720391, 0.87035, 0.162603}, + {0.730889, 0.871916, 0.156029}, + {0.741388, 0.873449, 0.149561}, + {0.751884, 0.874951, 0.143228}, + {0.762373, 0.876424, 0.137064}, + {0.772852, 0.877868, 0.131109}, + {0.783315, 0.879285, 0.125405}, + {0.79376, 0.880678, 0.120005}, + {0.804182, 0.882046, 0.114965}, + {0.814576, 0.883393, 0.110347}, + {0.82494, 0.88472, 0.106217}, + {0.83527, 0.886029, 0.102646}, + {0.845561, 0.887322, 0.099702}, + {0.85581, 0.888601, 0.097452}, + {0.866013, 0.889868, 0.095953}, + {0.876168, 0.891125, 0.09525}, + {0.886271, 0.892374, 0.095374}, + {0.89632, 0.893616, 0.096335}, + {0.906311, 0.894855, 0.098125}, + {0.916242, 0.896091, 0.100717}, + {0.926106, 0.89733, 0.104071}, + {0.935904, 0.89857, 0.108131}, + {0.945636, 0.899815, 0.112838}, + {0.9553, 0.901065, 0.118128}, + {0.964894, 0.902323, 0.123941}, + {0.974417, 0.90359, 0.130215}, + {0.983868, 0.904867, 0.136897}, + {0.993248, 0.906157, 0.143936}}; -} // namespace colormaps +}// namespace colormaps diff --git a/src/debug_image.cpp b/src/debug_image.cpp index 3af0b2063e0ac1c3c8468f97a86c4105fa2f5bd2..94a0cfa5a893b1ca8d4294bc0fbdfb89a234df2f 100644 --- a/src/debug_image.cpp +++ b/src/debug_image.cpp @@ -15,8 +15,7 @@ DebugImage::DebugImage(std::string name) { vk::SharingMode::eExclusive, 1, &resources.gQ, - vk::ImageLayout::eUndefined - ); + vk::ImageLayout::eUndefined); createImage(resources.pDevice, resources.device, imageInfo, {vk::MemoryPropertyFlagBits::eDeviceLocal}, std::move(name), image, imageMemory); @@ -27,8 +26,10 @@ DebugImage::DebugImage(std::string name) { vk::Format::eR8G8B8A8Unorm, {}, {{vk::ImageAspectFlagBits::eColor}, - 0, 1, 0, 1} - ); + 0, + 1, + 0, + 1}); view = resources.device.createImageView(viewInfo); descriptorInfo = vk::DescriptorImageInfo(nullptr, view, vk::ImageLayout::eColorAttachmentOptimal); @@ -40,8 +41,7 @@ DebugImage::DebugImage(std::string name) { image, resources.surfaceFormat.format, vk::ImageLayout::eUndefined, - vk::ImageLayout::eGeneral - ); + vk::ImageLayout::eGeneral); } DebugImage::~DebugImage() { @@ -50,8 +50,8 @@ DebugImage::~DebugImage() { resources.device.freeMemory(imageMemory); } -void DebugImage::clear(vk::CommandBuffer cmd, std::array<float,4> color) { - vk::ImageSubresourceRange resource(vk::ImageAspectFlagBits::eColor, 0, 1,0,1); +void DebugImage::clear(vk::CommandBuffer cmd, std::array<float, 4> color) { + vk::ImageSubresourceRange resource(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1); cmd.clearColorImage(image, vk::ImageLayout::eGeneral, color, resource); } @@ -60,7 +60,5 @@ vk::DescriptorSetLayoutBinding DebugImage::getLayout(uint32_t binding) { } vk::WriteDescriptorSet DebugImage::getWrite(vk::DescriptorSet set, uint32_t binding) { - return {set, binding, 0,vk::DescriptorType::eStorageImage, descriptorInfo }; + return {set, binding, 0, vk::DescriptorType::eStorageImage, descriptorInfo}; } - - diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp index 2ccffc1308bc53957107efdf3e51e6adb61f33e1..fdff9900a1d048447f740cb8ad772bc650fdd2f6 100644 --- a/src/imgui_ui.cpp +++ b/src/imgui_ui.cpp @@ -1,15 +1,14 @@ #include "imgui_ui.h" #include "imgui.h" -#include "imgui_impl_vulkan.h" #include "imgui_impl_glfw.h" +#include "imgui_impl_vulkan.h" #include "simulation_parameters.h" #include "simulation_state.h" - ImguiUi::ImguiUi() { const vk::DescriptorPoolSize pool_sizes[] = { - {vk::DescriptorType::eSampler, 10}, + {vk::DescriptorType::eSampler, 10}, {vk::DescriptorType::eUniformBuffer, 10}, {vk::DescriptorType::eStorageBuffer, 10}, }; @@ -33,8 +32,7 @@ ImguiUi::ImguiUi() { vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::ePresentSrcKHR, - vk::ImageLayout::ePresentSrcKHR - ); + vk::ImageLayout::ePresentSrcKHR); vk::AttachmentReference color_attachment(0, vk::ImageLayout::eColorAttachmentOptimal); @@ -45,8 +43,7 @@ ImguiUi::ImguiUi() { color_attachment, {}, nullptr, - {} - ); + {}); vk::SubpassDependency externalDependency( VK_SUBPASS_EXTERNAL, @@ -54,8 +51,7 @@ ImguiUi::ImguiUi() { {vk::PipelineStageFlagBits::eColorAttachmentOutput}, {vk::PipelineStageFlagBits::eColorAttachmentOutput}, {vk::AccessFlagBits::eColorAttachmentWrite}, - {vk::AccessFlagBits::eColorAttachmentWrite} - ); + {vk::AccessFlagBits::eColorAttachmentWrite}); vk::RenderPassCreateInfo info({}, attachment, ui_subpass, externalDependency); renderPass = resources.device.createRenderPass(info); @@ -78,8 +74,7 @@ ImguiUi::ImguiUi() { {}, nullptr, nullptr, - 0 - }; + 0}; ImGui_ImplVulkan_Init(&init_info, renderPass); ImGui::StyleColorsDark(); @@ -106,8 +101,7 @@ void ImguiUi::initCommandBuffers() { resources.swapchainImageViews[i], resources.extent.width, resources.extent.height, - 1 - ); + 1); frameBuffers.push_back(resources.device.createFramebuffer(info)); } } @@ -121,7 +115,6 @@ vk::CommandBuffer ImguiUi::updateCommandBuffer(uint32_t index, UiBindings &bindi cmd.reset(); - ImGui_ImplVulkan_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); @@ -134,7 +127,7 @@ vk::CommandBuffer ImguiUi::updateCommandBuffer(uint32_t index, UiBindings &bindi cmd.begin(cmdBeginInfo); - vk::ClearValue color(std::array<float, 4>{0, 0, 0, 0}); + vk::ClearValue color(std::array<float, 4> {0, 0, 0, 0}); vk::Rect2D area({0, 0}, resources.extent); @@ -150,11 +143,11 @@ vk::CommandBuffer ImguiUi::updateCommandBuffer(uint32_t index, UiBindings &bindi return cmd; } -template <typename T> +template<typename T> bool EnumCombo(const char *name, T *currentValue, const Mappings<T> &mappings) { // static should be per type static const auto comboValueArray = imguiComboArray(mappings); - return ImGui::Combo(name, reinterpret_cast<int*>(currentValue), comboValueArray.data(), comboValueArray.size()); + return ImGui::Combo(name, reinterpret_cast<int *>(currentValue), comboValueArray.data(), comboValueArray.size()); } void ImguiUi::drawUi(UiBindings &bindings) { @@ -190,7 +183,10 @@ void ImguiUi::drawUi(UiBindings &bindings) { updateFlags.resetSimulation |= ImGui::Button("Restart Simulation"); auto &simulation = bindings.simulationParameters; - ImGui::DragInt("Num Particles", reinterpret_cast<int*>(&simulation.numParticles), 16, 16, 1024 * 1024 * 1024); + ImGui::DragInt("Num Particles", reinterpret_cast<int *>(&simulation.numParticles), 16, 16, 1024 * 1024 * 1024); + ImGui::DragFloat("Gravity", &simulation.gravity, 0.1f); + ImGui::DragFloat("Delta Time", &simulation.deltaTime, 0.001f); + ImGui::DragFloat("Collision Damping", &simulation.collisionDampingFactor, 0.01f); } ImGui::End(); @@ -203,7 +199,8 @@ void ImguiUi::destroyCommandBuffers() { commandPool = nullptr; } if (!frameBuffers.empty()) { - for (auto framebuffer: frameBuffers) resources.device.destroyFramebuffer(framebuffer); + for (auto framebuffer: frameBuffers) + resources.device.destroyFramebuffer(framebuffer); frameBuffers.clear(); } } diff --git a/src/initialization.cpp b/src/initialization.cpp index 07be923ac00c06176266e24b42f416b0c8c08e6d..44d0c9240c5b0f585613be3b199122291fa0e268 100644 --- a/src/initialization.cpp +++ b/src/initialization.cpp @@ -1,7 +1,7 @@ -#include <iostream> -#include <fstream> #include <cstring> +#include <fstream> #include <functional> +#include <iostream> #include <optional> #define VK_ENABLE_BETA_EXTENSIONS @@ -28,18 +28,18 @@ const bool enableValidationLayers = false; const bool enableValidationLayers = true; #endif -const std::vector<const char*> validationLayers = { +const std::vector<const char *> validationLayers = { #ifndef NDEBUG - "VK_LAYER_KHRONOS_validation" + "VK_LAYER_KHRONOS_validation" #endif }; -const std::vector<const char*> staticInstanceExtensions = { +const std::vector<const char *> staticInstanceExtensions = { #ifndef NDEBUG - VK_EXT_DEBUG_UTILS_EXTENSION_NAME, + VK_EXT_DEBUG_UTILS_EXTENSION_NAME, #endif }; -const std::vector<const char*> staticExtensionNames = { +const std::vector<const char *> staticExtensionNames = { #ifndef NDEBUG #endif @@ -53,7 +53,7 @@ void AppResources::destroy() { //this->device.destroyCommandPool(this->transferCommandPool); this->device.destroyCommandPool(this->graphicsCommandPool); - for (auto imageView : this->swapchainImageViews) { + for (auto imageView: this->swapchainImageViews) { this->device.destroyImageView(imageView); } this->swapchainImageViews.resize(0); @@ -75,14 +75,14 @@ void AppResources::destroy() { glfwDestroyWindow(this->window); } -void initApp(AppResources& app, bool withWindow, const std::string& name, int width, int height) { +void initApp(AppResources &app, bool withWindow, const std::string &name, int width, int height) { app.window = nullptr; if (withWindow) { if (!glfwInit()) throw std::runtime_error("GLFW initialization failed!"); if (!glfwVulkanSupported()) throw std::runtime_error( - "GLFW reports to have no Vulkan support! Maybe it couldn't find the Vulkan loader!"); + "GLFW reports to have no Vulkan support! Maybe it couldn't find the Vulkan loader!"); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); app.window = glfwCreateWindow(width, height, name.c_str(), nullptr, nullptr); @@ -111,8 +111,7 @@ void initApp(AppResources& app, bool withWindow, const std::string& name, int wi if (app.cQ != -1) { app.device.getQueue(app.cQ, 0U, &app.computeQueue); createCommandPool(app.device, app.computeCommandPool, app.cQ); - } - else { + } else { app.computeQueue = app.graphicsQueue; app.computeCommandPool = app.graphicsCommandPool; } @@ -120,8 +119,7 @@ void initApp(AppResources& app, bool withWindow, const std::string& name, int wi if (app.tQ != -1) { app.device.getQueue(app.tQ, 0U, &app.transferQueue); createCommandPool(app.device, app.transferCommandPool, app.tQ); - } - else { + } else { app.transferQueue = app.graphicsQueue; app.transferCommandPool = app.graphicsCommandPool; } @@ -141,8 +139,8 @@ void initApp(AppResources& app, bool withWindow, const std::string& name, int wi VKAPI_ATTR VkBool32 VKAPI_CALL debugUtilsMessengerCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, - VkDebugUtilsMessengerCallbackDataEXT const* pCallbackData, - void* /*pUserData*/) { + VkDebugUtilsMessengerCallbackDataEXT const *pCallbackData, + void * /*pUserData*/) { if (enableValidationLayers) { if (pCallbackData->messageIdNumber == 648835635) { // UNASSIGNED-khronos-Validation-debug-build-warning-message @@ -155,47 +153,47 @@ debugUtilsMessengerCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeveri } std::cerr << vk::to_string(static_cast<vk::DebugUtilsMessageSeverityFlagBitsEXT>(messageSeverity)) << ": " - << vk::to_string(static_cast<vk::DebugUtilsMessageTypeFlagsEXT>(messageTypes)) << ":\n"; + << vk::to_string(static_cast<vk::DebugUtilsMessageTypeFlagsEXT>(messageTypes)) << ":\n"; std::cerr << "\t" - << "messageIDName = <" << pCallbackData->pMessageIdName << ">\n"; + << "messageIDName = <" << pCallbackData->pMessageIdName << ">\n"; std::cerr << "\t" - << "messageIdNumber = " << pCallbackData->messageIdNumber << "\n"; + << "messageIdNumber = " << pCallbackData->messageIdNumber << "\n"; std::cerr << "\t" - << "message = <" << pCallbackData->pMessage << ">\n"; + << "message = <" << pCallbackData->pMessage << ">\n"; if (0 < pCallbackData->queueLabelCount) { std::cerr << "\t" - << "Queue Labels:\n"; + << "Queue Labels:\n"; for (uint8_t i = 0; i < pCallbackData->queueLabelCount; i++) { std::cerr << "\t\t" - << "labelName = <" << pCallbackData->pQueueLabels[i].pLabelName << ">\n"; + << "labelName = <" << pCallbackData->pQueueLabels[i].pLabelName << ">\n"; } } if (0 < pCallbackData->cmdBufLabelCount) { std::cerr << "\t" - << "CommandBuffer Labels:\n"; + << "CommandBuffer Labels:\n"; for (uint8_t i = 0; i < pCallbackData->cmdBufLabelCount; i++) { std::cerr << "\t\t" - << "labelName = <" << pCallbackData->pCmdBufLabels[i].pLabelName << ">\n"; + << "labelName = <" << pCallbackData->pCmdBufLabels[i].pLabelName << ">\n"; } } if (0 < pCallbackData->objectCount) { std::cerr << "\t" - << "Objects:\n"; + << "Objects:\n"; for (uint8_t i = 0; i < pCallbackData->objectCount; i++) { std::cerr << "\t\t" - << "Object " << i << "\n"; + << "Object " << i << "\n"; std::cerr << "\t\t\t" - << "objectType = " - << vk::to_string(static_cast<vk::ObjectType>(pCallbackData->pObjects[i].objectType)) << "\n"; + << "objectType = " + << vk::to_string(static_cast<vk::ObjectType>(pCallbackData->pObjects[i].objectType)) << "\n"; std::cerr << "\t\t\t" - << "objectHandle = " << pCallbackData->pObjects[i].objectHandle << "\n"; + << "objectHandle = " << pCallbackData->pObjects[i].objectHandle << "\n"; if (pCallbackData->pObjects[i].pObjectName) { std::cerr << "\t\t\t" - << "objectName = <" << pCallbackData->pObjects[i].pObjectName << ">\n"; + << "objectName = <" << pCallbackData->pObjects[i].pObjectName << ">\n"; } } } - std::cout<<std::endl; + std::cout << std::endl; return VK_TRUE; } @@ -204,14 +202,13 @@ debugUtilsMessengerCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeveri which error messages should go through */ vk::DebugUtilsMessengerCreateInfoEXT makeDebugUtilsMessengerCreateInfoEXT() { - using SEVERITY = vk::DebugUtilsMessageSeverityFlagBitsEXT; // for readability + using SEVERITY = vk::DebugUtilsMessageSeverityFlagBitsEXT;// for readability using MESSAGE = vk::DebugUtilsMessageTypeFlagBitsEXT; return { - {}, - SEVERITY::eWarning | SEVERITY::eError, - MESSAGE::eGeneral | MESSAGE::ePerformance | MESSAGE::eValidation, - &debugUtilsMessengerCallback - }; + {}, + SEVERITY::eWarning | SEVERITY::eError, + MESSAGE::eGeneral | MESSAGE::ePerformance | MESSAGE::eValidation, + &debugUtilsMessengerCallback}; } /* @@ -221,28 +218,28 @@ vk::DebugUtilsMessengerCreateInfoEXT makeDebugUtilsMessengerCreateInfoEXT() { void initDynamicLoader() { static vk::DynamicLoader dl; static PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = dl.getProcAddress<PFN_vkGetInstanceProcAddr>( - "vkGetInstanceProcAddr"); + "vkGetInstanceProcAddr"); VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr); } -void createInstance(vk::Instance& instance, vk::DebugUtilsMessengerEXT& debugUtilsMessenger, +void createInstance(vk::Instance &instance, vk::DebugUtilsMessengerEXT &debugUtilsMessenger, std::string appName, std::string engineName, bool withWindow) { initDynamicLoader(); vk::ApplicationInfo applicationInfo(appName.c_str(), 1, engineName.c_str(), 1, VK_API_VERSION_1_2); - std::vector<const char*> instanceExtensions(staticInstanceExtensions); + std::vector<const char *> instanceExtensions(staticInstanceExtensions); if (withWindow) { // GLFW gives us the platform specific extensions for surface handling uint32_t count; - const char** extensions = glfwGetRequiredInstanceExtensions(&count); + const char **extensions = glfwGetRequiredInstanceExtensions(&count); instanceExtensions.insert(instanceExtensions.end(), extensions, extensions + count); } // ### initialize the InstanceCreateInfo ### - vk::InstanceCreateInfo instanceCreateInfo( //flags, pAppInfo, layerCount, layerNames, extcount, extNames - {}, &applicationInfo, - static_cast<uint32_t>(validationLayers.size()), validationLayers.data(), - static_cast<uint32_t>(instanceExtensions.size()), instanceExtensions.data()); + vk::InstanceCreateInfo instanceCreateInfo(//flags, pAppInfo, layerCount, layerNames, extcount, extNames + {}, &applicationInfo, + static_cast<uint32_t>(validationLayers.size()), validationLayers.data(), + static_cast<uint32_t>(instanceExtensions.size()), instanceExtensions.data()); // ### DebugInfo: use of StructureChain instead of pNext ### // DebugUtils is used to catch errors from the instance @@ -250,9 +247,9 @@ void createInstance(vk::Instance& instance, vk::DebugUtilsMessengerEXT& debugUti // the StructureChain fills the pNext member of the struct in a typesafe way // this is only possible with vulkan-hpp, in plain vulkan there is no typechecking vk::StructureChain<vk::InstanceCreateInfo, vk::DebugUtilsMessengerCreateInfoEXT> chain = - {instanceCreateInfo, debugCreateInfo}; + {instanceCreateInfo, debugCreateInfo}; - if (!enableValidationLayers) // for Release mode + if (!enableValidationLayers)// for Release mode chain.unlink<vk::DebugUtilsMessengerCreateInfoEXT>(); // create an Instance @@ -266,7 +263,7 @@ void createInstance(vk::Instance& instance, vk::DebugUtilsMessengerEXT& debugUti } -std::tuple<uint32_t, uint32_t, uint32_t> getGCTQueues(vk::PhysicalDevice& pDevice) { +std::tuple<uint32_t, uint32_t, uint32_t> getGCTQueues(vk::PhysicalDevice &pDevice) { uint32_t gq = -1; uint32_t cq = -1; uint32_t ocq = -1; @@ -275,11 +272,11 @@ std::tuple<uint32_t, uint32_t, uint32_t> getGCTQueues(vk::PhysicalDevice& pDevic using Chain = vk::StructureChain<vk::QueueFamilyProperties2, vk::QueueFamilyCheckpointPropertiesNV>; using QFB = vk::QueueFlagBits; auto queueFamilyProperties2 = pDevice.getQueueFamilyProperties2< - Chain, std::allocator<Chain>, vk::DispatchLoaderDynamic>(); + Chain, std::allocator<Chain>, vk::DispatchLoaderDynamic>(); for (uint32_t j = 0; j < queueFamilyProperties2.size(); j++) { - vk::QueueFamilyProperties const& properties = - queueFamilyProperties2[static_cast<size_t>(j)].get<vk::QueueFamilyProperties2>().queueFamilyProperties; + vk::QueueFamilyProperties const &properties = + queueFamilyProperties2[static_cast<size_t>(j)].get<vk::QueueFamilyProperties2>().queueFamilyProperties; if (properties.queueFlags & QFB::eGraphics) if (gq == -1) gq = j; @@ -291,7 +288,7 @@ std::tuple<uint32_t, uint32_t, uint32_t> getGCTQueues(vk::PhysicalDevice& pDevic if (properties.queueFlags & QFB::eTransfer) if (otq == -1 && !(properties.queueFlags & QFB::eCompute || properties.queueFlags & QFB::eGraphics)) otq = - j; + j; } if (ocq == -1) ocq = cq; @@ -299,22 +296,22 @@ std::tuple<uint32_t, uint32_t, uint32_t> getGCTQueues(vk::PhysicalDevice& pDevic return std::tuple<uint32_t, uint32_t, uint32_t>(gq, ocq, otq); } -void selectPhysicalDevice(vk::Instance& instance, vk::PhysicalDevice& pDevice) { +void selectPhysicalDevice(vk::Instance &instance, vk::PhysicalDevice &pDevice) { // takes the first one // Get list of Physical Devices // Enumerate Physical devices the vkInstance can access std::vector<vk::PhysicalDevice> physDs = instance.enumeratePhysicalDevices(); - const static char* cache_name = "device_selection_cache"; - const static char* recreation_message = - "To select a new device, delete the file \"device_selection_cache\" in your working directory before executing the framework."; + const static char *cache_name = "device_selection_cache"; + const static char *recreation_message = + "To select a new device, delete the file \"device_selection_cache\" in your working directory before executing the framework."; std::ifstream ifile(cache_name, std::ios::binary); if (ifile.is_open()) { DeviceSelectionCache cache; - ifile.read(reinterpret_cast<char*>(&cache), sizeof(cache)); + ifile.read(reinterpret_cast<char *>(&cache), sizeof(cache)); ifile.close(); - for (auto physD : physDs) { + for (auto physD: physDs) { auto props = physD.getProperties2().properties; if (props.vendorID == cache.vendorID && props.deviceID == cache.deviceID) { std::cout << "Selecting previously selected device: \"" << props.deviceName << "\"" << std::endl; @@ -324,8 +321,7 @@ void selectPhysicalDevice(vk::Instance& instance, vk::PhysicalDevice& pDevice) { } } std::cout << "Previously selected device was not found." << std::endl; - } - else { + } else { std::cout << "No previous device selection found." << std::endl; } @@ -349,16 +345,16 @@ void selectPhysicalDevice(vk::Instance& instance, vk::PhysicalDevice& pDevice) { cache.deviceID = props.deviceID; std::ofstream ofile(cache_name, std::ios::out | std::ios::binary); - ofile.write(reinterpret_cast<const char*>(&cache), sizeof(cache)); + ofile.write(reinterpret_cast<const char *>(&cache), sizeof(cache)); ofile.close(); std::cout << "Selected device: \"" << props.deviceName.data() << "\"" << std::endl - << "This device will be automatically selected in the future." << std::endl - << recreation_message << std::endl; + << "This device will be automatically selected in the future." << std::endl + << recreation_message << std::endl; pDevice = physDs[i]; } -static std::vector<const char*> requiredDeviceExtensionNames(bool withWindow) { +static std::vector<const char *> requiredDeviceExtensionNames(bool withWindow) { std::vector extensionNames(staticExtensionNames); // Add VK_KHR_SWAPCHAIN extension if we want to create a window @@ -372,7 +368,7 @@ static std::vector<const char*> requiredDeviceExtensionNames(bool withWindow) { /* The logical device holds the queues and will be used in almost every call from now on */ -void createLogicalDevice(vk::Instance& instance, vk::PhysicalDevice& pDevice, vk::Device& device, bool withWindow) { +void createLogicalDevice(vk::Instance &instance, vk::PhysicalDevice &pDevice, vk::Device &device, bool withWindow) { //first get the queues uint32_t gQ, ocQ, otQ; std::tie(gQ, ocQ, otQ) = getGCTQueues(pDevice); @@ -397,7 +393,7 @@ void createLogicalDevice(vk::Instance& instance, vk::PhysicalDevice& pDevice, vk // Add VK_KHR_PORTABILITY_SUBSET extension if the device supports it auto deviceExtensionProperties = pDevice.enumerateDeviceExtensionProperties(); - for (auto ext : deviceExtensionProperties) { + for (auto ext: deviceExtensionProperties) { if (strcmp(ext.extensionName.data(), VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME) == 0) { extensionNames.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); break; @@ -419,8 +415,7 @@ void createLogicalDevice(vk::Instance& instance, vk::PhysicalDevice& pDevice, vk validationLayers, extensionNames, &deviceFeatures, - &timelineFeatures - ); + &timelineFeatures); device = pDevice.createDevice(dci); VULKAN_HPP_DEFAULT_DISPATCHER.init(device); @@ -428,76 +423,76 @@ void createLogicalDevice(vk::Instance& instance, vk::PhysicalDevice& pDevice, vk setObjectName(device, device, "This is my lovely device !"); } -void createCommandPool(vk::Device& device, vk::CommandPool& commandPool, uint32_t queueIndex) { +void createCommandPool(vk::Device &device, vk::CommandPool &commandPool, uint32_t queueIndex) { vk::CommandPoolCreateInfo cpi({vk::CommandPoolCreateFlagBits::eResetCommandBuffer}, queueIndex); commandPool = device.createCommandPool(cpi); } -void destroyInstance(vk::Instance& instance, vk::DebugUtilsMessengerEXT& debugUtilsMessenger) { +void destroyInstance(vk::Instance &instance, vk::DebugUtilsMessengerEXT &debugUtilsMessenger) { #ifndef NDEBUG instance.destroyDebugUtilsMessengerEXT(debugUtilsMessenger); #endif instance.destroy(); } -void destroyLogicalDevice(vk::Device& device) { +void destroyLogicalDevice(vk::Device &device) { device.destroy(); } -void destroyCommandPool(vk::Device& device, vk::CommandPool& commandPool) { +void destroyCommandPool(vk::Device &device, vk::CommandPool &commandPool) { device.destroyCommandPool(commandPool); commandPool = vk::CommandPool(); } -void showAvailableQueues(vk::PhysicalDevice& pDevice, bool diagExt) { +void showAvailableQueues(vk::PhysicalDevice &pDevice, bool diagExt) { using Chain = vk::StructureChain<vk::QueueFamilyProperties2, vk::QueueFamilyCheckpointPropertiesNV>; auto queueFamilyProperties2 = pDevice.getQueueFamilyProperties2< - Chain, std::allocator<Chain>, vk::DispatchLoaderDynamic>(); + Chain, std::allocator<Chain>, vk::DispatchLoaderDynamic>(); for (size_t j = 0; j < queueFamilyProperties2.size(); j++) { std::cout << "\t" - << "QueueFamily " << j << "\n"; - vk::QueueFamilyProperties const& properties = - queueFamilyProperties2[j].get<vk::QueueFamilyProperties2>().queueFamilyProperties; + << "QueueFamily " << j << "\n"; + vk::QueueFamilyProperties const &properties = + queueFamilyProperties2[j].get<vk::QueueFamilyProperties2>().queueFamilyProperties; std::cout << "\t\t" - << "QueueFamilyProperties:\n"; + << "QueueFamilyProperties:\n"; std::cout << "\t\t\t" - << "queueFlags = " << vk::to_string(properties.queueFlags) << "\n"; + << "queueFlags = " << vk::to_string(properties.queueFlags) << "\n"; std::cout << "\t\t\t" - << "queueCount = " << properties.queueCount << "\n"; + << "queueCount = " << properties.queueCount << "\n"; std::cout << "\t\t\t" - << "timestampValidBits = " << properties.timestampValidBits << "\n"; + << "timestampValidBits = " << properties.timestampValidBits << "\n"; std::cout << "\t\t\t" - << "minImageTransferGranularity = " << properties.minImageTransferGranularity.width << " x " - << properties.minImageTransferGranularity.height << " x " - << properties.minImageTransferGranularity.depth << "\n"; + << "minImageTransferGranularity = " << properties.minImageTransferGranularity.width << " x " + << properties.minImageTransferGranularity.height << " x " + << properties.minImageTransferGranularity.depth << "\n"; std::cout << "\n"; if (diagExt) { - vk::QueueFamilyCheckpointPropertiesNV const& checkpointProperties = - queueFamilyProperties2[j].get<vk::QueueFamilyCheckpointPropertiesNV>(); + vk::QueueFamilyCheckpointPropertiesNV const &checkpointProperties = + queueFamilyProperties2[j].get<vk::QueueFamilyCheckpointPropertiesNV>(); std::cout << "\t\t" - << "CheckPointPropertiesNV:\n"; + << "CheckPointPropertiesNV:\n"; std::cout << "\t\t\t" - << "checkpointExecutionStageMask = " - << vk::to_string(checkpointProperties.checkpointExecutionStageMask) << "\n"; + << "checkpointExecutionStageMask = " + << vk::to_string(checkpointProperties.checkpointExecutionStageMask) << "\n"; std::cout << "\n"; } } } -void createTimestampQueryPool(vk::Device& device, vk::QueryPool& queryPool, uint32_t queryCount) { +void createTimestampQueryPool(vk::Device &device, vk::QueryPool &queryPool, uint32_t queryCount) { vk::QueryPoolCreateInfo createInfo({}, vk::QueryType::eTimestamp, queryCount); queryPool = device.createQueryPool(createInfo); } -void destroyQueryPool(vk::Device& device, vk::QueryPool& queryPool) { +void destroyQueryPool(vk::Device &device, vk::QueryPool &queryPool) { device.destroyQueryPool(queryPool); queryPool = vk::QueryPool(); } -void createSwapchain(AppResources& app) { +void createSwapchain(AppResources &app) { // -- CAPABILITIES -- // Get the surface capabilities for the given surface on the given physical device auto capabilities = app.pDevice.getSurfaceCapabilitiesKHR(app.surface); @@ -512,9 +507,9 @@ void createSwapchain(AppResources& app) { throw std::runtime_error("Surface doesn't support any present modes!"); vk::SurfaceFormatKHR selectedSurfaceFormat = surfaceFormats[0]; - for (const auto& surfaceFormat : surfaceFormats) { + for (const auto &surfaceFormat: surfaceFormats) { if (surfaceFormat.format == vk::Format::eR8G8B8A8Srgb && surfaceFormat.colorSpace == - vk::ColorSpaceKHR::eSrgbNonlinear) { + vk::ColorSpaceKHR::eSrgbNonlinear) { selectedSurfaceFormat = surfaceFormat; break; } @@ -526,7 +521,7 @@ void createSwapchain(AppResources& app) { vk::PresentModeKHR selectedPresentMode = presentModes[0]; // Look for Immediate presentation mode - for (const auto& presentMode : presentModes) { + for (const auto &presentMode: presentModes) { if (presentMode == vk::PresentModeKHR::eImmediate) { selectedPresentMode = presentMode; break; @@ -538,8 +533,7 @@ void createSwapchain(AppResources& app) { if (capabilities.currentExtent.width != UINT32_MAX) { selectedExtent.width = capabilities.currentExtent.width; selectedExtent.height = capabilities.currentExtent.height; - } - else { + } else { // If value can vary, need to set manually // Get window size @@ -547,7 +541,7 @@ void createSwapchain(AppResources& app) { glfwGetFramebufferSize(app.window, &width, &height); // Create new extent using window size - selectedExtent = {(uint32_t)width, (uint32_t)height}; + selectedExtent = {(uint32_t) width, (uint32_t) height}; // Surface also defines max and min, so make sure within boundaries by clamping value selectedExtent.width = std::clamp(selectedExtent.width, capabilities.minImageExtent.width, @@ -565,53 +559,47 @@ void createSwapchain(AppResources& app) { // Creation information for swap chain vk::SwapchainCreateInfoKHR createInfo( - vk::SwapchainCreateFlagBitsKHR(), - app.surface, // Swapchain surface - selectedImageCount, // Minimum images in swapchain - selectedSurfaceFormat.format, // Swapchain format - selectedSurfaceFormat.colorSpace, // Swapchain colour space - selectedExtent, // Swapchain image extents - 1, // Number of layers for each image in chain - vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst, // What attachment images will be used as - vk::SharingMode::eExclusive, - 0, - nullptr, - vk::SurfaceTransformFlagBitsKHR::eIdentity, // Transform to perform on swap chain images - vk::CompositeAlphaFlagBitsKHR::eOpaque, - // How to handle blending images with external graphics (e.g. other windows) - selectedPresentMode, // Swapchain presentation mode - false, - VK_NULL_HANDLE - ); + vk::SwapchainCreateFlagBitsKHR(), + app.surface, // Swapchain surface + selectedImageCount, // Minimum images in swapchain + selectedSurfaceFormat.format, // Swapchain format + selectedSurfaceFormat.colorSpace, // Swapchain colour space + selectedExtent, // Swapchain image extents + 1, // Number of layers for each image in chain + vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst,// What attachment images will be used as + vk::SharingMode::eExclusive, + 0, + nullptr, + vk::SurfaceTransformFlagBitsKHR::eIdentity,// Transform to perform on swap chain images + vk::CompositeAlphaFlagBitsKHR::eOpaque, + // How to handle blending images with external graphics (e.g. other windows) + selectedPresentMode,// Swapchain presentation mode + false, + VK_NULL_HANDLE); app.swapchain = app.device.createSwapchainKHR(createInfo, nullptr); // Get swap chain images (first count, then values) app.swapchainImages = app.device.getSwapchainImagesKHR(app.swapchain); app.swapchainImageViews.resize(0); - for (auto image : app.swapchainImages) { + for (auto image: app.swapchainImages) { vk::ImageViewCreateInfo createInfo( - vk::ImageViewCreateFlagBits(), - image, - vk::ImageViewType::e2D, - selectedSurfaceFormat.format, - { - vk::ComponentSwizzle::eIdentity, - vk::ComponentSwizzle::eIdentity, - vk::ComponentSwizzle::eIdentity, - vk::ComponentSwizzle::eIdentity - }, - { - vk::ImageAspectFlagBits::eColor, - 0, 1, 0, 1 - } - ); + vk::ImageViewCreateFlagBits(), + image, + vk::ImageViewType::e2D, + selectedSurfaceFormat.format, + {vk::ComponentSwizzle::eIdentity, + vk::ComponentSwizzle::eIdentity, + vk::ComponentSwizzle::eIdentity, + vk::ComponentSwizzle::eIdentity}, + {vk::ImageAspectFlagBits::eColor, + 0, 1, 0, 1}); app.swapchainImageViews.push_back(app.device.createImageView(createInfo)); } } -void printDeviceCapabilities(vk::PhysicalDevice& pDevice) { +void printDeviceCapabilities(vk::PhysicalDevice &pDevice) { //vk::PhysicalDeviceFeatures features = physicalDevice.getFeatures(); std::vector<vk::ExtensionProperties> ext = pDevice.enumerateDeviceExtensionProperties(); std::vector<vk::LayerProperties> layers = pDevice.enumerateDeviceLayerProperties(); @@ -620,18 +608,18 @@ void printDeviceCapabilities(vk::PhysicalDevice& pDevice) { vk::PhysicalDeviceType dt = properties.deviceType; std::cout << "====================" << std::endl - << "Device Name: " << properties.deviceName << std::endl - << "Device ID: " << properties.deviceID << std::endl - << "Device Type: " << vk::to_string(properties.deviceType) << std::endl - << "Driver Version: " << properties.driverVersion << std::endl - << "API Version: " << properties.apiVersion << std::endl - << "====================" << std::endl - << std::endl; + << "Device Name: " << properties.deviceName << std::endl + << "Device ID: " << properties.deviceID << std::endl + << "Device Type: " << vk::to_string(properties.deviceType) << std::endl + << "Driver Version: " << properties.driverVersion << std::endl + << "API Version: " << properties.apiVersion << std::endl + << "====================" << std::endl + << std::endl; bool budgetExt = false; bool diagExt = false; std::cout << "This device supports the following extensions (" << ext.size() << "): " << std::endl; - for (vk::ExtensionProperties e : ext) { + for (vk::ExtensionProperties e: ext) { std::cout << std::string(e.extensionName.data()) << std::endl; if (std::string(e.extensionName.data()) == VK_EXT_MEMORY_BUDGET_EXTENSION_NAME) budgetExt = true; @@ -639,10 +627,9 @@ void printDeviceCapabilities(vk::PhysicalDevice& pDevice) { diagExt = true; } - std::cout << "This device supports the following memory types (" << memoryProperties.memoryTypeCount << "): " << - std::endl; + std::cout << "This device supports the following memory types (" << memoryProperties.memoryTypeCount << "): " << std::endl; uint32_t c = 0U; - for (vk::MemoryType e : memoryProperties.memoryTypes) { + for (vk::MemoryType e: memoryProperties.memoryTypes) { if (c > memoryProperties.memoryTypeCount) break; @@ -651,12 +638,12 @@ void printDeviceCapabilities(vk::PhysicalDevice& pDevice) { c++; } std::cout << "====================" << std::endl - << std::endl; + << std::endl; if (budgetExt) { std::cout << "This device has the following heaps (" << memoryProperties.memoryHeapCount << "): " << std::endl; c = 0U; - for (vk::MemoryHeap e : memoryProperties.memoryHeaps) { + for (vk::MemoryHeap e: memoryProperties.memoryHeaps) { if (c > memoryProperties.memoryHeapCount) break; @@ -667,12 +654,12 @@ void printDeviceCapabilities(vk::PhysicalDevice& pDevice) { } std::cout << "====================" << std::endl - << std::endl - << "This device has the following layers (" << layers.size() << "): " << std::endl; - for (vk::LayerProperties l : layers) + << std::endl + << "This device has the following layers (" << layers.size() << "): " << std::endl; + for (vk::LayerProperties l: layers) std::cout << std::string(l.layerName.data()) << "\t : " << std::string(l.description.data()) << std::endl; std::cout << "====================" << std::endl - << std::endl; + << std::endl; showAvailableQueues(pDevice, diagExt); } diff --git a/src/main.cpp b/src/main.cpp index 4920964a6b552e208cb8f6302db61dea5abadb84..079b815d2d227ca0619ea2f026976a5851a61106 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,20 +2,20 @@ #define GLM_FORCE_RADIANS #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 -#include <iostream> #include <cstdlib> +#include <iostream> -#include <vulkan/vulkan.hpp> -#include <vector> #include "initialization.h" #include "utils.h" #include <GLFW/glfw3.h> #include <thread> +#include <vector> +#include <vulkan/vulkan.hpp> #include "project.h" -#include "renderdoc.h" #include "render.h" +#include "renderdoc.h" #include "simulation.h" int width = 1200; @@ -26,7 +26,7 @@ void render() { renderdoc::startCapture(); Render render(resources, 2); - SimulationParameters parameters { "../scenes/default.yaml" }; + SimulationParameters parameters {"../scenes/default.yaml"}; Simulation simulation(parameters, render.camera); renderdoc::endCapture(); @@ -69,12 +69,10 @@ int main() { catch (vk::SystemError& err) { std::cout << "vk::SystemError: " << err.what() << std::endl; exit(-1); - } - catch (std::exception& err) { + } catch (std::exception &err) { std::cout << "std::exception: " << err.what() << std::endl; exit(-1); - } - catch (...) { + } catch (...) { std::cout << "unknown error/n"; exit(-1); } diff --git a/src/obj.cpp b/src/obj.cpp index 89829f22383f9d4440fcb4b1e11948694d3fb85a..e57d0444b5d8c437dbe0f3491131c3192ffe8233 100644 --- a/src/obj.cpp +++ b/src/obj.cpp @@ -1,2 +1,2 @@ -#define TINYOBJLOADER_IMPLEMENTATION +#define TINYOBJLOADER_IMPLEMENTATION #include "tiny_obj_loader.h" diff --git a/src/parameters.cpp b/src/parameters.cpp index 59e37cf95adfb82c457ee5c0ab57c92d8ff3f17c..61cdfe3bb7c10f925a4d43ca34fe6e8b39a2a4d7 100644 --- a/src/parameters.cpp +++ b/src/parameters.cpp @@ -1,15 +1,15 @@ #include "simulation_parameters.h" -#include <yaml-cpp/yaml.h> -#include <stdexcept> #include <random> +#include <stdexcept> +#include <yaml-cpp/yaml.h> -template <typename T> +template<typename T> T parseEnum(const YAML::Node &yaml, const std::string &key, std::initializer_list<std::pair<std::string, T>> mappings) { if (!yaml[key]) return mappings.begin()->second; - for (const auto& [k, v] : mappings) { + for (const auto &[k, v]: mappings) { if (k == yaml[key].as<std::string>()) return v; } @@ -19,16 +19,16 @@ T parseEnum(const YAML::Node &yaml, const std::string &key, std::initializer_lis throw std::invalid_argument(oss.str()); } -template <typename T> +template<typename T> std::string dumpEnum(const T &value, std::initializer_list<std::pair<std::string, T>> mappings) { - for (const auto& [k, v] : mappings) + for (const auto &[k, v]: mappings) if (value == v) return k; throw std::invalid_argument("No mapping for enum value"); } -template <typename T> +template<typename T> T parse(const YAML::Node &yaml, const std::string &key, const T defaultValue) { if (!yaml[key]) return defaultValue; @@ -37,22 +37,18 @@ T parse(const YAML::Node &yaml, const std::string &key, const T defaultValue) { } const Mappings<SceneType> sceneTypeMappings { - { "sph_box_2d", SceneType::SPH_BOX_2D } -}; + {"sph_box_2d", SceneType::SPH_BOX_2D}}; const Mappings<InitializationFunction> initializationFunctionMappings { - { "uniform", InitializationFunction::UNIFORM }, - { "poisson_disk", InitializationFunction::POISSON_DISK } -}; + {"uniform", InitializationFunction::UNIFORM}, + {"poisson_disk", InitializationFunction::POISSON_DISK}}; const Mappings<SelectedImage> selectedImageMappings { - { "render", SelectedImage::RENDER }, - { "debug_physics", SelectedImage::DEBUG_PHYSICS }, - { "debug_sort", SelectedImage::DEBUG_SORT }, - { "debug_renderer", SelectedImage::DEBUG_RENDERER } -}; + {"render", SelectedImage::RENDER}, + {"debug_physics", SelectedImage::DEBUG_PHYSICS}, + {"debug_sort", SelectedImage::DEBUG_SORT}, + {"debug_renderer", SelectedImage::DEBUG_RENDERER}}; const Mappings<RenderBackgroundField> renderBackgroundFieldMappings { - { "cell_hash", RenderBackgroundField::CELL_HASH }, - { "density", RenderBackgroundField::DENSITY } -}; + {"cell_hash", RenderBackgroundField::CELL_HASH}, + {"density", RenderBackgroundField::DENSITY}}; SimulationParameters::SimulationParameters(const std::string &file) { YAML::Node yaml = YAML::LoadFile(file); @@ -63,8 +59,11 @@ SimulationParameters::SimulationParameters(const std::string &file) { initializationFunctionMappings); numParticles = parse<uint32_t>(yaml, "num_particles", numParticles); - std::random_device rd; // seed with TRNG if no seed is supplied + std::random_device rd;// seed with TRNG if no seed is supplied randomSeed = parse<uint32_t>(yaml, "random_seed", rd()); + gravity = parse<float>(yaml, "gravity", gravity); + deltaTime = parse<float>(yaml, "delta_time", deltaTime); + collisionDampingFactor = parse<float>(yaml, "collision_damping_factor", collisionDampingFactor); } std::string SimulationParameters::printToYaml() const { diff --git a/src/particle_physics.cpp b/src/particle_physics.cpp index 3ffa99ae74cea5e669bd1b4ff2e76d21fca982f1..71808228dee81f8ea0ced582f2bb5fb10efe7cad 100644 --- a/src/particle_physics.cpp +++ b/src/particle_physics.cpp @@ -1,5 +1,76 @@ #include "particle_physics.h" -vk::CommandBuffer ParticleSimulation::run() { - return nullptr; + +ParticleSimulation::ParticleSimulation(const SimulationParameters ¶meters) : simulationParameters(parameters) { + // 0 for coordinates, 1 for velocities + Cmn::addStorage(classResources.bindings, 0); + Cmn::addStorage(classResources.bindings, 1); + + Cmn::createDescriptorSetLayout(resources.device, classResources.bindings, classResources.descriptorSetLayout); + Cmn::createDescriptorPool(resources.device, classResources.bindings, classResources.descriptorPool); + Cmn::allocateDescriptorSet(resources.device, classResources.descriptorSet, classResources.descriptorPool, classResources.descriptorSetLayout); + + vk::PushConstantRange pcr({vk::ShaderStageFlagBits::eCompute}, 0, sizeof(PushStruct)); + vk::PipelineLayoutCreateInfo pipelineLayoutInfo({}, classResources.descriptorSetLayout, pcr); + + classResources.pipelineLayout = resources.device.createPipelineLayout(pipelineLayoutInfo); + + vk::ShaderModule particleComputeSM; + Cmn::createShader(resources.device, particleComputeSM, shaderPath("particle_simulation.comp")); + + std::array<vk::SpecializationMapEntry, 2> specEntries = std::array<vk::SpecializationMapEntry, 2> { + vk::SpecializationMapEntry {0U, 0U, sizeof(workgroupSizeX)}, + vk::SpecializationMapEntry {1U, sizeof(workgroupSizeX), sizeof(workgroupSizeY)}}; + std::array<const uint32_t, 2> specValues = {workgroupSizeX, workgroupSizeY}; + vk::SpecializationInfo specInfo(specEntries, vk::ArrayProxyNoTemporaries<const uint32_t>(specValues)); + + Cmn::createPipeline(resources.device, classResources.pipeline, classResources.pipelineLayout, specInfo, particleComputeSM); + + resources.device.destroyShaderModule(particleComputeSM); +} + +void ParticleSimulation::updateCmd(const SimulationState &simulationState) { + if (cmd == nullptr) { + std::cout << "Command buffer is null, allocating new one" << std::endl; + vk::CommandBufferAllocateInfo cmdInfo(resources.computeCommandPool, vk::CommandBufferLevel::ePrimary, 1); + cmd = resources.device.allocateCommandBuffers(cmdInfo)[0]; + } else { + std::cout << "Resetting command buffer" << std::endl; + cmd.reset(); + } + + Cmn::bindBuffers(resources.device, simulationState.particleCoordinateBuffer.buf, classResources.descriptorSet, 0); + Cmn::bindBuffers(resources.device, simulationState.particleVelocityBuffer.buf, classResources.descriptorSet, 1); + uint32_t dx = (simulationState.parameters.numParticles + workgroupSizeX - 1) / workgroupSizeX; + uint32_t dy = 1;// TODO : make this dynamic + + pushStruct.gravity = simulationState.parameters.gravity; + pushStruct.deltaTime = simulationState.parameters.deltaTime; + pushStruct.numParticles = simulationState.parameters.numParticles; + pushStruct.collisionDamping = simulationState.parameters.collisionDampingFactor; + + cmd.begin(vk::CommandBufferBeginInfo()); + + cmd.bindDescriptorSets(vk::PipelineBindPoint::eCompute, classResources.pipelineLayout, 0, classResources.descriptorSet, {}); + cmd.pushConstants(classResources.pipelineLayout, {vk::ShaderStageFlagBits::eCompute}, 0, vk::ArrayProxy<const PushStruct>(pushStruct)); + + // write into spatial-lookup and reset spatial-indices + cmd.bindPipeline(vk::PipelineBindPoint::eCompute, classResources.pipeline); + cmd.dispatch(dx, dy, 1); + cmd.end(); +} + +vk::CommandBuffer ParticleSimulation::run(const SimulationState &simulationState) { + if (nullptr == cmd) { + std::cout << "ParticleSimulation::run called when cmd==NULL, updating the command buffer" << std::endl; + updateCmd(simulationState); + } + + return cmd; +} + + +ParticleSimulation::~ParticleSimulation() { + resources.device.freeCommandBuffers(resources.computeCommandPool, cmd); + classResources.destroy(resources.device); } diff --git a/src/particle_renderer.cpp b/src/particle_renderer.cpp index 90ea2a8456dc7b3b2a7892672f09db7850d7161b..959cd765d83755732d172c41f2cbfee72c5914d8 100644 --- a/src/particle_renderer.cpp +++ b/src/particle_renderer.cpp @@ -20,8 +20,7 @@ ParticleRenderer::ParticleRenderer(const SimulationParameters &simulationParamet vk::SharingMode::eExclusive, 1, &resources.gQ, - vk::ImageLayout::eUndefined - ); + vk::ImageLayout::eUndefined); createImage( resources.pDevice, @@ -30,8 +29,7 @@ ParticleRenderer::ParticleRenderer(const SimulationParameters &simulationParamet {vk::MemoryPropertyFlagBits::eDeviceLocal}, "render-color-attachment", colorAttachment, - colorAttachmentMemory - ); + colorAttachmentMemory); vk::ImageViewCreateInfo viewInfo( {}, @@ -40,8 +38,10 @@ ParticleRenderer::ParticleRenderer(const SimulationParameters &simulationParamet resources.surfaceFormat.format, {}, {{vk::ImageAspectFlagBits::eColor}, - 0, 1, 0, 1} - ); + 0, + 1, + 0, + 1}); colorAttachmentView = resources.device.createImageView(viewInfo); // can be removed later - layout transitions for the color attachment should be handled by render-pass @@ -52,8 +52,7 @@ ParticleRenderer::ParticleRenderer(const SimulationParameters &simulationParamet colorAttachment, resources.surfaceFormat.format, vk::ImageLayout::eUndefined, - vk::ImageLayout::eColorAttachmentOptimal - ); + vk::ImageLayout::eColorAttachmentOptimal); vk::AttachmentDescription colorAttachmentDescription { {}, @@ -64,52 +63,43 @@ ParticleRenderer::ParticleRenderer(const SimulationParameters &simulationParamet vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eColorAttachmentOptimal, - vk::ImageLayout::eColorAttachmentOptimal - }; + vk::ImageLayout::eColorAttachmentOptimal}; vk::AttachmentReference colorAttachmentReference { - 0, vk::ImageLayout::eColorAttachmentOptimal - }; + 0, vk::ImageLayout::eColorAttachmentOptimal}; vk::SubpassDescription subpasses[] { - { // background subpass - {}, - vk::PipelineBindPoint::eGraphics, - {}, - colorAttachmentReference, - {}, - nullptr, - {} - }, - { // particle subpass - {}, - vk::PipelineBindPoint::eGraphics, - {}, - colorAttachmentReference, - {}, - nullptr, - {} - } - }; + {// background subpass + {}, + vk::PipelineBindPoint::eGraphics, + {}, + colorAttachmentReference, + {}, + nullptr, + {}}, + {// particle subpass + {}, + vk::PipelineBindPoint::eGraphics, + {}, + colorAttachmentReference, + {}, + nullptr, + {}}}; vk::SubpassDependency dependencies[] { - { // external dependency - VK_SUBPASS_EXTERNAL, - 0, - { vk::PipelineStageFlagBits::eColorAttachmentOutput }, - { vk::PipelineStageFlagBits::eColorAttachmentOutput }, - { vk::AccessFlagBits::eColorAttachmentWrite }, - { vk::AccessFlagBits::eColorAttachmentWrite } - }, - { - 0, - 1, - { vk::PipelineStageFlagBits::eColorAttachmentOutput }, - { vk::PipelineStageFlagBits::eColorAttachmentOutput }, - { vk::AccessFlagBits::eColorAttachmentWrite }, - { vk::AccessFlagBits::eColorAttachmentWrite } - } - }; + {// external dependency + VK_SUBPASS_EXTERNAL, + 0, + {vk::PipelineStageFlagBits::eColorAttachmentOutput}, + {vk::PipelineStageFlagBits::eColorAttachmentOutput}, + {vk::AccessFlagBits::eColorAttachmentWrite}, + {vk::AccessFlagBits::eColorAttachmentWrite}}, + {0, + 1, + {vk::PipelineStageFlagBits::eColorAttachmentOutput}, + {vk::PipelineStageFlagBits::eColorAttachmentOutput}, + {vk::AccessFlagBits::eColorAttachmentWrite}, + {vk::AccessFlagBits::eColorAttachmentWrite}}}; vk::RenderPassCreateInfo renderPassCI { {}, @@ -118,59 +108,56 @@ ParticleRenderer::ParticleRenderer(const SimulationParameters &simulationParamet 2U, subpasses, 2U, - dependencies - }; + dependencies}; renderPass = resources.device.createRenderPass(renderPassCI); - framebuffer = resources.device.createFramebuffer({ - {}, renderPass, 1, &colorAttachmentView, imageInfo.extent.width, imageInfo.extent.height, imageInfo.extent.depth - }); + framebuffer = resources.device.createFramebuffer({{}, renderPass, 1, &colorAttachmentView, imageInfo.extent.width, imageInfo.extent.height, imageInfo.extent.depth}); createColormapTexture(colormaps::viridis); createPipeline(); // quad vertex buffer const std::vector<glm::vec2> quadVertices { - {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} - }; + {0.0f, 0.0f}, + {1.0f, 0.0f}, + {1.0f, 1.0f}, + {0.0f, 1.0f}}; const std::vector<uint16_t> quadIndices { - 0, 1, 2, 2, 3, 0 - }; + 0, 1, 2, 2, 3, 0}; quadVertexBuffer = createBuffer(resources.pDevice, resources.device, quadVertices.size() * sizeof(glm::vec2), - { vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst }, - { vk::MemoryPropertyFlagBits::eDeviceLocal }, - "quadVertexBuffer"); + {vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst}, + {vk::MemoryPropertyFlagBits::eDeviceLocal}, + "quadVertexBuffer"); quadIndexBuffer = createBuffer(resources.pDevice, resources.device, quadIndices.size() * sizeof(uint16_t), - { vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst }, - { vk::MemoryPropertyFlagBits::eDeviceLocal }, - "quadIndexBuffer"); + {vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst}, + {vk::MemoryPropertyFlagBits::eDeviceLocal}, + "quadIndexBuffer"); fillDeviceWithStagingBuffer(quadVertexBuffer, quadVertices); fillDeviceWithStagingBuffer(quadIndexBuffer, quadIndices); uniformBuffer = createBuffer(resources.pDevice, resources.device, sizeof(UniformBufferStruct), - { vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eTransferDst }, - { vk::MemoryPropertyFlagBits::eDeviceLocal }, - "render2dUniformBuffer"); + {vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eTransferDst}, + {vk::MemoryPropertyFlagBits::eDeviceLocal}, + "render2dUniformBuffer"); - const std::vector<UniformBufferStruct> uniformBufferVector { uniformBufferContent }; + const std::vector<UniformBufferStruct> uniformBufferVector {uniformBufferContent}; fillDeviceWithStagingBuffer(uniformBuffer, uniformBufferVector); } vk::CommandBuffer ParticleRenderer::run(const SimulationState &simulationState, const RenderParameters &renderParameters) { UniformBufferStruct ub { - simulationState.parameters.numParticles, - static_cast<uint32_t>(renderParameters.backgroundField), - renderParameters.particleRadius - }; + simulationState.parameters.numParticles, + static_cast<uint32_t>(renderParameters.backgroundField), + renderParameters.particleRadius}; if (!(ub == uniformBufferContent)) { uniformBufferContent = ub; - const std::vector<UniformBufferStruct> uniformBufferVector { uniformBufferContent }; + const std::vector<UniformBufferStruct> uniformBufferVector {uniformBufferContent}; fillDeviceWithStagingBuffer(uniformBuffer, uniformBufferVector); } @@ -207,21 +194,18 @@ void ParticleRenderer::createPipeline() { 0, vk::DescriptorType::eStorageBuffer, 1U, - vk::ShaderStageFlagBits::eFragment - ); + vk::ShaderStageFlagBits::eFragment); bindings.emplace_back( 1, vk::DescriptorType::eCombinedImageSampler, 1U, vk::ShaderStageFlagBits::eFragment, - nullptr - ); + nullptr); bindings.emplace_back( 2, vk::DescriptorType::eUniformBuffer, 1U, - vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eGeometry - ); + vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eGeometry); Cmn::createDescriptorSetLayout(resources.device, bindings, descriptorSetLayout); Cmn::createDescriptorPool(resources.device, bindings, descriptorPool); @@ -229,16 +213,14 @@ void ParticleRenderer::createPipeline() { vk::PushConstantRange pcr { - vk::ShaderStageFlagBits::eAll, 0, sizeof(PushStruct) - }; + vk::ShaderStageFlagBits::eAll, 0, sizeof(PushStruct)}; vk::PipelineLayoutCreateInfo pipelineLayoutCI { vk::PipelineLayoutCreateFlags(), 1U, &descriptorSetLayout, 1U, - &pcr - }; + &pcr}; particlePipelineLayout = resources.device.createPipelineLayout(pipelineLayoutCI); @@ -246,57 +228,57 @@ void ParticleRenderer::createPipeline() { /* =============================== Common Resources =============================== */ // Viewport & Scissor const vk::Viewport viewport = { - 0.f, // x start coordinate - (float)resources.extent.height, // y start coordinate - (float)resources.extent.width, // Width of viewport - -(float)resources.extent.height, // Height of viewport - 0.f, // Min framebuffer depth, - 1.f // Max framebuffer depth + 0.f, // x start coordinate + (float) resources.extent.height, // y start coordinate + (float) resources.extent.width, // Width of viewport + -(float) resources.extent.height,// Height of viewport + 0.f, // Min framebuffer depth, + 1.f // Max framebuffer depth }; const vk::Rect2D scissor = { - {0, 0}, // Offset to use region from - resources.extent // Extent to describe region to use, starting at offset + {0, 0}, // Offset to use region from + resources.extent// Extent to describe region to use, starting at offset }; const vk::PipelineViewportStateCreateInfo viewportSCI = { {}, - 1, // Viewport count - &viewport, // Viewport used - 1, // Scissor count - &scissor // Scissor used + 1, // Viewport count + &viewport,// Viewport used + 1, // Scissor count + &scissor // Scissor used }; // Rasterizer const vk::PipelineRasterizationStateCreateInfo rasterizationSCI = { {}, - false, // Change if fragments beyond near/far planes are clipped (default) or clamped to plane + false,// Change if fragments beyond near/far planes are clipped (default) or clamped to plane false, // Whether to discard data and skip rasterizer. Never creates fragments, only suitable for pipeline without framebuffer output - vk::PolygonMode::eFill, // How to handle filling points between vertices - vk::CullModeFlagBits::eBack, // Which face of a tri to cull - vk::FrontFace::eCounterClockwise, // Winding to determine which side is front - false, // Whether to add depth bias to fragments (good for stopping "shadow acne" in shadow mapping) + vk::PolygonMode::eFill, // How to handle filling points between vertices + vk::CullModeFlagBits::eBack, // Which face of a tri to cull + vk::FrontFace::eCounterClockwise,// Winding to determine which side is front + false, // Whether to add depth bias to fragments (good for stopping "shadow acne" in shadow mapping) 0.f, 0.f, 0.f, - 1.f // How thick lines should be when drawn + 1.f// How thick lines should be when drawn }; const vk::PipelineMultisampleStateCreateInfo multisampleSCI = { {}, - vk::SampleCountFlagBits::e1, // Number of samples to use per fragment - false, // Enable multisample shading or not + vk::SampleCountFlagBits::e1,// Number of samples to use per fragment + false, // Enable multisample shading or not 0.f, nullptr, false, - false - }; + false}; // Depth stencil creation const vk::PipelineDepthStencilStateCreateInfo depthStencilSCI = { - {}, vk::False -// {}, vk::True, vk::False, vk::CompareOp::eAlways, vk::False, vk::False, {}, {}, 0.0f, 0.0f -// {}, true, false, vk::CompareOp::eLess, false, false, {}, {}, 0.f, 0.f + {}, + vk::False + // {}, vk::True, vk::False, vk::CompareOp::eAlways, vk::False, vk::False, {}, {}, 0.0f, 0.0f + // {}, true, false, vk::CompareOp::eLess, false, false, {}, {}, 0.f, 0.f }; /* =============================== Particle Pipeline =============================== */ @@ -315,20 +297,18 @@ void ParticleRenderer::createPipeline() { }; vk::VertexInputBindingDescription particleVertexInputBindings[] { - { 0, 2 * 4, vk::VertexInputRate::eVertex } - }; + {0, 2 * 4, vk::VertexInputRate::eVertex}}; vk::VertexInputAttributeDescription particleVertexInputAttributeDescriptions[] { - { 0, 0, vk::Format::eR32G32Sfloat, 0 } - }; -// + {0, 0, vk::Format::eR32G32Sfloat, 0}}; + // // Vertex input vk::PipelineVertexInputStateCreateInfo particleVertexInputSCI { {}, - 1, // Vertex binding description count - particleVertexInputBindings, // List of Vertex Binding Descriptions (data spacing/stride information) - 1, // Vertex attribute description count - particleVertexInputAttributeDescriptions // List of Vertex Attribute Descriptions (data format and where to bind to/from) + 1, // Vertex binding description count + particleVertexInputBindings, // List of Vertex Binding Descriptions (data spacing/stride information) + 1, // Vertex attribute description count + particleVertexInputAttributeDescriptions// List of Vertex Attribute Descriptions (data format and where to bind to/from) }; vk::PipelineInputAssemblyStateCreateInfo particleInputAssemblySCI { @@ -347,8 +327,7 @@ void ParticleRenderer::createPipeline() { vk::BlendFactor::eZero, vk::BlendOp::eAdd, vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | - vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA - }; + vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; vk::PipelineColorBlendStateCreateInfo particleColorBlendSCI { {}, @@ -356,8 +335,7 @@ void ParticleRenderer::createPipeline() { {}, 1, &particleColorBlendAttachmentState, - {} - }; + {}}; vk::GraphicsPipelineCreateInfo particlePipelineCI { {}, @@ -374,10 +352,9 @@ void ParticleRenderer::createPipeline() { nullptr, particlePipelineLayout, renderPass, - 1, // subpass + 1,// subpass {}, - 0 - }; + 0}; /* =============================== Background Pipeline =============================== */ vk::ShaderModule backgroundVertexSM, backgroundFragmentSM; @@ -394,19 +371,17 @@ void ParticleRenderer::createPipeline() { vk::VertexInputBindingDescription backgroundVertexInputBindings[] { - { 0, 2 * 4, vk::VertexInputRate::eVertex } - }; + {0, 2 * 4, vk::VertexInputRate::eVertex}}; vk::VertexInputAttributeDescription backgroundVertexInputAttributeDescriptions[] { - { 0, 0, vk::Format::eR32G32Sfloat, 0 } - }; + {0, 0, vk::Format::eR32G32Sfloat, 0}}; vk::PipelineVertexInputStateCreateInfo backgroundVertexInputSCI { {}, - 1, // Vertex binding description count - backgroundVertexInputBindings, // List of Vertex Binding Descriptions (data spacing/stride information) - 1, // Vertex attribute description count - backgroundVertexInputAttributeDescriptions // List of Vertex Attribute Descriptions (data format and where to bind to/from) + 1, // Vertex binding description count + backgroundVertexInputBindings, // List of Vertex Binding Descriptions (data spacing/stride information) + 1, // Vertex attribute description count + backgroundVertexInputAttributeDescriptions// List of Vertex Attribute Descriptions (data format and where to bind to/from) }; vk::PipelineInputAssemblyStateCreateInfo backgroundInputAssemblySCI { @@ -427,16 +402,15 @@ void ParticleRenderer::createPipeline() { &rasterizationSCI, &multisampleSCI, &depthStencilSCI, - &particleColorBlendSCI, // TODO + &particleColorBlendSCI,// TODO nullptr, particlePipelineLayout, renderPass, - 0, // subpass + 0,// subpass {}, - 0 - }; + 0}; - auto pipelines = resources.device.createGraphicsPipelines(VK_NULL_HANDLE, { backgroundPipelineCI, particlePipelineCI }); + auto pipelines = resources.device.createGraphicsPipelines(VK_NULL_HANDLE, {backgroundPipelineCI, particlePipelineCI}); if (pipelines.result != vk::Result::eSuccess) throw std::runtime_error("Pipeline creation failed"); @@ -453,7 +427,7 @@ void ParticleRenderer::createPipeline() { void ParticleRenderer::createColormapTexture(const std::vector<colormaps::RGB_F32> &colormap) { auto imageFormat = vk::Format::eR8G8B8A8Unorm; - vk::Extent3D imageExtent = { static_cast<uint32_t>(colormap.size()), 1, 1 }; + vk::Extent3D imageExtent = {static_cast<uint32_t>(colormap.size()), 1, 1}; vk::ImageCreateInfo imageCI { {}, @@ -464,7 +438,7 @@ void ParticleRenderer::createColormapTexture(const std::vector<colormaps::RGB_F3 1, vk::SampleCountFlagBits::e1, vk::ImageTiling::eOptimal, - { vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst }, + {vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst}, vk::SharingMode::eExclusive, 1, &resources.gQ, @@ -475,11 +449,10 @@ void ParticleRenderer::createColormapTexture(const std::vector<colormaps::RGB_F3 resources.pDevice, resources.device, imageCI, - { vk::MemoryPropertyFlagBits::eDeviceLocal }, + {vk::MemoryPropertyFlagBits::eDeviceLocal}, "colormapTexture", colormapImage, - colormapImageMemory - ); + colormapImageMemory); vk::ImageViewCreateInfo viewCI { {}, @@ -487,23 +460,21 @@ void ParticleRenderer::createColormapTexture(const std::vector<colormaps::RGB_F3 vk::ImageViewType::e1D, imageFormat, {}, - {{ vk::ImageAspectFlagBits::eColor }, 0, 1, 0, 1 } - }; + {{vk::ImageAspectFlagBits::eColor}, 0, 1, 0, 1}}; colormapImageView = resources.device.createImageView(viewCI); struct RGBA_int8 { uint8_t r, g, b, a; }; - std::vector<RGBA_int8> converted { colormap.size(), { 0, 0, 0} }; + std::vector<RGBA_int8> converted {colormap.size(), {0, 0, 0}}; for (size_t i = 0; i < colormap.size(); i++) { auto &c = colormap[i]; converted[i] = { static_cast<uint8_t>(c.r * 256.0f), static_cast<uint8_t>(c.g * 256.0f), static_cast<uint8_t>(c.b * 256.0f), - 255 - }; + 255}; } fillImageWithStagingBuffer(colormapImage, vk::ImageLayout::eShaderReadOnlyOptimal, imageExtent, converted); @@ -524,8 +495,7 @@ void ParticleRenderer::createColormapTexture(const std::vector<colormaps::RGB_F3 0, 0, vk::BorderColor::eFloatOpaqueBlack, - vk::False - }; + vk::False}; colormapSampler = resources.device.createSampler(samplerCI); } @@ -539,8 +509,7 @@ void ParticleRenderer::updateDescriptorSets(const SimulationState &simulationSta void ParticleRenderer::updateCmd(const SimulationState &simulationState) { if (commandBuffer == nullptr) commandBuffer = resources.device.allocateCommandBuffers( - { resources.graphicsCommandPool, vk::CommandBufferLevel::ePrimary, 1U } - )[0]; + {resources.graphicsCommandPool, vk::CommandBufferLevel::ePrimary, 1U})[0]; else commandBuffer.reset(); @@ -553,12 +522,12 @@ void ParticleRenderer::updateCmd(const SimulationState &simulationState) { pushStruct.mvp = simulationState.camera->viewProjectionMatrix(); commandBuffer.begin(vk::CommandBufferBeginInfo {}); - uint64_t offsets[] = { 0UL }; + uint64_t offsets[] = {0UL}; vk::ClearValue clearValue; - clearValue.color.uint32 = {{ 0, 0, 0, 0 }}; + clearValue.color.uint32 = {{0, 0, 0, 0}}; commandBuffer.beginRenderPass( - { renderPass, framebuffer, {{ 0, 0}, resources.extent }, 1, &clearValue}, + {renderPass, framebuffer, {{0, 0}, resources.extent}, 1, &clearValue}, vk::SubpassContents::eInline); /* ========== Background Subpass ========== */ commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, backgroundPipeline); @@ -567,7 +536,7 @@ void ParticleRenderer::updateCmd(const SimulationState &simulationState) { commandBuffer.pushConstants(particlePipelineLayout, vk::ShaderStageFlagBits::eAll, 0, sizeof(PushStruct), &pushStruct); commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, particlePipelineLayout, 0, 1, &descriptorSet, 0, nullptr); - commandBuffer.drawIndexed(6, 1, 0, 0, 0); // draw quad + commandBuffer.drawIndexed(6, 1, 0, 0, 0);// draw quad /* ========== Particle Subpass ========== */ commandBuffer.nextSubpass(vk::SubpassContents::eInline); diff --git a/src/particles.cpp b/src/particles.cpp index 3f73feb0bb171bb53bac2b973f74dc625682f507..85e5b4cccf9b6f44aea6515a19a5798c3ee90159 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -1,29 +1,26 @@ -#include "project.h" #include "host_timer.h" +#include "project.h" -ProjectSolution::ProjectSolution(AppResources& app, ProjectData& datad, uint32_t workGroupSize_x, - uint32_t triangleCacheSize) : - app(app), data(datad), workGroupSize_x(workGroupSize_x), triangleCacheSize(triangleCacheSize) { +ProjectSolution::ProjectSolution(AppResources &app, ProjectData &datad, uint32_t workGroupSize_x, + uint32_t triangleCacheSize) : app(app), data(datad), workGroupSize_x(workGroupSize_x), triangleCacheSize(triangleCacheSize) { if (triangleCacheSize % 3 != 0) throw std::runtime_error("error: trangleCacheSize must be divisible by 3 or 0"); - // ########## Setup Integrate ############ + // ########## Setup Integrate ############ app.device.destroyShaderModule(particleShader); std::string compute = workingDir + "build/shaders/particles.comp.spv"; Cmn::createShader(app.device, particleShader, compute); // ### Create Pipeline ### - std::array<vk::SpecializationMapEntry, 3> specEntries = std::array<vk::SpecializationMapEntry, 3>{ - vk::SpecializationMapEntry{0U, 0U, sizeof(int)}, - vk::SpecializationMapEntry{1U, sizeof(int), sizeof(int)}, - vk::SpecializationMapEntry{2U, 2 * sizeof(int), sizeof(int)} - }; + std::array<vk::SpecializationMapEntry, 3> specEntries = std::array<vk::SpecializationMapEntry, 3> { + vk::SpecializationMapEntry {0U, 0U, sizeof(int)}, + vk::SpecializationMapEntry {1U, sizeof(int), sizeof(int)}, + vk::SpecializationMapEntry {2U, 2 * sizeof(int), sizeof(int)}}; std::array<int, 3> specValues = { - int(workGroupSize_x), - int(data.particleCount), - int(data.triangleCount) - }; //for workgroup sizes + int(workGroupSize_x), + int(data.particleCount), + int(data.triangleCount)};//for workgroup sizes vk::SpecializationInfo specInfo = vk::SpecializationInfo(CAST(specEntries), specEntries.data(), CAST(specValues) * sizeof(int), specValues.data()); @@ -37,7 +34,7 @@ ProjectSolution::ProjectSolution(AppResources& app, ProjectData& datad, uint32_t particlePipeline = app.device.createComputePipeline(nullptr, computeInfo, nullptr).value; vk::CommandBufferAllocateInfo allocInfo( - app.computeCommandPool, vk::CommandBufferLevel::ePrimary, 1U); + app.computeCommandPool, vk::CommandBufferLevel::ePrimary, 1U); cb = app.device.allocateCommandBuffers(allocInfo)[0]; setObjectName(app.device, cb, "particleComputeCommandBuffer"); } @@ -65,14 +62,14 @@ void ProjectSolution::compute() { cb.end(); // submit the command buffer to the queue and set up a fence. - vk::SubmitInfo submitInfo = vk::SubmitInfo(0, nullptr, nullptr, 1, &cb); // submit a single command buffer + vk::SubmitInfo submitInfo = vk::SubmitInfo(0, nullptr, nullptr, 1, &cb);// submit a single command buffer vk::Fence fence = app.device.createFence(vk::FenceCreateInfo()); // fence makes sure the control is not returned to CPU till command buffer is depleted app.computeQueue.submit({submitInfo}, fence); HostTimer timer; - vk::Result haveIWaited = app.device.waitForFences({fence}, true, uint64_t(-1)); // wait for the fence indefinitely + vk::Result haveIWaited = app.device.waitForFences({fence}, true, uint64_t(-1));// wait for the fence indefinitely app.device.destroyFence(fence); mstime = timer.elapsed() * 1000; diff --git a/src/project.cpp b/src/project.cpp index 1a8f8d1a9124249039122af9bacc80d5612ae75b..673aa1a10133227abb04f6f3969290b2e8fc7f82 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -1,19 +1,19 @@ #include "project.h" -#include <iostream> #include <cstdlib> +#include <iostream> #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 -#include <vulkan/vulkan.hpp> -#include <fstream> -#include <vector> -#include "initialization.h" -#include "utils.h" -#include "task_common.h" #include "host_timer.h" +#include "initialization.h" #include "stb_image_write.h" +#include "task_common.h" +#include "utils.h" +#include <fstream> +#include <vector> +#include <vulkan/vulkan.hpp> -Project::Project(AppResources& app, Render& render, const uint32_t particleCount, +Project::Project(AppResources &app, Render &render, const uint32_t particleCount, std::string objName) : app(app), render(app, render) { data.NUM_FORCE_LINES = 100; data.particleCount = particleCount; @@ -28,13 +28,13 @@ Project::Project(AppResources& app, Render& render, const uint32_t particleCount data.triangleCount = tSoup.size() / 3; - Cmn::addStorage(data.bindings, 0); // gAlive - Cmn::addStorage(data.bindings, 1); // gPosLife - Cmn::addStorage(data.bindings, 2); // gVelMass - Cmn::addStorage(data.bindings, 3); // gTriangleSoup - Cmn::addCombinedImageSampler(data.bindings, 4); // texture sampler - Cmn::addStorage(data.bindings, 5); // gNormals - Cmn::addStorage(data.bindings, 6); // gForceLines + Cmn::addStorage(data.bindings, 0); // gAlive + Cmn::addStorage(data.bindings, 1); // gPosLife + Cmn::addStorage(data.bindings, 2); // gVelMass + Cmn::addStorage(data.bindings, 3); // gTriangleSoup + Cmn::addCombinedImageSampler(data.bindings, 4);// texture sampler + Cmn::addStorage(data.bindings, 5); // gNormals + Cmn::addStorage(data.bindings, 6); // gForceLines Cmn::createDescriptorSetLayout(app.device, data.bindings, data.descriptorSetLayout); @@ -56,7 +56,7 @@ Project::Project(AppResources& app, Render& render, const uint32_t particleCount data.gForceLines = makeDLocalBuffer(BFlag::eTransferDst | BFlag::eStorageBuffer, pForce.size() * sizeof(float) * 4, "gForceLines"); - initParticles(); // fills gAlive, gPosLife and gVelMass + initParticles();// fills gAlive, gPosLife and gVelMass fillDeviceWithStagingBuffer(app.pDevice, app.device, app.transferCommandPool, app.transferQueue, data.gTriangleSoup, tSoup); fillDeviceWithStagingBuffer(app.pDevice, app.device, app.transferCommandPool, app.transferQueue, data.gNormals, @@ -85,7 +85,7 @@ Project::Project(AppResources& app, Render& render, const uint32_t particleCount } -void Project::loop(ProjectSolution& solution) { +void Project::loop(ProjectSolution &solution) { solution.compute(); render.renderFrame(data); } @@ -102,7 +102,7 @@ void Project::cleanup() { app.device.destroyDescriptorSetLayout(data.descriptorSetLayout); data.bindings.clear(); - auto Bclean = [&](Buffer& b) { + auto Bclean = [&](Buffer &b) { app.device.destroyBuffer(b.buf); app.device.freeMemory(b.mem); }; diff --git a/src/renderdoc.cpp b/src/renderdoc.cpp index 53f08bd342d58dd14637a101c9527f17c9ac4da7..554edfc6ec1aef7f44e7d3e4135502c755b770c8 100644 --- a/src/renderdoc.cpp +++ b/src/renderdoc.cpp @@ -3,48 +3,48 @@ #include <cassert> #ifdef ENABLE_RENDERDOC - #include "renderdoc_app.h" +#include "renderdoc_app.h" - #ifdef _WIN32 - #include <windows.h> - #elif __linux__ - #include <dlfcn.h> - #endif +#ifdef _WIN32 +#include <windows.h> +#elif __linux__ +#include <dlfcn.h> +#endif - static RENDERDOC_API_1_1_2 *rdoc_api = NULL; +static RENDERDOC_API_1_1_2 *rdoc_api = nullptr; #endif namespace renderdoc { - void initialize() { - #ifdef ENABLE_RENDERDOC - pRENDERDOC_GetAPI RENDERDOC_GetAPI = nullptr; - - #ifdef _WIN32 - if(HMODULE mod = GetModuleHandleA("renderdoc.dll")) - RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI"); - #elif __linux__ - if(void *mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD)) - RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI"); - #endif - - if (RENDERDOC_GetAPI != nullptr) { - int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **)&rdoc_api); - assert(ret == 1); - } - #endif - } +void initialize() { +#ifdef ENABLE_RENDERDOC + pRENDERDOC_GetAPI RENDERDOC_GetAPI = nullptr; + +#ifdef _WIN32 + if (HMODULE mod = GetModuleHandleA("renderdoc.dll")) + RENDERDOC_GetAPI = (pRENDERDOC_GetAPI) GetProcAddress(mod, "RENDERDOC_GetAPI"); +#elif __linux__ + if (void *mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD)) + RENDERDOC_GetAPI = (pRENDERDOC_GetAPI) dlsym(mod, "RENDERDOC_GetAPI"); +#endif - void startCapture() { - #ifdef ENABLE_RENDERDOC - if (rdoc_api) - rdoc_api->StartFrameCapture(NULL, NULL); - #endif + if (RENDERDOC_GetAPI != nullptr) { + int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **) &rdoc_api); + assert(ret == 1); } +#endif +} - void endCapture() { - #ifdef ENABLE_RENDERDOC - if (rdoc_api) - rdoc_api->EndFrameCapture(NULL, NULL); - #endif - } +void startCapture() { +#ifdef ENABLE_RENDERDOC + if (rdoc_api) + rdoc_api->StartFrameCapture(nullptr, nullptr); +#endif +} + +void endCapture() { +#ifdef ENABLE_RENDERDOC + if (rdoc_api) + rdoc_api->EndFrameCapture(nullptr, nullptr); +#endif } +}// namespace renderdoc diff --git a/src/renderer.cpp b/src/renderer.cpp index 7c0c8d0c63f58dba01917d256b4b54cc30402ab1..b8241d146d18b9af3258cbdbd14a0acfea6e5b4b 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -21,7 +21,7 @@ Renderer2D::Renderer2D() { shaderStageCI, }; - auto pipelines = resources.device.createGraphicsPipelines(VK_NULL_HANDLE, { particlePipelineCI}); + auto pipelines = resources.device.createGraphicsPipelines(VK_NULL_HANDLE, {particlePipelineCI}); if (pipelines.result != vk::Result::eSuccess) throw std::runtime_error("Pipeline creation failed"); @@ -29,7 +29,6 @@ Renderer2D::Renderer2D() { } Renderer2D::~Renderer2D() { - } vk::CommandBuffer Renderer2D::run(const SimulationState &state) { @@ -37,11 +36,9 @@ vk::CommandBuffer Renderer2D::run(const SimulationState &state) { } Renderer::Renderer() : renderer2D() { - } Renderer::~Renderer() { - } vk::CommandBuffer Renderer::run(const SimulationState &state) { diff --git a/src/simulation.cpp b/src/simulation.cpp index fcda734cfb146f07593cdaa5912a2099d38504f1..706650c8c89638afe076a69b6d3b7607dfe00a6e 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -1,15 +1,15 @@ #include "simulation.h" -#include "particle_renderer.h" +#include "debug_image.h" #include "particle_physics.h" -#include "spatial_lookup.h" +#include "particle_renderer.h" #include "render.h" -#include "debug_image.h" +#include "spatial_lookup.h" Simulation::Simulation(const SimulationParameters ¶meters, std::shared_ptr<Camera> camera) -: simulationParameters(parameters), simulationState(std::make_unique<SimulationState>(parameters, std::move(camera))) { + : simulationParameters(parameters), simulationState(std::make_unique<SimulationState>(parameters, std::move(camera))) { - particlePhysics = std::make_unique<ParticleSimulation>(); + particlePhysics = std::make_unique<ParticleSimulation>(simulationParameters); hashGrid = std::make_unique<SpatialLookup>(simulationParameters); imguiUi = std::make_unique<ImguiUi>(); particleRenderer = std::make_unique<ParticleRenderer>(simulationParameters); @@ -21,9 +21,9 @@ Simulation::Simulation(const SimulationParameters ¶meters, std::shared_ptr<C cmdReset = allocated[1]; cmdReset.begin(vk::CommandBufferBeginInfo()); - simulationState->debugImagePhysics->clear(cmdReset, { 1, 0, 0, 1 }); - simulationState->debugImageSort->clear(cmdReset, { 0, 1, 0, 1 }); - simulationState->debugImageRenderer->clear(cmdReset, { 0, 0, 1, 1 }); + simulationState->debugImagePhysics->clear(cmdReset, {1, 0, 0, 1}); + simulationState->debugImageSort->clear(cmdReset, {0, 1, 0, 1}); + simulationState->debugImageRenderer->clear(cmdReset, {0, 0, 1, 1}); cmdReset.end(); cmdEmpty = allocated[2]; @@ -32,7 +32,6 @@ Simulation::Simulation(const SimulationParameters ¶meters, std::shared_ptr<C } - vk::Semaphore Simulation::initSemaphore() { if (nullptr != timelineSemaphore) { resources.device.destroySemaphore(timelineSemaphore); @@ -59,8 +58,8 @@ void Simulation::run(uint32_t imageIndex, vk::Semaphore waitImageAvailable, vk:: timelineSemaphore = initSemaphore(); - UiBindings uiBindings { imageIndex, simulationParameters, renderParameters, simulationState.get() }; - std::array<std::tuple<vk::Queue,vk::CommandBuffer>,cmd_count> buffers; + UiBindings uiBindings {imageIndex, simulationParameters, renderParameters, simulationState.get()}; + std::array<std::tuple<vk::Queue, vk::CommandBuffer>, cmd_count> buffers; auto imguiCommandBuffer = imguiUi->updateCommandBuffer(imageIndex, uiBindings); lastUpdate = uiBindings.updateFlags; @@ -76,14 +75,14 @@ void Simulation::run(uint32_t imageIndex, vk::Semaphore waitImageAvailable, vk:: bool doTick = simulationState->time.advance(delta); - buffers[0] = { resources.transferQueue, cmdReset }; - buffers[1] = { resources.computeQueue, doTick ? particlePhysics->run() : nullptr }; - buffers[2] = { resources.computeQueue, doTick ? hashGrid->run(*simulationState) : nullptr }; - buffers[3] = { resources.graphicsQueue,particleRenderer->run(*simulationState, renderParameters) }; - buffers[4] = { resources.graphicsQueue, copy(imageIndex) }; - buffers[5] = { resources.graphicsQueue, imguiCommandBuffer }; + buffers[0] = {resources.transferQueue, cmdReset}; + buffers[1] = {resources.computeQueue, doTick ? particlePhysics->run(*simulationState) : nullptr}; + buffers[2] = {resources.computeQueue, doTick ? hashGrid->run(*simulationState) : nullptr}; + buffers[3] = {resources.graphicsQueue, particleRenderer->run(*simulationState, renderParameters)}; + buffers[4] = {resources.graphicsQueue, copy(imageIndex)}; + buffers[5] = {resources.graphicsQueue, imguiCommandBuffer}; - for (uint64_t wait = 0,signal = 1; wait < buffers.size(); ++wait,++signal) { + for (uint64_t wait = 0, signal = 1; wait < buffers.size(); ++wait, ++signal) { auto queue = std::get<0>(buffers[wait]); auto cmd = std::get<1>(buffers[wait]); queue = nullptr == cmd ? resources.transferQueue : queue; @@ -91,36 +90,34 @@ void Simulation::run(uint32_t imageIndex, vk::Semaphore waitImageAvailable, vk:: vk::TimelineSemaphoreSubmitInfo timeline( wait, - signal - ); + signal); - std::array<vk::PipelineStageFlags,1> flags{ vk::PipelineStageFlagBits::eAllCommands }; + std::array<vk::PipelineStageFlags, 1> flags {vk::PipelineStageFlagBits::eAllCommands}; vk::SubmitInfo submit( timelineSemaphore, flags, cmd, timelineSemaphore, - &timeline - ); + &timeline); - if (wait == 0) { // first submit has no dependencies + if (wait == 0) {// first submit has no dependencies submit.waitSemaphoreCount = 0; timeline.waitSemaphoreValueCount = 0; } - if (cmd == cmdCopy) { // copy needs to wait for the swapchain image - auto waitSemaphores = std::array<vk::Semaphore,2> {timelineSemaphore, waitImageAvailable}; - auto waitSemaphoreValues = std::array<uint64_t ,2> {wait, 0}; - auto waitStageFlags = std::array<vk::PipelineStageFlags, 2> {vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eTransfer }; + if (cmd == cmdCopy) {// copy needs to wait for the swapchain image + auto waitSemaphores = std::array<vk::Semaphore, 2> {timelineSemaphore, waitImageAvailable}; + auto waitSemaphoreValues = std::array<uint64_t, 2> {wait, 0}; + auto waitStageFlags = std::array<vk::PipelineStageFlags, 2> {vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eTransfer}; submit.setWaitSemaphores(waitSemaphores); timeline.setWaitSemaphoreValues(waitSemaphoreValues); submit.setWaitDstStageMask(waitStageFlags); } - if (wait == buffers.size() - 1){ // last submit signals submit-finished - auto signalSemaphores = std::array<vk::Semaphore,2> {timelineSemaphore, signalRenderFinished}; - auto signalSemaphoreValues = std::array<uint64_t ,2> {signal, 0}; + if (wait == buffers.size() - 1) {// last submit signals submit-finished + auto signalSemaphores = std::array<vk::Semaphore, 2> {timelineSemaphore, signalRenderFinished}; + auto signalSemaphoreValues = std::array<uint64_t, 2> {signal, 0}; submit.setSignalSemaphores(signalSemaphores); timeline.setSignalSemaphoreValues(signalSemaphoreValues); @@ -151,10 +148,9 @@ void Simulation::run(uint32_t imageIndex, vk::Semaphore waitImageAvailable, vk:: std::vector<SpatialLookupEntry> spatial_lookup_sorted(spatial_lookup.begin(), spatial_lookup.end()); std::sort(spatial_lookup_sorted.begin(), spatial_lookup_sorted.end(), - [](SpatialLookupEntry left,SpatialLookupEntry right)-> bool { return left.cellKey < right.cellKey;} - ); + [](SpatialLookupEntry left, SpatialLookupEntry right) -> bool { return left.cellKey < right.cellKey; }); - for (uint32_t i = 0;i<simulationParameters.numParticles;i++) { + for (uint32_t i = 0; i < simulationParameters.numParticles; i++) { if (spatial_lookup[i].cellKey != spatial_lookup_sorted[i].cellKey) { throw std::runtime_error("spatial lookup not sorted"); } @@ -186,12 +182,12 @@ vk::CommandBuffer Simulation::copy(uint32_t imageIndex) { } auto barrier = [&](vk::Image image, - vk::AccessFlags srcAccessMask, - vk::AccessFlags dstAccessMask, - vk::ImageLayout oldLayout, - vk::ImageLayout newLayout, - vk::PipelineStageFlags srcStageMask, - vk::PipelineStageFlags dstStageMask) { + vk::AccessFlags srcAccessMask, + vk::AccessFlags dstAccessMask, + vk::ImageLayout oldLayout, + vk::ImageLayout newLayout, + vk::PipelineStageFlags srcStageMask, + vk::PipelineStageFlags dstStageMask) { vk::ImageMemoryBarrier barrier( srcAccessMask, dstAccessMask, @@ -200,16 +196,14 @@ vk::CommandBuffer Simulation::copy(uint32_t imageIndex) { VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, image, - {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1} - ); + {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}); cmdCopy.pipelineBarrier( srcStageMask, dstStageMask, {}, nullptr, nullptr, - barrier - ); + barrier); }; cmdCopy.reset(); @@ -224,8 +218,7 @@ vk::CommandBuffer Simulation::copy(uint32_t imageIndex) { vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, vk::PipelineStageFlagBits::eTopOfPipe, - vk::PipelineStageFlagBits::eTransfer - ); + vk::PipelineStageFlagBits::eTransfer); // transition source image to transfer source barrier( @@ -234,25 +227,22 @@ vk::CommandBuffer Simulation::copy(uint32_t imageIndex) { vk::AccessFlagBits::eTransferRead, srcImageLayout, vk::ImageLayout::eTransferSrcOptimal, - vk::PipelineStageFlagBits::eTopOfPipe, - vk::PipelineStageFlagBits::eTransfer - ); + vk::PipelineStageFlagBits::eTopOfPipe, + vk::PipelineStageFlagBits::eTransfer); vk::ImageCopy copy( - { {vk::ImageAspectFlagBits::eColor}, 0,0,1}, + {{vk::ImageAspectFlagBits::eColor}, 0, 0, 1}, {}, - { {vk::ImageAspectFlagBits::eColor}, 0,0,1}, + {{vk::ImageAspectFlagBits::eColor}, 0, 0, 1}, {}, - {resources.extent.width, resources.extent.height, 1} - ); + {resources.extent.width, resources.extent.height, 1}); cmdCopy.copyImage( srcImage, vk::ImageLayout::eTransferSrcOptimal, resources.swapchainImages[imageIndex], vk::ImageLayout::eTransferDstOptimal, - copy - ); + copy); // transition swapchain image to present barrier( @@ -262,8 +252,7 @@ vk::CommandBuffer Simulation::copy(uint32_t imageIndex) { vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::ePresentSrcKHR, vk::PipelineStageFlagBits::eTransfer, - vk::PipelineStageFlagBits::eBottomOfPipe - ); + vk::PipelineStageFlagBits::eBottomOfPipe); // transition source image back to original layout barrier( @@ -273,8 +262,7 @@ vk::CommandBuffer Simulation::copy(uint32_t imageIndex) { vk::ImageLayout::eTransferSrcOptimal, srcImageLayout, vk::PipelineStageFlagBits::eTransfer, - vk::PipelineStageFlagBits::eBottomOfPipe - ); + vk::PipelineStageFlagBits::eBottomOfPipe); cmdCopy.end(); @@ -291,9 +279,9 @@ void Simulation::processUpdateFlags(const UiBindings::UpdateFlags &updateFlags) // debug images are part of the simulation state and used in the cmdReset command buffer // this needs to be rebuilt somewhere before the old state gets deleted, might as well be here cmdReset.begin(vk::CommandBufferBeginInfo()); - newState->debugImagePhysics->clear(cmdReset, { 1, 0, 0, 1 }); - newState->debugImageSort->clear(cmdReset, { 0, 1, 0, 1 }); - newState->debugImageRenderer->clear(cmdReset, { 0, 0, 1, 1 }); + newState->debugImagePhysics->clear(cmdReset, {1, 0, 0, 1}); + newState->debugImageSort->clear(cmdReset, {0, 1, 0, 1}); + newState->debugImageRenderer->clear(cmdReset, {0, 0, 1, 1}); cmdReset.end(); simulationState = std::move(newState); @@ -304,13 +292,12 @@ void Simulation::processUpdateFlags(const UiBindings::UpdateFlags &updateFlags) simulationState->paused = !simulationState->paused; // advance sets paused to true for only one step (see run()), needs to be reset here - if (updateFlags.stepSimulation){ + if (updateFlags.stepSimulation) { simulationState->paused = true; simulationState->step = true; } - // moved here to update every frame, since MVP matrix is a push-constant updateCommandBuffers(); } @@ -318,5 +305,5 @@ void Simulation::processUpdateFlags(const UiBindings::UpdateFlags &updateFlags) void Simulation::updateCommandBuffers() { hashGrid->updateCmd(*simulationState); particleRenderer->updateCmd(*simulationState); + particlePhysics->updateCmd(*simulationState); } - diff --git a/src/simulation_state.cpp b/src/simulation_state.cpp index 723f6d2350d57d7b73e3a4ae0429da4e53c81577..b431db34c0beb1defa02f3ec9e75852aa295b0e0 100644 --- a/src/simulation_state.cpp +++ b/src/simulation_state.cpp @@ -1,12 +1,12 @@ -#include <utility> -#include <vector> +#include "simulation_state.h" +#include "debug_image.h" +#include "render.h" #include <cstdint> +#include <memory> #include <random> #include <stdexcept> -#include <memory> -#include "simulation_state.h" -#include "render.h" -#include "debug_image.h" +#include <utility> +#include <vector> std::vector<float> initUniform(SceneType sceneType, uint32_t numParticles, std::mt19937 &random) { std::vector<float> values; @@ -15,7 +15,7 @@ std::vector<float> initUniform(SceneType sceneType, uint32_t numParticles, std:: case SceneType::SPH_BOX_2D: values.resize(2 * numParticles); std::uniform_real_distribution<float> distribution(0.0f, 1.0f); - for (auto &v : values) { + for (auto &v: values) { v = distribution(random); } } @@ -46,24 +46,27 @@ SimulationState::SimulationState(const SimulationParameters &_parameters, std::s vk::DeviceSize coordinateBufferSize; switch (parameters.type) { case SceneType::SPH_BOX_2D: - coordinateBufferSize = sizeof(Particle) * parameters.numParticles; + coordinateBufferSize = sizeof(glm::vec2) * parameters.numParticles; break; } - + // Particles particleCoordinateBuffer = createDeviceLocalBuffer("buffer-particles", coordinateBufferSize, vk::BufferUsageFlagBits::eVertexBuffer); - std::vector<float> values; + particleVelocityBuffer = createDeviceLocalBuffer("buffer-velocities", coordinateBufferSize);//just a storage buffer + std::vector<float> coordinateValues; + std::vector<float> velocityValues(2 * parameters.numParticles, 0.0f);// initialize velocities to 0 + switch (parameters.initializationFunction) { case InitializationFunction::UNIFORM: - values = initUniform(parameters.type, parameters.numParticles, random); + coordinateValues = initUniform(parameters.type, parameters.numParticles, random); break; case InitializationFunction::POISSON_DISK: - values = initPoissonDisk(parameters.type, parameters.numParticles, random); + coordinateValues = initPoissonDisk(parameters.type, parameters.numParticles, random); break; } - fillDeviceWithStagingBuffer(particleCoordinateBuffer, values); + fillDeviceWithStagingBuffer(particleCoordinateBuffer, coordinateValues); // Spatial Lookup - spatialLookup = createDeviceLocalBuffer("spatialLookup", parameters.numParticles * sizeof (SpatialLookupEntry)); + spatialLookup = createDeviceLocalBuffer("spatialLookup", parameters.numParticles * sizeof(SpatialLookupEntry)); spatialIndices = createDeviceLocalBuffer("startIndices", parameters.numParticles * sizeof(uint32_t)); } @@ -75,7 +78,7 @@ bool SimulationTime::advance(double add) { time += add; // it's time for a tick - if (time > lastUpdate + tickRate){ + if (time > lastUpdate + tickRate) { lastUpdate += tickRate; ticks++; return true; diff --git a/src/spatial_lookup.cpp b/src/spatial_lookup.cpp index 65174d502a6f622904369febadeee90f7055bbce..e7f6800730e382d709f28d821d8bac41f1dec4b0 100644 --- a/src/spatial_lookup.cpp +++ b/src/spatial_lookup.cpp @@ -1,6 +1,6 @@ #include "spatial_lookup.h" -struct PushConstants{ +struct PushConstants { uint32_t size; }; @@ -18,7 +18,7 @@ SpatialLookup::SpatialLookup(const SimulationParameters ¶meters) { Cmn::createDescriptorPool(resources.device, descriptorBindings, descriptorPool); Cmn::allocateDescriptorSet(resources.device, descriptorSet, descriptorPool, descriptorLayout); - vk::PushConstantRange pcr({vk::ShaderStageFlagBits::eCompute}, 0, sizeof (PushConstants)); + vk::PushConstantRange pcr({vk::ShaderStageFlagBits::eCompute}, 0, sizeof(PushConstants)); vk::PipelineLayoutCreateInfo pipelineLayoutInfo({}, descriptorLayout, pcr); pipelineLayout = resources.device.createPipelineLayout(pipelineLayoutInfo); @@ -27,19 +27,16 @@ SpatialLookup::SpatialLookup(const SimulationParameters ¶meters) { Cmn::createShader(resources.device, indexShader, shaderPath("spatial_lookup.index.comp")); std::array<vk::SpecializationMapEntry, 1> specEntries { - vk::SpecializationMapEntry(0,0, sizeof(workgroupSizeX)) - }; + vk::SpecializationMapEntry(0, 0, sizeof(workgroupSizeX))}; std::array<const uint32_t, 1> specValues = { - workgroupSizeX - }; + workgroupSizeX}; vk::SpecializationInfo specInfo(specEntries, vk::ArrayProxyNoTemporaries<const uint32_t>(specValues)); Cmn::createPipeline(resources.device, writePipeline, pipelineLayout, specInfo, writeShader); Cmn::createPipeline(resources.device, sortPipeline, pipelineLayout, specInfo, sortShader); Cmn::createPipeline(resources.device, indexPipeline, pipelineLayout, specInfo, indexShader); - } @@ -59,7 +56,7 @@ SpatialLookup::~SpatialLookup() { void SpatialLookup::updateCmd(const SimulationState &state) { - if (nullptr == cmd){ + if (nullptr == cmd) { vk::CommandBufferAllocateInfo cmdInfo(resources.computeCommandPool, vk::CommandBufferLevel::ePrimary, 1); cmd = resources.device.allocateCommandBuffers(cmdInfo)[0]; } else { @@ -73,8 +70,7 @@ void SpatialLookup::updateCmd(const SimulationState &state) { uint32_t dx = (state.parameters.numParticles + workgroupSizeX - 1) / workgroupSizeX; PushConstants pushConstants { - state.parameters.numParticles - }; + state.parameters.numParticles}; cmd.begin(vk::CommandBufferBeginInfo()); diff --git a/src/task_common.cpp b/src/task_common.cpp index 91984360fc5d979efb7e5d7678bf97c32a3916ec..ef55ef57a89164b60fc36493b53b442061259dc7 100644 --- a/src/task_common.cpp +++ b/src/task_common.cpp @@ -1,89 +1,84 @@ -#include <iostream> #include <cstdlib> +#include <iostream> #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 -#include <vulkan/vulkan.hpp> -#include <fstream> -#include <vector> -#include "task_common.h" #include "initialization.h" +#include "task_common.h" #include "utils.h" +#include <fstream> +#include <vector> +#include <vulkan/vulkan.hpp> -namespace Cmn{ - //We have a binding vector ready to become a descriptorSetLayout +namespace Cmn { +//We have a binding vector ready to become a descriptorSetLayout void createDescriptorSetLayout(vk::Device &device, - std::vector<vk::DescriptorSetLayoutBinding> &bindings, vk::DescriptorSetLayout &descLayout) -{ + std::vector<vk::DescriptorSetLayoutBinding> &bindings, vk::DescriptorSetLayout &descLayout) { vk::DescriptorSetLayoutCreateInfo layoutInfo( - {}, - CAST(bindings), // Number of binding infos - bindings.data() // Array of binding infos + {}, + CAST(bindings),// Number of binding infos + bindings.data()// Array of binding infos ); descLayout = device.createDescriptorSetLayout(layoutInfo); } -void addStorage(std::vector<vk::DescriptorSetLayoutBinding> &bindings, uint32_t binding) -{ +void addStorage(std::vector<vk::DescriptorSetLayoutBinding> &bindings, uint32_t binding) { //Binding Info //Bindings needed for DescriptorSetLayout //The DescriptorType eStorageBuffer is used in our case as storage buffer for compute shader //The ID binding(argument) is needed in the shader //DescriptorCount is set to 1U bindings.push_back(vk::DescriptorSetLayoutBinding( - binding, // The binding number of this entry - vk::DescriptorType::eStorageBuffer, // Type of resource descriptors used for this binding - 1U, // Number of descriptors contained in the binding - vk::ShaderStageFlagBits::eAll) // All defined shader stages can access the resource + binding, // The binding number of this entry + vk::DescriptorType::eStorageBuffer,// Type of resource descriptors used for this binding + 1U, // Number of descriptors contained in the binding + vk::ShaderStageFlagBits::eAll) // All defined shader stages can access the resource ); } -void addCombinedImageSampler(std::vector<vk::DescriptorSetLayoutBinding> &bindings, uint32_t binding) -{ +void addCombinedImageSampler(std::vector<vk::DescriptorSetLayoutBinding> &bindings, uint32_t binding) { //Binding Info bindings.push_back(vk::DescriptorSetLayoutBinding( - binding, // The binding number of this entry - vk::DescriptorType::eCombinedImageSampler, // Type of resource descriptors used for this binding - 1U, // Number of descriptors contained in the binding - vk::ShaderStageFlagBits::eAll) // All defined shader stages can access the resource + binding, // The binding number of this entry + vk::DescriptorType::eCombinedImageSampler,// Type of resource descriptors used for this binding + 1U, // Number of descriptors contained in the binding + vk::ShaderStageFlagBits::eAll) // All defined shader stages can access the resource ); } void allocateDescriptorSet(vk::Device &device, vk::DescriptorSet &descSet, vk::DescriptorPool &descPool, - vk::DescriptorSetLayout &descLayout) -{ + vk::DescriptorSetLayout &descLayout) { // You can technically allocate multiple layouts at once, we don't need that (so we put 1) vk::DescriptorSetAllocateInfo descAllocInfo(descPool, 1U, &descLayout); - // Therefore the vector is length one, we want to take its (only) element + // Therefore the vector is length one, we want to take its (only) element descSet = device.allocateDescriptorSets(descAllocInfo)[0]; } -void bindCombinedImageSampler(vk::Device &device, vk::ImageView &view, vk::Sampler &sampler, vk::DescriptorSet &set, uint32_t binding){ +void bindCombinedImageSampler(vk::Device &device, vk::ImageView &view, vk::Sampler &sampler, vk::DescriptorSet &set, uint32_t binding) { // Colour Attachment Descriptor - vk::DescriptorImageInfo imageInfo( sampler, view, - vk::ImageLayout::eShaderReadOnlyOptimal); + vk::DescriptorImageInfo imageInfo(sampler, view, + vk::ImageLayout::eShaderReadOnlyOptimal); // Colour Attachment Descriptor Write vk::WriteDescriptorSet write(set, binding, 0U, 1U, - vk::DescriptorType::eCombinedImageSampler, &imageInfo); + vk::DescriptorType::eCombinedImageSampler, &imageInfo); device.updateDescriptorSets(1U, &write, 0U, nullptr); } -void bindBuffers(vk::Device &device, const vk::Buffer &b, vk::DescriptorSet &set, uint32_t binding, vk::DescriptorType type) -{ +void bindBuffers(vk::Device &device, const vk::Buffer &b, vk::DescriptorSet &set, uint32_t binding, vk::DescriptorType type) { // Buffer info and data offset info vk::DescriptorBufferInfo descInfo( - b, // Buffer to get data from - 0ULL, // Position of start of data - VK_WHOLE_SIZE // Size of data + b, // Buffer to get data from + 0ULL, // Position of start of data + VK_WHOLE_SIZE// Size of data ); // Binding index in the shader V // Data about connection between binding and buffer vk::WriteDescriptorSet write( - set, // Descriptor Set to update - binding, // Binding to update (matches with binding on layout/shader) - 0U, // Index in array to update - 1U, // Amount to update - type, // Type of descriptor - nullptr, - &descInfo // Information about buffer data to bind + set, // Descriptor Set to update + binding,// Binding to update (matches with binding on layout/shader) + 0U, // Index in array to update + 1U, // Amount to update + type, // Type of descriptor + nullptr, + &descInfo// Information about buffer data to bind ); // Update the descriptor sets with new buffer/binding info @@ -91,9 +86,8 @@ void bindBuffers(vk::Device &device, const vk::Buffer &b, vk::DescriptorSet &set } void createPipeline(vk::Device &device, vk::Pipeline &pipeline, - vk::PipelineLayout &pipLayout, vk::SpecializationInfo &specInfo, - vk::ShaderModule &sModule) -{ + vk::PipelineLayout &pipLayout, vk::SpecializationInfo &specInfo, + vk::ShaderModule &sModule) { vk::PipelineShaderStageCreateInfo stageInfo(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eCompute, sModule, "main", &specInfo); @@ -105,18 +99,20 @@ void createPipeline(vk::Device &device, vk::Pipeline &pipeline, pipeline = device.createComputePipeline(nullptr, computeInfo, nullptr).value; } //Number of DescriptorSets is one by default -void createDescriptorPool(vk::Device &device, std::vector<vk::DescriptorSetLayoutBinding> &bindings, vk::DescriptorPool &descPool, uint32_t numDescriptorSets) -{ +void createDescriptorPool(vk::Device &device, std::vector<vk::DescriptorSetLayoutBinding> &bindings, vk::DescriptorPool &descPool, uint32_t numDescriptorSets) { uint32_t numStorage = 0, numCombinedImageSampler = 0, numUniform = 0; - for (const auto & binding : bindings) { - switch(binding.descriptorType) { + for (const auto &binding: bindings) { + switch (binding.descriptorType) { case vk::DescriptorType::eStorageBuffer: - numStorage++; break; + numStorage++; + break; case vk::DescriptorType::eCombinedImageSampler: - numCombinedImageSampler++; break; + numCombinedImageSampler++; + break; case vk::DescriptorType::eUniformBuffer: - numUniform++; break; + numUniform++; + break; default: break; } @@ -126,37 +122,33 @@ void createDescriptorPool(vk::Device &device, std::vector<vk::DescriptorSetLayou std::vector<vk::DescriptorPoolSize> descriptorPoolSizes; if (numStorage > 0) descriptorPoolSizes.push_back(vk::DescriptorPoolSize { - vk::DescriptorType::eStorageBuffer, numStorage * numDescriptorSets - }); + vk::DescriptorType::eStorageBuffer, numStorage * numDescriptorSets}); if (numCombinedImageSampler > 0) descriptorPoolSizes.push_back(vk::DescriptorPoolSize { - vk::DescriptorType::eCombinedImageSampler, numCombinedImageSampler * numDescriptorSets - }); + vk::DescriptorType::eCombinedImageSampler, numCombinedImageSampler * numDescriptorSets}); if (numUniform > 0) descriptorPoolSizes.push_back(vk::DescriptorPoolSize { - vk::DescriptorType::eUniformBuffer, numUniform * numDescriptorSets - }); + vk::DescriptorType::eUniformBuffer, numUniform * numDescriptorSets}); // Data to create Descriptor Pool vk::DescriptorPoolCreateInfo descriptorPoolCI = vk::DescriptorPoolCreateInfo( - vk::DescriptorPoolCreateFlags(), numDescriptorSets, descriptorPoolSizes); + vk::DescriptorPoolCreateFlags(), numDescriptorSets, descriptorPoolSizes); descPool = device.createDescriptorPool(descriptorPoolCI); } -void createShader(vk::Device &device, vk::ShaderModule &shaderModule, const std::string &filename){ +void createShader(vk::Device &device, vk::ShaderModule &shaderModule, const std::string &filename) { std::vector<char> cshader = readFile(filename); // Shader Module creation information vk::ShaderModuleCreateInfo smi( - {}, - static_cast<uint32_t>(cshader.size()), // Size of code - reinterpret_cast<const uint32_t*>( cshader.data() )); // Pointer to code (of uint32_t pointer type) + {}, + static_cast<uint32_t>(cshader.size()), // Size of code + reinterpret_cast<const uint32_t *>(cshader.data()));// Pointer to code (of uint32_t pointer type) shaderModule = device.createShaderModule(smi); } -} +}// namespace Cmn -void TaskResources::destroy(vk::Device &device) -{ +void TaskResources::destroy(vk::Device &device) { //Destroy all the resources we created in reverse order //Pipeline Should be destroyed before PipelineLayout device.destroyPipeline(this->pipeline); @@ -171,4 +163,3 @@ void TaskResources::destroy(vk::Device &device) std::cout << std::endl << "destroyed everything successfully in task" << std::endl; } - diff --git a/src/utils.cpp b/src/utils.cpp index a47ba60de78a57f97c9c6bc3548a6cfd678988f6..bb36ec80b8001361e91115a60468a42e008307c4 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,8 +1,8 @@ -#include <vector> -#include <iostream> -#include <fstream> #include <cstring> +#include <fstream> +#include <iostream> #include <sstream> +#include <vector> #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 #include <vulkan/vulkan.hpp> @@ -13,16 +13,14 @@ AppResources dontUse = AppResources(); AppResources &resources = dontUse; -std::vector<char> readFile(const std::string &filename) -{ +std::vector<char> readFile(const std::string &filename) { std::ifstream file(filename, std::ios::ate | std::ios::binary); - if (!file.is_open()) - { + if (!file.is_open()) { std::string error = "failed to open file: " + filename; throw std::runtime_error(error); } - size_t fileSize = (size_t)file.tellg(); + size_t fileSize = (size_t) file.tellg(); std::vector<char> buffer(fileSize); file.seekg(0); @@ -32,40 +30,29 @@ std::vector<char> readFile(const std::string &filename) return buffer; } -std::string formatSize(uint64_t size) -{ +std::string formatSize(uint64_t size) { std::ostringstream oss; - if (size < 1024) - { + if (size < 1024) { oss << size << " B"; - } - else if (size < 1024 * 1024) - { + } else if (size < 1024 * 1024) { oss << size / 1024.f << " KB"; - } - else if (size < 1024 * 1024 * 1024) - { + } else if (size < 1024 * 1024 * 1024) { oss << size / (1024.0f * 1024.0f) << " MB"; - } - else - { + } else { oss << size / (1024.0f * 1024.0f * 1024.0f) << " GB"; } return oss.str(); } -void writeFloatJpg(const std::string name, const std::vector<float> &inData, const int w, const int h) -{ +void writeFloatJpg(const std::string name, const std::vector<float> &inData, const int w, const int h) { std::vector<uint8_t> refINT(inData.size()); for (int i = 0; i < inData.size(); i++) refINT[i] = static_cast<uint8_t>(inData[i] * 255); stbi_write_jpg(name.c_str(), w, h, 1, refINT.data(), 100); } -uint32_t findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags properties, vk::PhysicalDevice &pdevice) -{ +uint32_t findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags properties, vk::PhysicalDevice &pdevice) { vk::PhysicalDeviceMemoryProperties memProperties = pdevice.getMemoryProperties(); - for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) - { + for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) return i; } @@ -75,9 +62,8 @@ uint32_t findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags properties, Buffer createBuffer(vk::PhysicalDevice &pDevice, vk::Device &device, - const vk::DeviceSize &size, vk::BufferUsageFlags usage, - vk::MemoryPropertyFlags properties, std::string name) -{ + const vk::DeviceSize &size, vk::BufferUsageFlags usage, + vk::MemoryPropertyFlags properties, std::string name) { vk::BufferCreateInfo inBufferInfo({}, size, usage); vk::Buffer buffer = device.createBuffer(inBufferInfo); setObjectName(device, buffer, name); @@ -93,8 +79,7 @@ Buffer createBuffer(vk::PhysicalDevice &pDevice, vk::Device &device, } void copyBuffer(vk::Device &device, vk::Queue &q, vk::CommandPool &commandPool, - const vk::Buffer &srcBuffer, const vk::Buffer &dstBuffer, vk::DeviceSize byteSize) -{ + const vk::Buffer &srcBuffer, const vk::Buffer &dstBuffer, vk::DeviceSize byteSize) { vk::CommandBuffer commandBuffer = beginSingleTimeCommands(device, commandPool); vk::BufferCopy copyRegion(0ULL, 0ULL, byteSize); @@ -103,9 +88,8 @@ void copyBuffer(vk::Device &device, vk::Queue &q, vk::CommandPool &commandPool, endSingleTimeCommands(device, q, commandPool, commandBuffer); } -void createImage(vk::PhysicalDevice &pDevice, vk::Device &device, vk::ImageCreateInfo createInfo,vk::MemoryPropertyFlags properties, - std::string name, vk::Image &image, vk::DeviceMemory &imageMemory) -{ +void createImage(vk::PhysicalDevice &pDevice, vk::Device &device, vk::ImageCreateInfo createInfo, vk::MemoryPropertyFlags properties, + std::string name, vk::Image &image, vk::DeviceMemory &imageMemory) { image = device.createImage(createInfo); setObjectName(device, image, name); auto memReq = device.getImageMemoryRequirements(image); @@ -115,8 +99,7 @@ void createImage(vk::PhysicalDevice &pDevice, vk::Device &device, vk::ImageCreat } -vk::CommandBuffer beginSingleTimeCommands(vk::Device &device, vk::CommandPool &commandPool) -{ +vk::CommandBuffer beginSingleTimeCommands(vk::Device &device, vk::CommandPool &commandPool) { vk::CommandBufferAllocateInfo allocInfo(commandPool, vk::CommandBufferLevel::ePrimary, 1); vk::CommandBuffer commandBuffer = device.allocateCommandBuffers(allocInfo)[0]; @@ -128,8 +111,7 @@ vk::CommandBuffer beginSingleTimeCommands(vk::Device &device, vk::CommandPool &c } void endSingleTimeCommands(vk::Device &device, vk::Queue &q, - vk::CommandPool &commandPool, vk::CommandBuffer &commandBuffer) -{ + vk::CommandPool &commandPool, vk::CommandBuffer &commandBuffer) { commandBuffer.end(); vk::SubmitInfo submitInfo(0U, nullptr, nullptr, 1U, &commandBuffer); q.submit({submitInfo}, nullptr); @@ -142,23 +124,23 @@ void ownershipTransfer(vk::Device &device, vk::CommandPool &srcCommandPool, vk:: vk::CommandBuffer commandBuffer = beginSingleTimeCommands(device, srcCommandPool); vk::ImageMemoryBarrier barrier( - vk::AccessFlagBits::eNoneKHR, vk::AccessFlagBits::eNoneKHR, - oldLayout, newLayout, - srcQueueFamilyIndex, dstQueueFamilyIndex, - image, - vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor,0,1,0,1)); + vk::AccessFlagBits::eNoneKHR, vk::AccessFlagBits::eNoneKHR, + oldLayout, newLayout, + srcQueueFamilyIndex, dstQueueFamilyIndex, + image, + vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1)); vk::PipelineStageFlags sourceStage; vk::PipelineStageFlags destinationStage; - + using psf = vk::PipelineStageFlagBits; - if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal ) { + if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal) { barrier.setDstAccessMask(vk::AccessFlagBits::eTransferWrite); sourceStage = psf::eTopOfPipe; destinationStage = psf::eBottomOfPipe; - } else if ( oldLayout == vk::ImageLayout::eTransferDstOptimal && - newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) { + } else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && + newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) { barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite; barrier.dstAccessMask = {}; @@ -166,15 +148,14 @@ void ownershipTransfer(vk::Device &device, vk::CommandPool &srcCommandPool, vk:: destinationStage = psf::eBottomOfPipe; } else { throw std::invalid_argument("unsupported layout transition!"); - } - + } + commandBuffer.pipelineBarrier( - sourceStage, destinationStage, - vk::DependencyFlagBits::eByRegion, - 0,nullptr, - 0,nullptr, - 1,&barrier - ); + sourceStage, destinationStage, + vk::DependencyFlagBits::eByRegion, + 0, nullptr, + 0, nullptr, + 1, &barrier); endSingleTimeCommands(device, srcQueue, srcCommandPool, commandBuffer); } @@ -183,23 +164,23 @@ void ownershipTransfer(vk::Device &device, vk::CommandPool &srcCommandPool, vk:: vk::CommandBuffer commandBuffer = beginSingleTimeCommands(device, dstCommandPool); vk::ImageMemoryBarrier barrier( - vk::AccessFlagBits::eNoneKHR, vk::AccessFlagBits::eNoneKHR, - oldLayout, newLayout, - srcQueueFamilyIndex, dstQueueFamilyIndex, - image, - vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor,0,1,0,1)); + vk::AccessFlagBits::eNoneKHR, vk::AccessFlagBits::eNoneKHR, + oldLayout, newLayout, + srcQueueFamilyIndex, dstQueueFamilyIndex, + image, + vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1)); vk::PipelineStageFlags sourceStage; vk::PipelineStageFlags destinationStage; - + using psf = vk::PipelineStageFlagBits; - if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal ) { + if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal) { barrier.setDstAccessMask(vk::AccessFlagBits::eTransferWrite); sourceStage = psf::eTopOfPipe; destinationStage = psf::eTransfer; - } else if ( oldLayout == vk::ImageLayout::eTransferDstOptimal && - newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) { + } else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && + newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) { barrier.srcAccessMask = {}; barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead; @@ -207,15 +188,14 @@ void ownershipTransfer(vk::Device &device, vk::CommandPool &srcCommandPool, vk:: destinationStage = psf::eComputeShader; } else { throw std::invalid_argument("unsupported layout transition!"); - } - + } + commandBuffer.pipelineBarrier( - sourceStage, destinationStage, - vk::DependencyFlagBits::eByRegion, - 0,nullptr, - 0,nullptr, - 1,&barrier - ); + sourceStage, destinationStage, + vk::DependencyFlagBits::eByRegion, + 0, nullptr, + 0, nullptr, + 1, &barrier); endSingleTimeCommands(device, dstQueue, dstCommandPool, commandBuffer); } @@ -225,17 +205,17 @@ void transitionImageLayout(vk::Device &device, vk::CommandPool &pool, vk::Queue vk::CommandBuffer commandBuffer = beginSingleTimeCommands(device, pool); vk::ImageMemoryBarrier barrier( - vk::AccessFlagBits::eNoneKHR, vk::AccessFlagBits::eNoneKHR, - oldLayout, newLayout, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - image, - vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor,0,1,0,1)); + vk::AccessFlagBits::eNoneKHR, vk::AccessFlagBits::eNoneKHR, + oldLayout, newLayout, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, + image, + vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1)); vk::PipelineStageFlags sourceStage; vk::PipelineStageFlags destinationStage; - + using psf = vk::PipelineStageFlagBits; - if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal ) { + if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal) { barrier.setDstAccessMask(vk::AccessFlagBits::eTransferWrite); sourceStage = psf::eTopOfPipe; @@ -245,13 +225,13 @@ void transitionImageLayout(vk::Device &device, vk::CommandPool &pool, vk::Queue sourceStage = psf::eTopOfPipe; destinationStage = psf::eTransfer; - }else if (oldLayout == vk::ImageLayout::eTransferDstOptimal &&newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) { + } else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) { barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite; barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead; sourceStage = psf::eTransfer; destinationStage = psf::eComputeShader; - } else if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eGeneral){ + } else if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eGeneral) { barrier.setDstAccessMask(vk::AccessFlagBits::eTransferWrite); sourceStage = psf::eTopOfPipe; @@ -268,15 +248,14 @@ void transitionImageLayout(vk::Device &device, vk::CommandPool &pool, vk::Queue destinationStage = psf::eColorAttachmentOutput; } else { throw std::invalid_argument("unsupported layout transition!"); - } + } commandBuffer.pipelineBarrier( - sourceStage, destinationStage, - vk::DependencyFlagBits::eByRegion, - 0,nullptr, - 0,nullptr, - 1,&barrier - ); + sourceStage, destinationStage, + vk::DependencyFlagBits::eByRegion, + 0, nullptr, + 0, nullptr, + 1, &barrier); endSingleTimeCommands(device, queue, pool, commandBuffer); } @@ -284,11 +263,11 @@ void transitionImageLayout(vk::Device &device, vk::CommandPool &pool, vk::Queue void copyBufferToImage(vk::Device &device, vk::CommandPool &pool, vk::Queue &queue, vk::Buffer &buffer, vk::Image &image, uint32_t width, uint32_t height, uint32_t depth) { vk::CommandBuffer commandBuffer = beginSingleTimeCommands(device, pool); - vk::BufferImageCopy region( 0,0,0, - vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor,0,0,1), - vk::Offset3D(0,0,0), vk::Extent3D(width,height,depth)); - commandBuffer.copyBufferToImage(buffer,image, vk::ImageLayout::eTransferDstOptimal, 1, ®ion); - + vk::BufferImageCopy region(0, 0, 0, + vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1), + vk::Offset3D(0, 0, 0), vk::Extent3D(width, height, depth)); + commandBuffer.copyBufferToImage(buffer, image, vk::ImageLayout::eTransferDstOptimal, 1, ®ion); + endSingleTimeCommands(device, queue, pool, commandBuffer); } @@ -299,8 +278,7 @@ Buffer createDeviceLocalBuffer(const std::string &name, vk::DeviceSize size, vk: size, {additionalUsageBits | vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst}, {vk::MemoryPropertyFlagBits::eDeviceLocal}, - name - ); + name); } void computeBarrier(vk::CommandBuffer &cmd) { @@ -310,6 +288,5 @@ void computeBarrier(vk::CommandBuffer &cmd) { {}, {vk::MemoryBarrier(vk::AccessFlagBits::eShaderWrite, vk::AccessFlagBits::eShaderRead)}, {}, - {} - ); + {}); }