addon.cpp things - clshortfuse/renodx GitHub Wiki
Swap chain proxy (= Final shader)
Example: addon.cpp / final pixel / final vertex
Required in addon.cpp:
renodx::mods::swapchain::use_resource_cloning = true;
//renodx::mods::swapchain::swapchain_proxy_compatibility_mode = true;
renodx::mods::swapchain::swap_chain_proxy_vertex_shader = __swap_chain_proxy_vertex_shader;
renodx::mods::swapchain::swap_chain_proxy_pixel_shader = __swap_chain_proxy_pixel_shader;
renodx::mods::swapchain::Use(fdw_reason, &shader_injection);
Note: compatibility_mode allows REST to access resources drawn on swapchain. Otherwise, cloning is preferred for efficiency (& possibly quality with 10bit swapchain).
swap_chain_proxy_vertex_shader.vs_X_X.hlsl content:
void main(uint id : SV_VERTEXID, out float4 pos : SV_POSITION,
out float2 uv : TEXCOORD0) {
uv.x = (id == 1) ? 2.0 : 0.0;
uv.y = (id == 2) ? 2.0 : 0.0;
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
}
swap_chain_proxy_pixel_shader.ps_X_X.hlsl content:
Texture2D t0 : register(t0);
SamplerState s0 : register(s0);
float4 main(float4 vpos : SV_POSITION, float2 uv : TEXCOORD0) : SV_TARGET {
float4 color = t0.Sample(s0, uv);
//color.rgb = ...;
color.a = 1.f;
return color;
}
Shader_hash based upgrade
Here is what's required to upgrade targets based on shader hashes. Everything happens in addon.cpp file.
The following functions can be placed in namespace. Ignore wrapping blocs, they're just indicators:
//----what usually preceeds in addon.cpp----//
#include "../../utils/settings.hpp"
#include "./shared.h"
namespace {
ShaderInjectData shader_injection;
//----what usually preceeds in addon.cpp----//
// DX11 Only
#define UpgradeRTVReplaceShader(value) \
{ \
value, \
{ \
.crc32 = value, \
.code = __##value, \
.on_draw = [](auto* cmd_list) { \
auto rtvs = renodx::utils::swapchain::GetRenderTargets(cmd_list); \
bool changed = false; \
for (auto rtv : rtvs) { \
changed = renodx::mods::swapchain::ActivateCloneHotSwap(cmd_list->get_device(), rtv); \
} \
if (changed) { \
renodx::mods::swapchain::FlushDescriptors(cmd_list); \
renodx::mods::swapchain::RewriteRenderTargets(cmd_list, rtvs.size(), rtvs.data(), {0}); \
} \
return true; }, \
}, \
}
#define UpgradeRTVShader(value) \
{ \
value, \
{ \
.crc32 = value, \
.on_draw = [](auto* cmd_list) { \
auto rtvs = renodx::utils::swapchain::GetRenderTargets(cmd_list); \
bool changed = false; \
for (auto rtv : rtvs) { \
changed = renodx::mods::swapchain::ActivateCloneHotSwap(cmd_list->get_device(), rtv); \
} \
if (changed) { \
renodx::mods::swapchain::FlushDescriptors(cmd_list); \
renodx::mods::swapchain::RewriteRenderTargets(cmd_list, rtvs.size(), rtvs.data(), {0}); \
} \
return true; }, \
}, \
}
renodx::mods::shader::CustomShaders custom_shaders = {
CustomShaderEntry(0xFFFFFFFF),
CustomShaderEntry(0xFFFFFFF),
UpgradeRTVReplaceShader(0xFFFFFFFF), // tonemapper > upgrade RTV & replace shader
UpgradeRTVShader(0xFFFFFFFF), // clamping resource 1 > upgrade RTV only
UpgradeRTVShader(0xFFFFFFFF), // clamping resource 2
};
//----what usually follows in addon.cpp----//
renodx::utils::settings::Settings settings = {
new renodx::utils::settings::Setting{
//----what usually follows in addon.cpp----//
Then you need resource cloning enabled and hotswap on corresponding resource upgrade. Again ignore wrapping blocs.
//----what usually preceeds in addon.cpp----//
BOOL APIENTRY DllMain(HMODULE h_module, DWORD fdw_reason, LPVOID lpv_reserved) {
switch (fdw_reason) {
case DLL_PROCESS_ATTACH:
if (!reshade::register_addon(h_module)) return FALSE;
//----what usually preceeds in addon.cpp----//
renodx::mods::swapchain::use_resource_cloning = true;
renodx::mods::swapchain::swap_chain_upgrade_targets.push_back({
.old_format = reshade::api::format::r8g8b8a8_unorm, // adjust to your needs
.new_format = reshade::api::format::r16g16b16a16_float,
//.ignore_size = true, // usual stuff can be used, but only both below are required
.use_resource_view_cloning = true,
.use_resource_view_hot_swap = true,
});
//----what usually follows in addon.cpp----//
break;
case DLL_PROCESS_DETACH:
reshade::unregister_addon(h_module);
break;
}
//----what usually follows in addon.cpp----//
Perceptual film grain
In addon.cpp:
// at the top
#include "../../utils/random.hpp"
// slider
renodx::templates::settings::CreateSetting({
.key = "FxGrainStrength",
.binding = &shader_injection.custom_grain_strength,
.default_value = 0.f,
.label = "Grain Strength",
.section = "Effects",
.parse = [](float value) { return value * 0.01f; },
}),
// in DllMain:
renodx::utils::random::binds.push_back(&shader_injection.custom_random);
renodx::utils::random::Use(fdw_reason);
In shared.h:
#define CUSTOM_GRAIN_STRENGTH shader_injection.custom_grain_strength
#define CUSTOM_RANDOM shader_injection.custom_random
// Must be 32bit aligned
// Should be 4x32
struct ShaderInjectData {
float custom_grain_strength;
float custom_random;
};
In shader.hlsl:
float3 grained_color = renodx::effects::ApplyFilmGrain(
linearColor.rgb,
TEXCOORD.xy,
CUSTOM_RANDOM,
CUSTOM_GRAIN_STRENGTH * 0.03f);