Skip to content
Snippets Groups Projects
Verified Commit 2d555684 authored by Tobias Frisch's avatar Tobias Frisch
Browse files

Add remaining helper functions

parent 880b06c4
Branches
Tags
1 merge request!107Resolve "Include FSR 2.0 in the upscaling module"
......@@ -10,11 +10,69 @@
namespace vkcv::upscaling {
/**
/**
* @addtogroup vkcv_upscaling
* @{
*/
/**
* Enum to set the mode of quality for
* FSR2 upscaling.
*/
enum class FSR2QualityMode : int {
/**
* Don't upscale anything.
*/
NONE = 0,
/**
* High quality of FSR upscaling:
* 1.5x per dimension
*/
QUALITY = 2,
/**
* Medium quality of FSR upscaling:
* 1.7x per dimension
*/
BALANCED = 3,
/**
* Low quality of FSR upscaling:
* 2.0x per dimension
*/
PERFORMANCE = 4,
/**
* Lowest quality of FSR upscaling:
* 3.0x per dimension
*/
ULTRA_PERFORMANCE = 5,
};
/**
* Calculates the internal resolution for actual rendering if
* a specific mode of quality is used for upscaling with FSR2.
*
* @param[in] mode Mode of quality
* @param[in] outputWidth Final resolution width
* @param[in] outputHeight Final resolution height
* @param[out] inputWidth Internal resolution width
* @param[out] inputHeight Internal resolution height
*/
void getFSR2Resolution(FSR2QualityMode mode,
uint32_t outputWidth, uint32_t outputHeight,
uint32_t &inputWidth, uint32_t &inputHeight);
/**
* Returns the matching negative lod bias to reduce artifacts
* upscaling with FSR2 under a given mode of quality.
*
* @param mode Mode of quality
* @return Lod bias
*/
float getFSR2LodBias(FSR2QualityMode mode);
/**
* A class to handle upscaling via FidelityFX Super Resolution.
* https://github.com/GPUOpen-Effects/FidelityFX-FSR2
......@@ -29,6 +87,8 @@ namespace vkcv::upscaling {
ImageHandle m_depth;
ImageHandle m_velocity;
uint32_t m_frameIndex;
float m_frameDeltaTime;
bool m_reset;
......@@ -83,6 +143,20 @@ namespace vkcv::upscaling {
*/
void update(float deltaTime, bool reset = false);
/**
* Calculates the jitter offset for the projection
* matrix of the camera to use in the current frame.
*
* @param[in] renderWidth Render resolution width
* @param[in] renderHeight Render resolution height
* @param[out] jitterOffsetX Jitter offset x-coordinate
* @param[out] jitterOffsetY Jitter offset y-coordinate
*/
void calcJitterOffset(uint32_t renderWidth,
uint32_t renderHeight,
float& jitterOffsetX,
float& jitterOffsetY);
/**
* Bind the depth buffer image to use with the FSR2
* upscaling instance for utilizing depth information.
......
......@@ -45,12 +45,6 @@ namespace vkcv::upscaling {
* 2.0x per dimension
*/
PERFORMANCE = 4,
/**
* Lowest quality of FSR upscaling:
* 3.0x per dimension
*/
ULTRA_PERFORMANCE = 5,
};
/**
......
#include "vkcv/upscaling/FSR2Upscaling.hpp"
#include <cmath>
#define FFX_GCC
#include <ffx_fsr2_vk.h>
#undef FFX_GCC
namespace vkcv::upscaling {
void getFSR2Resolution(FSR2QualityMode mode,
uint32_t outputWidth, uint32_t outputHeight,
uint32_t &inputWidth, uint32_t &inputHeight) {
float scale;
switch (mode) {
case FSR2QualityMode::QUALITY:
scale = 1.5f;
break;
case FSR2QualityMode::BALANCED:
scale = 1.7f;
break;
case FSR2QualityMode::PERFORMANCE:
scale = 2.0f;
break;
case FSR2QualityMode::ULTRA_PERFORMANCE:
scale = 3.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)
);
}
float getFSR2LodBias(FSR2QualityMode mode) {
switch (mode) {
case FSR2QualityMode::QUALITY:
return -1.58f;
case FSR2QualityMode::BALANCED:
return -1.76f;
case FSR2QualityMode::PERFORMANCE:
return -2.0f;
case FSR2QualityMode::ULTRA_PERFORMANCE:
return -2.58f;
default:
return 0.0f;
}
}
void FSR2Upscaling::createFSR2Context(uint32_t displayWidth,
uint32_t displayHeight,
uint32_t renderWidth,
......@@ -30,6 +79,8 @@ namespace vkcv::upscaling {
m_core.getContext().getDevice().waitIdle();
assert(ffxFsr2ContextDestroy(&m_context) == FFX_OK);
m_frameIndex = 0;
}
FSR2Upscaling::FSR2Upscaling(Core &core) : Upscaling(core) {
......@@ -60,10 +111,33 @@ namespace vkcv::upscaling {
}
void FSR2Upscaling::update(float deltaTime, bool reset) {
if (reset) {
m_frameIndex = 0;
}
m_frameDeltaTime = deltaTime;
m_reset = reset;
}
void FSR2Upscaling::calcJitterOffset(uint32_t renderWidth,
uint32_t renderHeight,
float &jitterOffsetX,
float &jitterOffsetY) {
const int32_t phaseCount = ffxFsr2GetJitterPhaseCount(
renderWidth,
renderHeight
);
const int32_t phaseIndex = (static_cast<int32_t>(m_frameIndex) % phaseCount);
assert(ffxFsr2GetJitterOffset(
&jitterOffsetX,
&jitterOffsetY,
phaseIndex,
phaseCount
) == FFX_OK);
}
void FSR2Upscaling::bindDepthBuffer(const ImageHandle &depthInput) {
m_depth = depthInput;
}
......@@ -166,11 +240,15 @@ namespace vkcv::upscaling {
static_cast<VkFormat>(m_core.getImageFormat(output))
);
dispatch.jitterOffset.x = 0;
dispatch.jitterOffset.y = 0;
calcJitterOffset(
inputWidth,
inputHeight,
dispatch.jitterOffset.x,
dispatch.jitterOffset.y
);
dispatch.motionVectorScale.x = 0;
dispatch.motionVectorScale.y = 0;
dispatch.motionVectorScale.x = static_cast<float>(inputWidth);
dispatch.motionVectorScale.y = static_cast<float>(inputHeight);
dispatch.renderSize.width = inputWidth;
dispatch.renderSize.height = inputHeight;
......@@ -194,6 +272,7 @@ namespace vkcv::upscaling {
&dispatch
) == FFX_OK);
m_frameIndex++;
m_reset = false;
});
}
......
......@@ -36,9 +36,6 @@ namespace vkcv::upscaling {
case FSRQualityMode::PERFORMANCE:
scale = 2.0f;
break;
case FSRQualityMode::ULTRA_PERFORMANCE:
scale = 3.0f;
break;
default:
scale = 1.0f;
break;
......@@ -63,8 +60,6 @@ namespace vkcv::upscaling {
return -0.79f;
case FSRQualityMode::PERFORMANCE:
return -1.0f;
case FSRQualityMode::ULTRA_PERFORMANCE:
return -2.0f;
default:
return 0.0f;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment