Compare commits
3 Commits
Canary-1.2
...
feature/av
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d64bf7d93c | ||
|
|
52338db1e8 | ||
|
|
aa01f70f46 |
4
.github/workflows/canary.yml
vendored
4
.github/workflows/canary.yml
vendored
@@ -29,7 +29,7 @@ env:
|
||||
jobs:
|
||||
tag:
|
||||
name: Create tag
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Get version info
|
||||
id: version_info
|
||||
@@ -202,7 +202,7 @@ jobs:
|
||||
|
||||
macos_release:
|
||||
name: Release MacOS universal
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -18,7 +18,7 @@ env:
|
||||
jobs:
|
||||
tag:
|
||||
name: Create tag
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Get version info
|
||||
id: version_info
|
||||
@@ -183,7 +183,7 @@ jobs:
|
||||
|
||||
macos_release:
|
||||
name: Release MacOS universal
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
||||
@@ -39,12 +39,12 @@
|
||||
<p align="center">
|
||||
Click below to join the Discord:
|
||||
<br>
|
||||
<a href="https://discord.gg/PEuzjrFXUA">
|
||||
<a href="https://discord.gg/dHPrkBkkyA">
|
||||
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
<img src="https://raw.githubusercontent.com/Ryubing/Ryujinx/refs/heads/master/docs/shell.png">
|
||||
<img src="https://raw.githubusercontent.com/GreemDev/Ryujinx/refs/heads/master/docs/shell.png">
|
||||
</p>
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -332,7 +332,6 @@
|
||||
0100E680149DC000,"Arcaea",,playable,2023-03-16 19:31:21
|
||||
01003C2010C78000,"Archaica: The Path Of Light",crash,nothing,2020-10-16 13:22:26
|
||||
01004DA012976000,"Area 86",,playable,2020-12-16 16:45:52
|
||||
01008d8006a6a000,"Arena of Valor",crash,boots,2025-02-03 22:19:34
|
||||
0100691013C46000,"ARIA CHRONICLE",,playable,2022-11-16 13:50:55
|
||||
0100D4A00B284000,"ARK: Survival Evolved",gpu;nvdec;online-broken;UE4;ldn-untested,ingame,2024-04-16 00:53:56
|
||||
0100C56012C96000,"Arkanoid vs. Space Invaders",services,ingame,2021-01-21 12:50:30
|
||||
@@ -427,7 +426,6 @@
|
||||
0100E48013A34000,"Balan Wonderworld Demo",gpu;services;UE4;demo,ingame,2023-02-16 20:05:07
|
||||
0100CD801CE5E000,"Balatro",,ingame,2024-04-21 02:01:53
|
||||
010010A00DA48000,"Baldur's Gate and Baldur's Gate II: Enhanced Editions",32-bit,playable,2022-09-12 23:52:15
|
||||
0100fd1014726000,"Baldur's Gate: Dark Alliance",ldn-untested,ingame,2025-02-03 22:21:00
|
||||
0100BC400FB64000,"Balthazar's Dream",,playable,2022-09-13 00:13:22
|
||||
01008D30128E0000,"Bamerang",,playable,2022-10-26 00:29:39
|
||||
010013C010C5C000,"Banner of the Maid",,playable,2021-06-14 15:23:37
|
||||
@@ -530,7 +528,6 @@
|
||||
01005950022EC000,"Blade Strangers",nvdec,playable,2022-07-17 19:02:43
|
||||
0100DF0011A6A000,"Bladed Fury",,playable,2022-10-26 11:36:26
|
||||
0100CFA00CC74000,"Blades of Time",deadlock;online,boots,2022-07-17 19:19:58
|
||||
01003d700dd8a000,"Blades",,boots,2025-02-03 22:22:00
|
||||
01006CC01182C000,"Blair Witch",nvdec;UE4,playable,2022-10-01 14:06:16
|
||||
010039501405E000,"Blanc",gpu;slow,ingame,2023-02-22 14:00:13
|
||||
0100698009C6E000,"Blasphemous",nvdec,playable,2021-03-01 12:15:31
|
||||
@@ -958,7 +955,7 @@
|
||||
010012800EBAE000,"Disney TSUM TSUM FESTIVAL",crash,menus,2020-07-14 14:05:28
|
||||
01009740120FE000,"DISTRAINT 2",,playable,2020-09-03 16:08:12
|
||||
010075B004DD2000,"DISTRAINT: Deluxe Edition",,playable,2020-06-15 23:42:24
|
||||
010027400CDC6000,"Divinity: Original Sin 2 - Definitive Edition",services;crash;online-broken;regression,ingame,2025-02-03 22:12:30
|
||||
010027400CDC6000,"Divinity: Original Sin 2 - Definitive Edition",services;crash;online-broken;regression,menus,2023-08-13 17:20:03
|
||||
01001770115C8000,"Dodo Peak",nvdec;UE4,playable,2022-10-04 16:13:05
|
||||
010077B0100DA000,"Dogurai",,playable,2020-10-04 02:40:16
|
||||
010048100D51A000,"Dokapon Up! Mugen no Roulette",gpu;Needs Update,menus,2022-12-08 19:39:10
|
||||
@@ -969,7 +966,6 @@
|
||||
0100751007ADA000,"Don't Starve: Nintendo Switch Edition",nvdec,playable,2022-02-05 20:43:34
|
||||
010088B010DD2000,"Dongo Adventure",,playable,2022-10-04 16:22:26
|
||||
0100C1F0051B6000,"Donkey Kong Country™: Tropical Freeze",,playable,2024-08-05 16:46:10
|
||||
01009D901BC56000,"Donkey Kong Country™: Returns HD",gpu,ingame,2025-02-16 13:44:12
|
||||
0100F2C00F060000,"Doodle Derby",,boots,2020-12-04 22:51:48
|
||||
0100416004C00000,"DOOM",gpu;slow;nvdec;online-broken,ingame,2024-09-23 15:40:07
|
||||
010018900DD00000,"DOOM (1993)",nvdec;online-broken,menus,2022-09-06 13:32:19
|
||||
@@ -1159,7 +1155,7 @@
|
||||
010095600AA36000,"Fill-a-Pix: Phil's Epic Adventure",,playable,2020-12-22 13:48:22
|
||||
0100C3A00BB76000,"Fimbul",nvdec,playable,2022-07-26 13:31:47
|
||||
0100C8200E942000,"Fin and the Ancient Mystery",nvdec,playable,2020-12-17 16:40:39
|
||||
01000EA014150000,"FINAL FANTASY",,playable,2025-02-16 21:27:30
|
||||
01000EA014150000,"FINAL FANTASY",crash,nothing,2024-09-05 20:55:30
|
||||
01006B7014156000,"FINAL FANTASY II",crash,nothing,2024-04-13 19:18:04
|
||||
01006F000B056000,"FINAL FANTASY IX",audout;nvdec,playable,2021-06-05 11:35:00
|
||||
0100AA201415C000,"FINAL FANTASY V",,playable,2023-04-26 01:11:55
|
||||
@@ -1250,7 +1246,7 @@
|
||||
0100A6B00D4EC000,"Furwind",,playable,2021-02-19 19:44:08
|
||||
0100ECE00C0C4000,"Fury Unleashed",crash;services,ingame,2020-10-18 11:52:40
|
||||
010070000ED9E000,"Fury Unleashed Demo",,playable,2020-10-08 20:09:21
|
||||
0100E1F013674000,"FUSER™",nvdec;UE4;slow;gpu,ingame,2025-02-12 16:03:00
|
||||
0100E1F013674000,"FUSER™",nvdec;UE4,playable,2022-10-17 20:58:32
|
||||
0100A7A015E4C000,"Fushigi no Gensokyo Lotus Labyrinth",Needs Update;audio;gpu;nvdec,ingame,2021-01-20 15:30:02
|
||||
01003C300B274000,"Futari de! Nyanko Daisensou",,playable,2024-01-05 22:26:52
|
||||
010055801134E000,"FUZE Player",online-broken;vulkan-backend-bug,ingame,2022-10-18 12:23:53
|
||||
@@ -1658,7 +1654,7 @@
|
||||
0100A73006E74000,"Legendary Eleven",,playable,2021-06-08 12:09:03
|
||||
0100A7700B46C000,"Legendary Fishing",online,playable,2021-04-14 15:08:46
|
||||
0100739018020000,"LEGO® 2K Drive",gpu;ldn-works,ingame,2024-04-09 02:05:12
|
||||
010085500130a000,"LEGO® CITY Undercover",nvdec,playable,2024-09-30 08:44:27
|
||||
01003A30012C0000,"LEGO® CITY Undercover",nvdec,playable,2024-09-30 08:44:27
|
||||
010070D009FEC000,"LEGO® DC Super-Villains",,playable,2021-05-27 18:10:37
|
||||
010052A00B5D2000,"LEGO® Harry Potter™ Collection",crash,ingame,2024-01-31 10:28:07
|
||||
010073C01AF34000,"LEGO® Horizon Adventures™",vulkan-backend-bug;opengl-backend-bug;UE4,ingame,2025-01-07 04:24:56
|
||||
@@ -1917,7 +1913,6 @@
|
||||
010073E008E6E000,"Mugsters",,playable,2021-01-28 17:57:17
|
||||
0100A8400471A000,"MUJO",,playable,2020-05-08 16:31:04
|
||||
0100211005E94000,"Mulaka",,playable,2021-01-28 18:07:20
|
||||
01008e2013fb4000,"Multi Quiz",ldn-untested,ingame,2025-02-03 22:26:00
|
||||
010038B00B9AE000,"Mummy Pinball",,playable,2022-08-05 16:08:11
|
||||
01008E200C5C2000,"Muse Dash",,playable,2020-06-06 14:41:29
|
||||
010035901046C000,"Mushroom Quest",,playable,2020-05-17 13:07:08
|
||||
@@ -2033,7 +2028,6 @@
|
||||
010003C00B868000,"Ninjin: Clash of Carrots",online-broken,playable,2024-07-10 05:12:26
|
||||
0100746010E4C000,"NinNinDays",,playable,2022-11-20 15:17:29
|
||||
0100C9A00ECE6000,"Nintendo 64™ – Nintendo Switch Online",gpu;vulkan,ingame,2024-04-23 20:21:07
|
||||
0100e0601c632000,"Nintendo 64™ – Nintendo Switch Online: MATURE 17+",,ingame,2025-02-03 22:27:00
|
||||
0100D870045B6000,"Nintendo Entertainment System™ - Nintendo Switch Online",online,playable,2022-07-01 15:45:06
|
||||
0100C4B0034B2000,"Nintendo Labo Toy-Con 01 Variety Kit",gpu,ingame,2022-08-07 12:56:07
|
||||
01001E9003502000,"Nintendo Labo Toy-Con 03 Vehicle Kit",services;crash,menus,2022-08-03 17:20:11
|
||||
@@ -2064,7 +2058,7 @@
|
||||
010002700C34C000,"Numbala",,playable,2020-05-11 12:01:07
|
||||
010020500C8C8000,"Number Place 10000",gpu,menus,2021-11-24 09:14:23
|
||||
010003701002C000,"Nurse Love Syndrome",,playable,2022-10-13 10:05:22
|
||||
,"nx-hbmenu",Needs Update;homebrew,boots,2024-04-06 22:05:32
|
||||
0000000000000000,"nx-hbmenu",Needs Update;homebrew,boots,2024-04-06 22:05:32
|
||||
,"nxquake2",services;crash;homebrew,nothing,2022-08-04 23:14:04
|
||||
010049F00EC30000,"Nyan Cat: Lost in Space",online,playable,2021-06-12 13:22:03
|
||||
01002E6014FC4000,"O---O",,playable,2022-10-29 12:12:14
|
||||
@@ -2472,7 +2466,7 @@
|
||||
0100AFE00DDAC000,"Royal Roads",,playable,2020-11-17 12:54:38
|
||||
0100E2C00B414000,"RPG Maker MV",nvdec,playable,2021-01-05 20:12:01
|
||||
01005CD015986000,"rRootage Reloaded",,playable,2022-08-05 23:20:18
|
||||
,"RSDKv5u",homebrew,ingame,2024-04-01 16:25:34
|
||||
0000000000000000,"RSDKv5u",homebrew,ingame,2024-04-01 16:25:34
|
||||
010009B00D33C000,"Rugby Challenge 4",slow;online-broken;UE4,playable,2022-10-06 12:45:53
|
||||
01006EC00F2CC000,"RUINER",UE4,playable,2022-10-03 14:11:33
|
||||
010074F00DE4A000,"Run the Fan",,playable,2021-02-27 13:36:28
|
||||
@@ -2481,7 +2475,6 @@
|
||||
010081C0191D8000,"Rune Factory 3 Special",,playable,2023-10-15 08:32:49
|
||||
010051D00E3A4000,"Rune Factory 4 Special",32-bit;crash;nvdec,ingame,2023-05-06 08:49:17
|
||||
010014D01216E000,"Rune Factory 5 (JP)",gpu,ingame,2021-06-01 12:00:36
|
||||
010071E0145F8000,"Rustler",,playable,2025-02-10 20:17:12
|
||||
0100E21013908000,"RWBY: Grimm Eclipse - Definitive Edition",online-broken,playable,2022-11-03 10:44:01
|
||||
010012C0060F0000,"RXN -Raijin-",nvdec,playable,2021-01-10 16:05:43
|
||||
0100B8B012ECA000,"S.N.I.P.E.R. - Hunter Scope",,playable,2021-04-19 15:58:09
|
||||
@@ -2490,7 +2483,7 @@
|
||||
0100A5200C2E0000,"Safety First!",,playable,2021-01-06 09:05:23
|
||||
0100A51013530000,"SaGa Frontier Remastered",nvdec,playable,2022-11-03 13:54:56
|
||||
010003A00D0B4000,"SaGa SCARLET GRACE: AMBITIONS™",,playable,2022-10-06 13:20:31
|
||||
01008D100D43E000,"Saints Row IV®: Re-Elected™",ldn-untested;LAN;deadlock,ingame,2025-02-02 16:57:53
|
||||
01008D100D43E000,"Saints Row IV®: Re-Elected™",ldn-untested;LAN,playable,2023-12-04 18:33:37
|
||||
0100DE600BEEE000,"SAINTS ROW®: THE THIRD™ - THE FULL PACKAGE",slow;LAN,playable,2023-08-24 02:40:58
|
||||
01007F000EB36000,"Sakai and...",nvdec,playable,2022-12-15 13:53:19
|
||||
0100B1400E8FE000,"Sakuna: Of Rice and Ruin",,playable,2023-07-24 13:47:13
|
||||
@@ -2539,7 +2532,7 @@
|
||||
0100C3E00B700000,"SEGA AGES Space Harrier",,playable,2021-01-11 12:57:40
|
||||
010054400D2E6000,"SEGA AGES Virtua Racing",online-broken,playable,2023-01-29 17:08:39
|
||||
01001E700AC60000,"SEGA AGES Wonder Boy: Monster Land",online,playable,2021-05-05 16:28:25
|
||||
0100B3C014BDA000,"SEGA Genesis™ – Nintendo Switch Online",crash;regression,ingame,2025-02-03 22:13:30
|
||||
0100B3C014BDA000,"SEGA Genesis™ – Nintendo Switch Online",crash;regression,nothing,2022-04-11 07:27:21
|
||||
0100F7300B24E000,"SEGA Mega Drive Classics",online,playable,2021-01-05 11:08:00
|
||||
01009840046BC000,"Semispheres",,playable,2021-01-06 23:08:31
|
||||
0100D1800D902000,"SENRAN KAGURA Peach Ball",,playable,2021-06-03 15:12:10
|
||||
@@ -2675,10 +2668,10 @@
|
||||
01004F401BEBE000,"Song of Nunu: A League of Legends Story",,ingame,2024-07-12 18:53:44
|
||||
0100E5400BF94000,"Songbird Symphony",,playable,2021-02-27 02:44:04
|
||||
010031D00A604000,"Songbringer",,playable,2020-06-22 10:42:02
|
||||
,"Sonic 1 (2013)",crash;homebrew,ingame,2024-04-06 18:31:20
|
||||
,"Sonic 2 (2013)",crash;homebrew,ingame,2024-04-01 16:25:30
|
||||
,"Sonic A.I.R",homebrew,ingame,2024-04-01 16:25:32
|
||||
,"Sonic CD",crash;homebrew,ingame,2024-04-01 16:25:31
|
||||
0000000000000000,"Sonic 1 (2013)",crash;homebrew,ingame,2024-04-06 18:31:20
|
||||
0000000000000000,"Sonic 2 (2013)",crash;homebrew,ingame,2024-04-01 16:25:30
|
||||
0000000000000000,"Sonic A.I.R",homebrew,ingame,2024-04-01 16:25:32
|
||||
0000000000000000,"Sonic CD",crash;homebrew,ingame,2024-04-01 16:25:31
|
||||
010040E0116B8000,"Sonic Colors: Ultimate",,playable,2022-11-12 21:24:26
|
||||
01001270012B6000,"SONIC FORCES™",,playable,2024-07-28 13:11:21
|
||||
01004AD014BF0000,"Sonic Frontiers",gpu;deadlock;amd-vendor-bug;intel-vendor-bug,ingame,2024-09-05 09:18:53
|
||||
@@ -2695,7 +2688,7 @@
|
||||
0100707011722000,"Space Elite Force",,playable,2020-11-27 15:21:05
|
||||
010047B010260000,"Space Pioneer",,playable,2022-10-20 12:24:37
|
||||
010010A009830000,"Space Ribbon",,playable,2022-08-15 17:17:10
|
||||
,"SpaceCadetPinball",homebrew,ingame,2024-04-18 19:30:04
|
||||
0000000000000000,"SpaceCadetPinball",homebrew,ingame,2024-04-18 19:30:04
|
||||
0100D9B0041CE000,"Spacecats with Lasers",,playable,2022-08-15 17:22:44
|
||||
010034800FB60000,"Spaceland",,playable,2020-11-01 14:31:56
|
||||
010028D0045CE000,"Sparkle 2",,playable,2020-10-19 11:51:39
|
||||
@@ -2839,9 +2832,8 @@
|
||||
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
|
||||
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
|
||||
0100BC0018138000,"Super Mario RPG™",gpu;audio;nvdec,ingame,2024-06-19 17:43:42
|
||||
,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
|
||||
0000000000000000,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
|
||||
010049900F546000,"Super Mario™ 3D All-Stars",services-horizon;slow;vulkan;amd-vendor-bug,ingame,2024-05-07 02:38:16
|
||||
010028600EBDA000,"Super Mario™ 3D World + Bowser’s Fury",ldn-works,playable,2024-07-31 10:45:37
|
||||
01004F8006A78000,"Super Meat Boy",services,playable,2020-04-02 23:10:07
|
||||
@@ -2972,7 +2964,6 @@
|
||||
0100C38004DCC000,"The Flame In The Flood: Complete Edition",gpu;nvdec;UE4,ingame,2022-08-22 16:23:49
|
||||
010007700D4AC000,"The Forbidden Arts",,playable,2021-01-26 16:26:24
|
||||
010030700CBBC000,"The friends of Ringo Ishikawa",,playable,2022-08-22 16:33:17
|
||||
0100b620139d8000,"The Game of Life 2",ldn-untested,ingame,2025-02-03 22:30:00
|
||||
01006350148DA000,"The Gardener and the Wild Vines",gpu,ingame,2024-04-29 16:32:10
|
||||
0100B13007A6A000,"The Gardens Between",,playable,2021-01-29 16:16:53
|
||||
010036E00FB20000,"The Great Ace Attorney Chronicles",,playable,2023-06-22 21:26:29
|
||||
@@ -2990,8 +2981,6 @@
|
||||
010015D003EE4000,"The Jackbox Party Pack 2",online-working,playable,2022-08-22 18:23:40
|
||||
0100CC80013D6000,"The Jackbox Party Pack 3",slow;online-working,playable,2022-08-22 18:41:06
|
||||
0100E1F003EE8000,"The Jackbox Party Pack 4",online-working,playable,2022-08-22 18:56:34
|
||||
01006fe0096ac000,"The Jackbox Party Pack 5",slow;online-working,ingame,2025-02-14 05:32:00
|
||||
01005a400db52000,"The Jackbox Party Pack 6",slow;online-working,ingame,2025-02-14 05:26:00
|
||||
010052C00B184000,"The Journey Down: Chapter One",nvdec,playable,2021-02-24 13:32:41
|
||||
01006BC00B188000,"The Journey Down: Chapter Three",nvdec,playable,2021-02-24 13:45:27
|
||||
01009AB00B186000,"The Journey Down: Chapter Two",nvdec,playable,2021-02-24 13:32:13
|
||||
@@ -3170,7 +3159,6 @@
|
||||
010055E00CA68000,"Trine 4: The Nightmare Prince",gpu,nothing,2025-01-07 05:47:46
|
||||
0100D9000A930000,"Trine Enchanted Edition",ldn-untested;nvdec,playable,2021-06-03 11:28:15
|
||||
01002D7010A54000,"Trinity Trigger",crash,ingame,2023-03-03 03:09:09
|
||||
010020700a5e0000,"TRIVIAL PURSUIT Live!",ldn-untested,ingame,2025-02-03 22:35:00
|
||||
0100868013FFC000,"TRIVIAL PURSUIT Live! 2",,boots,2022-12-19 00:04:33
|
||||
0100F78002040000,"Troll and I™",gpu;nvdec,ingame,2021-06-04 16:58:50
|
||||
0100145011008000,"Trollhunters: Defenders of Arcadia",gpu;nvdec,ingame,2020-11-30 13:27:09
|
||||
@@ -3220,7 +3208,6 @@
|
||||
0100AB2010B4C000,"Unlock The King",,playable,2020-09-01 13:58:27
|
||||
0100A3E011CB0000,"Unlock the King 2",,playable,2021-06-15 20:43:55
|
||||
01005AA00372A000,"UNO® for Nintendo Switch",nvdec;ldn-untested,playable,2022-07-28 14:49:47
|
||||
0100b6e012ebe000,"UNO",ldn-untested,ingame,2025-02-03 22:40:00
|
||||
0100E5D00CC0C000,"Unravel Two",nvdec,playable,2024-05-23 15:45:05
|
||||
010001300CC4A000,"Unruly Heroes",,playable,2021-01-07 18:09:31
|
||||
0100B410138C0000,"Unspottable",,playable,2022-10-25 19:28:49
|
||||
@@ -3385,7 +3372,6 @@
|
||||
0100F47016F26000,"Yomawari 3",,playable,2022-05-10 08:26:51
|
||||
010012F00B6F2000,"Yomawari: The Long Night Collection",,playable,2022-09-03 14:36:59
|
||||
0100CC600ABB2000,"Yonder: The Cloud Catcher Chronicles (Retail Only)",,playable,2021-01-28 14:06:25
|
||||
0100534009ff2000,"Yonder: The Cloud Catcher Chronicles",,playable,2025-02-03 22:19:13
|
||||
0100BE50042F6000,"Yono and the Celestial Elephants",,playable,2021-01-28 18:23:58
|
||||
0100F110029C8000,"Yooka-Laylee",,playable,2021-01-28 14:21:45
|
||||
010022F00DA66000,"Yooka-Laylee and the Impossible Lair",,playable,2021-03-05 17:32:21
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using ARMeilleure.CodeGen.Linking;
|
||||
using ARMeilleure.CodeGen.Unwinding;
|
||||
using ARMeilleure.Translation.Cache;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ARMeilleure.CodeGen
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace ARMeilleure.Memory
|
||||
public const int DefaultGranularity = 65536; // Mapping granularity in Windows.
|
||||
|
||||
public IJitMemoryBlock Block { get; }
|
||||
public IJitMemoryAllocator Allocator { get; }
|
||||
|
||||
public nint Pointer => Block.Pointer;
|
||||
|
||||
@@ -22,7 +21,6 @@ namespace ARMeilleure.Memory
|
||||
granularity = DefaultGranularity;
|
||||
}
|
||||
|
||||
Allocator = allocator;
|
||||
Block = allocator.Reserve(maxSize);
|
||||
_maxSize = maxSize;
|
||||
_sizeGranularity = granularity;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using Ryujinx.Common.Memory.PartialUnmaps;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using ARMeilleure.Memory;
|
||||
using System;
|
||||
|
||||
namespace ARMeilleure.State
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ using ARMeilleure.Instructions;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
|
||||
@@ -2,8 +2,6 @@ using ARMeilleure.CodeGen;
|
||||
using ARMeilleure.CodeGen.Unwinding;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.Native;
|
||||
using Humanizer;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -20,8 +18,9 @@ namespace ARMeilleure.Translation.Cache
|
||||
private static readonly int _pageMask = _pageSize - 1;
|
||||
|
||||
private const int CodeAlignment = 4; // Bytes.
|
||||
private const int CacheSize = 256 * 1024 * 1024;
|
||||
private const int CacheSize = 2047 * 1024 * 1024;
|
||||
|
||||
private static ReservedRegion _jitRegion;
|
||||
private static JitCacheInvalidation _jitCacheInvalidator;
|
||||
|
||||
private static CacheMemoryAllocator _cacheAllocator;
|
||||
@@ -31,9 +30,6 @@ namespace ARMeilleure.Translation.Cache
|
||||
private static readonly Lock _lock = new();
|
||||
private static bool _initialized;
|
||||
|
||||
private static readonly List<ReservedRegion> _jitRegions = new();
|
||||
private static int _activeRegionIndex = 0;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
[LibraryImport("kernel32.dll", SetLastError = true)]
|
||||
public static partial nint FlushInstructionCache(nint hProcess, nint lpAddress, nuint dwSize);
|
||||
@@ -52,9 +48,7 @@ namespace ARMeilleure.Translation.Cache
|
||||
return;
|
||||
}
|
||||
|
||||
ReservedRegion firstRegion = new(allocator, CacheSize);
|
||||
_jitRegions.Add(firstRegion);
|
||||
_activeRegionIndex = 0;
|
||||
_jitRegion = new ReservedRegion(allocator, CacheSize);
|
||||
|
||||
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
|
||||
{
|
||||
@@ -65,9 +59,7 @@ namespace ARMeilleure.Translation.Cache
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
JitUnwindWindows.InstallFunctionTableHandler(
|
||||
firstRegion.Pointer, CacheSize, firstRegion.Pointer + Allocate(_pageSize)
|
||||
);
|
||||
JitUnwindWindows.InstallFunctionTableHandler(_jitRegion.Pointer, CacheSize, _jitRegion.Pointer + Allocate(_pageSize));
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
@@ -83,8 +75,8 @@ namespace ARMeilleure.Translation.Cache
|
||||
Debug.Assert(_initialized);
|
||||
|
||||
int funcOffset = Allocate(code.Length);
|
||||
ReservedRegion targetRegion = _jitRegions[_activeRegionIndex];
|
||||
nint funcPtr = targetRegion.Pointer + funcOffset;
|
||||
|
||||
nint funcPtr = _jitRegion.Pointer + funcOffset;
|
||||
|
||||
if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||
{
|
||||
@@ -98,9 +90,9 @@ namespace ARMeilleure.Translation.Cache
|
||||
}
|
||||
else
|
||||
{
|
||||
ReprotectAsWritable(targetRegion, funcOffset, code.Length);
|
||||
ReprotectAsWritable(funcOffset, code.Length);
|
||||
Marshal.Copy(code, 0, funcPtr, code.Length);
|
||||
ReprotectAsExecutable(targetRegion, funcOffset, code.Length);
|
||||
ReprotectAsExecutable(funcOffset, code.Length);
|
||||
|
||||
if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||
{
|
||||
@@ -124,82 +116,51 @@ namespace ARMeilleure.Translation.Cache
|
||||
{
|
||||
Debug.Assert(_initialized);
|
||||
|
||||
foreach (ReservedRegion region in _jitRegions)
|
||||
{
|
||||
if (pointer.ToInt64() < region.Pointer.ToInt64() ||
|
||||
pointer.ToInt64() >= (region.Pointer + CacheSize).ToInt64())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int funcOffset = (int)(pointer.ToInt64() - region.Pointer.ToInt64());
|
||||
int funcOffset = (int)(pointer.ToInt64() - _jitRegion.Pointer.ToInt64());
|
||||
|
||||
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
|
||||
{
|
||||
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
|
||||
_cacheEntries.RemoveAt(entryIndex);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReprotectAsWritable(ReservedRegion region, int offset, int size)
|
||||
private static void ReprotectAsWritable(int offset, int size)
|
||||
{
|
||||
int endOffs = offset + size;
|
||||
|
||||
int regionStart = offset & ~_pageMask;
|
||||
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
||||
|
||||
region.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||
_jitRegion.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||
}
|
||||
|
||||
private static void ReprotectAsExecutable(ReservedRegion region, int offset, int size)
|
||||
private static void ReprotectAsExecutable(int offset, int size)
|
||||
{
|
||||
int endOffs = offset + size;
|
||||
|
||||
int regionStart = offset & ~_pageMask;
|
||||
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
||||
|
||||
region.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||
_jitRegion.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||
}
|
||||
|
||||
private static int Allocate(int codeSize)
|
||||
{
|
||||
codeSize = AlignCodeSize(codeSize);
|
||||
|
||||
for (int i = _activeRegionIndex; i < _jitRegions.Count; i++)
|
||||
{
|
||||
int allocOffset = _cacheAllocator.Allocate(codeSize);
|
||||
|
||||
if (allocOffset >= 0)
|
||||
if (allocOffset < 0)
|
||||
{
|
||||
_jitRegions[i].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
||||
_activeRegionIndex = i;
|
||||
throw new OutOfMemoryException("JIT Cache exhausted.");
|
||||
}
|
||||
|
||||
_jitRegion.ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
||||
|
||||
return allocOffset;
|
||||
}
|
||||
}
|
||||
|
||||
int exhaustedRegion = _activeRegionIndex;
|
||||
var newRegion = new ReservedRegion(_jitRegions[0].Allocator, CacheSize);
|
||||
_jitRegions.Add(newRegion);
|
||||
_activeRegionIndex = _jitRegions.Count - 1;
|
||||
|
||||
int newRegionNumber = _activeRegionIndex;
|
||||
|
||||
Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((long)(newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation).");
|
||||
|
||||
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
|
||||
|
||||
int allocOffsetNew = _cacheAllocator.Allocate(codeSize);
|
||||
if (allocOffsetNew < 0)
|
||||
{
|
||||
throw new OutOfMemoryException("Failed to allocate in new Cache Region!");
|
||||
}
|
||||
|
||||
newRegion.ExpandIfNeeded((ulong)allocOffsetNew + (ulong)codeSize);
|
||||
return allocOffsetNew;
|
||||
}
|
||||
|
||||
|
||||
private static int AlignCodeSize(int codeSize)
|
||||
{
|
||||
@@ -223,8 +184,6 @@ namespace ARMeilleure.Translation.Cache
|
||||
public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
foreach (ReservedRegion _ in _jitRegions)
|
||||
{
|
||||
int index = _cacheEntries.BinarySearch(new CacheEntry(offset, 0, default));
|
||||
|
||||
@@ -240,7 +199,6 @@ namespace ARMeilleure.Translation.Cache
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entry = default;
|
||||
entryIndex = 0;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using ARMeilleure.Memory;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ARMeilleure.Translation.Cache
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
{
|
||||
class DelegateInfo
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
{
|
||||
delegate void DispatcherFunction(nint nativeContext, ulong startAddress);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
{
|
||||
delegate ulong GuestFunction(nint nativeContextPtr);
|
||||
|
||||
@@ -144,15 +144,17 @@ namespace ARMeilleure.Translation.PTC
|
||||
|
||||
public List<ulong> GetBlacklistedFunctions()
|
||||
{
|
||||
List<ulong> funcs = [];
|
||||
List<ulong> funcs = new List<ulong>();
|
||||
|
||||
foreach ((ulong ptr, FuncProfile funcProfile) in ProfiledFuncs)
|
||||
foreach (var profiledFunc in ProfiledFuncs)
|
||||
{
|
||||
if (!funcProfile.Blacklist)
|
||||
continue;
|
||||
|
||||
if (!funcs.Contains(ptr))
|
||||
funcs.Add(ptr);
|
||||
if (profiledFunc.Value.Blacklist)
|
||||
{
|
||||
if (!funcs.Contains(profiledFunc.Key))
|
||||
{
|
||||
funcs.Add(profiledFunc.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return funcs;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using ARMeilleure.Common;
|
||||
using System;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using ARMeilleure.Diagnostics;
|
||||
using ARMeilleure.Instructions;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.Signal;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation.Cache;
|
||||
using ARMeilleure.Translation.PTC;
|
||||
|
||||
@@ -4,6 +4,7 @@ using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation.Cache;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
|
||||
|
||||
@@ -4,6 +4,7 @@ using Ryujinx.Audio.Common;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Audio.Backends.Common
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using CpuAddress = System.UInt64;
|
||||
using DspAddress = System.UInt64;
|
||||
|
||||
@@ -6,16 +6,4 @@ namespace Ryujinx.Common.Configuration
|
||||
Unbounded,
|
||||
Custom
|
||||
}
|
||||
|
||||
public static class VSyncModeExtensions
|
||||
{
|
||||
public static VSyncMode Next(this VSyncMode vsync, bool customEnabled = false) =>
|
||||
vsync switch
|
||||
{
|
||||
VSyncMode.Switch => customEnabled ? VSyncMode.Custom : VSyncMode.Unbounded,
|
||||
VSyncMode.Unbounded => VSyncMode.Switch,
|
||||
VSyncMode.Custom => VSyncMode.Unbounded,
|
||||
_ => VSyncMode.Switch
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Win32;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Ryujinx.Common.Helper
|
||||
{
|
||||
public static partial class Patterns
|
||||
{
|
||||
#region Accessors
|
||||
|
||||
public static readonly Regex Numeric = NumericRegex();
|
||||
|
||||
public static readonly Regex AmdGcn = AmdGcnRegex();
|
||||
public static readonly Regex NvidiaConsumerClass = NvidiaConsumerClassRegex();
|
||||
|
||||
public static readonly Regex DomainLp1Ns = DomainLp1NsRegex();
|
||||
public static readonly Regex DomainLp1Lp1Npln = DomainLp1Lp1NplnRegex();
|
||||
public static readonly Regex DomainLp1Znc = DomainLp1ZncRegex();
|
||||
public static readonly Regex DomainSbApi = DomainSbApiRegex();
|
||||
public static readonly Regex DomainSbAccounts = DomainSbAccountsRegex();
|
||||
public static readonly Regex DomainAccounts = DomainAccountsRegex();
|
||||
|
||||
public static readonly Regex Module = ModuleRegex();
|
||||
public static readonly Regex FsSdk = FsSdkRegex();
|
||||
public static readonly Regex SdkMw = SdkMwRegex();
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public static readonly Regex CJK = CJKRegex();
|
||||
|
||||
public static readonly Regex LdnPassphrase = LdnPassphraseRegex();
|
||||
|
||||
public static readonly Regex CleanText = CleanTextRegex();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Generated pattern stubs
|
||||
|
||||
#region Numeric validation
|
||||
|
||||
[GeneratedRegex("[0-9]|.")]
|
||||
internal static partial Regex NumericRegex();
|
||||
|
||||
#endregion
|
||||
|
||||
#region GPU names
|
||||
|
||||
[GeneratedRegex(
|
||||
"Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\\d{2}(\\D|$))|([7-8]\\d{3}(\\D|$))|Fury|Nano))|(Pro Duo)")]
|
||||
internal static partial Regex AmdGcnRegex();
|
||||
|
||||
[GeneratedRegex("NVIDIA GeForce (R|G)?TX? (\\d{3}\\d?)M?")]
|
||||
internal static partial Regex NvidiaConsumerClassRegex();
|
||||
|
||||
#endregion
|
||||
|
||||
#region DNS blocking
|
||||
|
||||
public static readonly Regex[] BlockedHosts =
|
||||
[
|
||||
DomainLp1Ns,
|
||||
DomainLp1Lp1Npln,
|
||||
DomainLp1Znc,
|
||||
DomainSbApi,
|
||||
DomainSbAccounts,
|
||||
DomainAccounts
|
||||
];
|
||||
|
||||
const RegexOptions DnsRegexOpts =
|
||||
RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture;
|
||||
|
||||
[GeneratedRegex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", DnsRegexOpts)]
|
||||
internal static partial Regex DomainLp1NsRegex();
|
||||
|
||||
[GeneratedRegex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", DnsRegexOpts)]
|
||||
internal static partial Regex DomainLp1Lp1NplnRegex();
|
||||
|
||||
[GeneratedRegex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", DnsRegexOpts)]
|
||||
internal static partial Regex DomainLp1ZncRegex();
|
||||
|
||||
[GeneratedRegex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", DnsRegexOpts)]
|
||||
internal static partial Regex DomainSbApiRegex();
|
||||
|
||||
[GeneratedRegex(@"^(.*)\-sb\.accounts\.nintendo\.com$", DnsRegexOpts)]
|
||||
internal static partial Regex DomainSbAccountsRegex();
|
||||
|
||||
[GeneratedRegex(@"^accounts\.nintendo\.com$", DnsRegexOpts)]
|
||||
internal static partial Regex DomainAccountsRegex();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Executable information
|
||||
|
||||
[GeneratedRegex(@"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
|
||||
internal static partial Regex ModuleRegex();
|
||||
|
||||
[GeneratedRegex(@"sdk_version: ([0-9.]*)")]
|
||||
internal static partial Regex FsSdkRegex();
|
||||
|
||||
[GeneratedRegex(@"SDK MW[ -~]*")]
|
||||
internal static partial Regex SdkMwRegex();
|
||||
|
||||
#endregion
|
||||
|
||||
#region CJK
|
||||
|
||||
[GeneratedRegex(
|
||||
"\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")]
|
||||
private static partial Regex CJKRegex();
|
||||
|
||||
#endregion
|
||||
|
||||
[GeneratedRegex("Ryujinx-[0-9a-f]{8}")]
|
||||
private static partial Regex LdnPassphraseRegex();
|
||||
|
||||
[GeneratedRegex(@"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..")]
|
||||
private static partial Regex CleanTextRegex();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
using Gommon;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Common.Helper
|
||||
{
|
||||
public class RefEvent<T>
|
||||
{
|
||||
public delegate void Handler(ref T arg);
|
||||
|
||||
private readonly Lock _subLock = new();
|
||||
private readonly List<Handler> _subscriptions = [];
|
||||
|
||||
public bool HasSubscribers
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_subLock)
|
||||
return _subscriptions.Count != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<Handler> Subscriptions
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_subLock)
|
||||
return _subscriptions;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(Handler subscriber)
|
||||
{
|
||||
Guard.Require(subscriber, nameof(subscriber));
|
||||
lock (_subLock)
|
||||
_subscriptions.Add(subscriber);
|
||||
}
|
||||
|
||||
public void Remove(Handler subscriber)
|
||||
{
|
||||
Guard.Require(subscriber, nameof(subscriber));
|
||||
lock (_subLock)
|
||||
_subscriptions.Remove(subscriber);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock (_subLock)
|
||||
_subscriptions.Clear();
|
||||
}
|
||||
|
||||
public void Call(ref T arg)
|
||||
{
|
||||
foreach (Handler subscription in Subscriptions)
|
||||
subscription(ref arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,17 +11,13 @@ namespace Ryujinx.Common.Helper
|
||||
public static bool IsWindows => OperatingSystem.IsWindows();
|
||||
public static bool IsLinux => OperatingSystem.IsLinux();
|
||||
|
||||
public static bool IsArm => RuntimeInformation.OSArchitecture is Architecture.Arm64;
|
||||
public static bool IsIntelMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.X64;
|
||||
public static bool IsArmMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.Arm64;
|
||||
|
||||
public static bool IsX64 => RuntimeInformation.OSArchitecture is Architecture.X64;
|
||||
public static bool IsX64Windows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.X64);
|
||||
public static bool IsArmWindows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
|
||||
|
||||
public static bool IsIntelMac => IsMacOS && IsX64;
|
||||
public static bool IsArmMac => IsMacOS && IsArm;
|
||||
|
||||
public static bool IsX64Windows => IsWindows && IsX64;
|
||||
public static bool IsArmWindows => IsWindows && IsArm;
|
||||
|
||||
public static bool IsX64Linux => IsLinux && IsX64;
|
||||
public static bool IsArmLinux => IsLinux && IsArmMac;
|
||||
public static bool IsX64Linux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.X64);
|
||||
public static bool IsArmLinux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Helper;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Common
|
||||
{
|
||||
@@ -29,11 +30,10 @@ namespace Ryujinx.Common
|
||||
|
||||
public static readonly string[] GreatMetalTitles =
|
||||
[
|
||||
"01009b500007c000", // ARMS
|
||||
"010076f0049a2000", // Bayonetta
|
||||
"0100a5c00d162000", // Cuphead
|
||||
"010023800d64a000", // Deltarune
|
||||
"01003a30012c0000", // LEGO City Undercover
|
||||
"010048701995e000", // Luigi's Manion 2 HD
|
||||
"010028600EBDA000", // Mario 3D World
|
||||
"0100152000022000", // Mario Kart 8 Deluxe
|
||||
"010075a016a3a000", // Persona 4 Arena Ultimax
|
||||
@@ -47,15 +47,11 @@ namespace Ryujinx.Common
|
||||
"01006f8002326000", // Animal Crossings: New Horizons
|
||||
"01009bf0072d4000", // Captain Toad: Treasure Tracker
|
||||
"01009510001ca000", // Fast RMX
|
||||
"01005CA01580E000", // Persona 5 Royal
|
||||
"0100b880154fc000", // Persona 5 The Royal (Japan)
|
||||
"010015100b514000", // Super Mario Bros. Wonder
|
||||
"01005CA01580E000", // Persona 5 Royale
|
||||
"0100000000010000", // Super Mario Odyssey
|
||||
|
||||
// Further testing is appreciated, I did not test the entire game:
|
||||
//"010076f0049a2000", // Bayonetta
|
||||
//"0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon
|
||||
//"0100f4300bf2c000", // New Pokemon Snap
|
||||
//Isaac claims it has a issue in level 2, but I am not able to replicate it on my M3. More testing would be appreciated:
|
||||
"010015100b514000", // Super Mario Bros. Wonder
|
||||
];
|
||||
|
||||
public static string GetDiscordGameAsset(string titleId)
|
||||
@@ -163,16 +159,15 @@ namespace Ryujinx.Common
|
||||
"0100ba0018500000", // Splatoon 3: Splatfest World Premiere
|
||||
|
||||
//NSO Membership games
|
||||
"0100ccf019c8c000", // F-ZERO 99
|
||||
"0100c62011050000", // GB - Nintendo Switch Online
|
||||
"010012f017576000", // GBA - Nintendo Switch Online
|
||||
"0100c9a00ece6000", // N64 - Nintendo Switch Online
|
||||
"0100e0601c632000", // N64 - Nintendo Switch Online 18+
|
||||
"0100d870045b6000", // NES - Nintendo Switch Online
|
||||
"0100b3c014bda000", // SEGA Genesis - Nintendo Switch Online
|
||||
"01008d300c50c000", // SNES - Nintendo Switch Online
|
||||
"0100ccf019c8c000", // F-ZERO 99
|
||||
"0100ad9012510000", // PAC-MAN 99
|
||||
"010040600c5ce000", // Tetris 99
|
||||
"01008d300c50c000", // SNES - Nintendo Switch Online
|
||||
"0100277011f1a000", // Super Mario Bros. 35
|
||||
|
||||
//Misc Nintendo 1st party games
|
||||
@@ -218,7 +213,6 @@ namespace Ryujinx.Common
|
||||
//Misc Games
|
||||
"010056e00853a000", // A Hat in Time
|
||||
"0100fd1014726000", // Baldurs Gate: Dark Alliance
|
||||
"01008c2019598000", // Bluey: The Video Game
|
||||
"0100c6800b934000", // Brawlhalla
|
||||
"0100dbf01000a000", // Burnout Paradise Remastered
|
||||
"0100744001588000", // Cars 3: Driven to Win
|
||||
@@ -229,7 +223,6 @@ namespace Ryujinx.Common
|
||||
"01008c8012920000", // Dying Light Platinum Edition
|
||||
"01001cc01b2d4000", // Goat Simulator 3
|
||||
"01003620068ea000", // Hand of Fate 2
|
||||
"0100f7e00c70e000", // Hogwarts Legacy
|
||||
"010085500130a000", // Lego City: Undercover
|
||||
"010073c01af34000", // LEGO Horizon Adventures
|
||||
"0100d71004694000", // Minecraft
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Gommon;
|
||||
using Ryujinx.Common.Helper;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
@@ -56,7 +55,7 @@ namespace Ryujinx.Common.Utilities
|
||||
{
|
||||
_color = HsbToRgb((_color.GetHue() + Speed) / 360);
|
||||
|
||||
_updatedHandler.Call(ref _color);
|
||||
_updatedHandler.Call(_color.ToArgb());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,13 +67,13 @@ namespace Ryujinx.Common.Utilities
|
||||
_color = Color.Blue;
|
||||
}
|
||||
|
||||
public static event RefEvent<Color>.Handler Updated
|
||||
public static event Action<int> Updated
|
||||
{
|
||||
add => _updatedHandler.Add(value);
|
||||
remove => _updatedHandler.Remove(value);
|
||||
}
|
||||
|
||||
private static readonly RefEvent<Color> _updatedHandler = new();
|
||||
private static readonly Event<int> _updatedHandler = new();
|
||||
|
||||
private static Color HsbToRgb(float hue, float saturation = 1, float brightness = 1)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using ARMeilleure.State;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Ryujinx.Memory.Tracking;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using ARMeilleure.Common;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.Translation;
|
||||
using Ryujinx.Cpu.Signal;
|
||||
using Ryujinx.Memory;
|
||||
|
||||
namespace Ryujinx.Cpu.Jit
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using Ryujinx.Memory.Tracking;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
@@ -8,6 +8,7 @@ using Ryujinx.Memory.Tracking;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Ryujinx.Cpu.Jit
|
||||
|
||||
@@ -3,6 +3,7 @@ using ARMeilleure.Memory;
|
||||
using Ryujinx.Cpu.LightningJit.Arm32;
|
||||
using Ryujinx.Cpu.LightningJit.Arm64;
|
||||
using Ryujinx.Cpu.LightningJit.State;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Cpu.LightningJit
|
||||
|
||||
@@ -2,6 +2,7 @@ using ARMeilleure.Common;
|
||||
using ARMeilleure.Memory;
|
||||
using Ryujinx.Cpu.LightningJit.CodeGen;
|
||||
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Cpu.LightningJit.CodeGen;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Ryujinx.Cpu.LightningJit.CodeGen;
|
||||
|
||||
namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
||||
{
|
||||
static class InstEmitVfpMove
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Cpu.LightningJit.Arm64
|
||||
{
|
||||
static class SysUtils
|
||||
|
||||
@@ -3,6 +3,7 @@ using ARMeilleure.Memory;
|
||||
using Ryujinx.Cpu.LightningJit.CodeGen;
|
||||
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
|
||||
using Ryujinx.Cpu.LightningJit.Graph;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using ARMeilleure.Memory;
|
||||
using Humanizer;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -17,8 +15,9 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
||||
private static readonly int _pageMask = _pageSize - 1;
|
||||
|
||||
private const int CodeAlignment = 4; // Bytes.
|
||||
private const int CacheSize = 256 * 1024 * 1024;
|
||||
private const int CacheSize = 2047 * 1024 * 1024;
|
||||
|
||||
private static ReservedRegion _jitRegion;
|
||||
private static JitCacheInvalidation _jitCacheInvalidator;
|
||||
|
||||
private static CacheMemoryAllocator _cacheAllocator;
|
||||
@@ -27,8 +26,6 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
||||
|
||||
private static readonly Lock _lock = new();
|
||||
private static bool _initialized;
|
||||
private static readonly List<ReservedRegion> _jitRegions = new();
|
||||
private static int _activeRegionIndex = 0;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
[LibraryImport("kernel32.dll", SetLastError = true)]
|
||||
@@ -48,9 +45,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
||||
return;
|
||||
}
|
||||
|
||||
ReservedRegion firstRegion = new(allocator, CacheSize);
|
||||
_jitRegions.Add(firstRegion);
|
||||
_activeRegionIndex = 0;
|
||||
_jitRegion = new ReservedRegion(allocator, CacheSize);
|
||||
|
||||
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
|
||||
{
|
||||
@@ -70,8 +65,8 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
||||
Debug.Assert(_initialized);
|
||||
|
||||
int funcOffset = Allocate(code.Length);
|
||||
ReservedRegion targetRegion = _jitRegions[_activeRegionIndex];
|
||||
nint funcPtr = targetRegion.Pointer + funcOffset;
|
||||
|
||||
nint funcPtr = _jitRegion.Pointer + funcOffset;
|
||||
|
||||
if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||
{
|
||||
@@ -85,12 +80,19 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
||||
}
|
||||
else
|
||||
{
|
||||
ReprotectAsWritable(targetRegion, funcOffset, code.Length);
|
||||
Marshal.Copy(code.ToArray(), 0, funcPtr, code.Length);
|
||||
ReprotectAsExecutable(targetRegion, funcOffset, code.Length);
|
||||
ReprotectAsWritable(funcOffset, code.Length);
|
||||
code.CopyTo(new Span<byte>((void*)funcPtr, code.Length));
|
||||
ReprotectAsExecutable(funcOffset, code.Length);
|
||||
|
||||
if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||
{
|
||||
FlushInstructionCache(Process.GetCurrentProcess().Handle, funcPtr, (nuint)code.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
_jitCacheInvalidator?.Invalidate(funcPtr, (ulong)code.Length);
|
||||
}
|
||||
}
|
||||
|
||||
Add(funcOffset, code.Length);
|
||||
|
||||
@@ -104,81 +106,51 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
||||
{
|
||||
Debug.Assert(_initialized);
|
||||
|
||||
foreach (ReservedRegion region in _jitRegions)
|
||||
{
|
||||
if (pointer.ToInt64() < region.Pointer.ToInt64() ||
|
||||
pointer.ToInt64() >= (region.Pointer + CacheSize).ToInt64())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int funcOffset = (int)(pointer.ToInt64() - region.Pointer.ToInt64());
|
||||
int funcOffset = (int)(pointer.ToInt64() - _jitRegion.Pointer.ToInt64());
|
||||
|
||||
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
|
||||
{
|
||||
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
|
||||
_cacheEntries.RemoveAt(entryIndex);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReprotectAsWritable(ReservedRegion region, int offset, int size)
|
||||
private static void ReprotectAsWritable(int offset, int size)
|
||||
{
|
||||
int endOffs = offset + size;
|
||||
|
||||
int regionStart = offset & ~_pageMask;
|
||||
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
||||
|
||||
region.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||
_jitRegion.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||
}
|
||||
|
||||
private static void ReprotectAsExecutable(ReservedRegion region, int offset, int size)
|
||||
private static void ReprotectAsExecutable(int offset, int size)
|
||||
{
|
||||
int endOffs = offset + size;
|
||||
|
||||
int regionStart = offset & ~_pageMask;
|
||||
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
||||
|
||||
region.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||
_jitRegion.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||
}
|
||||
|
||||
private static int Allocate(int codeSize)
|
||||
{
|
||||
codeSize = AlignCodeSize(codeSize);
|
||||
|
||||
for (int i = _activeRegionIndex; i < _jitRegions.Count; i++)
|
||||
{
|
||||
int allocOffset = _cacheAllocator.Allocate(codeSize);
|
||||
|
||||
if (allocOffset >= 0)
|
||||
if (allocOffset < 0)
|
||||
{
|
||||
_jitRegions[i].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
||||
_activeRegionIndex = i;
|
||||
throw new OutOfMemoryException("JIT Cache exhausted.");
|
||||
}
|
||||
|
||||
_jitRegion.ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
||||
|
||||
return allocOffset;
|
||||
}
|
||||
}
|
||||
|
||||
int exhaustedRegion = _activeRegionIndex;
|
||||
ReservedRegion newRegion = new(_jitRegions[0].Allocator, CacheSize);
|
||||
_jitRegions.Add(newRegion);
|
||||
_activeRegionIndex = _jitRegions.Count - 1;
|
||||
|
||||
int newRegionNumber = _activeRegionIndex;
|
||||
|
||||
Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((long)(newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation).");
|
||||
|
||||
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
|
||||
|
||||
int allocOffsetNew = _cacheAllocator.Allocate(codeSize);
|
||||
if (allocOffsetNew < 0)
|
||||
{
|
||||
throw new OutOfMemoryException("Failed to allocate in new Cache Region!");
|
||||
}
|
||||
|
||||
newRegion.ExpandIfNeeded((ulong)allocOffsetNew + (ulong)codeSize);
|
||||
return allocOffsetNew;
|
||||
}
|
||||
|
||||
private static int AlignCodeSize(int codeSize)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using ARMeilleure.Memory;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Cpu.LightningJit.Cache
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
||||
{
|
||||
private const int CodeAlignment = 4; // Bytes.
|
||||
private const int SharedCacheSize = 2047 * 1024 * 1024;
|
||||
private const int LocalCacheSize = 256 * 1024 * 1024;
|
||||
private const int LocalCacheSize = 128 * 1024 * 1024;
|
||||
|
||||
// How many calls to the same function we allow until we pad the shared cache to force the function to become available there
|
||||
// and allow the guest to take the fast path.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Cpu.LightningJit
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Cpu.LightningJit
|
||||
{
|
||||
class TranslatedFunction
|
||||
|
||||
@@ -5,6 +5,7 @@ using Ryujinx.Cpu.LightningJit.Cache;
|
||||
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
|
||||
using Ryujinx.Cpu.LightningJit.State;
|
||||
using Ryujinx.Cpu.Signal;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Cpu.Signal
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Graphics.Device
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Ryujinx.Graphics.Device;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
@@ -4,6 +4,7 @@ using Ryujinx.Graphics.Gpu.Memory;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using Ryujinx.Memory;
|
||||
using Ryujinx.Memory.Range;
|
||||
using System;
|
||||
|
||||
@@ -7,6 +7,7 @@ using Ryujinx.Memory;
|
||||
using Ryujinx.Memory.Range;
|
||||
using Ryujinx.Memory.Tracking;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu.Engine;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Shader
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Ryujinx.Graphics.Gpu.Synchronization
|
||||
}
|
||||
|
||||
using ManualResetEvent waitEvent = new(false);
|
||||
SyncpointWaiterHandle info = _syncpoints[id].RegisterCallback(threshold, _ => waitEvent.Set());
|
||||
SyncpointWaiterHandle info = _syncpoints[id].RegisterCallback(threshold, (x) => waitEvent.Set());
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
@@ -96,7 +96,7 @@ namespace Ryujinx.Graphics.Gpu.Synchronization
|
||||
|
||||
bool signaled = waitEvent.WaitOne(timeout);
|
||||
|
||||
if (!signaled)
|
||||
if (!signaled && info != null)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Gpu, $"Wait on syncpoint {id} for threshold {threshold} took more than {timeout.TotalMilliseconds}ms, resuming execution...");
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using SharpMetal.Metal;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Ryujinx.Graphics.Metal
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||
{
|
||||
struct AVCodec
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||
{
|
||||
struct AVCodec501
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||
{
|
||||
struct FFCodec<T> where T : struct
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||
{
|
||||
struct FFCodecLegacy<T> where T : struct
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Ryujinx.Graphics.Nvdec.FFmpeg.Native;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
||||
{
|
||||
|
||||
@@ -1,75 +1,56 @@
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal enum CodecErr
|
||||
{
|
||||
/// <summary>
|
||||
/// Operation completed without error
|
||||
/// </summary>
|
||||
Ok,
|
||||
/*!\brief Operation completed without error */
|
||||
CodecOk,
|
||||
|
||||
/// <summary>
|
||||
/// Unspecified error
|
||||
/// </summary>
|
||||
Error,
|
||||
/*!\brief Unspecified error */
|
||||
CodecError,
|
||||
|
||||
/// <summary>
|
||||
/// Memory operation failed
|
||||
/// </summary>
|
||||
MemError,
|
||||
/*!\brief Memory operation failed */
|
||||
CodecMemError,
|
||||
|
||||
/// <summary>
|
||||
/// ABI version mismatch
|
||||
/// </summary>
|
||||
AbiMismatch,
|
||||
/*!\brief ABI version mismatch */
|
||||
CodecAbiMismatch,
|
||||
|
||||
/// <summary>
|
||||
/// Algorithm does not have required capability
|
||||
/// </summary>
|
||||
Incapable,
|
||||
/*!\brief Algorithm does not have required capability */
|
||||
CodecIncapable,
|
||||
|
||||
/// <summary>
|
||||
/// The given bitstream is not supported.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The bitstream was unable to be parsed at the highest level.<br/>
|
||||
/// The decoder is unable to proceed.<br/>
|
||||
/// This error SHOULD be treated as fatal to the stream.
|
||||
/// </remarks>
|
||||
UnsupBitstream,
|
||||
/*!\brief The given bitstream is not supported.
|
||||
*
|
||||
* The bitstream was unable to be parsed at the highest level. The decoder
|
||||
* is unable to proceed. This error \ref SHOULD be treated as fatal to the
|
||||
* stream. */
|
||||
CodecUnsupBitstream,
|
||||
|
||||
/// <summary>
|
||||
/// Encoded bitstream uses an unsupported feature
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The decoder does not implement a feature required by the encoder.<br/>
|
||||
/// This return code should only be used for features that prevent future
|
||||
/// pictures from being properly decoded.<br/>
|
||||
/// <br/>
|
||||
/// This error MAY be treated as fatal to the stream or MAY be treated as fatal to the current GOP.
|
||||
/// </remarks>
|
||||
UnsupFeature,
|
||||
/*!\brief Encoded bitstream uses an unsupported feature
|
||||
*
|
||||
* The decoder does not implement a feature required by the encoder. This
|
||||
* return code should only be used for features that prevent future
|
||||
* pictures from being properly decoded. This error \ref MAY be treated as
|
||||
* fatal to the stream or \ref MAY be treated as fatal to the current GOP.
|
||||
*/
|
||||
CodecUnsupFeature,
|
||||
|
||||
/// <summary>
|
||||
/// The coded data for this stream is corrupt or incomplete.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There was a problem decoding the current frame.<br/>
|
||||
/// This return code should only be used
|
||||
/// for failures that prevent future pictures from being properly decoded.<br/>
|
||||
/// <br/>
|
||||
/// This error MAY be treated as fatal to the stream or MAY be treated as fatal to the current GOP.<br/>
|
||||
/// If decoding is continued for the current GOP, artifacts may be present.
|
||||
/// </remarks>
|
||||
CorruptFrame,
|
||||
/*!\brief The coded data for this stream is corrupt or incomplete
|
||||
*
|
||||
* There was a problem decoding the current frame. This return code
|
||||
* should only be used for failures that prevent future pictures from
|
||||
* being properly decoded. This error \ref MAY be treated as fatal to the
|
||||
* stream or \ref MAY be treated as fatal to the current GOP. If decoding
|
||||
* is continued for the current GOP, artifacts may be present.
|
||||
*/
|
||||
CodecCorruptFrame,
|
||||
|
||||
/// <summary>
|
||||
/// An application-supplied parameter is not valid.
|
||||
/// </summary>
|
||||
InvalidParam,
|
||||
/*!\brief An application-supplied parameter is not valid.
|
||||
*
|
||||
*/
|
||||
CodecInvalidParam,
|
||||
|
||||
/// <summary>
|
||||
/// An iterator reached the end of list.
|
||||
/// </summary>
|
||||
ListEnd
|
||||
/*!\brief An iterator reached the end of list.
|
||||
*
|
||||
*/
|
||||
CodecListEnd,
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte ClipPixel(int val)
|
||||
{
|
||||
return (byte)(val > 255 ? 255 : val < 0 ? 0 : val);
|
||||
return (byte)((val > 255) ? 255 : (val < 0) ? 0 : val);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
||||
@@ -51,7 +51,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
||||
{
|
||||
Marshal.FreeHGlobal(item.Pointer);
|
||||
}
|
||||
|
||||
item.Pointer = ptr;
|
||||
item.Length = lengthInBytes;
|
||||
break;
|
||||
@@ -59,11 +58,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
||||
}
|
||||
}
|
||||
|
||||
ArrayPtr<T> allocation = new ArrayPtr<T>(ptr, length);
|
||||
|
||||
allocation.AsSpan().Fill(default);
|
||||
|
||||
return allocation;
|
||||
return new ArrayPtr<T>(ptr, length);
|
||||
}
|
||||
|
||||
public unsafe void Free<T>(ArrayPtr<T> arr) where T : unmanaged
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class Constants
|
||||
{
|
||||
public const int InterpExtend = 4;
|
||||
public const int Vp9InterpExtend = 4;
|
||||
|
||||
public const int MaxMbPlane = 3;
|
||||
|
||||
@@ -27,7 +25,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
/* Segment Feature Masks */
|
||||
public const int MaxMvRefCandidates = 2;
|
||||
|
||||
public const int IntraInterContexts = 4;
|
||||
public const int CompInterContexts = 5;
|
||||
public const int RefContexts = 5;
|
||||
|
||||
@@ -35,26 +32,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
public const int EightTapSmooth = 1;
|
||||
public const int EightTapSharp = 2;
|
||||
public const int SwitchableFilters = 3; /* Number of switchable filters */
|
||||
|
||||
public const int Bilinear = 3;
|
||||
|
||||
// The codec can operate in four possible inter prediction filter mode:
|
||||
// 8-tap, 8-tap-smooth, 8-tap-sharp, and switching between the three.
|
||||
public const int SwitchableFilterContexts = SwitchableFilters + 1;
|
||||
public const int Switchable = 4; /* Should be the last one */
|
||||
public const int Switchable = 4; /* should be the last one */
|
||||
|
||||
// Frame
|
||||
public const int RefsPerFrame = 3;
|
||||
|
||||
public const int RefFramesLog2 = 3;
|
||||
public const int RefFrames = 1 << RefFramesLog2;
|
||||
|
||||
// 1 scratch frame for the new frame, 3 for scaled references on the encoder.
|
||||
public const int FrameBuffers = RefFrames + 4;
|
||||
|
||||
public const int FrameContextsLog2 = 2;
|
||||
public const int FrameContexts = 1 << FrameContextsLog2;
|
||||
|
||||
public const int NumPingPongBuffers = 2;
|
||||
|
||||
public const int Class0Bits = 1; /* bits at integer precision for class 0 */
|
||||
@@ -82,19 +65,5 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
public const int SegmentAbsData = 1;
|
||||
public const int MaxSegments = 8;
|
||||
|
||||
public const int PartitionTypes = (int)PartitionType.PartitionTypes;
|
||||
|
||||
public const int PartitionPlOffset = 4; // Number of probability models per block size
|
||||
public const int PartitionContexts = 4 * PartitionPlOffset;
|
||||
|
||||
public const int PlaneTypes = (int)PlaneType.PlaneTypes;
|
||||
|
||||
public const int IntraModes = (int)PredictionMode.TmPred + 1;
|
||||
|
||||
public const int InterModes = 1 + (int)PredictionMode.NewMv - (int)PredictionMode.NearestMv;
|
||||
|
||||
public const int SkipContexts = 3;
|
||||
public const int InterModeContexts = 7;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class DSubExp
|
||||
{
|
||||
public static int InvRecenterNonneg(int v, int m)
|
||||
{
|
||||
if (v > 2 * m)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
return (v & 1) != 0 ? m - ((v + 1) >> 1) : m + (v >> 1);
|
||||
}
|
||||
|
||||
private static readonly byte[] InvMapTable =
|
||||
{
|
||||
7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176, 189, 202, 215, 228, 241, 254, 1, 2, 3, 4,
|
||||
5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34,
|
||||
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62,
|
||||
63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90,
|
||||
91, 92, 93, 94, 95, 96, 97, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114,
|
||||
115, 116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
|
||||
138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157, 158, 159,
|
||||
160, 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
|
||||
183, 184, 185, 186, 187, 188, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205,
|
||||
206, 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
|
||||
229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250,
|
||||
251, 252, 253, 253
|
||||
};
|
||||
|
||||
public static int InvRemapProb(int v, int m)
|
||||
{
|
||||
Debug.Assert(v < InvMapTable.Length / sizeof(byte));
|
||||
|
||||
v = InvMapTable[v];
|
||||
m--;
|
||||
if (m << 1 <= Prob.MaxProb)
|
||||
{
|
||||
return 1 + InvRecenterNonneg(v, m);
|
||||
}
|
||||
|
||||
return Prob.MaxProb - InvRecenterNonneg(v, Prob.MaxProb - 1 - m);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Dsp;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
@@ -10,11 +10,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class DecodeMv
|
||||
{
|
||||
private const int RefNeighbours = 8;
|
||||
private const int MvrefNeighbours = 8;
|
||||
|
||||
private static PredictionMode ReadIntraMode(ref Reader r, ReadOnlySpan<byte> p)
|
||||
{
|
||||
return (PredictionMode)r.ReadTree(Luts.IntraModeTree, p);
|
||||
return (PredictionMode)r.ReadTree(Luts.Vp9IntraModeTree, p);
|
||||
}
|
||||
|
||||
private static PredictionMode ReadIntraModeY(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r, int sizeGroup)
|
||||
@@ -41,7 +41,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private static PredictionMode ReadInterMode(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r, int ctx)
|
||||
{
|
||||
int mode = r.ReadTree(Luts.InterModeTree, cm.Fc.Value.InterModeProb[ctx].AsSpan());
|
||||
int mode = r.ReadTree(Luts.Vp9InterModeTree, cm.Fc.Value.InterModeProb[ctx].AsSpan());
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
++xd.Counts.Value.InterMode[ctx][mode];
|
||||
@@ -52,18 +52,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private static int ReadSegmentId(ref Reader r, ref Array7<byte> segTreeProbs)
|
||||
{
|
||||
return r.ReadTree(Luts.SegmentTree, segTreeProbs.AsSpan());
|
||||
return r.ReadTree(Luts.Vp9SegmentTree, segTreeProbs.AsSpan());
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> GetTxProbs(ref Vp9EntropyProbs fc, TxSize maxTxSize, int ctx)
|
||||
{
|
||||
switch (maxTxSize)
|
||||
{
|
||||
case TxSize.Tx8x8: return fc.Tx8x8Prob[ctx].AsSpan();
|
||||
case TxSize.Tx16x16: return fc.Tx16x16Prob[ctx].AsSpan();
|
||||
case TxSize.Tx32x32: return fc.Tx32x32Prob[ctx].AsSpan();
|
||||
case TxSize.Tx8x8:
|
||||
return fc.Tx8x8Prob[ctx].AsSpan();
|
||||
case TxSize.Tx16x16:
|
||||
return fc.Tx16x16Prob[ctx].AsSpan();
|
||||
case TxSize.Tx32x32:
|
||||
return fc.Tx32x32Prob[ctx].AsSpan();
|
||||
default:
|
||||
Debug.Assert(false, "Invalid maxTxSize.");
|
||||
|
||||
return ReadOnlySpan<byte>.Empty;
|
||||
}
|
||||
}
|
||||
@@ -72,11 +76,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
switch (maxTxSize)
|
||||
{
|
||||
case TxSize.Tx8x8: return counts.Tx8x8[ctx].AsSpan();
|
||||
case TxSize.Tx16x16: return counts.Tx16x16[ctx].AsSpan();
|
||||
case TxSize.Tx32x32: return counts.Tx32x32[ctx].AsSpan();
|
||||
case TxSize.Tx8x8:
|
||||
return counts.Tx8x8[ctx].AsSpan();
|
||||
case TxSize.Tx16x16:
|
||||
return counts.Tx16x16[ctx].AsSpan();
|
||||
case TxSize.Tx32x32:
|
||||
return counts.Tx32x32[ctx].AsSpan();
|
||||
default:
|
||||
Debug.Assert(false, "Invalid maxTxSize.");
|
||||
|
||||
return Span<uint>.Empty;
|
||||
}
|
||||
}
|
||||
@@ -116,32 +124,34 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return (TxSize)Math.Min((int)maxTxSize, (int)Luts.TxModeToBiggestTxSize[(int)txMode]);
|
||||
}
|
||||
|
||||
private static int DecGetSegmentId(ref Vp9Common cm, ArrayPtr<byte> segmentIds, int miOffset, int xMis,
|
||||
int yMis)
|
||||
private static int DecGetSegmentId(ref Vp9Common cm, ArrayPtr<byte> segmentIds, int miOffset, int xMis, int yMis)
|
||||
{
|
||||
int segmentId = int.MaxValue;
|
||||
int x, y, segmentId = int.MaxValue;
|
||||
|
||||
for (int y = 0; y < yMis; y++)
|
||||
for (y = 0; y < yMis; y++)
|
||||
{
|
||||
for (int x = 0; x < xMis; x++)
|
||||
for (x = 0; x < xMis; x++)
|
||||
{
|
||||
segmentId = Math.Min(segmentId, segmentIds[miOffset + (y * cm.MiCols) + x]);
|
||||
segmentId = Math.Min(segmentId, segmentIds[miOffset + y * cm.MiCols + x]);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Assert(segmentId >= 0 && segmentId < Constants.MaxSegments);
|
||||
|
||||
return segmentId;
|
||||
}
|
||||
|
||||
private static void SetSegmentId(ref Vp9Common cm, int miOffset, int xMis, int yMis, int segmentId)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
Debug.Assert(segmentId >= 0 && segmentId < Constants.MaxSegments);
|
||||
|
||||
for (int y = 0; y < yMis; y++)
|
||||
for (y = 0; y < yMis; y++)
|
||||
{
|
||||
for (int x = 0; x < xMis; x++)
|
||||
for (x = 0; x < xMis; x++)
|
||||
{
|
||||
cm.CurrentFrameSegMap[miOffset + (y * cm.MiCols) + x] = (byte)segmentId;
|
||||
cm.CurrentFrameSegMap[miOffset + y * cm.MiCols + x] = (byte)segmentId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,13 +164,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int xMis,
|
||||
int yMis)
|
||||
{
|
||||
for (int y = 0; y < yMis; y++)
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < yMis; y++)
|
||||
{
|
||||
for (int x = 0; x < xMis; x++)
|
||||
for (x = 0; x < xMis; x++)
|
||||
{
|
||||
currentSegmentIds[miOffset + (y * cm.MiCols) + x] = (byte)(!lastSegmentIds.IsNull
|
||||
? lastSegmentIds[miOffset + (y * cm.MiCols) + x]
|
||||
: 0);
|
||||
currentSegmentIds[miOffset + y * cm.MiCols + x] = (byte)(!lastSegmentIds.IsNull ? lastSegmentIds[miOffset + y * cm.MiCols + x] : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,11 +188,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (!seg.UpdateMap)
|
||||
{
|
||||
CopySegmentId(ref cm, cm.LastFrameSegMap, cm.CurrentFrameSegMap, miOffset, xMis, yMis);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
segmentId = ReadSegmentId(ref r, ref cm.Fc.Value.SegTreeProb);
|
||||
SetSegmentId(ref cm, miOffset, xMis, yMis, segmentId);
|
||||
|
||||
return segmentId;
|
||||
}
|
||||
|
||||
@@ -198,7 +210,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Segmentation seg = ref cm.Seg;
|
||||
ref ModeInfo mi = ref xd.Mi[0].Value;
|
||||
int predictedSegmentId, segmentId;
|
||||
int miOffset = (miRow * cm.MiCols) + miCol;
|
||||
int miOffset = miRow * cm.MiCols + miCol;
|
||||
|
||||
if (!seg.Enabled)
|
||||
{
|
||||
@@ -212,6 +224,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (!seg.UpdateMap)
|
||||
{
|
||||
CopySegmentId(ref cm, cm.LastFrameSegMap, cm.CurrentFrameSegMap, miOffset, xMis, yMis);
|
||||
|
||||
return predictedSegmentId;
|
||||
}
|
||||
|
||||
@@ -219,22 +232,20 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
byte predProb = Segmentation.GetPredProbSegId(ref cm.Fc.Value.SegPredProb, ref xd);
|
||||
mi.SegIdPredicted = (sbyte)r.Read(predProb);
|
||||
segmentId = mi.SegIdPredicted != 0
|
||||
? predictedSegmentId
|
||||
: ReadSegmentId(ref r, ref cm.Fc.Value.SegTreeProb);
|
||||
segmentId = mi.SegIdPredicted != 0 ? predictedSegmentId : ReadSegmentId(ref r, ref cm.Fc.Value.SegTreeProb);
|
||||
}
|
||||
else
|
||||
{
|
||||
segmentId = ReadSegmentId(ref r, ref cm.Fc.Value.SegTreeProb);
|
||||
}
|
||||
|
||||
SetSegmentId(ref cm, miOffset, xMis, yMis, segmentId);
|
||||
|
||||
return segmentId;
|
||||
}
|
||||
|
||||
private static int ReadSkip(ref Vp9Common cm, ref MacroBlockD xd, int segmentId, ref Reader r)
|
||||
{
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.Skip) != 0)
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.SegLvlSkip) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -249,12 +260,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return skip;
|
||||
}
|
||||
|
||||
private static int ReadComponent(ref Reader r, ref Vp9EntropyProbs fc, int mvcomp, bool usehp)
|
||||
private static int ReadMvComponent(ref Reader r, ref Vp9EntropyProbs fc, int mvcomp, bool usehp)
|
||||
{
|
||||
int mag, d, fr, hp;
|
||||
bool sign = r.Read(fc.Sign[mvcomp]) != 0;
|
||||
MvClassType mvClass = (MvClassType)r.ReadTree(Luts.MvClassTree, fc.Classes[mvcomp].AsSpan());
|
||||
bool class0 = mvClass == MvClassType.Class0;
|
||||
MvClassType mvClass = (MvClassType)r.ReadTree(Luts.Vp9MvClassTree, fc.Classes[mvcomp].AsSpan());
|
||||
bool class0 = mvClass == MvClassType.MvClass0;
|
||||
|
||||
// Integer part
|
||||
if (class0)
|
||||
@@ -264,10 +275,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
int n = (int)mvClass + Constants.Class0Bits - 1; // Number of bits
|
||||
|
||||
d = 0;
|
||||
for (int i = 0; i < n; ++i)
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
d |= r.Read(fc.Bits[mvcomp][i]) << i;
|
||||
}
|
||||
@@ -276,39 +288,40 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
// Fractional part
|
||||
fr = r.ReadTree(Luts.MvFPTree, class0 ? fc.Class0Fp[mvcomp][d].AsSpan() : fc.Fp[mvcomp].AsSpan());
|
||||
fr = r.ReadTree(Luts.Vp9MvFPTree, class0 ? fc.Class0Fp[mvcomp][d].AsSpan() : fc.Fp[mvcomp].AsSpan());
|
||||
|
||||
// High precision part (if hp is not used, the default value of the hp is 1)
|
||||
hp = usehp ? r.Read(class0 ? fc.Class0Hp[mvcomp] : fc.Hp[mvcomp]) : 1;
|
||||
|
||||
// Result
|
||||
mag += ((d << 3) | (fr << 1) | hp) + 1;
|
||||
|
||||
return sign ? -mag : mag;
|
||||
}
|
||||
|
||||
private static void Read(
|
||||
private static void ReadMv(
|
||||
ref Reader r,
|
||||
ref Mv mv,
|
||||
ref Mv refr,
|
||||
ref Vp9EntropyProbs fc,
|
||||
Ptr<Vp9BackwardUpdates> counts,
|
||||
bool allowHp)
|
||||
bool allowHP)
|
||||
{
|
||||
MvJointType jointType = (MvJointType)r.ReadTree(Luts.MvJointTree, fc.Joints.AsSpan());
|
||||
bool useHp = allowHp && refr.UseHp();
|
||||
MvJointType jointType = (MvJointType)r.ReadTree(Luts.Vp9MvJointTree, fc.Joints.AsSpan());
|
||||
bool useHP = allowHP && refr.UseMvHp();
|
||||
Mv diff = new();
|
||||
|
||||
if (Mv.JointVertical(jointType))
|
||||
if (Mv.MvJointVertical(jointType))
|
||||
{
|
||||
diff.Row = (short)ReadComponent(ref r, ref fc, 0, useHp);
|
||||
diff.Row = (short)ReadMvComponent(ref r, ref fc, 0, useHP);
|
||||
}
|
||||
|
||||
if (Mv.JointHorizontal(jointType))
|
||||
if (Mv.MvJointHorizontal(jointType))
|
||||
{
|
||||
diff.Col = (short)ReadComponent(ref r, ref fc, 1, useHp);
|
||||
diff.Col = (short)ReadMvComponent(ref r, ref fc, 1, useHP);
|
||||
}
|
||||
|
||||
diff.Inc(counts);
|
||||
diff.IncMv(counts);
|
||||
|
||||
mv.Row = (short)(refr.Row + diff.Row);
|
||||
mv.Col = (short)(refr.Col + diff.Col);
|
||||
@@ -316,7 +329,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private static ReferenceMode ReadBlockReferenceMode(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r)
|
||||
{
|
||||
if (cm.ReferenceMode == ReferenceMode.Select)
|
||||
if (cm.ReferenceMode == ReferenceMode.ReferenceModeSelect)
|
||||
{
|
||||
int ctx = PredCommon.GetReferenceModeContext(ref cm, ref xd);
|
||||
ReferenceMode mode = (ReferenceMode)r.Read(cm.Fc.Value.CompInterProb[ctx]);
|
||||
@@ -341,15 +354,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
ref Vp9EntropyProbs fc = ref cm.Fc.Value;
|
||||
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.RefFrame) != 0)
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.SegLvlRefFrame) != 0)
|
||||
{
|
||||
refFrame[0] = (sbyte)cm.Seg.GetSegData(segmentId, SegLvlFeatures.RefFrame);
|
||||
refFrame[0] = (sbyte)cm.Seg.GetSegData(segmentId, SegLvlFeatures.SegLvlRefFrame);
|
||||
refFrame[1] = Constants.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReferenceMode mode = ReadBlockReferenceMode(ref cm, ref xd, ref r);
|
||||
if (mode == ReferenceMode.Compound)
|
||||
if (mode == ReferenceMode.CompoundReference)
|
||||
{
|
||||
int idx = cm.RefFrameSignBias[cm.CompFixedRef];
|
||||
int ctx = PredCommon.GetPredContextCompRefP(ref cm, ref xd);
|
||||
@@ -362,7 +375,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
refFrame[idx] = cm.CompFixedRef;
|
||||
refFrame[idx == 0 ? 1 : 0] = cm.CompVarRef[bit];
|
||||
}
|
||||
else if (mode == ReferenceMode.Single)
|
||||
else if (mode == ReferenceMode.SingleReference)
|
||||
{
|
||||
int ctx0 = PredCommon.GetPredContextSingleRefP1(ref xd);
|
||||
int bit0 = r.Read(fc.SingleRefProb[ctx0][0]);
|
||||
@@ -399,7 +412,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
private static byte ReadSwitchableInterpFilter(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r)
|
||||
{
|
||||
int ctx = xd.GetPredContextSwitchableInterp();
|
||||
byte type = (byte)r.ReadTree(Luts.SwitchableInterpTree, cm.Fc.Value.SwitchableInterpProb[ctx].AsSpan());
|
||||
byte type = (byte)r.ReadTree(Luts.Vp9SwitchableInterpTree, cm.Fc.Value.SwitchableInterpProb[ctx].AsSpan());
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
++xd.Counts.Value.SwitchableInterp[ctx][type];
|
||||
@@ -411,12 +424,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
private static void ReadIntraBlockModeInfo(ref Vp9Common cm, ref MacroBlockD xd, ref ModeInfo mi, ref Reader r)
|
||||
{
|
||||
BlockSize bsize = mi.SbType;
|
||||
|
||||
int i;
|
||||
|
||||
switch (bsize)
|
||||
{
|
||||
case BlockSize.Block4x4:
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
mi.Bmi[i].Mode = ReadIntraModeY(ref cm, ref xd, ref r, 0);
|
||||
}
|
||||
@@ -446,19 +459,27 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
mi.RefFrame[1] = Constants.None;
|
||||
}
|
||||
|
||||
private static void CopyPair(ref Array2<Mv> dst, ref Array2<Mv> src)
|
||||
private static bool IsMvValid(ref Mv mv)
|
||||
{
|
||||
return mv.Row > Constants.MvLow &&
|
||||
mv.Row < Constants.MvUpp &&
|
||||
mv.Col > Constants.MvLow &&
|
||||
mv.Col < Constants.MvUpp;
|
||||
}
|
||||
|
||||
private static void CopyMvPair(ref Array2<Mv> dst, ref Array2<Mv> src)
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
}
|
||||
|
||||
private static void ZeroPair(ref Array2<Mv> dst)
|
||||
private static void ZeroMvPair(ref Array2<Mv> dst)
|
||||
{
|
||||
dst[0] = new Mv();
|
||||
dst[1] = new Mv();
|
||||
}
|
||||
|
||||
private static bool Assign(
|
||||
private static bool AssignMv(
|
||||
ref Vp9Common cm,
|
||||
ref MacroBlockD xd,
|
||||
PredictionMode mode,
|
||||
@@ -466,45 +487,45 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Array2<Mv> refMv,
|
||||
ref Array2<Mv> nearNearestMv,
|
||||
int isCompound,
|
||||
bool allowHp,
|
||||
bool allowHP,
|
||||
ref Reader r)
|
||||
{
|
||||
int i;
|
||||
bool ret = true;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case PredictionMode.NewMv:
|
||||
{
|
||||
for (int i = 0; i < 1 + isCompound; ++i)
|
||||
for (i = 0; i < 1 + isCompound; ++i)
|
||||
{
|
||||
Read(ref r, ref mv[i], ref refMv[i], ref cm.Fc.Value, xd.Counts, allowHp);
|
||||
ret = ret && mv[i].IsValid();
|
||||
ReadMv(ref r, ref mv[i], ref refMv[i], ref cm.Fc.Value, xd.Counts, allowHP);
|
||||
ret = ret && IsMvValid(ref mv[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PredictionMode.NearMv:
|
||||
case PredictionMode.NearestMv:
|
||||
{
|
||||
CopyPair(ref mv, ref nearNearestMv);
|
||||
CopyMvPair(ref mv, ref nearNearestMv);
|
||||
break;
|
||||
}
|
||||
case PredictionMode.ZeroMv:
|
||||
{
|
||||
ZeroPair(ref mv);
|
||||
ZeroMvPair(ref mv);
|
||||
break;
|
||||
}
|
||||
default: return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool ReadIsInterBlock(ref Vp9Common cm, ref MacroBlockD xd, int segmentId, ref Reader r)
|
||||
{
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.RefFrame) != 0)
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.SegLvlRefFrame) != 0)
|
||||
{
|
||||
return cm.Seg.GetSegData(segmentId, SegLvlFeatures.RefFrame) != Constants.IntraFrame;
|
||||
return cm.Seg.GetSegData(segmentId, SegLvlFeatures.SegLvlRefFrame) != Constants.IntraFrame;
|
||||
}
|
||||
|
||||
int ctx = xd.GetIntraInterContext();
|
||||
@@ -517,30 +538,33 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return isInter;
|
||||
}
|
||||
|
||||
private static void DecFindBestRefs(bool allowHp, Span<Mv> mvlist, ref Mv bestMv, int refmvCount)
|
||||
private static void DecFindBestRefMvs(bool allowHP, Span<Mv> mvlist, ref Mv bestMv, int refmvCount)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Make sure all the candidates are properly clamped etc
|
||||
for (int i = 0; i < refmvCount; ++i)
|
||||
for (i = 0; i < refmvCount; ++i)
|
||||
{
|
||||
mvlist[i].LowerPrecision(allowHp);
|
||||
mvlist[i].LowerMvPrecision(allowHP);
|
||||
bestMv = mvlist[i];
|
||||
}
|
||||
}
|
||||
|
||||
private static bool AddRefListEb(Mv mv, ref int refCount, Span<Mv> mvRefList, bool earlyBreak)
|
||||
private static bool AddMvRefListEb(Mv mv, ref int refMvCount, Span<Mv> mvRefList, bool earlyBreak)
|
||||
{
|
||||
if (refCount != 0)
|
||||
if (refMvCount != 0)
|
||||
{
|
||||
if (Unsafe.As<Mv, int>(ref mv) != Unsafe.As<Mv, int>(ref mvRefList[0]))
|
||||
{
|
||||
mvRefList[refCount] = mv;
|
||||
refCount++;
|
||||
mvRefList[refMvCount] = mv;
|
||||
refMvCount++;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mvRefList[refCount++] = mv;
|
||||
mvRefList[refMvCount++] = mv;
|
||||
if (earlyBreak)
|
||||
{
|
||||
return true;
|
||||
@@ -550,7 +574,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsDiffRefFrameAddEb(
|
||||
// Performs mv sign inversion if indicated by the reference frame combination.
|
||||
private static Mv ScaleMv(ref ModeInfo mi, int refr, sbyte thisRefFrame, ref Array4<sbyte> refSignBias)
|
||||
{
|
||||
Mv mv = mi.Mv[refr];
|
||||
if (refSignBias[mi.RefFrame[refr]] != refSignBias[thisRefFrame])
|
||||
{
|
||||
mv.Row *= -1;
|
||||
mv.Col *= -1;
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
|
||||
private static bool IsDiffRefFrameAddMvEb(
|
||||
ref ModeInfo mbmi,
|
||||
sbyte refFrame,
|
||||
ref Array4<sbyte> refSignBias,
|
||||
@@ -562,30 +598,26 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
if (mbmi.RefFrame[0] != refFrame)
|
||||
{
|
||||
if (AddRefListEb(mbmi.ScaleMv(0, refFrame, ref refSignBias), ref refmvCount, mvRefList,
|
||||
earlyBreak))
|
||||
if (AddMvRefListEb(ScaleMv(ref mbmi, 0, refFrame, ref refSignBias), ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (mbmi.HasSecondRef() && mbmi.RefFrame[1] != refFrame && Unsafe.As<Mv, int>(ref mbmi.Mv[1]) != Unsafe.As<Mv, int>(ref mbmi.Mv[0]))
|
||||
{
|
||||
if (AddMvRefListEb(ScaleMv(ref mbmi, 1, refFrame, ref refSignBias), ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mbmi.HasSecondRef() && mbmi.RefFrame[1] != refFrame &&
|
||||
Unsafe.As<Mv, int>(ref mbmi.Mv[1]) != Unsafe.As<Mv, int>(ref mbmi.Mv[0]))
|
||||
{
|
||||
if (AddRefListEb(mbmi.ScaleMv(1, refFrame, ref refSignBias), ref refmvCount, mvRefList,
|
||||
earlyBreak))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function searches the neighborhood of a given MB/SB
|
||||
// to try and find candidate reference vectors.
|
||||
private static int DecFindRefs(
|
||||
private static int DecFindMvRefs(
|
||||
ref Vp9Common cm,
|
||||
ref MacroBlockD xd,
|
||||
PredictionMode mode,
|
||||
@@ -595,24 +627,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int miRow,
|
||||
int miCol,
|
||||
int block,
|
||||
int isSub8x8)
|
||||
int isSub8X8)
|
||||
{
|
||||
ref Array4<sbyte> refSignBias = ref cm.RefFrameSignBias;
|
||||
int i, refmvCount = 0;
|
||||
bool differentRefFound = false;
|
||||
Ptr<MvRef> prevFrameMvs = cm.UsePrevFrameMvs
|
||||
? new Ptr<MvRef>(ref cm.PrevFrameMvs[(miRow * cm.MiCols) + miCol])
|
||||
: Ptr<MvRef>.Null;
|
||||
Ptr<MvRef> prevFrameMvs = cm.UsePrevFrameMvs ? new Ptr<MvRef>(ref cm.PrevFrameMvs[miRow * cm.MiCols + miCol]) : Ptr<MvRef>.Null;
|
||||
ref TileInfo tile = ref xd.Tile;
|
||||
// If mode is nearestmv or newmv (uses nearestmv as a reference) then stop
|
||||
// searching after the first mv is found.
|
||||
bool earlyBreak = mode != PredictionMode.NearMv;
|
||||
|
||||
// Blank the reference vector list
|
||||
mvRefList.Slice(0, Constants.MaxMvRefCandidates).Fill(new Mv());
|
||||
mvRefList[..Constants.MaxMvRefCandidates].Clear();
|
||||
|
||||
i = 0;
|
||||
if (isSub8x8 != 0)
|
||||
if (isSub8X8 != 0)
|
||||
{
|
||||
// If the size < 8x8 we get the mv from the bmi substructure for the
|
||||
// nearest two blocks.
|
||||
@@ -621,21 +651,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Position mvRef = ref mvRefSearch[i];
|
||||
if (tile.IsInside(miCol, miRow, cm.MiRows, ref mvRef))
|
||||
{
|
||||
ref ModeInfo candidateMi = ref xd.Mi[mvRef.Col + (mvRef.Row * xd.MiStride)].Value;
|
||||
ref ModeInfo candidateMi = ref xd.Mi[mvRef.Col + mvRef.Row * xd.MiStride].Value;
|
||||
differentRefFound = true;
|
||||
|
||||
if (candidateMi.RefFrame[0] == refFrame)
|
||||
{
|
||||
if (AddRefListEb(candidateMi.GetSubBlockMv(0, mvRef.Col, block), ref refmvCount,
|
||||
mvRefList, earlyBreak))
|
||||
if (AddMvRefListEb(candidateMi.GetSubBlockMv(0, mvRef.Col, block), ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
else if (candidateMi.RefFrame[1] == refFrame)
|
||||
{
|
||||
if (AddRefListEb(candidateMi.GetSubBlockMv(1, mvRef.Col, block), ref refmvCount,
|
||||
mvRefList, earlyBreak))
|
||||
if (AddMvRefListEb(candidateMi.GetSubBlockMv(1, mvRef.Col, block), ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -647,24 +675,24 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// Check the rest of the neighbors in much the same way
|
||||
// as before except we don't need to keep track of sub blocks or
|
||||
// mode counts.
|
||||
for (; i < RefNeighbours; ++i)
|
||||
for (; i < MvrefNeighbours; ++i)
|
||||
{
|
||||
ref Position mvRef = ref mvRefSearch[i];
|
||||
if (tile.IsInside(miCol, miRow, cm.MiRows, ref mvRef))
|
||||
{
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + (mvRef.Row * xd.MiStride)].Value;
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + mvRef.Row * xd.MiStride].Value;
|
||||
differentRefFound = true;
|
||||
|
||||
if (candidate.RefFrame[0] == refFrame)
|
||||
{
|
||||
if (AddRefListEb(candidate.Mv[0], ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddMvRefListEb(candidate.Mv[0], ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
else if (candidate.RefFrame[1] == refFrame)
|
||||
{
|
||||
if (AddRefListEb(candidate.Mv[1], ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddMvRefListEb(candidate.Mv[1], ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -677,14 +705,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
if (prevFrameMvs.Value.RefFrame[0] == refFrame)
|
||||
{
|
||||
if (AddRefListEb(prevFrameMvs.Value.Mv[0], ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddMvRefListEb(prevFrameMvs.Value.Mv[0], ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
else if (prevFrameMvs.Value.RefFrame[1] == refFrame)
|
||||
{
|
||||
if (AddRefListEb(prevFrameMvs.Value.Mv[1], ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddMvRefListEb(prevFrameMvs.Value.Mv[1], ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -696,16 +724,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// different reference frames.
|
||||
if (differentRefFound)
|
||||
{
|
||||
for (i = 0; i < RefNeighbours; ++i)
|
||||
for (i = 0; i < MvrefNeighbours; ++i)
|
||||
{
|
||||
ref Position mvRef = ref mvRefSearch[i];
|
||||
if (tile.IsInside(miCol, miRow, cm.MiRows, ref mvRef))
|
||||
{
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + (mvRef.Row * xd.MiStride)].Value;
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + mvRef.Row * xd.MiStride].Value;
|
||||
|
||||
// If the candidate is Intra we don't want to consider its mv.
|
||||
if (IsDiffRefFrameAddEb(ref candidate, refFrame, ref refSignBias, ref refmvCount, mvRefList,
|
||||
earlyBreak))
|
||||
if (IsDiffRefFrameAddMvEb(ref candidate, refFrame, ref refSignBias, ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -724,8 +751,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
mv.Row *= -1;
|
||||
mv.Col *= -1;
|
||||
}
|
||||
|
||||
if (AddRefListEb(mv, ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddMvRefListEb(mv, ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -733,8 +759,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
if (prevFrameMvs.Value.RefFrame[1] > Constants.IntraFrame &&
|
||||
prevFrameMvs.Value.RefFrame[1] != refFrame &&
|
||||
Unsafe.As<Mv, int>(ref prevFrameMvs.Value.Mv[1]) !=
|
||||
Unsafe.As<Mv, int>(ref prevFrameMvs.Value.Mv[0]))
|
||||
Unsafe.As<Mv, int>(ref prevFrameMvs.Value.Mv[1]) != Unsafe.As<Mv, int>(ref prevFrameMvs.Value.Mv[0]))
|
||||
{
|
||||
Mv mv = prevFrameMvs.Value.Mv[1];
|
||||
if (refSignBias[prevFrameMvs.Value.RefFrame[1]] != refSignBias[refFrame])
|
||||
@@ -742,8 +767,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
mv.Row *= -1;
|
||||
mv.Col *= -1;
|
||||
}
|
||||
|
||||
if (AddRefListEb(mv, ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddMvRefListEb(mv, ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -764,13 +788,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// Clamp vectors
|
||||
for (i = 0; i < refmvCount; ++i)
|
||||
{
|
||||
mvRefList[i].ClampRef(ref xd);
|
||||
mvRefList[i].ClampMvRef(ref xd);
|
||||
}
|
||||
|
||||
return refmvCount;
|
||||
}
|
||||
|
||||
private static void AppendSub8x8ForIdx(
|
||||
private static void AppendSub8x8MvsForIdx(
|
||||
ref Vp9Common cm,
|
||||
ref MacroBlockD xd,
|
||||
Span<Position> mvRefSearch,
|
||||
@@ -784,12 +808,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
Span<Mv> mvList = stackalloc Mv[Constants.MaxMvRefCandidates];
|
||||
ref ModeInfo mi = ref xd.Mi[0].Value;
|
||||
ref Array4<BModeInfo> bmi = ref mi.Bmi;
|
||||
int n;
|
||||
int refmvCount;
|
||||
|
||||
Debug.Assert(Constants.MaxMvRefCandidates == 2);
|
||||
|
||||
refmvCount = DecFindRefs(ref cm, ref xd, bMode, mi.RefFrame[refr], mvRefSearch, mvList, miRow, miCol,
|
||||
block, 1);
|
||||
refmvCount = DecFindMvRefs(ref cm, ref xd, bMode, mi.RefFrame[refr], mvRefSearch, mvList, miRow, miCol, block, 1);
|
||||
|
||||
switch (block)
|
||||
{
|
||||
@@ -805,7 +829,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
else
|
||||
{
|
||||
bestSub8x8 = new Mv();
|
||||
for (int n = 0; n < refmvCount; ++n)
|
||||
for (n = 0; n < refmvCount; ++n)
|
||||
{
|
||||
if (Unsafe.As<Mv, int>(ref bmi[0].Mv[refr]) != Unsafe.As<Mv, int>(ref mvList[n]))
|
||||
{
|
||||
@@ -814,7 +838,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 3:
|
||||
if (bMode == PredictionMode.NearestMv)
|
||||
@@ -829,7 +852,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
candidates[2] = mvList[0];
|
||||
candidates[3] = mvList[1];
|
||||
bestSub8x8 = new Mv();
|
||||
for (int n = 0; n < 2 + Constants.MaxMvRefCandidates; ++n)
|
||||
for (n = 0; n < 2 + Constants.MaxMvRefCandidates; ++n)
|
||||
{
|
||||
if (Unsafe.As<Mv, int>(ref bmi[2].Mv[refr]) != Unsafe.As<Mv, int>(ref candidates[n]))
|
||||
{
|
||||
@@ -838,7 +861,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid block index.");
|
||||
@@ -846,19 +868,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static byte GetModeContext(ref Vp9Common cm, ref MacroBlockD xd, Span<Position> mvRefSearch, int miRow,
|
||||
int miCol)
|
||||
private static byte GetModeContext(ref Vp9Common cm, ref MacroBlockD xd, Span<Position> mvRefSearch, int miRow, int miCol)
|
||||
{
|
||||
int i;
|
||||
int contextCounter = 0;
|
||||
ref TileInfo tile = ref xd.Tile;
|
||||
|
||||
// Get mode count from nearest 2 blocks
|
||||
for (int i = 0; i < 2; ++i)
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
ref Position mvRef = ref mvRefSearch[i];
|
||||
if (tile.IsInside(miCol, miRow, cm.MiRows, ref mvRef))
|
||||
{
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + (mvRef.Row * xd.MiStride)].Value;
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + mvRef.Row * xd.MiStride].Value;
|
||||
// Keep counts for entropy encoding.
|
||||
contextCounter += Luts.Mode2Counter[(int)candidate.Mode];
|
||||
}
|
||||
@@ -876,7 +898,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Reader r)
|
||||
{
|
||||
BlockSize bsize = mi.SbType;
|
||||
bool allowHp = cm.AllowHighPrecisionMv;
|
||||
bool allowHP = cm.AllowHighPrecisionMv;
|
||||
Array2<Mv> bestRefMvs = new();
|
||||
int refr, isCompound;
|
||||
byte interModeCtx;
|
||||
@@ -886,13 +908,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
isCompound = mi.HasSecondRef() ? 1 : 0;
|
||||
interModeCtx = GetModeContext(ref cm, ref xd, mvRefSearch, miRow, miCol);
|
||||
|
||||
if (cm.Seg.IsSegFeatureActive(mi.SegmentId, SegLvlFeatures.Skip) != 0)
|
||||
if (cm.Seg.IsSegFeatureActive(mi.SegmentId, SegLvlFeatures.SegLvlSkip) != 0)
|
||||
{
|
||||
mi.Mode = PredictionMode.ZeroMv;
|
||||
if (bsize < BlockSize.Block8x8)
|
||||
{
|
||||
xd.ErrorInfo.Value.InternalError(CodecErr.UnsupBitstream,
|
||||
"Invalid usage of segement feature on small blocks");
|
||||
xd.ErrorInfo.Value.InternalError(CodecErr.CodecUnsupBitstream, "Invalid usage of segement feature on small blocks");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -920,58 +942,53 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
sbyte frame = mi.RefFrame[refr];
|
||||
int refmvCount;
|
||||
|
||||
refmvCount = DecFindRefs(ref cm, ref xd, mi.Mode, frame, mvRefSearch, tmpMvs, miRow, miCol,
|
||||
-1, 0);
|
||||
refmvCount = DecFindMvRefs(ref cm, ref xd, mi.Mode, frame, mvRefSearch, tmpMvs, miRow, miCol, -1, 0);
|
||||
|
||||
DecFindBestRefs(allowHp, tmpMvs, ref bestRefMvs[refr], refmvCount);
|
||||
DecFindBestRefMvs(allowHP, tmpMvs, ref bestRefMvs[refr], refmvCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mi.InterpFilter = cm.InterpFilter == Constants.Switchable
|
||||
? ReadSwitchableInterpFilter(ref cm, ref xd, ref r)
|
||||
: cm.InterpFilter;
|
||||
mi.InterpFilter = (cm.InterpFilter == Constants.Switchable) ? ReadSwitchableInterpFilter(ref cm, ref xd, ref r) : cm.InterpFilter;
|
||||
|
||||
if (bsize < BlockSize.Block8x8)
|
||||
{
|
||||
int num4x4W = 1 << xd.BmodeBlocksWl;
|
||||
int num4x4H = 1 << xd.BmodeBlocksHl;
|
||||
int num4X4W = 1 << xd.BmodeBlocksWl;
|
||||
int num4X4H = 1 << xd.BmodeBlocksHl;
|
||||
int idx, idy;
|
||||
PredictionMode bMode = 0;
|
||||
Array2<Mv> bestSub8x8 = new();
|
||||
const uint invalidMv = 0x80008000;
|
||||
const uint InvalidMv = 0x80008000;
|
||||
// Initialize the 2nd element as even though it won't be used meaningfully
|
||||
// if isCompound is false.
|
||||
Unsafe.As<Mv, uint>(ref bestSub8x8[1]) = invalidMv;
|
||||
for (idy = 0; idy < 2; idy += num4x4H)
|
||||
Unsafe.As<Mv, uint>(ref bestSub8x8[1]) = InvalidMv;
|
||||
for (idy = 0; idy < 2; idy += num4X4H)
|
||||
{
|
||||
for (idx = 0; idx < 2; idx += num4x4W)
|
||||
for (idx = 0; idx < 2; idx += num4X4W)
|
||||
{
|
||||
int j = (idy * 2) + idx;
|
||||
int j = idy * 2 + idx;
|
||||
bMode = ReadInterMode(ref cm, ref xd, ref r, interModeCtx);
|
||||
|
||||
if (bMode == PredictionMode.NearestMv || bMode == PredictionMode.NearMv)
|
||||
{
|
||||
for (refr = 0; refr < 1 + isCompound; ++refr)
|
||||
{
|
||||
AppendSub8x8ForIdx(ref cm, ref xd, mvRefSearch, bMode, j, refr, miRow, miCol,
|
||||
ref bestSub8x8[refr]);
|
||||
AppendSub8x8MvsForIdx(ref cm, ref xd, mvRefSearch, bMode, j, refr, miRow, miCol, ref bestSub8x8[refr]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Assign(ref cm, ref xd, bMode, ref mi.Bmi[j].Mv, ref bestRefMvs, ref bestSub8x8,
|
||||
isCompound, allowHp, ref r))
|
||||
if (!AssignMv(ref cm, ref xd, bMode, ref mi.Bmi[j].Mv, ref bestRefMvs, ref bestSub8x8, isCompound, allowHP, ref r))
|
||||
{
|
||||
xd.Corrupted |= true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (num4x4H == 2)
|
||||
if (num4X4H == 2)
|
||||
{
|
||||
mi.Bmi[j + 2] = mi.Bmi[j];
|
||||
}
|
||||
|
||||
if (num4x4W == 2)
|
||||
if (num4X4W == 2)
|
||||
{
|
||||
mi.Bmi[j + 1] = mi.Bmi[j];
|
||||
}
|
||||
@@ -980,12 +997,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
mi.Mode = bMode;
|
||||
|
||||
CopyPair(ref mi.Mv, ref mi.Bmi[3].Mv);
|
||||
CopyMvPair(ref mi.Mv, ref mi.Bmi[3].Mv);
|
||||
}
|
||||
else
|
||||
{
|
||||
xd.Corrupted |= !Assign(ref cm, ref xd, mi.Mode, ref mi.Mv, ref bestRefMvs, ref bestRefMvs,
|
||||
isCompound, allowHp, ref r);
|
||||
xd.Corrupted |= !AssignMv(ref cm, ref xd, mi.Mode, ref mi.Mv, ref bestRefMvs, ref bestRefMvs, isCompound, allowHP, ref r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1029,6 +1045,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
Debug.Assert(b == 1 || b == 3);
|
||||
|
||||
return curMi.Value.Bmi[b - 1].Mode;
|
||||
}
|
||||
|
||||
@@ -1045,6 +1062,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
Debug.Assert(b == 2 || b == 3);
|
||||
|
||||
return curMi.Value.Bmi[b - 2].Mode;
|
||||
}
|
||||
|
||||
@@ -1057,6 +1075,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
PredictionMode above = AboveBlockMode(mi, aboveMi, block);
|
||||
PredictionMode left = LeftBlockMode(mi, leftMi, block);
|
||||
|
||||
return fc.KfYModeProb[(int)above][(int)left].AsSpan();
|
||||
}
|
||||
|
||||
@@ -1073,8 +1092,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
Ptr<ModeInfo> aboveMi = xd.AboveMi;
|
||||
Ptr<ModeInfo> leftMi = xd.LeftMi;
|
||||
BlockSize bsize = mi.Value.SbType;
|
||||
|
||||
int miOffset = (miRow * cm.MiCols) + miCol;
|
||||
int i;
|
||||
int miOffset = miRow * cm.MiCols + miCol;
|
||||
|
||||
mi.Value.SegmentId = (sbyte)ReadIntraSegmentId(ref cm, miOffset, xMis, yMis, ref r);
|
||||
mi.Value.Skip = (sbyte)ReadSkip(ref cm, ref xd, mi.Value.SegmentId, ref r);
|
||||
@@ -1085,7 +1104,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
switch (bsize)
|
||||
{
|
||||
case BlockSize.Block4x4:
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
mi.Value.Bmi[i].Mode =
|
||||
ReadIntraMode(ref r, GetYModeProbs(ref cm.Fc.Value, mi, aboveMi, leftMi, i));
|
||||
@@ -1130,7 +1149,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Reader r = ref twd.BitReader;
|
||||
ref MacroBlockD xd = ref twd.Xd;
|
||||
ref ModeInfo mi = ref xd.Mi[0].Value;
|
||||
ArrayPtr<MvRef> frameMvs = cm.CurFrameMvs.Slice((miRow * cm.MiCols) + miCol);
|
||||
ArrayPtr<MvRef> frameMvs = cm.CurFrameMvs.Slice(miRow * cm.MiCols + miCol);
|
||||
int w, h;
|
||||
|
||||
if (cm.FrameIsIntraOnly())
|
||||
{
|
||||
@@ -1140,15 +1160,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
ReadInterFrameModeInfo(ref cm, ref xd, miRow, miCol, ref r, xMis, yMis);
|
||||
|
||||
for (int h = 0; h < yMis; ++h)
|
||||
for (h = 0; h < yMis; ++h)
|
||||
{
|
||||
for (int w = 0; w < xMis; ++w)
|
||||
for (w = 0; w < xMis; ++w)
|
||||
{
|
||||
ref MvRef mv = ref frameMvs[w];
|
||||
CopyRefFramePair(ref mv.RefFrame, ref mi.RefFrame);
|
||||
CopyPair(ref mv.Mv, ref mi.Mv);
|
||||
CopyMvPair(ref mv.Mv, ref mi.Mv);
|
||||
}
|
||||
|
||||
frameMvs = frameMvs.Slice(cm.MiCols);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
@@ -12,14 +12,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private readonly MemoryAllocator _allocator = new();
|
||||
|
||||
public ISurface CreateSurface(int width, int height)
|
||||
{
|
||||
return new Surface(width, height);
|
||||
}
|
||||
public ISurface CreateSurface(int width, int height) => new Surface(width, height);
|
||||
|
||||
private static ReadOnlySpan<byte> LiteralToFilter => new byte[]
|
||||
{
|
||||
Constants.EightTapSmooth, Constants.EightTap, Constants.EightTapSharp, Constants.Bilinear
|
||||
Constants.EightTapSmooth,
|
||||
Constants.EightTap,
|
||||
Constants.EightTapSharp,
|
||||
Constants.Bilinear,
|
||||
};
|
||||
|
||||
public unsafe bool Decode(
|
||||
@@ -29,24 +29,25 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ReadOnlySpan<Vp9MvRef> mvsIn,
|
||||
Span<Vp9MvRef> mvsOut)
|
||||
{
|
||||
Vp9Common cm = new();
|
||||
Vp9Common cm = new()
|
||||
{
|
||||
FrameType = pictureInfo.IsKeyFrame ? FrameType.KeyFrame : FrameType.InterFrame,
|
||||
IntraOnly = pictureInfo.IntraOnly,
|
||||
|
||||
cm.FrameType = pictureInfo.IsKeyFrame ? FrameType.KeyFrame : FrameType.InterFrame;
|
||||
cm.IntraOnly = pictureInfo.IntraOnly;
|
||||
Width = output.Width,
|
||||
Height = output.Height,
|
||||
SubsamplingX = 1,
|
||||
SubsamplingY = 1,
|
||||
|
||||
cm.Width = output.Width;
|
||||
cm.Height = output.Height;
|
||||
cm.SubsamplingX = 1;
|
||||
cm.SubsamplingY = 1;
|
||||
UsePrevFrameMvs = pictureInfo.UsePrevInFindMvRefs,
|
||||
|
||||
cm.UsePrevFrameMvs = pictureInfo.UsePrevInFindMvRefs;
|
||||
RefFrameSignBias = pictureInfo.RefFrameSignBias,
|
||||
|
||||
cm.RefFrameSignBias = pictureInfo.RefFrameSignBias;
|
||||
|
||||
cm.BaseQindex = pictureInfo.BaseQIndex;
|
||||
cm.YDcDeltaQ = pictureInfo.YDcDeltaQ;
|
||||
cm.UvAcDeltaQ = pictureInfo.UvAcDeltaQ;
|
||||
cm.UvDcDeltaQ = pictureInfo.UvDcDeltaQ;
|
||||
BaseQindex = pictureInfo.BaseQIndex,
|
||||
YDcDeltaQ = pictureInfo.YDcDeltaQ,
|
||||
UvAcDeltaQ = pictureInfo.UvAcDeltaQ,
|
||||
UvDcDeltaQ = pictureInfo.UvDcDeltaQ,
|
||||
};
|
||||
|
||||
cm.Mb.Lossless = pictureInfo.Lossless;
|
||||
cm.Mb.Bd = 8;
|
||||
@@ -67,8 +68,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
cm.CompFixedRef = pictureInfo.CompFixedRef;
|
||||
cm.CompVarRef = pictureInfo.CompVarRef;
|
||||
|
||||
cm.BitDepth = BitDepth.Bits8;
|
||||
|
||||
cm.Log2TileCols = pictureInfo.Log2TileCols;
|
||||
cm.Log2TileRows = pictureInfo.Log2TileRows;
|
||||
|
||||
@@ -79,8 +78,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
cm.Seg.FeatureMask = pictureInfo.SegmentFeatureEnable;
|
||||
cm.Seg.FeatureData = pictureInfo.SegmentFeatureData;
|
||||
|
||||
cm.Lf.FilterLevel = pictureInfo.LoopFilterLevel;
|
||||
cm.Lf.SharpnessLevel = pictureInfo.LoopFilterSharpnessLevel;
|
||||
cm.Lf.ModeRefDeltaEnabled = pictureInfo.ModeRefDeltaEnabled;
|
||||
cm.Lf.RefDeltas = pictureInfo.RefDeltas;
|
||||
cm.Lf.ModeDeltas = pictureInfo.ModeDeltas;
|
||||
@@ -108,12 +105,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
cm.SetupSegmentationDequant();
|
||||
cm.SetupScaleFactors();
|
||||
|
||||
cm.SetMvs(mvsIn);
|
||||
|
||||
if (cm.Lf.FilterLevel != 0 && cm.SkipLoopFilter == 0)
|
||||
{
|
||||
LoopFilter.LoopFilterFrameInit(ref cm, cm.Lf.FilterLevel);
|
||||
}
|
||||
SetMvs(ref cm, mvsIn);
|
||||
|
||||
fixed (byte* dataPtr = bitstream)
|
||||
{
|
||||
@@ -122,27 +114,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (maxThreads > 1 && tileRows == 1 && tileCols > 1)
|
||||
{
|
||||
DecodeFrame.DecodeTilesMt(ref cm, new ArrayPtr<byte>(dataPtr, bitstream.Length), maxThreads);
|
||||
|
||||
LoopFilter.LoopFilterFrameMt(
|
||||
ref cm.Mb.CurBuf,
|
||||
ref cm,
|
||||
ref cm.Mb,
|
||||
cm.Lf.FilterLevel,
|
||||
false,
|
||||
false,
|
||||
maxThreads);
|
||||
}
|
||||
else
|
||||
{
|
||||
DecodeFrame.DecodeTiles(ref cm, new ArrayPtr<byte>(dataPtr, bitstream.Length));
|
||||
|
||||
LoopFilter.LoopFilterFrame(
|
||||
ref cm.Mb.CurBuf,
|
||||
ref cm,
|
||||
ref cm.Mb,
|
||||
cm.Lf.FilterLevel,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
}
|
||||
catch (InternalErrorException)
|
||||
@@ -151,7 +126,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
cm.GetMvs(mvsOut);
|
||||
GetMvs(ref cm, mvsOut);
|
||||
|
||||
cm.FreeTileWorkerData(_allocator);
|
||||
cm.FreeContextBuffers(_allocator);
|
||||
@@ -159,9 +134,48 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
private static void SetMvs(ref Vp9Common cm, ReadOnlySpan<Vp9MvRef> mvs)
|
||||
{
|
||||
_allocator.Dispose();
|
||||
if (mvs.Length > cm.PrevFrameMvs.Length)
|
||||
{
|
||||
throw new ArgumentException($"Size mismatch, expected: {cm.PrevFrameMvs.Length}, but got: {mvs.Length}.");
|
||||
}
|
||||
|
||||
for (int i = 0; i < mvs.Length; i++)
|
||||
{
|
||||
ref var mv = ref cm.PrevFrameMvs[i];
|
||||
|
||||
mv.Mv[0].Row = mvs[i].Mvs[0].Row;
|
||||
mv.Mv[0].Col = mvs[i].Mvs[0].Col;
|
||||
mv.Mv[1].Row = mvs[i].Mvs[1].Row;
|
||||
mv.Mv[1].Col = mvs[i].Mvs[1].Col;
|
||||
|
||||
mv.RefFrame[0] = (sbyte)mvs[i].RefFrames[0];
|
||||
mv.RefFrame[1] = (sbyte)mvs[i].RefFrames[1];
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetMvs(ref Vp9Common cm, Span<Vp9MvRef> mvs)
|
||||
{
|
||||
if (mvs.Length > cm.CurFrameMvs.Length)
|
||||
{
|
||||
throw new ArgumentException($"Size mismatch, expected: {cm.CurFrameMvs.Length}, but got: {mvs.Length}.");
|
||||
}
|
||||
|
||||
for (int i = 0; i < mvs.Length; i++)
|
||||
{
|
||||
ref var mv = ref cm.CurFrameMvs[i];
|
||||
|
||||
mvs[i].Mvs[0].Row = mv.Mv[0].Row;
|
||||
mvs[i].Mvs[0].Col = mv.Mv[0].Col;
|
||||
mvs[i].Mvs[1].Row = mv.Mv[1].Row;
|
||||
mvs[i].Mvs[1].Col = mv.Mv[1].Col;
|
||||
|
||||
mvs[i].RefFrames[0] = mv.RefFrame[0];
|
||||
mvs[i].RefFrames[1] = mv.RefFrame[1];
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() => _allocator.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Dsp;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
@@ -17,10 +17,26 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private static int GetCoefContext(ReadOnlySpan<short> neighbors, ReadOnlySpan<byte> tokenCache, int c)
|
||||
{
|
||||
const int maxNeighbors = 2;
|
||||
const int MaxNeighbors = 2;
|
||||
|
||||
return (1 + tokenCache[neighbors[(maxNeighbors * c) + 0]] +
|
||||
tokenCache[neighbors[(maxNeighbors * c) + 1]]) >> 1;
|
||||
return (1 + tokenCache[neighbors[MaxNeighbors * c + 0]] + tokenCache[neighbors[MaxNeighbors * c + 1]]) >> 1;
|
||||
}
|
||||
|
||||
private static int ReadCoeff(
|
||||
ref Reader r,
|
||||
ReadOnlySpan<byte> probs,
|
||||
int n,
|
||||
ref ulong value,
|
||||
ref int count,
|
||||
ref uint range)
|
||||
{
|
||||
int i, val = 0;
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
val = (val << 1) | r.ReadBool(probs[i], ref value, ref count, ref range);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private static int DecodeCoefs(
|
||||
@@ -42,15 +58,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Array6<Array6<Array3<byte>>> coefProbs = ref fc.CoefProbs[(int)txSize][(int)type][refr];
|
||||
Span<byte> tokenCache = stackalloc byte[32 * 32];
|
||||
ReadOnlySpan<byte> bandTranslate = Luts.GetBandTranslate(txSize);
|
||||
int dqShift = txSize == TxSize.Tx32x32 ? 1 : 0;
|
||||
int dqShift = (txSize == TxSize.Tx32x32) ? 1 : 0;
|
||||
int v;
|
||||
short dqv = dq[0];
|
||||
ReadOnlySpan<byte> cat6Prob = xd.Bd == 12
|
||||
? Luts.Cat6ProbHigh12
|
||||
: xd.Bd == 10
|
||||
? Luts.Cat6ProbHigh12.Slice(2)
|
||||
: Luts.Cat6Prob;
|
||||
int cat6Bits = xd.Bd == 12 ? 18 : xd.Bd == 10 ? 16 : 14;
|
||||
ReadOnlySpan<byte> cat6Prob = (xd.Bd == 12)
|
||||
? Luts.Vp9Cat6ProbHigh12
|
||||
: (xd.Bd == 10) ? Luts.Vp9Cat6ProbHigh12[2..] : Luts.Vp9Cat6Prob;
|
||||
int cat6Bits = (xd.Bd == 12) ? 18 : (xd.Bd == 10) ? 16 : 14;
|
||||
// Keep value, range, and count as locals. The compiler produces better
|
||||
// results with the locals than using r directly.
|
||||
ulong value = r.Value;
|
||||
@@ -61,7 +75,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
int val = -1;
|
||||
band = bandTranslate[0];
|
||||
bandTranslate = bandTranslate.Slice(1);
|
||||
bandTranslate = bandTranslate[1..];
|
||||
ref Array3<byte> prob = ref coefProbs[band][ctx];
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
@@ -93,18 +107,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
r.Value = value;
|
||||
r.Range = range;
|
||||
r.Count = count;
|
||||
|
||||
return c; // Zero tokens at the end (no eob token)
|
||||
}
|
||||
|
||||
ctx = GetCoefContext(nb, tokenCache, c);
|
||||
band = bandTranslate[0];
|
||||
bandTranslate = bandTranslate.Slice(1);
|
||||
bandTranslate = bandTranslate[1..];
|
||||
prob = ref coefProbs[band][ctx];
|
||||
}
|
||||
|
||||
if (r.ReadBool(prob[OneContextNode], ref value, ref count, ref range) != 0)
|
||||
{
|
||||
ReadOnlySpan<byte> p = Luts.Pareto8Full[prob[Constants.PivotNode] - 1];
|
||||
ReadOnlySpan<byte> p = Luts.Vp9Pareto8Full[prob[Constants.PivotNode] - 1];
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
++counts.Coef[(int)txSize][(int)type][refr][band][ctx][Constants.TwoToken];
|
||||
@@ -119,24 +133,20 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
if (r.ReadBool(p[7], ref value, ref count, ref range) != 0)
|
||||
{
|
||||
val = Constants.Cat6MinVal + r.ReadCoeff(cat6Prob, cat6Bits, ref value,
|
||||
ref count, ref range);
|
||||
val = Constants.Cat6MinVal + ReadCoeff(ref r, cat6Prob, cat6Bits, ref value, ref count, ref range);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Constants.Cat5MinVal + r.ReadCoeff(Luts.Cat5Prob, 5, ref value,
|
||||
ref count, ref range);
|
||||
val = Constants.Cat5MinVal + ReadCoeff(ref r, Luts.Vp9Cat5Prob, 5, ref value, ref count, ref range);
|
||||
}
|
||||
}
|
||||
else if (r.ReadBool(p[6], ref value, ref count, ref range) != 0)
|
||||
{
|
||||
val = Constants.Cat4MinVal + r.ReadCoeff(Luts.Cat4Prob, 4, ref value, ref count,
|
||||
ref range);
|
||||
val = Constants.Cat4MinVal + ReadCoeff(ref r, Luts.Vp9Cat4Prob, 4, ref value, ref count, ref range);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Constants.Cat3MinVal + r.ReadCoeff(Luts.Cat3Prob, 3, ref value, ref count,
|
||||
ref range);
|
||||
val = Constants.Cat3MinVal + ReadCoeff(ref r, Luts.Vp9Cat3Prob, 3, ref value, ref count, ref range);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -144,16 +154,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
tokenCache[scan[c]] = 4;
|
||||
if (r.ReadBool(p[4], ref value, ref count, ref range) != 0)
|
||||
{
|
||||
val = Constants.Cat2MinVal + r.ReadCoeff(Luts.Cat2Prob, 2, ref value, ref count,
|
||||
ref range);
|
||||
val = Constants.Cat2MinVal + ReadCoeff(ref r, Luts.Vp9Cat2Prob, 2, ref value, ref count, ref range);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Constants.Cat1MinVal + r.ReadCoeff(Luts.Cat1Prob, 1, ref value, ref count,
|
||||
ref range);
|
||||
val = Constants.Cat1MinVal + ReadCoeff(ref r, Luts.Vp9Cat1Prob, 1, ref value, ref count, ref range);
|
||||
}
|
||||
}
|
||||
|
||||
// Val may use 18-bits
|
||||
v = (int)(((long)val * dqv) >> dqShift);
|
||||
}
|
||||
@@ -181,9 +188,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
tokenCache[scan[c]] = 1;
|
||||
v = dqv >> dqShift;
|
||||
}
|
||||
|
||||
dqcoeff[scan[c]] = (int)HighbdCheckRange(r.ReadBool(128, ref value, ref count, ref range) != 0 ? -v : v,
|
||||
xd.Bd);
|
||||
dqcoeff[scan[c]] = (int)HighbdCheckRange(r.ReadBool(128, ref value, ref count, ref range) != 0 ? -v : v, xd.Bd);
|
||||
++c;
|
||||
ctx = GetCoefContext(nb, tokenCache, c);
|
||||
dqv = dq[1];
|
||||
@@ -192,11 +197,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
r.Value = value;
|
||||
r.Range = range;
|
||||
r.Count = count;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private static void GetCtxShift(ref MacroBlockD xd, ref int ctxShiftA, ref int ctxShiftL, int x, int y,
|
||||
uint txSizeInBlocks)
|
||||
private static void GetCtxShift(ref MacroBlockD xd, ref int ctxShiftA, ref int ctxShiftL, int x, int y, uint txSizeInBlocks)
|
||||
{
|
||||
if (xd.MaxBlocksWide != 0)
|
||||
{
|
||||
@@ -205,7 +210,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ctxShiftA = (int)(txSizeInBlocks - (xd.MaxBlocksWide - x)) * 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (xd.MaxBlocksHigh != 0)
|
||||
{
|
||||
if (txSizeInBlocks + y > xd.MaxBlocksHigh)
|
||||
@@ -234,8 +238,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref MacroBlockDPlane pd = ref xd.Plane[plane];
|
||||
ref Array2<short> dequant = ref pd.SegDequant[segId];
|
||||
int eob;
|
||||
Span<sbyte> a = pd.AboveContext.AsSpan().Slice(x);
|
||||
Span<sbyte> l = pd.LeftContext.AsSpan().Slice(y);
|
||||
Span<sbyte> a = pd.AboveContext.AsSpan()[x..];
|
||||
Span<sbyte> l = pd.LeftContext.AsSpan()[y..];
|
||||
int ctx;
|
||||
int ctxShiftA = 0;
|
||||
int ctxShiftL = 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -75,16 +75,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Vector128<int> zero = Vector128<int>.Zero;
|
||||
Vector128<int> const64 = Vector128.Create(64);
|
||||
|
||||
src -= (SubpelTaps / 2) - 1;
|
||||
ulong x, y;
|
||||
src -= SubpelTaps / 2 - 1;
|
||||
|
||||
fixed (Array8<short>* xFilter = xFilters)
|
||||
{
|
||||
Vector128<short> vfilter = Sse2.LoadVector128((short*)xFilter + ((uint)(x0Q4 & SubpelMask) * 8));
|
||||
Vector128<short> vfilter = Sse2.LoadVector128((short*)xFilter + (uint)(x0Q4 & SubpelMask) * 8);
|
||||
|
||||
for (ulong y = 0; y < (uint)h; ++y)
|
||||
for (y = 0; y < (uint)h; ++y)
|
||||
{
|
||||
ulong srcOffset = (uint)x0Q4 >> SubpelBits;
|
||||
for (ulong x = 0; x < (uint)w; x += 4)
|
||||
for (x = 0; x < (uint)w; x += 4)
|
||||
{
|
||||
Vector128<short> vsrc0 = Sse41.ConvertToVector128Int16(&src[srcOffset + x]);
|
||||
Vector128<short> vsrc1 = Sse41.ConvertToVector128Int16(&src[srcOffset + x + 1]);
|
||||
@@ -93,10 +94,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
Vector128<int> sum0123 = MultiplyAddAdjacent(vsrc0, vsrc1, vsrc2, vsrc3, vfilter, zero);
|
||||
|
||||
Sse.StoreScalar((float*)&dst[x],
|
||||
PackUnsignedSaturate(RoundShift(sum0123, const64), zero).AsSingle());
|
||||
Sse.StoreScalar((float*)&dst[x], PackUnsignedSaturate(RoundShift(sum0123, const64), zero).AsSingle());
|
||||
}
|
||||
|
||||
src += srcStride;
|
||||
dst += dstStride;
|
||||
}
|
||||
@@ -118,20 +117,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
if (Sse41.IsSupported && UseIntrinsics && xStepQ4 == 1 << SubpelBits)
|
||||
{
|
||||
ConvolveHorizSse41(src, srcStride, dst, dstStride, xFilters, x0Q4, w, h);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
src -= (SubpelTaps / 2) - 1;
|
||||
int x, y;
|
||||
src -= SubpelTaps / 2 - 1;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
int xQ4 = x0Q4;
|
||||
for (int x = 0; x < w; ++x)
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
byte* srcX = &src[xQ4 >> SubpelBits];
|
||||
ref Array8<short> xFilter = ref xFilters[xQ4 & SubpelMask];
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcX[k] * xFilter[k];
|
||||
}
|
||||
@@ -139,7 +140,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[x] = BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits));
|
||||
xQ4 += xStepQ4;
|
||||
}
|
||||
|
||||
src += srcStride;
|
||||
dst += dstStride;
|
||||
}
|
||||
@@ -156,26 +156,25 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
src -= (SubpelTaps / 2) - 1;
|
||||
int x, y;
|
||||
src -= SubpelTaps / 2 - 1;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
int xQ4 = x0Q4;
|
||||
for (int x = 0; x < w; ++x)
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
byte* srcX = &src[xQ4 >> SubpelBits];
|
||||
ref Array8<short> xFilter = ref xFilters[xQ4 & SubpelMask];
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcX[k] * xFilter[k];
|
||||
}
|
||||
|
||||
dst[x] = (byte)BitUtils.RoundPowerOfTwo(
|
||||
dst[x] + BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits)), 1);
|
||||
dst[x] = (byte)BitUtils.RoundPowerOfTwo(dst[x] + BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits)), 1);
|
||||
xQ4 += xStepQ4;
|
||||
}
|
||||
|
||||
src += srcStride;
|
||||
dst += dstStride;
|
||||
}
|
||||
@@ -204,17 +203,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
srcStride * 6,
|
||||
srcStride * 7);
|
||||
|
||||
src -= srcStride * ((SubpelTaps / 2) - 1);
|
||||
ulong x, y;
|
||||
src -= srcStride * (SubpelTaps / 2 - 1);
|
||||
|
||||
fixed (Array8<short>* yFilter = yFilters)
|
||||
{
|
||||
Vector128<short> vfilter = Sse2.LoadVector128((short*)yFilter + ((uint)(y0Q4 & SubpelMask) * 8));
|
||||
Vector128<short> vfilter = Sse2.LoadVector128((short*)yFilter + (uint)(y0Q4 & SubpelMask) * 8);
|
||||
|
||||
ulong srcBaseY = (uint)y0Q4 >> SubpelBits;
|
||||
for (ulong y = 0; y < (uint)h; ++y)
|
||||
for (y = 0; y < (uint)h; ++y)
|
||||
{
|
||||
ulong srcOffset = (srcBaseY + y) * (uint)srcStride;
|
||||
for (ulong x = 0; x < (uint)w; x += 4)
|
||||
for (x = 0; x < (uint)w; x += 4)
|
||||
{
|
||||
Vector256<int> vsrc = Avx2.GatherVector256((uint*)&src[srcOffset + x], indices, 1).AsInt32();
|
||||
|
||||
@@ -240,10 +240,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
Vector128<int> sum0123 = MultiplyAddAdjacent(vsrc0, vsrc1, vsrc2, vsrc3, vfilter, zero);
|
||||
|
||||
Sse.StoreScalar((float*)&dst[x],
|
||||
PackUnsignedSaturate(RoundShift(sum0123, const64), zero).AsSingle());
|
||||
Sse.StoreScalar((float*)&dst[x], PackUnsignedSaturate(RoundShift(sum0123, const64), zero).AsSingle());
|
||||
}
|
||||
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
||||
@@ -264,20 +262,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
if (Avx2.IsSupported && UseIntrinsics && yStepQ4 == 1 << SubpelBits)
|
||||
{
|
||||
ConvolveVertAvx2(src, srcStride, dst, dstStride, yFilters, y0Q4, w, h);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
src -= srcStride * ((SubpelTaps / 2) - 1);
|
||||
int x, y;
|
||||
src -= srcStride * (SubpelTaps / 2 - 1);
|
||||
|
||||
for (int x = 0; x < w; ++x)
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
int yQ4 = y0Q4;
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
byte* srcY = &src[(yQ4 >> SubpelBits) * srcStride];
|
||||
ref Array8<short> yFilter = ref yFilters[yQ4 & SubpelMask];
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcY[k * srcStride] * yFilter[k];
|
||||
}
|
||||
@@ -285,7 +285,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[y * dstStride] = BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits));
|
||||
yQ4 += yStepQ4;
|
||||
}
|
||||
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
@@ -302,17 +301,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
src -= srcStride * ((SubpelTaps / 2) - 1);
|
||||
int x, y;
|
||||
src -= srcStride * (SubpelTaps / 2 - 1);
|
||||
|
||||
for (int x = 0; x < w; ++x)
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
int yQ4 = y0Q4;
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
byte* srcY = &src[(yQ4 >> SubpelBits) * srcStride];
|
||||
ref Array8<short> yFilter = ref yFilters[yQ4 & SubpelMask];
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcY[k * srcStride] * yFilter[k];
|
||||
}
|
||||
@@ -321,7 +321,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[y * dstStride] + BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits)), 1);
|
||||
yQ4 += yStepQ4;
|
||||
}
|
||||
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
@@ -421,16 +420,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
// ==> yStepQ4 = 64. Since w and h are at most 16, the temp buffer is still
|
||||
// big enough.
|
||||
byte* temp = stackalloc byte[64 * 135];
|
||||
int intermediateHeight = ((((h - 1) * yStepQ4) + y0Q4) >> SubpelBits) + SubpelTaps;
|
||||
int intermediateHeight = (((h - 1) * yStepQ4 + y0Q4) >> SubpelBits) + SubpelTaps;
|
||||
|
||||
Debug.Assert(w <= 64);
|
||||
Debug.Assert(h <= 64);
|
||||
Debug.Assert(yStepQ4 <= 32 || (yStepQ4 <= 64 && h <= 32));
|
||||
Debug.Assert(xStepQ4 <= 64);
|
||||
|
||||
ConvolveHoriz(src - (srcStride * ((SubpelTaps / 2) - 1)), srcStride, temp, 64, filter, x0Q4, xStepQ4, w,
|
||||
intermediateHeight);
|
||||
ConvolveVert(temp + (64 * ((SubpelTaps / 2) - 1)), 64, dst, dstStride, filter, y0Q4, yStepQ4, w, h);
|
||||
ConvolveHoriz(src - srcStride * (SubpelTaps / 2 - 1), srcStride, temp, 64, filter, x0Q4, xStepQ4, w, intermediateHeight);
|
||||
ConvolveVert(temp + 64 * (SubpelTaps / 2 - 1), 64, dst, dstStride, filter, y0Q4, yStepQ4, w, h);
|
||||
}
|
||||
|
||||
public static unsafe void Convolve8Avg(
|
||||
@@ -491,9 +489,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
for (int y = 0; y < h; ++y)
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
for (int x = 0; x < w; ++x)
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
dst[x] = (byte)BitUtils.RoundPowerOfTwo(dst[x] + src[x], 1);
|
||||
}
|
||||
@@ -611,17 +611,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int h,
|
||||
int bd)
|
||||
{
|
||||
src -= (SubpelTaps / 2) - 1;
|
||||
int x, y;
|
||||
src -= SubpelTaps / 2 - 1;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
int xQ4 = x0Q4;
|
||||
for (int x = 0; x < w; ++x)
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
ushort* srcX = &src[xQ4 >> SubpelBits];
|
||||
ref Array8<short> xFilter = ref xFilters[xQ4 & SubpelMask];
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcX[k] * xFilter[k];
|
||||
}
|
||||
@@ -629,7 +630,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[x] = BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd);
|
||||
xQ4 += xStepQ4;
|
||||
}
|
||||
|
||||
src += srcStride;
|
||||
dst += dstStride;
|
||||
}
|
||||
@@ -647,26 +647,25 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int h,
|
||||
int bd)
|
||||
{
|
||||
src -= (SubpelTaps / 2) - 1;
|
||||
int x, y;
|
||||
src -= SubpelTaps / 2 - 1;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
int xQ4 = x0Q4;
|
||||
for (int x = 0; x < w; ++x)
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
ushort* srcX = &src[xQ4 >> SubpelBits];
|
||||
ref Array8<short> xFilter = ref xFilters[xQ4 & SubpelMask];
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcX[k] * xFilter[k];
|
||||
}
|
||||
|
||||
dst[x] = (ushort)BitUtils.RoundPowerOfTwo(
|
||||
dst[x] + BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd), 1);
|
||||
dst[x] = (ushort)BitUtils.RoundPowerOfTwo(dst[x] + BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd), 1);
|
||||
xQ4 += xStepQ4;
|
||||
}
|
||||
|
||||
src += srcStride;
|
||||
dst += dstStride;
|
||||
}
|
||||
@@ -684,17 +683,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int h,
|
||||
int bd)
|
||||
{
|
||||
src -= srcStride * ((SubpelTaps / 2) - 1);
|
||||
int x, y;
|
||||
src -= srcStride * (SubpelTaps / 2 - 1);
|
||||
|
||||
for (int x = 0; x < w; ++x)
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
int yQ4 = y0Q4;
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
ushort* srcY = &src[(yQ4 >> SubpelBits) * srcStride];
|
||||
ref Array8<short> yFilter = ref yFilters[yQ4 & SubpelMask];
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcY[k * srcStride] * yFilter[k];
|
||||
}
|
||||
@@ -702,7 +702,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[y * dstStride] = BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd);
|
||||
yQ4 += yStepQ4;
|
||||
}
|
||||
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
@@ -720,27 +719,26 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int h,
|
||||
int bd)
|
||||
{
|
||||
src -= srcStride * ((SubpelTaps / 2) - 1);
|
||||
int x, y;
|
||||
src -= srcStride * (SubpelTaps / 2 - 1);
|
||||
|
||||
for (int x = 0; x < w; ++x)
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
int yQ4 = y0Q4;
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
ushort* srcY = &src[(yQ4 >> SubpelBits) * srcStride];
|
||||
ref Array8<short> yFilter = ref yFilters[yQ4 & SubpelMask];
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcY[k * srcStride] * yFilter[k];
|
||||
}
|
||||
|
||||
dst[y * dstStride] = (ushort)BitUtils.RoundPowerOfTwo(
|
||||
dst[y * dstStride] + BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd),
|
||||
1);
|
||||
dst[y * dstStride] + BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd), 1);
|
||||
yQ4 += yStepQ4;
|
||||
}
|
||||
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
@@ -773,17 +771,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
// --Require an additional SubpelTaps rows for the 8-tap filter tails.
|
||||
// --((64 - 1) * 32 + 15) >> 4 + 8 = 135.
|
||||
ushort* temp = stackalloc ushort[64 * 135];
|
||||
int intermediateHeight = ((((h - 1) * yStepQ4) + y0Q4) >> SubpelBits) + SubpelTaps;
|
||||
int intermediateHeight = (((h - 1) * yStepQ4 + y0Q4) >> SubpelBits) + SubpelTaps;
|
||||
|
||||
Debug.Assert(w <= 64);
|
||||
Debug.Assert(h <= 64);
|
||||
Debug.Assert(yStepQ4 <= 32);
|
||||
Debug.Assert(xStepQ4 <= 32);
|
||||
|
||||
HighbdConvolveHoriz(src - (srcStride * ((SubpelTaps / 2) - 1)), srcStride, temp, 64, filter, x0Q4, xStepQ4,
|
||||
w, intermediateHeight, bd);
|
||||
HighbdConvolveVert(temp + (64 * ((SubpelTaps / 2) - 1)), 64, dst, dstStride, filter, y0Q4, yStepQ4, w, h,
|
||||
bd);
|
||||
HighbdConvolveHoriz(src - srcStride * (SubpelTaps / 2 - 1), srcStride, temp, 64, filter, x0Q4, xStepQ4, w, intermediateHeight, bd);
|
||||
HighbdConvolveVert(temp + 64 * (SubpelTaps / 2 - 1), 64, dst, dstStride, filter, y0Q4, yStepQ4, w, h, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdConvolve8Horiz(
|
||||
@@ -932,9 +928,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int h,
|
||||
int bd)
|
||||
{
|
||||
for (int y = 0; y < h; ++y)
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
for (int x = 0; x < w; ++x)
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
dst[x] = (ushort)BitUtils.RoundPowerOfTwo(dst[x] + src[x], 1);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
@@ -6,22 +6,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
private static unsafe ref byte Dst(byte* dst, int stride, int x, int y)
|
||||
{
|
||||
return ref dst[x + (y * stride)];
|
||||
return ref dst[x + y * stride];
|
||||
}
|
||||
|
||||
private static unsafe ref ushort Dst(ushort* dst, int stride, int x, int y)
|
||||
{
|
||||
return ref dst[x + (y * stride)];
|
||||
return ref dst[x + y * stride];
|
||||
}
|
||||
|
||||
private static byte Avg3(byte a, byte b, byte c)
|
||||
{
|
||||
return (byte)((a + (2 * b) + c + 2) >> 2);
|
||||
return (byte)((a + 2 * b + c + 2) >> 2);
|
||||
}
|
||||
|
||||
private static ushort Avg3(ushort a, ushort b, ushort c)
|
||||
{
|
||||
return (ushort)((a + (2 * b) + c + 2) >> 2);
|
||||
return (ushort)((a + 2 * b + c + 2) >> 2);
|
||||
}
|
||||
|
||||
private static byte Avg2(byte a, byte b)
|
||||
@@ -51,8 +51,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void D207Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r, c;
|
||||
// First column
|
||||
for (int r = 0; r < bs - 1; ++r)
|
||||
for (r = 0; r < bs - 1; ++r)
|
||||
{
|
||||
dst[r * stride] = Avg2(left[r], left[r + 1]);
|
||||
}
|
||||
@@ -61,7 +62,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst++;
|
||||
|
||||
// Second column
|
||||
for (int r = 0; r < bs - 2; ++r)
|
||||
for (r = 0; r < bs - 2; ++r)
|
||||
{
|
||||
dst[r * stride] = Avg3(left[r], left[r + 1], left[r + 2]);
|
||||
}
|
||||
@@ -71,16 +72,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst++;
|
||||
|
||||
// Rest of last row
|
||||
for (int c = 0; c < bs - 2; ++c)
|
||||
for (c = 0; c < bs - 2; ++c)
|
||||
{
|
||||
dst[((bs - 1) * stride) + c] = left[bs - 1];
|
||||
dst[(bs - 1) * stride + c] = left[bs - 1];
|
||||
}
|
||||
|
||||
for (int r = bs - 2; r >= 0; --r)
|
||||
for (r = bs - 2; r >= 0; --r)
|
||||
{
|
||||
for (int c = 0; c < bs - 2; ++c)
|
||||
for (c = 0; c < bs - 2; ++c)
|
||||
{
|
||||
dst[(r * stride) + c] = dst[((r + 1) * stride) + c - 2];
|
||||
dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,18 +103,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void D63Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
for (int c = 0; c < bs; ++c)
|
||||
int r, c;
|
||||
int size;
|
||||
for (c = 0; c < bs; ++c)
|
||||
{
|
||||
dst[c] = Avg2(above[c], above[c + 1]);
|
||||
dst[stride + c] = Avg3(above[c], above[c + 1], above[c + 2]);
|
||||
}
|
||||
|
||||
for (int r = 2, size = bs - 2; r < bs; r += 2, --size)
|
||||
for (r = 2, size = bs - 2; r < bs; r += 2, --size)
|
||||
{
|
||||
MemoryUtil.Copy(dst + ((r + 0) * stride), dst + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + ((r + 0) * stride) + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + ((r + 1) * stride), dst + stride + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + ((r + 1) * stride) + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + (r + 0) * stride, dst + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + (r + 0) * stride + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + (r + 1) * stride, dst + stride + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + (r + 1) * stride + size, above[bs - 1], bs - size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,15 +138,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
byte aboveRight = above[bs - 1];
|
||||
byte* dstRow0 = dst;
|
||||
int x, size;
|
||||
|
||||
for (int x = 0; x < bs - 1; ++x)
|
||||
for (x = 0; x < bs - 1; ++x)
|
||||
{
|
||||
dst[x] = Avg3(above[x], above[x + 1], above[x + 2]);
|
||||
}
|
||||
|
||||
dst[bs - 1] = aboveRight;
|
||||
dst += stride;
|
||||
for (int x = 1, size = bs - 2; x < bs; ++x, --size)
|
||||
for (x = 1, size = bs - 2; x < bs; ++x, --size)
|
||||
{
|
||||
MemoryUtil.Copy(dst, dstRow0 + x, size);
|
||||
MemoryUtil.Fill(dst + size, aboveRight, x + 1);
|
||||
@@ -169,8 +171,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void D117Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r, c;
|
||||
|
||||
// First row
|
||||
for (int c = 0; c < bs; c++)
|
||||
for (c = 0; c < bs; c++)
|
||||
{
|
||||
dst[c] = Avg2(above[c - 1], above[c]);
|
||||
}
|
||||
@@ -179,7 +183,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
// Second row
|
||||
dst[0] = Avg3(left[0], above[-1], above[0]);
|
||||
for (int c = 1; c < bs; c++)
|
||||
for (c = 1; c < bs; c++)
|
||||
{
|
||||
dst[c] = Avg3(above[c - 2], above[c - 1], above[c]);
|
||||
}
|
||||
@@ -188,17 +192,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
// The rest of first col
|
||||
dst[0] = Avg3(above[-1], left[0], left[1]);
|
||||
for (int r = 3; r < bs; ++r)
|
||||
for (r = 3; r < bs; ++r)
|
||||
{
|
||||
dst[(r - 2) * stride] = Avg3(left[r - 3], left[r - 2], left[r - 1]);
|
||||
}
|
||||
|
||||
// The rest of the block
|
||||
for (int r = 2; r < bs; ++r)
|
||||
for (r = 2; r < bs; ++r)
|
||||
{
|
||||
for (int c = 1; c < bs; c++)
|
||||
for (c = 1; c < bs; c++)
|
||||
{
|
||||
dst[c] = dst[(-2 * stride) + c - 1];
|
||||
dst[c] = dst[-2 * stride + c - 1];
|
||||
}
|
||||
|
||||
dst += stride;
|
||||
@@ -222,26 +226,26 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void D135Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int i;
|
||||
byte* border = stackalloc byte[32 + 32 - 1]; // outer border from bottom-left to top-right
|
||||
|
||||
// Dst(dst, stride, bs, bs - 2)[0], i.e., border starting at bottom-left
|
||||
for (int i = 0; i < bs - 2; ++i)
|
||||
for (i = 0; i < bs - 2; ++i)
|
||||
{
|
||||
border[i] = Avg3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]);
|
||||
}
|
||||
|
||||
border[bs - 2] = Avg3(above[-1], left[0], left[1]);
|
||||
border[bs - 1] = Avg3(left[0], above[-1], above[0]);
|
||||
border[bs - 0] = Avg3(above[-1], above[0], above[1]);
|
||||
// dst[0][2, size), i.e., remaining top border ascending
|
||||
for (int i = 0; i < bs - 2; ++i)
|
||||
for (i = 0; i < bs - 2; ++i)
|
||||
{
|
||||
border[bs + 1 + i] = Avg3(above[i], above[i + 1], above[i + 2]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < bs; ++i)
|
||||
for (i = 0; i < bs; ++i)
|
||||
{
|
||||
MemoryUtil.Copy(dst + (i * stride), border + bs - 1 - i, bs);
|
||||
MemoryUtil.Copy(dst + i * stride, border + bs - 1 - i, bs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,8 +266,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void D153Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r, c;
|
||||
dst[0] = Avg2(above[-1], left[0]);
|
||||
for (int r = 1; r < bs; r++)
|
||||
for (r = 1; r < bs; r++)
|
||||
{
|
||||
dst[r * stride] = Avg2(left[r - 1], left[r]);
|
||||
}
|
||||
@@ -272,23 +277,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
dst[0] = Avg3(left[0], above[-1], above[0]);
|
||||
dst[stride] = Avg3(above[-1], left[0], left[1]);
|
||||
for (int r = 2; r < bs; r++)
|
||||
for (r = 2; r < bs; r++)
|
||||
{
|
||||
dst[r * stride] = Avg3(left[r - 2], left[r - 1], left[r]);
|
||||
}
|
||||
|
||||
dst++;
|
||||
|
||||
for (int c = 0; c < bs - 2; c++)
|
||||
for (c = 0; c < bs - 2; c++)
|
||||
{
|
||||
dst[c] = Avg3(above[c - 1], above[c], above[c + 1]);
|
||||
}
|
||||
|
||||
dst += stride;
|
||||
|
||||
for (int r = 1; r < bs; ++r)
|
||||
for (r = 1; r < bs; ++r)
|
||||
{
|
||||
for (int c = 0; c < bs - 2; c++)
|
||||
for (c = 0; c < bs - 2; c++)
|
||||
{
|
||||
dst[c] = dst[-stride + c - 2];
|
||||
}
|
||||
@@ -319,7 +324,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void VPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
for (int r = 0; r < bs; r++)
|
||||
int r;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Copy(dst, above, bs);
|
||||
dst += stride;
|
||||
@@ -348,40 +355,43 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void HPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
for (int r = 0; r < bs; r++)
|
||||
int r;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, left[r], bs);
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void TmPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TMPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TmPredictor(dst, stride, 4, above, left);
|
||||
TMPredictor(dst, stride, 4, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void TmPredictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TMPredictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TmPredictor(dst, stride, 8, above, left);
|
||||
TMPredictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void TmPredictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TMPredictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TmPredictor(dst, stride, 16, above, left);
|
||||
TMPredictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void TmPredictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TMPredictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TmPredictor(dst, stride, 32, above, left);
|
||||
TMPredictor(dst, stride, 32, above, left);
|
||||
}
|
||||
|
||||
private static unsafe void TmPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
private static unsafe void TMPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r, c;
|
||||
int yTopLeft = above[-1];
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
for (int c = 0; c < bs; c++)
|
||||
for (c = 0; c < bs; c++)
|
||||
{
|
||||
dst[c] = BitUtils.ClipPixel(left[r] + above[c] - yTopLeft);
|
||||
}
|
||||
@@ -412,7 +422,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void Dc128Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
for (int r = 0; r < bs; r++)
|
||||
int r;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (byte)128, bs);
|
||||
dst += stride;
|
||||
@@ -441,16 +453,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void DcLeftPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int i, r, expectedDc, sum = 0;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
for (i = 0; i < bs; i++)
|
||||
{
|
||||
sum += left[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (byte)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -479,16 +491,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void DcTopPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int i, r, expectedDc, sum = 0;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
for (i = 0; i < bs; i++)
|
||||
{
|
||||
sum += above[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (byte)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -517,10 +529,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void DcPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int i, r, expectedDc, sum = 0;
|
||||
int count = 2 * bs;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
for (i = 0; i < bs; i++)
|
||||
{
|
||||
sum += above[i];
|
||||
sum += left[i];
|
||||
@@ -528,7 +540,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
expectedDc = (sum + (count >> 1)) / count;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (byte)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -543,10 +555,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
byte k = left[2];
|
||||
byte l = left[3];
|
||||
|
||||
MemoryUtil.Fill(dst + (stride * 0), Avg3(h, I, j), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 1), Avg3(I, j, k), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 2), Avg3(j, k, l), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 3), Avg3(k, l, l), 4);
|
||||
MemoryUtil.Fill(dst + stride * 0, Avg3(h, I, j), 4);
|
||||
MemoryUtil.Fill(dst + stride * 1, Avg3(I, j, k), 4);
|
||||
MemoryUtil.Fill(dst + stride * 2, Avg3(j, k, l), 4);
|
||||
MemoryUtil.Fill(dst + stride * 3, Avg3(k, l, l), 4);
|
||||
}
|
||||
|
||||
public static unsafe void VePredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
@@ -562,9 +574,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[1] = Avg3(I, j, k);
|
||||
dst[2] = Avg3(j, k, l);
|
||||
dst[3] = Avg3(k, l, m);
|
||||
MemoryUtil.Copy(dst + (stride * 1), dst, 4);
|
||||
MemoryUtil.Copy(dst + (stride * 2), dst, 4);
|
||||
MemoryUtil.Copy(dst + (stride * 3), dst, 4);
|
||||
MemoryUtil.Copy(dst + stride * 1, dst, 4);
|
||||
MemoryUtil.Copy(dst + stride * 2, dst, 4);
|
||||
MemoryUtil.Copy(dst + stride * 3, dst, 4);
|
||||
}
|
||||
|
||||
public static unsafe void D207Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
@@ -579,8 +591,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 1, 0) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 1, 1) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 1, 2) = Avg3(k, l, l);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 0, 3) =
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 2, 3) = Dst(dst, stride, 3, 3) = l;
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 0, 3) = Dst(dst, stride, 1, 3) = Dst(dst, stride, 2, 3) = Dst(dst, stride, 3, 3) = l;
|
||||
}
|
||||
|
||||
public static unsafe void D63Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
@@ -605,7 +616,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 3, 3) = Avg3(e, f, g); // Differs from vp8
|
||||
}
|
||||
|
||||
public static unsafe void D63EPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D63ePredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte a = above[0];
|
||||
byte b = above[1];
|
||||
@@ -641,14 +652,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 0, 0) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 0, 1) = Avg3(b, c, d);
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 2) = Avg3(c, d, e);
|
||||
Dst(dst, stride, 3, 0) =
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 3) = Avg3(e, f, g);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 3) = Avg3(f, g, h);
|
||||
Dst(dst, stride, 3, 3) = h; // differs from vp8
|
||||
}
|
||||
|
||||
public static unsafe void D45EPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D45ePredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte a = above[0];
|
||||
byte b = above[1];
|
||||
@@ -661,8 +671,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 0, 0) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 0, 1) = Avg3(b, c, d);
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 2) = Avg3(c, d, e);
|
||||
Dst(dst, stride, 3, 0) =
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 3) = Avg3(e, f, g);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 3) = Avg3(f, g, h);
|
||||
Dst(dst, stride, 3, 3) = Avg3(g, h, h);
|
||||
@@ -705,8 +714,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 0, 3) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 0, 2) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 2, 3) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 1) = Avg3(x, I, j);
|
||||
Dst(dst, stride, 3, 3) =
|
||||
Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, I);
|
||||
Dst(dst, stride, 3, 3) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, I);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 0) = Avg3(b, a, x);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 0) = Avg3(c, b, a);
|
||||
Dst(dst, stride, 3, 0) = Avg3(d, c, b);
|
||||
@@ -750,39 +758,38 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD207Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD207Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdD207Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
int r, c;
|
||||
|
||||
// First column.
|
||||
for (int r = 0; r < bs - 1; ++r)
|
||||
for (r = 0; r < bs - 1; ++r)
|
||||
{
|
||||
dst[r * stride] = Avg2(left[r], left[r + 1]);
|
||||
}
|
||||
|
||||
dst[(bs - 1) * stride] = left[bs - 1];
|
||||
dst++;
|
||||
|
||||
// Second column.
|
||||
for (int r = 0; r < bs - 2; ++r)
|
||||
for (r = 0; r < bs - 2; ++r)
|
||||
{
|
||||
dst[r * stride] = Avg3(left[r], left[r + 1], left[r + 2]);
|
||||
}
|
||||
|
||||
dst[(bs - 2) * stride] = Avg3(left[bs - 2], left[bs - 1], left[bs - 1]);
|
||||
dst[(bs - 1) * stride] = left[bs - 1];
|
||||
dst++;
|
||||
|
||||
// Rest of last row.
|
||||
for (int c = 0; c < bs - 2; ++c)
|
||||
for (c = 0; c < bs - 2; ++c)
|
||||
{
|
||||
dst[((bs - 1) * stride) + c] = left[bs - 1];
|
||||
dst[(bs - 1) * stride + c] = left[bs - 1];
|
||||
}
|
||||
|
||||
for (int r = bs - 2; r >= 0; --r)
|
||||
for (r = bs - 2; r >= 0; --r)
|
||||
{
|
||||
for (int c = 0; c < bs - 2; ++c)
|
||||
for (c = 0; c < bs - 2; ++c)
|
||||
{
|
||||
dst[(r * stride) + c] = dst[((r + 1) * stride) + c - 2];
|
||||
dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -802,21 +809,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD63Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD63Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdD63Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
for (int c = 0; c < bs; ++c)
|
||||
int r, c;
|
||||
int size;
|
||||
for (c = 0; c < bs; ++c)
|
||||
{
|
||||
dst[c] = Avg2(above[c], above[c + 1]);
|
||||
dst[stride + c] = Avg3(above[c], above[c + 1], above[c + 2]);
|
||||
}
|
||||
|
||||
for (int r = 2, size = bs - 2; r < bs; r += 2, --size)
|
||||
for (r = 2, size = bs - 2; r < bs; r += 2, --size)
|
||||
{
|
||||
MemoryUtil.Copy(dst + ((r + 0) * stride), dst + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + ((r + 0) * stride) + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + ((r + 1) * stride), dst + stride + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + ((r + 1) * stride) + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + (r + 0) * stride, dst + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + (r + 0) * stride + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + (r + 1) * stride, dst + stride + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + (r + 1) * stride + size, above[bs - 1], bs - size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,20 +842,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD45Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD45Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdD45Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
ushort aboveRight = above[bs - 1];
|
||||
ushort* dstRow0 = dst;
|
||||
int x, size;
|
||||
|
||||
for (int x = 0; x < bs - 1; ++x)
|
||||
for (x = 0; x < bs - 1; ++x)
|
||||
{
|
||||
dst[x] = Avg3(above[x], above[x + 1], above[x + 2]);
|
||||
}
|
||||
|
||||
dst[bs - 1] = aboveRight;
|
||||
dst += stride;
|
||||
for (int x = 1, size = bs - 2; x < bs; ++x, --size)
|
||||
for (x = 1, size = bs - 2; x < bs; ++x, --size)
|
||||
{
|
||||
MemoryUtil.Copy(dst, dstRow0 + x, size);
|
||||
MemoryUtil.Fill(dst + size, aboveRight, x + 1);
|
||||
@@ -871,11 +877,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD117Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD117Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdD117Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
int r, c;
|
||||
|
||||
// First row
|
||||
for (int c = 0; c < bs; c++)
|
||||
for (c = 0; c < bs; c++)
|
||||
{
|
||||
dst[c] = Avg2(above[c - 1], above[c]);
|
||||
}
|
||||
@@ -884,7 +891,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
// Second row
|
||||
dst[0] = Avg3(left[0], above[-1], above[0]);
|
||||
for (int c = 1; c < bs; c++)
|
||||
for (c = 1; c < bs; c++)
|
||||
{
|
||||
dst[c] = Avg3(above[c - 2], above[c - 1], above[c]);
|
||||
}
|
||||
@@ -893,17 +900,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
// The rest of first col
|
||||
dst[0] = Avg3(above[-1], left[0], left[1]);
|
||||
for (int r = 3; r < bs; ++r)
|
||||
for (r = 3; r < bs; ++r)
|
||||
{
|
||||
dst[(r - 2) * stride] = Avg3(left[r - 3], left[r - 2], left[r - 1]);
|
||||
}
|
||||
|
||||
// The rest of the block
|
||||
for (int r = 2; r < bs; ++r)
|
||||
for (r = 2; r < bs; ++r)
|
||||
{
|
||||
for (int c = 1; c < bs; c++)
|
||||
for (c = 1; c < bs; c++)
|
||||
{
|
||||
dst[c] = dst[(-2 * stride) + c - 1];
|
||||
dst[c] = dst[-2 * stride + c - 1];
|
||||
}
|
||||
|
||||
dst += stride;
|
||||
@@ -925,29 +932,28 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD135Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD135Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdD135Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
int i;
|
||||
ushort* border = stackalloc ushort[32 + 32 - 1]; // Outer border from bottom-left to top-right
|
||||
|
||||
// Dst(dst, stride, bs, bs - 2)[0], i.e., border starting at bottom-left
|
||||
for (int i = 0; i < bs - 2; ++i)
|
||||
for (i = 0; i < bs - 2; ++i)
|
||||
{
|
||||
border[i] = Avg3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]);
|
||||
}
|
||||
|
||||
border[bs - 2] = Avg3(above[-1], left[0], left[1]);
|
||||
border[bs - 1] = Avg3(left[0], above[-1], above[0]);
|
||||
border[bs - 0] = Avg3(above[-1], above[0], above[1]);
|
||||
// dst[0][2, size), i.e., remaining top border ascending
|
||||
for (int i = 0; i < bs - 2; ++i)
|
||||
for (i = 0; i < bs - 2; ++i)
|
||||
{
|
||||
border[bs + 1 + i] = Avg3(above[i], above[i + 1], above[i + 2]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < bs; ++i)
|
||||
for (i = 0; i < bs; ++i)
|
||||
{
|
||||
MemoryUtil.Copy(dst + (i * stride), border + bs - 1 - i, bs);
|
||||
MemoryUtil.Copy(dst + i * stride, border + bs - 1 - i, bs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -966,11 +972,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD153Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD153Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdD153Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
int r, c;
|
||||
dst[0] = Avg2(above[-1], left[0]);
|
||||
for (int r = 1; r < bs; r++)
|
||||
for (r = 1; r < bs; r++)
|
||||
{
|
||||
dst[r * stride] = Avg2(left[r - 1], left[r]);
|
||||
}
|
||||
@@ -979,23 +985,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
dst[0] = Avg3(left[0], above[-1], above[0]);
|
||||
dst[stride] = Avg3(above[-1], left[0], left[1]);
|
||||
for (int r = 2; r < bs; r++)
|
||||
for (r = 2; r < bs; r++)
|
||||
{
|
||||
dst[r * stride] = Avg3(left[r - 2], left[r - 1], left[r]);
|
||||
}
|
||||
|
||||
dst++;
|
||||
|
||||
for (int c = 0; c < bs - 2; c++)
|
||||
for (c = 0; c < bs - 2; c++)
|
||||
{
|
||||
dst[c] = Avg3(above[c - 1], above[c], above[c + 1]);
|
||||
}
|
||||
|
||||
dst += stride;
|
||||
|
||||
for (int r = 1; r < bs; ++r)
|
||||
for (r = 1; r < bs; ++r)
|
||||
{
|
||||
for (int c = 0; c < bs - 2; c++)
|
||||
for (c = 0; c < bs - 2; c++)
|
||||
{
|
||||
dst[c] = dst[-stride + c - 2];
|
||||
}
|
||||
@@ -1024,10 +1030,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdVPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdVPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdVPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
for (int r = 0; r < bs; r++)
|
||||
int r;
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Copy(dst, above, bs);
|
||||
dst += stride;
|
||||
@@ -1054,44 +1060,44 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdHPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdHPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdHPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
for (int r = 0; r < bs; r++)
|
||||
int r;
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, left[r], bs);
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTmPredictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTMPredictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTmPredictor(dst, stride, 4, above, left, bd);
|
||||
HighbdTMPredictor(dst, stride, 4, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTmPredictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTMPredictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTmPredictor(dst, stride, 8, above, left, bd);
|
||||
HighbdTMPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTmPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTMPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTmPredictor(dst, stride, 16, above, left, bd);
|
||||
HighbdTMPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTmPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTMPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTmPredictor(dst, stride, 32, above, left, bd);
|
||||
HighbdTMPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdTmPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdTMPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
int r, c;
|
||||
int yTopLeft = above[-1];
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
for (int c = 0; c < bs; c++)
|
||||
for (c = 0; c < bs; c++)
|
||||
{
|
||||
dst[c] = BitUtils.ClipPixelHighbd(left[r] + above[c] - yTopLeft, bd);
|
||||
}
|
||||
@@ -1110,22 +1116,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdDc128Predictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDc128Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
public static unsafe void HighbdDc128Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDc128Predictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDc128Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
public static unsafe void HighbdDc128Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDc128Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdDc128Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdDc128Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
for (int r = 0; r < bs; r++)
|
||||
int r;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (ushort)(128 << (bd - 8)), bs);
|
||||
dst += stride;
|
||||
@@ -1142,31 +1147,28 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdDcLeftPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcLeftPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
public static unsafe void HighbdDcLeftPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcLeftPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcLeftPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
public static unsafe void HighbdDcLeftPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcLeftPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdDcLeftPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdDcLeftPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int i, r, expectedDc, sum = 0;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
for (i = 0; i < bs; i++)
|
||||
{
|
||||
sum += left[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (ushort)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -1183,31 +1185,28 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdDcTopPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcTopPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
public static unsafe void HighbdDcTopPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcTopPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcTopPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
public static unsafe void HighbdDcTopPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcTopPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdDcTopPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdDcTopPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int i, r, expectedDc, sum = 0;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
for (i = 0; i < bs; i++)
|
||||
{
|
||||
sum += above[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (ushort)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -1234,13 +1233,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdDcPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdDcPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
private static unsafe void HighbdDcPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int i, r, expectedDc, sum = 0;
|
||||
int count = 2 * bs;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
for (i = 0; i < bs; i++)
|
||||
{
|
||||
sum += above[i];
|
||||
sum += left[i];
|
||||
@@ -1248,7 +1246,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
expectedDc = (sum + (count >> 1)) / count;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
for (r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (ushort)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -1267,8 +1265,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 1, 0) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 1, 1) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 1, 2) = Avg3(k, l, l);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 0, 3) =
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 2, 3) = Dst(dst, stride, 3, 3) = l;
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 0, 3) = Dst(dst, stride, 1, 3) = Dst(dst, stride, 2, 3) = Dst(dst, stride, 3, 3) = l;
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD63Predictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
@@ -1306,8 +1303,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 0, 0) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 0, 1) = Avg3(b, c, d);
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 2) = Avg3(c, d, e);
|
||||
Dst(dst, stride, 3, 0) =
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 3) = Avg3(e, f, g);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 3) = Avg3(f, g, h);
|
||||
Dst(dst, stride, 3, 3) = h; // Differs from vp8
|
||||
@@ -1350,8 +1346,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 0, 3) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 0, 2) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 2, 3) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 1) = Avg3(x, I, j);
|
||||
Dst(dst, stride, 3, 3) =
|
||||
Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, I);
|
||||
Dst(dst, stride, 3, 3) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, I);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 0) = Avg3(b, a, x);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 0) = Avg3(c, b, a);
|
||||
Dst(dst, stride, 3, 0) = Avg3(d, c, b);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,229 +0,0 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
internal class LoopFilterAuto
|
||||
{
|
||||
public static void LpfHorizontal4(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal4(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal4(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfHorizontal4Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit0,
|
||||
ReadOnlySpan<byte> limit0,
|
||||
ReadOnlySpan<byte> thresh0,
|
||||
ReadOnlySpan<byte> blimit1,
|
||||
ReadOnlySpan<byte> limit1,
|
||||
ReadOnlySpan<byte> thresh1)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal4Dual(s, pitch, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal4Dual(s, pitch, blimit0[0], limit0[0], thresh0[0], blimit1[0], limit1[0],
|
||||
thresh1[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfHorizontal8(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal8(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal8(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfHorizontal8Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit0,
|
||||
ReadOnlySpan<byte> limit0,
|
||||
ReadOnlySpan<byte> thresh0,
|
||||
ReadOnlySpan<byte> blimit1,
|
||||
ReadOnlySpan<byte> limit1,
|
||||
ReadOnlySpan<byte> thresh1)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal8Dual(s, pitch, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal8Dual(s, pitch, blimit0[0], limit0[0], thresh0[0], blimit1[0], limit1[0],
|
||||
thresh1[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfHorizontal16(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal16(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal16(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfHorizontal16Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal16Dual(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal16Dual(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical4(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical4(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical4(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical4Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit0,
|
||||
ReadOnlySpan<byte> limit0,
|
||||
ReadOnlySpan<byte> thresh0,
|
||||
ReadOnlySpan<byte> blimit1,
|
||||
ReadOnlySpan<byte> limit1,
|
||||
ReadOnlySpan<byte> thresh1)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical4Dual(s, pitch, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical4Dual(s, pitch, blimit0[0], limit0[0], thresh0[0], blimit1[0], limit1[0],
|
||||
thresh1[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical8(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical8(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical8(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical8Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit0,
|
||||
ReadOnlySpan<byte> limit0,
|
||||
ReadOnlySpan<byte> thresh0,
|
||||
ReadOnlySpan<byte> blimit1,
|
||||
ReadOnlySpan<byte> limit1,
|
||||
ReadOnlySpan<byte> thresh1)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical8Dual(s, pitch, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical8Dual(s, pitch, blimit0[0], limit0[0], thresh0[0], blimit1[0], limit1[0],
|
||||
thresh1[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical16(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical16(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical16(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical16Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical16Dual(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical16Dual(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
@@ -12,9 +12,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
Debug.Assert(den != 0);
|
||||
{
|
||||
int p = (int)((((ulong)num * 256) + (den >> 1)) / den);
|
||||
int p = (int)(((ulong)num * 256 + (den >> 1)) / den);
|
||||
// (p > 255) ? 255 : (p < 1) ? 1 : p;
|
||||
int clippedProb = p | ((255 - p) >> 23) | (p == 0 ? 1 : 0);
|
||||
|
||||
return (byte)clippedProb;
|
||||
}
|
||||
}
|
||||
@@ -22,13 +23,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
/* This function assumes prob1 and prob2 are already within [1,255] range. */
|
||||
public static byte WeightedProb(int prob1, int prob2, int factor)
|
||||
{
|
||||
return (byte)BitUtils.RoundPowerOfTwo((prob1 * (256 - factor)) + (prob2 * factor), 8);
|
||||
return (byte)BitUtils.RoundPowerOfTwo(prob1 * (256 - factor) + prob2 * factor, 8);
|
||||
}
|
||||
|
||||
// MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT;
|
||||
private static readonly uint[] CountToUpdateFactor =
|
||||
{
|
||||
0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64, 70, 76, 83, 89, 96, 102, 108, 115, 121, 128
|
||||
private static readonly uint[] _countToUpdateFactor = {
|
||||
0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64,
|
||||
70, 76, 83, 89, 96, 102, 108, 115, 121, 128,
|
||||
};
|
||||
|
||||
private const int ModeMvCountSat = 20;
|
||||
@@ -40,12 +41,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
return preProb;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
uint count = Math.Min(den, ModeMvCountSat);
|
||||
uint factor = CountToUpdateFactor[(int)count];
|
||||
uint factor = _countToUpdateFactor[(int)count];
|
||||
byte prob = GetProb(ct0, den);
|
||||
|
||||
return WeightedProb(preProb, prob, (int)factor);
|
||||
}
|
||||
}
|
||||
|
||||
private static uint TreeMergeProbsImpl(
|
||||
uint i,
|
||||
@@ -55,15 +59,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Span<byte> probs)
|
||||
{
|
||||
int l = tree[i];
|
||||
uint leftCount = l <= 0 ? counts[-l] : TreeMergeProbsImpl((uint)l, tree, preProbs, counts, probs);
|
||||
uint leftCount = (l <= 0) ? counts[-l] : TreeMergeProbsImpl((uint)l, tree, preProbs, counts, probs);
|
||||
int r = tree[i + 1];
|
||||
uint rightCount = r <= 0 ? counts[-r] : TreeMergeProbsImpl((uint)r, tree, preProbs, counts, probs);
|
||||
uint rightCount = (r <= 0) ? counts[-r] : TreeMergeProbsImpl((uint)r, tree, preProbs, counts, probs);
|
||||
probs[(int)(i >> 1)] = ModeMvMergeProbs(preProbs[(int)(i >> 1)], leftCount, rightCount);
|
||||
|
||||
return leftCount + rightCount;
|
||||
}
|
||||
|
||||
public static void TreeMergeProbs(sbyte[] tree, ReadOnlySpan<byte> preProbs, ReadOnlySpan<uint> counts,
|
||||
Span<byte> probs)
|
||||
public static void TreeMergeProbs(sbyte[] tree, ReadOnlySpan<byte> preProbs, ReadOnlySpan<uint> counts, Span<byte> probs)
|
||||
{
|
||||
TreeMergeProbsImpl(0, tree, preProbs, counts, probs);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
|
||||
@@ -7,18 +6,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
internal struct Reader
|
||||
{
|
||||
private static readonly byte[] Norm =
|
||||
{
|
||||
0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
private static readonly byte[] _norm = {
|
||||
0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
private const int BdValueSize = sizeof(ulong) * 8;
|
||||
|
||||
// This is meant to be a large, positive constant that can still be efficiently
|
||||
@@ -37,14 +36,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
_buffer = new ArrayPtr<byte>(ref buffer[0], size);
|
||||
Value = 0;
|
||||
Count = -8;
|
||||
Range = 255;
|
||||
Fill();
|
||||
|
||||
return ReadBit() != 0; // Marker bit
|
||||
}
|
||||
}
|
||||
|
||||
private void Fill()
|
||||
{
|
||||
@@ -63,7 +65,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
ulong bigEndianValues = BinaryPrimitives.ReadUInt64BigEndian(buffer);
|
||||
nv = bigEndianValues >> (BdValueSize - bits);
|
||||
count += bits;
|
||||
buffer = buffer.Slice(bits >> 3);
|
||||
buffer = buffer[(bits >> 3)..];
|
||||
value = Value | (nv << (shift & 0x7));
|
||||
}
|
||||
else
|
||||
@@ -82,7 +84,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
count += 8;
|
||||
value |= (ulong)buffer[0] << shift;
|
||||
buffer = buffer.Slice(1);
|
||||
buffer = buffer[1..];
|
||||
shift -= 8;
|
||||
}
|
||||
}
|
||||
@@ -96,7 +98,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Count = count;
|
||||
}
|
||||
|
||||
public bool HasError()
|
||||
public readonly bool HasError()
|
||||
{
|
||||
// Check if we have reached the end of the buffer.
|
||||
//
|
||||
@@ -122,7 +124,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
ulong bigsplit;
|
||||
int count;
|
||||
uint range;
|
||||
uint split = ((Range * (uint)prob) + (256 - (uint)prob)) >> 8;
|
||||
uint split = (Range * (uint)prob + (256 - (uint)prob)) >> 8;
|
||||
|
||||
if (Count < 0)
|
||||
{
|
||||
@@ -144,7 +146,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
{
|
||||
int shift = Norm[range];
|
||||
int shift = _norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
@@ -186,7 +188,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
public int ReadBool(int prob, ref ulong value, ref int count, ref uint range)
|
||||
{
|
||||
uint split = ((range * (uint)prob) + (256 - (uint)prob)) >> 8;
|
||||
uint split = (range * (uint)prob + (256 - (uint)prob)) >> 8;
|
||||
ulong bigsplit = (ulong)split << (BdValueSize - 8);
|
||||
|
||||
if (count < 0)
|
||||
@@ -200,20 +202,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
if (value >= bigsplit)
|
||||
{
|
||||
range = range - split;
|
||||
value = value - bigsplit;
|
||||
range -= split;
|
||||
value -= bigsplit;
|
||||
{
|
||||
int shift = Norm[range];
|
||||
int shift = _norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
range = split;
|
||||
{
|
||||
int shift = Norm[range];
|
||||
int shift = _norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
@@ -229,82 +230,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Count -= 8;
|
||||
_buffer = _buffer.Slice(-1);
|
||||
}
|
||||
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
private int DecodeUniform()
|
||||
{
|
||||
const int l = 8;
|
||||
const int m = (1 << l) - 191;
|
||||
int v = ReadLiteral(l - 1);
|
||||
return v < m ? v : (v << 1) - m + ReadBit();
|
||||
}
|
||||
|
||||
public int DecodeTermSubexp()
|
||||
{
|
||||
if (ReadBit() == 0)
|
||||
{
|
||||
return ReadLiteral(4);
|
||||
}
|
||||
|
||||
if (ReadBit() == 0)
|
||||
{
|
||||
return ReadLiteral(4) + 16;
|
||||
}
|
||||
|
||||
if (ReadBit() == 0)
|
||||
{
|
||||
return ReadLiteral(5) + 32;
|
||||
}
|
||||
|
||||
return DecodeUniform() + 64;
|
||||
}
|
||||
|
||||
public TxMode ReadTxMode()
|
||||
{
|
||||
TxMode txMode = (TxMode)ReadLiteral(2);
|
||||
if (txMode == TxMode.Allow32x32)
|
||||
{
|
||||
txMode += ReadBit();
|
||||
}
|
||||
|
||||
return txMode;
|
||||
}
|
||||
|
||||
public int ReadCoeff(
|
||||
ReadOnlySpan<byte> probs,
|
||||
int n,
|
||||
ref ulong value,
|
||||
ref int count,
|
||||
ref uint range)
|
||||
{
|
||||
int val = 0;
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
val = (val << 1) | ReadBool(probs[i], ref value, ref count, ref range);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public void DiffUpdateProb(ref byte p)
|
||||
{
|
||||
if (Read(Entropy.DiffUpdateProb) != 0)
|
||||
{
|
||||
p = (byte)DSubExp.InvRemapProb(DecodeTermSubexp(), p);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateMvProbs(Span<byte> p, int n)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (Read(EntropyMv.UpdateProb) != 0)
|
||||
{
|
||||
p[i] = (byte)((ReadLiteral(7) << 1) | 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,42 +13,42 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
// for (int i = 1; i < 32; ++i)
|
||||
// Console.WriteLine("public const short CosPi{0}_64 = {1};", i, MathF.Round(16384 * MathF.Cos(i * MathF.PI / 64)));
|
||||
// Note: sin(k * Pi / 64) = cos((32 - k) * Pi / 64)
|
||||
public const short CosPi164 = 16364;
|
||||
public const short CosPi264 = 16305;
|
||||
public const short CosPi364 = 16207;
|
||||
public const short CosPi464 = 16069;
|
||||
public const short CosPi564 = 15893;
|
||||
public const short CosPi664 = 15679;
|
||||
public const short CosPi764 = 15426;
|
||||
public const short CosPi864 = 15137;
|
||||
public const short CosPi964 = 14811;
|
||||
public const short CosPi1064 = 14449;
|
||||
public const short CosPi1164 = 14053;
|
||||
public const short CosPi1264 = 13623;
|
||||
public const short CosPi1364 = 13160;
|
||||
public const short CosPi1464 = 12665;
|
||||
public const short CosPi1564 = 12140;
|
||||
public const short CosPi1664 = 11585;
|
||||
public const short CosPi1764 = 11003;
|
||||
public const short CosPi1864 = 10394;
|
||||
public const short CosPi1964 = 9760;
|
||||
public const short CosPi2064 = 9102;
|
||||
public const short CosPi2164 = 8423;
|
||||
public const short CosPi2264 = 7723;
|
||||
public const short CosPi2364 = 7005;
|
||||
public const short CosPi2464 = 6270;
|
||||
public const short CosPi2564 = 5520;
|
||||
public const short CosPi2664 = 4756;
|
||||
public const short CosPi2764 = 3981;
|
||||
public const short CosPi2864 = 3196;
|
||||
public const short CosPi2964 = 2404;
|
||||
public const short CosPi3064 = 1606;
|
||||
public const short CosPi3164 = 804;
|
||||
public const short CosPi1_64 = 16364;
|
||||
public const short CosPi2_64 = 16305;
|
||||
public const short CosPi3_64 = 16207;
|
||||
public const short CosPi4_64 = 16069;
|
||||
public const short CosPi5_64 = 15893;
|
||||
public const short CosPi6_64 = 15679;
|
||||
public const short CosPi7_64 = 15426;
|
||||
public const short CosPi8_64 = 15137;
|
||||
public const short CosPi9_64 = 14811;
|
||||
public const short CosPi10_64 = 14449;
|
||||
public const short CosPi11_64 = 14053;
|
||||
public const short CosPi12_64 = 13623;
|
||||
public const short CosPi13_64 = 13160;
|
||||
public const short CosPi14_64 = 12665;
|
||||
public const short CosPi15_64 = 12140;
|
||||
public const short CosPi16_64 = 11585;
|
||||
public const short CosPi17_64 = 11003;
|
||||
public const short CosPi18_64 = 10394;
|
||||
public const short CosPi19_64 = 9760;
|
||||
public const short CosPi20_64 = 9102;
|
||||
public const short CosPi21_64 = 8423;
|
||||
public const short CosPi22_64 = 7723;
|
||||
public const short CosPi23_64 = 7005;
|
||||
public const short CosPi24_64 = 6270;
|
||||
public const short CosPi25_64 = 5520;
|
||||
public const short CosPi26_64 = 4756;
|
||||
public const short CosPi27_64 = 3981;
|
||||
public const short CosPi28_64 = 3196;
|
||||
public const short CosPi29_64 = 2404;
|
||||
public const short CosPi30_64 = 1606;
|
||||
public const short CosPi31_64 = 804;
|
||||
|
||||
// 16384 * sqrt(2) * sin(kPi / 9) * 2 / 3
|
||||
public const short SinPi19 = 5283;
|
||||
public const short SinPi29 = 9929;
|
||||
public const short SinPi39 = 13377;
|
||||
public const short SinPi49 = 15212;
|
||||
public const short SinPi1_9 = 5283;
|
||||
public const short SinPi2_9 = 9929;
|
||||
public const short SinPi3_9 = 13377;
|
||||
public const short SinPi4_9 = 15212;
|
||||
}
|
||||
}
|
||||
@@ -1,623 +0,0 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class Entropy
|
||||
{
|
||||
public const int DiffUpdateProb = 252;
|
||||
|
||||
// Coefficient token alphabet
|
||||
public const int ZeroToken = 0; // 0 Extra Bits 0+0
|
||||
public const int OneToken = 1; // 1 Extra Bits 0+1
|
||||
public const int TwoToken = 2; // 2 Extra Bits 0+1
|
||||
public const int ThreeToken = 3; // 3 Extra Bits 0+1
|
||||
public const int FourToken = 4; // 4 Extra Bits 0+1
|
||||
public const int Category1Token = 5; // 5-6 Extra Bits 1+1
|
||||
public const int Category2Token = 6; // 7-10 Extra Bits 2+1
|
||||
public const int Category3Token = 7; // 11-18 Extra Bits 3+1
|
||||
public const int Category4Token = 8; // 19-34 Extra Bits 4+1
|
||||
public const int Category5Token = 9; // 35-66 Extra Bits 5+1
|
||||
public const int Category6Token = 10; // 67+ Extra Bits 14+1
|
||||
public const int EobToken = 11; // EOB Extra Bits 0+0
|
||||
|
||||
public const int EntropyTokens = 12;
|
||||
|
||||
public const int RefTypes = 2; // intra=0, inter=1
|
||||
|
||||
/* Middle dimension reflects the coefficient position within the transform. */
|
||||
public const int CoefBands = 6;
|
||||
|
||||
/* Inside dimension is measure of nearby complexity, that reflects the energy
|
||||
of nearby coefficients are nonzero. For the first coefficient (DC, unless
|
||||
block type is 0), we look at the (already encoded) blocks above and to the
|
||||
left of the current block. The context index is then the number (0,1,or 2)
|
||||
of these blocks having nonzero coefficients.
|
||||
After decoding a coefficient, the measure is determined by the size of the
|
||||
most recently decoded coefficient.
|
||||
Note that the intuitive meaning of this measure changes as coefficients
|
||||
are decoded, e.g., prior to the first token, a zero means that my neighbors
|
||||
are empty while, after the first token, because of the use of end-of-block,
|
||||
a zero means we just decoded a zero and hence guarantees that a non-zero
|
||||
coefficient will appear later in this block. However, this shift
|
||||
in meaning is perfectly OK because our context depends also on the
|
||||
coefficient band (and since zigzag positions 0, 1, and 2 are in
|
||||
distinct bands). */
|
||||
|
||||
public const int CoeffContexts = 6;
|
||||
|
||||
public static int BAND_COEFF_CONTEXTS(int band)
|
||||
{
|
||||
return band == 0 ? 3 : CoeffContexts;
|
||||
}
|
||||
|
||||
public const int UnconstrainedNodes = 3;
|
||||
|
||||
public const int PivotNode = 2;
|
||||
|
||||
public const int Cat1MinVal = 5;
|
||||
public const int Cat2MinVal = 7;
|
||||
public const int Cat3MinVal = 11;
|
||||
public const int Cat4MinVal = 19;
|
||||
public const int Cat5MinVal = 35;
|
||||
public const int Cat6MinVal = 67;
|
||||
|
||||
public static readonly byte[] Cat1Prob = { 159 };
|
||||
public static readonly byte[] Cat2Prob = { 165, 145 };
|
||||
public static readonly byte[] Cat3Prob = { 173, 148, 140 };
|
||||
public static readonly byte[] Cat4Prob = { 176, 155, 140, 135 };
|
||||
public static readonly byte[] Cat5Prob = { 180, 157, 141, 134, 130 };
|
||||
|
||||
public static readonly byte[] Cat6Prob =
|
||||
{
|
||||
254, 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129
|
||||
};
|
||||
|
||||
public static readonly byte[] Cat6ProbHigh12 =
|
||||
{
|
||||
255, 255, 255, 255, 254, 254, 54, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129
|
||||
};
|
||||
|
||||
public const int EobModelToken = 3;
|
||||
|
||||
private static readonly byte[] CoefbandTrans8x8Plus =
|
||||
{
|
||||
0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
|
||||
// beyond MAXBAND_INDEX+1 all values are filled as 5
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
|
||||
};
|
||||
|
||||
private static readonly byte[] CoefbandTrans4x4 = { 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5 };
|
||||
|
||||
public static readonly byte[][] Pareto8Full =
|
||||
{
|
||||
new byte[] { 3, 86, 128, 6, 86, 23, 88, 29 }, new byte[] { 6, 86, 128, 11, 87, 42, 91, 52 },
|
||||
new byte[] { 9, 86, 129, 17, 88, 61, 94, 76 }, new byte[] { 12, 86, 129, 22, 88, 77, 97, 93 },
|
||||
new byte[] { 15, 87, 129, 28, 89, 93, 100, 110 }, new byte[] { 17, 87, 129, 33, 90, 105, 103, 123 },
|
||||
new byte[] { 20, 88, 130, 38, 91, 118, 106, 136 }, new byte[] { 23, 88, 130, 43, 91, 128, 108, 146 },
|
||||
new byte[] { 26, 89, 131, 48, 92, 139, 111, 156 }, new byte[] { 28, 89, 131, 53, 93, 147, 114, 163 },
|
||||
new byte[] { 31, 90, 131, 58, 94, 156, 117, 171 }, new byte[] { 34, 90, 131, 62, 94, 163, 119, 177 },
|
||||
new byte[] { 37, 90, 132, 66, 95, 171, 122, 184 }, new byte[] { 39, 90, 132, 70, 96, 177, 124, 189 },
|
||||
new byte[] { 42, 91, 132, 75, 97, 183, 127, 194 }, new byte[] { 44, 91, 132, 79, 97, 188, 129, 198 },
|
||||
new byte[] { 47, 92, 133, 83, 98, 193, 132, 202 }, new byte[] { 49, 92, 133, 86, 99, 197, 134, 205 },
|
||||
new byte[] { 52, 93, 133, 90, 100, 201, 137, 208 }, new byte[] { 54, 93, 133, 94, 100, 204, 139, 211 },
|
||||
new byte[] { 57, 94, 134, 98, 101, 208, 142, 214 }, new byte[] { 59, 94, 134, 101, 102, 211, 144, 216 },
|
||||
new byte[] { 62, 94, 135, 105, 103, 214, 146, 218 },
|
||||
new byte[] { 64, 94, 135, 108, 103, 216, 148, 220 },
|
||||
new byte[] { 66, 95, 135, 111, 104, 219, 151, 222 },
|
||||
new byte[] { 68, 95, 135, 114, 105, 221, 153, 223 },
|
||||
new byte[] { 71, 96, 136, 117, 106, 224, 155, 225 },
|
||||
new byte[] { 73, 96, 136, 120, 106, 225, 157, 226 },
|
||||
new byte[] { 76, 97, 136, 123, 107, 227, 159, 228 },
|
||||
new byte[] { 78, 97, 136, 126, 108, 229, 160, 229 },
|
||||
new byte[] { 80, 98, 137, 129, 109, 231, 162, 231 },
|
||||
new byte[] { 82, 98, 137, 131, 109, 232, 164, 232 },
|
||||
new byte[] { 84, 98, 138, 134, 110, 234, 166, 233 },
|
||||
new byte[] { 86, 98, 138, 137, 111, 235, 168, 234 },
|
||||
new byte[] { 89, 99, 138, 140, 112, 236, 170, 235 },
|
||||
new byte[] { 91, 99, 138, 142, 112, 237, 171, 235 },
|
||||
new byte[] { 93, 100, 139, 145, 113, 238, 173, 236 },
|
||||
new byte[] { 95, 100, 139, 147, 114, 239, 174, 237 },
|
||||
new byte[] { 97, 101, 140, 149, 115, 240, 176, 238 },
|
||||
new byte[] { 99, 101, 140, 151, 115, 241, 177, 238 },
|
||||
new byte[] { 101, 102, 140, 154, 116, 242, 179, 239 },
|
||||
new byte[] { 103, 102, 140, 156, 117, 242, 180, 239 },
|
||||
new byte[] { 105, 103, 141, 158, 118, 243, 182, 240 },
|
||||
new byte[] { 107, 103, 141, 160, 118, 243, 183, 240 },
|
||||
new byte[] { 109, 104, 141, 162, 119, 244, 185, 241 },
|
||||
new byte[] { 111, 104, 141, 164, 119, 244, 186, 241 },
|
||||
new byte[] { 113, 104, 142, 166, 120, 245, 187, 242 },
|
||||
new byte[] { 114, 104, 142, 168, 121, 245, 188, 242 },
|
||||
new byte[] { 116, 105, 143, 170, 122, 246, 190, 243 },
|
||||
new byte[] { 118, 105, 143, 171, 122, 246, 191, 243 },
|
||||
new byte[] { 120, 106, 143, 173, 123, 247, 192, 244 },
|
||||
new byte[] { 121, 106, 143, 175, 124, 247, 193, 244 },
|
||||
new byte[] { 123, 107, 144, 177, 125, 248, 195, 244 },
|
||||
new byte[] { 125, 107, 144, 178, 125, 248, 196, 244 },
|
||||
new byte[] { 127, 108, 145, 180, 126, 249, 197, 245 },
|
||||
new byte[] { 128, 108, 145, 181, 127, 249, 198, 245 },
|
||||
new byte[] { 130, 109, 145, 183, 128, 249, 199, 245 },
|
||||
new byte[] { 132, 109, 145, 184, 128, 249, 200, 245 },
|
||||
new byte[] { 134, 110, 146, 186, 129, 250, 201, 246 },
|
||||
new byte[] { 135, 110, 146, 187, 130, 250, 202, 246 },
|
||||
new byte[] { 137, 111, 147, 189, 131, 251, 203, 246 },
|
||||
new byte[] { 138, 111, 147, 190, 131, 251, 204, 246 },
|
||||
new byte[] { 140, 112, 147, 192, 132, 251, 205, 247 },
|
||||
new byte[] { 141, 112, 147, 193, 132, 251, 206, 247 },
|
||||
new byte[] { 143, 113, 148, 194, 133, 251, 207, 247 },
|
||||
new byte[] { 144, 113, 148, 195, 134, 251, 207, 247 },
|
||||
new byte[] { 146, 114, 149, 197, 135, 252, 208, 248 },
|
||||
new byte[] { 147, 114, 149, 198, 135, 252, 209, 248 },
|
||||
new byte[] { 149, 115, 149, 199, 136, 252, 210, 248 },
|
||||
new byte[] { 150, 115, 149, 200, 137, 252, 210, 248 },
|
||||
new byte[] { 152, 115, 150, 201, 138, 252, 211, 248 },
|
||||
new byte[] { 153, 115, 150, 202, 138, 252, 212, 248 },
|
||||
new byte[] { 155, 116, 151, 204, 139, 253, 213, 249 },
|
||||
new byte[] { 156, 116, 151, 205, 139, 253, 213, 249 },
|
||||
new byte[] { 158, 117, 151, 206, 140, 253, 214, 249 },
|
||||
new byte[] { 159, 117, 151, 207, 141, 253, 215, 249 },
|
||||
new byte[] { 161, 118, 152, 208, 142, 253, 216, 249 },
|
||||
new byte[] { 162, 118, 152, 209, 142, 253, 216, 249 },
|
||||
new byte[] { 163, 119, 153, 210, 143, 253, 217, 249 },
|
||||
new byte[] { 164, 119, 153, 211, 143, 253, 217, 249 },
|
||||
new byte[] { 166, 120, 153, 212, 144, 254, 218, 250 },
|
||||
new byte[] { 167, 120, 153, 212, 145, 254, 219, 250 },
|
||||
new byte[] { 168, 121, 154, 213, 146, 254, 220, 250 },
|
||||
new byte[] { 169, 121, 154, 214, 146, 254, 220, 250 },
|
||||
new byte[] { 171, 122, 155, 215, 147, 254, 221, 250 },
|
||||
new byte[] { 172, 122, 155, 216, 147, 254, 221, 250 },
|
||||
new byte[] { 173, 123, 155, 217, 148, 254, 222, 250 },
|
||||
new byte[] { 174, 123, 155, 217, 149, 254, 222, 250 },
|
||||
new byte[] { 176, 124, 156, 218, 150, 254, 223, 250 },
|
||||
new byte[] { 177, 124, 156, 219, 150, 254, 223, 250 },
|
||||
new byte[] { 178, 125, 157, 220, 151, 254, 224, 251 },
|
||||
new byte[] { 179, 125, 157, 220, 151, 254, 224, 251 },
|
||||
new byte[] { 180, 126, 157, 221, 152, 254, 225, 251 },
|
||||
new byte[] { 181, 126, 157, 221, 152, 254, 225, 251 },
|
||||
new byte[] { 183, 127, 158, 222, 153, 254, 226, 251 },
|
||||
new byte[] { 184, 127, 158, 223, 154, 254, 226, 251 },
|
||||
new byte[] { 185, 128, 159, 224, 155, 255, 227, 251 },
|
||||
new byte[] { 186, 128, 159, 224, 155, 255, 227, 251 },
|
||||
new byte[] { 187, 129, 160, 225, 156, 255, 228, 251 },
|
||||
new byte[] { 188, 130, 160, 225, 156, 255, 228, 251 },
|
||||
new byte[] { 189, 131, 160, 226, 157, 255, 228, 251 },
|
||||
new byte[] { 190, 131, 160, 226, 158, 255, 228, 251 },
|
||||
new byte[] { 191, 132, 161, 227, 159, 255, 229, 251 },
|
||||
new byte[] { 192, 132, 161, 227, 159, 255, 229, 251 },
|
||||
new byte[] { 193, 133, 162, 228, 160, 255, 230, 252 },
|
||||
new byte[] { 194, 133, 162, 229, 160, 255, 230, 252 },
|
||||
new byte[] { 195, 134, 163, 230, 161, 255, 231, 252 },
|
||||
new byte[] { 196, 134, 163, 230, 161, 255, 231, 252 },
|
||||
new byte[] { 197, 135, 163, 231, 162, 255, 231, 252 },
|
||||
new byte[] { 198, 135, 163, 231, 162, 255, 231, 252 },
|
||||
new byte[] { 199, 136, 164, 232, 163, 255, 232, 252 },
|
||||
new byte[] { 200, 136, 164, 232, 164, 255, 232, 252 },
|
||||
new byte[] { 201, 137, 165, 233, 165, 255, 233, 252 },
|
||||
new byte[] { 201, 137, 165, 233, 165, 255, 233, 252 },
|
||||
new byte[] { 202, 138, 166, 233, 166, 255, 233, 252 },
|
||||
new byte[] { 203, 138, 166, 233, 166, 255, 233, 252 },
|
||||
new byte[] { 204, 139, 166, 234, 167, 255, 234, 252 },
|
||||
new byte[] { 205, 139, 166, 234, 167, 255, 234, 252 },
|
||||
new byte[] { 206, 140, 167, 235, 168, 255, 235, 252 },
|
||||
new byte[] { 206, 140, 167, 235, 168, 255, 235, 252 },
|
||||
new byte[] { 207, 141, 168, 236, 169, 255, 235, 252 },
|
||||
new byte[] { 208, 141, 168, 236, 170, 255, 235, 252 },
|
||||
new byte[] { 209, 142, 169, 237, 171, 255, 236, 252 },
|
||||
new byte[] { 209, 143, 169, 237, 171, 255, 236, 252 },
|
||||
new byte[] { 210, 144, 169, 237, 172, 255, 236, 252 },
|
||||
new byte[] { 211, 144, 169, 237, 172, 255, 236, 252 },
|
||||
new byte[] { 212, 145, 170, 238, 173, 255, 237, 252 },
|
||||
new byte[] { 213, 145, 170, 238, 173, 255, 237, 252 },
|
||||
new byte[] { 214, 146, 171, 239, 174, 255, 237, 253 },
|
||||
new byte[] { 214, 146, 171, 239, 174, 255, 237, 253 },
|
||||
new byte[] { 215, 147, 172, 240, 175, 255, 238, 253 },
|
||||
new byte[] { 215, 147, 172, 240, 175, 255, 238, 253 },
|
||||
new byte[] { 216, 148, 173, 240, 176, 255, 238, 253 },
|
||||
new byte[] { 217, 148, 173, 240, 176, 255, 238, 253 },
|
||||
new byte[] { 218, 149, 173, 241, 177, 255, 239, 253 },
|
||||
new byte[] { 218, 149, 173, 241, 178, 255, 239, 253 },
|
||||
new byte[] { 219, 150, 174, 241, 179, 255, 239, 253 },
|
||||
new byte[] { 219, 151, 174, 241, 179, 255, 239, 253 },
|
||||
new byte[] { 220, 152, 175, 242, 180, 255, 240, 253 },
|
||||
new byte[] { 221, 152, 175, 242, 180, 255, 240, 253 },
|
||||
new byte[] { 222, 153, 176, 242, 181, 255, 240, 253 },
|
||||
new byte[] { 222, 153, 176, 242, 181, 255, 240, 253 },
|
||||
new byte[] { 223, 154, 177, 243, 182, 255, 240, 253 },
|
||||
new byte[] { 223, 154, 177, 243, 182, 255, 240, 253 },
|
||||
new byte[] { 224, 155, 178, 244, 183, 255, 241, 253 },
|
||||
new byte[] { 224, 155, 178, 244, 183, 255, 241, 253 },
|
||||
new byte[] { 225, 156, 178, 244, 184, 255, 241, 253 },
|
||||
new byte[] { 225, 157, 178, 244, 184, 255, 241, 253 },
|
||||
new byte[] { 226, 158, 179, 244, 185, 255, 242, 253 },
|
||||
new byte[] { 227, 158, 179, 244, 185, 255, 242, 253 },
|
||||
new byte[] { 228, 159, 180, 245, 186, 255, 242, 253 },
|
||||
new byte[] { 228, 159, 180, 245, 186, 255, 242, 253 },
|
||||
new byte[] { 229, 160, 181, 245, 187, 255, 242, 253 },
|
||||
new byte[] { 229, 160, 181, 245, 187, 255, 242, 253 },
|
||||
new byte[] { 230, 161, 182, 246, 188, 255, 243, 253 },
|
||||
new byte[] { 230, 162, 182, 246, 188, 255, 243, 253 },
|
||||
new byte[] { 231, 163, 183, 246, 189, 255, 243, 253 },
|
||||
new byte[] { 231, 163, 183, 246, 189, 255, 243, 253 },
|
||||
new byte[] { 232, 164, 184, 247, 190, 255, 243, 253 },
|
||||
new byte[] { 232, 164, 184, 247, 190, 255, 243, 253 },
|
||||
new byte[] { 233, 165, 185, 247, 191, 255, 244, 253 },
|
||||
new byte[] { 233, 165, 185, 247, 191, 255, 244, 253 },
|
||||
new byte[] { 234, 166, 185, 247, 192, 255, 244, 253 },
|
||||
new byte[] { 234, 167, 185, 247, 192, 255, 244, 253 },
|
||||
new byte[] { 235, 168, 186, 248, 193, 255, 244, 253 },
|
||||
new byte[] { 235, 168, 186, 248, 193, 255, 244, 253 },
|
||||
new byte[] { 236, 169, 187, 248, 194, 255, 244, 253 },
|
||||
new byte[] { 236, 169, 187, 248, 194, 255, 244, 253 },
|
||||
new byte[] { 236, 170, 188, 248, 195, 255, 245, 253 },
|
||||
new byte[] { 236, 170, 188, 248, 195, 255, 245, 253 },
|
||||
new byte[] { 237, 171, 189, 249, 196, 255, 245, 254 },
|
||||
new byte[] { 237, 172, 189, 249, 196, 255, 245, 254 },
|
||||
new byte[] { 238, 173, 190, 249, 197, 255, 245, 254 },
|
||||
new byte[] { 238, 173, 190, 249, 197, 255, 245, 254 },
|
||||
new byte[] { 239, 174, 191, 249, 198, 255, 245, 254 },
|
||||
new byte[] { 239, 174, 191, 249, 198, 255, 245, 254 },
|
||||
new byte[] { 240, 175, 192, 249, 199, 255, 246, 254 },
|
||||
new byte[] { 240, 176, 192, 249, 199, 255, 246, 254 },
|
||||
new byte[] { 240, 177, 193, 250, 200, 255, 246, 254 },
|
||||
new byte[] { 240, 177, 193, 250, 200, 255, 246, 254 },
|
||||
new byte[] { 241, 178, 194, 250, 201, 255, 246, 254 },
|
||||
new byte[] { 241, 178, 194, 250, 201, 255, 246, 254 },
|
||||
new byte[] { 242, 179, 195, 250, 202, 255, 246, 254 },
|
||||
new byte[] { 242, 180, 195, 250, 202, 255, 246, 254 },
|
||||
new byte[] { 242, 181, 196, 250, 203, 255, 247, 254 },
|
||||
new byte[] { 242, 181, 196, 250, 203, 255, 247, 254 },
|
||||
new byte[] { 243, 182, 197, 251, 204, 255, 247, 254 },
|
||||
new byte[] { 243, 183, 197, 251, 204, 255, 247, 254 },
|
||||
new byte[] { 244, 184, 198, 251, 205, 255, 247, 254 },
|
||||
new byte[] { 244, 184, 198, 251, 205, 255, 247, 254 },
|
||||
new byte[] { 244, 185, 199, 251, 206, 255, 247, 254 },
|
||||
new byte[] { 244, 185, 199, 251, 206, 255, 247, 254 },
|
||||
new byte[] { 245, 186, 200, 251, 207, 255, 247, 254 },
|
||||
new byte[] { 245, 187, 200, 251, 207, 255, 247, 254 },
|
||||
new byte[] { 246, 188, 201, 252, 207, 255, 248, 254 },
|
||||
new byte[] { 246, 188, 201, 252, 207, 255, 248, 254 },
|
||||
new byte[] { 246, 189, 202, 252, 208, 255, 248, 254 },
|
||||
new byte[] { 246, 190, 202, 252, 208, 255, 248, 254 },
|
||||
new byte[] { 247, 191, 203, 252, 209, 255, 248, 254 },
|
||||
new byte[] { 247, 191, 203, 252, 209, 255, 248, 254 },
|
||||
new byte[] { 247, 192, 204, 252, 210, 255, 248, 254 },
|
||||
new byte[] { 247, 193, 204, 252, 210, 255, 248, 254 },
|
||||
new byte[] { 248, 194, 205, 252, 211, 255, 248, 254 },
|
||||
new byte[] { 248, 194, 205, 252, 211, 255, 248, 254 },
|
||||
new byte[] { 248, 195, 206, 252, 212, 255, 249, 254 },
|
||||
new byte[] { 248, 196, 206, 252, 212, 255, 249, 254 },
|
||||
new byte[] { 249, 197, 207, 253, 213, 255, 249, 254 },
|
||||
new byte[] { 249, 197, 207, 253, 213, 255, 249, 254 },
|
||||
new byte[] { 249, 198, 208, 253, 214, 255, 249, 254 },
|
||||
new byte[] { 249, 199, 209, 253, 214, 255, 249, 254 },
|
||||
new byte[] { 250, 200, 210, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 200, 210, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 201, 211, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 202, 211, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 203, 212, 253, 216, 255, 249, 254 },
|
||||
new byte[] { 250, 203, 212, 253, 216, 255, 249, 254 },
|
||||
new byte[] { 251, 204, 213, 253, 217, 255, 250, 254 },
|
||||
new byte[] { 251, 205, 213, 253, 217, 255, 250, 254 },
|
||||
new byte[] { 251, 206, 214, 254, 218, 255, 250, 254 },
|
||||
new byte[] { 251, 206, 215, 254, 218, 255, 250, 254 },
|
||||
new byte[] { 252, 207, 216, 254, 219, 255, 250, 254 },
|
||||
new byte[] { 252, 208, 216, 254, 219, 255, 250, 254 },
|
||||
new byte[] { 252, 209, 217, 254, 220, 255, 250, 254 },
|
||||
new byte[] { 252, 210, 217, 254, 220, 255, 250, 254 },
|
||||
new byte[] { 252, 211, 218, 254, 221, 255, 250, 254 },
|
||||
new byte[] { 252, 212, 218, 254, 221, 255, 250, 254 },
|
||||
new byte[] { 253, 213, 219, 254, 222, 255, 250, 254 },
|
||||
new byte[] { 253, 213, 220, 254, 222, 255, 250, 254 },
|
||||
new byte[] { 253, 214, 221, 254, 223, 255, 250, 254 },
|
||||
new byte[] { 253, 215, 221, 254, 223, 255, 250, 254 },
|
||||
new byte[] { 253, 216, 222, 254, 224, 255, 251, 254 },
|
||||
new byte[] { 253, 217, 223, 254, 224, 255, 251, 254 },
|
||||
new byte[] { 253, 218, 224, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 253, 219, 224, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 254, 220, 225, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 254, 221, 226, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 254, 222, 227, 255, 226, 255, 251, 254 },
|
||||
new byte[] { 254, 223, 227, 255, 226, 255, 251, 254 },
|
||||
new byte[] { 254, 224, 228, 255, 227, 255, 251, 254 },
|
||||
new byte[] { 254, 225, 229, 255, 227, 255, 251, 254 },
|
||||
new byte[] { 254, 226, 230, 255, 228, 255, 251, 254 },
|
||||
new byte[] { 254, 227, 230, 255, 229, 255, 251, 254 },
|
||||
new byte[] { 255, 228, 231, 255, 230, 255, 251, 254 },
|
||||
new byte[] { 255, 229, 232, 255, 230, 255, 251, 254 },
|
||||
new byte[] { 255, 230, 233, 255, 231, 255, 252, 254 },
|
||||
new byte[] { 255, 231, 234, 255, 231, 255, 252, 254 },
|
||||
new byte[] { 255, 232, 235, 255, 232, 255, 252, 254 },
|
||||
new byte[] { 255, 233, 236, 255, 232, 255, 252, 254 },
|
||||
new byte[] { 255, 235, 237, 255, 233, 255, 252, 254 },
|
||||
new byte[] { 255, 236, 238, 255, 234, 255, 252, 254 },
|
||||
new byte[] { 255, 238, 240, 255, 235, 255, 252, 255 },
|
||||
new byte[] { 255, 239, 241, 255, 235, 255, 252, 254 },
|
||||
new byte[] { 255, 241, 243, 255, 236, 255, 252, 254 },
|
||||
new byte[] { 255, 243, 245, 255, 237, 255, 252, 254 },
|
||||
new byte[] { 255, 246, 247, 255, 239, 255, 253, 255 }
|
||||
};
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs4x4 =
|
||||
{
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
195, 29, 183, 84, 49, 136, 8, 42, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
31, 107, 169, 35, 99, 159, 17, 82, 140, 8, 66, 114, 2, 44, 76, 1, 19, 32,
|
||||
// Band 2
|
||||
40, 132, 201, 29, 114, 187, 13, 91, 157, 7, 75, 127, 3, 58, 95, 1, 28, 47,
|
||||
// Band 3
|
||||
69, 142, 221, 42, 122, 201, 15, 91, 159, 6, 67, 121, 1, 42, 77, 1, 17, 31,
|
||||
// Band 4
|
||||
102, 148, 228, 67, 117, 204, 17, 82, 154, 6, 59, 114, 2, 39, 75, 1, 15, 29,
|
||||
// Band 5
|
||||
156, 57, 233, 119, 57, 212, 58, 48, 163, 29, 40, 124, 12, 30, 81, 3, 12, 31,
|
||||
// Inter
|
||||
// Band 0
|
||||
191, 107, 226, 124, 117, 204, 25, 99, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
29, 148, 210, 37, 126, 194, 8, 93, 157, 2, 68, 118, 1, 39, 69, 1, 17, 33,
|
||||
// Band 2
|
||||
41, 151, 213, 27, 123, 193, 3, 82, 144, 1, 58, 105, 1, 32, 60, 1, 13, 26,
|
||||
// Band 3
|
||||
59, 159, 220, 23, 126, 198, 4, 88, 151, 1, 66, 114, 1, 38, 71, 1, 18, 34,
|
||||
// Band 4
|
||||
114, 136, 232, 51, 114, 207, 11, 83, 155, 3, 56, 105, 1, 33, 65, 1, 17, 34,
|
||||
// Band 5
|
||||
149, 65, 234, 121, 57, 215, 61, 49, 166, 28, 36, 114, 12, 25, 76, 3, 16, 42,
|
||||
// UV plane
|
||||
// Intra
|
||||
// Band 0
|
||||
214, 49, 220, 132, 63, 188, 42, 65, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
85, 137, 221, 104, 131, 216, 49, 111, 192, 21, 87, 155, 2, 49, 87, 1, 16, 28,
|
||||
// Band 2
|
||||
89, 163, 230, 90, 137, 220, 29, 100, 183, 10, 70, 135, 2, 42, 81, 1, 17, 33,
|
||||
// Band 3
|
||||
108, 167, 237, 55, 133, 222, 15, 97, 179, 4, 72, 135, 1, 45, 85, 1, 19, 38,
|
||||
// Band 4
|
||||
124, 146, 240, 66, 124, 224, 17, 88, 175, 4, 58, 122, 1, 36, 75, 1, 18, 37,
|
||||
// Band 5
|
||||
141, 79, 241, 126, 70, 227, 66, 58, 182, 30, 44, 136, 12, 34, 96, 2, 20, 47,
|
||||
// Inter
|
||||
// Band 0
|
||||
229, 99, 249, 143, 111, 235, 46, 109, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
82, 158, 236, 94, 146, 224, 25, 117, 191, 9, 87, 149, 3, 56, 99, 1, 33, 57,
|
||||
// Band 2
|
||||
83, 167, 237, 68, 145, 222, 10, 103, 177, 2, 72, 131, 1, 41, 79, 1, 20, 39,
|
||||
// Band 3
|
||||
99, 167, 239, 47, 141, 224, 10, 104, 178, 2, 73, 133, 1, 44, 85, 1, 22, 47,
|
||||
// Band 4
|
||||
127, 145, 243, 71, 129, 228, 17, 93, 177, 3, 61, 124, 1, 41, 84, 1, 21, 52,
|
||||
// Band 5
|
||||
157, 78, 244, 140, 72, 231, 69, 58, 184, 31, 44, 137, 14, 38, 105, 8, 23, 61
|
||||
};
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs8x8 =
|
||||
{
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
125, 34, 187, 52, 41, 133, 6, 31, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
37, 109, 153, 51, 102, 147, 23, 87, 128, 8, 67, 101, 1, 41, 63, 1, 19, 29,
|
||||
// Band 2
|
||||
31, 154, 185, 17, 127, 175, 6, 96, 145, 2, 73, 114, 1, 51, 82, 1, 28, 45,
|
||||
// Band 3
|
||||
23, 163, 200, 10, 131, 185, 2, 93, 148, 1, 67, 111, 1, 41, 69, 1, 14, 24,
|
||||
// Band 4
|
||||
29, 176, 217, 12, 145, 201, 3, 101, 156, 1, 69, 111, 1, 39, 63, 1, 14, 23,
|
||||
// Band 5
|
||||
57, 192, 233, 25, 154, 215, 6, 109, 167, 3, 78, 118, 1, 48, 69, 1, 21, 29,
|
||||
// Inter
|
||||
// Band 0
|
||||
202, 105, 245, 108, 106, 216, 18, 90, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
33, 172, 219, 64, 149, 206, 14, 117, 177, 5, 90, 141, 2, 61, 95, 1, 37, 57,
|
||||
// Band 2
|
||||
33, 179, 220, 11, 140, 198, 1, 89, 148, 1, 60, 104, 1, 33, 57, 1, 12, 21,
|
||||
// Band 3
|
||||
30, 181, 221, 8, 141, 198, 1, 87, 145, 1, 58, 100, 1, 31, 55, 1, 12, 20,
|
||||
// Band 4
|
||||
32, 186, 224, 7, 142, 198, 1, 86, 143, 1, 58, 100, 1, 31, 55, 1, 12, 22,
|
||||
// Band 5
|
||||
57, 192, 227, 20, 143, 204, 3, 96, 154, 1, 68, 112, 1, 42, 69, 1, 19, 32,
|
||||
// UV plane
|
||||
// Intra
|
||||
// Band 0
|
||||
212, 35, 215, 113, 47, 169, 29, 48, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
74, 129, 203, 106, 120, 203, 49, 107, 178, 19, 84, 144, 4, 50, 84, 1, 15, 25,
|
||||
// Band 2
|
||||
71, 172, 217, 44, 141, 209, 15, 102, 173, 6, 76, 133, 2, 51, 89, 1, 24, 42,
|
||||
// Band 3
|
||||
64, 185, 231, 31, 148, 216, 8, 103, 175, 3, 74, 131, 1, 46, 81, 1, 18, 30,
|
||||
// Band 4
|
||||
65, 196, 235, 25, 157, 221, 5, 105, 174, 1, 67, 120, 1, 38, 69, 1, 15, 30,
|
||||
// Band 5
|
||||
65, 204, 238, 30, 156, 224, 7, 107, 177, 2, 70, 124, 1, 42, 73, 1, 18, 34,
|
||||
// Inter
|
||||
// Band 0
|
||||
225, 86, 251, 144, 104, 235, 42, 99, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
85, 175, 239, 112, 165, 229, 29, 136, 200, 12, 103, 162, 6, 77, 123, 2, 53, 84,
|
||||
// Band 2
|
||||
75, 183, 239, 30, 155, 221, 3, 106, 171, 1, 74, 128, 1, 44, 76, 1, 17, 28,
|
||||
// Band 3
|
||||
73, 185, 240, 27, 159, 222, 2, 107, 172, 1, 75, 127, 1, 42, 73, 1, 17, 29,
|
||||
// Band 4
|
||||
62, 190, 238, 21, 159, 222, 2, 107, 172, 1, 72, 122, 1, 40, 71, 1, 18, 32,
|
||||
// Band 5
|
||||
61, 199, 240, 27, 161, 226, 4, 113, 180, 1, 76, 129, 1, 46, 80, 1, 23, 41
|
||||
};
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs16x16 =
|
||||
{
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
7, 27, 153, 5, 30, 95, 1, 16, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
50, 75, 127, 57, 75, 124, 27, 67, 108, 10, 54, 86, 1, 33, 52, 1, 12, 18,
|
||||
// Band 2
|
||||
43, 125, 151, 26, 108, 148, 7, 83, 122, 2, 59, 89, 1, 38, 60, 1, 17, 27,
|
||||
// Band 3
|
||||
23, 144, 163, 13, 112, 154, 2, 75, 117, 1, 50, 81, 1, 31, 51, 1, 14, 23,
|
||||
// Band 4
|
||||
18, 162, 185, 6, 123, 171, 1, 78, 125, 1, 51, 86, 1, 31, 54, 1, 14, 23,
|
||||
// Band 5
|
||||
15, 199, 227, 3, 150, 204, 1, 91, 146, 1, 55, 95, 1, 30, 53, 1, 11, 20,
|
||||
// Inter
|
||||
// Band 0
|
||||
19, 55, 240, 19, 59, 196, 3, 52, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
41, 166, 207, 104, 153, 199, 31, 123, 181, 14, 101, 152, 5, 72, 106, 1, 36, 52,
|
||||
// Band 2
|
||||
35, 176, 211, 12, 131, 190, 2, 88, 144, 1, 60, 101, 1, 36, 60, 1, 16, 28,
|
||||
// Band 3
|
||||
28, 183, 213, 8, 134, 191, 1, 86, 142, 1, 56, 96, 1, 30, 53, 1, 12, 20,
|
||||
// Band 4
|
||||
20, 190, 215, 4, 135, 192, 1, 84, 139, 1, 53, 91, 1, 28, 49, 1, 11, 20,
|
||||
// Band 5
|
||||
13, 196, 216, 2, 137, 192, 1, 86, 143, 1, 57, 99, 1, 32, 56, 1, 13, 24,
|
||||
// UV plane
|
||||
// Intra
|
||||
// Band 0
|
||||
211, 29, 217, 96, 47, 156, 22, 43, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
78, 120, 193, 111, 116, 186, 46, 102, 164, 15, 80, 128, 2, 49, 76, 1, 18, 28,
|
||||
// Band 2
|
||||
71, 161, 203, 42, 132, 192, 10, 98, 150, 3, 69, 109, 1, 44, 70, 1, 18, 29,
|
||||
// Band 3
|
||||
57, 186, 211, 30, 140, 196, 4, 93, 146, 1, 62, 102, 1, 38, 65, 1, 16, 27,
|
||||
// Band 4
|
||||
47, 199, 217, 14, 145, 196, 1, 88, 142, 1, 57, 98, 1, 36, 62, 1, 15, 26,
|
||||
// Band 5
|
||||
26, 219, 229, 5, 155, 207, 1, 94, 151, 1, 60, 104, 1, 36, 62, 1, 16, 28,
|
||||
// Inter
|
||||
// Band 0
|
||||
233, 29, 248, 146, 47, 220, 43, 52, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
100, 163, 232, 179, 161, 222, 63, 142, 204, 37, 113, 174, 26, 89, 137, 18, 68, 97,
|
||||
// Band 2
|
||||
85, 181, 230, 32, 146, 209, 7, 100, 164, 3, 71, 121, 1, 45, 77, 1, 18, 30,
|
||||
// Band 3
|
||||
65, 187, 230, 20, 148, 207, 2, 97, 159, 1, 68, 116, 1, 40, 70, 1, 14, 29,
|
||||
// Band 4
|
||||
40, 194, 227, 8, 147, 204, 1, 94, 155, 1, 65, 112, 1, 39, 66, 1, 14, 26,
|
||||
// Band 5
|
||||
16, 208, 228, 3, 151, 207, 1, 98, 160, 1, 67, 117, 1, 41, 74, 1, 17, 31
|
||||
};
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs32x32 =
|
||||
{
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
17, 38, 140, 7, 34, 80, 1, 17, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
37, 75, 128, 41, 76, 128, 26, 66, 116, 12, 52, 94, 2, 32, 55, 1, 10, 16,
|
||||
// Band 2
|
||||
50, 127, 154, 37, 109, 152, 16, 82, 121, 5, 59, 85, 1, 35, 54, 1, 13, 20,
|
||||
// Band 3
|
||||
40, 142, 167, 17, 110, 157, 2, 71, 112, 1, 44, 72, 1, 27, 45, 1, 11, 17,
|
||||
// Band 4
|
||||
30, 175, 188, 9, 124, 169, 1, 74, 116, 1, 48, 78, 1, 30, 49, 1, 11, 18,
|
||||
// Band 5
|
||||
10, 222, 223, 2, 150, 194, 1, 83, 128, 1, 48, 79, 1, 27, 45, 1, 11, 17,
|
||||
// Inter
|
||||
// Band 0
|
||||
36, 41, 235, 29, 36, 193, 10, 27, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
85, 165, 222, 177, 162, 215, 110, 135, 195, 57, 113, 168, 23, 83, 120, 10, 49, 61,
|
||||
// Band 2
|
||||
85, 190, 223, 36, 139, 200, 5, 90, 146, 1, 60, 103, 1, 38, 65, 1, 18, 30,
|
||||
// Band 3
|
||||
72, 202, 223, 23, 141, 199, 2, 86, 140, 1, 56, 97, 1, 36, 61, 1, 16, 27,
|
||||
// Band 4
|
||||
55, 218, 225, 13, 145, 200, 1, 86, 141, 1, 57, 99, 1, 35, 61, 1, 13, 22,
|
||||
// Band 5
|
||||
15, 235, 212, 1, 132, 184, 1, 84, 139, 1, 57, 97, 1, 34, 56, 1, 14, 23,
|
||||
// UV plane
|
||||
// Intra
|
||||
// Band 0
|
||||
181, 21, 201, 61, 37, 123, 10, 38, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
47, 106, 172, 95, 104, 173, 42, 93, 159, 18, 77, 131, 4, 50, 81, 1, 17, 23,
|
||||
// Band 2
|
||||
62, 147, 199, 44, 130, 189, 28, 102, 154, 18, 75, 115, 2, 44, 65, 1, 12, 19,
|
||||
// Band 3
|
||||
55, 153, 210, 24, 130, 194, 3, 93, 146, 1, 61, 97, 1, 31, 50, 1, 10, 16,
|
||||
// Band 4
|
||||
49, 186, 223, 17, 148, 204, 1, 96, 142, 1, 53, 83, 1, 26, 44, 1, 11, 17,
|
||||
// Band 5
|
||||
13, 217, 212, 2, 136, 180, 1, 78, 124, 1, 50, 83, 1, 29, 49, 1, 14, 23,
|
||||
// Inter
|
||||
// Band 0
|
||||
197, 13, 247, 82, 17, 222, 25, 17, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
126, 186, 247, 234, 191, 243, 176, 177, 234, 104, 158, 220, 66, 128, 186, 55, 90, 137,
|
||||
// Band 2
|
||||
111, 197, 242, 46, 158, 219, 9, 104, 171, 2, 65, 125, 1, 44, 80, 1, 17, 91,
|
||||
// Band 3
|
||||
104, 208, 245, 39, 168, 224, 3, 109, 162, 1, 79, 124, 1, 50, 102, 1, 43, 102,
|
||||
// Band 4
|
||||
84, 220, 246, 31, 177, 231, 2, 115, 180, 1, 79, 134, 1, 55, 77, 1, 60, 79,
|
||||
// Band 5
|
||||
43, 243, 240, 8, 180, 217, 1, 115, 166, 1, 84, 121, 1, 51, 67, 1, 16, 6
|
||||
};
|
||||
|
||||
public static byte[] GetBandTranslate(int txSize)
|
||||
{
|
||||
return txSize == (int)TxSize.Tx4x4 ? CoefbandTrans4x4 : CoefbandTrans8x8Plus;
|
||||
}
|
||||
|
||||
public static void CopyProbs<T>(ref T dest, ReadOnlySpan<byte> probs) where T : unmanaged
|
||||
{
|
||||
if (Unsafe.SizeOf<T>() != probs.Length)
|
||||
{
|
||||
throw new Exception("size mismatch expected: " + probs.Length + " got: " + Unsafe.SizeOf<T>());
|
||||
}
|
||||
|
||||
probs.CopyTo(MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateSpan(ref dest, 1)));
|
||||
}
|
||||
|
||||
internal const int CoefCountSat = 24;
|
||||
internal const int CoefMaxUpdateFactor = 112;
|
||||
internal const int CoefCountSatKey = 24;
|
||||
internal const int CoefMaxUpdateFactorKey = 112;
|
||||
internal const int CoefCountSatAfterKey = 24;
|
||||
internal const int CoefMaxUpdateFactorAfterKey = 128;
|
||||
}
|
||||
}
|
||||
@@ -1,400 +0,0 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal class EntropyMode
|
||||
{
|
||||
public const int BlockSizeGroups = 4;
|
||||
|
||||
public const int TxSizeContexts = 2;
|
||||
|
||||
public static readonly byte[][][] KfYModeProb =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
// above = dc
|
||||
new byte[] { 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc
|
||||
new byte[] { 92, 45, 102, 136, 116, 180, 74, 90, 100 }, // left = v
|
||||
new byte[] { 73, 32, 19, 187, 222, 215, 46, 34, 100 }, // left = h
|
||||
new byte[] { 91, 30, 32, 116, 121, 186, 93, 86, 94 }, // left = d45
|
||||
new byte[] { 72, 35, 36, 149, 68, 206, 68, 63, 105 }, // left = d135
|
||||
new byte[] { 73, 31, 28, 138, 57, 124, 55, 122, 151 }, // left = d117
|
||||
new byte[] { 67, 23, 21, 140, 126, 197, 40, 37, 171 }, // left = d153
|
||||
new byte[] { 86, 27, 28, 128, 154, 212, 45, 43, 53 }, // left = d207
|
||||
new byte[] { 74, 32, 27, 107, 86, 160, 63, 134, 102 }, // left = d63
|
||||
new byte[] { 59, 67, 44, 140, 161, 202, 78, 67, 119 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = v
|
||||
new byte[] { 63, 36, 126, 146, 123, 158, 60, 90, 96 }, // left = dc
|
||||
new byte[] { 43, 46, 168, 134, 107, 128, 69, 142, 92 }, // left = v
|
||||
new byte[] { 44, 29, 68, 159, 201, 177, 50, 57, 77 }, // left = h
|
||||
new byte[] { 58, 38, 76, 114, 97, 172, 78, 133, 92 }, // left = d45
|
||||
new byte[] { 46, 41, 76, 140, 63, 184, 69, 112, 57 }, // left = d135
|
||||
new byte[] { 38, 32, 85, 140, 46, 112, 54, 151, 133 }, // left = d117
|
||||
new byte[] { 39, 27, 61, 131, 110, 175, 44, 75, 136 }, // left = d153
|
||||
new byte[] { 52, 30, 74, 113, 130, 175, 51, 64, 58 }, // left = d207
|
||||
new byte[] { 47, 35, 80, 100, 74, 143, 64, 163, 74 }, // left = d63
|
||||
new byte[] { 36, 61, 116, 114, 128, 162, 80, 125, 82 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = h
|
||||
new byte[] { 82, 26, 26, 171, 208, 204, 44, 32, 105 }, // left = dc
|
||||
new byte[] { 55, 44, 68, 166, 179, 192, 57, 57, 108 }, // left = v
|
||||
new byte[] { 42, 26, 11, 199, 241, 228, 23, 15, 85 }, // left = h
|
||||
new byte[] { 68, 42, 19, 131, 160, 199, 55, 52, 83 }, // left = d45
|
||||
new byte[] { 58, 50, 25, 139, 115, 232, 39, 52, 118 }, // left = d135
|
||||
new byte[] { 50, 35, 33, 153, 104, 162, 64, 59, 131 }, // left = d117
|
||||
new byte[] { 44, 24, 16, 150, 177, 202, 33, 19, 156 }, // left = d153
|
||||
new byte[] { 55, 27, 12, 153, 203, 218, 26, 27, 49 }, // left = d207
|
||||
new byte[] { 53, 49, 21, 110, 116, 168, 59, 80, 76 }, // left = d63
|
||||
new byte[] { 38, 72, 19, 168, 203, 212, 50, 50, 107 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d45
|
||||
new byte[] { 103, 26, 36, 129, 132, 201, 83, 80, 93 }, // left = dc
|
||||
new byte[] { 59, 38, 83, 112, 103, 162, 98, 136, 90 }, // left = v
|
||||
new byte[] { 62, 30, 23, 158, 200, 207, 59, 57, 50 }, // left = h
|
||||
new byte[] { 67, 30, 29, 84, 86, 191, 102, 91, 59 }, // left = d45
|
||||
new byte[] { 60, 32, 33, 112, 71, 220, 64, 89, 104 }, // left = d135
|
||||
new byte[] { 53, 26, 34, 130, 56, 149, 84, 120, 103 }, // left = d117
|
||||
new byte[] { 53, 21, 23, 133, 109, 210, 56, 77, 172 }, // left = d153
|
||||
new byte[] { 77, 19, 29, 112, 142, 228, 55, 66, 36 }, // left = d207
|
||||
new byte[] { 61, 29, 29, 93, 97, 165, 83, 175, 162 }, // left = d63
|
||||
new byte[] { 47, 47, 43, 114, 137, 181, 100, 99, 95 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d135
|
||||
new byte[] { 69, 23, 29, 128, 83, 199, 46, 44, 101 }, // left = dc
|
||||
new byte[] { 53, 40, 55, 139, 69, 183, 61, 80, 110 }, // left = v
|
||||
new byte[] { 40, 29, 19, 161, 180, 207, 43, 24, 91 }, // left = h
|
||||
new byte[] { 60, 34, 19, 105, 61, 198, 53, 64, 89 }, // left = d45
|
||||
new byte[] { 52, 31, 22, 158, 40, 209, 58, 62, 89 }, // left = d135
|
||||
new byte[] { 44, 31, 29, 147, 46, 158, 56, 102, 198 }, // left = d117
|
||||
new byte[] { 35, 19, 12, 135, 87, 209, 41, 45, 167 }, // left = d153
|
||||
new byte[] { 55, 25, 21, 118, 95, 215, 38, 39, 66 }, // left = d207
|
||||
new byte[] { 51, 38, 25, 113, 58, 164, 70, 93, 97 }, // left = d63
|
||||
new byte[] { 47, 54, 34, 146, 108, 203, 72, 103, 151 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d117
|
||||
new byte[] { 64, 19, 37, 156, 66, 138, 49, 95, 133 }, // left = dc
|
||||
new byte[] { 46, 27, 80, 150, 55, 124, 55, 121, 135 }, // left = v
|
||||
new byte[] { 36, 23, 27, 165, 149, 166, 54, 64, 118 }, // left = h
|
||||
new byte[] { 53, 21, 36, 131, 63, 163, 60, 109, 81 }, // left = d45
|
||||
new byte[] { 40, 26, 35, 154, 40, 185, 51, 97, 123 }, // left = d135
|
||||
new byte[] { 35, 19, 34, 179, 19, 97, 48, 129, 124 }, // left = d117
|
||||
new byte[] { 36, 20, 26, 136, 62, 164, 33, 77, 154 }, // left = d153
|
||||
new byte[] { 45, 18, 32, 130, 90, 157, 40, 79, 91 }, // left = d207
|
||||
new byte[] { 45, 26, 28, 129, 45, 129, 49, 147, 123 }, // left = d63
|
||||
new byte[] { 38, 44, 51, 136, 74, 162, 57, 97, 121 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d153
|
||||
new byte[] { 75, 17, 22, 136, 138, 185, 32, 34, 166 }, // left = dc
|
||||
new byte[] { 56, 39, 58, 133, 117, 173, 48, 53, 187 }, // left = v
|
||||
new byte[] { 35, 21, 12, 161, 212, 207, 20, 23, 145 }, // left = h
|
||||
new byte[] { 56, 29, 19, 117, 109, 181, 55, 68, 112 }, // left = d45
|
||||
new byte[] { 47, 29, 17, 153, 64, 220, 59, 51, 114 }, // left = d135
|
||||
new byte[] { 46, 16, 24, 136, 76, 147, 41, 64, 172 }, // left = d117
|
||||
new byte[] { 34, 17, 11, 108, 152, 187, 13, 15, 209 }, // left = d153
|
||||
new byte[] { 51, 24, 14, 115, 133, 209, 32, 26, 104 }, // left = d207
|
||||
new byte[] { 55, 30, 18, 122, 79, 179, 44, 88, 116 }, // left = d63
|
||||
new byte[] { 37, 49, 25, 129, 168, 164, 41, 54, 148 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d207
|
||||
new byte[] { 82, 22, 32, 127, 143, 213, 39, 41, 70 }, // left = dc
|
||||
new byte[] { 62, 44, 61, 123, 105, 189, 48, 57, 64 }, // left = v
|
||||
new byte[] { 47, 25, 17, 175, 222, 220, 24, 30, 86 }, // left = h
|
||||
new byte[] { 68, 36, 17, 106, 102, 206, 59, 74, 74 }, // left = d45
|
||||
new byte[] { 57, 39, 23, 151, 68, 216, 55, 63, 58 }, // left = d135
|
||||
new byte[] { 49, 30, 35, 141, 70, 168, 82, 40, 115 }, // left = d117
|
||||
new byte[] { 51, 25, 15, 136, 129, 202, 38, 35, 139 }, // left = d153
|
||||
new byte[] { 68, 26, 16, 111, 141, 215, 29, 28, 28 }, // left = d207
|
||||
new byte[] { 59, 39, 19, 114, 75, 180, 77, 104, 42 }, // left = d63
|
||||
new byte[] { 40, 61, 26, 126, 152, 206, 61, 59, 93 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d63
|
||||
new byte[] { 78, 23, 39, 111, 117, 170, 74, 124, 94 }, // left = dc
|
||||
new byte[] { 48, 34, 86, 101, 92, 146, 78, 179, 134 }, // left = v
|
||||
new byte[] { 47, 22, 24, 138, 187, 178, 68, 69, 59 }, // left = h
|
||||
new byte[] { 56, 25, 33, 105, 112, 187, 95, 177, 129 }, // left = d45
|
||||
new byte[] { 48, 31, 27, 114, 63, 183, 82, 116, 56 }, // left = d135
|
||||
new byte[] { 43, 28, 37, 121, 63, 123, 61, 192, 169 }, // left = d117
|
||||
new byte[] { 42, 17, 24, 109, 97, 177, 56, 76, 122 }, // left = d153
|
||||
new byte[] { 58, 18, 28, 105, 139, 182, 70, 92, 63 }, // left = d207
|
||||
new byte[] { 46, 23, 32, 74, 86, 150, 67, 183, 88 }, // left = d63
|
||||
new byte[] { 36, 38, 48, 92, 122, 165, 88, 137, 91 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = tm
|
||||
new byte[] { 65, 70, 60, 155, 159, 199, 61, 60, 81 }, // left = dc
|
||||
new byte[] { 44, 78, 115, 132, 119, 173, 71, 112, 93 }, // left = v
|
||||
new byte[] { 39, 38, 21, 184, 227, 206, 42, 32, 64 }, // left = h
|
||||
new byte[] { 58, 47, 36, 124, 137, 193, 80, 82, 78 }, // left = d45
|
||||
new byte[] { 49, 50, 35, 144, 95, 205, 63, 78, 59 }, // left = d135
|
||||
new byte[] { 41, 53, 52, 148, 71, 142, 65, 128, 51 }, // left = d117
|
||||
new byte[] { 40, 36, 28, 143, 143, 202, 40, 55, 137 }, // left = d153
|
||||
new byte[] { 52, 34, 29, 129, 183, 227, 42, 35, 43 }, // left = d207
|
||||
new byte[] { 42, 44, 44, 104, 105, 164, 64, 130, 80 }, // left = d63
|
||||
new byte[] { 43, 81, 53, 140, 169, 204, 68, 84, 72 } // left = tm
|
||||
}
|
||||
};
|
||||
|
||||
public static readonly byte[][] KfUvModeProb =
|
||||
{
|
||||
new byte[] { 144, 11, 54, 157, 195, 130, 46, 58, 108 }, // y = dc
|
||||
new byte[] { 118, 15, 123, 148, 131, 101, 44, 93, 131 }, // y = v
|
||||
new byte[] { 113, 12, 23, 188, 226, 142, 26, 32, 125 }, // y = h
|
||||
new byte[] { 120, 11, 50, 123, 163, 135, 64, 77, 103 }, // y = d45
|
||||
new byte[] { 113, 9, 36, 155, 111, 157, 32, 44, 161 }, // y = d135
|
||||
new byte[] { 116, 9, 55, 176, 76, 96, 37, 61, 149 }, // y = d117
|
||||
new byte[] { 115, 9, 28, 141, 161, 167, 21, 25, 193 }, // y = d153
|
||||
new byte[] { 120, 12, 32, 145, 195, 142, 32, 38, 86 }, // y = d207
|
||||
new byte[] { 116, 12, 64, 120, 140, 125, 49, 115, 121 }, // y = d63
|
||||
new byte[] { 102, 19, 66, 162, 182, 122, 35, 59, 128 } // y = tm
|
||||
};
|
||||
|
||||
private static readonly byte[] DefaultIfYProbs =
|
||||
{
|
||||
65, 32, 18, 144, 162, 194, 41, 51, 98, // block_size < 8x8
|
||||
132, 68, 18, 165, 217, 196, 45, 40, 78, // block_size < 16x16
|
||||
173, 80, 19, 176, 240, 193, 64, 35, 46, // block_size < 32x32
|
||||
221, 135, 38, 194, 248, 121, 96, 85, 29 // block_size >= 32x32
|
||||
};
|
||||
|
||||
private static readonly byte[] DefaultIfUvProbs =
|
||||
{
|
||||
120, 7, 76, 176, 208, 126, 28, 54, 103, // y = dc
|
||||
48, 12, 154, 155, 139, 90, 34, 117, 119, // y = v
|
||||
67, 6, 25, 204, 243, 158, 13, 21, 96, // y = h
|
||||
97, 5, 44, 131, 176, 139, 48, 68, 97, // y = d45
|
||||
83, 5, 42, 156, 111, 152, 26, 49, 152, // y = d135
|
||||
80, 5, 58, 178, 74, 83, 33, 62, 145, // y = d117
|
||||
86, 5, 32, 154, 192, 168, 14, 22, 163, // y = d153
|
||||
85, 5, 32, 156, 216, 148, 19, 29, 73, // y = d207
|
||||
77, 7, 64, 116, 132, 122, 37, 126, 120, // y = d63
|
||||
101, 21, 107, 181, 192, 103, 19, 67, 125 // y = tm
|
||||
};
|
||||
|
||||
private static readonly byte[] DefaultPartitionProbs =
|
||||
{
|
||||
// 8x8 . 4x4
|
||||
199, 122, 141, // a/l both not split
|
||||
147, 63, 159, // a split, l not split
|
||||
148, 133, 118, // l split, a not split
|
||||
121, 104, 114, // a/l both split
|
||||
// 16x16 . 8x8
|
||||
174, 73, 87, // a/l both not split
|
||||
92, 41, 83, // a split, l not split
|
||||
82, 99, 50, // l split, a not split
|
||||
53, 39, 39, // a/l both split
|
||||
// 32x32 . 16x16
|
||||
177, 58, 59, // a/l both not split
|
||||
68, 26, 63, // a split, l not split
|
||||
52, 79, 25, // l split, a not split
|
||||
17, 14, 12, // a/l both split
|
||||
// 64x64 . 32x32
|
||||
222, 34, 30, // a/l both not split
|
||||
72, 16, 44, // a split, l not split
|
||||
58, 32, 12, // l split, a not split
|
||||
10, 7, 6 // a/l both split
|
||||
};
|
||||
|
||||
private static readonly byte[] DefaultInterModeProbs =
|
||||
{
|
||||
2, 173, 34, // 0 = both zero mv
|
||||
7, 145, 85, // 1 = one zero mv + one a predicted mv
|
||||
7, 166, 63, // 2 = two predicted mvs
|
||||
7, 94, 66, // 3 = one predicted/zero and one new mv
|
||||
8, 64, 46, // 4 = two new mvs
|
||||
17, 81, 31, // 5 = one intra neighbour + x
|
||||
25, 29, 30 // 6 = two intra neighbours
|
||||
};
|
||||
|
||||
/* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
|
||||
public static readonly sbyte[] IntraModeTree =
|
||||
{
|
||||
-(int)PredictionMode.DcPred, 2, /* 0 = DC_NODE */ -(int)PredictionMode.TmPred, 4, /* 1 = TM_NODE */
|
||||
-(int)PredictionMode.VPred, 6, /* 2 = V_NODE */ 8, 12, /* 3 = COM_NODE */ -(int)PredictionMode.HPred,
|
||||
10, /* 4 = H_NODE */ -(int)PredictionMode.D135Pred, -(int)PredictionMode.D117Pred, /* 5 = D135_NODE */
|
||||
-(int)PredictionMode.D45Pred, 14, /* 6 = D45_NODE */ -(int)PredictionMode.D63Pred,
|
||||
16, /* 7 = D63_NODE */ -(int)PredictionMode.D153Pred, -(int)PredictionMode.D207Pred /* 8 = D153_NODE */
|
||||
};
|
||||
|
||||
public static readonly sbyte[] InterModeTree =
|
||||
{
|
||||
-((int)PredictionMode.ZeroMv - (int)PredictionMode.NearestMv), 2,
|
||||
-((int)PredictionMode.NearestMv - (int)PredictionMode.NearestMv), 4,
|
||||
-((int)PredictionMode.NearMv - (int)PredictionMode.NearestMv),
|
||||
-((int)PredictionMode.NewMv - (int)PredictionMode.NearestMv)
|
||||
};
|
||||
|
||||
public static readonly sbyte[] PartitionTree =
|
||||
{
|
||||
-(sbyte)PartitionType.PartitionNone, 2, -(sbyte)PartitionType.PartitionHorz, 4,
|
||||
-(sbyte)PartitionType.PartitionVert, -(sbyte)PartitionType.PartitionSplit
|
||||
};
|
||||
|
||||
public static readonly sbyte[] SwitchableInterpTree =
|
||||
{
|
||||
-Constants.EightTap, 2, -Constants.EightTapSmooth, -Constants.EightTapSharp
|
||||
};
|
||||
|
||||
private static readonly byte[] DefaultIntraInterP = { 9, 102, 187, 225 };
|
||||
private static readonly byte[] DefaultCompInterP = { 239, 183, 119, 96, 41 };
|
||||
private static readonly byte[] DefaultCompRefP = { 50, 126, 123, 221, 226 };
|
||||
private static readonly byte[] DefaultSingleRefP = { 33, 16, 77, 74, 142, 142, 172, 170, 238, 247 };
|
||||
private static readonly byte[] DefaultTxProbs = { 3, 136, 37, 5, 52, 13, 20, 152, 15, 101, 100, 66 };
|
||||
|
||||
static EntropyMode()
|
||||
{
|
||||
byte[][] KfPartitionProbs =
|
||||
{
|
||||
// 8x8 . 4x4
|
||||
new byte[] { 158, 97, 94 }, // a/l both not split
|
||||
new byte[] { 93, 24, 99 }, // a split, l not split
|
||||
new byte[] { 85, 119, 44 }, // l split, a not split
|
||||
new byte[] { 62, 59, 67 }, // a/l both split
|
||||
|
||||
// 16x16 . 8x8
|
||||
new byte[] { 149, 53, 53 }, // a/l both not split
|
||||
new byte[] { 94, 20, 48 }, // a split, l not split
|
||||
new byte[] { 83, 53, 24 }, // l split, a not split
|
||||
new byte[] { 52, 18, 18 }, // a/l both split
|
||||
|
||||
// 32x32 . 16x16
|
||||
new byte[] { 150, 40, 39 }, // a/l both not split
|
||||
new byte[] { 78, 12, 26 }, // a split, l not split
|
||||
new byte[] { 67, 33, 11 }, // l split, a not split
|
||||
new byte[] { 24, 7, 5 }, // a/l both split
|
||||
|
||||
// 64x64 . 32x32
|
||||
new byte[] { 174, 35, 49 }, // a/l both not split
|
||||
new byte[] { 68, 11, 27 }, // a split, l not split
|
||||
new byte[] { 57, 15, 9 }, // l split, a not split
|
||||
new byte[] { 12, 3, 3 } // a/l both split
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly byte[] DefaultSkipProbs = { 192, 128, 64 };
|
||||
|
||||
private static readonly byte[] DefaultSwitchableInterpProb = { 235, 162, 36, 255, 34, 3, 149, 144 };
|
||||
|
||||
private static void InitModeProbs(ref Vp9EntropyProbs fc)
|
||||
{
|
||||
Entropy.CopyProbs(ref fc.UvModeProb, DefaultIfUvProbs);
|
||||
Entropy.CopyProbs(ref fc.YModeProb, DefaultIfYProbs);
|
||||
Entropy.CopyProbs(ref fc.SwitchableInterpProb, DefaultSwitchableInterpProb);
|
||||
Entropy.CopyProbs(ref fc.PartitionProb, DefaultPartitionProbs);
|
||||
Entropy.CopyProbs(ref fc.IntraInterProb, DefaultIntraInterP);
|
||||
Entropy.CopyProbs(ref fc.CompInterProb, DefaultCompInterP);
|
||||
Entropy.CopyProbs(ref fc.CompRefProb, DefaultCompRefP);
|
||||
Entropy.CopyProbs(ref fc.SingleRefProb, DefaultSingleRefP);
|
||||
Entropy.CopyProbs(ref fc.Tx32x32Prob, DefaultTxProbs.AsSpan().Slice(0, 6));
|
||||
Entropy.CopyProbs(ref fc.Tx16x16Prob, DefaultTxProbs.AsSpan().Slice(6, 4));
|
||||
Entropy.CopyProbs(ref fc.Tx8x8Prob, DefaultTxProbs.AsSpan().Slice(10, 2));
|
||||
Entropy.CopyProbs(ref fc.SkipProb, DefaultSkipProbs);
|
||||
Entropy.CopyProbs(ref fc.InterModeProb, DefaultInterModeProbs);
|
||||
}
|
||||
|
||||
internal static void TxCountsToBranchCounts32x32(ReadOnlySpan<uint> txCount32x32P,
|
||||
ref Array3<Array2<uint>> ct32x32P)
|
||||
{
|
||||
ct32x32P[0][0] = txCount32x32P[(int)TxSize.Tx4x4];
|
||||
ct32x32P[0][1] = txCount32x32P[(int)TxSize.Tx8x8] + txCount32x32P[(int)TxSize.Tx16x16] +
|
||||
txCount32x32P[(int)TxSize.Tx32x32];
|
||||
ct32x32P[1][0] = txCount32x32P[(int)TxSize.Tx8x8];
|
||||
ct32x32P[1][1] = txCount32x32P[(int)TxSize.Tx16x16] + txCount32x32P[(int)TxSize.Tx32x32];
|
||||
ct32x32P[2][0] = txCount32x32P[(int)TxSize.Tx16x16];
|
||||
ct32x32P[2][1] = txCount32x32P[(int)TxSize.Tx32x32];
|
||||
}
|
||||
|
||||
internal static void TxCountsToBranchCounts16x16(ReadOnlySpan<uint> txCount16x16P,
|
||||
ref Array2<Array2<uint>> ct16x16P)
|
||||
{
|
||||
ct16x16P[0][0] = txCount16x16P[(int)TxSize.Tx4x4];
|
||||
ct16x16P[0][1] = txCount16x16P[(int)TxSize.Tx8x8] + txCount16x16P[(int)TxSize.Tx16x16];
|
||||
ct16x16P[1][0] = txCount16x16P[(int)TxSize.Tx8x8];
|
||||
ct16x16P[1][1] = txCount16x16P[(int)TxSize.Tx16x16];
|
||||
}
|
||||
|
||||
internal static void TxCountsToBranchCounts8x8(ReadOnlySpan<uint> txCount8x8P,
|
||||
ref Array1<Array2<uint>> ct8x8P)
|
||||
{
|
||||
ct8x8P[0][0] = txCount8x8P[(int)TxSize.Tx4x4];
|
||||
ct8x8P[0][1] = txCount8x8P[(int)TxSize.Tx8x8];
|
||||
}
|
||||
|
||||
public static unsafe void SetupPastIndependence(ref Vp9Common cm)
|
||||
{
|
||||
// Reset the segment feature data to the default stats:
|
||||
// Features disabled, 0, with delta coding (Default state).
|
||||
ref Types.LoopFilter lf = ref cm.Lf;
|
||||
|
||||
cm.Seg.ClearAllSegFeatures();
|
||||
cm.Seg.AbsDelta = Segmentation.SegmentDeltadata;
|
||||
|
||||
if (!cm.LastFrameSegMap.IsNull)
|
||||
{
|
||||
MemoryUtil.Fill(cm.LastFrameSegMap.ToPointer(), (byte)0, cm.MiRows * cm.MiCols);
|
||||
}
|
||||
|
||||
if (!cm.CurrentFrameSegMap.IsNull)
|
||||
{
|
||||
MemoryUtil.Fill(cm.CurrentFrameSegMap.ToPointer(), (byte)0, cm.MiRows * cm.MiCols);
|
||||
}
|
||||
|
||||
// Reset the mode ref deltas for loop filter
|
||||
lf.LastRefDeltas = new Array4<sbyte>();
|
||||
lf.LastModeDeltas = new Array2<sbyte>();
|
||||
lf.SetDefaultLfDeltas();
|
||||
|
||||
// To force update of the sharpness
|
||||
lf.LastSharpnessLevel = -1;
|
||||
|
||||
cm.DefaultCoefProbs();
|
||||
InitModeProbs(ref cm.Fc.Value);
|
||||
cm.InitMvProbs();
|
||||
|
||||
if (cm.FrameType == FrameType.KeyFrame || cm.ErrorResilientMode != 0 || cm.ResetFrameContext == 3)
|
||||
{
|
||||
// Reset all frame contexts.
|
||||
for (int i = 0; i < Constants.FrameContexts; ++i)
|
||||
{
|
||||
cm.FrameContexts[i] = cm.Fc.Value;
|
||||
}
|
||||
}
|
||||
else if (cm.ResetFrameContext == 2)
|
||||
{
|
||||
// Reset only the frame context specified in the frame header.
|
||||
cm.FrameContexts[(int)cm.FrameContextIdx] = cm.Fc.Value;
|
||||
}
|
||||
|
||||
// prev_mip will only be allocated in encoder.
|
||||
if (cm.FrameIsIntraOnly() && !cm.PrevMip.IsNull)
|
||||
{
|
||||
cm.PrevMi.Value = new ModeInfo();
|
||||
}
|
||||
|
||||
cm.RefFrameSignBias = new Array4<sbyte>();
|
||||
|
||||
cm.FrameContextIdx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class EntropyMv
|
||||
{
|
||||
public const int UpdateProb = 252;
|
||||
|
||||
/* Symbols for coding which components are zero jointly */
|
||||
public const int Joints = 4;
|
||||
|
||||
|
||||
public static readonly sbyte[] JointTree =
|
||||
{
|
||||
-(sbyte)MvJointType.Zero, 2, -(sbyte)MvJointType.Hnzvz, 4,
|
||||
-(sbyte)MvJointType.Hzvnz, -(sbyte)MvJointType.Hnzvnz
|
||||
};
|
||||
|
||||
public static readonly sbyte[] ClassTree =
|
||||
{
|
||||
-(sbyte)MvClassType.Class0, 2, -(sbyte)MvClassType.Class1, 4, 6, 8, -(sbyte)MvClassType.Class2,
|
||||
-(sbyte)MvClassType.Class3, 10, 12, -(sbyte)MvClassType.Class4, -(sbyte)MvClassType.Class5,
|
||||
-(sbyte)MvClassType.Class6, 14, 16, 18, -(sbyte)MvClassType.Class7, -(sbyte)MvClassType.Class8,
|
||||
-(sbyte)MvClassType.Class9, -(sbyte)MvClassType.Class10
|
||||
};
|
||||
|
||||
public static readonly sbyte[] Class0Tree = { -0, -1 };
|
||||
|
||||
public static readonly sbyte[] FpTree = { -0, 2, -1, 4, -2, -3 };
|
||||
|
||||
private static bool JointVertical(MvJointType type)
|
||||
{
|
||||
return type == MvJointType.Hzvnz || type == MvJointType.Hnzvnz;
|
||||
}
|
||||
|
||||
private static bool JointHorizontal(MvJointType type)
|
||||
{
|
||||
return type == MvJointType.Hnzvz || type == MvJointType.Hnzvnz;
|
||||
}
|
||||
|
||||
private static readonly byte[] LogInBase2 =
|
||||
{
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 10
|
||||
};
|
||||
|
||||
private static int ClassBase(MvClassType c)
|
||||
{
|
||||
return c != 0 ? Class0Size << ((int)c + 2) : 0;
|
||||
}
|
||||
|
||||
private static MvClassType GetClass(int z, Ptr<int> offset)
|
||||
{
|
||||
MvClassType c = z >= Class0Size * 4096
|
||||
? MvClassType.Class10
|
||||
: (MvClassType)LogInBase2[z >> 3];
|
||||
if (!offset.IsNull)
|
||||
{
|
||||
offset.Value = z - ClassBase(c);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private static void IncComponent(int v, ref Vp9BackwardUpdates compCounts, int compIndex, int incr, int usehp)
|
||||
{
|
||||
int s, z, c, o = 0, d, e, f;
|
||||
Debug.Assert(v != 0); /* should not be zero */
|
||||
s = v < 0 ? 1 : 0;
|
||||
compCounts.Sign[compIndex][s] += (uint)incr;
|
||||
z = (s != 0 ? -v : v) - 1; /* magnitude - 1 */
|
||||
|
||||
c = (int)GetClass(z, new Ptr<int>(ref o));
|
||||
compCounts.Classes[compIndex][c] += (uint)incr;
|
||||
|
||||
d = o >> 3; /* int mv data */
|
||||
f = (o >> 1) & 3; /* fractional pel mv data */
|
||||
e = o & 1; /* high precision mv data */
|
||||
|
||||
if (c == (int)MvClassType.Class0)
|
||||
{
|
||||
compCounts.Class0[compIndex][d] += (uint)incr;
|
||||
compCounts.Class0Fp[compIndex][d][f] += (uint)incr;
|
||||
compCounts.Class0Hp[compIndex][e] += (uint)(usehp * incr);
|
||||
}
|
||||
else
|
||||
{
|
||||
int b = c + Class0Bits - 1; // number of bits
|
||||
for (int i = 0; i < b; ++i)
|
||||
{
|
||||
compCounts.Bits[compIndex][i][(d >> i) & 1] += (uint)incr;
|
||||
}
|
||||
|
||||
compCounts.Fp[compIndex][f] += (uint)incr;
|
||||
compCounts.Hp[compIndex][e] += (uint)(usehp * incr);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Inc(ref Mv mv, Ptr<Vp9BackwardUpdates> counts)
|
||||
{
|
||||
if (!counts.IsNull)
|
||||
{
|
||||
MvJointType j = mv.GetJoint();
|
||||
++counts.Value.Joints[(int)j];
|
||||
|
||||
if (JointVertical(j))
|
||||
{
|
||||
IncComponent(mv.Row, ref counts.Value, 0, 1, 1);
|
||||
}
|
||||
|
||||
if (JointHorizontal(j))
|
||||
{
|
||||
IncComponent(mv.Col, ref counts.Value, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Symbols for coding magnitude class of nonzero components */
|
||||
public const int Classes = 11;
|
||||
|
||||
public const int Class0Bits = 1; /* bits at integer precision for class 0 */
|
||||
public const int Class0Size = 1 << Class0Bits;
|
||||
public const int OffsetBits = Classes + Class0Bits - 2;
|
||||
public const int FpSize = 4;
|
||||
|
||||
public const int MaxBits = Classes + Class0Bits + 2;
|
||||
public const int Max = (1 << MaxBits) - 1;
|
||||
public const int Vals = (Max << 1) + 1;
|
||||
|
||||
public const int InUseBits = 14;
|
||||
public const int Upp = (1 << InUseBits) - 1;
|
||||
public const int Low = -(1 << InUseBits);
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal struct InternalFrameBuffer
|
||||
{
|
||||
public ArrayPtr<byte> Data;
|
||||
public bool InUse;
|
||||
}
|
||||
|
||||
internal struct InternalFrameBufferList
|
||||
{
|
||||
public ArrayPtr<InternalFrameBuffer> IntFb;
|
||||
}
|
||||
|
||||
internal static class FrameBuffers
|
||||
{
|
||||
public static int GetFrameBuffer(MemoryAllocator allocator, Ptr<InternalFrameBufferList> cbPriv, ulong minSize,
|
||||
ref VpxCodecFrameBuffer fb)
|
||||
{
|
||||
int i;
|
||||
Ptr<InternalFrameBufferList> intFbList = cbPriv;
|
||||
if (intFbList.IsNull)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Find a free frame buffer.
|
||||
for (i = 0; i < intFbList.Value.IntFb.Length; ++i)
|
||||
{
|
||||
if (!intFbList.Value.IntFb[i].InUse)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == intFbList.Value.IntFb.Length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ulong)intFbList.Value.IntFb[i].Data.Length < minSize)
|
||||
{
|
||||
if (!intFbList.Value.IntFb[i].Data.IsNull)
|
||||
{
|
||||
allocator.Free(intFbList.Value.IntFb[i].Data);
|
||||
}
|
||||
|
||||
// The data must be zeroed to fix a valgrind error from the C loop filter
|
||||
// due to access uninitialized memory in frame border. It could be
|
||||
// skipped if border were totally removed.
|
||||
intFbList.Value.IntFb[i].Data = allocator.Allocate<byte>((int)minSize);
|
||||
if (intFbList.Value.IntFb[i].Data.IsNull)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fb.Data = intFbList.Value.IntFb[i].Data;
|
||||
intFbList.Value.IntFb[i].InUse = true;
|
||||
|
||||
// Set the frame buffer's private data to point at the internal frame buffer.
|
||||
fb.Priv = new Ptr<InternalFrameBuffer>(ref intFbList.Value.IntFb[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int ReleaseFrameBuffer(Ptr<InternalFrameBufferList> cbPriv, ref VpxCodecFrameBuffer fb)
|
||||
{
|
||||
if (!fb.Priv.IsNull)
|
||||
{
|
||||
fb.Priv.Value.InUse = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System;
|
||||
using static Ryujinx.Graphics.Nvdec.Vp9.Dsp.InvTxfm;
|
||||
@@ -8,13 +8,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
internal static class Idct
|
||||
{
|
||||
private delegate void Transform1D(ReadOnlySpan<int> input, Span<int> output);
|
||||
|
||||
private delegate void HighbdTransform1D(ReadOnlySpan<int> input, Span<int> output, int bd);
|
||||
|
||||
private struct Transform2D
|
||||
{
|
||||
public readonly Transform1D Cols; // Vertical and horizontal
|
||||
public readonly Transform1D Rows; // Vertical and horizontal
|
||||
public Transform1D Cols, Rows; // Vertical and horizontal
|
||||
|
||||
public Transform2D(Transform1D cols, Transform1D rows)
|
||||
{
|
||||
@@ -25,8 +23,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private struct HighbdTransform2D
|
||||
{
|
||||
public readonly HighbdTransform1D Cols; // Vertical and horizontal
|
||||
public readonly HighbdTransform1D Rows; // Vertical and horizontal
|
||||
public HighbdTransform1D Cols, Rows; // Vertical and horizontal
|
||||
|
||||
public HighbdTransform2D(HighbdTransform1D cols, HighbdTransform1D rows)
|
||||
{
|
||||
@@ -35,124 +32,121 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] Iht4 =
|
||||
{
|
||||
private static readonly Transform2D[] _iht4 = {
|
||||
new(Idct4, Idct4), // DCT_DCT = 0
|
||||
new(Iadst4, Idct4), // ADST_DCT = 1
|
||||
new(Idct4, Iadst4), // DCT_ADST = 2
|
||||
new(Iadst4, Iadst4) // ADST_ADST = 3
|
||||
new(Iadst4, Iadst4), // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void Iht4x416Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[4 * 4];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[4];
|
||||
Span<int> tempOut = stackalloc int[4];
|
||||
|
||||
// Inverse transform row vectors
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
Iht4[txType].Rows(input, outptr);
|
||||
input = input.Slice(4);
|
||||
outptr = outptr.Slice(4);
|
||||
_iht4[txType].Rows(input, outptr);
|
||||
input = input[4..];
|
||||
outptr = outptr[4..];
|
||||
}
|
||||
|
||||
// Inverse transform column vectors
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
for (int j = 0; j < 4; ++j)
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
tempIn[j] = output[(j * 4) + i];
|
||||
tempIn[j] = output[j * 4 + i];
|
||||
}
|
||||
|
||||
Iht4[txType].Cols(tempIn, tempOut);
|
||||
for (int j = 0; j < 4; ++j)
|
||||
_iht4[txType].Cols(tempIn, tempOut);
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
dest[(j * stride) + i] =
|
||||
ClipPixelAdd(dest[(j * stride) + i], BitUtils.RoundPowerOfTwo(tempOut[j], 4));
|
||||
dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] Iht8 =
|
||||
{
|
||||
private static readonly Transform2D[] _iht8 = {
|
||||
new(Idct8, Idct8), // DCT_DCT = 0
|
||||
new(Iadst8, Idct8), // ADST_DCT = 1
|
||||
new(Idct8, Iadst8), // DCT_ADST = 2
|
||||
new(Iadst8, Iadst8) // ADST_ADST = 3
|
||||
new(Iadst8, Iadst8), // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void Iht8x864Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[8 * 8];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[8];
|
||||
Span<int> tempOut = stackalloc int[8];
|
||||
Transform2D ht = Iht8[txType];
|
||||
Transform2D ht = _iht8[txType];
|
||||
|
||||
// Inverse transform row vectors
|
||||
for (int i = 0; i < 8; ++i)
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr);
|
||||
input = input.Slice(8);
|
||||
outptr = outptr.Slice(8);
|
||||
input = input[8..];
|
||||
outptr = outptr[8..];
|
||||
}
|
||||
|
||||
// Inverse transform column vectors
|
||||
for (int i = 0; i < 8; ++i)
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
for (int j = 0; j < 8; ++j)
|
||||
for (j = 0; j < 8; ++j)
|
||||
{
|
||||
tempIn[j] = output[(j * 8) + i];
|
||||
tempIn[j] = output[j * 8 + i];
|
||||
}
|
||||
|
||||
ht.Cols(tempIn, tempOut);
|
||||
for (int j = 0; j < 8; ++j)
|
||||
for (j = 0; j < 8; ++j)
|
||||
{
|
||||
dest[(j * stride) + i] =
|
||||
ClipPixelAdd(dest[(j * stride) + i], BitUtils.RoundPowerOfTwo(tempOut[j], 5));
|
||||
dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] Iht16 =
|
||||
{
|
||||
private static readonly Transform2D[] _iht16 = {
|
||||
new(Idct16, Idct16), // DCT_DCT = 0
|
||||
new(Iadst16, Idct16), // ADST_DCT = 1
|
||||
new(Idct16, Iadst16), // DCT_ADST = 2
|
||||
new(Iadst16, Iadst16) // ADST_ADST = 3
|
||||
new(Iadst16, Iadst16), // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void Iht16x16256Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
Transform2D ht = Iht16[txType];
|
||||
Transform2D ht = _iht16[txType];
|
||||
|
||||
// Rows
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr);
|
||||
input = input.Slice(16);
|
||||
outptr = outptr.Slice(16);
|
||||
input = input[16..];
|
||||
outptr = outptr[16..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
for (int j = 0; j < 16; ++j)
|
||||
for (j = 0; j < 16; ++j)
|
||||
{
|
||||
tempIn[j] = output[(j * 16) + i];
|
||||
tempIn[j] = output[j * 16 + i];
|
||||
}
|
||||
|
||||
ht.Cols(tempIn, tempOut);
|
||||
for (int j = 0; j < 16; ++j)
|
||||
for (j = 0; j < 16; ++j)
|
||||
{
|
||||
dest[(j * stride) + i] =
|
||||
ClipPixelAdd(dest[(j * stride) + i], BitUtils.RoundPowerOfTwo(tempOut[j], 6));
|
||||
dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 6));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -286,125 +280,121 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] HighbdIht4 =
|
||||
{
|
||||
private static readonly HighbdTransform2D[] _highbdIht4 = {
|
||||
new(HighbdIdct4, HighbdIdct4), // DCT_DCT = 0
|
||||
new(HighbdIadst4, HighbdIdct4), // ADST_DCT = 1
|
||||
new(HighbdIdct4, HighbdIadst4), // DCT_ADST = 2
|
||||
new(HighbdIadst4, HighbdIadst4) // ADST_ADST = 3
|
||||
new(HighbdIadst4, HighbdIadst4), // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void HighbdIht4x416Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[4 * 4];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[4];
|
||||
Span<int> tempOut = stackalloc int[4];
|
||||
|
||||
// Inverse transform row vectors.
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
HighbdIht4[txType].Rows(input, outptr, bd);
|
||||
input = input.Slice(4);
|
||||
outptr = outptr.Slice(4);
|
||||
_highbdIht4[txType].Rows(input, outptr, bd);
|
||||
input = input[4..];
|
||||
outptr = outptr[4..];
|
||||
}
|
||||
|
||||
// Inverse transform column vectors.
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
for (int j = 0; j < 4; ++j)
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
tempIn[j] = output[(j * 4) + i];
|
||||
tempIn[j] = output[j * 4 + i];
|
||||
}
|
||||
|
||||
HighbdIht4[txType].Cols(tempIn, tempOut, bd);
|
||||
for (int j = 0; j < 4; ++j)
|
||||
_highbdIht4[txType].Cols(tempIn, tempOut, bd);
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
dest[(j * stride) + i] = HighbdClipPixelAdd(dest[(j * stride) + i],
|
||||
BitUtils.RoundPowerOfTwo(tempOut[j], 4), bd);
|
||||
dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 4), bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] HighIht8 =
|
||||
{
|
||||
private static readonly HighbdTransform2D[] _highIht8 = {
|
||||
new(HighbdIdct8, HighbdIdct8), // DCT_DCT = 0
|
||||
new(HighbdIadst8, HighbdIdct8), // ADST_DCT = 1
|
||||
new(HighbdIdct8, HighbdIadst8), // DCT_ADST = 2
|
||||
new(HighbdIadst8, HighbdIadst8) // ADST_ADST = 3
|
||||
new(HighbdIadst8, HighbdIadst8), // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void HighbdIht8x864Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[8 * 8];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[8];
|
||||
Span<int> tempOut = stackalloc int[8];
|
||||
HighbdTransform2D ht = HighIht8[txType];
|
||||
HighbdTransform2D ht = _highIht8[txType];
|
||||
|
||||
// Inverse transform row vectors.
|
||||
for (int i = 0; i < 8; ++i)
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr, bd);
|
||||
input = input.Slice(8);
|
||||
outptr = output.Slice(8);
|
||||
input = input[8..];
|
||||
outptr = output[8..];
|
||||
}
|
||||
|
||||
// Inverse transform column vectors.
|
||||
for (int i = 0; i < 8; ++i)
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
for (int j = 0; j < 8; ++j)
|
||||
for (j = 0; j < 8; ++j)
|
||||
{
|
||||
tempIn[j] = output[(j * 8) + i];
|
||||
tempIn[j] = output[j * 8 + i];
|
||||
}
|
||||
|
||||
ht.Cols(tempIn, tempOut, bd);
|
||||
for (int j = 0; j < 8; ++j)
|
||||
for (j = 0; j < 8; ++j)
|
||||
{
|
||||
dest[(j * stride) + i] = HighbdClipPixelAdd(dest[(j * stride) + i],
|
||||
BitUtils.RoundPowerOfTwo(tempOut[j], 5), bd);
|
||||
dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 5), bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] HighIht16 =
|
||||
{
|
||||
private static readonly HighbdTransform2D[] _highIht16 = {
|
||||
new(HighbdIdct16, HighbdIdct16), // DCT_DCT = 0
|
||||
new(HighbdIadst16, HighbdIdct16), // ADST_DCT = 1
|
||||
new(HighbdIdct16, HighbdIadst16), // DCT_ADST = 2
|
||||
new(HighbdIadst16, HighbdIadst16) // ADST_ADST = 3
|
||||
new(HighbdIadst16, HighbdIadst16), // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void HighbdIht16x16256Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType,
|
||||
int bd)
|
||||
public static void HighbdIht16x16256Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
HighbdTransform2D ht = HighIht16[txType];
|
||||
HighbdTransform2D ht = _highIht16[txType];
|
||||
|
||||
// Rows
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr, bd);
|
||||
input = input.Slice(16);
|
||||
outptr = output.Slice(16);
|
||||
input = input[16..];
|
||||
outptr = output[16..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
for (int j = 0; j < 16; ++j)
|
||||
for (j = 0; j < 16; ++j)
|
||||
{
|
||||
tempIn[j] = output[(j * 16) + i];
|
||||
tempIn[j] = output[j * 16 + i];
|
||||
}
|
||||
|
||||
ht.Cols(tempIn, tempOut, bd);
|
||||
for (int j = 0; j < 16; ++j)
|
||||
for (j = 0; j < 16; ++j)
|
||||
{
|
||||
dest[(j * stride) + i] = HighbdClipPixelAdd(dest[(j * stride) + i],
|
||||
BitUtils.RoundPowerOfTwo(tempOut[j], 6), bd);
|
||||
dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 6), bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -444,7 +434,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// DC only DCT coefficient
|
||||
if (eob == 1)
|
||||
{
|
||||
VpxHighbdidct8x81AddC(input, dest, stride, bd);
|
||||
Vpx_Highbdidct8x8_1_add_c(input, dest, stride, bd);
|
||||
}
|
||||
else if (eob <= 12)
|
||||
{
|
||||
@@ -501,8 +491,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
// Iht
|
||||
public static void HighbdIht4x4Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
int eob, int bd)
|
||||
public static void HighbdIht4x4Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
@@ -514,8 +503,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIht8x8Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
int eob, int bd)
|
||||
public static void HighbdIht8x8Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
@@ -527,8 +515,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
int eob, int bd)
|
||||
public static void HighbdIht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal class InternalErrorException : Exception
|
||||
class InternalErrorException : Exception
|
||||
{
|
||||
public InternalErrorException(string message) : base(message)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user