Compare commits

..

11 Commits

Author SHA1 Message Date
Domenico V
2be8b6ea45 CPU (A64): Add Fmaxp & Fminp Scalar Inst.s, Fast & Slow Paths; with Tests. (#5502)
* Add Fmaxp & Fminp Scalar Inst.s, Fast & Slow Paths; with Tests.

* Ptc.InternalVersion = 5502
2023-07-30 20:57:37 -03:00
gdkchan
f95b7c5877 Fix incorrect fragment origin when YNegate is enabled (#4673)
* Fix incorrect fragment origin when YNegate is enabled

* Shader cache version bump

* Do not update support buffer if shader does not read gl_FragCoord

* Pass unscaled viewport size to the support buffer
2023-07-29 18:47:03 -03:00
TSRBerry
eb528ae0f0 Add workflow to automatically check code style issues for PRs (#4670)
* Add workflow to perform automated checks for PRs

* Downgrade Microsoft.CodeAnalysis to 4.4.0

This is a workaround to fix issues with dotnet-format.
See:
- https://github.com/dotnet/format/issues/1805
- https://github.com/dotnet/format/issues/1800

* Adjust editorconfig to be more compatible with Ryujinx code-style

* Adjust .editorconfig line endings to match .gitattributes

* Disable 'prefer switch expression' rule

* Remove naming styles

These are the default rules, so we don't need to override them.

* Silence IDE0060 in .editorconfig

* Slightly adjust .editorconfig

* Add lost workflow changes

* Move .editorconfig comment to the top

* .editorconfig: private static readonly fields should be _lowerCamelCase

* .editorconfig: Remove alignment for declarations as well

* editorconfig: Add rule for local constants

* Disable CA1822 for HLE services

* Disable CA1822 for ViewModels

Bindings won't work with static members, but this issue is silently ignored.

* Run dotnet format for the whole solution

* Check result code of SDL_GetDisplayBounds

* Fix dotnet format style issues

* Add missing trailing commas

* Update Microsoft.CodeAnalysis.CSharp to 4.6.0

Skipping 4.5.0 since it breaks dotnet format

* Restore old default naming rules for dotnet format

* Add naming rule exception for CPU tests

* checks: Include all files before excluding paths

* Fix dotnet format issues

* Check dotnet format version

* checks: Run dotnet format with severity info again

* checks: Disable naming style rules until they won't crash the process anymore

* Remove unread private member

* checks: Attempt to run analyzers 3 times before giving up

* checks: Enable naming style rules again with the new retry logic
2023-07-24 18:35:04 +02:00
Mary
487261592e ava: Fix regression on title updater and dlc manager window caused by precious commit 2023-07-21 22:50:10 +02:00
MutantAura
9e04e6cba1 Ava UI: Remove IsActive checks from dialog methods (#5456)
* Remove `IsActive` checks from dialog methods

* Remove old windows bandaid

* Remove null dialog code path entirely and return nothing.
2023-07-21 12:24:13 +01:00
TSRBerry
4cf2419e6c HLE: Fix corrupted Mii structs (#5468)
* StructArrayHelpers: Add PureAttribute to all AsSpan() methods

* Fix broken Mii structs
2023-07-19 22:02:31 -03:00
Mary
440abac9f8 chore: Update Ryujinx.SDL2-CS to 2.28.1 (#5453) 2023-07-18 16:08:48 +02:00
TSRBerry
732714349e [Hotfix] sockets: Resolve empty port requests to 0 again (#5459) 2023-07-17 20:47:47 +02:00
TSRBerry
016262514d cpu: Hotfix missing ToNearest rounding mode cases 2023-07-16 20:39:08 +01:00
TSRBerry
326749498b [Ryujinx.HLE] Address dotnet-format issues (#5380)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2208 warnings

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

* Address dotnet format CA2211 warnings

* Address dotnet format CA1822 warnings

* Address or silence dotnet format CA1069 warnings

* Make dotnet format succeed in style mode

* Address or silence dotnet format CA2211 warnings

* Address review comments

* Address dotnet format CA2208 warnings properly

* Make ProcessResult readonly

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

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

* Add previously silenced warnings back

I have no clue how these disappeared

* Revert formatting changes for while and for-loops

* Format if-blocks correctly

* Run dotnet format style after rebase

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Fix a few disabled warnings

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

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

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Run dotnet format after rebase

* Use using declaration instead of block syntax

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

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

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix naming rule violations

* Fix typo

* Add trailing commas, use targeted new and use array initializer

* Fix build issues

* Fix remaining build issues

* Remove SuppressMessage for CA1069 where possible

* Address dotnet format issues

* Address formatting issues

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

* Add GetHashCode implementation for RenderingSurfaceInfo

* Explicitly silence CA1822 for every affected method in Syscall

* Address formatting issues in Demangler.cs

* Address review feedback

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

* Revert marking service methods as static

* Next dotnet format pass

* Address review feedback

---------

Co-authored-by: Ac_K <acoustik666@gmail.com>
2023-07-16 19:31:14 +02:00
Mary
fec8291c17 infra: do not assign developers team for now
Hopefully fix PR triage for real...
2023-07-14 11:32:14 +02:00
1122 changed files with 8844 additions and 7823 deletions

View File

@@ -1,8 +1,7 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories # Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true root = true
# C# files [*]
[*.cs]
#### Core EditorConfig Options #### #### Core EditorConfig Options ####
@@ -12,8 +11,11 @@ indent_style = space
tab_width = 4 tab_width = 4
# New line preferences # New line preferences
end_of_line = crlf end_of_line = lf
insert_final_newline = false insert_final_newline = true
# C# files
[*.cs]
#### .NET Coding Conventions #### #### .NET Coding Conventions ####
@@ -59,7 +61,7 @@ dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_readonly_field = true:suggestion dotnet_style_readonly_field = true:suggestion
# Parameter preferences # Parameter preferences
dotnet_code_quality_unused_parameters = all:suggestion dotnet_code_quality_unused_parameters = all:silent
#### C# Coding Conventions #### #### C# Coding Conventions ####
@@ -85,7 +87,7 @@ csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences # Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_prefer_switch_expression = true:suggestion csharp_style_prefer_switch_expression = false:silent
# Null-checking preferences # Null-checking preferences
csharp_style_conditional_delegate_call = true:suggestion csharp_style_conditional_delegate_call = true:suggestion
@@ -94,6 +96,7 @@ csharp_style_conditional_delegate_call = true:suggestion
csharp_prefer_static_local_function = true:suggestion csharp_prefer_static_local_function = true:suggestion
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
csharp_style_prefer_readonly_struct = true csharp_style_prefer_readonly_struct = true
csharp_style_prefer_method_group_conversion = true
# Code-block preferences # Code-block preferences
csharp_prefer_braces = true:silent csharp_prefer_braces = true:silent
@@ -109,6 +112,7 @@ csharp_style_prefer_range_operator = true:suggestion
csharp_style_throw_expression = true:suggestion csharp_style_throw_expression = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent csharp_style_unused_value_expression_statement_preference = discard_variable:silent
csharp_style_implicit_object_creation_when_type_is_apparent = true
# 'using' directive preferences # 'using' directive preferences
csharp_using_directive_placement = outside_namespace:silent csharp_using_directive_placement = outside_namespace:silent
@@ -140,7 +144,6 @@ csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false csharp_space_before_comma = false
csharp_space_before_dot = false csharp_space_before_dot = false
@@ -158,23 +161,31 @@ csharp_space_between_square_brackets = false
# Wrapping preferences # Wrapping preferences
csharp_preserve_single_line_blocks = true csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true csharp_preserve_single_line_statements = false
#### Naming styles #### #### Naming styles ####
# Naming rules # Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion dotnet_naming_rule.interfaces_should_be_prefixed_with_I.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface dotnet_naming_rule.interfaces_should_be_prefixed_with_I.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i dotnet_naming_rule.interfaces_should_be_prefixed_with_I.style = IPascalCase
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case dotnet_naming_rule.types_should_be_pascal_case.style = PascalCase
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case dotnet_naming_rule.non_field_members_should_be_pascal_case.style = PascalCase
dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.symbols = private_static_readonly_fields
dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.severity = suggestion
dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.style = _camelCase
dotnet_naming_rule.local_constants_should_be_pascal_case.symbols = local_constants
dotnet_naming_rule.local_constants_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.local_constants_should_be_pascal_case.style = PascalCase
# Symbol specifications # Symbol specifications
@@ -190,14 +201,39 @@ dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, meth
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers = dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private
dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = static, readonly
dotnet_naming_symbols.local_constants.applicable_kinds = local
dotnet_naming_symbols.local_constants.applicable_accessibilities = local
dotnet_naming_symbols.local_constants.required_modifiers = const
# Naming styles # Naming styles
dotnet_naming_style.pascal_case.required_prefix = dotnet_naming_style._camelCase.required_prefix = _
dotnet_naming_style.pascal_case.required_suffix = dotnet_naming_style._camelCase.required_suffix =
dotnet_naming_style.pascal_case.word_separator = dotnet_naming_style._camelCase.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case dotnet_naming_style._camelCase.capitalization = camel_case
dotnet_naming_style.begins_with_i.required_prefix = I dotnet_naming_style.PascalCase.required_prefix =
dotnet_naming_style.begins_with_i.required_suffix = dotnet_naming_style.PascalCase.required_suffix =
dotnet_naming_style.begins_with_i.word_separator = dotnet_naming_style.PascalCase.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case dotnet_naming_style.PascalCase.capitalization = pascal_case
dotnet_naming_style.IPascalCase.required_prefix = I
dotnet_naming_style.IPascalCase.required_suffix =
dotnet_naming_style.IPascalCase.word_separator =
dotnet_naming_style.IPascalCase.capitalization = pascal_case
[src/Ryujinx.HLE/HOS/Services/**.cs]
# Disable "mark members as static" rule for services
dotnet_diagnostic.CA1822.severity = none
[src/Ryujinx.Ava/UI/ViewModels/**.cs]
# Disable "mark members as static" rule for ViewModels
dotnet_diagnostic.CA1822.severity = none
[src/Ryujinx.Tests/Cpu/*.cs]
# Disable naming rules for CPU tests
dotnet_diagnostic.IDE1006.severity = none

View File

@@ -29,4 +29,4 @@ infra:
- TSRBerry - TSRBerry
default: default:
- "@developers" - marysaka

View File

@@ -1,19 +1,10 @@
name: Build job name: Build job
on: on:
workflow_dispatch: workflow_call:
inputs: {}
pull_request:
branches: [ master ]
paths-ignore:
- '.github/**'
- '*.yml'
- '*.json'
- '*.config'
- 'README.md'
concurrency: concurrency:
group: pr-checks-${{ github.event.number }} group: pr-builds-${{ github.event.number }}
cancel-in-progress: true cancel-in-progress: true
env: env:

71
.github/workflows/checks.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
name: Perform checks
on:
pull_request:
branches: [ master ]
paths:
- '**'
- '!.github/**'
- '!*.yml'
- '!*.config'
- '!README.md'
- '.github/workflows/*.yml'
permissions:
pull-requests: write
checks: write
concurrency:
group: pr-checks-${{ github.event.number }}
cancel-in-progress: true
jobs:
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-dotnet@v3
with:
global-json-file: global.json
- run: dotnet restore
- name: Print dotnet format version
run: dotnet format --version
- name: Run dotnet format whitespace
run: |
dotnet format whitespace --verify-no-changes --report ./whitespace-report.json -v d
- name: Run dotnet format style
run: |
dotnet format style --severity info --verify-no-changes --report ./style-report.json -v d
# For some reason this step sometimes fails with exit code 139 (segfault?),
# so should that be the case we'll try again (3 tries max).
- name: Run dotnet format analyzers
run: |
attempt=0
exit_code=139
until [ $attempt -ge 3 ] || [ $exit_code -ne 139 ]; do
((attempt+=1))
exit_code=0
echo "Attempt: ${attempt}/3"
dotnet format analyzers --severity info --verify-no-changes --report ./analyzers-report.json -v d || exit_code=$?
done
exit $exit_code
- name: Upload report
if: failure()
uses: actions/upload-artifact@v3
with:
name: dotnet-format
path: ./*-report.json
pr_build:
uses: ./.github/workflows/build.yml
needs: format
secrets: inherit

View File

@@ -1,8 +1,10 @@
name: Comment PR artifacts links name: Comment PR artifacts links
on: on:
workflow_run: workflow_run:
workflows: ['Build job'] workflows: ['Perform checks']
types: [completed] types: [completed]
jobs: jobs:
pr_comment: pr_comment:
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'

View File

@@ -20,7 +20,7 @@
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" /> <PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" />
<PackageVersion Include="LibHac" Version="0.18.0" /> <PackageVersion Include="LibHac" Version="0.18.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" /> <PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" /> <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.6.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.3" /> <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" /> <PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" /> <PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
@@ -34,7 +34,7 @@
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
<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.GtkSharp" Version="3.24.24.59-ryujinx" /> <PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.3-build25" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.28.1-build28" />
<PackageVersion Include="shaderc.net" Version="0.1.0" /> <PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" /> <PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" /> <PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />

View File

@@ -330,6 +330,7 @@ namespace ARMeilleure.Decoders
SetA64("011111100x110000110010xxxxxxxxxx", InstName.Fmaxnmp_S, InstEmit.Fmaxnmp_S, OpCodeSimd.Create); SetA64("011111100x110000110010xxxxxxxxxx", InstName.Fmaxnmp_S, InstEmit.Fmaxnmp_S, OpCodeSimd.Create);
SetA64("0>1011100<1xxxxx110001xxxxxxxxxx", InstName.Fmaxnmp_V, InstEmit.Fmaxnmp_V, OpCodeSimdReg.Create); SetA64("0>1011100<1xxxxx110001xxxxxxxxxx", InstName.Fmaxnmp_V, InstEmit.Fmaxnmp_V, OpCodeSimdReg.Create);
SetA64("0110111000110000110010xxxxxxxxxx", InstName.Fmaxnmv_V, InstEmit.Fmaxnmv_V, OpCodeSimd.Create); SetA64("0110111000110000110010xxxxxxxxxx", InstName.Fmaxnmv_V, InstEmit.Fmaxnmv_V, OpCodeSimd.Create);
SetA64("011111100x110000111110xxxxxxxxxx", InstName.Fmaxp_S, InstEmit.Fmaxp_S, OpCodeSimd.Create);
SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", InstName.Fmaxp_V, InstEmit.Fmaxp_V, OpCodeSimdReg.Create); SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", InstName.Fmaxp_V, InstEmit.Fmaxp_V, OpCodeSimdReg.Create);
SetA64("0110111000110000111110xxxxxxxxxx", InstName.Fmaxv_V, InstEmit.Fmaxv_V, OpCodeSimd.Create); SetA64("0110111000110000111110xxxxxxxxxx", InstName.Fmaxv_V, InstEmit.Fmaxv_V, OpCodeSimd.Create);
SetA64("000111100x1xxxxx010110xxxxxxxxxx", InstName.Fmin_S, InstEmit.Fmin_S, OpCodeSimdReg.Create); SetA64("000111100x1xxxxx010110xxxxxxxxxx", InstName.Fmin_S, InstEmit.Fmin_S, OpCodeSimdReg.Create);
@@ -339,6 +340,7 @@ namespace ARMeilleure.Decoders
SetA64("011111101x110000110010xxxxxxxxxx", InstName.Fminnmp_S, InstEmit.Fminnmp_S, OpCodeSimd.Create); SetA64("011111101x110000110010xxxxxxxxxx", InstName.Fminnmp_S, InstEmit.Fminnmp_S, OpCodeSimd.Create);
SetA64("0>1011101<1xxxxx110001xxxxxxxxxx", InstName.Fminnmp_V, InstEmit.Fminnmp_V, OpCodeSimdReg.Create); SetA64("0>1011101<1xxxxx110001xxxxxxxxxx", InstName.Fminnmp_V, InstEmit.Fminnmp_V, OpCodeSimdReg.Create);
SetA64("0110111010110000110010xxxxxxxxxx", InstName.Fminnmv_V, InstEmit.Fminnmv_V, OpCodeSimd.Create); SetA64("0110111010110000110010xxxxxxxxxx", InstName.Fminnmv_V, InstEmit.Fminnmv_V, OpCodeSimd.Create);
SetA64("011111101x110000111110xxxxxxxxxx", InstName.Fminp_S, InstEmit.Fminp_S, OpCodeSimd.Create);
SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", InstName.Fminp_V, InstEmit.Fminp_V, OpCodeSimdReg.Create); SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", InstName.Fminp_V, InstEmit.Fminp_V, OpCodeSimdReg.Create);
SetA64("0110111010110000111110xxxxxxxxxx", InstName.Fminv_V, InstEmit.Fminv_V, OpCodeSimd.Create); SetA64("0110111010110000111110xxxxxxxxxx", InstName.Fminv_V, InstEmit.Fminv_V, OpCodeSimd.Create);
SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", InstName.Fmla_Se, InstEmit.Fmla_Se, OpCodeSimdRegElemF.Create); SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", InstName.Fmla_Se, InstEmit.Fmla_Se, OpCodeSimdRegElemF.Create);

View File

@@ -883,6 +883,31 @@ namespace ARMeilleure.Instructions
} }
} }
public static void Fmaxp_S(ArmEmitterContext context)
{
if (Optimizations.UseAdvSimd)
{
InstEmitSimdHelperArm64.EmitScalarUnaryOpF(context, Intrinsic.Arm64FmaxpS);
}
else if (Optimizations.FastFP && Optimizations.UseSse41)
{
EmitSse2ScalarPairwiseOpF(context, (op1, op2) =>
{
return EmitSse41ProcessNaNsOpF(context, (op1, op2) =>
{
return EmitSse2VectorMaxMinOpF(context, op1, op2, isMax: true);
}, scalar: true, op1, op2);
});
}
else
{
EmitScalarPairwiseOpF(context, (op1, op2) =>
{
return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax), op1, op2);
});
}
}
public static void Fmaxp_V(ArmEmitterContext context) public static void Fmaxp_V(ArmEmitterContext context)
{ {
if (Optimizations.UseAdvSimd) if (Optimizations.UseAdvSimd)
@@ -1081,6 +1106,31 @@ namespace ARMeilleure.Instructions
} }
} }
public static void Fminp_S(ArmEmitterContext context)
{
if (Optimizations.UseAdvSimd)
{
InstEmitSimdHelperArm64.EmitScalarUnaryOpF(context, Intrinsic.Arm64FminpS);
}
else if (Optimizations.FastFP && Optimizations.UseSse41)
{
EmitSse2ScalarPairwiseOpF(context, (op1, op2) =>
{
return EmitSse41ProcessNaNsOpF(context, (op1, op2) =>
{
return EmitSse2VectorMaxMinOpF(context, op1, op2, isMax: false);
}, scalar: true, op1, op2);
});
}
else
{
EmitScalarPairwiseOpF(context, (op1, op2) =>
{
return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin), op1, op2);
});
}
}
public static void Fminp_V(ArmEmitterContext context) public static void Fminp_V(ArmEmitterContext context)
{ {
if (Optimizations.UseAdvSimd) if (Optimizations.UseAdvSimd)

View File

@@ -228,6 +228,7 @@ namespace ARMeilleure.Instructions
Fmaxnmp_S, Fmaxnmp_S,
Fmaxnmp_V, Fmaxnmp_V,
Fmaxnmv_V, Fmaxnmv_V,
Fmaxp_S,
Fmaxp_V, Fmaxp_V,
Fmaxv_V, Fmaxv_V,
Fmin_S, Fmin_S,
@@ -237,6 +238,7 @@ namespace ARMeilleure.Instructions
Fminnmp_S, Fminnmp_S,
Fminnmp_V, Fminnmp_V,
Fminnmv_V, Fminnmv_V,
Fminp_S,
Fminp_V, Fminp_V,
Fminv_V, Fminv_V,
Fmla_Se, Fmla_Se,

View File

@@ -1448,6 +1448,7 @@ namespace ARMeilleure.Instructions
{ {
var overflowToInf = fpcr.GetRoundingMode() switch var overflowToInf = fpcr.GetRoundingMode() switch
{ {
FPRoundingMode.ToNearest => true,
FPRoundingMode.TowardsPlusInfinity => !sign, FPRoundingMode.TowardsPlusInfinity => !sign,
FPRoundingMode.TowardsMinusInfinity => sign, FPRoundingMode.TowardsMinusInfinity => sign,
FPRoundingMode.TowardsZero => false, FPRoundingMode.TowardsZero => false,
@@ -2879,6 +2880,7 @@ namespace ARMeilleure.Instructions
{ {
var overflowToInf = fpcr.GetRoundingMode() switch var overflowToInf = fpcr.GetRoundingMode() switch
{ {
FPRoundingMode.ToNearest => true,
FPRoundingMode.TowardsPlusInfinity => !sign, FPRoundingMode.TowardsPlusInfinity => !sign,
FPRoundingMode.TowardsMinusInfinity => sign, FPRoundingMode.TowardsMinusInfinity => sign,
FPRoundingMode.TowardsZero => false, FPRoundingMode.TowardsZero => false,

View File

@@ -29,7 +29,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 5343; //! To be incremented manually for each change to the ARMeilleure project. private const uint InternalVersion = 5502; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0"; private const string ActualDir = "0";
private const string BackupDir = "1"; private const string BackupDir = "1";

View File

@@ -31,7 +31,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
_stillRunning = true; _stillRunning = true;
_updaterThread = new Thread(Update) _updaterThread = new Thread(Update)
{ {
Name = "HardwareDeviceDriver.OpenAL" Name = "HardwareDeviceDriver.OpenAL",
}; };
_updaterThread.Start(); _updaterThread.Start();

View File

@@ -67,7 +67,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
{ {
DriverIdentifier = buffer.DataPointer, DriverIdentifier = buffer.DataPointer,
BufferId = AL.GenBuffer(), BufferId = AL.GenBuffer(),
SampleCount = GetSampleCount(buffer) SampleCount = GetSampleCount(buffer),
}; };
AL.BufferData(driverBuffer.BufferId, _targetFormat, buffer.Data, (int)RequestedSampleRate); AL.BufferData(driverBuffer.BufferId, _targetFormat, buffer.Data, (int)RequestedSampleRate);

View File

@@ -7,7 +7,6 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver; using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
using static SDL2.SDL; using static SDL2.SDL;
@@ -111,7 +110,7 @@ namespace Ryujinx.Audio.Backends.SDL2
channels = (byte)requestedChannelCount, channels = (byte)requestedChannelCount,
format = GetSDL2Format(requestedSampleFormat), format = GetSDL2Format(requestedSampleFormat),
freq = (int)requestedSampleRate, freq = (int)requestedSampleRate,
samples = (ushort)sampleCount samples = (ushort)sampleCount,
}; };
} }

View File

@@ -8,6 +8,6 @@
Alsa = 3, Alsa = 3,
CoreAudio = 4, CoreAudio = 4,
Wasapi = 5, Wasapi = 5,
Dummy = 6 Dummy = 6,
} }
} }

View File

@@ -3,6 +3,6 @@
public enum SoundIoDeviceAim public enum SoundIoDeviceAim
{ {
SoundIoDeviceAimInput = 0, SoundIoDeviceAimInput = 0,
SoundIoDeviceAimOutput = 1 SoundIoDeviceAimOutput = 1,
} }
} }

View File

@@ -114,7 +114,7 @@ namespace Ryujinx.Ava.Common
public static void OpenSaveDir(ulong saveDataId) public static void OpenSaveDir(ulong saveDataId)
{ {
string saveRootPath = Path.Combine(_virtualFileSystem.GetNandPath(), $"user/save/{saveDataId:x16}"); string saveRootPath = Path.Combine(VirtualFileSystem.GetNandPath(), $"user/save/{saveDataId:x16}");
if (!Directory.Exists(saveRootPath)) if (!Directory.Exists(saveRootPath))
{ {

View File

@@ -53,8 +53,6 @@ namespace Ryujinx.Ava.UI.Applet
bool opened = false; bool opened = false;
_parent.Activate();
UserResult response = await ContentDialogHelper.ShowDeferredContentDialog(_parent, UserResult response = await ContentDialogHelper.ShowDeferredContentDialog(_parent,
title, title,
message, message,

View File

@@ -315,8 +315,10 @@ namespace Ryujinx.Ava.UI.Helpers
Window parent = GetMainWindow(); Window parent = GetMainWindow();
if (parent is { IsActive: true } and MainWindow window && window.ViewModel.IsGameRunning) if (parent is MainWindow window)
{ {
parent.Activate();
contentDialogOverlayWindow = new() contentDialogOverlayWindow = new()
{ {
Height = parent.Bounds.Height, Height = parent.Bounds.Height,
@@ -369,7 +371,9 @@ namespace Ryujinx.Ava.UI.Helpers
} }
else else
{ {
result = await contentDialog.ShowAsync(); result = ContentDialogResult.None;
Logger.Warning?.Print(LogClass.Ui, "Content dialog overlay failed to populate. Default value has been returned.");
} }
return result; return result;
@@ -390,7 +394,7 @@ namespace Ryujinx.Ava.UI.Helpers
{ {
foreach (Window item in al.Windows) foreach (Window item in al.Windows)
{ {
if (item.IsActive && item is MainWindow window) if (item is MainWindow window)
{ {
return window; return window;
} }

View File

@@ -4,6 +4,6 @@
{ {
List, List,
Grid, Grid,
Chip Chip,
} }
} }

View File

@@ -2,6 +2,7 @@ using LibHac.Fs;
using LibHac.Ncm; using LibHac.Ncm;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.HLE.FileSystem;
using Ryujinx.Ui.App.Common; using Ryujinx.Ui.App.Common;
using System; using System;
using System.IO; using System.IO;
@@ -81,7 +82,7 @@ namespace Ryujinx.Ava.UI.Models
Task.Run(() => Task.Run(() =>
{ {
var saveRoot = Path.Combine(MainWindow.MainWindowViewModel.VirtualFileSystem.GetNandPath(), $"user/save/{info.SaveDataId:x16}"); var saveRoot = Path.Combine(VirtualFileSystem.GetNandPath(), $"user/save/{info.SaveDataId:x16}");
long totalSize = GetDirectorySize(saveRoot); long totalSize = GetDirectorySize(saveRoot);

View File

@@ -105,7 +105,7 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
string contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.BuiltInSystem, NcaContentType.Data); string contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.BuiltInSystem, NcaContentType.Data);
string avatarPath = virtualFileSystem.SwitchPathToSystemPath(contentPath); string avatarPath = VirtualFileSystem.SwitchPathToSystemPath(contentPath);
if (!string.IsNullOrWhiteSpace(avatarPath)) if (!string.IsNullOrWhiteSpace(avatarPath))
{ {

View File

@@ -25,7 +25,7 @@ namespace Ryujinx.Common
_workerThread = new Thread(DoWork) _workerThread = new Thread(DoWork)
{ {
Name = name, Name = name,
IsBackground = true IsBackground = true,
}; };
_workerThread.Start(); _workerThread.Start();
} }

View File

@@ -8,6 +8,6 @@ namespace Ryujinx.Common.Configuration
{ {
Auto, Auto,
Off, Off,
On On,
} }
} }

View File

@@ -7,6 +7,6 @@ namespace Ryujinx.Common.Configuration
public enum GraphicsBackend public enum GraphicsBackend
{ {
Vulkan, Vulkan,
OpenGl OpenGl,
} }
} }

View File

@@ -9,6 +9,6 @@ namespace Ryujinx.Common.Configuration
None, None,
Error, Error,
Slowdowns, Slowdowns,
All All,
} }
} }

View File

@@ -8,6 +8,6 @@ namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
{ {
Invalid, Invalid,
GamepadDriver, GamepadDriver,
CemuHook CemuHook,
} }
} }

View File

@@ -8,6 +8,6 @@ namespace Ryujinx.Common.Configuration
{ {
SoftwarePageTable, SoftwarePageTable,
HostMapped, HostMapped,
HostMappedUnsafe HostMappedUnsafe,
} }
} }

View File

@@ -6,6 +6,6 @@
OglThreadControlDefault = 0, OglThreadControlDefault = 0,
OglThreadControlEnable = 1, OglThreadControlEnable = 1,
OglThreadControlDisable = 2 OglThreadControlDisable = 2,
} }
} }

View File

@@ -14,6 +14,6 @@ namespace Ryujinx.Common.Logging
Guest, Guest,
AccessLog, AccessLog,
Notice, Notice,
Trace Trace,
} }
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#pragma warning disable CS0169, IDE0051 // Remove unused private member #pragma warning disable CS0169, IDE0051 // Remove unused private member
@@ -9,6 +10,8 @@ namespace Ryujinx.Common.Memory
T _e0; T _e0;
public readonly int Length => 1; public readonly int Length => 1;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -18,6 +21,8 @@ namespace Ryujinx.Common.Memory
Array1<T> _other; Array1<T> _other;
public readonly int Length => 2; public readonly int Length => 2;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -27,6 +32,8 @@ namespace Ryujinx.Common.Memory
Array2<T> _other; Array2<T> _other;
public readonly int Length => 3; public readonly int Length => 3;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -36,6 +43,8 @@ namespace Ryujinx.Common.Memory
Array3<T> _other; Array3<T> _other;
public readonly int Length => 4; public readonly int Length => 4;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -45,6 +54,8 @@ namespace Ryujinx.Common.Memory
Array4<T> _other; Array4<T> _other;
public readonly int Length => 5; public readonly int Length => 5;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -54,6 +65,8 @@ namespace Ryujinx.Common.Memory
Array5<T> _other; Array5<T> _other;
public readonly int Length => 6; public readonly int Length => 6;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -63,6 +76,8 @@ namespace Ryujinx.Common.Memory
Array6<T> _other; Array6<T> _other;
public readonly int Length => 7; public readonly int Length => 7;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -72,6 +87,8 @@ namespace Ryujinx.Common.Memory
Array7<T> _other; Array7<T> _other;
public readonly int Length => 8; public readonly int Length => 8;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -81,6 +98,8 @@ namespace Ryujinx.Common.Memory
Array8<T> _other; Array8<T> _other;
public readonly int Length => 9; public readonly int Length => 9;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -90,6 +109,8 @@ namespace Ryujinx.Common.Memory
Array9<T> _other; Array9<T> _other;
public readonly int Length => 10; public readonly int Length => 10;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -99,6 +120,8 @@ namespace Ryujinx.Common.Memory
Array10<T> _other; Array10<T> _other;
public readonly int Length => 11; public readonly int Length => 11;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -108,6 +131,8 @@ namespace Ryujinx.Common.Memory
Array11<T> _other; Array11<T> _other;
public readonly int Length => 12; public readonly int Length => 12;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -117,6 +142,8 @@ namespace Ryujinx.Common.Memory
Array12<T> _other; Array12<T> _other;
public readonly int Length => 13; public readonly int Length => 13;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -126,6 +153,8 @@ namespace Ryujinx.Common.Memory
Array13<T> _other; Array13<T> _other;
public readonly int Length => 14; public readonly int Length => 14;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -135,6 +164,8 @@ namespace Ryujinx.Common.Memory
Array14<T> _other; Array14<T> _other;
public readonly int Length => 15; public readonly int Length => 15;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -144,6 +175,8 @@ namespace Ryujinx.Common.Memory
Array15<T> _other; Array15<T> _other;
public readonly int Length => 16; public readonly int Length => 16;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -153,6 +186,8 @@ namespace Ryujinx.Common.Memory
Array16<T> _other; Array16<T> _other;
public readonly int Length => 17; public readonly int Length => 17;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -162,6 +197,8 @@ namespace Ryujinx.Common.Memory
Array17<T> _other; Array17<T> _other;
public readonly int Length => 18; public readonly int Length => 18;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -171,6 +208,8 @@ namespace Ryujinx.Common.Memory
Array18<T> _other; Array18<T> _other;
public readonly int Length => 19; public readonly int Length => 19;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -180,6 +219,8 @@ namespace Ryujinx.Common.Memory
Array19<T> _other; Array19<T> _other;
public readonly int Length => 20; public readonly int Length => 20;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -189,6 +230,8 @@ namespace Ryujinx.Common.Memory
Array20<T> _other; Array20<T> _other;
public readonly int Length => 21; public readonly int Length => 21;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -198,6 +241,8 @@ namespace Ryujinx.Common.Memory
Array21<T> _other; Array21<T> _other;
public readonly int Length => 22; public readonly int Length => 22;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -207,6 +252,8 @@ namespace Ryujinx.Common.Memory
Array22<T> _other; Array22<T> _other;
public readonly int Length => 23; public readonly int Length => 23;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -217,6 +264,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 24; public readonly int Length => 24;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -227,6 +276,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 25; public readonly int Length => 25;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -237,6 +288,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 26; public readonly int Length => 26;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -247,6 +300,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 27; public readonly int Length => 27;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -257,6 +312,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 28; public readonly int Length => 28;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -267,6 +324,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 29; public readonly int Length => 29;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -277,6 +336,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 30; public readonly int Length => 30;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -287,6 +348,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 31; public readonly int Length => 31;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -297,6 +360,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 32; public readonly int Length => 32;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -307,6 +372,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 33; public readonly int Length => 33;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -317,6 +384,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 34; public readonly int Length => 34;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -327,6 +396,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 35; public readonly int Length => 35;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -337,6 +408,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 36; public readonly int Length => 36;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -347,6 +420,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 37; public readonly int Length => 37;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -357,6 +432,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 38; public readonly int Length => 38;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -367,6 +444,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 39; public readonly int Length => 39;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -377,6 +456,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 40; public readonly int Length => 40;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -387,6 +468,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 41; public readonly int Length => 41;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -397,6 +480,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 42; public readonly int Length => 42;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -407,6 +492,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 43; public readonly int Length => 43;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -417,6 +504,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 44; public readonly int Length => 44;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -427,6 +516,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 45; public readonly int Length => 45;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -437,6 +528,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 46; public readonly int Length => 46;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -447,6 +540,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 47; public readonly int Length => 47;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -457,6 +552,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 48; public readonly int Length => 48;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -467,6 +564,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 49; public readonly int Length => 49;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -477,6 +576,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 50; public readonly int Length => 50;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -487,6 +588,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 51; public readonly int Length => 51;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -497,6 +600,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 52; public readonly int Length => 52;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -507,6 +612,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 53; public readonly int Length => 53;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -517,6 +624,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 54; public readonly int Length => 54;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -527,6 +636,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 55; public readonly int Length => 55;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -537,6 +648,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 56; public readonly int Length => 56;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -547,6 +660,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 57; public readonly int Length => 57;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -557,6 +672,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 58; public readonly int Length => 58;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -567,6 +684,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 59; public readonly int Length => 59;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -576,6 +695,8 @@ namespace Ryujinx.Common.Memory
Array59<T> _other; Array59<T> _other;
public readonly int Length => 60; public readonly int Length => 60;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -585,6 +706,8 @@ namespace Ryujinx.Common.Memory
Array60<T> _other; Array60<T> _other;
public readonly int Length => 61; public readonly int Length => 61;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -594,6 +717,8 @@ namespace Ryujinx.Common.Memory
Array61<T> _other; Array61<T> _other;
public readonly int Length => 62; public readonly int Length => 62;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -603,6 +728,8 @@ namespace Ryujinx.Common.Memory
Array62<T> _other; Array62<T> _other;
public readonly int Length => 63; public readonly int Length => 63;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -612,6 +739,8 @@ namespace Ryujinx.Common.Memory
Array63<T> _other; Array63<T> _other;
public readonly int Length => 64; public readonly int Length => 64;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -622,6 +751,8 @@ namespace Ryujinx.Common.Memory
Array8<T> _other2; Array8<T> _other2;
public readonly int Length => 73; public readonly int Length => 73;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -632,6 +763,8 @@ namespace Ryujinx.Common.Memory
Array62<T> _other2; Array62<T> _other2;
public readonly int Length => 127; public readonly int Length => 127;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -642,6 +775,8 @@ namespace Ryujinx.Common.Memory
Array63<T> _other2; Array63<T> _other2;
public readonly int Length => 128; public readonly int Length => 128;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
@@ -652,6 +787,8 @@ namespace Ryujinx.Common.Memory
Array127<T> _other2; Array127<T> _other2;
public readonly int Length => 256; public readonly int Length => 256;
public ref T this[int index] => ref AsSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
} }
} }

View File

@@ -179,7 +179,7 @@ namespace Ryujinx.Cpu
{ {
addressSpace = null; addressSpace = null;
const MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible; const MemoryAllocationFlags AsFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36); ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36);
@@ -191,8 +191,8 @@ namespace Ryujinx.Cpu
try try
{ {
baseMemory = new MemoryBlock(addressSpaceSize, asFlags); baseMemory = new MemoryBlock(addressSpaceSize, AsFlags);
mirrorMemory = new MemoryBlock(addressSpaceSize, asFlags); mirrorMemory = new MemoryBlock(addressSpaceSize, AsFlags);
addressSpace = new AddressSpace(backingMemory, baseMemory, mirrorMemory, addressSpaceSize, supports4KBPages); addressSpace = new AddressSpace(backingMemory, baseMemory, mirrorMemory, addressSpaceSize, supports4KBPages);
break; break;

View File

@@ -22,6 +22,6 @@ namespace Ryujinx.Cpu.AppleHv.Arm
UserNoneKernelReadWrite = (1UL << (int)PxnShift) | (1UL << (int)UxnShift) | (0UL << (int)ApShift), UserNoneKernelReadWrite = (1UL << (int)PxnShift) | (1UL << (int)UxnShift) | (0UL << (int)ApShift),
UserNoneKernelRead = (1UL << (int)PxnShift) | (1UL << (int)UxnShift) | (2UL << (int)ApShift), UserNoneKernelRead = (1UL << (int)PxnShift) | (1UL << (int)UxnShift) | (2UL << (int)ApShift),
UserReadKernelRead = (1UL << (int)PxnShift) | (1UL << (int)UxnShift) | (3UL << (int)ApShift) UserReadKernelRead = (1UL << (int)PxnShift) | (1UL << (int)UxnShift) | (3UL << (int)ApShift),
} }
} }

View File

@@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.Device
TypeCode.Double => sizeof(double), TypeCode.Double => sizeof(double),
TypeCode.Decimal => sizeof(decimal), TypeCode.Decimal => sizeof(decimal),
TypeCode.Boolean => sizeof(bool), TypeCode.Boolean => sizeof(bool),
_ => throw new ArgumentException($"Length for type \"{type.Name}\" is unknown.") _ => throw new ArgumentException($"Length for type \"{type.Name}\" is unknown."),
}; };
} }
} }

View File

@@ -412,7 +412,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved) public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
{ {
ThreadedCounterEvent evt = new ThreadedCounterEvent(this, type, _lastSampleCounterClear); ThreadedCounterEvent evt = new(this, type, _lastSampleCounterClear);
New<ReportCounterCommand>().Set(Ref(evt), type, Ref(resultHandler), divisor, hostReserved); New<ReportCounterCommand>().Set(Ref(evt), type, Ref(resultHandler), divisor, hostReserved);
QueueCommand(); QueueCommand();

View File

@@ -342,5 +342,19 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
Signal(); Signal();
} }
} }
/// <summary>
/// Sets the Y negate enabled state.
/// </summary>
/// <param name="enabled">True if Y negate of the fragment coordinates is enabled</param>
public void SetYNegateEnabled(bool enabled)
{
if (enabled != _graphics.YNegateEnabled)
{
_graphics.YNegateEnabled = enabled;
Signal();
}
}
} }
} }

View File

@@ -37,6 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
private ProgramPipelineState _pipeline; private ProgramPipelineState _pipeline;
private bool _fsReadsFragCoord;
private bool _vsUsesDrawParameters; private bool _vsUsesDrawParameters;
private bool _vtgWritesRtLayer; private bool _vtgWritesRtLayer;
private byte _vsClipDistancesWritten; private byte _vsClipDistancesWritten;
@@ -692,12 +693,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
var face = _state.State.FaceState; var face = _state.State.FaceState;
bool disableTransform = _state.State.ViewportTransformEnable == 0; bool disableTransform = _state.State.ViewportTransformEnable == 0;
bool yNegate = yControl.HasFlag(YControl.NegateY);
UpdateFrontFace(yControl, face.FrontFace); UpdateFrontFace(yControl, face.FrontFace);
UpdateDepthMode(); UpdateDepthMode();
bool flipY = yControl.HasFlag(YControl.NegateY);
Span<Viewport> viewports = stackalloc Viewport[Constants.TotalViewports]; Span<Viewport> viewports = stackalloc Viewport[Constants.TotalViewports];
for (int index = 0; index < Constants.TotalViewports; index++) for (int index = 0; index < Constants.TotalViewports; index++)
@@ -719,7 +719,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
float scaleX = MathF.Abs(transform.ScaleX); float scaleX = MathF.Abs(transform.ScaleX);
float scaleY = transform.ScaleY; float scaleY = transform.ScaleY;
if (flipY) if (yNegate)
{ {
scaleY = -scaleY; scaleY = -scaleY;
} }
@@ -771,8 +771,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_channel.TextureManager.RenderTargetScale, _channel.TextureManager.RenderTargetScale,
disableTransform); disableTransform);
// Viewport size is only used on the shader when YNegate is enabled,
// and if the fragment shader accesses gl_FragCoord,
// so there's no need to update it in other cases.
if (yNegate && _fsReadsFragCoord)
{
UpdateSupportBufferViewportSize();
}
_currentSpecState.SetViewportTransformDisable(disableTransform); _currentSpecState.SetViewportTransformDisable(disableTransform);
_currentSpecState.SetDepthMode(GetDepthMode() == DepthMode.MinusOneToOne); _currentSpecState.SetDepthMode(GetDepthMode() == DepthMode.MinusOneToOne);
_currentSpecState.SetYNegateEnabled(yNegate);
} }
/// <summary> /// <summary>
@@ -1415,9 +1424,41 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_currentProgramInfo[stageIndex] = info; _currentProgramInfo[stageIndex] = info;
} }
if (gs.Shaders[5]?.Info.UsesFragCoord == true)
{
// Make sure we update the viewport size on the support buffer if it will be consumed on the new shader.
if (!_fsReadsFragCoord && _state.State.YControl.HasFlag(YControl.NegateY))
{
UpdateSupportBufferViewportSize();
}
_fsReadsFragCoord = true;
}
else
{
_fsReadsFragCoord = false;
}
_context.Renderer.Pipeline.SetProgram(gs.HostProgram); _context.Renderer.Pipeline.SetProgram(gs.HostProgram);
} }
/// <summary>
/// Updates the viewport size on the support buffer for fragment shader access.
/// </summary>
private void UpdateSupportBufferViewportSize()
{
ref var transform = ref _state.State.ViewportTransform[0];
float scaleX = MathF.Abs(transform.ScaleX);
float scaleY = transform.ScaleY;
float width = scaleX * 2;
float height = scaleY * 2;
_context.SupportBufferUpdater.SetViewportSize(width, MathF.Abs(height));
}
/// <summary> /// <summary>
/// Updates bindings consumed by the shader on the texture and buffer managers. /// Updates bindings consumed by the shader on the texture and buffer managers.
/// </summary> /// </summary>

View File

@@ -112,6 +112,17 @@ namespace Ryujinx.Graphics.Gpu.Memory
MarkDirty(SupportBuffer.ViewportInverseOffset, SupportBuffer.FieldSize); MarkDirty(SupportBuffer.ViewportInverseOffset, SupportBuffer.FieldSize);
} }
/// <summary>
/// Updates the viewport size vector.
/// </summary>
/// <param name="data">Viewport size vector</param>
private void UpdateViewportSize(Vector4<float> data)
{
_data.ViewportSize = data;
MarkDirty(SupportBuffer.ViewportSizeOffset, SupportBuffer.FieldSize);
}
/// <summary> /// <summary>
/// Sets the scale of all output render targets (they should all have the same scale). /// Sets the scale of all output render targets (they should all have the same scale).
/// </summary> /// </summary>
@@ -187,7 +198,26 @@ namespace Ryujinx.Graphics.Gpu.Memory
X = scale * 2f / viewportWidth, X = scale * 2f / viewportWidth,
Y = scale * 2f / viewportHeight, Y = scale * 2f / viewportHeight,
Z = 1, Z = 1,
W = disableTransformF W = disableTransformF,
});
}
}
/// <summary>
/// Sets the viewport size, used to invert the fragment coordinates Y value.
/// </summary>
/// <param name="viewportWidth">Value used as viewport width</param>
/// <param name="viewportHeight">Value used as viewport height</param>
public void SetViewportSize(float viewportWidth, float viewportHeight)
{
if (_data.ViewportSize.X != viewportWidth || _data.ViewportSize.Y != viewportHeight)
{
UpdateViewportSize(new Vector4<float>
{
X = viewportWidth,
Y = viewportHeight,
Z = 1,
W = 0
}); });
} }
} }
@@ -210,7 +240,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
ReadOnlySpan<byte> data = MemoryMarshal.Cast<SupportBuffer, byte>(MemoryMarshal.CreateSpan(ref _data, 1)); ReadOnlySpan<byte> data = MemoryMarshal.Cast<SupportBuffer, byte>(MemoryMarshal.CreateSpan(ref _data, 1));
_renderer.SetBufferData(_handle, _startOffset, data.Slice(_startOffset, _endOffset - _startOffset)); _renderer.SetBufferData(_handle, _startOffset, data[_startOffset.._endOffset]);
_startOffset = -1; _startOffset = -1;
_endOffset = -1; _endOffset = -1;

View File

@@ -247,6 +247,12 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
return _oldSpecState.GraphicsState.ViewportTransformDisable; return _oldSpecState.GraphicsState.ViewportTransformDisable;
} }
/// <inheritdoc/>
public bool QueryYNegateEnabled()
{
return _oldSpecState.GraphicsState.YNegateEnabled;
}
/// <inheritdoc/> /// <inheritdoc/>
public void RegisterTexture(int handle, int cbufSlot) public void RegisterTexture(int handle, int cbufSlot)
{ {

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2; private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 5266; private const uint CodeGenVersion = 4675;
private const string SharedTocFileName = "shared.toc"; private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";
@@ -140,6 +140,11 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
/// </summary> /// </summary>
public ShaderStage Stage; public ShaderStage Stage;
/// <summary>
/// Indicates if the fragment shader accesses the fragment coordinate built-in variable.
/// </summary>
public bool UsesFragCoord;
/// <summary> /// <summary>
/// Indicates if the shader accesses the Instance ID built-in variable. /// Indicates if the shader accesses the Instance ID built-in variable.
/// </summary> /// </summary>
@@ -781,6 +786,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
ShaderIdentification.None, ShaderIdentification.None,
0, 0,
dataInfo.Stage, dataInfo.Stage,
dataInfo.UsesFragCoord,
dataInfo.UsesInstanceId, dataInfo.UsesInstanceId,
dataInfo.UsesDrawParameters, dataInfo.UsesDrawParameters,
dataInfo.UsesRtLayer, dataInfo.UsesRtLayer,
@@ -807,6 +813,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
TexturesCount = (ushort)info.Textures.Count, TexturesCount = (ushort)info.Textures.Count,
ImagesCount = (ushort)info.Images.Count, ImagesCount = (ushort)info.Images.Count,
Stage = info.Stage, Stage = info.Stage,
UsesFragCoord = info.UsesFragCoord,
UsesInstanceId = info.UsesInstanceId, UsesInstanceId = info.UsesInstanceId,
UsesDrawParameters = info.UsesDrawParameters, UsesDrawParameters = info.UsesDrawParameters,
UsesRtLayer = info.UsesRtLayer, UsesRtLayer = info.UsesRtLayer,

View File

@@ -113,6 +113,13 @@ namespace Ryujinx.Graphics.Gpu.Shader
return _state.GraphicsState.AttributeTypes[location]; return _state.GraphicsState.AttributeTypes[location];
} }
/// <inheritdoc/>
public bool QueryEarlyZForce()
{
_state.SpecializationState?.RecordEarlyZForce();
return _state.GraphicsState.EarlyZForce;
}
/// <inheritdoc/> /// <inheritdoc/>
public AttributeType QueryFragmentOutputType(int location) public AttributeType QueryFragmentOutputType(int location)
{ {
@@ -275,19 +282,18 @@ namespace Ryujinx.Graphics.Gpu.Shader
return _state.TransformFeedbackDescriptors[bufferIndex].Stride; return _state.TransformFeedbackDescriptors[bufferIndex].Stride;
} }
/// <inheritdoc/>
public bool QueryEarlyZForce()
{
_state.SpecializationState?.RecordEarlyZForce();
return _state.GraphicsState.EarlyZForce;
}
/// <inheritdoc/> /// <inheritdoc/>
public bool QueryViewportTransformDisable() public bool QueryViewportTransformDisable()
{ {
return _state.GraphicsState.ViewportTransformDisable; return _state.GraphicsState.ViewportTransformDisable;
} }
/// <inheritdoc/>
public bool QueryYNegateEnabled()
{
return _state.GraphicsState.YNegateEnabled;
}
/// <inheritdoc/> /// <inheritdoc/>
public void RegisterTexture(int handle, int cbufSlot) public void RegisterTexture(int handle, int cbufSlot)
{ {

View File

@@ -97,6 +97,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// </summary> /// </summary>
public bool DualSourceBlendEnable; public bool DualSourceBlendEnable;
/// <summary>
/// Indicates whether Y negate of the fragment coordinates is enabled.
/// </summary>
public bool YNegateEnabled;
/// <summary> /// <summary>
/// Creates a new GPU graphics state. /// Creates a new GPU graphics state.
/// </summary> /// </summary>
@@ -116,7 +121,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <param name="hasConstantBufferDrawParameters">Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0</param> /// <param name="hasConstantBufferDrawParameters">Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0</param>
/// <param name="hasUnalignedStorageBuffer">Indicates that any storage buffer use is unaligned</param> /// <param name="hasUnalignedStorageBuffer">Indicates that any storage buffer use is unaligned</param>
/// <param name="fragmentOutputTypes">Type of the fragment shader outputs</param> /// <param name="fragmentOutputTypes">Type of the fragment shader outputs</param>
/// <param name="dualSourceBlendEnable">Type of the vertex attributes consumed by the shader</param> /// <param name="dualSourceBlendEnable">Indicates whether dual source blend is enabled</param>
/// <param name="yNegateEnabled">Indicates whether Y negate of the fragment coordinates is enabled</param>
public GpuChannelGraphicsState( public GpuChannelGraphicsState(
bool earlyZForce, bool earlyZForce,
PrimitiveTopology topology, PrimitiveTopology topology,
@@ -134,7 +140,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
bool hasConstantBufferDrawParameters, bool hasConstantBufferDrawParameters,
bool hasUnalignedStorageBuffer, bool hasUnalignedStorageBuffer,
ref Array8<AttributeType> fragmentOutputTypes, ref Array8<AttributeType> fragmentOutputTypes,
bool dualSourceBlendEnable) bool dualSourceBlendEnable,
bool yNegateEnabled)
{ {
EarlyZForce = earlyZForce; EarlyZForce = earlyZForce;
Topology = topology; Topology = topology;
@@ -153,6 +160,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
HasUnalignedStorageBuffer = hasUnalignedStorageBuffer; HasUnalignedStorageBuffer = hasUnalignedStorageBuffer;
FragmentOutputTypes = fragmentOutputTypes; FragmentOutputTypes = fragmentOutputTypes;
DualSourceBlendEnable = dualSourceBlendEnable; DualSourceBlendEnable = dualSourceBlendEnable;
YNegateEnabled = yNegateEnabled;
} }
} }
} }

View File

@@ -540,6 +540,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
return false; return false;
} }
if (graphicsState.YNegateEnabled != GraphicsState.YNegateEnabled)
{
return false;
}
return Matches(channel, ref poolState, checkTextures, isCompute: false); return Matches(channel, ref poolState, checkTextures, isCompute: false);
} }

View File

@@ -8,8 +8,6 @@ using System.Threading;
namespace Ryujinx.Graphics.Gpu namespace Ryujinx.Graphics.Gpu
{ {
using Texture = Image.Texture;
/// <summary> /// <summary>
/// GPU image presentation window. /// GPU image presentation window.
/// </summary> /// </summary>
@@ -202,13 +200,13 @@ namespace Ryujinx.Graphics.Gpu
{ {
pt.AcquireCallback(_context, pt.UserObj); pt.AcquireCallback(_context, pt.UserObj);
Texture texture = pt.Cache.FindOrCreateTexture(null, TextureSearchFlags.WithUpscale, pt.Info, 0, pt.Range); Image.Texture texture = pt.Cache.FindOrCreateTexture(null, TextureSearchFlags.WithUpscale, pt.Info, 0, pt.Range);
pt.Cache.Tick(); pt.Cache.Tick();
texture.SynchronizeMemory(); texture.SynchronizeMemory();
ImageCrop crop = new ImageCrop( ImageCrop crop = new(
(int)(pt.Crop.Left * texture.ScaleFactor), (int)(pt.Crop.Left * texture.ScaleFactor),
(int)MathF.Ceiling(pt.Crop.Right * texture.ScaleFactor), (int)MathF.Ceiling(pt.Crop.Right * texture.ScaleFactor),
(int)(pt.Crop.Top * texture.ScaleFactor), (int)(pt.Crop.Top * texture.ScaleFactor),

View File

@@ -15,6 +15,6 @@
Tsec = 0xe0, Tsec = 0xe0,
Tsecb = 0xe1, Tsecb = 0xe1,
Nvjpg = 0xc0, Nvjpg = 0xc0,
Nvdec = 0xf0 Nvdec = 0xf0,
} }
} }

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Host1x
_syncMgr = syncMgr; _syncMgr = syncMgr;
_state = new DeviceState<Host1xClassRegisters>(new Dictionary<string, RwCallback> _state = new DeviceState<Host1xClassRegisters>(new Dictionary<string, RwCallback>
{ {
{ nameof(Host1xClassRegisters.WaitSyncpt32), new RwCallback(WaitSyncpt32, null) } { nameof(Host1xClassRegisters.WaitSyncpt32), new RwCallback(WaitSyncpt32, null) },
}); });
} }

View File

@@ -16,6 +16,6 @@
NonIncrW, NonIncrW,
GatherW, GatherW,
RestartW, RestartW,
Extend Extend,
} }
} }

View File

@@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Host1x
_state = new DeviceState<ThiRegisters>(new Dictionary<string, RwCallback> _state = new DeviceState<ThiRegisters>(new Dictionary<string, RwCallback>
{ {
{ nameof(ThiRegisters.IncrSyncpt), new RwCallback(IncrSyncpt, null) }, { nameof(ThiRegisters.IncrSyncpt), new RwCallback(IncrSyncpt, null) },
{ nameof(ThiRegisters.Method1), new RwCallback(Method1, null) } { nameof(ThiRegisters.Method1), new RwCallback(Method1, null) },
}); });
_previousContextId = -1; _previousContextId = -1;

View File

@@ -127,7 +127,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264
35, 42, 49, 56, 57, 50, 43, 36, 35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51, 29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46, 58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63 53, 60, 61, 54, 47, 55, 62, 63,
}; };
private static ReadOnlySpan<byte> ZigZagScan => new byte[] private static ReadOnlySpan<byte> ZigZagScan => new byte[]
@@ -135,7 +135,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264
0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4, 0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4,
1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4, 1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4,
1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4, 1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4,
3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4 3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4,
}; };
private static void WriteScalingList(ref H264BitStreamWriter writer, IArray<byte> list) private static void WriteScalingList(ref H264BitStreamWriter writer, IArray<byte> list)

View File

@@ -10,6 +10,6 @@
Verbose = 40, Verbose = 40,
Debug = 48, Debug = 48,
Trace = 56, Trace = 56,
MaxOffset = 64 MaxOffset = 64,
} }
} }

View File

@@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
private static readonly Dictionary<string, (int, int)> _librariesWhitelist = new() private static readonly Dictionary<string, (int, int)> _librariesWhitelist = new()
{ {
{ AvCodecLibraryName, (58, 59) }, { AvCodecLibraryName, (58, 59) },
{ AvUtilLibraryName, (56, 57) } { AvUtilLibraryName, (56, 57) },
}; };
private static string FormatLibraryNameForCurrentOs(string libraryName, int version) private static string FormatLibraryNameForCurrentOs(string libraryName, int version)

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Nvdec
_rm = new ResourceManager(gmm, new SurfaceCache(gmm)); _rm = new ResourceManager(gmm, new SurfaceCache(gmm));
_state = new DeviceState<NvdecRegisters>(new Dictionary<string, RwCallback> _state = new DeviceState<NvdecRegisters>(new Dictionary<string, RwCallback>
{ {
{ nameof(NvdecRegisters.Execute), new RwCallback(Execute, null) } { nameof(NvdecRegisters.Execute), new RwCallback(Execute, null) },
}); });
_contexts = new ConcurrentDictionary<long, NvdecDecoderContext>(); _contexts = new ConcurrentDictionary<long, NvdecDecoderContext>();
} }

View File

@@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Nvdec.Types.H264
FrameType = 0, FrameType = 0,
PicWidthInMbsMinus1 = PicWidthInMbs - 1, PicWidthInMbsMinus1 = PicWidthInMbs - 1,
PicHeightInMapUnitsMinus1 = (PicHeightInMbs >> (FrameMbsOnlyFlag != 0 ? 0 : 1)) - 1, PicHeightInMapUnitsMinus1 = (PicHeightInMbs >> (FrameMbsOnlyFlag != 0 ? 0 : 1)) - 1,
QpprimeYZeroTransformBypassFlag = QpprimeYZeroTransformBypassFlag QpprimeYZeroTransformBypassFlag = QpprimeYZeroTransformBypassFlag,
}; };
} }
} }

View File

@@ -68,7 +68,7 @@ namespace Ryujinx.Graphics.Nvdec.Types.Vp8
FirstPartSize = FirstPartSize, FirstPartSize = FirstPartSize,
Version = Version, Version = Version,
FrameWidth = FrameWidth, FrameWidth = FrameWidth,
FrameHeight = FrameHeight FrameHeight = FrameHeight,
}; };
} }
} }

View File

@@ -7,6 +7,6 @@
FrameSizeChanged = 1 << 2, FrameSizeChanged = 1 << 2,
ErrorResilientMode = 1 << 3, ErrorResilientMode = 1 << 3,
LastShowFrame = 1 << 4, LastShowFrame = 1 << 4,
IntraOnly = 1 << 5 IntraOnly = 1 << 5,
} }
} }

View File

@@ -80,7 +80,7 @@ namespace Ryujinx.Graphics.Nvdec.Types.Vp9
SegmentFeatureData = Seg.FeatureData, SegmentFeatureData = Seg.FeatureData,
ModeRefDeltaEnabled = Lf.ModeRefDeltaEnabled != 0, ModeRefDeltaEnabled = Lf.ModeRefDeltaEnabled != 0,
RefDeltas = Lf.RefDeltas, RefDeltas = Lf.RefDeltas,
ModeDeltas = Lf.ModeDeltas ModeDeltas = Lf.ModeDeltas,
}; };
} }
} }

View File

@@ -668,7 +668,7 @@ namespace Ryujinx.Graphics.OpenGL
ShaderStage.TessellationEvaluation => ShaderType.TessEvaluationShader, ShaderStage.TessellationEvaluation => ShaderType.TessEvaluationShader,
ShaderStage.Geometry => ShaderType.GeometryShader, ShaderStage.Geometry => ShaderType.GeometryShader,
ShaderStage.Fragment => ShaderType.FragmentShader, ShaderStage.Fragment => ShaderType.FragmentShader,
_ => ShaderType.VertexShader _ => ShaderType.VertexShader,
}; };
} }
} }

View File

@@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.OpenGL
AmdUnix, AmdUnix,
IntelWindows, IntelWindows,
IntelUnix, IntelUnix,
Nvidia Nvidia,
} }
private static readonly Lazy<GpuVendor> _gpuVendor = new(GetGpuVendor); private static readonly Lazy<GpuVendor> _gpuVendor = new(GetGpuVendor);

View File

@@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
info.BorderColor.Red, info.BorderColor.Red,
info.BorderColor.Green, info.BorderColor.Green,
info.BorderColor.Blue, info.BorderColor.Blue,
info.BorderColor.Alpha info.BorderColor.Alpha,
}; };
GL.SamplerParameter(Handle, SamplerParameterName.TextureBorderColor, borderColor); GL.SamplerParameter(Handle, SamplerParameterName.TextureBorderColor, borderColor);

View File

@@ -133,7 +133,7 @@ void main()
1 => SizedInternalFormat.R8ui, 1 => SizedInternalFormat.R8ui,
2 => SizedInternalFormat.Rg8ui, 2 => SizedInternalFormat.Rg8ui,
4 => SizedInternalFormat.Rgba8ui, 4 => SizedInternalFormat.Rgba8ui,
_ => throw new ArgumentException($"Invalid components count {componentsCount}.") _ => throw new ArgumentException($"Invalid components count {componentsCount}."),
}; };
} }
else if (componentSize == 2) else if (componentSize == 2)
@@ -143,7 +143,7 @@ void main()
1 => SizedInternalFormat.R16ui, 1 => SizedInternalFormat.R16ui,
2 => SizedInternalFormat.Rg16ui, 2 => SizedInternalFormat.Rg16ui,
4 => SizedInternalFormat.Rgba16ui, 4 => SizedInternalFormat.Rgba16ui,
_ => throw new ArgumentException($"Invalid components count {componentsCount}.") _ => throw new ArgumentException($"Invalid components count {componentsCount}."),
}; };
} }
else if (componentSize == 4) else if (componentSize == 4)
@@ -153,7 +153,7 @@ void main()
1 => SizedInternalFormat.R32ui, 1 => SizedInternalFormat.R32ui,
2 => SizedInternalFormat.Rg32ui, 2 => SizedInternalFormat.Rg32ui,
4 => SizedInternalFormat.Rgba32ui, 4 => SizedInternalFormat.Rgba32ui,
_ => throw new ArgumentException($"Invalid components count {componentsCount}.") _ => throw new ArgumentException($"Invalid components count {componentsCount}."),
}; };
} }
else else

View File

@@ -173,7 +173,7 @@ void main()
4 => SizedInternalFormat.R32ui, 4 => SizedInternalFormat.R32ui,
8 => SizedInternalFormat.Rg32ui, 8 => SizedInternalFormat.Rg32ui,
16 => SizedInternalFormat.Rgba32ui, 16 => SizedInternalFormat.Rgba32ui,
_ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}.") _ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}."),
}; };
} }

View File

@@ -72,7 +72,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
(int)Info.SwizzleR.Convert(), (int)Info.SwizzleR.Convert(),
(int)Info.SwizzleG.Convert(), (int)Info.SwizzleG.Convert(),
(int)Info.SwizzleB.Convert(), (int)Info.SwizzleB.Convert(),
(int)Info.SwizzleA.Convert() (int)Info.SwizzleA.Convert(),
}; };
if (Info.Format == Format.A1B5G5R5Unorm) if (Info.Format == Format.A1B5G5R5Unorm)
@@ -210,7 +210,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
Target.Texture2DMultisample => Target.Texture2D, Target.Texture2DMultisample => Target.Texture2D,
Target.Texture2DMultisampleArray => Target.Texture2DArray, Target.Texture2DMultisampleArray => Target.Texture2DArray,
_ => Target _ => Target,
}; };
TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast( TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast(
@@ -354,7 +354,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
TextureTarget.TextureCubeMapArray => (layer / 6) * mipSize, TextureTarget.TextureCubeMapArray => (layer / 6) * mipSize,
TextureTarget.Texture1DArray => layer * mipSize, TextureTarget.Texture1DArray => layer * mipSize,
TextureTarget.Texture2DArray => layer * mipSize, TextureTarget.Texture2DArray => layer * mipSize,
_ => 0 _ => 0,
}; };
} }

View File

@@ -210,7 +210,7 @@ namespace Ryujinx.Graphics.OpenGL
GL.Arb.MaxShaderCompilerThreads(Math.Min(Environment.ProcessorCount, 8)); GL.Arb.MaxShaderCompilerThreads(Math.Min(Environment.ProcessorCount, 8));
} }
_counters.Initialize(_pipeline); _counters.Initialize();
// This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles. // This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles.
// This call is expected to fail if we're running with a core profile, // This call is expected to fail if we're running with a core profile,

View File

@@ -5,7 +5,6 @@ using Ryujinx.Graphics.OpenGL.Image;
using Ryujinx.Graphics.OpenGL.Queries; using Ryujinx.Graphics.OpenGL.Queries;
using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader;
using System; using System;
using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.OpenGL namespace Ryujinx.Graphics.OpenGL
{ {
@@ -44,7 +43,7 @@ namespace Ryujinx.Graphics.OpenGL
private CounterQueueEvent _activeConditionalRender; private CounterQueueEvent _activeConditionalRender;
private Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount]; private readonly Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount];
private readonly (TextureBase, Format)[] _images; private readonly (TextureBase, Format)[] _images;
private TextureBase _unit0Texture; private TextureBase _unit0Texture;

View File

@@ -13,8 +13,6 @@ namespace Ryujinx.Graphics.OpenGL.Queries
public CounterType Type { get; } public CounterType Type { get; }
public bool Disposed { get; private set; } public bool Disposed { get; private set; }
private readonly Pipeline _pipeline;
private readonly Queue<CounterQueueEvent> _events = new(); private readonly Queue<CounterQueueEvent> _events = new();
private CounterQueueEvent _current; private CounterQueueEvent _current;
@@ -30,12 +28,10 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private readonly Thread _consumerThread; private readonly Thread _consumerThread;
internal CounterQueue(Pipeline pipeline, CounterType type) internal CounterQueue(CounterType type)
{ {
Type = type; Type = type;
_pipeline = pipeline;
QueryTarget glType = GetTarget(Type); QueryTarget glType = GetTarget(Type);
_queryPool = new Queue<BufferedQuery>(QueryPoolInitialSize); _queryPool = new Queue<BufferedQuery>(QueryPoolInitialSize);

View File

@@ -14,12 +14,12 @@ namespace Ryujinx.Graphics.OpenGL.Queries
_counterQueues = new CounterQueue[count]; _counterQueues = new CounterQueue[count];
} }
public void Initialize(Pipeline pipeline) public void Initialize()
{ {
for (int index = 0; index < _counterQueues.Length; index++) for (int index = 0; index < _counterQueues.Length; index++)
{ {
CounterType type = (CounterType)index; CounterType type = (CounterType)index;
_counterQueues[index] = new CounterQueue(pipeline, type); _counterQueues[index] = new CounterQueue(type);
} }
} }

View File

@@ -41,7 +41,7 @@ namespace Ryujinx.Graphics.OpenGL
{ {
Info = view.Info, Info = view.Info,
View = view, View = view,
RemainingFrames = DisposedLiveFrames RemainingFrames = DisposedLiveFrames,
}); });
} }
} }

View File

@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.OpenGL
SyncHandle handle = new() SyncHandle handle = new()
{ {
ID = id, ID = id,
Handle = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None) Handle = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None),
}; };

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.Shader namespace Ryujinx.Graphics.Shader
{ {
public struct BufferDescriptor public readonly struct BufferDescriptor
{ {
// New fields should be added to the end of the struct to keep disk shader cache compatibility. // New fields should be added to the end of the struct to keep disk shader cache compatibility.

View File

@@ -188,12 +188,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
context.AppendLine(); context.AppendLine();
} }
if (context.Config.Stage == ShaderStage.Fragment && context.Config.GpuAccessor.QueryEarlyZForce()) if (context.Config.Stage == ShaderStage.Fragment)
{
if (context.Config.GpuAccessor.QueryEarlyZForce())
{ {
context.AppendLine("layout (early_fragment_tests) in;"); context.AppendLine("layout (early_fragment_tests) in;");
context.AppendLine(); context.AppendLine();
} }
if (context.Config.Properties.OriginUpperLeft)
{
context.AppendLine("layout (origin_upper_left) in vec4 gl_FragCoord;");
context.AppendLine();
}
}
if ((info.HelperFunctionsMask & HelperFunctionsMask.MultiplyHighS32) != 0) if ((info.HelperFunctionsMask & HelperFunctionsMask.MultiplyHighS32) != 0)
{ {
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighS32.glsl"); AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighS32.glsl");

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{ {
class OperandManager class OperandManager
{ {
private Dictionary<AstOperand, string> _locals; private readonly Dictionary<AstOperand, string> _locals;
public OperandManager() public OperandManager()
{ {

View File

@@ -13,8 +13,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{ {
static class Declarations static class Declarations
{ {
private static readonly string[] _stagePrefixes = { "cp", "vp", "tcp", "tep", "gp", "fp" };
public static void DeclareParameters(CodeGenContext context, StructuredFunction function) public static void DeclareParameters(CodeGenContext context, StructuredFunction function)
{ {
DeclareParameters(context, function.InArguments, 0); DeclareParameters(context, function.InArguments, 0);
@@ -192,7 +190,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
SamplerType.Texture3D => Dim.Dim3D, SamplerType.Texture3D => Dim.Dim3D,
SamplerType.TextureCube => Dim.Cube, SamplerType.TextureCube => Dim.Cube,
SamplerType.TextureBuffer => Dim.Buffer, SamplerType.TextureBuffer => Dim.Buffer,
_ => throw new InvalidOperationException($"Invalid sampler type \"{sampler.Type & SamplerType.Mask}\".") _ => throw new InvalidOperationException($"Invalid sampler type \"{sampler.Type & SamplerType.Mask}\"."),
}; };
var imageType = context.TypeImage( var imageType = context.TypeImage(
@@ -519,10 +517,5 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
: (isOutput ? context.Outputs : context.Inputs); : (isOutput ? context.Outputs : context.Inputs);
dict.Add(ioDefinition, spvVar); dict.Add(ioDefinition, spvVar);
} }
private static string GetStagePrefix(ShaderStage stage)
{
return _stagePrefixes[(int)stage];
}
} }
} }

View File

@@ -251,7 +251,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
} }
else if (context.Config.Stage == ShaderStage.Fragment) else if (context.Config.Stage == ShaderStage.Fragment)
{ {
context.AddExecutionMode(spvFunc, context.Config.Options.TargetApi == TargetApi.Vulkan context.AddExecutionMode(spvFunc, context.Config.Properties.OriginUpperLeft
? ExecutionMode.OriginUpperLeft ? ExecutionMode.OriginUpperLeft
: ExecutionMode.OriginLowerLeft); : ExecutionMode.OriginLowerLeft);

View File

@@ -178,6 +178,15 @@ namespace Ryujinx.Graphics.Shader
return 0; return 0;
} }
/// <summary>
/// Queries if host state forces early depth testing.
/// </summary>
/// <returns>True if early depth testing is forced</returns>
bool QueryEarlyZForce()
{
return false;
}
/// <summary> /// <summary>
/// Queries whenever the current draw has written the base vertex and base instance into Constant Buffer 0. /// Queries whenever the current draw has written the base vertex and base instance into Constant Buffer 0.
/// </summary> /// </summary>
@@ -534,19 +543,19 @@ namespace Ryujinx.Graphics.Shader
} }
/// <summary> /// <summary>
/// Queries if host state forces early depth testing. /// Queries if host state disables the viewport transform.
/// </summary> /// </summary>
/// <returns>True if early depth testing is forced</returns> /// <returns>True if the viewport transform is disabled</returns>
bool QueryEarlyZForce() bool QueryViewportTransformDisable()
{ {
return false; return false;
} }
/// <summary> /// <summary>
/// Queries if host state disables the viewport transform. /// Queries Y negate enable state.
/// </summary> /// </summary>
/// <returns>True if the viewport transform is disabled</returns> /// <returns>True if Y negate of the fragment coordinates is enabled, false otherwise</returns>
bool QueryViewportTransformDisable() bool QueryYNegateEnabled()
{ {
return false; return false;
} }

View File

@@ -161,6 +161,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
// FragCoord X/Y must be divided by the render target scale, if resolution scaling is active, // FragCoord X/Y must be divided by the render target scale, if resolution scaling is active,
// because the shader code is not expecting scaled values. // because the shader code is not expecting scaled values.
res = context.FPDivide(res, context.Load(StorageKind.ConstantBuffer, SupportBuffer.Binding, Const((int)SupportBufferField.RenderScale), Const(0))); res = context.FPDivide(res, context.Load(StorageKind.ConstantBuffer, SupportBuffer.Binding, Const((int)SupportBufferField.RenderScale), Const(0)));
if (op.Imm10 == AttributeConsts.PositionY && context.Config.Options.TargetApi != TargetApi.OpenGL)
{
// If YNegate is enabled, we need to flip the fragment coordinates vertically, unless
// the API supports changing the origin (only OpenGL does).
if (context.Config.GpuAccessor.QueryYNegateEnabled())
{
Operand viewportHeight = context.Load(StorageKind.ConstantBuffer, 0, Const((int)SupportBufferField.ViewportSize), Const(1));
res = context.FPSubtract(viewportHeight, res);
}
}
} }
else if (op.Imm10 == AttributeConsts.FrontFacing && context.Config.GpuAccessor.QueryHostHasFrontFacingBug()) else if (op.Imm10 == AttributeConsts.FrontFacing && context.Config.GpuAccessor.QueryHostHasFrontFacingBug())
{ {

View File

@@ -13,6 +13,7 @@ namespace Ryujinx.Graphics.Shader
public ShaderIdentification Identification { get; } public ShaderIdentification Identification { get; }
public int GpLayerInputAttribute { get; } public int GpLayerInputAttribute { get; }
public ShaderStage Stage { get; } public ShaderStage Stage { get; }
public bool UsesFragCoord { get; }
public bool UsesInstanceId { get; } public bool UsesInstanceId { get; }
public bool UsesDrawParameters { get; } public bool UsesDrawParameters { get; }
public bool UsesRtLayer { get; } public bool UsesRtLayer { get; }
@@ -27,6 +28,7 @@ namespace Ryujinx.Graphics.Shader
ShaderIdentification identification, ShaderIdentification identification,
int gpLayerInputAttribute, int gpLayerInputAttribute,
ShaderStage stage, ShaderStage stage,
bool usesFragCoord,
bool usesInstanceId, bool usesInstanceId,
bool usesDrawParameters, bool usesDrawParameters,
bool usesRtLayer, bool usesRtLayer,
@@ -41,6 +43,7 @@ namespace Ryujinx.Graphics.Shader
Identification = identification; Identification = identification;
GpLayerInputAttribute = gpLayerInputAttribute; GpLayerInputAttribute = gpLayerInputAttribute;
Stage = stage; Stage = stage;
UsesFragCoord = usesFragCoord;
UsesInstanceId = usesInstanceId; UsesInstanceId = usesInstanceId;
UsesDrawParameters = usesDrawParameters; UsesDrawParameters = usesDrawParameters;
UsesRtLayer = usesRtLayer; UsesRtLayer = usesRtLayer;

View File

@@ -18,6 +18,8 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
public IReadOnlyDictionary<int, MemoryDefinition> LocalMemories => _localMemories; public IReadOnlyDictionary<int, MemoryDefinition> LocalMemories => _localMemories;
public IReadOnlyDictionary<int, MemoryDefinition> SharedMemories => _sharedMemories; public IReadOnlyDictionary<int, MemoryDefinition> SharedMemories => _sharedMemories;
public readonly bool OriginUpperLeft;
public ShaderProperties() public ShaderProperties()
{ {
_constantBuffers = new Dictionary<int, BufferDefinition>(); _constantBuffers = new Dictionary<int, BufferDefinition>();
@@ -28,6 +30,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
_sharedMemories = new Dictionary<int, MemoryDefinition>(); _sharedMemories = new Dictionary<int, MemoryDefinition>();
} }
public ShaderProperties(bool originUpperLeft) : this()
{
OriginUpperLeft = originUpperLeft;
}
public void AddOrUpdateConstantBuffer(int binding, BufferDefinition definition) public void AddOrUpdateConstantBuffer(int binding, BufferDefinition definition)
{ {
_constantBuffers[binding] = definition; _constantBuffers[binding] = definition;

View File

@@ -19,6 +19,7 @@ namespace Ryujinx.Graphics.Shader
FragmentAlphaTest, FragmentAlphaTest,
FragmentIsBgra, FragmentIsBgra,
ViewportInverse, ViewportInverse,
ViewportSize,
FragmentRenderScaleCount, FragmentRenderScaleCount,
RenderScale, RenderScale,
} }
@@ -33,6 +34,7 @@ namespace Ryujinx.Graphics.Shader
public static readonly int FragmentAlphaTestOffset; public static readonly int FragmentAlphaTestOffset;
public static readonly int FragmentIsBgraOffset; public static readonly int FragmentIsBgraOffset;
public static readonly int ViewportInverseOffset; public static readonly int ViewportInverseOffset;
public static readonly int ViewportSizeOffset;
public static readonly int FragmentRenderScaleCountOffset; public static readonly int FragmentRenderScaleCountOffset;
public static readonly int GraphicsRenderScaleOffset; public static readonly int GraphicsRenderScaleOffset;
public static readonly int ComputeRenderScaleOffset; public static readonly int ComputeRenderScaleOffset;
@@ -56,6 +58,7 @@ namespace Ryujinx.Graphics.Shader
FragmentAlphaTestOffset = OffsetOf(ref instance, ref instance.FragmentAlphaTest); FragmentAlphaTestOffset = OffsetOf(ref instance, ref instance.FragmentAlphaTest);
FragmentIsBgraOffset = OffsetOf(ref instance, ref instance.FragmentIsBgra); FragmentIsBgraOffset = OffsetOf(ref instance, ref instance.FragmentIsBgra);
ViewportInverseOffset = OffsetOf(ref instance, ref instance.ViewportInverse); ViewportInverseOffset = OffsetOf(ref instance, ref instance.ViewportInverse);
ViewportSizeOffset = OffsetOf(ref instance, ref instance.ViewportSize);
FragmentRenderScaleCountOffset = OffsetOf(ref instance, ref instance.FragmentRenderScaleCount); FragmentRenderScaleCountOffset = OffsetOf(ref instance, ref instance.FragmentRenderScaleCount);
GraphicsRenderScaleOffset = OffsetOf(ref instance, ref instance.RenderScale); GraphicsRenderScaleOffset = OffsetOf(ref instance, ref instance.RenderScale);
ComputeRenderScaleOffset = GraphicsRenderScaleOffset + FieldSize; ComputeRenderScaleOffset = GraphicsRenderScaleOffset + FieldSize;
@@ -68,6 +71,7 @@ namespace Ryujinx.Graphics.Shader
new StructureField(AggregateType.U32, "s_alpha_test"), new StructureField(AggregateType.U32, "s_alpha_test"),
new StructureField(AggregateType.Array | AggregateType.U32, "s_is_bgra", FragmentIsBgraCount), new StructureField(AggregateType.Array | AggregateType.U32, "s_is_bgra", FragmentIsBgraCount),
new StructureField(AggregateType.Vector4 | AggregateType.FP32, "s_viewport_inverse"), new StructureField(AggregateType.Vector4 | AggregateType.FP32, "s_viewport_inverse"),
new StructureField(AggregateType.Vector4 | AggregateType.FP32, "s_viewport_size"),
new StructureField(AggregateType.S32, "s_frag_scale_count"), new StructureField(AggregateType.S32, "s_frag_scale_count"),
new StructureField(AggregateType.Array | AggregateType.FP32, "s_render_scale", RenderScaleMaxCount), new StructureField(AggregateType.Array | AggregateType.FP32, "s_render_scale", RenderScaleMaxCount),
}); });
@@ -76,6 +80,7 @@ namespace Ryujinx.Graphics.Shader
public Vector4<int> FragmentAlphaTest; public Vector4<int> FragmentAlphaTest;
public Array8<Vector4<int>> FragmentIsBgra; public Array8<Vector4<int>> FragmentIsBgra;
public Vector4<float> ViewportInverse; public Vector4<float> ViewportInverse;
public Vector4<float> ViewportSize;
public Vector4<int> FragmentRenderScaleCount; public Vector4<int> FragmentRenderScaleCount;
// Render scale max count: 1 + 64 + 8. First scale is fragment output scale, others are textures/image inputs. // Render scale max count: 1 + 64 + 8. First scale is fragment output scale, others are textures/image inputs.

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.Shader namespace Ryujinx.Graphics.Shader
{ {
public struct TextureDescriptor public readonly struct TextureDescriptor
{ {
// New fields should be added to the end of the struct to keep disk shader cache compatibility. // New fields should be added to the end of the struct to keep disk shader cache compatibility.

View File

@@ -429,6 +429,11 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(Instruction.FP32 | Instruction.SquareRoot, Local(), a); return context.Add(Instruction.FP32 | Instruction.SquareRoot, Local(), a);
} }
public static Operand FPSubtract(this EmitterContext context, Operand a, Operand b, Instruction fpType = Instruction.FP32)
{
return context.Add(fpType | Instruction.Subtract, Local(), a, b);
}
public static Operand FPTruncate(this EmitterContext context, Operand a, Instruction fpType = Instruction.FP32) public static Operand FPTruncate(this EmitterContext context, Operand a, Instruction fpType = Instruction.FP32)
{ {
return context.Add(fpType | Instruction.Truncate, Local(), a); return context.Add(fpType | Instruction.Truncate, Local(), a);

View File

@@ -266,7 +266,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{ {
AccurateType = accurateType, AccurateType = accurateType,
Type = type, Type = type,
UsageFlags = usageFlags UsageFlags = usageFlags,
}; };
int binding; int binding;

View File

@@ -123,7 +123,20 @@ namespace Ryujinx.Graphics.Shader.Translation
UsedInputAttributesPerPatch = new HashSet<int>(); UsedInputAttributesPerPatch = new HashSet<int>();
UsedOutputAttributesPerPatch = new HashSet<int>(); UsedOutputAttributesPerPatch = new HashSet<int>();
ResourceManager = new ResourceManager(stage, gpuAccessor, new ShaderProperties()); ShaderProperties properties;
switch (stage)
{
case ShaderStage.Fragment:
bool originUpperLeft = options.TargetApi == TargetApi.Vulkan || gpuAccessor.QueryYNegateEnabled();
properties = new ShaderProperties(originUpperLeft);
break;
default:
properties = new ShaderProperties();
break;
}
ResourceManager = new ResourceManager(stage, gpuAccessor, properties);
if (!gpuAccessor.QueryHostSupportsTransformFeedback() && gpuAccessor.QueryTransformFeedbackEnabled()) if (!gpuAccessor.QueryHostSupportsTransformFeedback() && gpuAccessor.QueryTransformFeedbackEnabled())
{ {
@@ -135,7 +148,7 @@ namespace Ryujinx.Graphics.Shader.Translation
BufferDefinition tfeInfoBuffer = new(BufferLayout.Std430, 1, Constants.TfeInfoBinding, "tfe_info", tfeInfoStruct); BufferDefinition tfeInfoBuffer = new(BufferLayout.Std430, 1, Constants.TfeInfoBinding, "tfe_info", tfeInfoStruct);
Properties.AddOrUpdateStorageBuffer(Constants.TfeInfoBinding, tfeInfoBuffer); properties.AddOrUpdateStorageBuffer(Constants.TfeInfoBinding, tfeInfoBuffer);
StructureType tfeDataStruct = new(new StructureField[] StructureType tfeDataStruct = new(new StructureField[]
{ {
@@ -146,7 +159,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{ {
int binding = Constants.TfeBufferBaseBinding + i; int binding = Constants.TfeBufferBaseBinding + i;
BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct); BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct);
Properties.AddOrUpdateStorageBuffer(binding, tfeDataBuffer); properties.AddOrUpdateStorageBuffer(binding, tfeDataBuffer);
} }
} }
} }
@@ -615,6 +628,7 @@ namespace Ryujinx.Graphics.Shader.Translation
identification, identification,
GpLayerInputAttribute, GpLayerInputAttribute,
Stage, Stage,
UsedFeatures.HasFlag(FeatureFlags.FragCoordXY),
UsedFeatures.HasFlag(FeatureFlags.InstanceId), UsedFeatures.HasFlag(FeatureFlags.InstanceId),
UsedFeatures.HasFlag(FeatureFlags.DrawParameters), UsedFeatures.HasFlag(FeatureFlags.DrawParameters),
UsedFeatures.HasFlag(FeatureFlags.RtLayer), UsedFeatures.HasFlag(FeatureFlags.RtLayer),

View File

@@ -889,7 +889,7 @@ namespace Ryujinx.Graphics.Texture.Astc
0 => 0, 0 => 0,
1 => 32, 1 => 32,
2 => 63, 2 => 63,
_ => 0 _ => 0,
}; };
break; break;
@@ -942,7 +942,7 @@ namespace Ryujinx.Graphics.Texture.Astc
2 => 32, 2 => 32,
3 => 47, 3 => 47,
4 => 63, 4 => 63,
_ => 0 _ => 0,
}; };
break; break;

View File

@@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Texture.Astc
{ {
JustBits, JustBits,
Quint, Quint,
Trit Trit,
} }
readonly EIntegerEncoding _encoding; readonly EIntegerEncoding _encoding;
@@ -162,7 +162,7 @@ namespace Ryujinx.Graphics.Texture.Astc
IntegerEncoded intEncoded = new(EIntegerEncoding.Quint, numberBitsPerValue) IntegerEncoded intEncoded = new(EIntegerEncoding.Quint, numberBitsPerValue)
{ {
BitValue = m[i], BitValue = m[i],
QuintValue = encodings[i] QuintValue = encodings[i],
}; };
listIntegerEncoded.Add(ref intEncoded); listIntegerEncoded.Add(ref intEncoded);
@@ -309,7 +309,7 @@ namespace Ryujinx.Graphics.Texture.Astc
2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 0, 2, 1, 1, 2,
1, 2, 1, 1, 2, 2, 2, 1, 1, 2, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 2, 2, 1, 1, 2, 2, 1, 2, 1, 2,
0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 1, 2, 2, 2 2, 1, 2, 2, 2,
}; };
private static ReadOnlySpan<byte> QuintEncodings => new byte[] private static ReadOnlySpan<byte> QuintEncodings => new byte[]
@@ -339,7 +339,7 @@ namespace Ryujinx.Graphics.Texture.Astc
0, 1, 4, 1, 1, 4, 0, 2, 3, 1, 2, 3, 2, 2, 3, 0, 1, 4, 1, 1, 4, 0, 2, 3, 1, 2, 3, 2, 2, 3,
3, 2, 3, 4, 2, 3, 2, 4, 3, 0, 2, 4, 1, 2, 4, 3, 2, 3, 4, 2, 3, 2, 4, 3, 0, 2, 4, 1, 2, 4,
0, 3, 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, 4, 3, 3, 0, 3, 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, 4, 3, 3,
3, 4, 3, 0, 3, 4, 1, 3, 4 3, 4, 3, 0, 3, 4, 1, 3, 4,
}; };
} }
} }

View File

@@ -21,12 +21,12 @@ namespace Ryujinx.Graphics.Texture
new int[] { 18, 60, -18, -60 }, new int[] { 18, 60, -18, -60 },
new int[] { 24, 80, -24, -80 }, new int[] { 24, 80, -24, -80 },
new int[] { 33, 106, -33, -106 }, new int[] { 33, 106, -33, -106 },
new int[] { 47, 183, -47, -183 } new int[] { 47, 183, -47, -183 },
}; };
private static readonly int[] _etc2Lut = private static readonly int[] _etc2Lut =
{ {
3, 6, 11, 16, 23, 32, 41, 64 3, 6, 11, 16, 23, 32, 41, 64,
}; };
private static readonly int[][] _etc2AlphaLut = private static readonly int[][] _etc2AlphaLut =
@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Texture
new int[] { -3, -4, -7, -10, 2, 3, 6, 9 }, new int[] { -3, -4, -7, -10, 2, 3, 6, 9 },
new int[] { -1, -2, -3, -10, 0, 1, 2, 9 }, new int[] { -1, -2, -3, -10, 0, 1, 2, 9 },
new int[] { -4, -6, -8, -9, 3, 5, 7, 8 }, new int[] { -4, -6, -8, -9, 3, 5, 7, 8 },
new int[] { -3, -5, -7, -9, 2, 4, 6, 8 } new int[] { -3, -5, -7, -9, 2, 4, 6, 8 },
}; };
public static byte[] DecodeRgb(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers) public static byte[] DecodeRgb(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)

View File

@@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.Texture.Encoders
private static readonly int[] _mostFrequentPartitions = new int[] private static readonly int[] _mostFrequentPartitions = new int[]
{ {
0, 13, 2, 1, 15, 14, 10, 23 0, 13, 2, 1, 15, 14, 10, 23,
}; };
private static Block CompressBlock(ReadOnlySpan<byte> data, int x, int y, int width, int height, bool fastMode) private static Block CompressBlock(ReadOnlySpan<byte> data, int x, int y, int width, int height, bool fastMode)
@@ -233,7 +233,7 @@ namespace Ryujinx.Graphics.Texture.Encoders
1 => new RgbaColor8(255, 0, 0, 0).ToUInt32(), 1 => new RgbaColor8(255, 0, 0, 0).ToUInt32(),
2 => new RgbaColor8(0, 255, 0, 0).ToUInt32(), 2 => new RgbaColor8(0, 255, 0, 0).ToUInt32(),
3 => new RgbaColor8(0, 0, 255, 0).ToUInt32(), 3 => new RgbaColor8(0, 0, 255, 0).ToUInt32(),
_ => new RgbaColor8(0, 0, 0, 255).ToUInt32() _ => new RgbaColor8(0, 0, 0, 255).ToUInt32(),
}; };
} }
else else

View File

@@ -5,6 +5,6 @@
Fast, Fast,
Exhaustive, Exhaustive,
ModeMask = 0xff, ModeMask = 0xff,
Multithreaded = 1 << 8 Multithreaded = 1 << 8,
} }
} }

View File

@@ -89,7 +89,7 @@ namespace Ryujinx.Graphics.Texture
8 => Convert<ulong>(dst, data), 8 => Convert<ulong>(dst, data),
12 => Convert<Bpp12Pixel>(dst, data), 12 => Convert<Bpp12Pixel>(dst, data),
16 => Convert<Vector128<byte>>(dst, data), 16 => Convert<Vector128<byte>>(dst, data),
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format.") _ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format."),
}; };
} }
@@ -240,7 +240,7 @@ namespace Ryujinx.Graphics.Texture
8 => Convert<ulong>(output, data), 8 => Convert<ulong>(output, data),
12 => Convert<Bpp12Pixel>(output, data), 12 => Convert<Bpp12Pixel>(output, data),
16 => Convert<Vector128<byte>>(output, data), 16 => Convert<Vector128<byte>>(output, data),
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format.") _ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format."),
}; };
} }
return output; return output;
@@ -359,7 +359,7 @@ namespace Ryujinx.Graphics.Texture
8 => Convert<ulong>(dst, data), 8 => Convert<ulong>(dst, data),
12 => Convert<Bpp12Pixel>(dst, data), 12 => Convert<Bpp12Pixel>(dst, data),
16 => Convert<Vector128<byte>>(dst, data), 16 => Convert<Vector128<byte>>(dst, data),
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format.") _ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format."),
}; };
} }
@@ -504,7 +504,7 @@ namespace Ryujinx.Graphics.Texture
8 => Convert<ulong>(output, data), 8 => Convert<ulong>(output, data),
12 => Convert<Bpp12Pixel>(output, data), 12 => Convert<Bpp12Pixel>(output, data),
16 => Convert<Vector128<byte>>(output, data), 16 => Convert<Vector128<byte>>(output, data),
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format.") _ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format."),
}; };
} }

View File

@@ -11,21 +11,21 @@
new BC7ModeInfo(1, 0, 0, 2, 1, 2, 3, 5, 6), new BC7ModeInfo(1, 0, 0, 2, 1, 2, 3, 5, 6),
new BC7ModeInfo(1, 0, 0, 2, 0, 2, 2, 7, 8), new BC7ModeInfo(1, 0, 0, 2, 0, 2, 2, 7, 8),
new BC7ModeInfo(1, 0, 2, 0, 0, 4, 0, 7, 7), new BC7ModeInfo(1, 0, 2, 0, 0, 4, 0, 7, 7),
new BC7ModeInfo(2, 6, 4, 0, 0, 2, 0, 5, 5) new BC7ModeInfo(2, 6, 4, 0, 0, 2, 0, 5, 5),
}; };
public static readonly byte[][] Weights = public static readonly byte[][] Weights =
{ {
new byte[] { 0, 21, 43, 64 }, new byte[] { 0, 21, 43, 64 },
new byte[] { 0, 9, 18, 27, 37, 46, 55, 64 }, new byte[] { 0, 9, 18, 27, 37, 46, 55, 64 },
new byte[] { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 } new byte[] { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 },
}; };
public static readonly byte[][] InverseWeights = public static readonly byte[][] InverseWeights =
{ {
new byte[] { 64, 43, 21, 0 }, new byte[] { 64, 43, 21, 0 },
new byte[] { 64, 55, 46, 37, 27, 18, 9, 0 }, new byte[] { 64, 55, 46, 37, 27, 18, 9, 0 },
new byte[] { 64, 60, 55, 51, 47, 43, 38, 34, 30, 26, 21, 17, 13, 9, 4, 0 } new byte[] { 64, 60, 55, 51, 47, 43, 38, 34, 30, 26, 21, 17, 13, 9, 4, 0 },
}; };
public static readonly byte[][][] FixUpIndices = new byte[3][][] public static readonly byte[][][] FixUpIndices = new byte[3][][]
@@ -47,7 +47,7 @@
new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 },
new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 },
new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 },
new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 } new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 },
}, },
new byte[64][] new byte[64][]
{ {
@@ -66,7 +66,7 @@
new byte[] { 0, 6, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 6, 0 }, new byte[] { 0, 8, 0 }, new byte[] { 0, 6, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 6, 0 }, new byte[] { 0, 8, 0 },
new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 2, 0 },
new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 },
new byte[] { 0, 15, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 15, 0 } new byte[] { 0, 15, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 15, 0 },
}, },
new byte[64][] new byte[64][]
{ {
@@ -85,8 +85,8 @@
new byte[] { 0, 3, 15 }, new byte[] { 0, 15, 3 }, new byte[] { 0, 5, 15 }, new byte[] { 0, 5, 15 }, new byte[] { 0, 3, 15 }, new byte[] { 0, 15, 3 }, new byte[] { 0, 5, 15 }, new byte[] { 0, 5, 15 },
new byte[] { 0, 5, 15 }, new byte[] { 0, 8, 15 }, new byte[] { 0, 5, 15 }, new byte[] { 0, 10, 15 }, new byte[] { 0, 5, 15 }, new byte[] { 0, 8, 15 }, new byte[] { 0, 5, 15 }, new byte[] { 0, 10, 15 },
new byte[] { 0, 5, 15 }, new byte[] { 0, 10, 15 }, new byte[] { 0, 8, 15 }, new byte[] { 0, 13, 15 }, new byte[] { 0, 5, 15 }, new byte[] { 0, 10, 15 }, new byte[] { 0, 8, 15 }, new byte[] { 0, 13, 15 },
new byte[] { 0, 15, 3 }, new byte[] { 0, 12, 15 }, new byte[] { 0, 3, 15 }, new byte[] { 0, 3, 8 } new byte[] { 0, 15, 3 }, new byte[] { 0, 12, 15 }, new byte[] { 0, 3, 15 }, new byte[] { 0, 3, 8 },
} },
}; };
public static readonly byte[][][] PartitionTable = new byte[3][][] public static readonly byte[][][] PartitionTable = new byte[3][][]
@@ -156,7 +156,7 @@
new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 60 new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 60
new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 61 new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 61
new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 62 new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 62
new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // 63 new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 63
}, },
new byte[64][] new byte[64][]
{ {
@@ -223,7 +223,7 @@
new byte[16] { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, // 60 new byte[16] { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, // 60
new byte[16] { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, // 61 new byte[16] { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, // 61
new byte[16] { 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0 }, // 62 new byte[16] { 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0 }, // 62
new byte[16] { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1 } // 63 new byte[16] { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1 }, // 63
}, },
new byte[64][] new byte[64][]
{ {
@@ -290,8 +290,8 @@
new byte[16] { 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1 }, // 60 new byte[16] { 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1 }, // 60
new byte[16] { 0, 2, 2, 2, 1, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2 }, // 61 new byte[16] { 0, 2, 2, 2, 1, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2 }, // 61
new byte[16] { 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, // 62 new byte[16] { 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, // 62
new byte[16] { 0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 2, 2, 2, 0 } // 63 new byte[16] { 0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 2, 2, 2, 0 }, // 63
} },
}; };
} }
} }

View File

@@ -1199,7 +1199,7 @@ namespace Ryujinx.Graphics.Texture.Utils
RgbaColor32 weightV = new(colorWeight) RgbaColor32 weightV = new(colorWeight)
{ {
A = alphaWeight A = alphaWeight,
}; };
RgbaColor32 invWeightV = new RgbaColor32(64) - weightV; RgbaColor32 invWeightV = new RgbaColor32(64) - weightV;

View File

@@ -77,7 +77,7 @@ namespace Ryujinx.Graphics.Texture.Utils
1 => G, 1 => G,
2 => B, 2 => B,
3 => A, 3 => A,
_ => throw new ArgumentOutOfRangeException(nameof(index)) _ => throw new ArgumentOutOfRangeException(nameof(index)),
}; };
} }
} }

View File

@@ -417,7 +417,7 @@ namespace Ryujinx.Graphics.Vic.Image
0 => offsets.LumaOffset, 0 => offsets.LumaOffset,
1 => offsets.ChromaUOffset, 1 => offsets.ChromaUOffset,
2 => offsets.ChromaVOffset, 2 => offsets.ChromaVOffset,
_ => throw new ArgumentOutOfRangeException(nameof(plane)) _ => throw new ArgumentOutOfRangeException(nameof(plane)),
}; };
} }

View File

@@ -7,6 +7,6 @@ namespace Ryujinx.Graphics.Vic.Types
Bob, Bob,
NewBob, NewBob,
Disi1, Disi1,
WeaveLumaBobFieldChroma WeaveLumaBobFieldChroma,
} }
} }

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Vic.Types
TopFieldChromaBottom, TopFieldChromaBottom,
BottomFieldChromaTop, BottomFieldChromaTop,
SubPicTopFieldChromaBottom, SubPicTopFieldChromaBottom,
SubPicBottomFieldChromaTop SubPicBottomFieldChromaTop,
} }
static class FrameFormatExtensions static class FrameFormatExtensions

View File

@@ -76,6 +76,6 @@
Y8___U8___V8_N422R, Y8___U8___V8_N422R,
Y8___U8___V8_N420, Y8___U8___V8_N420,
U8, U8,
V8 V8,
} }
} }

View File

@@ -19,7 +19,7 @@ namespace Ryujinx.Graphics.Vic
_rm = new ResourceManager(gmm, new BufferPool<Pixel>(), new BufferPool<byte>()); _rm = new ResourceManager(gmm, new BufferPool<Pixel>(), new BufferPool<byte>());
_state = new DeviceState<VicRegisters>(new Dictionary<string, RwCallback> _state = new DeviceState<VicRegisters>(new Dictionary<string, RwCallback>
{ {
{ nameof(VicRegisters.Execute), new RwCallback(Execute, null) } { nameof(VicRegisters.Execute), new RwCallback(Execute, null) },
}); });
} }

View File

@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.Video
public enum FrameField public enum FrameField
{ {
Progressive, Progressive,
Interlaced Interlaced,
} }
} }

View File

@@ -709,12 +709,14 @@ namespace Ryujinx.Graphics.Vulkan
return CommandBuffer.Handle == cb.Handle; return CommandBuffer.Handle == cb.Handle;
} }
#pragma warning disable CA1822 // Mark member as static
public void SetAlphaTest(bool enable, float reference, CompareOp op) public void SetAlphaTest(bool enable, float reference, CompareOp op)
{ {
// This is currently handled using shader specialization, as Vulkan does not support alpha test. // This is currently handled using shader specialization, as Vulkan does not support alpha test.
// In the future, we may want to use this to write the reference value into the support buffer, // In the future, we may want to use this to write the reference value into the support buffer,
// to avoid creating one version of the shader per reference value used. // to avoid creating one version of the shader per reference value used.
} }
#pragma warning restore CA1822
public void SetBlendState(AdvancedBlendDescriptor blend) public void SetBlendState(AdvancedBlendDescriptor blend)
{ {

View File

@@ -47,7 +47,7 @@ namespace Ryujinx.HLE.Exceptions
private string BuildMessage() private string BuildMessage()
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new();
// Print the IPC command details (service name, command ID, and handler) // Print the IPC command details (service name, command ID, and handler)
(Type callingType, MethodBase callingMethod) = WalkStackTrace(new StackTrace(this)); (Type callingType, MethodBase callingMethod) = WalkStackTrace(new StackTrace(this));

View File

@@ -30,13 +30,13 @@ namespace Ryujinx.HLE.FileSystem
private Dictionary<StorageId, LinkedList<LocationEntry>> _locationEntries; private Dictionary<StorageId, LinkedList<LocationEntry>> _locationEntries;
private Dictionary<string, ulong> _sharedFontTitleDictionary; private readonly Dictionary<string, ulong> _sharedFontTitleDictionary;
private Dictionary<ulong, string> _systemTitlesNameDictionary; private readonly Dictionary<ulong, string> _systemTitlesNameDictionary;
private Dictionary<string, string> _sharedFontFilenameDictionary; private readonly Dictionary<string, string> _sharedFontFilenameDictionary;
private SortedDictionary<(ulong titleId, NcaContentType type), string> _contentDictionary; private SortedDictionary<(ulong titleId, NcaContentType type), string> _contentDictionary;
private struct AocItem private readonly struct AocItem
{ {
public readonly string ContainerPath; public readonly string ContainerPath;
public readonly string NcaPath; public readonly string NcaPath;
@@ -48,9 +48,9 @@ namespace Ryujinx.HLE.FileSystem
} }
} }
private SortedList<ulong, AocItem> _aocData { get; } private SortedList<ulong, AocItem> AocData { get; }
private VirtualFileSystem _virtualFileSystem; private readonly VirtualFileSystem _virtualFileSystem;
private readonly object _lock = new(); private readonly object _lock = new();
@@ -66,7 +66,7 @@ namespace Ryujinx.HLE.FileSystem
{ "FontExtendedChineseSimplified", 0x0100000000000814 }, { "FontExtendedChineseSimplified", 0x0100000000000814 },
{ "FontKorean", 0x0100000000000812 }, { "FontKorean", 0x0100000000000812 },
{ "FontChineseTraditional", 0x0100000000000813 }, { "FontChineseTraditional", 0x0100000000000813 },
{ "FontNintendoExtended", 0x0100000000000810 } { "FontNintendoExtended", 0x0100000000000810 },
}; };
_systemTitlesNameDictionary = new Dictionary<ulong, string>() _systemTitlesNameDictionary = new Dictionary<ulong, string>()
@@ -86,12 +86,12 @@ namespace Ryujinx.HLE.FileSystem
{ "FontExtendedChineseSimplified", "nintendo_udsg-r_ext_zh-cn_003.bfttf" }, { "FontExtendedChineseSimplified", "nintendo_udsg-r_ext_zh-cn_003.bfttf" },
{ "FontKorean", "nintendo_udsg-r_ko_003.bfttf" }, { "FontKorean", "nintendo_udsg-r_ko_003.bfttf" },
{ "FontChineseTraditional", "nintendo_udjxh-db_zh-tw_003.bfttf" }, { "FontChineseTraditional", "nintendo_udjxh-db_zh-tw_003.bfttf" },
{ "FontNintendoExtended", "nintendo_ext_003.bfttf" } { "FontNintendoExtended", "nintendo_ext_003.bfttf" },
}; };
_virtualFileSystem = virtualFileSystem; _virtualFileSystem = virtualFileSystem;
_aocData = new SortedList<ulong, AocItem>(); AocData = new SortedList<ulong, AocItem>();
} }
public void LoadEntries(Switch device = null) public void LoadEntries(Switch device = null)
@@ -110,7 +110,7 @@ namespace Ryujinx.HLE.FileSystem
try try
{ {
contentPathString = ContentPath.GetContentPath(storageId); contentPathString = ContentPath.GetContentPath(storageId);
contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString); contentDirectory = ContentPath.GetRealPath(contentPathString);
registeredDirectory = Path.Combine(contentDirectory, "registered"); registeredDirectory = Path.Combine(contentDirectory, "registered");
} }
catch (NotSupportedException) catch (NotSupportedException)
@@ -120,7 +120,7 @@ namespace Ryujinx.HLE.FileSystem
Directory.CreateDirectory(registeredDirectory); Directory.CreateDirectory(registeredDirectory);
LinkedList<LocationEntry> locationList = new LinkedList<LocationEntry>(); LinkedList<LocationEntry> locationList = new();
void AddEntry(LocationEntry entry) void AddEntry(LocationEntry entry)
{ {
@@ -133,26 +133,21 @@ namespace Ryujinx.HLE.FileSystem
{ {
string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty); string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty);
using (FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0])) using FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0]);
{ Nca nca = new(_virtualFileSystem.KeySet, ncaFile.AsStorage());
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
string switchPath = contentPathString + ":/" + ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar); string switchPath = contentPathString + ":/" + ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar);
// Change path format to switch's // Change path format to switch's
switchPath = switchPath.Replace('\\', '/'); switchPath = switchPath.Replace('\\', '/');
LocationEntry entry = new LocationEntry(switchPath, LocationEntry entry = new(switchPath, 0, nca.Header.TitleId, nca.Header.ContentType);
0,
nca.Header.TitleId,
nca.Header.ContentType);
AddEntry(entry); AddEntry(entry);
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName);
} }
} }
}
foreach (string filePath in Directory.EnumerateFiles(contentDirectory)) foreach (string filePath in Directory.EnumerateFiles(contentDirectory))
{ {
@@ -160,36 +155,28 @@ namespace Ryujinx.HLE.FileSystem
{ {
string ncaName = Path.GetFileNameWithoutExtension(filePath); string ncaName = Path.GetFileNameWithoutExtension(filePath);
using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read)) using FileStream ncaFile = new(filePath, FileMode.Open, FileAccess.Read);
{ Nca nca = new(_virtualFileSystem.KeySet, ncaFile.AsStorage());
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
string switchPath = contentPathString + ":/" + filePath.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar); string switchPath = contentPathString + ":/" + filePath.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar);
// Change path format to switch's // Change path format to switch's
switchPath = switchPath.Replace('\\', '/'); switchPath = switchPath.Replace('\\', '/');
LocationEntry entry = new LocationEntry(switchPath, LocationEntry entry = new(switchPath, 0, nca.Header.TitleId, nca.Header.ContentType);
0,
nca.Header.TitleId,
nca.Header.ContentType);
AddEntry(entry); AddEntry(entry);
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName);
} }
} }
}
if (_locationEntries.TryGetValue(storageId, out var locationEntriesItem) && locationEntriesItem?.Count == 0) if (_locationEntries.TryGetValue(storageId, out var locationEntriesItem) && locationEntriesItem?.Count == 0)
{ {
_locationEntries.Remove(storageId); _locationEntries.Remove(storageId);
} }
if (!_locationEntries.ContainsKey(storageId)) _locationEntries.TryAdd(storageId, locationList);
{
_locationEntries.Add(storageId, locationList);
}
} }
if (device != null) if (device != null)
@@ -239,7 +226,7 @@ namespace Ryujinx.HLE.FileSystem
public void AddAocItem(ulong titleId, string containerPath, string ncaPath, bool mergedToContainer = false) public void AddAocItem(ulong titleId, string containerPath, string ncaPath, bool mergedToContainer = false)
{ {
// TODO: Check Aoc version. // TODO: Check Aoc version.
if (!_aocData.TryAdd(titleId, new AocItem(containerPath, ncaPath))) if (!AocData.TryAdd(titleId, new AocItem(containerPath, ncaPath)))
{ {
Logger.Warning?.Print(LogClass.Application, $"Duplicate AddOnContent detected. TitleId {titleId:X16}"); Logger.Warning?.Print(LogClass.Application, $"Duplicate AddOnContent detected. TitleId {titleId:X16}");
} }
@@ -257,17 +244,17 @@ namespace Ryujinx.HLE.FileSystem
} }
} }
public void ClearAocData() => _aocData.Clear(); public void ClearAocData() => AocData.Clear();
public int GetAocCount() => _aocData.Count; public int GetAocCount() => AocData.Count;
public IList<ulong> GetAocTitleIds() => _aocData.Select(e => e.Key).ToList(); public IList<ulong> GetAocTitleIds() => AocData.Select(e => e.Key).ToList();
public bool GetAocDataStorage(ulong aocTitleId, out IStorage aocStorage, IntegrityCheckLevel integrityCheckLevel) public bool GetAocDataStorage(ulong aocTitleId, out IStorage aocStorage, IntegrityCheckLevel integrityCheckLevel)
{ {
aocStorage = null; aocStorage = null;
if (_aocData.TryGetValue(aocTitleId, out AocItem aoc)) if (AocData.TryGetValue(aocTitleId, out AocItem aoc))
{ {
var file = new FileStream(aoc.ContainerPath, FileMode.Open, FileAccess.Read); var file = new FileStream(aoc.ContainerPath, FileMode.Open, FileAccess.Read);
using var ncaFile = new UniqueRef<IFile>(); using var ncaFile = new UniqueRef<IFile>();
@@ -331,7 +318,7 @@ namespace Ryujinx.HLE.FileSystem
if (_contentDictionary.ContainsValue(ncaId)) if (_contentDictionary.ContainsValue(ncaId))
{ {
var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId); var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId);
ulong titleId = content.Key.Item1; ulong titleId = content.Key.titleId;
NcaContentType contentType = content.Key.type; NcaContentType contentType = content.Key.type;
StorageId storage = GetInstalledStorage(titleId, contentType, storageId); StorageId storage = GetInstalledStorage(titleId, contentType, storageId);
@@ -403,21 +390,19 @@ namespace Ryujinx.HLE.FileSystem
return false; return false;
} }
string installedPath = _virtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath); string installedPath = VirtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
if (!string.IsNullOrWhiteSpace(installedPath)) if (!string.IsNullOrWhiteSpace(installedPath))
{ {
if (File.Exists(installedPath)) if (File.Exists(installedPath))
{ {
using (FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read)) using FileStream file = new(installedPath, FileMode.Open, FileAccess.Read);
{ Nca nca = new(_virtualFileSystem.KeySet, file.AsStorage());
Nca nca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
bool contentCheck = nca.Header.ContentType == contentType; bool contentCheck = nca.Header.ContentType == contentType;
return contentCheck; return contentCheck;
} }
} }
}
return false; return false;
} }
@@ -426,9 +411,9 @@ namespace Ryujinx.HLE.FileSystem
{ {
LinkedList<LocationEntry> locationList = null; LinkedList<LocationEntry> locationList = null;
if (_locationEntries.ContainsKey(storageId)) if (_locationEntries.TryGetValue(storageId, out LinkedList<LocationEntry> locationEntry))
{ {
locationList = _locationEntries[storageId]; locationList = locationEntry;
} }
if (locationList != null) if (locationList != null)
@@ -446,9 +431,9 @@ namespace Ryujinx.HLE.FileSystem
{ {
LinkedList<LocationEntry> locationList = null; LinkedList<LocationEntry> locationList = null;
if (_locationEntries.ContainsKey(storageId)) if (_locationEntries.TryGetValue(storageId, out LinkedList<LocationEntry> locationEntry))
{ {
locationList = _locationEntries[storageId]; locationList = locationEntry;
} }
if (locationList != null) if (locationList != null)
@@ -488,7 +473,7 @@ namespace Ryujinx.HLE.FileSystem
public void InstallFirmware(string firmwareSource) public void InstallFirmware(string firmwareSource)
{ {
string contentPathString = ContentPath.GetContentPath(StorageId.BuiltInSystem); string contentPathString = ContentPath.GetContentPath(StorageId.BuiltInSystem);
string contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString); string contentDirectory = ContentPath.GetRealPath(contentPathString);
string registeredDirectory = Path.Combine(contentDirectory, "registered"); string registeredDirectory = Path.Combine(contentDirectory, "registered");
string temporaryDirectory = Path.Combine(contentDirectory, "temp"); string temporaryDirectory = Path.Combine(contentDirectory, "temp");
@@ -510,10 +495,10 @@ namespace Ryujinx.HLE.FileSystem
throw new FileNotFoundException("Firmware file does not exist."); throw new FileNotFoundException("Firmware file does not exist.");
} }
FileInfo info = new FileInfo(firmwareSource); FileInfo info = new(firmwareSource);
using FileStream file = File.OpenRead(firmwareSource);
using (FileStream file = File.OpenRead(firmwareSource))
{
switch (info.Extension) switch (info.Extension)
{ {
case ".zip": case ".zip":
@@ -523,7 +508,7 @@ namespace Ryujinx.HLE.FileSystem
} }
break; break;
case ".xci": case ".xci":
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage()); Xci xci = new(_virtualFileSystem.KeySet, file.AsStorage());
InstallFromCart(xci, temporaryDirectory); InstallFromCart(xci, temporaryDirectory);
break; break;
default: default:
@@ -532,7 +517,6 @@ namespace Ryujinx.HLE.FileSystem
FinishInstallation(temporaryDirectory, registeredDirectory); FinishInstallation(temporaryDirectory, registeredDirectory);
} }
}
private void FinishInstallation(string temporaryDirectory, string registeredDirectory) private void FinishInstallation(string temporaryDirectory, string registeredDirectory)
{ {
@@ -555,7 +539,7 @@ namespace Ryujinx.HLE.FileSystem
{ {
foreach (var entry in filesystem.EnumerateEntries("/", "*.nca")) foreach (var entry in filesystem.EnumerateEntries("/", "*.nca"))
{ {
Nca nca = new Nca(_virtualFileSystem.KeySet, OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage()); Nca nca = new(_virtualFileSystem.KeySet, OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage());
SaveNca(nca, entry.Name.Remove(entry.Name.IndexOf('.')), temporaryDirectory); SaveNca(nca, entry.Name.Remove(entry.Name.IndexOf('.')), temporaryDirectory);
} }
@@ -575,9 +559,7 @@ namespace Ryujinx.HLE.FileSystem
} }
} }
private void InstallFromZip(ZipArchive archive, string temporaryDirectory) private static void InstallFromZip(ZipArchive archive, string temporaryDirectory)
{
using (archive)
{ {
foreach (var entry in archive.Entries) foreach (var entry in archive.Entries)
{ {
@@ -587,12 +569,12 @@ namespace Ryujinx.HLE.FileSystem
string[] pathComponents = entry.FullName.Replace(".cnmt", "").Split('/'); string[] pathComponents = entry.FullName.Replace(".cnmt", "").Split('/');
string ncaId = pathComponents[pathComponents.Length - 1]; string ncaId = pathComponents[^1];
// If this is a fragmented nca, we need to get the previous element.GetZip // If this is a fragmented nca, we need to get the previous element.GetZip
if (ncaId.Equals("00")) if (ncaId.Equals("00"))
{ {
ncaId = pathComponents[pathComponents.Length - 2]; ncaId = pathComponents[^2];
} }
if (ncaId.Contains(".nca")) if (ncaId.Contains(".nca"))
@@ -606,21 +588,18 @@ namespace Ryujinx.HLE.FileSystem
} }
} }
} }
}
public void SaveNca(Nca nca, string ncaId, string temporaryDirectory) public static void SaveNca(Nca nca, string ncaId, string temporaryDirectory)
{ {
string newPath = Path.Combine(temporaryDirectory, ncaId + ".nca"); string newPath = Path.Combine(temporaryDirectory, ncaId + ".nca");
Directory.CreateDirectory(newPath); Directory.CreateDirectory(newPath);
using (FileStream file = File.Create(Path.Combine(newPath, "00"))) using FileStream file = File.Create(Path.Combine(newPath, "00"));
{
nca.BaseStorage.AsStream().CopyTo(file); nca.BaseStorage.AsStream().CopyTo(file);
} }
}
private IFile OpenPossibleFragmentedFile(IFileSystem filesystem, string path, OpenMode mode) private static IFile OpenPossibleFragmentedFile(IFileSystem filesystem, string path, OpenMode mode)
{ {
using var file = new UniqueRef<IFile>(); using var file = new UniqueRef<IFile>();
@@ -636,14 +615,12 @@ namespace Ryujinx.HLE.FileSystem
return file.Release(); return file.Release();
} }
private Stream GetZipStream(ZipArchiveEntry entry) private static Stream GetZipStream(ZipArchiveEntry entry)
{ {
MemoryStream dest = MemoryStreamManager.Shared.GetStream(); MemoryStream dest = MemoryStreamManager.Shared.GetStream();
using (Stream src = entry.Open()) using Stream src = entry.Open();
{
src.CopyTo(dest); src.CopyTo(dest);
}
return dest; return dest;
} }
@@ -659,7 +636,7 @@ namespace Ryujinx.HLE.FileSystem
throw new MissingKeyException("HeaderKey is empty. Cannot decrypt NCA headers."); throw new MissingKeyException("HeaderKey is empty. Cannot decrypt NCA headers.");
} }
Dictionary<ulong, List<(NcaContentType type, string path)>> updateNcas = new Dictionary<ulong, List<(NcaContentType, string)>>(); Dictionary<ulong, List<(NcaContentType type, string path)>> updateNcas = new();
if (Directory.Exists(firmwarePackage)) if (Directory.Exists(firmwarePackage))
{ {
@@ -671,10 +648,10 @@ namespace Ryujinx.HLE.FileSystem
throw new FileNotFoundException("Firmware file does not exist."); throw new FileNotFoundException("Firmware file does not exist.");
} }
FileInfo info = new FileInfo(firmwarePackage); FileInfo info = new(firmwarePackage);
using FileStream file = File.OpenRead(firmwarePackage);
using (FileStream file = File.OpenRead(firmwarePackage))
{
switch (info.Extension) switch (info.Extension)
{ {
case ".zip": case ".zip":
@@ -683,7 +660,7 @@ namespace Ryujinx.HLE.FileSystem
return VerifyAndGetVersionZip(archive); return VerifyAndGetVersionZip(archive);
} }
case ".xci": case ".xci":
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage()); Xci xci = new(_virtualFileSystem.KeySet, file.AsStorage());
if (xci.HasPartition(XciPartitionType.Update)) if (xci.HasPartition(XciPartitionType.Update))
{ {
@@ -698,7 +675,6 @@ namespace Ryujinx.HLE.FileSystem
default: default:
break; break;
} }
}
SystemVersion VerifyAndGetVersionDirectory(string firmwareDirectory) SystemVersion VerifyAndGetVersionDirectory(string firmwareDirectory)
{ {
@@ -713,11 +689,10 @@ namespace Ryujinx.HLE.FileSystem
{ {
if (entry.FullName.EndsWith(".nca") || entry.FullName.EndsWith(".nca/00")) if (entry.FullName.EndsWith(".nca") || entry.FullName.EndsWith(".nca/00"))
{ {
using (Stream ncaStream = GetZipStream(entry)) using Stream ncaStream = GetZipStream(entry);
{
IStorage storage = ncaStream.AsStorage(); IStorage storage = ncaStream.AsStorage();
Nca nca = new Nca(_virtualFileSystem.KeySet, storage); Nca nca = new(_virtualFileSystem.KeySet, storage);
if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem)) if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem))
{ {
@@ -730,7 +705,6 @@ namespace Ryujinx.HLE.FileSystem
} }
} }
} }
}
if (updateNcas.TryGetValue(SystemUpdateTitleId, out var ncaEntry)) if (updateNcas.TryGetValue(SystemUpdateTitleId, out var ncaEntry))
{ {
@@ -742,7 +716,7 @@ namespace Ryujinx.HLE.FileSystem
using (Stream ncaStream = GetZipStream(fileEntry)) using (Stream ncaStream = GetZipStream(fileEntry))
{ {
Nca metaNca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage()); Nca metaNca = new(_virtualFileSystem.KeySet, ncaStream.AsStorage());
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
@@ -772,9 +746,8 @@ namespace Ryujinx.HLE.FileSystem
{ {
string versionEntry = updateNcasItem.Find(x => x.type != NcaContentType.Meta).path; string versionEntry = updateNcasItem.Find(x => x.type != NcaContentType.Meta).path;
using (Stream ncaStream = GetZipStream(archive.GetEntry(versionEntry))) using Stream ncaStream = GetZipStream(archive.GetEntry(versionEntry));
{ Nca nca = new(_virtualFileSystem.KeySet, ncaStream.AsStorage());
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage());
var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
@@ -785,7 +758,6 @@ namespace Ryujinx.HLE.FileSystem
systemVersion = new SystemVersion(systemVersionFile.Get.AsStream()); systemVersion = new SystemVersion(systemVersionFile.Get.AsStream());
} }
} }
}
foreach (CnmtContentMetaEntry metaEntry in metaEntries) foreach (CnmtContentMetaEntry metaEntry in metaEntries)
{ {
@@ -807,11 +779,9 @@ namespace Ryujinx.HLE.FileSystem
ZipArchiveEntry metaZipEntry = archive.GetEntry(metaPath); ZipArchiveEntry metaZipEntry = archive.GetEntry(metaPath);
ZipArchiveEntry contentZipEntry = archive.GetEntry(contentPath); ZipArchiveEntry contentZipEntry = archive.GetEntry(contentPath);
using (Stream metaNcaStream = GetZipStream(metaZipEntry)) using Stream metaNcaStream = GetZipStream(metaZipEntry);
{ using Stream contentNcaStream = GetZipStream(contentZipEntry);
using (Stream contentNcaStream = GetZipStream(contentZipEntry)) Nca metaNca = new(_virtualFileSystem.KeySet, metaNcaStream.AsStorage());
{
Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaNcaStream.AsStorage());
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
@@ -828,11 +798,11 @@ namespace Ryujinx.HLE.FileSystem
{ {
byte[] contentData = new byte[size]; byte[] contentData = new byte[size];
Span<byte> content = new Span<byte>(contentData); Span<byte> content = new(contentData);
contentStorage.Read(0, content); contentStorage.Read(0, content);
Span<byte> hash = new Span<byte>(new byte[32]); Span<byte> hash = new(new byte[32]);
LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash); LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash);
@@ -844,8 +814,6 @@ namespace Ryujinx.HLE.FileSystem
} }
} }
} }
}
}
if (updateNcas.Count > 0) if (updateNcas.Count > 0)
{ {
@@ -853,9 +821,9 @@ namespace Ryujinx.HLE.FileSystem
foreach (var entry in updateNcas) foreach (var entry in updateNcas)
{ {
foreach (var nca in entry.Value) foreach (var (type, path) in entry.Value)
{ {
extraNcas += nca.path + Environment.NewLine; extraNcas += path + Environment.NewLine;
} }
} }
@@ -880,7 +848,7 @@ namespace Ryujinx.HLE.FileSystem
{ {
IStorage ncaStorage = OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage(); IStorage ncaStorage = OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage();
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStorage); Nca nca = new(_virtualFileSystem.KeySet, ncaStorage);
if (nca.Header.TitleId == SystemUpdateTitleId && nca.Header.ContentType == NcaContentType.Meta) if (nca.Header.TitleId == SystemUpdateTitleId && nca.Header.ContentType == NcaContentType.Meta)
{ {
@@ -936,7 +904,7 @@ namespace Ryujinx.HLE.FileSystem
{ {
if (updateNcas.TryGetValue(metaEntry.TitleId, out var ncaEntry)) if (updateNcas.TryGetValue(metaEntry.TitleId, out var ncaEntry))
{ {
var metaNcaEntry = ncaEntry.Find(x => x.type == NcaContentType.Meta); string metaNcaPath = ncaEntry.Find(x => x.type == NcaContentType.Meta).path;
string contentPath = ncaEntry.Find(x => x.type != NcaContentType.Meta).path; string contentPath = ncaEntry.Find(x => x.type != NcaContentType.Meta).path;
// Nintendo in 9.0.0, removed PPC and only kept the meta nca of it. // Nintendo in 9.0.0, removed PPC and only kept the meta nca of it.
@@ -948,10 +916,10 @@ namespace Ryujinx.HLE.FileSystem
continue; continue;
} }
IStorage metaStorage = OpenPossibleFragmentedFile(filesystem, metaNcaEntry.path, OpenMode.Read).AsStorage(); IStorage metaStorage = OpenPossibleFragmentedFile(filesystem, metaNcaPath, OpenMode.Read).AsStorage();
IStorage contentStorage = OpenPossibleFragmentedFile(filesystem, contentPath, OpenMode.Read).AsStorage(); IStorage contentStorage = OpenPossibleFragmentedFile(filesystem, contentPath, OpenMode.Read).AsStorage();
Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaStorage); Nca metaNca = new(_virtualFileSystem.KeySet, metaStorage);
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
@@ -967,11 +935,11 @@ namespace Ryujinx.HLE.FileSystem
{ {
byte[] contentData = new byte[size]; byte[] contentData = new byte[size];
Span<byte> content = new Span<byte>(contentData); Span<byte> content = new(contentData);
contentStorage.Read(0, content); contentStorage.Read(0, content);
Span<byte> hash = new Span<byte>(new byte[32]); Span<byte> hash = new(new byte[32]);
LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash); LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash);
@@ -1017,11 +985,10 @@ namespace Ryujinx.HLE.FileSystem
{ {
if (entry.ContentType == NcaContentType.Data) if (entry.ContentType == NcaContentType.Data)
{ {
var path = _virtualFileSystem.SwitchPathToSystemPath(entry.ContentPath); var path = VirtualFileSystem.SwitchPathToSystemPath(entry.ContentPath);
using (FileStream fileStream = File.OpenRead(path)) using FileStream fileStream = File.OpenRead(path);
{ Nca nca = new(_virtualFileSystem.KeySet, fileStream.AsStorage());
Nca nca = new Nca(_virtualFileSystem.KeySet, fileStream.AsStorage());
if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data) if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data)
{ {
@@ -1034,8 +1001,6 @@ namespace Ryujinx.HLE.FileSystem
return new SystemVersion(systemVersionFile.Get.AsStream()); return new SystemVersion(systemVersionFile.Get.AsStream());
} }
} }
}
} }
} }
} }

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