From d38defae25196b543255efb9236b3e0e89a9a014 Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Sat, 18 Jun 2022 19:05:51 +0200
Subject: [PATCH] Correct SPD fallback mechanic for safe downsampling

Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de>
---
 .../vkcv/algorithm/SinglePassDownsampler.cpp  | 28 ++++++++++++++++---
 modules/scene/src/vkcv/scene/Scene.cpp        | 18 ++----------
 2 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/modules/algorithm/src/vkcv/algorithm/SinglePassDownsampler.cpp b/modules/algorithm/src/vkcv/algorithm/SinglePassDownsampler.cpp
index ea6331b0..d022fbed 100644
--- a/modules/algorithm/src/vkcv/algorithm/SinglePassDownsampler.cpp
+++ b/modules/algorithm/src/vkcv/algorithm/SinglePassDownsampler.cpp
@@ -146,7 +146,7 @@ namespace vkcv::algorithm {
 		 vkcv::Downsampler(core),
 		 m_pipeline(),
 		
-		 m_descriptorSetLayout(m_core.createDescriptorSetLayout(getDescriptorBindings(sampler))),
+		 m_descriptorSetLayout(),
 		 m_descriptorSets(),
 		
 		 m_globalCounter(m_core.createBuffer<uint32_t>(
@@ -155,6 +155,21 @@ namespace vkcv::algorithm {
 		 )),
 		 
 		 m_sampler(sampler) {
+		const auto& featureManager = m_core.getContext().getFeatureManager();
+		
+		const bool partialBound = featureManager.checkFeatures<vk::PhysicalDeviceDescriptorIndexingFeatures>(
+				vk::StructureType::ePhysicalDeviceDescriptorIndexingFeatures,
+				[](const vk::PhysicalDeviceDescriptorIndexingFeatures& features) {
+					return features.descriptorBindingPartiallyBound;
+				}
+		);
+		
+		if (!partialBound) {
+			return;
+		}
+		
+		m_descriptorSetLayout = m_core.createDescriptorSetLayout(getDescriptorBindings(sampler));
+		
 		vkcv::shader::GLSLCompiler compiler (vkcv::shader::GLSLCompileTarget::SUBGROUP_OP);
 		
 		vk::PhysicalDeviceSubgroupProperties subgroupProperties;
@@ -169,8 +184,6 @@ namespace vkcv::algorithm {
 			compiler.setDefine("SPD_NO_WAVE_OPERATIONS", "1");
 		}
 		
-		const auto& featureManager = m_core.getContext().getFeatureManager();
-		
 		const bool float16Support = (
 				featureManager.checkFeatures<vk::PhysicalDeviceFloat16Int8FeaturesKHR>(
 						vk::StructureType::ePhysicalDeviceShaderFloat16Int8FeaturesKHR,
@@ -229,13 +242,20 @@ namespace vkcv::algorithm {
 	
 	void SinglePassDownsampler::recordDownsampling(const CommandStreamHandle &cmdStream,
 												   const ImageHandle &image) {
+		Downsampler& fallback = m_core.getDownsampler();
+		
+		if (m_pipeline) {
+			fallback.recordDownsampling(cmdStream, image);
+			return;
+		}
+		
 		const uint32_t mipLevels = m_core.getImageMipLevels(image);
 		const uint32_t depth = m_core.getImageDepth(image);
 		
 		m_core.prepareImageForSampling(cmdStream, image);
 		
 		if ((mipLevels < 4) || (depth > 1) || (!m_core.isImageSupportingStorage(image))) {
-			m_core.getDownsampler().recordDownsampling(cmdStream, image);
+			fallback.recordDownsampling(cmdStream, image);
 			return;
 		}
 		
diff --git a/modules/scene/src/vkcv/scene/Scene.cpp b/modules/scene/src/vkcv/scene/Scene.cpp
index cb819370..9a8ded0f 100644
--- a/modules/scene/src/vkcv/scene/Scene.cpp
+++ b/modules/scene/src/vkcv/scene/Scene.cpp
@@ -284,26 +284,12 @@ namespace vkcv::scene {
 		);
 		
 		const vkcv::FeatureManager& featureManager = core.getContext().getFeatureManager();
-		const bool partialBound = featureManager.checkFeatures<vk::PhysicalDeviceDescriptorIndexingFeatures>(
-				vk::StructureType::ePhysicalDeviceDescriptorIndexingFeatures,
-				[](const vk::PhysicalDeviceDescriptorIndexingFeatures& features) {
-					return features.descriptorBindingPartiallyBound;
-				}
-		);
 		
-		vkcv::Downsampler& downsampler = core.getDownsampler();
 		vkcv::algorithm::SinglePassDownsampler spdDownsampler (core, sampler);
-		
 		auto mipStream = core.createCommandStream(vkcv::QueueType::Graphics);
 		
-		if (partialBound) {
-			for (auto& material : scene.m_materials) {
-				material.m_data.recordMipChainGeneration(mipStream, spdDownsampler);
-			}
-		} else {
-			for (auto& material : scene.m_materials) {
-				material.m_data.recordMipChainGeneration(mipStream, downsampler);
-			}
+		for (auto& material : scene.m_materials) {
+			material.m_data.recordMipChainGeneration(mipStream, spdDownsampler);
 		}
 		
 		core.submitCommandStream(mipStream, false);
-- 
GitLab