Fix OptiScaler NGX routing and align marker polling defaults
- Explicitly route OptiScaler to d4r\nvngx.dll in release packages. - Extract INI generation into a helper that preserves line endings and rejects missing or duplicate settings. - Check NGX routing separately from file presence and return failure when the installation is incomplete or misconfigured. - Add an optional OptiScaler patch for external DLSS backends while preserving AMD identity for FSR4, with matching launch guidance. - Align portable and launcher marker polling defaults at 200 us. - Log when d4r's model override replaces game or OptiScaler presets. - Add configuration, package, routing and coexistence regression tests. - Update installation documentation, add FSR/DLSS comparison videos and ignore local .tools artifacts. Refs: #7, #14
This commit is contained in:
1 parent
f66cccaf28
commit
cb08e1c313
17 files changed
+738
-31
No files matched your search
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Apply release settings to the supplied OptiScaler INI, preserving its defaults/CRLF."""
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def configure(source, settings):
|
||||
lines = source.split("\n")
|
||||
for setting in settings.splitlines():
|
||||
setting = setting.strip()
|
||||
if not setting or setting.startswith("#"):
|
||||
continue
|
||||
path, value = setting.split("=", 1)
|
||||
section, key = path.split(".", 1)
|
||||
starts = [i for i, line in enumerate(lines) if line.strip().casefold() == f"[{section}]".casefold()]
|
||||
if len(starts) != 1:
|
||||
raise ValueError(f"OptiScaler.ini must have exactly one [{section}]")
|
||||
start = starts[0]
|
||||
end = next((i for i in range(start + 1, len(lines)) if lines[i].lstrip().startswith("[")), len(lines))
|
||||
matches = [i for i in range(start + 1, end)
|
||||
if re.match(rf"\s*{re.escape(key)}\s*=", lines[i], re.IGNORECASE)]
|
||||
if len(matches) != 1:
|
||||
raise ValueError(f"OptiScaler.ini must have exactly one {key} in [{section}]")
|
||||
i = matches[0]
|
||||
lines[i] = f"{key}={value}" + ("\r" if lines[i].endswith("\r") else "")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def main():
|
||||
source, settings, output = map(Path, sys.argv[1:])
|
||||
try:
|
||||
# read_text() would translate CRLF before we could preserve it.
|
||||
with source.open(encoding="utf-8", newline="") as handle:
|
||||
result = configure(handle.read(), settings.read_text(encoding="utf-8"))
|
||||
except ValueError as error:
|
||||
sys.exit(str(error))
|
||||
with output.open("w", encoding="utf-8", newline="") as handle:
|
||||
handle.write(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -146,7 +146,7 @@ def main(argv):
|
||||
value = flag("Interop", key)
|
||||
if value is not None:
|
||||
env[var] = "1" if value else "0"
|
||||
value = get("Interop", "MarkerPollUs")
|
||||
value = get("Interop", "MarkerPollUs") or "200"
|
||||
dilation = get("Interop", "MotionVectorDilation")
|
||||
if dilation is not None and dilation not in ("0", "1", "2"):
|
||||
fail("[Interop] MotionVectorDilation must be 0, 1 or 2")
|
||||
|
||||
@@ -77,27 +77,8 @@ else
|
||||
esac
|
||||
fi
|
||||
cp "$OPTI/OptiScaler.dll" "$STAGE/dxgi.dll"
|
||||
python3 - "$OPTI/OptiScaler.ini" "$ROOT/packaging/optiscaler.settings" "$STAGE/OptiScaler.ini" <<'PY'
|
||||
import re, sys
|
||||
lines = open(sys.argv[1], encoding="utf-8", newline="").read().split("\n") # keeps the file's line endings
|
||||
for setting in open(sys.argv[2], encoding="utf-8"):
|
||||
setting = setting.strip()
|
||||
if not setting or setting.startswith("#"):
|
||||
continue
|
||||
path, value = setting.split("=", 1)
|
||||
section, key = path.split(".", 1)
|
||||
start = next((i for i, l in enumerate(lines) if l.strip() == f"[{section}]"), None)
|
||||
if start is None:
|
||||
sys.exit(f"OptiScaler.ini has no [{section}]")
|
||||
end = next((i for i in range(start + 1, len(lines)) if lines[i].startswith("[")), len(lines))
|
||||
for i in range(start + 1, end):
|
||||
if re.match(rf"{re.escape(key)}\s*=", lines[i]):
|
||||
lines[i] = f"{key}={value}" + ("\r" if lines[i].endswith("\r") else "")
|
||||
break
|
||||
else:
|
||||
sys.exit(f"OptiScaler.ini has no {key} in [{section}]")
|
||||
open(sys.argv[3], "w", encoding="utf-8", newline="").write("\n".join(lines))
|
||||
PY
|
||||
python3 "$ROOT/scripts/configure_optiscaler.py" \
|
||||
"$OPTI/OptiScaler.ini" "$ROOT/packaging/optiscaler.settings" "$STAGE/OptiScaler.ini"
|
||||
|
||||
# d4r-patched vkd3d-proton: same-frame DLSS results
|
||||
cp "$VKD3D/d3d12.dll" "$VKD3D/d3d12core.dll" "$STAGE/"
|
||||
|
||||
Reference in new issue
Block a user