Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
649d372f7d | |||
f9a538bb0f | |||
f92921a6d1 | |||
32d21ddf17 | |||
82f90704a0 | |||
f978d3726a | |||
6f28c4abad | |||
105c9712c1 | |||
4d804ed45e | |||
4a27d29412 | |||
5bd2c58ad6 | |||
cf4c78b9c8 | |||
52aa4b6c22 | |||
5a02433080 | |||
915a0f7173 | |||
0cc266ff19 | |||
9a1b74799d | |||
638f3761f3 | |||
193ca3c9a2 | |||
eb0bb36bbf | |||
0e95a8271a | |||
76b474e97b | |||
27ee86f33b | |||
f7ec310231 | |||
e94d24f508 | |||
2bf4555591 | |||
86de288142 | |||
f35aa8e9d6 | |||
0e8e735a6d | |||
0003a7c118 | |||
2cdcfe46d8 | |||
fe30c03cac | |||
5813b2e354 | |||
af1906ea04 | |||
68848000f7 | |||
d98da47a0f | |||
306f7e93a0 | |||
8954ff3af2 | |||
d2f3adbf69 | |||
d511c845b7 |
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,9 +44,9 @@
|
|||||||
<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.2" />
|
||||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||||
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
|
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -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 ||
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OpCode32SimdSelMode : int
|
enum OpCode32SimdSelMode
|
||||||
{
|
{
|
||||||
Eq = 0,
|
Eq = 0,
|
||||||
Vs,
|
Vs,
|
||||||
|
@ -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;
|
||||||
|
@ -78,7 +78,7 @@ namespace ARMeilleure.Signal
|
|||||||
private static IntPtr _signalHandlerPtr;
|
private static IntPtr _signalHandlerPtr;
|
||||||
private static IntPtr _signalHandlerHandle;
|
private static IntPtr _signalHandlerHandle;
|
||||||
|
|
||||||
private static readonly object _lock = new object();
|
private static readonly object _lock = new();
|
||||||
private static bool _initialized;
|
private static bool _initialized;
|
||||||
|
|
||||||
static NativeSignalHandler()
|
static NativeSignalHandler()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
namespace ARMeilleure.State
|
namespace ARMeilleure.State
|
||||||
{
|
{
|
||||||
enum ExecutionMode : int
|
enum ExecutionMode
|
||||||
{
|
{
|
||||||
Aarch32Arm = 0,
|
Aarch32Arm = 0,
|
||||||
Aarch32Thumb = 1,
|
Aarch32Thumb = 1,
|
||||||
|
@ -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;
|
||||||
@ -25,7 +26,7 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
|
|
||||||
private static readonly List<CacheEntry> _cacheEntries = new List<CacheEntry>();
|
private static readonly List<CacheEntry> _cacheEntries = new List<CacheEntry>();
|
||||||
|
|
||||||
private static readonly object _lock = new object();
|
private static readonly object _lock = new();
|
||||||
private static bool _initialized;
|
private static bool _initialized;
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
|
@ -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";
|
||||||
|
@ -17,7 +17,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
|
|||||||
private Queue<OpenALAudioBuffer> _queuedBuffers;
|
private Queue<OpenALAudioBuffer> _queuedBuffers;
|
||||||
private ulong _playedSampleCount;
|
private ulong _playedSampleCount;
|
||||||
|
|
||||||
private object _lock = new object();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
public OpenALHardwareDeviceSession(OpenALHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
|
public OpenALHardwareDeviceSession(OpenALHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
namespace Ryujinx.Audio.Backends.SoundIo.Native
|
namespace Ryujinx.Audio.Backends.SoundIo.Native
|
||||||
{
|
{
|
||||||
public enum SoundIoBackend : int
|
public enum SoundIoBackend
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
Jack = 1,
|
Jack = 1,
|
||||||
|
@ -11,7 +11,7 @@ namespace Ryujinx.Audio
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock used to control the waiters registration.
|
/// Lock used to control the waiters registration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private object _lock = new object();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Events signaled when the driver played audio buffers.
|
/// Events signaled when the driver played audio buffers.
|
||||||
|
@ -10,7 +10,7 @@ namespace Ryujinx.Audio.Backends.Common
|
|||||||
{
|
{
|
||||||
private const int RingBufferAlignment = 2048;
|
private const int RingBufferAlignment = 2048;
|
||||||
|
|
||||||
private object _lock = new object();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
private byte[] _buffer;
|
private byte[] _buffer;
|
||||||
private int _size;
|
private int _size;
|
||||||
|
@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Input
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class AudioInputManager : IDisposable
|
public class AudioInputManager : IDisposable
|
||||||
{
|
{
|
||||||
private object _lock = new object();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock used for session allocation.
|
/// Lock used for session allocation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private object _sessionLock = new object();
|
private readonly object _sessionLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The session ids allocation table.
|
/// The session ids allocation table.
|
||||||
|
@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Input
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The lock of the parent.
|
/// The lock of the parent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private object _parentLock;
|
private readonly object _parentLock;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The dispose state.
|
/// The dispose state.
|
||||||
|
@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Output
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class AudioOutputManager : IDisposable
|
public class AudioOutputManager : IDisposable
|
||||||
{
|
{
|
||||||
private object _lock = new object();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock used for session allocation.
|
/// Lock used for session allocation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private object _sessionLock = new object();
|
private readonly object _sessionLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The session ids allocation table.
|
/// The session ids allocation table.
|
||||||
|
@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Output
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// THe lock of the parent.
|
/// THe lock of the parent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private object _parentLock;
|
private readonly object _parentLock;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The dispose state.
|
/// The dispose state.
|
||||||
|
@ -26,7 +26,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
public class AudioRenderSystem : IDisposable
|
public class AudioRenderSystem : IDisposable
|
||||||
{
|
{
|
||||||
private object _lock = new object();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
private AudioRendererRenderingDevice _renderingDevice;
|
private AudioRendererRenderingDevice _renderingDevice;
|
||||||
private AudioRendererExecutionMode _executionMode;
|
private AudioRendererExecutionMode _executionMode;
|
||||||
|
@ -19,12 +19,12 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock used for session allocation.
|
/// Lock used for session allocation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private object _sessionLock = new object();
|
private readonly object _sessionLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock used to control the <see cref="AudioProcessor"/> running state.
|
/// Lock used to control the <see cref="AudioProcessor"/> running state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private object _audioProcessorLock = new object();
|
private readonly object _audioProcessorLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The session ids allocation table.
|
/// The session ids allocation table.
|
||||||
|
@ -16,7 +16,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Global lock of the object.
|
/// Global lock of the object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private object Lock = new object();
|
private readonly object Lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The upsamplers instances.
|
/// The upsamplers instances.
|
||||||
|
@ -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)
|
||||||
|
@ -544,6 +544,9 @@
|
|||||||
"SwkbdMinCharacters": "Must be at least {0} characters long",
|
"SwkbdMinCharacters": "Must be at least {0} characters long",
|
||||||
"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",
|
||||||
|
"SoftwareKeyboardModeAlphabet": "Must be non CJK-characters 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.",
|
||||||
"DialogControllerAppletDockModeSet": "Docked mode set. Handheld is also invalid.\n\n",
|
"DialogControllerAppletDockModeSet": "Docked mode set. Handheld is also invalid.\n\n",
|
||||||
|
@ -527,6 +527,9 @@
|
|||||||
"SwkbdMinCharacters": "至少应为 {0} 个字长",
|
"SwkbdMinCharacters": "至少应为 {0} 个字长",
|
||||||
"SwkbdMinRangeCharacters": "必须为 {0}-{1} 个字长",
|
"SwkbdMinRangeCharacters": "必须为 {0}-{1} 个字长",
|
||||||
"SoftwareKeyboard": "软件键盘",
|
"SoftwareKeyboard": "软件键盘",
|
||||||
|
"SoftwareKeyboardModeNumbersOnly": "只接受数字",
|
||||||
|
"SoftwareKeyboardModeAlphabet": "只接受英文字母",
|
||||||
|
"SoftwareKeyboardModeASCII": "只接受 ASCII 符号",
|
||||||
"DialogControllerAppletMessagePlayerRange": "游戏需要 {0} 个玩家并满足以下要求:\n\n手柄类型:{1}\n\n玩家类型:{2}\n\n{3}请打开设置窗口,重新配置手柄输入;或者关闭返回。",
|
"DialogControllerAppletMessagePlayerRange": "游戏需要 {0} 个玩家并满足以下要求:\n\n手柄类型:{1}\n\n玩家类型:{2}\n\n{3}请打开设置窗口,重新配置手柄输入;或者关闭返回。",
|
||||||
"DialogControllerAppletMessage": "游戏需要刚好 {0} 个玩家并满足以下要求:\n\n手柄类型:{1}\n\n玩家类型:{2}\n\n{3}请打开设置窗口,重新配置手柄输入;或者关闭返回。",
|
"DialogControllerAppletMessage": "游戏需要刚好 {0} 个玩家并满足以下要求:\n\n手柄类型:{1}\n\n玩家类型:{2}\n\n{3}请打开设置窗口,重新配置手柄输入;或者关闭返回。",
|
||||||
"DialogControllerAppletDockModeSet": "目前处于主机模式,无法使用掌机操作方式",
|
"DialogControllerAppletDockModeSet": "目前处于主机模式,无法使用掌机操作方式",
|
||||||
|
@ -527,6 +527,9 @@
|
|||||||
"SwkbdMinCharacters": "至少應為 {0} 個字長",
|
"SwkbdMinCharacters": "至少應為 {0} 個字長",
|
||||||
"SwkbdMinRangeCharacters": "必須為 {0}-{1} 個字長",
|
"SwkbdMinRangeCharacters": "必須為 {0}-{1} 個字長",
|
||||||
"SoftwareKeyboard": "軟體鍵盤",
|
"SoftwareKeyboard": "軟體鍵盤",
|
||||||
|
"SoftwareKeyboardModeNumbersOnly": "只接受數字",
|
||||||
|
"SoftwareKeyboardModeAlphabet": "只接受英文字母",
|
||||||
|
"SoftwareKeyboardModeASCII": "只接受 ASCII 符號",
|
||||||
"DialogControllerAppletMessagePlayerRange": "本遊戲需要 {0} 個玩家持有:\n\n類型:{1}\n\n玩家:{2}\n\n{3}請打開設定畫面,配置手把,或者關閉本視窗。",
|
"DialogControllerAppletMessagePlayerRange": "本遊戲需要 {0} 個玩家持有:\n\n類型:{1}\n\n玩家:{2}\n\n{3}請打開設定畫面,配置手把,或者關閉本視窗。",
|
||||||
"DialogControllerAppletMessage": "本遊戲需要剛好 {0} 個玩家持有:\n\n類型:{1}\n\n玩家:{2}\n\n{3}請打開設定畫面,配置手把,或者關閉本視窗。",
|
"DialogControllerAppletMessage": "本遊戲需要剛好 {0} 個玩家持有:\n\n類型:{1}\n\n玩家:{2}\n\n{3}請打開設定畫面,配置手把,或者關閉本視窗。",
|
||||||
"DialogControllerAppletDockModeSet": "現在處於主機模式,無法使用掌機操作方式\n\n",
|
"DialogControllerAppletDockModeSet": "現在處於主機模式,無法使用掌機操作方式\n\n",
|
||||||
|
@ -740,6 +740,18 @@ 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
|
||||||
|
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.
|
||||||
|
var oldFiles = Directory.EnumerateFiles(HomeDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName);
|
||||||
|
var newFiles = Directory.EnumerateFiles(UpdatePublishDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName);
|
||||||
|
var userFiles = oldFiles.Except(newFiles).Select(filename => Path.Combine(HomeDir, filename));
|
||||||
|
|
||||||
|
// Remove user files from the paths in files.
|
||||||
|
files = files.Except(userFiles);
|
||||||
|
}
|
||||||
|
|
||||||
if (OperatingSystem.IsWindows())
|
if (OperatingSystem.IsWindows())
|
||||||
{
|
{
|
||||||
foreach (string dir in WindowsDependencyDirs)
|
foreach (string dir in WindowsDependencyDirs)
|
||||||
|
@ -9,14 +9,17 @@ using Ryujinx.Ava.Common.Locale;
|
|||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.HLE.HOS.Applets;
|
using Ryujinx.HLE.HOS.Applets;
|
||||||
|
using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Controls
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
{
|
{
|
||||||
internal partial class SwkbdAppletDialog : UserControl
|
internal partial class SwkbdAppletDialog : UserControl
|
||||||
{
|
{
|
||||||
private Predicate<int> _checkLength;
|
private Predicate<int> _checkLength = _ => true;
|
||||||
|
private Predicate<string> _checkInput = _ => true;
|
||||||
private int _inputMax;
|
private int _inputMax;
|
||||||
private int _inputMin;
|
private int _inputMin;
|
||||||
private string _placeholder;
|
private string _placeholder;
|
||||||
@ -35,8 +38,6 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
Input.Watermark = _placeholder;
|
Input.Watermark = _placeholder;
|
||||||
|
|
||||||
Input.AddHandler(TextInputEvent, Message_TextInput, RoutingStrategies.Tunnel, true);
|
Input.AddHandler(TextInputEvent, Message_TextInput, RoutingStrategies.Tunnel, true);
|
||||||
|
|
||||||
SetInputLengthValidation(0, int.MaxValue); // Disable by default.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SwkbdAppletDialog()
|
public SwkbdAppletDialog()
|
||||||
@ -67,6 +68,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
string input = string.Empty;
|
string input = string.Empty;
|
||||||
|
|
||||||
content.SetInputLengthValidation(args.StringLengthMin, args.StringLengthMax);
|
content.SetInputLengthValidation(args.StringLengthMin, args.StringLengthMax);
|
||||||
|
content.SetInputValidation(args.KeyboardMode);
|
||||||
|
|
||||||
content._host = contentDialog;
|
content._host = contentDialog;
|
||||||
contentDialog.Title = title;
|
contentDialog.Title = title;
|
||||||
@ -91,6 +93,12 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
return (result, input);
|
return (result, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ApplyValidationInfo(string text)
|
||||||
|
{
|
||||||
|
Error.IsVisible = !string.IsNullOrEmpty(text);
|
||||||
|
Error.Text = text;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetInputLengthValidation(int min, int max)
|
public void SetInputLengthValidation(int min, int max)
|
||||||
{
|
{
|
||||||
_inputMin = Math.Min(min, max);
|
_inputMin = Math.Min(min, max);
|
||||||
@ -99,6 +107,8 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
Error.IsVisible = false;
|
Error.IsVisible = false;
|
||||||
Error.FontStyle = FontStyle.Italic;
|
Error.FontStyle = FontStyle.Italic;
|
||||||
|
|
||||||
|
string validationInfoText = "";
|
||||||
|
|
||||||
if (_inputMin <= 0 && _inputMax == int.MaxValue) // Disable.
|
if (_inputMin <= 0 && _inputMax == int.MaxValue) // Disable.
|
||||||
{
|
{
|
||||||
Error.IsVisible = false;
|
Error.IsVisible = false;
|
||||||
@ -107,21 +117,48 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
}
|
}
|
||||||
else if (_inputMin > 0 && _inputMax == int.MaxValue)
|
else if (_inputMin > 0 && _inputMax == int.MaxValue)
|
||||||
{
|
{
|
||||||
Error.IsVisible = true;
|
validationInfoText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinCharacters, _inputMin);
|
||||||
|
|
||||||
Error.Text = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinCharacters, _inputMin);
|
|
||||||
|
|
||||||
_checkLength = length => _inputMin <= length;
|
_checkLength = length => _inputMin <= length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Error.IsVisible = true;
|
validationInfoText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinRangeCharacters, _inputMin, _inputMax);
|
||||||
|
|
||||||
Error.Text = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinRangeCharacters, _inputMin, _inputMax);
|
|
||||||
|
|
||||||
_checkLength = length => _inputMin <= length && length <= _inputMax;
|
_checkLength = length => _inputMin <= length && length <= _inputMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApplyValidationInfo(validationInfoText);
|
||||||
|
Message_TextInput(this, new TextInputEventArgs());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetInputValidation(KeyboardMode mode)
|
||||||
|
{
|
||||||
|
string validationInfoText = Error.Text;
|
||||||
|
string localeText;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case KeyboardMode.NumbersOnly:
|
||||||
|
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeNumbersOnly);
|
||||||
|
validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
|
||||||
|
_checkInput = text => text.All(char.IsDigit);
|
||||||
|
break;
|
||||||
|
case KeyboardMode.Alphabet:
|
||||||
|
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet);
|
||||||
|
validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
|
||||||
|
_checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value));
|
||||||
|
break;
|
||||||
|
case KeyboardMode.ASCII:
|
||||||
|
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeASCII);
|
||||||
|
validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
|
||||||
|
_checkInput = text => text.All(char.IsAscii);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_checkInput = _ => true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyValidationInfo(validationInfoText);
|
||||||
Message_TextInput(this, new TextInputEventArgs());
|
Message_TextInput(this, new TextInputEventArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +166,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
{
|
{
|
||||||
if (_host != null)
|
if (_host != null)
|
||||||
{
|
{
|
||||||
_host.IsPrimaryButtonEnabled = _checkLength(Message.Length);
|
_host.IsPrimaryButtonEnabled = _checkLength(Message.Length) && _checkInput(Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +178,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_host.IsPrimaryButtonEnabled = _checkLength(Message.Length);
|
_host.IsPrimaryButtonEnabled = _checkLength(Message.Length) && _checkInput(Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,10 @@
|
|||||||
<ListBox.ItemsPanel>
|
<ListBox.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<flex:FlexPanel
|
<flex:FlexPanel
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
AlignContent="FlexStart"
|
AlignContent="FlexStart"
|
||||||
JustifyContent="Center" />
|
JustifyContent="FlexStart" />
|
||||||
</ItemsPanelTemplate>
|
</ItemsPanelTemplate>
|
||||||
</ListBox.ItemsPanel>
|
</ListBox.ItemsPanel>
|
||||||
<ListBox.Styles>
|
<ListBox.Styles>
|
||||||
|
@ -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);
|
||||||
|
@ -7,7 +7,7 @@ namespace Ryujinx.Common.Configuration.Hid
|
|||||||
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
||||||
[Flags]
|
[Flags]
|
||||||
[JsonConverter(typeof(TypedStringEnumConverter<ControllerType>))]
|
[JsonConverter(typeof(TypedStringEnumConverter<ControllerType>))]
|
||||||
public enum ControllerType : int
|
public enum ControllerType
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
ProController = 1 << 0,
|
ProController = 1 << 0,
|
||||||
|
@ -5,7 +5,7 @@ namespace Ryujinx.Common.Configuration.Hid
|
|||||||
{
|
{
|
||||||
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
||||||
[JsonConverter(typeof(TypedStringEnumConverter<PlayerIndex>))]
|
[JsonConverter(typeof(TypedStringEnumConverter<PlayerIndex>))]
|
||||||
public enum PlayerIndex : int
|
public enum PlayerIndex
|
||||||
{
|
{
|
||||||
Player1 = 0,
|
Player1 = 0,
|
||||||
Player2 = 1,
|
Player2 = 1,
|
||||||
|
@ -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);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
@ -18,12 +19,14 @@ namespace Ryujinx.Common.Utilities
|
|||||||
public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
var enumValue = reader.GetString();
|
var enumValue = reader.GetString();
|
||||||
if (string.IsNullOrEmpty(enumValue))
|
|
||||||
|
if (Enum.TryParse(enumValue, out TEnum value))
|
||||||
{
|
{
|
||||||
return default;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Enum.Parse<TEnum>(enumValue);
|
Logger.Warning?.Print(LogClass.Configuration, $"Failed to parse enum value \"{enumValue}\" for {typeof(TEnum)}, using default \"{default(TEnum)}\"");
|
||||||
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options)
|
public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options)
|
||||||
@ -31,4 +34,4 @@ namespace Ryujinx.Common.Utilities
|
|||||||
writer.WriteStringValue(value.ToString());
|
writer.WriteStringValue(value.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ using System;
|
|||||||
|
|
||||||
namespace Ryujinx.Cpu
|
namespace Ryujinx.Cpu
|
||||||
{
|
{
|
||||||
class AddressSpace : IDisposable
|
public class AddressSpace : IDisposable
|
||||||
{
|
{
|
||||||
private const ulong PageSize = 0x1000;
|
private const ulong PageSize = 0x1000;
|
||||||
|
|
||||||
@ -154,7 +154,9 @@ namespace Ryujinx.Cpu
|
|||||||
public MemoryBlock Base { get; }
|
public MemoryBlock Base { get; }
|
||||||
public MemoryBlock Mirror { get; }
|
public MemoryBlock Mirror { get; }
|
||||||
|
|
||||||
public AddressSpace(MemoryBlock backingMemory, ulong asSize, bool supports4KBPages)
|
public ulong AddressSpaceSize { get; }
|
||||||
|
|
||||||
|
public AddressSpace(MemoryBlock backingMemory, MemoryBlock baseMemory, MemoryBlock mirrorMemory, ulong addressSpaceSize, bool supports4KBPages)
|
||||||
{
|
{
|
||||||
if (!supports4KBPages)
|
if (!supports4KBPages)
|
||||||
{
|
{
|
||||||
@ -163,17 +165,48 @@ namespace Ryujinx.Cpu
|
|||||||
_privateTree = new IntrusiveRedBlackTree<PrivateMapping>();
|
_privateTree = new IntrusiveRedBlackTree<PrivateMapping>();
|
||||||
_treeLock = new object();
|
_treeLock = new object();
|
||||||
|
|
||||||
_mappingTree.Add(new Mapping(0UL, asSize, MappingType.None));
|
_mappingTree.Add(new Mapping(0UL, addressSpaceSize, MappingType.None));
|
||||||
_privateTree.Add(new PrivateMapping(0UL, asSize, default));
|
_privateTree.Add(new PrivateMapping(0UL, addressSpaceSize, default));
|
||||||
}
|
}
|
||||||
|
|
||||||
_backingMemory = backingMemory;
|
_backingMemory = backingMemory;
|
||||||
_supports4KBPages = supports4KBPages;
|
_supports4KBPages = supports4KBPages;
|
||||||
|
|
||||||
|
Base = baseMemory;
|
||||||
|
Mirror = mirrorMemory;
|
||||||
|
AddressSpaceSize = addressSpaceSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryCreate(MemoryBlock backingMemory, ulong asSize, bool supports4KBPages, out AddressSpace addressSpace)
|
||||||
|
{
|
||||||
|
addressSpace = null;
|
||||||
|
|
||||||
MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
|
MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
|
||||||
|
|
||||||
Base = new MemoryBlock(asSize, asFlags);
|
ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36);
|
||||||
Mirror = new MemoryBlock(asSize, asFlags);
|
|
||||||
|
// Attempt to create the address space with expected size or try to reduce it until it succeed.
|
||||||
|
for (ulong addressSpaceSize = asSize; addressSpaceSize >= minAddressSpaceSize; addressSpaceSize >>= 1)
|
||||||
|
{
|
||||||
|
MemoryBlock baseMemory = null;
|
||||||
|
MemoryBlock mirrorMemory = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
baseMemory = new MemoryBlock(addressSpaceSize, asFlags);
|
||||||
|
mirrorMemory = new MemoryBlock(addressSpaceSize, asFlags);
|
||||||
|
addressSpace = new AddressSpace(backingMemory, baseMemory, mirrorMemory, addressSpaceSize, supports4KBPages);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (OutOfMemoryException)
|
||||||
|
{
|
||||||
|
baseMemory?.Dispose();
|
||||||
|
mirrorMemory?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return addressSpace != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags)
|
public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags)
|
||||||
|
@ -38,7 +38,8 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
private readonly bool _unsafeMode;
|
private readonly bool _unsafeMode;
|
||||||
|
|
||||||
private readonly AddressSpace _addressSpace;
|
private readonly AddressSpace _addressSpace;
|
||||||
private readonly ulong _addressSpaceSize;
|
|
||||||
|
public ulong AddressSpaceSize { get; }
|
||||||
|
|
||||||
private readonly PageTable<ulong> _pageTable;
|
private readonly PageTable<ulong> _pageTable;
|
||||||
|
|
||||||
@ -62,21 +63,21 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the host mapped memory manager.
|
/// Creates a new instance of the host mapped memory manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="backingMemory">Physical backing memory where virtual memory will be mapped to</param>
|
/// <param name="addressSpace">Address space instance to use</param>
|
||||||
/// <param name="addressSpaceSize">Size of the address space</param>
|
|
||||||
/// <param name="unsafeMode">True if unmanaged access should not be masked (unsafe), false otherwise.</param>
|
/// <param name="unsafeMode">True if unmanaged access should not be masked (unsafe), false otherwise.</param>
|
||||||
/// <param name="invalidAccessHandler">Optional function to handle invalid memory accesses</param>
|
/// <param name="invalidAccessHandler">Optional function to handle invalid memory accesses</param>
|
||||||
public MemoryManagerHostMapped(MemoryBlock backingMemory, ulong addressSpaceSize, bool unsafeMode, InvalidAccessHandler invalidAccessHandler = null)
|
public MemoryManagerHostMapped(AddressSpace addressSpace, bool unsafeMode, InvalidAccessHandler invalidAccessHandler)
|
||||||
{
|
{
|
||||||
|
_addressSpace = addressSpace;
|
||||||
_pageTable = new PageTable<ulong>();
|
_pageTable = new PageTable<ulong>();
|
||||||
_invalidAccessHandler = invalidAccessHandler;
|
_invalidAccessHandler = invalidAccessHandler;
|
||||||
_unsafeMode = unsafeMode;
|
_unsafeMode = unsafeMode;
|
||||||
_addressSpaceSize = addressSpaceSize;
|
AddressSpaceSize = addressSpace.AddressSpaceSize;
|
||||||
|
|
||||||
ulong asSize = PageSize;
|
ulong asSize = PageSize;
|
||||||
int asBits = PageBits;
|
int asBits = PageBits;
|
||||||
|
|
||||||
while (asSize < addressSpaceSize)
|
while (asSize < AddressSpaceSize)
|
||||||
{
|
{
|
||||||
asSize <<= 1;
|
asSize <<= 1;
|
||||||
asBits++;
|
asBits++;
|
||||||
@ -86,8 +87,6 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
|
|
||||||
_pageBitmap = new ulong[1 << (AddressSpaceBits - (PageBits + PageToPteShift))];
|
_pageBitmap = new ulong[1 << (AddressSpaceBits - (PageBits + PageToPteShift))];
|
||||||
|
|
||||||
_addressSpace = new AddressSpace(backingMemory, asSize, Supports4KBPages);
|
|
||||||
|
|
||||||
Tracking = new MemoryTracking(this, (int)MemoryBlock.GetPageSize(), invalidAccessHandler);
|
Tracking = new MemoryTracking(this, (int)MemoryBlock.GetPageSize(), invalidAccessHandler);
|
||||||
_memoryEh = new MemoryEhMeilleure(_addressSpace.Base, _addressSpace.Mirror, Tracking);
|
_memoryEh = new MemoryEhMeilleure(_addressSpace.Base, _addressSpace.Mirror, Tracking);
|
||||||
}
|
}
|
||||||
@ -99,7 +98,7 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
/// <returns>True if the virtual address is part of the addressable space</returns>
|
/// <returns>True if the virtual address is part of the addressable space</returns>
|
||||||
private bool ValidateAddress(ulong va)
|
private bool ValidateAddress(ulong va)
|
||||||
{
|
{
|
||||||
return va < _addressSpaceSize;
|
return va < AddressSpaceSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -111,7 +110,7 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
private bool ValidateAddressAndSize(ulong va, ulong size)
|
private bool ValidateAddressAndSize(ulong va, ulong size)
|
||||||
{
|
{
|
||||||
ulong endVa = va + size;
|
ulong endVa = va + size;
|
||||||
return endVa >= va && endVa >= size && endVa <= _addressSpaceSize;
|
return endVa >= va && endVa >= size && endVa <= AddressSpaceSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -28,12 +28,15 @@ 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;
|
||||||
public readonly bool SupportsCubemapView;
|
public readonly bool SupportsCubemapView;
|
||||||
public readonly bool SupportsNonConstantTextureOffset;
|
public readonly bool SupportsNonConstantTextureOffset;
|
||||||
public readonly bool SupportsShaderBallot;
|
public readonly bool SupportsShaderBallot;
|
||||||
|
public readonly bool SupportsShaderBarrierDivergence;
|
||||||
|
public readonly bool SupportsShaderFloat64;
|
||||||
public readonly bool SupportsTextureShadowLod;
|
public readonly bool SupportsTextureShadowLod;
|
||||||
public readonly bool SupportsViewportIndexVertexTessellation;
|
public readonly bool SupportsViewportIndexVertexTessellation;
|
||||||
public readonly bool SupportsViewportMask;
|
public readonly bool SupportsViewportMask;
|
||||||
@ -75,12 +78,15 @@ 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,
|
||||||
bool supportsCubemapView,
|
bool supportsCubemapView,
|
||||||
bool supportsNonConstantTextureOffset,
|
bool supportsNonConstantTextureOffset,
|
||||||
bool supportsShaderBallot,
|
bool supportsShaderBallot,
|
||||||
|
bool supportsShaderBarrierDivergence,
|
||||||
|
bool supportsShaderFloat64,
|
||||||
bool supportsTextureShadowLod,
|
bool supportsTextureShadowLod,
|
||||||
bool supportsViewportIndexVertexTessellation,
|
bool supportsViewportIndexVertexTessellation,
|
||||||
bool supportsViewportMask,
|
bool supportsViewportMask,
|
||||||
@ -118,12 +124,15 @@ 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;
|
||||||
SupportsCubemapView = supportsCubemapView;
|
SupportsCubemapView = supportsCubemapView;
|
||||||
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
|
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
|
||||||
SupportsShaderBallot = supportsShaderBallot;
|
SupportsShaderBallot = supportsShaderBallot;
|
||||||
|
SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence;
|
||||||
|
SupportsShaderFloat64 = supportsShaderFloat64;
|
||||||
SupportsTextureShadowLod = supportsTextureShadowLod;
|
SupportsTextureShadowLod = supportsTextureShadowLod;
|
||||||
SupportsViewportIndexVertexTessellation = supportsViewportIndexVertexTessellation;
|
SupportsViewportIndexVertexTessellation = supportsViewportIndexVertexTessellation;
|
||||||
SupportsViewportMask = supportsViewportMask;
|
SupportsViewportMask = supportsViewportMask;
|
||||||
|
@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
private int _refConsumerPtr;
|
private int _refConsumerPtr;
|
||||||
|
|
||||||
private Action _interruptAction;
|
private Action _interruptAction;
|
||||||
private object _interruptLock = new();
|
private readonly object _interruptLock = new();
|
||||||
|
|
||||||
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
||||||
|
|
||||||
|
@ -151,8 +151,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
|
|
||||||
ShaderProgramInfo info = cs.Shaders[0].Info;
|
ShaderProgramInfo info = cs.Shaders[0].Info;
|
||||||
|
|
||||||
bool hasUnaligned = _channel.BufferManager.HasUnalignedStorageBuffers;
|
|
||||||
|
|
||||||
for (int index = 0; index < info.SBuffers.Count; index++)
|
for (int index = 0; index < info.SBuffers.Count; index++)
|
||||||
{
|
{
|
||||||
BufferDescriptor sb = info.SBuffers[index];
|
BufferDescriptor sb = info.SBuffers[index];
|
||||||
@ -177,9 +175,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
_channel.BufferManager.SetComputeStorageBuffer(sb.Slot, sbDescriptor.PackAddress(), size, sb.Flags);
|
_channel.BufferManager.SetComputeStorageBuffer(sb.Slot, sbDescriptor.PackAddress(), size, sb.Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_channel.BufferManager.HasUnalignedStorageBuffers) != hasUnaligned)
|
if (_channel.BufferManager.HasUnalignedStorageBuffers != computeState.HasUnalignedStorageBuffer)
|
||||||
{
|
{
|
||||||
// Refetch the shader, as assumptions about storage buffer alignment have changed.
|
// Refetch the shader, as assumptions about storage buffer alignment have changed.
|
||||||
|
computeState = new GpuChannelComputeState(
|
||||||
|
qmd.CtaThreadDimension0,
|
||||||
|
qmd.CtaThreadDimension1,
|
||||||
|
qmd.CtaThreadDimension2,
|
||||||
|
localMemorySize,
|
||||||
|
sharedMemorySize,
|
||||||
|
_channel.BufferManager.HasUnalignedStorageBuffers);
|
||||||
|
|
||||||
cs = memoryManager.Physical.ShaderCache.GetComputeShader(_channel, poolState, computeState, shaderGpuVa);
|
cs = memoryManager.Physical.ShaderCache.GetComputeShader(_channel, poolState, computeState, shaderGpuVa);
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetProgram(cs.HostProgram);
|
_context.Renderer.Pipeline.SetProgram(cs.HostProgram);
|
||||||
|
@ -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;
|
||||||
|
@ -541,7 +541,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
depth,
|
depth,
|
||||||
lhs.FormatInfo.BlockHeight,
|
lhs.FormatInfo.BlockHeight,
|
||||||
lhs.GobBlocksInY,
|
lhs.GobBlocksInY,
|
||||||
lhs.GobBlocksInZ);
|
lhs.GobBlocksInZ,
|
||||||
|
level);
|
||||||
|
|
||||||
return gobBlocksInY == rhs.GobBlocksInY &&
|
return gobBlocksInY == rhs.GobBlocksInY &&
|
||||||
gobBlocksInZ == rhs.GobBlocksInZ;
|
gobBlocksInZ == rhs.GobBlocksInZ;
|
||||||
@ -587,7 +588,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
lhsDepth,
|
lhsDepth,
|
||||||
lhs.FormatInfo.BlockHeight,
|
lhs.FormatInfo.BlockHeight,
|
||||||
lhs.GobBlocksInY,
|
lhs.GobBlocksInY,
|
||||||
lhs.GobBlocksInZ);
|
lhs.GobBlocksInZ,
|
||||||
|
lhsLevel);
|
||||||
|
|
||||||
int rhsHeight = Math.Max(1, rhs.Height >> rhsLevel);
|
int rhsHeight = Math.Max(1, rhs.Height >> rhsLevel);
|
||||||
int rhsDepth = Math.Max(1, rhs.GetDepth() >> rhsLevel);
|
int rhsDepth = Math.Max(1, rhs.GetDepth() >> rhsLevel);
|
||||||
@ -597,7 +599,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
rhsDepth,
|
rhsDepth,
|
||||||
rhs.FormatInfo.BlockHeight,
|
rhs.FormatInfo.BlockHeight,
|
||||||
rhs.GobBlocksInY,
|
rhs.GobBlocksInY,
|
||||||
rhs.GobBlocksInZ);
|
rhs.GobBlocksInZ,
|
||||||
|
rhsLevel);
|
||||||
|
|
||||||
return lhsGobBlocksInY == rhsGobBlocksInY &&
|
return lhsGobBlocksInY == rhsGobBlocksInY &&
|
||||||
lhsGobBlocksInZ == rhsGobBlocksInZ;
|
lhsGobBlocksInZ == rhsGobBlocksInZ;
|
||||||
|
@ -484,7 +484,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
depthOrLayers = Math.Max(1, depthOrLayers >> minLod);
|
depthOrLayers = Math.Max(1, depthOrLayers >> minLod);
|
||||||
}
|
}
|
||||||
|
|
||||||
(gobBlocksInY, gobBlocksInZ) = SizeCalculator.GetMipGobBlockSizes(height, depth, formatInfo.BlockHeight, gobBlocksInY, gobBlocksInZ);
|
(gobBlocksInY, gobBlocksInZ) = SizeCalculator.GetMipGobBlockSizes(height, depth, formatInfo.BlockHeight, gobBlocksInY, gobBlocksInZ, minLod);
|
||||||
}
|
}
|
||||||
|
|
||||||
levels = (maxLod - minLod) + 1;
|
levels = (maxLod - minLod) + 1;
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
private List<BufferMigration> _sources;
|
private List<BufferMigration> _sources;
|
||||||
private BufferMigration _migrationTarget;
|
private BufferMigration _migrationTarget;
|
||||||
|
|
||||||
private object _lock = new object();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the modified range list has any entries or not.
|
/// Whether the modified range list has any entries or not.
|
||||||
@ -125,7 +125,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
BufferModifiedRange overlap = overlaps[i];
|
BufferModifiedRange overlap = overlaps[i];
|
||||||
|
|
||||||
if (overlap.Address > address)
|
if (overlap.Address > address)
|
||||||
{
|
{
|
||||||
// The start of the remaining region is uncovered by this overlap. Call the action for it.
|
// The start of the remaining region is uncovered by this overlap. Call the action for it.
|
||||||
|
@ -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 = 4992;
|
private const uint CodeGenVersion = 5241;
|
||||||
|
|
||||||
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)
|
||||||
@ -141,10 +157,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
|
|
||||||
public bool QueryHostSupportsShaderBallot() => _context.Capabilities.SupportsShaderBallot;
|
public bool QueryHostSupportsShaderBallot() => _context.Capabilities.SupportsShaderBallot;
|
||||||
|
|
||||||
|
public bool QueryHostSupportsShaderBarrierDivergence() => _context.Capabilities.SupportsShaderBarrierDivergence;
|
||||||
|
|
||||||
|
public bool QueryHostSupportsShaderFloat64() => _context.Capabilities.SupportsShaderFloat64;
|
||||||
|
|
||||||
public bool QueryHostSupportsSnormBufferTextureFormat() => _context.Capabilities.SupportsSnormBufferTextureFormat;
|
public bool QueryHostSupportsSnormBufferTextureFormat() => _context.Capabilities.SupportsSnormBufferTextureFormat;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -127,6 +127,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
public Capabilities GetCapabilities()
|
public Capabilities GetCapabilities()
|
||||||
{
|
{
|
||||||
bool intelWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows;
|
bool intelWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows;
|
||||||
|
bool intelUnix = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelUnix;
|
||||||
bool amdWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.AmdWindows;
|
bool amdWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.AmdWindows;
|
||||||
|
|
||||||
return new Capabilities(
|
return new Capabilities(
|
||||||
@ -152,12 +153,15 @@ 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,
|
||||||
supportsCubemapView: true,
|
supportsCubemapView: true,
|
||||||
supportsNonConstantTextureOffset: HwCapabilities.SupportsNonConstantTextureOffset,
|
supportsNonConstantTextureOffset: HwCapabilities.SupportsNonConstantTextureOffset,
|
||||||
supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
|
supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
|
||||||
|
supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
|
||||||
|
supportsShaderFloat64: true,
|
||||||
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
|
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
|
||||||
supportsViewportIndexVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
supportsViewportIndexVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
||||||
supportsViewportMask: HwCapabilities.SupportsViewportArray2,
|
supportsViewportMask: HwCapabilities.SupportsViewportArray2,
|
||||||
|
@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||||||
private ulong _accumulatedCounter;
|
private ulong _accumulatedCounter;
|
||||||
private int _waiterCount;
|
private int _waiterCount;
|
||||||
|
|
||||||
private object _lock = new object();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
private Queue<BufferedQuery> _queryPool;
|
private Queue<BufferedQuery> _queryPool;
|
||||||
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
|
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
|
||||||
|
@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||||||
private bool _hostAccessReserved = false;
|
private bool _hostAccessReserved = false;
|
||||||
private int _refCount = 1; // Starts with a reference from the counter queue.
|
private int _refCount = 1; // Starts with a reference from the counter queue.
|
||||||
|
|
||||||
private object _lock = new object();
|
private readonly object _lock = new();
|
||||||
private ulong _result = ulong.MaxValue;
|
private ulong _result = ulong.MaxValue;
|
||||||
private double _divisor = 1f;
|
private double _divisor = 1f;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
{
|
{
|
||||||
private const int DisposedLiveFrames = 2;
|
private const int DisposedLiveFrames = 2;
|
||||||
|
|
||||||
private readonly object _lock = new object();
|
private readonly object _lock = new();
|
||||||
private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new Dictionary<TextureCreateInfo, List<DisposedTexture>>();
|
private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new Dictionary<TextureCreateInfo, List<DisposedTexture>>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -71,40 +71,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
context.AppendLine($"const int {DefaultNames.UndefinedName} = 0;");
|
context.AppendLine($"const int {DefaultNames.UndefinedName} = 0;");
|
||||||
context.AppendLine();
|
context.AppendLine();
|
||||||
|
|
||||||
if (context.Config.Stage == ShaderStage.Compute)
|
|
||||||
{
|
|
||||||
int localMemorySize = BitUtils.DivRoundUp(context.Config.GpuAccessor.QueryComputeLocalMemorySize(), 4);
|
|
||||||
|
|
||||||
if (localMemorySize != 0)
|
|
||||||
{
|
|
||||||
string localMemorySizeStr = NumberFormatter.FormatInt(localMemorySize);
|
|
||||||
|
|
||||||
context.AppendLine($"uint {DefaultNames.LocalMemoryName}[{localMemorySizeStr}];");
|
|
||||||
context.AppendLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
int sharedMemorySize = BitUtils.DivRoundUp(context.Config.GpuAccessor.QueryComputeSharedMemorySize(), 4);
|
|
||||||
|
|
||||||
if (sharedMemorySize != 0)
|
|
||||||
{
|
|
||||||
string sharedMemorySizeStr = NumberFormatter.FormatInt(sharedMemorySize);
|
|
||||||
|
|
||||||
context.AppendLine($"shared uint {DefaultNames.SharedMemoryName}[{sharedMemorySizeStr}];");
|
|
||||||
context.AppendLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (context.Config.LocalMemorySize != 0)
|
|
||||||
{
|
|
||||||
int localMemorySize = BitUtils.DivRoundUp(context.Config.LocalMemorySize, 4);
|
|
||||||
|
|
||||||
string localMemorySizeStr = NumberFormatter.FormatInt(localMemorySize);
|
|
||||||
|
|
||||||
context.AppendLine($"uint {DefaultNames.LocalMemoryName}[{localMemorySizeStr}];");
|
|
||||||
context.AppendLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
|
DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
|
||||||
DeclareStorageBuffers(context, context.Config.Properties.StorageBuffers.Values);
|
DeclareStorageBuffers(context, context.Config.Properties.StorageBuffers.Values);
|
||||||
|
DeclareMemories(context, context.Config.Properties.LocalMemories.Values, isShared: false);
|
||||||
|
DeclareMemories(context, context.Config.Properties.SharedMemories.Values, isShared: true);
|
||||||
|
|
||||||
var textureDescriptors = context.Config.GetTextureDescriptors();
|
var textureDescriptors = context.Config.GetTextureDescriptors();
|
||||||
if (textureDescriptors.Length != 0)
|
if (textureDescriptors.Length != 0)
|
||||||
@ -238,11 +208,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
context.AppendLine();
|
context.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((info.HelperFunctionsMask & HelperFunctionsMask.AtomicMinMaxS32Shared) != 0)
|
|
||||||
{
|
|
||||||
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((info.HelperFunctionsMask & HelperFunctionsMask.MultiplyHighS32) != 0)
|
if ((info.HelperFunctionsMask & HelperFunctionsMask.MultiplyHighS32) != 0)
|
||||||
{
|
{
|
||||||
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighS32.glsl");
|
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighS32.glsl");
|
||||||
@ -273,11 +238,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleXor.glsl");
|
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleXor.glsl");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((info.HelperFunctionsMask & HelperFunctionsMask.StoreSharedSmallInt) != 0)
|
|
||||||
{
|
|
||||||
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreSharedSmallInt.glsl");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((info.HelperFunctionsMask & HelperFunctionsMask.SwizzleAdd) != 0)
|
if ((info.HelperFunctionsMask & HelperFunctionsMask.SwizzleAdd) != 0)
|
||||||
{
|
{
|
||||||
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/SwizzleAdd.glsl");
|
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/SwizzleAdd.glsl");
|
||||||
@ -358,7 +318,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
_ => "std430"
|
_ => "std430"
|
||||||
};
|
};
|
||||||
|
|
||||||
context.AppendLine($"layout (binding = {buffer.Binding}, {layout}) {declType} _{buffer.Name}");
|
string set = string.Empty;
|
||||||
|
|
||||||
|
if (context.Config.Options.TargetApi == TargetApi.Vulkan)
|
||||||
|
{
|
||||||
|
set = $"set = {buffer.Set}, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
context.AppendLine($"layout ({set}binding = {buffer.Binding}, {layout}) {declType} _{buffer.Name}");
|
||||||
context.EnterScope();
|
context.EnterScope();
|
||||||
|
|
||||||
foreach (StructureField field in buffer.Type.Fields)
|
foreach (StructureField field in buffer.Type.Fields)
|
||||||
@ -391,6 +358,27 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void DeclareMemories(CodeGenContext context, IEnumerable<MemoryDefinition> memories, bool isShared)
|
||||||
|
{
|
||||||
|
string prefix = isShared ? "shared " : string.Empty;
|
||||||
|
|
||||||
|
foreach (MemoryDefinition memory in memories)
|
||||||
|
{
|
||||||
|
string typeName = GetVarTypeName(context, memory.Type & ~AggregateType.Array);
|
||||||
|
|
||||||
|
if (memory.ArrayLength > 0)
|
||||||
|
{
|
||||||
|
string arraySize = memory.ArrayLength.ToString(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
context.AppendLine($"{prefix}{typeName} {memory.Name}[{arraySize}];");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.AppendLine($"{prefix}{typeName} {memory.Name}[];");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void DeclareSamplers(CodeGenContext context, TextureDescriptor[] descriptors)
|
private static void DeclareSamplers(CodeGenContext context, TextureDescriptor[] descriptors)
|
||||||
{
|
{
|
||||||
int arraySize = 0;
|
int arraySize = 0;
|
||||||
@ -717,7 +705,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
string code = EmbeddedResources.ReadAllText(filename);
|
string code = EmbeddedResources.ReadAllText(filename);
|
||||||
|
|
||||||
code = code.Replace("\t", CodeGenContext.Tab);
|
code = code.Replace("\t", CodeGenContext.Tab);
|
||||||
code = code.Replace("$SHARED_MEM$", DefaultNames.SharedMemoryName);
|
|
||||||
|
|
||||||
if (context.Config.GpuAccessor.QueryHostSupportsShaderBallot())
|
if (context.Config.GpuAccessor.QueryHostSupportsShaderBallot())
|
||||||
{
|
{
|
||||||
|
@ -11,9 +11,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
public const string IAttributePrefix = "in_attr";
|
public const string IAttributePrefix = "in_attr";
|
||||||
public const string OAttributePrefix = "out_attr";
|
public const string OAttributePrefix = "out_attr";
|
||||||
|
|
||||||
public const string LocalMemoryName = "local_mem";
|
|
||||||
public const string SharedMemoryName = "shared_mem";
|
|
||||||
|
|
||||||
public const string ArgumentNamePrefix = "a";
|
public const string ArgumentNamePrefix = "a";
|
||||||
|
|
||||||
public const string UndefinedName = "undef";
|
public const string UndefinedName = "undef";
|
||||||
|
@ -28,18 +28,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
for (int i = 1; i < info.Functions.Count; i++)
|
for (int i = 1; i < info.Functions.Count; i++)
|
||||||
{
|
{
|
||||||
PrintFunction(context, info, info.Functions[i]);
|
PrintFunction(context, info.Functions[i]);
|
||||||
|
|
||||||
context.AppendLine();
|
context.AppendLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintFunction(context, info, info.Functions[0], MainFunctionName);
|
PrintFunction(context, info.Functions[0], MainFunctionName);
|
||||||
|
|
||||||
return context.GetCode();
|
return context.GetCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PrintFunction(CodeGenContext context, StructuredProgramInfo info, StructuredFunction function, string funcName = null)
|
private static void PrintFunction(CodeGenContext context, StructuredFunction function, string funcName = null)
|
||||||
{
|
{
|
||||||
context.CurrentFunction = function;
|
context.CurrentFunction = function;
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
Declarations.DeclareLocals(context, function);
|
Declarations.DeclareLocals(context, function);
|
||||||
|
|
||||||
PrintBlock(context, function.MainBlock);
|
PrintBlock(context, function.MainBlock, funcName == MainFunctionName);
|
||||||
|
|
||||||
context.LeaveScope();
|
context.LeaveScope();
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
return $"{Declarations.GetVarTypeName(context, function.ReturnType)} {funcName ?? function.Name}({string.Join(", ", args)})";
|
return $"{Declarations.GetVarTypeName(context, function.ReturnType)} {funcName ?? function.Name}({string.Join(", ", args)})";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PrintBlock(CodeGenContext context, AstBlock block)
|
private static void PrintBlock(CodeGenContext context, AstBlock block, bool isMainFunction)
|
||||||
{
|
{
|
||||||
AstBlockVisitor visitor = new AstBlockVisitor(block);
|
AstBlockVisitor visitor = new AstBlockVisitor(block);
|
||||||
|
|
||||||
@ -112,10 +112,32 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool supportsBarrierDivergence = context.Config.GpuAccessor.QueryHostSupportsShaderBarrierDivergence();
|
||||||
|
bool mayHaveReturned = false;
|
||||||
|
|
||||||
foreach (IAstNode node in visitor.Visit())
|
foreach (IAstNode node in visitor.Visit())
|
||||||
{
|
{
|
||||||
if (node is AstOperation operation)
|
if (node is AstOperation operation)
|
||||||
{
|
{
|
||||||
|
if (!supportsBarrierDivergence)
|
||||||
|
{
|
||||||
|
if (operation.Inst == IntermediateRepresentation.Instruction.Barrier)
|
||||||
|
{
|
||||||
|
// Barrier on divergent control flow paths may cause the GPU to hang,
|
||||||
|
// so skip emitting the barrier for those cases.
|
||||||
|
if (visitor.Block.Type != AstBlockType.Main || mayHaveReturned || !isMainFunction)
|
||||||
|
{
|
||||||
|
context.Config.GpuAccessor.Log($"Shader has barrier on potentially divergent block, the barrier will be removed.");
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (operation.Inst == IntermediateRepresentation.Instruction.Return)
|
||||||
|
{
|
||||||
|
mayHaveReturned = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
string expr = InstGen.GetExpression(context, operation);
|
string expr = InstGen.GetExpression(context, operation);
|
||||||
|
|
||||||
if (expr != null)
|
if (expr != null)
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
int Helper_AtomicMaxS32(int offset, int value)
|
|
||||||
{
|
|
||||||
uint oldValue, newValue;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
oldValue = $SHARED_MEM$[offset];
|
|
||||||
newValue = uint(max(int(oldValue), value));
|
|
||||||
} while (atomicCompSwap($SHARED_MEM$[offset], oldValue, newValue) != oldValue);
|
|
||||||
return int(oldValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Helper_AtomicMinS32(int offset, int value)
|
|
||||||
{
|
|
||||||
uint oldValue, newValue;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
oldValue = $SHARED_MEM$[offset];
|
|
||||||
newValue = uint(min(int(oldValue), value));
|
|
||||||
} while (atomicCompSwap($SHARED_MEM$[offset], oldValue, newValue) != oldValue);
|
|
||||||
return int(oldValue);
|
|
||||||
}
|
|
@ -2,9 +2,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
{
|
{
|
||||||
static class HelperFunctionNames
|
static class HelperFunctionNames
|
||||||
{
|
{
|
||||||
public static string AtomicMaxS32 = "Helper_AtomicMaxS32";
|
|
||||||
public static string AtomicMinS32 = "Helper_AtomicMinS32";
|
|
||||||
|
|
||||||
public static string MultiplyHighS32 = "Helper_MultiplyHighS32";
|
public static string MultiplyHighS32 = "Helper_MultiplyHighS32";
|
||||||
public static string MultiplyHighU32 = "Helper_MultiplyHighU32";
|
public static string MultiplyHighU32 = "Helper_MultiplyHighU32";
|
||||||
|
|
||||||
@ -13,10 +10,5 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
public static string ShuffleUp = "Helper_ShuffleUp";
|
public static string ShuffleUp = "Helper_ShuffleUp";
|
||||||
public static string ShuffleXor = "Helper_ShuffleXor";
|
public static string ShuffleXor = "Helper_ShuffleXor";
|
||||||
public static string SwizzleAdd = "Helper_SwizzleAdd";
|
public static string SwizzleAdd = "Helper_SwizzleAdd";
|
||||||
|
|
||||||
public static string StoreShared16 = "Helper_StoreShared16";
|
|
||||||
public static string StoreShared8 = "Helper_StoreShared8";
|
|
||||||
public static string StoreStorage16 = "Helper_StoreStorage16";
|
|
||||||
public static string StoreStorage8 = "Helper_StoreStorage8";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,23 +0,0 @@
|
|||||||
void Helper_StoreShared16(int offset, uint value)
|
|
||||||
{
|
|
||||||
int wordOffset = offset >> 2;
|
|
||||||
int bitOffset = (offset & 3) * 8;
|
|
||||||
uint oldValue, newValue;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
oldValue = $SHARED_MEM$[wordOffset];
|
|
||||||
newValue = bitfieldInsert(oldValue, value, bitOffset, 16);
|
|
||||||
} while (atomicCompSwap($SHARED_MEM$[wordOffset], oldValue, newValue) != oldValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Helper_StoreShared8(int offset, uint value)
|
|
||||||
{
|
|
||||||
int wordOffset = offset >> 2;
|
|
||||||
int bitOffset = (offset & 3) * 8;
|
|
||||||
uint oldValue, newValue;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
oldValue = $SHARED_MEM$[wordOffset];
|
|
||||||
newValue = bitfieldInsert(oldValue, value, bitOffset, 8);
|
|
||||||
} while (atomicCompSwap($SHARED_MEM$[wordOffset], oldValue, newValue) != oldValue);
|
|
||||||
}
|
|
@ -68,7 +68,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
|
|
||||||
string args = string.Empty;
|
string args = string.Empty;
|
||||||
|
|
||||||
if (atomic && operation.StorageKind == StorageKind.StorageBuffer)
|
if (atomic && (operation.StorageKind == StorageKind.StorageBuffer || operation.StorageKind == StorageKind.SharedMemory))
|
||||||
{
|
{
|
||||||
args = GenerateLoadOrStore(context, operation, isStore: false);
|
args = GenerateLoadOrStore(context, operation, isStore: false);
|
||||||
|
|
||||||
@ -81,23 +81,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
args += ", " + GetSoureExpr(context, operation.GetSource(argIndex), dstType);
|
args += ", " + GetSoureExpr(context, operation.GetSource(argIndex), dstType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (atomic && operation.StorageKind == StorageKind.SharedMemory)
|
|
||||||
{
|
|
||||||
args = LoadShared(context, operation);
|
|
||||||
|
|
||||||
// For shared memory access, the second argument is unused and should be ignored.
|
|
||||||
// It is there to make both storage and shared access have the same number of arguments.
|
|
||||||
// For storage, both inputs are consumed when the argument index is 0, so we should skip it here.
|
|
||||||
|
|
||||||
for (int argIndex = 2; argIndex < arity; argIndex++)
|
|
||||||
{
|
|
||||||
args += ", ";
|
|
||||||
|
|
||||||
AggregateType dstType = GetSrcVarType(inst, argIndex);
|
|
||||||
|
|
||||||
args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int argIndex = 0; argIndex < arity; argIndex++)
|
for (int argIndex = 0; argIndex < arity; argIndex++)
|
||||||
@ -179,12 +162,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
case Instruction.Load:
|
case Instruction.Load:
|
||||||
return Load(context, operation);
|
return Load(context, operation);
|
||||||
|
|
||||||
case Instruction.LoadLocal:
|
|
||||||
return LoadLocal(context, operation);
|
|
||||||
|
|
||||||
case Instruction.LoadShared:
|
|
||||||
return LoadShared(context, operation);
|
|
||||||
|
|
||||||
case Instruction.Lod:
|
case Instruction.Lod:
|
||||||
return Lod(context, operation);
|
return Lod(context, operation);
|
||||||
|
|
||||||
@ -200,18 +177,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
case Instruction.Store:
|
case Instruction.Store:
|
||||||
return Store(context, operation);
|
return Store(context, operation);
|
||||||
|
|
||||||
case Instruction.StoreLocal:
|
|
||||||
return StoreLocal(context, operation);
|
|
||||||
|
|
||||||
case Instruction.StoreShared:
|
|
||||||
return StoreShared(context, operation);
|
|
||||||
|
|
||||||
case Instruction.StoreShared16:
|
|
||||||
return StoreShared16(context, operation);
|
|
||||||
|
|
||||||
case Instruction.StoreShared8:
|
|
||||||
return StoreShared8(context, operation);
|
|
||||||
|
|
||||||
case Instruction.TextureSample:
|
case Instruction.TextureSample:
|
||||||
return TextureSample(context, operation);
|
return TextureSample(context, operation);
|
||||||
|
|
||||||
|
@ -17,9 +17,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
Add(Instruction.AtomicAdd, InstType.AtomicBinary, "atomicAdd");
|
Add(Instruction.AtomicAdd, InstType.AtomicBinary, "atomicAdd");
|
||||||
Add(Instruction.AtomicAnd, InstType.AtomicBinary, "atomicAnd");
|
Add(Instruction.AtomicAnd, InstType.AtomicBinary, "atomicAnd");
|
||||||
Add(Instruction.AtomicCompareAndSwap, InstType.AtomicTernary, "atomicCompSwap");
|
Add(Instruction.AtomicCompareAndSwap, InstType.AtomicTernary, "atomicCompSwap");
|
||||||
Add(Instruction.AtomicMaxS32, InstType.CallTernary, HelperFunctionNames.AtomicMaxS32);
|
|
||||||
Add(Instruction.AtomicMaxU32, InstType.AtomicBinary, "atomicMax");
|
Add(Instruction.AtomicMaxU32, InstType.AtomicBinary, "atomicMax");
|
||||||
Add(Instruction.AtomicMinS32, InstType.CallTernary, HelperFunctionNames.AtomicMinS32);
|
|
||||||
Add(Instruction.AtomicMinU32, InstType.AtomicBinary, "atomicMin");
|
Add(Instruction.AtomicMinU32, InstType.AtomicBinary, "atomicMin");
|
||||||
Add(Instruction.AtomicOr, InstType.AtomicBinary, "atomicOr");
|
Add(Instruction.AtomicOr, InstType.AtomicBinary, "atomicOr");
|
||||||
Add(Instruction.AtomicSwap, InstType.AtomicBinary, "atomicExchange");
|
Add(Instruction.AtomicSwap, InstType.AtomicBinary, "atomicExchange");
|
||||||
@ -83,8 +81,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
Add(Instruction.ImageAtomic, InstType.Special);
|
Add(Instruction.ImageAtomic, InstType.Special);
|
||||||
Add(Instruction.IsNan, InstType.CallUnary, "isnan");
|
Add(Instruction.IsNan, InstType.CallUnary, "isnan");
|
||||||
Add(Instruction.Load, InstType.Special);
|
Add(Instruction.Load, InstType.Special);
|
||||||
Add(Instruction.LoadLocal, InstType.Special);
|
|
||||||
Add(Instruction.LoadShared, InstType.Special);
|
|
||||||
Add(Instruction.Lod, InstType.Special);
|
Add(Instruction.Lod, InstType.Special);
|
||||||
Add(Instruction.LogarithmB2, InstType.CallUnary, "log2");
|
Add(Instruction.LogarithmB2, InstType.CallUnary, "log2");
|
||||||
Add(Instruction.LogicalAnd, InstType.OpBinaryCom, "&&", 9);
|
Add(Instruction.LogicalAnd, InstType.OpBinaryCom, "&&", 9);
|
||||||
@ -118,10 +114,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
Add(Instruction.Sine, InstType.CallUnary, "sin");
|
Add(Instruction.Sine, InstType.CallUnary, "sin");
|
||||||
Add(Instruction.SquareRoot, InstType.CallUnary, "sqrt");
|
Add(Instruction.SquareRoot, InstType.CallUnary, "sqrt");
|
||||||
Add(Instruction.Store, InstType.Special);
|
Add(Instruction.Store, InstType.Special);
|
||||||
Add(Instruction.StoreLocal, InstType.Special);
|
|
||||||
Add(Instruction.StoreShared, InstType.Special);
|
|
||||||
Add(Instruction.StoreShared16, InstType.Special);
|
|
||||||
Add(Instruction.StoreShared8, InstType.Special);
|
|
||||||
Add(Instruction.Subtract, InstType.OpBinary, "-", 2);
|
Add(Instruction.Subtract, InstType.OpBinary, "-", 2);
|
||||||
Add(Instruction.SwizzleAdd, InstType.CallTernary, HelperFunctionNames.SwizzleAdd);
|
Add(Instruction.SwizzleAdd, InstType.CallTernary, HelperFunctionNames.SwizzleAdd);
|
||||||
Add(Instruction.TextureSample, InstType.Special);
|
Add(Instruction.TextureSample, InstType.Special);
|
||||||
|
@ -191,25 +191,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
return GenerateLoadOrStore(context, operation, isStore: false);
|
return GenerateLoadOrStore(context, operation, isStore: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string LoadLocal(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
return LoadLocalOrShared(context, operation, DefaultNames.LocalMemoryName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string LoadShared(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
return LoadLocalOrShared(context, operation, DefaultNames.SharedMemoryName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string LoadLocalOrShared(CodeGenContext context, AstOperation operation, string arrayName)
|
|
||||||
{
|
|
||||||
IAstNode src1 = operation.GetSource(0);
|
|
||||||
|
|
||||||
string offsetExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
|
||||||
|
|
||||||
return $"{arrayName}[{offsetExpr}]";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string Lod(CodeGenContext context, AstOperation operation)
|
public static string Lod(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||||
@ -263,58 +244,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
return GenerateLoadOrStore(context, operation, isStore: true);
|
return GenerateLoadOrStore(context, operation, isStore: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string StoreLocal(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
return StoreLocalOrShared(context, operation, DefaultNames.LocalMemoryName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string StoreShared(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
return StoreLocalOrShared(context, operation, DefaultNames.SharedMemoryName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string StoreLocalOrShared(CodeGenContext context, AstOperation operation, string arrayName)
|
|
||||||
{
|
|
||||||
IAstNode src1 = operation.GetSource(0);
|
|
||||||
IAstNode src2 = operation.GetSource(1);
|
|
||||||
|
|
||||||
string offsetExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
|
||||||
|
|
||||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src2);
|
|
||||||
|
|
||||||
string src = TypeConversion.ReinterpretCast(context, src2, srcType, AggregateType.U32);
|
|
||||||
|
|
||||||
return $"{arrayName}[{offsetExpr}] = {src}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string StoreShared16(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
IAstNode src1 = operation.GetSource(0);
|
|
||||||
IAstNode src2 = operation.GetSource(1);
|
|
||||||
|
|
||||||
string offsetExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
|
||||||
|
|
||||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src2);
|
|
||||||
|
|
||||||
string src = TypeConversion.ReinterpretCast(context, src2, srcType, AggregateType.U32);
|
|
||||||
|
|
||||||
return $"{HelperFunctionNames.StoreShared16}({offsetExpr}, {src})";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string StoreShared8(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
IAstNode src1 = operation.GetSource(0);
|
|
||||||
IAstNode src2 = operation.GetSource(1);
|
|
||||||
|
|
||||||
string offsetExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
|
||||||
|
|
||||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src2);
|
|
||||||
|
|
||||||
string src = TypeConversion.ReinterpretCast(context, src2, srcType, AggregateType.U32);
|
|
||||||
|
|
||||||
return $"{HelperFunctionNames.StoreShared8}({offsetExpr}, {src})";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string TextureSample(CodeGenContext context, AstOperation operation)
|
public static string TextureSample(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||||
@ -675,6 +604,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
varType = field.Type;
|
varType = field.Type;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case StorageKind.LocalMemory:
|
||||||
|
case StorageKind.SharedMemory:
|
||||||
|
if (!(operation.GetSource(srcIndex++) is AstOperand bindingId) || bindingId.Type != OperandType.Constant)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryDefinition memory = storageKind == StorageKind.LocalMemory
|
||||||
|
? context.Config.Properties.LocalMemories[bindingId.Value]
|
||||||
|
: context.Config.Properties.SharedMemories[bindingId.Value];
|
||||||
|
|
||||||
|
varName = memory.Name;
|
||||||
|
varType = memory.Type;
|
||||||
|
break;
|
||||||
|
|
||||||
case StorageKind.Input:
|
case StorageKind.Input:
|
||||||
case StorageKind.InputPerPatch:
|
case StorageKind.InputPerPatch:
|
||||||
case StorageKind.Output:
|
case StorageKind.Output:
|
||||||
|
@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
if (node is AstOperation operation)
|
if (node is AstOperation operation)
|
||||||
{
|
{
|
||||||
if (operation.Inst == Instruction.Load)
|
if (operation.Inst == Instruction.Load || operation.Inst.IsAtomic())
|
||||||
{
|
{
|
||||||
switch (operation.StorageKind)
|
switch (operation.StorageKind)
|
||||||
{
|
{
|
||||||
@ -136,6 +136,19 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
return field.Type & AggregateType.ElementTypeMask;
|
return field.Type & AggregateType.ElementTypeMask;
|
||||||
|
|
||||||
|
case StorageKind.LocalMemory:
|
||||||
|
case StorageKind.SharedMemory:
|
||||||
|
if (!(operation.GetSource(0) is AstOperand bindingId) || bindingId.Type != OperandType.Constant)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryDefinition memory = operation.StorageKind == StorageKind.LocalMemory
|
||||||
|
? context.Config.Properties.LocalMemories[bindingId.Value]
|
||||||
|
: context.Config.Properties.SharedMemories[bindingId.Value];
|
||||||
|
|
||||||
|
return memory.Type & AggregateType.ElementTypeMask;
|
||||||
|
|
||||||
case StorageKind.Input:
|
case StorageKind.Input:
|
||||||
case StorageKind.InputPerPatch:
|
case StorageKind.InputPerPatch:
|
||||||
case StorageKind.Output:
|
case StorageKind.Output:
|
||||||
|
@ -25,8 +25,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
public Dictionary<int, Instruction> ConstantBuffers { get; } = new Dictionary<int, Instruction>();
|
public Dictionary<int, Instruction> ConstantBuffers { get; } = new Dictionary<int, Instruction>();
|
||||||
public Dictionary<int, Instruction> StorageBuffers { get; } = new Dictionary<int, Instruction>();
|
public Dictionary<int, Instruction> StorageBuffers { get; } = new Dictionary<int, Instruction>();
|
||||||
public Instruction LocalMemory { get; set; }
|
public Dictionary<int, Instruction> LocalMemories { get; } = new Dictionary<int, Instruction>();
|
||||||
public Instruction SharedMemory { get; set; }
|
public Dictionary<int, Instruction> SharedMemories { get; } = new Dictionary<int, Instruction>();
|
||||||
public Dictionary<TextureMeta, SamplerType> SamplersTypes { get; } = new Dictionary<TextureMeta, SamplerType>();
|
public Dictionary<TextureMeta, SamplerType> SamplersTypes { get; } = new Dictionary<TextureMeta, SamplerType>();
|
||||||
public Dictionary<TextureMeta, (Instruction, Instruction, Instruction)> Samplers { get; } = new Dictionary<TextureMeta, (Instruction, Instruction, Instruction)>();
|
public Dictionary<TextureMeta, (Instruction, Instruction, Instruction)> Samplers { get; } = new Dictionary<TextureMeta, (Instruction, Instruction, Instruction)>();
|
||||||
public Dictionary<TextureMeta, (Instruction, Instruction)> Images { get; } = new Dictionary<TextureMeta, (Instruction, Instruction)>();
|
public Dictionary<TextureMeta, (Instruction, Instruction)> Images { get; } = new Dictionary<TextureMeta, (Instruction, Instruction)>();
|
||||||
@ -35,7 +35,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
public Dictionary<IoDefinition, Instruction> InputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>();
|
public Dictionary<IoDefinition, Instruction> InputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>();
|
||||||
public Dictionary<IoDefinition, Instruction> OutputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>();
|
public Dictionary<IoDefinition, Instruction> OutputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>();
|
||||||
|
|
||||||
public Instruction CoordTemp { get; set; }
|
|
||||||
public StructuredFunction CurrentFunction { get; set; }
|
public StructuredFunction CurrentFunction { get; set; }
|
||||||
private readonly Dictionary<AstOperand, Instruction> _locals = new Dictionary<AstOperand, Instruction>();
|
private readonly Dictionary<AstOperand, Instruction> _locals = new Dictionary<AstOperand, Instruction>();
|
||||||
private readonly Dictionary<int, Instruction[]> _localForArgs = new Dictionary<int, Instruction[]>();
|
private readonly Dictionary<int, Instruction[]> _localForArgs = new Dictionary<int, Instruction[]>();
|
||||||
@ -76,6 +75,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
public SpirvDelegates Delegates { get; }
|
public SpirvDelegates Delegates { get; }
|
||||||
|
|
||||||
|
public bool IsMainFunction { get; private set; }
|
||||||
|
public bool MayHaveReturned { get; set; }
|
||||||
|
|
||||||
public CodeGenContext(
|
public CodeGenContext(
|
||||||
StructuredProgramInfo info,
|
StructuredProgramInfo info,
|
||||||
ShaderConfig config,
|
ShaderConfig config,
|
||||||
@ -108,8 +110,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Delegates = new SpirvDelegates(this);
|
Delegates = new SpirvDelegates(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartFunction()
|
public void StartFunction(bool isMainFunction)
|
||||||
{
|
{
|
||||||
|
IsMainFunction = isMainFunction;
|
||||||
|
MayHaveReturned = false;
|
||||||
_locals.Clear();
|
_locals.Clear();
|
||||||
_localForArgs.Clear();
|
_localForArgs.Clear();
|
||||||
_funcArgs.Clear();
|
_funcArgs.Clear();
|
||||||
|
@ -6,7 +6,6 @@ using Spv.Generator;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using static Spv.Specification;
|
using static Spv.Specification;
|
||||||
using SpvInstruction = Spv.Generator.Instruction;
|
using SpvInstruction = Spv.Generator.Instruction;
|
||||||
@ -44,13 +43,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
context.AddLocalVariable(spvLocal);
|
context.AddLocalVariable(spvLocal);
|
||||||
context.DeclareLocal(local, spvLocal);
|
context.DeclareLocal(local, spvLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
var ivector2Type = context.TypeVector(context.TypeS32(), 2);
|
|
||||||
var coordTempPointerType = context.TypePointer(StorageClass.Function, ivector2Type);
|
|
||||||
var coordTemp = context.Variable(coordTempPointerType, StorageClass.Function);
|
|
||||||
|
|
||||||
context.AddLocalVariable(coordTemp);
|
|
||||||
context.CoordTemp = coordTemp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DeclareLocalForArgs(CodeGenContext context, List<StructuredFunction> functions)
|
public static void DeclareLocalForArgs(CodeGenContext context, List<StructuredFunction> functions)
|
||||||
@ -77,54 +69,30 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
public static void DeclareAll(CodeGenContext context, StructuredProgramInfo info)
|
public static void DeclareAll(CodeGenContext context, StructuredProgramInfo info)
|
||||||
{
|
{
|
||||||
if (context.Config.Stage == ShaderStage.Compute)
|
|
||||||
{
|
|
||||||
int localMemorySize = BitUtils.DivRoundUp(context.Config.GpuAccessor.QueryComputeLocalMemorySize(), 4);
|
|
||||||
|
|
||||||
if (localMemorySize != 0)
|
|
||||||
{
|
|
||||||
DeclareLocalMemory(context, localMemorySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sharedMemorySize = BitUtils.DivRoundUp(context.Config.GpuAccessor.QueryComputeSharedMemorySize(), 4);
|
|
||||||
|
|
||||||
if (sharedMemorySize != 0)
|
|
||||||
{
|
|
||||||
DeclareSharedMemory(context, sharedMemorySize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (context.Config.LocalMemorySize != 0)
|
|
||||||
{
|
|
||||||
int localMemorySize = BitUtils.DivRoundUp(context.Config.LocalMemorySize, 4);
|
|
||||||
DeclareLocalMemory(context, localMemorySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
|
DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
|
||||||
DeclareStorageBuffers(context, context.Config.Properties.StorageBuffers.Values);
|
DeclareStorageBuffers(context, context.Config.Properties.StorageBuffers.Values);
|
||||||
|
DeclareMemories(context, context.Config.Properties.LocalMemories, context.LocalMemories, StorageClass.Private);
|
||||||
|
DeclareMemories(context, context.Config.Properties.SharedMemories, context.SharedMemories, StorageClass.Workgroup);
|
||||||
DeclareSamplers(context, context.Config.GetTextureDescriptors());
|
DeclareSamplers(context, context.Config.GetTextureDescriptors());
|
||||||
DeclareImages(context, context.Config.GetImageDescriptors());
|
DeclareImages(context, context.Config.GetImageDescriptors());
|
||||||
DeclareInputsAndOutputs(context, info);
|
DeclareInputsAndOutputs(context, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DeclareLocalMemory(CodeGenContext context, int size)
|
private static void DeclareMemories(
|
||||||
|
CodeGenContext context,
|
||||||
|
IReadOnlyDictionary<int, MemoryDefinition> memories,
|
||||||
|
Dictionary<int, SpvInstruction> dict,
|
||||||
|
StorageClass storage)
|
||||||
{
|
{
|
||||||
context.LocalMemory = DeclareMemory(context, StorageClass.Private, size);
|
foreach ((int id, MemoryDefinition memory) in memories)
|
||||||
}
|
{
|
||||||
|
var pointerType = context.TypePointer(storage, context.GetType(memory.Type, memory.ArrayLength));
|
||||||
|
var variable = context.Variable(pointerType, storage);
|
||||||
|
|
||||||
private static void DeclareSharedMemory(CodeGenContext context, int size)
|
context.AddGlobalVariable(variable);
|
||||||
{
|
|
||||||
context.SharedMemory = DeclareMemory(context, StorageClass.Workgroup, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static SpvInstruction DeclareMemory(CodeGenContext context, StorageClass storage, int size)
|
dict.Add(id, variable);
|
||||||
{
|
}
|
||||||
var arrayType = context.TypeArray(context.TypeU32(), context.Constant(context.TypeU32(), size));
|
|
||||||
var pointerType = context.TypePointer(storage, arrayType);
|
|
||||||
var variable = context.Variable(pointerType, storage);
|
|
||||||
|
|
||||||
context.AddGlobalVariable(variable);
|
|
||||||
|
|
||||||
return variable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DeclareConstantBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
|
private static void DeclareConstantBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
|
||||||
|
@ -97,8 +97,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Add(Instruction.ImageStore, GenerateImageStore);
|
Add(Instruction.ImageStore, GenerateImageStore);
|
||||||
Add(Instruction.IsNan, GenerateIsNan);
|
Add(Instruction.IsNan, GenerateIsNan);
|
||||||
Add(Instruction.Load, GenerateLoad);
|
Add(Instruction.Load, GenerateLoad);
|
||||||
Add(Instruction.LoadLocal, GenerateLoadLocal);
|
|
||||||
Add(Instruction.LoadShared, GenerateLoadShared);
|
|
||||||
Add(Instruction.Lod, GenerateLod);
|
Add(Instruction.Lod, GenerateLod);
|
||||||
Add(Instruction.LogarithmB2, GenerateLogarithmB2);
|
Add(Instruction.LogarithmB2, GenerateLogarithmB2);
|
||||||
Add(Instruction.LogicalAnd, GenerateLogicalAnd);
|
Add(Instruction.LogicalAnd, GenerateLogicalAnd);
|
||||||
@ -132,10 +130,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Add(Instruction.Sine, GenerateSine);
|
Add(Instruction.Sine, GenerateSine);
|
||||||
Add(Instruction.SquareRoot, GenerateSquareRoot);
|
Add(Instruction.SquareRoot, GenerateSquareRoot);
|
||||||
Add(Instruction.Store, GenerateStore);
|
Add(Instruction.Store, GenerateStore);
|
||||||
Add(Instruction.StoreLocal, GenerateStoreLocal);
|
|
||||||
Add(Instruction.StoreShared, GenerateStoreShared);
|
|
||||||
Add(Instruction.StoreShared16, GenerateStoreShared16);
|
|
||||||
Add(Instruction.StoreShared8, GenerateStoreShared8);
|
|
||||||
Add(Instruction.Subtract, GenerateSubtract);
|
Add(Instruction.Subtract, GenerateSubtract);
|
||||||
Add(Instruction.SwizzleAdd, GenerateSwizzleAdd);
|
Add(Instruction.SwizzleAdd, GenerateSwizzleAdd);
|
||||||
Add(Instruction.TextureSample, GenerateTextureSample);
|
Add(Instruction.TextureSample, GenerateTextureSample);
|
||||||
@ -242,6 +236,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateBarrier(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateBarrier(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
|
// Barrier on divergent control flow paths may cause the GPU to hang,
|
||||||
|
// so skip emitting the barrier for those cases.
|
||||||
|
if (!context.Config.GpuAccessor.QueryHostSupportsShaderBarrierDivergence() &&
|
||||||
|
(context.CurrentBlock.Type != AstBlockType.Main || context.MayHaveReturned || !context.IsMainFunction))
|
||||||
|
{
|
||||||
|
context.Config.GpuAccessor.Log($"Shader has barrier on potentially divergent block, the barrier will be removed.");
|
||||||
|
|
||||||
|
return OperationResult.Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
context.ControlBarrier(
|
context.ControlBarrier(
|
||||||
context.Constant(context.TypeU32(), Scope.Workgroup),
|
context.Constant(context.TypeU32(), Scope.Workgroup),
|
||||||
context.Constant(context.TypeU32(), Scope.Workgroup),
|
context.Constant(context.TypeU32(), Scope.Workgroup),
|
||||||
@ -861,30 +865,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
return GenerateLoadOrStore(context, operation, isStore: false);
|
return GenerateLoadOrStore(context, operation, isStore: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateLoadLocal(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
return GenerateLoadLocalOrShared(context, operation, StorageClass.Private, context.LocalMemory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateLoadShared(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
return GenerateLoadLocalOrShared(context, operation, StorageClass.Workgroup, context.SharedMemory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateLoadLocalOrShared(
|
|
||||||
CodeGenContext context,
|
|
||||||
AstOperation operation,
|
|
||||||
StorageClass storageClass,
|
|
||||||
SpvInstruction memory)
|
|
||||||
{
|
|
||||||
var offset = context.Get(AggregateType.S32, operation.GetSource(0));
|
|
||||||
|
|
||||||
var elemPointer = context.AccessChain(context.TypePointer(storageClass, context.TypeU32()), memory, offset);
|
|
||||||
var value = context.Load(context.TypeU32(), elemPointer);
|
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateLod(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateLod(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||||
@ -1092,6 +1072,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateReturn(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateReturn(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
|
context.MayHaveReturned = true;
|
||||||
|
|
||||||
if (operation.SourcesCount != 0)
|
if (operation.SourcesCount != 0)
|
||||||
{
|
{
|
||||||
context.ReturnValue(context.Get(context.CurrentFunction.ReturnType, operation.GetSource(0)));
|
context.ReturnValue(context.Get(context.CurrentFunction.ReturnType, operation.GetSource(0)));
|
||||||
@ -1256,45 +1238,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
return GenerateLoadOrStore(context, operation, isStore: true);
|
return GenerateLoadOrStore(context, operation, isStore: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateStoreLocal(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
return GenerateStoreLocalOrShared(context, operation, StorageClass.Private, context.LocalMemory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateStoreShared(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
return GenerateStoreLocalOrShared(context, operation, StorageClass.Workgroup, context.SharedMemory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateStoreLocalOrShared(
|
|
||||||
CodeGenContext context,
|
|
||||||
AstOperation operation,
|
|
||||||
StorageClass storageClass,
|
|
||||||
SpvInstruction memory)
|
|
||||||
{
|
|
||||||
var offset = context.Get(AggregateType.S32, operation.GetSource(0));
|
|
||||||
var value = context.Get(AggregateType.U32, operation.GetSource(1));
|
|
||||||
|
|
||||||
var elemPointer = context.AccessChain(context.TypePointer(storageClass, context.TypeU32()), memory, offset);
|
|
||||||
context.Store(elemPointer, value);
|
|
||||||
|
|
||||||
return OperationResult.Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateStoreShared16(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
GenerateStoreSharedSmallInt(context, operation, 16);
|
|
||||||
|
|
||||||
return OperationResult.Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateStoreShared8(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
GenerateStoreSharedSmallInt(context, operation, 8);
|
|
||||||
|
|
||||||
return OperationResult.Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateSubtract(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateSubtract(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
return GenerateBinary(context, operation, context.Delegates.FSub, context.Delegates.ISub);
|
return GenerateBinary(context, operation, context.Delegates.FSub, context.Delegates.ISub);
|
||||||
@ -1815,55 +1758,27 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitU)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitU)
|
||||||
{
|
{
|
||||||
var value = context.GetU32(operation.GetSource(operation.SourcesCount - 1));
|
SpvInstruction elemPointer = GetStoragePointer(context, operation, out AggregateType varType);
|
||||||
|
|
||||||
SpvInstruction elemPointer;
|
var value = context.Get(varType, operation.GetSource(operation.SourcesCount - 1));
|
||||||
|
|
||||||
if (operation.StorageKind == StorageKind.StorageBuffer)
|
|
||||||
{
|
|
||||||
elemPointer = GetStoragePointer(context, operation, out _);
|
|
||||||
}
|
|
||||||
else if (operation.StorageKind == StorageKind.SharedMemory)
|
|
||||||
{
|
|
||||||
var offset = context.GetU32(operation.GetSource(0));
|
|
||||||
elemPointer = context.AccessChain(context.TypePointer(StorageClass.Workgroup, context.TypeU32()), context.SharedMemory, offset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"Invalid storage kind \"{operation.StorageKind}\".");
|
|
||||||
}
|
|
||||||
|
|
||||||
var one = context.Constant(context.TypeU32(), 1);
|
var one = context.Constant(context.TypeU32(), 1);
|
||||||
var zero = context.Constant(context.TypeU32(), 0);
|
var zero = context.Constant(context.TypeU32(), 0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, emitU(context.TypeU32(), elemPointer, one, zero, value));
|
return new OperationResult(varType, emitU(context.GetType(varType), elemPointer, one, zero, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateAtomicMemoryCas(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateAtomicMemoryCas(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var value0 = context.GetU32(operation.GetSource(operation.SourcesCount - 2));
|
SpvInstruction elemPointer = GetStoragePointer(context, operation, out AggregateType varType);
|
||||||
var value1 = context.GetU32(operation.GetSource(operation.SourcesCount - 1));
|
|
||||||
|
|
||||||
SpvInstruction elemPointer;
|
var value0 = context.Get(varType, operation.GetSource(operation.SourcesCount - 2));
|
||||||
|
var value1 = context.Get(varType, operation.GetSource(operation.SourcesCount - 1));
|
||||||
if (operation.StorageKind == StorageKind.StorageBuffer)
|
|
||||||
{
|
|
||||||
elemPointer = GetStoragePointer(context, operation, out _);
|
|
||||||
}
|
|
||||||
else if (operation.StorageKind == StorageKind.SharedMemory)
|
|
||||||
{
|
|
||||||
var offset = context.GetU32(operation.GetSource(0));
|
|
||||||
elemPointer = context.AccessChain(context.TypePointer(StorageClass.Workgroup, context.TypeU32()), context.SharedMemory, offset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"Invalid storage kind \"{operation.StorageKind}\".");
|
|
||||||
}
|
|
||||||
|
|
||||||
var one = context.Constant(context.TypeU32(), 1);
|
var one = context.Constant(context.TypeU32(), 1);
|
||||||
var zero = context.Constant(context.TypeU32(), 0);
|
var zero = context.Constant(context.TypeU32(), 0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, context.AtomicCompareExchange(context.TypeU32(), elemPointer, one, zero, zero, value1, value0));
|
return new OperationResult(varType, context.AtomicCompareExchange(context.GetType(varType), elemPointer, one, zero, zero, value1, value0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateLoadOrStore(CodeGenContext context, AstOperation operation, bool isStore)
|
private static OperationResult GenerateLoadOrStore(CodeGenContext context, AstOperation operation, bool isStore)
|
||||||
@ -1916,6 +1831,27 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
: context.StorageBuffers[bindingIndex.Value];
|
: context.StorageBuffers[bindingIndex.Value];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case StorageKind.LocalMemory:
|
||||||
|
case StorageKind.SharedMemory:
|
||||||
|
if (!(operation.GetSource(srcIndex++) is AstOperand bindingId) || bindingId.Type != OperandType.Constant)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (storageKind == StorageKind.LocalMemory)
|
||||||
|
{
|
||||||
|
storageClass = StorageClass.Private;
|
||||||
|
varType = context.Config.Properties.LocalMemories[bindingId.Value].Type & AggregateType.ElementTypeMask;
|
||||||
|
baseObj = context.LocalMemories[bindingId.Value];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
storageClass = StorageClass.Workgroup;
|
||||||
|
varType = context.Config.Properties.SharedMemories[bindingId.Value].Type & AggregateType.ElementTypeMask;
|
||||||
|
baseObj = context.SharedMemories[bindingId.Value];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case StorageKind.Input:
|
case StorageKind.Input:
|
||||||
case StorageKind.InputPerPatch:
|
case StorageKind.InputPerPatch:
|
||||||
case StorageKind.Output:
|
case StorageKind.Output:
|
||||||
@ -2036,50 +1972,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
return context.Load(context.GetType(varType), context.Inputs[ioDefinition]);
|
return context.Load(context.GetType(varType), context.Inputs[ioDefinition]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateStoreSharedSmallInt(CodeGenContext context, AstOperation operation, int bitSize)
|
|
||||||
{
|
|
||||||
var offset = context.Get(AggregateType.U32, operation.GetSource(0));
|
|
||||||
var value = context.Get(AggregateType.U32, operation.GetSource(1));
|
|
||||||
|
|
||||||
var wordOffset = context.ShiftRightLogical(context.TypeU32(), offset, context.Constant(context.TypeU32(), 2));
|
|
||||||
var bitOffset = context.BitwiseAnd(context.TypeU32(), offset, context.Constant(context.TypeU32(), 3));
|
|
||||||
bitOffset = context.ShiftLeftLogical(context.TypeU32(), bitOffset, context.Constant(context.TypeU32(), 3));
|
|
||||||
|
|
||||||
var memory = context.SharedMemory;
|
|
||||||
|
|
||||||
var elemPointer = context.AccessChain(context.TypePointer(StorageClass.Workgroup, context.TypeU32()), memory, wordOffset);
|
|
||||||
|
|
||||||
GenerateStoreSmallInt(context, elemPointer, bitOffset, value, bitSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void GenerateStoreSmallInt(
|
|
||||||
CodeGenContext context,
|
|
||||||
SpvInstruction elemPointer,
|
|
||||||
SpvInstruction bitOffset,
|
|
||||||
SpvInstruction value,
|
|
||||||
int bitSize)
|
|
||||||
{
|
|
||||||
var loopStart = context.Label();
|
|
||||||
var loopEnd = context.Label();
|
|
||||||
|
|
||||||
context.Branch(loopStart);
|
|
||||||
context.AddLabel(loopStart);
|
|
||||||
|
|
||||||
var oldValue = context.Load(context.TypeU32(), elemPointer);
|
|
||||||
var newValue = context.BitFieldInsert(context.TypeU32(), oldValue, value, bitOffset, context.Constant(context.TypeU32(), bitSize));
|
|
||||||
|
|
||||||
var one = context.Constant(context.TypeU32(), 1);
|
|
||||||
var zero = context.Constant(context.TypeU32(), 0);
|
|
||||||
|
|
||||||
var result = context.AtomicCompareExchange(context.TypeU32(), elemPointer, one, zero, zero, newValue, oldValue);
|
|
||||||
var failed = context.INotEqual(context.TypeBool(), result, oldValue);
|
|
||||||
|
|
||||||
context.LoopMerge(loopEnd, loopStart, LoopControlMask.MaskNone);
|
|
||||||
context.BranchConditional(failed, loopStart, loopEnd);
|
|
||||||
|
|
||||||
context.AddLabel(loopEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GetZeroOperationResult(
|
private static OperationResult GetZeroOperationResult(
|
||||||
CodeGenContext context,
|
CodeGenContext context,
|
||||||
AstTextureOperation texOp,
|
AstTextureOperation texOp,
|
||||||
|
@ -148,7 +148,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
context.CurrentFunction = function;
|
context.CurrentFunction = function;
|
||||||
context.AddFunction(spvFunc);
|
context.AddFunction(spvFunc);
|
||||||
context.StartFunction();
|
context.StartFunction(isMainFunction: funcIndex == 0);
|
||||||
|
|
||||||
Declarations.DeclareParameters(context, function);
|
Declarations.DeclareParameters(context, function);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -247,6 +247,17 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
{
|
{
|
||||||
block.AddPushOp(op);
|
block.AddPushOp(op);
|
||||||
}
|
}
|
||||||
|
else if (op.Name == InstName.Ldl || op.Name == InstName.Stl)
|
||||||
|
{
|
||||||
|
config.SetUsedFeature(FeatureFlags.LocalMemory);
|
||||||
|
}
|
||||||
|
else if (op.Name == InstName.Atoms ||
|
||||||
|
op.Name == InstName.AtomsCas ||
|
||||||
|
op.Name == InstName.Lds ||
|
||||||
|
op.Name == InstName.Sts)
|
||||||
|
{
|
||||||
|
config.SetUsedFeature(FeatureFlags.SharedMemory);
|
||||||
|
}
|
||||||
|
|
||||||
block.OpCodes.Add(op);
|
block.OpCodes.Add(op);
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user