Compare commits
5 Commits
Canary-1.2
...
428b1e5cea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
428b1e5cea | ||
|
|
e6f7d6e1d5 | ||
|
|
0ad5def417 | ||
|
|
f012c3fbef | ||
|
|
b69b432b4c |
4
.github/labeler.yml
vendored
4
.github/labeler.yml
vendored
@@ -18,10 +18,6 @@ gpu:
|
|||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**']
|
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**']
|
||||||
|
|
||||||
'graphics-backend:metal':
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Metal/**', 'src/Ryujinx.Graphics.Metal.SharpMetalExtensions/**']
|
|
||||||
|
|
||||||
gui:
|
gui:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**']
|
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**']
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Make sure your SDK version is higher or equal to the required version specified
|
|||||||
|
|
||||||
### Step 2
|
### Step 2
|
||||||
|
|
||||||
Either use `git clone https://github.com/Ryubing/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
Either use `git clone https://github.com/GreemDev/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
||||||
|
|
||||||
### Step 3
|
### Step 3
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ We always welcome bug reports, feature proposals and overall feedback. Here are
|
|||||||
|
|
||||||
### Finding Existing Issues
|
### Finding Existing Issues
|
||||||
|
|
||||||
Before filing a new issue, please search our [open issues](https://github.com/Ryubing/Ryujinx/issues) to check if it already exists.
|
Before filing a new issue, please search our [open issues](https://github.com/GreemDev/Ryujinx/issues) to check if it already exists.
|
||||||
|
|
||||||
If you do find an existing issue, please include your own feedback in the discussion. Do consider upvoting (👍 reaction) the original post, as this helps us prioritize popular issues in our backlog.
|
If you do find an existing issue, please include your own feedback in the discussion. Do consider upvoting (👍 reaction) the original post, as this helps us prioritize popular issues in our backlog.
|
||||||
|
|
||||||
### Writing a Good Feature Request
|
### Writing a Good Feature Request
|
||||||
|
|
||||||
Please review any feature requests already opened to both check it has not already been suggested, and to familiarize yourself with the format. When ready to submit a proposal, please use the [Feature Request issue template](https://github.com/Ryubing/Ryujinx/issues/new?assignees=&labels=&projects=&template=feature_request.yml&title=%5BFeature+Request%5D).
|
Please review any feature requests already opened to both check it has not already been suggested, and to familiarize yourself with the format. When ready to submit a proposal, please use the [Feature Request issue template](https://github.com/GreemDev/Ryujinx/issues/new?assignees=&labels=&projects=&template=feature_request.yml&title=%5BFeature+Request%5D).
|
||||||
|
|
||||||
### Writing a Good Bug Report
|
### Writing a Good Bug Report
|
||||||
|
|
||||||
@@ -34,13 +34,13 @@ Ideally, a bug report should contain the following information:
|
|||||||
* A Ryujinx log file of the run instance where the issue occurred. Log files can be found in `[Executable Folder]/Logs` and are named chronologically.
|
* A Ryujinx log file of the run instance where the issue occurred. Log files can be found in `[Executable Folder]/Logs` and are named chronologically.
|
||||||
* Additional information, e.g. is it a regression from previous versions? Are there any known workarounds?
|
* Additional information, e.g. is it a regression from previous versions? Are there any known workarounds?
|
||||||
|
|
||||||
When ready to submit a bug report, please use the [Bug Report issue template](https://github.com/Ryubing/Ryujinx/issues/new?assignees=&labels=bug&projects=&template=bug_report.yml&title=%5BBug%5D).
|
When ready to submit a bug report, please use the [Bug Report issue template](https://github.com/GreemDev/Ryujinx/issues/new?assignees=&labels=bug&projects=&template=bug_report.yml&title=%5BBug%5D).
|
||||||
|
|
||||||
## Contributing Changes
|
## Contributing Changes
|
||||||
|
|
||||||
Project maintainers will merge changes that both improve the project and meet our standards for code quality.
|
Project maintainers will merge changes that both improve the project and meet our standards for code quality.
|
||||||
|
|
||||||
The [Pull Request Guide](docs/workflow/pr-guide.md) and [License](https://github.com/Ryubing/Ryujinx/blob/master/LICENSE.txt) docs define additional guidance.
|
The [Pull Request Guide](docs/workflow/pr-guide.md) and [License](https://github.com/GreemDev/Ryujinx/blob/master/LICENSE.txt) docs define additional guidance.
|
||||||
|
|
||||||
### DOs and DON'Ts
|
### DOs and DON'Ts
|
||||||
|
|
||||||
@@ -74,14 +74,14 @@ We use and recommend the following workflow:
|
|||||||
3. In your fork, create a branch off of main (`git checkout -b mybranch`).
|
3. In your fork, create a branch off of main (`git checkout -b mybranch`).
|
||||||
- Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork.
|
- Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork.
|
||||||
4. Make and commit your changes to your branch.
|
4. Make and commit your changes to your branch.
|
||||||
- [Build Instructions](https://github.com/Ryubing/Ryujinx/blob/master/COMPILING.md) explains how to build and test.
|
- [Build Instructions](https://github.com/GreemDev/Ryujinx/blob/master/COMPILING.md) explains how to build and test.
|
||||||
- Commit messages should be clear statements of action and intent.
|
- Commit messages should be clear statements of action and intent.
|
||||||
6. Build the repository with your changes.
|
6. Build the repository with your changes.
|
||||||
- Make sure that the builds are clean.
|
- Make sure that the builds are clean.
|
||||||
- Make sure that `dotnet format` has been run and any corrections tested and committed.
|
- Make sure that `dotnet format` has been run and any corrections tested and committed.
|
||||||
7. Create a pull request (PR) against the Ryujinx/Ryujinx repository's **main** branch.
|
7. Create a pull request (PR) against the Ryujinx/Ryujinx repository's **main** branch.
|
||||||
- State in the description what issue or improvement your change is addressing.
|
- State in the description what issue or improvement your change is addressing.
|
||||||
- Check if all the Continuous Integration checks are passing. Refer to [Actions](https://github.com/Ryubing/Ryujinx/actions) to check for outstanding errors.
|
- Check if all the Continuous Integration checks are passing. Refer to [Actions](https://github.com/GreemDev/Ryujinx/actions) to check for outstanding errors.
|
||||||
8. Wait for feedback or approval of your changes from the core development team
|
8. Wait for feedback or approval of your changes from the core development team
|
||||||
- Details about the pull request [review procedure](docs/workflow/pr-guide.md).
|
- Details about the pull request [review procedure](docs/workflow/pr-guide.md).
|
||||||
9. When the team members have signed off, and all checks are green, your PR will be merged.
|
9. When the team members have signed off, and all checks are green, your PR will be merged.
|
||||||
@@ -90,7 +90,7 @@ We use and recommend the following workflow:
|
|||||||
|
|
||||||
### Good First Issues
|
### Good First Issues
|
||||||
|
|
||||||
The team marks the most straightforward issues as [good first issues](https://github.com/Ryubing/Ryujinx/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). This set of issues is the place to start if you are interested in contributing but new to the codebase.
|
The team marks the most straightforward issues as [good first issues](https://github.com/GreemDev/Ryujinx/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). This set of issues is the place to start if you are interested in contributing but new to the codebase.
|
||||||
|
|
||||||
### Commit Messages
|
### Commit Messages
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ Also do your best to factor commits appropriately, not too large with unrelated
|
|||||||
|
|
||||||
### PR - CI Process
|
### PR - CI Process
|
||||||
|
|
||||||
The [Ryujinx continuous integration](https://github.com/Ryubing/Ryujinx/actions) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean or have bugs properly filed against flaky/unexpected failures that are unrelated to your change.
|
The [Ryujinx continuous integration](https://github.com/GreemDev/Ryujinx/actions) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean or have bugs properly filed against flaky/unexpected failures that are unrelated to your change.
|
||||||
|
|
||||||
If the CI build fails for any reason, the PR actions tab should be consulted for further information on the failure. There are a few usual suspects for such a failure:
|
If the CI build fails for any reason, the PR actions tab should be consulted for further information on the failure. There are a few usual suspects for such a failure:
|
||||||
* `dotnet format` has not been run on the PR and has outstanding stylistic issues.
|
* `dotnet format` has not been run on the PR and has outstanding stylistic issues.
|
||||||
@@ -134,5 +134,5 @@ Ryujinx uses some implementations and frameworks from other projects. The follow
|
|||||||
|
|
||||||
- The license of the file is [permissive](https://en.wikipedia.org/wiki/Permissive_free_software_licence).
|
- The license of the file is [permissive](https://en.wikipedia.org/wiki/Permissive_free_software_licence).
|
||||||
- The license of the file is left in-tact.
|
- The license of the file is left in-tact.
|
||||||
- The contribution is correctly attributed in the [3rd party notices](https://github.com/Ryubing/Ryujinx/blob/master/distribution/legal/THIRDPARTY.md) file in the repository, as needed.
|
- The contribution is correctly attributed in the [3rd party notices](https://github.com/GreemDev/Ryujinx/blob/master/distribution/legal/THIRDPARTY.md) file in the repository, as needed.
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||||
<PackageVersion Include="Gommon" Version="2.7.1" />
|
<PackageVersion Include="Gommon" Version="2.7.0.2" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="Sep" Version="0.6.0" />
|
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
|
|||||||
23
README.md
23
README.md
@@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
# Ryujinx
|
# Ryujinx
|
||||||
|
|
||||||
[](https://github.com/Ryubing/Ryujinx/actions/workflows/release.yml)
|
[](https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml)
|
||||||
[](https://github.com/Ryubing/Ryujinx/releases/latest)
|
[](https://github.com/GreemDev/Ryujinx/releases/latest)
|
||||||
<br>
|
<br>
|
||||||
[](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml)
|
[](https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml)
|
||||||
[](https://github.com/Ryubing/Ryujinx-Canary/releases/latest)
|
[](https://github.com/GreemDev/Ryujinx-Canary/releases/latest)
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
Ryujinx is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#.
|
Ryujinx is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#.
|
||||||
This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds.
|
This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds.
|
||||||
It was written from scratch and development on the project began in September 2017.
|
It was written from scratch and development on the project began in September 2017.
|
||||||
Ryujinx is available on GitHub under the <a href="https://github.com/Ryubing/Ryujinx/blob/master/LICENSE.txt" target="_blank">MIT license</a>.
|
Ryujinx is available on GitHub under the <a href="https://github.com/GreemDev/Ryujinx/blob/master/LICENSE.txt" target="_blank">MIT license</a>.
|
||||||
<br />
|
<br />
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<br>
|
<br>
|
||||||
This is not a Ryujinx revival project. This is not a Phoenix project.
|
This is not a Ryujinx revival project. This is not a Phoenix project.
|
||||||
<br>
|
<br>
|
||||||
Guides and documentation can be found on the <a href="https://github.com/Ryubing/Ryujinx/wiki">Wiki tab</a>.
|
Guides and documentation can be found on the <a href="https://github.com/GreemDev/Ryujinx/wiki">Wiki tab</a>.
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
If you would like a more preservative fork of Ryujinx, check out <a href="https://github.com/ryujinx-mirror/ryujinx">ryujinx-mirror</a>.
|
If you would like a more preservative fork of Ryujinx, check out <a href="https://github.com/ryujinx-mirror/ryujinx">ryujinx-mirror</a>.
|
||||||
@@ -54,17 +54,16 @@ failing to meet this requirement may result in a poor gameplay experience or une
|
|||||||
|
|
||||||
## Latest build
|
## Latest build
|
||||||
|
|
||||||
Stable builds are made every so often, based on the `master` branch, that then gets put into the releases you know and love.
|
Stable builds are made every so often onto a separate "release" branch that then gets put into the releases you know and love.
|
||||||
These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
|
These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
|
||||||
They are released every month or so, to ensure consistent updates, while not being an annoying amount of individual updates to download over the course of that month.
|
|
||||||
|
|
||||||
You can find the latest stable release [here](https://github.com/Ryubing/Ryujinx/releases/latest).
|
You can find the latest stable release [here](https://github.com/GreemDev/Ryujinx/releases/latest).
|
||||||
|
|
||||||
Canary builds are compiled automatically for each commit on the `master` branch.
|
Canary builds are compiled automatically for each commit on the master branch.
|
||||||
While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**.
|
While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**.
|
||||||
These canary builds are only recommended for experienced users.
|
These canary builds are only recommended for experienced users.
|
||||||
|
|
||||||
You can find the latest canary release [here](https://github.com/Ryubing/Ryujinx-Canary/releases/latest).
|
You can find the latest canary release [here](https://github.com/GreemDev/Ryujinx-Canary/releases/latest).
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
@@ -110,7 +109,7 @@ If you are planning to contribute or just want to learn more about this project
|
|||||||
- **Configuration**
|
- **Configuration**
|
||||||
|
|
||||||
The emulator has settings for enabling or disabling some logging, remapping controllers, and more.
|
The emulator has settings for enabling or disabling some logging, remapping controllers, and more.
|
||||||
You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the Ryujinx data folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
|
You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the user folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -18,13 +18,13 @@ To merge pull requests, you must have write permissions in the repository.
|
|||||||
|
|
||||||
## Pull Request Ownership
|
## Pull Request Ownership
|
||||||
|
|
||||||
Every pull request will automatically have labels and reviewers assigned. The label not only indicates the code segment which the change touches but also the area reviewers to be assigned.
|
Every pull request will have automatically have labels and reviewers assigned. The label not only indicates the code segment which the change touches but also the area reviewers to be assigned.
|
||||||
|
|
||||||
If during the code review process a merge conflict occurs, the PR author is responsible for its resolution. Help will be provided if necessary although GitHub makes this easier by allowing simple conflict resolution using the [conflict-editor](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github).
|
If during the code review process a merge conflict occurs, the PR author is responsible for its resolution. Help will be provided if necessary although GitHub makes this easier by allowing simple conflict resolution using the [conflict-editor](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github).
|
||||||
|
|
||||||
## Pull Request Builds
|
## Pull Request Builds
|
||||||
|
|
||||||
When submitting a PR to the `Ryubing/Ryujinx` repository, various builds will run validating many areas to ensure we keep developer productivity and product quality high. These various workflows can be tracked in the [Actions](https://github.com/Ryubing/Ryujinx/actions) tab of the repository. If the job continues to completion, the build artifacts will be uploaded and posted as a comment in the PR discussion.
|
When submitting a PR to the `GreemDev/Ryujinx` repository, various builds will run validating many areas to ensure we keep developer productivity and product quality high. These various workflows can be tracked in the [Actions](https://github.com/GreemDev/Ryujinx/actions) tab of the repository. If the job continues to completion, the build artifacts will be uploaded and posted as a comment in the PR discussion.
|
||||||
|
|
||||||
## Review Turnaround Times
|
## Review Turnaround Times
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ Anyone with write access can merge a pull request manually when the following co
|
|||||||
|
|
||||||
* The PR has been approved by two reviewers and any other objections are addressed.
|
* The PR has been approved by two reviewers and any other objections are addressed.
|
||||||
* You can request follow up reviews from the original reviewers if they requested changes.
|
* You can request follow up reviews from the original reviewers if they requested changes.
|
||||||
* The PR successfully builds and passes all tests in the Continuous Integration (CI) system. In case of failures, refer to the [Actions](https://github.com/Ryubing/Ryujinx/actions) tab of your PR.
|
* The PR successfully builds and passes all tests in the Continuous Integration (CI) system. In case of failures, refer to the [Actions](https://github.com/GreemDev/Ryujinx/actions) tab of your PR.
|
||||||
|
|
||||||
Typically, PRs are merged as one commit (squash merges). It creates a simpler history than a Merge Commit. "Special circumstances" are rare, and typically mean that there are a series of cleanly separated changes that will be too hard to understand if squashed together, or for some reason we want to preserve the ability to dissect them.
|
Typically, PRs are merged as one commit (squash merges). It creates a simpler history than a Merge Commit. "Special circumstances" are rare, and typically mean that there are a series of cleanly separated changes that will be too hard to understand if squashed together, or for some reason we want to preserve the ability to dissect them.
|
||||||
|
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
public static void RunPass(ControlFlowGraph cfg)
|
public static void RunPass(ControlFlowGraph cfg)
|
||||||
{
|
{
|
||||||
Dictionary<ulong, Operand> constants = new();
|
var constants = new Dictionary<ulong, Operand>();
|
||||||
|
|
||||||
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
|
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
|
||||||
{
|
{
|
||||||
// If the constant has many uses, we also force a new constant mov to be added, in order
|
// If the constant has many uses, we also force a new constant mov to be added, in order
|
||||||
// to avoid overflow of the counts field (that is limited to 16 bits).
|
// to avoid overflow of the counts field (that is limited to 16 bits).
|
||||||
if (!constants.TryGetValue(source.Value, out Operand constant) || constant.UsesCount > MaxConstantUses)
|
if (!constants.TryGetValue(source.Value, out var constant) || constant.UsesCount > MaxConstantUses)
|
||||||
{
|
{
|
||||||
constant = Local(source.Type);
|
constant = Local(source.Type);
|
||||||
|
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
public void Cset(Operand rd, ArmCondition condition)
|
public void Cset(Operand rd, ArmCondition condition)
|
||||||
{
|
{
|
||||||
Operand zr = Factory.Register(ZrRegister, RegisterType.Integer, rd.Type);
|
var zr = Factory.Register(ZrRegister, RegisterType.Integer, rd.Type);
|
||||||
Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1));
|
Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
long target = _stream.Position;
|
long target = _stream.Position;
|
||||||
|
|
||||||
if (_pendingBranches.TryGetValue(block, out List<(ArmCondition Condition, long BranchPos)> list))
|
if (_pendingBranches.TryGetValue(block, out var list))
|
||||||
{
|
{
|
||||||
foreach ((ArmCondition condition, long branchPos) in list)
|
foreach ((ArmCondition condition, long branchPos) in list)
|
||||||
{
|
{
|
||||||
@@ -119,7 +119,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!_pendingBranches.TryGetValue(target, out List<(ArmCondition Condition, long BranchPos)> list))
|
if (!_pendingBranches.TryGetValue(target, out var list))
|
||||||
{
|
{
|
||||||
list = new List<(ArmCondition, long)>();
|
list = new List<(ArmCondition, long)>();
|
||||||
_pendingBranches.Add(target, list);
|
_pendingBranches.Add(target, list);
|
||||||
|
|||||||
@@ -322,7 +322,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
ArmCondition cond = ((Comparison)comp.AsInt32()).ToArmCondition();
|
var cond = ((Comparison)comp.AsInt32()).ToArmCondition();
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
@@ -354,7 +354,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Debug.Assert(dest.Type == OperandType.I32);
|
Debug.Assert(dest.Type == OperandType.I32);
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
ArmCondition cond = ((Comparison)comp.AsInt32()).ToArmCondition();
|
var cond = ((Comparison)comp.AsInt32()).ToArmCondition();
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
|
|||||||
@@ -847,7 +847,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
Comparison compType = (Comparison)comp.AsInt32();
|
var compType = (Comparison)comp.AsInt32();
|
||||||
|
|
||||||
return compType == Comparison.Equal || compType == Comparison.NotEqual;
|
return compType == Comparison.Equal || compType == Comparison.NotEqual;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace ARMeilleure.CodeGen.Linking
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets an empty <see cref="RelocInfo"/>.
|
/// Gets an empty <see cref="RelocInfo"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static RelocInfo Empty { get; } = new(null);
|
public static RelocInfo Empty { get; } = new RelocInfo(null);
|
||||||
|
|
||||||
private readonly RelocEntry[] _entries;
|
private readonly RelocEntry[] _entries;
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
{
|
{
|
||||||
NumberLocals(cfg, regMasks.RegistersCount);
|
NumberLocals(cfg, regMasks.RegistersCount);
|
||||||
|
|
||||||
AllocationContext context = new(stackAlloc, regMasks, _intervals.Count);
|
var context = new AllocationContext(stackAlloc, regMasks, _intervals.Count);
|
||||||
|
|
||||||
BuildIntervals(cfg, context);
|
BuildIntervals(cfg, context);
|
||||||
|
|
||||||
@@ -839,7 +839,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
{
|
{
|
||||||
dest.NumberLocal(_intervals.Count);
|
dest.NumberLocal(_intervals.Count);
|
||||||
|
|
||||||
LiveInterval interval = new(dest);
|
LiveInterval interval = new LiveInterval(dest);
|
||||||
_intervals.Add(interval);
|
_intervals.Add(interval);
|
||||||
|
|
||||||
SetVisited(dest);
|
SetVisited(dest);
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
{
|
{
|
||||||
if (_count + 1 > _capacity)
|
if (_count + 1 > _capacity)
|
||||||
{
|
{
|
||||||
Span<LiveInterval> oldSpan = Span;
|
var oldSpan = Span;
|
||||||
|
|
||||||
_capacity = Math.Max(4, _capacity * 2);
|
_capacity = Math.Max(4, _capacity * 2);
|
||||||
_items = Allocators.References.Allocate<LiveInterval>((uint)_capacity);
|
_items = Allocators.References.Allocate<LiveInterval>((uint)_capacity);
|
||||||
|
|
||||||
Span<LiveInterval> newSpan = Span;
|
var newSpan = Span;
|
||||||
|
|
||||||
oldSpan.CopyTo(newSpan);
|
oldSpan.CopyTo(newSpan);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
{
|
{
|
||||||
if (Count + 1 > _capacity)
|
if (Count + 1 > _capacity)
|
||||||
{
|
{
|
||||||
Span<int> oldSpan = Span;
|
var oldSpan = Span;
|
||||||
|
|
||||||
_capacity = Math.Max(4, _capacity * 2);
|
_capacity = Math.Max(4, _capacity * 2);
|
||||||
_items = Allocators.Default.Allocate<int>((uint)_capacity);
|
_items = Allocators.Default.Allocate<int>((uint)_capacity);
|
||||||
|
|
||||||
Span<int> newSpan = Span;
|
var newSpan = Span;
|
||||||
|
|
||||||
oldSpan.CopyTo(newSpan);
|
oldSpan.CopyTo(newSpan);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using ARMeilleure.CodeGen.Linking;
|
using ARMeilleure.CodeGen.Linking;
|
||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using Microsoft.IO;
|
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -1325,8 +1324,8 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
public (byte[], RelocInfo) GetCode()
|
public (byte[], RelocInfo) GetCode()
|
||||||
{
|
{
|
||||||
Span<Jump> jumps = CollectionsMarshal.AsSpan(_jumps);
|
var jumps = CollectionsMarshal.AsSpan(_jumps);
|
||||||
Span<Reloc> relocs = CollectionsMarshal.AsSpan(_relocs);
|
var relocs = CollectionsMarshal.AsSpan(_relocs);
|
||||||
|
|
||||||
// Write jump relative offsets.
|
// Write jump relative offsets.
|
||||||
bool modified;
|
bool modified;
|
||||||
@@ -1411,13 +1410,13 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
// Write the code, ignoring the dummy bytes after jumps, into a new stream.
|
// Write the code, ignoring the dummy bytes after jumps, into a new stream.
|
||||||
_stream.Seek(0, SeekOrigin.Begin);
|
_stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
using RecyclableMemoryStream codeStream = MemoryStreamManager.Shared.GetStream();
|
using var codeStream = MemoryStreamManager.Shared.GetStream();
|
||||||
Assembler assembler = new(codeStream, HasRelocs);
|
var assembler = new Assembler(codeStream, HasRelocs);
|
||||||
|
|
||||||
bool hasRelocs = HasRelocs;
|
bool hasRelocs = HasRelocs;
|
||||||
int relocIndex = 0;
|
int relocIndex = 0;
|
||||||
int relocOffset = 0;
|
int relocOffset = 0;
|
||||||
RelocEntry[] relocEntries = hasRelocs
|
var relocEntries = hasRelocs
|
||||||
? new RelocEntry[relocs.Length]
|
? new RelocEntry[relocs.Length]
|
||||||
: Array.Empty<RelocEntry>();
|
: Array.Empty<RelocEntry>();
|
||||||
|
|
||||||
@@ -1470,8 +1469,8 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
_stream.CopyTo(codeStream);
|
_stream.CopyTo(codeStream);
|
||||||
|
|
||||||
byte[] code = codeStream.ToArray();
|
var code = codeStream.ToArray();
|
||||||
RelocInfo relocInfo = new(relocEntries);
|
var relocInfo = new RelocInfo(relocEntries);
|
||||||
|
|
||||||
return (code, relocInfo);
|
return (code, relocInfo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -623,7 +623,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
X86Condition cond = ((Comparison)comp.AsInt32()).ToX86Condition();
|
var cond = ((Comparison)comp.AsInt32()).ToX86Condition();
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
@@ -661,7 +661,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Debug.Assert(dest.Type == OperandType.I32);
|
Debug.Assert(dest.Type == OperandType.I32);
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
X86Condition cond = ((Comparison)comp.AsInt32()).ToX86Condition();
|
var cond = ((Comparison)comp.AsInt32()).ToX86Condition();
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
memGetXcr0.Reprotect(0, (ulong)asmGetXcr0.Length, MemoryPermission.ReadAndExecute);
|
memGetXcr0.Reprotect(0, (ulong)asmGetXcr0.Length, MemoryPermission.ReadAndExecute);
|
||||||
|
|
||||||
GetXcr0 fGetXcr0 = Marshal.GetDelegateForFunctionPointer<GetXcr0>(memGetXcr0.Pointer);
|
var fGetXcr0 = Marshal.GetDelegateForFunctionPointer<GetXcr0>(memGetXcr0.Pointer);
|
||||||
|
|
||||||
return fGetXcr0();
|
return fGetXcr0();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -759,7 +759,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
Comparison compType = (Comparison)comp.AsInt32();
|
var compType = (Comparison)comp.AsInt32();
|
||||||
|
|
||||||
return compType == Comparison.Equal || compType == Comparison.NotEqual;
|
return compType == Comparison.Equal || compType == Comparison.NotEqual;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
public static void RunPass(ControlFlowGraph cfg)
|
public static void RunPass(ControlFlowGraph cfg)
|
||||||
{
|
{
|
||||||
Dictionary<ulong, Operand> constants = new();
|
var constants = new Dictionary<ulong, Operand>();
|
||||||
|
|
||||||
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
|
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
|
||||||
{
|
{
|
||||||
// If the constant has many uses, we also force a new constant mov to be added, in order
|
// If the constant has many uses, we also force a new constant mov to be added, in order
|
||||||
// to avoid overflow of the counts field (that is limited to 16 bits).
|
// to avoid overflow of the counts field (that is limited to 16 bits).
|
||||||
if (!constants.TryGetValue(source.Value, out Operand constant) || constant.UsesCount > MaxConstantUses)
|
if (!constants.TryGetValue(source.Value, out var constant) || constant.UsesCount > MaxConstantUses)
|
||||||
{
|
{
|
||||||
constant = Local(source.Type);
|
constant = Local(source.Type);
|
||||||
|
|
||||||
|
|||||||
@@ -129,13 +129,13 @@ namespace ARMeilleure.Common
|
|||||||
|
|
||||||
if (count > _count)
|
if (count > _count)
|
||||||
{
|
{
|
||||||
long* oldMask = _masks;
|
var oldMask = _masks;
|
||||||
Span<long> oldSpan = new(_masks, _count);
|
var oldSpan = new Span<long>(_masks, _count);
|
||||||
|
|
||||||
_masks = _allocator.Allocate<long>((uint)count);
|
_masks = _allocator.Allocate<long>((uint)count);
|
||||||
_count = count;
|
_count = count;
|
||||||
|
|
||||||
Span<long> newSpan = new(_masks, _count);
|
var newSpan = new Span<long>(_masks, _count);
|
||||||
|
|
||||||
oldSpan.CopyTo(newSpan);
|
oldSpan.CopyTo(newSpan);
|
||||||
newSpan[oldSpan.Length..].Clear();
|
newSpan[oldSpan.Length..].Clear();
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace ARMeilleure.Common
|
|||||||
}
|
}
|
||||||
|
|
||||||
int index = _freeHint++;
|
int index = _freeHint++;
|
||||||
Span<TEntry> page = GetPage(index);
|
var page = GetPage(index);
|
||||||
|
|
||||||
_allocated.Set(index);
|
_allocated.Set(index);
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ namespace ARMeilleure.Common
|
|||||||
throw new ArgumentException("Entry at the specified index was not allocated", nameof(index));
|
throw new ArgumentException("Entry at the specified index was not allocated", nameof(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<TEntry> page = GetPage(index);
|
var page = GetPage(index);
|
||||||
|
|
||||||
return ref GetValue(page, index);
|
return ref GetValue(page, index);
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ namespace ARMeilleure.Common
|
|||||||
/// <returns>Page for the specified <see cref="index"/></returns>
|
/// <returns>Page for the specified <see cref="index"/></returns>
|
||||||
private unsafe Span<TEntry> GetPage(int index)
|
private unsafe Span<TEntry> GetPage(int index)
|
||||||
{
|
{
|
||||||
int pageIndex = (int)((uint)(index & ~(_pageCapacity - 1)) >> _pageLogCapacity);
|
var pageIndex = (int)((uint)(index & ~(_pageCapacity - 1)) >> _pageLogCapacity);
|
||||||
|
|
||||||
if (!_pages.TryGetValue(pageIndex, out nint page))
|
if (!_pages.TryGetValue(pageIndex, out nint page))
|
||||||
{
|
{
|
||||||
@@ -168,7 +168,7 @@ namespace ARMeilleure.Common
|
|||||||
{
|
{
|
||||||
_allocated.Dispose();
|
_allocated.Dispose();
|
||||||
|
|
||||||
foreach (IntPtr page in _pages.Values)
|
foreach (var page in _pages.Values)
|
||||||
{
|
{
|
||||||
NativeAllocator.Instance.Free((void*)page);
|
NativeAllocator.Instance.Free((void*)page);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace ARMeilleure.Decoders
|
|||||||
|
|
||||||
public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
|
public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
|
||||||
{
|
{
|
||||||
int opc = (opCode >> 16) & 0xf;
|
var opc = (opCode >> 16) & 0xf;
|
||||||
|
|
||||||
if ((opc & 0b1) == 1)
|
if ((opc & 0b1) == 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace ARMeilleure.Decoders
|
|||||||
Op = (opCode >> 20) & 0x1;
|
Op = (opCode >> 20) & 0x1;
|
||||||
U = ((opCode >> 23) & 1) != 0;
|
U = ((opCode >> 23) & 1) != 0;
|
||||||
|
|
||||||
int opc = (((opCode >> 23) & 1) << 4) | (((opCode >> 21) & 0x3) << 2) | ((opCode >> 5) & 0x3);
|
var opc = (((opCode >> 23) & 1) << 4) | (((opCode >> 21) & 0x3) << 2) | ((opCode >> 5) & 0x3);
|
||||||
|
|
||||||
if ((opc & 0b01000) == 0b01000)
|
if ((opc & 0b01000) == 0b01000)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace ARMeilleure.Decoders
|
|||||||
}
|
}
|
||||||
else if (DataOp == DataOp.Logical)
|
else if (DataOp == DataOp.Logical)
|
||||||
{
|
{
|
||||||
DecoderHelper.BitMask bm = DecoderHelper.DecodeBitMask(opCode, true);
|
var bm = DecoderHelper.DecodeBitMask(opCode, true);
|
||||||
|
|
||||||
if (bm.IsUndefined)
|
if (bm.IsUndefined)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace ARMeilleure.Decoders
|
|||||||
|
|
||||||
public OpCodeBfm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
public OpCodeBfm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
{
|
{
|
||||||
DecoderHelper.BitMask bm = DecoderHelper.DecodeBitMask(opCode, false);
|
var bm = DecoderHelper.DecodeBitMask(opCode, false);
|
||||||
|
|
||||||
if (bm.IsUndefined)
|
if (bm.IsUndefined)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ namespace ARMeilleure.Decoders.Optimizations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Block> newBlocks = new(blocks.Count);
|
var newBlocks = new List<Block>(blocks.Count);
|
||||||
|
|
||||||
// Finally, rebuild decoded block list, ignoring blocks outside the contiguous range.
|
// Finally, rebuild decoded block list, ignoring blocks outside the contiguous range.
|
||||||
for (int i = 0; i < blocks.Count; i++)
|
for (int i = 0; i < blocks.Count; i++)
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ namespace ARMeilleure.Diagnostics
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OperandKind.Memory:
|
case OperandKind.Memory:
|
||||||
MemoryOperand memOp = operand.GetMemory();
|
var memOp = operand.GetMemory();
|
||||||
|
|
||||||
_builder.Append('[');
|
_builder.Append('[');
|
||||||
|
|
||||||
@@ -285,7 +285,7 @@ namespace ARMeilleure.Diagnostics
|
|||||||
|
|
||||||
public static string GetDump(ControlFlowGraph cfg)
|
public static string GetDump(ControlFlowGraph cfg)
|
||||||
{
|
{
|
||||||
IRDumper dumper = new(1);
|
var dumper = new IRDumper(1);
|
||||||
|
|
||||||
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
|
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
||||||
|
|
||||||
int msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
|
var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
|
||||||
|
|
||||||
Operand n = GetIntA32(context, op.Rn);
|
Operand n = GetIntA32(context, op.Rn);
|
||||||
Operand res = context.ShiftRightSI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
|
Operand res = context.ShiftRightSI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
|
||||||
@@ -547,7 +547,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
||||||
|
|
||||||
int msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
|
var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
|
||||||
|
|
||||||
Operand n = GetIntA32(context, op.Rn);
|
Operand n = GetIntA32(context, op.Rn);
|
||||||
Operand res = context.ShiftRightUI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
|
Operand res = context.ShiftRightUI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using ARMeilleure.CodeGen.Linking;
|
using ARMeilleure.CodeGen.Linking;
|
||||||
using ARMeilleure.Common;
|
|
||||||
using ARMeilleure.Decoders;
|
using ARMeilleure.Decoders;
|
||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
@@ -194,7 +193,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand hostAddress;
|
Operand hostAddress;
|
||||||
|
|
||||||
IAddressTable<ulong> table = context.FunctionTable;
|
var table = context.FunctionTable;
|
||||||
|
|
||||||
// If address is mapped onto the function table, we can skip the table walk. Otherwise we fallback
|
// If address is mapped onto the function table, we can skip the table walk. Otherwise we fallback
|
||||||
// onto the dispatch stub.
|
// onto the dispatch stub.
|
||||||
@@ -219,7 +218,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
for (int i = 0; i < table.Levels.Length; i++)
|
for (int i = 0; i < table.Levels.Length; i++)
|
||||||
{
|
{
|
||||||
AddressTableLevel level = table.Levels[i];
|
var level = table.Levels[i];
|
||||||
int clearBits = 64 - (level.Index + level.Length);
|
int clearBits = 64 - (level.Index + level.Length);
|
||||||
|
|
||||||
Operand index = context.ShiftLeft(
|
Operand index = context.ShiftLeft(
|
||||||
|
|||||||
@@ -143,8 +143,8 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand address = context.Copy(GetIntA32(context, op.Rn));
|
Operand address = context.Copy(GetIntA32(context, op.Rn));
|
||||||
|
|
||||||
bool exclusive = (accType & AccessType.Exclusive) != 0;
|
var exclusive = (accType & AccessType.Exclusive) != 0;
|
||||||
bool ordered = (accType & AccessType.Ordered) != 0;
|
var ordered = (accType & AccessType.Ordered) != 0;
|
||||||
|
|
||||||
if ((accType & AccessType.Load) != 0)
|
if ((accType & AccessType.Load) != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
private static Operand ZerosOrOnes(ArmEmitterContext context, Operand fromBool, OperandType baseType)
|
private static Operand ZerosOrOnes(ArmEmitterContext context, Operand fromBool, OperandType baseType)
|
||||||
{
|
{
|
||||||
Operand ones = (baseType == OperandType.I64) ? Const(-1L) : Const(-1);
|
var ones = (baseType == OperandType.I64) ? Const(-1L) : Const(-1);
|
||||||
|
|
||||||
return context.ConditionalSelect(fromBool, ones, Const(baseType, 0L));
|
return context.ConditionalSelect(fromBool, ones, Const(baseType, 0L));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,15 +118,15 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
OpCode32SimdCvtFFixed op = (OpCode32SimdCvtFFixed)context.CurrOp;
|
OpCode32SimdCvtFFixed op = (OpCode32SimdCvtFFixed)context.CurrOp;
|
||||||
|
|
||||||
bool toFixed = op.Opc == 1;
|
var toFixed = op.Opc == 1;
|
||||||
int fracBits = op.Fbits;
|
int fracBits = op.Fbits;
|
||||||
bool unsigned = op.U;
|
var unsigned = op.U;
|
||||||
|
|
||||||
if (toFixed) // F32 to S32 or U32 (fixed)
|
if (toFixed) // F32 to S32 or U32 (fixed)
|
||||||
{
|
{
|
||||||
EmitVectorUnaryOpF32(context, (op1) =>
|
EmitVectorUnaryOpF32(context, (op1) =>
|
||||||
{
|
{
|
||||||
Operand scaledValue = context.Multiply(op1, ConstF(MathF.Pow(2f, fracBits)));
|
var scaledValue = context.Multiply(op1, ConstF(MathF.Pow(2f, fracBits)));
|
||||||
MethodInfo info = unsigned ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32));
|
MethodInfo info = unsigned ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32));
|
||||||
|
|
||||||
return context.Call(info, scaledValue);
|
return context.Call(info, scaledValue);
|
||||||
@@ -136,7 +136,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
EmitVectorUnaryOpI32(context, (op1) =>
|
EmitVectorUnaryOpI32(context, (op1) =>
|
||||||
{
|
{
|
||||||
Operand floatValue = unsigned ? context.ConvertToFPUI(OperandType.FP32, op1) : context.ConvertToFP(OperandType.FP32, op1);
|
var floatValue = unsigned ? context.ConvertToFPUI(OperandType.FP32, op1) : context.ConvertToFP(OperandType.FP32, op1);
|
||||||
|
|
||||||
return context.Multiply(floatValue, ConstF(1f / MathF.Pow(2f, fracBits)));
|
return context.Multiply(floatValue, ConstF(1f / MathF.Pow(2f, fracBits)));
|
||||||
}, !unsigned);
|
}, !unsigned);
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
if (op.Replicate)
|
if (op.Replicate)
|
||||||
{
|
{
|
||||||
int regs = (count > 1) ? 1 : op.Increment;
|
var regs = (count > 1) ? 1 : op.Increment;
|
||||||
for (int reg = 0; reg < regs; reg++)
|
for (int reg = 0; reg < regs; reg++)
|
||||||
{
|
{
|
||||||
int dreg = reg + d;
|
int dreg = reg + d;
|
||||||
|
|||||||
@@ -1538,7 +1538,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else if (MathF.Abs(value) < MathF.Pow(2f, -128))
|
else if (MathF.Abs(value) < MathF.Pow(2f, -128))
|
||||||
{
|
{
|
||||||
bool overflowToInf = fpcr.GetRoundingMode() switch
|
var overflowToInf = fpcr.GetRoundingMode() switch
|
||||||
{
|
{
|
||||||
FPRoundingMode.ToNearest => true,
|
FPRoundingMode.ToNearest => true,
|
||||||
FPRoundingMode.TowardsPlusInfinity => !sign,
|
FPRoundingMode.TowardsPlusInfinity => !sign,
|
||||||
@@ -3073,7 +3073,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else if (Math.Abs(value) < Math.Pow(2d, -1024))
|
else if (Math.Abs(value) < Math.Pow(2d, -1024))
|
||||||
{
|
{
|
||||||
bool overflowToInf = fpcr.GetRoundingMode() switch
|
var overflowToInf = fpcr.GetRoundingMode() switch
|
||||||
{
|
{
|
||||||
FPRoundingMode.ToNearest => true,
|
FPRoundingMode.ToNearest => true,
|
||||||
FPRoundingMode.TowardsPlusInfinity => !sign,
|
FPRoundingMode.TowardsPlusInfinity => !sign,
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
ushort newCount = checked((ushort)(count + 1));
|
ushort newCount = checked((ushort)(count + 1));
|
||||||
ushort newCapacity = (ushort)Math.Min(capacity * 2, ushort.MaxValue);
|
ushort newCapacity = (ushort)Math.Min(capacity * 2, ushort.MaxValue);
|
||||||
|
|
||||||
Span<T> oldSpan = new(data, count);
|
var oldSpan = new Span<T>(data, count);
|
||||||
|
|
||||||
capacity = newCapacity;
|
capacity = newCapacity;
|
||||||
data = Allocators.References.Allocate<T>(capacity);
|
data = Allocators.References.Allocate<T>(capacity);
|
||||||
@@ -338,7 +338,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
throw new OverflowException();
|
throw new OverflowException();
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<T> oldSpan = new(data, (int)count);
|
var oldSpan = new Span<T>(data, (int)count);
|
||||||
|
|
||||||
capacity = newCapacity;
|
capacity = newCapacity;
|
||||||
data = Allocators.References.Allocate<T>(capacity);
|
data = Allocators.References.Allocate<T>(capacity);
|
||||||
@@ -352,7 +352,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
|
|
||||||
private static void Remove<T>(in T item, ref T* data, ref ushort count) where T : unmanaged
|
private static void Remove<T>(in T item, ref T* data, ref ushort count) where T : unmanaged
|
||||||
{
|
{
|
||||||
Span<T> span = new(data, count);
|
var span = new Span<T>(data, count);
|
||||||
|
|
||||||
for (int i = 0; i < span.Length; i++)
|
for (int i = 0; i < span.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -372,7 +372,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
|
|
||||||
private static void Remove<T>(in T item, ref T* data, ref uint count) where T : unmanaged
|
private static void Remove<T>(in T item, ref T* data, ref uint count) where T : unmanaged
|
||||||
{
|
{
|
||||||
Span<T> span = new(data, (int)count);
|
var span = new Span<T>(data, (int)count);
|
||||||
|
|
||||||
for (int i = 0; i < span.Length; i++)
|
for (int i = 0; i < span.Length; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace ARMeilleure.Signal
|
|||||||
{
|
{
|
||||||
EmitterContext context = new();
|
EmitterContext context = new();
|
||||||
|
|
||||||
Operand result = WindowsPartialUnmapHandler.EmitRetryFromAccessViolation(context);
|
var result = WindowsPartialUnmapHandler.EmitRetryFromAccessViolation(context);
|
||||||
|
|
||||||
context.Return(result);
|
context.Return(result);
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ namespace ARMeilleure.Signal
|
|||||||
{
|
{
|
||||||
EmitterContext context = new();
|
EmitterContext context = new();
|
||||||
|
|
||||||
Operand result = WindowsPartialUnmapHandler.EmitThreadLocalMapIntGetOrReserve(context, structPtr, context.LoadArgument(OperandType.I32, 0), context.LoadArgument(OperandType.I32, 1));
|
var result = WindowsPartialUnmapHandler.EmitThreadLocalMapIntGetOrReserve(context, structPtr, context.LoadArgument(OperandType.I32, 0), context.LoadArgument(OperandType.I32, 1));
|
||||||
|
|
||||||
context.Return(result);
|
context.Return(result);
|
||||||
|
|
||||||
|
|||||||
@@ -100,13 +100,13 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
return null; // Not found.
|
return null; // Not found.
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeGen.Unwinding.UnwindInfo unwindInfo = funcEntry.UnwindInfo;
|
var unwindInfo = funcEntry.UnwindInfo;
|
||||||
|
|
||||||
int codeIndex = 0;
|
int codeIndex = 0;
|
||||||
|
|
||||||
for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--)
|
for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--)
|
||||||
{
|
{
|
||||||
UnwindPushEntry entry = unwindInfo.PushEntries[index];
|
var entry = unwindInfo.PushEntries[index];
|
||||||
|
|
||||||
switch (entry.PseudoOp)
|
switch (entry.PseudoOp)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
RemoveUnreachableBlocks(Blocks);
|
RemoveUnreachableBlocks(Blocks);
|
||||||
|
|
||||||
HashSet<BasicBlock> visited = new();
|
var visited = new HashSet<BasicBlock>();
|
||||||
Stack<BasicBlock> blockStack = new();
|
var blockStack = new Stack<BasicBlock>();
|
||||||
|
|
||||||
Array.Resize(ref _postOrderBlocks, Blocks.Count);
|
Array.Resize(ref _postOrderBlocks, Blocks.Count);
|
||||||
Array.Resize(ref _postOrderMap, Blocks.Count);
|
Array.Resize(ref _postOrderMap, Blocks.Count);
|
||||||
@@ -88,8 +88,8 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
private void RemoveUnreachableBlocks(IntrusiveList<BasicBlock> blocks)
|
private void RemoveUnreachableBlocks(IntrusiveList<BasicBlock> blocks)
|
||||||
{
|
{
|
||||||
HashSet<BasicBlock> visited = new();
|
var visited = new HashSet<BasicBlock>();
|
||||||
Queue<BasicBlock> workQueue = new();
|
var workQueue = new Queue<BasicBlock>();
|
||||||
|
|
||||||
visited.Add(Entry);
|
visited.Add(Entry);
|
||||||
workQueue.Enqueue(Entry);
|
workQueue.Enqueue(Entry);
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -563,7 +562,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
|
|
||||||
bool isEntryChanged = infoEntry.Hash != ComputeHash(translator.Memory, infoEntry.Address, infoEntry.GuestSize);
|
bool isEntryChanged = infoEntry.Hash != ComputeHash(translator.Memory, infoEntry.Address, infoEntry.GuestSize);
|
||||||
|
|
||||||
if (isEntryChanged || (!infoEntry.HighCq && Profiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out PtcProfiler.FuncProfile value) && value.HighCq))
|
if (isEntryChanged || (!infoEntry.HighCq && Profiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out var value) && value.HighCq))
|
||||||
{
|
{
|
||||||
infoEntry.Stubbed = true;
|
infoEntry.Stubbed = true;
|
||||||
infoEntry.CodeLength = 0;
|
infoEntry.CodeLength = 0;
|
||||||
@@ -750,8 +749,8 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
UnwindInfo unwindInfo,
|
UnwindInfo unwindInfo,
|
||||||
bool highCq)
|
bool highCq)
|
||||||
{
|
{
|
||||||
CompiledFunction cFunc = new(code, unwindInfo, RelocInfo.Empty);
|
var cFunc = new CompiledFunction(code, unwindInfo, RelocInfo.Empty);
|
||||||
GuestFunction gFunc = cFunc.MapWithPointer<GuestFunction>(out nint gFuncPointer);
|
var gFunc = cFunc.MapWithPointer<GuestFunction>(out nint gFuncPointer);
|
||||||
|
|
||||||
return new TranslatedFunction(gFunc, gFuncPointer, callCounter, guestSize, highCq);
|
return new TranslatedFunction(gFunc, gFuncPointer, callCounter, guestSize, highCq);
|
||||||
}
|
}
|
||||||
@@ -788,7 +787,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
|
|
||||||
public void MakeAndSaveTranslations(Translator translator)
|
public void MakeAndSaveTranslations(Translator translator)
|
||||||
{
|
{
|
||||||
ConcurrentQueue<(ulong address, PtcProfiler.FuncProfile funcProfile)> profiledFuncsToTranslate = Profiler.GetProfiledFuncsToTranslate(translator.Functions);
|
var profiledFuncsToTranslate = Profiler.GetProfiledFuncsToTranslate(translator.Functions);
|
||||||
|
|
||||||
_translateCount = 0;
|
_translateCount = 0;
|
||||||
_translateTotalCount = profiledFuncsToTranslate.Count;
|
_translateTotalCount = profiledFuncsToTranslate.Count;
|
||||||
@@ -832,7 +831,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
|
|
||||||
void TranslateFuncs()
|
void TranslateFuncs()
|
||||||
{
|
{
|
||||||
while (profiledFuncsToTranslate.TryDequeue(out (ulong address, PtcProfiler.FuncProfile funcProfile) item))
|
while (profiledFuncsToTranslate.TryDequeue(out var item))
|
||||||
{
|
{
|
||||||
ulong address = item.address;
|
ulong address = item.address;
|
||||||
|
|
||||||
@@ -867,11 +866,11 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
|
|
||||||
Stopwatch sw = Stopwatch.StartNew();
|
Stopwatch sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
foreach (Thread thread in threads)
|
foreach (var thread in threads)
|
||||||
{
|
{
|
||||||
thread.Start();
|
thread.Start();
|
||||||
}
|
}
|
||||||
foreach (Thread thread in threads)
|
foreach (var thread in threads)
|
||||||
{
|
{
|
||||||
thread.Join();
|
thread.Join();
|
||||||
}
|
}
|
||||||
@@ -945,7 +944,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
WriteCode(code.AsSpan());
|
WriteCode(code.AsSpan());
|
||||||
|
|
||||||
// WriteReloc.
|
// WriteReloc.
|
||||||
using BinaryWriter relocInfoWriter = new(_relocsStream, EncodingCache.UTF8NoBOM, true);
|
using var relocInfoWriter = new BinaryWriter(_relocsStream, EncodingCache.UTF8NoBOM, true);
|
||||||
|
|
||||||
foreach (RelocEntry entry in relocInfo.Entries)
|
foreach (RelocEntry entry in relocInfo.Entries)
|
||||||
{
|
{
|
||||||
@@ -955,7 +954,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WriteUnwindInfo.
|
// WriteUnwindInfo.
|
||||||
using BinaryWriter unwindInfoWriter = new(_unwindInfosStream, EncodingCache.UTF8NoBOM, true);
|
using var unwindInfoWriter = new BinaryWriter(_unwindInfosStream, EncodingCache.UTF8NoBOM, true);
|
||||||
|
|
||||||
unwindInfoWriter.Write(unwindInfo.PushEntries.Length);
|
unwindInfoWriter.Write(unwindInfo.PushEntries.Length);
|
||||||
|
|
||||||
|
|||||||
@@ -111,9 +111,9 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
|
|
||||||
public ConcurrentQueue<(ulong address, FuncProfile funcProfile)> GetProfiledFuncsToTranslate(TranslatorCache<TranslatedFunction> funcs)
|
public ConcurrentQueue<(ulong address, FuncProfile funcProfile)> GetProfiledFuncsToTranslate(TranslatorCache<TranslatedFunction> funcs)
|
||||||
{
|
{
|
||||||
ConcurrentQueue<(ulong address, FuncProfile funcProfile)> profiledFuncsToTranslate = new();
|
var profiledFuncsToTranslate = new ConcurrentQueue<(ulong address, FuncProfile funcProfile)>();
|
||||||
|
|
||||||
foreach (KeyValuePair<ulong, FuncProfile> profiledFunc in ProfiledFuncs)
|
foreach (var profiledFunc in ProfiledFuncs)
|
||||||
{
|
{
|
||||||
if (!funcs.ContainsKey(profiledFunc.Key))
|
if (!funcs.ContainsKey(profiledFunc.Key))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ namespace ARMeilleure.Translation
|
|||||||
// This is required because we have a implicit context load at the start of the function,
|
// This is required because we have a implicit context load at the start of the function,
|
||||||
// but if there is a jump to the start of the function, the context load would trash the modified values.
|
// but if there is a jump to the start of the function, the context load would trash the modified values.
|
||||||
// Here we insert a new entry block that will jump to the existing entry block.
|
// Here we insert a new entry block that will jump to the existing entry block.
|
||||||
BasicBlock newEntry = new(cfg.Blocks.Count);
|
BasicBlock newEntry = new BasicBlock(cfg.Blocks.Count);
|
||||||
|
|
||||||
cfg.UpdateEntry(newEntry);
|
cfg.UpdateEntry(newEntry);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
public static void Construct(ControlFlowGraph cfg)
|
public static void Construct(ControlFlowGraph cfg)
|
||||||
{
|
{
|
||||||
DefMap[] globalDefs = new DefMap[cfg.Blocks.Count];
|
var globalDefs = new DefMap[cfg.Blocks.Count];
|
||||||
Operand[] localDefs = new Operand[cfg.LocalsCount + RegisterConsts.TotalCount];
|
var localDefs = new Operand[cfg.LocalsCount + RegisterConsts.TotalCount];
|
||||||
|
|
||||||
Queue<BasicBlock> dfPhiBlocks = new();
|
var dfPhiBlocks = new Queue<BasicBlock>();
|
||||||
|
|
||||||
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
|
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false)
|
internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false)
|
||||||
{
|
{
|
||||||
ArmEmitterContext context = new(
|
var context = new ArmEmitterContext(
|
||||||
Memory,
|
Memory,
|
||||||
CountTable,
|
CountTable,
|
||||||
FunctionTable,
|
FunctionTable,
|
||||||
@@ -259,10 +259,10 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
Logger.EndPass(PassName.RegisterUsage);
|
Logger.EndPass(PassName.RegisterUsage);
|
||||||
|
|
||||||
OperandType retType = OperandType.I64;
|
var retType = OperandType.I64;
|
||||||
OperandType[] argTypes = new OperandType[] { OperandType.I64 };
|
var argTypes = new OperandType[] { OperandType.I64 };
|
||||||
|
|
||||||
CompilerOptions options = highCq ? CompilerOptions.HighCq : CompilerOptions.None;
|
var options = highCq ? CompilerOptions.HighCq : CompilerOptions.None;
|
||||||
|
|
||||||
if (context.HasPtc && !singleStep)
|
if (context.HasPtc && !singleStep)
|
||||||
{
|
{
|
||||||
@@ -521,7 +521,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
List<TranslatedFunction> functions = Functions.AsList();
|
List<TranslatedFunction> functions = Functions.AsList();
|
||||||
|
|
||||||
foreach (TranslatedFunction func in functions)
|
foreach (var func in functions)
|
||||||
{
|
{
|
||||||
JitCache.Unmap(func.FuncPointer);
|
JitCache.Unmap(func.FuncPointer);
|
||||||
|
|
||||||
@@ -530,7 +530,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
Functions.Clear();
|
Functions.Clear();
|
||||||
|
|
||||||
while (_oldFuncs.TryDequeue(out KeyValuePair<ulong, TranslatedFunction> kv))
|
while (_oldFuncs.TryDequeue(out var kv))
|
||||||
{
|
{
|
||||||
JitCache.Unmap(kv.Value.FuncPointer);
|
JitCache.Unmap(kv.Value.FuncPointer);
|
||||||
|
|
||||||
@@ -551,7 +551,7 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
while (Queue.Count > 0 && Queue.TryDequeue(out RejitRequest request))
|
while (Queue.Count > 0 && Queue.TryDequeue(out RejitRequest request))
|
||||||
{
|
{
|
||||||
if (Functions.TryGetValue(request.Address, out TranslatedFunction func) && func.CallCounter != null)
|
if (Functions.TryGetValue(request.Address, out var func) && func.CallCounter != null)
|
||||||
{
|
{
|
||||||
Volatile.Write(ref func.CallCounter.Value, 0);
|
Volatile.Write(ref func.CallCounter.Value, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ namespace ARMeilleure.Translation
|
|||||||
/// <returns>Generated <see cref="DispatchStub"/></returns>
|
/// <returns>Generated <see cref="DispatchStub"/></returns>
|
||||||
private nint GenerateDispatchStub()
|
private nint GenerateDispatchStub()
|
||||||
{
|
{
|
||||||
EmitterContext context = new();
|
var context = new EmitterContext();
|
||||||
|
|
||||||
Operand lblFallback = Label();
|
Operand lblFallback = Label();
|
||||||
Operand lblEnd = Label();
|
Operand lblEnd = Label();
|
||||||
@@ -161,7 +161,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
for (int i = 0; i < _functionTable.Levels.Length; i++)
|
for (int i = 0; i < _functionTable.Levels.Length; i++)
|
||||||
{
|
{
|
||||||
ref AddressTableLevel level = ref _functionTable.Levels[i];
|
ref var level = ref _functionTable.Levels[i];
|
||||||
|
|
||||||
// level.Mask is not used directly because it is more often bigger than 32-bits, so it will not
|
// level.Mask is not used directly because it is more often bigger than 32-bits, so it will not
|
||||||
// be encoded as an immediate on x86's bitwise and operation.
|
// be encoded as an immediate on x86's bitwise and operation.
|
||||||
@@ -185,11 +185,11 @@ namespace ARMeilleure.Translation
|
|||||||
hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
|
hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
|
||||||
context.Tailcall(hostAddress, nativeContext);
|
context.Tailcall(hostAddress, nativeContext);
|
||||||
|
|
||||||
ControlFlowGraph cfg = context.GetControlFlowGraph();
|
var cfg = context.GetControlFlowGraph();
|
||||||
OperandType retType = OperandType.I64;
|
var retType = OperandType.I64;
|
||||||
OperandType[] argTypes = new[] { OperandType.I64 };
|
var argTypes = new[] { OperandType.I64 };
|
||||||
|
|
||||||
GuestFunction func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>();
|
var func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>();
|
||||||
|
|
||||||
return Marshal.GetFunctionPointerForDelegate(func);
|
return Marshal.GetFunctionPointerForDelegate(func);
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ namespace ARMeilleure.Translation
|
|||||||
/// <returns>Generated <see cref="SlowDispatchStub"/></returns>
|
/// <returns>Generated <see cref="SlowDispatchStub"/></returns>
|
||||||
private nint GenerateSlowDispatchStub()
|
private nint GenerateSlowDispatchStub()
|
||||||
{
|
{
|
||||||
EmitterContext context = new();
|
var context = new EmitterContext();
|
||||||
|
|
||||||
// Load the target guest address from the native context.
|
// Load the target guest address from the native context.
|
||||||
Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
|
Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
|
||||||
@@ -210,11 +210,11 @@ namespace ARMeilleure.Translation
|
|||||||
Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
|
Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
|
||||||
context.Tailcall(hostAddress, nativeContext);
|
context.Tailcall(hostAddress, nativeContext);
|
||||||
|
|
||||||
ControlFlowGraph cfg = context.GetControlFlowGraph();
|
var cfg = context.GetControlFlowGraph();
|
||||||
OperandType retType = OperandType.I64;
|
var retType = OperandType.I64;
|
||||||
OperandType[] argTypes = new[] { OperandType.I64 };
|
var argTypes = new[] { OperandType.I64 };
|
||||||
|
|
||||||
GuestFunction func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>();
|
var func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>();
|
||||||
|
|
||||||
return Marshal.GetFunctionPointerForDelegate(func);
|
return Marshal.GetFunctionPointerForDelegate(func);
|
||||||
}
|
}
|
||||||
@@ -251,7 +251,7 @@ namespace ARMeilleure.Translation
|
|||||||
/// <returns><see cref="DispatchLoop"/> function</returns>
|
/// <returns><see cref="DispatchLoop"/> function</returns>
|
||||||
private DispatcherFunction GenerateDispatchLoop()
|
private DispatcherFunction GenerateDispatchLoop()
|
||||||
{
|
{
|
||||||
EmitterContext context = new();
|
var context = new EmitterContext();
|
||||||
|
|
||||||
Operand beginLbl = Label();
|
Operand beginLbl = Label();
|
||||||
Operand endLbl = Label();
|
Operand endLbl = Label();
|
||||||
@@ -279,9 +279,9 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
context.Return();
|
context.Return();
|
||||||
|
|
||||||
ControlFlowGraph cfg = context.GetControlFlowGraph();
|
var cfg = context.GetControlFlowGraph();
|
||||||
OperandType retType = OperandType.None;
|
var retType = OperandType.None;
|
||||||
OperandType[] argTypes = new[] { OperandType.I64, OperandType.I64 };
|
var argTypes = new[] { OperandType.I64, OperandType.I64 };
|
||||||
|
|
||||||
return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DispatcherFunction>();
|
return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DispatcherFunction>();
|
||||||
}
|
}
|
||||||
@@ -292,7 +292,7 @@ namespace ARMeilleure.Translation
|
|||||||
/// <returns><see cref="ContextWrapper"/> function</returns>
|
/// <returns><see cref="ContextWrapper"/> function</returns>
|
||||||
private WrapperFunction GenerateContextWrapper()
|
private WrapperFunction GenerateContextWrapper()
|
||||||
{
|
{
|
||||||
EmitterContext context = new();
|
var context = new EmitterContext();
|
||||||
|
|
||||||
Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
|
Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
|
||||||
Operand guestMethod = context.LoadArgument(OperandType.I64, 1);
|
Operand guestMethod = context.LoadArgument(OperandType.I64, 1);
|
||||||
@@ -303,9 +303,9 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
context.Return(returnValue);
|
context.Return(returnValue);
|
||||||
|
|
||||||
ControlFlowGraph cfg = context.GetControlFlowGraph();
|
var cfg = context.GetControlFlowGraph();
|
||||||
OperandType retType = OperandType.I64;
|
var retType = OperandType.I64;
|
||||||
OperandType[] argTypes = new[] { OperandType.I64, OperandType.I64 };
|
var argTypes = new[] { OperandType.I64, OperandType.I64 };
|
||||||
|
|
||||||
return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<WrapperFunction>();
|
return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<WrapperFunction>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
|
|
||||||
SDL2Driver.Instance.Initialize();
|
SDL2Driver.Instance.Initialize();
|
||||||
|
|
||||||
int res = SDL_GetDefaultAudioInfo(nint.Zero, out SDL_AudioSpec spec, 0);
|
int res = SDL_GetDefaultAudioInfo(nint.Zero, out var spec, 0);
|
||||||
|
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace Ryujinx.Audio.Backends.SoundIo.Native
|
|||||||
get => Marshal.PtrToStringAnsi(GetOutContext().Name);
|
get => Marshal.PtrToStringAnsi(GetOutContext().Name);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
SoundIoOutStream context = GetOutContext();
|
var context = GetOutContext();
|
||||||
|
|
||||||
if (_nameStored != nint.Zero && context.Name == _nameStored)
|
if (_nameStored != nint.Zero && context.Name == _nameStored)
|
||||||
{
|
{
|
||||||
@@ -129,8 +129,8 @@ namespace Ryujinx.Audio.Backends.SoundIo.Native
|
|||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
int* frameCountPtr = &nativeFrameCount;
|
var frameCountPtr = &nativeFrameCount;
|
||||||
IntPtr* arenasPtr = &arenas;
|
var arenasPtr = &arenas;
|
||||||
CheckError(soundio_outstream_begin_write(_context, (nint)arenasPtr, (nint)frameCountPtr));
|
CheckError(soundio_outstream_begin_write(_context, (nint)arenasPtr, (nint)frameCountPtr));
|
||||||
|
|
||||||
frameCount = *frameCountPtr;
|
frameCount = *frameCountPtr;
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolMapper poolMapper = new(_processHandle, _memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled());
|
PoolMapper poolMapper = new PoolMapper(_processHandle, _memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled());
|
||||||
|
|
||||||
result = stateUpdater.UpdateVoices(_voiceContext, poolMapper);
|
result = stateUpdater.UpdateVoices(_voiceContext, poolMapper);
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace Ryujinx.Audio.Renderer.Utils
|
|||||||
|
|
||||||
private void UpdateHeader()
|
private void UpdateHeader()
|
||||||
{
|
{
|
||||||
BinaryWriter writer = new(_stream);
|
var writer = new BinaryWriter(_stream);
|
||||||
|
|
||||||
long currentPos = writer.Seek(0, SeekOrigin.Current);
|
long currentPos = writer.Seek(0, SeekOrigin.Current);
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace Ryujinx.BuildValidationTasks
|
|||||||
if (isGitRunner && encounteredIssue)
|
if (isGitRunner && encounteredIssue)
|
||||||
throw new JsonException("1 or more locales are invalid!");
|
throw new JsonException("1 or more locales are invalid!");
|
||||||
|
|
||||||
JsonSerializerOptions jsonOptions = new()
|
JsonSerializerOptions jsonOptions = new JsonSerializerOptions()
|
||||||
{
|
{
|
||||||
WriteIndented = true,
|
WriteIndented = true,
|
||||||
NewLine = "\n",
|
NewLine = "\n",
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace Ryujinx.Common
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (T item in _queue.GetConsumingEnumerable(_cts.Token))
|
foreach (var item in _queue.GetConsumingEnumerable(_cts.Token))
|
||||||
{
|
{
|
||||||
_workerAction(item);
|
_workerAction(item);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,8 @@ namespace Ryujinx.Common.Configuration
|
|||||||
|
|
||||||
public static EnabledDirtyHack Unpack(ulong packedHack)
|
public static EnabledDirtyHack Unpack(ulong packedHack)
|
||||||
{
|
{
|
||||||
uint[] unpackedFields = packedHack.UnpackBitFields(PackedFormat);
|
var unpackedFields = packedHack.UnpackBitFields(PackedFormat);
|
||||||
// ReSharper disable once PatternAlwaysMatches
|
if (unpackedFields is not [var hack, var value])
|
||||||
if (unpackedFields is not [uint hack, uint value])
|
|
||||||
throw new Exception("The unpack operation on the integer resulted in an invalid unpacked result.");
|
throw new Exception("The unpack operation on the integer resulted in an invalid unpacked result.");
|
||||||
|
|
||||||
return new EnabledDirtyHack((DirtyHack)hack, (int)value);
|
return new EnabledDirtyHack((DirtyHack)hack, (int)value);
|
||||||
@@ -54,7 +53,7 @@ namespace Ryujinx.Common.Configuration
|
|||||||
public static implicit operator DirtyHacks(EnabledDirtyHack[] hacks) => new(hacks);
|
public static implicit operator DirtyHacks(EnabledDirtyHack[] hacks) => new(hacks);
|
||||||
public static implicit operator DirtyHacks(ulong[] packedHacks) => new(packedHacks);
|
public static implicit operator DirtyHacks(ulong[] packedHacks) => new(packedHacks);
|
||||||
|
|
||||||
public new int this[DirtyHack hack] => TryGetValue(hack, out int value) ? value : -1;
|
public new int this[DirtyHack hack] => TryGetValue(hack, out var value) ? value : -1;
|
||||||
|
|
||||||
public bool IsEnabled(DirtyHack hack) => ContainsKey(hack);
|
public bool IsEnabled(DirtyHack hack) => ContainsKey(hack);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,24 +2,14 @@
|
|||||||
{
|
{
|
||||||
public class LedConfigController
|
public class LedConfigController
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Enable LED color changing by the emulator
|
|
||||||
/// </summary>
|
|
||||||
public bool EnableLed { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ignores the color and disables the LED entirely.
|
|
||||||
/// </summary>
|
|
||||||
public bool TurnOffLed { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ignores the color and uses the rainbow color functionality for the LED.
|
|
||||||
/// </summary>
|
|
||||||
public bool UseRainbow { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Packed RGB int of the color
|
/// Packed RGB int of the color
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint LedColor { get; set; }
|
public uint LedColor { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable LED color changing by the emulator
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableLed { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
@@ -17,15 +16,15 @@ namespace Ryujinx.Common.Extensions
|
|||||||
/// <param name="fileFullName">The path and name of the file to create and dump to</param>
|
/// <param name="fileFullName">The path and name of the file to create and dump to</param>
|
||||||
public static void DumpToFile(this ref SequenceReader<byte> reader, string fileFullName)
|
public static void DumpToFile(this ref SequenceReader<byte> reader, string fileFullName)
|
||||||
{
|
{
|
||||||
long initialConsumed = reader.Consumed;
|
var initialConsumed = reader.Consumed;
|
||||||
|
|
||||||
reader.Rewind(initialConsumed);
|
reader.Rewind(initialConsumed);
|
||||||
|
|
||||||
using (FileStream fileStream = System.IO.File.Create(fileFullName, 4096, System.IO.FileOptions.None))
|
using (var fileStream = System.IO.File.Create(fileFullName, 4096, System.IO.FileOptions.None))
|
||||||
{
|
{
|
||||||
while (reader.End == false)
|
while (reader.End == false)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<byte> span = reader.CurrentSpan;
|
var span = reader.CurrentSpan;
|
||||||
fileStream.Write(span);
|
fileStream.Write(span);
|
||||||
reader.Advance(span.Length);
|
reader.Advance(span.Length);
|
||||||
}
|
}
|
||||||
@@ -164,7 +163,7 @@ namespace Ryujinx.Common.Extensions
|
|||||||
// Not enough data in the current segment, try to peek for the data we need.
|
// Not enough data in the current segment, try to peek for the data we need.
|
||||||
T buffer = default;
|
T buffer = default;
|
||||||
|
|
||||||
Span<byte> tempSpan = new(&buffer, sizeof(T));
|
Span<byte> tempSpan = new Span<byte>(&buffer, sizeof(T));
|
||||||
|
|
||||||
if (!reader.TryCopyTo(tempSpan))
|
if (!reader.TryCopyTo(tempSpan))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace Ryujinx.Common.Helper
|
|||||||
{
|
{
|
||||||
RegistryKey key = Registry.CurrentUser.OpenSubKey(@$"Software\Classes\{ext}");
|
RegistryKey key = Registry.CurrentUser.OpenSubKey(@$"Software\Classes\{ext}");
|
||||||
|
|
||||||
RegistryKey openCmd = key?.OpenSubKey(@"shell\open\command");
|
var openCmd = key?.OpenSubKey(@"shell\open\command");
|
||||||
|
|
||||||
if (openCmd is null)
|
if (openCmd is null)
|
||||||
{
|
{
|
||||||
@@ -143,7 +143,7 @@ namespace Ryujinx.Common.Helper
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using RegistryKey key = Registry.CurrentUser.CreateSubKey(keyString);
|
using var key = Registry.CurrentUser.CreateSubKey(keyString);
|
||||||
|
|
||||||
if (key is null)
|
if (key is null)
|
||||||
{
|
{
|
||||||
@@ -151,7 +151,7 @@ namespace Ryujinx.Common.Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}");
|
Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}");
|
||||||
using RegistryKey openCmd = key.CreateSubKey(@"shell\open\command");
|
using var openCmd = key.CreateSubKey(@"shell\open\command");
|
||||||
openCmd.SetValue(string.Empty, $"\"{Environment.ProcessPath}\" \"%1\"");
|
openCmd.SetValue(string.Empty, $"\"{Environment.ProcessPath}\" \"%1\"");
|
||||||
Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}");
|
Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}");
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Ryujinx.Common.Helper
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (string searchPath in pathVar.Split(":", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries))
|
foreach (var searchPath in pathVar.Split(":", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
string binaryPath = Path.Combine(searchPath, binary);
|
string binaryPath = Path.Combine(searchPath, binary);
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace Ryujinx.Common.Helper
|
|||||||
{
|
{
|
||||||
ObjectiveC.NSString nsStringPath = new(path);
|
ObjectiveC.NSString nsStringPath = new(path);
|
||||||
ObjectiveC.Object nsUrl = new("NSURL");
|
ObjectiveC.Object nsUrl = new("NSURL");
|
||||||
ObjectiveC.Object urlPtr = nsUrl.GetFromMessage("fileURLWithPath:", nsStringPath);
|
var urlPtr = nsUrl.GetFromMessage("fileURLWithPath:", nsStringPath);
|
||||||
|
|
||||||
ObjectiveC.Object nsArray = new("NSArray");
|
ObjectiveC.Object nsArray = new("NSArray");
|
||||||
ObjectiveC.Object urlArray = nsArray.GetFromMessage("arrayWithObject:", urlPtr);
|
ObjectiveC.Object urlArray = nsArray.GetFromMessage("arrayWithObject:", urlPtr);
|
||||||
@@ -99,7 +99,7 @@ namespace Ryujinx.Common.Helper
|
|||||||
{
|
{
|
||||||
ObjectiveC.NSString nsStringPath = new(url);
|
ObjectiveC.NSString nsStringPath = new(url);
|
||||||
ObjectiveC.Object nsUrl = new("NSURL");
|
ObjectiveC.Object nsUrl = new("NSURL");
|
||||||
ObjectiveC.Object urlPtr = nsUrl.GetFromMessage("URLWithString:", nsStringPath);
|
var urlPtr = nsUrl.GetFromMessage("URLWithString:", nsStringPath);
|
||||||
|
|
||||||
ObjectiveC.Object nsWorkspace = new("NSWorkspace");
|
ObjectiveC.Object nsWorkspace = new("NSWorkspace");
|
||||||
ObjectiveC.Object sharedWorkspace = nsWorkspace.GetFromMessage("sharedWorkspace");
|
ObjectiveC.Object sharedWorkspace = nsWorkspace.GetFromMessage("sharedWorkspace");
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
// ReSharper disable MemberCanBePrivate.Global
|
|
||||||
// ReSharper disable InconsistentNaming
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Helper
|
|
||||||
{
|
|
||||||
public static class RunningPlatform
|
|
||||||
{
|
|
||||||
public static bool IsMacOS => OperatingSystem.IsMacOS();
|
|
||||||
public static bool IsWindows => OperatingSystem.IsWindows();
|
|
||||||
public static bool IsLinux => OperatingSystem.IsLinux();
|
|
||||||
|
|
||||||
public static bool IsIntelMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.X64;
|
|
||||||
public static bool IsArmMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.Arm64;
|
|
||||||
|
|
||||||
public static bool IsX64Windows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.X64);
|
|
||||||
public static bool IsArmWindows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
|
|
||||||
|
|
||||||
public static bool IsX64Linux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.X64);
|
|
||||||
public static bool IsArmLinux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -41,7 +41,7 @@ namespace Ryujinx.Common.Logging.Formatters
|
|||||||
|
|
||||||
sb.Append('{');
|
sb.Append('{');
|
||||||
|
|
||||||
foreach (PropertyInfo prop in props)
|
foreach (var prop in props)
|
||||||
{
|
{
|
||||||
sb.Append(prop.Name);
|
sb.Append(prop.Name);
|
||||||
sb.Append(": ");
|
sb.Append(": ");
|
||||||
@@ -52,7 +52,7 @@ namespace Ryujinx.Common.Logging.Formatters
|
|||||||
|
|
||||||
if (array is not null)
|
if (array is not null)
|
||||||
{
|
{
|
||||||
foreach (object? item in array)
|
foreach (var item in array)
|
||||||
{
|
{
|
||||||
sb.Append(item);
|
sb.Append(item);
|
||||||
sb.Append(", ");
|
sb.Append(", ");
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ namespace Ryujinx.Common.Logging
|
|||||||
|
|
||||||
_stdErrAdapter.Dispose();
|
_stdErrAdapter.Dispose();
|
||||||
|
|
||||||
foreach (ILogTarget target in _logTargets)
|
foreach (var target in _logTargets)
|
||||||
{
|
{
|
||||||
target.Dispose();
|
target.Dispose();
|
||||||
}
|
}
|
||||||
@@ -203,9 +203,9 @@ namespace Ryujinx.Common.Logging
|
|||||||
|
|
||||||
public static IReadOnlyCollection<LogLevel> GetEnabledLevels()
|
public static IReadOnlyCollection<LogLevel> GetEnabledLevels()
|
||||||
{
|
{
|
||||||
Log?[] logs = new[] { Debug, Info, Warning, Error, Guest, AccessLog, Stub, Trace };
|
var logs = new[] { Debug, Info, Warning, Error, Guest, AccessLog, Stub, Trace };
|
||||||
List<LogLevel> levels = new(logs.Length);
|
List<LogLevel> levels = new(logs.Length);
|
||||||
foreach (Log? log in logs)
|
foreach (var log in logs)
|
||||||
{
|
{
|
||||||
if (log.HasValue)
|
if (log.HasValue)
|
||||||
levels.Add(log.Value.Level);
|
levels.Add(log.Value.Level);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace Ryujinx.Common.Logging.Targets
|
|||||||
|
|
||||||
public void Log(object sender, LogEventArgs e)
|
public void Log(object sender, LogEventArgs e)
|
||||||
{
|
{
|
||||||
LogEventArgsJson logEventArgsJson = LogEventArgsJson.FromLogEventArgs(e);
|
var logEventArgsJson = LogEventArgsJson.FromLogEventArgs(e);
|
||||||
JsonHelper.SerializeToStream(_stream, logEventArgsJson, LogEventJsonSerializerContext.Default.LogEventArgsJson);
|
JsonHelper.SerializeToStream(_stream, logEventArgsJson, LogEventJsonSerializerContext.Default.LogEventArgsJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Helper;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@@ -9,7 +8,7 @@ namespace Ryujinx.Common
|
|||||||
{
|
{
|
||||||
public static class TitleIDs
|
public static class TitleIDs
|
||||||
{
|
{
|
||||||
public static ReactiveObject<Optional<string>> CurrentApplication { get; } = new();
|
public static ReactiveObject<Optional<string>> CurrentApplication { get; set; } = new();
|
||||||
|
|
||||||
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
|
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
|
||||||
{
|
{
|
||||||
@@ -22,7 +21,7 @@ namespace Ryujinx.Common
|
|||||||
return currentBackend;
|
return currentBackend;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RunningPlatform.IsArmMac)
|
if (!(OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture is Architecture.Arm64))
|
||||||
return GraphicsBackend.Vulkan;
|
return GraphicsBackend.Vulkan;
|
||||||
|
|
||||||
return GreatMetalTitles.ContainsIgnoreCase(titleId) ? GraphicsBackend.Metal : GraphicsBackend.Vulkan;
|
return GreatMetalTitles.ContainsIgnoreCase(titleId) ? GraphicsBackend.Metal : GraphicsBackend.Vulkan;
|
||||||
@@ -105,7 +104,6 @@ namespace Ryujinx.Common
|
|||||||
"0100b04011742000", // Monster Hunter Rise
|
"0100b04011742000", // Monster Hunter Rise
|
||||||
|
|
||||||
//Mario Franchise
|
//Mario Franchise
|
||||||
"010021d00812a000", // Arcade Archives VS. SUPER MARIO BROS.
|
|
||||||
"01006d0017f7a000", // Mario & Luigi: Brothership
|
"01006d0017f7a000", // Mario & Luigi: Brothership
|
||||||
"010003000e146000", // Mario & Sonic at the Olympic Games Tokyo 2020
|
"010003000e146000", // Mario & Sonic at the Olympic Games Tokyo 2020
|
||||||
"010067300059a000", // Mario + Rabbids: Kingdom Battle
|
"010067300059a000", // Mario + Rabbids: Kingdom Battle
|
||||||
@@ -213,41 +211,32 @@ namespace Ryujinx.Common
|
|||||||
//Misc Games
|
//Misc Games
|
||||||
"010056e00853a000", // A Hat in Time
|
"010056e00853a000", // A Hat in Time
|
||||||
"0100fd1014726000", // Baldurs Gate: Dark Alliance
|
"0100fd1014726000", // Baldurs Gate: Dark Alliance
|
||||||
"0100c6800b934000", // Brawlhalla
|
|
||||||
"0100dbf01000a000", // Burnout Paradise Remastered
|
"0100dbf01000a000", // Burnout Paradise Remastered
|
||||||
"0100744001588000", // Cars 3: Driven to Win
|
"0100744001588000", // Cars 3: Driven to Win
|
||||||
"0100b41013c82000", // Cruis'n Blast
|
"0100b41013c82000", // Cruis'n Blast
|
||||||
"010085900337e000", // Death Squared
|
"010085900337e000", // Death Squared
|
||||||
"01001b300b9be000", // Diablo III: Eternal Collection
|
"01001b300b9be000", // Diablo III: Eternal Collection
|
||||||
"010027400cdc6000", // Divinity Original 2 - Definitive Edition
|
|
||||||
"01008c8012920000", // Dying Light Platinum Edition
|
"01008c8012920000", // Dying Light Platinum Edition
|
||||||
"01001cc01b2d4000", // Goat Simulator 3
|
"01001cc01b2d4000", // Goat Simulator 3
|
||||||
"01003620068ea000", // Hand of Fate 2
|
"01003620068ea000", // Hand of Fate 2
|
||||||
"010085500130a000", // Lego City: Undercover
|
"010085500130a000", // Lego City: Undercover
|
||||||
"010073c01af34000", // LEGO Horizon Adventures
|
"010073c01af34000", // LEGO Horizon Adventures
|
||||||
"0100d71004694000", // Minecraft
|
|
||||||
"01007430037f6000", // Monopoly
|
|
||||||
"0100853015e86000", // No Man's Sky
|
"0100853015e86000", // No Man's Sky
|
||||||
"01007bb017812000", // Portal
|
"01007bb017812000", // Portal
|
||||||
"0100abd01785c000", // Portal 2
|
"0100abd01785c000", // Portal 2
|
||||||
"01008e200c5c2000", // Muse Dash
|
"01008e200c5c2000", // Muse Dash
|
||||||
"01007820196a6000", // Red Dead Redemption
|
"01007820196a6000", // Red Dead Redemption
|
||||||
"0100e8300a67a000", // Risk
|
|
||||||
"01002f7013224000", // Rune Factory 5
|
"01002f7013224000", // Rune Factory 5
|
||||||
"01008d100d43e000", // Saints Row IV
|
"01008d100d43e000", // Saints Row IV
|
||||||
"0100de600beee000", // Saints Row: The Third - The Full Package
|
"0100de600beee000", // Saints Row: The Third - The Full Package
|
||||||
"01001180021fa000", // Shovel Knight: Specter of Torment
|
"01001180021fa000", // Shovel Knight: Specter of Torment
|
||||||
"0100e65002bb8000", // Stardew Valley
|
|
||||||
"0100d7a01b7a2000", // Star Wars: Bounty Hunter
|
"0100d7a01b7a2000", // Star Wars: Bounty Hunter
|
||||||
"0100800015926000", // Suika Game
|
"0100800015926000", // Suika Game
|
||||||
"01007ad00013e000", // Super Bomberman R
|
|
||||||
"0100e46006708000", // Terraria
|
"0100e46006708000", // Terraria
|
||||||
"0100605008268000", // Titan Quest
|
|
||||||
"01000a10041ea000", // The Elder Scrolls V: Skyrim
|
"01000a10041ea000", // The Elder Scrolls V: Skyrim
|
||||||
"010057a01e4d4000", // TSUKIHIME -A piece of blue glass moon-
|
"010057a01e4d4000", // TSUKIHIME -A piece of blue glass moon-
|
||||||
"010080b00ad66000", // Undertale
|
"010080b00ad66000", // Undertale
|
||||||
"010069401adb8000", // Unicorn Overlord
|
"010069401adb8000", // Unicorn Overlord
|
||||||
"01005c600ac68000", // Valkyria Chronicles 4
|
|
||||||
"0100534009ff2000", // Yonder - The cloud catcher chronicles
|
"0100534009ff2000", // Yonder - The cloud catcher chronicles
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,21 +19,21 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
public static byte[] Read(string filename)
|
public static byte[] Read(string filename)
|
||||||
{
|
{
|
||||||
(Assembly assembly, string path) = ResolveManifestPath(filename);
|
var (assembly, path) = ResolveManifestPath(filename);
|
||||||
|
|
||||||
return Read(assembly, path);
|
return Read(assembly, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task<byte[]> ReadAsync(string filename)
|
public static Task<byte[]> ReadAsync(string filename)
|
||||||
{
|
{
|
||||||
(Assembly assembly, string path) = ResolveManifestPath(filename);
|
var (assembly, path) = ResolveManifestPath(filename);
|
||||||
|
|
||||||
return ReadAsync(assembly, path);
|
return ReadAsync(assembly, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] Read(Assembly assembly, string filename)
|
public static byte[] Read(Assembly assembly, string filename)
|
||||||
{
|
{
|
||||||
using Stream stream = GetStream(assembly, filename);
|
using var stream = GetStream(assembly, filename);
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -44,14 +44,14 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
public static MemoryOwner<byte> ReadFileToRentedMemory(string filename)
|
public static MemoryOwner<byte> ReadFileToRentedMemory(string filename)
|
||||||
{
|
{
|
||||||
(Assembly assembly, string path) = ResolveManifestPath(filename);
|
var (assembly, path) = ResolveManifestPath(filename);
|
||||||
|
|
||||||
return ReadFileToRentedMemory(assembly, path);
|
return ReadFileToRentedMemory(assembly, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MemoryOwner<byte> ReadFileToRentedMemory(Assembly assembly, string filename)
|
public static MemoryOwner<byte> ReadFileToRentedMemory(Assembly assembly, string filename)
|
||||||
{
|
{
|
||||||
using Stream stream = GetStream(assembly, filename);
|
using var stream = GetStream(assembly, filename);
|
||||||
|
|
||||||
return stream is null
|
return stream is null
|
||||||
? null
|
? null
|
||||||
@@ -60,7 +60,7 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
public async static Task<byte[]> ReadAsync(Assembly assembly, string filename)
|
public async static Task<byte[]> ReadAsync(Assembly assembly, string filename)
|
||||||
{
|
{
|
||||||
using Stream stream = GetStream(assembly, filename);
|
using var stream = GetStream(assembly, filename);
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -71,55 +71,55 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
public static string ReadAllText(string filename)
|
public static string ReadAllText(string filename)
|
||||||
{
|
{
|
||||||
(Assembly assembly, string path) = ResolveManifestPath(filename);
|
var (assembly, path) = ResolveManifestPath(filename);
|
||||||
|
|
||||||
return ReadAllText(assembly, path);
|
return ReadAllText(assembly, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task<string> ReadAllTextAsync(string filename)
|
public static Task<string> ReadAllTextAsync(string filename)
|
||||||
{
|
{
|
||||||
(Assembly assembly, string path) = ResolveManifestPath(filename);
|
var (assembly, path) = ResolveManifestPath(filename);
|
||||||
|
|
||||||
return ReadAllTextAsync(assembly, path);
|
return ReadAllTextAsync(assembly, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ReadAllText(Assembly assembly, string filename)
|
public static string ReadAllText(Assembly assembly, string filename)
|
||||||
{
|
{
|
||||||
using Stream stream = GetStream(assembly, filename);
|
using var stream = GetStream(assembly, filename);
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
using StreamReader reader = new(stream);
|
using var reader = new StreamReader(stream);
|
||||||
return reader.ReadToEnd();
|
return reader.ReadToEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async static Task<string> ReadAllTextAsync(Assembly assembly, string filename)
|
public async static Task<string> ReadAllTextAsync(Assembly assembly, string filename)
|
||||||
{
|
{
|
||||||
using Stream stream = GetStream(assembly, filename);
|
using var stream = GetStream(assembly, filename);
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
using StreamReader reader = new(stream);
|
using var reader = new StreamReader(stream);
|
||||||
return await reader.ReadToEndAsync();
|
return await reader.ReadToEndAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Stream GetStream(string filename)
|
public static Stream GetStream(string filename)
|
||||||
{
|
{
|
||||||
(Assembly assembly, string path) = ResolveManifestPath(filename);
|
var (assembly, path) = ResolveManifestPath(filename);
|
||||||
|
|
||||||
return GetStream(assembly, path);
|
return GetStream(assembly, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Stream GetStream(Assembly assembly, string filename)
|
public static Stream GetStream(Assembly assembly, string filename)
|
||||||
{
|
{
|
||||||
string @namespace = assembly.GetName().Name;
|
var @namespace = assembly.GetName().Name;
|
||||||
string manifestUri = @namespace + "." + filename.Replace('/', '.');
|
var manifestUri = @namespace + "." + filename.Replace('/', '.');
|
||||||
|
|
||||||
Stream stream = assembly.GetManifestResourceStream(manifestUri);
|
var stream = assembly.GetManifestResourceStream(manifestUri);
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
@@ -133,11 +133,11 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
private static (Assembly, string) ResolveManifestPath(string filename)
|
private static (Assembly, string) ResolveManifestPath(string filename)
|
||||||
{
|
{
|
||||||
string[] segments = filename.Split('/', 2, StringSplitOptions.RemoveEmptyEntries);
|
var segments = filename.Split('/', 2, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
if (segments.Length >= 2)
|
if (segments.Length >= 2)
|
||||||
{
|
{
|
||||||
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||||
{
|
{
|
||||||
if (assembly.GetName().Name == segments[0])
|
if (assembly.GetName().Name == segments[0])
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive)
|
public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive)
|
||||||
{
|
{
|
||||||
// Get information about the source directory
|
// Get information about the source directory
|
||||||
DirectoryInfo dir = new(sourceDir);
|
var dir = new DirectoryInfo(sourceDir);
|
||||||
|
|
||||||
// Check if the source directory exists
|
// Check if the source directory exists
|
||||||
if (!dir.Exists)
|
if (!dir.Exists)
|
||||||
@@ -49,7 +49,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
|
|
||||||
public static string SanitizeFileName(string fileName)
|
public static string SanitizeFileName(string fileName)
|
||||||
{
|
{
|
||||||
HashSet<char> reservedChars = new(Path.GetInvalidFileNameChars());
|
var reservedChars = new HashSet<char>(Path.GetInvalidFileNameChars());
|
||||||
return string.Concat(fileName.Select(c => reservedChars.Contains(c) ? '_' : c));
|
return string.Concat(fileName.Select(c => reservedChars.Contains(c) ? '_' : c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using MsgPack;
|
using MsgPack;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Utilities
|
namespace Ryujinx.Common.Utilities
|
||||||
@@ -19,7 +18,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
|
|
||||||
public static string Format(MessagePackObject obj)
|
public static string Format(MessagePackObject obj)
|
||||||
{
|
{
|
||||||
IndentedStringBuilder builder = new();
|
var builder = new IndentedStringBuilder();
|
||||||
|
|
||||||
FormatMsgPackObj(obj, builder);
|
FormatMsgPackObj(obj, builder);
|
||||||
|
|
||||||
@@ -42,7 +41,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
object literal = obj.ToObject();
|
var literal = obj.ToObject();
|
||||||
|
|
||||||
if (literal is String)
|
if (literal is String)
|
||||||
{
|
{
|
||||||
@@ -89,7 +88,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
{
|
{
|
||||||
builder.Append("[ ");
|
builder.Append("[ ");
|
||||||
|
|
||||||
foreach (byte b in arr)
|
foreach (var b in arr)
|
||||||
{
|
{
|
||||||
builder.Append("0x");
|
builder.Append("0x");
|
||||||
builder.Append(ToHexChar(b >> 4));
|
builder.Append(ToHexChar(b >> 4));
|
||||||
@@ -112,7 +111,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
builder.Append("0x");
|
builder.Append("0x");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (byte b in arr)
|
foreach (var b in arr)
|
||||||
{
|
{
|
||||||
builder.Append(ToHexChar(b >> 4));
|
builder.Append(ToHexChar(b >> 4));
|
||||||
builder.Append(ToHexChar(b & 0xF));
|
builder.Append(ToHexChar(b & 0xF));
|
||||||
@@ -123,7 +122,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
|
|
||||||
private static void FormatMsgPackMap(MessagePackObject obj, IndentedStringBuilder builder)
|
private static void FormatMsgPackMap(MessagePackObject obj, IndentedStringBuilder builder)
|
||||||
{
|
{
|
||||||
MessagePackObjectDictionary map = obj.AsDictionary();
|
var map = obj.AsDictionary();
|
||||||
|
|
||||||
builder.Append('{');
|
builder.Append('{');
|
||||||
|
|
||||||
@@ -131,7 +130,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
builder.IncreaseIndent()
|
builder.IncreaseIndent()
|
||||||
.AppendLine();
|
.AppendLine();
|
||||||
|
|
||||||
foreach (KeyValuePair<MessagePackObject, MessagePackObject> item in map)
|
foreach (var item in map)
|
||||||
{
|
{
|
||||||
FormatMsgPackObj(item.Key, builder);
|
FormatMsgPackObj(item.Key, builder);
|
||||||
|
|
||||||
@@ -155,11 +154,11 @@ namespace Ryujinx.Common.Utilities
|
|||||||
|
|
||||||
private static void FormatMsgPackArray(MessagePackObject obj, IndentedStringBuilder builder)
|
private static void FormatMsgPackArray(MessagePackObject obj, IndentedStringBuilder builder)
|
||||||
{
|
{
|
||||||
IList<MessagePackObject> arr = obj.AsList();
|
var arr = obj.AsList();
|
||||||
|
|
||||||
builder.Append("[ ");
|
builder.Append("[ ");
|
||||||
|
|
||||||
foreach (MessagePackObject item in arr)
|
foreach (var item in arr)
|
||||||
{
|
{
|
||||||
FormatMsgPackObj(item, builder);
|
FormatMsgPackObj(item, builder);
|
||||||
|
|
||||||
|
|||||||
@@ -1,129 +0,0 @@
|
|||||||
using Gommon;
|
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Utilities
|
|
||||||
{
|
|
||||||
public static class Rainbow
|
|
||||||
{
|
|
||||||
public static bool CyclingEnabled { get; set; }
|
|
||||||
|
|
||||||
public static void Enable()
|
|
||||||
{
|
|
||||||
if (!CyclingEnabled)
|
|
||||||
{
|
|
||||||
CyclingEnabled = true;
|
|
||||||
Executor.ExecuteBackgroundAsync(async () =>
|
|
||||||
{
|
|
||||||
while (CyclingEnabled)
|
|
||||||
{
|
|
||||||
await Task.Delay(20);
|
|
||||||
Tick();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Disable()
|
|
||||||
{
|
|
||||||
CyclingEnabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static float Speed { get; set; } = 1;
|
|
||||||
|
|
||||||
private static readonly Lock _lock = new();
|
|
||||||
|
|
||||||
private static Color _color = Color.Blue;
|
|
||||||
|
|
||||||
public static ref Color Color
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
return ref _color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Tick()
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
_color = HsbToRgb((_color.GetHue() + Speed) / 360);
|
|
||||||
|
|
||||||
_updatedHandler.Call(_color.ToArgb());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Reset()
|
|
||||||
{
|
|
||||||
_updatedHandler.Clear();
|
|
||||||
|
|
||||||
lock (_lock)
|
|
||||||
_color = Color.Blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static event Action<int> Updated
|
|
||||||
{
|
|
||||||
add => _updatedHandler.Add(value);
|
|
||||||
remove => _updatedHandler.Remove(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly Event<int> _updatedHandler = new();
|
|
||||||
|
|
||||||
private static Color HsbToRgb(float hue, float saturation = 1, float brightness = 1)
|
|
||||||
{
|
|
||||||
int r = 0, g = 0, b = 0;
|
|
||||||
if (saturation == 0)
|
|
||||||
{
|
|
||||||
r = g = b = (int)(brightness * 255.0f + 0.5f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float h = (hue - (float)Math.Floor(hue)) * 6.0f;
|
|
||||||
float f = h - (float)Math.Floor(h);
|
|
||||||
float p = brightness * (1.0f - saturation);
|
|
||||||
float q = brightness * (1.0f - saturation * f);
|
|
||||||
float t = brightness * (1.0f - (saturation * (1.0f - f)));
|
|
||||||
switch ((int)h)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
r = (int)(brightness * 255.0f + 0.5f);
|
|
||||||
g = (int)(t * 255.0f + 0.5f);
|
|
||||||
b = (int)(p * 255.0f + 0.5f);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
r = (int)(q * 255.0f + 0.5f);
|
|
||||||
g = (int)(brightness * 255.0f + 0.5f);
|
|
||||||
b = (int)(p * 255.0f + 0.5f);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
r = (int)(p * 255.0f + 0.5f);
|
|
||||||
g = (int)(brightness * 255.0f + 0.5f);
|
|
||||||
b = (int)(t * 255.0f + 0.5f);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
r = (int)(p * 255.0f + 0.5f);
|
|
||||||
g = (int)(q * 255.0f + 0.5f);
|
|
||||||
b = (int)(brightness * 255.0f + 0.5f);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
r = (int)(t * 255.0f + 0.5f);
|
|
||||||
g = (int)(p * 255.0f + 0.5f);
|
|
||||||
b = (int)(brightness * 255.0f + 0.5f);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
r = (int)(brightness * 255.0f + 0.5f);
|
|
||||||
g = (int)(p * 255.0f + 0.5f);
|
|
||||||
b = (int)(q * 255.0f + 0.5f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Color.FromArgb(Convert.ToByte(255), Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using Microsoft.IO;
|
using Microsoft.IO;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -28,7 +27,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
|
|
||||||
MemoryOwner<byte> ownedMemory = MemoryOwner<byte>.Rent(checked((int)bytesExpected));
|
MemoryOwner<byte> ownedMemory = MemoryOwner<byte>.Rent(checked((int)bytesExpected));
|
||||||
|
|
||||||
Span<byte> destSpan = ownedMemory.Span;
|
var destSpan = ownedMemory.Span;
|
||||||
|
|
||||||
int totalBytesRead = 0;
|
int totalBytesRead = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
{
|
{
|
||||||
public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
string? enumValue = reader.GetString();
|
var enumValue = reader.GetString();
|
||||||
|
|
||||||
if (Enum.TryParse(enumValue, out TEnum value))
|
if (Enum.TryParse(enumValue, out TEnum value))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
{
|
{
|
||||||
if (Path.GetExtension(filename).Equals(".XCI", StringComparison.InvariantCultureIgnoreCase))
|
if (Path.GetExtension(filename).Equals(".XCI", StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
XCIFileTrimmer trimmer = new(filename, log);
|
var trimmer = new XCIFileTrimmer(filename, log);
|
||||||
return trimmer.CanBeTrimmed;
|
return trimmer.CanBeTrimmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
{
|
{
|
||||||
if (Path.GetExtension(filename).Equals(".XCI", StringComparison.InvariantCultureIgnoreCase))
|
if (Path.GetExtension(filename).Equals(".XCI", StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
XCIFileTrimmer trimmer = new(filename, log);
|
var trimmer = new XCIFileTrimmer(filename, log);
|
||||||
return trimmer.CanBeUntrimmed;
|
return trimmer.CanBeUntrimmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
{
|
{
|
||||||
long maxReads = readSizeB / XCIFileTrimmer.BufferSize;
|
long maxReads = readSizeB / XCIFileTrimmer.BufferSize;
|
||||||
long read = 0;
|
long read = 0;
|
||||||
byte[] buffer = new byte[BufferSize];
|
var buffer = new byte[BufferSize];
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@@ -267,7 +267,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FileInfo info = new(Filename);
|
var info = new FileInfo(Filename);
|
||||||
if ((info.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
|
if ((info.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -288,7 +288,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
return OperationOutcome.FileSizeChanged;
|
return OperationOutcome.FileSizeChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream outfileStream = new(_filename, FileMode.Open, FileAccess.Write, FileShare.Write);
|
var outfileStream = new FileStream(_filename, FileMode.Open, FileAccess.Write, FileShare.Write);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -327,7 +327,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
{
|
{
|
||||||
Log?.Write(LogType.Info, "Untrimming...");
|
Log?.Write(LogType.Info, "Untrimming...");
|
||||||
|
|
||||||
FileInfo info = new(Filename);
|
var info = new FileInfo(Filename);
|
||||||
if ((info.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
|
if ((info.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -348,7 +348,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
return OperationOutcome.FileSizeChanged;
|
return OperationOutcome.FileSizeChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream outfileStream = new(_filename, FileMode.Append, FileAccess.Write, FileShare.Write);
|
var outfileStream = new FileStream(_filename, FileMode.Append, FileAccess.Write, FileShare.Write);
|
||||||
long bytesToWriteB = UntrimmedFileSizeB - FileSizeB;
|
long bytesToWriteB = UntrimmedFileSizeB - FileSizeB;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -393,7 +393,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[BufferSize];
|
var buffer = new byte[BufferSize];
|
||||||
Array.Fill<byte>(buffer, XCIFileTrimmer.PaddingByte);
|
Array.Fill<byte>(buffer, XCIFileTrimmer.PaddingByte);
|
||||||
|
|
||||||
while (bytesLeftToWriteB > 0)
|
while (bytesLeftToWriteB > 0)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace ARMeilleure.Common
|
|||||||
|
|
||||||
public TableSparseBlock(ulong size, Action<IntPtr> ensureMapped, PageInitDelegate pageInit)
|
public TableSparseBlock(ulong size, Action<IntPtr> ensureMapped, PageInitDelegate pageInit)
|
||||||
{
|
{
|
||||||
SparseMemoryBlock block = new(size, pageInit, null);
|
var block = new SparseMemoryBlock(size, pageInit, null);
|
||||||
|
|
||||||
_trackingEvent = (ulong address, ulong size, bool write) =>
|
_trackingEvent = (ulong address, ulong size, bool write) =>
|
||||||
{
|
{
|
||||||
@@ -146,7 +146,7 @@ namespace ARMeilleure.Common
|
|||||||
Levels = levels;
|
Levels = levels;
|
||||||
Mask = 0;
|
Mask = 0;
|
||||||
|
|
||||||
foreach (AddressTableLevel level in Levels)
|
foreach (var level in Levels)
|
||||||
{
|
{
|
||||||
Mask |= level.Mask;
|
Mask |= level.Mask;
|
||||||
}
|
}
|
||||||
@@ -363,7 +363,7 @@ namespace ARMeilleure.Common
|
|||||||
/// <returns>The new sparse block that was added</returns>
|
/// <returns>The new sparse block that was added</returns>
|
||||||
private TableSparseBlock ReserveNewSparseBlock()
|
private TableSparseBlock ReserveNewSparseBlock()
|
||||||
{
|
{
|
||||||
TableSparseBlock block = new(_sparseBlockSize, EnsureMapped, InitLeafPage);
|
var block = new TableSparseBlock(_sparseBlockSize, EnsureMapped, InitLeafPage);
|
||||||
|
|
||||||
_sparseReserved.Add(block);
|
_sparseReserved.Add(block);
|
||||||
_sparseReservedOffset = 0;
|
_sparseReservedOffset = 0;
|
||||||
@@ -381,7 +381,7 @@ namespace ARMeilleure.Common
|
|||||||
/// <returns>Allocated block</returns>
|
/// <returns>Allocated block</returns>
|
||||||
private IntPtr Allocate<T>(int length, T fill, bool leaf) where T : unmanaged
|
private IntPtr Allocate<T>(int length, T fill, bool leaf) where T : unmanaged
|
||||||
{
|
{
|
||||||
int size = sizeof(T) * length;
|
var size = sizeof(T) * length;
|
||||||
|
|
||||||
AddressTablePage page;
|
AddressTablePage page;
|
||||||
|
|
||||||
@@ -413,10 +413,10 @@ namespace ARMeilleure.Common
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IntPtr address = (IntPtr)NativeAllocator.Instance.Allocate((uint)size);
|
var address = (IntPtr)NativeAllocator.Instance.Allocate((uint)size);
|
||||||
page = new AddressTablePage(false, address);
|
page = new AddressTablePage(false, address);
|
||||||
|
|
||||||
Span<T> span = new((void*)page.Address, length);
|
var span = new Span<T>((void*)page.Address, length);
|
||||||
span.Fill(fill);
|
span.Fill(fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,7 +445,7 @@ namespace ARMeilleure.Common
|
|||||||
{
|
{
|
||||||
if (!_disposed)
|
if (!_disposed)
|
||||||
{
|
{
|
||||||
foreach (AddressTablePage page in _pages)
|
foreach (var page in _pages)
|
||||||
{
|
{
|
||||||
if (!page.IsSparse)
|
if (!page.IsSparse)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
|
|
||||||
public HvAddressSpace(MemoryBlock backingMemory, ulong asSize)
|
public HvAddressSpace(MemoryBlock backingMemory, ulong asSize)
|
||||||
{
|
{
|
||||||
(_asBase, HvIpaAllocator ipaAllocator) = HvVm.CreateAddressSpace(backingMemory);
|
(_asBase, var ipaAllocator) = HvVm.CreateAddressSpace(backingMemory);
|
||||||
_backingSize = backingMemory.Size;
|
_backingSize = backingMemory.Size;
|
||||||
|
|
||||||
_userRange = new HvAddressSpaceRange(ipaAllocator);
|
_userRange = new HvAddressSpaceRange(ipaAllocator);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
|
|
||||||
public HvMemoryBlockAllocation Allocate(ulong size, ulong alignment)
|
public HvMemoryBlockAllocation Allocate(ulong size, ulong alignment)
|
||||||
{
|
{
|
||||||
Allocation allocation = Allocate(size, alignment, CreateBlock);
|
var allocation = Allocate(size, alignment, CreateBlock);
|
||||||
|
|
||||||
return new HvMemoryBlockAllocation(this, allocation.Block, allocation.Offset, allocation.Size);
|
return new HvMemoryBlockAllocation(this, allocation.Block, allocation.Offset, allocation.Size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -233,13 +233,13 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<MemoryRange> guestRegions = GetPhysicalRegionsImpl(va, size);
|
var guestRegions = GetPhysicalRegionsImpl(va, size);
|
||||||
if (guestRegions == null)
|
if (guestRegions == null)
|
||||||
{
|
{
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (MemoryRange guestRegion in guestRegions)
|
foreach (var guestRegion in guestRegions)
|
||||||
{
|
{
|
||||||
nint pointer = _backingMemory.GetPointer(guestRegion.Address, guestRegion.Size);
|
nint pointer = _backingMemory.GetPointer(guestRegion.Address, guestRegion.Size);
|
||||||
yield return new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size);
|
yield return new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size);
|
||||||
@@ -254,7 +254,7 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (MemoryRange physicalRegion in GetPhysicalRegionsImpl(va, size))
|
foreach (var physicalRegion in GetPhysicalRegionsImpl(va, size))
|
||||||
{
|
{
|
||||||
yield return physicalRegion;
|
yield return physicalRegion;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
{
|
{
|
||||||
// Calculate our time delta in ticks based on the current clock frequency.
|
// Calculate our time delta in ticks based on the current clock frequency.
|
||||||
|
|
||||||
int result = TimeApi.mach_timebase_info(out MachTimebaseInfo timeBaseInfo);
|
int result = TimeApi.mach_timebase_info(out var timeBaseInfo);
|
||||||
|
|
||||||
Debug.Assert(result == 0);
|
Debug.Assert(result == 0);
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment);
|
baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
HvMemoryFlags rwx = HvMemoryFlags.Read | HvMemoryFlags.Write | HvMemoryFlags.Exec;
|
var rwx = HvMemoryFlags.Read | HvMemoryFlags.Write | HvMemoryFlags.Exec;
|
||||||
|
|
||||||
HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError();
|
HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError();
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ namespace Ryujinx.Cpu.Jit.HostTracked
|
|||||||
Debug.Assert(leftSize > 0);
|
Debug.Assert(leftSize > 0);
|
||||||
Debug.Assert(rightSize > 0);
|
Debug.Assert(rightSize > 0);
|
||||||
|
|
||||||
(PrivateMemoryAllocation leftAllocation, PrivateAllocation) = PrivateAllocation.Split(leftSize);
|
(var leftAllocation, PrivateAllocation) = PrivateAllocation.Split(leftSize);
|
||||||
|
|
||||||
PrivateMapping left = new(Address, leftSize, leftAllocation);
|
PrivateMapping left = new(Address, leftSize, leftAllocation);
|
||||||
|
|
||||||
|
|||||||
@@ -253,13 +253,13 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<MemoryRange> guestRegions = GetPhysicalRegionsImpl(va, size);
|
var guestRegions = GetPhysicalRegionsImpl(va, size);
|
||||||
if (guestRegions == null)
|
if (guestRegions == null)
|
||||||
{
|
{
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (MemoryRange guestRegion in guestRegions)
|
foreach (var guestRegion in guestRegions)
|
||||||
{
|
{
|
||||||
nint pointer = _backingMemory.GetPointer(guestRegion.Address, guestRegion.Size);
|
nint pointer = _backingMemory.GetPointer(guestRegion.Address, guestRegion.Size);
|
||||||
yield return new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size);
|
yield return new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size);
|
||||||
@@ -274,7 +274,7 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (MemoryRange physicalRegion in GetPhysicalRegionsImpl(va, size))
|
foreach (var physicalRegion in GetPhysicalRegionsImpl(va, size))
|
||||||
{
|
{
|
||||||
yield return physicalRegion;
|
yield return physicalRegion;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
{
|
{
|
||||||
int pages = GetPagesCount(va, (uint)size, out va);
|
int pages = GetPagesCount(va, (uint)size, out va);
|
||||||
|
|
||||||
List<MemoryRange> regions = new();
|
var regions = new List<MemoryRange>();
|
||||||
|
|
||||||
ulong regionStart = GetPhysicalAddressChecked(va);
|
ulong regionStart = GetPhysicalAddressChecked(va);
|
||||||
ulong regionSize = PageSize;
|
ulong regionSize = PageSize;
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
|
|
||||||
if (TryGetVirtualContiguous(va, data.Length, out MemoryBlock memoryBlock, out ulong offset))
|
if (TryGetVirtualContiguous(va, data.Length, out MemoryBlock memoryBlock, out ulong offset))
|
||||||
{
|
{
|
||||||
Span<byte> target = memoryBlock.GetSpan(offset, data.Length);
|
var target = memoryBlock.GetSpan(offset, data.Length);
|
||||||
|
|
||||||
bool changed = !data.SequenceEqual(target);
|
bool changed = !data.SequenceEqual(target);
|
||||||
|
|
||||||
@@ -443,7 +443,7 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<HostMemoryRange> regions = new();
|
var regions = new List<HostMemoryRange>();
|
||||||
ulong endVa = va + size;
|
ulong endVa = va + size;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
|
|
||||||
for (int i = 0; i < funcTable.Levels.Length; i++)
|
for (int i = 0; i < funcTable.Levels.Length; i++)
|
||||||
{
|
{
|
||||||
AddressTableLevel level = funcTable.Levels[i];
|
var level = funcTable.Levels[i];
|
||||||
asm.Ubfx(indexReg, guestAddress, level.Index, level.Length);
|
asm.Ubfx(indexReg, guestAddress, level.Index, level.Length);
|
||||||
asm.Lsl(indexReg, indexReg, Const(3));
|
asm.Lsl(indexReg, indexReg, Const(3));
|
||||||
|
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
|||||||
|
|
||||||
for (int i = 0; i < funcTable.Levels.Length; i++)
|
for (int i = 0; i < funcTable.Levels.Length; i++)
|
||||||
{
|
{
|
||||||
AddressTableLevel level = funcTable.Levels[i];
|
var level = funcTable.Levels[i];
|
||||||
asm.Ubfx(indexReg, guestAddress, level.Index, level.Length);
|
asm.Ubfx(indexReg, guestAddress, level.Index, level.Length);
|
||||||
asm.Lsl(indexReg, indexReg, Const(3));
|
asm.Lsl(indexReg, indexReg, Const(3));
|
||||||
|
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
|||||||
|
|
||||||
private bool TryGetThreadLocalFunction(ulong guestAddress, out nint funcPtr)
|
private bool TryGetThreadLocalFunction(ulong guestAddress, out nint funcPtr)
|
||||||
{
|
{
|
||||||
if ((_threadLocalCache ??= new()).TryGetValue(guestAddress, out ThreadLocalCacheEntry entry))
|
if ((_threadLocalCache ??= new()).TryGetValue(guestAddress, out var entry))
|
||||||
{
|
{
|
||||||
if (entry.IncrementUseCount() >= MinCallsForPad)
|
if (entry.IncrementUseCount() >= MinCallsForPad)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
int targetIndex = _code.Count;
|
int targetIndex = _code.Count;
|
||||||
|
|
||||||
LabelState state = _labels[label.AsInt32()];
|
var state = _labels[label.AsInt32()];
|
||||||
|
|
||||||
state.TargetIndex = targetIndex;
|
state.TargetIndex = targetIndex;
|
||||||
state.HasTarget = true;
|
state.HasTarget = true;
|
||||||
@@ -68,7 +68,7 @@ namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
int branchIndex = _code.Count;
|
int branchIndex = _code.Count;
|
||||||
|
|
||||||
LabelState state = _labels[label.AsInt32()];
|
var state = _labels[label.AsInt32()];
|
||||||
|
|
||||||
state.BranchIndex = branchIndex;
|
state.BranchIndex = branchIndex;
|
||||||
state.HasBranch = true;
|
state.HasBranch = true;
|
||||||
@@ -94,7 +94,7 @@ namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
int branchIndex = _code.Count;
|
int branchIndex = _code.Count;
|
||||||
|
|
||||||
LabelState state = _labels[label.AsInt32()];
|
var state = _labels[label.AsInt32()];
|
||||||
|
|
||||||
state.BranchIndex = branchIndex;
|
state.BranchIndex = branchIndex;
|
||||||
state.HasBranch = true;
|
state.HasBranch = true;
|
||||||
@@ -113,7 +113,7 @@ namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
int branchIndex = _code.Count;
|
int branchIndex = _code.Count;
|
||||||
|
|
||||||
LabelState state = _labels[label.AsInt32()];
|
var state = _labels[label.AsInt32()];
|
||||||
|
|
||||||
state.BranchIndex = branchIndex;
|
state.BranchIndex = branchIndex;
|
||||||
state.HasBranch = true;
|
state.HasBranch = true;
|
||||||
@@ -342,7 +342,7 @@ namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
|
|||||||
|
|
||||||
public readonly void Cset(Operand rd, ArmCondition condition)
|
public readonly void Cset(Operand rd, ArmCondition condition)
|
||||||
{
|
{
|
||||||
Operand zr = new(ZrRegister, RegisterType.Integer, rd.Type);
|
var zr = new Operand(ZrRegister, RegisterType.Integer, rd.Type);
|
||||||
Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1));
|
Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -857,7 +857,7 @@ namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
|
|||||||
|
|
||||||
public readonly void PrfmI(Operand rn, int imm, uint type, uint target, uint policy)
|
public readonly void PrfmI(Operand rn, int imm, uint type, uint target, uint policy)
|
||||||
{
|
{
|
||||||
Operand rt = new((int)EncodeTypeTargetPolicy(type, target, policy), RegisterType.Integer, OperandType.I32);
|
Operand rt = new Operand((int)EncodeTypeTargetPolicy(type, target, policy), RegisterType.Integer, OperandType.I32);
|
||||||
WriteInstruction(0xf9800000u | (EncodeUImm12(imm, 3) << 10), rt, rn);
|
WriteInstruction(0xf9800000u | (EncodeUImm12(imm, 3) << 10), rt, rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -868,7 +868,7 @@ namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
|
|||||||
|
|
||||||
public readonly void Prfum(Operand rn, int imm, uint type, uint target, uint policy)
|
public readonly void Prfum(Operand rn, int imm, uint type, uint target, uint policy)
|
||||||
{
|
{
|
||||||
Operand rt = new((int)EncodeTypeTargetPolicy(type, target, policy), RegisterType.Integer, OperandType.I32);
|
Operand rt = new Operand((int)EncodeTypeTargetPolicy(type, target, policy), RegisterType.Integer, OperandType.I32);
|
||||||
WriteInstruction(0xf8800000u | (EncodeSImm9(imm) << 12), rt, rn);
|
WriteInstruction(0xf8800000u | (EncodeSImm9(imm) << 12), rt, rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -163,14 +163,14 @@ namespace Ryujinx.Cpu.LightningJit
|
|||||||
{
|
{
|
||||||
List<TranslatedFunction> functions = Functions.AsList();
|
List<TranslatedFunction> functions = Functions.AsList();
|
||||||
|
|
||||||
foreach (TranslatedFunction func in functions)
|
foreach (var func in functions)
|
||||||
{
|
{
|
||||||
JitCache.Unmap(func.FuncPointer);
|
JitCache.Unmap(func.FuncPointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Functions.Clear();
|
Functions.Clear();
|
||||||
|
|
||||||
while (_oldFuncs.TryDequeue(out KeyValuePair<ulong, TranslatedFunction> kv))
|
while (_oldFuncs.TryDequeue(out var kv))
|
||||||
{
|
{
|
||||||
JitCache.Unmap(kv.Value.FuncPointer);
|
JitCache.Unmap(kv.Value.FuncPointer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ namespace Ryujinx.Cpu.LightningJit
|
|||||||
|
|
||||||
for (int i = 0; i < _functionTable.Levels.Length; i++)
|
for (int i = 0; i < _functionTable.Levels.Length; i++)
|
||||||
{
|
{
|
||||||
ref AddressTableLevel level = ref _functionTable.Levels[i];
|
ref var level = ref _functionTable.Levels[i];
|
||||||
|
|
||||||
asm.Mov(mask, level.Mask >> level.Index);
|
asm.Mov(mask, level.Mask >> level.Index);
|
||||||
asm.And(index, mask, guestAddress, ArmShiftType.Lsr, level.Index);
|
asm.And(index, mask, guestAddress, ArmShiftType.Lsr, level.Index);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace Ryujinx.Cpu
|
|||||||
Size = size;
|
Size = size;
|
||||||
_freeRanges = new List<Range>
|
_freeRanges = new List<Range>
|
||||||
{
|
{
|
||||||
new(0, size),
|
new Range(0, size),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ namespace Ryujinx.Cpu
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _freeRanges.Count; i++)
|
for (int i = 0; i < _freeRanges.Count; i++)
|
||||||
{
|
{
|
||||||
Range range = _freeRanges[i];
|
var range = _freeRanges[i];
|
||||||
|
|
||||||
ulong alignedOffset = BitUtils.AlignUp(range.Offset, alignment);
|
ulong alignedOffset = BitUtils.AlignUp(range.Offset, alignment);
|
||||||
ulong sizeDelta = alignedOffset - range.Offset;
|
ulong sizeDelta = alignedOffset - range.Offset;
|
||||||
@@ -84,7 +84,7 @@ namespace Ryujinx.Cpu
|
|||||||
|
|
||||||
private void InsertFreeRange(ulong offset, ulong size)
|
private void InsertFreeRange(ulong offset, ulong size)
|
||||||
{
|
{
|
||||||
Range range = new(offset, size);
|
var range = new Range(offset, size);
|
||||||
int index = _freeRanges.BinarySearch(range);
|
int index = _freeRanges.BinarySearch(range);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
@@ -97,7 +97,7 @@ namespace Ryujinx.Cpu
|
|||||||
private void InsertFreeRangeComingled(ulong offset, ulong size)
|
private void InsertFreeRangeComingled(ulong offset, ulong size)
|
||||||
{
|
{
|
||||||
ulong endOffset = offset + size;
|
ulong endOffset = offset + size;
|
||||||
Range range = new(offset, size);
|
var range = new Range(offset, size);
|
||||||
int index = _freeRanges.BinarySearch(range);
|
int index = _freeRanges.BinarySearch(range);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
@@ -149,7 +149,7 @@ namespace Ryujinx.Cpu
|
|||||||
|
|
||||||
public PrivateMemoryAllocation Allocate(ulong size, ulong alignment)
|
public PrivateMemoryAllocation Allocate(ulong size, ulong alignment)
|
||||||
{
|
{
|
||||||
Allocation allocation = Allocate(size, alignment, CreateBlock);
|
var allocation = Allocate(size, alignment, CreateBlock);
|
||||||
|
|
||||||
return new PrivateMemoryAllocation(this, allocation.Block, allocation.Offset, allocation.Size);
|
return new PrivateMemoryAllocation(this, allocation.Block, allocation.Offset, allocation.Size);
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ namespace Ryujinx.Cpu
|
|||||||
|
|
||||||
for (int i = 0; i < _blocks.Count; i++)
|
for (int i = 0; i < _blocks.Count; i++)
|
||||||
{
|
{
|
||||||
T block = _blocks[i];
|
var block = _blocks[i];
|
||||||
|
|
||||||
if (block.Size >= size)
|
if (block.Size >= size)
|
||||||
{
|
{
|
||||||
@@ -214,8 +214,8 @@ namespace Ryujinx.Cpu
|
|||||||
|
|
||||||
ulong blockAlignedSize = BitUtils.AlignUp(size, _blockAlignment);
|
ulong blockAlignedSize = BitUtils.AlignUp(size, _blockAlignment);
|
||||||
|
|
||||||
MemoryBlock memory = new(blockAlignedSize, _allocationFlags);
|
var memory = new MemoryBlock(blockAlignedSize, _allocationFlags);
|
||||||
T newBlock = createBlock(memory, blockAlignedSize);
|
var newBlock = createBlock(memory, blockAlignedSize);
|
||||||
|
|
||||||
InsertBlock(newBlock);
|
InsertBlock(newBlock);
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ namespace Ryujinx.Cpu.Signal
|
|||||||
_signalHandlerPtr = customSignalHandlerFactory(UnixSignalHandlerRegistration.GetSegfaultExceptionHandler().sa_handler, _signalHandlerPtr);
|
_signalHandlerPtr = customSignalHandlerFactory(UnixSignalHandlerRegistration.GetSegfaultExceptionHandler().sa_handler, _signalHandlerPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnixSignalHandlerRegistration.SigAction old = UnixSignalHandlerRegistration.RegisterExceptionHandler(_signalHandlerPtr);
|
var old = UnixSignalHandlerRegistration.RegisterExceptionHandler(_signalHandlerPtr);
|
||||||
|
|
||||||
config.UnixOldSigaction = (nuint)(ulong)old.sa_handler;
|
config.UnixOldSigaction = (nuint)(ulong)old.sa_handler;
|
||||||
config.UnixOldSigaction3Arg = old.sa_flags & 4;
|
config.UnixOldSigaction3Arg = old.sa_flags & 4;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
@@ -33,15 +32,15 @@ namespace Ryujinx.Graphics.Device
|
|||||||
_debugLogCallback = debugLogCallback;
|
_debugLogCallback = debugLogCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldInfo[] fields = typeof(TState).GetFields();
|
var fields = typeof(TState).GetFields();
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
for (int fieldIndex = 0; fieldIndex < fields.Length; fieldIndex++)
|
for (int fieldIndex = 0; fieldIndex < fields.Length; fieldIndex++)
|
||||||
{
|
{
|
||||||
FieldInfo field = fields[fieldIndex];
|
var field = fields[fieldIndex];
|
||||||
|
|
||||||
int currentFieldOffset = (int)Marshal.OffsetOf<TState>(field.Name);
|
var currentFieldOffset = (int)Marshal.OffsetOf<TState>(field.Name);
|
||||||
int nextFieldOffset = fieldIndex + 1 == fields.Length ? Unsafe.SizeOf<TState>() : (int)Marshal.OffsetOf<TState>(fields[fieldIndex + 1].Name);
|
var nextFieldOffset = fieldIndex + 1 == fields.Length ? Unsafe.SizeOf<TState>() : (int)Marshal.OffsetOf<TState>(fields[fieldIndex + 1].Name);
|
||||||
|
|
||||||
int sizeOfField = nextFieldOffset - currentFieldOffset;
|
int sizeOfField = nextFieldOffset - currentFieldOffset;
|
||||||
|
|
||||||
@@ -49,7 +48,7 @@ namespace Ryujinx.Graphics.Device
|
|||||||
{
|
{
|
||||||
int index = (offset + i) / RegisterSize;
|
int index = (offset + i) / RegisterSize;
|
||||||
|
|
||||||
if (callbacks != null && callbacks.TryGetValue(field.Name, out RwCallback cb))
|
if (callbacks != null && callbacks.TryGetValue(field.Name, out var cb))
|
||||||
{
|
{
|
||||||
if (cb.Read != null)
|
if (cb.Read != null)
|
||||||
{
|
{
|
||||||
@@ -82,7 +81,7 @@ namespace Ryujinx.Graphics.Device
|
|||||||
{
|
{
|
||||||
uint alignedOffset = index * RegisterSize;
|
uint alignedOffset = index * RegisterSize;
|
||||||
|
|
||||||
Func<int> readCallback = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_readCallbacks), (nint)index);
|
var readCallback = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_readCallbacks), (nint)index);
|
||||||
if (readCallback != null)
|
if (readCallback != null)
|
||||||
{
|
{
|
||||||
return readCallback();
|
return readCallback();
|
||||||
@@ -120,7 +119,7 @@ namespace Ryujinx.Graphics.Device
|
|||||||
uint alignedOffset = index * RegisterSize;
|
uint alignedOffset = index * RegisterSize;
|
||||||
DebugWrite(alignedOffset, data);
|
DebugWrite(alignedOffset, data);
|
||||||
|
|
||||||
ref int storage = ref GetRefIntAlignedUncheck(index);
|
ref var storage = ref GetRefIntAlignedUncheck(index);
|
||||||
changed = storage != data;
|
changed = storage != data;
|
||||||
storage = data;
|
storage = data;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
{
|
{
|
||||||
public readonly struct ComputeSize
|
public readonly struct ComputeSize
|
||||||
{
|
{
|
||||||
public readonly static ComputeSize VtgAsCompute = new(32, 32, 1);
|
public readonly static ComputeSize VtgAsCompute = new ComputeSize(32, 32, 1);
|
||||||
|
|
||||||
public readonly int X;
|
public readonly int X;
|
||||||
public readonly int Y;
|
public readonly int Y;
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
|
|
||||||
public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
|
public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
|
||||||
{
|
{
|
||||||
ThreadedCounterEvent evt = value as ThreadedCounterEvent;
|
var evt = value as ThreadedCounterEvent;
|
||||||
if (evt != null)
|
if (evt != null)
|
||||||
{
|
{
|
||||||
if (compare == 0 && evt.Type == CounterType.SamplesPassed && evt.ClearCounter)
|
if (compare == 0 && evt.Type == CounterType.SamplesPassed && evt.ClearCounter)
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
|
|
||||||
public IImageArray CreateImageArray(int size, bool isBuffer)
|
public IImageArray CreateImageArray(int size, bool isBuffer)
|
||||||
{
|
{
|
||||||
ThreadedImageArray imageArray = new(this);
|
var imageArray = new ThreadedImageArray(this);
|
||||||
New<CreateImageArrayCommand>().Set(Ref(imageArray), size, isBuffer);
|
New<CreateImageArrayCommand>().Set(Ref(imageArray), size, isBuffer);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
@@ -303,7 +303,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
|
|
||||||
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
||||||
{
|
{
|
||||||
ThreadedProgram program = new(this);
|
var program = new ThreadedProgram(this);
|
||||||
|
|
||||||
SourceProgramRequest request = new(program, shaders, info);
|
SourceProgramRequest request = new(program, shaders, info);
|
||||||
|
|
||||||
@@ -319,7 +319,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
|
|
||||||
public ISampler CreateSampler(SamplerCreateInfo info)
|
public ISampler CreateSampler(SamplerCreateInfo info)
|
||||||
{
|
{
|
||||||
ThreadedSampler sampler = new(this);
|
var sampler = new ThreadedSampler(this);
|
||||||
New<CreateSamplerCommand>().Set(Ref(sampler), info);
|
New<CreateSamplerCommand>().Set(Ref(sampler), info);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
@@ -337,7 +337,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
{
|
{
|
||||||
if (IsGpuThread())
|
if (IsGpuThread())
|
||||||
{
|
{
|
||||||
ThreadedTexture texture = new(this, info);
|
var texture = new ThreadedTexture(this, info);
|
||||||
New<CreateTextureCommand>().Set(Ref(texture), info);
|
New<CreateTextureCommand>().Set(Ref(texture), info);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadedTexture texture = new(this, info)
|
var texture = new ThreadedTexture(this, info)
|
||||||
{
|
{
|
||||||
Base = _baseRenderer.CreateTexture(info),
|
Base = _baseRenderer.CreateTexture(info),
|
||||||
};
|
};
|
||||||
@@ -355,7 +355,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
}
|
}
|
||||||
public ITextureArray CreateTextureArray(int size, bool isBuffer)
|
public ITextureArray CreateTextureArray(int size, bool isBuffer)
|
||||||
{
|
{
|
||||||
ThreadedTextureArray textureArray = new(this);
|
var textureArray = new ThreadedTextureArray(this);
|
||||||
New<CreateTextureArrayCommand>().Set(Ref(textureArray), size, isBuffer);
|
New<CreateTextureArrayCommand>().Set(Ref(textureArray), size, isBuffer);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
@@ -414,7 +414,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
|
|
||||||
public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
|
public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
|
||||||
{
|
{
|
||||||
ThreadedProgram program = new(this);
|
var program = new ThreadedProgram(this);
|
||||||
|
|
||||||
BinaryProgramRequest request = new(program, programBinary, hasFragmentShader, info);
|
BinaryProgramRequest request = new(program, programBinary, hasFragmentShader, info);
|
||||||
Programs.Add(request);
|
Programs.Add(request);
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
|
|
||||||
if (Descriptors != null)
|
if (Descriptors != null)
|
||||||
{
|
{
|
||||||
foreach (ResourceDescriptor descriptor in Descriptors)
|
foreach (var descriptor in Descriptors)
|
||||||
{
|
{
|
||||||
hasher.Add(descriptor);
|
hasher.Add(descriptor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Ryujinx.Graphics.Device;
|
|||||||
using Ryujinx.Graphics.Gpu.Engine.InlineToMemory;
|
using Ryujinx.Graphics.Gpu.Engine.InlineToMemory;
|
||||||
using Ryujinx.Graphics.Gpu.Engine.Threed;
|
using Ryujinx.Graphics.Gpu.Engine.Threed;
|
||||||
using Ryujinx.Graphics.Gpu.Engine.Types;
|
using Ryujinx.Graphics.Gpu.Engine.Types;
|
||||||
using Ryujinx.Graphics.Gpu.Memory;
|
|
||||||
using Ryujinx.Graphics.Gpu.Shader;
|
using Ryujinx.Graphics.Gpu.Shader;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using System;
|
using System;
|
||||||
@@ -91,7 +90,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
/// <param name="argument">Method call argument</param>
|
/// <param name="argument">Method call argument</param>
|
||||||
private void SendSignalingPcasB(int argument)
|
private void SendSignalingPcasB(int argument)
|
||||||
{
|
{
|
||||||
MemoryManager memoryManager = _channel.MemoryManager;
|
var memoryManager = _channel.MemoryManager;
|
||||||
|
|
||||||
// Since we're going to change the state, make sure any pending instanced draws are done.
|
// Since we're going to change the state, make sure any pending instanced draws are done.
|
||||||
_3dEngine.PerformDeferredDraws();
|
_3dEngine.PerformDeferredDraws();
|
||||||
@@ -101,7 +100,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
|
|
||||||
uint qmdAddress = _state.State.SendPcasA;
|
uint qmdAddress = _state.State.SendPcasA;
|
||||||
|
|
||||||
ComputeQmd qmd = _channel.MemoryManager.Read<ComputeQmd>((ulong)qmdAddress << 8);
|
var qmd = _channel.MemoryManager.Read<ComputeQmd>((ulong)qmdAddress << 8);
|
||||||
|
|
||||||
ulong shaderGpuVa = ((ulong)_state.State.SetProgramRegionAAddressUpper << 32) | _state.State.SetProgramRegionB;
|
ulong shaderGpuVa = ((ulong)_state.State.SetProgramRegionAAddressUpper << 32) | _state.State.SetProgramRegionB;
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void WriteWithRedundancyCheck(int offset, int value, out bool changed)
|
public void WriteWithRedundancyCheck(int offset, int value, out bool changed)
|
||||||
{
|
{
|
||||||
SetMmeShadowRamControlMode shadowRamControl = _state.State.SetMmeShadowRamControlMode;
|
var shadowRamControl = _state.State.SetMmeShadowRamControlMode;
|
||||||
if (shadowRamControl == SetMmeShadowRamControlMode.MethodPassthrough || offset < 0x200)
|
if (shadowRamControl == SetMmeShadowRamControlMode.MethodPassthrough || offset < 0x200)
|
||||||
{
|
{
|
||||||
_state.WriteWithRedundancyCheck(offset, value, out changed);
|
_state.WriteWithRedundancyCheck(offset, value, out changed);
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
/// <param name="argument">The LaunchDma call argument</param>
|
/// <param name="argument">The LaunchDma call argument</param>
|
||||||
private void DmaCopy(int argument)
|
private void DmaCopy(int argument)
|
||||||
{
|
{
|
||||||
MemoryManager memoryManager = _channel.MemoryManager;
|
var memoryManager = _channel.MemoryManager;
|
||||||
|
|
||||||
CopyFlags copyFlags = (CopyFlags)argument;
|
CopyFlags copyFlags = (CopyFlags)argument;
|
||||||
|
|
||||||
@@ -225,8 +225,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
int srcBpp = remap ? srcComponents * componentSize : 1;
|
int srcBpp = remap ? srcComponents * componentSize : 1;
|
||||||
int dstBpp = remap ? dstComponents * componentSize : 1;
|
int dstBpp = remap ? dstComponents * componentSize : 1;
|
||||||
|
|
||||||
DmaTexture dst = Unsafe.As<uint, DmaTexture>(ref _state.State.SetDstBlockSize);
|
var dst = Unsafe.As<uint, DmaTexture>(ref _state.State.SetDstBlockSize);
|
||||||
DmaTexture src = Unsafe.As<uint, DmaTexture>(ref _state.State.SetSrcBlockSize);
|
var src = Unsafe.As<uint, DmaTexture>(ref _state.State.SetSrcBlockSize);
|
||||||
|
|
||||||
int srcRegionX = 0, srcRegionY = 0, dstRegionX = 0, dstRegionY = 0;
|
int srcRegionX = 0, srcRegionY = 0, dstRegionX = 0, dstRegionY = 0;
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
int srcStride = (int)_state.State.PitchIn;
|
int srcStride = (int)_state.State.PitchIn;
|
||||||
int dstStride = (int)_state.State.PitchOut;
|
int dstStride = (int)_state.State.PitchOut;
|
||||||
|
|
||||||
OffsetCalculator srcCalculator = new(
|
var srcCalculator = new OffsetCalculator(
|
||||||
src.Width,
|
src.Width,
|
||||||
src.Height,
|
src.Height,
|
||||||
srcStride,
|
srcStride,
|
||||||
@@ -254,7 +254,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
src.MemoryLayout.UnpackGobBlocksInZ(),
|
src.MemoryLayout.UnpackGobBlocksInZ(),
|
||||||
srcBpp);
|
srcBpp);
|
||||||
|
|
||||||
OffsetCalculator dstCalculator = new(
|
var dstCalculator = new OffsetCalculator(
|
||||||
dst.Width,
|
dst.Width,
|
||||||
dst.Height,
|
dst.Height,
|
||||||
dstStride,
|
dstStride,
|
||||||
@@ -293,7 +293,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
|
|
||||||
if (completeSource && completeDest && !srcLinear && isIdentityRemap)
|
if (completeSource && completeDest && !srcLinear && isIdentityRemap)
|
||||||
{
|
{
|
||||||
Image.Texture source = memoryManager.Physical.TextureCache.FindTexture(
|
var source = memoryManager.Physical.TextureCache.FindTexture(
|
||||||
memoryManager,
|
memoryManager,
|
||||||
srcGpuVa,
|
srcGpuVa,
|
||||||
srcBpp,
|
srcBpp,
|
||||||
@@ -309,7 +309,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
{
|
{
|
||||||
source.SynchronizeMemory();
|
source.SynchronizeMemory();
|
||||||
|
|
||||||
Image.Texture target = memoryManager.Physical.TextureCache.FindOrCreateTexture(
|
var target = memoryManager.Physical.TextureCache.FindOrCreateTexture(
|
||||||
memoryManager,
|
memoryManager,
|
||||||
source.Info.FormatInfo,
|
source.Info.FormatInfo,
|
||||||
dstGpuVa,
|
dstGpuVa,
|
||||||
@@ -339,7 +339,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
|
|
||||||
if (completeSource && completeDest && !(dstLinear && !srcLinear) && isIdentityRemap)
|
if (completeSource && completeDest && !(dstLinear && !srcLinear) && isIdentityRemap)
|
||||||
{
|
{
|
||||||
Image.Texture target = memoryManager.Physical.TextureCache.FindTexture(
|
var target = memoryManager.Physical.TextureCache.FindTexture(
|
||||||
memoryManager,
|
memoryManager,
|
||||||
dstGpuVa,
|
dstGpuVa,
|
||||||
dstBpp,
|
dstBpp,
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||||||
int availableCount = commandBuffer.Length - offset;
|
int availableCount = commandBuffer.Length - offset;
|
||||||
int consumeCount = Math.Min(_state.MethodCount, availableCount);
|
int consumeCount = Math.Min(_state.MethodCount, availableCount);
|
||||||
|
|
||||||
ReadOnlySpan<int> data = commandBuffer.Slice(offset, consumeCount);
|
var data = commandBuffer.Slice(offset, consumeCount);
|
||||||
|
|
||||||
if (_state.SubChannel == 0)
|
if (_state.SubChannel == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Graphics.Device;
|
using Ryujinx.Graphics.Device;
|
||||||
using Ryujinx.Graphics.Gpu.Memory;
|
|
||||||
using Ryujinx.Graphics.Texture;
|
using Ryujinx.Graphics.Texture;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -169,9 +168,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void FinishTransfer()
|
private void FinishTransfer()
|
||||||
{
|
{
|
||||||
MemoryManager memoryManager = _channel.MemoryManager;
|
var memoryManager = _channel.MemoryManager;
|
||||||
|
|
||||||
Span<byte> data = MemoryMarshal.Cast<int, byte>(_buffer)[.._size];
|
var data = MemoryMarshal.Cast<int, byte>(_buffer)[.._size];
|
||||||
|
|
||||||
if (_isLinear && _lineCount == 1)
|
if (_isLinear && _lineCount == 1)
|
||||||
{
|
{
|
||||||
@@ -185,7 +184,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||||||
// Right now the copy code at the bottom assumes that it is used on both which might be incorrect.
|
// Right now the copy code at the bottom assumes that it is used on both which might be incorrect.
|
||||||
if (!_isLinear)
|
if (!_isLinear)
|
||||||
{
|
{
|
||||||
Image.Texture target = memoryManager.Physical.TextureCache.FindTexture(
|
var target = memoryManager.Physical.TextureCache.FindTexture(
|
||||||
memoryManager,
|
memoryManager,
|
||||||
_dstGpuVa,
|
_dstGpuVa,
|
||||||
1,
|
1,
|
||||||
@@ -200,7 +199,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||||||
if (target != null)
|
if (target != null)
|
||||||
{
|
{
|
||||||
target.SynchronizeMemory();
|
target.SynchronizeMemory();
|
||||||
MemoryOwner<byte> dataCopy = MemoryOwner<byte>.RentCopy(data);
|
var dataCopy = MemoryOwner<byte>.RentCopy(data);
|
||||||
target.SetData(dataCopy, 0, 0, new GAL.Rectangle<int>(_dstX, _dstY, _lineLengthIn / target.Info.FormatInfo.BytesPerPixel, _lineCount));
|
target.SetData(dataCopy, 0, 0, new GAL.Rectangle<int>(_dstX, _dstY, _lineLengthIn / target.Info.FormatInfo.BytesPerPixel, _lineCount));
|
||||||
target.SignalModified();
|
target.SignalModified();
|
||||||
|
|
||||||
@@ -208,7 +207,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OffsetCalculator dstCalculator = new(
|
var dstCalculator = new OffsetCalculator(
|
||||||
_dstWidth,
|
_dstWidth,
|
||||||
_dstHeight,
|
_dstHeight,
|
||||||
_dstStride,
|
_dstStride,
|
||||||
|
|||||||
@@ -285,12 +285,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||||||
/// <param name="arg0">First argument of the call</param>
|
/// <param name="arg0">First argument of the call</param>
|
||||||
private void DrawArraysInstanced(IDeviceState state, int arg0)
|
private void DrawArraysInstanced(IDeviceState state, int arg0)
|
||||||
{
|
{
|
||||||
PrimitiveTopology topology = (PrimitiveTopology)arg0;
|
var topology = (PrimitiveTopology)arg0;
|
||||||
|
|
||||||
FifoWord count = FetchParam();
|
var count = FetchParam();
|
||||||
FifoWord instanceCount = FetchParam();
|
var instanceCount = FetchParam();
|
||||||
FifoWord firstVertex = FetchParam();
|
var firstVertex = FetchParam();
|
||||||
FifoWord firstInstance = FetchParam();
|
var firstInstance = FetchParam();
|
||||||
|
|
||||||
if (ShouldSkipDraw(state, instanceCount.Word))
|
if (ShouldSkipDraw(state, instanceCount.Word))
|
||||||
{
|
{
|
||||||
@@ -314,13 +314,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||||||
/// <param name="arg0">First argument of the call</param>
|
/// <param name="arg0">First argument of the call</param>
|
||||||
private void DrawElements(IDeviceState state, int arg0)
|
private void DrawElements(IDeviceState state, int arg0)
|
||||||
{
|
{
|
||||||
PrimitiveTopology topology = (PrimitiveTopology)arg0;
|
var topology = (PrimitiveTopology)arg0;
|
||||||
|
|
||||||
FifoWord indexAddressHigh = FetchParam();
|
var indexAddressHigh = FetchParam();
|
||||||
FifoWord indexAddressLow = FetchParam();
|
var indexAddressLow = FetchParam();
|
||||||
FifoWord indexType = FetchParam();
|
var indexType = FetchParam();
|
||||||
int firstIndex = 0;
|
var firstIndex = 0;
|
||||||
FifoWord indexCount = FetchParam();
|
var indexCount = FetchParam();
|
||||||
|
|
||||||
_processor.ThreedClass.UpdateIndexBuffer(
|
_processor.ThreedClass.UpdateIndexBuffer(
|
||||||
(uint)indexAddressHigh.Word,
|
(uint)indexAddressHigh.Word,
|
||||||
@@ -344,13 +344,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||||||
/// <param name="arg0">First argument of the call</param>
|
/// <param name="arg0">First argument of the call</param>
|
||||||
private void DrawElementsInstanced(IDeviceState state, int arg0)
|
private void DrawElementsInstanced(IDeviceState state, int arg0)
|
||||||
{
|
{
|
||||||
PrimitiveTopology topology = (PrimitiveTopology)arg0;
|
var topology = (PrimitiveTopology)arg0;
|
||||||
|
|
||||||
FifoWord count = FetchParam();
|
var count = FetchParam();
|
||||||
FifoWord instanceCount = FetchParam();
|
var instanceCount = FetchParam();
|
||||||
FifoWord firstIndex = FetchParam();
|
var firstIndex = FetchParam();
|
||||||
FifoWord firstVertex = FetchParam();
|
var firstVertex = FetchParam();
|
||||||
FifoWord firstInstance = FetchParam();
|
var firstInstance = FetchParam();
|
||||||
|
|
||||||
if (ShouldSkipDraw(state, instanceCount.Word))
|
if (ShouldSkipDraw(state, instanceCount.Word))
|
||||||
{
|
{
|
||||||
@@ -374,17 +374,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||||||
/// <param name="arg0">First argument of the call</param>
|
/// <param name="arg0">First argument of the call</param>
|
||||||
private void DrawElementsIndirect(IDeviceState state, int arg0)
|
private void DrawElementsIndirect(IDeviceState state, int arg0)
|
||||||
{
|
{
|
||||||
PrimitiveTopology topology = (PrimitiveTopology)arg0;
|
var topology = (PrimitiveTopology)arg0;
|
||||||
|
|
||||||
FifoWord count = FetchParam();
|
var count = FetchParam();
|
||||||
FifoWord instanceCount = FetchParam();
|
var instanceCount = FetchParam();
|
||||||
FifoWord firstIndex = FetchParam();
|
var firstIndex = FetchParam();
|
||||||
FifoWord firstVertex = FetchParam();
|
var firstVertex = FetchParam();
|
||||||
FifoWord firstInstance = FetchParam();
|
var firstInstance = FetchParam();
|
||||||
|
|
||||||
ulong indirectBufferGpuVa = count.GpuVa;
|
ulong indirectBufferGpuVa = count.GpuVa;
|
||||||
|
|
||||||
BufferCache bufferCache = _processor.MemoryManager.Physical.BufferCache;
|
var bufferCache = _processor.MemoryManager.Physical.BufferCache;
|
||||||
|
|
||||||
bool useBuffer = bufferCache.CheckModified(_processor.MemoryManager, indirectBufferGpuVa, IndirectIndexedDataEntrySize, out ulong indirectBufferAddress);
|
bool useBuffer = bufferCache.CheckModified(_processor.MemoryManager, indirectBufferGpuVa, IndirectIndexedDataEntrySize, out ulong indirectBufferAddress);
|
||||||
|
|
||||||
@@ -432,7 +432,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||||||
|
|
||||||
int startDraw = arg0;
|
int startDraw = arg0;
|
||||||
int endDraw = arg1;
|
int endDraw = arg1;
|
||||||
PrimitiveTopology topology = (PrimitiveTopology)arg2;
|
var topology = (PrimitiveTopology)arg2;
|
||||||
int paddingWords = arg3;
|
int paddingWords = arg3;
|
||||||
int stride = paddingWords * 4 + 0x14;
|
int stride = paddingWords * 4 + 0x14;
|
||||||
|
|
||||||
@@ -468,12 +468,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||||||
|
|
||||||
for (int i = 0; i < maxDrawCount; i++)
|
for (int i = 0; i < maxDrawCount; i++)
|
||||||
{
|
{
|
||||||
FifoWord count = FetchParam();
|
var count = FetchParam();
|
||||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||||
FifoWord instanceCount = FetchParam();
|
var instanceCount = FetchParam();
|
||||||
FifoWord firstIndex = FetchParam();
|
var firstIndex = FetchParam();
|
||||||
FifoWord firstVertex = FetchParam();
|
var firstVertex = FetchParam();
|
||||||
FifoWord firstInstance = FetchParam();
|
var firstInstance = FetchParam();
|
||||||
#pragma warning restore IDE0059
|
#pragma warning restore IDE0059
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
@@ -492,7 +492,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCache bufferCache = _processor.MemoryManager.Physical.BufferCache;
|
var bufferCache = _processor.MemoryManager.Physical.BufferCache;
|
||||||
|
|
||||||
ulong indirectBufferSize = (ulong)maxDrawCount * (ulong)stride;
|
ulong indirectBufferSize = (ulong)maxDrawCount * (ulong)stride;
|
||||||
|
|
||||||
@@ -526,7 +526,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||||||
/// <returns>The call argument, or a 0 value with null address if the FIFO is empty</returns>
|
/// <returns>The call argument, or a 0 value with null address if the FIFO is empty</returns>
|
||||||
private FifoWord FetchParam()
|
private FifoWord FetchParam()
|
||||||
{
|
{
|
||||||
if (!Fifo.TryDequeue(out FifoWord value))
|
if (!Fifo.TryDequeue(out var value))
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Gpu, "Macro attempted to fetch an inexistent argument.");
|
Logger.Warning?.Print(LogClass.Gpu, "Macro attempted to fetch an inexistent argument.");
|
||||||
|
|
||||||
|
|||||||
@@ -90,13 +90,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||||||
/// <returns>True if there is a implementation available and supported, false otherwise</returns>
|
/// <returns>True if there is a implementation available and supported, false otherwise</returns>
|
||||||
public static bool TryGetMacroHLEFunction(ReadOnlySpan<int> code, Capabilities caps, out MacroHLEFunctionName name)
|
public static bool TryGetMacroHLEFunction(ReadOnlySpan<int> code, Capabilities caps, out MacroHLEFunctionName name)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<byte> mc = MemoryMarshal.Cast<int, byte>(code);
|
var mc = MemoryMarshal.Cast<int, byte>(code);
|
||||||
|
|
||||||
for (int i = 0; i < _table.Length; i++)
|
for (int i = 0; i < _table.Length; i++)
|
||||||
{
|
{
|
||||||
ref TableEntry entry = ref _table[i];
|
ref var entry = ref _table[i];
|
||||||
|
|
||||||
Hash128 hash = Hash128.ComputeHash(mc[..entry.Length]);
|
var hash = Hash128.ComputeHash(mc[..entry.Length]);
|
||||||
if (hash == entry.Hash)
|
if (hash == entry.Hash)
|
||||||
{
|
{
|
||||||
if (IsMacroHLESupported(caps, entry.Name))
|
if (IsMacroHLESupported(caps, entry.Name))
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user