// SPDX-License-Identifier: MIT // Copyright (c) 2026 The Roofer Dev - Beast Roofer Edition. Clean-room integration code. // Built on Ryujinx (MIT). DLSS, DLAA and NIS are NVIDIA technologies; this is integration code only. using Ryujinx.Common.Logging; using System; namespace Ryujinx.Graphics.Gpu.Engine.Threed { /// /// ⛔⛔ MORT PAR LA MESURE, 29/07 AU SOIR -- NE PAS RE-ARMER, NE PAS RE-REGLER. Sonde `HDRTRY` : /// la passe de scene HDR existe dans **98,9 %** des images 3D, mais la camera n'y est **lisible /// que dans 36,5 %** des cas. N'autoriser QUE cette passe ferait donc tomber la publication de /// 83 % a ~37 % : la camera serait AFFAMEE, et une camera manquee fait ecrire zero sur toute /// l'image. Ce n'est pas un probleme de reglage du filet -- le filet mal dimensionne (voir plus /// bas) n'etait que le symptome. Le remplacant est , qui ECARTE la pire /// passe au lieu d'en ELIRE une. Ce fichier est conserve pour la trace, et parce que /// sert encore a la sonde. /// /// [SCENEPASS 29/07 SOIR] Capturer la camera sur LA PASSE DE LA SCENE, et non sur la premiere /// passe 3D venue (RYUJINX_MVPP_SCENEPASS=1, coupe par defaut). /// /// POURQUOI, ET SUR QUELLE MESURE. capture au PREMIER /// dessin de l'image qui passe le pre-filtre, puis se tait. Ce pre-filtre reconnait "une passe /// 3D", pas "LA passe de la scene". Recensement CTXPROBE du 29/07 au soir, run etalon de 3 min, /// 3 633 lectures et 177 intruses -- du GROS volume, pas trois evenements tires au sort : /// /// cible couleur branchee a la lecture lectures intruses taux /// R8G8B8A8Unorm (8 bits, LDR) 1 340 119 8,9 % <- 67 % des intruses /// aucune (passe profondeur seule) 2 044 52 2,5 % /// R11G11B10Float (couleur HDR de scene) 230 3 1,3 % <- la vraie passe /// R32Float 19 3 15,8 % /// /// La passe 8 bits donne SEPT FOIS plus d'intruses que la couleur HDR et fournit deux tiers du /// total. Le discriminant que le dossier croyait inexistant n'est pas dans la MATRICE (fermé le /// 27/07 : vue-projection structurellement parfaite, rien ne l'identifie) -- il est dans la /// PASSE. Et il y a de quoi choisir : 125 passes qualifiantes par image en moyenne, dont ~87 /// sur la couleur HDR. /// /// LE CRITERE EST GENERIQUE -- forme de pipeline, rien d'autre : cible couleur attachee, NON /// CARREE (une cible carree est un atlas d'ombres), format flottant HDR. C'est mot pour mot /// celui que utilise deja pour epingler la couleur de scene. /// Aucune adresse, aucun hash, aucune resolution, aucun nom de jeu. /// /// ⛔ CE QUE CE FICHIER NE PROMET PAS. Attendu : 4,9 % d'intruses -> 1,3 %, soit environ 73 % /// de moins. PAS zero : la passe de scene elle-meme en porte 3 sur 230. C'est une attenuation, /// obtenue a la source au lieu d'un filtre pose apres coup -- ce n'est pas une execution. /// /// ⚠️ LE RISQUE EST LA PUBLICATION, PAS L'INTRUSE, et c'est la borne INFERIEURE qui protege /// (lecon du 29/07 : pour un composant dont le role est de refuser, prouver "il ne refuse /// jamais plus" est la moitie inutile de la question). Une camera manquee fait ecrire ZERO sur /// toute l'image. Donc la restriction s'auto-desarme, en deux etages : /// 1. RATTRAPAGE -- deux images d'affilee avec des passes qualifiantes mais AUCUNE capture, /// et la restriction se leve pour 300 images (comportement d'avant, a l'identique). Perte /// bornee : 2 images sur 300, soit 0,7 %. /// 2. DESARMEMENT -- cinq rattrapages, et la restriction se coupe pour la session, avec une /// ligne de journal explicite. Si la passe HDR n'est pas fiable sur ce jeu, on le DIT au /// lieu de saigner 2 images sur 3. /// Le taux de publication se lit dans l'instrument qui existe deja ("MVPP capture window: /// enq/pub") : mesure de reference du 29/07 au soir = 6 761 / 8 127 = 83,2 %. En dessous, le /// correctif est mauvais quel que soit son gain sur les intruses. /// /// Les compteurs sont approximatifs : OnDraw tourne sur le fil GPU, OnFrame sur celui de la /// presentation. On ne batit aucune conclusion fine dessus -- seulement des ordres de grandeur. /// static class MvppScenePass { public static readonly bool Enabled = Environment.GetEnvironmentVariable("RYUJINX_MVPP_SCENEPASS") == "1"; private const int MissesBeforeCatchUp = 2; private const int CatchUpFrames = 300; private const int CatchUpsBeforeDisarm = 5; private const int ReportMs = 5000; private static bool _disarmed; private static int _missStreak; private static int _catchUpLeft; private static int _catchUps; private static bool _qualThisFrame; private static int _frames; private static int _captured; private static int _skips; private static int _catchUpFramesSeen; private static long _lastReportMs; /// /// Appelee sur un dessin qualifiant tant que l'image n'a pas encore sa camera. Rend false /// pour SAUTER la tentative de capture sur ce dessin -- ce qui laisse la capture se faire /// plus loin dans la MEME image, sur la passe de la scene. /// public static bool Allows(GpuChannel channel) { _qualThisFrame = true; if (_disarmed || _catchUpLeft > 0) { return true; } if (IsSceneColorPass(channel)) { return true; } _skips++; return false; } /// /// Reconnait la passe de la scene a la FORME de sa cible couleur : attachee, non carree, /// format flottant HDR. Meme critere que . Une cible 8 bits /// (interface, composition, passe auxiliaire) et une passe sans couleur du tout echouent /// ici -- ce sont exactement les deux contextes qui portaient 96 % des intruses. /// internal static bool IsSceneColorPass(GpuChannel channel) { Image.Texture col0 = channel.TextureManager.RenderTargetColor0; if (col0 == null || col0.Info.Width == col0.Info.Height) { return false; } GAL.Format f = col0.Info.FormatInfo.Format; return f == GAL.Format.R11G11B10Float || f == GAL.Format.R16G16B16A16Float; } /// /// Une fois par image presentee, AVANT que le drapeau de capture ne soit re-arme. C'est ici /// que vit le filet de securite : une image qui avait des passes qualifiantes et n'a rien /// capture est une image potentiellement perdue, et on ne l'accepte pas deux fois de suite. /// public static void OnFrame(bool captured) { if (!_qualThisFrame) { // Image sans passe 3D (menu, chargement) : elle n'a jamais eu de camera a prendre, // la compter comme un manque ferait declencher le rattrapage pour rien. return; } _qualThisFrame = false; _frames++; if (_catchUpLeft > 0) { _catchUpLeft--; _catchUpFramesSeen++; } if (captured) { _captured++; _missStreak = 0; } else if (!_disarmed && _catchUpLeft == 0) { _missStreak++; if (_missStreak >= MissesBeforeCatchUp) { _missStreak = 0; _catchUps++; _catchUpLeft = CatchUpFrames; if (_catchUps >= CatchUpsBeforeDisarm) { _disarmed = true; Logger.Warning?.Print(LogClass.Gpu, $"MVPP SCENEPASS DESARME : {_catchUps} rattrapages, la passe de scene HDR " + "n'est pas assez fiable sur ce jeu pour porter la capture. Retour au " + "comportement d'avant pour le reste de la session."); } else { Logger.Info?.Print(LogClass.Gpu, $"MVPP SCENEPASS rattrapage #{_catchUps} : {MissesBeforeCatchUp} images " + $"d'affilee sans capture, restriction levee pour {CatchUpFrames} images."); } } } long now = Environment.TickCount64; if (now - _lastReportMs >= ReportMs) { _lastReportMs = now; Logger.Info?.Print(LogClass.Gpu, $"MVPP SCENEPASS : {_frames} images 3D, {_captured} avec camera " + $"({(_frames > 0 ? 100f * _captured / _frames : 0f):0.#} %), " + $"{_skips} dessins sautes, {_catchUps} rattrapages " + $"({_catchUpFramesSeen} images en rattrapage)" + $"{(_disarmed ? " · DESARME" : "")}"); } } } }