diff --git a/src/refresh/vkpt/fsr.c b/src/refresh/vkpt/fsr.c index 788c873e5..9a44afba3 100644 --- a/src/refresh/vkpt/fsr.c +++ b/src/refresh/vkpt/fsr.c @@ -25,7 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc., enum { FSR_EASU, - FSR_RCAS, + FSR_RCAS_AFTER_EASU, + FSR_RCAS_AFTER_TAAU, FSR_NUM_PIPELINES }; @@ -33,6 +34,7 @@ static VkPipeline pipeline_fsr[FSR_NUM_PIPELINES]; static VkPipelineLayout pipeline_layout_fsr; cvar_t *cvar_flt_fsr_enable = NULL; +cvar_t *cvar_flt_fsr_easu = NULL; cvar_t *cvar_flt_fsr_rcas = NULL; cvar_t *cvar_flt_fsr_sharpness = NULL; @@ -40,6 +42,8 @@ void vkpt_fsr_init_cvars() { // FSR enable toggle cvar_flt_fsr_enable = Cvar_Get("flt_fsr_enable", "0", CVAR_ARCHIVE); + // FSR EASU (upscaling) toggle + cvar_flt_fsr_easu = Cvar_Get("flt_fsr_easu", "1", CVAR_ARCHIVE); // FSR RCAS (sharpening) toggle cvar_flt_fsr_rcas = Cvar_Get("flt_fsr_rcas", "1", CVAR_ARCHIVE); // FSR sharpness setting (float, 0..2) @@ -73,15 +77,34 @@ vkpt_fsr_destroy() VkResult vkpt_fsr_create_pipelines() { + VkSpecializationMapEntry specEntries[] = { + { .constantID = 0, .offset = 0, .size = sizeof(uint32_t) } + }; + + uint32_t spec_data[] = { + 0, + 1 + }; + + VkSpecializationInfo specInfo[] = { + { .mapEntryCount = 1, .pMapEntries = specEntries, .dataSize = sizeof(uint32_t), .pData = &spec_data[0] }, + { .mapEntryCount = 1, .pMapEntries = specEntries, .dataSize = sizeof(uint32_t), .pData = &spec_data[1] }, + }; + VkComputePipelineCreateInfo pipeline_info[FSR_NUM_PIPELINES] = { [FSR_EASU] = { .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, .stage = SHADER_STAGE(QVK_MOD_FSR_EASU_COMP, VK_SHADER_STAGE_COMPUTE_BIT), .layout = pipeline_layout_fsr, }, - [FSR_RCAS] = { + [FSR_RCAS_AFTER_EASU] = { .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, - .stage = SHADER_STAGE(QVK_MOD_FSR_RCAS_COMP, VK_SHADER_STAGE_COMPUTE_BIT), + .stage = SHADER_STAGE_SPEC(QVK_MOD_FSR_RCAS_COMP, VK_SHADER_STAGE_COMPUTE_BIT, &specInfo[0]), + .layout = pipeline_layout_fsr, + }, + [FSR_RCAS_AFTER_TAAU] = { + .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + .stage = SHADER_STAGE_SPEC(QVK_MOD_FSR_RCAS_COMP, VK_SHADER_STAGE_COMPUTE_BIT, &specInfo[1]), .layout = pipeline_layout_fsr, }, }; @@ -99,6 +122,16 @@ vkpt_fsr_destroy_pipelines() return VK_SUCCESS; } +qboolean vkpt_fsr_is_enabled() +{ + return (cvar_flt_fsr_enable->integer != 0) && ((cvar_flt_fsr_easu->integer != 0) || (cvar_flt_fsr_rcas->integer != 0)); +} + +qboolean vkpt_fsr_needs_upscale() +{ + return cvar_flt_fsr_easu->integer == 0; +} + void vkpt_fsr_update_ubo(QVKUniformBuffer_t *ubo) { FsrEasuCon(&ubo->easu_const0[0], &ubo->easu_const1[0], &ubo->easu_const2[0], &ubo->easu_const3[0], @@ -161,7 +194,7 @@ static void vkpt_fsr_rcas(VkCommandBuffer cmd_buf) BEGIN_PERF_MARKER(cmd_buf, PROFILER_FSR_RCAS); - vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_fsr[FSR_RCAS]); + vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_fsr[cvar_flt_fsr_easu->integer != 0 ? FSR_RCAS_AFTER_EASU : FSR_RCAS_AFTER_TAAU]); vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout_fsr, 0, LENGTH(desc_sets), desc_sets, 0, 0); @@ -181,7 +214,8 @@ VkResult vkpt_fsr_do(VkCommandBuffer cmd_buf) { BEGIN_PERF_MARKER(cmd_buf, PROFILER_FSR); - vkpt_fsr_easu(cmd_buf); + if(cvar_flt_fsr_easu->integer != 0) + vkpt_fsr_easu(cmd_buf); if(cvar_flt_fsr_rcas->integer != 0) vkpt_fsr_rcas(cmd_buf); diff --git a/src/refresh/vkpt/main.c b/src/refresh/vkpt/main.c index 447561654..b8f155c66 100644 --- a/src/refresh/vkpt/main.c +++ b/src/refresh/vkpt/main.c @@ -76,7 +76,6 @@ extern cvar_t *cvar_bloom_enable; extern cvar_t* cvar_flt_taa; static int drs_current_scale = 0; static int drs_effective_scale = 0; -extern cvar_t *cvar_flt_fsr_enable; cvar_t* cvar_min_driver_version_nvidia = NULL; cvar_t* cvar_min_driver_version_amd = NULL; @@ -2359,11 +2358,19 @@ evaluate_taa_settings(const reference_mode_t* ref_mode) if (!ref_mode->enable_denoiser) return; - if (cvar_flt_taa->integer == AA_MODE_TAA) + int flt_taa = cvar_flt_taa->integer; + // FSR RCAS needs upscaled input; if EASU was disabled, force to TAAU + qboolean force_upscaling = vkpt_fsr_is_enabled() && vkpt_fsr_needs_upscale(); + if(force_upscaling) + { + flt_taa = AA_MODE_UPSCALE; + } + + if (flt_taa == AA_MODE_TAA) { qvk.effective_aa_mode = AA_MODE_TAA; } - else if (cvar_flt_taa->integer == AA_MODE_UPSCALE) // TAAU or TAA+FSR + else if (flt_taa == AA_MODE_UPSCALE) // TAAU or TAA+FSR { if (qvk.extent_render.width > qvk.extent_unscaled.width || qvk.extent_render.height > qvk.extent_unscaled.height) { @@ -2372,7 +2379,7 @@ evaluate_taa_settings(const reference_mode_t* ref_mode) else { qvk.effective_aa_mode = AA_MODE_UPSCALE; - if (cvar_flt_fsr_enable->integer == 0) + if (!vkpt_fsr_is_enabled() || force_upscaling) qvk.extent_taa_output = qvk.extent_unscaled; } } @@ -2531,7 +2538,7 @@ prepare_ubo(refdef_t *fd, mleaf_t* viewleaf, const reference_mode_t* ref_mode, c ubo->pt_ndf_trim = 1.f; } } - else if((cvar_flt_fsr_enable->integer != 0) || (qvk.effective_aa_mode == AA_MODE_UPSCALE)) + else if(vkpt_fsr_is_enabled() || (qvk.effective_aa_mode == AA_MODE_UPSCALE)) { // adjust texture LOD bias to the resolution scale, i.e. use negative bias if scale is < 100 float resolution_scale = (drs_effective_scale != 0) ? (float)drs_effective_scale : (float)scr_viewsize->integer; @@ -2605,7 +2612,7 @@ prepare_ubo(refdef_t *fd, mleaf_t* viewleaf, const reference_mode_t* ref_mode, c } // Set up constants for FSR - if (cvar_flt_fsr_enable->integer != 0) + if (vkpt_fsr_is_enabled()) { vkpt_fsr_update_ubo(ubo); } @@ -2941,7 +2948,7 @@ R_RenderFrame_RTX(refdef_t *fd) } END_PERF_MARKER(post_cmd_buf, PROFILER_TONE_MAPPING); - if(cvar_flt_fsr_enable->integer != 0) + if(vkpt_fsr_is_enabled()) { vkpt_fsr_do(post_cmd_buf); } @@ -3201,7 +3208,7 @@ R_EndFrame_RTX(void) if (frame_ready) { - if (cvar_flt_fsr_enable->integer != 0) + if (vkpt_fsr_is_enabled()) { vkpt_fsr_final_blit(cmd_buf); } diff --git a/src/refresh/vkpt/shader/fsr_rcas.comp b/src/refresh/vkpt/shader/fsr_rcas.comp index ec71b3ac4..ffa235137 100644 --- a/src/refresh/vkpt/shader/fsr_rcas.comp +++ b/src/refresh/vkpt/shader/fsr_rcas.comp @@ -21,6 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable +layout(constant_id = 0) const uint spec_input_tex = 0; + #include "utils.glsl" #define GLOBAL_UBO_DESC_SET_IDX 0 @@ -40,10 +42,14 @@ with this program; if not, write to the Free Software Foundation, Inc., layout(local_size_x=64) in; -// Input: TEX_FSR_EASU_OUTPUT AF4 FsrRcasLoadF(ASU2 p) { - return texelFetch(TEX_FSR_EASU_OUTPUT, ivec2(p), 0); + if(spec_input_tex == 0) + // RCAS after EASU + return texelFetch(TEX_FSR_EASU_OUTPUT, ivec2(p), 0); + else + // RCAS after TAAU + return texelFetch(TEX_TAA_OUTPUT, ivec2(p), 0); } void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {} diff --git a/src/refresh/vkpt/vkpt.h b/src/refresh/vkpt/vkpt.h index 774118537..4b3f737eb 100644 --- a/src/refresh/vkpt/vkpt.h +++ b/src/refresh/vkpt/vkpt.h @@ -637,6 +637,8 @@ VkResult vkpt_fsr_initialize(); VkResult vkpt_fsr_destroy(); VkResult vkpt_fsr_create_pipelines(); VkResult vkpt_fsr_destroy_pipelines(); +qboolean vkpt_fsr_is_enabled(); +qboolean vkpt_fsr_needs_upscale(); void vkpt_fsr_update_ubo(QVKUniformBuffer_t *ubo); VkResult vkpt_fsr_do(VkCommandBuffer cmd_buf); VkResult vkpt_fsr_final_blit(VkCommandBuffer cmd_buf);