diff --git a/include/vkcv/DescriptorWrites.hpp b/include/vkcv/DescriptorWrites.hpp index d67e8e3233e184b207d109e652adeca43407d7e0..016bdab7c337d3ebada5ed8e9a035606eb937211 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 f8e35ccbfa6eda1143c1293eb3a0ae947b6760d7..9e1f9708c6318aa6deb750097c414358ffde2c65 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 a101a03aae245701fcc097b677cd486fa4445561..12b179e77815bfb45983bff267a2a29ba8b626b1 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 0e62b059fb5bef1f73681c10c83aa6c79c806fa4..81039e5e69ae586914c9fbe6a836767babc954e1 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 53c25e6dfcd43efcd0d9e0957b6c34f82fad0b5a..b37f6869c39dee7dbfed4b0c1a3add3613b87a8f 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 f591daf90b47b57a758b2b24c7fa87b5c33e3c46..265532232304106f7271fdd445d52074b7c011a1 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 0a3353f7248fc417c9f49701be7d5f81455ad667..c48b015335e00f23a892bb96d3e89a2c0877ae61 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 14d7c506a526634a894163e387a8504b0d48241b..a3364ce0dfd6f59dc78c85b43570eea25cfc052d 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 9cd1a8dec6d37af7e01273993cc6a38c06b68ce6..ecba7eb5959c1d78a0be41e0b3ac555bffd92d95 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);