Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6f28c4abad | ||
|
105c9712c1 | ||
|
4d804ed45e | ||
|
4a27d29412 | ||
|
5bd2c58ad6 | ||
|
cf4c78b9c8 | ||
|
52aa4b6c22 | ||
|
5a02433080 | ||
|
915a0f7173 | ||
|
0cc266ff19 | ||
|
9a1b74799d | ||
|
638f3761f3 | ||
|
193ca3c9a2 | ||
|
eb0bb36bbf | ||
|
0e95a8271a | ||
|
76b474e97b | ||
|
27ee86f33b | ||
|
f7ec310231 | ||
|
e94d24f508 | ||
|
2bf4555591 | ||
|
86de288142 | ||
|
f35aa8e9d6 | ||
|
0e8e735a6d |
8
.github/assign/audio.yml
vendored
Normal file
8
.github/assign/audio.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- marysaka
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- audio
|
11
.github/assign/cpu.yml
vendored
Normal file
11
.github/assign/cpu.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- gdkchan
|
||||||
|
- riperiperi
|
||||||
|
- marysaka
|
||||||
|
- LDj3SNuD
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- cpu
|
4
.github/assign/global.yml
vendored
Normal file
4
.github/assign/global.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- Ryujinx/developers
|
10
.github/assign/gpu.yml
vendored
Normal file
10
.github/assign/gpu.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- gdkchan
|
||||||
|
- riperiperi
|
||||||
|
- marysaka
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- gpu
|
11
.github/assign/gui.yml
vendored
Normal file
11
.github/assign/gui.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- Ack77
|
||||||
|
- emmauss
|
||||||
|
- TSRBerry
|
||||||
|
- marysaka
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- gui
|
11
.github/assign/horizon.yml
vendored
Normal file
11
.github/assign/horizon.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- gdkchan
|
||||||
|
- Ack77
|
||||||
|
- marysaka
|
||||||
|
- TSRBerry
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- horizon
|
9
.github/assign/infra.yml
vendored
Normal file
9
.github/assign/infra.yml
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- marysaka
|
||||||
|
- TSRBerry
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- infra
|
33
.github/labeler.yml
vendored
Normal file
33
.github/labeler.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
audio: 'src/Ryujinx.Audio*/**'
|
||||||
|
|
||||||
|
cpu:
|
||||||
|
- 'src/ARMeilleure/**'
|
||||||
|
- 'src/Ryujinx.Cpu/**'
|
||||||
|
- 'src/Ryujinx.Memory/**'
|
||||||
|
|
||||||
|
gpu:
|
||||||
|
- 'src/Ryujinx.Graphics.*/**'
|
||||||
|
- 'src/Spv.Generator/**'
|
||||||
|
- 'src/Ryujinx.ShaderTools/**'
|
||||||
|
|
||||||
|
'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/**'
|
||||||
|
'graphics-backend:vulkan':
|
||||||
|
- 'src/Ryujinx.Graphics.Vulkan/**'
|
||||||
|
- 'src/Spv.Generator/**'
|
||||||
|
|
||||||
|
gui:
|
||||||
|
- 'src/Ryujinx/**'
|
||||||
|
- 'src/Ryujinx.Ui.Common/**'
|
||||||
|
- 'src/Ryujinx.Ui.LocaleGenerator/**'
|
||||||
|
- 'src/Ryujinx.Ava/**'
|
||||||
|
|
||||||
|
horizon:
|
||||||
|
- 'src/Ryujinx.HLE/**'
|
||||||
|
- 'src/Ryujinx.Horizon*/**'
|
||||||
|
|
||||||
|
kernel: 'src/Ryujinx.HLE/HOS/Kernel/**'
|
||||||
|
|
||||||
|
infra:
|
||||||
|
- '.github/**'
|
||||||
|
- 'distribution/**'
|
||||||
|
- 'Directory.Packages.props'
|
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -3,19 +3,13 @@ name: Build job
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs: {}
|
inputs: {}
|
||||||
#push:
|
|
||||||
# branches: [ master ]
|
|
||||||
# paths-ignore:
|
|
||||||
# - '.github/*'
|
|
||||||
# - '.github/ISSUE_TEMPLATE/**'
|
|
||||||
# - '*.yml'
|
|
||||||
# - 'README.md'
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '.github/*'
|
- '.github/**'
|
||||||
- '.github/ISSUE_TEMPLATE/**'
|
|
||||||
- '*.yml'
|
- '*.yml'
|
||||||
|
- '*.json'
|
||||||
|
- '*.config'
|
||||||
- 'README.md'
|
- 'README.md'
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
54
.github/workflows/pr_triage.yml
vendored
Normal file
54
.github/workflows/pr_triage.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
name: "Pull Request Triage"
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened, ready_for_review]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
triage:
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Update labels based on changes
|
||||||
|
uses: actions/labeler@v4
|
||||||
|
with:
|
||||||
|
sync-labels: true
|
||||||
|
dot: true
|
||||||
|
|
||||||
|
- name: Auto Assign [Audio]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/audio.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [CPU]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/cpu.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [GPU]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/gpu.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [GUI]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/gui.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [Horizon]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/horizon.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [Infra]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/infra.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [Global]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/global.yml'
|
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@@ -6,9 +6,10 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '.github/*'
|
- '.github/**'
|
||||||
- '.github/ISSUE_TEMPLATE/**'
|
|
||||||
- '*.yml'
|
- '*.yml'
|
||||||
|
- '*.json'
|
||||||
|
- '*.config'
|
||||||
- 'README.md'
|
- 'README.md'
|
||||||
|
|
||||||
concurrency: release
|
concurrency: release
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
<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.5.0" />
|
||||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
|
||||||
<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" />
|
||||||
<PackageVersion Include="NUnit" Version="3.13.3" />
|
<PackageVersion Include="NUnit" Version="3.13.3" />
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
|
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
|
||||||
<PackageVersion Include="SPB" Version="0.0.4-build28" />
|
<PackageVersion Include="SPB" Version="0.0.4-build28" />
|
||||||
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
|
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
|
||||||
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.30.1" />
|
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
|
||||||
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
|
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
|
||||||
<PackageVersion Include="System.Management" Version="7.0.1" />
|
<PackageVersion Include="System.Management" Version="7.0.1" />
|
||||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||||
|
@@ -168,8 +168,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
Logger.StartPass(PassName.CodeGeneration);
|
Logger.StartPass(PassName.CodeGeneration);
|
||||||
|
|
||||||
//Console.Error.WriteLine(IRDumper.GetDump(cfg));
|
|
||||||
|
|
||||||
bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0;
|
bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0;
|
||||||
|
|
||||||
CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable);
|
CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable);
|
||||||
|
@@ -179,6 +179,35 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
(uint)operation.GetSource(2).AsInt32());
|
(uint)operation.GetSource(2).AsInt32());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IntrinsicType.Vector128Unary:
|
||||||
|
GenerateVectorUnary(
|
||||||
|
context,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
info.Inst,
|
||||||
|
operation.Destination,
|
||||||
|
operation.GetSource(0));
|
||||||
|
break;
|
||||||
|
case IntrinsicType.Vector128Binary:
|
||||||
|
GenerateVectorBinary(
|
||||||
|
context,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
info.Inst,
|
||||||
|
operation.Destination,
|
||||||
|
operation.GetSource(0),
|
||||||
|
operation.GetSource(1));
|
||||||
|
break;
|
||||||
|
case IntrinsicType.Vector128BinaryRd:
|
||||||
|
GenerateVectorUnary(
|
||||||
|
context,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
info.Inst,
|
||||||
|
operation.Destination,
|
||||||
|
operation.GetSource(1));
|
||||||
|
break;
|
||||||
|
|
||||||
case IntrinsicType.VectorUnary:
|
case IntrinsicType.VectorUnary:
|
||||||
GenerateVectorUnary(
|
GenerateVectorUnary(
|
||||||
context,
|
context,
|
||||||
|
@@ -19,8 +19,8 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary));
|
Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary));
|
||||||
Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary));
|
Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary));
|
||||||
Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary));
|
Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary));
|
||||||
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128Unary));
|
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128BinaryRd));
|
||||||
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128Unary));
|
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128BinaryRd));
|
||||||
Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary));
|
Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary));
|
||||||
Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary));
|
Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary));
|
||||||
Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise));
|
Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise));
|
||||||
|
@@ -23,6 +23,10 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
ScalarTernaryShlRd,
|
ScalarTernaryShlRd,
|
||||||
ScalarTernaryShrRd,
|
ScalarTernaryShrRd,
|
||||||
|
|
||||||
|
Vector128Unary,
|
||||||
|
Vector128Binary,
|
||||||
|
Vector128BinaryRd,
|
||||||
|
|
||||||
VectorUnary,
|
VectorUnary,
|
||||||
VectorUnaryBitwise,
|
VectorUnaryBitwise,
|
||||||
VectorUnaryByElem,
|
VectorUnaryByElem,
|
||||||
@@ -50,9 +54,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
VectorTernaryShlRd,
|
VectorTernaryShlRd,
|
||||||
VectorTernaryShrRd,
|
VectorTernaryShrRd,
|
||||||
|
|
||||||
Vector128Unary,
|
|
||||||
Vector128Binary,
|
|
||||||
|
|
||||||
GetRegister,
|
GetRegister,
|
||||||
SetRegister
|
SetRegister
|
||||||
}
|
}
|
||||||
|
@@ -746,6 +746,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
|
info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
|
||||||
info.Type == IntrinsicType.ScalarTernaryShlRd ||
|
info.Type == IntrinsicType.ScalarTernaryShlRd ||
|
||||||
info.Type == IntrinsicType.ScalarTernaryShrRd ||
|
info.Type == IntrinsicType.ScalarTernaryShrRd ||
|
||||||
|
info.Type == IntrinsicType.Vector128BinaryRd ||
|
||||||
info.Type == IntrinsicType.VectorBinaryRd ||
|
info.Type == IntrinsicType.VectorBinaryRd ||
|
||||||
info.Type == IntrinsicType.VectorInsertByElem ||
|
info.Type == IntrinsicType.VectorInsertByElem ||
|
||||||
info.Type == IntrinsicType.VectorTernaryRd ||
|
info.Type == IntrinsicType.VectorTernaryRd ||
|
||||||
|
@@ -17,7 +17,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesdV, d, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||||
}
|
}
|
||||||
@@ -38,7 +42,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AeseV, d, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||||
}
|
}
|
||||||
@@ -58,7 +66,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
||||||
}
|
}
|
||||||
@@ -78,7 +90,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
Operand roundKey = context.VectorZero();
|
Operand roundKey = context.VectorZero();
|
||||||
|
|
||||||
|
@@ -17,7 +17,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesdV, d, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||||
}
|
}
|
||||||
@@ -38,7 +42,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AeseV, d, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||||
}
|
}
|
||||||
@@ -58,7 +66,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
||||||
}
|
}
|
||||||
@@ -78,7 +90,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
Operand roundKey = context.VectorZero();
|
Operand roundKey = context.VectorZero();
|
||||||
|
|
||||||
|
@@ -165,7 +165,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
Operand m = GetVecA32(op.Vm >> 1);
|
Operand m = GetVecA32(op.Vm >> 1);
|
||||||
|
|
||||||
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, doubleSize);
|
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
|
||||||
|
|
||||||
Intrinsic inst = (unsigned ? Intrinsic.Arm64FcvtzuGp : Intrinsic.Arm64FcvtzsGp) | Intrinsic.Arm64VDouble;
|
Intrinsic inst = (unsigned ? Intrinsic.Arm64FcvtzuGp : Intrinsic.Arm64FcvtzsGp) | Intrinsic.Arm64VDouble;
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS);
|
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!roundWithFpscr && Optimizations.UseSse41)
|
else if (!roundWithFpscr && Optimizations.UseSse41)
|
||||||
@@ -260,28 +260,64 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
if (Optimizations.UseAdvSimd)
|
if (Optimizations.UseAdvSimd)
|
||||||
{
|
{
|
||||||
if (unsigned)
|
bool doubleSize = floatSize == OperandType.FP64;
|
||||||
|
|
||||||
|
if (doubleSize)
|
||||||
{
|
{
|
||||||
inst = rm switch {
|
Operand m = GetVecA32(op.Vm >> 1);
|
||||||
0b00 => Intrinsic.Arm64FcvtauS,
|
|
||||||
0b01 => Intrinsic.Arm64FcvtnuS,
|
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
|
||||||
0b10 => Intrinsic.Arm64FcvtpuS,
|
|
||||||
0b11 => Intrinsic.Arm64FcvtmuS,
|
if (unsigned)
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
{
|
||||||
};
|
inst = rm switch {
|
||||||
|
0b00 => Intrinsic.Arm64FcvtauGp,
|
||||||
|
0b01 => Intrinsic.Arm64FcvtnuGp,
|
||||||
|
0b10 => Intrinsic.Arm64FcvtpuGp,
|
||||||
|
0b11 => Intrinsic.Arm64FcvtmuGp,
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inst = rm switch {
|
||||||
|
0b00 => Intrinsic.Arm64FcvtasGp,
|
||||||
|
0b01 => Intrinsic.Arm64FcvtnsGp,
|
||||||
|
0b10 => Intrinsic.Arm64FcvtpsGp,
|
||||||
|
0b11 => Intrinsic.Arm64FcvtmsGp,
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand asInteger = context.AddIntrinsicInt(inst | Intrinsic.Arm64VDouble, toConvert);
|
||||||
|
|
||||||
|
InsertScalar(context, op.Vd, asInteger);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inst = rm switch {
|
if (unsigned)
|
||||||
0b00 => Intrinsic.Arm64FcvtasS,
|
{
|
||||||
0b01 => Intrinsic.Arm64FcvtnsS,
|
inst = rm switch {
|
||||||
0b10 => Intrinsic.Arm64FcvtpsS,
|
0b00 => Intrinsic.Arm64FcvtauS,
|
||||||
0b11 => Intrinsic.Arm64FcvtmsS,
|
0b01 => Intrinsic.Arm64FcvtnuS,
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
0b10 => Intrinsic.Arm64FcvtpuS,
|
||||||
};
|
0b11 => Intrinsic.Arm64FcvtmuS,
|
||||||
}
|
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inst = rm switch {
|
||||||
|
0b00 => Intrinsic.Arm64FcvtasS,
|
||||||
|
0b01 => Intrinsic.Arm64FcvtnsS,
|
||||||
|
0b10 => Intrinsic.Arm64FcvtpsS,
|
||||||
|
0b11 => Intrinsic.Arm64FcvtmsS,
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
|
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (Optimizations.UseSse41)
|
else if (Optimizations.UseSse41)
|
||||||
{
|
{
|
||||||
|
@@ -192,11 +192,10 @@ namespace ARMeilleure.Instructions
|
|||||||
EmitVectorTernaryOpSimd32(context, (d, n, m) => context.AddIntrinsic(inst, d, n, m));
|
EmitVectorTernaryOpSimd32(context, (d, n, m) => context.AddIntrinsic(inst, d, n, m));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc)
|
public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc, bool doubleSize)
|
||||||
{
|
{
|
||||||
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
|
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
|
||||||
|
|
||||||
bool doubleSize = (op.Size & 1) != 0;
|
|
||||||
int shift = doubleSize ? 1 : 2;
|
int shift = doubleSize ? 1 : 2;
|
||||||
Operand m = GetVecA32(op.Vm >> shift);
|
Operand m = GetVecA32(op.Vm >> shift);
|
||||||
Operand d = GetVecA32(op.Vd >> shift);
|
Operand d = GetVecA32(op.Vd >> shift);
|
||||||
@@ -215,8 +214,13 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
|
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
|
||||||
|
|
||||||
inst |= ((op.Size & 1) != 0 ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128;
|
EmitScalarUnaryOpF32(context, inst, (op.Size & 1) != 0);
|
||||||
EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m));
|
}
|
||||||
|
|
||||||
|
public static void EmitScalarUnaryOpF32(ArmEmitterContext context, Intrinsic inst, bool doubleSize)
|
||||||
|
{
|
||||||
|
inst |= (doubleSize ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128;
|
||||||
|
EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m), doubleSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EmitScalarBinaryOpSimd32(ArmEmitterContext context, Func2I scalarFunc)
|
public static void EmitScalarBinaryOpSimd32(ArmEmitterContext context, Func2I scalarFunc)
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace ARMeilleure.IntermediateRepresentation
|
namespace ARMeilleure.IntermediateRepresentation
|
||||||
{
|
{
|
||||||
|
[Flags]
|
||||||
enum Intrinsic : ushort
|
enum Intrinsic : ushort
|
||||||
{
|
{
|
||||||
// X86 (SSE and AVX)
|
// X86 (SSE and AVX)
|
||||||
|
@@ -13,6 +13,7 @@ namespace ARMeilleure
|
|||||||
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
||||||
|
|
||||||
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
||||||
|
public static bool UseArm64AesIfAvailable { get; set; } = true;
|
||||||
public static bool UseArm64PmullIfAvailable { get; set; } = true;
|
public static bool UseArm64PmullIfAvailable { get; set; } = true;
|
||||||
|
|
||||||
public static bool UseSseIfAvailable { get; set; } = true;
|
public static bool UseSseIfAvailable { get; set; } = true;
|
||||||
@@ -41,6 +42,7 @@ namespace ARMeilleure
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal static bool UseAdvSimd => UseAdvSimdIfAvailable && Arm64HardwareCapabilities.SupportsAdvSimd;
|
internal static bool UseAdvSimd => UseAdvSimdIfAvailable && Arm64HardwareCapabilities.SupportsAdvSimd;
|
||||||
|
internal static bool UseArm64Aes => UseArm64AesIfAvailable && Arm64HardwareCapabilities.SupportsAes;
|
||||||
internal static bool UseArm64Pmull => UseArm64PmullIfAvailable && Arm64HardwareCapabilities.SupportsPmull;
|
internal static bool UseArm64Pmull => UseArm64PmullIfAvailable && Arm64HardwareCapabilities.SupportsPmull;
|
||||||
|
|
||||||
internal static bool UseSse => UseSseIfAvailable && X86HardwareCapabilities.SupportsSse;
|
internal static bool UseSse => UseSseIfAvailable && X86HardwareCapabilities.SupportsSse;
|
||||||
|
@@ -2,6 +2,7 @@ using ARMeilleure.CodeGen;
|
|||||||
using ARMeilleure.CodeGen.Unwinding;
|
using ARMeilleure.CodeGen.Unwinding;
|
||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using ARMeilleure.Native;
|
using ARMeilleure.Native;
|
||||||
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -12,8 +13,8 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
{
|
{
|
||||||
static partial class JitCache
|
static partial class JitCache
|
||||||
{
|
{
|
||||||
private const int PageSize = 4 * 1024;
|
private static readonly int PageSize = (int)MemoryBlock.GetPageSize();
|
||||||
private const int PageMask = PageSize - 1;
|
private static readonly int PageMask = PageSize - 1;
|
||||||
|
|
||||||
private const int CodeAlignment = 4; // Bytes.
|
private const int CodeAlignment = 4; // Bytes.
|
||||||
private const int CacheSize = 2047 * 1024 * 1024;
|
private const int CacheSize = 2047 * 1024 * 1024;
|
||||||
|
@@ -30,7 +30,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 = 4661; //! To be incremented manually for each change to the ARMeilleure project.
|
private const uint InternalVersion = 5292; //! 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";
|
||||||
|
@@ -40,6 +40,7 @@ using SixLabors.ImageSharp;
|
|||||||
using SixLabors.ImageSharp.Formats.Png;
|
using SixLabors.ImageSharp.Formats.Png;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using SPB.Graphics.Exceptions;
|
||||||
using SPB.Graphics.Vulkan;
|
using SPB.Graphics.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -475,11 +476,20 @@ namespace Ryujinx.Ava
|
|||||||
_windowsMultimediaTimerResolution = null;
|
_windowsMultimediaTimerResolution = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent();
|
if (_rendererHost.EmbeddedWindow is EmbeddedWindowOpenGL openGlWindow)
|
||||||
|
{
|
||||||
|
// Try to bind the OpenGL context before calling the shutdown event.
|
||||||
|
openGlWindow.MakeCurrent(false, false);
|
||||||
|
|
||||||
Device.DisposeGpu();
|
Device.DisposeGpu();
|
||||||
|
|
||||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);
|
// Unbind context and destroy everything.
|
||||||
|
openGlWindow.MakeCurrent(true, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Device.DisposeGpu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HideCursorState_Changed(object sender, ReactiveEventArgs<HideCursorMode> state)
|
private void HideCursorState_Changed(object sender, ReactiveEventArgs<HideCursorMode> state)
|
||||||
@@ -930,7 +940,7 @@ namespace Ryujinx.Ava
|
|||||||
_gpuDoneEvent.Set();
|
_gpuDoneEvent.Set();
|
||||||
});
|
});
|
||||||
|
|
||||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);
|
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateStatus()
|
public void UpdateStatus()
|
||||||
@@ -1044,7 +1054,7 @@ namespace Ryujinx.Ava
|
|||||||
ScreenshotRequested = true;
|
ScreenshotRequested = true;
|
||||||
break;
|
break;
|
||||||
case KeyboardHotkeyState.ShowUi:
|
case KeyboardHotkeyState.ShowUi:
|
||||||
_viewModel.ShowMenuAndStatusBar = true;
|
_viewModel.ShowMenuAndStatusBar = !_viewModel.ShowMenuAndStatusBar;
|
||||||
break;
|
break;
|
||||||
case KeyboardHotkeyState.Pause:
|
case KeyboardHotkeyState.Pause:
|
||||||
if (_viewModel.IsPaused)
|
if (_viewModel.IsPaused)
|
||||||
|
@@ -545,7 +545,7 @@
|
|||||||
"SwkbdMinRangeCharacters": "Must be {0}-{1} characters long",
|
"SwkbdMinRangeCharacters": "Must be {0}-{1} characters long",
|
||||||
"SoftwareKeyboard": "Software Keyboard",
|
"SoftwareKeyboard": "Software Keyboard",
|
||||||
"SoftwareKeyboardModeNumbersOnly": "Must be numbers only",
|
"SoftwareKeyboardModeNumbersOnly": "Must be numbers only",
|
||||||
"SoftwareKeyboardModeAlphabet": "Must be alphabets only",
|
"SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only",
|
||||||
"SoftwareKeyboardModeASCII": "Must be ASCII text only",
|
"SoftwareKeyboardModeASCII": "Must be ASCII text only",
|
||||||
"DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
|
"DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
|
||||||
"DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
|
"DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
|
||||||
|
@@ -741,7 +741,7 @@ namespace Ryujinx.Modules
|
|||||||
var files = Directory.EnumerateFiles(HomeDir); // All files directly in base dir.
|
var files = Directory.EnumerateFiles(HomeDir); // All files directly in base dir.
|
||||||
|
|
||||||
// Determine and exclude user files only when the updater is running, not when cleaning old files
|
// Determine and exclude user files only when the updater is running, not when cleaning old files
|
||||||
if (_running)
|
if (_running && !OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
// Compare the loose files in base directory against the loose files from the incoming update, and store foreign ones in a user list.
|
// Compare the loose files in base directory against the loose files from the incoming update, and store foreign ones in a user list.
|
||||||
var oldFiles = Directory.EnumerateFiles(HomeDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName);
|
var oldFiles = Directory.EnumerateFiles(HomeDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName);
|
||||||
|
@@ -146,7 +146,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
case KeyboardMode.Alphabet:
|
case KeyboardMode.Alphabet:
|
||||||
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet);
|
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet);
|
||||||
validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
|
validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
|
||||||
_checkInput = text => text.All(char.IsAsciiLetter);
|
_checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value));
|
||||||
break;
|
break;
|
||||||
case KeyboardMode.ASCII:
|
case KeyboardMode.ASCII:
|
||||||
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeASCII);
|
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeASCII);
|
||||||
|
@@ -123,7 +123,7 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
X11Window = PlatformHelper.CreateOpenGLWindow(FramebufferFormat.Default, 0, 0, 100, 100) as GLXWindow;
|
X11Window = PlatformHelper.CreateOpenGLWindow(new FramebufferFormat(new ColorFormat(8, 8, 8, 0), 16, 0, ColorFormat.Zero, 0, 2, false), 0, 0, 100, 100) as GLXWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowHandle = X11Window.WindowHandle.RawHandle;
|
WindowHandle = X11Window.WindowHandle.RawHandle;
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.OpenGL;
|
using Ryujinx.Graphics.OpenGL;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.Ui.Common.Configuration;
|
||||||
using SPB.Graphics;
|
using SPB.Graphics;
|
||||||
|
using SPB.Graphics.Exceptions;
|
||||||
using SPB.Graphics.OpenGL;
|
using SPB.Graphics.OpenGL;
|
||||||
using SPB.Platform;
|
using SPB.Platform;
|
||||||
using SPB.Platform.WGL;
|
using SPB.Platform.WGL;
|
||||||
@@ -18,8 +20,6 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
|
|
||||||
public OpenGLContextBase Context { get; set; }
|
public OpenGLContextBase Context { get; set; }
|
||||||
|
|
||||||
public EmbeddedWindowOpenGL() { }
|
|
||||||
|
|
||||||
protected override void OnWindowDestroying()
|
protected override void OnWindowDestroying()
|
||||||
{
|
{
|
||||||
Context.Dispose();
|
Context.Dispose();
|
||||||
@@ -62,14 +62,21 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
Context.MakeCurrent(null);
|
Context.MakeCurrent(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MakeCurrent()
|
public void MakeCurrent(bool unbind = false, bool shouldThrow = true)
|
||||||
{
|
{
|
||||||
Context?.MakeCurrent(_window);
|
try
|
||||||
}
|
{
|
||||||
|
Context?.MakeCurrent(!unbind ? _window : null);
|
||||||
|
}
|
||||||
|
catch (ContextException e)
|
||||||
|
{
|
||||||
|
if (shouldThrow)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
public void MakeCurrent(NativeWindowBase window)
|
Logger.Warning?.Print(LogClass.Ui, $"Failed to {(!unbind ? "bind" : "unbind")} OpenGL context: {e}");
|
||||||
{
|
}
|
||||||
Context?.MakeCurrent(window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SwapBuffers()
|
public void SwapBuffers()
|
||||||
|
@@ -96,7 +96,7 @@ namespace Ryujinx.Common.Configuration
|
|||||||
if (OperatingSystem.IsMacOS() && Mode == LaunchMode.UserProfile)
|
if (OperatingSystem.IsMacOS() && Mode == LaunchMode.UserProfile)
|
||||||
{
|
{
|
||||||
string oldConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir);
|
string oldConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir);
|
||||||
if (Path.Exists(oldConfigPath) && !Path.Exists(BaseDirPath))
|
if (Path.Exists(oldConfigPath) && !IsPathSymlink(oldConfigPath) && !Path.Exists(BaseDirPath))
|
||||||
{
|
{
|
||||||
CopyDirectory(oldConfigPath, BaseDirPath);
|
CopyDirectory(oldConfigPath, BaseDirPath);
|
||||||
Directory.Delete(oldConfigPath, true);
|
Directory.Delete(oldConfigPath, true);
|
||||||
@@ -115,6 +115,14 @@ namespace Ryujinx.Common.Configuration
|
|||||||
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));
|
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if existing old baseDirPath is a symlink, to prevent possible errors.
|
||||||
|
// Should be removed, when the existance of the old directory isn't checked anymore.
|
||||||
|
private static bool IsPathSymlink(string path)
|
||||||
|
{
|
||||||
|
FileAttributes attributes = File.GetAttributes(path);
|
||||||
|
return (attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint;
|
||||||
|
}
|
||||||
|
|
||||||
private static void CopyDirectory(string sourceDir, string destinationDir)
|
private static void CopyDirectory(string sourceDir, string destinationDir)
|
||||||
{
|
{
|
||||||
var dir = new DirectoryInfo(sourceDir);
|
var dir = new DirectoryInfo(sourceDir);
|
||||||
|
@@ -24,6 +24,24 @@ namespace Ryujinx.Common.Memory
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryRead<T>(out T value) where T : unmanaged
|
||||||
|
{
|
||||||
|
int valueSize = Unsafe.SizeOf<T>();
|
||||||
|
|
||||||
|
if (valueSize > _input.Length)
|
||||||
|
{
|
||||||
|
value = default;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = MemoryMarshal.Cast<byte, T>(_input)[0];
|
||||||
|
|
||||||
|
_input = _input.Slice(valueSize);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public ReadOnlySpan<byte> GetSpan(int size)
|
public ReadOnlySpan<byte> GetSpan(int size)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<byte> data = _input.Slice(0, size);
|
ReadOnlySpan<byte> data = _input.Slice(0, size);
|
||||||
|
@@ -28,6 +28,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
public readonly bool SupportsFragmentShaderOrderingIntel;
|
public readonly bool SupportsFragmentShaderOrderingIntel;
|
||||||
public readonly bool SupportsGeometryShader;
|
public readonly bool SupportsGeometryShader;
|
||||||
public readonly bool SupportsGeometryShaderPassthrough;
|
public readonly bool SupportsGeometryShaderPassthrough;
|
||||||
|
public readonly bool SupportsTransformFeedback;
|
||||||
public readonly bool SupportsImageLoadFormatted;
|
public readonly bool SupportsImageLoadFormatted;
|
||||||
public readonly bool SupportsLayerVertexTessellation;
|
public readonly bool SupportsLayerVertexTessellation;
|
||||||
public readonly bool SupportsMismatchingViewFormat;
|
public readonly bool SupportsMismatchingViewFormat;
|
||||||
@@ -77,6 +78,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
bool supportsFragmentShaderOrderingIntel,
|
bool supportsFragmentShaderOrderingIntel,
|
||||||
bool supportsGeometryShader,
|
bool supportsGeometryShader,
|
||||||
bool supportsGeometryShaderPassthrough,
|
bool supportsGeometryShaderPassthrough,
|
||||||
|
bool supportsTransformFeedback,
|
||||||
bool supportsImageLoadFormatted,
|
bool supportsImageLoadFormatted,
|
||||||
bool supportsLayerVertexTessellation,
|
bool supportsLayerVertexTessellation,
|
||||||
bool supportsMismatchingViewFormat,
|
bool supportsMismatchingViewFormat,
|
||||||
@@ -122,6 +124,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
||||||
SupportsGeometryShader = supportsGeometryShader;
|
SupportsGeometryShader = supportsGeometryShader;
|
||||||
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
||||||
|
SupportsTransformFeedback = supportsTransformFeedback;
|
||||||
SupportsImageLoadFormatted = supportsImageLoadFormatted;
|
SupportsImageLoadFormatted = supportsImageLoadFormatted;
|
||||||
SupportsLayerVertexTessellation = supportsLayerVertexTessellation;
|
SupportsLayerVertexTessellation = supportsLayerVertexTessellation;
|
||||||
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
|
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
|
||||||
|
@@ -100,22 +100,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
public uint SetObject;
|
public uint SetObject;
|
||||||
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
|
public int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||||
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||||
public fixed uint Reserved04[63];
|
public fixed uint Reserved04[63];
|
||||||
public uint NoOperation;
|
public uint NoOperation;
|
||||||
public uint SetNotifyA;
|
public uint SetNotifyA;
|
||||||
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
|
public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0xFF);
|
||||||
public uint SetNotifyB;
|
public uint SetNotifyB;
|
||||||
public uint Notify;
|
public uint Notify;
|
||||||
public NotifyType NotifyType => (NotifyType)(Notify);
|
public NotifyType NotifyType => (NotifyType)(Notify);
|
||||||
public uint WaitForIdle;
|
public uint WaitForIdle;
|
||||||
public fixed uint Reserved114[7];
|
public fixed uint Reserved114[7];
|
||||||
public uint SetGlobalRenderEnableA;
|
public uint SetGlobalRenderEnableA;
|
||||||
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
|
public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
|
||||||
public uint SetGlobalRenderEnableB;
|
public uint SetGlobalRenderEnableB;
|
||||||
public uint SetGlobalRenderEnableC;
|
public uint SetGlobalRenderEnableC;
|
||||||
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
|
public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
|
||||||
public uint SendGoIdle;
|
public uint SendGoIdle;
|
||||||
public uint PmTrigger;
|
public uint PmTrigger;
|
||||||
public uint PmTriggerWfi;
|
public uint PmTriggerWfi;
|
||||||
@@ -126,11 +126,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public uint LineLengthIn;
|
public uint LineLengthIn;
|
||||||
public uint LineCount;
|
public uint LineCount;
|
||||||
public uint OffsetOutUpper;
|
public uint OffsetOutUpper;
|
||||||
public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
|
public int OffsetOutUpperValue => (int)(OffsetOutUpper & 0xFF);
|
||||||
public uint OffsetOut;
|
public uint OffsetOut;
|
||||||
public uint PitchOut;
|
public uint PitchOut;
|
||||||
public uint SetDstBlockSize;
|
public uint SetDstBlockSize;
|
||||||
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
|
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)(SetDstBlockSize & 0xF);
|
||||||
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
||||||
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
||||||
public uint SetDstWidth;
|
public uint SetDstWidth;
|
||||||
@@ -138,11 +138,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public uint SetDstDepth;
|
public uint SetDstDepth;
|
||||||
public uint SetDstLayer;
|
public uint SetDstLayer;
|
||||||
public uint SetDstOriginBytesX;
|
public uint SetDstOriginBytesX;
|
||||||
public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
|
public int SetDstOriginBytesXV => (int)(SetDstOriginBytesX & 0xFFFFF);
|
||||||
public uint SetDstOriginSamplesY;
|
public uint SetDstOriginSamplesY;
|
||||||
public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
|
public int SetDstOriginSamplesYV => (int)(SetDstOriginSamplesY & 0xFFFF);
|
||||||
public uint LaunchDma;
|
public uint LaunchDma;
|
||||||
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
|
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)(LaunchDma & 0x1);
|
||||||
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
|
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
|
||||||
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
|
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
|
||||||
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
|
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
|
||||||
@@ -153,7 +153,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public uint LoadInlineData;
|
public uint LoadInlineData;
|
||||||
public fixed uint Reserved1B8[9];
|
public fixed uint Reserved1B8[9];
|
||||||
public uint SetI2mSemaphoreA;
|
public uint SetI2mSemaphoreA;
|
||||||
public int SetI2mSemaphoreAOffsetUpper => (int)((SetI2mSemaphoreA >> 0) & 0xFF);
|
public int SetI2mSemaphoreAOffsetUpper => (int)(SetI2mSemaphoreA & 0xFF);
|
||||||
public uint SetI2mSemaphoreB;
|
public uint SetI2mSemaphoreB;
|
||||||
public uint SetI2mSemaphoreC;
|
public uint SetI2mSemaphoreC;
|
||||||
public fixed uint Reserved1E8[2];
|
public fixed uint Reserved1E8[2];
|
||||||
@@ -162,7 +162,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public uint SetI2mSpareNoop02;
|
public uint SetI2mSpareNoop02;
|
||||||
public uint SetI2mSpareNoop03;
|
public uint SetI2mSpareNoop03;
|
||||||
public uint SetValidSpanOverflowAreaA;
|
public uint SetValidSpanOverflowAreaA;
|
||||||
public int SetValidSpanOverflowAreaAAddressUpper => (int)((SetValidSpanOverflowAreaA >> 0) & 0xFF);
|
public int SetValidSpanOverflowAreaAAddressUpper => (int)(SetValidSpanOverflowAreaA & 0xFF);
|
||||||
public uint SetValidSpanOverflowAreaB;
|
public uint SetValidSpanOverflowAreaB;
|
||||||
public uint SetValidSpanOverflowAreaC;
|
public uint SetValidSpanOverflowAreaC;
|
||||||
public uint SetCoalesceWaitingPeriodUnit;
|
public uint SetCoalesceWaitingPeriodUnit;
|
||||||
@@ -185,12 +185,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public uint SetReservedSwMethod06;
|
public uint SetReservedSwMethod06;
|
||||||
public uint SetReservedSwMethod07;
|
public uint SetReservedSwMethod07;
|
||||||
public uint SetCwdControl;
|
public uint SetCwdControl;
|
||||||
public SetCwdControlSmSelection SetCwdControlSmSelection => (SetCwdControlSmSelection)((SetCwdControl >> 0) & 0x1);
|
public SetCwdControlSmSelection SetCwdControlSmSelection => (SetCwdControlSmSelection)(SetCwdControl & 0x1);
|
||||||
public uint InvalidateTextureHeaderCacheNoWfi;
|
public uint InvalidateTextureHeaderCacheNoWfi;
|
||||||
public InvalidateCacheLines InvalidateTextureHeaderCacheNoWfiLines => (InvalidateCacheLines)((InvalidateTextureHeaderCacheNoWfi >> 0) & 0x1);
|
public InvalidateCacheLines InvalidateTextureHeaderCacheNoWfiLines => (InvalidateCacheLines)(InvalidateTextureHeaderCacheNoWfi & 0x1);
|
||||||
public int InvalidateTextureHeaderCacheNoWfiTag => (int)((InvalidateTextureHeaderCacheNoWfi >> 4) & 0x3FFFFF);
|
public int InvalidateTextureHeaderCacheNoWfiTag => (int)((InvalidateTextureHeaderCacheNoWfi >> 4) & 0x3FFFFF);
|
||||||
public uint SetCwdRefCounter;
|
public uint SetCwdRefCounter;
|
||||||
public int SetCwdRefCounterSelect => (int)((SetCwdRefCounter >> 0) & 0x3F);
|
public int SetCwdRefCounterSelect => (int)(SetCwdRefCounter & 0x3F);
|
||||||
public int SetCwdRefCounterValue => (int)((SetCwdRefCounter >> 8) & 0xFFFF);
|
public int SetCwdRefCounterValue => (int)((SetCwdRefCounter >> 8) & 0xFFFF);
|
||||||
public uint SetReservedSwMethod08;
|
public uint SetReservedSwMethod08;
|
||||||
public uint SetReservedSwMethod09;
|
public uint SetReservedSwMethod09;
|
||||||
@@ -201,28 +201,28 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public uint SetReservedSwMethod14;
|
public uint SetReservedSwMethod14;
|
||||||
public uint SetReservedSwMethod15;
|
public uint SetReservedSwMethod15;
|
||||||
public uint SetGwcScgType;
|
public uint SetGwcScgType;
|
||||||
public SetGwcScgTypeScgType SetGwcScgTypeScgType => (SetGwcScgTypeScgType)((SetGwcScgType >> 0) & 0x1);
|
public SetGwcScgTypeScgType SetGwcScgTypeScgType => (SetGwcScgTypeScgType)(SetGwcScgType & 0x1);
|
||||||
public uint SetScgControl;
|
public uint SetScgControl;
|
||||||
public int SetScgControlCompute1MaxSmCount => (int)((SetScgControl >> 0) & 0x1FF);
|
public int SetScgControlCompute1MaxSmCount => (int)(SetScgControl & 0x1FF);
|
||||||
public uint InvalidateConstantBufferCacheA;
|
public uint InvalidateConstantBufferCacheA;
|
||||||
public int InvalidateConstantBufferCacheAAddressUpper => (int)((InvalidateConstantBufferCacheA >> 0) & 0xFF);
|
public int InvalidateConstantBufferCacheAAddressUpper => (int)(InvalidateConstantBufferCacheA & 0xFF);
|
||||||
public uint InvalidateConstantBufferCacheB;
|
public uint InvalidateConstantBufferCacheB;
|
||||||
public uint InvalidateConstantBufferCacheC;
|
public uint InvalidateConstantBufferCacheC;
|
||||||
public int InvalidateConstantBufferCacheCByteCount => (int)((InvalidateConstantBufferCacheC >> 0) & 0x1FFFF);
|
public int InvalidateConstantBufferCacheCByteCount => (int)(InvalidateConstantBufferCacheC & 0x1FFFF);
|
||||||
public bool InvalidateConstantBufferCacheCThruL2 => (InvalidateConstantBufferCacheC & 0x80000000) != 0;
|
public bool InvalidateConstantBufferCacheCThruL2 => (InvalidateConstantBufferCacheC & 0x80000000) != 0;
|
||||||
public uint SetComputeClassVersion;
|
public uint SetComputeClassVersion;
|
||||||
public int SetComputeClassVersionCurrent => (int)((SetComputeClassVersion >> 0) & 0xFFFF);
|
public int SetComputeClassVersionCurrent => (int)(SetComputeClassVersion & 0xFFFF);
|
||||||
public int SetComputeClassVersionOldestSupported => (int)((SetComputeClassVersion >> 16) & 0xFFFF);
|
public int SetComputeClassVersionOldestSupported => (int)((SetComputeClassVersion >> 16) & 0xFFFF);
|
||||||
public uint CheckComputeClassVersion;
|
public uint CheckComputeClassVersion;
|
||||||
public int CheckComputeClassVersionCurrent => (int)((CheckComputeClassVersion >> 0) & 0xFFFF);
|
public int CheckComputeClassVersionCurrent => (int)(CheckComputeClassVersion & 0xFFFF);
|
||||||
public int CheckComputeClassVersionOldestSupported => (int)((CheckComputeClassVersion >> 16) & 0xFFFF);
|
public int CheckComputeClassVersionOldestSupported => (int)((CheckComputeClassVersion >> 16) & 0xFFFF);
|
||||||
public uint SetQmdVersion;
|
public uint SetQmdVersion;
|
||||||
public int SetQmdVersionCurrent => (int)((SetQmdVersion >> 0) & 0xFFFF);
|
public int SetQmdVersionCurrent => (int)(SetQmdVersion & 0xFFFF);
|
||||||
public int SetQmdVersionOldestSupported => (int)((SetQmdVersion >> 16) & 0xFFFF);
|
public int SetQmdVersionOldestSupported => (int)((SetQmdVersion >> 16) & 0xFFFF);
|
||||||
public uint SetWfiConfig;
|
public uint SetWfiConfig;
|
||||||
public bool SetWfiConfigEnableScgTypeWfi => (SetWfiConfig & 0x1) != 0;
|
public bool SetWfiConfigEnableScgTypeWfi => (SetWfiConfig & 0x1) != 0;
|
||||||
public uint CheckQmdVersion;
|
public uint CheckQmdVersion;
|
||||||
public int CheckQmdVersionCurrent => (int)((CheckQmdVersion >> 0) & 0xFFFF);
|
public int CheckQmdVersionCurrent => (int)(CheckQmdVersion & 0xFFFF);
|
||||||
public int CheckQmdVersionOldestSupported => (int)((CheckQmdVersion >> 16) & 0xFFFF);
|
public int CheckQmdVersionOldestSupported => (int)((CheckQmdVersion >> 16) & 0xFFFF);
|
||||||
public uint WaitForIdleScgType;
|
public uint WaitForIdleScgType;
|
||||||
public uint InvalidateSkedCaches;
|
public uint InvalidateSkedCaches;
|
||||||
@@ -231,28 +231,28 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public bool SetScgRenderEnableControlCompute1UsesRenderEnable => (SetScgRenderEnableControl & 0x1) != 0;
|
public bool SetScgRenderEnableControlCompute1UsesRenderEnable => (SetScgRenderEnableControl & 0x1) != 0;
|
||||||
public fixed uint Reserved2A0[4];
|
public fixed uint Reserved2A0[4];
|
||||||
public uint SetCwdSlotCount;
|
public uint SetCwdSlotCount;
|
||||||
public int SetCwdSlotCountV => (int)((SetCwdSlotCount >> 0) & 0xFF);
|
public int SetCwdSlotCountV => (int)(SetCwdSlotCount & 0xFF);
|
||||||
public uint SendPcasA;
|
public uint SendPcasA;
|
||||||
public uint SendPcasB;
|
public uint SendPcasB;
|
||||||
public int SendPcasBFrom => (int)((SendPcasB >> 0) & 0xFFFFFF);
|
public int SendPcasBFrom => (int)(SendPcasB & 0xFFFFFF);
|
||||||
public int SendPcasBDelta => (int)((SendPcasB >> 24) & 0xFF);
|
public int SendPcasBDelta => (int)((SendPcasB >> 24) & 0xFF);
|
||||||
public uint SendSignalingPcasB;
|
public uint SendSignalingPcasB;
|
||||||
public bool SendSignalingPcasBInvalidate => (SendSignalingPcasB & 0x1) != 0;
|
public bool SendSignalingPcasBInvalidate => (SendSignalingPcasB & 0x1) != 0;
|
||||||
public bool SendSignalingPcasBSchedule => (SendSignalingPcasB & 0x2) != 0;
|
public bool SendSignalingPcasBSchedule => (SendSignalingPcasB & 0x2) != 0;
|
||||||
public fixed uint Reserved2C0[9];
|
public fixed uint Reserved2C0[9];
|
||||||
public uint SetShaderLocalMemoryNonThrottledA;
|
public uint SetShaderLocalMemoryNonThrottledA;
|
||||||
public int SetShaderLocalMemoryNonThrottledASizeUpper => (int)((SetShaderLocalMemoryNonThrottledA >> 0) & 0xFF);
|
public int SetShaderLocalMemoryNonThrottledASizeUpper => (int)(SetShaderLocalMemoryNonThrottledA & 0xFF);
|
||||||
public uint SetShaderLocalMemoryNonThrottledB;
|
public uint SetShaderLocalMemoryNonThrottledB;
|
||||||
public uint SetShaderLocalMemoryNonThrottledC;
|
public uint SetShaderLocalMemoryNonThrottledC;
|
||||||
public int SetShaderLocalMemoryNonThrottledCMaxSmCount => (int)((SetShaderLocalMemoryNonThrottledC >> 0) & 0x1FF);
|
public int SetShaderLocalMemoryNonThrottledCMaxSmCount => (int)(SetShaderLocalMemoryNonThrottledC & 0x1FF);
|
||||||
public uint SetShaderLocalMemoryThrottledA;
|
public uint SetShaderLocalMemoryThrottledA;
|
||||||
public int SetShaderLocalMemoryThrottledASizeUpper => (int)((SetShaderLocalMemoryThrottledA >> 0) & 0xFF);
|
public int SetShaderLocalMemoryThrottledASizeUpper => (int)(SetShaderLocalMemoryThrottledA & 0xFF);
|
||||||
public uint SetShaderLocalMemoryThrottledB;
|
public uint SetShaderLocalMemoryThrottledB;
|
||||||
public uint SetShaderLocalMemoryThrottledC;
|
public uint SetShaderLocalMemoryThrottledC;
|
||||||
public int SetShaderLocalMemoryThrottledCMaxSmCount => (int)((SetShaderLocalMemoryThrottledC >> 0) & 0x1FF);
|
public int SetShaderLocalMemoryThrottledCMaxSmCount => (int)(SetShaderLocalMemoryThrottledC & 0x1FF);
|
||||||
public fixed uint Reserved2FC[5];
|
public fixed uint Reserved2FC[5];
|
||||||
public uint SetSpaVersion;
|
public uint SetSpaVersion;
|
||||||
public int SetSpaVersionMinor => (int)((SetSpaVersion >> 0) & 0xFF);
|
public int SetSpaVersionMinor => (int)(SetSpaVersion & 0xFF);
|
||||||
public int SetSpaVersionMajor => (int)((SetSpaVersion >> 8) & 0xFF);
|
public int SetSpaVersionMajor => (int)((SetSpaVersion >> 8) & 0xFF);
|
||||||
public fixed uint Reserved314[123];
|
public fixed uint Reserved314[123];
|
||||||
public uint SetFalcon00;
|
public uint SetFalcon00;
|
||||||
@@ -291,14 +291,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public uint SetShaderLocalMemoryWindow;
|
public uint SetShaderLocalMemoryWindow;
|
||||||
public fixed uint Reserved780[4];
|
public fixed uint Reserved780[4];
|
||||||
public uint SetShaderLocalMemoryA;
|
public uint SetShaderLocalMemoryA;
|
||||||
public int SetShaderLocalMemoryAAddressUpper => (int)((SetShaderLocalMemoryA >> 0) & 0xFF);
|
public int SetShaderLocalMemoryAAddressUpper => (int)(SetShaderLocalMemoryA & 0xFF);
|
||||||
public uint SetShaderLocalMemoryB;
|
public uint SetShaderLocalMemoryB;
|
||||||
public fixed uint Reserved798[383];
|
public fixed uint Reserved798[383];
|
||||||
public uint SetShaderCacheControl;
|
public uint SetShaderCacheControl;
|
||||||
public bool SetShaderCacheControlIcachePrefetchEnable => (SetShaderCacheControl & 0x1) != 0;
|
public bool SetShaderCacheControlIcachePrefetchEnable => (SetShaderCacheControl & 0x1) != 0;
|
||||||
public fixed uint ReservedD98[19];
|
public fixed uint ReservedD98[19];
|
||||||
public uint SetSmTimeoutInterval;
|
public uint SetSmTimeoutInterval;
|
||||||
public int SetSmTimeoutIntervalCounterBit => (int)((SetSmTimeoutInterval >> 0) & 0x3F);
|
public int SetSmTimeoutIntervalCounterBit => (int)(SetSmTimeoutInterval & 0x3F);
|
||||||
public fixed uint ReservedDE8[87];
|
public fixed uint ReservedDE8[87];
|
||||||
public uint SetSpareNoop12;
|
public uint SetSpareNoop12;
|
||||||
public uint SetSpareNoop13;
|
public uint SetSpareNoop13;
|
||||||
@@ -324,48 +324,48 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public bool InvalidateTextureHeaderCacheAllV => (InvalidateTextureHeaderCacheAll & 0x1) != 0;
|
public bool InvalidateTextureHeaderCacheAllV => (InvalidateTextureHeaderCacheAll & 0x1) != 0;
|
||||||
public fixed uint Reserved1214[29];
|
public fixed uint Reserved1214[29];
|
||||||
public uint InvalidateTextureDataCacheNoWfi;
|
public uint InvalidateTextureDataCacheNoWfi;
|
||||||
public InvalidateCacheLines InvalidateTextureDataCacheNoWfiLines => (InvalidateCacheLines)((InvalidateTextureDataCacheNoWfi >> 0) & 0x1);
|
public InvalidateCacheLines InvalidateTextureDataCacheNoWfiLines => (InvalidateCacheLines)(InvalidateTextureDataCacheNoWfi & 0x1);
|
||||||
public int InvalidateTextureDataCacheNoWfiTag => (int)((InvalidateTextureDataCacheNoWfi >> 4) & 0x3FFFFF);
|
public int InvalidateTextureDataCacheNoWfiTag => (int)((InvalidateTextureDataCacheNoWfi >> 4) & 0x3FFFFF);
|
||||||
public fixed uint Reserved128C[7];
|
public fixed uint Reserved128C[7];
|
||||||
public uint ActivatePerfSettingsForComputeContext;
|
public uint ActivatePerfSettingsForComputeContext;
|
||||||
public bool ActivatePerfSettingsForComputeContextAll => (ActivatePerfSettingsForComputeContext & 0x1) != 0;
|
public bool ActivatePerfSettingsForComputeContextAll => (ActivatePerfSettingsForComputeContext & 0x1) != 0;
|
||||||
public fixed uint Reserved12AC[33];
|
public fixed uint Reserved12AC[33];
|
||||||
public uint InvalidateSamplerCache;
|
public uint InvalidateSamplerCache;
|
||||||
public InvalidateCacheLines InvalidateSamplerCacheLines => (InvalidateCacheLines)((InvalidateSamplerCache >> 0) & 0x1);
|
public InvalidateCacheLines InvalidateSamplerCacheLines => (InvalidateCacheLines)(InvalidateSamplerCache & 0x1);
|
||||||
public int InvalidateSamplerCacheTag => (int)((InvalidateSamplerCache >> 4) & 0x3FFFFF);
|
public int InvalidateSamplerCacheTag => (int)((InvalidateSamplerCache >> 4) & 0x3FFFFF);
|
||||||
public uint InvalidateTextureHeaderCache;
|
public uint InvalidateTextureHeaderCache;
|
||||||
public InvalidateCacheLines InvalidateTextureHeaderCacheLines => (InvalidateCacheLines)((InvalidateTextureHeaderCache >> 0) & 0x1);
|
public InvalidateCacheLines InvalidateTextureHeaderCacheLines => (InvalidateCacheLines)(InvalidateTextureHeaderCache & 0x1);
|
||||||
public int InvalidateTextureHeaderCacheTag => (int)((InvalidateTextureHeaderCache >> 4) & 0x3FFFFF);
|
public int InvalidateTextureHeaderCacheTag => (int)((InvalidateTextureHeaderCache >> 4) & 0x3FFFFF);
|
||||||
public uint InvalidateTextureDataCache;
|
public uint InvalidateTextureDataCache;
|
||||||
public InvalidateCacheLines InvalidateTextureDataCacheLines => (InvalidateCacheLines)((InvalidateTextureDataCache >> 0) & 0x1);
|
public InvalidateCacheLines InvalidateTextureDataCacheLines => (InvalidateCacheLines)(InvalidateTextureDataCache & 0x1);
|
||||||
public int InvalidateTextureDataCacheTag => (int)((InvalidateTextureDataCache >> 4) & 0x3FFFFF);
|
public int InvalidateTextureDataCacheTag => (int)((InvalidateTextureDataCache >> 4) & 0x3FFFFF);
|
||||||
public fixed uint Reserved133C[58];
|
public fixed uint Reserved133C[58];
|
||||||
public uint InvalidateSamplerCacheNoWfi;
|
public uint InvalidateSamplerCacheNoWfi;
|
||||||
public InvalidateCacheLines InvalidateSamplerCacheNoWfiLines => (InvalidateCacheLines)((InvalidateSamplerCacheNoWfi >> 0) & 0x1);
|
public InvalidateCacheLines InvalidateSamplerCacheNoWfiLines => (InvalidateCacheLines)(InvalidateSamplerCacheNoWfi & 0x1);
|
||||||
public int InvalidateSamplerCacheNoWfiTag => (int)((InvalidateSamplerCacheNoWfi >> 4) & 0x3FFFFF);
|
public int InvalidateSamplerCacheNoWfiTag => (int)((InvalidateSamplerCacheNoWfi >> 4) & 0x3FFFFF);
|
||||||
public fixed uint Reserved1428[64];
|
public fixed uint Reserved1428[64];
|
||||||
public uint SetShaderExceptions;
|
public uint SetShaderExceptions;
|
||||||
public bool SetShaderExceptionsEnable => (SetShaderExceptions & 0x1) != 0;
|
public bool SetShaderExceptionsEnable => (SetShaderExceptions & 0x1) != 0;
|
||||||
public fixed uint Reserved152C[9];
|
public fixed uint Reserved152C[9];
|
||||||
public uint SetRenderEnableA;
|
public uint SetRenderEnableA;
|
||||||
public int SetRenderEnableAOffsetUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
|
public int SetRenderEnableAOffsetUpper => (int)(SetRenderEnableA & 0xFF);
|
||||||
public uint SetRenderEnableB;
|
public uint SetRenderEnableB;
|
||||||
public uint SetRenderEnableC;
|
public uint SetRenderEnableC;
|
||||||
public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
|
public int SetRenderEnableCMode => (int)(SetRenderEnableC & 0x7);
|
||||||
public uint SetTexSamplerPoolA;
|
public uint SetTexSamplerPoolA;
|
||||||
public int SetTexSamplerPoolAOffsetUpper => (int)((SetTexSamplerPoolA >> 0) & 0xFF);
|
public int SetTexSamplerPoolAOffsetUpper => (int)(SetTexSamplerPoolA & 0xFF);
|
||||||
public uint SetTexSamplerPoolB;
|
public uint SetTexSamplerPoolB;
|
||||||
public uint SetTexSamplerPoolC;
|
public uint SetTexSamplerPoolC;
|
||||||
public int SetTexSamplerPoolCMaximumIndex => (int)((SetTexSamplerPoolC >> 0) & 0xFFFFF);
|
public int SetTexSamplerPoolCMaximumIndex => (int)(SetTexSamplerPoolC & 0xFFFFF);
|
||||||
public fixed uint Reserved1568[3];
|
public fixed uint Reserved1568[3];
|
||||||
public uint SetTexHeaderPoolA;
|
public uint SetTexHeaderPoolA;
|
||||||
public int SetTexHeaderPoolAOffsetUpper => (int)((SetTexHeaderPoolA >> 0) & 0xFF);
|
public int SetTexHeaderPoolAOffsetUpper => (int)(SetTexHeaderPoolA & 0xFF);
|
||||||
public uint SetTexHeaderPoolB;
|
public uint SetTexHeaderPoolB;
|
||||||
public uint SetTexHeaderPoolC;
|
public uint SetTexHeaderPoolC;
|
||||||
public int SetTexHeaderPoolCMaximumIndex => (int)((SetTexHeaderPoolC >> 0) & 0x3FFFFF);
|
public int SetTexHeaderPoolCMaximumIndex => (int)(SetTexHeaderPoolC & 0x3FFFFF);
|
||||||
public fixed uint Reserved1580[34];
|
public fixed uint Reserved1580[34];
|
||||||
public uint SetProgramRegionA;
|
public uint SetProgramRegionA;
|
||||||
public int SetProgramRegionAAddressUpper => (int)((SetProgramRegionA >> 0) & 0xFF);
|
public int SetProgramRegionAAddressUpper => (int)(SetProgramRegionA & 0xFF);
|
||||||
public uint SetProgramRegionB;
|
public uint SetProgramRegionB;
|
||||||
public fixed uint Reserved1610[34];
|
public fixed uint Reserved1610[34];
|
||||||
public uint InvalidateShaderCachesNoWfi;
|
public uint InvalidateShaderCachesNoWfi;
|
||||||
@@ -374,7 +374,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public bool InvalidateShaderCachesNoWfiConstant => (InvalidateShaderCachesNoWfi & 0x1000) != 0;
|
public bool InvalidateShaderCachesNoWfiConstant => (InvalidateShaderCachesNoWfi & 0x1000) != 0;
|
||||||
public fixed uint Reserved169C[170];
|
public fixed uint Reserved169C[170];
|
||||||
public uint SetRenderEnableOverride;
|
public uint SetRenderEnableOverride;
|
||||||
public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)((SetRenderEnableOverride >> 0) & 0x3);
|
public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)(SetRenderEnableOverride & 0x3);
|
||||||
public fixed uint Reserved1948[57];
|
public fixed uint Reserved1948[57];
|
||||||
public uint PipeNop;
|
public uint PipeNop;
|
||||||
public uint SetSpare00;
|
public uint SetSpare00;
|
||||||
@@ -383,11 +383,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public uint SetSpare03;
|
public uint SetSpare03;
|
||||||
public fixed uint Reserved1A40[48];
|
public fixed uint Reserved1A40[48];
|
||||||
public uint SetReportSemaphoreA;
|
public uint SetReportSemaphoreA;
|
||||||
public int SetReportSemaphoreAOffsetUpper => (int)((SetReportSemaphoreA >> 0) & 0xFF);
|
public int SetReportSemaphoreAOffsetUpper => (int)(SetReportSemaphoreA & 0xFF);
|
||||||
public uint SetReportSemaphoreB;
|
public uint SetReportSemaphoreB;
|
||||||
public uint SetReportSemaphoreC;
|
public uint SetReportSemaphoreC;
|
||||||
public uint SetReportSemaphoreD;
|
public uint SetReportSemaphoreD;
|
||||||
public SetReportSemaphoreDOperation SetReportSemaphoreDOperation => (SetReportSemaphoreDOperation)((SetReportSemaphoreD >> 0) & 0x3);
|
public SetReportSemaphoreDOperation SetReportSemaphoreDOperation => (SetReportSemaphoreDOperation)(SetReportSemaphoreD & 0x3);
|
||||||
public bool SetReportSemaphoreDAwakenEnable => (SetReportSemaphoreD & 0x100000) != 0;
|
public bool SetReportSemaphoreDAwakenEnable => (SetReportSemaphoreD & 0x100000) != 0;
|
||||||
public SetReportSemaphoreDStructureSize SetReportSemaphoreDStructureSize => (SetReportSemaphoreDStructureSize)((SetReportSemaphoreD >> 28) & 0x1);
|
public SetReportSemaphoreDStructureSize SetReportSemaphoreDStructureSize => (SetReportSemaphoreDStructureSize)((SetReportSemaphoreD >> 28) & 0x1);
|
||||||
public bool SetReportSemaphoreDFlushDisable => (SetReportSemaphoreD & 0x4) != 0;
|
public bool SetReportSemaphoreDFlushDisable => (SetReportSemaphoreD & 0x4) != 0;
|
||||||
@@ -396,7 +396,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public SetReportSemaphoreDReductionFormat SetReportSemaphoreDReductionFormat => (SetReportSemaphoreDReductionFormat)((SetReportSemaphoreD >> 17) & 0x3);
|
public SetReportSemaphoreDReductionFormat SetReportSemaphoreDReductionFormat => (SetReportSemaphoreDReductionFormat)((SetReportSemaphoreD >> 17) & 0x3);
|
||||||
public fixed uint Reserved1B10[702];
|
public fixed uint Reserved1B10[702];
|
||||||
public uint SetBindlessTexture;
|
public uint SetBindlessTexture;
|
||||||
public int SetBindlessTextureConstantBufferSlotSelect => (int)((SetBindlessTexture >> 0) & 0x7);
|
public int SetBindlessTextureConstantBufferSlotSelect => (int)(SetBindlessTexture & 0x7);
|
||||||
public uint SetTrapHandler;
|
public uint SetTrapHandler;
|
||||||
public fixed uint Reserved2610[843];
|
public fixed uint Reserved2610[843];
|
||||||
public Array8<uint> SetShaderPerformanceCounterValueUpper;
|
public Array8<uint> SetShaderPerformanceCounterValueUpper;
|
||||||
@@ -423,11 +423,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
public bool SetShaderPerformanceCounterControlBWindowed(int i) => (SetShaderPerformanceCounterControlB[i] & 0x8) != 0;
|
public bool SetShaderPerformanceCounterControlBWindowed(int i) => (SetShaderPerformanceCounterControlB[i] & 0x8) != 0;
|
||||||
public int SetShaderPerformanceCounterControlBFunc(int i) => (int)((SetShaderPerformanceCounterControlB[i] >> 4) & 0xFFFF);
|
public int SetShaderPerformanceCounterControlBFunc(int i) => (int)((SetShaderPerformanceCounterControlB[i] >> 4) & 0xFFFF);
|
||||||
public uint SetShaderPerformanceCounterTrapControl;
|
public uint SetShaderPerformanceCounterTrapControl;
|
||||||
public int SetShaderPerformanceCounterTrapControlMask => (int)((SetShaderPerformanceCounterTrapControl >> 0) & 0xFF);
|
public int SetShaderPerformanceCounterTrapControlMask => (int)(SetShaderPerformanceCounterTrapControl & 0xFF);
|
||||||
public uint StartShaderPerformanceCounter;
|
public uint StartShaderPerformanceCounter;
|
||||||
public int StartShaderPerformanceCounterCounterMask => (int)((StartShaderPerformanceCounter >> 0) & 0xFF);
|
public int StartShaderPerformanceCounterCounterMask => (int)(StartShaderPerformanceCounter & 0xFF);
|
||||||
public uint StopShaderPerformanceCounter;
|
public uint StopShaderPerformanceCounter;
|
||||||
public int StopShaderPerformanceCounterCounterMask => (int)((StopShaderPerformanceCounter >> 0) & 0xFF);
|
public int StopShaderPerformanceCounterCounterMask => (int)(StopShaderPerformanceCounter & 0xFF);
|
||||||
public fixed uint Reserved33E8[6];
|
public fixed uint Reserved33E8[6];
|
||||||
public MmeShadowScratch SetMmeShadowScratch;
|
public MmeShadowScratch SetMmeShadowScratch;
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
|
@@ -186,22 +186,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
public uint PmTrigger;
|
public uint PmTrigger;
|
||||||
public fixed uint Reserved144[63];
|
public fixed uint Reserved144[63];
|
||||||
public uint SetSemaphoreA;
|
public uint SetSemaphoreA;
|
||||||
public int SetSemaphoreAUpper => (int)((SetSemaphoreA >> 0) & 0xFF);
|
public int SetSemaphoreAUpper => (int)(SetSemaphoreA & 0xFF);
|
||||||
public uint SetSemaphoreB;
|
public uint SetSemaphoreB;
|
||||||
public uint SetSemaphorePayload;
|
public uint SetSemaphorePayload;
|
||||||
public fixed uint Reserved24C[2];
|
public fixed uint Reserved24C[2];
|
||||||
public uint SetRenderEnableA;
|
public uint SetRenderEnableA;
|
||||||
public int SetRenderEnableAUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
|
public int SetRenderEnableAUpper => (int)(SetRenderEnableA & 0xFF);
|
||||||
public uint SetRenderEnableB;
|
public uint SetRenderEnableB;
|
||||||
public uint SetRenderEnableC;
|
public uint SetRenderEnableC;
|
||||||
public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
|
public int SetRenderEnableCMode => (int)(SetRenderEnableC & 0x7);
|
||||||
public uint SetSrcPhysMode;
|
public uint SetSrcPhysMode;
|
||||||
public SetPhysModeTarget SetSrcPhysModeTarget => (SetPhysModeTarget)((SetSrcPhysMode >> 0) & 0x3);
|
public SetPhysModeTarget SetSrcPhysModeTarget => (SetPhysModeTarget)(SetSrcPhysMode & 0x3);
|
||||||
public uint SetDstPhysMode;
|
public uint SetDstPhysMode;
|
||||||
public SetPhysModeTarget SetDstPhysModeTarget => (SetPhysModeTarget)((SetDstPhysMode >> 0) & 0x3);
|
public SetPhysModeTarget SetDstPhysModeTarget => (SetPhysModeTarget)(SetDstPhysMode & 0x3);
|
||||||
public fixed uint Reserved268[38];
|
public fixed uint Reserved268[38];
|
||||||
public uint LaunchDma;
|
public uint LaunchDma;
|
||||||
public LaunchDmaDataTransferType LaunchDmaDataTransferType => (LaunchDmaDataTransferType)((LaunchDma >> 0) & 0x3);
|
public LaunchDmaDataTransferType LaunchDmaDataTransferType => (LaunchDmaDataTransferType)(LaunchDma & 0x3);
|
||||||
public bool LaunchDmaFlushEnable => (LaunchDma & 0x4) != 0;
|
public bool LaunchDmaFlushEnable => (LaunchDma & 0x4) != 0;
|
||||||
public LaunchDmaSemaphoreType LaunchDmaSemaphoreType => (LaunchDmaSemaphoreType)((LaunchDma >> 3) & 0x3);
|
public LaunchDmaSemaphoreType LaunchDmaSemaphoreType => (LaunchDmaSemaphoreType)((LaunchDma >> 3) & 0x3);
|
||||||
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 5) & 0x3);
|
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 5) & 0x3);
|
||||||
@@ -218,10 +218,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
public LaunchDmaBypassL2 LaunchDmaBypassL2 => (LaunchDmaBypassL2)((LaunchDma >> 20) & 0x1);
|
public LaunchDmaBypassL2 LaunchDmaBypassL2 => (LaunchDmaBypassL2)((LaunchDma >> 20) & 0x1);
|
||||||
public fixed uint Reserved304[63];
|
public fixed uint Reserved304[63];
|
||||||
public uint OffsetInUpper;
|
public uint OffsetInUpper;
|
||||||
public int OffsetInUpperUpper => (int)((OffsetInUpper >> 0) & 0xFF);
|
public int OffsetInUpperUpper => (int)(OffsetInUpper & 0xFF);
|
||||||
public uint OffsetInLower;
|
public uint OffsetInLower;
|
||||||
public uint OffsetOutUpper;
|
public uint OffsetOutUpper;
|
||||||
public int OffsetOutUpperUpper => (int)((OffsetOutUpper >> 0) & 0xFF);
|
public int OffsetOutUpperUpper => (int)(OffsetOutUpper & 0xFF);
|
||||||
public uint OffsetOutLower;
|
public uint OffsetOutLower;
|
||||||
public uint PitchIn;
|
public uint PitchIn;
|
||||||
public uint PitchOut;
|
public uint PitchOut;
|
||||||
@@ -231,7 +231,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
public uint SetRemapConstA;
|
public uint SetRemapConstA;
|
||||||
public uint SetRemapConstB;
|
public uint SetRemapConstB;
|
||||||
public uint SetRemapComponents;
|
public uint SetRemapComponents;
|
||||||
public SetRemapComponentsDst SetRemapComponentsDstX => (SetRemapComponentsDst)((SetRemapComponents >> 0) & 0x7);
|
public SetRemapComponentsDst SetRemapComponentsDstX => (SetRemapComponentsDst)(SetRemapComponents & 0x7);
|
||||||
public SetRemapComponentsDst SetRemapComponentsDstY => (SetRemapComponentsDst)((SetRemapComponents >> 4) & 0x7);
|
public SetRemapComponentsDst SetRemapComponentsDstY => (SetRemapComponentsDst)((SetRemapComponents >> 4) & 0x7);
|
||||||
public SetRemapComponentsDst SetRemapComponentsDstZ => (SetRemapComponentsDst)((SetRemapComponents >> 8) & 0x7);
|
public SetRemapComponentsDst SetRemapComponentsDstZ => (SetRemapComponentsDst)((SetRemapComponents >> 8) & 0x7);
|
||||||
public SetRemapComponentsDst SetRemapComponentsDstW => (SetRemapComponentsDst)((SetRemapComponents >> 12) & 0x7);
|
public SetRemapComponentsDst SetRemapComponentsDstW => (SetRemapComponentsDst)((SetRemapComponents >> 12) & 0x7);
|
||||||
@@ -239,7 +239,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
public SetRemapComponentsNumComponents SetRemapComponentsNumSrcComponents => (SetRemapComponentsNumComponents)((SetRemapComponents >> 20) & 0x3);
|
public SetRemapComponentsNumComponents SetRemapComponentsNumSrcComponents => (SetRemapComponentsNumComponents)((SetRemapComponents >> 20) & 0x3);
|
||||||
public SetRemapComponentsNumComponents SetRemapComponentsNumDstComponents => (SetRemapComponentsNumComponents)((SetRemapComponents >> 24) & 0x3);
|
public SetRemapComponentsNumComponents SetRemapComponentsNumDstComponents => (SetRemapComponentsNumComponents)((SetRemapComponents >> 24) & 0x3);
|
||||||
public uint SetDstBlockSize;
|
public uint SetDstBlockSize;
|
||||||
public SetBlockSizeWidth SetDstBlockSizeWidth => (SetBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
|
public SetBlockSizeWidth SetDstBlockSizeWidth => (SetBlockSizeWidth)(SetDstBlockSize & 0xF);
|
||||||
public SetBlockSizeHeight SetDstBlockSizeHeight => (SetBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
public SetBlockSizeHeight SetDstBlockSizeHeight => (SetBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
||||||
public SetBlockSizeDepth SetDstBlockSizeDepth => (SetBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
public SetBlockSizeDepth SetDstBlockSizeDepth => (SetBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
||||||
public SetBlockSizeGobHeight SetDstBlockSizeGobHeight => (SetBlockSizeGobHeight)((SetDstBlockSize >> 12) & 0xF);
|
public SetBlockSizeGobHeight SetDstBlockSizeGobHeight => (SetBlockSizeGobHeight)((SetDstBlockSize >> 12) & 0xF);
|
||||||
@@ -248,11 +248,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
public uint SetDstDepth;
|
public uint SetDstDepth;
|
||||||
public uint SetDstLayer;
|
public uint SetDstLayer;
|
||||||
public uint SetDstOrigin;
|
public uint SetDstOrigin;
|
||||||
public int SetDstOriginX => (int)((SetDstOrigin >> 0) & 0xFFFF);
|
public int SetDstOriginX => (int)(SetDstOrigin & 0xFFFF);
|
||||||
public int SetDstOriginY => (int)((SetDstOrigin >> 16) & 0xFFFF);
|
public int SetDstOriginY => (int)((SetDstOrigin >> 16) & 0xFFFF);
|
||||||
public uint Reserved724;
|
public uint Reserved724;
|
||||||
public uint SetSrcBlockSize;
|
public uint SetSrcBlockSize;
|
||||||
public SetBlockSizeWidth SetSrcBlockSizeWidth => (SetBlockSizeWidth)((SetSrcBlockSize >> 0) & 0xF);
|
public SetBlockSizeWidth SetSrcBlockSizeWidth => (SetBlockSizeWidth)(SetSrcBlockSize & 0xF);
|
||||||
public SetBlockSizeHeight SetSrcBlockSizeHeight => (SetBlockSizeHeight)((SetSrcBlockSize >> 4) & 0xF);
|
public SetBlockSizeHeight SetSrcBlockSizeHeight => (SetBlockSizeHeight)((SetSrcBlockSize >> 4) & 0xF);
|
||||||
public SetBlockSizeDepth SetSrcBlockSizeDepth => (SetBlockSizeDepth)((SetSrcBlockSize >> 8) & 0xF);
|
public SetBlockSizeDepth SetSrcBlockSizeDepth => (SetBlockSizeDepth)((SetSrcBlockSize >> 8) & 0xF);
|
||||||
public SetBlockSizeGobHeight SetSrcBlockSizeGobHeight => (SetBlockSizeGobHeight)((SetSrcBlockSize >> 12) & 0xF);
|
public SetBlockSizeGobHeight SetSrcBlockSizeGobHeight => (SetBlockSizeGobHeight)((SetSrcBlockSize >> 12) & 0xF);
|
||||||
@@ -261,7 +261,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
public uint SetSrcDepth;
|
public uint SetSrcDepth;
|
||||||
public uint SetSrcLayer;
|
public uint SetSrcLayer;
|
||||||
public uint SetSrcOrigin;
|
public uint SetSrcOrigin;
|
||||||
public int SetSrcOriginX => (int)((SetSrcOrigin >> 0) & 0xFFFF);
|
public int SetSrcOriginX => (int)(SetSrcOrigin & 0xFFFF);
|
||||||
public int SetSrcOriginY => (int)((SetSrcOrigin >> 16) & 0xFFFF);
|
public int SetSrcOriginY => (int)((SetSrcOrigin >> 16) & 0xFFFF);
|
||||||
public fixed uint Reserved740[629];
|
public fixed uint Reserved740[629];
|
||||||
public uint PmTriggerEnd;
|
public uint PmTriggerEnd;
|
||||||
|
@@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||||||
public uint Method;
|
public uint Method;
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
public int MethodAddressOld => (int)((Method >> 2) & 0x7FF);
|
public int MethodAddressOld => (int)((Method >> 2) & 0x7FF);
|
||||||
public int MethodAddress => (int)((Method >> 0) & 0xFFF);
|
public int MethodAddress => (int)(Method & 0xFFF);
|
||||||
public int SubdeviceMask => (int)((Method >> 4) & 0xFFF);
|
public int SubdeviceMask => (int)((Method >> 4) & 0xFFF);
|
||||||
public int MethodSubchannel => (int)((Method >> 13) & 0x7);
|
public int MethodSubchannel => (int)((Method >> 13) & 0x7);
|
||||||
public TertOp TertOp => (TertOp)((Method >> 16) & 0x3);
|
public TertOp TertOp => (TertOp)((Method >> 16) & 0x3);
|
||||||
|
@@ -39,17 +39,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
public uint Entry0;
|
public uint Entry0;
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
public Entry0Fetch Entry0Fetch => (Entry0Fetch)((Entry0 >> 0) & 0x1);
|
public Entry0Fetch Entry0Fetch => (Entry0Fetch)(Entry0 & 0x1);
|
||||||
public int Entry0Get => (int)((Entry0 >> 2) & 0x3FFFFFFF);
|
public int Entry0Get => (int)((Entry0 >> 2) & 0x3FFFFFFF);
|
||||||
public int Entry0Operand => (int)(Entry0);
|
public int Entry0Operand => (int)(Entry0);
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
public uint Entry1;
|
public uint Entry1;
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
public int Entry1GetHi => (int)((Entry1 >> 0) & 0xFF);
|
public int Entry1GetHi => (int)(Entry1 & 0xFF);
|
||||||
public Entry1Priv Entry1Priv => (Entry1Priv)((Entry1 >> 8) & 0x1);
|
public Entry1Priv Entry1Priv => (Entry1Priv)((Entry1 >> 8) & 0x1);
|
||||||
public Entry1Level Entry1Level => (Entry1Level)((Entry1 >> 9) & 0x1);
|
public Entry1Level Entry1Level => (Entry1Level)((Entry1 >> 9) & 0x1);
|
||||||
public int Entry1Length => (int)((Entry1 >> 10) & 0x1FFFFF);
|
public int Entry1Length => (int)((Entry1 >> 10) & 0x1FFFFF);
|
||||||
public Entry1Sync Entry1Sync => (Entry1Sync)((Entry1 >> 31) & 0x1);
|
public Entry1Sync Entry1Sync => (Entry1Sync)((Entry1 >> 31) & 0x1);
|
||||||
public Entry1Opcode Entry1Opcode => (Entry1Opcode)((Entry1 >> 0) & 0xFF);
|
public Entry1Opcode Entry1Opcode => (Entry1Opcode)(Entry1 & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -153,7 +153,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
public uint SetObject;
|
public uint SetObject;
|
||||||
public int SetObjectNvclass => (int)((SetObject >> 0) & 0xFFFF);
|
public int SetObjectNvclass => (int)(SetObject & 0xFFFF);
|
||||||
public int SetObjectEngine => (int)((SetObject >> 16) & 0x1F);
|
public int SetObjectEngine => (int)((SetObject >> 16) & 0x1F);
|
||||||
public uint Illegal;
|
public uint Illegal;
|
||||||
public int IllegalHandle => (int)(Illegal);
|
public int IllegalHandle => (int)(Illegal);
|
||||||
@@ -161,13 +161,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||||||
public int NopHandle => (int)(Nop);
|
public int NopHandle => (int)(Nop);
|
||||||
public uint Reserved0C;
|
public uint Reserved0C;
|
||||||
public uint Semaphorea;
|
public uint Semaphorea;
|
||||||
public int SemaphoreaOffsetUpper => (int)((Semaphorea >> 0) & 0xFF);
|
public int SemaphoreaOffsetUpper => (int)(Semaphorea & 0xFF);
|
||||||
public uint Semaphoreb;
|
public uint Semaphoreb;
|
||||||
public int SemaphorebOffsetLower => (int)((Semaphoreb >> 2) & 0x3FFFFFFF);
|
public int SemaphorebOffsetLower => (int)((Semaphoreb >> 2) & 0x3FFFFFFF);
|
||||||
public uint Semaphorec;
|
public uint Semaphorec;
|
||||||
public int SemaphorecPayload => (int)(Semaphorec);
|
public int SemaphorecPayload => (int)(Semaphorec);
|
||||||
public uint Semaphored;
|
public uint Semaphored;
|
||||||
public SemaphoredOperation SemaphoredOperation => (SemaphoredOperation)((Semaphored >> 0) & 0x1F);
|
public SemaphoredOperation SemaphoredOperation => (SemaphoredOperation)(Semaphored & 0x1F);
|
||||||
public SemaphoredAcquireSwitch SemaphoredAcquireSwitch => (SemaphoredAcquireSwitch)((Semaphored >> 12) & 0x1);
|
public SemaphoredAcquireSwitch SemaphoredAcquireSwitch => (SemaphoredAcquireSwitch)((Semaphored >> 12) & 0x1);
|
||||||
public SemaphoredReleaseWfi SemaphoredReleaseWfi => (SemaphoredReleaseWfi)((Semaphored >> 20) & 0x1);
|
public SemaphoredReleaseWfi SemaphoredReleaseWfi => (SemaphoredReleaseWfi)((Semaphored >> 20) & 0x1);
|
||||||
public SemaphoredReleaseSize SemaphoredReleaseSize => (SemaphoredReleaseSize)((Semaphored >> 24) & 0x1);
|
public SemaphoredReleaseSize SemaphoredReleaseSize => (SemaphoredReleaseSize)((Semaphored >> 24) & 0x1);
|
||||||
@@ -181,14 +181,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||||||
public uint Reserved2C;
|
public uint Reserved2C;
|
||||||
public uint MemOpC;
|
public uint MemOpC;
|
||||||
public int MemOpCOperandLow => (int)((MemOpC >> 2) & 0x3FFFFFFF);
|
public int MemOpCOperandLow => (int)((MemOpC >> 2) & 0x3FFFFFFF);
|
||||||
public MemOpCTlbInvalidatePdb MemOpCTlbInvalidatePdb => (MemOpCTlbInvalidatePdb)((MemOpC >> 0) & 0x1);
|
public MemOpCTlbInvalidatePdb MemOpCTlbInvalidatePdb => (MemOpCTlbInvalidatePdb)(MemOpC & 0x1);
|
||||||
public MemOpCTlbInvalidateGpc MemOpCTlbInvalidateGpc => (MemOpCTlbInvalidateGpc)((MemOpC >> 1) & 0x1);
|
public MemOpCTlbInvalidateGpc MemOpCTlbInvalidateGpc => (MemOpCTlbInvalidateGpc)((MemOpC >> 1) & 0x1);
|
||||||
public MemOpCTlbInvalidateTarget MemOpCTlbInvalidateTarget => (MemOpCTlbInvalidateTarget)((MemOpC >> 10) & 0x3);
|
public MemOpCTlbInvalidateTarget MemOpCTlbInvalidateTarget => (MemOpCTlbInvalidateTarget)((MemOpC >> 10) & 0x3);
|
||||||
public int MemOpCTlbInvalidateAddrLo => (int)((MemOpC >> 12) & 0xFFFFF);
|
public int MemOpCTlbInvalidateAddrLo => (int)((MemOpC >> 12) & 0xFFFFF);
|
||||||
public uint MemOpD;
|
public uint MemOpD;
|
||||||
public int MemOpDOperandHigh => (int)((MemOpD >> 0) & 0xFF);
|
public int MemOpDOperandHigh => (int)(MemOpD & 0xFF);
|
||||||
public MemOpDOperation MemOpDOperation => (MemOpDOperation)((MemOpD >> 27) & 0x1F);
|
public MemOpDOperation MemOpDOperation => (MemOpDOperation)((MemOpD >> 27) & 0x1F);
|
||||||
public int MemOpDTlbInvalidateAddrHi => (int)((MemOpD >> 0) & 0xFF);
|
public int MemOpDTlbInvalidateAddrHi => (int)(MemOpD & 0xFF);
|
||||||
public uint Reserved38;
|
public uint Reserved38;
|
||||||
public uint Reserved3C;
|
public uint Reserved3C;
|
||||||
public uint Reserved40;
|
public uint Reserved40;
|
||||||
@@ -207,15 +207,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||||||
public uint Syncpointa;
|
public uint Syncpointa;
|
||||||
public int SyncpointaPayload => (int)(Syncpointa);
|
public int SyncpointaPayload => (int)(Syncpointa);
|
||||||
public uint Syncpointb;
|
public uint Syncpointb;
|
||||||
public SyncpointbOperation SyncpointbOperation => (SyncpointbOperation)((Syncpointb >> 0) & 0x1);
|
public SyncpointbOperation SyncpointbOperation => (SyncpointbOperation)(Syncpointb & 0x1);
|
||||||
public SyncpointbWaitSwitch SyncpointbWaitSwitch => (SyncpointbWaitSwitch)((Syncpointb >> 4) & 0x1);
|
public SyncpointbWaitSwitch SyncpointbWaitSwitch => (SyncpointbWaitSwitch)((Syncpointb >> 4) & 0x1);
|
||||||
public int SyncpointbSyncptIndex => (int)((Syncpointb >> 8) & 0xFFF);
|
public int SyncpointbSyncptIndex => (int)((Syncpointb >> 8) & 0xFFF);
|
||||||
public uint Wfi;
|
public uint Wfi;
|
||||||
public WfiScope WfiScope => (WfiScope)((Wfi >> 0) & 0x1);
|
public WfiScope WfiScope => (WfiScope)(Wfi & 0x1);
|
||||||
public uint CrcCheck;
|
public uint CrcCheck;
|
||||||
public int CrcCheckValue => (int)(CrcCheck);
|
public int CrcCheckValue => (int)(CrcCheck);
|
||||||
public uint Yield;
|
public uint Yield;
|
||||||
public YieldOp YieldOp => (YieldOp)((Yield >> 0) & 0x3);
|
public YieldOp YieldOp => (YieldOp)(Yield & 0x3);
|
||||||
// TODO: Eventually move this to per-engine state.
|
// TODO: Eventually move this to per-engine state.
|
||||||
public Array31<uint> Reserved84;
|
public Array31<uint> Reserved84;
|
||||||
public uint NoOperation;
|
public uint NoOperation;
|
||||||
|
@@ -113,22 +113,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
public uint SetObject;
|
public uint SetObject;
|
||||||
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
|
public int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||||
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||||
public fixed uint Reserved04[63];
|
public fixed uint Reserved04[63];
|
||||||
public uint NoOperation;
|
public uint NoOperation;
|
||||||
public uint SetNotifyA;
|
public uint SetNotifyA;
|
||||||
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
|
public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0xFF);
|
||||||
public uint SetNotifyB;
|
public uint SetNotifyB;
|
||||||
public uint Notify;
|
public uint Notify;
|
||||||
public NotifyType NotifyType => (NotifyType)(Notify);
|
public NotifyType NotifyType => (NotifyType)(Notify);
|
||||||
public uint WaitForIdle;
|
public uint WaitForIdle;
|
||||||
public fixed uint Reserved114[7];
|
public fixed uint Reserved114[7];
|
||||||
public uint SetGlobalRenderEnableA;
|
public uint SetGlobalRenderEnableA;
|
||||||
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
|
public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
|
||||||
public uint SetGlobalRenderEnableB;
|
public uint SetGlobalRenderEnableB;
|
||||||
public uint SetGlobalRenderEnableC;
|
public uint SetGlobalRenderEnableC;
|
||||||
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
|
public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
|
||||||
public uint SendGoIdle;
|
public uint SendGoIdle;
|
||||||
public uint PmTrigger;
|
public uint PmTrigger;
|
||||||
public uint PmTriggerWfi;
|
public uint PmTriggerWfi;
|
||||||
@@ -139,11 +139,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||||||
public uint LineLengthIn;
|
public uint LineLengthIn;
|
||||||
public uint LineCount;
|
public uint LineCount;
|
||||||
public uint OffsetOutUpper;
|
public uint OffsetOutUpper;
|
||||||
public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
|
public int OffsetOutUpperValue => (int)(OffsetOutUpper & 0xFF);
|
||||||
public uint OffsetOut;
|
public uint OffsetOut;
|
||||||
public uint PitchOut;
|
public uint PitchOut;
|
||||||
public uint SetDstBlockSize;
|
public uint SetDstBlockSize;
|
||||||
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
|
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)(SetDstBlockSize & 0xF);
|
||||||
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
||||||
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
||||||
public uint SetDstWidth;
|
public uint SetDstWidth;
|
||||||
@@ -151,11 +151,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||||||
public uint SetDstDepth;
|
public uint SetDstDepth;
|
||||||
public uint SetDstLayer;
|
public uint SetDstLayer;
|
||||||
public uint SetDstOriginBytesX;
|
public uint SetDstOriginBytesX;
|
||||||
public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
|
public int SetDstOriginBytesXV => (int)(SetDstOriginBytesX & 0xFFFFF);
|
||||||
public uint SetDstOriginSamplesY;
|
public uint SetDstOriginSamplesY;
|
||||||
public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
|
public int SetDstOriginSamplesYV => (int)(SetDstOriginSamplesY & 0xFFFF);
|
||||||
public uint LaunchDma;
|
public uint LaunchDma;
|
||||||
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
|
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)(LaunchDma & 0x1);
|
||||||
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
|
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
|
||||||
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
|
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
|
||||||
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
|
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
|
||||||
@@ -166,7 +166,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||||||
public uint LoadInlineData;
|
public uint LoadInlineData;
|
||||||
public fixed uint Reserved1B8[9];
|
public fixed uint Reserved1B8[9];
|
||||||
public uint SetI2mSemaphoreA;
|
public uint SetI2mSemaphoreA;
|
||||||
public int SetI2mSemaphoreAOffsetUpper => (int)((SetI2mSemaphoreA >> 0) & 0xFF);
|
public int SetI2mSemaphoreAOffsetUpper => (int)(SetI2mSemaphoreA & 0xFF);
|
||||||
public uint SetI2mSemaphoreB;
|
public uint SetI2mSemaphoreB;
|
||||||
public uint SetI2mSemaphoreC;
|
public uint SetI2mSemaphoreC;
|
||||||
public fixed uint Reserved1E8[2];
|
public fixed uint Reserved1E8[2];
|
||||||
|
@@ -539,6 +539,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
|
|
||||||
engine.UpdateState();
|
engine.UpdateState();
|
||||||
|
|
||||||
|
if (instanceCount > 1)
|
||||||
|
{
|
||||||
|
// Must be called after UpdateState as it assumes the shader state
|
||||||
|
// has already been set, and that bindings have been updated already.
|
||||||
|
|
||||||
|
_channel.BufferManager.SetInstancedDrawVertexCount(count);
|
||||||
|
}
|
||||||
|
|
||||||
if (indexed)
|
if (indexed)
|
||||||
{
|
{
|
||||||
_context.Renderer.Pipeline.DrawIndexed(count, instanceCount, firstIndex, firstVertex, firstInstance);
|
_context.Renderer.Pipeline.DrawIndexed(count, instanceCount, firstIndex, firstVertex, firstInstance);
|
||||||
@@ -676,6 +684,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
_channel.BufferManager.SetIndexBuffer(br, IndexType.UInt);
|
_channel.BufferManager.SetIndexBuffer(br, IndexType.UInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_channel.BufferManager.SetInstancedDrawVertexCount(_instancedIndexCount);
|
||||||
|
|
||||||
_context.Renderer.Pipeline.DrawIndexed(
|
_context.Renderer.Pipeline.DrawIndexed(
|
||||||
_instancedIndexCount,
|
_instancedIndexCount,
|
||||||
_instanceIndex + 1,
|
_instanceIndex + 1,
|
||||||
@@ -685,6 +695,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
_channel.BufferManager.SetInstancedDrawVertexCount(_instancedDrawStateCount);
|
||||||
|
|
||||||
_context.Renderer.Pipeline.Draw(
|
_context.Renderer.Pipeline.Draw(
|
||||||
_instancedDrawStateCount,
|
_instancedDrawStateCount,
|
||||||
_instanceIndex + 1,
|
_instanceIndex + 1,
|
||||||
|
@@ -269,7 +269,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
_prevFirstVertex = _state.State.FirstVertex;
|
_prevFirstVertex = _state.State.FirstVertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tfEnable = _state.State.TfEnable;
|
bool tfEnable = _state.State.TfEnable && _context.Capabilities.SupportsTransformFeedback;
|
||||||
|
|
||||||
if (!tfEnable && _prevTfEnable)
|
if (!tfEnable && _prevTfEnable)
|
||||||
{
|
{
|
||||||
@@ -1367,6 +1367,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
_vsUsesDrawParameters = gs.Shaders[1]?.Info.UsesDrawParameters ?? false;
|
_vsUsesDrawParameters = gs.Shaders[1]?.Info.UsesDrawParameters ?? false;
|
||||||
_vsClipDistancesWritten = gs.Shaders[1]?.Info.ClipDistancesWritten ?? 0;
|
_vsClipDistancesWritten = gs.Shaders[1]?.Info.ClipDistancesWritten ?? 0;
|
||||||
|
|
||||||
|
bool hasTransformFeedback = gs.SpecializationState.TransformFeedbackDescriptors != null;
|
||||||
|
if (hasTransformFeedback != _channel.BufferManager.HasTransformFeedbackOutputs)
|
||||||
|
{
|
||||||
|
if (!_context.Capabilities.SupportsTransformFeedback)
|
||||||
|
{
|
||||||
|
// If host does not support transform feedback, and the shader changed,
|
||||||
|
// we might need to update bindings as transform feedback emulation
|
||||||
|
// uses storage buffer bindings that might have been used for something
|
||||||
|
// else in a previous draw.
|
||||||
|
|
||||||
|
_channel.BufferManager.ForceTransformFeedbackAndStorageBuffersDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
_channel.BufferManager.HasTransformFeedbackOutputs = hasTransformFeedback;
|
||||||
|
}
|
||||||
|
|
||||||
if (oldVsClipDistancesWritten != _vsClipDistancesWritten)
|
if (oldVsClipDistancesWritten != _vsClipDistancesWritten)
|
||||||
{
|
{
|
||||||
UpdateUserClipState();
|
UpdateUserClipState();
|
||||||
|
@@ -746,12 +746,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
public uint SetObject;
|
public uint SetObject;
|
||||||
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
|
public int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||||
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||||
public fixed uint Reserved04[63];
|
public fixed uint Reserved04[63];
|
||||||
public uint NoOperation;
|
public uint NoOperation;
|
||||||
public uint SetNotifyA;
|
public uint SetNotifyA;
|
||||||
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
|
public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0xFF);
|
||||||
public uint SetNotifyB;
|
public uint SetNotifyB;
|
||||||
public uint Notify;
|
public uint Notify;
|
||||||
public NotifyType NotifyType => (NotifyType)(Notify);
|
public NotifyType NotifyType => (NotifyType)(Notify);
|
||||||
@@ -761,13 +761,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
public uint LoadMmeStartAddressRamPointer;
|
public uint LoadMmeStartAddressRamPointer;
|
||||||
public uint LoadMmeStartAddressRam;
|
public uint LoadMmeStartAddressRam;
|
||||||
public uint SetMmeShadowRamControl;
|
public uint SetMmeShadowRamControl;
|
||||||
public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)((SetMmeShadowRamControl >> 0) & 0x3);
|
public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)(SetMmeShadowRamControl & 0x3);
|
||||||
public fixed uint Reserved128[2];
|
public fixed uint Reserved128[2];
|
||||||
public uint SetGlobalRenderEnableA;
|
public uint SetGlobalRenderEnableA;
|
||||||
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
|
public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
|
||||||
public uint SetGlobalRenderEnableB;
|
public uint SetGlobalRenderEnableB;
|
||||||
public uint SetGlobalRenderEnableC;
|
public uint SetGlobalRenderEnableC;
|
||||||
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
|
public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
|
||||||
public uint SendGoIdle;
|
public uint SendGoIdle;
|
||||||
public uint PmTrigger;
|
public uint PmTrigger;
|
||||||
public uint PmTriggerWfi;
|
public uint PmTriggerWfi;
|
||||||
@@ -778,11 +778,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
public uint LineLengthIn;
|
public uint LineLengthIn;
|
||||||
public uint LineCount;
|
public uint LineCount;
|
||||||
public uint OffsetOutUpper;
|
public uint OffsetOutUpper;
|
||||||
public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
|
public int OffsetOutUpperValue => (int)(OffsetOutUpper & 0xFF);
|
||||||
public uint OffsetOut;
|
public uint OffsetOut;
|
||||||
public uint PitchOut;
|
public uint PitchOut;
|
||||||
public uint SetDstBlockSize;
|
public uint SetDstBlockSize;
|
||||||
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
|
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)(SetDstBlockSize & 0xF);
|
||||||
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
||||||
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
||||||
public uint SetDstWidth;
|
public uint SetDstWidth;
|
||||||
@@ -790,11 +790,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
public uint SetDstDepth;
|
public uint SetDstDepth;
|
||||||
public uint SetDstLayer;
|
public uint SetDstLayer;
|
||||||
public uint SetDstOriginBytesX;
|
public uint SetDstOriginBytesX;
|
||||||
public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
|
public int SetDstOriginBytesXV => (int)(SetDstOriginBytesX & 0xFFFFF);
|
||||||
public uint SetDstOriginSamplesY;
|
public uint SetDstOriginSamplesY;
|
||||||
public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
|
public int SetDstOriginSamplesYV => (int)(SetDstOriginSamplesY & 0xFFFF);
|
||||||
public uint LaunchDma;
|
public uint LaunchDma;
|
||||||
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
|
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)(LaunchDma & 0x1);
|
||||||
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
|
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
|
||||||
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
|
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
|
||||||
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
|
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
|
||||||
|
@@ -499,12 +499,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
public uint SetObject;
|
public uint SetObject;
|
||||||
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
|
public int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||||
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||||
public fixed uint Reserved04[63];
|
public fixed uint Reserved04[63];
|
||||||
public uint NoOperation;
|
public uint NoOperation;
|
||||||
public uint SetNotifyA;
|
public uint SetNotifyA;
|
||||||
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0x1FFFFFF);
|
public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0x1FFFFFF);
|
||||||
public uint SetNotifyB;
|
public uint SetNotifyB;
|
||||||
public uint Notify;
|
public uint Notify;
|
||||||
public NotifyType NotifyType => (NotifyType)(Notify);
|
public NotifyType NotifyType => (NotifyType)(Notify);
|
||||||
@@ -514,13 +514,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||||||
public uint LoadMmeStartAddressRamPointer;
|
public uint LoadMmeStartAddressRamPointer;
|
||||||
public uint LoadMmeStartAddressRam;
|
public uint LoadMmeStartAddressRam;
|
||||||
public uint SetMmeShadowRamControl;
|
public uint SetMmeShadowRamControl;
|
||||||
public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)((SetMmeShadowRamControl >> 0) & 0x3);
|
public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)(SetMmeShadowRamControl & 0x3);
|
||||||
public fixed uint Reserved128[2];
|
public fixed uint Reserved128[2];
|
||||||
public uint SetGlobalRenderEnableA;
|
public uint SetGlobalRenderEnableA;
|
||||||
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
|
public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
|
||||||
public uint SetGlobalRenderEnableB;
|
public uint SetGlobalRenderEnableB;
|
||||||
public uint SetGlobalRenderEnableC;
|
public uint SetGlobalRenderEnableC;
|
||||||
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
|
public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
|
||||||
public uint SendGoIdle;
|
public uint SendGoIdle;
|
||||||
public uint PmTrigger;
|
public uint PmTrigger;
|
||||||
public fixed uint Reserved144[3];
|
public fixed uint Reserved144[3];
|
||||||
@@ -533,9 +533,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||||||
public int SetMmeSwitchStateRestoreMacro => (int)((SetMmeSwitchState >> 12) & 0xFF);
|
public int SetMmeSwitchStateRestoreMacro => (int)((SetMmeSwitchState >> 12) & 0xFF);
|
||||||
public fixed uint Reserved1F0[4];
|
public fixed uint Reserved1F0[4];
|
||||||
public uint SetDstFormat;
|
public uint SetDstFormat;
|
||||||
public SetDstFormatV SetDstFormatV => (SetDstFormatV)((SetDstFormat >> 0) & 0xFF);
|
public SetDstFormatV SetDstFormatV => (SetDstFormatV)(SetDstFormat & 0xFF);
|
||||||
public uint SetDstMemoryLayout;
|
public uint SetDstMemoryLayout;
|
||||||
public SetDstMemoryLayoutV SetDstMemoryLayoutV => (SetDstMemoryLayoutV)((SetDstMemoryLayout >> 0) & 0x1);
|
public SetDstMemoryLayoutV SetDstMemoryLayoutV => (SetDstMemoryLayoutV)(SetDstMemoryLayout & 0x1);
|
||||||
public uint SetDstBlockSize;
|
public uint SetDstBlockSize;
|
||||||
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0x7);
|
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0x7);
|
||||||
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0x7);
|
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0x7);
|
||||||
@@ -545,37 +545,37 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||||||
public uint SetDstWidth;
|
public uint SetDstWidth;
|
||||||
public uint SetDstHeight;
|
public uint SetDstHeight;
|
||||||
public uint SetDstOffsetUpper;
|
public uint SetDstOffsetUpper;
|
||||||
public int SetDstOffsetUpperV => (int)((SetDstOffsetUpper >> 0) & 0xFF);
|
public int SetDstOffsetUpperV => (int)(SetDstOffsetUpper & 0xFF);
|
||||||
public uint SetDstOffsetLower;
|
public uint SetDstOffsetLower;
|
||||||
public uint FlushAndInvalidateRopMiniCache;
|
public uint FlushAndInvalidateRopMiniCache;
|
||||||
public bool FlushAndInvalidateRopMiniCacheV => (FlushAndInvalidateRopMiniCache & 0x1) != 0;
|
public bool FlushAndInvalidateRopMiniCacheV => (FlushAndInvalidateRopMiniCache & 0x1) != 0;
|
||||||
public uint SetSpareNoop06;
|
public uint SetSpareNoop06;
|
||||||
public uint SetSrcFormat;
|
public uint SetSrcFormat;
|
||||||
public SetSrcFormatV SetSrcFormatV => (SetSrcFormatV)((SetSrcFormat >> 0) & 0xFF);
|
public SetSrcFormatV SetSrcFormatV => (SetSrcFormatV)(SetSrcFormat & 0xFF);
|
||||||
public uint SetSrcMemoryLayout;
|
public uint SetSrcMemoryLayout;
|
||||||
public SetSrcMemoryLayoutV SetSrcMemoryLayoutV => (SetSrcMemoryLayoutV)((SetSrcMemoryLayout >> 0) & 0x1);
|
public SetSrcMemoryLayoutV SetSrcMemoryLayoutV => (SetSrcMemoryLayoutV)(SetSrcMemoryLayout & 0x1);
|
||||||
public uint SetSrcBlockSize;
|
public uint SetSrcBlockSize;
|
||||||
public SetSrcBlockSizeHeight SetSrcBlockSizeHeight => (SetSrcBlockSizeHeight)((SetSrcBlockSize >> 4) & 0x7);
|
public SetSrcBlockSizeHeight SetSrcBlockSizeHeight => (SetSrcBlockSizeHeight)((SetSrcBlockSize >> 4) & 0x7);
|
||||||
public SetSrcBlockSizeDepth SetSrcBlockSizeDepth => (SetSrcBlockSizeDepth)((SetSrcBlockSize >> 8) & 0x7);
|
public SetSrcBlockSizeDepth SetSrcBlockSizeDepth => (SetSrcBlockSizeDepth)((SetSrcBlockSize >> 8) & 0x7);
|
||||||
public uint SetSrcDepth;
|
public uint SetSrcDepth;
|
||||||
public uint TwodInvalidateTextureDataCache;
|
public uint TwodInvalidateTextureDataCache;
|
||||||
public TwodInvalidateTextureDataCacheV TwodInvalidateTextureDataCacheV => (TwodInvalidateTextureDataCacheV)((TwodInvalidateTextureDataCache >> 0) & 0x3);
|
public TwodInvalidateTextureDataCacheV TwodInvalidateTextureDataCacheV => (TwodInvalidateTextureDataCacheV)(TwodInvalidateTextureDataCache & 0x3);
|
||||||
public uint SetSrcPitch;
|
public uint SetSrcPitch;
|
||||||
public uint SetSrcWidth;
|
public uint SetSrcWidth;
|
||||||
public uint SetSrcHeight;
|
public uint SetSrcHeight;
|
||||||
public uint SetSrcOffsetUpper;
|
public uint SetSrcOffsetUpper;
|
||||||
public int SetSrcOffsetUpperV => (int)((SetSrcOffsetUpper >> 0) & 0xFF);
|
public int SetSrcOffsetUpperV => (int)(SetSrcOffsetUpper & 0xFF);
|
||||||
public uint SetSrcOffsetLower;
|
public uint SetSrcOffsetLower;
|
||||||
public uint SetPixelsFromMemorySectorPromotion;
|
public uint SetPixelsFromMemorySectorPromotion;
|
||||||
public SetPixelsFromMemorySectorPromotionV SetPixelsFromMemorySectorPromotionV => (SetPixelsFromMemorySectorPromotionV)((SetPixelsFromMemorySectorPromotion >> 0) & 0x3);
|
public SetPixelsFromMemorySectorPromotionV SetPixelsFromMemorySectorPromotionV => (SetPixelsFromMemorySectorPromotionV)(SetPixelsFromMemorySectorPromotion & 0x3);
|
||||||
public uint SetSpareNoop12;
|
public uint SetSpareNoop12;
|
||||||
public uint SetNumProcessingClusters;
|
public uint SetNumProcessingClusters;
|
||||||
public SetNumProcessingClustersV SetNumProcessingClustersV => (SetNumProcessingClustersV)((SetNumProcessingClusters >> 0) & 0x1);
|
public SetNumProcessingClustersV SetNumProcessingClustersV => (SetNumProcessingClustersV)(SetNumProcessingClusters & 0x1);
|
||||||
public uint SetRenderEnableA;
|
public uint SetRenderEnableA;
|
||||||
public int SetRenderEnableAOffsetUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
|
public int SetRenderEnableAOffsetUpper => (int)(SetRenderEnableA & 0xFF);
|
||||||
public uint SetRenderEnableB;
|
public uint SetRenderEnableB;
|
||||||
public uint SetRenderEnableC;
|
public uint SetRenderEnableC;
|
||||||
public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
|
public int SetRenderEnableCMode => (int)(SetRenderEnableC & 0x7);
|
||||||
public uint SetSpareNoop08;
|
public uint SetSpareNoop08;
|
||||||
public uint SetSpareNoop01;
|
public uint SetSpareNoop01;
|
||||||
public uint SetSpareNoop11;
|
public uint SetSpareNoop11;
|
||||||
@@ -587,25 +587,25 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||||||
public uint SetClipEnable;
|
public uint SetClipEnable;
|
||||||
public bool SetClipEnableV => (SetClipEnable & 0x1) != 0;
|
public bool SetClipEnableV => (SetClipEnable & 0x1) != 0;
|
||||||
public uint SetColorKeyFormat;
|
public uint SetColorKeyFormat;
|
||||||
public SetColorKeyFormatV SetColorKeyFormatV => (SetColorKeyFormatV)((SetColorKeyFormat >> 0) & 0x7);
|
public SetColorKeyFormatV SetColorKeyFormatV => (SetColorKeyFormatV)(SetColorKeyFormat & 0x7);
|
||||||
public uint SetColorKey;
|
public uint SetColorKey;
|
||||||
public uint SetColorKeyEnable;
|
public uint SetColorKeyEnable;
|
||||||
public bool SetColorKeyEnableV => (SetColorKeyEnable & 0x1) != 0;
|
public bool SetColorKeyEnableV => (SetColorKeyEnable & 0x1) != 0;
|
||||||
public uint SetRop;
|
public uint SetRop;
|
||||||
public int SetRopV => (int)((SetRop >> 0) & 0xFF);
|
public int SetRopV => (int)(SetRop & 0xFF);
|
||||||
public uint SetBeta1;
|
public uint SetBeta1;
|
||||||
public uint SetBeta4;
|
public uint SetBeta4;
|
||||||
public int SetBeta4B => (int)((SetBeta4 >> 0) & 0xFF);
|
public int SetBeta4B => (int)(SetBeta4 & 0xFF);
|
||||||
public int SetBeta4G => (int)((SetBeta4 >> 8) & 0xFF);
|
public int SetBeta4G => (int)((SetBeta4 >> 8) & 0xFF);
|
||||||
public int SetBeta4R => (int)((SetBeta4 >> 16) & 0xFF);
|
public int SetBeta4R => (int)((SetBeta4 >> 16) & 0xFF);
|
||||||
public int SetBeta4A => (int)((SetBeta4 >> 24) & 0xFF);
|
public int SetBeta4A => (int)((SetBeta4 >> 24) & 0xFF);
|
||||||
public uint SetOperation;
|
public uint SetOperation;
|
||||||
public SetOperationV SetOperationV => (SetOperationV)((SetOperation >> 0) & 0x7);
|
public SetOperationV SetOperationV => (SetOperationV)(SetOperation & 0x7);
|
||||||
public uint SetPatternOffset;
|
public uint SetPatternOffset;
|
||||||
public int SetPatternOffsetX => (int)((SetPatternOffset >> 0) & 0x3F);
|
public int SetPatternOffsetX => (int)(SetPatternOffset & 0x3F);
|
||||||
public int SetPatternOffsetY => (int)((SetPatternOffset >> 8) & 0x3F);
|
public int SetPatternOffsetY => (int)((SetPatternOffset >> 8) & 0x3F);
|
||||||
public uint SetPatternSelect;
|
public uint SetPatternSelect;
|
||||||
public SetPatternSelectV SetPatternSelectV => (SetPatternSelectV)((SetPatternSelect >> 0) & 0x3);
|
public SetPatternSelectV SetPatternSelectV => (SetPatternSelectV)(SetPatternSelect & 0x3);
|
||||||
public uint SetDstColorRenderToZetaSurface;
|
public uint SetDstColorRenderToZetaSurface;
|
||||||
public bool SetDstColorRenderToZetaSurfaceV => (SetDstColorRenderToZetaSurface & 0x1) != 0;
|
public bool SetDstColorRenderToZetaSurfaceV => (SetDstColorRenderToZetaSurface & 0x1) != 0;
|
||||||
public uint SetSpareNoop04;
|
public uint SetSpareNoop04;
|
||||||
@@ -618,15 +618,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||||||
public bool SetCompressionEnable => (SetCompression & 0x1) != 0;
|
public bool SetCompressionEnable => (SetCompression & 0x1) != 0;
|
||||||
public uint SetSpareNoop09;
|
public uint SetSpareNoop09;
|
||||||
public uint SetRenderEnableOverride;
|
public uint SetRenderEnableOverride;
|
||||||
public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)((SetRenderEnableOverride >> 0) & 0x3);
|
public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)(SetRenderEnableOverride & 0x3);
|
||||||
public uint SetPixelsFromMemoryDirection;
|
public uint SetPixelsFromMemoryDirection;
|
||||||
public SetPixelsFromMemoryDirectionHorizontal SetPixelsFromMemoryDirectionHorizontal => (SetPixelsFromMemoryDirectionHorizontal)((SetPixelsFromMemoryDirection >> 0) & 0x3);
|
public SetPixelsFromMemoryDirectionHorizontal SetPixelsFromMemoryDirectionHorizontal => (SetPixelsFromMemoryDirectionHorizontal)(SetPixelsFromMemoryDirection & 0x3);
|
||||||
public SetPixelsFromMemoryDirectionVertical SetPixelsFromMemoryDirectionVertical => (SetPixelsFromMemoryDirectionVertical)((SetPixelsFromMemoryDirection >> 4) & 0x3);
|
public SetPixelsFromMemoryDirectionVertical SetPixelsFromMemoryDirectionVertical => (SetPixelsFromMemoryDirectionVertical)((SetPixelsFromMemoryDirection >> 4) & 0x3);
|
||||||
public uint SetSpareNoop10;
|
public uint SetSpareNoop10;
|
||||||
public uint SetMonochromePatternColorFormat;
|
public uint SetMonochromePatternColorFormat;
|
||||||
public SetMonochromePatternColorFormatV SetMonochromePatternColorFormatV => (SetMonochromePatternColorFormatV)((SetMonochromePatternColorFormat >> 0) & 0x7);
|
public SetMonochromePatternColorFormatV SetMonochromePatternColorFormatV => (SetMonochromePatternColorFormatV)(SetMonochromePatternColorFormat & 0x7);
|
||||||
public uint SetMonochromePatternFormat;
|
public uint SetMonochromePatternFormat;
|
||||||
public SetMonochromePatternFormatV SetMonochromePatternFormatV => (SetMonochromePatternFormatV)((SetMonochromePatternFormat >> 0) & 0x1);
|
public SetMonochromePatternFormatV SetMonochromePatternFormatV => (SetMonochromePatternFormatV)(SetMonochromePatternFormat & 0x1);
|
||||||
public uint SetMonochromePatternColor0;
|
public uint SetMonochromePatternColor0;
|
||||||
public uint SetMonochromePatternColor1;
|
public uint SetMonochromePatternColor1;
|
||||||
public uint SetMonochromePattern0;
|
public uint SetMonochromePattern0;
|
||||||
@@ -662,26 +662,26 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||||||
public uint SetRenderSolidPrimColor2;
|
public uint SetRenderSolidPrimColor2;
|
||||||
public uint SetRenderSolidPrimColor3;
|
public uint SetRenderSolidPrimColor3;
|
||||||
public uint SetMmeMemAddressA;
|
public uint SetMmeMemAddressA;
|
||||||
public int SetMmeMemAddressAUpper => (int)((SetMmeMemAddressA >> 0) & 0x1FFFFFF);
|
public int SetMmeMemAddressAUpper => (int)(SetMmeMemAddressA & 0x1FFFFFF);
|
||||||
public uint SetMmeMemAddressB;
|
public uint SetMmeMemAddressB;
|
||||||
public uint SetMmeDataRamAddress;
|
public uint SetMmeDataRamAddress;
|
||||||
public uint MmeDmaRead;
|
public uint MmeDmaRead;
|
||||||
public uint MmeDmaReadFifoed;
|
public uint MmeDmaReadFifoed;
|
||||||
public uint MmeDmaWrite;
|
public uint MmeDmaWrite;
|
||||||
public uint MmeDmaReduction;
|
public uint MmeDmaReduction;
|
||||||
public MmeDmaReductionReductionOp MmeDmaReductionReductionOp => (MmeDmaReductionReductionOp)((MmeDmaReduction >> 0) & 0x7);
|
public MmeDmaReductionReductionOp MmeDmaReductionReductionOp => (MmeDmaReductionReductionOp)(MmeDmaReduction & 0x7);
|
||||||
public MmeDmaReductionReductionFormat MmeDmaReductionReductionFormat => (MmeDmaReductionReductionFormat)((MmeDmaReduction >> 4) & 0x3);
|
public MmeDmaReductionReductionFormat MmeDmaReductionReductionFormat => (MmeDmaReductionReductionFormat)((MmeDmaReduction >> 4) & 0x3);
|
||||||
public MmeDmaReductionReductionSize MmeDmaReductionReductionSize => (MmeDmaReductionReductionSize)((MmeDmaReduction >> 8) & 0x1);
|
public MmeDmaReductionReductionSize MmeDmaReductionReductionSize => (MmeDmaReductionReductionSize)((MmeDmaReduction >> 8) & 0x1);
|
||||||
public uint MmeDmaSysmembar;
|
public uint MmeDmaSysmembar;
|
||||||
public bool MmeDmaSysmembarV => (MmeDmaSysmembar & 0x1) != 0;
|
public bool MmeDmaSysmembarV => (MmeDmaSysmembar & 0x1) != 0;
|
||||||
public uint MmeDmaSync;
|
public uint MmeDmaSync;
|
||||||
public uint SetMmeDataFifoConfig;
|
public uint SetMmeDataFifoConfig;
|
||||||
public SetMmeDataFifoConfigFifoSize SetMmeDataFifoConfigFifoSize => (SetMmeDataFifoConfigFifoSize)((SetMmeDataFifoConfig >> 0) & 0x7);
|
public SetMmeDataFifoConfigFifoSize SetMmeDataFifoConfigFifoSize => (SetMmeDataFifoConfigFifoSize)(SetMmeDataFifoConfig & 0x7);
|
||||||
public fixed uint Reserved578[2];
|
public fixed uint Reserved578[2];
|
||||||
public uint RenderSolidPrimMode;
|
public uint RenderSolidPrimMode;
|
||||||
public RenderSolidPrimModeV RenderSolidPrimModeV => (RenderSolidPrimModeV)((RenderSolidPrimMode >> 0) & 0x7);
|
public RenderSolidPrimModeV RenderSolidPrimModeV => (RenderSolidPrimModeV)(RenderSolidPrimMode & 0x7);
|
||||||
public uint SetRenderSolidPrimColorFormat;
|
public uint SetRenderSolidPrimColorFormat;
|
||||||
public SetRenderSolidPrimColorFormatV SetRenderSolidPrimColorFormatV => (SetRenderSolidPrimColorFormatV)((SetRenderSolidPrimColorFormat >> 0) & 0xFF);
|
public SetRenderSolidPrimColorFormatV SetRenderSolidPrimColorFormatV => (SetRenderSolidPrimColorFormatV)(SetRenderSolidPrimColorFormat & 0xFF);
|
||||||
public uint SetRenderSolidPrimColor;
|
public uint SetRenderSolidPrimColor;
|
||||||
public uint SetRenderSolidLineTieBreakBits;
|
public uint SetRenderSolidLineTieBreakBits;
|
||||||
public bool SetRenderSolidLineTieBreakBitsXmajXincYinc => (SetRenderSolidLineTieBreakBits & 0x1) != 0;
|
public bool SetRenderSolidLineTieBreakBitsXmajXincYinc => (SetRenderSolidLineTieBreakBits & 0x1) != 0;
|
||||||
@@ -690,24 +690,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||||||
public bool SetRenderSolidLineTieBreakBitsYmajXdecYinc => (SetRenderSolidLineTieBreakBits & 0x1000) != 0;
|
public bool SetRenderSolidLineTieBreakBitsYmajXdecYinc => (SetRenderSolidLineTieBreakBits & 0x1000) != 0;
|
||||||
public fixed uint Reserved590[20];
|
public fixed uint Reserved590[20];
|
||||||
public uint RenderSolidPrimPointXY;
|
public uint RenderSolidPrimPointXY;
|
||||||
public int RenderSolidPrimPointXYX => (int)((RenderSolidPrimPointXY >> 0) & 0xFFFF);
|
public int RenderSolidPrimPointXYX => (int)(RenderSolidPrimPointXY & 0xFFFF);
|
||||||
public int RenderSolidPrimPointXYY => (int)((RenderSolidPrimPointXY >> 16) & 0xFFFF);
|
public int RenderSolidPrimPointXYY => (int)((RenderSolidPrimPointXY >> 16) & 0xFFFF);
|
||||||
public fixed uint Reserved5E4[7];
|
public fixed uint Reserved5E4[7];
|
||||||
public Array64<RenderSolidPrimPoint> RenderSolidPrimPoint;
|
public Array64<RenderSolidPrimPoint> RenderSolidPrimPoint;
|
||||||
public uint SetPixelsFromCpuDataType;
|
public uint SetPixelsFromCpuDataType;
|
||||||
public SetPixelsFromCpuDataTypeV SetPixelsFromCpuDataTypeV => (SetPixelsFromCpuDataTypeV)((SetPixelsFromCpuDataType >> 0) & 0x1);
|
public SetPixelsFromCpuDataTypeV SetPixelsFromCpuDataTypeV => (SetPixelsFromCpuDataTypeV)(SetPixelsFromCpuDataType & 0x1);
|
||||||
public uint SetPixelsFromCpuColorFormat;
|
public uint SetPixelsFromCpuColorFormat;
|
||||||
public SetPixelsFromCpuColorFormatV SetPixelsFromCpuColorFormatV => (SetPixelsFromCpuColorFormatV)((SetPixelsFromCpuColorFormat >> 0) & 0xFF);
|
public SetPixelsFromCpuColorFormatV SetPixelsFromCpuColorFormatV => (SetPixelsFromCpuColorFormatV)(SetPixelsFromCpuColorFormat & 0xFF);
|
||||||
public uint SetPixelsFromCpuIndexFormat;
|
public uint SetPixelsFromCpuIndexFormat;
|
||||||
public SetPixelsFromCpuIndexFormatV SetPixelsFromCpuIndexFormatV => (SetPixelsFromCpuIndexFormatV)((SetPixelsFromCpuIndexFormat >> 0) & 0x3);
|
public SetPixelsFromCpuIndexFormatV SetPixelsFromCpuIndexFormatV => (SetPixelsFromCpuIndexFormatV)(SetPixelsFromCpuIndexFormat & 0x3);
|
||||||
public uint SetPixelsFromCpuMonoFormat;
|
public uint SetPixelsFromCpuMonoFormat;
|
||||||
public SetPixelsFromCpuMonoFormatV SetPixelsFromCpuMonoFormatV => (SetPixelsFromCpuMonoFormatV)((SetPixelsFromCpuMonoFormat >> 0) & 0x1);
|
public SetPixelsFromCpuMonoFormatV SetPixelsFromCpuMonoFormatV => (SetPixelsFromCpuMonoFormatV)(SetPixelsFromCpuMonoFormat & 0x1);
|
||||||
public uint SetPixelsFromCpuWrap;
|
public uint SetPixelsFromCpuWrap;
|
||||||
public SetPixelsFromCpuWrapV SetPixelsFromCpuWrapV => (SetPixelsFromCpuWrapV)((SetPixelsFromCpuWrap >> 0) & 0x3);
|
public SetPixelsFromCpuWrapV SetPixelsFromCpuWrapV => (SetPixelsFromCpuWrapV)(SetPixelsFromCpuWrap & 0x3);
|
||||||
public uint SetPixelsFromCpuColor0;
|
public uint SetPixelsFromCpuColor0;
|
||||||
public uint SetPixelsFromCpuColor1;
|
public uint SetPixelsFromCpuColor1;
|
||||||
public uint SetPixelsFromCpuMonoOpacity;
|
public uint SetPixelsFromCpuMonoOpacity;
|
||||||
public SetPixelsFromCpuMonoOpacityV SetPixelsFromCpuMonoOpacityV => (SetPixelsFromCpuMonoOpacityV)((SetPixelsFromCpuMonoOpacity >> 0) & 0x1);
|
public SetPixelsFromCpuMonoOpacityV SetPixelsFromCpuMonoOpacityV => (SetPixelsFromCpuMonoOpacityV)(SetPixelsFromCpuMonoOpacity & 0x1);
|
||||||
public fixed uint Reserved820[6];
|
public fixed uint Reserved820[6];
|
||||||
public uint SetPixelsFromCpuSrcWidth;
|
public uint SetPixelsFromCpuSrcWidth;
|
||||||
public uint SetPixelsFromCpuSrcHeight;
|
public uint SetPixelsFromCpuSrcHeight;
|
||||||
@@ -753,13 +753,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||||||
public bool SetBigEndianControlOverride => (SetBigEndianControl & 0x10000000) != 0;
|
public bool SetBigEndianControlOverride => (SetBigEndianControl & 0x10000000) != 0;
|
||||||
public fixed uint Reserved874[3];
|
public fixed uint Reserved874[3];
|
||||||
public uint SetPixelsFromMemoryBlockShape;
|
public uint SetPixelsFromMemoryBlockShape;
|
||||||
public SetPixelsFromMemoryBlockShapeV SetPixelsFromMemoryBlockShapeV => (SetPixelsFromMemoryBlockShapeV)((SetPixelsFromMemoryBlockShape >> 0) & 0x7);
|
public SetPixelsFromMemoryBlockShapeV SetPixelsFromMemoryBlockShapeV => (SetPixelsFromMemoryBlockShapeV)(SetPixelsFromMemoryBlockShape & 0x7);
|
||||||
public uint SetPixelsFromMemoryCorralSize;
|
public uint SetPixelsFromMemoryCorralSize;
|
||||||
public int SetPixelsFromMemoryCorralSizeV => (int)((SetPixelsFromMemoryCorralSize >> 0) & 0x3FF);
|
public int SetPixelsFromMemoryCorralSizeV => (int)(SetPixelsFromMemoryCorralSize & 0x3FF);
|
||||||
public uint SetPixelsFromMemorySafeOverlap;
|
public uint SetPixelsFromMemorySafeOverlap;
|
||||||
public bool SetPixelsFromMemorySafeOverlapV => (SetPixelsFromMemorySafeOverlap & 0x1) != 0;
|
public bool SetPixelsFromMemorySafeOverlapV => (SetPixelsFromMemorySafeOverlap & 0x1) != 0;
|
||||||
public uint SetPixelsFromMemorySampleMode;
|
public uint SetPixelsFromMemorySampleMode;
|
||||||
public SetPixelsFromMemorySampleModeOrigin SetPixelsFromMemorySampleModeOrigin => (SetPixelsFromMemorySampleModeOrigin)((SetPixelsFromMemorySampleMode >> 0) & 0x1);
|
public SetPixelsFromMemorySampleModeOrigin SetPixelsFromMemorySampleModeOrigin => (SetPixelsFromMemorySampleModeOrigin)(SetPixelsFromMemorySampleMode & 0x1);
|
||||||
public SetPixelsFromMemorySampleModeFilter SetPixelsFromMemorySampleModeFilter => (SetPixelsFromMemorySampleModeFilter)((SetPixelsFromMemorySampleMode >> 4) & 0x1);
|
public SetPixelsFromMemorySampleModeFilter SetPixelsFromMemorySampleModeFilter => (SetPixelsFromMemorySampleModeFilter)((SetPixelsFromMemorySampleMode >> 4) & 0x1);
|
||||||
public fixed uint Reserved890[8];
|
public fixed uint Reserved890[8];
|
||||||
public uint SetPixelsFromMemoryDstX0;
|
public uint SetPixelsFromMemoryDstX0;
|
||||||
|
@@ -6,6 +6,7 @@ using Ryujinx.Graphics.Shader;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Memory
|
namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
{
|
{
|
||||||
@@ -14,12 +15,17 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
class BufferManager
|
class BufferManager
|
||||||
{
|
{
|
||||||
|
private const int TfInfoVertexCountOffset = Constants.TotalTransformFeedbackBuffers * sizeof(int);
|
||||||
|
private const int TfInfoBufferSize = TfInfoVertexCountOffset + sizeof(int);
|
||||||
|
|
||||||
private readonly GpuContext _context;
|
private readonly GpuContext _context;
|
||||||
private readonly GpuChannel _channel;
|
private readonly GpuChannel _channel;
|
||||||
|
|
||||||
private int _unalignedStorageBuffers;
|
private int _unalignedStorageBuffers;
|
||||||
public bool HasUnalignedStorageBuffers => _unalignedStorageBuffers > 0;
|
public bool HasUnalignedStorageBuffers => _unalignedStorageBuffers > 0;
|
||||||
|
|
||||||
|
public bool HasTransformFeedbackOutputs { get; set; }
|
||||||
|
|
||||||
private IndexBuffer _indexBuffer;
|
private IndexBuffer _indexBuffer;
|
||||||
private readonly VertexBuffer[] _vertexBuffers;
|
private readonly VertexBuffer[] _vertexBuffers;
|
||||||
private readonly BufferBounds[] _transformFeedbackBuffers;
|
private readonly BufferBounds[] _transformFeedbackBuffers;
|
||||||
@@ -98,6 +104,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
private readonly BuffersPerStage[] _gpStorageBuffers;
|
private readonly BuffersPerStage[] _gpStorageBuffers;
|
||||||
private readonly BuffersPerStage[] _gpUniformBuffers;
|
private readonly BuffersPerStage[] _gpUniformBuffers;
|
||||||
|
|
||||||
|
private BufferHandle _tfInfoBuffer;
|
||||||
|
private int[] _tfInfoData;
|
||||||
|
|
||||||
private bool _gpStorageBuffersDirty;
|
private bool _gpStorageBuffersDirty;
|
||||||
private bool _gpUniformBuffersDirty;
|
private bool _gpUniformBuffersDirty;
|
||||||
|
|
||||||
@@ -137,6 +146,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
_bufferTextures = new List<BufferTextureBinding>();
|
_bufferTextures = new List<BufferTextureBinding>();
|
||||||
|
|
||||||
_ranges = new BufferAssignment[Constants.TotalGpUniformBuffers * Constants.ShaderStages];
|
_ranges = new BufferAssignment[Constants.TotalGpUniformBuffers * Constants.ShaderStages];
|
||||||
|
|
||||||
|
if (!context.Capabilities.SupportsTransformFeedback)
|
||||||
|
{
|
||||||
|
_tfInfoData = new int[Constants.TotalTransformFeedbackBuffers];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -319,6 +333,31 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
_gpUniformBuffersDirty = true;
|
_gpUniformBuffersDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the number of vertices per instance on a instanced draw. Used for transform feedback emulation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertexCount">Vertex count per instance</param>
|
||||||
|
public void SetInstancedDrawVertexCount(int vertexCount)
|
||||||
|
{
|
||||||
|
if (!_context.Capabilities.SupportsTransformFeedback &&
|
||||||
|
HasTransformFeedbackOutputs &&
|
||||||
|
_tfInfoBuffer != BufferHandle.Null)
|
||||||
|
{
|
||||||
|
Span<byte> data = stackalloc byte[sizeof(int)];
|
||||||
|
MemoryMarshal.Cast<byte, int>(data)[0] = vertexCount;
|
||||||
|
_context.Renderer.SetBufferData(_tfInfoBuffer, TfInfoVertexCountOffset, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Forces transform feedback and storage buffers to be updated on the next draw.
|
||||||
|
/// </summary>
|
||||||
|
public void ForceTransformFeedbackAndStorageBuffersDirty()
|
||||||
|
{
|
||||||
|
_transformFeedbackBuffersDirty = true;
|
||||||
|
_gpStorageBuffersDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the binding points for the storage buffers bound on the compute pipeline.
|
/// Sets the binding points for the storage buffers bound on the compute pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -537,22 +576,75 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
{
|
{
|
||||||
_transformFeedbackBuffersDirty = false;
|
_transformFeedbackBuffersDirty = false;
|
||||||
|
|
||||||
Span<BufferRange> tfbs = stackalloc BufferRange[Constants.TotalTransformFeedbackBuffers];
|
if (_context.Capabilities.SupportsTransformFeedback)
|
||||||
|
|
||||||
for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
|
|
||||||
{
|
{
|
||||||
BufferBounds tfb = _transformFeedbackBuffers[index];
|
Span<BufferRange> tfbs = stackalloc BufferRange[Constants.TotalTransformFeedbackBuffers];
|
||||||
|
|
||||||
if (tfb.Address == 0)
|
for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
|
||||||
{
|
{
|
||||||
tfbs[index] = BufferRange.Empty;
|
BufferBounds tfb = _transformFeedbackBuffers[index];
|
||||||
continue;
|
|
||||||
|
if (tfb.Address == 0)
|
||||||
|
{
|
||||||
|
tfbs[index] = BufferRange.Empty;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tfbs[index] = bufferCache.GetBufferRange(tfb.Address, tfb.Size, write: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
tfbs[index] = bufferCache.GetBufferRange(tfb.Address, tfb.Size, write: true);
|
_context.Renderer.Pipeline.SetTransformFeedbackBuffers(tfbs);
|
||||||
}
|
}
|
||||||
|
else if (HasTransformFeedbackOutputs)
|
||||||
|
{
|
||||||
|
Span<int> info = _tfInfoData.AsSpan();
|
||||||
|
Span<BufferAssignment> buffers = stackalloc BufferAssignment[Constants.TotalTransformFeedbackBuffers + 1];
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetTransformFeedbackBuffers(tfbs);
|
bool needsDataUpdate = false;
|
||||||
|
|
||||||
|
if (_tfInfoBuffer == BufferHandle.Null)
|
||||||
|
{
|
||||||
|
_tfInfoBuffer = _context.Renderer.CreateBuffer(TfInfoBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers[0] = new BufferAssignment(0, new BufferRange(_tfInfoBuffer, 0, TfInfoBufferSize));
|
||||||
|
|
||||||
|
int alignment = _context.Capabilities.StorageBufferOffsetAlignment;
|
||||||
|
|
||||||
|
for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
|
||||||
|
{
|
||||||
|
BufferBounds tfb = _transformFeedbackBuffers[index];
|
||||||
|
|
||||||
|
if (tfb.Address == 0)
|
||||||
|
{
|
||||||
|
buffers[1 + index] = new BufferAssignment(1 + index, BufferRange.Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulong endAddress = tfb.Address + tfb.Size;
|
||||||
|
ulong address = BitUtils.AlignDown(tfb.Address, (ulong)alignment);
|
||||||
|
ulong size = endAddress - address;
|
||||||
|
|
||||||
|
int tfeOffset = ((int)tfb.Address & (alignment - 1)) / 4;
|
||||||
|
|
||||||
|
if (info[index] != tfeOffset)
|
||||||
|
{
|
||||||
|
info[index] = tfeOffset;
|
||||||
|
needsDataUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers[1 + index] = new BufferAssignment(1 + index, bufferCache.GetBufferRange(address, size, write: true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsDataUpdate)
|
||||||
|
{
|
||||||
|
Span<byte> infoData = MemoryMarshal.Cast<int, byte>(info);
|
||||||
|
_context.Renderer.SetBufferData(_tfInfoBuffer, 0, infoData);
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.Renderer.Pipeline.SetStorageBuffers(buffers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
ShaderSpecializationState oldSpecState,
|
ShaderSpecializationState oldSpecState,
|
||||||
ShaderSpecializationState newSpecState,
|
ShaderSpecializationState newSpecState,
|
||||||
ResourceCounts counts,
|
ResourceCounts counts,
|
||||||
int stageIndex) : base(context, counts, stageIndex)
|
int stageIndex) : base(context, counts, stageIndex, oldSpecState.TransformFeedbackDescriptors != null)
|
||||||
{
|
{
|
||||||
_data = data;
|
_data = data;
|
||||||
_cb1Data = cb1Data;
|
_cb1Data = cb1Data;
|
||||||
|
@@ -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 = 5044;
|
private const uint CodeGenVersion = 5080;
|
||||||
|
|
||||||
private const string SharedTocFileName = "shared.toc";
|
private const string SharedTocFileName = "shared.toc";
|
||||||
private const string SharedDataFileName = "shared.data";
|
private const string SharedDataFileName = "shared.data";
|
||||||
@@ -368,7 +368,11 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
|
|
||||||
if (hostCode != null)
|
if (hostCode != null)
|
||||||
{
|
{
|
||||||
ShaderInfo shaderInfo = ShaderInfoBuilder.BuildForCache(context, shaders, specState.PipelineState);
|
ShaderInfo shaderInfo = ShaderInfoBuilder.BuildForCache(
|
||||||
|
context,
|
||||||
|
shaders,
|
||||||
|
specState.PipelineState,
|
||||||
|
specState.TransformFeedbackDescriptors != null);
|
||||||
|
|
||||||
IProgram hostProgram;
|
IProgram hostProgram;
|
||||||
|
|
||||||
|
@@ -491,7 +491,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
{
|
{
|
||||||
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
|
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
|
||||||
|
|
||||||
ShaderInfoBuilder shaderInfoBuilder = new ShaderInfoBuilder(_context);
|
ShaderInfoBuilder shaderInfoBuilder = new ShaderInfoBuilder(_context, compilation.SpecializationState.TransformFeedbackDescriptors != null);
|
||||||
|
|
||||||
for (int index = 0; index < compilation.TranslatedStages.Length; index++)
|
for (int index = 0; index < compilation.TranslatedStages.Length; index++)
|
||||||
{
|
{
|
||||||
|
@@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
GpuContext context,
|
GpuContext context,
|
||||||
GpuChannel channel,
|
GpuChannel channel,
|
||||||
GpuAccessorState state,
|
GpuAccessorState state,
|
||||||
int stageIndex) : base(context, state.ResourceCounts, stageIndex)
|
int stageIndex) : base(context, state.ResourceCounts, stageIndex, state.TransformFeedbackDescriptors != null)
|
||||||
{
|
{
|
||||||
_isVulkan = context.Capabilities.Api == TargetApi.Vulkan;
|
_isVulkan = context.Capabilities.Api == TargetApi.Vulkan;
|
||||||
_channel = channel;
|
_channel = channel;
|
||||||
@@ -44,7 +44,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// <param name="context">GPU context</param>
|
/// <param name="context">GPU context</param>
|
||||||
/// <param name="channel">GPU channel</param>
|
/// <param name="channel">GPU channel</param>
|
||||||
/// <param name="state">Current GPU state</param>
|
/// <param name="state">Current GPU state</param>
|
||||||
public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state) : base(context, state.ResourceCounts, 0)
|
public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state) : base(context, state.ResourceCounts, 0, false)
|
||||||
{
|
{
|
||||||
_channel = channel;
|
_channel = channel;
|
||||||
_state = state;
|
_state = state;
|
||||||
|
@@ -17,40 +17,56 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
private readonly ResourceCounts _resourceCounts;
|
private readonly ResourceCounts _resourceCounts;
|
||||||
private readonly int _stageIndex;
|
private readonly int _stageIndex;
|
||||||
|
|
||||||
|
private readonly int _reservedConstantBuffers;
|
||||||
|
private readonly int _reservedStorageBuffers;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new GPU accessor.
|
/// Creates a new GPU accessor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">GPU context</param>
|
/// <param name="context">GPU context</param>
|
||||||
public GpuAccessorBase(GpuContext context, ResourceCounts resourceCounts, int stageIndex)
|
/// <param name="resourceCounts">Counter of GPU resources used by the shader</param>
|
||||||
|
/// <param name="stageIndex">Index of the shader stage, 0 for compute</param>
|
||||||
|
/// <param name="tfEnabled">Indicates if the current graphics shader is used with transform feedback enabled</param>
|
||||||
|
public GpuAccessorBase(GpuContext context, ResourceCounts resourceCounts, int stageIndex, bool tfEnabled)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_resourceCounts = resourceCounts;
|
_resourceCounts = resourceCounts;
|
||||||
_stageIndex = stageIndex;
|
_stageIndex = stageIndex;
|
||||||
|
|
||||||
|
_reservedConstantBuffers = 1; // For the support buffer.
|
||||||
|
_reservedStorageBuffers = !context.Capabilities.SupportsTransformFeedback && tfEnabled ? 5 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int QueryBindingConstantBuffer(int index)
|
public int QueryBindingConstantBuffer(int index)
|
||||||
{
|
{
|
||||||
|
int binding;
|
||||||
|
|
||||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||||
{
|
{
|
||||||
// We need to start counting from 1 since binding 0 is reserved for the support uniform buffer.
|
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer");
|
||||||
return GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer") + 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return _resourceCounts.UniformBuffersCount++;
|
binding = _resourceCounts.UniformBuffersCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return binding + _reservedConstantBuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int QueryBindingStorageBuffer(int index)
|
public int QueryBindingStorageBuffer(int index)
|
||||||
{
|
{
|
||||||
|
int binding;
|
||||||
|
|
||||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||||
{
|
{
|
||||||
return GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
|
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return _resourceCounts.StorageBuffersCount++;
|
binding = _resourceCounts.StorageBuffersCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return binding + _reservedStorageBuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int QueryBindingTexture(int index, bool isBuffer)
|
public int QueryBindingTexture(int index, bool isBuffer)
|
||||||
@@ -149,6 +165,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
|
|
||||||
public bool QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
|
public bool QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
|
||||||
|
|
||||||
|
public bool QueryHostSupportsTransformFeedback() => _context.Capabilities.SupportsTransformFeedback;
|
||||||
|
|
||||||
public bool QueryHostSupportsViewportIndexVertexTessellation() => _context.Capabilities.SupportsViewportIndexVertexTessellation;
|
public bool QueryHostSupportsViewportIndexVertexTessellation() => _context.Capabilities.SupportsViewportIndexVertexTessellation;
|
||||||
|
|
||||||
public bool QueryHostSupportsViewportMask() => _context.Capabilities.SupportsViewportMask;
|
public bool QueryHostSupportsViewportMask() => _context.Capabilities.SupportsViewportMask;
|
||||||
|
@@ -24,13 +24,5 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// Total of images used by the shaders.
|
/// Total of images used by the shaders.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ImagesCount;
|
public int ImagesCount;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of the shader resource counts class.
|
|
||||||
/// </summary>
|
|
||||||
public ResourceCounts()
|
|
||||||
{
|
|
||||||
UniformBuffersCount = 1; // The first binding is reserved for the support buffer.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -362,7 +362,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
|
|
||||||
TranslatorContext previousStage = null;
|
TranslatorContext previousStage = null;
|
||||||
|
|
||||||
ShaderInfoBuilder infoBuilder = new ShaderInfoBuilder(_context);
|
ShaderInfoBuilder infoBuilder = new ShaderInfoBuilder(_context, transformFeedbackDescriptors != null);
|
||||||
|
|
||||||
for (int stageIndex = 0; stageIndex < Constants.ShaderStages; stageIndex++)
|
for (int stageIndex = 0; stageIndex < Constants.ShaderStages; stageIndex++)
|
||||||
{
|
{
|
||||||
|
@@ -16,15 +16,24 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
private const int TextureSetIndex = 2;
|
private const int TextureSetIndex = 2;
|
||||||
private const int ImageSetIndex = 3;
|
private const int ImageSetIndex = 3;
|
||||||
|
|
||||||
private const ResourceStages SupportBufferStags =
|
private const ResourceStages SupportBufferStages =
|
||||||
ResourceStages.Compute |
|
ResourceStages.Compute |
|
||||||
ResourceStages.Vertex |
|
ResourceStages.Vertex |
|
||||||
ResourceStages.Fragment;
|
ResourceStages.Fragment;
|
||||||
|
|
||||||
|
private const ResourceStages VtgStages =
|
||||||
|
ResourceStages.Vertex |
|
||||||
|
ResourceStages.TessellationControl |
|
||||||
|
ResourceStages.TessellationEvaluation |
|
||||||
|
ResourceStages.Geometry;
|
||||||
|
|
||||||
private readonly GpuContext _context;
|
private readonly GpuContext _context;
|
||||||
|
|
||||||
private int _fragmentOutputMap;
|
private int _fragmentOutputMap;
|
||||||
|
|
||||||
|
private readonly int _reservedConstantBuffers;
|
||||||
|
private readonly int _reservedStorageBuffers;
|
||||||
|
|
||||||
private readonly List<ResourceDescriptor>[] _resourceDescriptors;
|
private readonly List<ResourceDescriptor>[] _resourceDescriptors;
|
||||||
private readonly List<ResourceUsage>[] _resourceUsages;
|
private readonly List<ResourceUsage>[] _resourceUsages;
|
||||||
|
|
||||||
@@ -32,7 +41,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// Creates a new shader info builder.
|
/// Creates a new shader info builder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">GPU context that owns the shaders that will be added to the builder</param>
|
/// <param name="context">GPU context that owns the shaders that will be added to the builder</param>
|
||||||
public ShaderInfoBuilder(GpuContext context)
|
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||||
|
public ShaderInfoBuilder(GpuContext context, bool tfEnabled)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
|
|
||||||
@@ -47,7 +57,22 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
_resourceUsages[index] = new();
|
_resourceUsages[index] = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
AddDescriptor(SupportBufferStags, ResourceType.UniformBuffer, UniformSetIndex, 0, 1);
|
AddDescriptor(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1);
|
||||||
|
|
||||||
|
_reservedConstantBuffers = 1; // For the support buffer.
|
||||||
|
|
||||||
|
if (!context.Capabilities.SupportsTransformFeedback && tfEnabled)
|
||||||
|
{
|
||||||
|
_reservedStorageBuffers = 5;
|
||||||
|
|
||||||
|
AddDescriptor(VtgStages, ResourceType.StorageBuffer, StorageSetIndex, 0, 5);
|
||||||
|
AddUsage(VtgStages, ResourceType.StorageBuffer, ResourceAccess.Read, StorageSetIndex, 0, 1);
|
||||||
|
AddUsage(VtgStages, ResourceType.StorageBuffer, ResourceAccess.Write, StorageSetIndex, 1, 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_reservedStorageBuffers = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -86,8 +111,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
int texturesPerStage = (int)_context.Capabilities.MaximumTexturesPerStage;
|
int texturesPerStage = (int)_context.Capabilities.MaximumTexturesPerStage;
|
||||||
int imagesPerStage = (int)_context.Capabilities.MaximumImagesPerStage;
|
int imagesPerStage = (int)_context.Capabilities.MaximumImagesPerStage;
|
||||||
|
|
||||||
int uniformBinding = 1 + stageIndex * uniformsPerStage;
|
int uniformBinding = _reservedConstantBuffers + stageIndex * uniformsPerStage;
|
||||||
int storageBinding = stageIndex * storagesPerStage;
|
int storageBinding = _reservedStorageBuffers + stageIndex * storagesPerStage;
|
||||||
int textureBinding = stageIndex * texturesPerStage * 2;
|
int textureBinding = stageIndex * texturesPerStage * 2;
|
||||||
int imageBinding = stageIndex * imagesPerStage * 2;
|
int imageBinding = stageIndex * imagesPerStage * 2;
|
||||||
|
|
||||||
@@ -133,6 +158,23 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
AddDescriptor(stages, type2, setIndex, binding + count, count);
|
AddDescriptor(stages, type2, setIndex, binding + count, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds buffer usage information to the list of usages.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stages">Shader stages where the resource is used</param>
|
||||||
|
/// <param name="type">Type of the resource</param>
|
||||||
|
/// <param name="access">How the resource is accessed by the shader stages where it is used</param>
|
||||||
|
/// <param name="setIndex">Descriptor set number where the resource will be bound</param>
|
||||||
|
/// <param name="binding">Binding number where the resource will be bound</param>
|
||||||
|
/// <param name="count">Number of resources bound at the binding location</param>
|
||||||
|
private void AddUsage(ResourceStages stages, ResourceType type, ResourceAccess access, int setIndex, int binding, int count)
|
||||||
|
{
|
||||||
|
for (int index = 0; index < count; index++)
|
||||||
|
{
|
||||||
|
_resourceUsages[setIndex].Add(new ResourceUsage(binding + index, type, stages, access));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds buffer usage information to the list of usages.
|
/// Adds buffer usage information to the list of usages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -212,10 +254,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// <param name="context">GPU context that owns the shaders</param>
|
/// <param name="context">GPU context that owns the shaders</param>
|
||||||
/// <param name="programs">Shaders from the disk cache</param>
|
/// <param name="programs">Shaders from the disk cache</param>
|
||||||
/// <param name="pipeline">Optional pipeline for background compilation</param>
|
/// <param name="pipeline">Optional pipeline for background compilation</param>
|
||||||
|
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||||
/// <returns>Shader information</returns>
|
/// <returns>Shader information</returns>
|
||||||
public static ShaderInfo BuildForCache(GpuContext context, IEnumerable<CachedShaderStage> programs, ProgramPipelineState? pipeline)
|
public static ShaderInfo BuildForCache(
|
||||||
|
GpuContext context,
|
||||||
|
IEnumerable<CachedShaderStage> programs,
|
||||||
|
ProgramPipelineState? pipeline,
|
||||||
|
bool tfEnabled)
|
||||||
{
|
{
|
||||||
ShaderInfoBuilder builder = new ShaderInfoBuilder(context);
|
ShaderInfoBuilder builder = new ShaderInfoBuilder(context, tfEnabled);
|
||||||
|
|
||||||
foreach (CachedShaderStage program in programs)
|
foreach (CachedShaderStage program in programs)
|
||||||
{
|
{
|
||||||
@@ -237,7 +284,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// <returns>Shader information</returns>
|
/// <returns>Shader information</returns>
|
||||||
public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, bool fromCache = false)
|
public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, bool fromCache = false)
|
||||||
{
|
{
|
||||||
ShaderInfoBuilder builder = new ShaderInfoBuilder(context);
|
ShaderInfoBuilder builder = new ShaderInfoBuilder(context, tfEnabled: false);
|
||||||
|
|
||||||
builder.AddStageInfo(info);
|
builder.AddStageInfo(info);
|
||||||
|
|
||||||
|
@@ -153,6 +153,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
||||||
supportsGeometryShader: true,
|
supportsGeometryShader: true,
|
||||||
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
|
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
|
||||||
|
supportsTransformFeedback: true,
|
||||||
supportsImageLoadFormatted: HwCapabilities.SupportsImageLoadFormatted,
|
supportsImageLoadFormatted: HwCapabilities.SupportsImageLoadFormatted,
|
||||||
supportsLayerVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
supportsLayerVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
||||||
supportsMismatchingViewFormat: HwCapabilities.SupportsMismatchingViewFormat,
|
supportsMismatchingViewFormat: HwCapabilities.SupportsMismatchingViewFormat,
|
||||||
|
@@ -10,5 +10,11 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
public const int NvnBaseVertexByteOffset = 0x640;
|
public const int NvnBaseVertexByteOffset = 0x640;
|
||||||
public const int NvnBaseInstanceByteOffset = 0x644;
|
public const int NvnBaseInstanceByteOffset = 0x644;
|
||||||
public const int NvnDrawIndexByteOffset = 0x648;
|
public const int NvnDrawIndexByteOffset = 0x648;
|
||||||
|
|
||||||
|
// Transform Feedback emulation.
|
||||||
|
|
||||||
|
public const int TfeInfoBinding = 0;
|
||||||
|
public const int TfeBufferBaseBinding = 1;
|
||||||
|
public const int TfeBuffersCount = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Decoders
|
namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
{
|
{
|
||||||
|
[Flags]
|
||||||
enum InstProps : ushort
|
enum InstProps : ushort
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
@@ -367,6 +367,15 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host GPU transform feedback support.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the GPU and driver supports transform feedback, false otherwise</returns>
|
||||||
|
bool QueryHostSupportsTransformFeedback()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queries host support for writes to the viewport index from vertex or tessellation shader stages.
|
/// Queries host support for writes to the viewport index from vertex or tessellation shader stages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -61,7 +61,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static int UnpackTextureId(int packedId)
|
public static int UnpackTextureId(int packedId)
|
||||||
{
|
{
|
||||||
return (packedId >> 0) & 0xfffff;
|
return packedId & 0xfffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
namespace Ryujinx.Graphics.Shader.Translation
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Shader.Translation
|
||||||
{
|
{
|
||||||
|
[Flags]
|
||||||
enum AggregateType
|
enum AggregateType
|
||||||
{
|
{
|
||||||
Invalid,
|
Invalid,
|
||||||
|
@@ -234,6 +234,45 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public void PrepareForVertexReturn()
|
public void PrepareForVertexReturn()
|
||||||
{
|
{
|
||||||
|
if (!Config.GpuAccessor.QueryHostSupportsTransformFeedback() && Config.GpuAccessor.QueryTransformFeedbackEnabled())
|
||||||
|
{
|
||||||
|
Operand vertexCount = this.Load(StorageKind.StorageBuffer, Constants.TfeInfoBinding, Const(1));
|
||||||
|
|
||||||
|
for (int tfbIndex = 0; tfbIndex < Constants.TfeBuffersCount; tfbIndex++)
|
||||||
|
{
|
||||||
|
var locations = Config.GpuAccessor.QueryTransformFeedbackVaryingLocations(tfbIndex);
|
||||||
|
var stride = Config.GpuAccessor.QueryTransformFeedbackStride(tfbIndex);
|
||||||
|
|
||||||
|
Operand baseOffset = this.Load(StorageKind.StorageBuffer, Constants.TfeInfoBinding, Const(0), Const(tfbIndex));
|
||||||
|
Operand baseVertex = this.Load(StorageKind.Input, IoVariable.BaseVertex);
|
||||||
|
Operand baseInstance = this.Load(StorageKind.Input, IoVariable.BaseInstance);
|
||||||
|
Operand vertexIndex = this.Load(StorageKind.Input, IoVariable.VertexIndex);
|
||||||
|
Operand instanceIndex = this.Load(StorageKind.Input, IoVariable.InstanceIndex);
|
||||||
|
|
||||||
|
Operand outputVertexOffset = this.ISubtract(vertexIndex, baseVertex);
|
||||||
|
Operand outputInstanceOffset = this.ISubtract(instanceIndex, baseInstance);
|
||||||
|
|
||||||
|
Operand outputBaseVertex = this.IMultiply(outputInstanceOffset, vertexCount);
|
||||||
|
|
||||||
|
Operand vertexOffset = this.IMultiply(this.IAdd(outputBaseVertex, outputVertexOffset), Const(stride / 4));
|
||||||
|
baseOffset = this.IAdd(baseOffset, vertexOffset);
|
||||||
|
|
||||||
|
for (int j = 0; j < locations.Length; j++)
|
||||||
|
{
|
||||||
|
byte location = locations[j];
|
||||||
|
if (location == 0xff)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand offset = this.IAdd(baseOffset, Const(j));
|
||||||
|
Operand value = Instructions.AttributeMap.GenerateAttributeLoad(this, null, location * 4, isOutput: true, isPerPatch: false);
|
||||||
|
|
||||||
|
this.Store(StorageKind.StorageBuffer, Constants.TfeBufferBaseBinding + tfbIndex, Const(0), offset, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Config.GpuAccessor.QueryViewportTransformDisable())
|
if (Config.GpuAccessor.QueryViewportTransformDisable())
|
||||||
{
|
{
|
||||||
Operand x = this.Load(StorageKind.Output, IoVariable.Position, null, Const(0));
|
Operand x = this.Load(StorageKind.Output, IoVariable.Position, null, Const(0));
|
||||||
|
@@ -132,6 +132,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
_transformFeedbackDefinitions = new Dictionary<TransformFeedbackVariable, TransformFeedbackOutput>();
|
_transformFeedbackDefinitions = new Dictionary<TransformFeedbackVariable, TransformFeedbackOutput>();
|
||||||
|
|
||||||
|
TransformFeedbackEnabled =
|
||||||
|
stage != ShaderStage.Compute &&
|
||||||
|
gpuAccessor.QueryTransformFeedbackEnabled() &&
|
||||||
|
gpuAccessor.QueryHostSupportsTransformFeedback();
|
||||||
|
|
||||||
UsedInputAttributesPerPatch = new HashSet<int>();
|
UsedInputAttributesPerPatch = new HashSet<int>();
|
||||||
UsedOutputAttributesPerPatch = new HashSet<int>();
|
UsedOutputAttributesPerPatch = new HashSet<int>();
|
||||||
|
|
||||||
@@ -139,6 +144,31 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
_usedImages = new Dictionary<TextureInfo, TextureMeta>();
|
_usedImages = new Dictionary<TextureInfo, TextureMeta>();
|
||||||
|
|
||||||
ResourceManager = new ResourceManager(stage, gpuAccessor, new ShaderProperties());
|
ResourceManager = new ResourceManager(stage, gpuAccessor, new ShaderProperties());
|
||||||
|
|
||||||
|
if (!gpuAccessor.QueryHostSupportsTransformFeedback() && gpuAccessor.QueryTransformFeedbackEnabled())
|
||||||
|
{
|
||||||
|
StructureType tfeInfoStruct = new StructureType(new StructureField[]
|
||||||
|
{
|
||||||
|
new StructureField(AggregateType.Array | AggregateType.U32, "base_offset", 4),
|
||||||
|
new StructureField(AggregateType.U32, "vertex_count")
|
||||||
|
});
|
||||||
|
|
||||||
|
BufferDefinition tfeInfoBuffer = new BufferDefinition(BufferLayout.Std430, 1, Constants.TfeInfoBinding, "tfe_info", tfeInfoStruct);
|
||||||
|
|
||||||
|
Properties.AddStorageBuffer(Constants.TfeInfoBinding, tfeInfoBuffer);
|
||||||
|
|
||||||
|
StructureType tfeDataStruct = new StructureType(new StructureField[]
|
||||||
|
{
|
||||||
|
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0)
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int i = 0; i < Constants.TfeBuffersCount; i++)
|
||||||
|
{
|
||||||
|
int binding = Constants.TfeBufferBaseBinding + i;
|
||||||
|
BufferDefinition tfeDataBuffer = new BufferDefinition(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct);
|
||||||
|
Properties.AddStorageBuffer(binding, tfeDataBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderConfig(
|
public ShaderConfig(
|
||||||
@@ -151,7 +181,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
ThreadsPerInputPrimitive = 1;
|
ThreadsPerInputPrimitive = 1;
|
||||||
OutputTopology = outputTopology;
|
OutputTopology = outputTopology;
|
||||||
MaxOutputVertices = maxOutputVertices;
|
MaxOutputVertices = maxOutputVertices;
|
||||||
TransformFeedbackEnabled = gpuAccessor.QueryTransformFeedbackEnabled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationOptions options) : this(header.Stage, gpuAccessor, options)
|
public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationOptions options) : this(header.Stage, gpuAccessor, options)
|
||||||
@@ -165,7 +194,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
OmapTargets = header.OmapTargets;
|
OmapTargets = header.OmapTargets;
|
||||||
OmapSampleMask = header.OmapSampleMask;
|
OmapSampleMask = header.OmapSampleMask;
|
||||||
OmapDepth = header.OmapDepth;
|
OmapDepth = header.OmapDepth;
|
||||||
TransformFeedbackEnabled = gpuAccessor.QueryTransformFeedbackEnabled();
|
|
||||||
LastInVertexPipeline = header.Stage < ShaderStage.Fragment;
|
LastInVertexPipeline = header.Stage < ShaderStage.Fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,7 +754,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
var descriptors = new TextureDescriptor[dict.Count];
|
var descriptors = new TextureDescriptor[dict.Count];
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var kv in dict.OrderBy(x => x.Key.Indexed).OrderBy(x => x.Key.Handle))
|
foreach (var kv in dict.OrderBy(x => x.Key.Indexed).ThenBy(x => x.Key.Handle))
|
||||||
{
|
{
|
||||||
var info = kv.Key;
|
var info = kv.Key;
|
||||||
var meta = kv.Value;
|
var meta = kv.Value;
|
||||||
@@ -824,4 +852,4 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
OmapTargets);
|
OmapTargets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,9 +16,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_descriptorSets = descriptorSets;
|
_descriptorSets = descriptorSets;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeBuffers(int setIndex, int baseBinding, int countPerUnit, DescriptorType type, VkBuffer dummyBuffer)
|
public void InitializeBuffers(int setIndex, int baseBinding, int count, DescriptorType type, VkBuffer dummyBuffer)
|
||||||
{
|
{
|
||||||
Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[countPerUnit];
|
Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[count];
|
||||||
|
|
||||||
infos.Fill(new DescriptorBufferInfo()
|
infos.Fill(new DescriptorBufferInfo()
|
||||||
{
|
{
|
||||||
|
@@ -596,36 +596,19 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void Initialize(CommandBufferScoped cbs, int setIndex, DescriptorSetCollection dsc)
|
private void Initialize(CommandBufferScoped cbs, int setIndex, DescriptorSetCollection dsc)
|
||||||
{
|
{
|
||||||
|
// We don't support clearing texture descriptors currently.
|
||||||
|
if (setIndex != PipelineBase.UniformSetIndex && setIndex != PipelineBase.StorageSetIndex)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var dummyBuffer = _dummyBuffer?.GetBuffer().Get(cbs).Value ?? default;
|
var dummyBuffer = _dummyBuffer?.GetBuffer().Get(cbs).Value ?? default;
|
||||||
|
|
||||||
uint stages = _program.Stages;
|
foreach (ResourceBindingSegment segment in _program.ClearSegments[setIndex])
|
||||||
|
|
||||||
while (stages != 0)
|
|
||||||
{
|
{
|
||||||
int stage = BitOperations.TrailingZeroCount(stages);
|
dsc.InitializeBuffers(0, segment.Binding, segment.Count, segment.Type.Convert(), dummyBuffer);
|
||||||
stages &= ~(1u << stage);
|
|
||||||
|
|
||||||
if (setIndex == PipelineBase.UniformSetIndex)
|
|
||||||
{
|
|
||||||
dsc.InitializeBuffers(
|
|
||||||
0,
|
|
||||||
1 + stage * Constants.MaxUniformBuffersPerStage,
|
|
||||||
Constants.MaxUniformBuffersPerStage,
|
|
||||||
DescriptorType.UniformBuffer,
|
|
||||||
dummyBuffer);
|
|
||||||
}
|
|
||||||
else if (setIndex == PipelineBase.StorageSetIndex)
|
|
||||||
{
|
|
||||||
dsc.InitializeBuffers(
|
|
||||||
0,
|
|
||||||
stage * Constants.MaxStorageBuffersPerStage,
|
|
||||||
Constants.MaxStorageBuffersPerStage,
|
|
||||||
DescriptorType.StorageBuffer,
|
|
||||||
dummyBuffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
private uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
||||||
private uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
private uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
||||||
private uint ViewportsCount => (byte)((Id6 >> 54) & 0xFF);
|
private uint ViewportsCount => (byte)((Id6 >> 54) & 0xFF);
|
||||||
private uint ScissorsCount => (byte)((Id7 >> 0) & 0xFF);
|
private uint ScissorsCount => (byte)(Id7 & 0xFF);
|
||||||
private uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
private uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
||||||
private bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
private bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public uint Stages { get; }
|
public uint Stages { get; }
|
||||||
|
|
||||||
|
public ResourceBindingSegment[][] ClearSegments { get; }
|
||||||
public ResourceBindingSegment[][] BindingSegments { get; }
|
public ResourceBindingSegment[][] BindingSegments { get; }
|
||||||
|
|
||||||
public ProgramLinkStatus LinkStatus { get; private set; }
|
public ProgramLinkStatus LinkStatus { get; private set; }
|
||||||
@@ -115,6 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Stages = stages;
|
Stages = stages;
|
||||||
|
|
||||||
|
ClearSegments = BuildClearSegments(resourceLayout.Sets);
|
||||||
BindingSegments = BuildBindingSegments(resourceLayout.SetUsages);
|
BindingSegments = BuildBindingSegments(resourceLayout.SetUsages);
|
||||||
|
|
||||||
_compileTask = Task.CompletedTask;
|
_compileTask = Task.CompletedTask;
|
||||||
@@ -135,6 +137,60 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_firstBackgroundUse = !fromCache;
|
_firstBackgroundUse = !fromCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ResourceBindingSegment[][] BuildClearSegments(ReadOnlyCollection<ResourceDescriptorCollection> sets)
|
||||||
|
{
|
||||||
|
ResourceBindingSegment[][] segments = new ResourceBindingSegment[sets.Count][];
|
||||||
|
|
||||||
|
for (int setIndex = 0; setIndex < sets.Count; setIndex++)
|
||||||
|
{
|
||||||
|
List<ResourceBindingSegment> currentSegments = new List<ResourceBindingSegment>();
|
||||||
|
|
||||||
|
ResourceDescriptor currentDescriptor = default;
|
||||||
|
int currentCount = 0;
|
||||||
|
|
||||||
|
for (int index = 0; index < sets[setIndex].Descriptors.Count; index++)
|
||||||
|
{
|
||||||
|
ResourceDescriptor descriptor = sets[setIndex].Descriptors[index];
|
||||||
|
|
||||||
|
if (currentDescriptor.Binding + currentCount != descriptor.Binding ||
|
||||||
|
currentDescriptor.Type != descriptor.Type ||
|
||||||
|
currentDescriptor.Stages != descriptor.Stages)
|
||||||
|
{
|
||||||
|
if (currentCount != 0)
|
||||||
|
{
|
||||||
|
currentSegments.Add(new ResourceBindingSegment(
|
||||||
|
currentDescriptor.Binding,
|
||||||
|
currentCount,
|
||||||
|
currentDescriptor.Type,
|
||||||
|
currentDescriptor.Stages,
|
||||||
|
ResourceAccess.ReadWrite));
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDescriptor = descriptor;
|
||||||
|
currentCount = descriptor.Count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentCount += descriptor.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentCount != 0)
|
||||||
|
{
|
||||||
|
currentSegments.Add(new ResourceBindingSegment(
|
||||||
|
currentDescriptor.Binding,
|
||||||
|
currentCount,
|
||||||
|
currentDescriptor.Type,
|
||||||
|
currentDescriptor.Stages,
|
||||||
|
ResourceAccess.ReadWrite));
|
||||||
|
}
|
||||||
|
|
||||||
|
segments[setIndex] = currentSegments.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return segments;
|
||||||
|
}
|
||||||
|
|
||||||
private static ResourceBindingSegment[][] BuildBindingSegments(ReadOnlyCollection<ResourceUsageCollection> setUsages)
|
private static ResourceBindingSegment[][] BuildBindingSegments(ReadOnlyCollection<ResourceUsageCollection> setUsages)
|
||||||
{
|
{
|
||||||
ResourceBindingSegment[][] segments = new ResourceBindingSegment[setUsages.Count][];
|
ResourceBindingSegment[][] segments = new ResourceBindingSegment[setUsages.Count][];
|
||||||
|
@@ -589,6 +589,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
supportsFragmentShaderOrderingIntel: false,
|
supportsFragmentShaderOrderingIntel: false,
|
||||||
supportsGeometryShader: Capabilities.SupportsGeometryShader,
|
supportsGeometryShader: Capabilities.SupportsGeometryShader,
|
||||||
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
|
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
|
||||||
|
supportsTransformFeedback: Capabilities.SupportsTransformFeedback,
|
||||||
supportsImageLoadFormatted: features2.Features.ShaderStorageImageReadWithoutFormat,
|
supportsImageLoadFormatted: features2.Features.ShaderStorageImageReadWithoutFormat,
|
||||||
supportsLayerVertexTessellation: featuresVk12.ShaderOutputLayer,
|
supportsLayerVertexTessellation: featuresVk12.ShaderOutputLayer,
|
||||||
supportsMismatchingViewFormat: true,
|
supportsMismatchingViewFormat: true,
|
||||||
|
@@ -181,7 +181,7 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_locationEntries.ContainsKey(storageId) && _locationEntries[storageId]?.Count == 0)
|
if (_locationEntries.TryGetValue(storageId, out var locationEntriesItem) && locationEntriesItem?.Count == 0)
|
||||||
{
|
{
|
||||||
_locationEntries.Remove(storageId);
|
_locationEntries.Remove(storageId);
|
||||||
}
|
}
|
||||||
@@ -347,9 +347,9 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
if (_contentDictionary.ContainsKey((titleId, contentType)))
|
if (_contentDictionary.TryGetValue((titleId, contentType), out var contentDictionaryItem))
|
||||||
{
|
{
|
||||||
return UInt128Utils.FromHex(_contentDictionary[(titleId, contentType)]);
|
return UInt128Utils.FromHex(contentDictionaryItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,9 +719,9 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
|
|
||||||
Nca nca = new Nca(_virtualFileSystem.KeySet, storage);
|
Nca nca = new Nca(_virtualFileSystem.KeySet, storage);
|
||||||
|
|
||||||
if (updateNcas.ContainsKey(nca.Header.TitleId))
|
if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem))
|
||||||
{
|
{
|
||||||
updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullName));
|
updateNcasItem.Add((nca.Header.ContentType, entry.FullName));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -732,10 +732,8 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateNcas.ContainsKey(SystemUpdateTitleId))
|
if (updateNcas.TryGetValue(SystemUpdateTitleId, out var ncaEntry))
|
||||||
{
|
{
|
||||||
var ncaEntry = updateNcas[SystemUpdateTitleId];
|
|
||||||
|
|
||||||
string metaPath = ncaEntry.Find(x => x.type == NcaContentType.Meta).path;
|
string metaPath = ncaEntry.Find(x => x.type == NcaContentType.Meta).path;
|
||||||
|
|
||||||
CnmtContentMetaEntry[] metaEntries = null;
|
CnmtContentMetaEntry[] metaEntries = null;
|
||||||
@@ -770,9 +768,9 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
throw new FileNotFoundException("System update title was not found in the firmware package.");
|
throw new FileNotFoundException("System update title was not found in the firmware package.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateNcas.ContainsKey(SystemVersionTitleId))
|
if (updateNcas.TryGetValue(SystemVersionTitleId, out var updateNcasItem))
|
||||||
{
|
{
|
||||||
string versionEntry = updateNcas[SystemVersionTitleId].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)))
|
||||||
{
|
{
|
||||||
@@ -916,9 +914,9 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateNcas.ContainsKey(nca.Header.TitleId))
|
if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem))
|
||||||
{
|
{
|
||||||
updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullPath));
|
updateNcasItem.Add((nca.Header.ContentType, entry.FullPath));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||||
|
{
|
||||||
|
public static partial class CJKCharacterValidation
|
||||||
|
{
|
||||||
|
public static bool IsCJK(char value)
|
||||||
|
{
|
||||||
|
Regex regex = CJKRegex();
|
||||||
|
|
||||||
|
return regex.IsMatch(value.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")]
|
||||||
|
private static partial Regex CJKRegex();
|
||||||
|
}
|
||||||
|
}
|
@@ -6,22 +6,30 @@
|
|||||||
public enum KeyboardMode : uint
|
public enum KeyboardMode : uint
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A full alpha-numeric keyboard.
|
/// All UTF-16 characters allowed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Default = 0,
|
Default = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Number pad.
|
/// Only numbers allowed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
NumbersOnly = 1,
|
NumbersOnly = 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ASCII characters keyboard.
|
/// Only ASCII characters allowed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ASCII = 2,
|
ASCII = 2,
|
||||||
|
|
||||||
FullLatin = 3,
|
/// <summary>
|
||||||
Alphabet = 4,
|
/// Synonymous with default.
|
||||||
|
/// </summary>
|
||||||
|
FullLatin = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All UTF-16 characters except CJK characters allowed.
|
||||||
|
/// </summary>
|
||||||
|
Alphabet = 4,
|
||||||
|
|
||||||
SimplifiedChinese = 5,
|
SimplifiedChinese = 5,
|
||||||
TraditionalChinese = 6,
|
TraditionalChinese = 6,
|
||||||
Korean = 7,
|
Korean = 7,
|
||||||
|
@@ -137,7 +137,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||||||
|
|
||||||
public void CancelHandleReservation(int handle)
|
public void CancelHandleReservation(int handle)
|
||||||
{
|
{
|
||||||
int index = (handle >> 0) & 0x7fff;
|
int index = handle & 0x7fff;
|
||||||
|
|
||||||
lock (_table)
|
lock (_table)
|
||||||
{
|
{
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Kernel.Threading
|
namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||||
{
|
{
|
||||||
|
[Flags]
|
||||||
enum ThreadSchedState : ushort
|
enum ThreadSchedState : ushort
|
||||||
{
|
{
|
||||||
LowMask = 0xf,
|
LowMask = 0xf,
|
||||||
|
@@ -154,7 +154,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static DirectoryInfo FindTitleDir(DirectoryInfo contentsDir, string titleId)
|
private static DirectoryInfo FindTitleDir(DirectoryInfo contentsDir, string titleId)
|
||||||
=> contentsDir.EnumerateDirectories($"{titleId}*", DirEnumOptions).FirstOrDefault();
|
=> contentsDir.EnumerateDirectories(titleId, DirEnumOptions).FirstOrDefault();
|
||||||
|
|
||||||
private static void AddModsFromDirectory(ModCache mods, DirectoryInfo dir, string titleId)
|
private static void AddModsFromDirectory(ModCache mods, DirectoryInfo dir, string titleId)
|
||||||
{
|
{
|
||||||
|
@@ -1,8 +1,29 @@
|
|||||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
{
|
{
|
||||||
[Service("hidbus")]
|
[Service("hidbus")]
|
||||||
class IHidbusServer : IpcService
|
class IHidbusServer : IpcService
|
||||||
{
|
{
|
||||||
public IHidbusServer(ServiceCtx context) { }
|
public IHidbusServer(ServiceCtx context) { }
|
||||||
|
|
||||||
|
[CommandCmif(1)]
|
||||||
|
// GetBusHandle(nn::hid::NpadIdType, nn::hidbus::BusType, nn::applet::AppletResourceUserId) -> (bool HasHandle, nn::hidbus::BusHandle)
|
||||||
|
public ResultCode GetBusHandle(ServiceCtx context)
|
||||||
|
{
|
||||||
|
NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadInt32();
|
||||||
|
context.RequestData.BaseStream.Position += 4; // Padding
|
||||||
|
BusType busType = (BusType)context.RequestData.ReadInt64();
|
||||||
|
long appletResourceUserId = context.RequestData.ReadInt64();
|
||||||
|
|
||||||
|
context.ResponseData.Write(false);
|
||||||
|
context.ResponseData.BaseStream.Position += 7; // Padding
|
||||||
|
context.ResponseData.WriteStruct(new BusHandle());
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadIdType, busType, appletResourceUserId });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
14
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs
Normal file
14
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct BusHandle
|
||||||
|
{
|
||||||
|
public int AbstractedPadId;
|
||||||
|
public byte InternalIndex;
|
||||||
|
public byte PlayerNumber;
|
||||||
|
public byte BusTypeId;
|
||||||
|
public byte IsValid;
|
||||||
|
}
|
||||||
|
}
|
9
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs
Normal file
9
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
|
{
|
||||||
|
public enum BusType : long
|
||||||
|
{
|
||||||
|
LeftJoyRail = 0,
|
||||||
|
RightJoyRail = 1,
|
||||||
|
InternalBus = 2
|
||||||
|
}
|
||||||
|
}
|
@@ -17,7 +17,7 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
|||||||
private const int MessageLengthLimit = 5000;
|
private const int MessageLengthLimit = 5000;
|
||||||
|
|
||||||
private readonly LogService _log;
|
private readonly LogService _log;
|
||||||
private readonly ulong _pid;
|
private readonly ulong _pid;
|
||||||
|
|
||||||
private LogPacket _logPacket;
|
private LogPacket _logPacket;
|
||||||
|
|
||||||
@@ -74,8 +74,12 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
|||||||
|
|
||||||
private bool LogImpl(ReadOnlySpan<byte> message)
|
private bool LogImpl(ReadOnlySpan<byte> message)
|
||||||
{
|
{
|
||||||
SpanReader reader = new(message);
|
SpanReader reader = new(message);
|
||||||
LogPacketHeader header = reader.Read<LogPacketHeader>();
|
|
||||||
|
if (!reader.TryRead(out LogPacketHeader header))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool isHeadPacket = (header.Flags & LogPacketFlags.IsHead) != 0;
|
bool isHeadPacket = (header.Flags & LogPacketFlags.IsHead) != 0;
|
||||||
bool isTailPacket = (header.Flags & LogPacketFlags.IsTail) != 0;
|
bool isTailPacket = (header.Flags & LogPacketFlags.IsTail) != 0;
|
||||||
@@ -84,8 +88,10 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
|||||||
|
|
||||||
while (reader.Length > 0)
|
while (reader.Length > 0)
|
||||||
{
|
{
|
||||||
int type = ReadUleb128(ref reader);
|
if (!TryReadUleb128(ref reader, out int type) || !TryReadUleb128(ref reader, out int size))
|
||||||
int size = ReadUleb128(ref reader);
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
LogDataChunkKey key = (LogDataChunkKey)type;
|
LogDataChunkKey key = (LogDataChunkKey)type;
|
||||||
|
|
||||||
@@ -101,15 +107,24 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
|||||||
}
|
}
|
||||||
else if (key == LogDataChunkKey.Line)
|
else if (key == LogDataChunkKey.Line)
|
||||||
{
|
{
|
||||||
_logPacket.Line = reader.Read<int>();
|
if (!reader.TryRead<int>(out _logPacket.Line))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (key == LogDataChunkKey.DropCount)
|
else if (key == LogDataChunkKey.DropCount)
|
||||||
{
|
{
|
||||||
_logPacket.DropCount = reader.Read<long>();
|
if (!reader.TryRead<long>(out _logPacket.DropCount))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (key == LogDataChunkKey.Time)
|
else if (key == LogDataChunkKey.Time)
|
||||||
{
|
{
|
||||||
_logPacket.Time = reader.Read<long>();
|
if (!reader.TryRead<long>(out _logPacket.Time))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (key == LogDataChunkKey.Message)
|
else if (key == LogDataChunkKey.Message)
|
||||||
{
|
{
|
||||||
@@ -154,23 +169,25 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
|||||||
return isTailPacket;
|
return isTailPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ReadUleb128(ref SpanReader reader)
|
private static bool TryReadUleb128(ref SpanReader reader, out int result)
|
||||||
{
|
{
|
||||||
int result = 0;
|
result = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
byte encoded;
|
byte encoded;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
encoded = reader.Read<byte>();
|
if (!reader.TryRead<byte>(out encoded))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
result += (encoded & 0x7F) << (7 * count);
|
result += (encoded & 0x7F) << (7 * count);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
} while ((encoded & 0x80) != 0);
|
} while ((encoded & 0x80) != 0);
|
||||||
|
|
||||||
return result;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -338,12 +338,10 @@ namespace Ryujinx.Input.Motion.CemuHook
|
|||||||
{
|
{
|
||||||
int slot = inputData.Shared.Slot;
|
int slot = inputData.Shared.Slot;
|
||||||
|
|
||||||
if (_motionData.ContainsKey(clientId))
|
if (_motionData.TryGetValue(clientId, out var motionDataItem))
|
||||||
{
|
{
|
||||||
if (_motionData[clientId].ContainsKey(slot))
|
if (motionDataItem.TryGetValue(slot, out var previousData))
|
||||||
{
|
{
|
||||||
MotionInput previousData = _motionData[clientId][slot];
|
|
||||||
|
|
||||||
previousData.Update(accelerometer, gyroscrope, timestamp, cemuHookConfig.Sensitivity, (float)cemuHookConfig.GyroDeadzone);
|
previousData.Update(accelerometer, gyroscrope, timestamp, cemuHookConfig.Sensitivity, (float)cemuHookConfig.GyroDeadzone);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -352,7 +350,7 @@ namespace Ryujinx.Input.Motion.CemuHook
|
|||||||
|
|
||||||
input.Update(accelerometer, gyroscrope, timestamp, cemuHookConfig.Sensitivity, (float)cemuHookConfig.GyroDeadzone);
|
input.Update(accelerometer, gyroscrope, timestamp, cemuHookConfig.Sensitivity, (float)cemuHookConfig.GyroDeadzone);
|
||||||
|
|
||||||
_motionData[clientId].Add(slot, input);
|
motionDataItem.Add(slot, input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -7,7 +7,7 @@ namespace Ryujinx.Tests.Memory
|
|||||||
{
|
{
|
||||||
public class Tests
|
public class Tests
|
||||||
{
|
{
|
||||||
private const ulong MemorySize = 0x8000;
|
private static readonly ulong MemorySize = MemoryBlock.GetPageSize() * 8;
|
||||||
|
|
||||||
private MemoryBlock _memoryBlock;
|
private MemoryBlock _memoryBlock;
|
||||||
|
|
||||||
@@ -44,14 +44,17 @@ namespace Ryujinx.Tests.Memory
|
|||||||
[Platform(Exclude = "MacOsX")]
|
[Platform(Exclude = "MacOsX")]
|
||||||
public void Test_Alias()
|
public void Test_Alias()
|
||||||
{
|
{
|
||||||
using MemoryBlock backing = new MemoryBlock(0x10000, MemoryAllocationFlags.Mirrorable);
|
ulong pageSize = MemoryBlock.GetPageSize();
|
||||||
using MemoryBlock toAlias = new MemoryBlock(0x10000, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
|
ulong blockSize = MemoryBlock.GetPageSize() * 16;
|
||||||
|
|
||||||
toAlias.MapView(backing, 0x1000, 0, 0x4000);
|
using MemoryBlock backing = new MemoryBlock(blockSize, MemoryAllocationFlags.Mirrorable);
|
||||||
toAlias.UnmapView(backing, 0x3000, 0x1000);
|
using MemoryBlock toAlias = new MemoryBlock(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
|
||||||
|
|
||||||
|
toAlias.MapView(backing, pageSize, 0, pageSize * 4);
|
||||||
|
toAlias.UnmapView(backing, pageSize * 3, pageSize);
|
||||||
|
|
||||||
toAlias.Write(0, 0xbadc0de);
|
toAlias.Write(0, 0xbadc0de);
|
||||||
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, 0x1000), 0xbadc0de);
|
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (int)pageSize), 0xbadc0de);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -59,8 +62,12 @@ namespace Ryujinx.Tests.Memory
|
|||||||
[Platform(Exclude = "MacOsX")]
|
[Platform(Exclude = "MacOsX")]
|
||||||
public void Test_AliasRandom()
|
public void Test_AliasRandom()
|
||||||
{
|
{
|
||||||
using MemoryBlock backing = new MemoryBlock(0x80000, MemoryAllocationFlags.Mirrorable);
|
ulong pageSize = MemoryBlock.GetPageSize();
|
||||||
using MemoryBlock toAlias = new MemoryBlock(0x80000, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
|
int pageBits = (int)ulong.Log2(pageSize);
|
||||||
|
ulong blockSize = MemoryBlock.GetPageSize() * 128;
|
||||||
|
|
||||||
|
using MemoryBlock backing = new MemoryBlock(blockSize, MemoryAllocationFlags.Mirrorable);
|
||||||
|
using MemoryBlock toAlias = new MemoryBlock(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
|
||||||
|
|
||||||
Random rng = new Random(123);
|
Random rng = new Random(123);
|
||||||
|
|
||||||
@@ -72,16 +79,16 @@ namespace Ryujinx.Tests.Memory
|
|||||||
|
|
||||||
if ((rng.Next() & 1) != 0)
|
if ((rng.Next() & 1) != 0)
|
||||||
{
|
{
|
||||||
toAlias.MapView(backing, (ulong)srcPage << 12, (ulong)dstPage << 12, (ulong)pages << 12);
|
toAlias.MapView(backing, (ulong)srcPage << pageBits, (ulong)dstPage << pageBits, (ulong)pages << pageBits);
|
||||||
|
|
||||||
int offset = rng.Next(0, 0x1000 - sizeof(int));
|
int offset = rng.Next(0, (int)pageSize - sizeof(int));
|
||||||
|
|
||||||
toAlias.Write((ulong)((dstPage << 12) + offset), 0xbadc0de);
|
toAlias.Write((ulong)((dstPage << pageBits) + offset), 0xbadc0de);
|
||||||
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << 12) + offset), 0xbadc0de);
|
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << pageBits) + offset), 0xbadc0de);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
toAlias.UnmapView(backing, (ulong)dstPage << 12, (ulong)pages << 12);
|
toAlias.UnmapView(backing, (ulong)dstPage << pageBits, (ulong)pages << pageBits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,7 +98,7 @@ namespace Ryujinx.Tests.Memory
|
|||||||
[Platform(Exclude = "MacOsX")]
|
[Platform(Exclude = "MacOsX")]
|
||||||
public void Test_AliasMapLeak()
|
public void Test_AliasMapLeak()
|
||||||
{
|
{
|
||||||
ulong pageSize = 4096;
|
ulong pageSize = MemoryBlock.GetPageSize();
|
||||||
ulong size = 100000 * pageSize; // The mappings limit on Linux is usually around 65K, so let's make sure we are above that.
|
ulong size = 100000 * pageSize; // The mappings limit on Linux is usually around 65K, so let's make sure we are above that.
|
||||||
|
|
||||||
using MemoryBlock backing = new MemoryBlock(pageSize, MemoryAllocationFlags.Mirrorable);
|
using MemoryBlock backing = new MemoryBlock(pageSize, MemoryAllocationFlags.Mirrorable);
|
||||||
|
@@ -13,9 +13,9 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class CpuTest
|
public class CpuTest
|
||||||
{
|
{
|
||||||
protected const ulong Size = 0x1000;
|
protected static readonly ulong Size = MemoryBlock.GetPageSize();
|
||||||
protected const ulong CodeBaseAddress = 0x1000;
|
protected static ulong CodeBaseAddress = Size;
|
||||||
protected const ulong DataBaseAddress = CodeBaseAddress + Size;
|
protected static ulong DataBaseAddress = CodeBaseAddress + Size;
|
||||||
|
|
||||||
private static bool Ignore_FpcrFz = false;
|
private static bool Ignore_FpcrFz = false;
|
||||||
private static bool Ignore_FpcrDn = false;
|
private static bool Ignore_FpcrDn = false;
|
||||||
@@ -39,12 +39,24 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_currAddress = CodeBaseAddress;
|
int pageBits = (int)ulong.Log2(Size);
|
||||||
|
|
||||||
_ram = new MemoryBlock(Size * 2);
|
_ram = new MemoryBlock(Size * 2);
|
||||||
_memory = new MemoryManager(_ram, 1ul << 16);
|
_memory = new MemoryManager(_ram, 1ul << (pageBits + 4));
|
||||||
_memory.IncrementReferenceCount();
|
_memory.IncrementReferenceCount();
|
||||||
_memory.Map(CodeBaseAddress, 0, Size * 2, MemoryMapFlags.Private);
|
|
||||||
|
// Some tests depends on hardcoded address that were computed for 4KiB.
|
||||||
|
// We change the layout on non 4KiB platforms to keep compat here.
|
||||||
|
if (Size > 0x1000)
|
||||||
|
{
|
||||||
|
DataBaseAddress = 0;
|
||||||
|
CodeBaseAddress = Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currAddress = CodeBaseAddress;
|
||||||
|
|
||||||
|
_memory.Map(CodeBaseAddress, 0, Size, MemoryMapFlags.Private);
|
||||||
|
_memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private);
|
||||||
|
|
||||||
_context = CpuContext.CreateExecutionContext();
|
_context = CpuContext.CreateExecutionContext();
|
||||||
Translator.IsReadyForTranslation.Set();
|
Translator.IsReadyForTranslation.Set();
|
||||||
|
@@ -13,9 +13,9 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class CpuTest32
|
public class CpuTest32
|
||||||
{
|
{
|
||||||
protected const uint Size = 0x1000;
|
protected static readonly uint Size = (uint)MemoryBlock.GetPageSize();
|
||||||
protected const uint CodeBaseAddress = 0x1000;
|
protected static uint CodeBaseAddress = Size;
|
||||||
protected const uint DataBaseAddress = CodeBaseAddress + Size;
|
protected static uint DataBaseAddress = CodeBaseAddress + Size;
|
||||||
|
|
||||||
private uint _currAddress;
|
private uint _currAddress;
|
||||||
|
|
||||||
@@ -33,12 +33,24 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_currAddress = CodeBaseAddress;
|
int pageBits = (int)ulong.Log2(Size);
|
||||||
|
|
||||||
_ram = new MemoryBlock(Size * 2);
|
_ram = new MemoryBlock(Size * 2);
|
||||||
_memory = new MemoryManager(_ram, 1ul << 16);
|
_memory = new MemoryManager(_ram, 1ul << (pageBits + 4));
|
||||||
_memory.IncrementReferenceCount();
|
_memory.IncrementReferenceCount();
|
||||||
_memory.Map(CodeBaseAddress, 0, Size * 2, MemoryMapFlags.Private);
|
|
||||||
|
// Some tests depends on hardcoded address that were computed for 4KiB.
|
||||||
|
// We change the layout on non 4KiB platforms to keep compat here.
|
||||||
|
if (Size > 0x1000)
|
||||||
|
{
|
||||||
|
DataBaseAddress = 0;
|
||||||
|
CodeBaseAddress = Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currAddress = CodeBaseAddress;
|
||||||
|
|
||||||
|
_memory.Map(CodeBaseAddress, 0, Size, MemoryMapFlags.Private);
|
||||||
|
_memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private);
|
||||||
|
|
||||||
_context = CpuContext.CreateExecutionContext();
|
_context = CpuContext.CreateExecutionContext();
|
||||||
_context.IsAarch32 = true;
|
_context.IsAarch32 = true;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#define SimdMemory32
|
#define SimdMemory32
|
||||||
|
|
||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
|
using Ryujinx.Memory;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Category("SimdMemory32")]
|
[Category("SimdMemory32")]
|
||||||
public sealed class CpuTestSimdMemory32 : CpuTest32
|
public sealed class CpuTestSimdMemory32 : CpuTest32
|
||||||
{
|
{
|
||||||
|
private static readonly uint TestOffset = DataBaseAddress + 0x500;
|
||||||
#if SimdMemory32
|
#if SimdMemory32
|
||||||
|
|
||||||
private uint[] _ldStModes =
|
private uint[] _ldStModes =
|
||||||
@@ -42,7 +44,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Range(0u, 3u)] uint n,
|
[Range(0u, 3u)] uint n,
|
||||||
[Values(0x0u)] uint offset)
|
[Values(0x0u)] uint offset)
|
||||||
{
|
{
|
||||||
var data = GenerateVectorSequence(0x1000);
|
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||||
SetWorkingMemory(0, data);
|
SetWorkingMemory(0, data);
|
||||||
|
|
||||||
uint opcode = 0xf4a00000u; // VLD1.8 {D0[0]}, [R0], R0
|
uint opcode = 0xf4a00000u; // VLD1.8 {D0[0]}, [R0], R0
|
||||||
@@ -58,7 +60,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
|
|
||||||
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
|
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
|
||||||
|
|
||||||
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500);
|
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
@@ -72,7 +74,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Values] bool t,
|
[Values] bool t,
|
||||||
[Values(0x0u)] uint offset)
|
[Values(0x0u)] uint offset)
|
||||||
{
|
{
|
||||||
var data = GenerateVectorSequence(0x1000);
|
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||||
SetWorkingMemory(0, data);
|
SetWorkingMemory(0, data);
|
||||||
|
|
||||||
uint opcode = 0xf4a00c00u; // VLD1.8 {D0[0]}, [R0], R0
|
uint opcode = 0xf4a00c00u; // VLD1.8 {D0[0]}, [R0], R0
|
||||||
@@ -85,7 +87,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
|
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
|
||||||
if (t) opcode |= 1 << 5;
|
if (t) opcode |= 1 << 5;
|
||||||
|
|
||||||
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500);
|
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
@@ -98,7 +100,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Range(0u, 10u)] uint mode,
|
[Range(0u, 10u)] uint mode,
|
||||||
[Values(0x0u)] uint offset)
|
[Values(0x0u)] uint offset)
|
||||||
{
|
{
|
||||||
var data = GenerateVectorSequence(0x1000);
|
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||||
SetWorkingMemory(0, data);
|
SetWorkingMemory(0, data);
|
||||||
|
|
||||||
uint opcode = 0xf4200000u; // VLD4.8 {D0, D1, D2, D3}, [R0], R0
|
uint opcode = 0xf4200000u; // VLD4.8 {D0, D1, D2, D3}, [R0], R0
|
||||||
@@ -114,7 +116,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
opcode |= ((vd & 0x10) << 18);
|
opcode |= ((vd & 0x10) << 18);
|
||||||
opcode |= ((vd & 0xf) << 12);
|
opcode |= ((vd & 0xf) << 12);
|
||||||
|
|
||||||
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500);
|
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
@@ -128,7 +130,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Range(0u, 3u)] uint n,
|
[Range(0u, 3u)] uint n,
|
||||||
[Values(0x0u)] uint offset)
|
[Values(0x0u)] uint offset)
|
||||||
{
|
{
|
||||||
var data = GenerateVectorSequence(0x1000);
|
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||||
SetWorkingMemory(0, data);
|
SetWorkingMemory(0, data);
|
||||||
|
|
||||||
(V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors();
|
(V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors();
|
||||||
@@ -146,7 +148,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
|
|
||||||
opcode |= (n & 3) << 8; // ST1 is 0, ST2 is 1 etc.
|
opcode |= (n & 3) << 8; // ST1 is 0, ST2 is 1 etc.
|
||||||
|
|
||||||
SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500);
|
SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
@@ -159,7 +161,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Range(0u, 10u)] uint mode,
|
[Range(0u, 10u)] uint mode,
|
||||||
[Values(0x0u)] uint offset)
|
[Values(0x0u)] uint offset)
|
||||||
{
|
{
|
||||||
var data = GenerateVectorSequence(0x1000);
|
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||||
SetWorkingMemory(0, data);
|
SetWorkingMemory(0, data);
|
||||||
|
|
||||||
(V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors();
|
(V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors();
|
||||||
@@ -177,7 +179,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
opcode |= ((vd & 0x10) << 18);
|
opcode |= ((vd & 0x10) << 18);
|
||||||
opcode |= ((vd & 0xf) << 12);
|
opcode |= ((vd & 0xf) << 12);
|
||||||
|
|
||||||
SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500);
|
SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
@@ -189,7 +191,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Values(0x1u, 0x32u)] uint regs,
|
[Values(0x1u, 0x32u)] uint regs,
|
||||||
[Values] bool single)
|
[Values] bool single)
|
||||||
{
|
{
|
||||||
var data = GenerateVectorSequence(0x1000);
|
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||||
SetWorkingMemory(0, data);
|
SetWorkingMemory(0, data);
|
||||||
|
|
||||||
uint opcode = 0xec100a00u; // VST4.8 {D0, D1, D2, D3}, [R0], R0
|
uint opcode = 0xec100a00u; // VST4.8 {D0, D1, D2, D3}, [R0], R0
|
||||||
@@ -225,7 +227,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
|
|
||||||
opcode |= regs & 0xff;
|
opcode |= regs & 0xff;
|
||||||
|
|
||||||
SingleOpcode(opcode, r0: 0x2500, sp: 0x2500);
|
SingleOpcode(opcode, r0: TestOffset, sp: TestOffset);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
@@ -237,7 +239,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Values(0x0u)] uint imm,
|
[Values(0x0u)] uint imm,
|
||||||
[Values] bool sub)
|
[Values] bool sub)
|
||||||
{
|
{
|
||||||
var data = GenerateVectorSequence(0x1000);
|
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||||
SetWorkingMemory(0, data);
|
SetWorkingMemory(0, data);
|
||||||
|
|
||||||
uint opcode = 0xed900a00u; // VLDR.32 S0, [R0, #0]
|
uint opcode = 0xed900a00u; // VLDR.32 S0, [R0, #0]
|
||||||
@@ -260,7 +262,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
}
|
}
|
||||||
opcode |= imm & 0xff;
|
opcode |= imm & 0xff;
|
||||||
|
|
||||||
SingleOpcode(opcode, r0: 0x2500);
|
SingleOpcode(opcode, r0: TestOffset);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
@@ -272,7 +274,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Values(0x0u)] uint imm,
|
[Values(0x0u)] uint imm,
|
||||||
[Values] bool sub)
|
[Values] bool sub)
|
||||||
{
|
{
|
||||||
var data = GenerateVectorSequence(0x1000);
|
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||||
SetWorkingMemory(0, data);
|
SetWorkingMemory(0, data);
|
||||||
|
|
||||||
uint opcode = 0xed800a00u; // VSTR.32 S0, [R0, #0]
|
uint opcode = 0xed800a00u; // VSTR.32 S0, [R0, #0]
|
||||||
@@ -297,7 +299,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
|
|
||||||
(V128 vec1, V128 vec2, _, _) = GenerateTestVectors();
|
(V128 vec1, V128 vec2, _, _) = GenerateTestVectors();
|
||||||
|
|
||||||
SingleOpcode(opcode, r0: 0x2500, v0: vec1, v1: vec2);
|
SingleOpcode(opcode, r0: TestOffset, v0: vec1, v1: vec2);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
@@ -703,6 +704,11 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Values] bool q,
|
[Values] bool q,
|
||||||
[Values] bool u)
|
[Values] bool u)
|
||||||
{
|
{
|
||||||
|
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||||
|
{
|
||||||
|
Assert.Ignore("Unicorn on ARM64 crash while executing this test");
|
||||||
|
}
|
||||||
|
|
||||||
uint opcode = 0xf2000400u; // VSHL.S8 D0, D0, D0
|
uint opcode = 0xf2000400u; // VSHL.S8 D0, D0, D0
|
||||||
if (q)
|
if (q)
|
||||||
{
|
{
|
||||||
|
@@ -109,7 +109,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
|
|
||||||
ExecuteOpcodes(runUnicorn: false);
|
ExecuteOpcodes(runUnicorn: false);
|
||||||
|
|
||||||
Assert.That(GetContext().GetX(0), Is.EqualTo(0x1005));
|
Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x5));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -133,7 +133,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
|
|
||||||
ExecuteOpcodes(runUnicorn: false);
|
ExecuteOpcodes(runUnicorn: false);
|
||||||
|
|
||||||
Assert.That(GetContext().GetX(0), Is.EqualTo(0x1005));
|
Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x5));
|
||||||
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
|
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
|
|
||||||
ExecuteOpcodes(runUnicorn: false);
|
ExecuteOpcodes(runUnicorn: false);
|
||||||
|
|
||||||
Assert.That(GetContext().GetX(0), Is.EqualTo(0x1007));
|
Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x7));
|
||||||
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
|
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -268,6 +268,12 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestRandomTestCases([ValueSource(nameof(RandomTestCases))] PrecomputedThumbTestCase test)
|
public void TestRandomTestCases([ValueSource(nameof(RandomTestCases))] PrecomputedThumbTestCase test)
|
||||||
{
|
{
|
||||||
|
if (Size != 0x1000)
|
||||||
|
{
|
||||||
|
// TODO: Change it to depend on DataBaseAddress instead.
|
||||||
|
Assert.Ignore("This test currently only support 4KiB page size");
|
||||||
|
}
|
||||||
|
|
||||||
RunPrecomputedTestCase(test);
|
RunPrecomputedTestCase(test);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,10 +11,10 @@ namespace Ryujinx.Ui.Common.Helper
|
|||||||
{
|
{
|
||||||
public static partial class FileAssociationHelper
|
public static partial class FileAssociationHelper
|
||||||
{
|
{
|
||||||
private static string[] _fileExtensions = new string[] { ".nca", ".nro", ".nso", ".nsp", ".xci" };
|
private static readonly string[] _fileExtensions = { ".nca", ".nro", ".nso", ".nsp", ".xci" };
|
||||||
|
|
||||||
[SupportedOSPlatform("linux")]
|
[SupportedOSPlatform("linux")]
|
||||||
private static string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
|
private static readonly string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
|
||||||
|
|
||||||
private const int SHCNE_ASSOCCHANGED = 0x8000000;
|
private const int SHCNE_ASSOCCHANGED = 0x8000000;
|
||||||
private const int SHCNF_FLUSH = 0x1000;
|
private const int SHCNF_FLUSH = 0x1000;
|
||||||
@@ -32,7 +32,7 @@ namespace Ryujinx.Ui.Common.Helper
|
|||||||
{
|
{
|
||||||
string installKeyword = uninstall ? "uninstall" : "install";
|
string installKeyword = uninstall ? "uninstall" : "install";
|
||||||
|
|
||||||
if (!AreMimeTypesRegisteredLinux())
|
if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux()))
|
||||||
{
|
{
|
||||||
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
|
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
|
||||||
string additionalArgs = !uninstall ? "--novendor" : "";
|
string additionalArgs = !uninstall ? "--novendor" : "";
|
||||||
@@ -81,9 +81,9 @@ namespace Ryujinx.Ui.Common.Helper
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
key.OpenSubKey(@"shell\open\command");
|
var openCmd = key.OpenSubKey(@"shell\open\command");
|
||||||
|
|
||||||
string keyValue = (string)key.GetValue("");
|
string keyValue = (string)openCmd.GetValue("");
|
||||||
|
|
||||||
return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName));
|
return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName));
|
||||||
}
|
}
|
||||||
@@ -107,30 +107,31 @@ namespace Ryujinx.Ui.Common.Helper
|
|||||||
|
|
||||||
if (uninstall)
|
if (uninstall)
|
||||||
{
|
{
|
||||||
|
// If the types don't already exist, there's nothing to do and we can call this operation successful.
|
||||||
if (!AreMimeTypesRegisteredWindows())
|
if (!AreMimeTypesRegisteredWindows())
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
Logger.Debug?.Print(LogClass.Application, $"Removing type association {ext}");
|
||||||
Registry.CurrentUser.DeleteSubKeyTree(keyString);
|
Registry.CurrentUser.DeleteSubKeyTree(keyString);
|
||||||
|
Logger.Debug?.Print(LogClass.Application, $"Removed type association {ext}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RegistryKey key = Registry.CurrentUser.CreateSubKey(keyString);
|
using var key = Registry.CurrentUser.CreateSubKey(keyString);
|
||||||
|
|
||||||
if (key is null)
|
if (key is null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
key.CreateSubKey(@"shell\open\command");
|
Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}");
|
||||||
|
using var openCmd = key.CreateSubKey(@"shell\open\command");
|
||||||
|
openCmd.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
|
||||||
|
Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}");
|
||||||
|
|
||||||
key.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
|
|
||||||
key.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify Explorer the file association has been changed.
|
|
||||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +142,9 @@ namespace Ryujinx.Ui.Common.Helper
|
|||||||
registered |= RegisterExtension(ext, uninstall);
|
registered |= RegisterExtension(ext, uninstall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify Explorer the file association has been changed.
|
||||||
|
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
|
||||||
return registered;
|
return registered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -93,8 +93,8 @@ namespace Ryujinx.Ui.Applet
|
|||||||
_checkInput = text => text.All(char.IsDigit);
|
_checkInput = text => text.All(char.IsDigit);
|
||||||
break;
|
break;
|
||||||
case KeyboardMode.Alphabet:
|
case KeyboardMode.Alphabet:
|
||||||
_validationInfoText += "<i>Must be alphabets only.</i>";
|
_validationInfoText += "<i>Must be non CJK-characters only.</i>";
|
||||||
_checkInput = text => text.All(char.IsAsciiLetter);
|
_checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value));
|
||||||
break;
|
break;
|
||||||
case KeyboardMode.ASCII:
|
case KeyboardMode.ASCII:
|
||||||
_validationInfoText += "<i>Must be ASCII text only.</i>";
|
_validationInfoText += "<i>Must be ASCII text only.</i>";
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.OpenGL;
|
using Ryujinx.Graphics.OpenGL;
|
||||||
using Ryujinx.Input.HLE;
|
using Ryujinx.Input.HLE;
|
||||||
using SPB.Graphics;
|
using SPB.Graphics;
|
||||||
|
using SPB.Graphics.Exceptions;
|
||||||
using SPB.Graphics.OpenGL;
|
using SPB.Graphics.OpenGL;
|
||||||
using SPB.Platform;
|
using SPB.Platform;
|
||||||
using SPB.Platform.GLX;
|
using SPB.Platform.GLX;
|
||||||
@@ -112,24 +114,30 @@ namespace Ryujinx.Ui
|
|||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
// Try to bind the OpenGL context before calling the shutdown event
|
// Try to bind the OpenGL context before calling the shutdown event.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_openGLContext?.MakeCurrent(_nativeWindow);
|
_openGLContext?.MakeCurrent(_nativeWindow);
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (ContextException e)
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Ui, $"Failed to bind OpenGL context: {e}");
|
||||||
|
}
|
||||||
|
|
||||||
Device?.DisposeGpu();
|
Device?.DisposeGpu();
|
||||||
NpadManager.Dispose();
|
NpadManager.Dispose();
|
||||||
|
|
||||||
// Unbind context and destroy everything
|
// Unbind context and destroy everything.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_openGLContext?.MakeCurrent(null);
|
_openGLContext?.MakeCurrent(null);
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (ContextException e)
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Ui, $"Failed to unbind OpenGL context: {e}");
|
||||||
|
}
|
||||||
|
|
||||||
_openGLContext?.Dispose();
|
_openGLContext?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user