Skip to content

feat(fromsoft, resource): Rework tonemap and create AreCopyFormatsCompatible in resource.hpp#548

Merged
clshortfuse merged 12 commits into
clshortfuse:mainfrom
MohannedElfatih:fromsoftrewrite-ritsu
May 17, 2026
Merged

feat(fromsoft, resource): Rework tonemap and create AreCopyFormatsCompatible in resource.hpp#548
clshortfuse merged 12 commits into
clshortfuse:mainfrom
MohannedElfatih:fromsoftrewrite-ritsu

Conversation

@MohannedElfatih

Copy link
Copy Markdown
Contributor

Centralized AreCopyFormatsCompatible and added r32_g8_* families as compatible

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR centralizes copy/resolve format-compatibility logic into utils::resource::AreCopyFormatsCompatible and expands FromSoftware engine shader support with a reworked tonemapping pipeline (including new PsychoV tonemap components, UI visibility control, and LUT scaling/gamut-restoration options).

Changes:

  • Replaced repeated format-compatibility checks in resource upgrade hooks with a centralized AreCopyFormatsCompatible helper (and extended depth format family compatibility rules).
  • Reworked FromSoft tonemapper/final-pass shaders to route through shared helpers (ApplyFromSoftToneMapExtended, ApplyLUTAndToneMapAndRenderIntermediatePass, HandleFinal) and added SDR final shaders for some titles.
  • Expanded shader injection/settings surface (UI visibility, per-channel vs luminance scaling, hue emulation method, LUT strength/scaling/gamut restoration) and added vendor-specific backbuffer upgrade selection on device init.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/utils/resource_upgrade.hpp Switches copy/resolve compatibility logic to use centralized AreCopyFormatsCompatible.
src/utils/resource.hpp Adds IsDepthStencilCopyCompatible and AreCopyFormatsCompatible helpers.
src/games/fromsoft_engine/shared.h Extends injected constant buffer layout and adds new shader macros (UI visibility, scaling, hue emulation, LUT params).
src/games/fromsoft_engine/sekiro/tonemaptable_builder_0xC0C87BF5.ps_5_0.hlsl Adds a new tonemap table builder shader.
src/games/fromsoft_engine/sekiro/tonemapper_0x775D9A9E.ps_5_0.hlsl Reworks tonemapping path selection and integrates shared tonemap/LUT/intermediate-pass helper.
src/games/fromsoft_engine/sekiro/final_0xDB1689BD.ps_5_0.hlsl Moves HandleFinal earlier in the final combine stage.
src/games/fromsoft_engine/psycho_test17_custom.hlsli Introduces PsychoV test17 tonemap implementation and related helpers.
src/games/fromsoft_engine/nightreign/tonemapper_0x0F2159FD.ps_6_0.hlsl Refactors tonemap + LUT + HDR/SDR handling to use shared helpers.
src/games/fromsoft_engine/nightreign/final_sdr_0x7719EB4E.ps_6_0.hlsl Adds a dedicated SDR final pass using HandleFinal(..., force=true).
src/games/fromsoft_engine/nightreign/final_0x8C99CA89.ps_6_0.hlsl Moves HandleFinal to the top of the HDR final pass.
src/games/fromsoft_engine/macleod_boynton.hlsli Adds MacLeod–Boynton gamut/purity utilities and correction helpers used by tonemap code.
src/games/fromsoft_engine/eldenring/tonemapper_0xC6109CC1.ps_6_0.hlsl Refactors tonemap + LUT + HDR/SDR handling to use shared helpers.
src/games/fromsoft_engine/eldenring/final_sdr_0x82C25BCF.ps_6_0.hlsl Adds a dedicated SDR final pass using HandleFinal(..., force=true).
src/games/fromsoft_engine/eldenring/final_0x66C073FB.ps_6_0.hlsl Moves HandleFinal to the top of the HDR final pass.
src/games/fromsoft_engine/common.hlsl Major tonemap pipeline rework: extended Reinhard, LUT scaling/restoration, PsychoV mapping, UI blend, new HandleFinal signature.
src/games/fromsoft_engine/armoredcore6/tonemapper_0x74971D15.ps_6_0.hlsl Refactors tonemap + LUT + HDR handling to use shared helpers.
src/games/fromsoft_engine/armoredcore6/final_0x6557F4B9.ps_6_0.hlsl Moves HandleFinal to the top of the final pass.
src/games/fromsoft_engine/armoredcore6/final_0x21706BCF.ps_6_0.hlsl Moves HandleFinal to the top of the final pass (scaled UV sampling variant).
src/games/fromsoft_engine/addon.cpp Updates settings/options, adds device-init vendor selection for backbuffer format upgrade, and wires resource/swapchain/random usage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils/resource.hpp
Comment on lines +1133 to +1142
// Depth-only copies make r32_* and r32_g8_* families copy-compatible
switch (source_typeless) {
case reshade::api::format::r32_typeless:
return destination_typeless == reshade::api::format::r32_g8_typeless;
case reshade::api::format::r32_g8_typeless:
return destination_typeless == reshade::api::format::r32_typeless;
case reshade::api::format::d24_unorm_x8_uint:
return destination_typeless == reshade::api::format::r24_g8_typeless;
case reshade::api::format::r24_g8_typeless:
return destination_typeless == reshade::api::format::d24_unorm_x8_uint;

Copilot AI Apr 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IsDepthStencilCopyCompatible currently treats r32_typeless <-> r32_g8_typeless (and d24_unorm_x8_uint <-> r24_g8_typeless) as copy-compatible purely based on typeless families. Since FormatToTypeless(d32_float_s8_uint) maps to r32_g8_typeless and FormatToTypeless(d24_unorm_s8_uint) maps to r24_g8_typeless, this will also mark copies between depth-only formats and depth+stencil formats as compatible, even though the copy path here does not guarantee a depth-only plane copy. That can lead to invalid CopyResource/CopyTextureRegion calls (and potential GPU errors). Consider restricting these special-cases to the depth-only view formats (e.g., r32_float_x8_uint/x32_float_g8_uint and excluding *_s8_uint), or moving the special-case logic to the call site where the plane/aspect being copied is known.

Copilot uses AI. Check for mistakes.
Comment thread src/games/fromsoft_engine/addon.cpp

} // namespace psycho
} // namespace tonemap
} // namespace renodx

Copilot AI Apr 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The closing namespace comment says // namespace renodx, but this file opens namespace renodx_custom { ... }. Update the comment to match the actual namespace to avoid confusion when navigating the shader code.

Suggested change
} // namespace renodx
} // namespace renodx_custom

Copilot uses AI. Check for mistakes.

} // namespace macleod_boynton
} // namespace color
} // namespace renodx

Copilot AI Apr 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The closing namespace comment says // namespace renodx, but the file opens namespace renodx_custom { ... }. Adjust the comment to reflect renodx_custom to keep namespace annotations accurate.

Suggested change
} // namespace renodx
} // namespace renodx_custom

Copilot uses AI. Check for mistakes.
@clshortfuse

Copy link
Copy Markdown
Owner

@MohannedElfatih needs conflict resolution

mqhaji and others added 10 commits May 12, 2026 22:10
- use extended tonemap
- use macleod boynton for grading and hue/purity correction
- add luminosity/macleod-boynton grading
- use neutwo maxch
- use neutwo in ui blend
- add lut scaling, lut strength, tonemap scaling sliders
- add gamut compression and decompression for lut
- add fp11 upgrades for nvidia and amd
- fix film grain
@MohannedElfatih MohannedElfatih force-pushed the fromsoftrewrite-ritsu branch from 9e6108f to 59262cb Compare May 12, 2026 18:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 8 comments.

Comment thread src/games/fromsoft_engine/addon.cpp Outdated
renodx::utils::settings::Use(fdw_reason, &settings, &OnPresetOff);
// renodx::mods::swapchain::Use(fdw_reason, &shader_injection);

if (fdw_reason == DLL_PROCESS_ATTACH) { // ALways reset UI visibility to on
Comment on lines 136 to 138
float4 _192 = g_ToneMapTableTexture.SampleLevel(SS_ClampLinear, float2((((_177 / (_177 + 0.20000000298023224f)) * 0.9990234375f) + 0.00048828125f), 0.0f), 0.0f);
float4 _194 = g_ToneMapTableTexture.SampleLevel(SS_ClampLinear, float2((((_178 / (_178 + 0.20000000298023224f)) * 0.9990234375f) + 0.00048828125f), 0.0f), 0.0f);
float4 _196 = g_ToneMapTableTexture.SampleLevel(SS_ClampLinear, float2((((_179 / (_179 + 0.20000000298023224f)) * 0.9990234375f) + 0.00048828125f), 0.0f), 0.0f);
Comment on lines +30 to +35
if (HandleFinal(float4(HDRScene.Sample(SS_ClampLinear, TEXCOORD_1.xy).xyz, 1.f), UIScene.Sample(SS_ClampLinear, TEXCOORD_1.xy).xyzw, SV_Target, SV_Position)) {
return SV_Target;
}

float4 _10 = HDRScene.Sample(SS_ClampLinear, float2(TEXCOORD_1.x, TEXCOORD_1.y)); // Directly from tonemapper
float4 _14 = UIScene.Sample(SS_ClampLinear, float2(TEXCOORD_1.x, TEXCOORD_1.y));
Comment on lines +35 to +40
if (HandleFinal(float4(HDRScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyz, 1.f), UIScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyzw, SV_Target, SV_Position)) {
return SV_Target;
}

float4 _16 = HDRScene.Sample(LinearClampSampler, float2((g_HDRTexturePercentage.x * TEXCOORD_1.x), (g_HDRTexturePercentage.y * TEXCOORD_1.y)));
float4 _25 = UIScene.Sample(LinearClampSampler, float2((g_UITexturePercentage.x * TEXCOORD_1.x), (g_UITexturePercentage.y * TEXCOORD_1.y)));
Comment on lines +30 to +35
if (HandleFinal(float4(HDRScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyz, 1.f), UIScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyzw, SV_Target, SV_Position)) {
return SV_Target;
}

float4 _10 = HDRScene.Sample(LinearClampSampler, float2(TEXCOORD_1.x, TEXCOORD_1.y));
float4 _14 = UIScene.Sample(LinearClampSampler, float2(TEXCOORD_1.x, TEXCOORD_1.y));
Comment on lines +29 to +35
if (HandleFinal(float4(HDRScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyz, 1.f), UIScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyzw, SV_Target, SV_Position)) {
return SV_Target;
}

float4 _10 = HDRScene.Sample(LinearClampSampler, float2(TEXCOORD_1.x, TEXCOORD_1.y));
float4 _14 = UIScene.Sample(LinearClampSampler, float2(TEXCOORD_1.x, TEXCOORD_1.y));

Comment on lines 35 to 41

if (HandleFinal(float4(HDRScene.Sample(PointSampler_s, v2.xy).xyz, 1.f), UIScene.Sample(PointSampler_s, v2.xy).xyzw, o0, v0)) {
return;
}

r0.x = 0.100000024 * uiMaxLumScale;
r0.yzw = HDRScene.Sample(PointSampler_s, v2.xy).xyz;

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 10 comments.

Comment thread src/utils/resource.hpp
Comment on lines +1580 to +1585
// Depth-only copies make r32_* and r32_g8_* families copy-compatible
switch (source_typeless) {
case reshade::api::format::r32_typeless:
return destination_typeless == reshade::api::format::r32_g8_typeless;
case reshade::api::format::r32_g8_typeless:
return destination_typeless == reshade::api::format::r32_typeless;
Comment on lines +295 to +303
if (CUSTOM_LUT_STRENGTH > 0.f) {
renodx::lut::Config lut_config = renodx::lut::config::Create();
lut_config.lut_sampler = lut_sampler;
lut_config.tetrahedral = true;
lut_config.type_input = renodx::lut::config::type::GAMMA_2_2;
lut_config.type_output = renodx::lut::config::type::GAMMA_2_2;
lut_config.scaling = CUSTOM_LUT_SCALING;
lut_config.strength = CUSTOM_LUT_STRENGTH;
lut_config.gamut_compress = 2.f;
renodx::utils::settings::Use(fdw_reason, &settings, &OnPresetOff);
// renodx::mods::swapchain::Use(fdw_reason, &shader_injection);

if (fdw_reason == DLL_PROCESS_ATTACH) { // ALways reset UI visibility to on
Comment on lines 35 to 42

if (HandleFinal(float4(HDRScene.Sample(PointSampler_s, v2.xy).xyz, 1.f), UIScene.Sample(PointSampler_s, v2.xy).xyzw, o0, v0)) {
return;
}

r0.x = 0.100000024 * uiMaxLumScale;
r0.yzw = HDRScene.Sample(PointSampler_s, v2.xy).xyz;
float4 scene = float4(r0.yzw, 1.f);
Comment on lines +30 to +35
if (HandleFinal(float4(HDRScene.Sample(SS_ClampLinear, TEXCOORD_1.xy).xyz, 1.f), UIScene.Sample(SS_ClampLinear, TEXCOORD_1.xy).xyzw, SV_Target, SV_Position)) {
return SV_Target;
}

float4 _10 = HDRScene.Sample(SS_ClampLinear, float2(TEXCOORD_1.x, TEXCOORD_1.y)); // Directly from tonemapper
float4 _14 = UIScene.Sample(SS_ClampLinear, float2(TEXCOORD_1.x, TEXCOORD_1.y));
Comment on lines +30 to +35
if (HandleFinal(float4(HDRScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyz, 1.f), UIScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyzw, SV_Target, SV_Position)) {
return SV_Target;
}

float4 _10 = HDRScene.Sample(LinearClampSampler, float2(TEXCOORD_1.x, TEXCOORD_1.y));
float4 _14 = UIScene.Sample(LinearClampSampler, float2(TEXCOORD_1.x, TEXCOORD_1.y));
Comment on lines +29 to +34
if (HandleFinal(float4(HDRScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyz, 1.f), UIScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyzw, SV_Target, SV_Position)) {
return SV_Target;
}

float4 _10 = HDRScene.Sample(LinearClampSampler, float2(TEXCOORD_1.x, TEXCOORD_1.y));
float4 _14 = UIScene.Sample(LinearClampSampler, float2(TEXCOORD_1.x, TEXCOORD_1.y));
Comment on lines +35 to +41
if (HandleFinal(float4(HDRScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyz, 1.f), UIScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyzw, SV_Target, SV_Position)) {
return SV_Target;
}

float4 _16 = HDRScene.Sample(LinearClampSampler, float2((g_HDRTexturePercentage.x * TEXCOORD_1.x), (g_HDRTexturePercentage.y * TEXCOORD_1.y)));
float4 _25 = UIScene.Sample(LinearClampSampler, float2((g_UITexturePercentage.x * TEXCOORD_1.x), (g_UITexturePercentage.y * TEXCOORD_1.y)));

Comment on lines +28 to +33
if (HandleFinal(float4(HDRScene.Sample(SS_ClampLinear, TEXCOORD_1.xy).xyz, 1.f), UIScene.Sample(SS_ClampLinear, TEXCOORD_1.xy).xyzw, SV_Target, SV_Position, true)) {
return SV_Target;
}

float4 _7 = HDRScene.Sample(SS_ClampLinear, float2(TEXCOORD_1.x, TEXCOORD_1.y));
float4 _11 = UIScene.Sample(SS_ClampLinear, float2(TEXCOORD_1.x, TEXCOORD_1.y));
Comment on lines +28 to +33
if (HandleFinal(float4(HDRScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyz, 1.f), UIScene.Sample(LinearClampSampler, TEXCOORD_1.xy).xyzw, SV_Target, SV_Position, true)) {
return SV_Target;
}

float4 _7 = HDRScene.Sample(LinearClampSampler, float2(TEXCOORD_1.x, TEXCOORD_1.y));
float4 _11 = UIScene.Sample(LinearClampSampler, float2(TEXCOORD_1.x, TEXCOORD_1.y));
@MohannedElfatih

Copy link
Copy Markdown
Contributor Author

Ready btw.

@clshortfuse clshortfuse merged commit 442a44c into clshortfuse:main May 17, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants