Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2073,4 +2073,12 @@ if(BUILD_UNIT_TESTS)
target_include_directories(unit_macros PRIVATE ${CMAKE_SOURCE_DIR}/src)
add_test(NAME unit_macros COMMAND unit_macros)
set_tests_properties(unit_macros PROPERTIES LABELS "unit;validation")

add_executable(unit_vk_postfx_sanitize
tests/unit/test_vk_postfx_sanitize.c
src/renderers/vulkan/vk_postfx_sanitize.c)
target_include_directories(unit_vk_postfx_sanitize PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_link_libraries(unit_vk_postfx_sanitize PRIVATE m)
add_test(NAME unit_vk_postfx_sanitize COMMAND unit_vk_postfx_sanitize)
set_tests_properties(unit_vk_postfx_sanitize PROPERTIES LABELS "unit;validation")
endif()
25 changes: 15 additions & 10 deletions src/renderers/vulkan/vk_postfx_params.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "vk.h"
#include "vk_postfx.h"
#include "vk_postfx_params.h"
#include "vk_postfx_sanitize.h"
#include "vk_temporal.h"
#include "vk_util.h"
#include <math.h>
Expand Down Expand Up @@ -121,20 +122,24 @@ void vk_update_postfx_params( uint32_t cmd_index )
r_localExposure_strength = ri.Cvar_Get( "r_localExposure_strength", "0.35", 0 );
r_localExposure_shadowClamp = ri.Cvar_Get( "r_localExposure_shadowClamp", "1.5", 0 );
r_localExposure_highlightClamp = ri.Cvar_Get( "r_localExposure_highlightClamp", "1.5", 0 );
params.autoExposureParams[0] = vk.temporal.hasValidLuminance ? vk.temporal.filteredAvgLogLuminance :
log2f( fmaxf( 1e-4f, ( r_autoExposure_target ? r_autoExposure_target->value : 1.0f ) /
fmaxf( r_exposure ? r_exposure->value : 1.0f, 1e-4f ) ) );
params.autoExposureParams[1] = fmaxf( r_autoExposure_target ? r_autoExposure_target->value : 1.0f, 1e-4f );
params.autoExposureParams[2] = fmaxf( r_autoExposure_min ? r_autoExposure_min->value : 0.5f, 0.01f );
params.autoExposureParams[3] = fmaxf( r_autoExposure_max ? r_autoExposure_max->value : 4.0f, params.autoExposureParams[2] );
vk_postfx_sanitize_auto_exposure_params(
vk.temporal.hasValidLuminance ? 1 : 0,
vk.temporal.filteredAvgLogLuminance,
r_autoExposure_target ? r_autoExposure_target->value : 1.0f,
r_exposure ? r_exposure->value : 1.0f,
r_autoExposure_min ? r_autoExposure_min->value : 0.5f,
r_autoExposure_max ? r_autoExposure_max->value : 4.0f,
params.autoExposureParams );
params.localExposureParams[0] = ( r_localExposure && r_localExposure->integer ) ? 1.0f : 0.0f;
params.localExposureParams[1] = Com_Clamp( 0.0f, 1.0f, r_localExposure_strength ? r_localExposure_strength->value : 0.35f );
params.localExposureParams[2] = Com_Clamp( 0.0f, 3.0f, r_localExposure_shadowClamp ? r_localExposure_shadowClamp->value : 1.5f );
params.localExposureParams[3] = Com_Clamp( 0.0f, 3.0f, r_localExposure_highlightClamp ? r_localExposure_highlightClamp->value : 1.5f );
params.taaParams[0] = vk.temporal.hasValidTAAHistory ? 1.0f : 0.0f;
params.taaParams[1] = Com_Clamp( 0.0f, 0.99f, r_taa_feedbackStationary ? r_taa_feedbackStationary->value : 0.92f );
params.taaParams[2] = Com_Clamp( 0.0f, 0.99f, r_taa_feedbackMotion ? r_taa_feedbackMotion->value : 0.72f );
params.taaParams[3] = Com_Clamp( 0.0f, 1.0f, r_taa_sharpen ? r_taa_sharpen->value : 0.12f );
vk_postfx_sanitize_taa_params(
vk.temporal.hasValidTAAHistory ? 1 : 0,
r_taa_feedbackStationary ? r_taa_feedbackStationary->value : 0.92f,
r_taa_feedbackMotion ? r_taa_feedbackMotion->value : 0.72f,
r_taa_sharpen ? r_taa_sharpen->value : 0.12f,
params.taaParams );

if ( backEnd.projection2D || !tr.world || backEnd.viewParms.portalView != PV_NONE ) {
Com_Memcpy( vk.postfx_params_ptr[cmd_index], &params, sizeof( params ) );
Expand Down
56 changes: 56 additions & 0 deletions src/renderers/vulkan/vk_postfx_sanitize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "vk_postfx_sanitize.h"
#include <math.h>

static float vk_postfx_clamp( float min_value, float max_value, float value )
{
if ( value < min_value ) {
return min_value;
}
if ( value > max_value ) {
return max_value;
}
return value;
}

void vk_postfx_sanitize_taa_params( int has_valid_history,
float stationary_feedback,
float motion_feedback,
float sharpen,
float out_taa_params[4] )
{
if ( !out_taa_params ) {
return;
}

out_taa_params[0] = has_valid_history ? 1.0f : 0.0f;
out_taa_params[1] = vk_postfx_clamp( 0.0f, 0.99f, stationary_feedback );
out_taa_params[2] = vk_postfx_clamp( 0.0f, 0.99f, motion_feedback );
out_taa_params[3] = vk_postfx_clamp( 0.0f, 1.0f, sharpen );
}

void vk_postfx_sanitize_auto_exposure_params( int has_valid_luminance,
float filtered_avg_log_luminance,
float auto_target_luminance,
float manual_exposure,
float min_exposure,
float max_exposure,
float out_auto_exposure_params[4] )
{
const float safe_manual_exposure = fmaxf( manual_exposure, 1e-4f );
const float safe_target = fmaxf( auto_target_luminance, 1e-4f );
const float safe_min_exposure = fmaxf( min_exposure, 0.01f );
const float safe_max_exposure = fmaxf( max_exposure, safe_min_exposure );

if ( !out_auto_exposure_params ) {
return;
}

if ( has_valid_luminance ) {
out_auto_exposure_params[0] = filtered_avg_log_luminance;
} else {
out_auto_exposure_params[0] = log2f( safe_target / safe_manual_exposure );
}
out_auto_exposure_params[1] = safe_target;
out_auto_exposure_params[2] = safe_min_exposure;
out_auto_exposure_params[3] = safe_max_exposure;
}
26 changes: 26 additions & 0 deletions src/renderers/vulkan/vk_postfx_sanitize.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef VK_POSTFX_SANITIZE_H
#define VK_POSTFX_SANITIZE_H

#ifdef __cplusplus
extern "C" {
#endif

void vk_postfx_sanitize_taa_params( int has_valid_history,
float stationary_feedback,
float motion_feedback,
float sharpen,
float out_taa_params[4] );

void vk_postfx_sanitize_auto_exposure_params( int has_valid_luminance,
float filtered_avg_log_luminance,
float auto_target_luminance,
float manual_exposure,
float min_exposure,
float max_exposure,
float out_auto_exposure_params[4] );

#ifdef __cplusplus
}
#endif

#endif
49 changes: 49 additions & 0 deletions tests/unit/test_vk_postfx_sanitize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <math.h>
#include <stdio.h>

#include "renderers/vulkan/vk_postfx_sanitize.h"

#define ASSERT_TRUE(cond, msg) do { \
if ( !( cond ) ) { \
fprintf( stderr, "FAIL: %s\n", msg ); \
return 1; \
} \
} while ( 0 )

static int almost_equal( float a, float b )
{
return fabsf( a - b ) < 1e-6f;
}

int main( void )
{
float taa[4] = { 0.0f };
float exposure[4] = { 0.0f };

vk_postfx_sanitize_taa_params( 1, 1.3f, -0.1f, 1.4f, taa );
ASSERT_TRUE( almost_equal( taa[0], 1.0f ), "taa history flag" );
ASSERT_TRUE( almost_equal( taa[1], 0.99f ), "taa stationary clamp high" );
ASSERT_TRUE( almost_equal( taa[2], 0.0f ), "taa motion clamp low" );
ASSERT_TRUE( almost_equal( taa[3], 1.0f ), "taa sharpen clamp high" );

vk_postfx_sanitize_taa_params( 0, 0.92f, 0.72f, 0.12f, taa );
ASSERT_TRUE( almost_equal( taa[0], 0.0f ), "taa history disabled" );
ASSERT_TRUE( almost_equal( taa[1], 0.92f ), "taa stationary passthrough" );
ASSERT_TRUE( almost_equal( taa[2], 0.72f ), "taa motion passthrough" );
ASSERT_TRUE( almost_equal( taa[3], 0.12f ), "taa sharpen passthrough" );

vk_postfx_sanitize_auto_exposure_params( 0, 2.0f, 0.0f, 0.0f, -1.0f, -3.0f, exposure );
ASSERT_TRUE( almost_equal( exposure[0], 0.0f ), "auto exposure fallback log2 target/manual" );
ASSERT_TRUE( almost_equal( exposure[1], 1e-4f ), "auto exposure target floor" );
ASSERT_TRUE( almost_equal( exposure[2], 0.01f ), "auto exposure min floor" );
ASSERT_TRUE( almost_equal( exposure[3], 0.01f ), "auto exposure max floored to min" );

vk_postfx_sanitize_auto_exposure_params( 1, 1.5f, 0.8f, 2.0f, 0.25f, 4.0f, exposure );
ASSERT_TRUE( almost_equal( exposure[0], 1.5f ), "auto exposure uses valid luminance" );
ASSERT_TRUE( almost_equal( exposure[1], 0.8f ), "auto exposure target passthrough" );
ASSERT_TRUE( almost_equal( exposure[2], 0.25f ), "auto exposure min passthrough" );
ASSERT_TRUE( almost_equal( exposure[3], 4.0f ), "auto exposure max passthrough" );

printf( "PASS: unit_vk_postfx_sanitize\n" );
return 0;
}
Loading