6634d3ef87
Removes a bug introduced in v1.2.3: the DLSS clip-space jitter block was emitted into every vertex shader and read the Position output before writing it. Reading an unwritten output is undefined, so vertex positions could come out as garbage - whole 3D passes landing nowhere (the green screen reported on GYLT, Ghostbusters, Blair Witch and others) and the black block artifacts in Xenoblade Chronicles 2's motion-blur pass, which had been mistaken for a long-standing emulation defect and worked around by disabling the effect. With jitter off - how this fork ships - the vertex epilogue is now identical to the base emulator again, and the motion blur no longer needs to be disabled. CodeGenVersion bumped so existing shader caches are rebuilt. Also adds a DLSS sharpening slider (0-100, off by default) and an experimental advanced motion stack checkbox (off by default).
47 lines
2.0 KiB
C#
47 lines
2.0 KiB
C#
// SPDX-License-Identifier: MIT
|
|
// Copyright (c) 2026 The Roofer Dev - Beast Roofer Edition. Clean-room integration code.
|
|
// Built on Ryujinx (MIT).
|
|
|
|
using System;
|
|
using System.Globalization;
|
|
|
|
namespace Ryujinx.Graphics.Shader.Translation
|
|
{
|
|
/// <summary>
|
|
/// [HASH_TEST] Temporary VALIDATION experiment (RYUJINX_HASH_CONST=<float>), inert unless set.
|
|
/// It answers one question and is meant to be deleted afterwards: is the per-pixel dither hash
|
|
/// of the XC2 DoF bokeh shader required for the border-streak artifact?
|
|
///
|
|
/// That shader (guest FS 0x1000AE430) computes hash = fract(sin(...) * 43758.5469). While this
|
|
/// flag is set, the translator replaces ONLY that one multiply's result with the constant, so
|
|
/// hash = fract(const) and every other part of the shader (CoC, gathers, weights, accumulation,
|
|
/// normalization, sprite generation) is untouched. See InstEmit.Fmul32i for the injection site.
|
|
///
|
|
/// This is a codegen probe: it alters generated host code, so it MUST be listed in
|
|
/// DiskCacheHostStorage's probe interlock, otherwise the instrumented shader would be persisted
|
|
/// and served to a later probe-less launch. It is also address-gated, and the disk-cache
|
|
/// recompile path passes address 0 (ParallelDiskCacheLoader), so the experiment only actually
|
|
/// runs with the shader cache disabled -- the [HASH_TEST] log line is the proof it did.
|
|
/// </summary>
|
|
public static class HashTestProbe
|
|
{
|
|
public static readonly float? ConstValue = Parse();
|
|
|
|
public static bool Enabled => ConstValue.HasValue;
|
|
|
|
private static float? Parse()
|
|
{
|
|
string raw = Environment.GetEnvironmentVariable("RYUJINX_HASH_CONST");
|
|
|
|
// Invariant culture on purpose: "0.5" parses, "0,5" does not and leaves the probe off.
|
|
if (raw != null &&
|
|
float.TryParse(raw, NumberStyles.Float, CultureInfo.InvariantCulture, out float value))
|
|
{
|
|
return value;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|