From fa9a7f2efd1ceb51deb6942ac875b07cc59d3fa4 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Sat, 19 Jun 2021 16:45:49 +0200 Subject: [PATCH] [#81] Add option to visualize different voxel mips --- include/vkcv/DescriptorWrites.hpp | 4 ++- include/vkcv/Image.hpp | 2 +- projects/voxelization/src/Voxelization.cpp | 29 ++++++++++++++-------- projects/voxelization/src/Voxelization.hpp | 3 ++- projects/voxelization/src/main.cpp | 5 +++- src/vkcv/DescriptorManager.cpp | 2 +- src/vkcv/Image.cpp | 6 ++++- src/vkcv/ImageManager.cpp | 16 ++++++++++++ src/vkcv/ImageManager.hpp | 3 +++ 9 files changed, 53 insertions(+), 17 deletions(-) diff --git a/include/vkcv/DescriptorWrites.hpp b/include/vkcv/DescriptorWrites.hpp index d67e8e32..016bdab7 100644 --- a/include/vkcv/DescriptorWrites.hpp +++ b/include/vkcv/DescriptorWrites.hpp @@ -10,9 +10,11 @@ namespace vkcv { }; struct StorageImageDescriptorWrite { - inline StorageImageDescriptorWrite(uint32_t binding, ImageHandle image) : binding(binding), image(image) {}; + inline StorageImageDescriptorWrite(uint32_t binding, ImageHandle image, uint32_t mipLevel = 0) + : binding(binding), image(image), mipLevel(mipLevel) {}; uint32_t binding; ImageHandle image; + uint32_t mipLevel; }; struct UniformBufferDescriptorWrite { diff --git a/include/vkcv/Image.hpp b/include/vkcv/Image.hpp index f8e35ccb..9e1f9708 100644 --- a/include/vkcv/Image.hpp +++ b/include/vkcv/Image.hpp @@ -34,7 +34,7 @@ namespace vkcv { vkcv::ImageHandle getHandle() const; [[nodiscard]] - uint32_t getMipCount(); + uint32_t getMipCount() const; void switchLayout(vk::ImageLayout newLayout); diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp index a101a03a..12b179e7 100644 --- a/projects/voxelization/src/Voxelization.cpp +++ b/projects/voxelization/src/Voxelization.cpp @@ -1,6 +1,7 @@ #include "Voxelization.hpp" #include <vkcv/shader/GLSLCompiler.hpp> #include <glm/gtc/matrix_transform.hpp> +#include <algorithm> vkcv::ShaderProgram loadVoxelizationShader() { vkcv::shader::GLSLCompiler compiler; @@ -153,13 +154,6 @@ Voxelization::Voxelization( voxelIndexData.push_back(i); } - vkcv::DescriptorWrites voxelVisualisationDescriptorWrite; - voxelVisualisationDescriptorWrite.storageImageWrites = - { vkcv::StorageImageDescriptorWrite(0, m_voxelImage.getHandle()) }; - voxelVisualisationDescriptorWrite.uniformBufferWrites = - { vkcv::UniformBufferDescriptorWrite(1, m_voxelInfoBuffer.getHandle()) }; - m_corePtr->writeDescriptorSet(m_visualisationDescriptorSet, voxelVisualisationDescriptorWrite); - const vkcv::DescriptorSetUsage voxelizationDescriptorUsage(0, m_corePtr->getDescriptorSet(m_visualisationDescriptorSet).vulkanHandle); vkcv::ShaderProgram resetVoxelShader = loadVoxelResetShader(); @@ -277,14 +271,27 @@ void Voxelization::voxelizeMeshes( } void Voxelization::renderVoxelVisualisation( - vkcv::CommandStreamHandle cmdStream, - const glm::mat4& viewProjectin, - const std::vector<vkcv::ImageHandle>& renderTargets) { + vkcv::CommandStreamHandle cmdStream, + const glm::mat4& viewProjectin, + const std::vector<vkcv::ImageHandle>& renderTargets, + uint32_t mipLevel) { const vkcv::PushConstantData voxelVisualisationPushConstantData((void*)&viewProjectin, sizeof(glm::mat4)); + mipLevel = std::clamp(mipLevel, (uint32_t)0, m_voxelImage.getMipCount()-1); + + // write descriptor set + vkcv::DescriptorWrites voxelVisualisationDescriptorWrite; + voxelVisualisationDescriptorWrite.storageImageWrites = + { vkcv::StorageImageDescriptorWrite(0, m_voxelImage.getHandle(), mipLevel) }; + voxelVisualisationDescriptorWrite.uniformBufferWrites = + { vkcv::UniformBufferDescriptorWrite(1, m_voxelInfoBuffer.getHandle()) }; + m_corePtr->writeDescriptorSet(m_visualisationDescriptorSet, voxelVisualisationDescriptorWrite); + + uint32_t drawVoxelCount = voxelCount / exp2(mipLevel); + const auto drawcall = vkcv::DrawcallInfo( - vkcv::Mesh({}, nullptr, voxelCount), + vkcv::Mesh({}, nullptr, drawVoxelCount), { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_visualisationDescriptorSet).vulkanHandle) }); m_corePtr->recordDrawcallsToCmdStream( diff --git a/projects/voxelization/src/Voxelization.hpp b/projects/voxelization/src/Voxelization.hpp index 0e62b059..81039e5e 100644 --- a/projects/voxelization/src/Voxelization.hpp +++ b/projects/voxelization/src/Voxelization.hpp @@ -26,7 +26,8 @@ public: void renderVoxelVisualisation( vkcv::CommandStreamHandle cmdStream, const glm::mat4& viewProjectin, - const std::vector<vkcv::ImageHandle>& renderTargets); + const std::vector<vkcv::ImageHandle>& renderTargets, + uint32_t mipLevel); private: vkcv::Core* m_corePtr; diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index 53c25e6d..b37f6869 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -329,6 +329,7 @@ int main(int argc, const char** argv) { vkcv::gui::GUI gui(core, window); glm::vec2 lightAngles(90.f, 0.f); + int voxelVisualisationMip = 0; auto start = std::chrono::system_clock::now(); const auto appStartTime = start; @@ -429,7 +430,7 @@ int main(int argc, const char** argv) { renderTargets); if (renderVoxelVis) { - voxelization.renderVoxelVisualisation(cmdStream, viewProjectionCamera, renderTargets); + voxelization.renderVoxelVisualisation(cmdStream, viewProjectionCamera, renderTargets, voxelVisualisationMip); } const uint32_t tonemappingLocalGroupSize = 8; @@ -459,6 +460,8 @@ int main(int argc, const char** argv) { ImGui::DragFloat2("Light angles", &lightAngles.x); ImGui::ColorEdit3("Sun color", &lightInfo.sunColor.x); ImGui::DragFloat("Sun strength", &lightInfo.sunStrength); + ImGui::SliderInt("Visualisation mip", &voxelVisualisationMip, 0, 7); + voxelVisualisationMip = std::max(voxelVisualisationMip, 0); ImGui::End(); gui.endGUI(); diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index f591daf9..26553223 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -128,7 +128,7 @@ namespace vkcv for (const auto& write : writes.storageImageWrites) { const vk::DescriptorImageInfo imageInfo( nullptr, - imageManager.getVulkanImageView(write.image), + imageManager.getVulkanImageView(write.image, write.mipLevel), vk::ImageLayout::eGeneral ); diff --git a/src/vkcv/Image.cpp b/src/vkcv/Image.cpp index 0a3353f7..c48b0153 100644 --- a/src/vkcv/Image.cpp +++ b/src/vkcv/Image.cpp @@ -56,7 +56,11 @@ namespace vkcv{ vkcv::ImageHandle Image::getHandle() const { return m_handle; } - + + uint32_t Image::getMipCount() const { + return m_manager->getImageMipCount(m_handle); + } + void Image::fill(void *data, size_t size) { m_manager->fillImage(m_handle, data, size); } diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp index 14d7c506..a3364ce0 100644 --- a/src/vkcv/ImageManager.cpp +++ b/src/vkcv/ImageManager.cpp @@ -605,6 +605,22 @@ namespace vkcv { return isSwapchainFormat ? m_swapchainImages[m_currentSwapchainInputImage].m_format : m_images[id].m_format; } + uint32_t ImageManager::getImageMipCount(const ImageHandle& handle) const { + const uint64_t id = handle.getId(); + const bool isSwapchainFormat = handle.isSwapchainImage(); + + if (handle.isSwapchainImage()) { + return 1; + } + + if (id >= m_images.size()) { + vkcv_log(LogLevel::ERROR, "Invalid handle"); + return 0; + } + + return m_images[id].m_viewPerMip.size(); + } + void ImageManager::setCurrentSwapchainImageIndex(int index) { m_currentSwapchainInputImage = index; } diff --git a/src/vkcv/ImageManager.hpp b/src/vkcv/ImageManager.hpp index 9cd1a8de..ecba7eb5 100644 --- a/src/vkcv/ImageManager.hpp +++ b/src/vkcv/ImageManager.hpp @@ -117,6 +117,9 @@ namespace vkcv { [[nodiscard]] vk::Format getImageFormat(const ImageHandle& handle) const; + [[nodiscard]] + uint32_t getImageMipCount(const ImageHandle& handle) const; + void setCurrentSwapchainImageIndex(int index); void setSwapchainImages(const std::vector<vk::Image>& images, std::vector<vk::ImageView> views, uint32_t width, uint32_t height, vk::Format format); -- GitLab