From b3e2ed5749896a5c659f099eaa1425e96da2240e Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Mon, 19 Jul 2021 15:11:41 +0200
Subject: [PATCH] [#100] FSR modes enums

Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de>
---
 .../include/vkcv/upscaling/FSRUpscaling.hpp   | 12 ++++++
 .../src/vkcv/upscaling/FSRUpscaling.cpp       | 41 +++++++++++++++++-
 projects/voxelization/src/main.cpp            | 43 +++++++++----------
 3 files changed, 72 insertions(+), 24 deletions(-)

diff --git a/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp b/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp
index 274e1b99..955eb805 100644
--- a/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp
+++ b/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp
@@ -6,6 +6,18 @@
 
 namespace vkcv::upscaling {
 	
+	enum class FSRQualityMode : int {
+		NONE = 0,
+		ULTRA_QUALITY = 1,
+		QUALITY = 2,
+		BALANCED = 3,
+		PERFORMANCE = 4
+	};
+	
+	void getFSRResolution(FSRQualityMode mode,
+						  uint32_t outputWidth, uint32_t outputHeight,
+						  uint32_t &inputWidth, uint32_t &inputHeight);
+	
 	struct FSRConstants {
 		uint32_t Const0 [4];
 		uint32_t Const1 [4];
diff --git a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp
index 3d418c24..366e8561 100644
--- a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp
+++ b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp
@@ -18,6 +18,38 @@
 
 namespace vkcv::upscaling {
 	
+	void getFSRResolution(FSRQualityMode mode,
+						  uint32_t outputWidth, uint32_t outputHeight,
+						  uint32_t &inputWidth, uint32_t &inputHeight) {
+		float scale;
+		
+		switch (mode) {
+			case FSRQualityMode::ULTRA_QUALITY:
+				scale = 1.3f;
+				break;
+			case FSRQualityMode::QUALITY:
+				scale = 1.5f;
+				break;
+			case FSRQualityMode::BALANCED:
+				scale = 1.7f;
+				break;
+			case FSRQualityMode::PERFORMANCE:
+				scale = 2.0f;
+				break;
+			default:
+				scale = 1.0f;
+				break;
+		}
+		
+		inputWidth = static_cast<uint32_t>(
+				std::round(static_cast<float>(outputWidth) / scale)
+		);
+		
+		inputHeight = static_cast<uint32_t>(
+				std::round(static_cast<float>(outputHeight) / scale)
+		);
+	}
+	
 	static std::vector<DescriptorBinding> getDescriptorBindings() {
 		return std::vector<DescriptorBinding>({
 			DescriptorBinding(
@@ -215,6 +247,11 @@ namespace vkcv::upscaling {
 			m_core.prepareImageForStorage(cmdStream, m_intermediateImage);
 		}
 		
+		const bool rcasEnabled = (
+				(m_sharpness > +0.0f) &&
+				((inputWidth < outputWidth) || (inputHeight < outputHeight))
+		);
+		
 		{
 			FSRConstants consts = {};
 			
@@ -225,7 +262,7 @@ namespace vkcv::upscaling {
 					static_cast<AF1>(outputWidth), static_cast<AF1>(outputHeight)
 			);
 			
-			consts.Sample[0] = (((m_hdr) && (m_sharpness <= +0.0f)) ? 1 : 0);
+			consts.Sample[0] = (((m_hdr) && (!rcasEnabled)) ? 1 : 0);
 			
 			m_constants.fill(&consts, 1, 0);
 		}
@@ -239,7 +276,7 @@ namespace vkcv::upscaling {
 		
 		m_core.recordBufferMemoryBarrier(cmdStream, m_constants.getHandle());
 		
-		if (m_sharpness > +0.0f) {
+		if (rcasEnabled) {
 			{
 				DescriptorWrites writes;
 				writes.sampledImageWrites.emplace_back(1, input);
diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp
index 5763b653..8de24d2e 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -542,8 +542,16 @@ int main(int argc, const char** argv) {
 	vkcv::upscaling::FSRUpscaling upscaling (core);
 	uint32_t fsrWidth = windowWidth, fsrHeight = windowHeight;
 	
-	float fsrFactor = 1.5f;
-	float rcasSharpness = upscaling.getSharpness();
+	vkcv::upscaling::FSRQualityMode fsrMode = vkcv::upscaling::FSRQualityMode::NONE;
+	int fsrModeIndex = static_cast<int>(fsrMode);
+	
+	const std::vector<const char*> fsrModeNames = {
+			"None",
+			"Ultra Quality",
+			"Quality",
+			"Balanced",
+			"Performance"
+	};
 	
 	vkcv::gui::GUI gui(core, window);
 
@@ -573,15 +581,12 @@ int main(int argc, const char** argv) {
 			continue;
 		}
 		
-		if (fsrFactor < 1.0f) {
-			fsrFactor = 1.0f;
-		} else
-		if (fsrFactor > 2.0f) {
-			fsrFactor = 2.0f;
-		}
-		
-		const auto width = static_cast<uint32_t>(std::round(static_cast<float>(swapchainWidth) / fsrFactor));
-		const auto height = static_cast<uint32_t>(std::round(static_cast<float>(swapchainHeight) / fsrFactor));
+		uint32_t width, height;
+		vkcv::upscaling::getFSRResolution(
+				fsrMode,
+				swapchainWidth, swapchainHeight,
+				width, height
+		);
 
 		if ((width != fsrWidth) || ((height != fsrHeight))) {
 			fsrWidth = width;
@@ -799,16 +804,8 @@ int main(int argc, const char** argv) {
 		core.prepareImageForStorage(cmdStream, swapBuffer2);
 		core.prepareImageForSampling(cmdStream, swapBuffer);
 		
-		if (fsrFactor <= 1.0f) {
-			upscaling.setSharpness(0.0f);
-		}
-		
 		upscaling.recordUpscaling(cmdStream, swapBuffer, swapBuffer2);
 		
-		if (fsrFactor <= 1.0f) {
-			upscaling.setSharpness(rcasSharpness);
-		}
-		
 		core.prepareImageForStorage(cmdStream, swapchainInput);
 		core.prepareImageForSampling(cmdStream, swapBuffer2);
 		
@@ -868,10 +865,12 @@ int main(int argc, const char** argv) {
 			ImGui::ColorEdit3("Absorption color", &absorptionColor.x);
 			ImGui::DragFloat("Absorption density", &absorptionDensity, 0.0001);
 			ImGui::DragFloat("Volumetric ambient", &volumetricAmbient, 0.002);
-			ImGui::DragFloat("FidelityFX FSR Factor", &fsrFactor, 0.01f, 1.0f, 2.0f);
-			ImGui::DragFloat("RCAS Sharpness", &rcasSharpness, 0.01f, 0.0f, 1.0f);
 			
-			upscaling.setSharpness(rcasSharpness);
+			ImGui::Combo("FidelityFX FSR Quality Mode", &fsrModeIndex, fsrModeNames.data(), fsrModeNames.size());
+			
+			if ((fsrModeIndex >= 0) && (fsrModeIndex <= 4)) {
+				fsrMode = static_cast<vkcv::upscaling::FSRQualityMode>(fsrModeIndex);
+			}
 
 			if (ImGui::Button("Reload forward pass")) {
 
-- 
GitLab