Compare commits

...

9 Commits

Author SHA1 Message Date
AsperTheDog
58bd19a2f3 Fix Vulkan validation errors (#92)
This PR fixes several validation errors caused by invalid Vulkan usage. These validation errors often end up invoking Undefined Behavior on the driver side, which can lead to artifacts or crashes which are driver specific and otherwise incredibly hard to track. I don't think it should have any impact on performance, but it would be good to test it with as many games as possible (maybe a bug in a game was fixed?).

Each commit fixes an error. I added to each a description with the validation error that was fixed and a small explanation on what was causing it and how I fixed it.

Co-authored-by: AsperTheDog <guillerman0000@gmail.com>
Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/92
2026-05-15 15:36:14 +00:00
AsperTheDog
48888bd014 Change non-unform shader extension to be more conservative (#99)
The previous fix for Tomodachi Life (#91) included the extension to all shaders, independently on if it was needed or not. This PR fixes that by lazily adding the extension only when it is actually needed.

This change should not be noticed by anyone, but it avoids having to modify shaders that do not perform any type of dynamic indexing, which apparently is something some modders care about.

Co-authored-by: AsperTheDog <guillerman0000@gmail.com>
Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/99
2026-05-15 15:19:12 +00:00
Renovate Bot
d307afc454 Update dependency Sep to 0.14.1 (#98)
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [Sep](https://github.com/nietras/Sep) | `0.13.0` → `0.14.1` | ![age](https://developer.mend.io/api/mc/badges/age/nuget/Sep/0.14.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/nuget/Sep/0.13.0/0.14.1?slim=true) |

---

### Release Notes

<details>
<summary>nietras/Sep (Sep)</summary>

### [`v0.14.1`](https://github.com/nietras/Sep/releases/tag/v0.14.1): 0.14.1

#### What's Changed

- Improve SepReaderOptions.Unescape/.Trim comments by [@&#8203;nietras](https://github.com/nietras) in [#&#8203;542](https://github.com/nietras/Sep/pull/542)
- Improve SepReader/WriterExtensions.Strict() comments by [@&#8203;nietras](https://github.com/nietras) in [#&#8203;543](https://github.com/nietras/Sep/pull/543)

**Full Changelog**: <https://github.com/nietras/Sep/compare/v0.14.0...v0.14.1>

### [`v0.14.0`](https://github.com/nietras/Sep/releases/tag/v0.14.0): 0.14.0

#### What's Changed

- Add `leaveOpen` overloads for SepReaderOptions.From\* via SepTextReaderDisposers by [@&#8203;Copilot](https://github.com/Copilot) in [#&#8203;530](https://github.com/nietras/Sep/pull/530)
- Bump MSTest from 4.2.1 to 4.2.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;533](https://github.com/nietras/Sep/pull/533)
- Bump github/codeql-action from 4.35.2 to 4.35.3 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;532](https://github.com/nietras/Sep/pull/532)
- Bump step-security/harden-runner from 2.19.0 to 2.19.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;531](https://github.com/nietras/Sep/pull/531)
- Confirm statuses:write is the correct minimum permission for super-linter (not checks:write) by [@&#8203;Copilot](https://github.com/Copilot) in [#&#8203;540](https://github.com/nietras/Sep/pull/540)

**Full Changelog**: <https://github.com/nietras/Sep/compare/v0.13.0...v0.14.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzguMCIsInVwZGF0ZWRJblZlciI6IjQzLjE3OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/98
2026-05-15 15:14:23 +00:00
Renovate Bot
134453e62b Update dependency SharpCompress to 0.48.1 (#97)
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [SharpCompress](https://github.com/adamhathcock/sharpcompress) | `0.48.0` → `0.48.1` | ![age](https://developer.mend.io/api/mc/badges/age/nuget/SharpCompress/0.48.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/nuget/SharpCompress/0.48.0/0.48.1?slim=true) |

---

### Release Notes

<details>
<summary>adamhathcock/sharpcompress (SharpCompress)</summary>

### [`v0.48.1`](https://github.com/adamhathcock/sharpcompress/releases/tag/0.48.1): - GZip writing fix

[Compare Source](https://github.com/adamhathcock/sharpcompress/compare/0.48.0...0.48.1)

#### What's Changed

- release test cleanup by [@&#8203;adamhathcock](https://github.com/adamhathcock) in [#&#8203;1322](https://github.com/adamhathcock/sharpcompress/pull/1322)
- Fix GZip write async by [@&#8203;adamhathcock](https://github.com/adamhathcock) in [#&#8203;1320](https://github.com/adamhathcock/sharpcompress/pull/1320)

**Full Changelog**: <https://github.com/adamhathcock/sharpcompress/compare/0.48.0...0.48.1>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzguMCIsInVwZGF0ZWRJblZlciI6IjQzLjE3OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/97
2026-05-15 15:13:49 +00:00
Max
298b6c3959 [HLE] Stub ILibrarySelfAccessor:ExitAndReturn (10) (#96)
Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/96
2026-05-15 15:13:23 +00:00
shinyoyo
c96433eb13 Updated Simplified Chinese translation (#95)
Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/95
2026-05-14 14:00:16 +00:00
AsperTheDog
c0078088dd Add shader non-uniform indexing support (#91)
This PR marks ALL texture indexes as nonuniform to fix an issue with the paths in Tomodachi Life: Living the Dream on AMD cards. It should have a negligible impact on performance (and it should not have an impact at all on NVIDIA cards!)

It's caused by what is called 'implicit non-uniform sampler array indexing'. The idea is basically that some GPUs optimize texture lookups from indexed texture arrays, by assuming that you are never going to index different textures within a single workgroup. What this causes is that visual glitch where a subgroup is tasked with rendering a block of the screen, and in the boundaries some cores are indexing the wrong texture.

Co-authored-by: AsperTheDog <guillerman0000@gmail.com>
Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/91
2026-05-14 08:59:10 +00:00
Max
dcac29680a Updated PlayReports for more titles (#93)
- Echoes of Wisdom (Warps)
- Super Mario Odyssey (Kingdoms)
- Super Mario Bros. Wonder (World & Course)
- Pokemon Scarlet/Violet (DLC & Accademy Rooms)
- Super Mario 3D All Stars (Game Selection) (Berry is working on track showcase)

Co-authored-by: berrydiaboli <anthonyhoffman54444@gmail.com>
Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/93
2026-05-14 04:06:28 +00:00
Max
ec07e51807 Update compatibility.csv (#94)
- Emio – The Smiling Man: Famicom Detective Club (DEMO)
- GROOVE COASTER WAI WAI PARTY!!!!
- Metroid Prime 4: Beyond
- Mute Crimson DX
- Pokémon Champions
- Pokémon FireRed Version
- Pokémon LeafGreen Version
- Tomodachi Life: Living the Dream
- Tomodachi Life: Living the Dream – Welcome Edtion

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/94
2026-05-14 04:05:58 +00:00
25 changed files with 709 additions and 66 deletions

View File

@@ -8,7 +8,7 @@
<PackageVersion Include="Avalonia.Desktop" Version="11.3.15" /> <PackageVersion Include="Avalonia.Desktop" Version="11.3.15" />
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.15" /> <PackageVersion Include="Avalonia.Diagnostics" Version="11.3.15" />
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.15" /> <PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.15" />
<PackageVersion Include="SharpCompress" Version="0.48.0" /> <PackageVersion Include="SharpCompress" Version="0.48.1" />
<PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.9.5" /> <PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.9.5" />
<PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.9.5" /> <PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.9.5" />
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" /> <PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
@@ -51,7 +51,7 @@
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="2.0.6" /> <PackageVersion Include="Ryujinx.Systems.Update.Common" Version="2.0.6" />
<PackageVersion Include="Gommon" Version="2.8.1.2" /> <PackageVersion Include="Gommon" Version="2.8.1.2" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" /> <PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="Sep" Version="0.13.0" /> <PackageVersion Include="Sep" Version="0.14.1" />
<PackageVersion Include="shaderc.net" Version="0.1.0" /> <PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" /> <PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" /> <PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" />

View File

@@ -596,7 +596,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "", "zh_CN": "重启模拟",
"zh_TW": "重新啟動模擬" "zh_TW": "重新啟動模擬"
} }
}, },
@@ -6121,7 +6121,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "", "zh_CN": "开启网络日志",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -11371,7 +11371,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "", "zh_CN": "保存",
"zh_TW": "儲存" "zh_TW": "儲存"
} }
}, },
@@ -17121,7 +17121,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "", "zh_CN": "在控制台中显示网络日志",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -21496,7 +21496,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "", "zh_CN": "控制台将会在下次启动 Ryujinx 时可用。",
"zh_TW": "" "zh_TW": ""
} }
}, },

View File

@@ -1061,6 +1061,7 @@
0100BCA016636000,"eBaseball Powerful Pro Yakyuu 2022",gpu;services-horizon;crash,nothing,2024-05-26 23:07:19 0100BCA016636000,"eBaseball Powerful Pro Yakyuu 2022",gpu;services-horizon;crash,nothing,2024-05-26 23:07:19
01001F20100B8000,"Eclipse: Edge of Light",,playable,2020-08-11 23:06:29 01001F20100B8000,"Eclipse: Edge of Light",,playable,2020-08-11 23:06:29
0100E0A0110F4000,"eCrossminton",,playable,2020-07-11 18:24:27 0100E0A0110F4000,"eCrossminton",,playable,2020-07-11 18:24:27
010054601D54C000,"Emio The Smiling Man: Famicom Detective Club (DEMO)",demo,playable,2026-05-13 18:32:12
0100ABE00DB4E000,"Edna & Harvey: Harvey's New Eyes",nvdec,playable,2021-01-26 14:36:08 0100ABE00DB4E000,"Edna & Harvey: Harvey's New Eyes",nvdec,playable,2021-01-26 14:36:08
01004F000B716000,"Edna & Harvey: The Breakout Anniversary Edition",crash;nvdec,ingame,2022-08-01 16:59:56 01004F000B716000,"Edna & Harvey: The Breakout Anniversary Edition",crash;nvdec,ingame,2022-08-01 16:59:56
01002550129F0000,"Effie",,playable,2022-10-27 14:36:39 01002550129F0000,"Effie",,playable,2022-10-27 14:36:39
@@ -1204,7 +1205,7 @@
01003B200E440000,"Five Nights at Freddy's: Sister Location",,playable,2023-10-06 09:00:58 01003B200E440000,"Five Nights at Freddy's: Sister Location",,playable,2023-10-06 09:00:58
010038200E088000,"Flan",crash;regression,ingame,2021-11-17 07:39:28 010038200E088000,"Flan",crash;regression,ingame,2021-11-17 07:39:28
01000A0004C50000,"FLASHBACK™",nvdec,playable,2020-05-14 13:57:29 01000A0004C50000,"FLASHBACK™",nvdec,playable,2020-05-14 13:57:29
0100C53004C52000,"Flat Heroes",gpu,ingame,2022-07-26 19:37:37 0100C53004C52000,"Flat Heroes",,playable,2026-02-27 17:00:00
0100B54012798000,"Flatland: Prologue",,playable,2020-12-11 20:41:12 0100B54012798000,"Flatland: Prologue",,playable,2020-12-11 20:41:12
0100307004B4C000,"Flinthook",online,playable,2021-03-25 20:42:29 0100307004B4C000,"Flinthook",online,playable,2021-03-25 20:42:29
010095A004040000,"Flip Wars",services;ldn-untested,ingame,2022-05-02 15:39:18 010095A004040000,"Flip Wars",services;ldn-untested,ingame,2022-05-02 15:39:18
@@ -1394,6 +1395,7 @@
0100c3c012718000,"Grand Theft Auto: III The Definitive Edition",gpu;UE4,ingame,2022-10-31 20:13:52 0100c3c012718000,"Grand Theft Auto: III The Definitive Edition",gpu;UE4,ingame,2022-10-31 20:13:52
0100182014022000,"Grand Theft Auto: Vice City The Definitive Edition",gpu;UE4,ingame,2022-10-31 20:13:52 0100182014022000,"Grand Theft Auto: Vice City The Definitive Edition",gpu;UE4,ingame,2022-10-31 20:13:52
010065a014024000,"Grand Theft Auto: San Andreas The Definitive Edition",gpu;UE4,ingame,2022-10-31 20:13:52 010065a014024000,"Grand Theft Auto: San Andreas The Definitive Edition",gpu;UE4,ingame,2022-10-31 20:13:52
0100EB500D92E000,"GROOVE COASTER WAI WAI PARTY!!!!",gpu,ingame,2026-05-13 18:32:12
0100822012D76000,"HAAK",gpu,ingame,2023-02-19 14:31:05 0100822012D76000,"HAAK",gpu,ingame,2023-02-19 14:31:05
01007E100EFA8000,"Habroxia",,playable,2020-06-16 23:04:42 01007E100EFA8000,"Habroxia",,playable,2020-06-16 23:04:42
0100535012974000,"Hades",vulkan,playable,2022-10-05 10:45:21 0100535012974000,"Hades",vulkan,playable,2022-10-05 10:45:21
@@ -1832,6 +1834,7 @@
010055200E87E000,"Metamorphosis",UE4;audout;gpu;nvdec,ingame,2021-06-16 16:18:11 010055200E87E000,"Metamorphosis",UE4;audout;gpu;nvdec,ingame,2021-06-16 16:18:11
0100D4900E82C000,"Metro 2033 Redux",gpu,ingame,2022-11-09 10:53:13 0100D4900E82C000,"Metro 2033 Redux",gpu,ingame,2022-11-09 10:53:13
0100F0400E850000,"Metro: Last Light Redux",slow;nvdec;vulkan-backend-bug,ingame,2023-11-01 11:53:52 0100F0400E850000,"Metro: Last Light Redux",slow;nvdec;vulkan-backend-bug,ingame,2023-11-01 11:53:52
010019A01E2F2000,"Metroid Prime 4: Beyond",,ingame,2026-05-13 18:32:12
010012101468C000,"Metroid Prime™ Remastered",gpu;Needs Update;vulkan-backend-bug;opengl-backend-bug,ingame,2024-05-07 22:48:15 010012101468C000,"Metroid Prime™ Remastered",gpu;Needs Update;vulkan-backend-bug;opengl-backend-bug,ingame,2024-05-07 22:48:15
010093801237C000,"Metroid™ Dread",,playable,2023-11-13 04:02:36 010093801237C000,"Metroid™ Dread",,playable,2023-11-13 04:02:36
0100A1200F20C000,"Midnight Evil",,playable,2022-10-18 22:55:19 0100A1200F20C000,"Midnight Evil",,playable,2022-10-18 22:55:19
@@ -1945,6 +1948,7 @@
0100C3E00ACAA000,"Mutant Football League: Dynasty Edition",online-broken,playable,2022-08-05 17:01:51 0100C3E00ACAA000,"Mutant Football League: Dynasty Edition",online-broken,playable,2022-08-05 17:01:51
01004BE004A86000,"Mutant Mudds Collection",,playable,2022-08-05 17:11:38 01004BE004A86000,"Mutant Mudds Collection",,playable,2022-08-05 17:11:38
0100E6B00DEA4000,"Mutant Year Zero: Road to Eden - Deluxe Edition",nvdec;UE4,playable,2022-09-10 13:31:10 0100E6B00DEA4000,"Mutant Year Zero: Road to Eden - Deluxe Edition",nvdec;UE4,playable,2022-09-10 13:31:10
010037501F864000,"Mute Crimson DX",,ingame,2026-05-13 18:32:12
0100161009E5C000,"MX Nitro: Unleashed",,playable,2022-09-27 22:34:33 0100161009E5C000,"MX Nitro: Unleashed",,playable,2022-09-27 22:34:33
0100218011E7E000,"MX vs ATV All Out",nvdec;UE4;vulkan-backend-bug,playable,2022-10-25 19:51:46 0100218011E7E000,"MX vs ATV All Out",nvdec;UE4;vulkan-backend-bug,playable,2022-10-25 19:51:46
0100D940063A0000,"MXGP3 - The Official Motocross Videogame",UE4;gpu;nvdec,ingame,2020-12-16 14:00:20 0100D940063A0000,"MXGP3 - The Official Motocross Videogame",UE4;gpu;nvdec,ingame,2020-12-16 14:00:20
@@ -2268,6 +2272,7 @@
010086F0064CE000,"Poi: Explorer Edition",nvdec,playable,2021-01-21 19:32:00 010086F0064CE000,"Poi: Explorer Edition",nvdec,playable,2021-01-21 19:32:00
0100EB6012FD2000,"Poison Control",,playable,2021-05-16 14:01:54 0100EB6012FD2000,"Poison Control",,playable,2021-05-16 14:01:54
010072400E04A000,"Pokémon Café ReMix",,playable,2021-08-17 20:00:04 010072400E04A000,"Pokémon Café ReMix",,playable,2021-08-17 20:00:04
01005B7008C52800,"Pokémon Champions",Needs Update;services;online-broke,menus,2026-05-13 18:32:12
010008c01e742000,"Pokémon Friends",crash;services,menus,2025-07-24 13:32:00 010008c01e742000,"Pokémon Friends",crash;services,menus,2025-07-24 13:32:00
01003D200BAA2000,"Pokémon Mystery Dungeon™: Rescue Team DX",mac-bug,playable,2024-01-21 00:16:32 01003D200BAA2000,"Pokémon Mystery Dungeon™: Rescue Team DX",mac-bug,playable,2024-01-21 00:16:32
01008DB008C2C000,"Pokémon Shield + Pokémon Shield Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-12 07:20:22 01008DB008C2C000,"Pokémon Shield + Pokémon Shield Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-12 07:20:22
@@ -2275,6 +2280,8 @@
01009AD008C4C000,"Pokémon: Let's Go, Pikachu! demo",slow;demo,playable,2023-11-26 11:23:20 01009AD008C4C000,"Pokémon: Let's Go, Pikachu! demo",slow;demo,playable,2023-11-26 11:23:20
0100000011D90000,"Pokémon™ Brilliant Diamond",gpu;ldn-works,ingame,2024-08-28 13:26:35 0100000011D90000,"Pokémon™ Brilliant Diamond",gpu;ldn-works,ingame,2024-08-28 13:26:35
010018E011D92000,"Pokémon™ Shining Pearl",gpu;ldn-works,ingame,2024-08-28 13:26:35 010018E011D92000,"Pokémon™ Shining Pearl",gpu;ldn-works,ingame,2024-08-28 13:26:35
100554023408000,"Pokémon FireRed Version",crashes,nothing,2026-05-13 18:32:12
010034D02340E000,"Pokémon LeafGreen Version",crashes,nothing,2026-05-13 18:32:12
010015F008C54000,"Pokémon™ HOME",Needs Update;crash;services,menus,2020-12-06 06:01:51 010015F008C54000,"Pokémon™ HOME",Needs Update;crash;services,menus,2020-12-06 06:01:51
01001F5010DFA000,"Pokémon™ Legends: Arceus",gpu;Needs Update;ldn-works,ingame,2024-09-19 10:02:02 01001F5010DFA000,"Pokémon™ Legends: Arceus",gpu;Needs Update;ldn-works,ingame,2024-09-19 10:02:02
0100F43008C44000,"Pokémon™ Legends: Z-A",gpu;crash;ldn-works,ingame,2025-11-16 00:30:00 0100F43008C44000,"Pokémon™ Legends: Z-A",gpu;crash;ldn-works,ingame,2025-11-16 00:30:00
@@ -2866,7 +2873,7 @@
0100277011F1A000,"Super Mario Bros.™ 35",online-broken,menus,2022-08-07 16:27:25 0100277011F1A000,"Super Mario Bros.™ 35",online-broken,menus,2022-08-07 16:27:25
010015100B514000,"Super Mario Bros.™ Wonder",amd-vendor-bug,playable,2024-09-06 13:21:21 010015100B514000,"Super Mario Bros.™ Wonder",amd-vendor-bug,playable,2024-09-06 13:21:21
01009B90006DC000,"Super Mario Maker™ 2",online-broken;ldn-broken,playable,2024-08-25 11:05:19 01009B90006DC000,"Super Mario Maker™ 2",online-broken;ldn-broken,playable,2024-08-25 11:05:19
0100000000010000,"Super Mario Odyssey™",nvdec;intel-vendor-bug;mac-bug,playable,2024-08-25 01:32:34 0100000000010000,"Super Mario Odyssey™",nvdec;intel-vendor-bug;mac-bug;amd-vendor-bug,playable,2026-05-13 18:32:12
010036B0034E4000,"Super Mario Party™",gpu;Needs Update;ldn-works,ingame,2024-06-21 05:10:16 010036B0034E4000,"Super Mario Party™",gpu;Needs Update;ldn-works,ingame,2024-06-21 05:10:16
0100965017338000,"Super Mario Party Jamboree",mac-bug;gpu,ingame,2025-02-17 02:09:20 0100965017338000,"Super Mario Party Jamboree",mac-bug;gpu,ingame,2025-02-17 02:09:20
0100BC0018138000,"Super Mario RPG™",gpu;audio;nvdec,ingame,2024-06-19 17:43:42 0100BC0018138000,"Super Mario RPG™",gpu;audio;nvdec,ingame,2024-06-19 17:43:42
@@ -3163,6 +3170,8 @@
0100E2E00CB14000,"Tokyo School Life",,playable,2022-09-16 20:25:54 0100E2E00CB14000,"Tokyo School Life",,playable,2022-09-16 20:25:54
010024601BB16000,"Tomb Raider I-III Remastered Starring Lara Croft",gpu;opengl,ingame,2024-09-27 12:32:04 010024601BB16000,"Tomb Raider I-III Remastered Starring Lara Croft",gpu;opengl,ingame,2024-09-27 12:32:04
0100D7F01E49C000,"Tomba! Special Edition",services-horizon,nothing,2024-09-15 21:59:54 0100D7F01E49C000,"Tomba! Special Edition",services-horizon,nothing,2024-09-15 21:59:54
010051F0207B2000,"Tomodachi Life: Living the Dream",amd-vendor-bug;gpu;intel-vendor-bug;ldn-broken,ingame,2026-05-13 18:32:12
0100CA502552A000,"Tomodachi Life: Living the Dream Welcome Edtion",amd-vendor-bug;demo,playable,2026-05-13 18:32:12
0100D400100F8000,"Tonight We Riot",,playable,2021-02-26 15:55:09 0100D400100F8000,"Tonight We Riot",,playable,2021-02-26 15:55:09
0100CC00102B4000,"Tony Hawk's™ Pro Skater™ 1 + 2",gpu;Needs Update,ingame,2024-09-24 08:18:14 0100CC00102B4000,"Tony Hawk's™ Pro Skater™ 1 + 2",gpu;Needs Update,ingame,2024-09-24 08:18:14
010093F00E818000,"Tools Up!",crash,ingame,2020-07-21 12:58:17 010093F00E818000,"Tools Up!",crash,ingame,2020-07-21 12:58:17
1 title_id game_name labels status last_updated
1061 0100BCA016636000 eBaseball Powerful Pro Yakyuu 2022 gpu;services-horizon;crash nothing 2024-05-26 23:07:19
1062 01001F20100B8000 Eclipse: Edge of Light playable 2020-08-11 23:06:29
1063 0100E0A0110F4000 eCrossminton playable 2020-07-11 18:24:27
1064 010054601D54C000 Emio – The Smiling Man: Famicom Detective Club (DEMO) demo playable 2026-05-13 18:32:12
1065 0100ABE00DB4E000 Edna & Harvey: Harvey's New Eyes nvdec playable 2021-01-26 14:36:08
1066 01004F000B716000 Edna & Harvey: The Breakout – Anniversary Edition crash;nvdec ingame 2022-08-01 16:59:56
1067 01002550129F0000 Effie playable 2022-10-27 14:36:39
1205 01003B200E440000 Five Nights at Freddy's: Sister Location playable 2023-10-06 09:00:58
1206 010038200E088000 Flan crash;regression ingame 2021-11-17 07:39:28
1207 01000A0004C50000 FLASHBACK™ nvdec playable 2020-05-14 13:57:29
1208 0100C53004C52000 Flat Heroes gpu ingame playable 2022-07-26 19:37:37 2026-02-27 17:00:00
1209 0100B54012798000 Flatland: Prologue playable 2020-12-11 20:41:12
1210 0100307004B4C000 Flinthook online playable 2021-03-25 20:42:29
1211 010095A004040000 Flip Wars services;ldn-untested ingame 2022-05-02 15:39:18
1395 0100c3c012718000 Grand Theft Auto: III – The Definitive Edition gpu;UE4 ingame 2022-10-31 20:13:52
1396 0100182014022000 Grand Theft Auto: Vice City – The Definitive Edition gpu;UE4 ingame 2022-10-31 20:13:52
1397 010065a014024000 Grand Theft Auto: San Andreas – The Definitive Edition gpu;UE4 ingame 2022-10-31 20:13:52
1398 0100EB500D92E000 GROOVE COASTER WAI WAI PARTY!!!! gpu ingame 2026-05-13 18:32:12
1399 0100822012D76000 HAAK gpu ingame 2023-02-19 14:31:05
1400 01007E100EFA8000 Habroxia playable 2020-06-16 23:04:42
1401 0100535012974000 Hades vulkan playable 2022-10-05 10:45:21
1834 010055200E87E000 Metamorphosis UE4;audout;gpu;nvdec ingame 2021-06-16 16:18:11
1835 0100D4900E82C000 Metro 2033 Redux gpu ingame 2022-11-09 10:53:13
1836 0100F0400E850000 Metro: Last Light Redux slow;nvdec;vulkan-backend-bug ingame 2023-11-01 11:53:52
1837 010019A01E2F2000 Metroid Prime 4: Beyond ingame 2026-05-13 18:32:12
1838 010012101468C000 Metroid Prime™ Remastered gpu;Needs Update;vulkan-backend-bug;opengl-backend-bug ingame 2024-05-07 22:48:15
1839 010093801237C000 Metroid™ Dread playable 2023-11-13 04:02:36
1840 0100A1200F20C000 Midnight Evil playable 2022-10-18 22:55:19
1948 0100C3E00ACAA000 Mutant Football League: Dynasty Edition online-broken playable 2022-08-05 17:01:51
1949 01004BE004A86000 Mutant Mudds Collection playable 2022-08-05 17:11:38
1950 0100E6B00DEA4000 Mutant Year Zero: Road to Eden - Deluxe Edition nvdec;UE4 playable 2022-09-10 13:31:10
1951 010037501F864000 Mute Crimson DX ingame 2026-05-13 18:32:12
1952 0100161009E5C000 MX Nitro: Unleashed playable 2022-09-27 22:34:33
1953 0100218011E7E000 MX vs ATV All Out nvdec;UE4;vulkan-backend-bug playable 2022-10-25 19:51:46
1954 0100D940063A0000 MXGP3 - The Official Motocross Videogame UE4;gpu;nvdec ingame 2020-12-16 14:00:20
2272 010086F0064CE000 Poi: Explorer Edition nvdec playable 2021-01-21 19:32:00
2273 0100EB6012FD2000 Poison Control playable 2021-05-16 14:01:54
2274 010072400E04A000 Pokémon Café ReMix playable 2021-08-17 20:00:04
2275 01005B7008C52800 Pokémon Champions Needs Update;services;online-broke menus 2026-05-13 18:32:12
2276 010008c01e742000 Pokémon Friends crash;services menus 2025-07-24 13:32:00
2277 01003D200BAA2000 Pokémon Mystery Dungeon™: Rescue Team DX mac-bug playable 2024-01-21 00:16:32
2278 01008DB008C2C000 Pokémon Shield + Pokémon Shield Expansion Pass deadlock;crash;online-broken;ldn-works;LAN ingame 2024-08-12 07:20:22
2280 01009AD008C4C000 Pokémon: Let's Go, Pikachu! demo slow;demo playable 2023-11-26 11:23:20
2281 0100000011D90000 Pokémon™ Brilliant Diamond gpu;ldn-works ingame 2024-08-28 13:26:35
2282 010018E011D92000 Pokémon™ Shining Pearl gpu;ldn-works ingame 2024-08-28 13:26:35
2283 100554023408000 Pokémon FireRed Version crashes nothing 2026-05-13 18:32:12
2284 010034D02340E000 Pokémon LeafGreen Version crashes nothing 2026-05-13 18:32:12
2285 010015F008C54000 Pokémon™ HOME Needs Update;crash;services menus 2020-12-06 06:01:51
2286 01001F5010DFA000 Pokémon™ Legends: Arceus gpu;Needs Update;ldn-works ingame 2024-09-19 10:02:02
2287 0100F43008C44000 Pokémon™ Legends: Z-A gpu;crash;ldn-works ingame 2025-11-16 00:30:00
2873 0100277011F1A000 Super Mario Bros.™ 35 online-broken menus 2022-08-07 16:27:25
2874 010015100B514000 Super Mario Bros.™ Wonder amd-vendor-bug playable 2024-09-06 13:21:21
2875 01009B90006DC000 Super Mario Maker™ 2 online-broken;ldn-broken playable 2024-08-25 11:05:19
2876 0100000000010000 Super Mario Odyssey™ nvdec;intel-vendor-bug;mac-bug nvdec;intel-vendor-bug;mac-bug;amd-vendor-bug playable 2024-08-25 01:32:34 2026-05-13 18:32:12
2877 010036B0034E4000 Super Mario Party™ gpu;Needs Update;ldn-works ingame 2024-06-21 05:10:16
2878 0100965017338000 Super Mario Party Jamboree mac-bug;gpu ingame 2025-02-17 02:09:20
2879 0100BC0018138000 Super Mario RPG™ gpu;audio;nvdec ingame 2024-06-19 17:43:42
3170 0100E2E00CB14000 Tokyo School Life playable 2022-09-16 20:25:54
3171 010024601BB16000 Tomb Raider I-III Remastered Starring Lara Croft gpu;opengl ingame 2024-09-27 12:32:04
3172 0100D7F01E49C000 Tomba! Special Edition services-horizon nothing 2024-09-15 21:59:54
3173 010051F0207B2000 Tomodachi Life: Living the Dream amd-vendor-bug;gpu;intel-vendor-bug;ldn-broken ingame 2026-05-13 18:32:12
3174 0100CA502552A000 Tomodachi Life: Living the Dream – Welcome Edtion amd-vendor-bug;demo playable 2026-05-13 18:32:12
3175 0100D400100F8000 Tonight We Riot playable 2021-02-26 15:55:09
3176 0100CC00102B4000 Tony Hawk's™ Pro Skater™ 1 + 2 gpu;Needs Update ingame 2024-09-24 08:18:14
3177 010093F00E818000 Tools Up! crash ingame 2020-07-21 12:58:17

View File

@@ -59,6 +59,7 @@ namespace Ryujinx.Common
//Mario Franchise //Mario Franchise
"010021d00812a000", // Arcade Archives VS. SUPER MARIO BROS. "010021d00812a000", // Arcade Archives VS. SUPER MARIO BROS.
"01007fe0221d8000", // Hello, Mario!
"01006d0017f7a000", // Mario & Luigi: Brothership "01006d0017f7a000", // Mario & Luigi: Brothership
"010003000e146000", // Mario & Sonic at the Olympic Games Tokyo 2020 "010003000e146000", // Mario & Sonic at the Olympic Games Tokyo 2020
"010067300059a000", // Mario + Rabbids: Kingdom Battle "010067300059a000", // Mario + Rabbids: Kingdom Battle
@@ -70,6 +71,9 @@ namespace Ryujinx.Common
"0100bde00862a000", // Mario Tennis Aces "0100bde00862a000", // Mario Tennis Aces
"0100b99019412000", // Mario vs. Donkey Kong "0100b99019412000", // Mario vs. Donkey Kong
"010049900f546000", // Super Mario 3D All-Stars "010049900f546000", // Super Mario 3D All-Stars
"010049900f546001", // Super Mario 3D All-Stars | Super Mario 64
"010049900f546002", // Super Mario 3D All-Stars | Super Mario Sunshine
"010049900f546003", // Super Mario 3D All-Stars | Super Mario Galaxy
"010028600ebda000", // Super Mario 3D World + Bowser's Fury "010028600ebda000", // Super Mario 3D World + Bowser's Fury
"010049900F546001", // Super Mario 64 "010049900F546001", // Super Mario 64
"0100ea80032ea000", // Super Mario Bros. U Deluxe "0100ea80032ea000", // Super Mario Bros. U Deluxe
@@ -107,6 +111,11 @@ namespace Ryujinx.Common
"0100187003a36000", // Pokémon: Let's Go Eevee! "0100187003a36000", // Pokémon: Let's Go Eevee!
"010003f003a34000", // Pokémon: Let's Go Pikachu! "010003f003a34000", // Pokémon: Let's Go Pikachu!
"0100f43008c44000", // Pokémon Legends: Z-A "0100f43008c44000", // Pokémon Legends: Z-A
"0100554023408000", // Pokémon FireRed Version (EN)
"01006fa0233f8000", // Pokémon FireRed Version (JP)
"0100fd6023430000", // Pokémon LeafGreen Version (DE)
"0100f1e0233fa000", // Pokémon LeafGreen Version (JP)
"01005b7008c52000", // Pokémon Champions
//Splatoon Franchise //Splatoon Franchise
"0100f8f0000a2000", // Splatoon 2 (EU) "0100f8f0000a2000", // Splatoon 2 (EU)
@@ -116,13 +125,14 @@ namespace Ryujinx.Common
"0100ba0018500000", // Splatoon 3: Splatfest World Premiere "0100ba0018500000", // Splatoon 3: Splatfest World Premiere
//NSO Membership games //NSO Membership games
"0100d870045b6000", // NES - Nintendo Switch Online
"01008d300c50c000", // SNES - Nintendo Switch Online
"0100c62011050000", // GB - Nintendo Switch Online "0100c62011050000", // GB - Nintendo Switch Online
"010012f017576000", // GBA - Nintendo Switch Online "010012f017576000", // GBA - Nintendo Switch Online
"0100c9a00ece6000", // N64 - Nintendo Switch Online "0100c9a00ece6000", // N64 - Nintendo Switch Online
"0100e0601c632000", // N64 - Nintendo Switch Online 18+ "0100e0601c632000", // N64 - Nintendo Switch Online 18+
"0100d870045b6000", // NES - Nintendo Switch Online
"0100b3c014bda000", // SEGA Genesis - Nintendo Switch Online "0100b3c014bda000", // SEGA Genesis - Nintendo Switch Online
"01008d300c50c000", // SNES - Nintendo Switch Online "0100bfc01d976000", // Virtual Boy - Nintendo Switch Online
"0100ccf019c8c000", // F-ZERO 99 "0100ccf019c8c000", // F-ZERO 99
"0100ad9012510000", // PAC-MAN 99 "0100ad9012510000", // PAC-MAN 99
"010040600c5ce000", // Tetris 99 "010040600c5ce000", // Tetris 99
@@ -141,6 +151,8 @@ namespace Ryujinx.Common
"0100704000B3A000", // Snipperclips "0100704000B3A000", // Snipperclips
"01006a800016e000", // Super Smash Bros. Ultimate "01006a800016e000", // Super Smash Bros. Ultimate
"0100a9400c9c2000", // Tokyo Mirage Sessions #FE Encore "0100a9400c9c2000", // Tokyo Mirage Sessions #FE Encore
"0100ca502552a000", // Tomodachi Life: Living the Dream - Welcome Edition
"010051f0207b2000", // Tomodachi Life: Living the Dream
//Bayonetta Franchise //Bayonetta Franchise
"010076f0049a2000", // Bayonetta "010076f0049a2000", // Bayonetta
@@ -148,6 +160,9 @@ namespace Ryujinx.Common
"01004a4010fea000", // Bayonetta 3 "01004a4010fea000", // Bayonetta 3
"0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon "0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon
// Famicom Detective Club Franchise
"010054601d54c000", // Emio - The Smiling Man: Famicom Detective Series (DEMO)
//Persona Franchise //Persona Franchise
"0100dcd01525a000", // Persona 3 Portable "0100dcd01525a000", // Persona 3 Portable
"010075a016a3a000", // Persona 4 Arena Ultimax "010075a016a3a000", // Persona 4 Arena Ultimax
@@ -171,7 +186,9 @@ namespace Ryujinx.Common
"0100453019aa8000", // Xenoblade Chronicles: X Definitive Edition "0100453019aa8000", // Xenoblade Chronicles: X Definitive Edition
//Misc Games //Misc Games
"01003670066de000", // 36 Fragments of Midnight
"010056e00853a000", // A Hat in Time "010056e00853a000", // A Hat in Time
"0100c9f00aaee000", // Ascendence
"0100fd1014726000", // Baldurs Gate: Dark Alliance "0100fd1014726000", // Baldurs Gate: Dark Alliance
"01008c2019598000", // Bluey: The Video Game "01008c2019598000", // Bluey: The Video Game
"010096f00ff22000", // Borderlands 2: Game of the Year Edition "010096f00ff22000", // Borderlands 2: Game of the Year Edition
@@ -185,8 +202,10 @@ namespace Ryujinx.Common
"010027400cdc6000", // Divinity Original 2 - Definitive Edition "010027400cdc6000", // Divinity Original 2 - Definitive Edition
"01008c8012920000", // Dying Light Platinum Edition "01008c8012920000", // Dying Light Platinum Edition
"0100d11013e6a000", // Eschatos "0100d11013e6a000", // Eschatos
"01000490067ae000", // Frederic 2: Evil Strikes Back
"01001cc01b2d4000", // Goat Simulator 3 "01001cc01b2d4000", // Goat Simulator 3
"01003620068ea000", // Hand of Fate 2 "01003620068ea000", // Hand of Fate 2
"01007ac00e012000", // HEXAGRAVITY
"0100f7e00c70e000", // Hogwarts Legacy "0100f7e00c70e000", // Hogwarts Legacy
"010013c00e930000", // Hollow Knight: Silksong "010013c00e930000", // Hollow Knight: Silksong
"010085500130a000", // Lego City: Undercover "010085500130a000", // Lego City: Undercover
@@ -196,6 +215,7 @@ namespace Ryujinx.Common
"0100853015e86000", // No Man's Sky "0100853015e86000", // No Man's Sky
"0100f85014ed0000", // No More Heroes "0100f85014ed0000", // No More Heroes
"0100463014ed4000", // No More Heroes 2 "0100463014ed4000", // No More Heroes 2
"0100f7d00a1bc000", // NO THING
"0100e570094e8000", // Owlboy "0100e570094e8000", // Owlboy
"01007bb017812000", // Portal "01007bb017812000", // Portal
"0100abd01785c000", // Portal 2 "0100abd01785c000", // Portal 2
@@ -204,11 +224,14 @@ namespace Ryujinx.Common
"01008e200c5c2000", // Muse Dash "01008e200c5c2000", // Muse Dash
"01005ff002e2a000", // Rayman Legends "01005ff002e2a000", // Rayman Legends
"01007820196a6000", // Red Dead Redemption "01007820196a6000", // Red Dead Redemption
"01007a800d520000", // REFUNCT
"0100e8300a67a000", // Risk "0100e8300a67a000", // Risk
"01002f7013224000", // Rune Factory 5 "01002f7013224000", // Rune Factory 5
"01008d100d43e000", // Saints Row IV "01008d100d43e000", // Saints Row IV
"0100de600beee000", // Saints Row: The Third - The Full Package "0100de600beee000", // Saints Row: The Third - The Full Package
"01001180021fa000", // Shovel Knight: Specter of Torment "01001180021fa000", // Shovel Knight: Specter of Torment
"010079f00671c000", // Sparkle 2: Evo
"010077b00e046000", // Spyro: Reignited Trilogy
"0100e1D01eb2e000", // Squeakross: Home Squeak Home "0100e1D01eb2e000", // Squeakross: Home Squeak Home
"0100e65002bb8000", // Stardew Valley "0100e65002bb8000", // Stardew Valley
"0100d7a01b7a2000", // Star Wars: Bounty Hunter "0100d7a01b7a2000", // Star Wars: Bounty Hunter

View File

@@ -42,6 +42,7 @@ namespace Ryujinx.Graphics.GAL
public readonly bool SupportsShaderBallot; public readonly bool SupportsShaderBallot;
public readonly bool SupportsShaderBarrierDivergence; public readonly bool SupportsShaderBarrierDivergence;
public readonly bool SupportsShaderFloat64; public readonly bool SupportsShaderFloat64;
public readonly bool SupportsShaderNonUniformIndexing;
public readonly bool SupportsTextureGatherOffsets; public readonly bool SupportsTextureGatherOffsets;
public readonly bool SupportsTextureShadowLod; public readonly bool SupportsTextureShadowLod;
public readonly bool SupportsVertexStoreAndAtomics; public readonly bool SupportsVertexStoreAndAtomics;
@@ -110,6 +111,7 @@ namespace Ryujinx.Graphics.GAL
bool supportsShaderBallot, bool supportsShaderBallot,
bool supportsShaderBarrierDivergence, bool supportsShaderBarrierDivergence,
bool supportsShaderFloat64, bool supportsShaderFloat64,
bool supportsShaderNonUniformIndexing,
bool supportsTextureGatherOffsets, bool supportsTextureGatherOffsets,
bool supportsTextureShadowLod, bool supportsTextureShadowLod,
bool supportsVertexStoreAndAtomics, bool supportsVertexStoreAndAtomics,
@@ -172,6 +174,7 @@ namespace Ryujinx.Graphics.GAL
SupportsShaderBallot = supportsShaderBallot; SupportsShaderBallot = supportsShaderBallot;
SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence; SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence;
SupportsShaderFloat64 = supportsShaderFloat64; SupportsShaderFloat64 = supportsShaderFloat64;
SupportsShaderNonUniformIndexing = supportsShaderNonUniformIndexing;
SupportsTextureGatherOffsets = supportsTextureGatherOffsets; SupportsTextureGatherOffsets = supportsTextureGatherOffsets;
SupportsTextureShadowLod = supportsTextureShadowLod; SupportsTextureShadowLod = supportsTextureShadowLod;
SupportsVertexStoreAndAtomics = supportsVertexStoreAndAtomics; SupportsVertexStoreAndAtomics = supportsVertexStoreAndAtomics;

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2; private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 7353; private const uint CodeGenVersion = 7354;
private const string SharedTocFileName = "shared.toc"; private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";

View File

@@ -231,6 +231,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
public bool QueryHostSupportsShaderFloat64() => _context.Capabilities.SupportsShaderFloat64; public bool QueryHostSupportsShaderFloat64() => _context.Capabilities.SupportsShaderFloat64;
public bool QueryHostSupportsShaderNonUniformIndexing() => _context.Capabilities.SupportsShaderNonUniformIndexing;
public bool QueryHostSupportsSnormBufferTextureFormat() => _context.Capabilities.SupportsSnormBufferTextureFormat; public bool QueryHostSupportsSnormBufferTextureFormat() => _context.Capabilities.SupportsSnormBufferTextureFormat;
public bool QueryHostSupportsTextureGatherOffsets() => _context.Capabilities.SupportsTextureGatherOffsets; public bool QueryHostSupportsTextureGatherOffsets() => _context.Capabilities.SupportsTextureGatherOffsets;

View File

@@ -184,6 +184,7 @@ namespace Ryujinx.Graphics.OpenGL
supportsShaderBallot: HwCapabilities.SupportsShaderBallot, supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
supportsShaderBarrierDivergence: !(intelWindows || intelUnix), supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
supportsShaderFloat64: true, supportsShaderFloat64: true,
supportsShaderNonUniformIndexing: false,
supportsTextureGatherOffsets: true, supportsTextureGatherOffsets: true,
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod, supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
supportsVertexStoreAndAtomics: true, supportsVertexStoreAndAtomics: true,

View File

@@ -82,6 +82,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
public bool IsMainFunction { get; private set; } public bool IsMainFunction { get; private set; }
public bool MayHaveReturned { get; set; } public bool MayHaveReturned { get; set; }
public bool WasNonUniformAccessDeclared { get; set; }
public CodeGenContext( public CodeGenContext(
StructuredProgramInfo info, StructuredProgramInfo info,
@@ -89,6 +90,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
GeneratorPool<Instruction> instPool, GeneratorPool<Instruction> instPool,
GeneratorPool<LiteralInteger> integerPool) : base(SpirvVersionPacked, instPool, integerPool) GeneratorPool<LiteralInteger> integerPool) : base(SpirvVersionPacked, instPool, integerPool)
{ {
WasNonUniformAccessDeclared = false;
Info = info; Info = info;
AttributeUsage = parameters.AttributeUsage; AttributeUsage = parameters.AttributeUsage;
Definitions = parameters.Definitions; Definitions = parameters.Definitions;

View File

@@ -587,6 +587,23 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
return OperationResult.Invalid; return OperationResult.Invalid;
} }
private static void MarkNonUniform(CodeGenContext context, SpvInstruction inst)
{
if (context.HostCapabilities.SupportsShaderNonUniformIndexing)
{
if (!context.WasNonUniformAccessDeclared)
{
context.AddExtension("SPV_EXT_descriptor_indexing");
context.AddCapability(Capability.ShaderNonUniform);
context.AddCapability(Capability.SampledImageArrayNonUniformIndexing);
context.AddCapability(Capability.StorageImageArrayNonUniformIndexing);
}
context.Decorate(inst, Decoration.NonUniform);
context.WasNonUniformAccessDeclared = true;
}
}
private static OperationResult GenerateImageAtomic(CodeGenContext context, AstOperation operation) private static OperationResult GenerateImageAtomic(CodeGenContext context, AstOperation operation)
{ {
AstTextureOperation texOp = (AstTextureOperation)operation; AstTextureOperation texOp = (AstTextureOperation)operation;
@@ -613,6 +630,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
SpvInstruction textureIndex = Src(AggregateType.S32); SpvInstruction textureIndex = Src(AggregateType.S32);
image = context.AccessChain(imagePointerType, image, textureIndex); image = context.AccessChain(imagePointerType, image, textureIndex);
MarkNonUniform(context, image);
} }
int coordsCount = texOp.Type.Dimensions; int coordsCount = texOp.Type.Dimensions;
@@ -683,15 +701,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
ImageDeclaration declaration = context.Images[texOp.GetTextureSetAndBinding()]; ImageDeclaration declaration = context.Images[texOp.GetTextureSetAndBinding()];
SpvInstruction image = declaration.Image; SpvInstruction image = declaration.Image;
bool isIndexed = declaration.IsIndexed;
if (declaration.IsIndexed) if (isIndexed)
{ {
SpvInstruction textureIndex = Src(AggregateType.S32); SpvInstruction textureIndex = Src(AggregateType.S32);
image = context.AccessChain(declaration.ImagePointerType, image, textureIndex); image = context.AccessChain(declaration.ImagePointerType, image, textureIndex);
MarkNonUniform(context, image);
} }
image = context.Load(declaration.ImageType, image); image = context.Load(declaration.ImageType, image);
if (isIndexed)
{
MarkNonUniform(context, image);
}
int coordsCount = texOp.Type.Dimensions; int coordsCount = texOp.Type.Dimensions;
@@ -740,15 +764,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
ImageDeclaration declaration = context.Images[texOp.GetTextureSetAndBinding()]; ImageDeclaration declaration = context.Images[texOp.GetTextureSetAndBinding()];
SpvInstruction image = declaration.Image; SpvInstruction image = declaration.Image;
bool isIndexed = declaration.IsIndexed;
if (declaration.IsIndexed) if (isIndexed)
{ {
SpvInstruction textureIndex = Src(AggregateType.S32); SpvInstruction textureIndex = Src(AggregateType.S32);
image = context.AccessChain(declaration.ImagePointerType, image, textureIndex); image = context.AccessChain(declaration.ImagePointerType, image, textureIndex);
MarkNonUniform(context, image);
} }
image = context.Load(declaration.ImageType, image); image = context.Load(declaration.ImageType, image);
if (isIndexed)
{
MarkNonUniform(context, image);
}
int coordsCount = texOp.Type.Dimensions; int coordsCount = texOp.Type.Dimensions;
@@ -1878,35 +1908,56 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
private static SpvInstruction GenerateSampledImageLoad(CodeGenContext context, AstTextureOperation texOp, SamplerDeclaration declaration, ref int srcIndex) private static SpvInstruction GenerateSampledImageLoad(CodeGenContext context, AstTextureOperation texOp, SamplerDeclaration declaration, ref int srcIndex)
{ {
SpvInstruction image = declaration.Image; SpvInstruction image = declaration.Image;
bool imageIndexed = declaration.IsIndexed;
if (declaration.IsIndexed) if (imageIndexed)
{ {
SpvInstruction textureIndex = context.Get(AggregateType.S32, texOp.GetSource(srcIndex++)); SpvInstruction textureIndex = context.Get(AggregateType.S32, texOp.GetSource(srcIndex++));
image = context.AccessChain(declaration.SampledImagePointerType, image, textureIndex); image = context.AccessChain(declaration.SampledImagePointerType, image, textureIndex);
MarkNonUniform(context, image);
} }
if (texOp.IsSeparate) if (texOp.IsSeparate)
{ {
image = context.Load(declaration.ImageType, image); image = context.Load(declaration.ImageType, image);
if (imageIndexed)
{
MarkNonUniform(context, image);
}
SamplerDeclaration samplerDeclaration = context.Samplers[texOp.GetSamplerSetAndBinding()]; SamplerDeclaration samplerDeclaration = context.Samplers[texOp.GetSamplerSetAndBinding()];
SpvInstruction sampler = samplerDeclaration.Image; SpvInstruction sampler = samplerDeclaration.Image;
bool samplerIndexed = samplerDeclaration.IsIndexed;
if (samplerDeclaration.IsIndexed) if (samplerIndexed)
{ {
SpvInstruction samplerIndex = context.Get(AggregateType.S32, texOp.GetSource(srcIndex++)); SpvInstruction samplerIndex = context.Get(AggregateType.S32, texOp.GetSource(srcIndex++));
sampler = context.AccessChain(samplerDeclaration.SampledImagePointerType, sampler, samplerIndex); sampler = context.AccessChain(samplerDeclaration.SampledImagePointerType, sampler, samplerIndex);
MarkNonUniform(context, sampler);
} }
sampler = context.Load(samplerDeclaration.ImageType, sampler); sampler = context.Load(samplerDeclaration.ImageType, sampler);
if (samplerIndexed)
{
MarkNonUniform(context, sampler);
}
image = context.SampledImage(declaration.SampledImageType, image, sampler); image = context.SampledImage(declaration.SampledImageType, image, sampler);
if (imageIndexed || samplerIndexed)
{
MarkNonUniform(context, image);
}
} }
else else
{ {
image = context.Load(declaration.SampledImageType, image); image = context.Load(declaration.SampledImageType, image);
if (imageIndexed)
{
MarkNonUniform(context, image);
}
} }
return image; return image;

View File

@@ -336,6 +336,10 @@ namespace Ryujinx.Graphics.Shader
{ {
return true; return true;
} }
bool QueryHostSupportsShaderNonUniformIndexing()
{
return false;
}
/// <summary> /// <summary>
/// Queries host GPU support for signed normalized buffer texture formats. /// Queries host GPU support for signed normalized buffer texture formats.

View File

@@ -9,6 +9,7 @@ namespace Ryujinx.Graphics.Shader.Translation
public readonly bool SupportsShaderBallot; public readonly bool SupportsShaderBallot;
public readonly bool SupportsShaderBarrierDivergence; public readonly bool SupportsShaderBarrierDivergence;
public readonly bool SupportsShaderFloat64; public readonly bool SupportsShaderFloat64;
public readonly bool SupportsShaderNonUniformIndexing;
public readonly bool SupportsTextureShadowLod; public readonly bool SupportsTextureShadowLod;
public readonly bool SupportsViewportMask; public readonly bool SupportsViewportMask;
@@ -20,6 +21,7 @@ namespace Ryujinx.Graphics.Shader.Translation
bool supportsShaderBallot, bool supportsShaderBallot,
bool supportsShaderBarrierDivergence, bool supportsShaderBarrierDivergence,
bool supportsShaderFloat64, bool supportsShaderFloat64,
bool supportsShaderNonUniformIndexing,
bool supportsTextureShadowLod, bool supportsTextureShadowLod,
bool supportsViewportMask) bool supportsViewportMask)
{ {
@@ -30,6 +32,7 @@ namespace Ryujinx.Graphics.Shader.Translation
SupportsShaderBallot = supportsShaderBallot; SupportsShaderBallot = supportsShaderBallot;
SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence; SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence;
SupportsShaderFloat64 = supportsShaderFloat64; SupportsShaderFloat64 = supportsShaderFloat64;
SupportsShaderNonUniformIndexing = supportsShaderNonUniformIndexing;
SupportsTextureShadowLod = supportsTextureShadowLod; SupportsTextureShadowLod = supportsTextureShadowLod;
SupportsViewportMask = supportsViewportMask; SupportsViewportMask = supportsViewportMask;
} }

View File

@@ -364,6 +364,7 @@ namespace Ryujinx.Graphics.Shader.Translation
GpuAccessor.QueryHostSupportsShaderBallot(), GpuAccessor.QueryHostSupportsShaderBallot(),
GpuAccessor.QueryHostSupportsShaderBarrierDivergence(), GpuAccessor.QueryHostSupportsShaderBarrierDivergence(),
GpuAccessor.QueryHostSupportsShaderFloat64(), GpuAccessor.QueryHostSupportsShaderFloat64(),
GpuAccessor.QueryHostSupportsShaderNonUniformIndexing(),
GpuAccessor.QueryHostSupportsTextureShadowLod(), GpuAccessor.QueryHostSupportsTextureShadowLod(),
GpuAccessor.QueryHostSupportsViewportMask()); GpuAccessor.QueryHostSupportsViewportMask());

View File

@@ -46,7 +46,14 @@ namespace Ryujinx.Graphics.Vulkan
public static (AccessFlags Access, PipelineStageFlags Stages) GetSubpassAccessSuperset(VulkanRenderer gd) public static (AccessFlags Access, PipelineStageFlags Stages) GetSubpassAccessSuperset(VulkanRenderer gd)
{ {
AccessFlags access = BufferAccess; AccessFlags access = BufferAccess |
AccessFlags.ShaderReadBit |
AccessFlags.ShaderWriteBit |
AccessFlags.ColorAttachmentReadBit |
AccessFlags.ColorAttachmentWriteBit |
AccessFlags.DepthStencilAttachmentReadBit |
AccessFlags.DepthStencilAttachmentWriteBit;
PipelineStageFlags stages = PipelineStageFlags.AllGraphicsBit; PipelineStageFlags stages = PipelineStageFlags.AllGraphicsBit;
if (gd.TransformFeedbackApi != null) if (gd.TransformFeedbackApi != null)

View File

@@ -15,6 +15,8 @@ namespace Ryujinx.Graphics.Vulkan
Image dstImage, Image dstImage,
TextureCreateInfo srcInfo, TextureCreateInfo srcInfo,
TextureCreateInfo dstInfo, TextureCreateInfo dstInfo,
TextureCreateInfo srcStorageInfo,
TextureCreateInfo dstStorageInfo,
Extents2D srcRegion, Extents2D srcRegion,
Extents2D dstRegion, Extents2D dstRegion,
int srcLayer, int srcLayer,
@@ -40,6 +42,13 @@ namespace Ryujinx.Graphics.Vulkan
return (xy1, xy2); return (xy1, xy2);
} }
static (Offset3D, Offset3D) ClampOffsetsToMip(Offset3D xy1, Offset3D xy2, int mipW, int mipH)
{
return (
new Offset3D(Math.Min(xy1.X, mipW), Math.Min(xy1.Y, mipH), xy1.Z),
new Offset3D(Math.Min(xy2.X, mipW), Math.Min(xy2.Y, mipH), xy2.Z));
}
if (srcAspectFlags == 0) if (srcAspectFlags == 0)
{ {
srcAspectFlags = srcInfo.Format.ConvertAspectFlags(); srcAspectFlags = srcInfo.Format.ConvertAspectFlags();
@@ -80,6 +89,14 @@ namespace Ryujinx.Graphics.Vulkan
(srcOffsets.Element0, srcOffsets.Element1) = ExtentsToOffset3D(srcRegion, srcInfo.Width, srcInfo.Height, level); (srcOffsets.Element0, srcOffsets.Element1) = ExtentsToOffset3D(srcRegion, srcInfo.Width, srcInfo.Height, level);
(dstOffsets.Element0, dstOffsets.Element1) = ExtentsToOffset3D(dstRegion, dstInfo.Width, dstInfo.Height, level); (dstOffsets.Element0, dstOffsets.Element1) = ExtentsToOffset3D(dstRegion, dstInfo.Width, dstInfo.Height, level);
int srcMipW = Math.Max(1, srcStorageInfo.Width >> (int)copySrcLevel);
int srcMipH = Math.Max(1, srcStorageInfo.Height >> (int)copySrcLevel);
int dstMipW = Math.Max(1, dstStorageInfo.Width >> (int)copyDstLevel);
int dstMipH = Math.Max(1, dstStorageInfo.Height >> (int)copyDstLevel);
(srcOffsets.Element0, srcOffsets.Element1) = ClampOffsetsToMip(srcOffsets.Element0, srcOffsets.Element1, srcMipW, srcMipH);
(dstOffsets.Element0, dstOffsets.Element1) = ClampOffsetsToMip(dstOffsets.Element0, dstOffsets.Element1, dstMipW, dstMipH);
ImageBlit region = new() ImageBlit region = new()
{ {
SrcSubresource = srcSl, SrcSubresource = srcSl,
@@ -121,6 +138,8 @@ namespace Ryujinx.Graphics.Vulkan
Image dstImage, Image dstImage,
TextureCreateInfo srcInfo, TextureCreateInfo srcInfo,
TextureCreateInfo dstInfo, TextureCreateInfo dstInfo,
TextureCreateInfo srcStorageInfo,
TextureCreateInfo dstStorageInfo,
int srcViewLayer, int srcViewLayer,
int dstViewLayer, int dstViewLayer,
int srcViewLevel, int srcViewLevel,
@@ -151,6 +170,8 @@ namespace Ryujinx.Graphics.Vulkan
dstImage, dstImage,
srcInfo, srcInfo,
dstInfo, dstInfo,
srcStorageInfo,
dstStorageInfo,
srcViewLayer, srcViewLayer,
dstViewLayer, dstViewLayer,
srcViewLevel, srcViewLevel,
@@ -186,6 +207,8 @@ namespace Ryujinx.Graphics.Vulkan
Image dstImage, Image dstImage,
TextureCreateInfo srcInfo, TextureCreateInfo srcInfo,
TextureCreateInfo dstInfo, TextureCreateInfo dstInfo,
TextureCreateInfo srcStorageInfo,
TextureCreateInfo dstStorageInfo,
int srcViewLayer, int srcViewLayer,
int dstViewLayer, int dstViewLayer,
int srcViewLevel, int srcViewLevel,
@@ -314,6 +337,14 @@ namespace Ryujinx.Graphics.Vulkan
int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width; int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width;
int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height; int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height;
int srcMipW = Math.Max(1, srcStorageInfo.Width >> (srcViewLevel + srcLevel + level));
int srcMipH = Math.Max(1, srcStorageInfo.Height >> (srcViewLevel + srcLevel + level));
int dstMipW = Math.Max(1, dstStorageInfo.Width >> (dstViewLevel + dstLevel + level));
int dstMipH = Math.Max(1, dstStorageInfo.Height >> (dstViewLevel + dstLevel + level));
copyWidth = Math.Min(copyWidth, Math.Min(srcMipW, dstMipW));
copyHeight = Math.Min(copyHeight, Math.Min(srcMipH, dstMipH));
Extent3D extent = new((uint)copyWidth, (uint)copyHeight, (uint)srcDepth); Extent3D extent = new((uint)copyWidth, (uint)copyHeight, (uint)srcDepth);
if (srcInfo.Samples > 1 && srcInfo.Samples != dstInfo.Samples) if (srcInfo.Samples > 1 && srcInfo.Samples != dstInfo.Samples)

View File

@@ -67,6 +67,8 @@ namespace Ryujinx.Graphics.Vulkan
public VkFormat VkFormat { get; } public VkFormat VkFormat { get; }
public ImageUsageFlags UsageFlags { get; }
public unsafe TextureStorage( public unsafe TextureStorage(
VulkanRenderer gd, VulkanRenderer gd,
Device device, Device device,
@@ -93,7 +95,8 @@ namespace Ryujinx.Graphics.Vulkan
SampleCountFlags sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples); SampleCountFlags sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
ImageUsageFlags usage = GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, true); ImageUsageFlags usage = GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported);
UsageFlags = usage;
ImageCreateFlags flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit; ImageCreateFlags flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit;
@@ -159,7 +162,7 @@ namespace Ryujinx.Graphics.Vulkan
_imageAuto = new Auto<DisposableImage>(new DisposableImage(_gd.Api, device, _image)); _imageAuto = new Auto<DisposableImage>(new DisposableImage(_gd.Api, device, _image));
InitialTransition(ImageLayout.Preinitialized, ImageLayout.General); InitialTransition(ImageLayout.Undefined, ImageLayout.General);
} }
_slices = new TextureSliceInfo[levels * _depthOrLayers]; _slices = new TextureSliceInfo[levels * _depthOrLayers];
@@ -307,7 +310,7 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
public static ImageUsageFlags GetImageUsage(Format format, in HardwareCapabilities capabilities, bool isMsImageStorageSupported, bool extendedUsage) public static ImageUsageFlags GetImageUsage(Format format, in HardwareCapabilities capabilities, bool isMsImageStorageSupported)
{ {
ImageUsageFlags usage = DefaultUsageFlags; ImageUsageFlags usage = DefaultUsageFlags;
@@ -320,7 +323,7 @@ namespace Ryujinx.Graphics.Vulkan
usage |= ImageUsageFlags.ColorAttachmentBit; usage |= ImageUsageFlags.ColorAttachmentBit;
} }
if ((format.IsImageCompatible && isMsImageStorageSupported) || extendedUsage) if (format.IsImageCompatible && isMsImageStorageSupported)
{ {
usage |= ImageUsageFlags.StorageBit; usage |= ImageUsageFlags.StorageBit;
} }

View File

@@ -64,7 +64,7 @@ namespace Ryujinx.Graphics.Vulkan
bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample; bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample;
VkFormat format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported); VkFormat format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported);
ImageUsageFlags usage = TextureStorage.GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, false); ImageUsageFlags usage = TextureStorage.GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported) & storage.UsageFlags;
uint levels = (uint)info.Levels; uint levels = (uint)info.Levels;
uint layers = (uint)info.GetLayers(); uint layers = (uint)info.GetLayers();
@@ -133,6 +133,8 @@ namespace Ryujinx.Graphics.Vulkan
shaderUsage |= ImageUsageFlags.StorageBit; shaderUsage |= ImageUsageFlags.StorageBit;
} }
shaderUsage &= storage.UsageFlags;
_imageView = CreateImageView(componentMapping, subresourceRange, type, shaderUsage); _imageView = CreateImageView(componentMapping, subresourceRange, type, shaderUsage);
// Framebuffer attachments and storage images requires a identity component mapping. // Framebuffer attachments and storage images requires a identity component mapping.
@@ -257,6 +259,8 @@ namespace Ryujinx.Graphics.Vulkan
dstImage, dstImage,
src.Info, src.Info,
dst.Info, dst.Info,
src.Storage.Info,
dst.Storage.Info,
src.FirstLayer, src.FirstLayer,
dst.FirstLayer, dst.FirstLayer,
src.FirstLevel, src.FirstLevel,
@@ -310,6 +314,8 @@ namespace Ryujinx.Graphics.Vulkan
dstImage, dstImage,
src.Info, src.Info,
dst.Info, dst.Info,
src.Storage.Info,
dst.Storage.Info,
src.FirstLayer, src.FirstLayer,
dst.FirstLayer, dst.FirstLayer,
src.FirstLevel, src.FirstLevel,
@@ -385,6 +391,8 @@ namespace Ryujinx.Graphics.Vulkan
dst.GetImage().Get(cbs).Value, dst.GetImage().Get(cbs).Value,
src.Info, src.Info,
dst.Info, dst.Info,
src.Storage.Info,
dst.Storage.Info,
src.FirstLayer, src.FirstLayer,
dst.FirstLayer, dst.FirstLayer,
src.FirstLevel, src.FirstLevel,
@@ -410,6 +418,8 @@ namespace Ryujinx.Graphics.Vulkan
dst.GetImage().Get(cbs).Value, dst.GetImage().Get(cbs).Value,
src.Info, src.Info,
dst.Info, dst.Info,
src.Storage.Info,
dst.Storage.Info,
srcRegion, srcRegion,
dstRegion, dstRegion,
src.FirstLayer, src.FirstLayer,
@@ -463,6 +473,8 @@ namespace Ryujinx.Graphics.Vulkan
dstImage.Get(cbs).Value, dstImage.Get(cbs).Value,
src.Info, src.Info,
dst.Info, dst.Info,
src.Storage.Info,
dst.Storage.Info,
srcRegion, srcRegion,
dstRegion, dstRegion,
src.FirstLayer, src.FirstLayer,

View File

@@ -68,9 +68,7 @@ namespace Ryujinx.Graphics.Vulkan
int stride = (_stride + (alignment - 1)) & -alignment; int stride = (_stride + (alignment - 1)) & -alignment;
int newSize = (_size / _stride) * stride; int newSize = (_size / _stride) * stride;
Buffer buffer = autoBuffer.Get(cbs, 0, newSize).Value; updater.BindVertexBuffer(cbs, binding, autoBuffer, 0, newSize, (ulong)stride);
updater.BindVertexBuffer(cbs, binding, buffer, 0, (ulong)newSize, (ulong)stride);
_buffer = autoBuffer; _buffer = autoBuffer;
@@ -93,11 +91,7 @@ namespace Ryujinx.Graphics.Vulkan
if (autoBuffer != null) if (autoBuffer != null)
{ {
int offset = _offset; updater.BindVertexBuffer(cbs, binding, autoBuffer, _offset, _size, (ulong)_stride);
bool mirrorable = _size <= VertexBufferMaxMirrorable;
Buffer buffer = mirrorable ? autoBuffer.GetMirrorable(cbs, ref offset, _size, out _).Value : autoBuffer.Get(cbs, offset, _size).Value;
updater.BindVertexBuffer(cbs, binding, buffer, (ulong)offset, (ulong)_size, (ulong)_stride);
} }
} }

View File

@@ -15,6 +15,10 @@ namespace Ryujinx.Graphics.Vulkan
private readonly NativeArray<ulong> _sizes; private readonly NativeArray<ulong> _sizes;
private readonly NativeArray<ulong> _strides; private readonly NativeArray<ulong> _strides;
private readonly Auto<DisposableBuffer>[] _bufferAutos;
private readonly int[] _bufferOffsetsForGet;
private readonly int[] _bufferSizesForGet;
public VertexBufferUpdater(VulkanRenderer gd) public VertexBufferUpdater(VulkanRenderer gd)
{ {
_gd = gd; _gd = gd;
@@ -23,9 +27,13 @@ namespace Ryujinx.Graphics.Vulkan
_offsets = new NativeArray<ulong>(Constants.MaxVertexBuffers); _offsets = new NativeArray<ulong>(Constants.MaxVertexBuffers);
_sizes = new NativeArray<ulong>(Constants.MaxVertexBuffers); _sizes = new NativeArray<ulong>(Constants.MaxVertexBuffers);
_strides = new NativeArray<ulong>(Constants.MaxVertexBuffers); _strides = new NativeArray<ulong>(Constants.MaxVertexBuffers);
_bufferAutos = new Auto<DisposableBuffer>[Constants.MaxVertexBuffers];
_bufferOffsetsForGet = new int[Constants.MaxVertexBuffers];
_bufferSizesForGet = new int[Constants.MaxVertexBuffers];
} }
public void BindVertexBuffer(CommandBufferScoped cbs, uint binding, VkBuffer buffer, ulong offset, ulong size, ulong stride) public void BindVertexBuffer(CommandBufferScoped cbs, uint binding, Auto<DisposableBuffer> autoBuffer, int offset, int size, ulong stride)
{ {
if (_count == 0) if (_count == 0)
{ {
@@ -39,9 +47,11 @@ namespace Ryujinx.Graphics.Vulkan
int index = (int)_count; int index = (int)_count;
_buffers[index] = buffer; _bufferAutos[index] = autoBuffer;
_offsets[index] = offset; _bufferOffsetsForGet[index] = offset;
_sizes[index] = size; _bufferSizesForGet[index] = size;
_offsets[index] = (ulong)offset;
_sizes[index] = (ulong)size;
_strides[index] = stride; _strides[index] = stride;
_count++; _count++;
@@ -51,6 +61,12 @@ namespace Ryujinx.Graphics.Vulkan
{ {
if (_count != 0) if (_count != 0)
{ {
for (int i = 0; i < _count; i++)
{
_buffers[i] = _bufferAutos[i].Get(cbs, _bufferOffsetsForGet[i], _bufferSizesForGet[i]).Value;
_bufferAutos[i] = null;
}
if (_gd.Capabilities.SupportsExtendedDynamicState) if (_gd.Capabilities.SupportsExtendedDynamicState)
{ {
_gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2( _gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2(

View File

@@ -494,6 +494,8 @@ namespace Ryujinx.Graphics.Vulkan
UniformBufferStandardLayout = supportedPhysicalDeviceVulkan12Features.UniformBufferStandardLayout, UniformBufferStandardLayout = supportedPhysicalDeviceVulkan12Features.UniformBufferStandardLayout,
UniformAndStorageBuffer8BitAccess = supportedPhysicalDeviceVulkan12Features.UniformAndStorageBuffer8BitAccess, UniformAndStorageBuffer8BitAccess = supportedPhysicalDeviceVulkan12Features.UniformAndStorageBuffer8BitAccess,
StorageBuffer8BitAccess = supportedPhysicalDeviceVulkan12Features.StorageBuffer8BitAccess, StorageBuffer8BitAccess = supportedPhysicalDeviceVulkan12Features.StorageBuffer8BitAccess,
ShaderSampledImageArrayNonUniformIndexing = supportedPhysicalDeviceVulkan12Features.ShaderSampledImageArrayNonUniformIndexing,
ShaderStorageImageArrayNonUniformIndexing = supportedPhysicalDeviceVulkan12Features.ShaderStorageImageArrayNonUniformIndexing,
}; };
pExtendedFeatures = &featuresVk12; pExtendedFeatures = &featuresVk12;

View File

@@ -775,6 +775,9 @@ namespace Ryujinx.Graphics.Vulkan
supportsShaderBallot: false, supportsShaderBallot: false,
supportsShaderBarrierDivergence: Vendor != Vendor.Intel, supportsShaderBarrierDivergence: Vendor != Vendor.Intel,
supportsShaderFloat64: Capabilities.SupportsShaderFloat64, supportsShaderFloat64: Capabilities.SupportsShaderFloat64,
supportsShaderNonUniformIndexing:
featuresVk12.ShaderSampledImageArrayNonUniformIndexing &&
featuresVk12.ShaderStorageImageArrayNonUniformIndexing,
supportsTextureGatherOffsets: features2.Features.ShaderImageGatherExtended && !IsMoltenVk, supportsTextureGatherOffsets: features2.Features.ShaderImageGatherExtended && !IsMoltenVk,
supportsTextureShadowLod: false, supportsTextureShadowLod: false,
supportsVertexStoreAndAtomics: features2.Features.VertexPipelineStoresAndAtomics, supportsVertexStoreAndAtomics: features2.Features.VertexPipelineStoresAndAtomics,

View File

@@ -391,12 +391,12 @@ namespace Ryujinx.Graphics.Vulkan
{ {
if (_effect != null) if (_effect != null)
{ {
_gd.FlushAllCommands();
_gd.CommandBufferPool.Return( _gd.CommandBufferPool.Return(
cbs, cbs,
null, null,
[PipelineStageFlags.ColorAttachmentOutputBit], [PipelineStageFlags.ColorAttachmentOutputBit],
null); null);
_gd.FlushAllCommands();
cbs.GetFence().Wait(); cbs.GetFence().Wait();
cbs = _gd.CommandBufferPool.Rent(); cbs = _gd.CommandBufferPool.Rent();
} }
@@ -455,6 +455,8 @@ namespace Ryujinx.Graphics.Vulkan
ImageLayout.General, ImageLayout.General,
ImageLayout.PresentSrcKhr); ImageLayout.PresentSrcKhr);
_gd.FlushAllCommands();
_gd.CommandBufferPool.Return( _gd.CommandBufferPool.Return(
cbs, cbs,
[_imageAvailableSemaphores[semaphoreIndex]], [_imageAvailableSemaphores[semaphoreIndex]],

View File

@@ -1,4 +1,5 @@
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging;
using System; using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy
@@ -61,6 +62,19 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
return ResultCode.Success; return ResultCode.Success;
} }
[CommandCmif(10)]
// ExitProcessAndReturn -> nn::am::service::LibraryAppletInfo
public ResultCode ExitProcessAndReturn(ServiceCtx context)
{
// Exits the LibraryApplet and returns to running the title which launched this LibraryApplet (qlaunch for example).
// On success, official sw will enter an infinite loop with sleep-thread value 86400000000000.
// Since we don't currently support qlaunch, it's fine to stub it.
Logger.Stub?.PrintStub(LogClass.Service);
return ResultCode.Success;
}
[CommandCmif(11)] [CommandCmif(11)]
// GetLibraryAppletInfo() -> nn::am::service::LibraryAppletInfo // GetLibraryAppletInfo() -> nn::am::service::LibraryAppletInfo
public ResultCode GetLibraryAppletInfo(ServiceCtx context) public ResultCode GetLibraryAppletInfo(ServiceCtx context)
@@ -83,7 +97,8 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
AppletIdentifyInfo appletIdentifyInfo = new() AppletIdentifyInfo appletIdentifyInfo = new()
{ {
AppletId = AppletId.QLaunch, AppletId = AppletId.QLaunch,
TitleId = 0x0100000000001000, // 0x4 padding
TitleId = 0x0100000000001000, // qlaunch systemAppletMenu title ID
}; };
context.ResponseData.WriteStruct(appletIdentifyInfo); context.ResponseData.WriteStruct(appletIdentifyInfo);

View File

@@ -1,5 +1,6 @@
using Gommon; using Gommon;
using Humanizer; using Humanizer;
using MsgPack;
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Collections.Generic; using System.Collections.Generic;
@@ -23,24 +24,382 @@ namespace Ryujinx.Ava.Systems.PlayReport
private static FormattedValue SkywardSwordHD_Rupees(SingleValue value) private static FormattedValue SkywardSwordHD_Rupees(SingleValue value)
=> "rupee".ToQuantity(value.Matched.IntValue); => "rupee".ToQuantity(value.Matched.IntValue);
private static FormattedValue SuperMarioOdyssey_AssistMode(SingleValue value) private static FormattedValue EchoesOfWisdom_Warp(SingleValue value)
=> value.Matched.BoxedValue is 1 ? "Playing in Assist Mode" : "Playing in Regular Mode"; {
FormattedValue locations = value.Matched.IntValue switch
{
// Hyrule Field
23 => "Hyrule Field: Kakariko Village",
43 => "Hyrule Field: West of Hyrule Ranch",
45 => "Hyrule Field: North of Hyrule Ranch",
25 => "Hyrule Field: Hyrule Ranch",
26 => "Hyrule Field: West of Hyrule Castle",
48 => "Hyrule Field: Haunted Grove",
24 => "Hyrule Field: Hyrule Castle",
27 => "Hyrule Field: Northern Sanctuary",
28 => "Eastern Hyrule Field: Eastern Temple",
41 => "Eastern Hyrule Field: Dampé Studio",
22 => "Lake Hylia: Great Fairy Shrine",
// Eternal Forest
47 => "Eternal Forest: Entrance",
46 => "Eternal Forest: Great Deku Tree",
752 => "Eternal Forest: Stilled Ancient Ruins (Halfway Point)",
753 => "Eternal Forest: Stilled Ancient Ruins (Null)",
// Suthorn
33 => "Suthorn Prairie: Lueburry's House",
20 => "Suthorn Prairie: Suthorn Village",
21 => "Suthorn Forest: Suthorn Ruins",
// Faron Wetlands
13 => "Faron Wetlands: Entrance",
15 => "Faron Wetlands: Scrubton",
18 => "Faron Wetlands: Blossu's House",
17 => "Faron Wetlands: Heart Lake",
852 => "Faron Wetlands: Stilled Faron Wetlands",
601 => "Faron Wetlands: Faron Temple 3F",
602 => "Faron Wetlands: Faron Temple 2F (Underwater Entrance)",
603 => "Faron Wetlands: Faron Temple 2F (West Entrance)",
604 => "Faron Wetlands: Faron Temple 2F (Cliff Entrance)",
605 => "Faron Wetlands: Faron Temple 1F (Diababa)",
606 => "Faron Wetlands: Faron Temple 1F (Gohma)",
// Jabul Waters
11 => "Jabul Waters: River Zora Village",
9 => "Jabul Waters: Crossflows Plaza",
8 => "Jabul Waters: Seesyde Village",
12 => "Jabul Waters: Sea Zora Village",
10 => "Jabul Waters: Lord Jabu-Jabu's Den",
201 => "Jabul Waters: Jabul Ruins 1F (Entrance)",
202 => "Jabul Waters: Jabul Ruins 1F (Vocavor)",
// Gerudo Desert
40 => "Gerudo Desert: Entrance",
29 => "Gerudo Desert: Oasis",
32 => "Gerudo Desert: Ancestor's Cave Of Rest",
30 => "Gerudo Desert: Gerudo Town",
31 => "Gerudo Desert: Gerudo Sanctum",
351 => "Gerudo Desert: Stilled Gerudo Sanctum",
303 => "Gerudo Desert: Gerudo Sanctum 1F (West Entrance)",
304 => "Gerudo Desert: Gerudo Sanctum 1F (East Entrance)",
301 => "Gerudo Desert: Gerudo Sanctum 2F (The Key)",
302 => "Gerudo Desert: Gerudo Sanctum 2F (The Elephant Room)",
305 => "Gerudo Desert: Gerudo Sanctum 2F (Mogryph)",
// Eldin Volcano
4 => "Eldin Volcano: Eldin Volcano Trail",
44 => "Eldin Volcano: Lava Lake",
3 => "Eldin Volcano: Goron City",
5 => "Eldin Volcano: Rock Roast Volcano",
49 => "Eldin Volcano: Crater Shortcut",
552 => "Eldin Volcano: Stilled Eldin Volcano",
501 => "Eldin Volcano: Eldin Temple 1F",
503 => "Eldin Volcano: Eldin Temple 2F",
502 => "Eldin Volcano: Eldin Temple 3F",
// Hebra Mountain
34 => "Hebra Mountain: Hebra Mountain Passage (1)",
35 => "Hebra Mountain: Sheltered Hot Spring",
36 => "Hebra Mountain: Condé's House",
38 => "Hebra Mountain: Hebra Mountain Passage (2)",
37 => "Hebra Mountain: Hebra Mountain Passage (3)",
39 => "Hebra Mountain: Summit",
652 => "Hebra Mountain: Stilled Holy Mount Lanayru",
801 => "Hebra Mountain: Lanayru Temple 1F",
802 => "Hebra Mountain: Lanayru Temple B2",
803 => "Hebra Mountain: Lanayru Temple B4",
_ => FormattedValue.ForceReset
};
private static FormattedValue SuperMarioOdysseyChina_AssistMode(SingleValue value) return locations.Reset
=> value.Matched.BoxedValue is 1 ? "Playing in 帮助模式" : "Playing in 普通模式"; ? FormattedValue.ForceReset
: $"Warped to {locations}";
}
private static FormattedValue SuperMario3DAllStars(SingleValue value)
{
// TODO: Is this really necessary?
FormattedValue title = value.Matched.IntValue switch
{
1 => "Super Mario 64",
2 => "Super Mario Sunshine",
3 => "Super Mario Galaxy",
_ => FormattedValue.ForceReset
};
return title.Reset
? FormattedValue.ForceReset
: $"Playing {title}";
}
private static FormattedValue SuperMario3DAllStars_MainMenu(MultiValue value)
{
int albumId = value.Matched[0].IntValue;
int songId = value.Matched[1].IntValue;
string album = value.Matched[0].IntValue switch
{
1 => "Super Mario 64 OST",
2 => "Super Mario Sunshine OST",
3 => "Super Mario Galaxy OST",
_ => "Listening to Super Mario 3D All-Stars"
};
string song = (albumId, songId) switch
{
// Super Mario 64
(1, 0) => "It's a Me, Mario!",
(1, 1) => "Title Theme",
(1, 2) => "Peach's Message",
(1, 3) => "Opening",
(1, 4) => "Super Mario 64 Main Theme",
(1, 5) => "Slider",
(1, 6) => "Inside the Castle Walls",
(1, 7) => "Looping Steps",
(1, 8) => "Dire, Dire Docks",
(1, 9) => "Lethal Lava Land",
(1, 10) => "Snow Mountain",
(1, 11) => "Haunted House",
(1, 12) => "Merry-Go-Round",
(1, 13) => "Cave Dungeon",
(1, 14) => "Piranha Plant's Lullaby",
(1, 15) => "Powerful Mario",
(1, 16) => "Metallic Mario",
(1, 17) => "File Select",
(1, 18) => "Correct Solution",
(1, 19) => "Toad's Message",
(1, 20) => "Power Star",
(1, 21) => "Race Fanfare",
(1, 22) => "Star Catch Fanfare",
(1, 23) => "Game Start",
(1, 24) => "Course Clear",
(1, 25) => "Game Over",
(1, 26) => "Stage Boss",
(1, 27) => "Koopa's Message",
(1, 28) => "Koopa's Road",
(1, 29) => "Koopa's Theme",
(1, 30) => "Koopa Clear",
(1, 31) => "Ultimate Koopa",
(1, 32) => "Ultimate Koopa Clear",
(1, 33) => "Ending Demo",
(1, 34) => "Staff Roll",
(1, 35) => "Piranha Plant's Lullaby - Piano",
// Super Mario Sunshine
(2, 0) => "Isle Delfino",
(2, 1) => "Delfino Airstrip",
(2, 2) => "Bianco Hills",
(2, 3) => "Ricco Harbor",
(2, 4) => "Gelato Beach",
(2, 5) => "Pinna Beach",
(2, 6) => "Pinna Park",
(2, 7) => "Sirena Beach",
(2, 8) => "Hotel Delfino",
(2, 9) => "Casino",
(2, 10) => "Noki Bay",
(2, 11) => "Noki Depths",
(2, 12) => "Pianta Village",
(2, 13) => "Pianta Hot Spring",
(2, 14) => "Pianta Rescue",
(2, 15) => "Pianta Village - Fluff Festival",
(2, 16) => "Underground",
(2, 17) => "Secret Course",
(2, 18) => "Secret Course - Sky and Sea",
(2, 19) => "Corona Mountain",
(2, 20) => "Mid-Boss",
(2, 21) => "Proto Piranha",
(2, 22) => "Phantamanta",
(2, 23) => "Boss Battle",
(2, 24) => "Gooper Blooper Intro",
(2, 25) => "Wiggler Intro",
(2, 26) => "Mecha-Bowser",
(2, 27) => "Bowser",
(2, 28) => "Shadow Mario",
(2, 29) => "Racing Il Piantissimo",
(2, 30) => "Event",
(2, 31) => "Timed Event",
(2, 32) => "Yoshi-Go-Round",
(2, 33) => "Title Screen",
(2, 34) => "Opening Demo",
(2, 35) => "Select Data",
(2, 36) => "Select Scenario",
(2, 37) => "Course Intro",
(2, 38) => "Course Intro - Shadow Mario",
(2, 39) => "A Shine Sprite Appears",
(2, 40) => "Shine!",
(2, 41) => "Race Fanfare",
(2, 42) => "Casino Fanfare",
(2, 43) => "Too Bad!",
(2, 44) => "Game Over",
(2, 45) => "Welcome to Isle Delfino (Movie)",
(2, 46) => "Icky Goop (Movie)",
(2, 47) => "Mario on Trial (Movie)",
(2, 48) => "How to Use FLUDD (Movie)",
(2, 49) => "Shadow Mario Appears (Movie)",
(2, 50) => "The Kidnapping of Princess Peach (Movie)",
(2, 51) => "Mecha-Bowser Rises (Movie)",
(2, 52) => "Meet Bowser Jr. (Movie)",
(2, 53) => "FLUDD Theft (Movie)",
(2, 54) => "Hot Tub Intrusion (Movie)",
(2, 55) => "Epilogue (Movie)",
(2, 56) => "Staff Credits",
(2, 57) => "Have a Relaxing Vacation!",
// Super Mario Galaxy
(3, 0) => "Overture",
(3, 1) => "The Star Festival",
(3, 2) => "Attack of the Airships",
(3, 3) => "Catastrophe",
(3, 4) => "Peach's Castle Stolen",
(3, 5) => "Enter the Galaxy",
(3, 6) => "Egg Planet",
(3, 7) => "Rosaline in the Observatory 1",
(3, 8) => "The Honeyhive",
(3, 9) => "Space Junk Road",
(3, 10) => "Battlerock Galaxy",
(3, 11) => "Beach Bowl Galaxy",
(3, 12) => "Rosalina in the Observatory 2",
(3, 13) => "Enter Bowser Jr.!",
(3, 14) => "Waltz of the Boos",
(3, 15) => "Buoy Base Galaxy",
(3, 16) => "Gusty Garden Galaxy",
(3, 17) => "Rosaline in the Observatory 3",
(3, 18) => "King Bowser",
(3, 19) => "Melty Molten Galaxy",
(3, 20) => "The Galaxy Reactor",
(3, 21) => "Final Battle with Bowser",
(3, 22) => "A New Dawn",
(3, 23) => "Birth",
(3, 24) => "Super Mario Galaxy",
(3, 25) => "Purple Comet",
(3, 26) => "Blue Sky Athletic",
(3, 27) => "Super Mario 2007",
(3, 28) => "File Select",
(3, 29) => "Luma",
(3, 30) => "Gateway Galaxy",
(3, 31) => "Stolen Grand Star",
(3, 32) => "To the Observatory Grounds 1",
(3, 33) => "Observation Dome",
(3, 34) => "Course Select",
(3, 35) => "Dino Piranha",
(3, 36) => "A Chance to Grab a Star!",
(3, 37) => "A Tense Moment",
(3, 38) => "Big Bad Bugaboom",
(3, 39) => "King Kaliente",
(3, 40) => "The Toad Brigade",
(3, 41) => "Airship Armada",
(3, 42) => "Aquatic Race",
(3, 43) => "Space Fantasy",
(3, 44) => "Megaleg",
(3, 45) => "To The Observatory Grounds 2",
(3, 46) => "Space Athletic",
(3, 47) => "Speedy Comet",
(3, 48) => "Beach Bowl Galaxy - Undersea",
(3, 49) => "Interlude",
(3, 50) => "Bowser's Stronghold Appears",
(3, 51) => "The Fiery Stronghold",
(3, 52) => "The Big Staircase",
(3, 53) => "Bowser Appears",
(3, 54) => "Star Ball",
(3, 55) => "The Library",
(3, 56) => "Buoy Base Galaxy - Undersea",
(3, 57) => "Rainbow Mario",
(3, 58) => "Chase the Bunnies",
(3, 59) => "Help!",
(3, 60) => "Major Burrows",
(3, 61) => "Pipe Interior",
(3, 62) => "Cosmic Comet",
(3, 63) => "Drip Drop Galaxy",
(3, 64) => "Kingfin",
(3, 65) => "Boo Race",
(3, 66) => "Ice Mountain",
(3, 67) => "Ice Mario",
(3, 68) => "Lava Path",
(3, 69) => "Fire Mario",
(3, 70) => "Dusty Dune Galaxy",
(3, 71) => "Heavy Metal Mecha-Bowser",
(3, 72) => "A-wa-wa-wa!",
(3, 73) => "Deep Dark Galaxy",
(3, 74) => "Kamella",
(3, 75) => "Star Ball 2",
(3, 76) => "Sad Girl",
(3, 77) => "Flying Mario",
(3, 78) => "Star Child",
(3, 79) => "A Wish",
(3, 80) => "Family",
_ => ""
};
return string.IsNullOrEmpty(song) ? FormattedValue.ForceReset : $"{album} - {song}";
}
private static FormattedValue SuperMarioOdyssey(SingleValue value)
=> value.Matched.LongValue switch
{
// TODO: Needs updated for sub-areas.
2973331007 => "Cap Kingdom: Bonneton",
2661781375 => "Cascade Kingdom: Fossil Falls",
512560049 => "Sand Kingdom: Tostarena",
3079659402 => "Wooded Kingdom: Steam Gardens",
1941286268 => "Lake Kingdom: Lake Lamode",
3098209122 => "Cloud Kingdom: Nimbus Arena",
4088050842 => "Lost Kingdom: Forgotten Isle",
53003352 => "Metro Kingdom: New Donk City",
4265839612 => "Seaside Kingdom: Bubblaine",
3288863344 => "Snow Kingdom: Shiveria",
3180104973 => "Luncheon Kingdom: Mount Volbono",
2284558980 => "Ruined Kingdom: Crumbleden",
3024139598 => "Bowser's Kingdom: Bowser's Castle",
1351608174 => "Moon Kingdom: Honeylune Ridge",
1698750149 => "Dark Side: Rabbit Ridge",
3206301958 => "Darker Side: Culmina Crater",
3963002526 => "Mushroom Kingdom: Peach's Castle",
_ => FormattedValue.ForceReset
};
private static FormattedValue SuperMario3DWorldOrBowsersFury(SingleValue value) private static FormattedValue SuperMario3DWorldOrBowsersFury(SingleValue value)
=> value.Matched.BoxedValue is 0 ? "Playing Super Mario 3D World" : "Playing Bowser's Fury"; => value.Matched.BoxedValue is 0 ? "Playing Super Mario 3D World" : "Playing Bowser's Fury";
private static FormattedValue SuperMarioWonder(SingleValue value)
{
// TODO: Needs updated for course names.
MessagePackObject messagePackObject = value.Matched.PackedValue;
MessagePackObjectDictionary messagePackObjectDictionary = messagePackObject.AsDictionary();
int worldNumber = messagePackObjectDictionary["world_no"].AsInt32();
int courseNumber = 0;
if (messagePackObjectDictionary.TryGetValue("course_no", out MessagePackObject courseNumberVariable))
{
courseNumber = courseNumberVariable.AsInt32();
}
FormattedValue world = worldNumber switch
{
1 => "Pipe-Rock Plateau",
2 => "Petal Isles",
3 => "Fluff-Puff Peaks",
4 => "Shining Falls",
5 => "Sunbaked Desert",
6 => "Fungi Mines",
7 => "Deep Magma Bog",
9 => "Special World",
_ => FormattedValue.ForceReset
};
if (courseNumber == 0)
{
return FormattedValue.ForceReset;
}
return world.Reset
? FormattedValue.ForceReset
: $"{world}: {worldNumber}-{courseNumber}";
}
private static FormattedValue MarioKart8Deluxe_Mode(SingleValue value) private static FormattedValue MarioKart8Deluxe_Mode(SingleValue value)
=> value.Matched.StringValue switch => value.Matched.StringValue switch
{ {
// Single Player // Single Player
"Single" => "Single Player", "Single" => "Single Player",
// Multiplayer // Multiplayer
"Multi-2players" => "Multiplayer 2 Players", "Multi-2players" => "Multiplayer: 2 Players",
"Multi-3players" => "Multiplayer 3 Players", "Multi-3players" => "Multiplayer: 3 Players",
"Multi-4players" => "Multiplayer 4 Players", "Multi-4players" => "Multiplayer: 4 Players",
// Wireless/LAN Play // Wireless/LAN Play
"Local-Single" => "Wireless/LAN Play", "Local-Single" => "Wireless/LAN Play",
"Local-2players" => "Wireless/LAN Play 2 Players", "Local-2players" => "Wireless/LAN Play 2 Players",
@@ -62,8 +421,9 @@ namespace Ryujinx.Ava.Systems.PlayReport
private static FormattedValue PokemonSV(MultiValue values) private static FormattedValue PokemonSV(MultiValue values)
{ {
string region = PokemonSV_Region(values.Matched[1].ToString());
string playStatus = values.Matched[0].BoxedValue is 0 ? "Playing Alone" : "Playing in a group"; string union = values.Matched[0].BoxedValue is 0 ? "" : " with friends";
string academyName = PokemonSV_AcademyName(values.Application.Title);
FormattedValue locations = values.Matched[1].ToString() switch FormattedValue locations = values.Matched[1].ToString() switch
{ {
@@ -89,18 +449,86 @@ namespace Ryujinx.Ava.Systems.PlayReport
"a_w20" => "North Area Three", "a_w20" => "North Area Three",
"a_w21" => "North Area One", "a_w21" => "North Area One",
"a_w22" => "North Area Two", "a_w22" => "North Area Two",
"a_w23" => "The Great Crater of Paldea", "a_w23" => "Area Zero: The Great Crater of Paldea",
"a_w24" => "South Paldean Sea", "a_w24" => "South Paldean Sea",
"a_w25" => "West Paldean Sea", "a_w25" => "West Paldean Sea",
"a_w26" => "East Paldean Sea", "a_w26" => "East Paldean Sea",
"a_w27" => "North Paldean Sea", "a_w27" => "North Paldean Sea",
//TODO DLC Locations // Naranja / Uva Academy
"a_sch_entrance01" => $"{academyName} Academy: Entrance",
"a_sch_cafe01" => $"{academyName} Academy: Cafeteria",
"a_sch_shop01" => $"{academyName} Academy: School Store",
"a_sch_room01" => $"{academyName} Academy: Home Ec Room",
"a_sch_room02" => $"{academyName} Academy: Art Room",
"a_sch_room03" => $"{academyName} Academy: Biology Lab",
"a_sch_room04" => $"{academyName} Academy: Staff Room",
"a_sch_office01" => $"{academyName} Academy: Director's Office",
"a_sch_office03" => $"{academyName} Academy: Nurse's Office",
"a_sch_ground01" => $"{academyName} Academy: School Yard",
"a_sch_class1a" => $"{academyName} Academy: Classroom 1-A",
"a_sch_class1d" => $"{academyName} Academy: Classroom 1-D",
"a_sch_class2g" => $"{academyName} Academy: Classroom 2-G",
"a_sch_dorm01" => $"{academyName} Academy: Dorm Room (Trainer)",
"a_sch_dorm02" => $"{academyName} Academy: Dorm Room (Nemona)",
"a_sch_dorm03" => $"{academyName} Academy: Dorm Room (Arven)",
"a_sch_dorm04" => $"{academyName} Academy: Dorm Room (Penny)",
// DLC
// Kitakami
"a_su0101" => "Mossui Town",
"a_su0102" => "Loyalty Plaza",
"a_su0103" => "Kitakami Hall",
"a_su0104" => "Oni Mountain",
"a_su0105" => "Infernal Pass",
"a_su0106" => "Crystal Pool",
"a_su0107" => "Wistful Fields",
"a_su0108" => "Mossfell Confluence",
"a_su0109" => "Fellhorn Gorge",
"a_su0110" => "Paradise Barrens",
"a_su0111" => "Timeless Woods",
// Blueberry Academy: School
"a_sch_2_entrance0" => "Blueberry Academy: Entrance",
"a_sch_2_clubroom" => "Blueberry Academy: League Clubroom",
"a_sch_2_class1" => "Blueberry Academy: Classroom 1-4",
"a_sch_2_class2" => "Blueberry Academy: Classroom 3-2",
"a_sch_2_shop01" => "Blueberry Academy: School Store",
"a_sch_2_cafe01" => "Blueberry Academy: Cafeteria",
"a_sch_2_dorm01" => "Blueberry Academy: Dorm Room (Trainer)",
"a_sch_2_dorm02" => "Blueberry Academy: Dorm Room (Carmine)",
// Blueberry Academy: Terrarium
"a_su0201" => "Savanna Biome",
"a_su0202" => "Coastal Biome",
"a_su0203" => "Canyon Biome",
"a_su0204" => "Polar Biome",
_ => FormattedValue.ForceReset _ => FormattedValue.ForceReset
}; };
return locations.Reset return locations.Reset
? FormattedValue.ForceReset ? FormattedValue.ForceReset
: $"{playStatus} in {locations}"; : $"Exploring {region}{union} | {locations}";
}
private static string PokemonSV_Region(string location)
{
if (location.Contains("a_su02") || location.Contains("a_sch_2")) return "Unova";
if (location.Contains("a_su01")) return "Kitakami";
return "Paldea";
}
private static string PokemonSV_AcademyName(string title)
{
// TODO: Is this even necessary?
if (
title.Contains("Scarlet")
|| title.Contains("Escarlata")
|| title.Contains("Écarlate")
|| title.Contains("Karmesin")
|| title.Contains("Scarlatto")
|| title.Contains("スカーレット")
|| title.Contains("스칼렛")
|| title.Contains("朱")
) { return "Naranja"; }
return "Uva";
} }
private static FormattedValue SuperSmashBrosUltimate_Mode(SparseMultiValue values) private static FormattedValue SuperSmashBrosUltimate_Mode(SparseMultiValue values)
@@ -641,5 +1069,7 @@ namespace Ryujinx.Ava.Systems.PlayReport
_ => FormattedValue.ForceReset _ => FormattedValue.ForceReset
}; };
} }
} }

View File

@@ -14,7 +14,7 @@ namespace Ryujinx.Ava.Systems.PlayReport
private static readonly Lazy<Analyzer> _analyzerLazy = new(() => new Analyzer() private static readonly Lazy<Analyzer> _analyzerLazy = new(() => new Analyzer()
.AddSpec( .AddSpec(
"01007ef00011e000", "01007ef00011e000", // Breath of the Wild
spec => spec spec => spec
.WithDescription("based on being in Master Mode.") .WithDescription("based on being in Master Mode.")
.AddValueFormatter("IsHardMode", BreathOfTheWild_MasterMode) .AddValueFormatter("IsHardMode", BreathOfTheWild_MasterMode)
@@ -22,48 +22,74 @@ namespace Ryujinx.Ava.Systems.PlayReport
.AddValueFormatter("AoCVer", FormattedValue.SingleAlwaysResets) .AddValueFormatter("AoCVer", FormattedValue.SingleAlwaysResets)
) )
.AddSpec( .AddSpec(
"0100f2c0115b6000", "0100f2c0115b6000", // Tears of the Kingdom
spec => spec spec => spec
.WithDescription("based on where you are in Hyrule (Depths, Surface, Sky).") .WithDescription("based on where you are in Hyrule (Depths, Surface, Sky).")
.AddValueFormatter("PlayerPosY", TearsOfTheKingdom_CurrentField)) .AddValueFormatter("PlayerPosY", TearsOfTheKingdom_CurrentField))
.AddSpec( .AddSpec(
"01002da013484000", "01002da013484000", // Skyward Sword
spec => spec spec => spec
.WithDescription("based on how many Rupees you have.") .WithDescription("based on how many Rupees you have.")
.AddValueFormatter("rupees", SkywardSwordHD_Rupees)) .AddValueFormatter("rupees", SkywardSwordHD_Rupees))
.AddSpec( .AddSpec(
"0100000000010000", "01008cf01baac000", // Echoes of Wisdom
spec => spec spec => spec
.WithDescription("based on if you're playing with Assist Mode.") .WithDescription("based on where you've warped.")
.AddValueFormatter("is_kids_mode", SuperMarioOdyssey_AssistMode) .AddValueFormatter("dest_index", EchoesOfWisdom_Warp)
)
.AddSpec(
"010049900f546000", // Super Mario 3D All Stars
spec => spec
.WithDescription("based on what album and track you're listening to.")
.AddMultiValueFormatter(["app_id","song_id"], SuperMario3DAllStars_MainMenu)
) )
.AddSpec( .AddSpec(
"010075000ecbe000", ["010049900f546001", "010049900f546002", "010049900F546003"], // Super Mario 3D All Stars
spec => spec spec => spec
.WithDescription("based on if you're playing with Assist Mode.") .WithDescription("based on which game you've selected to play in the collection.")
.AddValueFormatter("is_kids_mode", SuperMarioOdysseyChina_AssistMode) .AddValueFormatter("program_id", SuperMario3DAllStars)
) )
.AddSpec( .AddSpec(
"010028600ebda000", "0100000000010000", // Super Mario Odyssey
spec => spec
.WithDescription("based on what kingdom you're in.")
.AddValueFormatter("stage_name", SuperMarioOdyssey)
)
.AddSpec(
"010028600ebda000", // Super Mario 3D World + Bowser's Fury
spec => spec spec => spec
.WithDescription("based on being in either Super Mario 3D World or Bowser's Fury.") .WithDescription("based on being in either Super Mario 3D World or Bowser's Fury.")
.AddValueFormatter("mode", SuperMario3DWorldOrBowsersFury) .AddValueFormatter("mode", SuperMario3DWorldOrBowsersFury)
) )
.AddSpec(
["010049900f546000", "010049900f546001", "010049900f546002", "010049900F546003"],
spec => spec
.WithDescription("based on which game you've selected to play in the collection.")
.AddValueFormatter("program_id", SuperMario3DAllStars)
)
.AddSpec(
"010015100b514000", // Super Mario Bros. Wonder
spec => spec
.WithDescription("based on what world and course you're in.")
.AddValueFormatter("stage_info", SuperMarioWonder)
)
.AddSpec( // Global & China IDs .AddSpec( // Global & China IDs
["0100152000022000", "010075100e8ec000"], ["0100152000022000", "010075100e8ec000"], // Mario Kart 8 Deluxe
spec => spec spec => spec
.WithDescription( .WithDescription(
"based on what modes you're selecting in the menu & whether or not you're in a race.") "based on what modes you're selecting in the menu & whether or not you're in a race.")
.AddValueFormatter("To", MarioKart8Deluxe_Mode) .AddValueFormatter("To", MarioKart8Deluxe_Mode)
) )
.AddSpec( .AddSpec(
["0100a3d008c5c000", "01008f6008c5e000"], ["0100a3d008c5c000", "01008f6008c5e000"], // Pokemon Scarlet/Violet
spec => spec spec => spec
.WithDescription("based on if you're playing alone or in a group and what area of Paldea you're exploring.") .WithDescription("based on if you're playing alone or in a group and what area of Paldea you're exploring.")
.AddMultiValueFormatter(["team_circle", "area_no"], PokemonSV) .AddMultiValueFormatter(["team_circle", "area_no"], PokemonSV)
) )
.AddSpec( .AddSpec(
"01006a800016e000", "01006a800016e000", // Super Smash Bros. Ultimate
spec => spec spec => spec
.WithDescription("based on what mode you're playing, who won, and what characters were present.") .WithDescription("based on what mode you're playing, who won, and what characters were present.")
.AddSparseMultiValueFormatter( .AddSparseMultiValueFormatter(
@@ -83,8 +109,10 @@ namespace Ryujinx.Ava.Systems.PlayReport
) )
.AddSpec( .AddSpec(
[ [
"0100c9a00ece6000", "01008d300c50c000", "0100d870045b6000", "0100B4E00444C000", "0100d870045b6000", "01008d300c50c000", "0100c62011050000", "010012f017576000",
"010012f017576000", "0100c62011050000", "0100b3c014bda000" /*Famicom*/ /*NES*/ /*SNES*/ /*GBC*/ /*GBA*/
"0100b3c014bda000", "0100c9a00ece6000", "0100e0601c632000", "0100bfc01d976000"
/*SEGA Genesis*/ /*N64*/ /*N64 MATURE*/ /*Virtual Boy*/
], ],
spec => spec spec => spec
.WithDescription( .WithDescription(