Skip to content
Snippets Groups Projects
Commit 0b7779ee authored by Alexander Gauggel's avatar Alexander Gauggel
Browse files

[#81] Compute voxel mip chain

parent 2e496737
No related branches found
No related tags found
1 merge request!68Resolve "Complete Voxelization"
Pipeline #25874 passed
...@@ -32,11 +32,15 @@ namespace vkcv { ...@@ -32,11 +32,15 @@ namespace vkcv {
[[nodiscard]] [[nodiscard]]
vkcv::ImageHandle getHandle() const; vkcv::ImageHandle getHandle() const;
[[nodiscard]]
uint32_t getMipCount();
void switchLayout(vk::ImageLayout newLayout); void switchLayout(vk::ImageLayout newLayout);
void fill(void* data, size_t size = SIZE_MAX); void fill(void* data, size_t size = SIZE_MAX);
void generateMipChainImmediate(); void generateMipChainImmediate();
void recordMipChainGeneration(const vkcv::CommandStreamHandle& cmdStream);
private: private:
ImageManager* const m_manager; ImageManager* const m_manager;
const ImageHandle m_handle; const ImageHandle m_handle;
......
...@@ -70,7 +70,7 @@ Voxelization::Voxelization( ...@@ -70,7 +70,7 @@ Voxelization::Voxelization(
vkcv::SamplerHandle shadowSampler) vkcv::SamplerHandle shadowSampler)
: :
m_corePtr(corePtr), m_corePtr(corePtr),
m_voxelImage(m_corePtr->createImage(vk::Format::eR16G16B16A16Sfloat, voxelResolution, voxelResolution, voxelResolution, false, true)), m_voxelImage(m_corePtr->createImage(vk::Format::eR16G16B16A16Sfloat, voxelResolution, voxelResolution, voxelResolution, true, true)),
m_dummyRenderTarget(m_corePtr->createImage(voxelizationDummyFormat, voxelResolution, voxelResolution, 1, false, false, true)), m_dummyRenderTarget(m_corePtr->createImage(voxelizationDummyFormat, voxelResolution, voxelResolution, 1, false, false, true)),
m_voxelInfoBuffer(m_corePtr->createBuffer<VoxelizationInfo>(vkcv::BufferType::UNIFORM, 1)), m_voxelInfoBuffer(m_corePtr->createBuffer<VoxelizationInfo>(vkcv::BufferType::UNIFORM, 1)),
m_voxelBuffer(m_corePtr->createBuffer<VoxelBufferContent>(vkcv::BufferType::STORAGE, voxelCount)){ m_voxelBuffer(m_corePtr->createBuffer<VoxelBufferContent>(vkcv::BufferType::STORAGE, voxelCount)){
...@@ -272,6 +272,8 @@ void Voxelization::voxelizeMeshes( ...@@ -272,6 +272,8 @@ void Voxelization::voxelizeMeshes(
vkcv::PushConstantData(nullptr, 0)); vkcv::PushConstantData(nullptr, 0));
m_corePtr->recordImageMemoryBarrier(cmdStream, m_voxelImage.getHandle()); m_corePtr->recordImageMemoryBarrier(cmdStream, m_voxelImage.getHandle());
m_voxelImage.recordMipChainGeneration(cmdStream);
} }
void Voxelization::renderVoxelVisualisation( void Voxelization::renderVoxelVisualisation(
......
...@@ -64,6 +64,10 @@ namespace vkcv{ ...@@ -64,6 +64,10 @@ namespace vkcv{
void Image::generateMipChainImmediate() { void Image::generateMipChainImmediate() {
m_manager->generateImageMipChainImmediate(m_handle); m_manager->generateImageMipChainImmediate(m_handle);
} }
void Image::recordMipChainGeneration(const vkcv::CommandStreamHandle& cmdStream) {
m_manager->recordImageMipChainGenerationToCmdStream(cmdStream, m_handle);
}
Image::Image(ImageManager* manager, const ImageHandle& handle) : Image::Image(ImageManager* manager, const ImageHandle& handle) :
m_manager(manager), m_manager(manager),
......
...@@ -438,6 +438,60 @@ namespace vkcv { ...@@ -438,6 +438,60 @@ namespace vkcv {
); );
} }
void ImageManager::recordImageMipGenerationToCmdBuffer(vk::CommandBuffer cmdBuffer, const ImageHandle& handle) {
const auto id = handle.getId();
if (id >= m_images.size()) {
vkcv_log(vkcv::LogLevel::ERROR, "Invalid image handle");
return;
}
auto& image = m_images[id];
recordImageLayoutTransition(handle, vk::ImageLayout::eGeneral, cmdBuffer);
vk::ImageAspectFlags aspectMask = isDepthImageFormat(image.m_format) ?
vk::ImageAspectFlagBits::eDepth : vk::ImageAspectFlagBits::eColor;
uint32_t srcWidth = image.m_width;
uint32_t srcHeight = image.m_height;
uint32_t srcDepth = image.m_depth;
auto half = [](uint32_t in) {
return std::max<uint32_t>(in / 2, 1);
};
uint32_t dstWidth = half(srcWidth);
uint32_t dstHeight = half(srcHeight);
uint32_t dstDepth = half(srcDepth);
for (uint32_t srcMip = 0; srcMip < image.m_viewPerMip.size() - 1; srcMip++) {
uint32_t dstMip = srcMip + 1;
vk::ImageBlit region(
vk::ImageSubresourceLayers(aspectMask, srcMip, 0, 1),
{ vk::Offset3D(0, 0, 0), vk::Offset3D(srcWidth, srcHeight, srcDepth) },
vk::ImageSubresourceLayers(aspectMask, dstMip, 0, 1),
{ vk::Offset3D(0, 0, 0), vk::Offset3D(dstWidth, dstHeight, dstDepth) });
cmdBuffer.blitImage(
image.m_handle,
vk::ImageLayout::eGeneral,
image.m_handle,
vk::ImageLayout::eGeneral,
region,
vk::Filter::eLinear);
srcWidth = dstWidth;
srcHeight = dstHeight;
srcDepth = dstDepth;
dstWidth = half(dstWidth);
dstHeight = half(dstHeight);
dstDepth = half(dstDepth);
recordImageMemoryBarrier(handle, cmdBuffer);
}
}
void ImageManager::generateImageMipChainImmediate(const ImageHandle& handle) { void ImageManager::generateImageMipChainImmediate(const ImageHandle& handle) {
const auto& device = m_core->getContext().getDevice(); const auto& device = m_core->getContext().getDevice();
...@@ -450,62 +504,23 @@ namespace vkcv { ...@@ -450,62 +504,23 @@ namespace vkcv {
return; return;
} }
const auto id = handle.getId(); const auto record = [this, handle](const vk::CommandBuffer cmdBuffer) {
if (id >= m_images.size()) { recordImageMipGenerationToCmdBuffer(cmdBuffer, handle);
vkcv_log(vkcv::LogLevel::ERROR, "Invalid image handle");
return;
}
auto& image = m_images[id];
switchImageLayoutImmediate(handle, vk::ImageLayout::eGeneral);
const auto record = [&image, this, handle](const vk::CommandBuffer cmdBuffer) {
vk::ImageAspectFlags aspectMask = isDepthImageFormat(image.m_format) ?
vk::ImageAspectFlagBits::eDepth : vk::ImageAspectFlagBits::eColor;
uint32_t srcWidth = image.m_width;
uint32_t srcHeight = image.m_height;
uint32_t srcDepth = image.m_depth;
auto half = [](uint32_t in) {
return std::max<uint32_t>(in / 2, 1);
};
uint32_t dstWidth = half(image.m_width);
uint32_t dstHeight = half(image.m_height);
uint32_t dstDepth = half(image.m_depth);
for (uint32_t srcMip = 0; srcMip < image.m_viewPerMip.size() - 1; srcMip++) {
uint32_t dstMip = srcMip + 1;
vk::ImageBlit region(
vk::ImageSubresourceLayers(aspectMask, srcMip, 0, 1),
{ vk::Offset3D(0, 0, 0), vk::Offset3D(srcWidth, srcHeight, srcDepth) },
vk::ImageSubresourceLayers(aspectMask, dstMip, 0, 1),
{ vk::Offset3D(0, 0, 0), vk::Offset3D(dstWidth, dstHeight, dstDepth) });
cmdBuffer.blitImage(
image.m_handle,
vk::ImageLayout::eGeneral,
image.m_handle,
vk::ImageLayout::eGeneral,
region,
vk::Filter::eLinear);
srcWidth = dstWidth;
srcHeight = dstHeight;
srcDepth = dstDepth;
dstWidth = half(dstWidth);
dstHeight = half(dstHeight);
dstDepth = half(dstDepth);
recordImageMemoryBarrier(handle, cmdBuffer);
}
}; };
m_core->recordAndSubmitCommandsImmediate(submitInfo, record, nullptr); m_core->recordAndSubmitCommandsImmediate(submitInfo, record, nullptr);
} }
void ImageManager::recordImageMipChainGenerationToCmdStream(
const vkcv::CommandStreamHandle& cmdStream,
const ImageHandle& handle) {
const auto record = [this, handle](const vk::CommandBuffer cmdBuffer) {
recordImageMipGenerationToCmdBuffer(cmdBuffer, handle);
};
m_core->recordCommandsToStream(cmdStream, record, nullptr);
}
uint32_t ImageManager::getImageWidth(const ImageHandle &handle) const { uint32_t ImageManager::getImageWidth(const ImageHandle &handle) const {
const uint64_t id = handle.getId(); const uint64_t id = handle.getId();
const bool isSwapchainImage = handle.isSwapchainImage(); const bool isSwapchainImage = handle.isSwapchainImage();
......
...@@ -60,7 +60,9 @@ namespace vkcv { ...@@ -60,7 +60,9 @@ namespace vkcv {
* @param id Image handle id * @param id Image handle id
*/ */
void destroyImageById(uint64_t id); void destroyImageById(uint64_t id);
void recordImageMipGenerationToCmdBuffer(vk::CommandBuffer cmdBuffer, const ImageHandle& handle);
public: public:
~ImageManager() noexcept; ~ImageManager() noexcept;
ImageManager(ImageManager&& other) = delete; ImageManager(ImageManager&& other) = delete;
...@@ -101,6 +103,7 @@ namespace vkcv { ...@@ -101,6 +103,7 @@ namespace vkcv {
void fillImage(const ImageHandle& handle, void* data, size_t size); void fillImage(const ImageHandle& handle, void* data, size_t size);
void generateImageMipChainImmediate(const ImageHandle& handle); void generateImageMipChainImmediate(const ImageHandle& handle);
void recordImageMipChainGenerationToCmdStream(const vkcv::CommandStreamHandle& cmdStream, const ImageHandle& handle);
[[nodiscard]] [[nodiscard]]
uint32_t getImageWidth(const ImageHandle& handle) const; uint32_t getImageWidth(const ImageHandle& handle) const;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment