diff --git a/Game/Resources_SoC_1.0006/gamedata/config/text/eng/ui_st_mm.xml b/Game/Resources_SoC_1.0006/gamedata/config/text/eng/ui_st_mm.xml
index 5f48be00fe..232dfbaed8 100644
--- a/Game/Resources_SoC_1.0006/gamedata/config/text/eng/ui_st_mm.xml
+++ b/Game/Resources_SoC_1.0006/gamedata/config/text/eng/ui_st_mm.xml
@@ -295,6 +295,63 @@
TAA
+
+ DLSS quality
+
+
+ DLSS preset
+
+
+ FSR3 quality
+
+
+ DLAA
+
+
+ Default
+
+
+ F (CNN)
+
+
+ J (Transformer)
+
+
+ K (Transformer)
+
+
+ L (Transformer)
+
+
+ M (Transformer)
+
+
+ Quality
+
+
+ Balanced
+
+
+ Performance
+
+
+ Ultra Performance
+
+
+ Native AA
+
+
+ Quality
+
+
+ Balanced
+
+
+ Performance
+
+
+ Ultra Performance
+
Antialiasing mode (R2)
@@ -886,6 +943,15 @@
Image upscaling in 3D scopes - r_3dss_scale_factor
+
+ DLSS quality - r_aa_dlss_quality
+
+
+ FSR3 quality - r_aa_fsr3_quality
+
+
+ DLSS preset - r_aa_dlss_preset
+
Motion blur - blurring of the image when turning the camera, playing scenes of movement or fast-moving objects.
@@ -1080,5 +1146,17 @@
If DLSS or FSR is enabled, this setting adjusts the scaling of the image in the 3D scopes to improve its clarity. %c[yellow] \nWhen set to 1, the image is not scaled. %c[green] \nOptimal value: 2. %c[red] \nValues ??greater than 2 may noticeably reduce FPS.
+
+ Sets the NVIDIA DLSS internal render scale. DLAA renders at native resolution for maximum image quality. Quality, Balanced, Performance and Ultra Performance render at progressively lower internal resolutions to gain FPS. Apply video settings or run vid_restart after changing this option.
+
+
+ Sets the AMD FSR3 internal render scale. Native AA renders at native resolution for maximum image quality. Quality, Balanced, Performance and Ultra Performance render at progressively lower internal resolutions to gain FPS. Apply video settings or run vid_restart after changing this option.
+
+
+ Selects the NVIDIA DLSS model. Presets not supported by the loaded DLSS library are grayed out.
+%c[yellow] \nCNN:\nF - legacy CNN model (deprecated).
+%c[green] \nTransformer:\nJ - less ghosting, more flicker (NVIDIA recommends K).\nK - 1st-gen transformer, default for DLAA / Quality / Balanced.\nL - 2nd-gen transformer, sharper and slower, default for Ultra Performance (RTX 40+).\nM - 2nd-gen transformer, similar to L but faster, default for Performance (RTX 40+).
+Default follows NVIDIA / driver OTA.
+
diff --git a/Game/Resources_SoC_1.0006/gamedata/config/text/rus/ui_st_mm.xml b/Game/Resources_SoC_1.0006/gamedata/config/text/rus/ui_st_mm.xml
index 24c75b1b71..de840e1972 100644
--- a/Game/Resources_SoC_1.0006/gamedata/config/text/rus/ui_st_mm.xml
+++ b/Game/Resources_SoC_1.0006/gamedata/config/text/rus/ui_st_mm.xml
@@ -289,6 +289,63 @@
AMD FSR3
+
+ Качество DLSS
+
+
+ Пресет DLSS
+
+
+ Качество FSR 3
+
+
+ DLAA
+
+
+ Default
+
+
+ F (CNN)
+
+
+ J (Transformer)
+
+
+ K (Transformer)
+
+
+ L (Transformer)
+
+
+ M (Transformer)
+
+
+ Качество
+
+
+ Баланс
+
+
+ Производительность
+
+
+ Ультрапроизводительность
+
+
+ Сглаживание в нативном разрешении
+
+
+ Качество
+
+
+ Баланс
+
+
+ Производительность
+
+
+ Ультрапроизводительность
+
TAA
@@ -861,6 +918,15 @@
Апскейлинг изображения в 3D прицелах - r_3dss_scale_factor
+
+ Качество DLSS - r_aa_dlss_quality
+
+
+ Качество FSR 3 - r_aa_fsr3_quality
+
+
+ Пресет DLSS - r_aa_dlss_preset
+
Motion blur - размытие изображения при повороте камеры, воспроизведении сцен движения или быстро движущихся объектов.
@@ -1046,5 +1112,17 @@
Если включен DLSS или FSR, эта настройка регулирует масштабирование изображения в 3D прицеле для улучшения его чёткости. %c[yellow] \nПри значении 1 изображение не масштабируется. %c[green] \nОптимальное значение: 2. %c[red] \nПри значениях больше 2 может заметно падать FPS.
+
+ Задаёт внутреннее разрешение NVIDIA DLSS. DLAA рендерит в нативном разрешении для максимального качества. Quality, Balanced, Performance и Ultra Performance постепенно снижают внутреннее разрешение ради FPS. После изменения примените видео настройки (vid_restart).
+
+
+ Задаёт внутреннее разрешение AMD FSR 3. Нативное сглаживание рендерит в нативном разрешении для максимального качества. Quality, Balanced, Performance и Ultra Performance постепенно снижают внутреннее разрешение ради FPS. После изменения примените видео настройки (vid_restart).
+
+
+ Выбор модели NVIDIA DLSS. Пресеты, которые не поддерживает загруженная библиотека DLSS, отображаются серым.
+%c[yellow] \nCNN:\nF — устаревшая CNN-модель (deprecated).
+%c[green] \nTransformer:\nJ — меньше шлейфов, больше мерцания (NVIDIA рекомендует K).\nK — трансформер 1-го поколения, по умолчанию для DLAA / Quality / Balanced.\nL — трансформер 2-го поколения, четче и медленнее, по умолчанию для Ultra Performance (RTX 40+).\nM — трансформер 2-го поколения, качество как у L, но быстрее, по умолчанию для Performance (RTX 40+).
+Default следует за NVIDIA / OTA драйвера.
+
diff --git a/Game/Resources_SoC_1.0006/gamedata/config/ui/ui_mm_opt.xml b/Game/Resources_SoC_1.0006/gamedata/config/ui/ui_mm_opt.xml
index 6fcbc9ee9e..4ece7ed89b 100644
--- a/Game/Resources_SoC_1.0006/gamedata/config/ui/ui_mm_opt.xml
+++ b/Game/Resources_SoC_1.0006/gamedata/config/ui/ui_mm_opt.xml
@@ -364,6 +364,45 @@
+
+ ui_mm_dlss_quality
+
+
+
+
+
+
+
+
+
+
+
+
+ ui_mm_dlss_preset
+
+
+
+
+
+
+
+
+
+
+
+
+ ui_mm_fsr3_quality
+
+
+
+
+
+
+
+
+
+
+
ui_mm_cas
diff --git a/Game/Resources_SoC_1.0006/gamedata/scripts/ui_mm_opt_main.script b/Game/Resources_SoC_1.0006/gamedata/scripts/ui_mm_opt_main.script
index ffb03535ca..2320324f2d 100644
--- a/Game/Resources_SoC_1.0006/gamedata/scripts/ui_mm_opt_main.script
+++ b/Game/Resources_SoC_1.0006/gamedata/scripts/ui_mm_opt_main.script
@@ -133,6 +133,10 @@ function options_dialog:OnPresetChanged()
opt:SetCurrentValues("mm_opt_video")
opt:SetCurrentValues("mm_opt_video_adv")
+ if self.dlg_video_adv and self.dlg_video_adv.UpdateUpscalerQualityRows then
+ self.dlg_video_adv:UpdateUpscalerQualityRows()
+ end
+
self:show_need_restart_wnd()
end
diff --git a/Game/Resources_SoC_1.0006/gamedata/scripts/ui_mm_opt_video_adv.script b/Game/Resources_SoC_1.0006/gamedata/scripts/ui_mm_opt_video_adv.script
index 84f61e1cf8..63d4abef5e 100644
--- a/Game/Resources_SoC_1.0006/gamedata/scripts/ui_mm_opt_video_adv.script
+++ b/Game/Resources_SoC_1.0006/gamedata/scripts/ui_mm_opt_video_adv.script
@@ -12,6 +12,9 @@ local adv_vid_opt_params = {
{ "hud_fov", "track", 0, hint_colors.green , "video_settings_name_62", "video_settings_desc_62" },
--
{ "aa", "list", 0, hint_colors.green , "video_settings_name_19", "video_settings_desc_19" },
+ { "dlss_quality", "list", 0, hint_colors.green , "video_settings_name_70", "video_settings_desc_70" },
+ { "dlss_preset", "list", 0, hint_colors.green , "video_settings_name_72", "video_settings_desc_72" },
+ { "fsr3_quality", "list", 0, hint_colors.green , "video_settings_name_71", "video_settings_desc_71" },
{ "cas", "track", 0, hint_colors.green , "video_settings_name_20", "video_settings_desc_20" },
-- { "3dss_scale_factor", "track", 0, hint_colors.yellow, "video_settings_name_69", "video_settings_desc_69" },
--
@@ -81,6 +84,7 @@ function opt_video_adv:InitControls(x, y, xml, handler)
xml:InitFrame("frame", self)
self.scroll_v = xml:InitScrollView("video_adv:scroll_v", self)
+ self.upscaler_rows = {}
-- перебираем с конца, поскольку в настройках scroll view в xml стоит параметр flip_vert="1",
-- который инвертирует порядок элементов, что в свою очередь сделано для того, чтобы визуально первые элементы
@@ -104,7 +108,14 @@ function opt_video_adv:InitControls(x, y, xml, handler)
ui_events.STATIC_FOCUS_RECEIVED,
function()
handler.hint_name:SetText(hint_caption and game.translate_string(hint_caption) or "")
- handler.hint_caption:SetText(hint_string and game.translate_string(hint_string) or "")
+ local desc = hint_string and game.translate_string(hint_string) or ""
+ if opt == "dlss_preset" then
+ local ver = get_console():get_string("r_aa_dlss_version") or ""
+ if ver ~= "" then
+ desc = desc .. "\nDLL: " .. ver
+ end
+ end
+ handler.hint_caption:SetText(desc)
end
)
@@ -119,8 +130,65 @@ function opt_video_adv:InitControls(x, y, xml, handler)
_st:Enable(enabled)
_st2:Enable(enabled)
+
+ if opt == "aa" then
+ self.aa_list = ctl
+ elseif opt == "dlss_quality" then
+ self.upscaler_rows[opt] = _st
+ self.dlss_quality_list = ctl
+ elseif opt == "dlss_preset" then
+ self.upscaler_rows[opt] = _st
+ self.dlss_preset_list = ctl
+ self.dlss_preset_cap = _st2
+ elseif opt == "fsr3_quality" then
+ self.upscaler_rows[opt] = _st
+ end
+ end
+
+ if self.aa_list then
+ handler:Register(self.aa_list, "video_adv:list_aa")
+ handler:AddCallback("video_adv:list_aa", ui_events.LIST_ITEM_SELECT, function()
+ self:UpdateUpscalerQualityRows()
+ end)
end
+ if self.dlss_quality_list then
+ handler:Register(self.dlss_quality_list, "video_adv:list_dlss_quality")
+ handler:AddCallback("video_adv:list_dlss_quality", ui_events.LIST_ITEM_SELECT, function()
+ if self.dlss_preset_list then
+ self.dlss_preset_list:SetCurrentValue()
+ end
+ end)
+ end
+ self:UpdateUpscalerQualityRows()
local btn = xml:Init3tButton("video_adv:btn_to_simply", self)
handler:Register(btn, "btn_simply_graphic")
end
+
+function opt_video_adv:UpdateUpscalerQualityRows()
+ local mode = get_console():get_string("r_aa_mode") or ""
+ if self.upscaler_rows.dlss_quality then
+ self.upscaler_rows.dlss_quality:Show(mode == "st_opt_dlss")
+ end
+ if self.upscaler_rows.dlss_preset then
+ self.upscaler_rows.dlss_preset:Show(mode == "st_opt_dlss")
+ end
+ if mode == "st_opt_dlss" and self.dlss_preset_list then
+ self.dlss_preset_list:SetCurrentValue()
+ end
+ if self.dlss_preset_cap then
+ local name = game.translate_string("ui_mm_dlss_preset")
+ local ver = get_console():get_string("r_aa_dlss_version") or ""
+ if mode == "st_opt_dlss" and ver ~= "" then
+ self.dlss_preset_cap:SetText(name .. " " .. ver)
+ else
+ self.dlss_preset_cap:SetText(name)
+ end
+ end
+ if self.upscaler_rows.fsr3_quality then
+ self.upscaler_rows.fsr3_quality:Show(mode == "st_opt_fsr3")
+ end
+ if self.scroll_v then
+ self.scroll_v:ForceUpdate()
+ end
+end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/3dss_reticle.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/3dss_reticle.ps
index 1648ed6cd9..8119682146 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/3dss_reticle.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/3dss_reticle.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine.s
index 2a5ca5864d..24b55cecb5 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine.s
@@ -53,7 +53,7 @@ function element_3(shader, t_base, t_second, t_detail)
:fog(false)
:zb(false, false)
shader:dx10texture("s_position", "$user$position")
- shader:dx10texture("s_image", "$user$generic0")
+ shader:dx10texture("s_image", "$user$postprocess0")
shader:dx10texture("s_bloom", "$user$bloom1")
shader:dx10texture("s_ssfx_bloom", "$user$ssfx_bloom1")
@@ -65,4 +65,4 @@ function element_3(shader, t_base, t_second, t_detail)
shader:dx10sampler("smp_nofilter")
shader:dx10sampler("smp_rtlinear")
shader:dx10sampler("smp_linear")
-end
\ No newline at end of file
+end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/contrast_adaptive_sharpening.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/contrast_adaptive_sharpening.s
index c371c647ba..3c75e056d2 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/contrast_adaptive_sharpening.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/contrast_adaptive_sharpening.s
@@ -2,6 +2,6 @@ function element_0(shader, t_base, t_second, t_detail)
shader:begin("stub_screen_space", "postprocess_cas")
:fog(false)
:zb(false, false)
- shader:dx10texture("t_current", "$user$generic0")
+ shader:dx10texture("t_current", "$user$postprocess0")
shader:dx10sampler("SamplerLinearClamp")
end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_bullet_tracer.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_bullet_tracer.ps
new file mode 100644
index 0000000000..ec7390f80c
Binary files /dev/null and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_bullet_tracer.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_bullet_tracer.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_bullet_tracer.s
index c70935f3fc..8c6877da4e 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_bullet_tracer.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_bullet_tracer.s
@@ -1,13 +1,10 @@
function normal (shader, t_base, t_second, t_detail)
- shader:begin("stub_default","stub_default")
- :zb(true, false)
+ shader:begin("effects_bullet_tracer","effects_bullet_tracer")
+ :zb(false, false)
:blend(true, blend.one, blend.one)
--- :blend(true, blend.srcalpha, blend.one)
--- :aref(true, 32)
--- Decouple sampler and texture
--- shader:sampler ("s_base") : texture(t_base) : clamp() : f_linear ()
--- TODO: DX10: move stub_default to smp_rtlinear
shader:dx10texture ("s_base", t_base)
+ shader:dx10texture ("s_position", "$user$position")
shader:dx10sampler ("smp_base")
-end
\ No newline at end of file
+ shader:dx10sampler ("smp_nofilter")
+end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_bullet_tracer.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_bullet_tracer.vs
new file mode 100644
index 0000000000..b28f2adea2
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_bullet_tracer.vs
@@ -0,0 +1,27 @@
+#include "common.h"
+
+struct v2p_tracer
+{
+ float2 Tex0 : TEXCOORD0;
+ float4 tctexgen : TEXCOORD1;
+ float view_z : TEXCOORD2;
+ float4 Color : COLOR;
+ float4 HPos : SV_Position;
+};
+
+uniform float4x4 mVPTexgen;
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Vertex
+v2p_tracer main(v_TL I)
+{
+ v2p_tracer O;
+
+ O.HPos = mul(m_WVP, I.P);
+ O.Tex0 = I.Tex0;
+ O.tctexgen = mul(mVPTexgen, I.P);
+ O.view_z = mul(m_WV, I.P).z;
+ O.Color = I.Color.bgra;
+
+ return O;
+}
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_ss_sunshafts_mrmnwar.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_ss_sunshafts_mrmnwar.s
index 27e0fba518..4cc1a986f9 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_ss_sunshafts_mrmnwar.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_ss_sunshafts_mrmnwar.s
@@ -3,7 +3,7 @@ function element_0(shader, t_base, t_second, t_detail) -- [0]
:fog (false)
:zb (false, false)
shader:dx10texture ("s_position", "$user$position")
- shader:dx10texture ("s_image", "$user$generic0")
+ shader:dx10texture ("s_image", "$user$postprocess0")
shader:dx10sampler("smp_nofilter")
end
@@ -34,6 +34,6 @@ function element_4(shader, t_base, t_second, t_detail) -- [4]
shader:begin("stub_screen_space", "ssss_mrmnwar_display")
:fog (false)
:zb (false, false)
- shader:dx10texture ("s_image", "$user$generic0")
+ shader:dx10texture ("s_image", "$user$postprocess0")
shader:dx10texture ("s_sunshafts", "$user$SunShaftsMaskSmoothed")
-end
\ No newline at end of file
+end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_ss_sunshafts_ogse.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_ss_sunshafts_ogse.s
index 828a5fd851..49e1155d7f 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_ss_sunshafts_ogse.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/effects_ss_sunshafts_ogse.s
@@ -3,7 +3,7 @@ function element_0(shader, t_base, t_second, t_detail) -- [0] generation of sun
:fog (false)
:zb (false, false)
shader:dx10texture ("s_position", "$user$position")
- shader:dx10texture ("s_image", "$user$generic0")
+ shader:dx10texture ("s_image", "$user$postprocess0")
shader:dx10sampler("smp_nofilter")
end
@@ -33,7 +33,7 @@ function element_4(shader, t_base, t_second, t_detail) -- [4] combine pass
:fog (false)
:zb (false, false)
shader:dx10texture ("s_position", "$user$position")
- shader:dx10texture ("s_image", "$user$generic0")
+ shader:dx10texture ("s_image", "$user$postprocess0")
shader:dx10texture ("s_sun_shafts", "$user$sun_shafts1")
-- Jitter
shader:dx10texture ("jitter0", "$user$jitter_0")
@@ -43,4 +43,4 @@ function element_4(shader, t_base, t_second, t_detail) -- [4] combine pass
shader:dx10sampler ("smp_jitter")
shader:dx10sampler("smp_rtlinear")
shader:dx10sampler("smp_nofilter")
-end
\ No newline at end of file
+end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/infrared.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/infrared.h
index 0a98b455c7..76cd582e96 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/infrared.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/infrared.h
@@ -38,15 +38,19 @@ uniform float4 heat_fade_distance;
#define color_gradient_warm COLOR_YELLOW
#define color_gradient_hot COLOR_RED
-float3 normal_blur(float2 pos2d, int samples)
+float3 normal_blur(float2 uv, int samples)
{
- float3 accum = (0.0, 0.0, 0.0);
+ const int2 maxPos = int2(render_res.xy) - 1;
+ const int2 center = clamp(int2(uv * render_res.xy), int2(0, 0), maxPos);
+
+ float3 accum = float3(0.0, 0.0, 0.0);
for (int i = -samples; i < samples; i++)
{
for (int j = -samples; j < samples; j++)
{
- accum += gbuf_unpack_normal(s_position.Load(int3(pos2d + float2(i, j), 0), 0).xy);
+ const int2 pos = clamp(center + int2(i, j), int2(0, 0), maxPos);
+ accum += gbuf_unpack_normal(s_position.Load(int3(pos, 0), 0).xy);
}
}
@@ -60,7 +64,7 @@ float3 greyscale(float3 img)
return float3(Y, Y, Y);
}
-float3 infrared(float3 N, float3 original, float depth, float2 HPos, float2 Tex0)
+float3 infrared(float3 N, float3 original, float depth, float2 Tex0)
{
// r_pnv_mode = 0 - disable
// r_pnv_mode = 1 - normal pnv
@@ -69,7 +73,8 @@ float3 infrared(float3 N, float3 original, float depth, float2 HPos, float2 Tex0
float heat_mode = pnv_param_1.z - 2.f;
- float3 hotness = s_heat.Load(int3(Tex0 * screen_res.xy, 0), 0);
+ const int2 renderPos = clamp(int2(Tex0 * render_res.xy), int2(0, 0), int2(render_res.xy) - 1);
+ float3 hotness = s_heat.Load(int3(renderPos, 0), 0);
float3 mixed;
if (hotness.y > 0.0)
@@ -101,7 +106,7 @@ float3 infrared(float3 N, float3 original, float depth, float2 HPos, float2 Tex0
{
int samples = lerp(heat_vision_blurring.x, heat_vision_blurring.y, smoothstep(0.0, heat_vision_blurring.z, depth));
- mixed = normal_blur(HPos, samples);
+ mixed = normal_blur(Tex0, samples);
mixed = normalize(mixed);
float projection = dot(mixed, float3(0.0, 0.0, -1.0));
@@ -165,19 +170,16 @@ float3 infrared(float3 N, float3 original, float depth, float2 HPos, float2 Tex0
}
}
- float4 jitter = float4(frac(sin(dot(Tex0, float2(12.0, 78.0) + (timers.x))) * 12345.0), frac(sin(dot(Tex0, float2(12.0, 78.0) + (timers.x))) * 67890.0),
- frac(sin(dot(Tex0, float2(12.0, 78.0) + (timers.x))) * 78372.0), frac(sin(dot(Tex0, float2(12.0, 78.0) + (timers.x))) * 37857.0));
-
if (heat_mode == 1.0)
- {
- mixed += jitter.y * (0.12);
mixed = greyscale(mixed);
- }
- else
- {
- mixed += jitter.y * (0.15);
- }
return mixed;
}
+
+float thermal_sensor_grain(float2 Tex0)
+{
+ const float heat_mode = pnv_param_1.z - 2.f;
+ const float n = frac(sin(dot(Tex0, float2(12.0, 78.0) + timers.x)) * 67890.0);
+ return n * (heat_mode == 1.0 ? 0.12 : 0.15);
+}
#endif
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/night_vision.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/night_vision.h
index 013a6c34bb..4a4a3f9810 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/night_vision.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/night_vision.h
@@ -296,10 +296,10 @@ float blurred_depth(float2 tc)
float Directions = 12.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower)
float Quality = 4.0; // BLUR QUALITY (Default 4.0 - More is better but slower)
float Size = 6;
- float2 Radius = Size / screen_res.xy;
+ float2 Radius = Size / render_res.xy;
// how far away is the center of our COC
- float center_depth = s_position.Load(int3((tc)*screen_res.xy, 0), 0).z;
+ float center_depth = s_position.Load(int3(tc * render_res.xy, 0), 0).z;
if (center_depth == 0)
{
center_depth = 10000;
@@ -321,7 +321,7 @@ float blurred_depth(float2 tc)
for (float d = 0.0; d < Pi; d += Pi / Directions) // where are we around the circle
{
// pull depth at our sample point
- depth_sample = s_position.Load(int3(((tc + float2(cos(d), sin(d)) * Radius * i) * screen_res.xy), 0), 0).z;
+ depth_sample = s_position.Load(int3((tc + float2(cos(d), sin(d)) * Radius * i) * render_res.xy, 0), 0).z;
// if we hit the sky, give it a depth of 10k
if (depth_sample == 0)
@@ -399,4 +399,4 @@ float3 glitchEffect(float3 image, float2 tc, float power)
wsum += 1.0f;
}
return sum.rgb /= wsum;
-}
\ No newline at end of file
+}
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.ps
index ce25ffc3c4..9cf03308eb 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.s
index bc44ac0b36..b9bb99a11c 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.s
@@ -10,7 +10,7 @@ local function elemets(shader, t_base, t_second, t_detail, s_image)
end
function element_0(shader, t_base, t_second, t_detail)
- elemets(shader, t_base, t_second, t_detail, "$user$generic0")
+ elemets(shader, t_base, t_second, t_detail, "$user$postprocess0")
end
function element_1(shader, t_base, t_second, t_detail)
@@ -18,7 +18,7 @@ function element_1(shader, t_base, t_second, t_detail)
end
function element_2(shader, t_base, t_second, t_detail)
- elemets(shader, t_base, t_second, t_detail, "$user$generic0")
+ elemets(shader, t_base, t_second, t_detail, "$user$postprocess0")
end
function element_3(shader, t_base, t_second, t_detail)
@@ -26,9 +26,9 @@ function element_3(shader, t_base, t_second, t_detail)
end
function element_4(shader, t_base, t_second, t_detail)
- elemets(shader, t_base, t_second, t_detail, "$user$generic0")
+ elemets(shader, t_base, t_second, t_detail, "$user$postprocess0")
end
function element_5(shader, t_base, t_second, t_detail)
elemets(shader, t_base, t_second, t_detail, "$user$blur_h_8")
-end
\ No newline at end of file
+end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.vs
index 0bea79b491..85cf6a7ec6 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_blur.vs
@@ -6,9 +6,10 @@ p_screen main(v2p_screen I)
{
p_screen O;
- // Transform to screen space (in d3d9 it was done automatically)
- O.hpos.x = (I.HPos.x * screen_res.z * 2 - 1);
- O.hpos.y = -(I.HPos.y * screen_res.w * 2 - 1);
+ // Fill the current viewport from UVs. Pixel positions * screen_res only
+ // cover a corner when the viewport is the (smaller) destination RT.
+ O.hpos.x = I.tc0.x * 2.0f - 1.0f;
+ O.hpos.y = -(I.tc0.y * 2.0f - 1.0f);
O.hpos.zw = I.HPos.zw;
O.tc0 = I.tc0;
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_dof.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_dof.s
index c5baaeb024..73f60e9b26 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_dof.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_dof.s
@@ -2,7 +2,7 @@ function element_0(shader, t_base, t_second, t_detail)
shader:begin("stub_screen_space", "ogsr_dof")
:fog(false)
:zb(false, false)
- shader:dx10texture("s_image", "$user$generic0")
+ shader:dx10texture("s_image", "$user$postprocess0")
shader:dx10texture("s_position", "$user$position")
shader:dx10texture("s_blur_2", "$user$blur_2")
shader:dx10texture("t_zbuffer", "$user$zbuffer_dof");
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_fakescope.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_fakescope.s
index c931a70280..9d2f6e353b 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_fakescope.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_fakescope.s
@@ -2,7 +2,7 @@ function element_0(shader, t_base, t_second, t_detail)
shader:begin("stub_screen_space", "ogsr_fakescope")
:fog(false)
:zb(false, false)
- shader:dx10texture("s_image", "$user$generic0")
+ shader:dx10texture("s_image", "$user$postprocess0")
shader:dx10texture("s_position", "$user$position")
shader:dx10texture("s_blur_2", "$user$blur_2")
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_gasmask.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_gasmask.s
index 243fb1f0e2..ba25a17c43 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_gasmask.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_gasmask.s
@@ -2,7 +2,7 @@ function element_0(shader, t_base, t_second, t_detail)
shader:begin("stub_screen_space", "ogsr_gasmask")
:fog(false)
:zb(false, false)
- shader:dx10texture("s_image", "$user$generic0")
+ shader:dx10texture("s_image", "$user$postprocess0")
shader:dx10texture("s_blur_2", "$user$blur_2")
shader:dx10texture("s_mask_nm_1", "shaders\\gasmasks\\mask_nm_1")
@@ -26,7 +26,7 @@ function element_1(shader, t_base, t_second, t_detail)
shader:begin("stub_screen_space", "ogsr_gasmask_blur")
:fog(false)
:zb(false, false)
- shader:dx10texture("s_image", "$user$generic0")
+ shader:dx10texture("s_image", "$user$postprocess0")
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_nofilter")
@@ -38,7 +38,7 @@ function element_2(shader, t_base, t_second, t_detail)
shader:begin("stub_screen_space", "ogsr_gasmask_breath")
:fog(false)
:zb(false, false)
- shader:dx10texture("s_image", "$user$generic0")
+ shader:dx10texture("s_image", "$user$postprocess0")
shader:dx10texture("s_image_blurred", "$user$mask_drops_blur")
shader:dx10texture("s_breath_noise", "shaders\\gasmasks\\mask_breath_noise")
shader:dx10texture("s_blur_2", "$user$blur_2")
@@ -49,4 +49,4 @@ function element_2(shader, t_base, t_second, t_detail)
shader:dx10sampler("smp_nofilter")
shader:dx10sampler("smp_rtlinear")
shader:dx10sampler("smp_linear")
-end
\ No newline at end of file
+end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision.ps
index 5da673fab5..66c5c948cc 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision.s
index ab94f862ce..c44819301c 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision.s
@@ -15,4 +15,16 @@ function element_0(shader, t_base, t_second, t_detail)
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_nofilter")
shader:dx10sampler("smp_rtlinear")
-end
\ No newline at end of file
+end
+
+function element_1(shader, t_base, t_second, t_detail)
+ shader:begin("stub_screen_space", "ogsr_heatvision_pp")
+ :fog(false)
+ :zb(false, false)
+ shader:dx10texture("s_image", "$user$postprocess0")
+ shader:dx10texture("s_blur_2", "$user$blur_2")
+
+ shader:dx10sampler("smp_base")
+ shader:dx10sampler("smp_nofilter")
+ shader:dx10sampler("smp_rtlinear")
+end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision_pp.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision_pp.ps
new file mode 100644
index 0000000000..49f1c58ce0
Binary files /dev/null and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_heatvision_pp.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_lut.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_lut.s
index a6a333c7ae..91532e9077 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_lut.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_lut.s
@@ -2,7 +2,7 @@ function element_0(shader, t_base, t_second, t_detail)
shader:begin("stub_screen_space", "pp_lut")
:fog(false)
:zb(false, false)
- shader:dx10texture("s_image", "$user$generic0")
+ shader:dx10texture("s_image", "$user$postprocess0")
shader:dx10texture("s_lut_atlas", "shaders\\lut_atlas")
shader:dx10sampler("smp_base")
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_nightvision.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_nightvision.s
index ff4f4ce3f8..6ff3eccda3 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_nightvision.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_nightvision.s
@@ -2,7 +2,7 @@ function element_0(shader, t_base, t_second, t_detail)
shader:begin("stub_screen_space", "ogsr_nightvision")
:fog(false)
:zb(false, false)
- shader:dx10texture("s_image", "$user$generic0")
+ shader:dx10texture("s_image", "$user$postprocess0")
shader:dx10texture("s_position", "$user$position")
shader:dx10texture("s_bloom_new", "$user$pp_bloom")
@@ -15,4 +15,4 @@ function element_0(shader, t_base, t_second, t_detail)
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_nofilter")
shader:dx10sampler("smp_rtlinear")
-end
\ No newline at end of file
+end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_rain_drops.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_rain_drops.s
index fbdfa771fd..fd9040c9b2 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_rain_drops.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ogsr_rain_drops.s
@@ -2,7 +2,7 @@ function element_0(shader, t_base, t_second, t_detail)
shader:begin("stub_screen_space", "ogsr_rain_drops")
:fog(false)
:zb(false, false)
- shader:dx10texture("s_image", "$user$generic0")
+ shader:dx10texture("s_image", "$user$postprocess0")
shader:dx10sampler("smp_nofilter")
shader:dx10sampler("smp_rtlinear")
end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shared/common.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shared/common.h
index bf66baed98..019dcc130b 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shared/common.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shared/common.h
@@ -61,6 +61,8 @@ cbuffer static_globals
uniform float4 parallax;
uniform float4 rain_params; // x = raindensity, y = wetness
uniform float4 screen_res; // Screen resolution (x-Width,y-Height, zw - 1/resolution)
+ uniform float4 render_res; // Physical scene resolution (xy) and reciprocal (zw)
+ uniform float4 display_res; // Display/post-process resolution (xy) and reciprocal (zw)
uniform float4 pp_img_corrections;
uniform float4 pp_img_cg;
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/slb_motion_blur.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/slb_motion_blur.h
index 4a781848a4..b40f12c47f 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/slb_motion_blur.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/slb_motion_blur.h
@@ -11,7 +11,7 @@ float4 SLB_Screen_GetPosition(float2 tc, uint iSample)
#ifdef SLB_GLSL /// return dummy
return float4(0.5, 0.5, float(abs(tc.x - 0.5) < 0.25) * 10.0 + 0.01, 0.0);
#else
- return SLB_SAMPLER_LOAD(s_position, int3(tc * screen_res.xy - 0.25, 0));
+ return SLB_SAMPLER_LOAD(s_position, int3(tc * render_res.xy - 0.25, 0));
#endif
}
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_mrmnwar_mask.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_mrmnwar_mask.ps
index 6f6f50df55..5366026c13 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_mrmnwar_mask.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_mrmnwar_mask.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_ogse_final.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_ogse_final.ps
index b479c0046e..4cf48ebb96 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_ogse_final.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_ogse_final.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_ogse_mask.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_ogse_mask.ps
index da8ced3dc4..cb0554bfce 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_ogse_mask.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_ogse_mask.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/temporal_resolve.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/temporal_resolve.ps
new file mode 100644
index 0000000000..681adffa96
Binary files /dev/null and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/temporal_resolve.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/temporal_resolve.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/temporal_resolve.s
new file mode 100644
index 0000000000..d4411ada42
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/temporal_resolve.s
@@ -0,0 +1,7 @@
+function element_0(shader, t_base, t_second, t_detail)
+ shader:begin("stub_screen_space", "temporal_resolve")
+ :fog(false)
+ :zb(false, false)
+ shader:dx10texture("t_current", "$user$generic0")
+ shader:dx10sampler("SamplerLinearClamp")
+end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/thermal_utils.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/thermal_utils.h
index 8468faf255..9b4647778a 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/thermal_utils.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/thermal_utils.h
@@ -57,7 +57,7 @@ float3 infrared(float3 N, float depth, float2 HPos, float2 Tex0)
{
int BW = 1;
- float3 hotness = s_heat.Load(int3(Tex0 * screen_res.xy, 0), 0);
+ float3 hotness = s_heat.Load(int3(Tex0 * render_res.xy, 0), 0);
float3 mixed;
if (hotness.r > 0.0)
@@ -133,4 +133,4 @@ float3 infrared(float3 N, float depth, float2 HPos, float2 Tex0)
mixed = greyscale(mixed);
return mixed;
-}
\ No newline at end of file
+}
diff --git a/Game/ShadersSln/ShadersSln.vcxproj b/Game/ShadersSln/ShadersSln.vcxproj
index 38005c8cd5..63f0d6b381 100644
--- a/Game/ShadersSln/ShadersSln.vcxproj
+++ b/Game/ShadersSln/ShadersSln.vcxproj
@@ -270,6 +270,8 @@
+
+
diff --git a/Game/ShadersSln/ShadersSln.vcxproj.filters b/Game/ShadersSln/ShadersSln.vcxproj.filters
index 06d39aff69..0e00ea62a7 100644
--- a/Game/ShadersSln/ShadersSln.vcxproj.filters
+++ b/Game/ShadersSln/ShadersSln.vcxproj.filters
@@ -563,6 +563,8 @@
+
+
diff --git a/ogsr_engine/Layers/xrRender/Blender_Recorder_StandartBinding.cpp b/ogsr_engine/Layers/xrRender/Blender_Recorder_StandartBinding.cpp
index d4a33aa70a..5ee6c1d4d5 100644
--- a/ogsr_engine/Layers/xrRender/Blender_Recorder_StandartBinding.cpp
+++ b/ogsr_engine/Layers/xrRender/Blender_Recorder_StandartBinding.cpp
@@ -341,10 +341,44 @@ static class cl_screen_res final : public R_constant_setup
{
void setup(CBackend& cmd_list, R_constant* C) override
{
- cmd_list.set_c(C, (float)Device.dwWidth, (float)Device.dwHeight, 1.0f / (float)Device.dwWidth, 1.0f / (float)Device.dwHeight);
+ const CRenderTarget* target = RImplementation.Target;
+ const float width = static_cast(target ? target->GetActiveWidth() : Device.dwWidth);
+ const float height = static_cast(target ? target->GetActiveHeight() : Device.dwHeight);
+ cmd_list.set_c(C, width, height, 1.f / width, 1.f / height);
}
} binder_screen_res;
+static class cl_render_res final : public R_constant_setup
+{
+ void setup(CBackend& cmd_list, R_constant* C) override
+ {
+ const CRenderTarget* target = RImplementation.Target;
+ const float width = static_cast(target ? target->GetRenderWidth() : Device.dwWidth);
+ const float height = static_cast(target ? target->GetRenderHeight() : Device.dwHeight);
+ cmd_list.set_c(C, width, height, 1.f / width, 1.f / height);
+ }
+} binder_render_res;
+
+static class cl_display_res final : public R_constant_setup
+{
+ void setup(CBackend& cmd_list, R_constant* C) override
+ {
+ const CRenderTarget* target = RImplementation.Target;
+ const float width = static_cast(target ? target->GetDisplayWidth() : Device.dwWidth);
+ const float height = static_cast(target ? target->GetDisplayHeight() : Device.dwHeight);
+ cmd_list.set_c(C, width, height, 1.f / width, 1.f / height);
+ }
+} binder_display_res;
+
+static class cl_render_subrect final : public R_constant_setup
+{
+ void setup(CBackend& cmd_list, R_constant* C) override
+ {
+ const CRenderTarget* target = RImplementation.Target;
+ cmd_list.set_c(C, target ? target->GetRenderSubrectScaleX() : 1.f, target ? target->GetRenderSubrectScaleY() : 1.f, 0.f, 0.f);
+ }
+} binder_render_subrect;
+
static class cl_screen_params final : public R_constant_setup
{
Fvector4 result;
@@ -668,7 +702,10 @@ static class cl_pos_decompress_params : public R_constant_setup
const float VertTan = -1.0f * tanf(deg2rad(Device.fFOV / 2.0f));
const float HorzTan = -VertTan / Device.fASPECT;
- cmd_list.set_c(C, HorzTan, VertTan, (2.0f * HorzTan) / (float)Device.dwWidth, (2.0f * VertTan) / (float)Device.dwHeight);
+ const CRenderTarget* target = RImplementation.Target;
+ const float width = static_cast(target ? target->GetActiveWidth() : Device.dwWidth);
+ const float height = static_cast(target ? target->GetActiveHeight() : Device.dwHeight);
+ cmd_list.set_c(C, HorzTan, VertTan, (2.0f * HorzTan) / width, (2.0f * VertTan) / height);
}
} binder_pos_decompress_params;
@@ -676,7 +713,10 @@ static class cl_pos_decompress_params2 : public R_constant_setup
{
virtual void setup(CBackend& cmd_list, R_constant* C)
{
- cmd_list.set_c(C, (float)Device.dwWidth, (float)Device.dwHeight, 1.0f / (float)Device.dwWidth, 1.0f / (float)Device.dwHeight);
+ const CRenderTarget* target = RImplementation.Target;
+ const float width = static_cast(target ? target->GetActiveWidth() : Device.dwWidth);
+ const float height = static_cast(target ? target->GetActiveHeight() : Device.dwHeight);
+ cmd_list.set_c(C, width, height, 1.f / width, 1.f / height);
}
} binder_pos_decompress_params2;
@@ -820,6 +860,9 @@ void CBlender_Compile::SetMapping() const
r_Constant("L_hemi_color", &binder_hemi_color);
r_Constant("screen_res", &binder_screen_res);
+ r_Constant("render_res", &binder_render_res);
+ r_Constant("display_res", &binder_display_res);
+ r_Constant("render_subrect", &binder_render_subrect);
r_Constant("ogse_c_screen", &binder_screen_params);
// misc
diff --git a/ogsr_engine/Layers/xrRender/RenderTargetPhaseAA.cpp b/ogsr_engine/Layers/xrRender/RenderTargetPhaseAA.cpp
index a5dfb82c0a..01c43fa548 100644
--- a/ogsr_engine/Layers/xrRender/RenderTargetPhaseAA.cpp
+++ b/ogsr_engine/Layers/xrRender/RenderTargetPhaseAA.cpp
@@ -1,4 +1,6 @@
#include "stdafx.h"
+#include "FidelityFX/host/ffx_fsr3.h"
+#include "FidelityFX/host/backends/dx11/ffx_dx11.h"
void CRenderTarget::ProcessSMAA(CBackend& cmd_list)
{
@@ -6,24 +8,31 @@ void CRenderTarget::ProcessSMAA(CBackend& cmd_list)
RenderScreenTriangle(cmd_list, rt_smaa_edgetex, s_pp_antialiasing->E[2]);
RenderScreenTriangle(cmd_list, rt_smaa_blendtex, s_pp_antialiasing->E[3]);
- RenderScreenTriangle(cmd_list, rt_Generic_combine, s_pp_antialiasing->E[4]);
+ RenderScreenTriangle(cmd_list, rt_Generic_scene_scratch, s_pp_antialiasing->E[4]);
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_scene_scratch->pSurface);
}
void CRenderTarget::ProcessTAA(CBackend& cmd_list)
{
PIX_EVENT(TAA);
- RenderScreenTriangle(cmd_list, rt_Generic_combine, s_taa->E[0]);
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ if (m_resetTemporalHistory)
+ {
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0_prev->pSurface, rt_Generic_0->pSurface);
+ m_resetTemporalHistory = false;
+ }
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0_prev->pSurface, rt_Generic_combine->pSurface);
+ RenderScreenTriangle(cmd_list, rt_Generic_scene_scratch, s_taa->E[0]);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_scene_scratch->pSurface);
+
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0_prev->pSurface, rt_Generic_scene_scratch->pSurface);
}
//*****************************************************************************************************
#include <..\NVIDIA_DLSS\DLSS\include\nvsdk_ngx.h>
#include <..\NVIDIA_DLSS\DLSS\include\nvsdk_ngx_helpers.h>
+#include
#ifdef _DEBUG
#if _ITERATOR_DEBUG_LEVEL == 0
@@ -39,6 +48,112 @@ void CRenderTarget::ProcessTAA(CBackend& cmd_list)
#endif
#endif
+#pragma comment(lib, "version.lib")
+
+char ps_r_dlss_dll_version[64]{};
+
+struct DlssDllFileVersion
+{
+ u32 major{};
+ u32 minor{};
+ u32 patch{};
+ u32 revision{};
+ bool valid{};
+};
+
+static DlssDllFileVersion g_dlss_dll_file_version{};
+
+static bool DlssDllVersionAtLeast(const u32 major, const u32 minor, const u32 patch)
+{
+ if (!g_dlss_dll_file_version.valid)
+ return false;
+ if (g_dlss_dll_file_version.major != major)
+ return g_dlss_dll_file_version.major > major;
+ if (g_dlss_dll_file_version.minor != minor)
+ return g_dlss_dll_file_version.minor > minor;
+ return g_dlss_dll_file_version.patch >= patch;
+}
+
+static void QueryLoadedDlssDllVersion()
+{
+ if (g_dlss_dll_file_version.valid)
+ return;
+
+ const HMODULE mod = GetModuleHandleW(L"nvngx_dlss.dll");
+ if (!mod)
+ return;
+
+ wchar_t path[MAX_PATH]{};
+ if (!GetModuleFileNameW(mod, path, MAX_PATH))
+ return;
+
+ DWORD dummy{};
+ const DWORD size = GetFileVersionInfoSizeW(path, &dummy);
+ if (!size)
+ return;
+
+ xr_vector data(size);
+ if (!GetFileVersionInfoW(path, 0, size, data.data()))
+ return;
+
+ VS_FIXEDFILEINFO* info{};
+ UINT info_size{};
+ if (!VerQueryValueW(data.data(), L"\\", reinterpret_cast(&info), &info_size) || !info)
+ return;
+
+ g_dlss_dll_file_version.major = HIWORD(info->dwFileVersionMS);
+ g_dlss_dll_file_version.minor = LOWORD(info->dwFileVersionMS);
+ g_dlss_dll_file_version.patch = HIWORD(info->dwFileVersionLS);
+ g_dlss_dll_file_version.revision = LOWORD(info->dwFileVersionLS);
+ g_dlss_dll_file_version.valid = true;
+
+ if (g_dlss_dll_file_version.revision == 0)
+ {
+ xr_sprintf(ps_r_dlss_dll_version, "%u.%u.%u", g_dlss_dll_file_version.major, g_dlss_dll_file_version.minor, g_dlss_dll_file_version.patch);
+ }
+ else
+ {
+ xr_sprintf(ps_r_dlss_dll_version, "%u.%u.%u.%u", g_dlss_dll_file_version.major, g_dlss_dll_file_version.minor, g_dlss_dll_file_version.patch,
+ g_dlss_dll_file_version.revision);
+ }
+
+ Msg("--[DLSS] loaded DLL version: [%s]", ps_r_dlss_dll_version);
+}
+
+struct DlssResolutionInfo
+{
+ u32 renderWidth{}, renderHeight{};
+ u32 minRenderWidth{}, minRenderHeight{};
+ u32 maxRenderWidth{}, maxRenderHeight{};
+ float sharpness{};
+};
+
+static NVSDK_NGX_PerfQuality_Value GetRequestedDlssQuality()
+{
+ switch (ps_r_dlss_quality)
+ {
+ case DLSS_QUALITY_QUALITY: return NVSDK_NGX_PerfQuality_Value_MaxQuality;
+ case DLSS_QUALITY_BALANCED: return NVSDK_NGX_PerfQuality_Value_Balanced;
+ case DLSS_QUALITY_PERFORMANCE: return NVSDK_NGX_PerfQuality_Value_MaxPerf;
+ case DLSS_QUALITY_ULTRA_PERFORMANCE: return NVSDK_NGX_PerfQuality_Value_UltraPerformance;
+ default: return NVSDK_NGX_PerfQuality_Value_DLAA;
+ }
+}
+
+static const char* GetDlssPresetParameterName(const NVSDK_NGX_PerfQuality_Value quality)
+{
+ switch (quality)
+ {
+ case NVSDK_NGX_PerfQuality_Value_MaxPerf: return NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Performance;
+ case NVSDK_NGX_PerfQuality_Value_Balanced: return NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Balanced;
+ case NVSDK_NGX_PerfQuality_Value_MaxQuality: return NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Quality;
+ case NVSDK_NGX_PerfQuality_Value_UltraPerformance: return NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_UltraPerformance;
+ case NVSDK_NGX_PerfQuality_Value_UltraQuality: return NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_UltraQuality;
+ case NVSDK_NGX_PerfQuality_Value_DLAA: return NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_DLAA;
+ default: return NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_DLAA;
+ }
+}
+
static class NGXWrapper
{
NVSDK_NGX_Parameter* NgxParameters{};
@@ -46,28 +161,21 @@ static class NGXWrapper
bool DLSSCreated{}, DLSSInited{};
ID3D11Resource* OutputRT{};
NVSDK_NGX_Dimensions saved_renderSize{};
+ bool resetHistory{true};
+ bool availablePresetsResolved{};
public:
u32 saved_w{}, saved_h{};
- uint32_t dlssPreset{}, dlssQuality{};
+ uint32_t dlssPreset{}, dlssQuality{}, requestedQuality{};
+ u32 availablePresetMask{~0u};
- bool Create(const u64 appid, const NVSDK_NGX_Dimensions& renderSize, const NVSDK_NGX_Dimensions& displaySize, ref_rt& out_rt, const u32 quality, u32& preset)
+ bool Initialize(const u64 appid)
{
- OutputRT = out_rt->pSurface;
- saved_w = out_rt->dwWidth;
- saved_h = out_rt->dwHeight;
- saved_renderSize = renderSize;
-
- if (DLSSCreated)
- {
- Destroy();
- }
+ if (!HW.pDevice)
+ return false;
if (HW.FeatureLevel < D3D_FEATURE_LEVEL_11_1)
- {
Msg("!![%s] Low FeatureLevel: [%d]", __FUNCTION__, HW.FeatureLevel);
- // return false;
- }
NVSDK_NGX_Result result{};
if (!DLSSInited)
@@ -78,44 +186,120 @@ static class NGXWrapper
Msg("!![%s] failed NVSDK_NGX_D3D11_Init. result: [%d]", __FUNCTION__, result);
return false;
}
-
DLSSInited = true;
}
- result = NVSDK_NGX_D3D11_GetCapabilityParameters(&NgxParameters);
- if (result != NVSDK_NGX_Result_Success)
+ if (!NgxParameters)
{
- Msg("!![%s] failed NVSDK_NGX_D3D11_GetCapabilityParameters. result: [%d]", __FUNCTION__, result);
- return false;
+ result = NVSDK_NGX_D3D11_GetCapabilityParameters(&NgxParameters);
+ if (result != NVSDK_NGX_Result_Success)
+ {
+ Msg("!![%s] failed NVSDK_NGX_D3D11_GetCapabilityParameters. result: [%d]", __FUNCTION__, result);
+ return false;
+ }
+
+ uint32_t needsUpdatedDriver{1};
+ NgxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver, &needsUpdatedDriver);
+ if (needsUpdatedDriver)
+ Msg("!![%s] PLEASE UPDATE YOUR DRIVER", __FUNCTION__);
+
+ uint32_t dlssAvailable{};
+ NgxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_Available, &dlssAvailable);
+ if (!dlssAvailable)
+ {
+ Msg("!![%s] DLSS NOT AVAILABLE", __FUNCTION__);
+ NVSDK_NGX_D3D11_DestroyParameters(NgxParameters);
+ NgxParameters = nullptr;
+ return false;
+ }
}
- uint32_t needsUpdatedDriver{1};
- result = NgxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver, &needsUpdatedDriver);
- if (needsUpdatedDriver)
+ QueryLoadedDlssDllVersion();
+ return true;
+ }
+
+ bool IsPresetAvailable(const u32 preset) const
+ {
+ if (preset > 31)
+ return false;
+ if (availablePresetMask == ~0u)
+ return true;
+ return (availablePresetMask & (1u << preset)) != 0;
+ }
+
+ void RefreshAvailablePresets()
+ {
+ if (!HW.pDevice)
+ return;
+
+ if (!Initialize(20082024151405ull) || !NgxParameters)
+ return;
+
+ QueryLoadedDlssDllVersion();
+ if (availablePresetsResolved)
+ return;
+
+ // NGX parameter Set/Get does not report whether a preset exists in the
+ // loaded DLL; it just stores the hint. NVIDIA added L/M in SDK 310.5.0.
+ u32 mask = 1u << NVSDK_NGX_DLSS_Hint_Render_Preset_Default;
+ mask |= 1u << NVSDK_NGX_DLSS_Hint_Render_Preset_F;
+ mask |= 1u << NVSDK_NGX_DLSS_Hint_Render_Preset_J;
+ mask |= 1u << NVSDK_NGX_DLSS_Hint_Render_Preset_K;
+ if (DlssDllVersionAtLeast(310, 5, 0))
{
- Msg("!![%s] PLEASE UPDATE YOUR DRIVER", __FUNCTION__);
+ mask |= 1u << NVSDK_NGX_DLSS_Hint_Render_Preset_L;
+ mask |= 1u << NVSDK_NGX_DLSS_Hint_Render_Preset_M;
}
- uint32_t dlssAvailable{};
- result = NgxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_Available, &dlssAvailable);
- if (!dlssAvailable)
+ availablePresetMask = mask;
+ if (g_dlss_dll_file_version.valid)
+ availablePresetsResolved = true;
+
+ Msg("--[DLSS] available presets for DLL [%s]: Default/F/J/K%s", ps_r_dlss_dll_version[0] ? ps_r_dlss_dll_version : "unknown",
+ DlssDllVersionAtLeast(310, 5, 0) ? "/L/M" : "");
+
+ if (!IsPresetAvailable(ps_r_dlss_preset))
{
- Msg("!![%s] DLSS NOT AVAILABLE", __FUNCTION__);
- NVSDK_NGX_D3D11_DestroyParameters(NgxParameters);
- return false;
+ Msg("!![%s] DLSS preset [%u] is unavailable, falling back to Default", __FUNCTION__, ps_r_dlss_preset);
+ ps_r_dlss_preset = NVSDK_NGX_DLSS_Hint_Render_Preset_Default;
}
+ }
- const char* preset_name{};
- switch (quality)
+ bool QueryOptimalSettings(const u32 displayWidth, const u32 displayHeight, const NVSDK_NGX_PerfQuality_Value quality, DlssResolutionInfo& out) const
+ {
+ if (!NgxParameters)
+ return false;
+
+ const NVSDK_NGX_Result result = NGX_DLSS_GET_OPTIMAL_SETTINGS(NgxParameters, displayWidth, displayHeight, quality, &out.renderWidth, &out.renderHeight,
+ &out.maxRenderWidth, &out.maxRenderHeight, &out.minRenderWidth, &out.minRenderHeight, &out.sharpness);
+ if (result != NVSDK_NGX_Result_Success)
{
- case NVSDK_NGX_PerfQuality_Value_MaxPerf: preset_name = NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Performance; break;
- case NVSDK_NGX_PerfQuality_Value_Balanced: preset_name = NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Balanced; break;
- case NVSDK_NGX_PerfQuality_Value_MaxQuality: preset_name = NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Quality; break;
- case NVSDK_NGX_PerfQuality_Value_UltraPerformance: preset_name = NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_UltraPerformance; break;
- case NVSDK_NGX_PerfQuality_Value_UltraQuality: preset_name = NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_UltraQuality; break;
- case NVSDK_NGX_PerfQuality_Value_DLAA: preset_name = NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_DLAA; break;
+ Msg("!![%s] failed for quality [%d]. result: [%d]", __FUNCTION__, quality, result);
+ return false;
}
+ Msg("--[DLSS] quality: [%d], output: [%ux%u], recommended render: [%ux%u], range: [%ux%u]-[%ux%u], sharpness: [%.3f]", quality,
+ displayWidth, displayHeight, out.renderWidth, out.renderHeight, out.minRenderWidth, out.minRenderHeight, out.maxRenderWidth, out.maxRenderHeight, out.sharpness);
+ return true;
+ }
+
+ bool Create(const u64 appid, const NVSDK_NGX_Dimensions& renderSize, const NVSDK_NGX_Dimensions& displaySize, ref_rt& out_rt, const u32 quality, u32& preset,
+ const NVSDK_NGX_PerfQuality_Value requested_quality)
+ {
+ DestroyFeature();
+ if (!Initialize(appid))
+ return false;
+
+ OutputRT = out_rt->pSurface;
+ saved_w = out_rt->dwWidth;
+ saved_h = out_rt->dwHeight;
+ saved_renderSize = renderSize;
+
+ NVSDK_NGX_Result result{};
+
+ requestedQuality = requested_quality;
+ const char* preset_name = GetDlssPresetParameterName(static_cast(quality));
+
NVSDK_NGX_Parameter_SetUI(NgxParameters, preset_name, preset);
result = NgxParameters->Get(preset_name, &dlssPreset);
@@ -171,16 +355,15 @@ static class NGXWrapper
}
DLSSCreated = true;
+ resetHistory = true;
+ QueryLoadedDlssDllVersion();
+ RefreshAvailablePresets();
return true;
}
void Destroy()
{
- if (Handle)
- {
- NVSDK_NGX_D3D11_ReleaseFeature(Handle);
- Handle = nullptr;
- }
+ DestroyFeature();
if (NgxParameters)
{
@@ -193,11 +376,20 @@ static class NGXWrapper
NVSDK_NGX_D3D11_Shutdown1(nullptr);
DLSSInited = false;
}
+ }
+ void DestroyFeature()
+ {
+ if (Handle)
+ {
+ NVSDK_NGX_D3D11_ReleaseFeature(Handle);
+ Handle = nullptr;
+ }
DLSSCreated = false;
+ OutputRT = nullptr;
}
- bool Draw() const
+ bool Draw()
{
if (!DLSSCreated)
{
@@ -225,6 +417,7 @@ static class NGXWrapper
dlssEvalParams.InMVScaleX = -static_cast(saved_renderSize.Width) * 0.5f;
dlssEvalParams.InMVScaleY = static_cast(saved_renderSize.Height) * 0.5f;
+ dlssEvalParams.InReset = resetHistory ? 1 : 0;
const NVSDK_NGX_Result result = NGX_D3D11_EVALUATE_DLSS_EXT(HW.get_context(CHW::IMM_CTX_ID), Handle, NgxParameters, &dlssEvalParams);
if (result != NVSDK_NGX_Result_Success)
@@ -233,12 +426,77 @@ static class NGXWrapper
return false;
}
+ resetHistory = false;
return true;
}
+ void RequestHistoryReset() { resetHistory = true; }
+
~NGXWrapper() { Destroy(); }
} NGXWrapper;
+bool R_dlss_is_preset_available(const u32 preset) { return NGXWrapper.IsPresetAvailable(preset); }
+
+void R_dlss_refresh_available_presets() { NGXWrapper.RefreshAvailablePresets(); }
+
+static FfxFsr3UpscalerQualityMode GetRequestedFsr3Quality()
+{
+ return static_cast(
+ std::clamp(ps_r_fsr3_quality, static_cast(FSR3_QUALITY_NATIVE_AA), static_cast(FSR3_QUALITY_ULTRA_PERFORMANCE)));
+}
+
+void CRenderTarget::ConfigureTemporalRenderSize()
+{
+ SetTemporalRenderSize(Device.dwWidth, Device.dwHeight, Device.dwWidth, Device.dwHeight);
+
+ if (ps_r_pp_aa_mode == DLSS)
+ {
+ const NVSDK_NGX_PerfQuality_Value quality = GetRequestedDlssQuality();
+ if (!NGXWrapper.Initialize(20082024151405ull))
+ {
+ ps_r_pp_aa_mode = FSR3;
+ }
+ else
+ {
+ NGXWrapper.RefreshAvailablePresets();
+ DlssResolutionInfo resolutionInfo{};
+ if (NGXWrapper.QueryOptimalSettings(Device.dwWidth, Device.dwHeight, quality, resolutionInfo))
+ {
+ SetTemporalRenderSize(resolutionInfo.renderWidth, resolutionInfo.renderHeight, Device.dwWidth, Device.dwHeight);
+ }
+ else
+ {
+ // Do not create an upscaling feature against native-sized
+ // resources after a failed quality query.
+ ps_r_dlss_quality = DLSS_QUALITY_DLAA;
+ Msg("!![DLSS] falling back to DLAA because optimal settings could not be queried");
+ }
+
+ Msg("--[DLSS] physical render domain: [%ux%u] -> [%ux%u]", GetRenderWidth(), GetRenderHeight(), GetDisplayWidth(), GetDisplayHeight());
+ return;
+ }
+ }
+
+ if (ps_r_pp_aa_mode != FSR3)
+ return;
+
+ u32 renderWidth{};
+ u32 renderHeight{};
+ const FfxFsr3UpscalerQualityMode quality = GetRequestedFsr3Quality();
+ const FfxErrorCode result =
+ ffxFsr3UpscalerGetRenderResolutionFromQualityMode(&renderWidth, &renderHeight, Device.dwWidth, Device.dwHeight, quality);
+ if (result != FFX_OK)
+ {
+ Msg("!![FSR3] failed to calculate render resolution for quality [%u]. Error: [%d]", ps_r_fsr3_quality, result);
+ ps_r_fsr3_quality = FSR3_QUALITY_NATIVE_AA;
+ return;
+ }
+
+ SetTemporalRenderSize(renderWidth, renderHeight, Device.dwWidth, Device.dwHeight);
+ Msg("--[FSR3] quality: [%u], physical render domain: [%ux%u] -> [%ux%u]", ps_r_fsr3_quality, GetRenderWidth(), GetRenderHeight(), GetDisplayWidth(),
+ GetDisplayHeight());
+}
+
static float saved_3dss_scale_factor{};
bool CRenderTarget::reset_3dss_rendertarget(const bool need_reset)
{
@@ -274,10 +532,14 @@ bool CRenderTarget::reset_3dss_rendertarget(const bool need_reset)
void CRenderTarget::InitDLSS()
{
- NGXWrapper.Destroy();
+ if (ps_r_pp_aa_mode != DLSS)
+ return;
+
+ const NVSDK_NGX_Dimensions renderSize{GetRenderWidth(), GetRenderHeight()};
+ const NVSDK_NGX_Dimensions displaySize{GetDisplayWidth(), GetDisplayHeight()};
+ const NVSDK_NGX_PerfQuality_Value requestedQuality = GetRequestedDlssQuality();
- const NVSDK_NGX_Dimensions RenderParams{Device.dwWidth, Device.dwHeight};
- if (!NGXWrapper.Create(20082024151405ull, RenderParams, RenderParams, rt_Generic_combine, NVSDK_NGX_PerfQuality_Value_DLAA, ps_r_dlss_preset))
+ if (!NGXWrapper.Create(20082024151405ull, renderSize, displaySize, rt_Generic_combine, requestedQuality, ps_r_dlss_preset, requestedQuality))
{
if (ps_r_pp_aa_mode == DLSS)
ps_r_pp_aa_mode = FSR3;
@@ -293,7 +555,21 @@ bool CRenderTarget::ProcessDLSS()
{
PIX_EVENT(DLSS);
- if (ps_r_dlss_preset != NGXWrapper.dlssPreset)
+ const NVSDK_NGX_PerfQuality_Value requestedQuality = GetRequestedDlssQuality();
+
+ const bool qualityMatchesPhysicalTargets = static_cast(requestedQuality) == NGXWrapper.requestedQuality;
+ if (!qualityMatchesPhysicalTargets)
+ {
+ static u32 lastReportedQuality = u32(-1);
+ if (lastReportedQuality != static_cast(requestedQuality))
+ {
+ Msg("--[DLSS] quality changes resize physical render targets; apply video settings or run vid_restart");
+ lastReportedQuality = static_cast(requestedQuality);
+ }
+ }
+
+ if (qualityMatchesPhysicalTargets && (ps_r_dlss_preset != NGXWrapper.dlssPreset || NGXWrapper.saved_w != Device.dwWidth ||
+ NGXWrapper.saved_h != Device.dwHeight))
{
InitDLSS();
}
@@ -304,10 +580,32 @@ bool CRenderTarget::ProcessDLSS()
return false;
}
- HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
return true;
}
+void CRenderTarget::BeginPostprocess(CBackend& cmd_list, const bool temporalOutput)
+{
+ // The last scene target is physically render-sized. Switch both the cached
+ // target dimensions and the D3D viewport before any display-sized pass.
+ u_setrt(cmd_list, GetDisplayWidth(), GetDisplayHeight(), nullptr, nullptr, nullptr, nullptr);
+ RImplementation.rmNormal(cmd_list);
+
+ if (temporalOutput)
+ {
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
+ }
+ else if (GetRenderWidth() == GetDisplayWidth() && GetRenderHeight() == GetDisplayHeight())
+ {
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_0->pSurface);
+ }
+ else
+ {
+ // CopyResource cannot scale. If a temporal upscaler is unavailable,
+ // stretch the render-sized scene so failure remains full-screen.
+ RenderScreenTriangle(cmd_list, rt_Postprocess_0, s_temporal_resolve->E[0]);
+ }
+}
+
//*****************************************************************************************************
void CRenderTarget::ProcessCAS(CBackend& cmd_list)
@@ -319,16 +617,75 @@ void CRenderTarget::ProcessCAS(CBackend& cmd_list)
const Fvector4 params{std::max(ps_r_cas, 0.01f), 0.f, 0.f, 0.f};
RenderScreenTriangle(cmd_list, rt_Generic_combine, s_cas->E[0], [&]() { cmd_list.set_c("f_cas_intensity", params); });
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
}
//*****************************************************************************************************
-#include "FidelityFX/host/ffx_fsr3.h"
-#include "FidelityFX/host/backends/dx11/ffx_dx11.h"
+static DXGI_FORMAT GetDxgiFormat(const FfxSurfaceFormat format)
+{
+ switch (format)
+ {
+ case FFX_SURFACE_FORMAT_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_TYPELESS;
+ case FFX_SURFACE_FORMAT_R32G32B32A32_UINT: return DXGI_FORMAT_R32G32B32A32_UINT;
+ case FFX_SURFACE_FORMAT_R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT;
+ case FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT;
+ case FFX_SURFACE_FORMAT_R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT;
+ case FFX_SURFACE_FORMAT_R8_UINT: return DXGI_FORMAT_R8_UINT;
+ case FFX_SURFACE_FORMAT_R32_UINT: return DXGI_FORMAT_R32_UINT;
+ case FFX_SURFACE_FORMAT_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UNORM;
+ case FFX_SURFACE_FORMAT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_TYPELESS;
+ case FFX_SURFACE_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM;
+ case FFX_SURFACE_FORMAT_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_SNORM;
+ case FFX_SURFACE_FORMAT_R8G8B8A8_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+ case FFX_SURFACE_FORMAT_R11G11B10_FLOAT: return DXGI_FORMAT_R11G11B10_FLOAT;
+ case FFX_SURFACE_FORMAT_R16G16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT;
+ case FFX_SURFACE_FORMAT_R16G16_UINT: return DXGI_FORMAT_R16G16_UINT;
+ case FFX_SURFACE_FORMAT_R16G16_SINT: return DXGI_FORMAT_R16G16_SINT;
+ case FFX_SURFACE_FORMAT_R16_FLOAT: return DXGI_FORMAT_R16_FLOAT;
+ case FFX_SURFACE_FORMAT_R16_UINT: return DXGI_FORMAT_R16_UINT;
+ case FFX_SURFACE_FORMAT_R16_UNORM: return DXGI_FORMAT_R16_UNORM;
+ case FFX_SURFACE_FORMAT_R16_SNORM: return DXGI_FORMAT_R16_SNORM;
+ case FFX_SURFACE_FORMAT_R8_UNORM: return DXGI_FORMAT_R8_UNORM;
+ case FFX_SURFACE_FORMAT_R8G8_UNORM: return DXGI_FORMAT_R8G8_UNORM;
+ case FFX_SURFACE_FORMAT_R8G8_UINT: return DXGI_FORMAT_R8G8_UINT;
+ case FFX_SURFACE_FORMAT_R32_FLOAT: return DXGI_FORMAT_R32_FLOAT;
+ default: return DXGI_FORMAT_UNKNOWN;
+ }
+}
+
+static HRESULT CreateFsrSharedTexture(const FfxCreateResourceDescription& createDescription, ID3D11Texture2D** texture)
+{
+ const FfxResourceDescription& resource = createDescription.resourceDescription;
+ if (resource.type != FFX_RESOURCE_TYPE_TEXTURE2D)
+ return E_INVALIDARG;
+
+ D3D11_TEXTURE2D_DESC description{};
+ description.Width = resource.width;
+ description.Height = resource.height;
+ description.MipLevels = resource.mipCount;
+ description.ArraySize = _max(1u, resource.depth);
+ description.Format = GetDxgiFormat(resource.format);
+ description.SampleDesc.Count = 1;
+ description.Usage = D3D11_USAGE_DEFAULT;
+ description.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+
+ if (resource.usage & FFX_RESOURCE_USAGE_UAV)
+ description.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
+ if (resource.usage & FFX_RESOURCE_USAGE_RENDERTARGET)
+ description.BindFlags |= D3D11_BIND_RENDER_TARGET;
+ if (resource.usage & FFX_RESOURCE_USAGE_DEPTHTARGET)
+ description.BindFlags |= D3D11_BIND_DEPTH_STENCIL;
+
+ if (description.Format == DXGI_FORMAT_UNKNOWN || !description.Width || !description.Height || !description.MipLevels)
+ return E_INVALIDARG;
+
+ return HW.pDevice->CreateTexture2D(&description, nullptr, texture);
+}
static class Fsr3Wrapper
{
bool fsr_created{};
+ bool resetHistory{true};
FfxFsr3UpscalerContext m_UpscalerContext{};
xr_vector m_scratchBuffer;
ID3D11Resource* OutputRT{};
@@ -338,15 +695,16 @@ static class Fsr3Wrapper
ID3D11Texture2D* dilatedMotionVectors{};
ID3D11Texture2D* reconstructedPrevNearestDepth{};
public:
- u32 saved_w{}, saved_h{};
+ u32 saved_w{}, saved_h{}, requestedQuality{};
- bool Create(const FfxDimensions2D& maxRenderSize, const FfxDimensions2D& displaySize, ref_rt& out_rt)
+ bool Create(const FfxDimensions2D& maxRenderSize, const FfxDimensions2D& displaySize, ref_rt& out_rt, const u32 quality)
{
OutputRT = out_rt->pSurface;
saved_w = out_rt->dwWidth;
saved_h = out_rt->dwHeight;
saved_maxRenderSize = maxRenderSize;
saved_displaySize = displaySize;
+ requestedQuality = quality;
if (fsr_created)
{
@@ -374,6 +732,7 @@ static class Fsr3Wrapper
m_UpscalercontextDesc.backendInterface = fsrInterface;
m_UpscalercontextDesc.maxRenderSize = maxRenderSize;
m_UpscalercontextDesc.maxUpscaleSize = displaySize;
+ m_UpscalercontextDesc.flags = FFX_FSR3UPSCALER_ENABLE_HIGH_DYNAMIC_RANGE;
errorCode = ffxFsr3UpscalerContextCreate(&m_UpscalerContext, &m_UpscalercontextDesc);
if (errorCode != FFX_OK)
@@ -383,26 +742,30 @@ static class Fsr3Wrapper
return false;
}
- auto CreateTexture = [&](const DXGI_FORMAT fmt, const bool need_rt, ID3D11Texture2D** out) {
- D3D11_TEXTURE2D_DESC Desc{};
- Desc.Width = maxRenderSize.width;
- Desc.Height = maxRenderSize.height;
- Desc.MipLevels = 1;
- Desc.ArraySize = 1;
- Desc.Format = fmt;
- Desc.SampleDesc.Count = 1;
- Desc.Usage = D3D11_USAGE_DEFAULT;
- Desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
- if (need_rt)
- Desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
- return HW.pDevice->CreateTexture2D(&Desc, nullptr, out);
- };
-
- R_CHK(CreateTexture(DXGI_FORMAT_R32_FLOAT, true, &dilatedDepth));
- R_CHK(CreateTexture(DXGI_FORMAT_R16G16_FLOAT, true, &dilatedMotionVectors));
- R_CHK(CreateTexture(DXGI_FORMAT_R32_UINT, false, &reconstructedPrevNearestDepth));
-
fsr_created = true;
+ resetHistory = true;
+
+ FfxFsr3UpscalerSharedResourceDescriptions sharedDescriptions{};
+ errorCode = ffxFsr3UpscalerGetSharedResourceDescriptions(&m_UpscalerContext, &sharedDescriptions);
+ if (errorCode != FFX_OK)
+ {
+ Msg("!!Failed ffxFsr3UpscalerGetSharedResourceDescriptions! Error: [%d]", errorCode);
+ Destroy();
+ return false;
+ }
+
+ const HRESULT dilatedDepthResult = CreateFsrSharedTexture(sharedDescriptions.dilatedDepth, &dilatedDepth);
+ const HRESULT dilatedMotionResult = CreateFsrSharedTexture(sharedDescriptions.dilatedMotionVectors, &dilatedMotionVectors);
+ const HRESULT reconstructedDepthResult =
+ CreateFsrSharedTexture(sharedDescriptions.reconstructedPrevNearestDepth, &reconstructedPrevNearestDepth);
+
+ if (FAILED(dilatedDepthResult) || FAILED(dilatedMotionResult) || FAILED(reconstructedDepthResult))
+ {
+ Msg("!!Failed to create FSR3 shared resources: [0x%08x, 0x%08x, 0x%08x]", dilatedDepthResult, dilatedMotionResult, reconstructedDepthResult);
+ Destroy();
+ return false;
+ }
+
return true;
}
@@ -417,6 +780,7 @@ static class Fsr3Wrapper
_RELEASE(dilatedDepth);
_RELEASE(dilatedMotionVectors);
_RELEASE(reconstructedPrevNearestDepth);
+ resetHistory = true;
}
bool Draw()
@@ -440,7 +804,7 @@ static class Fsr3Wrapper
dispatchParameters.reactive = ffxGetResourceDX11(nullptr, {}, L"FSR3_InputReactiveMap");
dispatchParameters.transparencyAndComposition = ffxGetResourceDX11(nullptr, {}, L"FSR3_TransparencyAndCompositionMap");
- dispatchParameters.dilatedDepth = ffxGetResourceDX11(dilatedDepth, GetFfxResourceDescriptionDX11(dilatedDepth), L"FSR3_dilatedDepth", FFX_RESOURCE_STATE_UNORDERED_ACCESS);
+ dispatchParameters.dilatedDepth = ffxGetResourceDX11(dilatedDepth, GetFfxResourceDescriptionDX11(dilatedDepth), L"FSR3_dilatedDepth", FFX_RESOURCE_STATE_UNORDERED_ACCESS);
dispatchParameters.dilatedMotionVectors =
ffxGetResourceDX11(dilatedMotionVectors, GetFfxResourceDescriptionDX11(dilatedMotionVectors), L"FSR3_DilatedMotion", FFX_RESOURCE_STATE_UNORDERED_ACCESS);
dispatchParameters.reconstructedPrevNearestDepth = ffxGetResourceDX11(reconstructedPrevNearestDepth, GetFfxResourceDescriptionDX11(reconstructedPrevNearestDepth),
@@ -467,6 +831,7 @@ static class Fsr3Wrapper
dispatchParameters.cameraFovAngleVertical = deg2rad(Device.fFOV);
dispatchParameters.viewSpaceToMetersFactor = 1.0f;
+ dispatchParameters.reset = resetHistory;
const FfxErrorCode errorCode = ffxFsr3UpscalerContextDispatch(&m_UpscalerContext, &dispatchParameters);
@@ -476,9 +841,12 @@ static class Fsr3Wrapper
return false;
}
+ resetHistory = false;
return true;
}
+ void RequestHistoryReset() { resetHistory = true; }
+
~Fsr3Wrapper() { Destroy(); }
} Fsr3Wrapper , Fsr3WrapperScope;
@@ -487,9 +855,11 @@ void CRenderTarget::InitFSR()
Fsr3Wrapper.Destroy();
Fsr3WrapperScope.Destroy();
- const FfxDimensions2D displaySize{Device.dwWidth, Device.dwHeight};
+ const FfxDimensions2D renderSize{GetRenderWidth(), GetRenderHeight()};
+ const FfxDimensions2D displaySize{GetDisplayWidth(), GetDisplayHeight()};
- if (!Fsr3Wrapper.Create(displaySize, displaySize, rt_Generic_combine))
+ const u32 quality = static_cast(GetRequestedFsr3Quality());
+ if (!Fsr3Wrapper.Create(renderSize, displaySize, rt_Generic_combine, quality))
{
if (ps_r_pp_aa_mode == FSR3)
ps_r_pp_aa_mode = TAA;
@@ -499,7 +869,7 @@ void CRenderTarget::InitFSR()
reset_3dss_rendertarget();
const FfxDimensions2D ScopeSize{rt_Generic_combine_scope->dwWidth, rt_Generic_combine_scope->dwHeight};
- R_ASSERT(Fsr3WrapperScope.Create(displaySize, ScopeSize, rt_Generic_combine_scope));
+ R_ASSERT(Fsr3WrapperScope.Create(renderSize, ScopeSize, rt_Generic_combine_scope, FSR3_QUALITY_NATIVE_AA));
}
}
@@ -509,17 +879,34 @@ void CRenderTarget::DestroyFSR()
Fsr3WrapperScope.Destroy();
}
-bool CRenderTarget::ProcessFSR() const
+void CRenderTarget::ResetTemporalHistory()
+{
+ m_resetTemporalHistory = true;
+ NGXWrapper.RequestHistoryReset();
+ Fsr3Wrapper.RequestHistoryReset();
+ Fsr3WrapperScope.RequestHistoryReset();
+}
+
+bool CRenderTarget::ProcessFSR()
{
PIX_EVENT(FSR);
+ if (ps_r_pp_aa_mode == FSR3 && ps_r_fsr3_quality != Fsr3Wrapper.requestedQuality)
+ {
+ static u32 lastReportedQuality = u32(-1);
+ if (lastReportedQuality != ps_r_fsr3_quality)
+ {
+ Msg("--[FSR3] quality changes resize physical render targets; apply video settings or run vid_restart");
+ lastReportedQuality = ps_r_fsr3_quality;
+ }
+ }
+
if (!Fsr3Wrapper.Draw())
{
Msg("!![%s] FAILED FSR DRAW!", __FUNCTION__);
return false;
}
- HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
return true;
}
@@ -544,21 +931,27 @@ bool CRenderTarget::ProcessFSR_3DSS(const bool need_reset)
void CRenderTarget::PhaseAA(CBackend& cmd_list)
{
- if (ps_pnv_mode > 1) // skip AA for heatvision
- return;
+ bool temporalOutput = false;
switch (ps_r_pp_aa_mode)
{
case DLSS: {
- if (!ProcessDLSS())
+ temporalOutput = ProcessDLSS();
+ if (!temporalOutput)
+ {
ps_r_pp_aa_mode = FSR3;
+ temporalOutput = ProcessFSR();
+ if (!temporalOutput)
+ ps_r_pp_aa_mode = TAA;
+ }
break;
}
case FSR3: {
u_setrt(cmd_list, get_width(cmd_list), get_height(cmd_list), nullptr, nullptr, nullptr, nullptr);
RImplementation.rmNormal(cmd_list);
- if (!ProcessFSR())
+ temporalOutput = ProcessFSR();
+ if (!temporalOutput)
ps_r_pp_aa_mode = TAA;
break;
}
@@ -566,6 +959,10 @@ void CRenderTarget::PhaseAA(CBackend& cmd_list)
case SMAA: ProcessSMAA(cmd_list); break;
}
+ EndTemporalUpscaleInput();
+ RImplementation.rmNormal(cmd_list);
+ BeginPostprocess(cmd_list, temporalOutput);
+
if (ps_r_pp_aa_mode != SMAA)
ProcessCAS(cmd_list);
}
diff --git a/ogsr_engine/Layers/xrRender/RenderTargetPhaseRainDrops.cpp b/ogsr_engine/Layers/xrRender/RenderTargetPhaseRainDrops.cpp
index 5f4a543dbd..d5bdde857b 100644
--- a/ogsr_engine/Layers/xrRender/RenderTargetPhaseRainDrops.cpp
+++ b/ogsr_engine/Layers/xrRender/RenderTargetPhaseRainDrops.cpp
@@ -80,5 +80,5 @@ void CRenderTarget::phase_rain_drops(CBackend& cmd_list)
const Fvector4 params{rain_drops_factor, ps_r2_rain_drops_intensity, ps_r2_rain_drops_speed, 0.0f};
RenderScreenTriangle(cmd_list, rt_Generic_combine, s_rain_drops->E[0], [&]() { cmd_list.set_c("rain_drops_params", params); });
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
}
diff --git a/ogsr_engine/Layers/xrRender/RenderTargetPhaseSSSS.cpp b/ogsr_engine/Layers/xrRender/RenderTargetPhaseSSSS.cpp
index 22f3d34600..9fff22f659 100644
--- a/ogsr_engine/Layers/xrRender/RenderTargetPhaseSSSS.cpp
+++ b/ogsr_engine/Layers/xrRender/RenderTargetPhaseSSSS.cpp
@@ -35,7 +35,7 @@ void CRenderTarget::PhaseSSSS(CBackend& cmd_list)
// Combine
RenderScreenTriangle(cmd_list, rt_Generic_combine, s_ssss_mrmnwar->E[4], [&]() { cmd_list.set_c("ssss_params", intensity, ps_r_prop_ss_blend, 0.0f, 0.0f); });
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
}
else if (mode == SS_SS_OGSE)
{
@@ -65,6 +65,6 @@ void CRenderTarget::PhaseSSSS(CBackend& cmd_list)
RenderScreenTriangle(cmd_list, rt_Generic_combine, s_ssss_ogse->E[4],
[&]() { cmd_list.set_c("ssss_params", intensity, ps_r_ss_sunshafts_length, 0.0f, ps_r_ss_sunshafts_radius); });
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
}
}
diff --git a/ogsr_engine/Layers/xrRender/RenderTargetRenderScreenQuad.cpp b/ogsr_engine/Layers/xrRender/RenderTargetRenderScreenQuad.cpp
index 2fb8439c21..455a496078 100644
--- a/ogsr_engine/Layers/xrRender/RenderTargetRenderScreenQuad.cpp
+++ b/ogsr_engine/Layers/xrRender/RenderTargetRenderScreenQuad.cpp
@@ -2,7 +2,8 @@
void CRenderTarget::RenderScreenTriangle(CBackend& cmd_list, const ref_rt& rt, ref_selement& sh, const std::function& lambda)
{
- u_setrt(cmd_list, Device.dwWidth, Device.dwHeight, rt->pRT, nullptr, nullptr, nullptr);
+ u_setrt(cmd_list, rt->dwWidth, rt->dwHeight, rt->pRT, nullptr, nullptr, nullptr);
+ cmd_list.SetViewport({0.f, 0.f, static_cast(rt->dwWidth), static_cast(rt->dwHeight), 0.f, 1.f});
cmd_list.set_CullMode(CULL_NONE);
cmd_list.set_Stencil(FALSE);
@@ -23,6 +24,7 @@ void CRenderTarget::RenderScreenQuad(CBackend& cmd_list, const u32 w, const u32
constexpr u32 C = color_rgba(0, 0, 0, 255);
u_setrt(cmd_list, w, h, rt->pRT, nullptr, nullptr, nullptr);
+ cmd_list.SetViewport({0.f, 0.f, static_cast(w), static_cast(h), 0.f, 1.f});
cmd_list.set_CullMode(CULL_NONE);
cmd_list.set_Stencil(FALSE);
diff --git a/ogsr_engine/Layers/xrRender/rendertarget_phase_dof.cpp b/ogsr_engine/Layers/xrRender/rendertarget_phase_dof.cpp
index 17a31d2af4..52093b9ffc 100644
--- a/ogsr_engine/Layers/xrRender/rendertarget_phase_dof.cpp
+++ b/ogsr_engine/Layers/xrRender/rendertarget_phase_dof.cpp
@@ -12,5 +12,5 @@ void CRenderTarget::phase_dof(CBackend& cmd_list)
RenderScreenTriangle(cmd_list, rt_Generic_combine, s_dof->E[1]);
//Resolve RT
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
}
diff --git a/ogsr_engine/Layers/xrRender/rendertarget_phase_fakescope.cpp b/ogsr_engine/Layers/xrRender/rendertarget_phase_fakescope.cpp
index bace154415..60bc1d35c5 100644
--- a/ogsr_engine/Layers/xrRender/rendertarget_phase_fakescope.cpp
+++ b/ogsr_engine/Layers/xrRender/rendertarget_phase_fakescope.cpp
@@ -8,5 +8,5 @@ void CRenderTarget::phase_fakescope(CBackend& cmd_list)
RenderScreenTriangle(cmd_list, rt_Generic_combine, s_fakescope->E[0]);
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
}
diff --git a/ogsr_engine/Layers/xrRender/rendertarget_phase_gasmask_dudv.cpp b/ogsr_engine/Layers/xrRender/rendertarget_phase_gasmask_dudv.cpp
index ae8b614528..e287776828 100644
--- a/ogsr_engine/Layers/xrRender/rendertarget_phase_gasmask_dudv.cpp
+++ b/ogsr_engine/Layers/xrRender/rendertarget_phase_gasmask_dudv.cpp
@@ -11,10 +11,10 @@ void CRenderTarget::phase_gasmask_dudv(CBackend& cmd_list)
cmd_list.set_c("mask_control", params);
cmd_list.set_c("addon_VControl", ps_r2_visor_refl_intensity, ps_r2_visor_refl_radius, 0.f, 1.f);
});
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
RenderScreenTriangle(cmd_list, rt_mask_drops_blur, s_gasmask_dudv->E[1]);
RenderScreenTriangle(cmd_list, rt_Generic_combine, s_gasmask_dudv->E[2]);
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
-}
\ No newline at end of file
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
+}
diff --git a/ogsr_engine/Layers/xrRender/rendertarget_phase_nightvision.cpp b/ogsr_engine/Layers/xrRender/rendertarget_phase_nightvision.cpp
index 265212ae31..a5b4409b41 100644
--- a/ogsr_engine/Layers/xrRender/rendertarget_phase_nightvision.cpp
+++ b/ogsr_engine/Layers/xrRender/rendertarget_phase_nightvision.cpp
@@ -5,5 +5,5 @@ void CRenderTarget::phase_nightvision(CBackend& cmd_list)
PIX_EVENT(phase_nightvision);
RenderScreenTriangle(cmd_list, rt_Generic_combine, s_nightvision->E[0]);
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
-}
\ No newline at end of file
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
+}
diff --git a/ogsr_engine/Layers/xrRender/rendertarget_phase_thermalvision.cpp b/ogsr_engine/Layers/xrRender/rendertarget_phase_thermalvision.cpp
index 2f98adc52c..7280253493 100644
--- a/ogsr_engine/Layers/xrRender/rendertarget_phase_thermalvision.cpp
+++ b/ogsr_engine/Layers/xrRender/rendertarget_phase_thermalvision.cpp
@@ -4,6 +4,14 @@ void CRenderTarget::phase_heatvision(CBackend& cmd_list)
{
PIX_EVENT(phase_heatvision);
- RenderScreenTriangle(cmd_list, rt_Generic_combine, s_heatvision->E[0]);
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ RenderScreenTriangle(cmd_list, rt_Generic_scene_scratch, s_heatvision->E[0]);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_scene_scratch->pSurface);
+}
+
+void CRenderTarget::phase_heatvision_overlay(CBackend& cmd_list)
+{
+ PIX_EVENT(phase_heatvision_overlay);
+
+ RenderScreenTriangle(cmd_list, rt_Generic_combine, s_heatvision->E[1]);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
}
diff --git a/ogsr_engine/Layers/xrRender/xrRender_console.cpp b/ogsr_engine/Layers/xrRender/xrRender_console.cpp
index 8cf0046315..f212d8c302 100644
--- a/ogsr_engine/Layers/xrRender/xrRender_console.cpp
+++ b/ogsr_engine/Layers/xrRender/xrRender_console.cpp
@@ -47,9 +47,31 @@ constexpr xr_token pp_aa_mode_token[] = {
u32 ps_r_dlss_preset = NVSDK_NGX_DLSS_Hint_Render_Preset_F;
constexpr xr_token dlss_mode_token[]{
{"st_opt_dlss_default", NVSDK_NGX_DLSS_Hint_Render_Preset_Default}, // default behavior, may or may not change after OTA
- {"st_opt_dlss_f", NVSDK_NGX_DLSS_Hint_Render_Preset_F},
- {"st_opt_dlss_j", NVSDK_NGX_DLSS_Hint_Render_Preset_J},
- {"st_opt_dlss_k", NVSDK_NGX_DLSS_Hint_Render_Preset_K},
+ {"st_opt_dlss_f", NVSDK_NGX_DLSS_Hint_Render_Preset_F}, // CNN
+ {"st_opt_dlss_j", NVSDK_NGX_DLSS_Hint_Render_Preset_J}, // Transformer
+ {"st_opt_dlss_k", NVSDK_NGX_DLSS_Hint_Render_Preset_K}, // Transformer
+ {"st_opt_dlss_l", NVSDK_NGX_DLSS_Hint_Render_Preset_L}, // Transformer
+ {"st_opt_dlss_m", NVSDK_NGX_DLSS_Hint_Render_Preset_M}, // Transformer
+ {},
+};
+
+u32 ps_r_dlss_quality = DLSS_QUALITY_DLAA;
+constexpr xr_token dlss_quality_token[]{
+ {"st_opt_dlaa", DLSS_QUALITY_DLAA},
+ {"st_opt_dlss_quality", DLSS_QUALITY_QUALITY},
+ {"st_opt_dlss_balanced", DLSS_QUALITY_BALANCED},
+ {"st_opt_dlss_performance", DLSS_QUALITY_PERFORMANCE},
+ {"st_opt_dlss_ultra_performance", DLSS_QUALITY_ULTRA_PERFORMANCE},
+ {},
+};
+
+u32 ps_r_fsr3_quality = FSR3_QUALITY_NATIVE_AA;
+constexpr xr_token fsr3_quality_token[]{
+ {"st_opt_fsr3_native_aa", FSR3_QUALITY_NATIVE_AA},
+ {"st_opt_fsr3_quality", FSR3_QUALITY_QUALITY},
+ {"st_opt_fsr3_balanced", FSR3_QUALITY_BALANCED},
+ {"st_opt_fsr3_performance", FSR3_QUALITY_PERFORMANCE},
+ {"st_opt_fsr3_ultra_performance", FSR3_QUALITY_ULTRA_PERFORMANCE},
{},
};
@@ -391,6 +413,55 @@ class CCC_ModelPoolStat : public IConsole_Command
virtual void Execute(LPCSTR args) { RImplementation.Models->dump(); }
};
+class CCC_DlssDllVersion : public IConsole_Command
+{
+public:
+ CCC_DlssDllVersion(LPCSTR N) : IConsole_Command(N)
+ {
+ bEmptyArgsHandled = TRUE;
+ bCanSave = FALSE;
+ }
+
+ void Execute(LPCSTR) override {}
+
+ void Status(TStatus& S) override { xr_strcpy(S, ps_r_dlss_dll_version); }
+};
+
+class CCC_DlssQuality : public CCC_Token
+{
+public:
+ CCC_DlssQuality(LPCSTR N, u32* V, const xr_token* T) : CCC_Token(N, V, T) {}
+
+ void Execute(LPCSTR args) override
+ {
+ CCC_Token::Execute(args);
+ R_dlss_refresh_available_presets();
+ }
+};
+
+class CCC_DlssRenderPreset : public CCC_Token
+{
+public:
+ CCC_DlssRenderPreset(LPCSTR N, u32* V, const xr_token* T) : CCC_Token(N, V, T) {}
+
+ bool TokenEnabled(int id) override
+ {
+ R_dlss_refresh_available_presets();
+ return R_dlss_is_preset_available(static_cast(id));
+ }
+
+ void Execute(LPCSTR args) override
+ {
+ CCC_Token::Execute(args);
+ R_dlss_refresh_available_presets();
+ if (!R_dlss_is_preset_available(*value))
+ {
+ Msg("! DLSS preset is not available, falling back to Default");
+ *value = NVSDK_NGX_DLSS_Hint_Render_Preset_Default;
+ }
+ }
+};
+
class CCC_Preset : public CCC_Token
{
public:
@@ -821,7 +892,10 @@ void xrRender_initconsole()
CMD4(CCC_Float, "r2_visor_refl_radius", &ps_r2_visor_refl_radius, 0.3f, 0.6f);
CMD3(CCC_Token, "r_aa_mode", &ps_r_pp_aa_mode, pp_aa_mode_token);
- //CMD3(CCC_Token, "r_aa_dlss_preset", &ps_r_dlss_preset, dlss_mode_token);
+ CMD3(CCC_DlssQuality, "r_aa_dlss_quality", &ps_r_dlss_quality, dlss_quality_token);
+ CMD3(CCC_Token, "r_aa_fsr3_quality", &ps_r_fsr3_quality, fsr3_quality_token);
+ CMD3(CCC_DlssRenderPreset, "r_aa_dlss_preset", &ps_r_dlss_preset, dlss_mode_token);
+ CMD1(CCC_DlssDllVersion, "r_aa_dlss_version");
CMD4(CCC_Float, "r_3dss_scale_factor", &ps_r_dlss_3dss_scale_factor, 1.f, 2.5f);
diff --git a/ogsr_engine/Layers/xrRender/xrRender_console.h b/ogsr_engine/Layers/xrRender/xrRender_console.h
index a57d3b88d6..e3f0c527f4 100644
--- a/ogsr_engine/Layers/xrRender/xrRender_console.h
+++ b/ogsr_engine/Layers/xrRender/xrRender_console.h
@@ -5,8 +5,32 @@ extern ECORE_API u32 r2_SmapCascade0Size, /*r2_SmapCascade1Size,*/ r2_SmapCascad
extern ECORE_API u32 ps_r_pp_aa_mode;
extern ECORE_API u32 ps_r_dlss_preset;
+extern ECORE_API u32 ps_r_dlss_quality;
+
+bool R_dlss_is_preset_available(u32 preset);
+void R_dlss_refresh_available_presets();
+extern char ps_r_dlss_dll_version[64];
+extern ECORE_API u32 ps_r_fsr3_quality;
extern float ps_r_dlss_3dss_scale_factor;
+enum : u32
+{
+ DLSS_QUALITY_DLAA,
+ DLSS_QUALITY_QUALITY,
+ DLSS_QUALITY_BALANCED,
+ DLSS_QUALITY_PERFORMANCE,
+ DLSS_QUALITY_ULTRA_PERFORMANCE,
+};
+
+enum : u32
+{
+ FSR3_QUALITY_NATIVE_AA,
+ FSR3_QUALITY_QUALITY,
+ FSR3_QUALITY_BALANCED,
+ FSR3_QUALITY_PERFORMANCE,
+ FSR3_QUALITY_ULTRA_PERFORMANCE,
+};
+
extern ECORE_API u32 ps_r_sun_shafts;
extern ECORE_API u32 ps_r_sunshafts_mode;
diff --git a/ogsr_engine/Layers/xrRenderDX10/3DFluid/dx103DFluidRenderer.cpp b/ogsr_engine/Layers/xrRenderDX10/3DFluid/dx103DFluidRenderer.cpp
index c98d1560b5..d73b58ef62 100644
--- a/ogsr_engine/Layers/xrRenderDX10/3DFluid/dx103DFluidRenderer.cpp
+++ b/ogsr_engine/Layers/xrRenderDX10/3DFluid/dx103DFluidRenderer.cpp
@@ -369,7 +369,7 @@ void dx103DFluidRenderer::Draw(CBackend& cmd_list, const dx103DFluidData& FluidD
RImplementation.rmNormal(cmd_list);
- PrepareCBuffer(cmd_list, FluidData, Device.dwWidth, Device.dwHeight);
+ PrepareCBuffer(cmd_list, FluidData, pTarget->GetRenderWidth(), pTarget->GetRenderHeight());
cmd_list.set_c(strDiffuseLight, LightData.m_vLightIntencity.x, LightData.m_vLightIntencity.y, LightData.m_vLightIntencity.z, 1.0f);
@@ -383,10 +383,11 @@ void dx103DFluidRenderer::ComputeRayData(CBackend& cmd_list, const dx103DFluidDa
CRenderTarget* pTarget = RImplementation.Target;
pTarget->u_setrt(cmd_list, RT[RRT_RayDataTex], nullptr, nullptr, nullptr); // LDR RT
+ RImplementation.rmNormal(cmd_list);
cmd_list.set_Element(m_RendererTechnique[RS_CompRayData_Back]);
- PrepareCBuffer(cmd_list, FluidData, Device.dwWidth, Device.dwHeight);
+ PrepareCBuffer(cmd_list, FluidData, pTarget->GetRenderWidth(), pTarget->GetRenderHeight());
// Render volume back faces
// We output xyz=(0,-1,0) and w=min(sceneDepth, boxDepth)
@@ -397,7 +398,7 @@ void dx103DFluidRenderer::ComputeRayData(CBackend& cmd_list, const dx103DFluidDa
// unless the pixel is occluded by the scene, in which case we output xyzw=(1,0,0,0)
pTarget->u_setrt(cmd_list, RT[RRT_RayDataTex], nullptr, nullptr, nullptr); // LDR RT
cmd_list.set_Element(m_RendererTechnique[RS_CompRayData_Front]);
- PrepareCBuffer(cmd_list, FluidData, Device.dwWidth, Device.dwHeight);
+ PrepareCBuffer(cmd_list, FluidData, pTarget->GetRenderWidth(), pTarget->GetRenderHeight());
DrawBox(cmd_list);
}
@@ -405,6 +406,7 @@ void dx103DFluidRenderer::ComputeEdgeTexture(CBackend& cmd_list, const dx103DFlu
{
CRenderTarget* pTarget = RImplementation.Target;
pTarget->u_setrt(cmd_list, RT[RRT_RayDataTexSmall], nullptr, nullptr, nullptr); // LDR RT
+ RImplementation.rmNormal(cmd_list);
cmd_list.set_Element(m_RendererTechnique[RS_QuadDownSampleRayDataTexture]);
// First setup viewport to match the size of the destination low-res texture
@@ -415,6 +417,7 @@ void dx103DFluidRenderer::ComputeEdgeTexture(CBackend& cmd_list, const dx103DFlu
// Create an edge texture, performing edge detection on 'rayDataTexSmall'
pTarget->u_setrt(cmd_list, RT[RRT_EdgeTex], nullptr, nullptr, nullptr); // LDR RT
+ RImplementation.rmNormal(cmd_list);
cmd_list.set_Element(m_RendererTechnique[RS_QuadEdgeDetect]);
PrepareCBuffer(cmd_list, FluidData, m_iRenderTextureWidth, m_iRenderTextureHeight);
DrawScreenQuad(cmd_list);
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4.cpp b/ogsr_engine/Layers/xrRenderPC_R4/r4.cpp
index 7ffe76935b..d5aef74031 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4.cpp
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4.cpp
@@ -120,7 +120,7 @@ void CRender::create()
#ifdef DX10_FLUID_ENABLE
FluidManager.Initialize(70, 70, 70);
// FluidManager.Initialize( 100, 100, 100 );
- FluidManager.SetScreenSize(Device.dwWidth, Device.dwHeight);
+ FluidManager.SetScreenSize(Target->GetRenderWidth(), Target->GetRenderHeight());
#endif
}
@@ -203,7 +203,7 @@ void CRender::reset_end()
//-AVO
#ifdef DX10_FLUID_ENABLE
- FluidManager.SetScreenSize(Device.dwWidth, Device.dwHeight);
+ FluidManager.SetScreenSize(Target->GetRenderWidth(), Target->GetRenderHeight());
#endif
cleanup_contexts();
@@ -236,7 +236,21 @@ void CRender::OnFrame()
// После рендера мира и пост-эффектов --#SM+#-- +SecondVP+
void CRender::AfterWorldRender() { Target->u_setrt(get_imm_context().cmd_list, Device.dwWidth, Device.dwHeight, Target->rt_second_vp->pRT, nullptr, nullptr, nullptr); }
-void CRender::AfterUIRender() { Target->u_setrt(get_imm_context().cmd_list, Device.dwWidth, Device.dwHeight, Target->get_base_rt(), nullptr, nullptr, nullptr); }
+void CRender::AfterUIRender() { SetupDisplayBackbuffer(); }
+
+void CRender::SetupDisplayBackbuffer()
+{
+ if (!Target)
+ return;
+
+ // Loading / 2D UI can run without CRender::Render(), so do not inherit the
+ // scene-resolution viewport or bind render-sized depth onto the swapchain.
+ Target->EndTemporalUpscaleInput();
+
+ auto& cmd_list = get_imm_context().cmd_list;
+ Target->u_setrt(cmd_list, Device.dwWidth, Device.dwHeight, Target->get_base_rt(), nullptr, nullptr, nullptr);
+ rmNormal(cmd_list);
+}
// Implementation
IRender_ObjectSpecific* CRender::ros_create(IRenderable* parent) { return xr_new(); }
@@ -381,22 +395,19 @@ void CRender::clear_static_wallmarks() { Wallmarks->Clear(); }
void CRender::rmNear(CBackend& cmd_list)
{
- IRender_Target* T = getTarget();
- const D3D_VIEWPORT viewport = {0, 0, T->get_width(cmd_list), T->get_height(cmd_list), 0.f, 0.02f};
+ const D3D_VIEWPORT viewport = {0, 0, Target->GetViewportWidth(cmd_list), Target->GetViewportHeight(cmd_list), 0.f, 0.02f};
cmd_list.SetViewport(viewport);
}
void CRender::rmFar(CBackend& cmd_list)
{
- IRender_Target* T = getTarget();
- const D3D_VIEWPORT viewport = {0, 0, T->get_width(cmd_list), T->get_height(cmd_list), 0.99999f, 1.f};
+ const D3D_VIEWPORT viewport = {0, 0, Target->GetViewportWidth(cmd_list), Target->GetViewportHeight(cmd_list), 0.99999f, 1.f};
cmd_list.SetViewport(viewport);
}
void CRender::rmNormal(CBackend& cmd_list)
{
- IRender_Target* T = getTarget();
- const D3D_VIEWPORT viewport = {0, 0, T->get_width(cmd_list), T->get_height(cmd_list), 0.f, 1.f};
+ const D3D_VIEWPORT viewport = {0, 0, Target->GetViewportWidth(cmd_list), Target->GetViewportHeight(cmd_list), 0.f, 1.f};
cmd_list.SetViewport(viewport);
}
@@ -961,7 +972,13 @@ void CRender::Begin()
}
// state main state parms on frame start only
- SSManager.SetParams(ps_r__tf_Anisotropic, ps_r__tf_Mipbias);
+ float mipBias = ps_r__tf_Mipbias;
+ if (Target && Target->GetRenderWidth() < Target->GetDisplayWidth())
+ {
+ const float renderScale = static_cast(Target->GetRenderWidth()) / static_cast(Target->GetDisplayWidth());
+ mipBias += std::log2(renderScale);
+ }
+ SSManager.SetParams(ps_r__tf_Anisotropic, mipBias);
Vertex.Flush();
Index.Flush();
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4.h b/ogsr_engine/Layers/xrRenderPC_R4/r4.h
index ec9fac31c2..5cea033cd8 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4.h
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4.h
@@ -325,6 +325,7 @@ class CRender : public IRender_interface, public pureFrame
void AfterWorldRender() override; //Вызывается после рендера мира и перед UI ПДА
void AfterUIRender() override; //После рендеринга UI. Вызывать только если нам нужно отрендерить кадр для пда.
+ void SetupDisplayBackbuffer() override;
// Render mode
virtual void rmNear(CBackend& cmd_list);
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4_R_render.cpp b/ogsr_engine/Layers/xrRenderPC_R4/r4_R_render.cpp
index 1f57c498cd..6442f755e3 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4_R_render.cpp
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4_R_render.cpp
@@ -276,27 +276,45 @@ void CRender::Render()
VERIFY(0 == mapDistort.size());
+ Target->BeginTemporalUpscaleInput();
+ Target->u_setrt(cmd_list, Target->GetRenderWidth(), Target->GetRenderHeight(), nullptr, nullptr, nullptr, nullptr);
rmNormal(cmd_list);
if (ShouldSkipRender())
{
- Target->u_setrt(cmd_list, Device.dwWidth, Device.dwHeight, Target->get_base_rt(), nullptr, nullptr, Target->get_base_zb());
+ Target->ResetTemporalHistory();
+ Target->EndTemporalUpscaleInput();
+ Target->u_setrt(cmd_list, Device.dwWidth, Device.dwHeight, Target->get_base_rt(), nullptr, nullptr, nullptr);
+ rmNormal(cmd_list);
return;
}
if (m_bFirstFrameAfterReset)
{
m_bFirstFrameAfterReset = false;
+ Target->EndTemporalUpscaleInput();
+ Target->u_setrt(cmd_list, Device.dwWidth, Device.dwHeight, Target->get_base_rt(), nullptr, nullptr, nullptr);
+ rmNormal(cmd_list);
return;
}
- if (ps_pnv_mode < 2 && (ps_r_pp_aa_mode == DLSS || ps_r_pp_aa_mode == FSR3 || ps_r_pp_aa_mode == TAA || ps_r2_ls_flags.test(R2FLAG_DBG_TAA_JITTER_ENABLE)))
+ constexpr float temporalCameraCutDistance = 5.f;
+ constexpr float temporalCameraCutDirectionDot = 0.25f;
+ if (Device.vCameraPosition.distance_to_sqr(Device.vCameraPositionSaved) > _sqr(temporalCameraCutDistance) ||
+ Device.vCameraDirection.dotproduct(Device.vCameraDirectionSaved) < temporalCameraCutDirectionDot)
{
- auto jitterPhaseCount = ffxFsr3UpscalerGetJitterPhaseCount(static_cast(Device.dwWidth), static_cast(Device.dwWidth));
+ Target->ResetTemporalHistory();
+ }
+
+ if (ps_r_pp_aa_mode == DLSS || ps_r_pp_aa_mode == FSR3 || ps_r_pp_aa_mode == TAA || ps_r2_ls_flags.test(R2FLAG_DBG_TAA_JITTER_ENABLE))
+ {
+ const u32 renderWidth = Target->GetRenderWidth();
+ const u32 renderHeight = Target->GetRenderHeight();
+ auto jitterPhaseCount = ffxFsr3UpscalerGetJitterPhaseCount(static_cast(renderWidth), static_cast(Target->GetDisplayWidth()));
ffxFsr3UpscalerGetJitterOffset(&ps_r_taa_jitter_full.x, &ps_r_taa_jitter_full.y, Device.dwFrame, jitterPhaseCount);
- ps_r_taa_jitter.x = 2.0f * ps_r_taa_jitter_full.x / Device.dwWidth;
- ps_r_taa_jitter.y = -2.0f * ps_r_taa_jitter_full.y / Device.dwHeight;
+ ps_r_taa_jitter.x = 2.0f * ps_r_taa_jitter_full.x / renderWidth;
+ ps_r_taa_jitter.y = -2.0f * ps_r_taa_jitter_full.y / renderHeight;
ps_r_taa_jitter.z = static_cast(Device.dwFrame % jitterPhaseCount) / static_cast(jitterPhaseCount) + EPS;
}
else
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget.cpp b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget.cpp
index 40315bd42a..c7006cde0d 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget.cpp
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget.cpp
@@ -122,6 +122,7 @@ void CRenderTarget::u_setrt(CBackend& cmd_list, u32 W, u32 H, ID3DRenderTargetVi
cmd_list.set_RT(_1, 0);
cmd_list.set_RT(_2, 1);
cmd_list.set_RT(_3, 2);
+ cmd_list.set_RT(nullptr, 3);
cmd_list.set_ZB(zb);
}
@@ -173,10 +174,21 @@ void CRenderTarget::reset_target_dimensions()
}
}
+void CRenderTarget::SetTemporalRenderSize(u32 renderWidth, u32 renderHeight, u32 displayWidth, u32 displayHeight)
+{
+ m_displayWidth = _max(1u, displayWidth);
+ m_displayHeight = _max(1u, displayHeight);
+ m_renderWidth = std::clamp(renderWidth, 1u, m_displayWidth);
+ m_renderHeight = std::clamp(renderHeight, 1u, m_displayHeight);
+}
+
CRenderTarget::CRenderTarget()
{
const auto& options = RImplementation.o;
+ SetTemporalRenderSize(Device.dwWidth, Device.dwHeight, Device.dwWidth, Device.dwHeight);
+ ConfigureTemporalRenderSize();
+
param_blur = 0.f;
param_gray = 0.f;
param_noise = 0.f;
@@ -199,14 +211,15 @@ CRenderTarget::CRenderTarget()
// NORMAL
{
- u32 w = Device.dwWidth, h = Device.dwHeight;
+ const u32 w = GetRenderWidth(), h = GetRenderHeight();
+ const u32 displayW = GetDisplayWidth(), displayH = GetDisplayHeight();
rt_base.resize(1);
for (u32 i = 0; i < 1; i++)
{
string32 temp;
xr_sprintf(temp, "%s%u", r2_RT_base, i);
- rt_base[i].create(temp, w, h, DXGI_FORMAT_R8G8B8A8_UNORM, 1, {CRT::CreateBase});
+ rt_base[i].create(temp, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM, 1, {CRT::CreateBase});
}
rt_Base_Depth.create(r2_RT_base_depth, w, h, DXGI_FORMAT_R24G8_TYPELESS);
@@ -226,44 +239,44 @@ CRenderTarget::CRenderTarget()
rt_Generic_3.create(r2_RT_generic3, w, h, DXGI_FORMAT_R16G16B16A16_FLOAT);
// RT Blur
- rt_blur_h_2.create(r2_RT_blur_h_2, u32(w / 2), u32(h / 2), DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_blur_2.create(r2_RT_blur_2, u32(w / 2), u32(h / 2), DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_blur_h_2.create(r2_RT_blur_h_2, u32(displayW / 2), u32(displayH / 2), DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_blur_2.create(r2_RT_blur_2, u32(displayW / 2), u32(displayH / 2), DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_blur_h_4.create(r2_RT_blur_h_4, u32(w / 4), u32(h / 4), DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_blur_4.create(r2_RT_blur_4, u32(w / 4), u32(h / 4), DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_blur_h_4.create(r2_RT_blur_h_4, u32(displayW / 4), u32(displayH / 4), DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_blur_4.create(r2_RT_blur_4, u32(displayW / 4), u32(displayH / 4), DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_blur_h_8.create(r2_RT_blur_h_8, u32(w / 8), u32(h / 8), DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_blur_8.create(r2_RT_blur_8, u32(w / 8), u32(h / 8), DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_blur_h_8.create(r2_RT_blur_h_8, u32(displayW / 8), u32(displayH / 8), DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_blur_8.create(r2_RT_blur_8, u32(displayW / 8), u32(displayH / 8), DXGI_FORMAT_R8G8B8A8_UNORM);
rt_pp_bloom.create(r2_RT_pp_bloom, w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_ssfx_bloom1.create(r2_RT_ssfx_bloom1, u32(w / 2), u32(h / 2), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom
+ rt_ssfx_bloom1.create(r2_RT_ssfx_bloom1, u32(displayW / 2), u32(displayH / 2), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom
rt_ssfx_bloom_emissive.create(r2_RT_ssfx_bloom_emissive, w, h, DXGI_FORMAT_R8G8B8A8_UNORM); // Emissive
- rt_ssfx_bloom_lens.create(r2_RT_ssfx_bloom_lens, u32(w / 4), u32(h / 4), DXGI_FORMAT_R8G8B8A8_UNORM); // Lens
- rt_ssfx_bloom_tmp2.create(r2_RT_ssfx_bloom_tmp2, u32(w / 2), u32(h / 2), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 2
- rt_ssfx_bloom_tmp4.create(r2_RT_ssfx_bloom_tmp4, u32(w / 4), u32(h / 4), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 4
- rt_ssfx_bloom_tmp8.create(r2_RT_ssfx_bloom_tmp8, u32(w / 8), u32(h / 8), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 8
- rt_ssfx_bloom_tmp16.create(r2_RT_ssfx_bloom_tmp16, u32(w / 16), u32(h / 16), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 16
- rt_ssfx_bloom_tmp32.create(r2_RT_ssfx_bloom_tmp32, u32(w / 32), u32(h / 32), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 32
- rt_ssfx_bloom_tmp64.create(r2_RT_ssfx_bloom_tmp64, u32(w / 64), u32(h / 64), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 64
- rt_ssfx_bloom_tmp32_2.create(r2_RT_ssfx_bloom_tmp32_2, u32(w / 32), u32(h / 32), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 32
- rt_ssfx_bloom_tmp16_2.create(r2_RT_ssfx_bloom_tmp16_2, u32(w / 16), u32(h / 16), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 16
- rt_ssfx_bloom_tmp8_2.create(r2_RT_ssfx_bloom_tmp8_2, u32(w / 8), u32(h / 8), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 8
- rt_ssfx_bloom_tmp4_2.create(r2_RT_ssfx_bloom_tmp4_2, u32(w / 4), u32(h / 4), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 4
+ rt_ssfx_bloom_lens.create(r2_RT_ssfx_bloom_lens, u32(displayW / 4), u32(displayH / 4), DXGI_FORMAT_R8G8B8A8_UNORM); // Lens
+ rt_ssfx_bloom_tmp2.create(r2_RT_ssfx_bloom_tmp2, u32(displayW / 2), u32(displayH / 2), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 2
+ rt_ssfx_bloom_tmp4.create(r2_RT_ssfx_bloom_tmp4, u32(displayW / 4), u32(displayH / 4), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 4
+ rt_ssfx_bloom_tmp8.create(r2_RT_ssfx_bloom_tmp8, u32(displayW / 8), u32(displayH / 8), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 8
+ rt_ssfx_bloom_tmp16.create(r2_RT_ssfx_bloom_tmp16, u32(displayW / 16), u32(displayH / 16), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 16
+ rt_ssfx_bloom_tmp32.create(r2_RT_ssfx_bloom_tmp32, u32(displayW / 32), u32(displayH / 32), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 32
+ rt_ssfx_bloom_tmp64.create(r2_RT_ssfx_bloom_tmp64, u32(displayW / 64), u32(displayH / 64), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 64
+ rt_ssfx_bloom_tmp32_2.create(r2_RT_ssfx_bloom_tmp32_2, u32(displayW / 32), u32(displayH / 32), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 32
+ rt_ssfx_bloom_tmp16_2.create(r2_RT_ssfx_bloom_tmp16_2, u32(displayW / 16), u32(displayH / 16), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 16
+ rt_ssfx_bloom_tmp8_2.create(r2_RT_ssfx_bloom_tmp8_2, u32(displayW / 8), u32(displayH / 8), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 8
+ rt_ssfx_bloom_tmp4_2.create(r2_RT_ssfx_bloom_tmp4_2, u32(displayW / 4), u32(displayH / 4), DXGI_FORMAT_R16G16B16A16_FLOAT); // Bloom / 4
- rt_dof.create(r2_RT_dof, w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_dof.create(r2_RT_dof, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_second_vp.create(r2_RT_secondVP, w, h, DXGI_FORMAT_R8G8B8A8_UNORM); //--#SM+#-- +SecondVP+
+ rt_second_vp.create(r2_RT_secondVP, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM); //--#SM+#-- +SecondVP+
- rt_fakescope.create(r2_RT_scopert, w, h, DXGI_FORMAT_R8G8B8A8_UNORM); // crookr fakescope
+ rt_fakescope.create(r2_RT_scopert, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM); // crookr fakescope
rt_heat.create(r2_RT_heat, w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_mask_drops_blur.create(r2_RT_mask_drops_blur, w, h, DXGI_FORMAT_R8G8B8A8_UNORM); // Create RT, full resolution
+ rt_mask_drops_blur.create(r2_RT_mask_drops_blur, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM); // Create RT, full resolution
rt_ssr1.create(r2_RT_ssr1, w, h, DXGI_FORMAT_R8G8B8A8_UNORM); // Generic RT
rt_ssr2.create(r2_RT_ssr2, w, h, DXGI_FORMAT_R8G8B8A8_UNORM); // Temp RT 8B
- rt_flares.create(r2_RT_flares, w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_flares.create(r2_RT_flares, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM);
rt_Velocity.create(r2_RT_velocity, w, h, DXGI_FORMAT_R16G16_FLOAT);
rt_zbuffer.create(r2_RT_zbuffer, w, h, DXGI_FORMAT_R24G8_TYPELESS);
@@ -275,7 +288,9 @@ CRenderTarget::CRenderTarget()
if (HW.FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
flg = {CRT::CreateUAV};
- rt_Generic_combine.create(r2_RT_generic_combine, w, h, DXGI_FORMAT_R16G16B16A16_FLOAT, 1, flg);
+ rt_Generic_scene_scratch.create("$user$generic_scene_scratch", w, h, DXGI_FORMAT_R16G16B16A16_FLOAT, 1, flg);
+ rt_Generic_combine.create(r2_RT_generic_combine, displayW, displayH, DXGI_FORMAT_R16G16B16A16_FLOAT, 1, flg);
+ rt_Postprocess_0.create("$user$postprocess0", displayW, displayH, DXGI_FORMAT_R16G16B16A16_FLOAT);
//if (!m_ImguiTex)
@@ -320,6 +335,7 @@ CRenderTarget::CRenderTarget()
s_taa.create("temporal_antialiasing");
s_cas.create("contrast_adaptive_sharpening");
+ s_temporal_resolve.create("temporal_resolve");
for (u32 idx{}; const auto& size : options.sun_cascades_smapsize)
{
@@ -407,7 +423,7 @@ CRenderTarget::CRenderTarget()
rt_LUM_pool[it].create(name, 1, 1, DXGI_FORMAT_R32_FLOAT);
RCache.ClearRT(rt_LUM_pool[it]->pRT, 0x7f7f7f7f);
}
- u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), nullptr, nullptr, get_base_zb());
+ u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), nullptr, nullptr, nullptr);
}
// COMBINE
@@ -439,18 +455,18 @@ CRenderTarget::CRenderTarget()
s_pp_antialiasing.create("effects_pp_antialiasing");
}
- // Mrmnwar SunShaft Screen Space
+ // Screen-space sunshafts run after temporal upscale, so they match the
+ // display-sized postprocess targets rather than the scene render size.
{
- rt_SunShaftsMask.create(r2_RT_SunShaftsMask, w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_SunShaftsMaskSmoothed.create(r2_RT_SunShaftsMaskSmoothed, w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_SunShaftsPass0.create(r2_RT_SunShaftsPass0, w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
+ const u32 displayW = GetDisplayWidth(), displayH = GetDisplayHeight();
+
+ rt_SunShaftsMask.create(r2_RT_SunShaftsMask, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_SunShaftsMaskSmoothed.create(r2_RT_SunShaftsMaskSmoothed, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_SunShaftsPass0.create(r2_RT_SunShaftsPass0, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM);
s_ssss_mrmnwar.create("effects\\ss_sunshafts_mrmnwar");
- }
- // RT - KD Screen space sunshafts
- {
- rt_sunshafts_0.create(r2_RT_sunshafts0, w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
- rt_sunshafts_1.create(r2_RT_sunshafts1, w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_sunshafts_0.create(r2_RT_sunshafts0, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM);
+ rt_sunshafts_1.create(r2_RT_sunshafts1, displayW, displayH, DXGI_FORMAT_R8G8B8A8_UNORM);
s_ssss_ogse.create("effects\\ss_sunshafts_ogse");
}
@@ -589,8 +605,8 @@ void CRenderTarget::reset_light_marker(CBackend& cmd_list, bool bResetStencil)
if (bResetStencil)
{
u32 Offset;
- const float _w = float(Device.dwWidth);
- const float _h = float(Device.dwHeight);
+ const float _w = float(get_width(cmd_list));
+ const float _h = float(get_height(cmd_list));
const u32 C = color_rgba(255, 255, 255, 255);
const float eps = 0;
const float _dw = 0.5f;
@@ -633,4 +649,4 @@ bool CRenderTarget::need_to_render_sunshafts()
if (fValue(m_renderWidth) / static_cast(m_displayWidth); }
+ float GetRenderSubrectScaleY() const { return static_cast(m_renderHeight) / static_cast(m_displayHeight); }
+ bool IsTemporalUpscaleInput() const { return m_temporalUpscaleInput; }
+
+ void SetTemporalRenderSize(u32 renderWidth, u32 renderHeight, u32 displayWidth, u32 displayHeight);
+ void ConfigureTemporalRenderSize();
+ void BeginTemporalUpscaleInput() { m_temporalUpscaleInput = true; }
+ void EndTemporalUpscaleInput() { m_temporalUpscaleInput = false; }
+ void ResetTemporalHistory();
+
virtual void set_cm_imfluence(float f) { param_color_map_influence = f; }
virtual void set_cm_interpolate(float f) { param_color_map_interpolate = f; }
virtual void set_cm_textures(const shared_str& tex0, const shared_str& tex1) { color_map_manager.SetTextures(tex0, tex1); }
@@ -333,13 +361,14 @@ class CRenderTarget : public IRender_Target
void DestroyDLSS();
void InitFSR();
- bool ProcessFSR() const;
+ bool ProcessFSR();
bool ProcessFSR_3DSS(const bool need_reset);
void DestroyFSR();
bool reset_3dss_rendertarget(const bool need_reset = false);
void ProcessCAS(CBackend& cmd_list);
+ void BeginPostprocess(CBackend& cmd_list, bool temporalOutput);
void PhaseSSSS(CBackend& cmd_list);
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_accum_direct.cpp b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_accum_direct.cpp
index 767c175159..9052b34500 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_accum_direct.cpp
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_accum_direct.cpp
@@ -43,8 +43,8 @@ void CRenderTarget::accum_direct_cascade(CBackend& cmd_list, u32 sub_phase, Fmat
// Common calc for quad-rendering
u32 Offset;
constexpr u32 C = color_rgba(255, 255, 255, 255);
- float _w = float(Device.dwWidth);
- float _h = float(Device.dwHeight);
+ float _w = float(get_width(cmd_list));
+ float _h = float(get_height(cmd_list));
Fvector2 p0, p1;
p0.set(.5f / _w, .5f / _h);
p1.set((_w + .5f) / _w, (_h + .5f) / _h);
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_draw_rain.cpp b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_draw_rain.cpp
index 919c34e9a1..e61a0f9cbf 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_draw_rain.cpp
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_draw_rain.cpp
@@ -5,8 +5,8 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup)
// Common calc for quad-rendering
u32 Offset;
u32 C = color_rgba(255, 255, 255, 255);
- float _w = float(Device.dwWidth);
- float _h = float(Device.dwHeight);
+ float _w = float(get_width(cmd_list));
+ float _h = float(get_height(cmd_list));
Fvector2 p0, p1;
p0.set(.5f / _w, .5f / _h);
p1.set((_w + .5f) / _w, (_h + .5f) / _h);
@@ -111,7 +111,7 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup)
// Make jitter texture
Fvector2 j0, j1;
- float scale_X = float(Device.dwWidth) / float(TEX_jitter);
+ float scale_X = _w / float(TEX_jitter);
float offset = (.5f / float(TEX_jitter));
j0.set(offset, offset);
j1.set(scale_X, scale_X).add(offset);
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_PP.cpp b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_PP.cpp
index fcbb736184..b103534544 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_PP.cpp
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_PP.cpp
@@ -84,6 +84,7 @@ void CRenderTarget::phase_pp(CBackend& cmd_list)
{
// combination/postprocess
u_setrt(cmd_list, Device.dwWidth, Device.dwHeight, get_base_rt(), nullptr, nullptr, nullptr);
+ RImplementation.rmNormal(cmd_list);
const bool bCMap = u_need_CM();
cmd_list.set_Element(s_postprocess->E[bCMap ? 4 : 0]);
@@ -121,4 +122,4 @@ void CRenderTarget::phase_pp(CBackend& cmd_list)
cmd_list.set_c("c_colormap", param_color_map_influence, param_color_map_interpolate, 0, 0);
cmd_list.set_Geometry(g_postprocess);
cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2);
-}
\ No newline at end of file
+}
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_bloom.cpp b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_bloom.cpp
index 175fb32016..ee25d82469 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_bloom.cpp
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_bloom.cpp
@@ -24,8 +24,8 @@ void CRenderTarget::phase_bloom(CBackend& cmd_list)
// Transfer into Bloom1
{
- float _w = float(Device.dwWidth);
- float _h = float(Device.dwHeight);
+ float _w = float(GetRenderWidth());
+ float _h = float(GetRenderHeight());
float _2w = _w / 2;
float tw = BLOOM_size_X;
float _2h = _h / 2;
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp
index 1e496caf1b..321bfef136 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp
@@ -117,12 +117,12 @@ void CRenderTarget::phase_combine(CBackend& cmd_list)
HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_ssr1->pSurface, rt_ssr2->pSurface);
- RenderScreenTriangle(cmd_list, rt_Generic_combine, s_ssr->E[1], [&]() {
+ RenderScreenTriangle(cmd_list, rt_Generic_scene_scratch, s_ssr->E[1], [&]() {
cmd_list.set_c("ssr_setup", ps_ssfx_ssr_1);
cmd_list.set_c("ssfx_ssr_2", ps_ssfx_ssr_2);
});
- HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_Generic_0->pSurface, rt_Generic_scene_scratch->pSurface);
}
// Forward rendering
@@ -163,8 +163,8 @@ void CRenderTarget::phase_combine(CBackend& cmd_list)
{
PIX_EVENT(combine_distort);
- RenderScreenTriangle(cmd_list, rt_Generic_combine, s_combine->E[1]);
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ RenderScreenTriangle(cmd_list, rt_Generic_scene_scratch, s_combine->E[1]);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_scene_scratch->pSurface);
}
}
@@ -176,17 +176,16 @@ void CRenderTarget::phase_combine(CBackend& cmd_list)
{
PIX_EVENT(combine_tonemap);
- RenderScreenTriangle(cmd_list, rt_Generic_combine, s_combine->E[2]);
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ RenderScreenTriangle(cmd_list, rt_Generic_scene_scratch, s_combine->E[2]);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_scene_scratch->pSurface);
}
const bool need_heatvision = (ps_pnv_mode == 2 || ps_pnv_mode == 3);
const bool need_3dss = !dsgraph.mapScopeHUDSorted.empty();
- if (need_heatvision) // должен быть до 3DSS
- {
+ // Stable false-color at render resolution so DLSS/FSR can reconstruct heat shapes.
+ if (need_heatvision)
phase_heatvision(cmd_list);
- }
const bool upscaled_3dss = (!need_heatvision && need_3dss && Phase3DSSUpscale(cmd_list));
@@ -194,6 +193,16 @@ void CRenderTarget::phase_combine(CBackend& cmd_list)
{
PhaseAA(cmd_list); // anti - aliasing
}
+ else
+ {
+ EndTemporalUpscaleInput();
+ RImplementation.rmNormal(cmd_list);
+ BeginPostprocess(cmd_list, false);
+ }
+
+ // Sensor noise / lens after temporal upscaling. Before 3DSS so the reticle is not thermal-tinted.
+ if (need_heatvision)
+ phase_heatvision_overlay(cmd_list);
if (!need_heatvision) // должны быть до 3DSS
{ // Screen space sunshafts
@@ -206,7 +215,10 @@ void CRenderTarget::phase_combine(CBackend& cmd_list)
{
PIX_EVENT(phase_3DSSReticle);
- u_setrt(cmd_list, rt_Generic_0, nullptr, nullptr, nullptr, get_base_zb());
+ // The reticle is composited after temporal upscaling. Scene depth is
+ // render-sized and cannot be bound with this display-sized color RT.
+ u_setrt(cmd_list, rt_Postprocess_0, nullptr, nullptr, nullptr, nullptr);
+ RImplementation.rmNormal(cmd_list);
cmd_list.set_CullMode(CULL_CCW);
cmd_list.set_Stencil(FALSE);
@@ -274,7 +286,7 @@ void CRenderTarget::phase_combine(CBackend& cmd_list)
cmd_list.set_c("m_blur", m_blur_scale.x, m_blur_scale.y, 0, 0);
});
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
}
{
@@ -304,7 +316,8 @@ void CRenderTarget::phase_combine(CBackend& cmd_list)
phase_flares(cmd_list);
- u_setrt(cmd_list, Device.dwWidth, Device.dwHeight, get_base_rt(), nullptr, nullptr, get_base_zb()); /// TODO: check cmd_list
+ u_setrt(cmd_list, Device.dwWidth, Device.dwHeight, get_base_rt(), nullptr, nullptr, nullptr);
+ RImplementation.rmNormal(cmd_list);
#ifdef DEBUG
cmd_list.set_CullMode(CULL_CCW);
@@ -389,7 +402,11 @@ void CRenderTarget::phase_flares(CBackend& cmd_list)
return;
// clear
- u_setrt(cmd_list, rt_flares, nullptr, nullptr, nullptr, rt_Base_Depth->pZRT[cmd_list.context_id]);
+ // Flares are generated after temporal upscaling and consumed by the
+ // display-sized combine pass. Keep their target and viewport in the
+ // display domain; the flare shader performs its own depth lookup.
+ u_setrt(cmd_list, rt_flares, nullptr, nullptr, nullptr, nullptr);
+ RImplementation.rmNormal(cmd_list);
// Targets
if (dwFlareClearMark != Device.dwFrame)
@@ -523,4 +540,4 @@ void CRenderTarget::render_flare(CBackend& cmd_list, light* L)
cmd_list.Render(D3DPT_TRIANGLELIST, VS_Offset, 0, 4, 0, 2);
-}
\ No newline at end of file
+}
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_lut.cpp b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_lut.cpp
index 75b1536417..39e29ad2b1 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_lut.cpp
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_lut.cpp
@@ -8,5 +8,5 @@ void CRenderTarget::phase_lut(CBackend& cmd_list)
PIX_EVENT(phase_LUT);
RenderScreenTriangle(cmd_list, rt_Generic_combine, s_lut->E[0]);
- HW.get_context(cmd_list.context_id)->CopyResource(rt_Generic_0->pSurface, rt_Generic_combine->pSurface);
-}
\ No newline at end of file
+ HW.get_context(cmd_list.context_id)->CopyResource(rt_Postprocess_0->pSurface, rt_Generic_combine->pSurface);
+}
diff --git a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_occq.cpp b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_occq.cpp
index e880770d8a..336f214de3 100644
--- a/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_occq.cpp
+++ b/ogsr_engine/Layers/xrRenderPC_R4/r4_rendertarget_phase_occq.cpp
@@ -2,7 +2,10 @@
void CRenderTarget::phase_occq(CBackend& cmd_list)
{
- u_setrt(cmd_list, Device.dwWidth, Device.dwHeight, get_base_rt(), nullptr, nullptr, rt_Base_Depth->pZRT[cmd_list.context_id]);
+ // Occlusion queries only need scene depth. Binding the display-sized base
+ // color target beside the render-sized depth view is invalid in D3D11.
+ u_setrt(cmd_list, nullptr, nullptr, nullptr, nullptr, rt_Base_Depth->pZRT[cmd_list.context_id]);
+ RImplementation.rmNormal(cmd_list);
cmd_list.set_Shader(s_occq);
cmd_list.set_CullMode(CULL_CCW);
diff --git a/ogsr_engine/xrGame/ui/UIComboBox.cpp b/ogsr_engine/xrGame/ui/UIComboBox.cpp
index 8e42005ed1..77c2261d67 100644
--- a/ogsr_engine/xrGame/ui/UIComboBox.cpp
+++ b/ogsr_engine/xrGame/ui/UIComboBox.cpp
@@ -106,6 +106,14 @@ void CUIComboBox::OnListItemSelect()
if (bk_itoken_id != m_itoken_id)
{
+ CUIListBoxItem* selected = m_list.GetSelectedItem();
+ if (selected && !selected->IsEnabled())
+ {
+ m_itoken_id = bk_itoken_id;
+ SetItem(m_itoken_id);
+ ShowList(false);
+ return;
+ }
SaveValue();
GetMessageTarget()->SendMessage(this, LIST_ITEM_SELECT, NULL);
}
@@ -119,7 +127,9 @@ void CUIComboBox::SetCurrentValue()
while (tok->name)
{
- AddItem_(tok->name, tok->id);
+ CUIListBoxItem* itm = AddItem_(tok->name, tok->id);
+ if (itm && !IsOptTokenEnabled(tok->id))
+ itm->Enable(false);
tok++;
}
@@ -163,6 +173,9 @@ void CUIComboBox::OnBtnClicked() { ShowList(!m_list.IsShown()); }
void CUIComboBox::ShowList(bool bShow)
{
+ if (bShow && m_entry == "r_aa_dlss_preset")
+ SetCurrentValue();
+
if (bShow)
{
SetHeight(m_text.GetHeight() + m_list.GetHeight());
diff --git a/ogsr_engine/xrGame/ui/UIComboBox_script.cpp b/ogsr_engine/xrGame/ui/UIComboBox_script.cpp
index f0da52c0ab..af0fea66d1 100644
--- a/ogsr_engine/xrGame/ui/UIComboBox_script.cpp
+++ b/ogsr_engine/xrGame/ui/UIComboBox_script.cpp
@@ -23,6 +23,7 @@ void CUIComboBox::script_register(lua_State* L)
.def("SetListLength", &CUIComboBox::SetListLength)
.def("CurrentID", &CUIComboBox::CurrentID)
.def("SetCurrentID", &CUIComboBox::SetItem)
+ .def("SetCurrentValue", &CUIComboBox::SetCurrentValue)
// .def("AddItem", (void (CUIComboBox::*)(LPCSTR, bool)) CUIComboBox::AddItem)
.def("AddItem", (CUIListBoxItem * (CUIComboBox::*)(LPCSTR)) & CUIComboBox::AddItem_)
diff --git a/ogsr_engine/xrGame/ui/UIListBoxItem.cpp b/ogsr_engine/xrGame/ui/UIListBoxItem.cpp
index aae948d82d..739d3623f8 100644
--- a/ogsr_engine/xrGame/ui/UIListBoxItem.cpp
+++ b/ogsr_engine/xrGame/ui/UIListBoxItem.cpp
@@ -47,6 +47,9 @@ bool CUIListBoxItem::OnDbClick()
bool CUIListBoxItem::OnMouseDown(int mouse_btn)
{
+ if (!IsEnabled())
+ return true;
+
if (mouse_btn == MOUSE_1)
{
smart_cast(GetParent()->GetParent())->SetSelected(this);
diff --git a/ogsr_engine/xrGame/ui/UIOptionsItem.cpp b/ogsr_engine/xrGame/ui/UIOptionsItem.cpp
index a60e32a475..90df4f4b6a 100644
--- a/ogsr_engine/xrGame/ui/UIOptionsItem.cpp
+++ b/ogsr_engine/xrGame/ui/UIOptionsItem.cpp
@@ -2,6 +2,7 @@
#include "UIOptionsItem.h"
#include "UIOptionsManager.h"
#include "..\..\xr_3da\xr_ioconsole.h"
+#include "..\..\xr_3da\xr_ioc_cmd.h"
CUIOptionsManager CUIOptionsItem::m_optionsManager;
@@ -71,6 +72,12 @@ const xr_token* CUIOptionsItem::GetOptToken()
return token;
}
+bool CUIOptionsItem::IsOptTokenEnabled(int id)
+{
+ CCC_Token* cf = smart_cast(Console->GetCommand(m_entry.c_str()));
+ return !cf || cf->TokenEnabled(id);
+}
+
void CUIOptionsItem::SaveOptTokenValue(const char* val) { SaveOptStringValue(val); }
#pragma todo("KRodin: желательно убрать этот хардкод, как в ЗП, конечно, но пока меня устраивает. Перетаскивать полностью движковые классы опций оттуда я точно не буду.")
diff --git a/ogsr_engine/xrGame/ui/UIOptionsItem.h b/ogsr_engine/xrGame/ui/UIOptionsItem.h
index 9e645c2383..2dfa4fde74 100644
--- a/ogsr_engine/xrGame/ui/UIOptionsItem.h
+++ b/ogsr_engine/xrGame/ui/UIOptionsItem.h
@@ -49,6 +49,7 @@ class CUIOptionsItem
// token
LPCSTR GetOptTokenValue();
const xr_token* GetOptToken();
+ bool IsOptTokenEnabled(int id);
void SaveOptTokenValue(const char* val);
xr_string m_entry;
diff --git a/ogsr_engine/xr_3da/Render.h b/ogsr_engine/xr_3da/Render.h
index 42c5aff250..26775f1484 100644
--- a/ogsr_engine/xr_3da/Render.h
+++ b/ogsr_engine/xr_3da/Render.h
@@ -226,6 +226,7 @@ class ENGINE_API IRender_interface
virtual void Render() = 0;
virtual void AfterWorldRender() = 0; //После рендеринга мира (перед UI ПДА)
virtual void AfterUIRender() = 0; //После рендеринга UI. Вызывать только если нам нужно отрендерить кадр для пда.
+ virtual void SetupDisplayBackbuffer() = 0;
virtual void Screenshot(ScreenshotMode mode = SM_NORMAL, LPCSTR name = nullptr) = 0;
diff --git a/ogsr_engine/xr_3da/x_ray.cpp b/ogsr_engine/xr_3da/x_ray.cpp
index 197b988b82..ea3ac3b5bc 100644
--- a/ogsr_engine/xr_3da/x_ray.cpp
+++ b/ogsr_engine/xr_3da/x_ray.cpp
@@ -788,6 +788,9 @@ extern void render_reshade_effects();
void CApplication::load_draw_internal() const
{
+ if (::Render)
+ ::Render->SetupDisplayBackbuffer();
+
if (use_reshade)
render_reshade_effects();
diff --git a/ogsr_engine/xr_3da/xr_ioc_cmd.h b/ogsr_engine/xr_3da/xr_ioc_cmd.h
index de3c3589fc..64aa439e30 100644
--- a/ogsr_engine/xr_3da/xr_ioc_cmd.h
+++ b/ogsr_engine/xr_3da/xr_ioc_cmd.h
@@ -293,6 +293,7 @@ class ENGINE_API CCC_Token : public IConsole_Command
}
}
virtual const xr_token* GetToken() { return tokens; }
+ virtual bool TokenEnabled(int /*id*/) { return true; }
virtual void fill_tips(vecTips& tips, u32 mode)
{