diff --git a/README.md b/README.md index 46ccc3d..8ba0918 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Dx12Upscaler=fsr31 ~/fgmod/fgmod %command% ## Technical Details ### What's Included -- **[OptiScaler 0.9.3](https://github.com/optiscaler/OptiScaler/releases/tag/v0.9.3)**: Official upstream OptiScaler bundle used by this plugin, with bundled FSR4 runtime variants for the archive-native RDNA4 path, the Steam Deck / RDNA2-3 optimized INT8 override, or the official 4.1.1 RDNA 3/4 override +- **[OptiScaler 0.9.3](https://github.com/optiscaler/OptiScaler/releases/tag/v0.9.3)**: Official upstream OptiScaler bundle used by this plugin, with bundled FSR4 runtime variants for the archive-native RDNA4 path, the Steam Deck / RDNA2-3 optimized INT8 override, the official 4.1.1 RDNA 3/4 override, or the experimental Valve 4.1.1 RDNA2 compatibility path with a pre10 OptiScaler injector - **Nukem9's DLSSG to FSR3 mod**: Allows use of DLSS inputs for FSR frame gen outputs, and xess or FSR upscaling outputs - **FakeNVAPI**: NVIDIA API emulation for AMD/Intel GPUs, to make DLSS options selectable in game - **Supporting Libraries**: All required DX12/Vulkan libraries (libxess.dll, amd_fidelityfx, etc.) diff --git a/defaults/assets/fgmod.sh b/defaults/assets/fgmod.sh index ba6d8ed..e0ee1d2 100755 --- a/defaults/assets/fgmod.sh +++ b/defaults/assets/fgmod.sh @@ -112,6 +112,7 @@ cleanup_files=( "${proxy_backup_files[@]}" "OptiScaler.dll" "amdxcffx64.dll" + "amdxc64.dll" "nvngx.dll" "_nvngx.dll" "nvngx-wrapper.dll" @@ -171,6 +172,7 @@ PY selected_fsr4_variant="$(resolve_fsr4_variant)" variant_dir="" variant_extra_files=() +variant_ini_overrides=() case "$selected_fsr4_variant" in rdna4-native) variant_dir="$fgmod_path/fsr4-rdna4" @@ -181,6 +183,13 @@ case "$selected_fsr4_variant" in fsr4_upscaler_src="$variant_dir/amd_fidelityfx_upscaler_dx12.dll" variant_extra_files+=("amdxcffx64.dll") ;; + rdna2-valve-411-pre10) + variant_dir="$fgmod_path/fsr4-rdna2-valve-411-pre10" + fsr4_upscaler_src="$variant_dir/amd_fidelityfx_upscaler_dx12.dll" + variant_extra_files+=("amdxcffx64.dll" "amdxc64.dll") + variant_ini_overrides+=("FSR.Fsr4ForceModel=2") + variant_ini_overrides+=("Plugins.LoadCustomAmdxc64OnRdna2=true") + ;; *) selected_fsr4_variant="rdna23-int8" variant_dir="$fgmod_path/fsr4-rdna2-3" @@ -200,7 +209,8 @@ is_managed_support_file() { "$fgmod_path/amd_fidelityfx_upscaler_dx12.dll" \ "$fgmod_path/fsr4-rdna2-3/amd_fidelityfx_upscaler_dx12.dll" \ "$fgmod_path/fsr4-rdna4/amd_fidelityfx_upscaler_dx12.dll" \ - "$fgmod_path/fsr4-rdna3-4-official-411/amd_fidelityfx_upscaler_dx12.dll"; do + "$fgmod_path/fsr4-rdna3-4-official-411/amd_fidelityfx_upscaler_dx12.dll" \ + "$fgmod_path/fsr4-rdna2-valve-411-pre10/amd_fidelityfx_upscaler_dx12.dll"; do [[ -f "$candidate" && -f "$existing_file" ]] && cmp -s "$existing_file" "$candidate" && return 0 done return 1 @@ -208,7 +218,15 @@ is_managed_support_file() { if [[ "$filename" == "amdxcffx64.dll" ]]; then for candidate in \ "$fgmod_path/amdxcffx64.dll" \ - "$fgmod_path/fsr4-rdna3-4-official-411/amdxcffx64.dll"; do + "$fgmod_path/fsr4-rdna3-4-official-411/amdxcffx64.dll" \ + "$fgmod_path/fsr4-rdna2-valve-411-pre10/amdxcffx64.dll"; do + [[ -f "$candidate" && -f "$existing_file" ]] && cmp -s "$existing_file" "$candidate" && return 0 + done + return 1 + fi + if [[ "$filename" == "amdxc64.dll" ]]; then + for candidate in \ + "$fgmod_path/fsr4-rdna2-valve-411-pre10/amdxc64.dll"; do [[ -f "$candidate" && -f "$existing_file" ]] && cmp -s "$existing_file" "$candidate" && return 0 done return 1 @@ -240,7 +258,7 @@ done unset cleanup_file # === Optional: Backup Original DLLs === -original_dlls=("d3dcompiler_47.dll" "amd_fidelityfx_dx12.dll" "amd_fidelityfx_framegeneration_dx12.dll" "amd_fidelityfx_upscaler_dx12.dll" "amdxcffx64.dll" "amd_fidelityfx_vk.dll") +original_dlls=("d3dcompiler_47.dll" "amd_fidelityfx_dx12.dll" "amd_fidelityfx_framegeneration_dx12.dll" "amd_fidelityfx_upscaler_dx12.dll" "amdxcffx64.dll" "amdxc64.dll" "amd_fidelityfx_vk.dll") for dll in "${original_dlls[@]}"; do existing_path="$exe_folder_path/$dll" backup_path="$exe_folder_path/$dll.b" @@ -261,7 +279,13 @@ rm -f "$exe_folder_path/nvapi64.dll" "$exe_folder_path/nvapi64.dll.b" echo " Cleaned up nvapi64.dll and backup (legacy fakenvapi conflicts)" # === Core Install === -if [[ -f "$fgmod_path/renames/$dll_name" ]]; then +if [[ -n "$variant_dir" && -f "$variant_dir/renames/$dll_name" ]]; then + echo " Using variant pre-renamed $dll_name" + cp "$variant_dir/renames/$dll_name" "$exe_folder_path/$dll_name" || error_exit " Failed to copy variant $dll_name" +elif [[ -n "$variant_dir" && -f "$variant_dir/OptiScaler.dll" ]]; then + echo " Using variant OptiScaler injector" + cp "$variant_dir/OptiScaler.dll" "$exe_folder_path/$dll_name" || error_exit " Failed to copy variant OptiScaler.dll as $dll_name" +elif [[ -f "$fgmod_path/renames/$dll_name" ]]; then echo " Using pre-renamed $dll_name" cp "$fgmod_path/renames/$dll_name" "$exe_folder_path/$dll_name" || error_exit " Failed to copy $dll_name" else @@ -288,6 +312,78 @@ fi # an external TTF that is not present. Only normalize the default auto value. sed -i 's/^UseHQFont[[:space:]]*=[[:space:]]*auto$/UseHQFont=false/' "$exe_folder_path/OptiScaler.ini" || true +if [[ ${#variant_ini_overrides[@]} -gt 0 && -n "$python_bin" ]]; then + "$python_bin" - "$exe_folder_path/OptiScaler.ini" "${variant_ini_overrides[@]}" <<'PY' +import re +import sys +from pathlib import Path + +path = Path(sys.argv[1]) +overrides = sys.argv[2:] +content = path.read_text(encoding='utf-8', errors='replace') +newline = '\r\n' if '\r\n' in content else '\n' +lines = content.splitlines(keepends=True) +section_pattern = re.compile(r'^\s*\[(?P
[^\]]+)\]\s*$') + +def ensure_trailing_newline(): + if lines and not lines[-1].endswith(('\n', '\r')): + lines[-1] += newline + +def upsert(section, key, value): + replacement = f'{key}={value}' + key_pattern = re.compile(rf'^(\s*{re.escape(key)}\s*)=.*$') + if section is None: + for idx, line in enumerate(lines): + if key_pattern.match(line): + line_ending = '\r\n' if line.endswith('\r\n') else ('\n' if line.endswith('\n') else newline) + lines[idx] = f'{replacement}{line_ending}' + return + ensure_trailing_newline() + lines.append(f'{replacement}{newline}') + return + + in_section = False + insert_at = None + for idx, line in enumerate(lines): + match = section_pattern.match(line.strip()) + if match: + if in_section: + insert_at = idx + break + if match.group('section') == section: + in_section = True + continue + if in_section and key_pattern.match(line): + line_ending = '\r\n' if line.endswith('\r\n') else ('\n' if line.endswith('\n') else newline) + lines[idx] = f'{replacement}{line_ending}' + return + + if in_section: + if insert_at is None: + ensure_trailing_newline() + insert_at = len(lines) + lines.insert(insert_at, f'{replacement}{newline}') + return + + ensure_trailing_newline() + if lines and lines[-1].strip(): + lines.append(newline) + lines.append(f'[{section}]{newline}') + lines.append(f'{replacement}{newline}') + +for override in overrides: + key_part, value = override.split('=', 1) + if '.' in key_part: + section, key = key_part.split('.', 1) + else: + section, key = None, key_part + if key: + upsert(section.strip() if section else None, key.strip(), value.strip()) + +path.write_text(''.join(lines), encoding='utf-8') +PY +fi + # === Migrate FGType → FGInput/FGOutput (pre-v0.9-final INIs) === # v0.9-final split the single FGType key into FGInput + FGOutput. Games that were # patched with an older build will have FGType= with no FGInput/FGOutput, diff --git a/main.py b/main.py index 70f1359..a4a6760 100644 --- a/main.py +++ b/main.py @@ -27,6 +27,24 @@ "version": "4.1.1-official", } +FSR4_VALVE_411_ASSET = { + "name": "amdxcffx64_valve_2.3.0.2913.dll", + "sha256": "4e7dc37aebea3a90e3d3cc43e24cb2b54176b2535315f20dbe63b3b7cfc56b1e", + "version": "4.1.1-valve-2.3.0.2913", +} + +AMDXC64_RDNA2_ASSET = { + "name": "amdxc64.dll", + "sha256": "a0a0af61d475e30a70966b3459f3793df772faf8f26ae3261d10554ff592cbd5", + "version": "8.18.10.0474", +} + +OPTISCALER_PRE10_ASSET = { + "name": "OptiScaler_0.10.0-pre1.20260622_135940.dll", + "sha256": "b374b19081cc066365d0c6da4808d768e16469b0cbdfc478b6e95999947d5364", + "version": "0.10.0-pre1.20260622_135940", +} + OPTIPATCHER_ASSET = { "name": "OptiPatcher_rolling.asi", "sha256": "88b9e1be3559737cd205fdf5f2c8550cf1923fb1def4c603e5bf03c3e84131b1", @@ -73,6 +91,39 @@ "source_version": FSR4_OFFICIAL_411_ASSET["version"], } ], + "config_overrides": {}, + }, + "rdna2-valve-411-pre10": { + "label": "4.1.1 Valve RDNA2 compatibility", + "dir_name": "fsr4-rdna2-valve-411-pre10", + "sha256": "ec7ed3ca674e288240e6f04b986342aece47454c41d9b0959449e82e22bd7f6d", + "source_asset_name": OPTISCALER_ARCHIVE_ASSET["name"], + "source_version": OPTISCALER_ARCHIVE_ASSET["version"], + "uses_archive_native": True, + "injector": { + "name": "OptiScaler.dll", + "sha256": OPTISCALER_PRE10_ASSET["sha256"], + "source_asset_name": OPTISCALER_PRE10_ASSET["name"], + "source_version": OPTISCALER_PRE10_ASSET["version"], + }, + "extra_files": [ + { + "name": FSR4_DRIVER_OVERRIDE_FILENAME, + "sha256": FSR4_VALVE_411_ASSET["sha256"], + "source_asset_name": FSR4_VALVE_411_ASSET["name"], + "source_version": FSR4_VALVE_411_ASSET["version"], + }, + { + "name": "amdxc64.dll", + "sha256": AMDXC64_RDNA2_ASSET["sha256"], + "source_asset_name": AMDXC64_RDNA2_ASSET["name"], + "source_version": AMDXC64_RDNA2_ASSET["version"], + } + ], + "config_overrides": { + "FSR.Fsr4ForceModel": "2", + "Plugins.LoadCustomAmdxc64OnRdna2": "true", + }, }, } VARIANT_EXTRA_FILENAMES = sorted( @@ -132,6 +183,7 @@ "amd_fidelityfx_framegeneration_dx12.dll", FSR4_UPSCALER_FILENAME, FSR4_DRIVER_OVERRIDE_FILENAME, + "amdxc64.dll", "amd_fidelityfx_vk.dll", ] @@ -375,6 +427,105 @@ def _fsr4_variant_extra_files(self, fsr4_variant: str | None) -> list[dict]: def _fsr4_variant_extra_file_path(self, fgmod_path: Path, fsr4_variant: str | None, filename: str) -> Path: return self._fsr4_variant_dir(fgmod_path, fsr4_variant) / filename + def _fsr4_variant_injector_info(self, fsr4_variant: str | None) -> dict | None: + variant = self._fsr4_variant_info(fsr4_variant) + injector = variant.get("injector") + return injector if isinstance(injector, dict) else None + + def _fsr4_variant_injector_path(self, fgmod_path: Path, fsr4_variant: str | None) -> Path | None: + injector = self._fsr4_variant_injector_info(fsr4_variant) + if not injector: + return None + return self._fsr4_variant_dir(fgmod_path, fsr4_variant) / injector.get("name", "OptiScaler.dll") + + def _fsr4_variant_renamed_proxy_path(self, fgmod_path: Path, fsr4_variant: str | None, dll_name: str) -> Path | None: + if not self._fsr4_variant_injector_info(fsr4_variant): + return None + return self._fsr4_variant_dir(fgmod_path, fsr4_variant) / "renames" / dll_name + + def _fsr4_variant_config_overrides(self, fsr4_variant: str | None) -> dict: + variant = self._fsr4_variant_info(fsr4_variant) + overrides = variant.get("config_overrides") or {} + return dict(overrides) if isinstance(overrides, dict) else {} + + def _split_ini_override_key(self, raw_key: str) -> tuple[str | None, str]: + key = str(raw_key).strip() + if "." in key: + section, section_key = key.split(".", 1) + section = section.strip() + section_key = section_key.strip() + if section and section_key: + return section, section_key + return None, key + + def _apply_optiscaler_ini_overrides(self, ini_file: Path, overrides: dict) -> bool: + if not overrides: + return True + try: + content = ini_file.read_text(encoding="utf-8", errors="replace") + newline = "\r\n" if "\r\n" in content else "\n" + lines = content.splitlines(keepends=True) + section_pattern = re.compile(r"^\s*\[(?P
[^\]]+)\]\s*$") + + def ensure_trailing_newline() -> None: + if lines and not lines[-1].endswith(("\n", "\r")): + lines[-1] += newline + + def upsert(section: str | None, key: str, value: str) -> None: + replacement = f"{key}={value}" + key_pattern = re.compile(rf"^(\s*{re.escape(key)}\s*)=.*$") + + if section is None: + for idx, line in enumerate(lines): + if key_pattern.match(line): + line_ending = "\r\n" if line.endswith("\r\n") else ("\n" if line.endswith("\n") else newline) + lines[idx] = f"{replacement}{line_ending}" + return + ensure_trailing_newline() + lines.append(f"{replacement}{newline}") + return + + in_section = False + insert_at = None + for idx, line in enumerate(lines): + match = section_pattern.match(line.strip()) + if match: + if in_section: + insert_at = idx + break + if match.group("section") == section: + in_section = True + continue + if in_section and key_pattern.match(line): + line_ending = "\r\n" if line.endswith("\r\n") else ("\n" if line.endswith("\n") else newline) + lines[idx] = f"{replacement}{line_ending}" + return + + if in_section: + if insert_at is None: + ensure_trailing_newline() + insert_at = len(lines) + lines.insert(insert_at, f"{replacement}{newline}") + return + + ensure_trailing_newline() + if lines and lines[-1].strip(): + lines.append(newline) + lines.append(f"[{section}]{newline}") + lines.append(f"{replacement}{newline}") + + for raw_key, raw_value in overrides.items(): + section, key = self._split_ini_override_key(str(raw_key)) + value = str(raw_value).strip() + if key: + upsert(section, key, value) + + ini_file.write_text("".join(lines), encoding="utf-8") + return True + except Exception as exc: + decky.logger.error(f"Failed to apply OptiScaler.ini overrides to {ini_file}: {exc}") + return False + def _sync_variant_root_extra_files(self, fgmod_path: Path, fsr4_variant: str | None) -> None: selected_extra_files = {extra_file["name"]: extra_file for extra_file in self._fsr4_variant_extra_files(fsr4_variant)} for filename in VARIANT_EXTRA_FILENAMES: @@ -580,11 +731,17 @@ async def extract_static_optiscaler(self, selected_default_variant: str = DEFAUL optiscaler_archive = bin_path / OPTISCALER_ARCHIVE_ASSET["name"] fsr4_int8_src = bin_path / FSR4_INT8_ASSET["name"] fsr4_official_411_src = bin_path / FSR4_OFFICIAL_411_ASSET["name"] + fsr4_valve_411_src = bin_path / FSR4_VALVE_411_ASSET["name"] + amdxc64_rdna2_src = bin_path / AMDXC64_RDNA2_ASSET["name"] + optiscaler_pre10_src = bin_path / OPTISCALER_PRE10_ASSET["name"] optipatcher_src = bin_path / OPTIPATCHER_ASSET["name"] for required_path, asset in [ (optiscaler_archive, OPTISCALER_ARCHIVE_ASSET), (fsr4_int8_src, FSR4_INT8_ASSET), (fsr4_official_411_src, FSR4_OFFICIAL_411_ASSET), + (fsr4_valve_411_src, FSR4_VALVE_411_ASSET), + (amdxc64_rdna2_src, AMDXC64_RDNA2_ASSET), + (optiscaler_pre10_src, OPTISCALER_PRE10_ASSET), (optipatcher_src, OPTIPATCHER_ASSET), ]: if not required_path.exists(): @@ -660,6 +817,54 @@ async def extract_static_optiscaler(self, selected_default_variant: str = DEFAUL "Prepared rdna34-official-411 driver override", ) + rdna2_valve_dir = extract_path / FSR4_VARIANTS["rdna2-valve-411-pre10"]["dir_name"] + rdna2_valve_dir.mkdir(parents=True, exist_ok=True) + rdna2_valve_upscaler = rdna2_valve_dir / FSR4_UPSCALER_FILENAME + shutil.copy2(native_upscaler_root, rdna2_valve_upscaler) + self._verify_bundled_asset( + rdna2_valve_upscaler, + FSR4_VARIANTS["rdna2-valve-411-pre10"]["sha256"], + "Prepared rdna2-valve-411-pre10 FSR4 upscaler", + ) + self._verify_bundled_asset( + fsr4_valve_411_src, + FSR4_VALVE_411_ASSET["sha256"], + "Bundled rdna2-valve-411-pre10 driver override", + ) + rdna2_valve_driver = rdna2_valve_dir / FSR4_DRIVER_OVERRIDE_FILENAME + shutil.copy2(fsr4_valve_411_src, rdna2_valve_driver) + self._verify_bundled_asset( + rdna2_valve_driver, + FSR4_VALVE_411_ASSET["sha256"], + "Prepared rdna2-valve-411-pre10 driver override", + ) + self._verify_bundled_asset( + amdxc64_rdna2_src, + AMDXC64_RDNA2_ASSET["sha256"], + "Bundled rdna2-valve-411-pre10 amdxc64 override", + ) + rdna2_valve_amdxc64 = rdna2_valve_dir / "amdxc64.dll" + shutil.copy2(amdxc64_rdna2_src, rdna2_valve_amdxc64) + self._verify_bundled_asset( + rdna2_valve_amdxc64, + AMDXC64_RDNA2_ASSET["sha256"], + "Prepared rdna2-valve-411-pre10 amdxc64 override", + ) + self._verify_bundled_asset( + optiscaler_pre10_src, + OPTISCALER_PRE10_ASSET["sha256"], + "Bundled rdna2-valve-411-pre10 OptiScaler injector", + ) + rdna2_valve_injector = rdna2_valve_dir / "OptiScaler.dll" + shutil.copy2(optiscaler_pre10_src, rdna2_valve_injector) + self._verify_bundled_asset( + rdna2_valve_injector, + OPTISCALER_PRE10_ASSET["sha256"], + "Prepared rdna2-valve-411-pre10 OptiScaler injector", + ) + if not self._create_renamed_copies(rdna2_valve_injector, rdna2_valve_dir / "renames"): + return {"status": "error", "message": "Failed to prepare renamed pre10 OptiScaler proxies."} + rdna23_dir = extract_path / FSR4_VARIANTS["rdna23-int8"]["dir_name"] rdna23_dir.mkdir(parents=True, exist_ok=True) self._verify_bundled_asset( @@ -704,6 +909,18 @@ async def extract_static_optiscaler(self, selected_default_variant: str = DEFAUL "source_asset_name": variant["source_asset_name"], "source_version": variant["source_version"], "uses_archive_native": bool(variant["uses_archive_native"]), + "injector": ( + { + "name": variant["injector"]["name"], + "sha256": variant["injector"]["sha256"], + "source_asset_name": variant["injector"]["source_asset_name"], + "source_version": variant["injector"]["source_version"], + "path": str((Path(variant["dir_name"]) / variant["injector"]["name"]).as_posix()), + } + if isinstance(variant.get("injector"), dict) + else None + ), + "config_overrides": dict(variant.get("config_overrides") or {}), "extra_files": [ { "name": extra_file["name"], @@ -864,11 +1081,17 @@ async def check_fgmod_path(self) -> dict: if not plugins_dir.exists() or not (plugins_dir / "OptiPatcher.asi").exists(): return {"exists": False} - for variant in FSR4_VARIANTS.values(): + for variant_id, variant in FSR4_VARIANTS.items(): variant_dir = path / variant["dir_name"] variant_path = variant_dir / FSR4_UPSCALER_FILENAME if not variant_path.exists(): return {"exists": False} + injector = variant.get("injector") + if isinstance(injector, dict): + if not (variant_dir / injector.get("name", "OptiScaler.dll")).exists(): + return {"exists": False} + if not (variant_dir / "renames" / "dxgi.dll").exists(): + return {"exists": False} for extra_file in variant.get("extra_files", []): if not (variant_dir / extra_file["name"]).exists(): return {"exists": False} @@ -917,8 +1140,14 @@ def _manual_patch_directory_impl( } preserve_ini = True + previous_marker_metadata = self._read_marker(directory / MARKER_FILENAME) + previous_variant = str(previous_marker_metadata.get("fsr4_variant") or "").strip() selected_variant = self._selected_fsr4_variant(fgmod_path, fsr4_variant) selected_variant_info = FSR4_VARIANTS[selected_variant] + selected_config_overrides = self._fsr4_variant_config_overrides(selected_variant) + if previous_variant == "rdna2-valve-411-pre10" and selected_variant != previous_variant: + selected_config_overrides.setdefault("FSR.Fsr4ForceModel", "auto") + selected_config_overrides.setdefault("Plugins.LoadCustomAmdxc64OnRdna2", "false") selected_upscaler_src = self._fsr4_variant_path(fgmod_path, selected_variant) if not selected_upscaler_src.exists(): selected_upscaler_src = fgmod_path / FSR4_UPSCALER_FILENAME @@ -976,9 +1205,18 @@ def _manual_patch_directory_impl( else "No original game DLLs required backup" ) - renamed = fgmod_path / "renames" / dll_name + variant_renamed = self._fsr4_variant_renamed_proxy_path(fgmod_path, selected_variant, dll_name) + variant_injector = self._fsr4_variant_injector_path(fgmod_path, selected_variant) + root_renamed = fgmod_path / "renames" / dll_name destination_dll = directory / dll_name - source_for_copy = renamed if renamed.exists() else optiscaler_dll + if variant_renamed and variant_renamed.exists(): + source_for_copy = variant_renamed + elif variant_injector and variant_injector.exists(): + source_for_copy = variant_injector + elif root_renamed.exists(): + source_for_copy = root_renamed + else: + source_for_copy = optiscaler_dll shutil.copy2(source_for_copy, destination_dll) decky.logger.info(f"Copied injector DLL from {source_for_copy} to {destination_dll}") @@ -995,6 +1233,7 @@ def _manual_patch_directory_impl( if target_ini.exists(): self._migrate_optiscaler_ini(target_ini) self._disable_hq_font_auto(target_ini) + self._apply_optiscaler_ini_overrides(target_ini, selected_config_overrides) plugins_src = fgmod_path / "plugins" plugins_dest = directory / "plugins" diff --git a/package.json b/package.json index 1712039..663b43b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "decky-framegen", - "version": "0.15.7", + "version": "0.16.3-pre", "description": "This plugin installs and manages OptiScaler, a tool that enhances upscaling and enables frame generation in a range of DirectX 12 games.", "type": "module", "scripts": { @@ -68,6 +68,21 @@ "url": "https://github.com/xXJSONDeruloXx/OptiScaler-Bleeding-Edge/releases/download/fsr-4-1-1/amdxcffx64.dll", "name": "amdxcffx64.dll" }, + { + "sha256hash": "a0a0af61d475e30a70966b3459f3793df772faf8f26ae3261d10554ff592cbd5", + "url": "https://github.com/xXJSONDeruloXx/OptiScaler-Bleeding-Edge/releases/download/fsr-4-1-1-rdna2/amdxc64.dll", + "name": "amdxc64.dll" + }, + { + "sha256hash": "4e7dc37aebea3a90e3d3cc43e24cb2b54176b2535315f20dbe63b3b7cfc56b1e", + "url": "https://github.com/xXJSONDeruloXx/OptiScaler-Bleeding-Edge/releases/download/fsr-4-1-1-rdna2/amdxcffx64.dll", + "name": "amdxcffx64_valve_2.3.0.2913.dll" + }, + { + "sha256hash": "b374b19081cc066365d0c6da4808d768e16469b0cbdfc478b6e95999947d5364", + "url": "https://github.com/xXJSONDeruloXx/OptiScaler-Bleeding-Edge/releases/download/fsr-4-1-1-rdna2/OptiScaler_0.10.0-pre1.20260622_135940.dll", + "name": "OptiScaler_0.10.0-pre1.20260622_135940.dll" + }, { "sha256hash": "88b9e1be3559737cd205fdf5f2c8550cf1923fb1def4c603e5bf03c3e84131b1", "url": "https://github.com/xXJSONDeruloXx/OptiScaler-Bleeding-Edge/releases/download/bins-for-optipatcher-rolling/OptiPatcher_rolling.asi", diff --git a/src/utils/constants.ts b/src/utils/constants.ts index b873b61..13bf505 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -62,18 +62,23 @@ export const DEFAULT_PROXY_DLL: ProxyDllValue = "dxgi.dll"; export const FSR4_VARIANT_OPTIONS = [ { value: "rdna23-int8", - label: "Steam Deck / RDNA2-3 optimized", + label: "4.0.2c | RDNA2/3 Mod", hint: "Uses the bundled FSR4 INT8 4.0.2c override. Recommended for Steam Deck and other non-RDNA4 systems.", }, { value: "rdna4-native", - label: "Native bundle / RDNA4", - hint: "Uses the amd_fidelityfx_upscaler_dx12.dll that ships inside the OptiScaler 0.9.3 bundle.", + label: "4.1.0 | RDNA4 Official", + hint: "Uses the AMD-supplied 4.1.0 amd_fidelityfx_upscaler_dx12.dll redistributed in the OptiScaler bundle.", }, { value: "rdna34-official-411", - label: "4.1.1 official for RDNA 3/4", - hint: "Uses the native 0.9.3 upscaler plus the official amdxcffx64.dll override for RDNA 3/4.", + label: "4.1.1 | RDNA3/4 Official", + hint: "Uses the 4.1.0 native upscaler plus the official 4.1.1 amdxcffx64.dll override for RDNA 3/4.", + }, + { + value: "rdna2-valve-411-pre10", + label: "4.1.1 | RDNA2 Mod", + hint: "Uses the pre10 OptiScaler injector, 4.1.0 native upscaler, Valve 4.1.1 amdxcffx64.dll, old amdxc64.dll, and RDNA2-specific INI overrides.", }, ] as const;