Compare commits

...

230 Commits

Author SHA1 Message Date
7805d27e67 MacOS: Fix rendering on AMD GPUs (#5446)
* MacOS: Fix rendering on AMD GPUs

* Only disable MultiViewPort on MoltenVK for AMD GPUs
2023-07-11 03:00:19 +02:00
6c515e1822 [Ryujinx.Ava] Address dotnet-format issues (#5361)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address dotnet format CA1822 warnings

* Address or silence dotnet format CA1069 warnings

* Make dotnet format succeed in style mode

* Address dotnet format CA1401 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* dotnet-format fixes after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address IDE0260 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* dotnet format pass with new editorconfig

* Fix naming style issues

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Revert one suggestion

* Second dotnet format pass and fix build issues

* Final pass of dotnet format

* Add trailing commas

* Fix formatting issues

* Keep unnecessary assignment in IconColorPicker.cs

* Use using declarations and extend resource lifetimes

* Fix rebase issues

* Adjust comment spacing

* Fix typo

* Fix naming issues

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Revert unintentional change

* Remove unused file

* Remove static keyword from ViewModels

Binding of static members doesn't work and is silently ignored.

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-07-07 23:03:27 +02:00
8a363b5df2 Revert "sdl: set SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS to 0 (#5433)" (#5439)
This reverts commit 2b5abac809.
2023-07-06 18:08:14 +02:00
2b5abac809 sdl: set SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS to 0 (#5433)
Nintendo controllers notoriously have the A/B and X/Y buttons swapped, compared to the standard.
In order to combat this, when setting the default controller layout, Ryujinx checks whether the controller name contains "Nintendo", and swaps the mapping accordingly.
However, the reason the mapping is inverted in the first place is because SDL has `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS` set to 1 by default. By setting it to 0, the mapping will be based on the buttons' position instead.
So, by doing it (and removing the `isNintendoStyle` variable), we get the following advantages:
- The mapping will be the same on all controllers, removing the need to adjust custom mappings depending on what controller is used
- Users who already set `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS` to 0 globally for other games/applications (like me) won't have a wrong default mapping
- Checking whether the controller name contains "Nintendo" is ugly

Disadvantages:
- Breaks the controller configuration for existing users who are using a Nintendo controller
2023-07-06 17:11:26 +02:00
c19c8bbade Headless: Add support for fullscreen option (#5339)
* Headless: Added support for fullscreen option

* Headless: cleanup of fullscreen support

* Headless: fullscreen support : implemented proposed changes

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: fix for OpenGL scaling

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: add. macOS fullscreen fix

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: cleanup
2023-07-06 12:10:15 +02:00
1c7a90ef35 Stop identifying shader textures with handle and cbuf, use binding instead (#5266)
* Stop identifying shader textures with handle and cbuf, use binding instead

* Remove now unused code

* Consider image operations as having accurate type information too

I don't know why that was not the case before

* Fix missing unscale on InsertCoordNormalization, stop calling SetUsageFlagsForTextureQuery when not needed

* Shader cache version bump

* Change get texture methods to return descriptors created from ResourceManager state

 This is required to ensure that reserved textures and images will not be bound as a guest texture/image

* Fix BindlessElimination.SetHandle inserting coords at the wrong place
2023-07-03 14:29:27 -03:00
3b46bb73f7 [Ryujinx.Graphics.Gpu] Address dotnet-format issues (#5367)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1069 warnings

* Address or silence dotnet format CA2211 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Another rebase, another dotnet format run

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Remove a few unused parameters

* Replace MmeShadowScratch with Array256<uint>

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Run dotnet format after rebase

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First pass of dotnet format

* Add unsafe dotnet format changes

* Fix typos

* Add trailing commas

* Disable formatting for FormatTable

* Address review feedback
2023-07-02 02:47:54 +02:00
2457cfc911 Fix naming issue in ControllerWindow (#5424) 2023-07-02 02:26:32 +02:00
515fc32b21 [Ryujinx.Audio] Address dotnet-format issues (#5362)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2208 warnings

* Address or silence dotnet format CA2211 warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format whitespace after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Fix naming rule violations, remove redundant code and fix build issues

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Address review feedback

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-07-02 01:27:18 +02:00
0684b00b3c [Ryujinx] Address dotnet-format issues (#5395)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2208 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address dotnet format CA1822 warnings

* Make dotnet format succeed in style mode

* Address dotnet format CA2208 warnings properly

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix build issues

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Second dotnet format pass

* Update src/Ryujinx/Modules/Updater/Updater.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas and improve formatting

* Fix formatting and naming issues

* Rename nvStutterWorkaround to nvidiaStutterWorkaround

* Use using declarations and extend resource lifetimes

* Fix GTK issues

* Add formatting for generated files

* Add trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-07-02 00:25:07 +02:00
02b5c7ea89 [Ryujinx.Horizon] Address dotnet-format issues (#5381)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1822 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Revert formatting changes for while and for-loops

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Add trailing commas and fix formatting issues

* Convert if-else chain to switch block

* Address review feedback
2023-07-01 12:42:10 +02:00
801b71a128 [Ryujinx.Graphics.Vulkan] Address dotnet-format issues (#5378)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0059 warnings

* Address dotnet format CA1816 warnings

* Fix new dotnet-format issues after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Run dotnet format after rebase

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix naming rule violations

* Remove redundant code

* Rename generics

* Address review feedback

* Remove SetOrigin
2023-07-01 12:31:42 +02:00
12c5f6ee89 Indexing at 0 should be used instead of the "Enumerable" extension method "First" (#5354) 2023-07-01 06:29:37 +00:00
79a1314ee4 [Ryujinx.Cpu] Address dotnet-format issues (#5365)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address most dotnet format whitespace warnings

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Adjust namespaces

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Address review feedback

* Remove redundant unsafe modifiers

* Fix build issues

* Add GC.SuppressFinalize() call

* Add trailing commas and fix naming rule violations

* Remove unused members and assignments
2023-07-01 02:18:52 +00:00
e9848339dd [Ryujinx.Tests] Address dotnet-format issues (#5389)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Fix new dotnet-format issues after rebase

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* cpu tests: Disable CA2211 for CodeBaseAddress and DataBaseAddress

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* First dotnet format pass

* Fix naming rule violations

* Remove naming rule violation exceptions

* Fix comment style

* Use targeted new

* Remove redundant code

* Remove comment alignment

* Remove naming rule exceptions

* Add trailing commas

* Use nameof expression

* Reformat to add remaining trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-07-01 02:14:34 +00:00
6e28a4dd13 [Ryujinx.Ui.Common] Address dotnet-format issues (#5392)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Silence dotnet format IDE0060 warnings

* Address dotnet format CA1401 warnings

* dotnet-format fixes after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Another rebase, another dotnet format run

* Run dotnet format style after rebase

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Small optimizations

* Remove alignment

* Apply formatting

* Fix build issues

* Final pass for dotnet format

* Add trailing commas

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-29 02:39:22 +02:00
7c989f88bd [Ryujinx.Graphics.GAL] Address dotnet-format issues (#5366)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1069 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Revert formatting changes for while and for-loops

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Address review feedback

* Add trailing commas

* Remove SuppressMessage for IDE0066

* Make explicit Equals implementation implicit
2023-06-28 20:20:10 +02:00
16fa983704 macOS: Fix warning in some shell scripts (#5398)
* macOS: Fix warning in some shell scripts

In a way to continue the cleaning of the project, there are some warnings which can be easily fixed.

* Try to fix CI

* Fix APP_ARGUMENTS

* Addresses feedback
2023-06-28 19:09:48 +02:00
40daca5684 [Ryujinx.Headless.SDL2] Address dotnet-format issues (#5379)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Add trailing commas

* Fix naming and formatting issues
2023-06-28 19:03:27 +02:00
981e0c082d [Spv.Generator] Address dotnet-format issues (#5394)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0052 warnings

* Address or silence dotnet format IDE1006 warnings

* Address or silence dotnet format CA1069 warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Rename Operand.cs to IOperand.cs

* Update src/Spv.Generator/Module.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Remove NotNullWhen attribute and use conditional access to avoid NRE

* Fix duplicated enum values

* Remove unread member

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-28 18:54:20 +02:00
cebfa54467 [Ryujinx.Graphics.Texture] Address dotnet-format issues (#5375)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format CA2208 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Address review feedback

* Update src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-28 18:46:18 +02:00
fc20d9b925 [Ryujinx.Common] Address dotnet-format issues (#5358)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2211 warnings

* Silence CA1806 and CA1834 issues

* Fix formatting for switch expressions

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Revert formatting changes for while and for-loops

* Format if-blocks correctly

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Replace MmeShadowScratch with Array256<uint>

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Run dotnet format after rebase

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Second dotnet format pass

* Fix build issues

* Fix StructArrayHelpers.cs

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Fix return statements

* Fix naming rule violations

* Update src/Ryujinx.Common/Utilities/StreamUtils.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas

* Address review feedback

* Address review feedback

* Rename remaining type parameters to TKey and TValue

* Fix manual formatting for logging levels

* Fix spacing before comments

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-28 18:41:38 +02:00
0a75b73fa4 [Ryujinx.Memory] Address dotnet-format issues (#5386)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1069 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Address review feedback

* Assign Decommit to ReplacePlaceholder

* Run final dotnet format pass

* Organize imports again

* Add trailing commas

* Add missing newline
2023-06-28 18:34:00 +02:00
46b7c905f5 [Ryujinx.Input] Address dotnet-format issues (#5384)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Remove redundant code, convert to auto-properties and fix naming rule violations

* Remove bogus change

* Address review feedback
2023-06-28 18:23:00 +02:00
40f2bd37e3 [Ryujinx.Graphics.OpenGL] Address dotnet-format issues (#5372)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Address or silence dotnet format IDE1006 warnings

* Fix IDE0090 after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Address review feedback
2023-06-28 18:10:55 +02:00
9288ffd26d Cpu: Implement VCVT (between floating-point and fixed-point) instruction (#5343)
* cpu: Implement VCVT (between floating-point and fixed-point) instruction

Rebase, fix and superseed of https://github.com/Ryujinx/Ryujinx/pull/2915

(Since I only have little CPU knowledge, I hope I have done everything good)

* Update Ptc.cs

* Fix wrong cast

* Rename tests

* Addresses feedback

Co-Authored-By: gdkchan <5624669+gdkchan@users.noreply.github.com>

* Remove extra empty line

---------

Co-authored-by: gdkchan <5624669+gdkchan@users.noreply.github.com>
2023-06-28 17:36:30 +02:00
2cdc82cb91 nuget: bump Microsoft.NET.Test.Sdk from 17.6.2 to 17.6.3 (#5406)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.2 to 17.6.3.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.6.2...v17.6.3)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-28 09:36:22 +02:00
6aa8d71588 [Ryujinx.Graphics.Nvdec.Vp9] Address dotnet-format issues (#5371)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Address or silence dotnet format IDE1006 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Fix empty lines before return

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas, remove redundant code and remove static modifier from Surface.HighBd

* Fix naming rule violations

* Fix naming rule violations

* Fix empty line before return

* Fix comment style

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Remove comment alignment

* Address review feedback

* Separate comments by 2 spaces and fix other formatting issues

* Make HighBd an auto-property

* Replace if-chain with if-else-chain

* Fix new naming rule violations

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-28 09:26:39 +02:00
9becbd7d72 [Ryujinx.Graphics.Shader] Address dotnet-format issues (#5373)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format CA1069 warnings

* Address or silence dotnet format CA2211 warnings

* Address review comments

* Fix formatting for switch expressions

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Fix naming rule violation, Convert shader properties to auto-property and convert values to const

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Run dotnet format after rebase

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Run dotnet format after rebase

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix naming rule violations

* Add trailing commas

* Remove unused members and most unnecessary value assignments

* Remove more unnecessary assignments

* Remove NRE suppressor
2023-06-28 08:59:13 +02:00
e055217292 [Ryujinx.Horizon.Kernel.Generators] Address dotnet-format issues (#5376)
* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Run dotnet format pass

* Remove left-over files and adjust namespaces

* Fix alignment
2023-06-27 23:27:48 +00:00
fbaf62c230 Apply new naming rule to all projects except Vp9 (#5407) 2023-06-28 01:18:19 +02:00
b186ec9fc5 [Ryujinx.Graphics.Video] Address dotnet-format issues (#5377)
* Address most dotnet format whitespace warnings

* dotnet format whitespace after rebase
2023-06-27 16:45:33 +02:00
0191e2396a [Ryujinx.Graphics.Host1x] Address dotnet-format issues (#5368)
* dotnet format style --severity info

Some changes were manually reverted.

* Address most dotnet format whitespace warnings

* Add comments to disabled warnings

* dotnet format whitespace after rebase
2023-06-27 16:35:48 +02:00
e96299eef5 [Ryujinx.Horizon.Generators] Address dotnet-format issues (#5383)
* dotnet format style --severity info

Some changes were manually reverted.

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* dotnet format whitespace after rebase
2023-06-26 07:35:19 +02:00
ff53dcf560 [ARMeilleure] Address dotnet-format issues (#5357)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address or silence dotnet format IDE1006 warnings

* Address or silence dotnet format CA2208 warnings

* Address dotnet format CA1822 warnings

* Address or silence dotnet format CA1069 warnings

* Silence CA1806 and CA1834 issues

* Address dotnet format CA1401 warnings

* Fix new dotnet-format issues after rebase

* Address review comments

* Address dotnet format CA2208 warnings properly

* Fix formatting for switch expressions

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add previously silenced warnings back

I have no clue how these disappeared

* Revert formatting changes for OpCodeTable.cs

* Enable formatting for a few cases again

* Format if-blocks correctly

* Enable formatting for a few more cases again

* Fix inline comment alignment

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Remove a few unused parameters

* Adjust namespaces

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Remove unnecessary formatting exclusion

* Add unsafe dotnet format changes

* Change visibility of JitSupportDarwin to internal
2023-06-26 07:25:06 +02:00
2de78a2d55 [Ryujinx.Input.SDL2] Address dotnet-format issues (#5385)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Add trailing commas, log errors instead of throwing and remove redundant code
2023-06-26 01:55:25 +00:00
b29ded1d60 [Ryujinx.SDL2.Common] Address dotnet-format issues (#5387)
* dotnet format style --severity info

Some changes were manually reverted.

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* dotnet format whitespace after rebase
2023-06-26 01:51:16 +00:00
9860bfb2cd misc: memory: Migrate from OutOfMemoryException to SystemException entirely (#5399)
Fix a regression with address space allocation while providing more
information about the context of the exception.
2023-06-26 01:37:12 +00:00
f6ada8d169 [Ryujinx.Graphics.Device] Address dotnet-format issues (#5363)
* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Address most dotnet format whitespace warnings

* dotnet format whitespace after rebase
2023-06-25 23:58:44 +02:00
42d31f646d [Ryujinx.Audio.Backends.SDL2] Address dotnet-format issues (#5364)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Address dotnet format CA1816 warnings

* Address most dotnet format whitespace warnings

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Update src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceDriver.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-25 22:50:59 +02:00
07fc3ded68 [Ryujinx.Graphics.Nvdec] Address dotnet-format issues (#5369)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add previously silenced warnings back

I have no clue how these disappeared

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass
2023-06-25 21:44:42 +02:00
fd01259d2b [Ryujinx.ShaderTools] Address dotnet-format issues (#5388)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format whitespace after rebase
2023-06-25 21:37:33 +02:00
7ffe7f8442 [Ryujinx.Graphics.Nvdec.FFmpeg] Address dotnet-format issues (#5370)
* dotnet format style --severity info

Some changes were manually reverted.

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass
2023-06-25 19:03:48 +02:00
2b2ce68f07 [Ryujinx.Tests.Memory] Address dotnet-format issues (#5390)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Address dotnet format CA1822 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Final dotnet format pass and fix naming rule violations

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Remove unused constant

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-25 18:37:53 +02:00
bc53d00463 [Ryujinx.Graphics.Vic] Address dotnet-format issues (#5374)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Address review comments

* Address most dotnet format whitespace warnings

* Add comments to disabled warnings

* Address IDE0251 warnings

* dotnet format whitespace after rebase

* Remove SuppressMessage attribute for removed rule
2023-06-25 18:37:09 +02:00
bddb2a1483 [Ryujinx.Tests.Unicorn] Address dotnet-format issues (#5391)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Final dotnet format pass and fix naming rule violations
2023-06-25 18:03:08 +02:00
e3bacfa774 Set COMPlus_DefaultStackSize to 2M in macOS (#5349)
* Set COMPlus_DefaultStackSize to 2M in macOS

* Remove the custom thread stack size on Ryujinx.Ava
2023-06-25 14:49:53 +02:00
7c2f07d124 [Ryujinx.Horizon.Common] Address dotnet-format issues (#5382)
* dotnet format style --severity info

Some changes were manually reverted.

* Address most dotnet format whitespace warnings

* Address IDE0251 warnings

* dotnet format whitespace after rebase
2023-06-25 13:40:37 +02:00
ede5b3c324 [Ryujinx.Audio.Backends.SoundIo] Address dotnet-format issues (#5360)
* dotnet format style --severity info

Some changes were manually reverted.

* Address dotnet format CA1816 warnings

* Address dotnet format CA1401 warnings

* Address most dotnet format whitespace warnings

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Address review feedback
2023-06-25 02:15:56 +02:00
df5be5812f [Ryujinx.Audio.Backends.OpenAL] Address dotnet-format issues (#5359)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Address dotnet format CA1816 warnings

* Address most dotnet format whitespace warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase
2023-06-25 01:29:40 +02:00
bc392e55df Empty "case" clauses that fall through to the "default" should be omitted (#5353)
* Empty "case" clauses that fall through to the "default" should be omitted

* default throw exception

* format
2023-06-24 12:06:58 +00:00
fffc3ed193 Mutable fields should not be "public static" (#5352) 2023-06-24 12:01:59 +00:00
7d160e98fd MemoryManagement: Change return types for Commit/Decommit to void (#5325)
* Replace return type with void for Commit/Decommit

* Small cleanup
2023-06-24 02:46:04 +02:00
bf96bc84a8 "Where" should be used before "OrderBy" (#5346) 2023-06-23 00:51:44 +00:00
91e4caaa69 "StartsWith" and "EndsWith" overloads that take a "char" should be used instead of the ones that take a "string" (#5347) 2023-06-23 02:15:14 +02:00
efbd29463d "Find" method should be used instead of the "FirstOrDefault" extension (#5344) 2023-06-23 01:42:23 +02:00
7608cb37ab "Exists" method should be used instead of the "Any" extension (#5345) 2023-06-23 01:37:25 +02:00
d604e98227 Fix regression introduced by 1.1.1733 on Intel GPUs (#5311)
* Fix regression introduced by 1.1733 on Intel iGPUs

* Should have actually figured the variable, oops.

* maybe something goes wrong here? honestly lost

* Shader cache bump
2023-06-22 21:35:06 +02:00
58907e2c29 GetHashCode should not reference mutable fields (#5331) 2023-06-22 18:36:07 +02:00
649d372f7d misc: Implement address space size workarounds (#5191)
* misc: Implement address space size workarounds

This adds code to support userland with less than 39 bits of address
space available by testing reserving multiple sizes and reducing
guess address space when needed.

This is required for ARM64 support when the kernel is
configured to use 63..39 bits for kernel space.(meaning only 38 bits is available to userland)

* Address comments

* Fix 32 bits address space support and address more comments
2023-06-20 17:33:54 +02:00
f9a538bb0f Ensure shader local and shared memory sizes are not zero (#5321) 2023-06-17 16:28:27 -03:00
f92921a6d1 Implement Load/Store Local/Shared and Atomic shared using new instructions (#5241)
* Implement Load/Store Local/Shared and Atomic shared using new instructions

* Remove now unused code

* Fix base offset register overwrite

* Fix missing storage buffer set index when generating GLSL for Vulkan

* Shader cache version bump

* Remove more unused code

* Some PR feedback
2023-06-15 17:31:53 -03:00
32d21ddf17 Inheritance list should not be redundant (#5230) 2023-06-15 03:54:27 +00:00
82f90704a0 Blocks should be synchronized on read-only fields (#5212)
* Blocks should be synchronized on read-only fields

* more readonlys

* fix alignment

* more

* Update ISelfController.cs

* simplify new

* simplify new
2023-06-15 00:34:55 +00:00
f978d3726a nuget: bump System.Management from 7.0.1 to 7.0.2 (#5302)
Bumps [System.Management](https://github.com/dotnet/runtime) from 7.0.1 to 7.0.2.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v7.0.1...v7.0.2)

---
updated-dependencies:
- dependency-name: System.Management
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-14 18:21:17 +02:00
6f28c4abad test: Make tests runnable on system without 4KiB page size (#5184)
* ARMeilleure: Do not hardcode 4KiB page size in JitCache

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Memory.Tests

Fix running tests on Asahi Linux with 16KiB pages.

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Cpu

Fix running tests on Asahi Linux.

Test runner still crash when trying to run all test suite.

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Cpu

Fix somecrashes on Asahi Linux.

* test: Ignore Vshl test on ARM64 due to unicorn crashes

* test: Workaround hardcoded size on some tests

Change mapping of code and data in case of non 4KiB configuration.

* test: Make CpuTestT32Flow depends on code address

Fix failure with different page size.

* test: Disable CpuTestThumb.TestRandomTestCases when page size isn't 4KiB

The test data needs to be reevaluated to take different page size into account.

* Address gdkchan's comments
2023-06-14 18:02:41 +02:00
105c9712c1 Fix Arm32 double to int/uint conversion on Arm64 (#5292)
* Fix Arm32 double to int/uint conversion on Arm64

* PPTC version bump
2023-06-14 00:57:02 -03:00
4d804ed45e Mod Loader: Stop loading mods from folders that don't exactly match titleId (#5298)
* Stop loading mods from folders that don't exactly match titleId

* What the worst that can happen?
2023-06-13 20:47:33 +02:00
4a27d29412 infra: Sync paths-ignore with release job and attempt to fix review assign 2023-06-13 11:51:22 +02:00
5bd2c58ad6 UI: Correctly set 'shell/open/command; registry key for file associations (#5244)
* Correctly set 'shell/open/command; registry key for file associations

* File association fixes
* 'using' statements instead of blocks
* Idempotent unregistration
* Single "hey shell, we changed file associations" notification at the
  end instead of 1 for every operation, speeds things up greatly.

* Adapt and fix Linux specific function as well

---------

Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
2023-06-13 00:36:40 +00:00
cf4c78b9c8 Make LM skip instead of crashing for invalid messages (#5290) 2023-06-13 00:12:06 +00:00
52aa4b6c22 Fix action version (#5299) 2023-06-12 21:57:07 +02:00
5a02433080 infra: Fix PR triage workflow glob patterns (#5297)
* Use glob patterns to match file paths

* Update ignored paths for releases

* Adjust build.yml as well

* Add names to auto-assign steps

* Fix developer team name

* Allow build workflows to run if workflows changed
2023-06-12 18:42:27 +00:00
915a0f7173 hle: Stub IHidbusServer.GetBusHandle (#5284) 2023-06-12 17:33:13 +02:00
0cc266ff19 infra: Add PR triage action (#5293)
This is a bare minimal triage action that handle big categories.

In the future we could also label all services correctly but
I didn't felt this was required for a first iteration.
2023-06-12 12:29:41 +02:00
9a1b74799d Ava: Fix OpenGL on Linux again (#5216)
* ava: Fix OpenGL on Linux again

This shouldn't be working like that, but for some reason it does.

* Apply the correct fix

* gtk: Add warning messages for caught exceptions

* ava: Handle disposing the same way as GTK does

* Address review feedback
2023-06-11 18:31:22 +02:00
638f3761f3 Show/Hide UI Hotkey fix on Avalonia (#5133)
* fix show/hide ui for ava

* revert style

* unbound by default

* revert
2023-06-11 15:34:56 +02:00
193ca3c9a2 Implement fast path for AES crypto instructions on Arm64 (#5281)
* Implement fast path for AES crypto instructions on Arm64

* PPTC version bump

* Use AES HW feature check
2023-06-11 00:51:35 +00:00
eb0bb36bbf Implement transform feedback emulation for hardware without native support (#5080)
* Implement transform feedback emulation for hardware without native support

* Stop doing some useless buffer updates and account for non-zero base instance

* Reduce redundant updates even more

* Update descriptor init logic to account for ResourceLayout

* Fix transform feedback and storage buffers not being updated in some cases

* Shader cache version bump

* PR feedback

* SetInstancedDrawVertexCount must be always called after UpdateState

* Minor typo
2023-06-10 18:31:38 -03:00
0e95a8271a Non-flags enums should not be used in bitwise operations (#5214) 2023-06-09 19:44:22 +02:00
76b474e97b Update ShaderConfig.cs (#5226) 2023-06-09 14:53:20 +00:00
27ee86f33b Exclude macOS from checking for changed files (#5270) 2023-06-09 15:35:24 +02:00
f7ec310231 Check if existing oldConfigPath is a Symlink (#5271) 2023-06-09 15:31:19 +02:00
e94d24f508 Prefer a 'TryGetValue' call over a Dictionary indexer access guarded by a 'ContainsKey' (#5231)
* Prefer a 'TryGetValue' call over a Dictionary indexer access guarded by a 'ContainsKey' check to avoid double lookup

* fix
2023-06-09 13:05:32 +02:00
2bf4555591 Swkbd Applet Fixes (#5236)
* Swkbd Applet Fixes

* Forgot a full stop

* Update src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Update src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-09 12:11:53 +02:00
86de288142 Removing shift by 0 (#5249)
* Integral numbers should not be shifted by zero or more than their number of bits-1

* more
2023-06-09 11:23:44 +02:00
f35aa8e9d6 nuget: bump Microsoft.NET.Test.Sdk from 17.6.1 to 17.6.2 (#5250)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.1 to 17.6.2.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.6.1...v17.6.2)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-09 11:02:56 +02:00
0e8e735a6d nuget: bump System.IdentityModel.Tokens.Jwt from 6.30.1 to 6.31.0 (#5265)
Bumps [System.IdentityModel.Tokens.Jwt](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet) from 6.30.1 to 6.31.0.
- [Release notes](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/releases)
- [Changelog](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/compare/6.30.1...6.31.0)

---
updated-dependencies:
- dependency-name: System.IdentityModel.Tokens.Jwt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-09 10:40:25 +02:00
0003a7c118 Vulkan: Use aspect flags for identity views for bindings (#5267) 2023-06-08 20:23:36 -03:00
2cdcfe46d8 Remove barrier on Intel if control flow is potentially divergent (#5044)
* Remove barrier on Intel if control flow is potentially divergent

* Shader cache version bump
2023-06-08 17:43:16 -03:00
fe30c03cac Implement soft float64 conversion on shaders when host has no support (#5159)
* Implement soft float64 conversion on shaders when host has no support

* Shader cache version bump

* Fix rebase error
2023-06-08 17:09:14 -03:00
5813b2e354 Updater: Ignore files introduced by the user in base directory (#5092)
* Updater: Ignore files introduced by the user in base directory

* Replicate logic in Avalonia version.

* Address requested changes

* Updater: Ignore files introduced by the user in base directory

* Replicate logic in Avalonia version.

* Address requested changes

* Address requested changes

* Address requested changes

* Comment cleanup

* Address feedback

* Forgot comment, tehe
2023-06-05 14:19:17 +02:00
af1906ea04 Fix wrong unaligned SB state when fetching compute shaders (#5223) 2023-06-05 14:01:33 +02:00
68848000f7 Texture: Fix 3D texture size when totalBlocksOfGobsInZ > 1 (#5228)
* Texture: Fix 3D texture size when totalBlocksOfGobsInZ > 0

When there is a remainder when dividing depth by gobs in z, it is used to remove the unused part of the 3D texture's size. This was done to calculate correct sizes for single slice views of 3D textures.

However, this case can also apply to 3D textures with many slices, and more than one total block of gobs in z. In this case it's meant to trim off the end of the level size. Most textures won't encounter this as their size will be aligned, but UE4 games tend to use 3D textures with funny unaligned sizes.

The size offset should have been applied to the level size instead of the slice size, and it should only affect the slice size if it ends up larger.

Hopefully should fix issues with UE4 games without breaking other stuff, I don't have much time to test.

* Whoops
2023-06-05 13:33:09 +02:00
d98da47a0f Better application grid flex (#5218) 2023-06-05 00:48:11 +00:00
306f7e93a0 Dont Error on Invalid Enum Values (#5169)
* Dont Error on Invalid Enum

* Use TryParse

* Log warning
2023-06-05 01:19:46 +02:00
8954ff3af2 Replacing ZbcColorArray with Array4<uint> (#5210)
* Related "if/else if" statements should not have the same condition

* replacing ZbcColorArray with Array4<uint>

* fix alignment
2023-06-04 20:30:04 +00:00
d2f3adbf69 Texture: Fix layout conversion when gobs in z is used with depth = 1 (#5220)
* Texture: Fix layout conversion when gobs in z is used with depth = 1

The size calculator methods deliberately reduce the gob size of textures if they are deemed too small for it. This is required to get correct sizes when iterating mip levels of a texture.

Rendering to a slice of a 3D texture can produce a 3D texture with depth 1, but a gob size matching a much larger texture. We _can't_ "correct" this gob size, as it is intended as a slice of a larger 3D texture. Ignoring it causes layout conversion to break on read and flush.

This caused an issue in Tears of the Kingdom where the compressed 3D texture used for the gloom would always break on OpenGL, and seemingly randomly break on Vulkan. In the first case, the data is forcibly flushed to decompress the BC4 texture on the CPU to upload it as 3D, which was broken due to the incorrect layout. In the second, the data may be randomly flushed if it falls out of the cache, but it will appear correct if it's able to form copy dependencies.

This change only allows gob sizes to be reduced once per mip level. For the purpose of aligned size, it can still be reduced infinitely as our texture cache isn't properly able to handle a view being _misaligned_.

The SizeCalculator has also been changed to reduce the size of rendered depth slices to only include the exact range a single depth slice will cover. (before, the size was way too small with gobs in z reduced to 1, and too large when using the correct value)

Gobs in Y logic remains untouched, we don't support Y slices of textures so it's fine as is.

This is probably worth testing in a few games as it also affects texture size and view logic.

* Improve wording

* Maybe a bit better
2023-06-04 20:25:57 +00:00
d511c845b7 Check KeyboardMode in GUI (#4343)
* Update SoftwareKeyboard to send KeyboardMode to UI

* Update GTK UI to check text against KeyboardMode

* Update Ava UI to check text against KeyboardMode

* Restructure input validation

* true when text is not empty

* Add English validation text for SoftwareKeyboardMode

* Add Chinese validation text for SoftwareKeyboardMode

* Update base on feedback

---------

Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
2023-06-04 05:30:24 +02:00
21c9ac6240 Implement shader storage buffer operations using new Load/Store instructions (#4993)
* Implement storage buffer operations using new Load/Store instruction

* Extend GenerateMultiTargetStorageOp to also match access with constant offset, and log and comments

* Remove now unused code

* Catch more complex cases of global memory usage

* Shader cache version bump

* Extend global access elimination to work with more shared memory cases

* Change alignment requirement from 16 bytes to 8 bytes, handle cases where we need more than 16 storage buffers

* Tweak preferencing to catch more cases

* Enable CB0 elimination even when host storage buffer alignment is > 16 (for Intel)

* Fix storage buffer bindings

* Simplify some code

* Shader cache version bump

* Fix typo

* Extend global memory elimination to handle shared memory with multiple possible offsets and local memory
2023-06-03 20:12:18 -03:00
81c9052847 ava: Fix Input Touch (#5204) 2023-06-03 16:03:42 +01:00
9367e3c35d ava: Fix Open Applet menu enabled (#5206)
Currently, the `Open Applet` menu is still enabled when a guest is running, which is wrong. This is not fixed by refreshing the property binding on `IsEnabled`.
2023-06-03 11:03:34 +02:00
52cf141874 Armeilleure: Fix support for Windows on ARM64 (#5202)
* Armeilleure: Fix support for Windows on ARM64

Tested on Windows DevKit 2023.

* Address gdkchan's comments
2023-06-03 10:23:51 +02:00
8a352df3c6 Allow BGRA images on Vulkan (#5203) 2023-06-03 03:43:00 +00:00
c545c59851 ava: Fix exit dialog while guest is running. (#5207)
* ava: Fix exit dialog while guest is running.

There is currently an issue while a game runs, the content dialog creation method check if `IsGameRunning` is true to show the popup.
But the condition here is wrong (`window` is null) so it throw a NullException silently in `Dispatcher.UIThread`.
This is now fixed by using the right casting.

* improve condition

* Fix spacing
2023-06-03 03:37:00 +00:00
96ea4e8c8e nuget: bump Microsoft.NET.Test.Sdk from 17.6.0 to 17.6.1 (#5192)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.0 to 17.6.1.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.6.0...v17.6.1)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-01 21:03:00 +02:00
b8f48bcf64 UI: Fix empty homebrew icon (#5189)
* UI: Fix empty homebrew icon

We currently don't check the icon size when we read it from the homebrew data. That could cause issues at UI side since the buffer isn't null but empty. Extra check have been added UI side too.
(I cleaned up some files during my research too)

Fixes #5188

* Remove additional check

* Remove unused using
2023-06-01 18:24:00 +02:00
6966211e07 Give Library header DockPanel explicit height (#5160) 2023-06-01 17:40:44 +02:00
57524a4c8a Add issue template for missing shader instructions (#5048)
* Add issue template for missing shader instructions

* fixup! Add issue template for missing shader instructions

* Update .github/ISSUE_TEMPLATE/missing_shader_instruction.yml

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-01 17:32:38 +02:00
f4539c49d8 [Logger] Add print with stacktrace method (#5129)
* Add print with stacktrace method

* Adjust logging namespaces

* Add static keyword to DynamicObjectFormatter
2023-06-01 13:47:53 +00:00
12c62fdbc2 nuget: bump DynamicData from 7.13.8 to 7.14.2 (#5148)
Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.13.8 to 7.14.2.
- [Release notes](https://github.com/reactiveui/DynamicData/releases)
- [Changelog](https://github.com/reactivemarbles/DynamicData/blob/main/ReleaseNotes.md)
- [Commits](https://github.com/reactiveui/DynamicData/compare/7.13.8...7.14.2)

---
updated-dependencies:
- dependency-name: DynamicData
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-01 13:35:04 +00:00
e3c6be5e29 Only run one workflow for a PR at a time (#5137) 2023-06-01 09:42:49 +02:00
4741a05df9 Vulkan: Include DepthMode in ProgramPipelineState (#5185) 2023-06-01 09:05:39 +02:00
c6676007bf GPU: Dispose Renderer after running deferred actions (#5144)
* GAL: Dispose Renderer after running deferred actions

Deferred actions from disposing physical memory instances always dispose the resources in their caches. The renderer can't be disposed before these resources get disposed, otherwise the dispose actions will not actually run, and the ThreadedRenderer may get stuck trying to enqueue too many commands when there is nothing consuming them.

This should fix most instances of the emulator freezing on close.

* Wait for main render commands to finish, but keep RenderThread alive til dispose

* Address some feedback.

* No parameterize needed

* Set thread name as part of constructor

* Port to Ava and SDL2
2023-05-31 21:43:20 +00:00
92b0b7d753 Avalonia UI: Fix letter "x" in Ryujinx logo being cut off (#5176)
Also make the pronunciation center-aligned
2023-05-31 21:03:11 +00:00
232237bf28 Skip draws with zero vertex count (#5149) 2023-05-31 17:51:11 -03:00
c27e453fd3 Share ResourceManager vertex vertex A and B shaders (#5181) 2023-05-31 17:17:50 -03:00
0e037d0213 macOS Headless Fixes (#5167)
* Default hypervisor to disabled

* Include MVK on macOS

* Properly sign headless builds on macOS

* Force Vulkan on macOS

* Suggestions
2023-05-31 09:08:50 +02:00
0dca1fbe12 Add Context Menu Option to Run Application (#5154) 2023-05-30 19:51:03 +01:00
35d91a0e58 Linux: Automatically increase vm.max_map_count if it's too low (#4702)
* memory: Check results of pinvoke calls

* Increase vm.max_map_count when running Ryujinx

* Add SupportedOSPlatform attribute for WindowsApiException

* Revert increasing vm.max_map_count via script

* Add LinuxHelper to detect and increase vm.max_map_count

With GUI dialogs, this should be a bit more user-friendly.

* Supply arguments as a list to RunPkExec

* Add error logging in case RunPkExec() fails

* Prevent Gtk from crashing
2023-05-30 01:48:37 +02:00
a73a5d7e85 nuget: bump Microsoft.NET.Test.Sdk from 17.5.0 to 17.6.0 (#4986)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.5.0 to 17.6.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.5.0...v17.6.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-29 01:14:07 +02:00
832a5e8852 Make sure blend is disabled if render target has integer format (#5122)
* Make sure blend is disabled if render target has integer format

* Change approach to avoid permanently mutating state
2023-05-29 00:38:04 +02:00
96d1f0da2d Workaround for MoltenVK barrier issues (#5118) 2023-05-29 00:24:35 +02:00
597388ecda Fix incorrect vertex attribute format change (#5112)
* Fix incorrect vertex attribute format change

* Only change vertex format if the host supports the new format
2023-05-29 00:17:07 +02:00
1cf6d7b7bb Fix #5108: Allow surround sound for SDL2 in more scenarios (#5131) 2023-05-29 00:07:27 +02:00
7bc9d0cdad Linux: Use gamemode if it is available when using Ryujinx.sh. (#4938)
* Linux: Detect if gamemode is installed and start it when launching Ryujinx.

When using the Ryujinx.sh script to start the emulator check if gamemoderun exists and use it if it does.

Gamemode mode on Linux changes some system settings to make performance during gaming more consistent mainly by changing the CPU governor to performance.

https://github.com/FeralInteractive/gamemode

* Removed if statement.

* Fix due to wrong assumption about the output of which.

Checks if the which output contains a no match response, otherwise use gamemoderun.

Using a case statement because it makes substring matching possible in sh and also it turns out that adding an empty string after env throws an error because env attempts to parse it as a paramater.

* Missed a couple semicolons.

* Different approach for checking if gamemode is available.

Should hopefully work across all implementations of which.

* Remove unneeded which command.

* Change code to keep launch command to a single line.
2023-05-28 23:54:22 +02:00
dc0dbc50ab Add support for VK_EXT_depth_clip_control. (#5027)
* Add support for VK_EXT_depth_clip_control.

* Code review feedback

Minor formatting

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Check .DepthClipControl to make sure the host actually supports the feature.

* Review feedback: remove Vulkan platform switch, relying on QueryHostSupportsDepthClipControl to drive the behaviour - OpenGL returns true, and any future platforms that don't support the [-1, 1] depth mode can return false for the transformation.

---------

Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2023-05-28 23:31:56 +02:00
994f4dc77d chore: Update Avalonia to 0.10.21 (#5124) 2023-05-28 23:25:55 +02:00
c9e297b74c About window: Add changelog link under ver. number (#5095) 2023-05-28 23:13:40 +02:00
dd514a115c Update LastPlayed date on emulation end. (#5056) 2023-05-28 23:03:27 +02:00
7e0b4bd538 Improve macOS updater (#5064)
* Fix macOS Updater (once again)

* Also fix my brain's issues

* Move set -e that lsof doesn't trigger exit 1

* Resolve yesterdays brain malfunction 2

* Revert "Move set -e that lsof doesn't trigger exit 1"

This reverts commit 589a630610.

* Also check if PID exists

* Remove lsof and instead check for running processes

* Remove empty lines

* Increase max iterations

* Address feedback

* Remove obsolete check for child processes

* Update comments

* Update comments

* I swear this is the last commit

* lsof + ps check
2023-05-28 22:54:30 +02:00
378080eb87 Added Custom Path case when saving screenshots (#5086) 2023-05-28 22:44:46 +02:00
e8f5e97fa4 actions: revert timeout-minutes changes for PR workflow
Varibales aren't exposed to PRs...
2023-05-28 11:34:57 +02:00
f3873620a3 actions: Workaround YAML limitation for timeout-minutes
Because Github Actions wants an int, we use fromJSON to hack around
this.
2023-05-28 08:10:43 +02:00
986ac9ff83 Use variables to configure job timeouts (#5123) 2023-05-28 08:02:30 +02:00
42b9c1e8fe Ryujinx.Ava: fixes for random hangs on exit (#4827)
* Attempt at fixing hang on exit by ending the WindowNotificationManager notification loop, so that the Thread running it can exit.

* explicitly apply the NotificationManager template to allow the notification loop to begin

* NotificationHelper - remove explicity call to ApplyTemplate(). Change to ManualResetEventSlim so we can cancel the Wait on it.

* add a timeout to AudioRenderSystem.Stop()'s waiting for the termination signal, log a warning if this timeout occurs, and continue execution

* NotifiationHelper - cancel first, the CompleteAdding()

* Remove AudioRenderSystem._terminationEvent, redundant

* NotificationHelper - use host.Closing event to trigger cancellation instead of _notifationManager.DetachedFromLogicalTree

* Change NotificationHelper to use an explicit Thread for background work.  Wait on the cancellationToken's WaitHandle so the Thread doesn't have to deal with async. Wrap foreach in try/catch (OperationCanceledException) to swallow the escaping exception from the GetConsumingEnumerable().

* adjust formatting of AsyncWorkQueue constructor to use object initializers consistently

* use AsyncWorkQueue to do everything I added in SetNotificationManager()

* Revert "use AsyncWorkQueue to do everything I added in SetNotificationManager()"

This reverts commit f0e78366b8776ec8e2fef8ab023c0db1833155d3.

* use AsyncWorkQueue to handle the Thread-related changes previously made to NotificationHelper.SetNotificationHelper(). Wrap it in Lazy<T> and force instantiation in the TemplateApplied event handler to accomodate for the fact that AsyncWorkQueue starts immediately, and the notification dispatch loop was being delayed by _templateAppliedEvent.

* impl changes suggested by AcK77

* impl changes suggested by AcK77 (more)
2023-05-26 23:57:43 +02:00
3b375525fb Force reciprocal operation with value biased by constant to be precise on macOS (#5110)
* Force operations to be precise in some cases on SPIR-V

* Make it a bit more strict, add comments

* Shader cache version bump
2023-05-26 15:19:37 -03:00
e6658c133c Fix resolution scaling of image operation coordinates (#5102)
* Fix resolution scaling of image operation coordinates

* Shader cache version bump
2023-05-25 23:42:49 -03:00
5b42a4d2c4 Fix mod names (#5088) 2023-05-25 23:41:03 +02:00
8f0c89ffd6 Generate scaling helper functions on IR (#4714)
* Generate scaling helper functions on IR

* Delete unused code

* Split RewriteTextureSample and move gather bias add to an earlier pass

* Remove using

* Shader cache version bump
2023-05-25 17:46:58 -03:00
2c9715acf6 Truncate vertex attribute format if it exceeds stride on MoltenVK (#5094)
* Truncate vertex attribute format if it exceeds stride on MoltenVK

* Fix BGR format

* Move vertex attribute check to pipeline creation to avoid costs

* No need for this to be public
2023-05-25 17:03:51 -03:00
274af65f69 Update release.yml (#5058) 2023-05-25 16:17:37 +02:00
4ca78eded5 Vulkan: Do not set storage flag for multisample textures if not supported (#5060) 2023-05-23 10:41:37 +02:00
6cb6b15612 Implement p2rc, p2ri, p2rr and r2p.cc shaders (#5031)
* implement P2rC, P2rI, P2rR shaders

* implement R2p.CC shader

* bump CodeGenVersion

* address feedback
2023-05-22 17:32:15 -03:00
2725e40838 Revert "Bump MVK Version (#5057)" (#5061)
This reverts commit c2e4c8f98e.
2023-05-22 17:12:11 -03:00
c2e4c8f98e Bump MVK Version (#5057) 2023-05-22 14:41:08 -03:00
b53e7ffd46 Ava UI: Input Menu Redesign (#4990)
* Cleanup

* Remove redundant locales

* Start SVG Fixes…

Better +/- buttons

Fix the grips

Bumpers

Better directional pad

More SVG stuff

Grip adjustments

Final stuff

* Make image bigger

* Border radius

* More cleanup

* Restructure

* Restructure Rumble View

* Use compiled bindings where possible

* Round those pesky corners

* Ack Suggestions

* More suggestions

* Update src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-05-22 01:16:20 +02:00
ac66643346 Fix crash in SettingsViewModel when Vulkan isn't available (#4985)
* fix crash when Vulkan isn't available

* add VulkanRenderer.GetPhysicalDevices() overload that provides its own Vk API object and logs on failure

* adjustments per AcK77
2023-05-21 21:39:06 +02:00
21e88f17f6 ServerBase thread safety (#4577)
* Add guard against ServerBase.Dispose() being called multiple times. Add reset event to avoid Dispose() being called while the ServerLoop is still running.

* remove unused usings

* rework ServerBase to use one collection each for sessions and ports, and make all accesses thread-safe.

* fix Logger call

* use GetSessionObj(int) instead of using _sessions directly

* move _threadStopped check inside "dispose once" test

* - Replace _threadStopped event with attempt to Join() the ending thread (if that isn't the current thread) instead.

- Use the instance-local _selfProcess and (new) _selfThread variables to avoid suggesting that the current KProcess and KThread could change. Per gdkchan, they can't currently, and this old IPC system will be removed before that changes.

- Re-order Dispose() so that the Interlocked _isDisposed check is the last check before disposing, to increase the likelihood that multiple callers will result in one of them succeeding.

* code style suggestions per AcK77

* add infinite wait for thread termination
2023-05-21 21:28:51 +02:00
5626f2ca1c Replace ShaderBindings with new ResourceLayout structure for Vulkan (#5025)
* Introduce ResourceLayout

* Part 1: Use new ResourceSegments array on UpdateAndBind

* Part 2: Use ResourceLayout to build PipelineLayout

* Delete old code

* XML docs

* Fix shader cache load NRE

* Fix typo
2023-05-21 14:04:21 -03:00
402f05b8ef Replace constant buffer access on shader with new Load instruction (#4646) 2023-05-20 16:19:26 -03:00
fb27042e01 Limit compute storage buffer size (#5028) 2023-05-20 16:15:07 +00:00
69a9de33d3 SPIR-V: Only allow implicit LOD sampling on fragment (#5026) 2023-05-20 15:52:26 +02:00
bba51c2eeb Fix macOS Update Script (#5014)
* Update updater.sh

* Better script

* Revert "Better script"

This reverts commit 9bf6be863892e5e10c2f2dba45f1d0a60daca688.
2023-05-19 21:20:01 +02:00
fc26189fe1 Eliminate redundant multiplications by gl_FragCoord.w on the shader (#4578)
* Eliminate redundant multiplications by gl_FragCoord.w on the shader

* Shader cache version bump
2023-05-19 11:52:31 -03:00
a40c90e7dd nuget: bump DynamicData from 7.13.5 to 7.13.8 (#5001)
Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.13.5 to 7.13.8.
- [Release notes](https://github.com/reactiveui/DynamicData/releases)
- [Changelog](https://github.com/reactivemarbles/DynamicData/blob/main/ReleaseNotes.md)
- [Commits](https://github.com/reactiveui/DynamicData/compare/7.13.5...7.13.8)

---
updated-dependencies:
- dependency-name: DynamicData
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-19 06:52:44 +02:00
f864a49014 Fix Vulkan blit-like operations swizzle (#5003) 2023-05-18 18:16:03 -03:00
ecbf303266 GPU: Avoid using garbage size for non-cb0 storage buffers (#4999)
* GPU: Avoid using garbage size for non-cb0 storage buffers

In the depths area, Tears of the Kingdom uses a global memory access with address on constant buffer slot 6. This isn't standard and thus doesn't actually have a size 8 bytes after it, so we were reading back a garbage size that ended up very large (at least in version 1.1.0), and would synchronize a lot of data per frame.

This PR makes storage buffers created from addresses outside constant buffer slot 0 get their size as the number of bytes remaining in the GPU mapping starting at the given virtual address. This should bound the buffer to a reasonable size, and ideally stop it crossing into other memory.

* Limit max size

* Add TODO

* Feedback
2023-05-18 08:56:34 +02:00
b3bf05356b ava: Fix crash when extracting sections from NCA with no data section (#5002)
Tested against Omega Strickers.
2023-05-17 19:27:49 +00:00
cb4b58052f Start GPU performance counter at 0 instead of host GPU value (#4992)
* Start performance counter at 0 instead of host perf counter value

* whitespace

* init _firstTimestamp in constructer per feedback

* change comment

* punctuation

* address feedback

* revise comment
2023-05-17 15:38:59 -03:00
f8cdd5f484 macos: Fix relaunch with updater when no arguments were provided to the emulator (#4987)
The updater still seems to be erroring when replacing installed folder under normal operations.
2023-05-17 19:02:15 +02:00
22202be394 [GUI] Fix always hide cursor mode not hiding the cursor until it was moved (#4927)
* gtk: Add missing isMouseInClient check for hide-cursor

* ava: Add missing events and default isCursorInRenderer to true

This is necessary because we don't receive a initial PointerEnter event for some reason.
2023-05-14 16:34:31 +02:00
17ba217940 Vulkan: Device map buffers written more than flushed (#4911) 2023-05-13 15:15:05 +02:00
aae4595bdb Add timeout of 35 minutes to workflow jobs (#4928) 2023-05-13 13:24:43 +02:00
880fd3cfcb audio: sdl2: Do not report 5.1 if the device doesn't support it (#4908)
* amadeus: adjust VirtualDevice channel configuration reporting with HardwareDevice

* audio: sdl2: Do not report 5.1 if device doesn't support it

SDL2 5.1 to Stereo conversion is terrible and make everything sound
quiet.

Let's not expose 5.1 if not truly supported by the device.
2023-05-13 07:15:16 +00:00
f679f25e08 Set OpenGL PixelPackBuffer to 0 when done (#4921) 2023-05-13 00:59:46 +00:00
c2709b3bdd macOS CI Adjustments (#4910)
* Fix macOS build name in CI

Fixes updater

* Update build.yml

Don't publish x86 Mac builds

* Naming nitpick

* Berry changes

* Use the same prefix for PR and release build archives

---------

Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
2023-05-13 00:53:52 +02:00
2b6e81deea Ava: Fix wrong MouseButton (#4900) 2023-05-12 21:39:42 +02:00
7271f1b18e Bump shader cache codegen version
That was missing from #4892
2023-05-12 18:53:14 +02:00
5fda543f84 Vulkan: Partially workaround MoltenVK InvalidResource error (#4880)
* Add MVK stage flags workaround

* Actually do the workaround

* Remove GS on VS stuff

* Address feedback
2023-05-11 22:06:15 -03:00
95c06de4c1 GPU: Remove swizzle undefined matching and rework depth aliasing (#4896)
* GPU: Remove swizzle undefined matching and rework depth aliasing

@gdkchan pointed out that UI textures in TOTK seemed to be setting their texture swizzle incorrectly (texture was RGB but was sampling A, swizzle for A was wrong), so I determined that SwizzleComponentMatches was the problem and set on eliminating it. This PR combines existing work to select the most recently modified texture (now used when selecting which aliased texture to use) with some additional changes to remove the swizzle check and support aliased view creation.

The original observation (#1538) was that we wanted to match depth textures for the purposes of aliasing with color textures, but they often had different swizzle from what was sampled (as it's generally the identity swizzle once rendered). At the time, I decided to allow swizzles to match if only the defined components matched, which fixed the issue in all known cases but could easily be broken by a game _expecting_ a given swizzle, such as a 1/0 value on a component.

This error case could also occur in textures that don't even depth alias, such as R11G11B10, as the rule was created to generally apply to all cases.

The solution is now to fail this exact match test, and allow the search for an R32 texture to create a swizzled view of a D32 texture (and other such cases). This allows the creation of a view that mismatches the requested format, which wasn't present before and was the reason for the swizzle matching approach.

The exact match and view creation rules now follow the same rules over what textures to select when there are multiple options (such as a "perfect" match and an "aliased" match at the same time). It now selects the most recently modified texture, which is done with a new sequence number in the GpuContext (because we don't have enough of these).

Reportedly fixes UI having weird coloured backgrounds in TOTK. This also fixes an issue in MK8D where returning from a race resulted in the character selection cubemaps being broken. May work around issues introduced by the "short texture cache" PR due to modification ordering, though they won't be truly fixed.

Should allow (#4365) to avoid copies in more cases. Need to test that.

I tested a bunch of games #1538 originally affected and they seem to be fine. This change affects all games so it would be good to get some wide testing on it.

* Address feedback 1, fix an issue

* Workaround: Do not allow copies for format alias.

These should be removed when D32<->R32 copy dependencies become legal
2023-05-11 21:30:47 -03:00
49c63ea077 Fix the restart after an update. (#4869)
* Fix the restart after an update.

* Fix the updater for the Ava UI too.

* Fixing up the code after some change requests.
Removed a line of code that was accidentally left in.

* Fix restarting on Linux Avalonia.

* Fix issues with escaped arguments.
2023-05-12 02:14:29 +02:00
531da8a1c0 Changed LastPlayed field from string to nullable DateTime (#4861)
* Changed LastPlayed field from string to nullable DateTime

Added ApplicationData.LastPlayedString property
Added NullableDateTimeConverter for the DateTime->string conversion in Avalonia

* Added migration from string-based last_played to DateTime-based last_played_utc

* Updated comment style

* Added MarkupExtension to NullableDateTimeConverter and changed its usage

Cleaned up leftover usings

* Missed one comment
2023-05-12 01:56:37 +02:00
5cbdfbc7a4 amadeus: Allow 5.1 sink output (#4894)
* amadeus: Allow 5.1 sink output

Also add a simple Stereo to 5.1 change for device sink.

Tested against NES - Nintendo Switch Online that output stereo on the
audio renderer.

* Remove outdated comment
2023-05-12 00:19:19 +02:00
e0544dd9c7 UI: Adjust input mapping view (#4866)
* refactor: clean up controller settings ui

- Remove inconsistencies between left and right side
- Use style to set ToggleButton properties (since they are all the same)
- Move topmost controller settings from one line to 2x2 grid for improved clarity
- Properly adjust borders, text widths, etc. to neighboring elements to eliminate misaligned visual lines

* fix: merge issues

* fix: prevent sliders from jumping by giving text block fixed width

* refactor: add more separators and increase margin

* refactor: center deadzone and range descriptions

* refactor: move rumble border top margin to -1 and prevent double border

* refactor: remove margins & double borders + switch profile & input selection

* style: apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-05-11 21:10:57 +00:00
aa784c3e5e nuget: bump System.IdentityModel.Tokens.Jwt from 6.30.0 to 6.30.1 (#4886)
Bumps [System.IdentityModel.Tokens.Jwt](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet) from 6.30.0 to 6.30.1.
- [Release notes](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/releases)
- [Changelog](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/compare/6.30.0...6.30.1)

---
updated-dependencies:
- dependency-name: System.IdentityModel.Tokens.Jwt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-11 21:42:46 +02:00
9205077590 Enable explicit LOD for array textures with depth compare on SPIR-V (#4892) 2023-05-11 21:35:36 +02:00
0ed40c7175 Fix incorrect ASTC endpoint color when using LuminanceDelta mode (#4890) 2023-05-11 20:47:55 +02:00
40d47b7aa2 amadeus: Fix wrong channel mapping check and an old typo (#4888)
* amadeus: Fix wrong channel mapping check

This was always going to happens, as a result quadratic would break and
move index after the channel count point, effectively breaking
input/output indices.

* amadeus: Fix reverb 3d early delay wrong output index
2023-05-11 20:14:02 +02:00
ec0bb74968 Stop SDL from inhibiting sleep. (#4842) 2023-05-11 20:13:01 +02:00
42f7f98666 Fix the issue of unequal check for amiibo file date due to the lack o… (#4832)
* Fix the issue of unequal check for amiibo file date due to the lack of sub-second units in the header, causing slow opening of the amiibo interface.

* Supplement the unrepaired.
2023-05-11 19:10:24 +02:00
95bad6995c GPU: Fix shader cache assuming past shader data was mapped (#4885)
This fixes a potential issue where a shader lookup could match the address of a previous _different_ shader, but that shader is now partially unmapped. This would just crash with an invalid region exception.

To compare a shader in the address cache with one in memory, we get the memory at the location with the previous shader's size. However, it's possible it has been unmapped and then remapped with a smaller size. In this case, we should just get back the mapped portion of the shader, which will then fail the comparison immediately and get to compile/lookup for the new one.

This might fix a random crash in TOTK that was reported by Piplup. I don't know if it does, because I don't have the game yet.
2023-05-11 18:41:34 +02:00
3d42995822 Attempt to fix release.yml after merge 2023-05-11 17:42:33 +02:00
9095941fd1 Update release workflow & Add jobs for macOS (#4837)
* Add build config and extra args to create_macos_build.sh

* Use matrix strategy for releases

* Add macOS jobs

Co-authored-by: Mary <thog@protonmail.com>

* Fix wrong version argument

* Fix check for the correct amount of args

* Install latest rcodesign release

Co-authored-by: Mary <thog@protonmail.com>

* Set executable bits for PR builds on linux

---------

Co-authored-by: Mary <thog@protonmail.com>
2023-05-11 17:36:53 +02:00
ba71141bdc Ensure background translation threads exited before disposing JIT (#4874) 2023-05-10 21:46:38 -03:00
0a0675a7f6 Fix missing domain service object dispose (#4879) 2023-05-11 00:29:17 +00:00
a7c6e6a8cf fix(mvk): resumeLostDevice (#4800)
Command buffer errors currently trigger an exception "DeviceLost" crashing the process.

Looking at [MKV's code](53a4eb26f2/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm (L392-L408)) we observe that:
- It hard fails if error is:
  ```
   MTLCommandBufferErrorBlacklisted || MTLCommandBufferErrorNotPermitted || MTLCommandBufferErrorDeviceRemoved
   ```
- Otherwise fails conditionally if `config.resumeLostDevice == false` (current default)

For Ryujinx's use-case it's more graceful to resume on those errors rather than crashing the app, the error isn't totally silenced since `mvk` still logs it

Fixes #4704, #4575
2023-05-10 03:31:52 +02:00
0bc8151c7e IPC - Refactor Bcat service to use new ipc - Revisit (#4803)
* bcat ipc

* fix hipc buffer flags

* add buffer fixed size flag on generator
2023-05-09 21:46:23 +00:00
40c17673f5 Replace DelegateHelper with pre-generated delegates (#4867) 2023-05-09 09:02:39 +00:00
a8950d6ac4 vulkan: Pass Vk instance to VulkanRenderer (#4859)
This will allow possible multiple driver selection without any need of
LD preload. (useful when testing custom version of mesa for example)
2023-05-08 13:05:37 +02:00
162798b026 vulkan: Avoid hardcoding features in CreateDevice (#4858)
Those shouldn't have been hardcoded.
2023-05-08 10:48:16 +00:00
1b28ecd63e Vulkan: Simplify MultiFenceHolder and managing them (#4845)
* Vulkan: Simplify waitable add/remove

Removal of unnecessary hashset and dictionary

* Thread safety for GetBufferData in PersistentFlushBuffer

* Fix WaitForFencesImpl thread safety

* Proper methods for risky reference increments

* Wrong type of CB.

* Address feedback
2023-05-08 12:45:12 +02:00
895d9b53bc Vulkan: Batch vertex buffer updates (#4843)
* Vulkan: Batch vertex buffer updates

Some games can bind a large number of vertex buffers for draws. This PR allows for vertex buffers to be updated with one call rather than one per buffer.

This mostly affects the AMD Mesa driver, the testing platform was Steam Deck with Super Mario Odyssey. It was taking about 12% before, should be greatly reduced now.

A small optimization has been added to avoid looking up the same buffer multiple times, as a common pattern is for the same buffer to be bound many times in a row with different ranges.

* Only rebind vertex buffers if they have changed

* Address feedback
2023-05-08 10:59:26 +02:00
0e06aace45 misc: Avoid copy of ApplicationControlProperty (#4849)
Avoid more giant copy when passing it around.
2023-05-08 01:50:07 +02:00
adf4ebcd60 Ava: Fix SystemTimeOffset calculation (#4848)
* Ava: Fix SystemTimeOffset calculation

During testing of #4822, Mary pointed out the way we calculate time offset is wrong in our Avalonia UI. This PR fixed that.
The axaml file is autoformatted too.

* DateTime.Now in local var
2023-05-08 00:31:08 +02:00
470a8031a4 time: Update for 15.0.0 changes and fixes long standing issues (#4822)
* time: Update for 15.0.0 changes

Last time we did an upgrade on the time service was during 9.x era, it was about time to take back that reverse again!

15.0.0 added a new structure on the shared memory to get steady clock raw timepoints with a granularity in nanoseconds.

This commit implements this new part.

I plan to write a follow up with a bit of refactoring of this ancient part of the emulator.

As always, reverse and work done by your truly.

PS: As a reminder, if this change is reused anywhere else, work should be credited as Ryujinx and not my person.

* time: Do not set setup value to posix time

This should fix local and network clock returning 0 under usage with
shared memory.

This probably fix #2430.

* Address gdkchan's comment

* Fix internal offset not working since changes and ensure that user clock have a valid clock id

* time: Report auto correcting clock and hardcode steady clock unique id

Fix Pokemon Sword Pokejobs for real.

* Address gdkchan's comment
2023-05-08 00:15:58 +02:00
5440d4ad5c misc: Switch ProcessResult to a class (#4846)
This avoid giant copies being performed when being returned or passed.
2023-05-07 20:50:45 +00:00
dde208b480 UI: Expose games build ID for cheat management (#4340)
* Ava UI: Expose games build ID for cheat management

* Fix bad merge

* Change integrity check level to error on invalid

* Add support for GDK

* Remove whitespace

* Add BID identifier

* PR Comments fix

* Restore title id in cheats GTK window

* use halign center instead of margin_left

* Merge

* fix after merge

* PR comments fix - design AVA

* PR fix - Move GetApplicationBuildId to ApplicationData class

* PR comment fix - Add empty line before method

* Align with PR #4755

* PR comments fix

* Change BuildId label to support translation

* Comments fix

* Remove unused BuildIdLabel property
2023-05-07 14:36:44 +00:00
4c3d2d5d75 UI: Add progress bar for re-packaging shaders (#4805)
* feat: introduce new shader loading state for progress tracking when writing shaders to disk

* fix: move translation to bottom of locale file

* fix: change back to foreach and add requested spacing between lines

* style: fix formatting

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

---------

Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2023-05-06 15:35:46 +02:00
fab11ba3f1 AM: Stub some service calls (#4825)
* AM: Stub some service call

Some IPC I have stubbed during private testing and I don't want to deal with them anymore. Nothing more.

* ICommonStateGetter disposable
2023-05-06 03:33:50 +02:00
332891b5ff Use correct offset for storage constant buffer elimination (#4821) 2023-05-05 23:59:36 +02:00
7df4fcada7 GPU: Remove CPU region handle containers (#4817)
* GPU: Remove CPU region handle containers.

Another one for the "I don't know why I didn't do this earlier" pile.

This removes the "Cpu" prefixed region handle classes, which each mirror a region handle type from Ryujinx.Memory.

Originally, not all projects had a reference to Ryujinx.Memory, so these classes were introduced to bridge the gap. Someone else crossed that bridge since, so these classes don't have much of a purpose anymore.

This PR replaces all uses of CpuRegionHandle etc to their direct Ryujinx.Memory versions.

RegionHandle methods (specifically QueryModified) are about the hottest path there is in the entire emulator, so there is a nice boost from doing this.

* Add docs
2023-05-05 23:40:46 +02:00
d6698680be UI: Fix sections extraction (#4820)
* UI: Fix sections extraction

There is currently an issue when the update NCA doesn't contains the section we want to extract, this is fixed by adding a check.
I have fixed the inverted handler of ExeFs/Logo introduced in #4755.

Fixes #4521

* Addresses feedback
2023-05-05 21:24:35 +00:00
e5c9838b0b Correct tooltips for add,remove,removeall buttons (#4819) 2023-05-05 22:38:57 +02:00
f8ec878796 Fix typo in TextureBindingsManager.cs (#4798)
accomodate -> accommodate
2023-05-05 22:17:36 +02:00
9ff21f9ab6 Use ToLowerInvariant when detecting GPU vendor. (#4815) 2023-05-05 16:35:59 +00:00
aa021085cf Allow any shader SSBO constant buffer slot and offset (#2237)
* Allow any shader SSBO constant buffer slot and offset

* Fix slot value passed to SetUsedStorageBuffer on fallback case

* Shader cache version

* Ensure that the storage buffer source constant buffer offset is word aligned

* Fix FirstBinding on GetUniformBufferDescriptors
2023-05-05 14:20:20 +00:00
1f5d881860 GPU: Allow granular buffer updates from the constant buffer updater (#4749)
* GPU: Allow granular buffer updates from the constant buffer updater

Sometimes, constant buffer updates can't be avoided, either due to a cb0 access that cannot be eliminated, or the game updating a buffer between draws to the detriment of everyone.

To avoid uploading the full 4096 bytes each time, this PR remembers the offset and size containing all constant buffer updates since the last sync. It will then upload that range after sync.

* Allow clearing the dirty range

* Always use precise

Might want to not do this if distance between the existing range and new one is too high.

* Use old force dirty mechanism when distance between regions is too great

* Update src/Ryujinx.Graphics.Gpu/Memory/Buffer.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Fix inheritance of _dirtyStart and _dirtyEnd

---------

Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2023-05-05 13:47:15 +00:00
1f664100bd ModLoader: Fix case sensitivy issues without breaking cheats (#4783)
* Fix case sensitivity for mod subdirectories

* Small refactoring of ModLoader

* Don't share instruction list between all cheats

Co-authored-by: riperiperi <rhy3756547@hotmail.com>

---------

Co-authored-by: riperiperi <rhy3756547@hotmail.com>
2023-05-05 09:39:08 +02:00
1f5e1ffa80 fix: linux launcher breaks when there are spaces in the directory path (#4795)
* fix: linux launcher breaks when there are spaces in the directory path

* Add quotes around $0 as well

---------

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
2023-05-05 09:06:15 +02:00
264438ff19 Revert "bcat ipc (#4446)" (#4801)
This reverts commit 4250732353.
2023-05-04 18:16:51 +02:00
3b8ac1641a UI: Move ApplicationContextMenu in a separated class (#4755)
* UI: Move ApplicationContextMenu in a separated class

This PR remove duplicated code related to the context menu on the Application list/grid by create a control for the menu which include related handler.

I've renamed "GameList/GameGrid" by "Application" for consistencies. And I've removed all uneeded field from the project file too.

While I cleaned up things, I've found an issue about purging Ptc/Shader cache, both methods list files even if the user say "No", shader cache is purged even if the user say "No". It's fixed.

* Adresses feedbacks
2023-05-04 14:41:06 +00:00
4250732353 bcat ipc (#4446) 2023-05-04 16:26:10 +02:00
4d1579acbf Fix some invalid blits involving depth textures (#4723) 2023-05-03 21:20:12 -03:00
6279f5e430 Update SettingsWindow.cs (#4785)
fix saving if directory path directly pasted in to the text field instead of using FileChooser.
2023-05-03 16:04:40 +02:00
b7d2bff6aa Revert "ModLoader: Fix case sensitivy issues (#4720)" (#4781)
This reverts commit cc1a933a2f.
2023-05-03 11:20:05 +02:00
7c327fecb3 Vulkan: Record modifications after changing the framebuffer (#4775)
Our Vulkan backend inserts image barriers when a texture is sampled after it is rendered. This is done via a "modification flag" which is set when a render target is unbound (presuming that a texture has finished drawing to it).

Imagine the following scenario:
- Game sets render target to texture A
- Game renders to texture A
- (render pass ends)
- Game binds texture A to a sampler
- Game sets render target to texture B
- Renders to texture B using texture A (barrier required)

Because of the previous behaviour, the check to add a barrier for sampling a texture actually happens before it is registered as modified, meaning no barrier was added at all. This isn't always the case, but it was definitely causing issues in Xenoblade 2.

This doesn't fix any more complicated issues where a texture is repeatedly sampled while it is currently being rendered.

Fixes visual glitches at lower resolutions in Xenoblade 2. May fix other cases.
2023-05-03 10:42:21 +02:00
cc1a933a2f ModLoader: Fix case sensitivy issues (#4720)
* Fix case sensitivity for mod subdirectories

* Small refactoring of ModLoader
2023-05-03 02:07:16 +02:00
dd574146fb Add hide-cursor command line argument & always hide cursor option (#4613)
* Add hide-cursor command line argument

* gtk: Adjust SettingsWindow for hide cursor options

* ava: Adjust SettingsWindow for hide cursor options

* ava: Add override check for HideCursor arg

* Remove copy&paste sins

* ava: Leave a little more room between the options

* gtk: Fix hide cursor issues

* ava: Only hide cursor if it's within the embedded window
2023-05-02 03:29:47 +02:00
2c94ac455e GPU: Keep rendered textures without any pool references alive (#4662)
* GPU: Keep sampled textures without any pool references alive

Occasionally games are very wasteful and clear/write to a texture without ever sampling it. As rendered textures in NVN games seem to all have overlapping memory ranges, the texture will eventually get overwritten.

Normally, this would trigger a removal from the auto delete cache, but a pool entry would keep the texture alive. However, with these textures that are never used, they will get deleted immediately and recreated on the next frame.

This change makes it so the ShortTextureCache can keep textures that have naver had a pool reference alive for a few frames, so they're not constantly being created and deleted.

This improves performance in Zelda BOTW a little.

* Cleanup
2023-05-01 16:27:51 -03:00
e18d258fa0 GPU: Pre-emptively flush textures that are flushed often (to imported memory when available) (#4711)
* WIP texture pre-flush

Improve performance of TextureView GetData to buffer

Fix copy/sync ordering

Fix minor bug

Make this actually work

WIP host mapping stuff

* Fix usage flags

* message

* Cleanup 1

* Fix rebase

* Fix

* Improve pre-flush rules

* Fix pre-flush

* A lot of cleanup

* Use the host memory bits

* Select the correct memory type

* Cleanup TextureGroupHandle

* Missing comment

* Remove debugging logs

* Revert BufferHandle _value access modifier

* One interrupt action at a time.

* Support D32S8 to D24S8 conversion, safeguards

* Interrupt cannot happen in sync handle's lock

Waitable needs to be checked twice now, but this should stop it from deadlocking.

* Remove unused using

* Address some feedback

* Address feedback

* Address more feedback

* Address more feedback

* Improve sync rules

Should allow for faster sync in some cases.
2023-05-01 16:05:12 -03:00
36f10df775 GPU: Fix errors handling texture remapping (#4745)
* GPU: Fix errors handling texture remapping

- Fixes an error where a pool entry and memory mapping changing at the same time could cause a texture to rebind its data from the wrong GPU VA (data swaps)
- Fixes an error where the texture pool could act on a mapping change before the mapping has actually been changed ("Unmapped" event happens before change, we need to signal it changed _after_ it completes)

TODO: remove textures from partially mapped list... if they aren't.

* Add Remap actions for handling post-mapping behaviours

* Remove unused code.

* Address feedback

* Nit
2023-05-01 15:32:32 -03:00
680e548022 Uneven frame pacing with vsync (#4744)
fixes issue #3906
2023-04-29 21:54:41 +01:00
21c4176157 Allow window to remember its size, position and state (GTK + Avalonia) (#4657)
* Update ConfigurationState.cs

* Update ConfigurationFileFormat.cs

* Update MainWindow.cs

* Update ConfigurationFileFormat.cs

* Update ConfigurationState.cs

* Update MainWindow.cs

* Update MainWindow.cs

* Update Ryujinx.Ui.Common/Configuration/ConfigurationState.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Update MainWindow.cs

* Update Ryujinx/Ui/MainWindow.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Initial properties

* Viewmodel adjustments and additions

* abstract and monitor dimension changes

* Remove position from ViewModel and simplify methods

* Remove unused dep

* Update configuration and fix typo from AA

* review changes

* Review changes

* Screensize checks - Ava

* Review changes 2

* basic review changes

* Standardise GTK/Ava functions

* Actually call function

---------

Co-authored-by: HaizenTrist <123991082+HaizenTrist@users.noreply.github.com>
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2023-04-28 22:59:53 +02:00
3b4ff2d6d9 nuget: bump System.IdentityModel.Tokens.Jwt from 6.29.0 to 6.30.0 (#4736)
Bumps [System.IdentityModel.Tokens.Jwt](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet) from 6.29.0 to 6.30.0.
- [Release notes](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/releases)
- [Changelog](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/compare/6.29.0...6.30.0)

---
updated-dependencies:
- dependency-name: System.IdentityModel.Tokens.Jwt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 11:54:19 +02:00
12504f280c Fix paths and typos for macOS scripts (#4738)
* Fix paths and typos for macOS scripts

* Update outdated comments about rcodesign

---------

Co-authored-by: Mary <thog@protonmail.com>
2023-04-28 08:14:44 +00:00
250fc51374 Adjust github workflows for new src directory 2023-04-27 23:51:14 +02:00
206e0882c2 Adjust Ryujinx.Tests.Memory namespace 2023-04-27 23:51:14 +02:00
609abc8b9b Rename Ryujinx.Memory.Tests to Ryujinx.Tests.Memory 2023-04-27 23:51:14 +02:00
cee7121058 Move solution and projects to src 2023-04-27 23:51:14 +02:00
3622 changed files with 39622 additions and 32676 deletions

View File

@ -0,0 +1,19 @@
name: Missing Shader Instruction
description: Shader Instruction is missing in Ryujinx.
title: "[GPU]"
labels: [gpu, not-implemented]
body:
- type: textarea
id: instruction
attributes:
label: Shader instruction
description: What shader instruction is missing?
validations:
required: true
- type: textarea
id: required
attributes:
label: Required by
description: Add links to the [compatibility list page(s)](https://github.com/Ryujinx/Ryujinx-Games-List/issues) of the game(s) that require this instruction.
validations:
required: true

8
.github/assign/audio.yml vendored Normal file
View File

@ -0,0 +1,8 @@
addReviewers: true
reviewers:
- marysaka
filterLabels:
include:
- audio

11
.github/assign/cpu.yml vendored Normal file
View File

@ -0,0 +1,11 @@
addReviewers: true
reviewers:
- gdkchan
- riperiperi
- marysaka
- LDj3SNuD
filterLabels:
include:
- cpu

4
.github/assign/global.yml vendored Normal file
View File

@ -0,0 +1,4 @@
addReviewers: true
reviewers:
- Ryujinx/developers

10
.github/assign/gpu.yml vendored Normal file
View File

@ -0,0 +1,10 @@
addReviewers: true
reviewers:
- gdkchan
- riperiperi
- marysaka
filterLabels:
include:
- gpu

11
.github/assign/gui.yml vendored Normal file
View File

@ -0,0 +1,11 @@
addReviewers: true
reviewers:
- Ack77
- emmauss
- TSRBerry
- marysaka
filterLabels:
include:
- gui

11
.github/assign/horizon.yml vendored Normal file
View File

@ -0,0 +1,11 @@
addReviewers: true
reviewers:
- gdkchan
- Ack77
- marysaka
- TSRBerry
filterLabels:
include:
- horizon

9
.github/assign/infra.yml vendored Normal file
View File

@ -0,0 +1,9 @@
addReviewers: true
reviewers:
- marysaka
- TSRBerry
filterLabels:
include:
- infra

33
.github/labeler.yml vendored Normal file
View File

@ -0,0 +1,33 @@
audio: 'src/Ryujinx.Audio*/**'
cpu:
- 'src/ARMeilleure/**'
- 'src/Ryujinx.Cpu/**'
- 'src/Ryujinx.Memory/**'
gpu:
- 'src/Ryujinx.Graphics.*/**'
- 'src/Spv.Generator/**'
- 'src/Ryujinx.ShaderTools/**'
'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/**'
'graphics-backend:vulkan':
- 'src/Ryujinx.Graphics.Vulkan/**'
- 'src/Spv.Generator/**'
gui:
- 'src/Ryujinx/**'
- 'src/Ryujinx.Ui.Common/**'
- 'src/Ryujinx.Ui.LocaleGenerator/**'
- 'src/Ryujinx.Ava/**'
horizon:
- 'src/Ryujinx.HLE/**'
- 'src/Ryujinx.Horizon*/**'
kernel: 'src/Ryujinx.HLE/HOS/Kernel/**'
infra:
- '.github/**'
- 'distribution/**'
- 'Directory.Packages.props'

View File

@ -3,25 +3,29 @@ name: Build job
on:
workflow_dispatch:
inputs: {}
#push:
# branches: [ master ]
# paths-ignore:
# - '.github/*'
# - '.github/ISSUE_TEMPLATE/**'
# - '*.yml'
# - 'README.md'
pull_request:
branches: [ master ]
paths-ignore:
- '.github/*'
- '.github/ISSUE_TEMPLATE/**'
- '.github/**'
- '*.yml'
- '*.json'
- '*.config'
- 'README.md'
concurrency:
group: pr-checks-${{ github.event.number }}
cancel-in-progress: true
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.1.0"
jobs:
build:
name: ${{ matrix.os }} (${{ matrix.configuration }})
name: ${{ matrix.OS_NAME }} (${{ matrix.configuration }})
runs-on: ${{ matrix.os }}
timeout-minutes: 45
strategy:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
@ -33,7 +37,7 @@ jobs:
RELEASE_ZIP_OS_NAME: linux_x64
- os: macOS-latest
OS_NAME: MacOS x64
OS_NAME: macOS x64
DOTNET_RUNTIME_IDENTIFIER: osx-x64
RELEASE_ZIP_OS_NAME: osx_x64
@ -43,47 +47,107 @@ jobs:
RELEASE_ZIP_OS_NAME: win_x64
fail-fast: false
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.1.0"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
global-json-file: global.json
- name: Get git short hash
id: git_short_hash
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Build
run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER
- name: Test
run: dotnet test --no-build -c "${{ matrix.configuration }}"
- name: Publish Ryujinx
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx --self-contained true
if: github.event_name == 'pull_request'
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
- name: Publish Ryujinx.Headless.SDL2
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Headless.SDL2 --self-contained true
if: github.event_name == 'pull_request'
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained true
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
- name: Publish Ryujinx.Ava
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Ava --self-contained true
if: github.event_name == 'pull_request'
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Ava --self-contained true
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
- name: Set executable bit
run: |
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
chmod +x ./publish_ava/Ryujinx.Ava ./publish_ava/Ryujinx.sh
if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest'
- name: Upload Ryujinx artifact
uses: actions/upload-artifact@v3
with:
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
path: publish
if: github.event_name == 'pull_request'
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
- name: Upload Ryujinx.Headless.SDL2 artifact
uses: actions/upload-artifact@v3
with:
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
path: publish_sdl2_headless
if: github.event_name == 'pull_request'
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
- name: Upload Ryujinx.Ava artifact
uses: actions/upload-artifact@v3
with:
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
path: publish_ava
if: github.event_name == 'pull_request'
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
build_macos:
name: macOS Universal (${{ matrix.configuration }})
runs-on: ubuntu-latest
timeout-minutes: 45
strategy:
matrix:
configuration: [ Debug, Release ]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
global-json-file: global.json
- name: Setup LLVM 14
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 14
- name: Install rcodesign
run: |
mkdir -p $HOME/.bin
gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz'
tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1
rm apple-codesign.tar.gz
mv rcodesign $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get git short hash
id: git_short_hash
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
- name: Publish macOS
run: |
./distribution/macos/create_macos_build.sh . publish_tmp publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
- name: Upload Ryujinx.Ava artifact
uses: actions/upload-artifact@v3
with:
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
path: "publish_ava/*.tar.gz"
if: github.event_name == 'pull_request'

View File

@ -12,13 +12,14 @@ concurrency: flatpak-release
jobs:
release:
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
runs-on: ubuntu-latest
env:
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
GIT_COMMITTER_NAME: "RyujinxBot"
GIT_COMMITTER_EMAIL: "61127645+RyujinxBot@users.noreply.github.com"
RYUJINX_PROJECT_FILE: "Ryujinx/Ryujinx.csproj"
RYUJINX_PROJECT_FILE: "src/Ryujinx/Ryujinx.csproj"
NUGET_SOURCES_DESTDIR: "nuget-sources"
RYUJINX_VERSION: "${{ inputs.ryujinx_version }}"
@ -168,4 +169,4 @@ jobs:
git config user.email "${{ env.GIT_COMMITTER_EMAIL }}"
git add .
git commit -m "$COMMIT_MESSAGE"
git push origin master
git push origin master

View File

@ -7,6 +7,7 @@ jobs:
pr_comment:
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
steps:
- uses: actions/github-script@v6
with:
@ -65,4 +66,4 @@ jobs:
} else {
core.info(`Creating a comment`);
await github.rest.issues.createComment({repo, owner, issue_number, body});
}
}

54
.github/workflows/pr_triage.yml vendored Normal file
View File

@ -0,0 +1,54 @@
name: "Pull Request Triage"
on:
pull_request_target:
types: [opened, ready_for_review]
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Update labels based on changes
uses: actions/labeler@v4
with:
sync-labels: true
dot: true
- name: Auto Assign [Audio]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/audio.yml'
- name: Auto Assign [CPU]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/cpu.yml'
- name: Auto Assign [GPU]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/gpu.yml'
- name: Auto Assign [GUI]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/gui.yml'
- name: Auto Assign [Horizon]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/horizon.yml'
- name: Auto Assign [Infra]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/infra.yml'
- name: Auto Assign [Global]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/global.yml'

View File

@ -6,9 +6,10 @@ on:
push:
branches: [ master ]
paths-ignore:
- '.github/*'
- '.github/ISSUE_TEMPLATE/**'
- '.github/**'
- '*.yml'
- '*.json'
- '*.config'
- 'README.md'
concurrency: release
@ -22,98 +23,18 @@ env:
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "release-channel-master"
jobs:
release:
runs-on: windows-latest
tag:
name: Create tag
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
global-json-file: global.json
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Configure for release
run: |
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Create output dir
run: "mkdir release_output"
- name: Publish Windows
run: |
dotnet publish -c Release -r win10-x64 -o ./publish_windows/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx --self-contained true
dotnet publish -c Release -r win10-x64 -o ./publish_windows_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx.Headless.SDL2 --self-contained true
dotnet publish -c Release -r win10-x64 -o ./publish_windows_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx.Ava --self-contained true
- name: Packing Windows builds
run: |
pushd publish_windows
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
popd
pushd publish_windows_sdl2_headless
7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
popd
pushd publish_windows_ava
7z a ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
popd
shell: bash
- name: Publish Linux
run: |
dotnet publish -c Release -r linux-x64 -o ./publish_linux/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx --self-contained true
dotnet publish -c Release -r linux-x64 -o ./publish_linux_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx.Headless.SDL2 --self-contained true
dotnet publish -c Release -r linux-x64 -o ./publish_linux_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx.Ava --self-contained true
- name: Packing Linux builds
run: |
pushd publish_linux
tar --exclude "publish/Ryujinx" --exclude "publish/Ryujinx.sh" -cvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar publish
python3 ../distribution/misc/add_tar_exec.py ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx" "publish/Ryujinx"
python3 ../distribution/misc/add_tar_exec.py ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.sh" "publish/Ryujinx.sh"
gzip -9 < ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar > ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz
rm ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar
popd
pushd publish_linux_sdl2_headless
tar --exclude "publish/Ryujinx.Headless.SDL2" --exclude "publish/Ryujinx.sh" -cvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar publish
python3 ../distribution/misc/add_tar_exec.py ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.Headless.SDL2" "publish/Ryujinx.Headless.SDL2"
python3 ../distribution/misc/add_tar_exec.py ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.sh" "publish/Ryujinx.sh"
gzip -9 < ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar > ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz
rm ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar
popd
pushd publish_linux_ava
tar --exclude "publish/Ryujinx.Ava" --exclude "publish/Ryujinx.sh" -cvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar publish
python3 ../distribution/misc/add_tar_exec.py ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.Ava" "publish/Ryujinx.Ava"
python3 ../distribution/misc/add_tar_exec.py ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.sh" "publish/Ryujinx.sh"
gzip -9 < ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar > ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz
rm ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar
popd
shell: bash
- name: Pushing new release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "release_output/*.tar.gz,release_output/*.zip"
tag: ${{ steps.version_info.outputs.build_version }}
body: "For more informations about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)."
allowUpdates: true
removeArtifacts: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
- name: Create tag
uses: actions/github-script@v5
uses: actions/github-script@v6
with:
script: |
github.rest.git.createRef({
@ -123,9 +44,168 @@ jobs:
sha: context.sha
})
release:
name: Release ${{ matrix.OS_NAME }}
runs-on: ${{ matrix.os }}
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
strategy:
matrix:
os: [ ubuntu-latest, windows-latest ]
include:
- os: ubuntu-latest
OS_NAME: Linux x64
DOTNET_RUNTIME_IDENTIFIER: linux-x64
RELEASE_ZIP_OS_NAME: linux_x64
- os: windows-latest
OS_NAME: Windows x64
DOTNET_RUNTIME_IDENTIFIER: win10-x64
RELEASE_ZIP_OS_NAME: win_x64
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
global-json-file: global.json
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Configure for release
run: |
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Create output dir
run: "mkdir release_output"
- name: Publish
run: |
dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_gtk/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true
dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true
dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Ava --self-contained true
- name: Packing Windows builds
if: matrix.os == 'windows-latest'
run: |
pushd publish_gtk
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
popd
pushd publish_sdl2_headless
7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
popd
pushd publish_ava
7z a ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
popd
shell: bash
- name: Packing Linux builds
if: matrix.os == 'ubuntu-latest'
run: |
pushd publish_gtk
chmod +x publish/Ryujinx.sh publish/Ryujinx
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
popd
pushd publish_sdl2_headless
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
popd
pushd publish_ava
chmod +x publish/Ryujinx.sh publish/Ryujinx.Ava
tar -czvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
popd
shell: bash
- name: Pushing new release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "release_output/*.tar.gz,release_output/*.zip"
tag: ${{ steps.version_info.outputs.build_version }}
body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)."
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
macos_release:
name: Release MacOS universal
runs-on: ubuntu-latest
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
global-json-file: global.json
- name: Setup LLVM 14
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 14
- name: Install rcodesign
run: |
mkdir -p $HOME/.bin
gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz'
tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1
rm apple-codesign.tar.gz
mv rcodesign $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
- name: Configure for release
run: |
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Publish macOS
run: |
./distribution/macos/create_macos_build.sh . publish_tmp publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
- name: Pushing new release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "publish_ava/*.tar.gz"
tag: ${{ steps.version_info.outputs.build_version }}
body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)."
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
flatpak_release:
uses: ./.github/workflows/flatpak.yml
needs: release
with:
ryujinx_version: "1.1.${{ github.run_number }}"
secrets: inherit
secrets: inherit

View File

@ -1,11 +0,0 @@
namespace ARMeilleure.Decoders
{
interface IOpCodeLit : IOpCode
{
int Rt { get; }
long Immediate { get; }
int Size { get; }
bool Signed { get; }
bool Prefetch { get; }
}
}

View File

@ -1,28 +0,0 @@
namespace ARMeilleure.Decoders
{
class OpCodeMemLit : OpCode, IOpCodeLit
{
public int Rt { get; }
public long Immediate { get; }
public int Size { get; }
public bool Signed { get; }
public bool Prefetch { get; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeMemLit(inst, address, opCode);
public OpCodeMemLit(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{
Rt = opCode & 0x1f;
Immediate = (long)address + DecoderHelper.DecodeImmS19_2(opCode);
switch ((opCode >> 30) & 3)
{
case 0: Size = 2; Signed = false; Prefetch = false; break;
case 1: Size = 3; Signed = false; Prefetch = false; break;
case 2: Size = 2; Signed = true; Prefetch = false; break;
case 3: Size = 0; Signed = false; Prefetch = true; break;
}
}
}
}

View File

@ -1,48 +0,0 @@
namespace ARMeilleure.Decoders
{
class OpCodeSimdMemMs : OpCodeMemReg, IOpCodeSimd
{
public int Reps { get; }
public int SElems { get; }
public int Elems { get; }
public bool WBack { get; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdMemMs(inst, address, opCode);
public OpCodeSimdMemMs(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{
switch ((opCode >> 12) & 0xf)
{
case 0b0000: Reps = 1; SElems = 4; break;
case 0b0010: Reps = 4; SElems = 1; break;
case 0b0100: Reps = 1; SElems = 3; break;
case 0b0110: Reps = 3; SElems = 1; break;
case 0b0111: Reps = 1; SElems = 1; break;
case 0b1000: Reps = 1; SElems = 2; break;
case 0b1010: Reps = 2; SElems = 1; break;
default: Instruction = InstDescriptor.Undefined; return;
}
Size = (opCode >> 10) & 3;
WBack = ((opCode >> 23) & 1) != 0;
bool q = ((opCode >> 30) & 1) != 0;
if (!q && Size == 3 && SElems != 1)
{
Instruction = InstDescriptor.Undefined;
return;
}
Extend64 = false;
RegisterSize = q
? RegisterSize.Simd128
: RegisterSize.Simd64;
Elems = (GetBitsCount() >> 3) >> Size;
}
}
}

View File

@ -1,97 +0,0 @@
namespace ARMeilleure.Decoders
{
class OpCodeSimdMemSs : OpCodeMemReg, IOpCodeSimd
{
public int SElems { get; }
public int Index { get; }
public bool Replicate { get; }
public bool WBack { get; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdMemSs(inst, address, opCode);
public OpCodeSimdMemSs(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{
int size = (opCode >> 10) & 3;
int s = (opCode >> 12) & 1;
int sElems = (opCode >> 12) & 2;
int scale = (opCode >> 14) & 3;
int l = (opCode >> 22) & 1;
int q = (opCode >> 30) & 1;
sElems |= (opCode >> 21) & 1;
sElems++;
int index = (q << 3) | (s << 2) | size;
switch (scale)
{
case 1:
{
if ((size & 1) != 0)
{
Instruction = InstDescriptor.Undefined;
return;
}
index >>= 1;
break;
}
case 2:
{
if ((size & 2) != 0 ||
((size & 1) != 0 && s != 0))
{
Instruction = InstDescriptor.Undefined;
return;
}
if ((size & 1) != 0)
{
index >>= 3;
scale = 3;
}
else
{
index >>= 2;
}
break;
}
case 3:
{
if (l == 0 || s != 0)
{
Instruction = InstDescriptor.Undefined;
return;
}
scale = size;
Replicate = true;
break;
}
}
Index = index;
SElems = sElems;
Size = scale;
Extend64 = false;
WBack = ((opCode >> 23) & 1) != 0;
RegisterSize = q != 0
? RegisterSize.Simd128
: RegisterSize.Simd64;
}
}
}

View File

@ -1,24 +0,0 @@
namespace ARMeilleure.IntermediateRepresentation
{
enum Comparison
{
Equal = 0,
NotEqual = 1,
Greater = 2,
LessOrEqual = 3,
GreaterUI = 4,
LessOrEqualUI = 5,
GreaterOrEqual = 6,
Less = 7,
GreaterOrEqualUI = 8,
LessUI = 9
}
static class ComparisonExtensions
{
public static Comparison Invert(this Comparison comp)
{
return (Comparison)((int)comp ^ 1);
}
}
}

View File

@ -1,65 +0,0 @@
using System;
namespace ARMeilleure.IntermediateRepresentation
{
enum OperandType
{
None,
I32,
I64,
FP32,
FP64,
V128
}
static class OperandTypeExtensions
{
public static bool IsInteger(this OperandType type)
{
return type == OperandType.I32 ||
type == OperandType.I64;
}
public static RegisterType ToRegisterType(this OperandType type)
{
switch (type)
{
case OperandType.FP32: return RegisterType.Vector;
case OperandType.FP64: return RegisterType.Vector;
case OperandType.I32: return RegisterType.Integer;
case OperandType.I64: return RegisterType.Integer;
case OperandType.V128: return RegisterType.Vector;
}
throw new InvalidOperationException($"Invalid operand type \"{type}\".");
}
public static int GetSizeInBytes(this OperandType type)
{
switch (type)
{
case OperandType.FP32: return 4;
case OperandType.FP64: return 8;
case OperandType.I32: return 4;
case OperandType.I64: return 8;
case OperandType.V128: return 16;
}
throw new InvalidOperationException($"Invalid operand type \"{type}\".");
}
public static int GetSizeInBytesLog2(this OperandType type)
{
switch (type)
{
case OperandType.FP32: return 2;
case OperandType.FP64: return 3;
case OperandType.I32: return 2;
case OperandType.I64: return 3;
case OperandType.V128: return 4;
}
throw new InvalidOperationException($"Invalid operand type \"{type}\".");
}
}
}

View File

@ -1,15 +0,0 @@
namespace ARMeilleure.State
{
enum Aarch32Mode
{
User = 0b10000,
Fiq = 0b10001,
Irq = 0b10010,
Supervisor = 0b10011,
Monitor = 0b10110,
Abort = 0b10111,
Hypervisor = 0b11010,
Undefined = 0b11011,
System = 0b11111
}
}

View File

@ -1,12 +0,0 @@
namespace ARMeilleure.State
{
enum FPException
{
InvalidOp = 0,
DivideByZero = 1,
Overflow = 2,
Underflow = 3,
Inexact = 4,
InputDenorm = 7
}
}

View File

@ -1,11 +0,0 @@
namespace ARMeilleure.State
{
public enum FPRoundingMode
{
ToNearest = 0, // With ties to even.
TowardsPlusInfinity = 1,
TowardsMinusInfinity = 2,
TowardsZero = 3,
ToNearestAway = 4 // With ties to away.
}
}

View File

@ -1,15 +0,0 @@
namespace ARMeilleure.State
{
static class RegisterConsts
{
public const int IntRegsCount = 32;
public const int VecRegsCount = 32;
public const int FlagsCount = 32;
public const int FpFlagsCount = 32;
public const int IntAndVecRegsCount = IntRegsCount + VecRegsCount;
public const int FpFlagsOffset = IntRegsCount + VecRegsCount + FlagsCount;
public const int TotalCount = IntRegsCount + VecRegsCount + FlagsCount + FpFlagsCount;
public const int ZeroIndex = 31;
}
}

View File

@ -1,104 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
namespace ARMeilleure.Translation
{
static class DelegateHelper
{
private const string DelegateTypesAssemblyName = "JitDelegateTypes";
private static readonly ModuleBuilder _modBuilder;
private static readonly Dictionary<string, Type> _delegateTypesCache;
static DelegateHelper()
{
AssemblyBuilder asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(DelegateTypesAssemblyName), AssemblyBuilderAccess.Run);
_modBuilder = asmBuilder.DefineDynamicModule(DelegateTypesAssemblyName);
_delegateTypesCache = new Dictionary<string, Type>();
}
public static Delegate GetDelegate(MethodInfo info)
{
ArgumentNullException.ThrowIfNull(info);
Type[] parameters = info.GetParameters().Select(pI => pI.ParameterType).ToArray();
Type returnType = info.ReturnType;
Type delegateType = GetDelegateType(parameters, returnType);
return Delegate.CreateDelegate(delegateType, info);
}
private static Type GetDelegateType(Type[] parameters, Type returnType)
{
string key = GetFunctionSignatureKey(parameters, returnType);
if (!_delegateTypesCache.TryGetValue(key, out Type delegateType))
{
delegateType = MakeDelegateType(parameters, returnType, key);
_delegateTypesCache.TryAdd(key, delegateType);
}
return delegateType;
}
private static string GetFunctionSignatureKey(Type[] parameters, Type returnType)
{
string sig = GetTypeName(returnType);
foreach (Type type in parameters)
{
sig += '_' + GetTypeName(type);
}
return sig;
}
private static string GetTypeName(Type type)
{
return type.FullName.Replace(".", string.Empty);
}
private const MethodAttributes CtorAttributes =
MethodAttributes.RTSpecialName |
MethodAttributes.HideBySig |
MethodAttributes.Public;
private const TypeAttributes DelegateTypeAttributes =
TypeAttributes.Class |
TypeAttributes.Public |
TypeAttributes.Sealed |
TypeAttributes.AnsiClass |
TypeAttributes.AutoClass;
private const MethodImplAttributes ImplAttributes =
MethodImplAttributes.Runtime |
MethodImplAttributes.Managed;
private const MethodAttributes InvokeAttributes =
MethodAttributes.Public |
MethodAttributes.HideBySig |
MethodAttributes.NewSlot |
MethodAttributes.Virtual;
private static readonly Type[] _delegateCtorSignature = { typeof(object), typeof(IntPtr) };
private static Type MakeDelegateType(Type[] parameters, Type returnType, string name)
{
TypeBuilder builder = _modBuilder.DefineType(name, DelegateTypeAttributes, typeof(MulticastDelegate));
builder.DefineConstructor(CtorAttributes, CallingConventions.Standard, _delegateCtorSignature).SetImplementationFlags(ImplAttributes);
builder.DefineMethod("Invoke", InvokeAttributes, returnType, parameters).SetImplementationFlags(ImplAttributes);
return builder.CreateTypeInfo();
}
}
}

View File

@ -1,261 +0,0 @@
using ARMeilleure.Instructions;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace ARMeilleure.Translation
{
static class Delegates
{
public static bool TryGetDelegateFuncPtrByIndex(int index, out IntPtr funcPtr)
{
if (index >= 0 && index < _delegates.Count)
{
funcPtr = _delegates.Values[index].FuncPtr; // O(1).
return true;
}
else
{
funcPtr = default;
return false;
}
}
public static IntPtr GetDelegateFuncPtrByIndex(int index)
{
if (index < 0 || index >= _delegates.Count)
{
throw new ArgumentOutOfRangeException($"({nameof(index)} = {index})");
}
return _delegates.Values[index].FuncPtr; // O(1).
}
public static IntPtr GetDelegateFuncPtr(MethodInfo info)
{
ArgumentNullException.ThrowIfNull(info);
string key = GetKey(info);
if (!_delegates.TryGetValue(key, out DelegateInfo dlgInfo)) // O(log(n)).
{
throw new KeyNotFoundException($"({nameof(key)} = {key})");
}
return dlgInfo.FuncPtr;
}
public static int GetDelegateIndex(MethodInfo info)
{
ArgumentNullException.ThrowIfNull(info);
string key = GetKey(info);
int index = _delegates.IndexOfKey(key); // O(log(n)).
if (index == -1)
{
throw new KeyNotFoundException($"({nameof(key)} = {key})");
}
return index;
}
private static void SetDelegateInfo(MethodInfo info)
{
string key = GetKey(info);
Delegate dlg = DelegateHelper.GetDelegate(info);
_delegates.Add(key, new DelegateInfo(dlg)); // ArgumentException (key).
}
private static string GetKey(MethodInfo info)
{
return $"{info.DeclaringType.Name}.{info.Name}";
}
private static readonly SortedList<string, DelegateInfo> _delegates;
static Delegates()
{
_delegates = new SortedList<string, DelegateInfo>();
SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Abs), new Type[] { typeof(double) }));
SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Ceiling), new Type[] { typeof(double) }));
SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Floor), new Type[] { typeof(double) }));
SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Round), new Type[] { typeof(double), typeof(MidpointRounding) }));
SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Truncate), new Type[] { typeof(double) }));
SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Abs), new Type[] { typeof(float) }));
SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Ceiling), new Type[] { typeof(float) }));
SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Floor), new Type[] { typeof(float) }));
SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Round), new Type[] { typeof(float), typeof(MidpointRounding) }));
SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Truncate), new Type[] { typeof(float) }));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Break)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Undefined)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32b)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cb)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32ch)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cw)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cx)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32h)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32w)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32x)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.FixedRotate)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashChoose)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashMajority)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashParity)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.PolynomialMult64_128)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS64)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU64)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS32)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS64)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU32)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU64)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart1)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart2)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl4)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx1)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)));
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)));
SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAdd)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAddFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompare)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQ)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGE)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGEFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGT)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGTFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLE)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLEFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLT)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLTFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPDiv)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMax)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNum)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNumFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMin)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNum)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNumFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMul)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAdd)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAddFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSub)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSubFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulX)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulAdd)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulSub)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimate)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimateFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStep))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStepFused)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecpX)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimate)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimateFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStep))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStepFused)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSqrt)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSub)));
SetDelegateInfo(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAdd)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAddFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompare)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQ)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGE)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGEFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGT)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGTFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLE)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLEFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLT)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLTFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPDiv)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMax)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNum)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNumFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMin)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNum)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNumFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMul)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAdd)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAddFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSub)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSubFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulX)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulAdd)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulSub)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimate)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimateFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStep))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStepFused)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecpX)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimate)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimateFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStep))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStepFused)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSqrt)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSub)));
SetDelegateInfo(typeof(SoftFloat64_16).GetMethod(nameof(SoftFloat64_16.FPConvert)));
}
}
}

View File

@ -3,17 +3,17 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Avalonia" Version="0.10.19" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.19" />
<PackageVersion Include="Avalonia.Desktop" Version="0.10.19" />
<PackageVersion Include="Avalonia.Diagnostics" Version="0.10.19" />
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="0.10.19" />
<PackageVersion Include="Avalonia" Version="0.10.21" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.21" />
<PackageVersion Include="Avalonia.Desktop" Version="0.10.21" />
<PackageVersion Include="Avalonia.Diagnostics" Version="0.10.21" />
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="0.10.21" />
<PackageVersion Include="Avalonia.Svg" Version="0.10.18" />
<PackageVersion Include="Avalonia.Svg.Skia" Version="0.10.18" />
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="Concentus" Version="1.1.7" />
<PackageVersion Include="DiscordRichPresence" Version="1.1.3.18" />
<PackageVersion Include="DynamicData" Version="7.13.5" />
<PackageVersion Include="DynamicData" Version="7.14.2" />
<PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" />
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
@ -21,7 +21,7 @@
<PackageVersion Include="LibHac" Version="0.18.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
<PackageVersion Include="NUnit" Version="3.13.3" />
@ -44,9 +44,9 @@
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
<PackageVersion Include="SPB" Version="0.0.4-build28" />
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.29.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
<PackageVersion Include="System.Management" Version="7.0.1" />
<PackageVersion Include="System.Management" Version="7.0.2" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
</ItemGroup>

View File

@ -1,756 +0,0 @@
using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Dsp.Command;
using Ryujinx.Audio.Renderer.Parameter.Effect;
using System;
using System.Diagnostics;
using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
namespace Ryujinx.Audio.Renderer.Server
{
/// <summary>
/// <see cref="ICommandProcessingTimeEstimator"/> version 3. (added with REV8)
/// </summary>
public class CommandProcessingTimeEstimatorVersion3 : ICommandProcessingTimeEstimator
{
protected uint _sampleCount;
protected uint _bufferCount;
public CommandProcessingTimeEstimatorVersion3(uint sampleCount, uint bufferCount)
{
_sampleCount = sampleCount;
_bufferCount = bufferCount;
}
public uint Estimate(PerformanceCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
return (uint)498.17f;
}
return (uint)489.42f;
}
public uint Estimate(ClearMixBufferCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
float costPerBuffer = 440.68f;
float baseCost = 0;
if (_sampleCount == 160)
{
costPerBuffer = 266.65f;
}
return (uint)(baseCost + costPerBuffer * _bufferCount);
}
public uint Estimate(BiquadFilterCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
return (uint)4173.2f;
}
return (uint)5585.1f;
}
public uint Estimate(MixRampGroupedCommand command)
{
float costPerSample = 6.4434f;
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
costPerSample = 6.708f;
}
int volumeCount = 0;
for (int i = 0; i < command.MixBufferCount; i++)
{
if (command.Volume0[i] != 0.0f || command.Volume1[i] != 0.0f)
{
volumeCount++;
}
}
return (uint)(_sampleCount * costPerSample * volumeCount);
}
public uint Estimate(MixRampCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
return (uint)1968.7f;
}
return (uint)2459.4f;
}
public uint Estimate(DepopPrepareCommand command)
{
return 0;
}
public uint Estimate(VolumeRampCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
return (uint)1425.3f;
}
return (uint)1700.0f;
}
public uint Estimate(PcmInt16DataSourceCommandVersion1 command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
float costPerSample = 710.143f;
float baseCost = 7853.286f;
if (_sampleCount == 160)
{
costPerSample = 427.52f;
baseCost = 6329.442f;
}
return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f))));
}
public uint Estimate(AdpcmDataSourceCommandVersion1 command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
float costPerSample = 3564.1f;
float baseCost = 9736.702f;
if (_sampleCount == 160)
{
costPerSample = 2125.6f;
baseCost = 7913.808f;
}
return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f))));
}
public uint Estimate(DepopForMixBuffersCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
return (uint)739.64f;
}
return (uint)910.97f;
}
public uint Estimate(CopyMixBufferCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
return (uint)842.59f;
}
return (uint)986.72f;
}
public uint Estimate(MixCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
return (uint)1402.8f;
}
return (uint)1853.2f;
}
public virtual uint Estimate(DelayCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)8929.04f;
case 2:
return (uint)25500.75f;
case 4:
return (uint)47759.62f;
case 6:
return (uint)82203.07f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)1295.20f;
case 2:
return (uint)1213.60f;
case 4:
return (uint)942.03f;
case 6:
return (uint)1001.55f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)11941.05f;
case 2:
return (uint)37197.37f;
case 4:
return (uint)69749.84f;
case 6:
return (uint)120042.40f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)997.67f;
case 2:
return (uint)977.63f;
case 4:
return (uint)792.30f;
case 6:
return (uint)875.43f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
public virtual uint Estimate(ReverbCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)81475.05f;
case 2:
return (uint)84975.0f;
case 4:
return (uint)91625.15f;
case 6:
return (uint)95332.27f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)536.30f;
case 2:
return (uint)588.70f;
case 4:
return (uint)643.70f;
case 6:
return (uint)706.0f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)120174.47f;
case 2:
return (uint)25262.22f;
case 4:
return (uint)135751.23f;
case 6:
return (uint)141129.23f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)617.64f;
case 2:
return (uint)659.54f;
case 4:
return (uint)711.43f;
case 6:
return (uint)778.07f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
public virtual uint Estimate(Reverb3dCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)116754.0f;
case 2:
return (uint)125912.05f;
case 4:
return (uint)146336.03f;
case 6:
return (uint)165812.66f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)734.0f;
case 2:
return (uint)766.62f;
case 4:
return (uint)797.46f;
case 6:
return (uint)867.43f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)170292.34f;
case 2:
return (uint)183875.63f;
case 4:
return (uint)214696.19f;
case 6:
return (uint)243846.77f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)508.47f;
case 2:
return (uint)582.45f;
case 4:
return (uint)626.42f;
case 6:
return (uint)682.47f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
public uint Estimate(AuxiliaryBufferCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
if (command.Enabled)
{
return (uint)7182.14f;
}
return (uint)472.11f;
}
if (command.Enabled)
{
return (uint)9435.96f;
}
return (uint)462.62f;
}
public uint Estimate(VolumeCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
return (uint)1311.1f;
}
return (uint)1713.6f;
}
public uint Estimate(CircularBufferSinkCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
float costPerBuffer = 770.26f;
float baseCost = 0f;
if (_sampleCount == 160)
{
costPerBuffer = 531.07f;
}
return (uint)(baseCost + costPerBuffer * command.InputCount);
}
public uint Estimate(DownMixSurroundToStereoCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
return (uint)9949.7f;
}
return (uint)14679.0f;
}
public uint Estimate(UpsampleCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
return (uint)312990.0f;
}
return (uint)0.0f;
}
public uint Estimate(DeviceSinkCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
Debug.Assert(command.InputCount == 2 || command.InputCount == 6);
if (command.InputCount == 2)
{
if (_sampleCount == 160)
{
return (uint)8980.0f;
}
return (uint)9221.9f;
}
if (_sampleCount == 160)
{
return (uint)9177.9f;
}
return (uint)9725.9f;
}
public uint Estimate(PcmFloatDataSourceCommandVersion1 command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
float costPerSample = 3490.9f;
float baseCost = 10090.9f;
if (_sampleCount == 160)
{
costPerSample = 2310.4f;
baseCost = 7845.25f;
}
return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f))));
}
public uint Estimate(DataSourceVersion2Command command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
(float baseCost, float costPerSample) = GetCostByFormat(_sampleCount, command.SampleFormat, command.SrcQuality);
return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f) - 1.0f)));
}
private static (float, float) GetCostByFormat(uint sampleCount, SampleFormat format, SampleRateConversionQuality quality)
{
Debug.Assert(sampleCount == 160 || sampleCount == 240);
switch (format)
{
case SampleFormat.PcmInt16:
switch (quality)
{
case SampleRateConversionQuality.Default:
if (sampleCount == 160)
{
return (6329.44f, 427.52f);
}
return (7853.28f, 710.14f);
case SampleRateConversionQuality.High:
if (sampleCount == 160)
{
return (8049.42f, 371.88f);
}
return (10138.84f, 610.49f);
case SampleRateConversionQuality.Low:
if (sampleCount == 160)
{
return (5062.66f, 423.43f);
}
return (5810.96f, 676.72f);
default:
throw new NotImplementedException($"{format} {quality}");
}
case SampleFormat.PcmFloat:
switch (quality)
{
case SampleRateConversionQuality.Default:
if (sampleCount == 160)
{
return (7845.25f, 2310.4f);
}
return (10090.9f, 3490.9f);
case SampleRateConversionQuality.High:
if (sampleCount == 160)
{
return (9446.36f, 2308.91f);
}
return (12520.85f, 3480.61f);
case SampleRateConversionQuality.Low:
if (sampleCount == 160)
{
return (9446.36f, 2308.91f);
}
return (12520.85f, 3480.61f);
default:
throw new NotImplementedException($"{format} {quality}");
}
case SampleFormat.Adpcm:
switch (quality)
{
case SampleRateConversionQuality.Default:
if (sampleCount == 160)
{
return (7913.81f, 1827.66f);
}
return (9736.70f, 2756.37f);
case SampleRateConversionQuality.High:
if (sampleCount == 160)
{
return (9607.81f, 1829.29f);
}
return (12154.38f, 2731.31f);
case SampleRateConversionQuality.Low:
if (sampleCount == 160)
{
return (6517.48f, 1824.61f);
}
return (7929.44f, 2732.15f);
default:
throw new NotImplementedException($"{format} {quality}");
}
default:
throw new NotImplementedException($"{format}");
}
}
private uint EstimateLimiterCommandCommon(LimiterParameter parameter, bool enabled)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
if (enabled)
{
switch (parameter.ChannelCount)
{
case 1:
return (uint)21392.0f;
case 2:
return (uint)26829.0f;
case 4:
return (uint)32405.0f;
case 6:
return (uint)52219.0f;
default:
throw new NotImplementedException($"{parameter.ChannelCount}");
}
}
else
{
switch (parameter.ChannelCount)
{
case 1:
return (uint)897.0f;
case 2:
return (uint)931.55f;
case 4:
return (uint)975.39f;
case 6:
return (uint)1016.8f;
default:
throw new NotImplementedException($"{parameter.ChannelCount}");
}
}
}
if (enabled)
{
switch (parameter.ChannelCount)
{
case 1:
return (uint)30556.0f;
case 2:
return (uint)39011.0f;
case 4:
return (uint)48270.0f;
case 6:
return (uint)76712.0f;
default:
throw new NotImplementedException($"{parameter.ChannelCount}");
}
}
else
{
switch (parameter.ChannelCount)
{
case 1:
return (uint)874.43f;
case 2:
return (uint)921.55f;
case 4:
return (uint)945.26f;
case 6:
return (uint)992.26f;
default:
throw new NotImplementedException($"{parameter.ChannelCount}");
}
}
}
public uint Estimate(LimiterCommandVersion1 command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
return EstimateLimiterCommandCommon(command.Parameter, command.IsEffectEnabled);
}
public uint Estimate(LimiterCommandVersion2 command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (!command.Parameter.StatisticsEnabled || !command.IsEffectEnabled)
{
return EstimateLimiterCommandCommon(command.Parameter, command.IsEffectEnabled);
}
if (_sampleCount == 160)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)23309.0f;
case 2:
return (uint)29954.0f;
case 4:
return (uint)35807.0f;
case 6:
return (uint)58340.0f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)33526.0f;
case 2:
return (uint)43549.0f;
case 4:
return (uint)52190.0f;
case 6:
return (uint)85527.0f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
public virtual uint Estimate(GroupedBiquadFilterCommand command)
{
return 0;
}
public virtual uint Estimate(CaptureBufferCommand command)
{
return 0;
}
public virtual uint Estimate(CompressorCommand command)
{
return 0;
}
}
}

View File

@ -1,310 +0,0 @@
using Ryujinx.Audio.Renderer.Dsp.Command;
using System;
using System.Diagnostics;
namespace Ryujinx.Audio.Renderer.Server
{
/// <summary>
/// <see cref="ICommandProcessingTimeEstimator"/> version 5. (added with REV11)
/// </summary>
public class CommandProcessingTimeEstimatorVersion5 : CommandProcessingTimeEstimatorVersion4
{
public CommandProcessingTimeEstimatorVersion5(uint sampleCount, uint bufferCount) : base(sampleCount, bufferCount) { }
public override uint Estimate(DelayCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return 8929;
case 2:
return 25501;
case 4:
return 47760;
case 6:
return 82203;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)1295.20f;
case 2:
return (uint)1213.60f;
case 4:
return (uint)942.03f;
case 6:
return (uint)1001.6f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return 11941;
case 2:
return 37197;
case 4:
return 69750;
case 6:
return 12004;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)997.67f;
case 2:
return (uint)977.63f;
case 4:
return (uint)792.31f;
case 6:
return (uint)875.43f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
public override uint Estimate(ReverbCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return 81475;
case 2:
return 84975;
case 4:
return 91625;
case 6:
return 95332;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)536.30f;
case 2:
return (uint)588.80f;
case 4:
return (uint)643.70f;
case 6:
return (uint)706.0f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return 120170;
case 2:
return 125260;
case 4:
return 135750;
case 6:
return 141130;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)617.64f;
case 2:
return (uint)659.54f;
case 4:
return (uint)711.44f;
case 6:
return (uint)778.07f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
public override uint Estimate(Reverb3dCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return 116750;
case 2:
return 125910;
case 4:
return 146340;
case 6:
return 165810;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return 735;
case 2:
return (uint)766.62f;
case 4:
return (uint)834.07f;
case 6:
return (uint)875.44f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return 170290;
case 2:
return 183880;
case 4:
return 214700;
case 6:
return 243850;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)508.47f;
case 2:
return (uint)582.45f;
case 4:
return (uint)626.42f;
case 6:
return (uint)682.47f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
public override uint Estimate(CompressorCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
if (_sampleCount == 160)
{
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return 34431;
case 2:
return 44253;
case 4:
return 63827;
case 6:
return 83361;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)630.12f;
case 2:
return (uint)638.27f;
case 4:
return (uint)705.86f;
case 6:
return (uint)782.02f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
if (command.Enabled)
{
switch (command.Parameter.ChannelCount)
{
case 1:
return 51095;
case 2:
return 65693;
case 4:
return 95383;
case 6:
return 124510;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
else
{
switch (command.Parameter.ChannelCount)
{
case 1:
return (uint)840.14f;
case 2:
return (uint)826.1f;
case 4:
return (uint)901.88f;
case 6:
return (uint)965.29f;
default:
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
}
}
}
}
}

View File

@ -1,177 +0,0 @@
<UserControl
x:Class="Ryujinx.Ava.UI.Controls.GameGridView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d"
Focusable="True">
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
<MenuFlyout x:Key="GameContextMenu">
<MenuItem
Command="{Binding ToggleFavorite}"
Header="{locale:Locale GameListContextMenuToggleFavorite}"
ToolTip.Tip="{locale:Locale GameListContextMenuToggleFavoriteToolTip}" />
<Separator />
<MenuItem
Command="{Binding OpenUserSaveDirectory}"
IsEnabled="{Binding EnabledUserSaveDirectory}"
Header="{locale:Locale GameListContextMenuOpenUserSaveDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenDeviceSaveDirectory}"
IsEnabled="{Binding EnabledDeviceSaveDirectory}"
Header="{locale:Locale GameListContextMenuOpenDeviceSaveDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenDeviceSaveDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenBcatSaveDirectory}"
IsEnabled="{Binding EnabledBcatSaveDirectory}"
Header="{locale:Locale GameListContextMenuOpenBcatSaveDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenBcatSaveDirectoryToolTip}" />
<Separator />
<MenuItem
Command="{Binding OpenTitleUpdateManager}"
Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
<MenuItem
Command="{Binding OpenDownloadableContentManager}"
Header="{locale:Locale GameListContextMenuManageDlc}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
<MenuItem
Command="{Binding OpenCheatManager}"
Header="{locale:Locale GameListContextMenuManageCheat}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageCheatToolTip}" />
<MenuItem
Command="{Binding OpenModsDirectory}"
Header="{locale:Locale GameListContextMenuOpenModsDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenSdModsDirectory}"
Header="{locale:Locale GameListContextMenuOpenSdModsDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
<Separator />
<MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
<MenuItem
Command="{Binding PurgePtcCache}"
Header="{locale:Locale GameListContextMenuCacheManagementPurgePptc}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
<MenuItem
Command="{Binding PurgeShaderCache}"
Header="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
<MenuItem
Command="{Binding OpenPtcDirectory}"
Header="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenShaderCacheDirectory}"
Header="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
</MenuItem>
<MenuItem Header="{locale:Locale GameListContextMenuExtractData}">
<MenuItem
Command="{Binding ExtractExeFs}"
Header="{locale:Locale GameListContextMenuExtractDataExeFS}"
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataExeFSToolTip}" />
<MenuItem
Command="{Binding ExtractRomFs}"
Header="{locale:Locale GameListContextMenuExtractDataRomFS}"
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataRomFSToolTip}" />
<MenuItem
Command="{Binding ExtractLogo}"
Header="{locale:Locale GameListContextMenuExtractDataLogo}"
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataLogoToolTip}" />
</MenuItem>
</MenuFlyout>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox
Grid.Row="0"
Padding="8"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ContextFlyout="{StaticResource GameContextMenu}"
DoubleTapped="GameList_DoubleTapped"
Items="{Binding AppsObservableList}"
SelectionChanged="GameList_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<flex:FlexPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AlignContent="FlexStart"
JustifyContent="Center" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="Margin" Value="5" />
<Setter Property="CornerRadius" Value="4" />
</Style>
<Style Selector="ListBoxItem:selected /template/ Border#SelectionIndicator">
<Setter Property="MinHeight" Value="{Binding $parent[UserControl].DataContext.GridItemSelectorSize}" />
</Style>
</ListBox.Styles>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Border
Margin="10"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
ClipToBounds="True"
CornerRadius="4">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
Grid.Row="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
<Panel
Grid.Row="1"
Height="50"
Margin="0 10 0 0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsVisible="{Binding $parent[UserControl].DataContext.ShowNames}">
<TextBlock
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Text="{Binding TitleName}"
TextAlignment="Center"
TextWrapping="Wrap" />
</Panel>
</Grid>
</Border>
<ui:SymbolIcon
Margin="5,5,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="16"
Foreground="{DynamicResource SystemAccentColor}"
IsVisible="{Binding Favorite}"
Symbol="StarFilled" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>

View File

@ -1,363 +0,0 @@
using Avalonia.Media;
using DynamicData;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Ncm;
using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.UI.Models;
using Ryujinx.HLE.FileSystem;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Color = Avalonia.Media.Color;
namespace Ryujinx.Ava.UI.ViewModels
{
internal class AvatarProfileViewModel : BaseModel, IDisposable
{
private const int MaxImageTasks = 4;
private static readonly Dictionary<string, byte[]> _avatarStore = new();
private static bool _isPreloading;
private static Action _loadCompleteAction;
private ObservableCollection<ProfileImageModel> _images;
private Color _backgroundColor = Colors.White;
private int _selectedIndex;
private int _imagesLoaded;
private bool _isActive;
private byte[] _selectedImage;
private bool _isIndeterminate = true;
public bool IsActive
{
get => _isActive;
set => _isActive = value;
}
public AvatarProfileViewModel()
{
_images = new ObservableCollection<ProfileImageModel>();
}
public AvatarProfileViewModel(Action loadCompleteAction)
{
_images = new ObservableCollection<ProfileImageModel>();
if (_isPreloading)
{
_loadCompleteAction = loadCompleteAction;
}
else
{
ReloadImages();
}
}
public Color BackgroundColor
{
get => _backgroundColor;
set
{
_backgroundColor = value;
IsActive = false;
ReloadImages();
}
}
public ObservableCollection<ProfileImageModel> Images
{
get => _images;
set
{
_images = value;
OnPropertyChanged();
}
}
public bool IsIndeterminate
{
get => _isIndeterminate;
set
{
_isIndeterminate = value;
OnPropertyChanged();
}
}
public int ImageCount => _avatarStore.Count;
public int ImagesLoaded
{
get => _imagesLoaded;
set
{
_imagesLoaded = value;
OnPropertyChanged();
}
}
public int SelectedIndex
{
get => _selectedIndex;
set
{
_selectedIndex = value;
if (_selectedIndex == -1)
{
SelectedImage = null;
}
else
{
SelectedImage = _images[_selectedIndex].Data;
}
OnPropertyChanged();
}
}
public byte[] SelectedImage
{
get => _selectedImage;
private set => _selectedImage = value;
}
public void ReloadImages()
{
if (_isPreloading)
{
IsIndeterminate = false;
return;
}
Task.Run(() =>
{
IsActive = true;
Images.Clear();
int selectedIndex = _selectedIndex;
int index = 0;
ImagesLoaded = 0;
IsIndeterminate = false;
var keys = _avatarStore.Keys.ToList();
var newImages = new List<ProfileImageModel>();
var tasks = new List<Task>();
for (int i = 0; i < MaxImageTasks; i++)
{
var start = i;
tasks.Add(Task.Run(() => ImageTask(start)));
}
Task.WaitAll(tasks.ToArray());
Images.AddRange(newImages);
void ImageTask(int start)
{
for (int i = start; i < keys.Count; i += MaxImageTasks)
{
if (!IsActive)
{
return;
}
var key = keys[i];
var image = _avatarStore[keys[i]];
var data = ProcessImage(image);
newImages.Add(new ProfileImageModel(key, data));
if (index++ == selectedIndex)
{
SelectedImage = data;
}
Interlocked.Increment(ref _imagesLoaded);
OnPropertyChanged(nameof(ImagesLoaded));
}
}
});
}
private byte[] ProcessImage(byte[] data)
{
using (MemoryStream streamJpg = new())
{
Image avatarImage = Image.Load(data, new PngDecoder());
avatarImage.Mutate(x => x.BackgroundColor(new Rgba32(BackgroundColor.R,
BackgroundColor.G,
BackgroundColor.B,
BackgroundColor.A)));
avatarImage.SaveAsJpeg(streamJpg);
return streamJpg.ToArray();
}
}
public static void PreloadAvatars(ContentManager contentManager, VirtualFileSystem virtualFileSystem)
{
try
{
if (_avatarStore.Count > 0)
{
return;
}
_isPreloading = true;
string contentPath =
contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.BuiltInSystem,
NcaContentType.Data);
string avatarPath = virtualFileSystem.SwitchPathToSystemPath(contentPath);
if (!string.IsNullOrWhiteSpace(avatarPath))
{
using (IStorage ncaFileStream = new LocalStorage(avatarPath, FileAccess.Read, FileMode.Open))
{
Nca nca = new(virtualFileSystem.KeySet, ncaFileStream);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
foreach (DirectoryEntryEx item in romfs.EnumerateEntries())
{
// TODO: Parse DatabaseInfo.bin and table.bin files for more accuracy.
if (item.Type == DirectoryEntryType.File && item.FullPath.Contains("chara") &&
item.FullPath.Contains("szs"))
{
using var file = new UniqueRef<IFile>();
romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read)
.ThrowIfFailure();
using (MemoryStream stream = new())
using (MemoryStream streamPng = new())
{
file.Get.AsStream().CopyTo(stream);
stream.Position = 0;
Image avatarImage = Image.LoadPixelData<Rgba32>(DecompressYaz0(stream), 256, 256);
avatarImage.SaveAsPng(streamPng);
_avatarStore.Add(item.FullPath, streamPng.ToArray());
}
}
}
}
}
}
finally
{
_isPreloading = false;
_loadCompleteAction?.Invoke();
}
}
private static byte[] DecompressYaz0(Stream stream)
{
using (BinaryReader reader = new(stream))
{
reader.ReadInt32(); // Magic
uint decodedLength = BinaryPrimitives.ReverseEndianness(reader.ReadUInt32());
reader.ReadInt64(); // Padding
byte[] input = new byte[stream.Length - stream.Position];
stream.Read(input, 0, input.Length);
uint inputOffset = 0;
byte[] output = new byte[decodedLength];
uint outputOffset = 0;
ushort mask = 0;
byte header = 0;
while (outputOffset < decodedLength)
{
if ((mask >>= 1) == 0)
{
header = input[inputOffset++];
mask = 0x80;
}
if ((header & mask) != 0)
{
if (outputOffset == output.Length)
{
break;
}
output[outputOffset++] = input[inputOffset++];
}
else
{
byte byte1 = input[inputOffset++];
byte byte2 = input[inputOffset++];
uint dist = (uint)((byte1 & 0xF) << 8) | byte2;
uint position = outputOffset - (dist + 1);
uint length = (uint)byte1 >> 4;
if (length == 0)
{
length = (uint)input[inputOffset++] + 0x12;
}
else
{
length += 2;
}
uint gap = outputOffset - position;
uint nonOverlappingLength = length;
if (nonOverlappingLength > gap)
{
nonOverlappingLength = gap;
}
Buffer.BlockCopy(output, (int)position, output, (int)outputOffset, (int)nonOverlappingLength);
outputOffset += nonOverlappingLength;
position += nonOverlappingLength;
length -= nonOverlappingLength;
while (length-- > 0)
{
output[outputOffset++] = output[position++];
}
}
}
return output;
}
}
public void Dispose()
{
_loadCompleteAction = null;
IsActive = false;
}
}
}

View File

@ -1,230 +0,0 @@
using Avalonia.Media;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Ncm;
using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.UI.Models;
using Ryujinx.HLE.FileSystem;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using Color = Avalonia.Media.Color;
namespace Ryujinx.Ava.UI.ViewModels
{
internal class UserFirmwareAvatarSelectorViewModel : BaseModel
{
private static readonly Dictionary<string, byte[]> _avatarStore = new();
private ObservableCollection<ProfileImageModel> _images;
private Color _backgroundColor = Colors.White;
private int _selectedIndex;
private byte[] _selectedImage;
public UserFirmwareAvatarSelectorViewModel()
{
_images = new ObservableCollection<ProfileImageModel>();
LoadImagesFromStore();
}
public Color BackgroundColor
{
get => _backgroundColor;
set
{
_backgroundColor = value;
OnPropertyChanged();
ChangeImageBackground();
}
}
public ObservableCollection<ProfileImageModel> Images
{
get => _images;
set
{
_images = value;
OnPropertyChanged();
}
}
public int SelectedIndex
{
get => _selectedIndex;
set
{
_selectedIndex = value;
if (_selectedIndex == -1)
{
SelectedImage = null;
}
else
{
SelectedImage = _images[_selectedIndex].Data;
}
OnPropertyChanged();
}
}
public byte[] SelectedImage
{
get => _selectedImage;
private set => _selectedImage = value;
}
private void LoadImagesFromStore()
{
Images.Clear();
foreach (var image in _avatarStore)
{
Images.Add(new ProfileImageModel(image.Key, image.Value));
}
}
private void ChangeImageBackground()
{
foreach (var image in Images)
{
image.BackgroundColor = new SolidColorBrush(BackgroundColor);
}
}
public static void PreloadAvatars(ContentManager contentManager, VirtualFileSystem virtualFileSystem)
{
if (_avatarStore.Count > 0)
{
return;
}
string contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.BuiltInSystem, NcaContentType.Data);
string avatarPath = virtualFileSystem.SwitchPathToSystemPath(contentPath);
if (!string.IsNullOrWhiteSpace(avatarPath))
{
using (IStorage ncaFileStream = new LocalStorage(avatarPath, FileAccess.Read, FileMode.Open))
{
Nca nca = new(virtualFileSystem.KeySet, ncaFileStream);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
foreach (DirectoryEntryEx item in romfs.EnumerateEntries())
{
// TODO: Parse DatabaseInfo.bin and table.bin files for more accuracy.
if (item.Type == DirectoryEntryType.File && item.FullPath.Contains("chara") && item.FullPath.Contains("szs"))
{
using var file = new UniqueRef<IFile>();
romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read).ThrowIfFailure();
using (MemoryStream stream = new())
using (MemoryStream streamPng = new())
{
file.Get.AsStream().CopyTo(stream);
stream.Position = 0;
Image avatarImage = Image.LoadPixelData<Rgba32>(DecompressYaz0(stream), 256, 256);
avatarImage.SaveAsPng(streamPng);
_avatarStore.Add(item.FullPath, streamPng.ToArray());
}
}
}
}
}
}
private static byte[] DecompressYaz0(Stream stream)
{
using (BinaryReader reader = new(stream))
{
reader.ReadInt32(); // Magic
uint decodedLength = BinaryPrimitives.ReverseEndianness(reader.ReadUInt32());
reader.ReadInt64(); // Padding
byte[] input = new byte[stream.Length - stream.Position];
stream.Read(input, 0, input.Length);
uint inputOffset = 0;
byte[] output = new byte[decodedLength];
uint outputOffset = 0;
ushort mask = 0;
byte header = 0;
while (outputOffset < decodedLength)
{
if ((mask >>= 1) == 0)
{
header = input[inputOffset++];
mask = 0x80;
}
if ((header & mask) != 0)
{
if (outputOffset == output.Length)
{
break;
}
output[outputOffset++] = input[inputOffset++];
}
else
{
byte byte1 = input[inputOffset++];
byte byte2 = input[inputOffset++];
uint dist = (uint)((byte1 & 0xF) << 8) | byte2;
uint position = outputOffset - (dist + 1);
uint length = (uint)byte1 >> 4;
if (length == 0)
{
length = (uint)input[inputOffset++] + 0x12;
}
else
{
length += 2;
}
uint gap = outputOffset - position;
uint nonOverlappingLength = length;
if (nonOverlappingLength > gap)
{
nonOverlappingLength = gap;
}
Buffer.BlockCopy(output, (int)position, output, (int)outputOffset, (int)nonOverlappingLength);
outputOffset += nonOverlappingLength;
position += nonOverlappingLength;
length -= nonOverlappingLength;
while (length-- > 0)
{
output[outputOffset++] = output[position++];
}
}
}
return output;
}
}
}
}

View File

@ -1,46 +0,0 @@
<UserControl
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsInputView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d"
x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel">
<Design.DataContext>
<viewModels:SettingsViewModel />
</Design.DataContext>
<ScrollViewer
Name="InputPage"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<Border Classes="settings">
<StackPanel Margin="4" Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<CheckBox Margin="5,0"
ToolTip.Tip="{locale:Locale DockModeToggleTooltip}"
IsChecked="{Binding EnableDockedMode}">
<TextBlock VerticalAlignment="Center"
Text="{locale:Locale SettingsTabInputEnableDockedMode}" />
</CheckBox>
<CheckBox Margin="5,0"
ToolTip.Tip="{locale:Locale DirectKeyboardTooltip}"
IsChecked="{Binding EnableKeyboard}">
<TextBlock Text="{locale:Locale SettingsTabInputDirectKeyboardAccess}" />
</CheckBox>
<CheckBox Margin="5,0"
ToolTip.Tip="{locale:Locale DirectMouseTooltip}"
IsChecked="{Binding EnableMouse}">
<TextBlock Text="{locale:Locale SettingsTabInputDirectMouseAccess}" />
</CheckBox>
</StackPanel>
<window:ControllerSettingsWindow Name="ControllerSettings" Margin="0" MinHeight="600" />
</StackPanel>
</Border>
</ScrollViewer>
</UserControl>

View File

@ -1,71 +0,0 @@
using Avalonia.Controls;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Common.Configuration.Hid.Controller;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows
{
public partial class MotionSettingsWindow : UserControl
{
private readonly InputConfiguration<GamepadInputId, StickInputId> _viewmodel;
public MotionSettingsWindow()
{
InitializeComponent();
DataContext = _viewmodel;
}
public MotionSettingsWindow(ControllerSettingsViewModel viewmodel)
{
var config = viewmodel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
_viewmodel = new InputConfiguration<GamepadInputId, StickInputId>()
{
Slot = config.Slot,
AltSlot = config.AltSlot,
DsuServerHost = config.DsuServerHost,
DsuServerPort = config.DsuServerPort,
MirrorInput = config.MirrorInput,
EnableMotion = config.EnableMotion,
Sensitivity = config.Sensitivity,
GyroDeadzone = config.GyroDeadzone,
EnableCemuHookMotion = config.EnableCemuHookMotion
};
InitializeComponent();
DataContext = _viewmodel;
}
public static async Task Show(ControllerSettingsViewModel viewmodel)
{
MotionSettingsWindow content = new MotionSettingsWindow(viewmodel);
ContentDialog contentDialog = new ContentDialog
{
Title = LocaleManager.Instance[LocaleKeys.ControllerMotionTitle],
PrimaryButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsSave],
SecondaryButtonText = "",
CloseButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsClose],
Content = content
};
contentDialog.PrimaryButtonClick += (sender, args) =>
{
var config = viewmodel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
config.Slot = content._viewmodel.Slot;
config.EnableMotion = content._viewmodel.EnableMotion;
config.Sensitivity = content._viewmodel.Sensitivity;
config.GyroDeadzone = content._viewmodel.GyroDeadzone;
config.AltSlot = content._viewmodel.AltSlot;
config.DsuServerHost = content._viewmodel.DsuServerHost;
config.DsuServerPort = content._viewmodel.DsuServerPort;
config.EnableCemuHookMotion = content._viewmodel.EnableCemuHookMotion;
config.MirrorInput = content._viewmodel.MirrorInput;
};
await contentDialog.ShowAsync();
}
}
}

View File

@ -1,57 +0,0 @@
using Avalonia.Controls;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Common.Configuration.Hid.Controller;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows
{
public partial class RumbleSettingsWindow : UserControl
{
private readonly InputConfiguration<GamepadInputId, StickInputId> _viewmodel;
public RumbleSettingsWindow()
{
InitializeComponent();
DataContext = _viewmodel;
}
public RumbleSettingsWindow(ControllerSettingsViewModel viewmodel)
{
var config = viewmodel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
_viewmodel = new InputConfiguration<GamepadInputId, StickInputId>()
{
StrongRumble = config.StrongRumble, WeakRumble = config.WeakRumble
};
InitializeComponent();
DataContext = _viewmodel;
}
public static async Task Show(ControllerSettingsViewModel viewmodel)
{
RumbleSettingsWindow content = new RumbleSettingsWindow(viewmodel);
ContentDialog contentDialog = new ContentDialog
{
Title = LocaleManager.Instance[LocaleKeys.ControllerRumbleTitle],
PrimaryButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsSave],
SecondaryButtonText = "",
CloseButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsClose],
Content = content,
};
contentDialog.PrimaryButtonClick += (sender, args) =>
{
var config = viewmodel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
config.StrongRumble = content._viewmodel.StrongRumble;
config.WeakRumble = content._viewmodel.WeakRumble;
};
await contentDialog.ShowAsync();
}
}
}

View File

@ -1,15 +0,0 @@
namespace Ryujinx.Common.Configuration.Hid
{
public class GenericInputConfigurationCommon<Button> : InputConfig where Button : unmanaged
{
/// <summary>
/// Left JoyCon Controller Bindings
/// </summary>
public LeftJoyconCommonConfig<Button> LeftJoycon { get; set; }
/// <summary>
/// Right JoyCon Controller Bindings
/// </summary>
public RightJoyconCommonConfig<Button> RightJoycon { get; set; }
}
}

View File

@ -1,11 +0,0 @@
namespace Ryujinx.Common.Configuration.Hid.Keyboard
{
public class JoyconConfigKeyboardStick<Key> where Key: unmanaged
{
public Key StickUp { get; set; }
public Key StickDown { get; set; }
public Key StickLeft { get; set; }
public Key StickRight { get; set; }
public Key StickButton { get; set; }
}
}

View File

@ -1,15 +0,0 @@
namespace Ryujinx.Common.Configuration.Hid
{
public class LeftJoyconCommonConfig<Button>
{
public Button ButtonMinus { get; set; }
public Button ButtonL { get; set; }
public Button ButtonZl { get; set; }
public Button ButtonSl { get; set; }
public Button ButtonSr { get; set; }
public Button DpadUp { get; set; }
public Button DpadDown { get; set; }
public Button DpadLeft { get; set; }
public Button DpadRight { get; set; }
}
}

View File

@ -1,15 +0,0 @@
namespace Ryujinx.Common.Configuration.Hid
{
public class RightJoyconCommonConfig<Button>
{
public Button ButtonPlus { get; set; }
public Button ButtonR { get; set; }
public Button ButtonZr { get; set; }
public Button ButtonSl { get; set; }
public Button ButtonSr { get; set; }
public Button ButtonX { get; set; }
public Button ButtonB { get; set; }
public Button ButtonY { get; set; }
public Button ButtonA { get; set; }
}
}

View File

@ -1,31 +0,0 @@
using Microsoft.IO;
using Ryujinx.Common.Memory;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Common.Utilities
{
public static class StreamUtils
{
public static byte[] StreamToBytes(Stream input)
{
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream())
{
input.CopyTo(stream);
return stream.ToArray();
}
}
public static async Task<byte[]> StreamToBytesAsync(Stream input, CancellationToken cancellationToken = default)
{
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream())
{
await input.CopyToAsync(stream, cancellationToken);
return stream.ToArray();
}
}
}
}

View File

@ -1,320 +0,0 @@
using ARMeilleure.State;
using System;
using System.Runtime.InteropServices;
namespace Ryujinx.Cpu.AppleHv
{
struct hv_vcpu_exit_exception_t
{
#pragma warning disable CS0649
public ulong syndrome;
public ulong virtual_address;
public ulong physical_address;
#pragma warning restore CS0649
}
struct hv_vcpu_exit_t
{
#pragma warning disable CS0649
public uint reason;
public hv_vcpu_exit_exception_t exception;
#pragma warning restore CS0649
}
enum hv_reg_t : uint
{
HV_REG_X0,
HV_REG_X1,
HV_REG_X2,
HV_REG_X3,
HV_REG_X4,
HV_REG_X5,
HV_REG_X6,
HV_REG_X7,
HV_REG_X8,
HV_REG_X9,
HV_REG_X10,
HV_REG_X11,
HV_REG_X12,
HV_REG_X13,
HV_REG_X14,
HV_REG_X15,
HV_REG_X16,
HV_REG_X17,
HV_REG_X18,
HV_REG_X19,
HV_REG_X20,
HV_REG_X21,
HV_REG_X22,
HV_REG_X23,
HV_REG_X24,
HV_REG_X25,
HV_REG_X26,
HV_REG_X27,
HV_REG_X28,
HV_REG_X29,
HV_REG_FP = HV_REG_X29,
HV_REG_X30,
HV_REG_LR = HV_REG_X30,
HV_REG_PC,
HV_REG_FPCR,
HV_REG_FPSR,
HV_REG_CPSR,
}
enum hv_simd_fp_reg_t : uint
{
HV_SIMD_FP_REG_Q0,
HV_SIMD_FP_REG_Q1,
HV_SIMD_FP_REG_Q2,
HV_SIMD_FP_REG_Q3,
HV_SIMD_FP_REG_Q4,
HV_SIMD_FP_REG_Q5,
HV_SIMD_FP_REG_Q6,
HV_SIMD_FP_REG_Q7,
HV_SIMD_FP_REG_Q8,
HV_SIMD_FP_REG_Q9,
HV_SIMD_FP_REG_Q10,
HV_SIMD_FP_REG_Q11,
HV_SIMD_FP_REG_Q12,
HV_SIMD_FP_REG_Q13,
HV_SIMD_FP_REG_Q14,
HV_SIMD_FP_REG_Q15,
HV_SIMD_FP_REG_Q16,
HV_SIMD_FP_REG_Q17,
HV_SIMD_FP_REG_Q18,
HV_SIMD_FP_REG_Q19,
HV_SIMD_FP_REG_Q20,
HV_SIMD_FP_REG_Q21,
HV_SIMD_FP_REG_Q22,
HV_SIMD_FP_REG_Q23,
HV_SIMD_FP_REG_Q24,
HV_SIMD_FP_REG_Q25,
HV_SIMD_FP_REG_Q26,
HV_SIMD_FP_REG_Q27,
HV_SIMD_FP_REG_Q28,
HV_SIMD_FP_REG_Q29,
HV_SIMD_FP_REG_Q30,
HV_SIMD_FP_REG_Q31,
}
enum hv_sys_reg_t : ushort
{
HV_SYS_REG_DBGBVR0_EL1 = 0x8004,
HV_SYS_REG_DBGBCR0_EL1 = 0x8005,
HV_SYS_REG_DBGWVR0_EL1 = 0x8006,
HV_SYS_REG_DBGWCR0_EL1 = 0x8007,
HV_SYS_REG_DBGBVR1_EL1 = 0x800c,
HV_SYS_REG_DBGBCR1_EL1 = 0x800d,
HV_SYS_REG_DBGWVR1_EL1 = 0x800e,
HV_SYS_REG_DBGWCR1_EL1 = 0x800f,
HV_SYS_REG_MDCCINT_EL1 = 0x8010,
HV_SYS_REG_MDSCR_EL1 = 0x8012,
HV_SYS_REG_DBGBVR2_EL1 = 0x8014,
HV_SYS_REG_DBGBCR2_EL1 = 0x8015,
HV_SYS_REG_DBGWVR2_EL1 = 0x8016,
HV_SYS_REG_DBGWCR2_EL1 = 0x8017,
HV_SYS_REG_DBGBVR3_EL1 = 0x801c,
HV_SYS_REG_DBGBCR3_EL1 = 0x801d,
HV_SYS_REG_DBGWVR3_EL1 = 0x801e,
HV_SYS_REG_DBGWCR3_EL1 = 0x801f,
HV_SYS_REG_DBGBVR4_EL1 = 0x8024,
HV_SYS_REG_DBGBCR4_EL1 = 0x8025,
HV_SYS_REG_DBGWVR4_EL1 = 0x8026,
HV_SYS_REG_DBGWCR4_EL1 = 0x8027,
HV_SYS_REG_DBGBVR5_EL1 = 0x802c,
HV_SYS_REG_DBGBCR5_EL1 = 0x802d,
HV_SYS_REG_DBGWVR5_EL1 = 0x802e,
HV_SYS_REG_DBGWCR5_EL1 = 0x802f,
HV_SYS_REG_DBGBVR6_EL1 = 0x8034,
HV_SYS_REG_DBGBCR6_EL1 = 0x8035,
HV_SYS_REG_DBGWVR6_EL1 = 0x8036,
HV_SYS_REG_DBGWCR6_EL1 = 0x8037,
HV_SYS_REG_DBGBVR7_EL1 = 0x803c,
HV_SYS_REG_DBGBCR7_EL1 = 0x803d,
HV_SYS_REG_DBGWVR7_EL1 = 0x803e,
HV_SYS_REG_DBGWCR7_EL1 = 0x803f,
HV_SYS_REG_DBGBVR8_EL1 = 0x8044,
HV_SYS_REG_DBGBCR8_EL1 = 0x8045,
HV_SYS_REG_DBGWVR8_EL1 = 0x8046,
HV_SYS_REG_DBGWCR8_EL1 = 0x8047,
HV_SYS_REG_DBGBVR9_EL1 = 0x804c,
HV_SYS_REG_DBGBCR9_EL1 = 0x804d,
HV_SYS_REG_DBGWVR9_EL1 = 0x804e,
HV_SYS_REG_DBGWCR9_EL1 = 0x804f,
HV_SYS_REG_DBGBVR10_EL1 = 0x8054,
HV_SYS_REG_DBGBCR10_EL1 = 0x8055,
HV_SYS_REG_DBGWVR10_EL1 = 0x8056,
HV_SYS_REG_DBGWCR10_EL1 = 0x8057,
HV_SYS_REG_DBGBVR11_EL1 = 0x805c,
HV_SYS_REG_DBGBCR11_EL1 = 0x805d,
HV_SYS_REG_DBGWVR11_EL1 = 0x805e,
HV_SYS_REG_DBGWCR11_EL1 = 0x805f,
HV_SYS_REG_DBGBVR12_EL1 = 0x8064,
HV_SYS_REG_DBGBCR12_EL1 = 0x8065,
HV_SYS_REG_DBGWVR12_EL1 = 0x8066,
HV_SYS_REG_DBGWCR12_EL1 = 0x8067,
HV_SYS_REG_DBGBVR13_EL1 = 0x806c,
HV_SYS_REG_DBGBCR13_EL1 = 0x806d,
HV_SYS_REG_DBGWVR13_EL1 = 0x806e,
HV_SYS_REG_DBGWCR13_EL1 = 0x806f,
HV_SYS_REG_DBGBVR14_EL1 = 0x8074,
HV_SYS_REG_DBGBCR14_EL1 = 0x8075,
HV_SYS_REG_DBGWVR14_EL1 = 0x8076,
HV_SYS_REG_DBGWCR14_EL1 = 0x8077,
HV_SYS_REG_DBGBVR15_EL1 = 0x807c,
HV_SYS_REG_DBGBCR15_EL1 = 0x807d,
HV_SYS_REG_DBGWVR15_EL1 = 0x807e,
HV_SYS_REG_DBGWCR15_EL1 = 0x807f,
HV_SYS_REG_MIDR_EL1 = 0xc000,
HV_SYS_REG_MPIDR_EL1 = 0xc005,
HV_SYS_REG_ID_AA64PFR0_EL1 = 0xc020,
HV_SYS_REG_ID_AA64PFR1_EL1 = 0xc021,
HV_SYS_REG_ID_AA64DFR0_EL1 = 0xc028,
HV_SYS_REG_ID_AA64DFR1_EL1 = 0xc029,
HV_SYS_REG_ID_AA64ISAR0_EL1 = 0xc030,
HV_SYS_REG_ID_AA64ISAR1_EL1 = 0xc031,
HV_SYS_REG_ID_AA64MMFR0_EL1 = 0xc038,
HV_SYS_REG_ID_AA64MMFR1_EL1 = 0xc039,
HV_SYS_REG_ID_AA64MMFR2_EL1 = 0xc03a,
HV_SYS_REG_SCTLR_EL1 = 0xc080,
HV_SYS_REG_CPACR_EL1 = 0xc082,
HV_SYS_REG_TTBR0_EL1 = 0xc100,
HV_SYS_REG_TTBR1_EL1 = 0xc101,
HV_SYS_REG_TCR_EL1 = 0xc102,
HV_SYS_REG_APIAKEYLO_EL1 = 0xc108,
HV_SYS_REG_APIAKEYHI_EL1 = 0xc109,
HV_SYS_REG_APIBKEYLO_EL1 = 0xc10a,
HV_SYS_REG_APIBKEYHI_EL1 = 0xc10b,
HV_SYS_REG_APDAKEYLO_EL1 = 0xc110,
HV_SYS_REG_APDAKEYHI_EL1 = 0xc111,
HV_SYS_REG_APDBKEYLO_EL1 = 0xc112,
HV_SYS_REG_APDBKEYHI_EL1 = 0xc113,
HV_SYS_REG_APGAKEYLO_EL1 = 0xc118,
HV_SYS_REG_APGAKEYHI_EL1 = 0xc119,
HV_SYS_REG_SPSR_EL1 = 0xc200,
HV_SYS_REG_ELR_EL1 = 0xc201,
HV_SYS_REG_SP_EL0 = 0xc208,
HV_SYS_REG_AFSR0_EL1 = 0xc288,
HV_SYS_REG_AFSR1_EL1 = 0xc289,
HV_SYS_REG_ESR_EL1 = 0xc290,
HV_SYS_REG_FAR_EL1 = 0xc300,
HV_SYS_REG_PAR_EL1 = 0xc3a0,
HV_SYS_REG_MAIR_EL1 = 0xc510,
HV_SYS_REG_AMAIR_EL1 = 0xc518,
HV_SYS_REG_VBAR_EL1 = 0xc600,
HV_SYS_REG_CONTEXTIDR_EL1 = 0xc681,
HV_SYS_REG_TPIDR_EL1 = 0xc684,
HV_SYS_REG_CNTKCTL_EL1 = 0xc708,
HV_SYS_REG_CSSELR_EL1 = 0xd000,
HV_SYS_REG_TPIDR_EL0 = 0xde82,
HV_SYS_REG_TPIDRRO_EL0 = 0xde83,
HV_SYS_REG_CNTV_CTL_EL0 = 0xdf19,
HV_SYS_REG_CNTV_CVAL_EL0 = 0xdf1a,
HV_SYS_REG_SP_EL1 = 0xe208,
}
enum hv_memory_flags_t : ulong
{
HV_MEMORY_READ = 1UL << 0,
HV_MEMORY_WRITE = 1UL << 1,
HV_MEMORY_EXEC = 1UL << 2
}
enum hv_result_t : uint
{
HV_SUCCESS = 0,
HV_ERROR = 0xfae94001,
HV_BUSY = 0xfae94002,
HV_BAD_ARGUMENT = 0xfae94003,
HV_NO_RESOURCES = 0xfae94005,
HV_NO_DEVICE = 0xfae94006,
HV_DENIED = 0xfae94007,
HV_UNSUPPORTED = 0xfae9400f
}
enum hv_interrupt_type_t : uint
{
HV_INTERRUPT_TYPE_IRQ,
HV_INTERRUPT_TYPE_FIQ
}
struct hv_simd_fp_uchar16_t
{
public ulong Low;
public ulong High;
}
static class HvResultExtensions
{
public static void ThrowOnError(this hv_result_t result)
{
if (result != hv_result_t.HV_SUCCESS)
{
throw new Exception($"Unexpected result \"{result}\".");
}
}
}
static partial class HvApi
{
public const string LibraryName = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor";
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_get_max_vcpu_count(out uint max_vcpu_count);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_create(IntPtr config);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_destroy();
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_map(ulong addr, ulong ipa, ulong size, hv_memory_flags_t flags);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_unmap(ulong ipa, ulong size);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_protect(ulong ipa, ulong size, hv_memory_flags_t flags);
[LibraryImport(LibraryName, SetLastError = true)]
public unsafe static partial hv_result_t hv_vcpu_create(out ulong vcpu, ref hv_vcpu_exit_t* exit, IntPtr config);
[LibraryImport(LibraryName, SetLastError = true)]
public unsafe static partial hv_result_t hv_vcpu_destroy(ulong vcpu);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_run(ulong vcpu);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpus_exit(ref ulong vcpus, uint vcpu_count);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_reg(ulong vcpu, hv_reg_t reg, out ulong value);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_reg(ulong vcpu, hv_reg_t reg, ulong value);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, out hv_simd_fp_uchar16_t value);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, hv_simd_fp_uchar16_t value); // DO NOT USE DIRECTLY!
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_sys_reg(ulong vcpu, hv_sys_reg_t reg, out ulong value);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_sys_reg(ulong vcpu, hv_sys_reg_t reg, ulong value);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] out bool pending);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] bool pending);
}
}

View File

@ -1,28 +0,0 @@
using Ryujinx.Memory.Tracking;
using System;
using System.Collections.Generic;
namespace Ryujinx.Cpu.Tracking
{
public class CpuMultiRegionHandle : IMultiRegionHandle
{
private readonly MultiRegionHandle _impl;
public bool Dirty => _impl.Dirty;
internal CpuMultiRegionHandle(MultiRegionHandle impl)
{
_impl = impl;
}
public void Dispose() => _impl.Dispose();
public void ForceDirty(ulong address, ulong size) => _impl.ForceDirty(address, size);
public IEnumerable<IRegionHandle> GetHandles() => _impl.GetHandles();
public void QueryModified(Action<ulong, ulong> modifiedAction) => _impl.QueryModified(modifiedAction);
public void QueryModified(ulong address, ulong size, Action<ulong, ulong> modifiedAction) => _impl.QueryModified(address, size, modifiedAction);
public void QueryModified(ulong address, ulong size, Action<ulong, ulong> modifiedAction, int sequenceNumber) => _impl.QueryModified(address, size, modifiedAction, sequenceNumber);
public void RegisterAction(ulong address, ulong size, RegionSignal action) => _impl.RegisterAction(address, size, action);
public void RegisterPreciseAction(ulong address, ulong size, PreciseRegionSignal action) => _impl.RegisterPreciseAction(address, size, action);
public void SignalWrite() => _impl.SignalWrite();
}
}

View File

@ -1,37 +0,0 @@
using Ryujinx.Memory.Tracking;
using System;
namespace Ryujinx.Cpu.Tracking
{
public class CpuRegionHandle : IRegionHandle
{
private readonly RegionHandle _impl;
public bool Dirty => _impl.Dirty;
public bool Unmapped => _impl.Unmapped;
public ulong Address => _impl.Address;
public ulong Size => _impl.Size;
public ulong EndAddress => _impl.EndAddress;
internal CpuRegionHandle(RegionHandle impl)
{
_impl = impl;
}
public void Dispose() => _impl.Dispose();
public bool DirtyOrVolatile() => _impl.DirtyOrVolatile();
public void ForceDirty() => _impl.ForceDirty();
public IRegionHandle GetHandle() => _impl;
public void RegisterAction(RegionSignal action) => _impl.RegisterAction(action);
public void RegisterPreciseAction(PreciseRegionSignal action) => _impl.RegisterPreciseAction(action);
public void RegisterDirtyEvent(Action action) => _impl.RegisterDirtyEvent(action);
public void Reprotect(bool asDirty = false) => _impl.Reprotect(asDirty);
public bool OverlapsWith(ulong address, ulong size) => _impl.OverlapsWith(address, size);
public bool RangeEquals(CpuRegionHandle other)
{
return _impl.RealAddress == other._impl.RealAddress && _impl.RealSize == other._impl.RealSize;
}
}
}

View File

@ -1,26 +0,0 @@
using Ryujinx.Memory.Tracking;
using System;
namespace Ryujinx.Cpu.Tracking
{
public class CpuSmartMultiRegionHandle : IMultiRegionHandle
{
private readonly SmartMultiRegionHandle _impl;
public bool Dirty => _impl.Dirty;
internal CpuSmartMultiRegionHandle(SmartMultiRegionHandle impl)
{
_impl = impl;
}
public void Dispose() => _impl.Dispose();
public void ForceDirty(ulong address, ulong size) => _impl.ForceDirty(address, size);
public void RegisterAction(RegionSignal action) => _impl.RegisterAction(action);
public void RegisterPreciseAction(PreciseRegionSignal action) => _impl.RegisterPreciseAction(action);
public void QueryModified(Action<ulong, ulong> modifiedAction) => _impl.QueryModified(modifiedAction);
public void QueryModified(ulong address, ulong size, Action<ulong, ulong> modifiedAction) => _impl.QueryModified(address, size, modifiedAction);
public void QueryModified(ulong address, ulong size, Action<ulong, ulong> modifiedAction, int sequenceNumber) => _impl.QueryModified(address, size, modifiedAction, sequenceNumber);
public void SignalWrite() => _impl.SignalWrite();
}
}

View File

@ -1,17 +0,0 @@
namespace Ryujinx.Graphics.GAL
{
public enum BlendOp
{
Add = 1,
Subtract,
ReverseSubtract,
Minimum,
Maximum,
AddGl = 0x8006,
MinimumGl = 0x8007,
MaximumGl = 0x8008,
SubtractGl = 0x800a,
ReverseSubtractGl = 0x800b
}
}

View File

@ -1,9 +0,0 @@
namespace Ryujinx.Graphics.GAL
{
public enum Face
{
Front = 0x404,
Back = 0x405,
FrontAndBack = 0x408
}
}

View File

@ -1,37 +0,0 @@
namespace Ryujinx.Graphics.GAL
{
public readonly struct ImageCrop
{
public int Left { get; }
public int Right { get; }
public int Top { get; }
public int Bottom { get; }
public bool FlipX { get; }
public bool FlipY { get; }
public bool IsStretched { get; }
public float AspectRatioX { get; }
public float AspectRatioY { get; }
public ImageCrop(
int left,
int right,
int top,
int bottom,
bool flipX,
bool flipY,
bool isStretched,
float aspectRatioX,
float aspectRatioY)
{
Left = left;
Right = right;
Top = top;
Bottom = bottom;
FlipX = flipX;
FlipY = flipY;
IsStretched = isStretched;
AspectRatioX = aspectRatioX;
AspectRatioY = aspectRatioY;
}
}
}

View File

@ -1,22 +0,0 @@
namespace Ryujinx.Graphics.GAL
{
public readonly struct ScreenCaptureImageInfo
{
public ScreenCaptureImageInfo(int width, int height, bool isBgra, byte[] data, bool flipX, bool flipY)
{
Width = width;
Height = height;
IsBgra = isBgra;
Data = data;
FlipX = flipX;
FlipY = flipY;
}
public int Width { get; }
public int Height { get; }
public byte[] Data { get; }
public bool IsBgra { get; }
public bool FlipX { get; }
public bool FlipY { get; }
}
}

View File

@ -1,24 +0,0 @@
using System.Collections.Generic;
namespace Ryujinx.Graphics.GAL
{
public readonly struct ShaderBindings
{
public IReadOnlyCollection<int> UniformBufferBindings { get; }
public IReadOnlyCollection<int> StorageBufferBindings { get; }
public IReadOnlyCollection<int> TextureBindings { get; }
public IReadOnlyCollection<int> ImageBindings { get; }
public ShaderBindings(
IReadOnlyCollection<int> uniformBufferBindings,
IReadOnlyCollection<int> storageBufferBindings,
IReadOnlyCollection<int> textureBindings,
IReadOnlyCollection<int> imageBindings)
{
UniformBufferBindings = uniformBufferBindings;
StorageBufferBindings = storageBufferBindings;
TextureBindings = textureBindings;
ImageBindings = imageBindings;
}
}
}

View File

@ -1,56 +0,0 @@
namespace Ryujinx.Graphics.GAL
{
public readonly struct StencilTestDescriptor
{
public bool TestEnable { get; }
public CompareOp FrontFunc { get; }
public StencilOp FrontSFail { get; }
public StencilOp FrontDpPass { get; }
public StencilOp FrontDpFail { get; }
public int FrontFuncRef { get; }
public int FrontFuncMask { get; }
public int FrontMask { get; }
public CompareOp BackFunc { get; }
public StencilOp BackSFail { get; }
public StencilOp BackDpPass { get; }
public StencilOp BackDpFail { get; }
public int BackFuncRef { get; }
public int BackFuncMask { get; }
public int BackMask { get; }
public StencilTestDescriptor(
bool testEnable,
CompareOp frontFunc,
StencilOp frontSFail,
StencilOp frontDpPass,
StencilOp frontDpFail,
int frontFuncRef,
int frontFuncMask,
int frontMask,
CompareOp backFunc,
StencilOp backSFail,
StencilOp backDpPass,
StencilOp backDpFail,
int backFuncRef,
int backFuncMask,
int backMask)
{
TestEnable = testEnable;
FrontFunc = frontFunc;
FrontSFail = frontSFail;
FrontDpPass = frontDpPass;
FrontDpFail = frontDpFail;
FrontFuncRef = frontFuncRef;
FrontFuncMask = frontFuncMask;
FrontMask = frontMask;
BackFunc = backFunc;
BackSFail = backSFail;
BackDpPass = backDpPass;
BackDpFail = backDpFail;
BackFuncRef = backFuncRef;
BackFuncMask = backFuncMask;
BackMask = backMask;
}
}
}

View File

@ -1,275 +0,0 @@
using Ryujinx.Graphics.Gpu.Engine.Types;
using System;
using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.Gpu.Engine.Compute
{
/// <summary>
/// Type of the dependent Queue Meta Data.
/// </summary>
enum DependentQmdType
{
Queue,
Grid
}
/// <summary>
/// Type of the release memory barrier.
/// </summary>
enum ReleaseMembarType
{
FeNone,
FeSysmembar
}
/// <summary>
/// Type of the CWD memory barrier.
/// </summary>
enum CwdMembarType
{
L1None,
L1Sysmembar,
L1Membar
}
/// <summary>
/// NaN behavior of 32-bits float operations on the shader.
/// </summary>
enum Fp32NanBehavior
{
Legacy,
Fp64Compatible
}
/// <summary>
/// NaN behavior of 32-bits float to integer conversion on the shader.
/// </summary>
enum Fp32F2iNanBehavior
{
PassZero,
PassIndefinite
}
/// <summary>
/// Limit of calls.
/// </summary>
enum ApiVisibleCallLimit
{
_32,
NoCheck
}
/// <summary>
/// Shared memory bank mapping mode.
/// </summary>
enum SharedMemoryBankMapping
{
FourBytesPerBank,
EightBytesPerBank
}
/// <summary>
/// Denormal behavior of 32-bits float narrowing instructions.
/// </summary>
enum Fp32NarrowInstruction
{
KeepDenorms,
FlushDenorms
}
/// <summary>
/// Configuration of the L1 cache.
/// </summary>
enum L1Configuration
{
DirectlyAddressableMemorySize16kb,
DirectlyAddressableMemorySize32kb,
DirectlyAddressableMemorySize48kb
}
/// <summary>
/// Reduction operation.
/// </summary>
enum ReductionOp
{
RedAdd,
RedMin,
RedMax,
RedInc,
RedDec,
RedAnd,
RedOr,
RedXor
}
/// <summary>
/// Reduction format.
/// </summary>
enum ReductionFormat
{
Unsigned32,
Signed32
}
/// <summary>
/// Size of a structure in words.
/// </summary>
enum StructureSize
{
FourWords,
OneWord
}
/// <summary>
/// Compute Queue Meta Data.
/// </summary>
unsafe struct ComputeQmd
{
private fixed int _words[64];
public int OuterPut => BitRange(30, 0);
public bool OuterOverflow => Bit(31);
public int OuterGet => BitRange(62, 32);
public bool OuterStickyOverflow => Bit(63);
public int InnerGet => BitRange(94, 64);
public bool InnerOverflow => Bit(95);
public int InnerPut => BitRange(126, 96);
public bool InnerStickyOverflow => Bit(127);
public int QmdReservedAA => BitRange(159, 128);
public int DependentQmdPointer => BitRange(191, 160);
public int QmdGroupId => BitRange(197, 192);
public bool SmGlobalCachingEnable => Bit(198);
public bool RunCtaInOneSmPartition => Bit(199);
public bool IsQueue => Bit(200);
public bool AddToHeadOfQmdGroupLinkedList => Bit(201);
public bool SemaphoreReleaseEnable0 => Bit(202);
public bool SemaphoreReleaseEnable1 => Bit(203);
public bool RequireSchedulingPcas => Bit(204);
public bool DependentQmdScheduleEnable => Bit(205);
public DependentQmdType DependentQmdType => (DependentQmdType)BitRange(206, 206);
public bool DependentQmdFieldCopy => Bit(207);
public int QmdReservedB => BitRange(223, 208);
public int CircularQueueSize => BitRange(248, 224);
public bool QmdReservedC => Bit(249);
public bool InvalidateTextureHeaderCache => Bit(250);
public bool InvalidateTextureSamplerCache => Bit(251);
public bool InvalidateTextureDataCache => Bit(252);
public bool InvalidateShaderDataCache => Bit(253);
public bool InvalidateInstructionCache => Bit(254);
public bool InvalidateShaderConstantCache => Bit(255);
public int ProgramOffset => BitRange(287, 256);
public int CircularQueueAddrLower => BitRange(319, 288);
public int CircularQueueAddrUpper => BitRange(327, 320);
public int QmdReservedD => BitRange(335, 328);
public int CircularQueueEntrySize => BitRange(351, 336);
public int CwdReferenceCountId => BitRange(357, 352);
public int CwdReferenceCountDeltaMinusOne => BitRange(365, 358);
public ReleaseMembarType ReleaseMembarType => (ReleaseMembarType)BitRange(366, 366);
public bool CwdReferenceCountIncrEnable => Bit(367);
public CwdMembarType CwdMembarType => (CwdMembarType)BitRange(369, 368);
public bool SequentiallyRunCtas => Bit(370);
public bool CwdReferenceCountDecrEnable => Bit(371);
public bool Throttled => Bit(372);
public Fp32NanBehavior Fp32NanBehavior => (Fp32NanBehavior)BitRange(376, 376);
public Fp32F2iNanBehavior Fp32F2iNanBehavior => (Fp32F2iNanBehavior)BitRange(377, 377);
public ApiVisibleCallLimit ApiVisibleCallLimit => (ApiVisibleCallLimit)BitRange(378, 378);
public SharedMemoryBankMapping SharedMemoryBankMapping => (SharedMemoryBankMapping)BitRange(379, 379);
public SamplerIndex SamplerIndex => (SamplerIndex)BitRange(382, 382);
public Fp32NarrowInstruction Fp32NarrowInstruction => (Fp32NarrowInstruction)BitRange(383, 383);
public int CtaRasterWidth => BitRange(415, 384);
public int CtaRasterHeight => BitRange(431, 416);
public int CtaRasterDepth => BitRange(447, 432);
public int CtaRasterWidthResume => BitRange(479, 448);
public int CtaRasterHeightResume => BitRange(495, 480);
public int CtaRasterDepthResume => BitRange(511, 496);
public int QueueEntriesPerCtaMinusOne => BitRange(518, 512);
public int CoalesceWaitingPeriod => BitRange(529, 522);
public int SharedMemorySize => BitRange(561, 544);
public int QmdReservedG => BitRange(575, 562);
public int QmdVersion => BitRange(579, 576);
public int QmdMajorVersion => BitRange(583, 580);
public int QmdReservedH => BitRange(591, 584);
public int CtaThreadDimension0 => BitRange(607, 592);
public int CtaThreadDimension1 => BitRange(623, 608);
public int CtaThreadDimension2 => BitRange(639, 624);
public bool ConstantBufferValid(int i) => Bit(640 + i * 1);
public int QmdReservedI => BitRange(668, 648);
public L1Configuration L1Configuration => (L1Configuration)BitRange(671, 669);
public int SmDisableMaskLower => BitRange(703, 672);
public int SmDisableMaskUpper => BitRange(735, 704);
public int Release0AddressLower => BitRange(767, 736);
public int Release0AddressUpper => BitRange(775, 768);
public int QmdReservedJ => BitRange(783, 776);
public ReductionOp Release0ReductionOp => (ReductionOp)BitRange(790, 788);
public bool QmdReservedK => Bit(791);
public ReductionFormat Release0ReductionFormat => (ReductionFormat)BitRange(793, 792);
public bool Release0ReductionEnable => Bit(794);
public StructureSize Release0StructureSize => (StructureSize)BitRange(799, 799);
public int Release0Payload => BitRange(831, 800);
public int Release1AddressLower => BitRange(863, 832);
public int Release1AddressUpper => BitRange(871, 864);
public int QmdReservedL => BitRange(879, 872);
public ReductionOp Release1ReductionOp => (ReductionOp)BitRange(886, 884);
public bool QmdReservedM => Bit(887);
public ReductionFormat Release1ReductionFormat => (ReductionFormat)BitRange(889, 888);
public bool Release1ReductionEnable => Bit(890);
public StructureSize Release1StructureSize => (StructureSize)BitRange(895, 895);
public int Release1Payload => BitRange(927, 896);
public int ConstantBufferAddrLower(int i) => BitRange(959 + i * 64, 928 + i * 64);
public int ConstantBufferAddrUpper(int i) => BitRange(967 + i * 64, 960 + i * 64);
public int ConstantBufferReservedAddr(int i) => BitRange(973 + i * 64, 968 + i * 64);
public bool ConstantBufferInvalidate(int i) => Bit(974 + i * 64);
public int ConstantBufferSize(int i) => BitRange(991 + i * 64, 975 + i * 64);
public int ShaderLocalMemoryLowSize => BitRange(1463, 1440);
public int QmdReservedN => BitRange(1466, 1464);
public int BarrierCount => BitRange(1471, 1467);
public int ShaderLocalMemoryHighSize => BitRange(1495, 1472);
public int RegisterCount => BitRange(1503, 1496);
public int ShaderLocalMemoryCrsSize => BitRange(1527, 1504);
public int SassVersion => BitRange(1535, 1528);
public int HwOnlyInnerGet => BitRange(1566, 1536);
public bool HwOnlyRequireSchedulingPcas => Bit(1567);
public int HwOnlyInnerPut => BitRange(1598, 1568);
public bool HwOnlyScgType => Bit(1599);
public int HwOnlySpanListHeadIndex => BitRange(1629, 1600);
public bool QmdReservedQ => Bit(1630);
public bool HwOnlySpanListHeadIndexValid => Bit(1631);
public int HwOnlySkedNextQmdPointer => BitRange(1663, 1632);
public int QmdSpareE => BitRange(1695, 1664);
public int QmdSpareF => BitRange(1727, 1696);
public int QmdSpareG => BitRange(1759, 1728);
public int QmdSpareH => BitRange(1791, 1760);
public int QmdSpareI => BitRange(1823, 1792);
public int QmdSpareJ => BitRange(1855, 1824);
public int QmdSpareK => BitRange(1887, 1856);
public int QmdSpareL => BitRange(1919, 1888);
public int QmdSpareM => BitRange(1951, 1920);
public int QmdSpareN => BitRange(1983, 1952);
public int DebugIdUpper => BitRange(2015, 1984);
public int DebugIdLower => BitRange(2047, 2016);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool Bit(int bit)
{
if ((uint)bit >= 64 * 32)
{
throw new ArgumentOutOfRangeException(nameof(bit));
}
return (_words[bit >> 5] & (1 << (bit & 31))) != 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int BitRange(int upper, int lower)
{
if ((uint)lower >= 64 * 32)
{
throw new ArgumentOutOfRangeException(nameof(lower));
}
int mask = (int)(uint.MaxValue >> (32 - (upper - lower + 1)));
return (_words[lower >> 5] >> (lower & 31)) & mask;
}
}
}

View File

@ -1,41 +0,0 @@
// This file was auto-generated from NVIDIA official Maxwell definitions.
namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
{
enum TertOp
{
Grp0IncMethod = 0,
Grp0SetSubDevMask = 1,
Grp0StoreSubDevMask = 2,
Grp0UseSubDevMask = 3,
Grp2NonIncMethod = 0
}
enum SecOp
{
Grp0UseTert = 0,
IncMethod = 1,
Grp2UseTert = 2,
NonIncMethod = 3,
ImmdDataMethod = 4,
OneInc = 5,
Reserved6 = 6,
EndPbSegment = 7
}
struct CompressedMethod
{
#pragma warning disable CS0649
public uint Method;
#pragma warning restore CS0649
public int MethodAddressOld => (int)((Method >> 2) & 0x7FF);
public int MethodAddress => (int)((Method >> 0) & 0xFFF);
public int SubdeviceMask => (int)((Method >> 4) & 0xFFF);
public int MethodSubchannel => (int)((Method >> 13) & 0x7);
public TertOp TertOp => (TertOp)((Method >> 16) & 0x3);
public int MethodCountOld => (int)((Method >> 18) & 0x7FF);
public int MethodCount => (int)((Method >> 16) & 0x1FFF);
public int ImmdData => (int)((Method >> 16) & 0x1FFF);
public SecOp SecOp => (SecOp)((Method >> 29) & 0x7);
}
}

View File

@ -1,55 +0,0 @@
// This file was auto-generated from NVIDIA official Maxwell definitions.
namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
{
enum Entry0Fetch
{
Unconditional = 0,
Conditional = 1,
}
enum Entry1Priv
{
User = 0,
Kernel = 1,
}
enum Entry1Level
{
Main = 0,
Subroutine = 1,
}
enum Entry1Sync
{
Proceed = 0,
Wait = 1,
}
enum Entry1Opcode
{
Nop = 0,
Illegal = 1,
Crc = 2,
PbCrc = 3,
}
struct GPEntry
{
#pragma warning disable CS0649
public uint Entry0;
#pragma warning restore CS0649
public Entry0Fetch Entry0Fetch => (Entry0Fetch)((Entry0 >> 0) & 0x1);
public int Entry0Get => (int)((Entry0 >> 2) & 0x3FFFFFFF);
public int Entry0Operand => (int)(Entry0);
#pragma warning disable CS0649
public uint Entry1;
#pragma warning restore CS0649
public int Entry1GetHi => (int)((Entry1 >> 0) & 0xFF);
public Entry1Priv Entry1Priv => (Entry1Priv)((Entry1 >> 8) & 0x1);
public Entry1Level Entry1Level => (Entry1Level)((Entry1 >> 9) & 0x1);
public int Entry1Length => (int)((Entry1 >> 10) & 0x1FFFFF);
public Entry1Sync Entry1Sync => (Entry1Sync)((Entry1 >> 31) & 0x1);
public Entry1Opcode Entry1Opcode => (Entry1Opcode)((Entry1 >> 0) & 0xFF);
}
}

View File

@ -1,14 +0,0 @@
namespace Ryujinx.Graphics.Gpu.Memory
{
public class UnmapEventArgs
{
public ulong Address { get; }
public ulong Size { get; }
public UnmapEventArgs(ulong address, ulong size)
{
Address = address;
Size = size;
}
}
}

View File

@ -1,21 +0,0 @@
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
{
internal enum PredictionMode
{
DcPred = 0, // Average of above and left pixels
VPred = 1, // Vertical
HPred = 2, // Horizontal
D45Pred = 3, // Directional 45 deg = round(arctan(1 / 1) * 180 / pi)
D135Pred = 4, // Directional 135 deg = 180 - 45
D117Pred = 5, // Directional 117 deg = 180 - 63
D153Pred = 6, // Directional 153 deg = 180 - 27
D207Pred = 7, // Directional 207 deg = 180 + 27
D63Pred = 8, // Directional 63 deg = round(arctan(2 / 1) * 180 / pi)
TmPred = 9, // True-motion
NearestMv = 10,
NearMv = 11,
ZeroMv = 12,
NewMv = 13,
MbModeCount = 14
}
}

View File

@ -1,11 +0,0 @@
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
{
internal enum SegLvlFeatures
{
SegLvlAltQ = 0, // Use alternate Quantizer ....
SegLvlAltLf = 1, // Use alternate loop filter value...
SegLvlRefFrame = 2, // Optional Segment reference frame
SegLvlSkip = 3, // Optional Segment (0,0) + skip mode
SegLvlMax = 4 // Number of features supported
}
}

View File

@ -1,12 +0,0 @@
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
{
public enum TxMode
{
Only4X4 = 0, // Only 4x4 transform used
Allow8X8 = 1, // Allow block transform size up to 8x8
Allow16X16 = 2, // Allow block transform size up to 16x16
Allow32X32 = 3, // Allow block transform size up to 32x32
TxModeSelect = 4, // Transform specified for each block
TxModes = 5
}
}

View File

@ -1,11 +0,0 @@
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
{
internal enum TxType
{
DctDct = 0, // DCT in both horizontal and vertical
AdstDct = 1, // ADST in vertical, DCT in horizontal
DctAdst = 2, // DCT in vertical, ADST in horizontal
AdstAdst = 3, // ADST in both directions
TxTypes = 4
}
}

View File

@ -1,45 +0,0 @@
using OpenTK.Graphics.OpenGL;
namespace Ryujinx.Graphics.OpenGL
{
readonly struct FormatInfo
{
public int Components { get; }
public bool Normalized { get; }
public bool Scaled { get; }
public PixelInternalFormat PixelInternalFormat { get; }
public PixelFormat PixelFormat { get; }
public PixelType PixelType { get; }
public bool IsCompressed { get; }
public FormatInfo(
int components,
bool normalized,
bool scaled,
All pixelInternalFormat,
PixelFormat pixelFormat,
PixelType pixelType)
{
Components = components;
Normalized = normalized;
Scaled = scaled;
PixelInternalFormat = (PixelInternalFormat)pixelInternalFormat;
PixelFormat = pixelFormat;
PixelType = pixelType;
IsCompressed = false;
}
public FormatInfo(int components, bool normalized, bool scaled, All pixelFormat)
{
Components = components;
Normalized = normalized;
Scaled = scaled;
PixelInternalFormat = 0;
PixelFormat = (PixelFormat)pixelFormat;
PixelType = 0;
IsCompressed = true;
}
}
}

View File

@ -1,142 +0,0 @@
using OpenTK.Graphics.OpenGL;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class HwCapabilities
{
private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new Lazy<bool>(() => HasExtension("GL_NV_alpha_to_coverage_dither_control"));
private static readonly Lazy<bool> _supportsAstcCompression = new Lazy<bool>(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
private static readonly Lazy<bool> _supportsBlendEquationAdvanced = new Lazy<bool>(() => HasExtension("GL_NV_blend_equation_advanced"));
private static readonly Lazy<bool> _supportsDrawTexture = new Lazy<bool>(() => HasExtension("GL_NV_draw_texture"));
private static readonly Lazy<bool> _supportsFragmentShaderInterlock = new Lazy<bool>(() => HasExtension("GL_ARB_fragment_shader_interlock"));
private static readonly Lazy<bool> _supportsFragmentShaderOrdering = new Lazy<bool>(() => HasExtension("GL_INTEL_fragment_shader_ordering"));
private static readonly Lazy<bool> _supportsGeometryShaderPassthrough = new Lazy<bool>(() => HasExtension("GL_NV_geometry_shader_passthrough"));
private static readonly Lazy<bool> _supportsImageLoadFormatted = new Lazy<bool>(() => HasExtension("GL_EXT_shader_image_load_formatted"));
private static readonly Lazy<bool> _supportsIndirectParameters = new Lazy<bool>(() => HasExtension("GL_ARB_indirect_parameters"));
private static readonly Lazy<bool> _supportsParallelShaderCompile = new Lazy<bool>(() => HasExtension("GL_ARB_parallel_shader_compile"));
private static readonly Lazy<bool> _supportsPolygonOffsetClamp = new Lazy<bool>(() => HasExtension("GL_EXT_polygon_offset_clamp"));
private static readonly Lazy<bool> _supportsQuads = new Lazy<bool>(SupportsQuadsCheck);
private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new Lazy<bool>(() => HasExtension("GL_ARB_seamless_cubemap_per_texture"));
private static readonly Lazy<bool> _supportsShaderBallot = new Lazy<bool>(() => HasExtension("GL_ARB_shader_ballot"));
private static readonly Lazy<bool> _supportsShaderViewportLayerArray = new Lazy<bool>(() => HasExtension("GL_ARB_shader_viewport_layer_array"));
private static readonly Lazy<bool> _supportsViewportArray2 = new Lazy<bool>(() => HasExtension("GL_NV_viewport_array2"));
private static readonly Lazy<bool> _supportsTextureCompressionBptc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_bptc"));
private static readonly Lazy<bool> _supportsTextureCompressionRgtc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_rgtc"));
private static readonly Lazy<bool> _supportsTextureCompressionS3tc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_s3tc"));
private static readonly Lazy<bool> _supportsTextureShadowLod = new Lazy<bool>(() => HasExtension("GL_EXT_texture_shadow_lod"));
private static readonly Lazy<bool> _supportsViewportSwizzle = new Lazy<bool>(() => HasExtension("GL_NV_viewport_swizzle"));
private static readonly Lazy<int> _maximumComputeSharedMemorySize = new Lazy<int>(() => GetLimit(All.MaxComputeSharedMemorySize));
private static readonly Lazy<int> _storageBufferOffsetAlignment = new Lazy<int>(() => GetLimit(All.ShaderStorageBufferOffsetAlignment));
public enum GpuVendor
{
Unknown,
AmdWindows,
AmdUnix,
IntelWindows,
IntelUnix,
Nvidia
}
private static readonly Lazy<GpuVendor> _gpuVendor = new Lazy<GpuVendor>(GetGpuVendor);
private static bool _isAMD => _gpuVendor.Value == GpuVendor.AmdWindows || _gpuVendor.Value == GpuVendor.AmdUnix;
private static bool _isIntel => _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix;
public static GpuVendor Vendor => _gpuVendor.Value;
private static Lazy<float> _maxSupportedAnisotropy = new Lazy<float>(GL.GetFloat((GetPName)All.MaxTextureMaxAnisotropy));
public static bool UsePersistentBufferForFlush => _gpuVendor.Value == GpuVendor.AmdWindows || _gpuVendor.Value == GpuVendor.Nvidia;
public static bool SupportsAlphaToCoverageDitherControl => _supportsAlphaToCoverageDitherControl.Value;
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
public static bool SupportsBlendEquationAdvanced => _supportsBlendEquationAdvanced.Value;
public static bool SupportsDrawTexture => _supportsDrawTexture.Value;
public static bool SupportsFragmentShaderInterlock => _supportsFragmentShaderInterlock.Value;
public static bool SupportsFragmentShaderOrdering => _supportsFragmentShaderOrdering.Value;
public static bool SupportsGeometryShaderPassthrough => _supportsGeometryShaderPassthrough.Value;
public static bool SupportsImageLoadFormatted => _supportsImageLoadFormatted.Value;
public static bool SupportsIndirectParameters => _supportsIndirectParameters.Value;
public static bool SupportsParallelShaderCompile => _supportsParallelShaderCompile.Value;
public static bool SupportsPolygonOffsetClamp => _supportsPolygonOffsetClamp.Value;
public static bool SupportsQuads => _supportsQuads.Value;
public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value;
public static bool SupportsShaderBallot => _supportsShaderBallot.Value;
public static bool SupportsShaderViewportLayerArray => _supportsShaderViewportLayerArray.Value;
public static bool SupportsViewportArray2 => _supportsViewportArray2.Value;
public static bool SupportsTextureCompressionBptc => _supportsTextureCompressionBptc.Value;
public static bool SupportsTextureCompressionRgtc => _supportsTextureCompressionRgtc.Value;
public static bool SupportsTextureCompressionS3tc => _supportsTextureCompressionS3tc.Value;
public static bool SupportsTextureShadowLod => _supportsTextureShadowLod.Value;
public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value;
public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.AmdWindows && _gpuVendor.Value != GpuVendor.IntelWindows;
public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia;
public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.AmdWindows || _isIntel;
public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value;
public static float MaximumSupportedAnisotropy => _maxSupportedAnisotropy.Value;
private static bool HasExtension(string name)
{
int numExtensions = GL.GetInteger(GetPName.NumExtensions);
for (int extension = 0; extension < numExtensions; extension++)
{
if (GL.GetString(StringNameIndexed.Extensions, extension) == name)
{
return true;
}
}
return false;
}
private static int GetLimit(All name)
{
return GL.GetInteger((GetPName)name);
}
private static GpuVendor GetGpuVendor()
{
string vendor = GL.GetString(StringName.Vendor).ToLower();
if (vendor == "nvidia corporation")
{
return GpuVendor.Nvidia;
}
else if (vendor == "intel")
{
string renderer = GL.GetString(StringName.Renderer).ToLower();
return renderer.Contains("mesa") ? GpuVendor.IntelUnix : GpuVendor.IntelWindows;
}
else if (vendor == "ati technologies inc." || vendor == "advanced micro devices, inc.")
{
return GpuVendor.AmdWindows;
}
else if (vendor == "amd" || vendor == "x.org")
{
return GpuVendor.AmdUnix;
}
else
{
return GpuVendor.Unknown;
}
}
private static bool SupportsQuadsCheck()
{
GL.GetError(); // Clear any existing error.
GL.Begin(PrimitiveType.Quads);
GL.End();
return GL.GetError() == ErrorCode.NoError;
}
}
}

View File

@ -1,26 +0,0 @@
namespace Ryujinx.Graphics.Shader
{
public struct BufferDescriptor
{
// New fields should be added to the end of the struct to keep disk shader cache compatibility.
public readonly int Binding;
public readonly int Slot;
public BufferUsageFlags Flags;
public BufferDescriptor(int binding, int slot)
{
Binding = binding;
Slot = slot;
Flags = BufferUsageFlags.None;
}
public BufferDescriptor SetFlag(BufferUsageFlags flag)
{
Flags |= flag;
return this;
}
}
}

View File

@ -1,37 +0,0 @@
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
static class DefaultNames
{
public const string LocalNamePrefix = "temp";
public const string SamplerNamePrefix = "tex";
public const string ImageNamePrefix = "img";
public const string PerPatchAttributePrefix = "patch_attr_";
public const string IAttributePrefix = "in_attr";
public const string OAttributePrefix = "out_attr";
public const string StorageNamePrefix = "s";
public const string DataName = "data";
public const string SupportBlockName = "support_block";
public const string SupportBlockAlphaTestName = "s_alpha_test";
public const string SupportBlockIsBgraName = "s_is_bgra";
public const string SupportBlockViewportInverse = "s_viewport_inverse";
public const string SupportBlockFragmentScaleCount = "s_frag_scale_count";
public const string SupportBlockRenderScaleName = "s_render_scale";
public const string BlockSuffix = "block";
public const string UniformNamePrefix = "c";
public const string UniformNameSuffix = "data";
public const string LocalMemoryName = "local_mem";
public const string SharedMemoryName = "shared_mem";
public const string ArgumentNamePrefix = "a";
public const string UndefinedName = "undef";
}
}

View File

@ -1,21 +0,0 @@
int Helper_AtomicMaxS32(int offset, int value)
{
uint oldValue, newValue;
do
{
oldValue = $SHARED_MEM$[offset];
newValue = uint(max(int(oldValue), value));
} while (atomicCompSwap($SHARED_MEM$[offset], oldValue, newValue) != oldValue);
return int(oldValue);
}
int Helper_AtomicMinS32(int offset, int value)
{
uint oldValue, newValue;
do
{
oldValue = $SHARED_MEM$[offset];
newValue = uint(min(int(oldValue), value));
} while (atomicCompSwap($SHARED_MEM$[offset], oldValue, newValue) != oldValue);
return int(oldValue);
}

View File

@ -1,21 +0,0 @@
int Helper_AtomicMaxS32(int index, int offset, int value)
{
uint oldValue, newValue;
do
{
oldValue = $STORAGE_MEM$[index].data[offset];
newValue = uint(max(int(oldValue), value));
} while (atomicCompSwap($STORAGE_MEM$[index].data[offset], oldValue, newValue) != oldValue);
return int(oldValue);
}
int Helper_AtomicMinS32(int index, int offset, int value)
{
uint oldValue, newValue;
do
{
oldValue = $STORAGE_MEM$[index].data[offset];
newValue = uint(min(int(oldValue), value));
} while (atomicCompSwap($STORAGE_MEM$[index].data[offset], oldValue, newValue) != oldValue);
return int(oldValue);
}

View File

@ -1,22 +0,0 @@
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
static class HelperFunctionNames
{
public static string AtomicMaxS32 = "Helper_AtomicMaxS32";
public static string AtomicMinS32 = "Helper_AtomicMinS32";
public static string MultiplyHighS32 = "Helper_MultiplyHighS32";
public static string MultiplyHighU32 = "Helper_MultiplyHighU32";
public static string Shuffle = "Helper_Shuffle";
public static string ShuffleDown = "Helper_ShuffleDown";
public static string ShuffleUp = "Helper_ShuffleUp";
public static string ShuffleXor = "Helper_ShuffleXor";
public static string SwizzleAdd = "Helper_SwizzleAdd";
public static string StoreShared16 = "Helper_StoreShared16";
public static string StoreShared8 = "Helper_StoreShared8";
public static string StoreStorage16 = "Helper_StoreStorage16";
public static string StoreStorage8 = "Helper_StoreStorage8";
}
}

View File

@ -1,23 +0,0 @@
void Helper_StoreShared16(int offset, uint value)
{
int wordOffset = offset >> 2;
int bitOffset = (offset & 3) * 8;
uint oldValue, newValue;
do
{
oldValue = $SHARED_MEM$[wordOffset];
newValue = bitfieldInsert(oldValue, value, bitOffset, 16);
} while (atomicCompSwap($SHARED_MEM$[wordOffset], oldValue, newValue) != oldValue);
}
void Helper_StoreShared8(int offset, uint value)
{
int wordOffset = offset >> 2;
int bitOffset = (offset & 3) * 8;
uint oldValue, newValue;
do
{
oldValue = $SHARED_MEM$[wordOffset];
newValue = bitfieldInsert(oldValue, value, bitOffset, 8);
} while (atomicCompSwap($SHARED_MEM$[wordOffset], oldValue, newValue) != oldValue);
}

View File

@ -1,23 +0,0 @@
void Helper_StoreStorage16(int index, int offset, uint value)
{
int wordOffset = offset >> 2;
int bitOffset = (offset & 3) * 8;
uint oldValue, newValue;
do
{
oldValue = $STORAGE_MEM$[index].data[wordOffset];
newValue = bitfieldInsert(oldValue, value, bitOffset, 16);
} while (atomicCompSwap($STORAGE_MEM$[index].data[wordOffset], oldValue, newValue) != oldValue);
}
void Helper_StoreStorage8(int index, int offset, uint value)
{
int wordOffset = offset >> 2;
int bitOffset = (offset & 3) * 8;
uint oldValue, newValue;
do
{
oldValue = $STORAGE_MEM$[index].data[wordOffset];
newValue = bitfieldInsert(oldValue, value, bitOffset, 8);
} while (atomicCompSwap($STORAGE_MEM$[index].data[wordOffset], oldValue, newValue) != oldValue);
}

View File

@ -1,19 +0,0 @@
ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
{
float scale = s_render_scale[samplerIndex];
if (scale == 1.0)
{
return inputVec;
}
return ivec2(vec2(inputVec) * scale);
}
int Helper_TextureSizeUnscale(int size, int samplerIndex)
{
float scale = s_render_scale[samplerIndex];
if (scale == 1.0)
{
return size;
}
return int(float(size) / scale);
}

View File

@ -1,26 +0,0 @@
ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
{
float scale = s_render_scale[1 + samplerIndex];
if (scale == 1.0)
{
return inputVec;
}
if (scale < 0.0) // If less than 0, try interpolate between texels by using the screen position.
{
return ivec2(vec2(inputVec) * (-scale) + mod(gl_FragCoord.xy, 0.0 - scale));
}
else
{
return ivec2(vec2(inputVec) * scale);
}
}
int Helper_TextureSizeUnscale(int size, int samplerIndex)
{
float scale = abs(s_render_scale[1 + samplerIndex]);
if (scale == 1.0)
{
return size;
}
return int(float(size) / scale);
}

View File

@ -1,20 +0,0 @@
ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
{
float scale = abs(s_render_scale[1 + samplerIndex + s_frag_scale_count]);
if (scale == 1.0)
{
return inputVec;
}
return ivec2(vec2(inputVec) * scale);
}
int Helper_TextureSizeUnscale(int size, int samplerIndex)
{
float scale = abs(s_render_scale[1 + samplerIndex + s_frag_scale_count]);
if (scale == 1.0)
{
return size;
}
return int(float(size) / scale);
}

View File

@ -1,33 +0,0 @@
using System;
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
{
[Flags]
enum InstType
{
OpNullary = Op | 0,
OpUnary = Op | 1,
OpBinary = Op | 2,
OpBinaryCom = Op | 2 | Commutative,
OpTernary = Op | 3,
CallNullary = Call | 0,
CallUnary = Call | 1,
CallBinary = Call | 2,
CallTernary = Call | 3,
CallQuaternary = Call | 4,
// The atomic instructions have one extra operand,
// for the storage slot and offset pair.
AtomicBinary = Call | Atomic | 3,
AtomicTernary = Call | Atomic | 4,
Commutative = 1 << 8,
Op = 1 << 9,
Call = 1 << 10,
Atomic = 1 << 11,
Special = 1 << 12,
ArityMask = 0xff
}
}

View File

@ -1,227 +0,0 @@
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using Ryujinx.Graphics.Shader.StructuredIr;
using Ryujinx.Graphics.Shader.Translation;
using static Spv.Specification;
namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
using SpvInstruction = Spv.Generator.Instruction;
static class ScalingHelpers
{
public static SpvInstruction ApplyScaling(
CodeGenContext context,
AstTextureOperation texOp,
SpvInstruction vector,
bool intCoords,
bool isBindless,
bool isIndexed,
bool isArray,
int pCount)
{
if (intCoords)
{
if (context.Config.Stage.SupportsRenderScale() &&
!isBindless &&
!isIndexed)
{
int index = texOp.Inst == Instruction.ImageLoad
? context.Config.GetTextureDescriptors().Length + context.Config.FindImageDescriptorIndex(texOp)
: context.Config.FindTextureDescriptorIndex(texOp);
if (pCount == 3 && isArray)
{
return ApplyScaling2DArray(context, vector, index);
}
else if (pCount == 2 && !isArray)
{
return ApplyScaling2D(context, vector, index);
}
}
}
return vector;
}
private static SpvInstruction ApplyScaling2DArray(CodeGenContext context, SpvInstruction vector, int index)
{
// The array index is not scaled, just x and y.
var vectorXY = context.VectorShuffle(context.TypeVector(context.TypeS32(), 2), vector, vector, 0, 1);
var vectorZ = context.CompositeExtract(context.TypeS32(), vector, 2);
var vectorXYScaled = ApplyScaling2D(context, vectorXY, index);
var vectorScaled = context.CompositeConstruct(context.TypeVector(context.TypeS32(), 3), vectorXYScaled, vectorZ);
return vectorScaled;
}
private static SpvInstruction ApplyScaling2D(CodeGenContext context, SpvInstruction vector, int index)
{
var pointerType = context.TypePointer(StorageClass.Uniform, context.TypeFP32());
var fieldIndex = context.Constant(context.TypeU32(), 4);
var scaleIndex = context.Constant(context.TypeU32(), index);
if (context.Config.Stage == ShaderStage.Vertex)
{
var scaleCountPointerType = context.TypePointer(StorageClass.Uniform, context.TypeS32());
var scaleCountElemPointer = context.AccessChain(scaleCountPointerType, context.SupportBuffer, context.Constant(context.TypeU32(), 3));
var scaleCount = context.Load(context.TypeS32(), scaleCountElemPointer);
scaleIndex = context.IAdd(context.TypeU32(), scaleIndex, scaleCount);
}
scaleIndex = context.IAdd(context.TypeU32(), scaleIndex, context.Constant(context.TypeU32(), 1));
var scaleElemPointer = context.AccessChain(pointerType, context.SupportBuffer, fieldIndex, scaleIndex);
var scale = context.Load(context.TypeFP32(), scaleElemPointer);
var ivector2Type = context.TypeVector(context.TypeS32(), 2);
var localVector = context.CoordTemp;
var passthrough = context.FOrdEqual(context.TypeBool(), scale, context.Constant(context.TypeFP32(), 1f));
var mergeLabel = context.Label();
if (context.Config.Stage == ShaderStage.Fragment)
{
var scaledInterpolatedLabel = context.Label();
var scaledNoInterpolationLabel = context.Label();
var needsInterpolation = context.FOrdLessThan(context.TypeBool(), scale, context.Constant(context.TypeFP32(), 0f));
context.SelectionMerge(mergeLabel, SelectionControlMask.MaskNone);
context.BranchConditional(needsInterpolation, scaledInterpolatedLabel, scaledNoInterpolationLabel);
// scale < 0.0
context.AddLabel(scaledInterpolatedLabel);
ApplyScalingInterpolated(context, localVector, vector, scale);
context.Branch(mergeLabel);
// scale >= 0.0
context.AddLabel(scaledNoInterpolationLabel);
ApplyScalingNoInterpolation(context, localVector, vector, scale);
context.Branch(mergeLabel);
context.AddLabel(mergeLabel);
var passthroughLabel = context.Label();
var finalMergeLabel = context.Label();
context.SelectionMerge(finalMergeLabel, SelectionControlMask.MaskNone);
context.BranchConditional(passthrough, passthroughLabel, finalMergeLabel);
context.AddLabel(passthroughLabel);
context.Store(localVector, vector);
context.Branch(finalMergeLabel);
context.AddLabel(finalMergeLabel);
return context.Load(ivector2Type, localVector);
}
else
{
var passthroughLabel = context.Label();
var scaledLabel = context.Label();
context.SelectionMerge(mergeLabel, SelectionControlMask.MaskNone);
context.BranchConditional(passthrough, passthroughLabel, scaledLabel);
// scale == 1.0
context.AddLabel(passthroughLabel);
context.Store(localVector, vector);
context.Branch(mergeLabel);
// scale != 1.0
context.AddLabel(scaledLabel);
ApplyScalingNoInterpolation(context, localVector, vector, scale);
context.Branch(mergeLabel);
context.AddLabel(mergeLabel);
return context.Load(ivector2Type, localVector);
}
}
private static void ApplyScalingInterpolated(CodeGenContext context, SpvInstruction output, SpvInstruction vector, SpvInstruction scale)
{
var vector2Type = context.TypeVector(context.TypeFP32(), 2);
var scaleNegated = context.FNegate(context.TypeFP32(), scale);
var scaleVector = context.CompositeConstruct(vector2Type, scaleNegated, scaleNegated);
var vectorFloat = context.ConvertSToF(vector2Type, vector);
var vectorScaled = context.VectorTimesScalar(vector2Type, vectorFloat, scaleNegated);
var fragCoordPointer = context.Inputs[new IoDefinition(StorageKind.Input, IoVariable.FragmentCoord)];
var fragCoord = context.Load(context.TypeVector(context.TypeFP32(), 4), fragCoordPointer);
var fragCoordXY = context.VectorShuffle(vector2Type, fragCoord, fragCoord, 0, 1);
var scaleMod = context.FMod(vector2Type, fragCoordXY, scaleVector);
var vectorInterpolated = context.FAdd(vector2Type, vectorScaled, scaleMod);
context.Store(output, context.ConvertFToS(context.TypeVector(context.TypeS32(), 2), vectorInterpolated));
}
private static void ApplyScalingNoInterpolation(CodeGenContext context, SpvInstruction output, SpvInstruction vector, SpvInstruction scale)
{
if (context.Config.Stage == ShaderStage.Vertex)
{
scale = context.GlslFAbs(context.TypeFP32(), scale);
}
var vector2Type = context.TypeVector(context.TypeFP32(), 2);
var vectorFloat = context.ConvertSToF(vector2Type, vector);
var vectorScaled = context.VectorTimesScalar(vector2Type, vectorFloat, scale);
context.Store(output, context.ConvertFToS(context.TypeVector(context.TypeS32(), 2), vectorScaled));
}
public static SpvInstruction ApplyUnscaling(
CodeGenContext context,
AstTextureOperation texOp,
SpvInstruction size,
bool isBindless,
bool isIndexed)
{
if (context.Config.Stage.SupportsRenderScale() &&
!isBindless &&
!isIndexed)
{
int index = context.Config.FindTextureDescriptorIndex(texOp);
var pointerType = context.TypePointer(StorageClass.Uniform, context.TypeFP32());
var fieldIndex = context.Constant(context.TypeU32(), 4);
var scaleIndex = context.Constant(context.TypeU32(), index);
if (context.Config.Stage == ShaderStage.Vertex)
{
var scaleCountPointerType = context.TypePointer(StorageClass.Uniform, context.TypeS32());
var scaleCountElemPointer = context.AccessChain(scaleCountPointerType, context.SupportBuffer, context.Constant(context.TypeU32(), 3));
var scaleCount = context.Load(context.TypeS32(), scaleCountElemPointer);
scaleIndex = context.IAdd(context.TypeU32(), scaleIndex, scaleCount);
}
scaleIndex = context.IAdd(context.TypeU32(), scaleIndex, context.Constant(context.TypeU32(), 1));
var scaleElemPointer = context.AccessChain(pointerType, context.SupportBuffer, fieldIndex, scaleIndex);
var scale = context.GlslFAbs(context.TypeFP32(), context.Load(context.TypeFP32(), scaleElemPointer));
var passthrough = context.FOrdEqual(context.TypeBool(), scale, context.Constant(context.TypeFP32(), 1f));
var sizeFloat = context.ConvertSToF(context.TypeFP32(), size);
var sizeUnscaled = context.FDiv(context.TypeFP32(), sizeFloat, scale);
var sizeUnscaledInt = context.ConvertFToS(context.TypeS32(), sizeUnscaled);
return context.Select(context.TypeS32(), passthrough, size, sizeUnscaledInt);
}
return size;
}
}
}

View File

@ -1,4 +0,0 @@
namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
readonly record struct TextureMeta(int CbufSlot, int Handle, TextureFormat Format);
}

View File

@ -1,54 +0,0 @@
using Ryujinx.Graphics.Shader.Decoders;
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using Ryujinx.Graphics.Shader.Translation;
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
namespace Ryujinx.Graphics.Shader.Instructions
{
static partial class InstEmit
{
public static void Pset(EmitterContext context)
{
InstPset op = context.GetOp<InstPset>();
Operand srcA = context.BitwiseNot(Register(op.Src2Pred, RegisterType.Predicate), op.Src2PredInv);
Operand srcB = context.BitwiseNot(Register(op.Src1Pred, RegisterType.Predicate), op.Src1PredInv);
Operand srcC = context.BitwiseNot(Register(op.SrcPred, RegisterType.Predicate), op.SrcPredInv);
Operand res = GetPredLogicalOp(context, op.BoolOpAB, srcA, srcB);
res = GetPredLogicalOp(context, op.BoolOpC, res, srcC);
Operand dest = GetDest(op.Dest);
if (op.BVal)
{
context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0)));
}
else
{
context.Copy(dest, res);
}
}
public static void Psetp(EmitterContext context)
{
InstPsetp op = context.GetOp<InstPsetp>();
Operand srcA = context.BitwiseNot(Register(op.Src2Pred, RegisterType.Predicate), op.Src2PredInv);
Operand srcB = context.BitwiseNot(Register(op.Src1Pred, RegisterType.Predicate), op.Src1PredInv);
Operand p0Res = GetPredLogicalOp(context, op.BoolOpAB, srcA, srcB);
Operand p1Res = context.BitwiseNot(p0Res);
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
p0Res = GetPredLogicalOp(context, op.BoolOpC, p0Res, srcPred);
p1Res = GetPredLogicalOp(context, op.BoolOpC, p1Res, srcPred);
context.Copy(Register(op.DestPred, RegisterType.Predicate), p0Res);
context.Copy(Register(op.DestPredInv, RegisterType.Predicate), p1Res);
}
}
}

View File

@ -1,32 +0,0 @@
using System;
namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
{
[Flags]
enum TextureFlags
{
None = 0,
Bindless = 1 << 0,
Gather = 1 << 1,
Derivatives = 1 << 2,
IntCoords = 1 << 3,
LodBias = 1 << 4,
LodLevel = 1 << 5,
Offset = 1 << 6,
Offsets = 1 << 7,
Coherent = 1 << 8,
AtomicMask = 15 << 16,
Add = 0 << 16,
Minimum = 1 << 16,
Maximum = 2 << 16,
Increment = 3 << 16,
Decrement = 4 << 16,
BitwiseAnd = 5 << 16,
BitwiseOr = 6 << 16,
BitwiseXor = 7 << 16,
Swap = 8 << 16,
CAS = 9 << 16
}
}

View File

@ -1,24 +0,0 @@
namespace Ryujinx.Graphics.Shader
{
enum OutputTopology
{
PointList = 1,
LineStrip = 6,
TriangleStrip = 7
}
static class OutputTopologyExtensions
{
public static string ToGlslString(this OutputTopology topology)
{
switch (topology)
{
case OutputTopology.LineStrip: return "line_strip";
case OutputTopology.PointList: return "points";
case OutputTopology.TriangleStrip: return "triangle_strip";
}
return "points";
}
}
}

View File

@ -1,21 +0,0 @@
using System;
namespace Ryujinx.Graphics.Shader.StructuredIr
{
[Flags]
enum HelperFunctionsMask
{
AtomicMinMaxS32Shared = 1 << 0,
AtomicMinMaxS32Storage = 1 << 1,
MultiplyHighS32 = 1 << 2,
MultiplyHighU32 = 1 << 3,
Shuffle = 1 << 4,
ShuffleDown = 1 << 5,
ShuffleUp = 1 << 6,
ShuffleXor = 1 << 7,
StoreSharedSmallInt = 1 << 8,
StoreStorageSmallInt = 1 << 9,
SwizzleAdd = 1 << 10,
FSI = 1 << 11
}
}

View File

@ -1,25 +0,0 @@
namespace Ryujinx.Graphics.Shader.Translation
{
enum AggregateType
{
Invalid,
Void,
Bool,
FP32,
FP64,
S32,
U32,
ElementTypeMask = 0xff,
ElementCountShift = 8,
ElementCountMask = 3 << ElementCountShift,
Scalar = 0 << ElementCountShift,
Vector2 = 1 << ElementCountShift,
Vector3 = 2 << ElementCountShift,
Vector4 = 3 << ElementCountShift,
Array = 1 << 10
}
}

View File

@ -1,52 +0,0 @@
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
namespace Ryujinx.Graphics.Shader.Translation
{
static class GlobalMemory
{
private const int StorageDescsBaseOffset = 0x44; // In words.
public const int StorageDescSize = 4; // In words.
public const int StorageMaxCount = 16;
public const int StorageDescsSize = StorageDescSize * StorageMaxCount;
public const int UbeBaseOffset = 0x98; // In words.
public const int UbeMaxCount = 9;
public const int UbeDescsSize = StorageDescSize * UbeMaxCount;
public const int UbeFirstCbuf = 8;
public static bool UsesGlobalMemory(Instruction inst, StorageKind storageKind)
{
return (inst.IsAtomic() && storageKind == StorageKind.GlobalMemory) ||
inst == Instruction.LoadGlobal ||
inst == Instruction.StoreGlobal ||
inst == Instruction.StoreGlobal16 ||
inst == Instruction.StoreGlobal8;
}
public static int GetStorageCbOffset(ShaderStage stage, int slot)
{
return GetStorageBaseCbOffset(stage) + slot * StorageDescSize;
}
public static int GetStorageBaseCbOffset(ShaderStage stage)
{
return stage switch
{
ShaderStage.Compute => StorageDescsBaseOffset + 2 * StorageDescsSize,
ShaderStage.Vertex => StorageDescsBaseOffset,
ShaderStage.TessellationControl => StorageDescsBaseOffset + 1 * StorageDescsSize,
ShaderStage.TessellationEvaluation => StorageDescsBaseOffset + 2 * StorageDescsSize,
ShaderStage.Geometry => StorageDescsBaseOffset + 3 * StorageDescsSize,
ShaderStage.Fragment => StorageDescsBaseOffset + 4 * StorageDescsSize,
_ => 0
};
}
public static int GetConstantUbeOffset(int slot)
{
return UbeBaseOffset + slot * StorageDescSize;
}
}
}

View File

@ -1,85 +0,0 @@
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using System.Collections.Generic;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{
static class BindlessToIndexed
{
public static void RunPass(BasicBlock block, ShaderConfig config)
{
// We can turn a bindless texture access into a indexed access,
// as long the following conditions are true:
// - The handle is loaded using a LDC instruction.
// - The handle is loaded from the constant buffer with the handles (CB2 for NVN).
// - The load has a constant offset.
// The base offset of the array of handles on the constant buffer is the constant offset.
for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
{
if (!(node.Value is TextureOperation texOp))
{
continue;
}
if ((texOp.Flags & TextureFlags.Bindless) == 0)
{
continue;
}
if (!(texOp.GetSource(0).AsgOp is Operation handleAsgOp))
{
continue;
}
if (handleAsgOp.Inst != Instruction.LoadConstant)
{
continue;
}
Operand ldcSrc0 = handleAsgOp.GetSource(0);
Operand ldcSrc1 = handleAsgOp.GetSource(1);
if (ldcSrc0.Type != OperandType.Constant || ldcSrc0.Value != 2)
{
continue;
}
if (!(ldcSrc1.AsgOp is Operation shrOp) || shrOp.Inst != Instruction.ShiftRightU32)
{
continue;
}
if (!(shrOp.GetSource(0).AsgOp is Operation addOp) || addOp.Inst != Instruction.Add)
{
continue;
}
Operand addSrc1 = addOp.GetSource(1);
if (addSrc1.Type != OperandType.Constant)
{
continue;
}
TurnIntoIndexed(config, texOp, addSrc1.Value / 4);
Operand index = Local();
Operand source = addOp.GetSource(0);
Operation shrBy3 = new Operation(Instruction.ShiftRightU32, index, source, Const(3));
block.Operations.AddBefore(node, shrBy3);
texOp.SetSource(0, index);
}
}
private static void TurnIntoIndexed(ShaderConfig config, TextureOperation texOp, int handle)
{
texOp.TurnIntoIndexed(handle);
config.SetUsedTexture(texOp.Inst, texOp.Type, texOp.Format, texOp.Flags, texOp.CbufSlot, handle);
}
}
}

View File

@ -1,433 +0,0 @@
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using System.Collections.Generic;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
using static Ryujinx.Graphics.Shader.Translation.GlobalMemory;
namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{
static class GlobalToStorage
{
public static void RunPass(BasicBlock block, ShaderConfig config, ref int sbUseMask, ref int ubeUseMask)
{
int sbStart = GetStorageBaseCbOffset(config.Stage);
int sbEnd = sbStart + StorageDescsSize;
int ubeStart = UbeBaseOffset;
int ubeEnd = UbeBaseOffset + UbeDescsSize;
for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
{
for (int index = 0; index < node.Value.SourcesCount; index++)
{
Operand src = node.Value.GetSource(index);
int storageIndex = GetStorageIndex(src, sbStart, sbEnd);
if (storageIndex >= 0)
{
sbUseMask |= 1 << storageIndex;
}
if (config.Stage == ShaderStage.Compute)
{
int constantIndex = GetStorageIndex(src, ubeStart, ubeEnd);
if (constantIndex >= 0)
{
ubeUseMask |= 1 << constantIndex;
}
}
}
if (!(node.Value is Operation operation))
{
continue;
}
if (UsesGlobalMemory(operation.Inst, operation.StorageKind))
{
Operand source = operation.GetSource(0);
int storageIndex = SearchForStorageBase(block, source, sbStart, sbEnd);
if (storageIndex >= 0)
{
// Storage buffers are implemented using global memory access.
// If we know from where the base address of the access is loaded,
// we can guess which storage buffer it is accessing.
// We can then replace the global memory access with a storage
// buffer access.
node = ReplaceGlobalWithStorage(block, node, config, storageIndex);
}
else if (config.Stage == ShaderStage.Compute && operation.Inst == Instruction.LoadGlobal)
{
// Here we effectively try to replace a LDG instruction with LDC.
// The hardware only supports a limited amount of constant buffers
// so NVN "emulates" more constant buffers using global memory access.
// Here we try to replace the global access back to a constant buffer
// load.
storageIndex = SearchForStorageBase(block, source, ubeStart, ubeStart + ubeEnd);
if (storageIndex >= 0)
{
node = ReplaceLdgWithLdc(node, config, storageIndex);
}
}
}
}
config.SetAccessibleBufferMasks(sbUseMask, ubeUseMask);
}
private static LinkedListNode<INode> ReplaceGlobalWithStorage(BasicBlock block, LinkedListNode<INode> node, ShaderConfig config, int storageIndex)
{
Operation operation = (Operation)node.Value;
bool isAtomic = operation.Inst.IsAtomic();
bool isStg16Or8 = operation.Inst == Instruction.StoreGlobal16 || operation.Inst == Instruction.StoreGlobal8;
bool isWrite = isAtomic || operation.Inst == Instruction.StoreGlobal || isStg16Or8;
config.SetUsedStorageBuffer(storageIndex, isWrite);
Operand[] sources = new Operand[operation.SourcesCount];
sources[0] = Const(storageIndex);
sources[1] = GetStorageOffset(block, node, config, storageIndex, operation.GetSource(0), isStg16Or8);
for (int index = 2; index < operation.SourcesCount; index++)
{
sources[index] = operation.GetSource(index);
}
Operation storageOp;
if (isAtomic)
{
storageOp = new Operation(operation.Inst, StorageKind.StorageBuffer, operation.Dest, sources);
}
else if (operation.Inst == Instruction.LoadGlobal)
{
storageOp = new Operation(Instruction.LoadStorage, operation.Dest, sources);
}
else
{
Instruction storeInst = operation.Inst switch
{
Instruction.StoreGlobal16 => Instruction.StoreStorage16,
Instruction.StoreGlobal8 => Instruction.StoreStorage8,
_ => Instruction.StoreStorage
};
storageOp = new Operation(storeInst, null, sources);
}
for (int index = 0; index < operation.SourcesCount; index++)
{
operation.SetSource(index, null);
}
LinkedListNode<INode> oldNode = node;
node = node.List.AddBefore(node, storageOp);
node.List.Remove(oldNode);
return node;
}
private static Operand GetStorageOffset(
BasicBlock block,
LinkedListNode<INode> node,
ShaderConfig config,
int storageIndex,
Operand addrLow,
bool isStg16Or8)
{
int baseAddressCbOffset = GetStorageCbOffset(config.Stage, storageIndex);
bool storageAligned = !(config.GpuAccessor.QueryHasUnalignedStorageBuffer() || config.GpuAccessor.QueryHostStorageBufferOffsetAlignment() > Constants.StorageAlignment);
(Operand byteOffset, int constantOffset) = storageAligned ?
GetStorageOffset(block, Utils.FindLastOperation(addrLow, block), baseAddressCbOffset) :
(null, 0);
if (byteOffset != null)
{
ReplaceAddressAlignment(node.List, addrLow, byteOffset, constantOffset);
}
if (byteOffset == null)
{
Operand baseAddrLow = Cbuf(0, baseAddressCbOffset);
Operand baseAddrTrunc = Local();
Operand alignMask = Const(-config.GpuAccessor.QueryHostStorageBufferOffsetAlignment());
Operation andOp = new Operation(Instruction.BitwiseAnd, baseAddrTrunc, baseAddrLow, alignMask);
node.List.AddBefore(node, andOp);
Operand offset = Local();
Operation subOp = new Operation(Instruction.Subtract, offset, addrLow, baseAddrTrunc);
node.List.AddBefore(node, subOp);
byteOffset = offset;
}
else if (constantOffset != 0)
{
Operand offset = Local();
Operation addOp = new Operation(Instruction.Add, offset, byteOffset, Const(constantOffset));
node.List.AddBefore(node, addOp);
byteOffset = offset;
}
if (isStg16Or8)
{
return byteOffset;
}
Operand wordOffset = Local();
Operation shrOp = new Operation(Instruction.ShiftRightU32, wordOffset, byteOffset, Const(2));
node.List.AddBefore(node, shrOp);
return wordOffset;
}
private static bool IsCb0Offset(Operand operand, int offset)
{
return operand.Type == OperandType.ConstantBuffer && operand.GetCbufSlot() == 0 && operand.GetCbufOffset() == offset;
}
private static void ReplaceAddressAlignment(LinkedList<INode> list, Operand address, Operand byteOffset, int constantOffset)
{
// When we emit 16/8-bit LDG, we add extra code to determine the address alignment.
// Eliminate the storage buffer base address from this too, leaving only the byte offset.
foreach (INode useNode in address.UseOps)
{
if (useNode is Operation op && op.Inst == Instruction.BitwiseAnd)
{
Operand src1 = op.GetSource(0);
Operand src2 = op.GetSource(1);
int addressIndex = -1;
if (src1 == address && src2.Type == OperandType.Constant && src2.Value == 3)
{
addressIndex = 0;
}
else if (src2 == address && src1.Type == OperandType.Constant && src1.Value == 3)
{
addressIndex = 1;
}
if (addressIndex != -1)
{
LinkedListNode<INode> node = list.Find(op);
// Add offset calculation before the use. Needs to be on the same block.
if (node != null)
{
Operand offset = Local();
Operation addOp = new Operation(Instruction.Add, offset, byteOffset, Const(constantOffset));
list.AddBefore(node, addOp);
op.SetSource(addressIndex, offset);
}
}
}
}
}
private static (Operand, int) GetStorageOffset(BasicBlock block, Operand address, int baseAddressCbOffset)
{
if (IsCb0Offset(address, baseAddressCbOffset))
{
// Direct offset: zero.
return (Const(0), 0);
}
(address, int constantOffset) = GetStorageConstantOffset(block, address);
address = Utils.FindLastOperation(address, block);
if (IsCb0Offset(address, baseAddressCbOffset))
{
// Only constant offset
return (Const(0), constantOffset);
}
if (!(address.AsgOp is Operation offsetAdd) || offsetAdd.Inst != Instruction.Add)
{
return (null, 0);
}
Operand src1 = offsetAdd.GetSource(0);
Operand src2 = Utils.FindLastOperation(offsetAdd.GetSource(1), block);
if (IsCb0Offset(src2, baseAddressCbOffset))
{
return (src1, constantOffset);
}
else if (IsCb0Offset(src1, baseAddressCbOffset))
{
return (src2, constantOffset);
}
return (null, 0);
}
private static (Operand, int) GetStorageConstantOffset(BasicBlock block, Operand address)
{
if (!(address.AsgOp is Operation offsetAdd) || offsetAdd.Inst != Instruction.Add)
{
return (address, 0);
}
Operand src1 = offsetAdd.GetSource(0);
Operand src2 = offsetAdd.GetSource(1);
if (src2.Type != OperandType.Constant)
{
return (address, 0);
}
return (src1, src2.Value);
}
private static LinkedListNode<INode> ReplaceLdgWithLdc(LinkedListNode<INode> node, ShaderConfig config, int storageIndex)
{
Operation operation = (Operation)node.Value;
Operand GetCbufOffset()
{
Operand addrLow = operation.GetSource(0);
Operand baseAddrLow = Cbuf(0, UbeBaseOffset + storageIndex * StorageDescSize);
Operand baseAddrTrunc = Local();
Operand alignMask = Const(-config.GpuAccessor.QueryHostStorageBufferOffsetAlignment());
Operation andOp = new Operation(Instruction.BitwiseAnd, baseAddrTrunc, baseAddrLow, alignMask);
node.List.AddBefore(node, andOp);
Operand byteOffset = Local();
Operand wordOffset = Local();
Operation subOp = new Operation(Instruction.Subtract, byteOffset, addrLow, baseAddrTrunc);
Operation shrOp = new Operation(Instruction.ShiftRightU32, wordOffset, byteOffset, Const(2));
node.List.AddBefore(node, subOp);
node.List.AddBefore(node, shrOp);
return wordOffset;
}
Operand[] sources = new Operand[operation.SourcesCount];
int cbSlot = UbeFirstCbuf + storageIndex;
sources[0] = Const(cbSlot);
sources[1] = GetCbufOffset();
config.SetUsedConstantBuffer(cbSlot);
for (int index = 2; index < operation.SourcesCount; index++)
{
sources[index] = operation.GetSource(index);
}
Operation ldcOp = new Operation(Instruction.LoadConstant, operation.Dest, sources);
for (int index = 0; index < operation.SourcesCount; index++)
{
operation.SetSource(index, null);
}
LinkedListNode<INode> oldNode = node;
node = node.List.AddBefore(node, ldcOp);
node.List.Remove(oldNode);
return node;
}
private static int SearchForStorageBase(BasicBlock block, Operand globalAddress, int sbStart, int sbEnd)
{
globalAddress = Utils.FindLastOperation(globalAddress, block);
if (globalAddress.Type == OperandType.ConstantBuffer)
{
return GetStorageIndex(globalAddress, sbStart, sbEnd);
}
Operation operation = globalAddress.AsgOp as Operation;
if (operation == null || operation.Inst != Instruction.Add)
{
return -1;
}
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
if ((src1.Type == OperandType.LocalVariable && src2.Type == OperandType.Constant) ||
(src2.Type == OperandType.LocalVariable && src1.Type == OperandType.Constant))
{
if (src1.Type == OperandType.LocalVariable)
{
operation = Utils.FindLastOperation(src1, block).AsgOp as Operation;
}
else
{
operation = Utils.FindLastOperation(src2, block).AsgOp as Operation;
}
if (operation == null || operation.Inst != Instruction.Add)
{
return -1;
}
}
for (int index = 0; index < operation.SourcesCount; index++)
{
Operand source = operation.GetSource(index);
int storageIndex = GetStorageIndex(source, sbStart, sbEnd);
if (storageIndex != -1)
{
return storageIndex;
}
}
return -1;
}
private static int GetStorageIndex(Operand operand, int sbStart, int sbEnd)
{
if (operand.Type == OperandType.ConstantBuffer)
{
int slot = operand.GetCbufSlot();
int offset = operand.GetCbufOffset();
if (slot == 0 && offset >= sbStart && offset < sbEnd)
{
int storageIndex = (offset - sbStart) / StorageDescSize;
return storageIndex;
}
}
return -1;
}
}
}

View File

@ -1,768 +0,0 @@
using Ryujinx.Graphics.Shader.Decoders;
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
using static Ryujinx.Graphics.Shader.Translation.GlobalMemory;
namespace Ryujinx.Graphics.Shader.Translation
{
static class Rewriter
{
public static void RunPass(BasicBlock[] blocks, ShaderConfig config)
{
bool isVertexShader = config.Stage == ShaderStage.Vertex;
bool hasConstantBufferDrawParameters = config.GpuAccessor.QueryHasConstantBufferDrawParameters();
bool supportsSnormBufferTextureFormat = config.GpuAccessor.QueryHostSupportsSnormBufferTextureFormat();
for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
{
BasicBlock block = blocks[blkIndex];
for (LinkedListNode<INode> node = block.Operations.First; node != null;)
{
if (node.Value is not Operation operation)
{
node = node.Next;
continue;
}
if (isVertexShader)
{
if (hasConstantBufferDrawParameters)
{
if (ReplaceConstantBufferWithDrawParameters(node, operation))
{
config.SetUsedFeature(FeatureFlags.DrawParameters);
}
}
else if (HasConstantBufferDrawParameters(operation))
{
config.SetUsedFeature(FeatureFlags.DrawParameters);
}
}
LinkedListNode<INode> nextNode = node.Next;
if (operation is TextureOperation texOp)
{
if (texOp.Inst == Instruction.TextureSample)
{
node = RewriteTextureSample(node, config);
if (texOp.Type == SamplerType.TextureBuffer && !supportsSnormBufferTextureFormat)
{
node = InsertSnormNormalization(node, config);
}
}
nextNode = node.Next;
}
else if (UsesGlobalMemory(operation.Inst, operation.StorageKind))
{
nextNode = RewriteGlobalAccess(node, config)?.Next ?? nextNode;
}
node = nextNode;
}
}
}
private static LinkedListNode<INode> RewriteGlobalAccess(LinkedListNode<INode> node, ShaderConfig config)
{
Operation operation = (Operation)node.Value;
bool isAtomic = operation.Inst.IsAtomic();
bool isStg16Or8 = operation.Inst == Instruction.StoreGlobal16 || operation.Inst == Instruction.StoreGlobal8;
bool isWrite = isAtomic || operation.Inst == Instruction.StoreGlobal || isStg16Or8;
Operation storageOp = null;
Operand PrependOperation(Instruction inst, params Operand[] sources)
{
Operand local = Local();
node.List.AddBefore(node, new Operation(inst, local, sources));
return local;
}
Operand PrependExistingOperation(Operation operation)
{
Operand local = Local();
operation.Dest = local;
node.List.AddBefore(node, operation);
return local;
}
Operand addrLow = operation.GetSource(0);
Operand addrHigh = operation.GetSource(1);
Operand sbBaseAddrLow = Const(0);
Operand sbSlot = Const(0);
Operand alignMask = Const(-config.GpuAccessor.QueryHostStorageBufferOffsetAlignment());
Operand BindingRangeCheck(int cbOffset, out Operand baseAddrLow)
{
baseAddrLow = Cbuf(0, cbOffset);
Operand baseAddrHigh = Cbuf(0, cbOffset + 1);
Operand size = Cbuf(0, cbOffset + 2);
Operand offset = PrependOperation(Instruction.Subtract, addrLow, baseAddrLow);
Operand borrow = PrependOperation(Instruction.CompareLessU32, addrLow, baseAddrLow);
Operand inRangeLow = PrependOperation(Instruction.CompareLessU32, offset, size);
Operand addrHighBorrowed = PrependOperation(Instruction.Add, addrHigh, borrow);
Operand inRangeHigh = PrependOperation(Instruction.CompareEqual, addrHighBorrowed, baseAddrHigh);
return PrependOperation(Instruction.BitwiseAnd, inRangeLow, inRangeHigh);
}
int sbUseMask = config.AccessibleStorageBuffersMask;
while (sbUseMask != 0)
{
int slot = BitOperations.TrailingZeroCount(sbUseMask);
sbUseMask &= ~(1 << slot);
config.SetUsedStorageBuffer(slot, isWrite);
int cbOffset = GetStorageCbOffset(config.Stage, slot);
Operand inRange = BindingRangeCheck(cbOffset, out Operand baseAddrLow);
sbBaseAddrLow = PrependOperation(Instruction.ConditionalSelect, inRange, baseAddrLow, sbBaseAddrLow);
sbSlot = PrependOperation(Instruction.ConditionalSelect, inRange, Const(slot), sbSlot);
}
if (config.AccessibleStorageBuffersMask != 0)
{
Operand baseAddrTrunc = PrependOperation(Instruction.BitwiseAnd, sbBaseAddrLow, alignMask);
Operand byteOffset = PrependOperation(Instruction.Subtract, addrLow, baseAddrTrunc);
Operand[] sources = new Operand[operation.SourcesCount];
sources[0] = sbSlot;
if (isStg16Or8)
{
sources[1] = byteOffset;
}
else
{
sources[1] = PrependOperation(Instruction.ShiftRightU32, byteOffset, Const(2));
}
for (int index = 2; index < operation.SourcesCount; index++)
{
sources[index] = operation.GetSource(index);
}
if (isAtomic)
{
storageOp = new Operation(operation.Inst, StorageKind.StorageBuffer, operation.Dest, sources);
}
else if (operation.Inst == Instruction.LoadGlobal)
{
storageOp = new Operation(Instruction.LoadStorage, operation.Dest, sources);
}
else
{
Instruction storeInst = operation.Inst switch
{
Instruction.StoreGlobal16 => Instruction.StoreStorage16,
Instruction.StoreGlobal8 => Instruction.StoreStorage8,
_ => Instruction.StoreStorage
};
storageOp = new Operation(storeInst, null, sources);
}
}
else if (operation.Dest != null)
{
storageOp = new Operation(Instruction.Copy, operation.Dest, Const(0));
}
if (operation.Inst == Instruction.LoadGlobal)
{
int cbeUseMask = config.AccessibleConstantBuffersMask;
while (cbeUseMask != 0)
{
int slot = BitOperations.TrailingZeroCount(cbeUseMask);
int cbSlot = UbeFirstCbuf + slot;
cbeUseMask &= ~(1 << slot);
config.SetUsedConstantBuffer(cbSlot);
Operand previousResult = PrependExistingOperation(storageOp);
int cbOffset = GetConstantUbeOffset(slot);
Operand inRange = BindingRangeCheck(cbOffset, out Operand baseAddrLow);
Operand baseAddrTruncConst = PrependOperation(Instruction.BitwiseAnd, baseAddrLow, alignMask);
Operand byteOffsetConst = PrependOperation(Instruction.Subtract, addrLow, baseAddrTruncConst);
Operand cbIndex = PrependOperation(Instruction.ShiftRightU32, byteOffsetConst, Const(2));
Operand[] sourcesCb = new Operand[operation.SourcesCount];
sourcesCb[0] = Const(cbSlot);
sourcesCb[1] = cbIndex;
for (int index = 2; index < operation.SourcesCount; index++)
{
sourcesCb[index] = operation.GetSource(index);
}
Operand ldcResult = PrependOperation(Instruction.LoadConstant, sourcesCb);
storageOp = new Operation(Instruction.ConditionalSelect, operation.Dest, inRange, ldcResult, previousResult);
}
}
for (int index = 0; index < operation.SourcesCount; index++)
{
operation.SetSource(index, null);
}
LinkedListNode<INode> oldNode = node;
LinkedList<INode> oldNodeList = oldNode.List;
if (storageOp != null)
{
node = node.List.AddBefore(node, storageOp);
}
else
{
node = null;
}
oldNodeList.Remove(oldNode);
return node;
}
private static LinkedListNode<INode> RewriteTextureSample(LinkedListNode<INode> node, ShaderConfig config)
{
TextureOperation texOp = (TextureOperation)node.Value;
bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0;
bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0;
bool hasInvalidOffset = (hasOffset || hasOffsets) && !config.GpuAccessor.QueryHostSupportsNonConstantTextureOffset();
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
bool isCoordNormalized = isBindless || config.GpuAccessor.QueryTextureCoordNormalized(texOp.Handle, texOp.CbufSlot);
if (!hasInvalidOffset && isCoordNormalized)
{
return node;
}
bool isGather = (texOp.Flags & TextureFlags.Gather) != 0;
bool hasDerivatives = (texOp.Flags & TextureFlags.Derivatives) != 0;
bool intCoords = (texOp.Flags & TextureFlags.IntCoords) != 0;
bool hasLodBias = (texOp.Flags & TextureFlags.LodBias) != 0;
bool hasLodLevel = (texOp.Flags & TextureFlags.LodLevel) != 0;
bool isArray = (texOp.Type & SamplerType.Array) != 0;
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
bool isMultisample = (texOp.Type & SamplerType.Multisample) != 0;
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
int coordsCount = texOp.Type.GetDimensions();
int offsetsCount;
if (hasOffsets)
{
offsetsCount = coordsCount * 4;
}
else if (hasOffset)
{
offsetsCount = coordsCount;
}
else
{
offsetsCount = 0;
}
Operand[] offsets = new Operand[offsetsCount];
Operand[] sources = new Operand[texOp.SourcesCount - offsetsCount];
int copyCount = 0;
if (isBindless || isIndexed)
{
copyCount++;
}
Operand[] lodSources = new Operand[copyCount + coordsCount];
for (int index = 0; index < lodSources.Length; index++)
{
lodSources[index] = texOp.GetSource(index);
}
copyCount += coordsCount;
if (isArray)
{
copyCount++;
}
if (isShadow)
{
copyCount++;
}
if (hasDerivatives)
{
copyCount += coordsCount * 2;
}
if (isMultisample)
{
copyCount++;
}
else if (hasLodLevel)
{
copyCount++;
}
int srcIndex = 0;
int dstIndex = 0;
for (int index = 0; index < copyCount; index++)
{
sources[dstIndex++] = texOp.GetSource(srcIndex++);
}
bool areAllOffsetsConstant = true;
for (int index = 0; index < offsetsCount; index++)
{
Operand offset = texOp.GetSource(srcIndex++);
areAllOffsetsConstant &= offset.Type == OperandType.Constant;
offsets[index] = offset;
}
hasInvalidOffset &= !areAllOffsetsConstant;
if (!hasInvalidOffset && isCoordNormalized)
{
return node;
}
if (hasLodBias)
{
sources[dstIndex++] = texOp.GetSource(srcIndex++);
}
if (isGather && !isShadow)
{
sources[dstIndex++] = texOp.GetSource(srcIndex++);
}
int coordsIndex = isBindless || isIndexed ? 1 : 0;
int componentIndex = texOp.Index;
Operand Float(Operand value)
{
Operand res = Local();
node.List.AddBefore(node, new Operation(Instruction.ConvertS32ToFP32, res, value));
return res;
}
// Emulate non-normalized coordinates by normalizing the coordinates on the shader.
// Without normalization, the coordinates are expected to the in the [0, W or H] range,
// and otherwise, it is expected to be in the [0, 1] range.
// We normalize by dividing the coords by the texture size.
if (!isCoordNormalized && !intCoords)
{
config.SetUsedFeature(FeatureFlags.IntegerSampling);
int normCoordsCount = (texOp.Type & SamplerType.Mask) == SamplerType.TextureCube ? 2 : coordsCount;
for (int index = 0; index < normCoordsCount; index++)
{
Operand coordSize = Local();
Operand[] texSizeSources;
if (isBindless || isIndexed)
{
texSizeSources = new Operand[] { sources[0], Const(0) };
}
else
{
texSizeSources = new Operand[] { Const(0) };
}
node.List.AddBefore(node, new TextureOperation(
Instruction.TextureSize,
texOp.Type,
texOp.Format,
texOp.Flags,
texOp.CbufSlot,
texOp.Handle,
index,
new[] { coordSize },
texSizeSources));
config.SetUsedTexture(Instruction.TextureSize, texOp.Type, texOp.Format, texOp.Flags, texOp.CbufSlot, texOp.Handle);
Operand source = sources[coordsIndex + index];
Operand coordNormalized = Local();
node.List.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Divide, coordNormalized, source, Float(coordSize)));
sources[coordsIndex + index] = coordNormalized;
}
}
Operand[] dests = new Operand[texOp.DestsCount];
for (int i = 0; i < texOp.DestsCount; i++)
{
dests[i] = texOp.GetDest(i);
}
Operand bindlessHandle = isBindless || isIndexed ? sources[0] : null;
LinkedListNode<INode> oldNode = node;
// Technically, non-constant texture offsets are not allowed (according to the spec),
// however some GPUs does support that.
// For GPUs where it is not supported, we can replace the instruction with the following:
// For texture*Offset, we replace it by texture*, and add the offset to the P coords.
// The offset can be calculated as offset / textureSize(lod), where lod = textureQueryLod(coords).
// For texelFetchOffset, we replace it by texelFetch and add the offset to the P coords directly.
// For textureGatherOffset, we split the operation into up to 4 operations, one for each component
// that is accessed, where each textureGather operation has a different offset for each pixel.
if (hasInvalidOffset && isGather && !isShadow)
{
config.SetUsedFeature(FeatureFlags.IntegerSampling);
Operand[] newSources = new Operand[sources.Length];
sources.CopyTo(newSources, 0);
Operand[] texSizes = InsertTextureSize(node, texOp, lodSources, bindlessHandle, coordsCount);
int destIndex = 0;
for (int compIndex = 0; compIndex < 4; compIndex++)
{
if (((texOp.Index >> compIndex) & 1) == 0)
{
continue;
}
for (int index = 0; index < coordsCount; index++)
{
config.SetUsedTexture(Instruction.TextureSize, texOp.Type, texOp.Format, texOp.Flags, texOp.CbufSlot, texOp.Handle);
Operand offset = Local();
Operand intOffset = offsets[index + (hasOffsets ? compIndex * coordsCount : 0)];
node.List.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Divide, offset, Float(intOffset), Float(texSizes[index])));
Operand source = sources[coordsIndex + index];
Operand coordPlusOffset = Local();
node.List.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Add, coordPlusOffset, source, offset));
newSources[coordsIndex + index] = coordPlusOffset;
}
TextureOperation newTexOp = new TextureOperation(
Instruction.TextureSample,
texOp.Type,
texOp.Format,
texOp.Flags & ~(TextureFlags.Offset | TextureFlags.Offsets),
texOp.CbufSlot,
texOp.Handle,
1,
new[] { dests[destIndex++] },
newSources);
node = node.List.AddBefore(node, newTexOp);
}
}
else
{
if (hasInvalidOffset)
{
if (intCoords)
{
for (int index = 0; index < coordsCount; index++)
{
Operand source = sources[coordsIndex + index];
Operand coordPlusOffset = Local();
node.List.AddBefore(node, new Operation(Instruction.Add, coordPlusOffset, source, offsets[index]));
sources[coordsIndex + index] = coordPlusOffset;
}
}
else
{
config.SetUsedFeature(FeatureFlags.IntegerSampling);
Operand[] texSizes = InsertTextureSize(node, texOp, lodSources, bindlessHandle, coordsCount);
for (int index = 0; index < coordsCount; index++)
{
config.SetUsedTexture(Instruction.TextureSize, texOp.Type, texOp.Format, texOp.Flags, texOp.CbufSlot, texOp.Handle);
Operand offset = Local();
Operand intOffset = offsets[index];
node.List.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Divide, offset, Float(intOffset), Float(texSizes[index])));
Operand source = sources[coordsIndex + index];
Operand coordPlusOffset = Local();
node.List.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Add, coordPlusOffset, source, offset));
sources[coordsIndex + index] = coordPlusOffset;
}
}
}
TextureOperation newTexOp = new TextureOperation(
Instruction.TextureSample,
texOp.Type,
texOp.Format,
texOp.Flags & ~(TextureFlags.Offset | TextureFlags.Offsets),
texOp.CbufSlot,
texOp.Handle,
componentIndex,
dests,
sources);
node = node.List.AddBefore(node, newTexOp);
}
node.List.Remove(oldNode);
for (int index = 0; index < texOp.SourcesCount; index++)
{
texOp.SetSource(index, null);
}
return node;
}
private static Operand[] InsertTextureSize(
LinkedListNode<INode> node,
TextureOperation texOp,
Operand[] lodSources,
Operand bindlessHandle,
int coordsCount)
{
Operand Int(Operand value)
{
Operand res = Local();
node.List.AddBefore(node, new Operation(Instruction.ConvertFP32ToS32, res, value));
return res;
}
Operand[] texSizes = new Operand[coordsCount];
Operand lod = Local();
node.List.AddBefore(node, new TextureOperation(
Instruction.Lod,
texOp.Type,
texOp.Format,
texOp.Flags,
texOp.CbufSlot,
texOp.Handle,
0,
new[] { lod },
lodSources));
for (int index = 0; index < coordsCount; index++)
{
texSizes[index] = Local();
Operand[] texSizeSources;
if (bindlessHandle != null)
{
texSizeSources = new Operand[] { bindlessHandle, Int(lod) };
}
else
{
texSizeSources = new Operand[] { Int(lod) };
}
node.List.AddBefore(node, new TextureOperation(
Instruction.TextureSize,
texOp.Type,
texOp.Format,
texOp.Flags,
texOp.CbufSlot,
texOp.Handle,
index,
new[] { texSizes[index] },
texSizeSources));
}
return texSizes;
}
private static LinkedListNode<INode> InsertSnormNormalization(LinkedListNode<INode> node, ShaderConfig config)
{
TextureOperation texOp = (TextureOperation)node.Value;
// We can't query the format of a bindless texture,
// because the handle is unknown, it can have any format.
if (texOp.Flags.HasFlag(TextureFlags.Bindless))
{
return node;
}
TextureFormat format = config.GpuAccessor.QueryTextureFormat(texOp.Handle, texOp.CbufSlot);
int maxPositive = format switch
{
TextureFormat.R8Snorm => sbyte.MaxValue,
TextureFormat.R8G8Snorm => sbyte.MaxValue,
TextureFormat.R8G8B8A8Snorm => sbyte.MaxValue,
TextureFormat.R16Snorm => short.MaxValue,
TextureFormat.R16G16Snorm => short.MaxValue,
TextureFormat.R16G16B16A16Snorm => short.MaxValue,
_ => 0
};
// The value being 0 means that the format is not a SNORM format,
// so there's nothing to do here.
if (maxPositive == 0)
{
return node;
}
// Do normalization. We assume SINT formats are being used
// as replacement for SNORM (which is not supported).
for (int i = 0; i < texOp.DestsCount; i++)
{
Operand dest = texOp.GetDest(i);
INode[] uses = dest.UseOps.ToArray();
Operation convOp = new Operation(Instruction.ConvertS32ToFP32, Local(), dest);
Operation normOp = new Operation(Instruction.FP32 | Instruction.Multiply, Local(), convOp.Dest, ConstF(1f / maxPositive));
node = node.List.AddAfter(node, convOp);
node = node.List.AddAfter(node, normOp);
foreach (INode useOp in uses)
{
if (useOp is not Operation op)
{
continue;
}
// Replace all uses of the texture pixel value with the normalized value.
for (int index = 0; index < op.SourcesCount; index++)
{
if (op.GetSource(index) == dest)
{
op.SetSource(index, normOp.Dest);
}
}
}
}
return node;
}
private static bool ReplaceConstantBufferWithDrawParameters(LinkedListNode<INode> node, Operation operation)
{
Operand GenerateLoad(IoVariable ioVariable)
{
Operand value = Local();
node.List.AddBefore(node, new Operation(Instruction.Load, StorageKind.Input, value, Const((int)ioVariable)));
return value;
}
bool modified = false;
for (int srcIndex = 0; srcIndex < operation.SourcesCount; srcIndex++)
{
Operand src = operation.GetSource(srcIndex);
if (src.Type == OperandType.ConstantBuffer && src.GetCbufSlot() == 0)
{
switch (src.GetCbufOffset())
{
case Constants.NvnBaseVertexByteOffset / 4:
operation.SetSource(srcIndex, GenerateLoad(IoVariable.BaseVertex));
modified = true;
break;
case Constants.NvnBaseInstanceByteOffset / 4:
operation.SetSource(srcIndex, GenerateLoad(IoVariable.BaseInstance));
modified = true;
break;
case Constants.NvnDrawIndexByteOffset / 4:
operation.SetSource(srcIndex, GenerateLoad(IoVariable.DrawIndex));
modified = true;
break;
}
}
}
return modified;
}
private static bool HasConstantBufferDrawParameters(Operation operation)
{
for (int srcIndex = 0; srcIndex < operation.SourcesCount; srcIndex++)
{
Operand src = operation.GetSource(srcIndex);
if (src.Type == OperandType.ConstantBuffer && src.GetCbufSlot() == 0)
{
switch (src.GetCbufOffset())
{
case Constants.NvnBaseVertexByteOffset / 4:
case Constants.NvnBaseInstanceByteOffset / 4:
case Constants.NvnDrawIndexByteOffset / 4:
return true;
}
}
}
return false;
}
}
}

View File

@ -1,15 +0,0 @@
using Ryujinx.Common.Utilities;
namespace Ryujinx.Graphics.Vic.Types
{
struct PipeConfig
{
#pragma warning disable CS0169, CS0649
private long _word0;
private long _word1;
#pragma warning restore CS0169, CS0649
public int DownsampleHoriz => (int)_word0.Extract(0, 11);
public int DownsampleVert => (int)_word0.Extract(16, 11);
}
}

View File

@ -1,374 +0,0 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Shader;
using Silk.NET.Vulkan;
using System;
namespace Ryujinx.Graphics.Vulkan
{
static class EnumConversion
{
public static ShaderStageFlags Convert(this ShaderStage stage)
{
return stage switch
{
ShaderStage.Vertex => ShaderStageFlags.VertexBit,
ShaderStage.Geometry => ShaderStageFlags.GeometryBit,
ShaderStage.TessellationControl => ShaderStageFlags.TessellationControlBit,
ShaderStage.TessellationEvaluation => ShaderStageFlags.TessellationEvaluationBit,
ShaderStage.Fragment => ShaderStageFlags.FragmentBit,
ShaderStage.Compute => ShaderStageFlags.ComputeBit,
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (ShaderStageFlags)0)
};
}
public static PipelineStageFlags ConvertToPipelineStageFlags(this ShaderStage stage)
{
return stage switch
{
ShaderStage.Vertex => PipelineStageFlags.VertexShaderBit,
ShaderStage.Geometry => PipelineStageFlags.GeometryShaderBit,
ShaderStage.TessellationControl => PipelineStageFlags.TessellationControlShaderBit,
ShaderStage.TessellationEvaluation => PipelineStageFlags.TessellationEvaluationShaderBit,
ShaderStage.Fragment => PipelineStageFlags.FragmentShaderBit,
ShaderStage.Compute => PipelineStageFlags.ComputeShaderBit,
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (PipelineStageFlags)0)
};
}
public static SamplerAddressMode Convert(this AddressMode mode)
{
return mode switch
{
AddressMode.Clamp => SamplerAddressMode.ClampToEdge, // TODO: Should be clamp.
AddressMode.Repeat => SamplerAddressMode.Repeat,
AddressMode.MirrorClamp => SamplerAddressMode.ClampToEdge, // TODO: Should be mirror clamp.
AddressMode.MirrorClampToEdge => SamplerAddressMode.MirrorClampToEdgeKhr,
AddressMode.MirrorClampToBorder => SamplerAddressMode.ClampToBorder, // TODO: Should be mirror clamp to border.
AddressMode.ClampToBorder => SamplerAddressMode.ClampToBorder,
AddressMode.MirroredRepeat => SamplerAddressMode.MirroredRepeat,
AddressMode.ClampToEdge => SamplerAddressMode.ClampToEdge,
_ => LogInvalidAndReturn(mode, nameof(AddressMode), SamplerAddressMode.ClampToEdge) // TODO: Should be clamp.
};
}
public static Silk.NET.Vulkan.BlendFactor Convert(this GAL.BlendFactor factor)
{
return factor switch
{
GAL.BlendFactor.Zero or GAL.BlendFactor.ZeroGl => Silk.NET.Vulkan.BlendFactor.Zero,
GAL.BlendFactor.One or GAL.BlendFactor.OneGl => Silk.NET.Vulkan.BlendFactor.One,
GAL.BlendFactor.SrcColor or GAL.BlendFactor.SrcColorGl => Silk.NET.Vulkan.BlendFactor.SrcColor,
GAL.BlendFactor.OneMinusSrcColor or GAL.BlendFactor.OneMinusSrcColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrcColor,
GAL.BlendFactor.SrcAlpha or GAL.BlendFactor.SrcAlphaGl => Silk.NET.Vulkan.BlendFactor.SrcAlpha,
GAL.BlendFactor.OneMinusSrcAlpha or GAL.BlendFactor.OneMinusSrcAlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrcAlpha,
GAL.BlendFactor.DstAlpha or GAL.BlendFactor.DstAlphaGl => Silk.NET.Vulkan.BlendFactor.DstAlpha,
GAL.BlendFactor.OneMinusDstAlpha or GAL.BlendFactor.OneMinusDstAlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusDstAlpha,
GAL.BlendFactor.DstColor or GAL.BlendFactor.DstColorGl => Silk.NET.Vulkan.BlendFactor.DstColor,
GAL.BlendFactor.OneMinusDstColor or GAL.BlendFactor.OneMinusDstColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusDstColor,
GAL.BlendFactor.SrcAlphaSaturate or GAL.BlendFactor.SrcAlphaSaturateGl => Silk.NET.Vulkan.BlendFactor.SrcAlphaSaturate,
GAL.BlendFactor.Src1Color or GAL.BlendFactor.Src1ColorGl => Silk.NET.Vulkan.BlendFactor.Src1Color,
GAL.BlendFactor.OneMinusSrc1Color or GAL.BlendFactor.OneMinusSrc1ColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrc1Color,
GAL.BlendFactor.Src1Alpha or GAL.BlendFactor.Src1AlphaGl => Silk.NET.Vulkan.BlendFactor.Src1Alpha,
GAL.BlendFactor.OneMinusSrc1Alpha or GAL.BlendFactor.OneMinusSrc1AlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrc1Alpha,
GAL.BlendFactor.ConstantColor => Silk.NET.Vulkan.BlendFactor.ConstantColor,
GAL.BlendFactor.OneMinusConstantColor => Silk.NET.Vulkan.BlendFactor.OneMinusConstantColor,
GAL.BlendFactor.ConstantAlpha => Silk.NET.Vulkan.BlendFactor.ConstantAlpha,
GAL.BlendFactor.OneMinusConstantAlpha => Silk.NET.Vulkan.BlendFactor.OneMinusConstantAlpha,
_ => LogInvalidAndReturn(factor, nameof(GAL.BlendFactor), Silk.NET.Vulkan.BlendFactor.Zero)
};
}
public static Silk.NET.Vulkan.BlendOp Convert(this GAL.AdvancedBlendOp op)
{
return op switch
{
GAL.AdvancedBlendOp.Zero => Silk.NET.Vulkan.BlendOp.ZeroExt,
GAL.AdvancedBlendOp.Src => Silk.NET.Vulkan.BlendOp.SrcExt,
GAL.AdvancedBlendOp.Dst => Silk.NET.Vulkan.BlendOp.DstExt,
GAL.AdvancedBlendOp.SrcOver => Silk.NET.Vulkan.BlendOp.SrcOverExt,
GAL.AdvancedBlendOp.DstOver => Silk.NET.Vulkan.BlendOp.DstOverExt,
GAL.AdvancedBlendOp.SrcIn => Silk.NET.Vulkan.BlendOp.SrcInExt,
GAL.AdvancedBlendOp.DstIn => Silk.NET.Vulkan.BlendOp.DstInExt,
GAL.AdvancedBlendOp.SrcOut => Silk.NET.Vulkan.BlendOp.SrcOutExt,
GAL.AdvancedBlendOp.DstOut => Silk.NET.Vulkan.BlendOp.DstOutExt,
GAL.AdvancedBlendOp.SrcAtop => Silk.NET.Vulkan.BlendOp.SrcAtopExt,
GAL.AdvancedBlendOp.DstAtop => Silk.NET.Vulkan.BlendOp.DstAtopExt,
GAL.AdvancedBlendOp.Xor => Silk.NET.Vulkan.BlendOp.XorExt,
GAL.AdvancedBlendOp.Plus => Silk.NET.Vulkan.BlendOp.PlusExt,
GAL.AdvancedBlendOp.PlusClamped => Silk.NET.Vulkan.BlendOp.PlusClampedExt,
GAL.AdvancedBlendOp.PlusClampedAlpha => Silk.NET.Vulkan.BlendOp.PlusClampedAlphaExt,
GAL.AdvancedBlendOp.PlusDarker => Silk.NET.Vulkan.BlendOp.PlusDarkerExt,
GAL.AdvancedBlendOp.Multiply => Silk.NET.Vulkan.BlendOp.MultiplyExt,
GAL.AdvancedBlendOp.Screen => Silk.NET.Vulkan.BlendOp.ScreenExt,
GAL.AdvancedBlendOp.Overlay => Silk.NET.Vulkan.BlendOp.OverlayExt,
GAL.AdvancedBlendOp.Darken => Silk.NET.Vulkan.BlendOp.DarkenExt,
GAL.AdvancedBlendOp.Lighten => Silk.NET.Vulkan.BlendOp.LightenExt,
GAL.AdvancedBlendOp.ColorDodge => Silk.NET.Vulkan.BlendOp.ColordodgeExt,
GAL.AdvancedBlendOp.ColorBurn => Silk.NET.Vulkan.BlendOp.ColorburnExt,
GAL.AdvancedBlendOp.HardLight => Silk.NET.Vulkan.BlendOp.HardlightExt,
GAL.AdvancedBlendOp.SoftLight => Silk.NET.Vulkan.BlendOp.SoftlightExt,
GAL.AdvancedBlendOp.Difference => Silk.NET.Vulkan.BlendOp.DifferenceExt,
GAL.AdvancedBlendOp.Minus => Silk.NET.Vulkan.BlendOp.MinusExt,
GAL.AdvancedBlendOp.MinusClamped => Silk.NET.Vulkan.BlendOp.MinusClampedExt,
GAL.AdvancedBlendOp.Exclusion => Silk.NET.Vulkan.BlendOp.ExclusionExt,
GAL.AdvancedBlendOp.Contrast => Silk.NET.Vulkan.BlendOp.ContrastExt,
GAL.AdvancedBlendOp.Invert => Silk.NET.Vulkan.BlendOp.InvertExt,
GAL.AdvancedBlendOp.InvertRGB => Silk.NET.Vulkan.BlendOp.InvertRgbExt,
GAL.AdvancedBlendOp.InvertOvg => Silk.NET.Vulkan.BlendOp.InvertOvgExt,
GAL.AdvancedBlendOp.LinearDodge => Silk.NET.Vulkan.BlendOp.LineardodgeExt,
GAL.AdvancedBlendOp.LinearBurn => Silk.NET.Vulkan.BlendOp.LinearburnExt,
GAL.AdvancedBlendOp.VividLight => Silk.NET.Vulkan.BlendOp.VividlightExt,
GAL.AdvancedBlendOp.LinearLight => Silk.NET.Vulkan.BlendOp.LinearlightExt,
GAL.AdvancedBlendOp.PinLight => Silk.NET.Vulkan.BlendOp.PinlightExt,
GAL.AdvancedBlendOp.HardMix => Silk.NET.Vulkan.BlendOp.HardmixExt,
GAL.AdvancedBlendOp.Red => Silk.NET.Vulkan.BlendOp.RedExt,
GAL.AdvancedBlendOp.Green => Silk.NET.Vulkan.BlendOp.GreenExt,
GAL.AdvancedBlendOp.Blue => Silk.NET.Vulkan.BlendOp.BlueExt,
GAL.AdvancedBlendOp.HslHue => Silk.NET.Vulkan.BlendOp.HslHueExt,
GAL.AdvancedBlendOp.HslSaturation => Silk.NET.Vulkan.BlendOp.HslSaturationExt,
GAL.AdvancedBlendOp.HslColor => Silk.NET.Vulkan.BlendOp.HslColorExt,
GAL.AdvancedBlendOp.HslLuminosity => Silk.NET.Vulkan.BlendOp.HslLuminosityExt,
_ => LogInvalidAndReturn(op, nameof(GAL.AdvancedBlendOp), Silk.NET.Vulkan.BlendOp.Add)
};
}
public static Silk.NET.Vulkan.BlendOp Convert(this GAL.BlendOp op)
{
return op switch
{
GAL.BlendOp.Add or GAL.BlendOp.AddGl => Silk.NET.Vulkan.BlendOp.Add,
GAL.BlendOp.Subtract or GAL.BlendOp.SubtractGl => Silk.NET.Vulkan.BlendOp.Subtract,
GAL.BlendOp.ReverseSubtract or GAL.BlendOp.ReverseSubtractGl => Silk.NET.Vulkan.BlendOp.ReverseSubtract,
GAL.BlendOp.Minimum or GAL.BlendOp.MinimumGl => Silk.NET.Vulkan.BlendOp.Min,
GAL.BlendOp.Maximum or GAL.BlendOp.MaximumGl => Silk.NET.Vulkan.BlendOp.Max,
_ => LogInvalidAndReturn(op, nameof(GAL.BlendOp), Silk.NET.Vulkan.BlendOp.Add)
};
}
public static Silk.NET.Vulkan.BlendOverlapEXT Convert(this GAL.AdvancedBlendOverlap overlap)
{
return overlap switch
{
GAL.AdvancedBlendOverlap.Uncorrelated => Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt,
GAL.AdvancedBlendOverlap.Disjoint => Silk.NET.Vulkan.BlendOverlapEXT.DisjointExt,
GAL.AdvancedBlendOverlap.Conjoint => Silk.NET.Vulkan.BlendOverlapEXT.ConjointExt,
_ => LogInvalidAndReturn(overlap, nameof(GAL.AdvancedBlendOverlap), Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt)
};
}
public static Silk.NET.Vulkan.CompareOp Convert(this GAL.CompareOp op)
{
return op switch
{
GAL.CompareOp.Never or GAL.CompareOp.NeverGl => Silk.NET.Vulkan.CompareOp.Never,
GAL.CompareOp.Less or GAL.CompareOp.LessGl => Silk.NET.Vulkan.CompareOp.Less,
GAL.CompareOp.Equal or GAL.CompareOp.EqualGl => Silk.NET.Vulkan.CompareOp.Equal,
GAL.CompareOp.LessOrEqual or GAL.CompareOp.LessOrEqualGl => Silk.NET.Vulkan.CompareOp.LessOrEqual,
GAL.CompareOp.Greater or GAL.CompareOp.GreaterGl => Silk.NET.Vulkan.CompareOp.Greater,
GAL.CompareOp.NotEqual or GAL.CompareOp.NotEqualGl => Silk.NET.Vulkan.CompareOp.NotEqual,
GAL.CompareOp.GreaterOrEqual or GAL.CompareOp.GreaterOrEqualGl => Silk.NET.Vulkan.CompareOp.GreaterOrEqual,
GAL.CompareOp.Always or GAL.CompareOp.AlwaysGl => Silk.NET.Vulkan.CompareOp.Always,
_ => LogInvalidAndReturn(op, nameof(GAL.CompareOp), Silk.NET.Vulkan.CompareOp.Never)
};
}
public static CullModeFlags Convert(this Face face)
{
return face switch
{
Face.Back => CullModeFlags.BackBit,
Face.Front => CullModeFlags.FrontBit,
Face.FrontAndBack => CullModeFlags.FrontAndBack,
_ => LogInvalidAndReturn(face, nameof(Face), CullModeFlags.BackBit)
};
}
public static Silk.NET.Vulkan.FrontFace Convert(this GAL.FrontFace frontFace)
{
// Flipped to account for origin differences.
return frontFace switch
{
GAL.FrontFace.Clockwise => Silk.NET.Vulkan.FrontFace.CounterClockwise,
GAL.FrontFace.CounterClockwise => Silk.NET.Vulkan.FrontFace.Clockwise,
_ => LogInvalidAndReturn(frontFace, nameof(GAL.FrontFace), Silk.NET.Vulkan.FrontFace.Clockwise)
};
}
public static Silk.NET.Vulkan.IndexType Convert(this GAL.IndexType type)
{
return type switch
{
GAL.IndexType.UByte => Silk.NET.Vulkan.IndexType.Uint8Ext,
GAL.IndexType.UShort => Silk.NET.Vulkan.IndexType.Uint16,
GAL.IndexType.UInt => Silk.NET.Vulkan.IndexType.Uint32,
_ => LogInvalidAndReturn(type, nameof(GAL.IndexType), Silk.NET.Vulkan.IndexType.Uint16)
};
}
public static Filter Convert(this MagFilter filter)
{
return filter switch
{
MagFilter.Nearest => Filter.Nearest,
MagFilter.Linear => Filter.Linear,
_ => LogInvalidAndReturn(filter, nameof(MagFilter), Filter.Nearest)
};
}
public static (Filter, SamplerMipmapMode) Convert(this MinFilter filter)
{
return filter switch
{
MinFilter.Nearest => (Filter.Nearest, SamplerMipmapMode.Nearest),
MinFilter.Linear => (Filter.Linear, SamplerMipmapMode.Nearest),
MinFilter.NearestMipmapNearest => (Filter.Nearest, SamplerMipmapMode.Nearest),
MinFilter.LinearMipmapNearest => (Filter.Linear, SamplerMipmapMode.Nearest),
MinFilter.NearestMipmapLinear => (Filter.Nearest, SamplerMipmapMode.Linear),
MinFilter.LinearMipmapLinear => (Filter.Linear, SamplerMipmapMode.Linear),
_ => LogInvalidAndReturn(filter, nameof(MinFilter), (Filter.Nearest, SamplerMipmapMode.Nearest))
};
}
public static Silk.NET.Vulkan.PrimitiveTopology Convert(this GAL.PrimitiveTopology topology)
{
return topology switch
{
GAL.PrimitiveTopology.Points => Silk.NET.Vulkan.PrimitiveTopology.PointList,
GAL.PrimitiveTopology.Lines => Silk.NET.Vulkan.PrimitiveTopology.LineList,
GAL.PrimitiveTopology.LineStrip => Silk.NET.Vulkan.PrimitiveTopology.LineStrip,
GAL.PrimitiveTopology.Triangles => Silk.NET.Vulkan.PrimitiveTopology.TriangleList,
GAL.PrimitiveTopology.TriangleStrip => Silk.NET.Vulkan.PrimitiveTopology.TriangleStrip,
GAL.PrimitiveTopology.TriangleFan => Silk.NET.Vulkan.PrimitiveTopology.TriangleFan,
GAL.PrimitiveTopology.LinesAdjacency => Silk.NET.Vulkan.PrimitiveTopology.LineListWithAdjacency,
GAL.PrimitiveTopology.LineStripAdjacency => Silk.NET.Vulkan.PrimitiveTopology.LineStripWithAdjacency,
GAL.PrimitiveTopology.TrianglesAdjacency => Silk.NET.Vulkan.PrimitiveTopology.TriangleListWithAdjacency,
GAL.PrimitiveTopology.TriangleStripAdjacency => Silk.NET.Vulkan.PrimitiveTopology.TriangleStripWithAdjacency,
GAL.PrimitiveTopology.Patches => Silk.NET.Vulkan.PrimitiveTopology.PatchList,
GAL.PrimitiveTopology.Polygon => Silk.NET.Vulkan.PrimitiveTopology.TriangleFan,
GAL.PrimitiveTopology.Quads => throw new NotSupportedException("Quad topology is not available in Vulkan."),
GAL.PrimitiveTopology.QuadStrip => throw new NotSupportedException("QuadStrip topology is not available in Vulkan."),
_ => LogInvalidAndReturn(topology, nameof(GAL.PrimitiveTopology), Silk.NET.Vulkan.PrimitiveTopology.TriangleList)
};
}
public static Silk.NET.Vulkan.StencilOp Convert(this GAL.StencilOp op)
{
return op switch
{
GAL.StencilOp.Keep or GAL.StencilOp.KeepGl => Silk.NET.Vulkan.StencilOp.Keep,
GAL.StencilOp.Zero or GAL.StencilOp.ZeroGl => Silk.NET.Vulkan.StencilOp.Zero,
GAL.StencilOp.Replace or GAL.StencilOp.ReplaceGl => Silk.NET.Vulkan.StencilOp.Replace,
GAL.StencilOp.IncrementAndClamp or GAL.StencilOp.IncrementAndClampGl => Silk.NET.Vulkan.StencilOp.IncrementAndClamp,
GAL.StencilOp.DecrementAndClamp or GAL.StencilOp.DecrementAndClampGl => Silk.NET.Vulkan.StencilOp.DecrementAndClamp,
GAL.StencilOp.Invert or GAL.StencilOp.InvertGl => Silk.NET.Vulkan.StencilOp.Invert,
GAL.StencilOp.IncrementAndWrap or GAL.StencilOp.IncrementAndWrapGl => Silk.NET.Vulkan.StencilOp.IncrementAndWrap,
GAL.StencilOp.DecrementAndWrap or GAL.StencilOp.DecrementAndWrapGl => Silk.NET.Vulkan.StencilOp.DecrementAndWrap,
_ => LogInvalidAndReturn(op, nameof(GAL.StencilOp), Silk.NET.Vulkan.StencilOp.Keep)
};
}
public static ComponentSwizzle Convert(this SwizzleComponent swizzleComponent)
{
return swizzleComponent switch
{
SwizzleComponent.Zero => ComponentSwizzle.Zero,
SwizzleComponent.One => ComponentSwizzle.One,
SwizzleComponent.Red => ComponentSwizzle.R,
SwizzleComponent.Green => ComponentSwizzle.G,
SwizzleComponent.Blue => ComponentSwizzle.B,
SwizzleComponent.Alpha => ComponentSwizzle.A,
_ => LogInvalidAndReturn(swizzleComponent, nameof(SwizzleComponent), ComponentSwizzle.Zero)
};
}
public static ImageType Convert(this Target target)
{
return target switch
{
Target.Texture1D or
Target.Texture1DArray or
Target.TextureBuffer => ImageType.Type1D,
Target.Texture2D or
Target.Texture2DArray or
Target.Texture2DMultisample or
Target.Cubemap or
Target.CubemapArray => ImageType.Type2D,
Target.Texture3D => ImageType.Type3D,
_ => LogInvalidAndReturn(target, nameof(Target), ImageType.Type2D)
};
}
public static ImageViewType ConvertView(this Target target)
{
return target switch
{
Target.Texture1D => ImageViewType.Type1D,
Target.Texture2D or Target.Texture2DMultisample => ImageViewType.Type2D,
Target.Texture3D => ImageViewType.Type3D,
Target.Texture1DArray => ImageViewType.Type1DArray,
Target.Texture2DArray => ImageViewType.Type2DArray,
Target.Cubemap => ImageViewType.TypeCube,
Target.CubemapArray => ImageViewType.TypeCubeArray,
_ => LogInvalidAndReturn(target, nameof(Target), ImageViewType.Type2D)
};
}
public static ImageAspectFlags ConvertAspectFlags(this GAL.Format format)
{
return format switch
{
GAL.Format.D16Unorm or GAL.Format.D32Float => ImageAspectFlags.DepthBit,
GAL.Format.S8Uint => ImageAspectFlags.StencilBit,
GAL.Format.D24UnormS8Uint or
GAL.Format.D32FloatS8Uint or
GAL.Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
_ => ImageAspectFlags.ColorBit
};
}
public static ImageAspectFlags ConvertAspectFlags(this GAL.Format format, DepthStencilMode depthStencilMode)
{
return format switch
{
GAL.Format.D16Unorm or GAL.Format.D32Float => ImageAspectFlags.DepthBit,
GAL.Format.S8Uint => ImageAspectFlags.StencilBit,
GAL.Format.D24UnormS8Uint or
GAL.Format.D32FloatS8Uint or
GAL.Format.S8UintD24Unorm => depthStencilMode == DepthStencilMode.Stencil ? ImageAspectFlags.StencilBit : ImageAspectFlags.DepthBit,
_ => ImageAspectFlags.ColorBit
};
}
public static LogicOp Convert(this LogicalOp op)
{
return op switch
{
LogicalOp.Clear => LogicOp.Clear,
LogicalOp.And => LogicOp.And,
LogicalOp.AndReverse => LogicOp.AndReverse,
LogicalOp.Copy => LogicOp.Copy,
LogicalOp.AndInverted => LogicOp.AndInverted,
LogicalOp.Noop => LogicOp.NoOp,
LogicalOp.Xor => LogicOp.Xor,
LogicalOp.Or => LogicOp.Or,
LogicalOp.Nor => LogicOp.Nor,
LogicalOp.Equiv => LogicOp.Equivalent,
LogicalOp.Invert => LogicOp.Invert,
LogicalOp.OrReverse => LogicOp.OrReverse,
LogicalOp.CopyInverted => LogicOp.CopyInverted,
LogicalOp.OrInverted => LogicOp.OrInverted,
LogicalOp.Nand => LogicOp.Nand,
LogicalOp.Set => LogicOp.Set,
_ => LogInvalidAndReturn(op, nameof(LogicalOp), LogicOp.Copy)
};
}
private static T2 LogInvalidAndReturn<T1, T2>(T1 value, string name, T2 defaultValue = default)
{
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {name} enum value: {value}.");
return defaultValue;
}
}
}

View File

@ -1,58 +0,0 @@
using Ryujinx.Graphics.GAL;
using Silk.NET.Vulkan;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Vulkan
{
class PipelineLayoutCache
{
private readonly PipelineLayoutCacheEntry[] _plce;
private readonly List<PipelineLayoutCacheEntry> _plceMinimal;
public PipelineLayoutCache()
{
_plce = new PipelineLayoutCacheEntry[1 << Constants.MaxShaderStages];
_plceMinimal = new List<PipelineLayoutCacheEntry>();
}
public PipelineLayoutCacheEntry Create(VulkanRenderer gd, Device device, ShaderSource[] shaders)
{
var plce = new PipelineLayoutCacheEntry(gd, device, shaders);
_plceMinimal.Add(plce);
return plce;
}
public PipelineLayoutCacheEntry GetOrCreate(VulkanRenderer gd, Device device, uint stages, bool usePd)
{
if (_plce[stages] == null)
{
_plce[stages] = new PipelineLayoutCacheEntry(gd, device, stages, usePd);
}
return _plce[stages];
}
protected virtual unsafe void Dispose(bool disposing)
{
if (disposing)
{
for (int i = 0; i < _plce.Length; i++)
{
_plce[i]?.Dispose();
}
foreach (var plce in _plceMinimal)
{
plce.Dispose();
}
_plceMinimal.Clear();
}
}
public void Dispose()
{
Dispose(true);
}
}
}

View File

@ -1,244 +0,0 @@
using Ryujinx.Graphics.GAL;
using Silk.NET.Vulkan;
using System.Collections.Generic;
using System.Numerics;
namespace Ryujinx.Graphics.Vulkan
{
static class PipelineLayoutFactory
{
private const ShaderStageFlags SupportBufferStages =
ShaderStageFlags.VertexBit |
ShaderStageFlags.FragmentBit |
ShaderStageFlags.ComputeBit;
public static unsafe DescriptorSetLayout[] Create(VulkanRenderer gd, Device device, uint stages, bool usePd, out PipelineLayout layout)
{
int stagesCount = BitOperations.PopCount(stages);
int uCount = Constants.MaxUniformBuffersPerStage * stagesCount + 1;
int tCount = Constants.MaxTexturesPerStage * 2 * stagesCount;
int iCount = Constants.MaxImagesPerStage * 2 * stagesCount;
DescriptorSetLayoutBinding* uLayoutBindings = stackalloc DescriptorSetLayoutBinding[uCount];
DescriptorSetLayoutBinding* sLayoutBindings = stackalloc DescriptorSetLayoutBinding[stagesCount];
DescriptorSetLayoutBinding* tLayoutBindings = stackalloc DescriptorSetLayoutBinding[tCount];
DescriptorSetLayoutBinding* iLayoutBindings = stackalloc DescriptorSetLayoutBinding[iCount];
uLayoutBindings[0] = new DescriptorSetLayoutBinding
{
Binding = 0,
DescriptorType = DescriptorType.UniformBuffer,
DescriptorCount = 1,
StageFlags = SupportBufferStages
};
int iter = 0;
while (stages != 0)
{
int stage = BitOperations.TrailingZeroCount(stages);
stages &= ~(1u << stage);
var stageFlags = stage switch
{
1 => ShaderStageFlags.FragmentBit,
2 => ShaderStageFlags.GeometryBit,
3 => ShaderStageFlags.TessellationControlBit,
4 => ShaderStageFlags.TessellationEvaluationBit,
_ => ShaderStageFlags.VertexBit | ShaderStageFlags.ComputeBit
};
void Set(DescriptorSetLayoutBinding* bindings, int maxPerStage, DescriptorType type, int start, int skip)
{
int totalPerStage = maxPerStage * skip;
for (int i = 0; i < maxPerStage; i++)
{
bindings[start + iter * totalPerStage + i] = new DescriptorSetLayoutBinding
{
Binding = (uint)(start + stage * totalPerStage + i),
DescriptorType = type,
DescriptorCount = 1,
StageFlags = stageFlags
};
}
}
void SetStorage(DescriptorSetLayoutBinding* bindings, int maxPerStage, int start = 0)
{
bindings[start + iter] = new DescriptorSetLayoutBinding
{
Binding = (uint)(start + stage * maxPerStage),
DescriptorType = DescriptorType.StorageBuffer,
DescriptorCount = (uint)maxPerStage,
StageFlags = stageFlags
};
}
Set(uLayoutBindings, Constants.MaxUniformBuffersPerStage, DescriptorType.UniformBuffer, 1, 1);
SetStorage(sLayoutBindings, Constants.MaxStorageBuffersPerStage);
Set(tLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.CombinedImageSampler, 0, 2);
Set(tLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.UniformTexelBuffer, Constants.MaxTexturesPerStage, 2);
Set(iLayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageImage, 0, 2);
Set(iLayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageTexelBuffer, Constants.MaxImagesPerStage, 2);
iter++;
}
DescriptorSetLayout[] layouts = new DescriptorSetLayout[PipelineBase.DescriptorSetLayouts];
var uDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = uLayoutBindings,
BindingCount = (uint)uCount,
Flags = usePd ? DescriptorSetLayoutCreateFlags.PushDescriptorBitKhr : 0
};
var sDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = sLayoutBindings,
BindingCount = (uint)stagesCount
};
var tDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = tLayoutBindings,
BindingCount = (uint)tCount
};
var iDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = iLayoutBindings,
BindingCount = (uint)iCount
};
gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[PipelineBase.UniformSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[PipelineBase.StorageSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[PipelineBase.TextureSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, iDescriptorSetLayoutCreateInfo, null, out layouts[PipelineBase.ImageSetIndex]).ThrowOnError();
fixed (DescriptorSetLayout* pLayouts = layouts)
{
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
{
SType = StructureType.PipelineLayoutCreateInfo,
PSetLayouts = pLayouts,
SetLayoutCount = PipelineBase.DescriptorSetLayouts
};
gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
}
return layouts;
}
public static unsafe DescriptorSetLayout[] CreateMinimal(VulkanRenderer gd, Device device, ShaderSource[] shaders, out PipelineLayout layout)
{
int stagesCount = shaders.Length;
int uCount = 0;
int sCount = 0;
int tCount = 0;
int iCount = 0;
foreach (var shader in shaders)
{
uCount += shader.Bindings.UniformBufferBindings.Count;
sCount += shader.Bindings.StorageBufferBindings.Count;
tCount += shader.Bindings.TextureBindings.Count;
iCount += shader.Bindings.ImageBindings.Count;
}
DescriptorSetLayoutBinding* uLayoutBindings = stackalloc DescriptorSetLayoutBinding[uCount];
DescriptorSetLayoutBinding* sLayoutBindings = stackalloc DescriptorSetLayoutBinding[sCount];
DescriptorSetLayoutBinding* tLayoutBindings = stackalloc DescriptorSetLayoutBinding[tCount];
DescriptorSetLayoutBinding* iLayoutBindings = stackalloc DescriptorSetLayoutBinding[iCount];
int uIndex = 0;
int sIndex = 0;
int tIndex = 0;
int iIndex = 0;
foreach (var shader in shaders)
{
var stageFlags = shader.Stage.Convert();
void Set(DescriptorSetLayoutBinding* bindings, DescriptorType type, ref int start, IEnumerable<int> bds)
{
foreach (var b in bds)
{
bindings[start++] = new DescriptorSetLayoutBinding
{
Binding = (uint)b,
DescriptorType = type,
DescriptorCount = 1,
StageFlags = stageFlags
};
}
}
// TODO: Support buffer textures and images here.
// This is only used for the helper shaders on the backend, and we don't use buffer textures on them
// so far, so it's not really necessary right now.
Set(uLayoutBindings, DescriptorType.UniformBuffer, ref uIndex, shader.Bindings.UniformBufferBindings);
Set(sLayoutBindings, DescriptorType.StorageBuffer, ref sIndex, shader.Bindings.StorageBufferBindings);
Set(tLayoutBindings, DescriptorType.CombinedImageSampler, ref tIndex, shader.Bindings.TextureBindings);
Set(iLayoutBindings, DescriptorType.StorageImage, ref iIndex, shader.Bindings.ImageBindings);
}
DescriptorSetLayout[] layouts = new DescriptorSetLayout[PipelineBase.DescriptorSetLayouts];
var uDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = uLayoutBindings,
BindingCount = (uint)uCount
};
var sDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = sLayoutBindings,
BindingCount = (uint)sCount
};
var tDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = tLayoutBindings,
BindingCount = (uint)tCount
};
var iDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = iLayoutBindings,
BindingCount = (uint)iCount
};
gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[PipelineBase.UniformSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[PipelineBase.StorageSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[PipelineBase.TextureSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, iDescriptorSetLayoutCreateInfo, null, out layouts[PipelineBase.ImageSetIndex]).ThrowOnError();
fixed (DescriptorSetLayout* pLayouts = layouts)
{
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
{
SType = StructureType.PipelineLayoutCreateInfo,
PSetLayouts = pLayouts,
SetLayoutCount = PipelineBase.DescriptorSetLayouts
};
gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
}
return layouts;
}
}
}

View File

@ -1,85 +0,0 @@
using LibHac;
using LibHac.Common;
using Ryujinx.Common;
using Ryujinx.HLE.HOS.Services.Arp;
using Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator;
namespace Ryujinx.HLE.HOS.Services.Bcat
{
[Service("bcat:a", "bcat:a")]
[Service("bcat:m", "bcat:m")]
[Service("bcat:u", "bcat:u")]
[Service("bcat:s", "bcat:s")]
class IServiceCreator : DisposableIpcService
{
private SharedRef<LibHac.Bcat.Impl.Ipc.IServiceCreator> _base;
public IServiceCreator(ServiceCtx context, string serviceName)
{
var applicationClient = context.Device.System.LibHacHorizonManager.ApplicationClient;
applicationClient.Sm.GetService(ref _base, serviceName).ThrowIfFailure();
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
_base.Destroy();
}
}
[CommandCmif(0)]
// CreateBcatService(pid) -> object<nn::bcat::detail::ipc::IBcatService>
public ResultCode CreateBcatService(ServiceCtx context)
{
// TODO: Call arp:r GetApplicationLaunchProperty with the pid to get the TitleId.
// Add an instance of nn::bcat::detail::service::core::PassphraseManager.
// Add an instance of nn::bcat::detail::service::ServiceMemoryManager.
// Add an instance of nn::bcat::detail::service::core::TaskManager who load "bcat-sys:/" system save data and open "dc/task.bin".
// If the file don't exist, create a new one (size of 0x800) and write 2 empty struct with a size of 0x400.
MakeObject(context, new IBcatService(ApplicationLaunchProperty.GetByPid(context)));
// NOTE: If the IBcatService is null this error is returned, Doesn't occur in our case.
// return ResultCode.NullObject;
return ResultCode.Success;
}
[CommandCmif(1)]
// CreateDeliveryCacheStorageService(pid) -> object<nn::bcat::detail::ipc::IDeliveryCacheStorageService>
public ResultCode CreateDeliveryCacheStorageService(ServiceCtx context)
{
ulong pid = context.RequestData.ReadUInt64();
using var serv = new SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheStorageService>();
Result rc = _base.Get.CreateDeliveryCacheStorageService(ref serv.Ref, pid);
if (rc.IsSuccess())
{
MakeObject(context, new IDeliveryCacheStorageService(context, ref serv.Ref));
}
return (ResultCode)rc.Value;
}
[CommandCmif(2)]
// CreateDeliveryCacheStorageServiceWithApplicationId(nn::ApplicationId) -> object<nn::bcat::detail::ipc::IDeliveryCacheStorageService>
public ResultCode CreateDeliveryCacheStorageServiceWithApplicationId(ServiceCtx context)
{
ApplicationId applicationId = context.RequestData.ReadStruct<ApplicationId>();
using var service = new SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheStorageService>();
Result rc = _base.Get.CreateDeliveryCacheStorageServiceWithApplicationId(ref service.Ref, applicationId);
if (rc.IsSuccess())
{
MakeObject(context, new IDeliveryCacheStorageService(context, ref service.Ref));
}
return (ResultCode)rc.Value;
}
}
}

View File

@ -1,29 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Bcat
{
enum ResultCode
{
ModuleId = 122,
ErrorCodeShift = 9,
Success = 0,
InvalidArgument = (1 << ErrorCodeShift) | ModuleId,
NotFound = (2 << ErrorCodeShift) | ModuleId,
TargetLocked = (3 << ErrorCodeShift) | ModuleId,
TargetAlreadyMounted = (4 << ErrorCodeShift) | ModuleId,
TargetNotMounted = (5 << ErrorCodeShift) | ModuleId,
AlreadyOpen = (6 << ErrorCodeShift) | ModuleId,
NotOpen = (7 << ErrorCodeShift) | ModuleId,
InternetRequestDenied = (8 << ErrorCodeShift) | ModuleId,
ServiceOpenLimitReached = (9 << ErrorCodeShift) | ModuleId,
SaveDataNotFound = (10 << ErrorCodeShift) | ModuleId,
NetworkServiceAccountNotAvailable = (31 << ErrorCodeShift) | ModuleId,
PassphrasePathNotFound = (80 << ErrorCodeShift) | ModuleId,
DataVerificationFailed = (81 << ErrorCodeShift) | ModuleId,
PermissionDenied = (90 << ErrorCodeShift) | ModuleId,
AllocationFailed = (91 << ErrorCodeShift) | ModuleId,
InvalidOperation = (98 << ErrorCodeShift) | ModuleId,
InvalidDeliveryCacheStorageFile = (204 << ErrorCodeShift) | ModuleId,
StorageOpenLimitReached = (205 << ErrorCodeShift) | ModuleId
}
}

View File

@ -1,18 +0,0 @@
using Ryujinx.HLE.HOS.Services.Arp;
namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator
{
class IBcatService : IpcService
{
public IBcatService(ApplicationLaunchProperty applicationLaunchProperty) { }
[CommandCmif(10100)]
// RequestSyncDeliveryCache() -> object<nn::bcat::detail::ipc::IDeliveryCacheProgressService>
public ResultCode RequestSyncDeliveryCache(ServiceCtx context)
{
MakeObject(context, new IDeliveryCacheProgressService(context));
return ResultCode.Success;
}
}
}

View File

@ -1,65 +0,0 @@
using LibHac;
using LibHac.Bcat;
using LibHac.Common;
using Ryujinx.Common;
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator
{
class IDeliveryCacheDirectoryService : DisposableIpcService
{
private SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheDirectoryService> _base;
public IDeliveryCacheDirectoryService(ref SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheDirectoryService> baseService)
{
_base = SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheDirectoryService>.CreateMove(ref baseService);
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
_base.Destroy();
}
}
[CommandCmif(0)]
// Open(nn::bcat::DirectoryName)
public ResultCode Open(ServiceCtx context)
{
DirectoryName directoryName = context.RequestData.ReadStruct<DirectoryName>();
Result result = _base.Get.Open(ref directoryName);
return (ResultCode)result.Value;
}
[CommandCmif(1)]
// Read() -> (u32, buffer<nn::bcat::DeliveryCacheDirectoryEntry, 6>)
public ResultCode Read(ServiceCtx context)
{
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _base.Get.Read(out int entriesRead, MemoryMarshal.Cast<byte, DeliveryCacheDirectoryEntry>(region.Memory.Span));
context.ResponseData.Write(entriesRead);
return (ResultCode)result.Value;
}
}
[CommandCmif(2)]
// GetCount() -> u32
public ResultCode GetCount(ServiceCtx context)
{
Result result = _base.Get.GetCount(out int count);
context.ResponseData.Write(count);
return (ResultCode)result.Value;
}
}
}

View File

@ -1,78 +0,0 @@
using LibHac;
using LibHac.Bcat;
using LibHac.Common;
using Ryujinx.Common;
namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator
{
class IDeliveryCacheFileService : DisposableIpcService
{
private SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheFileService> _base;
public IDeliveryCacheFileService(ref SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheFileService> baseService)
{
_base = SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheFileService>.CreateMove(ref baseService);
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
_base.Destroy();
}
}
[CommandCmif(0)]
// Open(nn::bcat::DirectoryName, nn::bcat::FileName)
public ResultCode Open(ServiceCtx context)
{
DirectoryName directoryName = context.RequestData.ReadStruct<DirectoryName>();
FileName fileName = context.RequestData.ReadStruct<FileName>();
Result result = _base.Get.Open(ref directoryName, ref fileName);
return (ResultCode)result.Value;
}
[CommandCmif(1)]
// Read(u64) -> (u64, buffer<bytes, 6>)
public ResultCode Read(ServiceCtx context)
{
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
long offset = context.RequestData.ReadInt64();
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _base.Get.Read(out long bytesRead, offset, region.Memory.Span);
context.ResponseData.Write(bytesRead);
return (ResultCode)result.Value;
}
}
[CommandCmif(2)]
// GetSize() -> u64
public ResultCode GetSize(ServiceCtx context)
{
Result result = _base.Get.GetSize(out long size);
context.ResponseData.Write(size);
return (ResultCode)result.Value;
}
[CommandCmif(3)]
// GetDigest() -> nn::bcat::Digest
public ResultCode GetDigest(ServiceCtx context)
{
Result result = _base.Get.GetDigest(out Digest digest);
context.ResponseData.WriteStruct(digest);
return (ResultCode)result.Value;
}
}
}

View File

@ -1,63 +0,0 @@
using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator.Types;
using Ryujinx.Horizon.Common;
using System;
namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator
{
class IDeliveryCacheProgressService : IpcService
{
private KEvent _event;
private int _eventHandle;
public IDeliveryCacheProgressService(ServiceCtx context)
{
_event = new KEvent(context.Device.System.KernelContext);
}
[CommandCmif(0)]
// GetEvent() -> handle<copy>
public ResultCode GetEvent(ServiceCtx context)
{
if (_eventHandle == 0)
{
if (context.Process.HandleTable.GenerateHandle(_event.ReadableEvent, out _eventHandle) != Result.Success)
{
throw new InvalidOperationException("Out of handles!");
}
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_eventHandle);
Logger.Stub?.PrintStub(LogClass.ServiceBcat);
return ResultCode.Success;
}
[CommandCmif(1)]
// GetImpl() -> buffer<nn::bcat::detail::DeliveryCacheProgressImpl, 0x1a>
public ResultCode GetImpl(ServiceCtx context)
{
DeliveryCacheProgressImpl deliveryCacheProgress = new DeliveryCacheProgressImpl
{
State = DeliveryCacheProgressImpl.Status.Done,
Result = 0
};
ulong dcpSize = WriteDeliveryCacheProgressImpl(context, context.Request.RecvListBuff[0], deliveryCacheProgress);
context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(dcpSize);
Logger.Stub?.PrintStub(LogClass.ServiceBcat);
return ResultCode.Success;
}
private ulong WriteDeliveryCacheProgressImpl(ServiceCtx context, IpcRecvListBuffDesc ipcDesc, DeliveryCacheProgressImpl deliveryCacheProgress)
{
return MemoryHelper.Write(context.Memory, ipcDesc.Position, deliveryCacheProgress);
}
}
}

View File

@ -1,74 +0,0 @@
using LibHac;
using LibHac.Bcat;
using LibHac.Common;
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator
{
class IDeliveryCacheStorageService : DisposableIpcService
{
private SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheStorageService> _base;
public IDeliveryCacheStorageService(ServiceCtx context, ref SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheStorageService> baseService)
{
_base = SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheStorageService>.CreateMove(ref baseService);
}
[CommandCmif(0)]
// CreateFileService() -> object<nn::bcat::detail::ipc::IDeliveryCacheFileService>
public ResultCode CreateFileService(ServiceCtx context)
{
using var service = new SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheFileService>();
Result result = _base.Get.CreateFileService(ref service.Ref);
if (result.IsSuccess())
{
MakeObject(context, new IDeliveryCacheFileService(ref service.Ref));
}
return (ResultCode)result.Value;
}
[CommandCmif(1)]
// CreateDirectoryService() -> object<nn::bcat::detail::ipc::IDeliveryCacheDirectoryService>
public ResultCode CreateDirectoryService(ServiceCtx context)
{
using var service = new SharedRef<LibHac.Bcat.Impl.Ipc.IDeliveryCacheDirectoryService>();
Result result = _base.Get.CreateDirectoryService(ref service.Ref);
if (result.IsSuccess())
{
MakeObject(context, new IDeliveryCacheDirectoryService(ref service.Ref));
}
return (ResultCode)result.Value;
}
[CommandCmif(10)]
// EnumerateDeliveryCacheDirectory() -> (u32, buffer<nn::bcat::DirectoryName, 6>)
public ResultCode EnumerateDeliveryCacheDirectory(ServiceCtx context)
{
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _base.Get.EnumerateDeliveryCacheDirectory(out int count, MemoryMarshal.Cast<byte, DirectoryName>(region.Memory.Span));
context.ResponseData.Write(count);
return (ResultCode)result.Value;
}
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
_base.Destroy();
}
}
}
}

View File

@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Hid
{
[Service("hidbus")]
class IHidbusServer : IpcService
{
public IHidbusServer(ServiceCtx context) { }
}
}

View File

@ -1,49 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types
{
[StructLayout(LayoutKind.Sequential)]
struct ZbcColorArray
{
private uint element0;
private uint element1;
private uint element2;
private uint element3;
public uint this[int index]
{
get
{
if (index == 0)
{
return element0;
}
else if (index == 1)
{
return element1;
}
else if (index == 2)
{
return element2;
}
else if (index == 2)
{
return element3;
}
throw new IndexOutOfRangeException();
}
}
}
[StructLayout(LayoutKind.Sequential)]
struct ZbcSetTableArguments
{
public ZbcColorArray ColorDs;
public ZbcColorArray ColorL2;
public uint Depth;
public uint Format;
public uint Type;
}
}

View File

@ -1,17 +0,0 @@
using Ryujinx.HLE.Ui;
namespace Ryujinx.Headless.SDL2
{
internal class HeadlessHostUiTheme : IHostUiTheme
{
public string FontFamily => "sans-serif";
public ThemeColor DefaultBackgroundColor => new ThemeColor(1, 0, 0, 0);
public ThemeColor DefaultForegroundColor => new ThemeColor(1, 1, 1, 1);
public ThemeColor DefaultBorderColor => new ThemeColor(1, 1, 1, 1);
public ThemeColor SelectionBackgroundColor => new ThemeColor(1, 1, 1, 1);
public ThemeColor SelectionForegroundColor => new ThemeColor(1, 0, 0, 0);
public HeadlessHostUiTheme() { }
}
}

View File

@ -1,9 +0,0 @@
namespace Ryujinx.Headless.SDL2
{
public enum HideCursor
{
Never,
OnIdle,
Always
}
}

View File

@ -1,39 +0,0 @@
namespace Ryujinx.Horizon.Common
{
public static class KernelResult
{
private const int ModuleId = 1;
public static Result SessionCountExceeded => new Result(ModuleId, 7);
public static Result InvalidCapability => new Result(ModuleId, 14);
public static Result ThreadNotStarted => new Result(ModuleId, 57);
public static Result ThreadTerminating => new Result(ModuleId, 59);
public static Result InvalidSize => new Result(ModuleId, 101);
public static Result InvalidAddress => new Result(ModuleId, 102);
public static Result OutOfResource => new Result(ModuleId, 103);
public static Result OutOfMemory => new Result(ModuleId, 104);
public static Result HandleTableFull => new Result(ModuleId, 105);
public static Result InvalidMemState => new Result(ModuleId, 106);
public static Result InvalidPermission => new Result(ModuleId, 108);
public static Result InvalidMemRange => new Result(ModuleId, 110);
public static Result InvalidPriority => new Result(ModuleId, 112);
public static Result InvalidCpuCore => new Result(ModuleId, 113);
public static Result InvalidHandle => new Result(ModuleId, 114);
public static Result UserCopyFailed => new Result(ModuleId, 115);
public static Result InvalidCombination => new Result(ModuleId, 116);
public static Result TimedOut => new Result(ModuleId, 117);
public static Result Cancelled => new Result(ModuleId, 118);
public static Result MaximumExceeded => new Result(ModuleId, 119);
public static Result InvalidEnumValue => new Result(ModuleId, 120);
public static Result NotFound => new Result(ModuleId, 121);
public static Result InvalidThread => new Result(ModuleId, 122);
public static Result PortRemoteClosed => new Result(ModuleId, 123);
public static Result InvalidState => new Result(ModuleId, 125);
public static Result ReservedValue => new Result(ModuleId, 126);
public static Result PortClosed => new Result(ModuleId, 131);
public static Result ResLimitExceeded => new Result(ModuleId, 132);
public static Result ReceiveListBroken => new Result(ModuleId, 258);
public static Result OutOfVaSpace => new Result(ModuleId, 259);
public static Result CmdBufferTooSmall => new Result(ModuleId, 260);
}
}

View File

@ -1,14 +0,0 @@
namespace Ryujinx.Horizon
{
public struct HorizonOptions
{
public bool IgnoreMissingServices { get; }
public bool ThrowOnInvalidCommandIds { get; }
public HorizonOptions(bool ignoreMissingServices)
{
IgnoreMissingServices = ignoreMissingServices;
ThrowOnInvalidCommandIds = true;
}
}
}

View File

@ -1,44 +0,0 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Memory;
using System;
namespace Ryujinx.Horizon
{
static class HorizonStatic
{
[ThreadStatic]
private static HorizonOptions _options;
[ThreadStatic]
private static ISyscallApi _syscall;
[ThreadStatic]
private static IVirtualMemoryManager _addressSpace;
[ThreadStatic]
private static IThreadContext _threadContext;
[ThreadStatic]
private static int _threadHandle;
public static HorizonOptions Options => _options;
public static ISyscallApi Syscall => _syscall;
public static IVirtualMemoryManager AddressSpace => _addressSpace;
public static IThreadContext ThreadContext => _threadContext;
public static int CurrentThreadHandle => _threadHandle;
public static void Register(
HorizonOptions options,
ISyscallApi syscallApi,
IVirtualMemoryManager addressSpace,
IThreadContext threadContext,
int threadHandle)
{
_options = options;
_syscall = syscallApi;
_addressSpace = addressSpace;
_threadContext = threadContext;
_threadHandle = threadHandle;
}
}
}

Some files were not shown because too many files have changed in this diff Show More