Compare commits
45 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
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 | ||
|
21c9ac6240 | ||
|
81c9052847 | ||
|
9367e3c35d | ||
|
52cf141874 | ||
|
8a352df3c6 | ||
|
c545c59851 | ||
|
96ea4e8c8e | ||
|
b8f48bcf64 | ||
|
6966211e07 | ||
|
57524a4c8a | ||
|
f4539c49d8 | ||
|
12c62fdbc2 | ||
|
e3c6be5e29 | ||
|
4741a05df9 | ||
|
c6676007bf | ||
|
92b0b7d753 | ||
|
232237bf28 | ||
|
c27e453fd3 | ||
|
0e037d0213 |
19
.github/ISSUE_TEMPLATE/missing_shader_instruction.yml
vendored
Normal file
19
.github/ISSUE_TEMPLATE/missing_shader_instruction.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
name: Missing Shader Instruction
|
||||||
|
description: Shader Instruction is missing in Ryujinx.
|
||||||
|
title: "[GPU]"
|
||||||
|
labels: [gpu, not-implemented]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: instruction
|
||||||
|
attributes:
|
||||||
|
label: Shader instruction
|
||||||
|
description: What shader instruction is missing?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: required
|
||||||
|
attributes:
|
||||||
|
label: Required by
|
||||||
|
description: Add links to the [compatibility list page(s)](https://github.com/Ryujinx/Ryujinx-Games-List/issues) of the game(s) that require this instruction.
|
||||||
|
validations:
|
||||||
|
required: true
|
8
.github/assign/audio.yml
vendored
Normal file
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:
|
||||||
|
- 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'
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -18,6 +18,10 @@ on:
|
|||||||
- '*.yml'
|
- '*.yml'
|
||||||
- 'README.md'
|
- 'README.md'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: pr-checks-${{ github.event.number }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
|
51
.github/workflows/pr_triage.yml
vendored
Normal file
51
.github/workflows/pr_triage.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
name: "Pull Request Triage"
|
||||||
|
on:
|
||||||
|
- pull_request_target
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
- uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/audio.yml'
|
||||||
|
if: github.event.action == 'opened'
|
||||||
|
|
||||||
|
- uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/cpu.yml'
|
||||||
|
if: github.event.action == 'opened'
|
||||||
|
|
||||||
|
- uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/gpu.yml'
|
||||||
|
if: github.event.action == 'opened'
|
||||||
|
|
||||||
|
- uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/gui.yml'
|
||||||
|
if: github.event.action == 'opened'
|
||||||
|
|
||||||
|
- uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/horizon.yml'
|
||||||
|
if: github.event.action == 'opened'
|
||||||
|
|
||||||
|
- uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/infra.yml'
|
||||||
|
if: github.event.action == 'opened'
|
||||||
|
|
||||||
|
- uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/global.yml'
|
||||||
|
if: github.event.action == 'opened'
|
@@ -13,7 +13,7 @@
|
|||||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageVersion Include="Concentus" Version="1.1.7" />
|
<PackageVersion Include="Concentus" Version="1.1.7" />
|
||||||
<PackageVersion Include="DiscordRichPresence" Version="1.1.3.18" />
|
<PackageVersion Include="DiscordRichPresence" Version="1.1.3.18" />
|
||||||
<PackageVersion Include="DynamicData" Version="7.13.8" />
|
<PackageVersion Include="DynamicData" Version="7.14.2" />
|
||||||
<PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" />
|
<PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" />
|
||||||
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
|
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
|
||||||
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
|
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
|
||||||
@@ -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.0" />
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
|
||||||
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
|
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
|
||||||
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
|
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
|
||||||
<PackageVersion Include="NUnit" Version="3.13.3" />
|
<PackageVersion Include="NUnit" Version="3.13.3" />
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
|
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
|
||||||
<PackageVersion Include="SPB" Version="0.0.4-build28" />
|
<PackageVersion Include="SPB" Version="0.0.4-build28" />
|
||||||
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
|
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
|
||||||
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.30.1" />
|
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
|
||||||
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
|
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
|
||||||
<PackageVersion Include="System.Management" Version="7.0.1" />
|
<PackageVersion Include="System.Management" Version="7.0.1" />
|
||||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||||
|
@@ -168,8 +168,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
Logger.StartPass(PassName.CodeGeneration);
|
Logger.StartPass(PassName.CodeGeneration);
|
||||||
|
|
||||||
//Console.Error.WriteLine(IRDumper.GetDump(cfg));
|
|
||||||
|
|
||||||
bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0;
|
bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0;
|
||||||
|
|
||||||
CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable);
|
CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable);
|
||||||
|
@@ -179,6 +179,35 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
(uint)operation.GetSource(2).AsInt32());
|
(uint)operation.GetSource(2).AsInt32());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IntrinsicType.Vector128Unary:
|
||||||
|
GenerateVectorUnary(
|
||||||
|
context,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
info.Inst,
|
||||||
|
operation.Destination,
|
||||||
|
operation.GetSource(0));
|
||||||
|
break;
|
||||||
|
case IntrinsicType.Vector128Binary:
|
||||||
|
GenerateVectorBinary(
|
||||||
|
context,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
info.Inst,
|
||||||
|
operation.Destination,
|
||||||
|
operation.GetSource(0),
|
||||||
|
operation.GetSource(1));
|
||||||
|
break;
|
||||||
|
case IntrinsicType.Vector128BinaryRd:
|
||||||
|
GenerateVectorUnary(
|
||||||
|
context,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
info.Inst,
|
||||||
|
operation.Destination,
|
||||||
|
operation.GetSource(1));
|
||||||
|
break;
|
||||||
|
|
||||||
case IntrinsicType.VectorUnary:
|
case IntrinsicType.VectorUnary:
|
||||||
GenerateVectorUnary(
|
GenerateVectorUnary(
|
||||||
context,
|
context,
|
||||||
|
@@ -19,8 +19,8 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary));
|
Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary));
|
||||||
Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary));
|
Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary));
|
||||||
Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary));
|
Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary));
|
||||||
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128Unary));
|
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128BinaryRd));
|
||||||
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128Unary));
|
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128BinaryRd));
|
||||||
Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary));
|
Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary));
|
||||||
Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary));
|
Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary));
|
||||||
Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise));
|
Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise));
|
||||||
|
@@ -23,6 +23,10 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
ScalarTernaryShlRd,
|
ScalarTernaryShlRd,
|
||||||
ScalarTernaryShrRd,
|
ScalarTernaryShrRd,
|
||||||
|
|
||||||
|
Vector128Unary,
|
||||||
|
Vector128Binary,
|
||||||
|
Vector128BinaryRd,
|
||||||
|
|
||||||
VectorUnary,
|
VectorUnary,
|
||||||
VectorUnaryBitwise,
|
VectorUnaryBitwise,
|
||||||
VectorUnaryByElem,
|
VectorUnaryByElem,
|
||||||
@@ -50,9 +54,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
VectorTernaryShlRd,
|
VectorTernaryShlRd,
|
||||||
VectorTernaryShrRd,
|
VectorTernaryShrRd,
|
||||||
|
|
||||||
Vector128Unary,
|
|
||||||
Vector128Binary,
|
|
||||||
|
|
||||||
GetRegister,
|
GetRegister,
|
||||||
SetRegister
|
SetRegister
|
||||||
}
|
}
|
||||||
|
@@ -746,6 +746,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
|
info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
|
||||||
info.Type == IntrinsicType.ScalarTernaryShlRd ||
|
info.Type == IntrinsicType.ScalarTernaryShlRd ||
|
||||||
info.Type == IntrinsicType.ScalarTernaryShrRd ||
|
info.Type == IntrinsicType.ScalarTernaryShrRd ||
|
||||||
|
info.Type == IntrinsicType.Vector128BinaryRd ||
|
||||||
info.Type == IntrinsicType.VectorBinaryRd ||
|
info.Type == IntrinsicType.VectorBinaryRd ||
|
||||||
info.Type == IntrinsicType.VectorInsertByElem ||
|
info.Type == IntrinsicType.VectorInsertByElem ||
|
||||||
info.Type == IntrinsicType.VectorTernaryRd ||
|
info.Type == IntrinsicType.VectorTernaryRd ||
|
||||||
|
@@ -17,7 +17,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesdV, d, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||||
}
|
}
|
||||||
@@ -38,7 +42,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AeseV, d, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||||
}
|
}
|
||||||
@@ -58,7 +66,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
||||||
}
|
}
|
||||||
@@ -78,7 +90,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
Operand roundKey = context.VectorZero();
|
Operand roundKey = context.VectorZero();
|
||||||
|
|
||||||
|
@@ -17,7 +17,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesdV, d, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||||
}
|
}
|
||||||
@@ -38,7 +42,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AeseV, d, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||||
}
|
}
|
||||||
@@ -58,7 +66,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
||||||
}
|
}
|
||||||
@@ -78,7 +90,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res;
|
Operand res;
|
||||||
|
|
||||||
if (Optimizations.UseAesni)
|
if (Optimizations.UseArm64Aes)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseAesni)
|
||||||
{
|
{
|
||||||
Operand roundKey = context.VectorZero();
|
Operand roundKey = context.VectorZero();
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -6,10 +6,11 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace ARMeilleure.Translation.Cache
|
namespace ARMeilleure.Translation.Cache
|
||||||
{
|
{
|
||||||
static class JitCache
|
static partial class JitCache
|
||||||
{
|
{
|
||||||
private const int PageSize = 4 * 1024;
|
private const int PageSize = 4 * 1024;
|
||||||
private const int PageMask = PageSize - 1;
|
private const int PageMask = PageSize - 1;
|
||||||
@@ -27,6 +28,10 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
private static readonly object _lock = new object();
|
private static readonly object _lock = new object();
|
||||||
private static bool _initialized;
|
private static bool _initialized;
|
||||||
|
|
||||||
|
[SupportedOSPlatform("windows")]
|
||||||
|
[LibraryImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static partial IntPtr FlushInstructionCache(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize);
|
||||||
|
|
||||||
public static void Initialize(IJitMemoryAllocator allocator)
|
public static void Initialize(IJitMemoryAllocator allocator)
|
||||||
{
|
{
|
||||||
if (_initialized) return;
|
if (_initialized) return;
|
||||||
@@ -36,7 +41,11 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
if (_initialized) return;
|
if (_initialized) return;
|
||||||
|
|
||||||
_jitRegion = new ReservedRegion(allocator, CacheSize);
|
_jitRegion = new ReservedRegion(allocator, CacheSize);
|
||||||
_jitCacheInvalidator = new JitCacheInvalidation(allocator);
|
|
||||||
|
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
|
||||||
|
{
|
||||||
|
_jitCacheInvalidator = new JitCacheInvalidation(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
|
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
|
||||||
|
|
||||||
@@ -77,7 +86,14 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
Marshal.Copy(code, 0, funcPtr, code.Length);
|
Marshal.Copy(code, 0, funcPtr, code.Length);
|
||||||
ReprotectAsExecutable(funcOffset, code.Length);
|
ReprotectAsExecutable(funcOffset, code.Length);
|
||||||
|
|
||||||
_jitCacheInvalidator.Invalidate(funcPtr, (ulong)code.Length);
|
if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||||
|
{
|
||||||
|
FlushInstructionCache(Process.GetCurrentProcess().Handle, funcPtr, (UIntPtr)code.Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_jitCacheInvalidator?.Invalidate(funcPtr, (ulong)code.Length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Add(funcOffset, code.Length, func.UnwindInfo);
|
Add(funcOffset, code.Length, func.UnwindInfo);
|
||||||
|
@@ -47,8 +47,8 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
|
|
||||||
public JitCacheInvalidation(IJitMemoryAllocator allocator)
|
public JitCacheInvalidation(IJitMemoryAllocator allocator)
|
||||||
{
|
{
|
||||||
// On macOS, a different path is used to write to the JIT cache, which does the invalidation.
|
// On macOS and Windows, a different path is used to write to the JIT cache, which does the invalidation.
|
||||||
if (!OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||||
{
|
{
|
||||||
ulong size = (ulong)_invalidationCode.Length * sizeof(int);
|
ulong size = (ulong)_invalidationCode.Length * sizeof(int);
|
||||||
ulong mask = (ulong)ReservedRegion.DefaultGranularity - 1;
|
ulong mask = (ulong)ReservedRegion.DefaultGranularity - 1;
|
||||||
|
@@ -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 = 5281; //! To be incremented manually for each change to the ARMeilleure project.
|
||||||
|
|
||||||
private const string ActualDir = "0";
|
private const string ActualDir = "0";
|
||||||
private const string BackupDir = "1";
|
private const string BackupDir = "1";
|
||||||
|
@@ -40,6 +40,7 @@ using SixLabors.ImageSharp;
|
|||||||
using SixLabors.ImageSharp.Formats.Png;
|
using SixLabors.ImageSharp.Formats.Png;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using SPB.Graphics.Exceptions;
|
||||||
using SPB.Graphics.Vulkan;
|
using SPB.Graphics.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -92,6 +93,8 @@ namespace Ryujinx.Ava
|
|||||||
private bool _isActive;
|
private bool _isActive;
|
||||||
private bool _renderingStarted;
|
private bool _renderingStarted;
|
||||||
|
|
||||||
|
private ManualResetEvent _gpuDoneEvent;
|
||||||
|
|
||||||
private IRenderer _renderer;
|
private IRenderer _renderer;
|
||||||
private readonly Thread _renderingThread;
|
private readonly Thread _renderingThread;
|
||||||
private readonly CancellationTokenSource _gpuCancellationTokenSource;
|
private readonly CancellationTokenSource _gpuCancellationTokenSource;
|
||||||
@@ -183,6 +186,7 @@ namespace Ryujinx.Ava
|
|||||||
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState;
|
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState;
|
||||||
|
|
||||||
_gpuCancellationTokenSource = new CancellationTokenSource();
|
_gpuCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
_gpuDoneEvent = new ManualResetEvent(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TopLevel_PointerEnterOrMoved(object sender, PointerEventArgs e)
|
private void TopLevel_PointerEnterOrMoved(object sender, PointerEventArgs e)
|
||||||
@@ -423,10 +427,10 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
_isActive = false;
|
_isActive = false;
|
||||||
|
|
||||||
if (_renderingThread.IsAlive)
|
// NOTE: The render loop is allowed to stay alive until the renderer itself is disposed, as it may handle resource dispose.
|
||||||
{
|
// We only need to wait for all commands submitted during the main gpu loop to be processed.
|
||||||
_renderingThread.Join();
|
_gpuDoneEvent.WaitOne();
|
||||||
}
|
_gpuDoneEvent.Dispose();
|
||||||
|
|
||||||
DisplaySleep.Restore();
|
DisplaySleep.Restore();
|
||||||
|
|
||||||
@@ -472,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)
|
||||||
@@ -917,9 +930,17 @@ namespace Ryujinx.Ava
|
|||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure all commands in the run loop are fully executed before leaving the loop.
|
||||||
|
if (Device.Gpu.Renderer is ThreadedRenderer threaded)
|
||||||
|
{
|
||||||
|
threaded.FlushThreadedCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
_gpuDoneEvent.Set();
|
||||||
});
|
});
|
||||||
|
|
||||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);
|
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateStatus()
|
public void UpdateStatus()
|
||||||
@@ -1033,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",
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using FluentAvalonia.Core;
|
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
@@ -30,14 +29,14 @@ namespace Ryujinx.Ava.Input
|
|||||||
_window = window;
|
_window = window;
|
||||||
|
|
||||||
_widget.PointerMoved += Parent_PointerMovedEvent;
|
_widget.PointerMoved += Parent_PointerMovedEvent;
|
||||||
_widget.PointerPressed += Parent_PointerPressEvent;
|
_widget.PointerPressed += Parent_PointerPressedEvent;
|
||||||
_widget.PointerReleased += Parent_PointerReleaseEvent;
|
_widget.PointerReleased += Parent_PointerReleasedEvent;
|
||||||
_widget.PointerWheelChanged += Parent_ScrollEvent;
|
_widget.PointerWheelChanged += Parent_PointerWheelChanged;
|
||||||
|
|
||||||
_window.PointerMoved += Parent_PointerMovedEvent;
|
_window.PointerMoved += Parent_PointerMovedEvent;
|
||||||
_window.PointerPressed += Parent_PointerPressEvent;
|
_window.PointerPressed += Parent_PointerPressedEvent;
|
||||||
_window.PointerReleased += Parent_PointerReleaseEvent;
|
_window.PointerReleased += Parent_PointerReleasedEvent;
|
||||||
_window.PointerWheelChanged += Parent_ScrollEvent;
|
_window.PointerWheelChanged += Parent_PointerWheelChanged;
|
||||||
|
|
||||||
PressedButtons = new bool[(int)MouseButton.Count];
|
PressedButtons = new bool[(int)MouseButton.Count];
|
||||||
|
|
||||||
@@ -63,29 +62,25 @@ namespace Ryujinx.Ava.Input
|
|||||||
_size = new Size((int)rect.Width, (int)rect.Height);
|
_size = new Size((int)rect.Width, (int)rect.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Parent_ScrollEvent(object o, PointerWheelEventArgs args)
|
private void Parent_PointerWheelChanged(object o, PointerWheelEventArgs args)
|
||||||
{
|
{
|
||||||
Scroll = new Vector2((float)args.Delta.X, (float)args.Delta.Y);
|
Scroll = new Vector2((float)args.Delta.X, (float)args.Delta.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Parent_PointerReleaseEvent(object o, PointerReleasedEventArgs args)
|
private void Parent_PointerReleasedEvent(object o, PointerReleasedEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.InitialPressMouseButton != Avalonia.Input.MouseButton.None)
|
uint button = (uint)args.InitialPressMouseButton - 1;
|
||||||
{
|
|
||||||
int button = (int)args.InitialPressMouseButton;
|
|
||||||
|
|
||||||
if (PressedButtons.Count() >= button)
|
if ((uint)PressedButtons.Length > button)
|
||||||
{
|
{
|
||||||
PressedButtons[button] = false;
|
PressedButtons[button] = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void Parent_PointerPressedEvent(object o, PointerPressedEventArgs args)
|
||||||
private void Parent_PointerPressEvent(object o, PointerPressedEventArgs args)
|
|
||||||
{
|
{
|
||||||
int button = (int)args.GetCurrentPoint(_widget).Properties.PointerUpdateKind;
|
uint button = (uint)args.GetCurrentPoint(_widget).Properties.PointerUpdateKind;
|
||||||
|
|
||||||
if (PressedButtons.Count() >= button)
|
if ((uint)PressedButtons.Length > button)
|
||||||
{
|
{
|
||||||
PressedButtons[button] = true;
|
PressedButtons[button] = true;
|
||||||
}
|
}
|
||||||
@@ -100,17 +95,17 @@ namespace Ryujinx.Ava.Input
|
|||||||
|
|
||||||
public void SetMousePressed(MouseButton button)
|
public void SetMousePressed(MouseButton button)
|
||||||
{
|
{
|
||||||
if (PressedButtons.Count() >= (int)button)
|
if ((uint)PressedButtons.Length > (uint)button)
|
||||||
{
|
{
|
||||||
PressedButtons[(int)button] = true;
|
PressedButtons[(uint)button] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMouseReleased(MouseButton button)
|
public void SetMouseReleased(MouseButton button)
|
||||||
{
|
{
|
||||||
if (PressedButtons.Count() >= (int)button)
|
if ((uint)PressedButtons.Length > (uint)button)
|
||||||
{
|
{
|
||||||
PressedButtons[(int)button] = false;
|
PressedButtons[(uint)button] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,9 +116,9 @@ namespace Ryujinx.Ava.Input
|
|||||||
|
|
||||||
public bool IsButtonPressed(MouseButton button)
|
public bool IsButtonPressed(MouseButton button)
|
||||||
{
|
{
|
||||||
if (PressedButtons.Count() >= (int)button)
|
if ((uint)PressedButtons.Length > (uint)button)
|
||||||
{
|
{
|
||||||
return PressedButtons[(int)button];
|
return PressedButtons[(uint)button];
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -149,14 +144,14 @@ namespace Ryujinx.Ava.Input
|
|||||||
_isDisposed = true;
|
_isDisposed = true;
|
||||||
|
|
||||||
_widget.PointerMoved -= Parent_PointerMovedEvent;
|
_widget.PointerMoved -= Parent_PointerMovedEvent;
|
||||||
_widget.PointerPressed -= Parent_PointerPressEvent;
|
_widget.PointerPressed -= Parent_PointerPressedEvent;
|
||||||
_widget.PointerReleased -= Parent_PointerReleaseEvent;
|
_widget.PointerReleased -= Parent_PointerReleasedEvent;
|
||||||
_widget.PointerWheelChanged -= Parent_ScrollEvent;
|
_widget.PointerWheelChanged -= Parent_PointerWheelChanged;
|
||||||
|
|
||||||
_window.PointerMoved -= Parent_PointerMovedEvent;
|
_window.PointerMoved -= Parent_PointerMovedEvent;
|
||||||
_window.PointerPressed -= Parent_PointerPressEvent;
|
_window.PointerPressed -= Parent_PointerPressedEvent;
|
||||||
_window.PointerReleased -= Parent_PointerReleaseEvent;
|
_window.PointerReleased -= Parent_PointerReleasedEvent;
|
||||||
_window.PointerWheelChanged -= Parent_ScrollEvent;
|
_window.PointerWheelChanged -= Parent_PointerWheelChanged;
|
||||||
|
|
||||||
_widget = null;
|
_widget = null;
|
||||||
}
|
}
|
||||||
|
@@ -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>
|
||||||
|
@@ -21,6 +21,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
if (value is byte[] buffer && targetType == typeof(IImage))
|
if (value is byte[] buffer && targetType == typeof(IImage))
|
||||||
{
|
{
|
||||||
MemoryStream mem = new(buffer);
|
MemoryStream mem = new(buffer);
|
||||||
|
|
||||||
return new Bitmap(mem);
|
return new Bitmap(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -318,7 +318,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
|
|
||||||
Window parent = GetMainWindow();
|
Window parent = GetMainWindow();
|
||||||
|
|
||||||
if (parent is { IsActive: true } and MainWindow window && window.ViewModel.IsGameRunning)
|
if (parent != null && parent.IsActive && (parent as MainWindow).ViewModel.IsGameRunning)
|
||||||
{
|
{
|
||||||
contentDialogOverlayWindow = new()
|
contentDialogOverlayWindow = new()
|
||||||
{
|
{
|
||||||
|
@@ -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()
|
||||||
|
@@ -257,6 +257,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
OnPropertyChanged(nameof(EnableNonGameRunningControls));
|
OnPropertyChanged(nameof(EnableNonGameRunningControls));
|
||||||
|
OnPropertyChanged(nameof(IsAppletMenuActive));
|
||||||
OnPropertyChanged(nameof(StatusBarVisible));
|
OnPropertyChanged(nameof(StatusBarVisible));
|
||||||
OnPropertyChanged(nameof(ShowFirmwareStatus));
|
OnPropertyChanged(nameof(ShowFirmwareStatus));
|
||||||
}
|
}
|
||||||
|
@@ -9,9 +9,7 @@ using Ryujinx.Ava.UI.ViewModels;
|
|||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.HOS;
|
|
||||||
using Ryujinx.Modules;
|
using Ryujinx.Modules;
|
||||||
using Ryujinx.Ui.App.Common;
|
|
||||||
using Ryujinx.Ui.Common;
|
using Ryujinx.Ui.Common;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.Ui.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.Ui.Common.Helper;
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
</Design.DataContext>
|
</Design.DataContext>
|
||||||
<DockPanel
|
<DockPanel
|
||||||
Margin="0,0,0,5"
|
Margin="0,0,0,5"
|
||||||
|
Height="35"
|
||||||
HorizontalAlignment="Stretch">
|
HorizontalAlignment="Stretch">
|
||||||
<Button
|
<Button
|
||||||
Width="40"
|
Width="40"
|
||||||
|
@@ -58,11 +58,20 @@
|
|||||||
JustifyContent="SpaceAround"
|
JustifyContent="SpaceAround"
|
||||||
RowSpacing="2">
|
RowSpacing="2">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
FontSize="28"
|
FontSize="28"
|
||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
Text="Ryujinx"
|
Text="Ryujinx"
|
||||||
TextAlignment="Left" />
|
TextAlignment="Center"
|
||||||
<TextBlock Text="(REE-YOU-JINX)" TextAlignment="Left" />
|
Width="100" />
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontSize="11"
|
||||||
|
Text="(REE-YOU-JINX)"
|
||||||
|
TextAlignment="Center"
|
||||||
|
Width="100" />
|
||||||
</flex:FlexPanel>
|
</flex:FlexPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
|
@@ -519,14 +519,14 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
private void ConfirmExit()
|
private void ConfirmExit()
|
||||||
{
|
{
|
||||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||||
{
|
{
|
||||||
ViewModel.IsClosing = await ContentDialogHelper.CreateExitDialog();
|
ViewModel.IsClosing = await ContentDialogHelper.CreateExitDialog();
|
||||||
|
|
||||||
if (ViewModel.IsClosing)
|
if (ViewModel.IsClosing)
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void LoadApplications()
|
public async void LoadApplications()
|
||||||
|
@@ -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);
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using System.Text;
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Logging
|
namespace Ryujinx.Common.Logging.Formatters
|
||||||
{
|
{
|
||||||
internal class DefaultLogFormatter : ILogFormatter
|
internal class DefaultLogFormatter : ILogFormatter
|
||||||
{
|
{
|
||||||
@@ -27,6 +28,14 @@ namespace Ryujinx.Common.Logging
|
|||||||
|
|
||||||
if (args.Data is not null)
|
if (args.Data is not null)
|
||||||
{
|
{
|
||||||
|
if (args.Data is StackTrace trace)
|
||||||
|
{
|
||||||
|
sb.Append('\n');
|
||||||
|
sb.Append(trace);
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
sb.Append(' ');
|
sb.Append(' ');
|
||||||
DynamicObjectFormatter.Format(sb, args.Data);
|
DynamicObjectFormatter.Format(sb, args.Data);
|
||||||
}
|
}
|
||||||
@@ -39,4 +48,4 @@ namespace Ryujinx.Common.Logging
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -3,9 +3,9 @@ using System;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Logging
|
namespace Ryujinx.Common.Logging.Formatters
|
||||||
{
|
{
|
||||||
internal class DynamicObjectFormatter
|
internal static class DynamicObjectFormatter
|
||||||
{
|
{
|
||||||
private static readonly ObjectPool<StringBuilder> StringBuilderPool = SharedPools.Default<StringBuilder>();
|
private static readonly ObjectPool<StringBuilder> StringBuilderPool = SharedPools.Default<StringBuilder>();
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ namespace Ryujinx.Common.Logging
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder sb = StringBuilderPool.Allocate();
|
StringBuilder sb = StringBuilderPool.Allocate();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Format(sb, dynamicObject);
|
Format(sb, dynamicObject);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
namespace Ryujinx.Common.Logging
|
namespace Ryujinx.Common.Logging.Formatters
|
||||||
{
|
{
|
||||||
interface ILogFormatter
|
interface ILogFormatter
|
||||||
{
|
{
|
||||||
string Format(LogEventArgs args);
|
string Format(LogEventArgs args);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Ryujinx.Common.Logging.Formatters;
|
||||||
|
using System;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Logging
|
namespace Ryujinx.Common.Logging
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using Ryujinx.Common.Logging.Targets;
|
||||||
using Ryujinx.Common.SystemInterop;
|
using Ryujinx.Common.SystemInterop;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -55,6 +56,16 @@ namespace Ryujinx.Common.Logging
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StackTraceHidden]
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void PrintStack(LogClass logClass, string message, [CallerMemberName] string caller = "")
|
||||||
|
{
|
||||||
|
if (m_EnabledClasses[(int)logClass])
|
||||||
|
{
|
||||||
|
Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, caller, message), new StackTrace(true)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void PrintStub(LogClass logClass, string message = "", [CallerMemberName] string caller = "")
|
public void PrintStub(LogClass logClass, string message = "", [CallerMemberName] string caller = "")
|
||||||
{
|
{
|
||||||
@@ -122,7 +133,7 @@ namespace Ryujinx.Common.Logging
|
|||||||
AsyncLogTargetOverflowAction.Discard));
|
AsyncLogTargetOverflowAction.Discard));
|
||||||
|
|
||||||
Notice = new Log(LogLevel.Notice);
|
Notice = new Log(LogLevel.Notice);
|
||||||
|
|
||||||
// Enable important log levels before configuration is loaded
|
// Enable important log levels before configuration is loaded
|
||||||
Error = new Log(LogLevel.Error);
|
Error = new Log(LogLevel.Error);
|
||||||
Warning = new Log(LogLevel.Warning);
|
Warning = new Log(LogLevel.Warning);
|
||||||
@@ -221,4 +232,4 @@ namespace Ryujinx.Common.Logging
|
|||||||
m_EnabledClasses[(int)logClass] = enabled;
|
m_EnabledClasses[(int)logClass] = enabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Logging
|
namespace Ryujinx.Common.Logging.Targets
|
||||||
{
|
{
|
||||||
public enum AsyncLogTargetOverflowAction
|
public enum AsyncLogTargetOverflowAction
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using Ryujinx.Common.Logging.Formatters;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Logging
|
namespace Ryujinx.Common.Logging.Targets
|
||||||
{
|
{
|
||||||
public class ConsoleLogTarget : ILogTarget
|
public class ConsoleLogTarget : ILogTarget
|
||||||
{
|
{
|
||||||
@@ -38,4 +39,4 @@ namespace Ryujinx.Common.Logging
|
|||||||
Console.ResetColor();
|
Console.ResetColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,8 +1,9 @@
|
|||||||
using System;
|
using Ryujinx.Common.Logging.Formatters;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Logging
|
namespace Ryujinx.Common.Logging.Targets
|
||||||
{
|
{
|
||||||
public class FileLogTarget : ILogTarget
|
public class FileLogTarget : ILogTarget
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Logging
|
namespace Ryujinx.Common.Logging.Targets
|
||||||
{
|
{
|
||||||
public interface ILogTarget : IDisposable
|
public interface ILogTarget : IDisposable
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Logging
|
namespace Ryujinx.Common.Logging.Targets
|
||||||
{
|
{
|
||||||
public class JsonLogTarget : ILogTarget
|
public class JsonLogTarget : ILogTarget
|
||||||
{
|
{
|
||||||
|
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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;
|
||||||
|
@@ -383,6 +383,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
case Format.R10G10B10A2Unorm:
|
case Format.R10G10B10A2Unorm:
|
||||||
case Format.R10G10B10A2Uint:
|
case Format.R10G10B10A2Uint:
|
||||||
case Format.R11G11B10Float:
|
case Format.R11G11B10Float:
|
||||||
|
case Format.B8G8R8A8Unorm:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL
|
namespace Ryujinx.Graphics.GAL
|
||||||
{
|
{
|
||||||
@@ -52,7 +53,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
|
|
||||||
void ResetCounter(CounterType type);
|
void ResetCounter(CounterType type);
|
||||||
|
|
||||||
void RunLoop(Action gpuLoop)
|
void RunLoop(ThreadStart gpuLoop)
|
||||||
{
|
{
|
||||||
gpuLoop();
|
gpuLoop();
|
||||||
}
|
}
|
||||||
|
@@ -30,7 +30,6 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
private IRenderer _baseRenderer;
|
private IRenderer _baseRenderer;
|
||||||
private Thread _gpuThread;
|
private Thread _gpuThread;
|
||||||
private Thread _backendThread;
|
private Thread _backendThread;
|
||||||
private bool _disposed;
|
|
||||||
private bool _running;
|
private bool _running;
|
||||||
|
|
||||||
private AutoResetEvent _frameComplete = new AutoResetEvent(true);
|
private AutoResetEvent _frameComplete = new AutoResetEvent(true);
|
||||||
@@ -98,19 +97,17 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
_refQueue = new object[MaxRefsPerCommand * QueueCount];
|
_refQueue = new object[MaxRefsPerCommand * QueueCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RunLoop(Action gpuLoop)
|
public void RunLoop(ThreadStart gpuLoop)
|
||||||
{
|
{
|
||||||
_running = true;
|
_running = true;
|
||||||
|
|
||||||
_backendThread = Thread.CurrentThread;
|
_backendThread = Thread.CurrentThread;
|
||||||
|
|
||||||
_gpuThread = new Thread(() => {
|
_gpuThread = new Thread(gpuLoop)
|
||||||
gpuLoop();
|
{
|
||||||
_running = false;
|
Name = "GPU.MainThread"
|
||||||
_galWorkAvailable.Set();
|
};
|
||||||
});
|
|
||||||
|
|
||||||
_gpuThread.Name = "GPU.MainThread";
|
|
||||||
_gpuThread.Start();
|
_gpuThread.Start();
|
||||||
|
|
||||||
RenderLoop();
|
RenderLoop();
|
||||||
@@ -120,7 +117,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
{
|
{
|
||||||
// Power through the render queue until the Gpu thread work is done.
|
// Power through the render queue until the Gpu thread work is done.
|
||||||
|
|
||||||
while (_running && !_disposed)
|
while (_running)
|
||||||
{
|
{
|
||||||
_galWorkAvailable.Wait();
|
_galWorkAvailable.Wait();
|
||||||
_galWorkAvailable.Reset();
|
_galWorkAvailable.Reset();
|
||||||
@@ -488,12 +485,23 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
return _baseRenderer.PrepareHostMapping(address, size);
|
return _baseRenderer.PrepareHostMapping(address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void FlushThreadedCommands()
|
||||||
|
{
|
||||||
|
SpinWait wait = new();
|
||||||
|
|
||||||
|
while (Volatile.Read(ref _commandCount) > 0)
|
||||||
|
{
|
||||||
|
wait.SpinOnce();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// Dispose must happen from the render thread, after all commands have completed.
|
// Dispose must happen from the render thread, after all commands have completed.
|
||||||
|
|
||||||
// Stop the GPU thread.
|
// Stop the GPU thread.
|
||||||
_disposed = true;
|
_running = false;
|
||||||
|
_galWorkAvailable.Set();
|
||||||
|
|
||||||
if (_gpuThread != null && _gpuThread.IsAlive)
|
if (_gpuThread != null && _gpuThread.IsAlive)
|
||||||
{
|
{
|
||||||
|
@@ -63,6 +63,8 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
public bool PrimitiveRestartEnable;
|
public bool PrimitiveRestartEnable;
|
||||||
public uint PatchControlPoints;
|
public uint PatchControlPoints;
|
||||||
|
|
||||||
|
public DepthMode DepthMode;
|
||||||
|
|
||||||
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
||||||
{
|
{
|
||||||
VertexAttribCount = vertexAttribs.Length;
|
VertexAttribCount = vertexAttribs.Length;
|
||||||
|
@@ -80,11 +80,6 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const int GobAlignment = 64;
|
public const int GobAlignment = 64;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Expected byte alignment for storage buffers
|
|
||||||
/// </summary>
|
|
||||||
public const int StorageAlignment = 16;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Number of the uniform buffer reserved by the driver to store the storage buffer base addresses.
|
/// Number of the uniform buffer reserved by the driver to store the storage buffer base addresses.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -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);
|
||||||
@@ -187,30 +193,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
info = cs.Shaders[0].Info;
|
info = cs.Shaders[0].Info;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index = 0; index < info.CBuffers.Count; index++)
|
|
||||||
{
|
|
||||||
BufferDescriptor cb = info.CBuffers[index];
|
|
||||||
|
|
||||||
// NVN uses the "hardware" constant buffer for anything that is less than 8,
|
|
||||||
// and those are already bound above.
|
|
||||||
// Anything greater than or equal to 8 uses the emulated constant buffers.
|
|
||||||
// They are emulated using global memory loads.
|
|
||||||
if (cb.Slot < 8)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ulong cbDescAddress = _channel.BufferManager.GetComputeUniformBufferAddress(0);
|
|
||||||
|
|
||||||
int cbDescOffset = 0x260 + (cb.Slot - 8) * 0x10;
|
|
||||||
|
|
||||||
cbDescAddress += (ulong)cbDescOffset;
|
|
||||||
|
|
||||||
SbDescriptor cbDescriptor = _channel.MemoryManager.Physical.Read<SbDescriptor>(cbDescAddress);
|
|
||||||
|
|
||||||
_channel.BufferManager.SetComputeUniformBuffer(cb.Slot, cbDescriptor.PackAddress(), (uint)cbDescriptor.Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
_channel.BufferManager.SetComputeBufferBindings(cs.Bindings);
|
_channel.BufferManager.SetComputeBufferBindings(cs.Bindings);
|
||||||
|
|
||||||
_channel.TextureManager.SetComputeBindings(cs.Bindings);
|
_channel.TextureManager.SetComputeBindings(cs.Bindings);
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
@@ -771,7 +771,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateDepthMode()
|
private void UpdateDepthMode()
|
||||||
{
|
{
|
||||||
_context.Renderer.Pipeline.SetDepthMode(GetDepthMode());
|
DepthMode mode = GetDepthMode();
|
||||||
|
|
||||||
|
_pipeline.DepthMode = mode;
|
||||||
|
|
||||||
|
_context.Renderer.Pipeline.SetDepthMode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1363,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;
|
||||||
|
@@ -390,7 +390,6 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Renderer.Dispose();
|
|
||||||
GPFifo.Dispose();
|
GPFifo.Dispose();
|
||||||
HostInitalized.Dispose();
|
HostInitalized.Dispose();
|
||||||
|
|
||||||
@@ -403,6 +402,8 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
PhysicalMemoryRegistry.Clear();
|
PhysicalMemoryRegistry.Clear();
|
||||||
|
|
||||||
RunDeferredActions();
|
RunDeferredActions();
|
||||||
|
|
||||||
|
Renderer.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -222,7 +236,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
/// <param name="gpuVa">Start GPU virtual address of the buffer</param>
|
/// <param name="gpuVa">Start GPU virtual address of the buffer</param>
|
||||||
private void RecordStorageAlignment(BuffersPerStage buffers, int index, ulong gpuVa)
|
private void RecordStorageAlignment(BuffersPerStage buffers, int index, ulong gpuVa)
|
||||||
{
|
{
|
||||||
bool unaligned = (gpuVa & (Constants.StorageAlignment - 1)) != 0;
|
bool unaligned = (gpuVa & ((ulong)_context.Capabilities.StorageBufferOffsetAlignment - 1)) != 0;
|
||||||
|
|
||||||
if (unaligned || HasUnalignedStorageBuffers)
|
if (unaligned || HasUnalignedStorageBuffers)
|
||||||
{
|
{
|
||||||
@@ -319,6 +333,31 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
_gpUniformBuffersDirty = true;
|
_gpUniformBuffersDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the number of vertices per instance on a instanced draw. Used for transform feedback emulation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertexCount">Vertex count per instance</param>
|
||||||
|
public void SetInstancedDrawVertexCount(int vertexCount)
|
||||||
|
{
|
||||||
|
if (!_context.Capabilities.SupportsTransformFeedback &&
|
||||||
|
HasTransformFeedbackOutputs &&
|
||||||
|
_tfInfoBuffer != BufferHandle.Null)
|
||||||
|
{
|
||||||
|
Span<byte> data = stackalloc byte[sizeof(int)];
|
||||||
|
MemoryMarshal.Cast<byte, int>(data)[0] = vertexCount;
|
||||||
|
_context.Renderer.SetBufferData(_tfInfoBuffer, TfInfoVertexCountOffset, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Forces transform feedback and storage buffers to be updated on the next draw.
|
||||||
|
/// </summary>
|
||||||
|
public void ForceTransformFeedbackAndStorageBuffersDirty()
|
||||||
|
{
|
||||||
|
_transformFeedbackBuffersDirty = true;
|
||||||
|
_gpStorageBuffersDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the binding points for the storage buffers bound on the compute pipeline.
|
/// Sets the binding points for the storage buffers bound on the compute pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -537,22 +576,75 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
{
|
{
|
||||||
_transformFeedbackBuffersDirty = false;
|
_transformFeedbackBuffersDirty = false;
|
||||||
|
|
||||||
Span<BufferRange> tfbs = stackalloc BufferRange[Constants.TotalTransformFeedbackBuffers];
|
if (_context.Capabilities.SupportsTransformFeedback)
|
||||||
|
|
||||||
for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
|
|
||||||
{
|
{
|
||||||
BufferBounds tfb = _transformFeedbackBuffers[index];
|
Span<BufferRange> tfbs = stackalloc BufferRange[Constants.TotalTransformFeedbackBuffers];
|
||||||
|
|
||||||
if (tfb.Address == 0)
|
for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
|
||||||
{
|
{
|
||||||
tfbs[index] = BufferRange.Empty;
|
BufferBounds tfb = _transformFeedbackBuffers[index];
|
||||||
continue;
|
|
||||||
|
if (tfb.Address == 0)
|
||||||
|
{
|
||||||
|
tfbs[index] = BufferRange.Empty;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tfbs[index] = bufferCache.GetBufferRange(tfb.Address, tfb.Size, write: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
tfbs[index] = bufferCache.GetBufferRange(tfb.Address, tfb.Size, write: true);
|
_context.Renderer.Pipeline.SetTransformFeedbackBuffers(tfbs);
|
||||||
}
|
}
|
||||||
|
else if (HasTransformFeedbackOutputs)
|
||||||
|
{
|
||||||
|
Span<int> info = _tfInfoData.AsSpan();
|
||||||
|
Span<BufferAssignment> buffers = stackalloc BufferAssignment[Constants.TotalTransformFeedbackBuffers + 1];
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetTransformFeedbackBuffers(tfbs);
|
bool needsDataUpdate = false;
|
||||||
|
|
||||||
|
if (_tfInfoBuffer == BufferHandle.Null)
|
||||||
|
{
|
||||||
|
_tfInfoBuffer = _context.Renderer.CreateBuffer(TfInfoBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers[0] = new BufferAssignment(0, new BufferRange(_tfInfoBuffer, 0, TfInfoBufferSize));
|
||||||
|
|
||||||
|
int alignment = _context.Capabilities.StorageBufferOffsetAlignment;
|
||||||
|
|
||||||
|
for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
|
||||||
|
{
|
||||||
|
BufferBounds tfb = _transformFeedbackBuffers[index];
|
||||||
|
|
||||||
|
if (tfb.Address == 0)
|
||||||
|
{
|
||||||
|
buffers[1 + index] = new BufferAssignment(1 + index, BufferRange.Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulong endAddress = tfb.Address + tfb.Size;
|
||||||
|
ulong address = BitUtils.AlignDown(tfb.Address, (ulong)alignment);
|
||||||
|
ulong size = endAddress - address;
|
||||||
|
|
||||||
|
int tfeOffset = ((int)tfb.Address & (alignment - 1)) / 4;
|
||||||
|
|
||||||
|
if (info[index] != tfeOffset)
|
||||||
|
{
|
||||||
|
info[index] = tfeOffset;
|
||||||
|
needsDataUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers[1 + index] = new BufferAssignment(1 + index, bufferCache.GetBufferRange(address, size, write: true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsDataUpdate)
|
||||||
|
{
|
||||||
|
Span<byte> infoData = MemoryMarshal.Cast<int, byte>(info);
|
||||||
|
_context.Renderer.SetBufferData(_tfInfoBuffer, 0, infoData);
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.Renderer.Pipeline.SetStorageBuffers(buffers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
ShaderSpecializationState oldSpecState,
|
ShaderSpecializationState oldSpecState,
|
||||||
ShaderSpecializationState newSpecState,
|
ShaderSpecializationState newSpecState,
|
||||||
ResourceCounts counts,
|
ResourceCounts counts,
|
||||||
int stageIndex) : base(context, counts, stageIndex)
|
int stageIndex) : base(context, counts, stageIndex, oldSpecState.TransformFeedbackDescriptors != null)
|
||||||
{
|
{
|
||||||
_data = data;
|
_data = data;
|
||||||
_cb1Data = cb1Data;
|
_cb1Data = cb1Data;
|
||||||
|
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
private const ushort FileFormatVersionMajor = 1;
|
private const ushort FileFormatVersionMajor = 1;
|
||||||
private const ushort FileFormatVersionMinor = 2;
|
private const ushort FileFormatVersionMinor = 2;
|
||||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||||
private const uint CodeGenVersion = 5027;
|
private const uint CodeGenVersion = 5080;
|
||||||
|
|
||||||
private const string SharedTocFileName = "shared.toc";
|
private const string SharedTocFileName = "shared.toc";
|
||||||
private const string SharedDataFileName = "shared.data";
|
private const string SharedDataFileName = "shared.data";
|
||||||
@@ -368,7 +368,11 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
|
|
||||||
if (hostCode != null)
|
if (hostCode != null)
|
||||||
{
|
{
|
||||||
ShaderInfo shaderInfo = ShaderInfoBuilder.BuildForCache(context, shaders, specState.PipelineState);
|
ShaderInfo shaderInfo = ShaderInfoBuilder.BuildForCache(
|
||||||
|
context,
|
||||||
|
shaders,
|
||||||
|
specState.PipelineState,
|
||||||
|
specState.TransformFeedbackDescriptors != null);
|
||||||
|
|
||||||
IProgram hostProgram;
|
IProgram hostProgram;
|
||||||
|
|
||||||
|
@@ -491,7 +491,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
{
|
{
|
||||||
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
|
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
|
||||||
|
|
||||||
ShaderInfoBuilder shaderInfoBuilder = new ShaderInfoBuilder(_context);
|
ShaderInfoBuilder shaderInfoBuilder = new ShaderInfoBuilder(_context, compilation.SpecializationState.TransformFeedbackDescriptors != null);
|
||||||
|
|
||||||
for (int index = 0; index < compilation.TranslatedStages.Length; index++)
|
for (int index = 0; index < compilation.TranslatedStages.Length; index++)
|
||||||
{
|
{
|
||||||
|
@@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
GpuContext context,
|
GpuContext context,
|
||||||
GpuChannel channel,
|
GpuChannel channel,
|
||||||
GpuAccessorState state,
|
GpuAccessorState state,
|
||||||
int stageIndex) : base(context, state.ResourceCounts, stageIndex)
|
int stageIndex) : base(context, state.ResourceCounts, stageIndex, state.TransformFeedbackDescriptors != null)
|
||||||
{
|
{
|
||||||
_isVulkan = context.Capabilities.Api == TargetApi.Vulkan;
|
_isVulkan = context.Capabilities.Api == TargetApi.Vulkan;
|
||||||
_channel = channel;
|
_channel = channel;
|
||||||
@@ -44,7 +44,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// <param name="context">GPU context</param>
|
/// <param name="context">GPU context</param>
|
||||||
/// <param name="channel">GPU channel</param>
|
/// <param name="channel">GPU channel</param>
|
||||||
/// <param name="state">Current GPU state</param>
|
/// <param name="state">Current GPU state</param>
|
||||||
public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state) : base(context, state.ResourceCounts, 0)
|
public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state) : base(context, state.ResourceCounts, 0, false)
|
||||||
{
|
{
|
||||||
_channel = channel;
|
_channel = channel;
|
||||||
_state = state;
|
_state = state;
|
||||||
|
@@ -17,56 +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[] _constantBufferBindings;
|
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;
|
||||||
|
|
||||||
if (context.Capabilities.Api != TargetApi.Vulkan)
|
_reservedConstantBuffers = 1; // For the support buffer.
|
||||||
{
|
_reservedStorageBuffers = !context.Capabilities.SupportsTransformFeedback && tfEnabled ? 5 : 0;
|
||||||
_constantBufferBindings = new int[Constants.TotalGpUniformBuffers];
|
|
||||||
_constantBufferBindings.AsSpan().Fill(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
int binding = _constantBufferBindings[index];
|
binding = _resourceCounts.UniformBuffersCount++;
|
||||||
|
|
||||||
if (binding < 0)
|
|
||||||
{
|
|
||||||
binding = _resourceCounts.UniformBuffersCount++;
|
|
||||||
_constantBufferBindings[index] = binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
return binding;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
@@ -157,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,13 +111,13 @@ 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;
|
||||||
|
|
||||||
AddDescriptor(stages, ResourceType.UniformBuffer, UniformSetIndex, uniformBinding, uniformsPerStage);
|
AddDescriptor(stages, ResourceType.UniformBuffer, UniformSetIndex, uniformBinding, uniformsPerStage);
|
||||||
AddArrayDescriptor(stages, ResourceType.StorageBuffer, StorageSetIndex, storageBinding, storagesPerStage);
|
AddDescriptor(stages, ResourceType.StorageBuffer, StorageSetIndex, storageBinding, storagesPerStage);
|
||||||
AddDualDescriptor(stages, ResourceType.TextureAndSampler, ResourceType.BufferTexture, TextureSetIndex, textureBinding, texturesPerStage);
|
AddDualDescriptor(stages, ResourceType.TextureAndSampler, ResourceType.BufferTexture, TextureSetIndex, textureBinding, texturesPerStage);
|
||||||
AddDualDescriptor(stages, ResourceType.Image, ResourceType.BufferImage, ImageSetIndex, imageBinding, imagesPerStage);
|
AddDualDescriptor(stages, ResourceType.Image, ResourceType.BufferImage, ImageSetIndex, imageBinding, imagesPerStage);
|
||||||
|
|
||||||
@@ -134,16 +159,20 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds an array resource to the list of descriptors.
|
/// Adds buffer usage information to the list of usages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stages">Shader stages where the resource is used</param>
|
/// <param name="stages">Shader stages where the resource is used</param>
|
||||||
/// <param name="type">Type of the resource</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="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="binding">Binding number where the resource will be bound</param>
|
||||||
/// <param name="count">Number of resources bound at the binding location</param>
|
/// <param name="count">Number of resources bound at the binding location</param>
|
||||||
private void AddArrayDescriptor(ResourceStages stages, ResourceType type, int setIndex, int binding, int count)
|
private void AddUsage(ResourceStages stages, ResourceType type, ResourceAccess access, int setIndex, int binding, int count)
|
||||||
{
|
{
|
||||||
_resourceDescriptors[setIndex].Add(new ResourceDescriptor(binding, count, type, stages));
|
for (int index = 0; index < count; index++)
|
||||||
|
{
|
||||||
|
_resourceUsages[setIndex].Add(new ResourceUsage(binding + index, type, stages, access));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -225,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)
|
||||||
{
|
{
|
||||||
@@ -250,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);
|
||||||
|
|
||||||
|
@@ -736,6 +736,19 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
return MatchesTexture(specializationState, descriptor);
|
return MatchesTexture(specializationState, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Populates pipeline state that doesn't exist in older caches with default values
|
||||||
|
/// based on specialization state.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pipelineState">Pipeline state to prepare</param>
|
||||||
|
private void PreparePipelineState(ref ProgramPipelineState pipelineState)
|
||||||
|
{
|
||||||
|
if (!_compute)
|
||||||
|
{
|
||||||
|
pipelineState.DepthMode = GraphicsState.DepthMode ? DepthMode.MinusOneToOne : DepthMode.ZeroToOne;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads shader specialization state that has been serialized.
|
/// Reads shader specialization state that has been serialized.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -776,6 +789,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
{
|
{
|
||||||
ProgramPipelineState pipelineState = default;
|
ProgramPipelineState pipelineState = default;
|
||||||
dataReader.ReadWithMagicAndSize(ref pipelineState, PgpsMagic);
|
dataReader.ReadWithMagicAndSize(ref pipelineState, PgpsMagic);
|
||||||
|
|
||||||
|
specState.PreparePipelineState(ref pipelineState);
|
||||||
specState.PipelineState = pipelineState;
|
specState.PipelineState = pipelineState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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,
|
||||||
|
@@ -104,14 +104,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
}
|
}
|
||||||
|
|
||||||
DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
|
DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
|
||||||
|
DeclareStorageBuffers(context, context.Config.Properties.StorageBuffers.Values);
|
||||||
var sBufferDescriptors = context.Config.GetStorageBufferDescriptors();
|
|
||||||
if (sBufferDescriptors.Length != 0)
|
|
||||||
{
|
|
||||||
DeclareStorages(context, sBufferDescriptors);
|
|
||||||
|
|
||||||
context.AppendLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
var textureDescriptors = context.Config.GetTextureDescriptors();
|
var textureDescriptors = context.Config.GetTextureDescriptors();
|
||||||
if (textureDescriptors.Length != 0)
|
if (textureDescriptors.Length != 0)
|
||||||
@@ -250,11 +243,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl");
|
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((info.HelperFunctionsMask & HelperFunctionsMask.AtomicMinMaxS32Storage) != 0)
|
|
||||||
{
|
|
||||||
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.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");
|
||||||
@@ -290,11 +278,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreSharedSmallInt.glsl");
|
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreSharedSmallInt.glsl");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((info.HelperFunctionsMask & HelperFunctionsMask.StoreStorageSmallInt) != 0)
|
|
||||||
{
|
|
||||||
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreStorageSmallInt.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");
|
||||||
@@ -356,6 +339,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void DeclareConstantBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
|
private static void DeclareConstantBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
|
||||||
|
{
|
||||||
|
DeclareBuffers(context, buffers, "uniform");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DeclareStorageBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
|
||||||
|
{
|
||||||
|
DeclareBuffers(context, buffers, "buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DeclareBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers, string declType)
|
||||||
{
|
{
|
||||||
foreach (BufferDefinition buffer in buffers)
|
foreach (BufferDefinition buffer in buffers)
|
||||||
{
|
{
|
||||||
@@ -365,7 +358,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
_ => "std430"
|
_ => "std430"
|
||||||
};
|
};
|
||||||
|
|
||||||
context.AppendLine($"layout (binding = {buffer.Binding}, {layout}) uniform _{buffer.Name}");
|
context.AppendLine($"layout (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)
|
||||||
@@ -373,9 +366,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
if (field.Type.HasFlag(AggregateType.Array))
|
if (field.Type.HasFlag(AggregateType.Array))
|
||||||
{
|
{
|
||||||
string typeName = GetVarTypeName(context, field.Type & ~AggregateType.Array);
|
string typeName = GetVarTypeName(context, field.Type & ~AggregateType.Array);
|
||||||
string arraySize = field.ArrayLength.ToString(CultureInfo.InvariantCulture);
|
|
||||||
|
|
||||||
context.AppendLine($"{typeName} {field.Name}[{arraySize}];");
|
if (field.ArrayLength > 0)
|
||||||
|
{
|
||||||
|
string arraySize = field.ArrayLength.ToString(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
context.AppendLine($"{typeName} {field.Name}[{arraySize}];");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.AppendLine($"{typeName} {field.Name}[];");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -390,22 +391,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DeclareStorages(CodeGenContext context, BufferDescriptor[] descriptors)
|
|
||||||
{
|
|
||||||
string sbName = OperandManager.GetShaderStagePrefix(context.Config.Stage);
|
|
||||||
|
|
||||||
sbName += "_" + DefaultNames.StorageNamePrefix;
|
|
||||||
|
|
||||||
string blockName = $"{sbName}_{DefaultNames.BlockSuffix}";
|
|
||||||
|
|
||||||
string layout = context.Config.Options.TargetApi == TargetApi.Vulkan ? ", set = 1" : string.Empty;
|
|
||||||
|
|
||||||
context.AppendLine($"layout (binding = {context.Config.FirstStorageBufferBinding}{layout}, std430) buffer {blockName}");
|
|
||||||
context.EnterScope();
|
|
||||||
context.AppendLine("uint " + DefaultNames.DataName + "[];");
|
|
||||||
context.LeaveScope($" {sbName}[{NumberFormatter.FormatInt(descriptors.Max(x => x.Slot) + 1)}];");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DeclareSamplers(CodeGenContext context, TextureDescriptor[] descriptors)
|
private static void DeclareSamplers(CodeGenContext context, TextureDescriptor[] descriptors)
|
||||||
{
|
{
|
||||||
int arraySize = 0;
|
int arraySize = 0;
|
||||||
@@ -733,7 +718,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
code = code.Replace("\t", CodeGenContext.Tab);
|
code = code.Replace("\t", CodeGenContext.Tab);
|
||||||
code = code.Replace("$SHARED_MEM$", DefaultNames.SharedMemoryName);
|
code = code.Replace("$SHARED_MEM$", DefaultNames.SharedMemoryName);
|
||||||
code = code.Replace("$STORAGE_MEM$", OperandManager.GetShaderStagePrefix(context.Config.Stage) + "_" + DefaultNames.StorageNamePrefix);
|
|
||||||
|
|
||||||
if (context.Config.GpuAccessor.QueryHostSupportsShaderBallot())
|
if (context.Config.GpuAccessor.QueryHostSupportsShaderBallot())
|
||||||
{
|
{
|
||||||
|
@@ -11,12 +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 StorageNamePrefix = "s";
|
|
||||||
|
|
||||||
public const string DataName = "data";
|
|
||||||
|
|
||||||
public const string BlockSuffix = "block";
|
|
||||||
|
|
||||||
public const string LocalMemoryName = "local_mem";
|
public const string LocalMemoryName = "local_mem";
|
||||||
public const string SharedMemoryName = "shared_mem";
|
public const string SharedMemoryName = "shared_mem";
|
||||||
|
|
||||||
|
@@ -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 index, int offset, int value)
|
|
||||||
{
|
|
||||||
uint oldValue, newValue;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
oldValue = $STORAGE_MEM$[index].data[offset];
|
|
||||||
newValue = uint(max(int(oldValue), value));
|
|
||||||
} while (atomicCompSwap($STORAGE_MEM$[index].data[offset], oldValue, newValue) != oldValue);
|
|
||||||
return int(oldValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Helper_AtomicMinS32(int index, int offset, int value)
|
|
||||||
{
|
|
||||||
uint oldValue, newValue;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
oldValue = $STORAGE_MEM$[index].data[offset];
|
|
||||||
newValue = uint(min(int(oldValue), value));
|
|
||||||
} while (atomicCompSwap($STORAGE_MEM$[index].data[offset], oldValue, newValue) != oldValue);
|
|
||||||
return int(oldValue);
|
|
||||||
}
|
|
@@ -1,23 +0,0 @@
|
|||||||
void Helper_StoreStorage16(int index, int offset, uint value)
|
|
||||||
{
|
|
||||||
int wordOffset = offset >> 2;
|
|
||||||
int bitOffset = (offset & 3) * 8;
|
|
||||||
uint oldValue, newValue;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
oldValue = $STORAGE_MEM$[index].data[wordOffset];
|
|
||||||
newValue = bitfieldInsert(oldValue, value, bitOffset, 16);
|
|
||||||
} while (atomicCompSwap($STORAGE_MEM$[index].data[wordOffset], oldValue, newValue) != oldValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Helper_StoreStorage8(int index, int offset, uint value)
|
|
||||||
{
|
|
||||||
int wordOffset = offset >> 2;
|
|
||||||
int bitOffset = (offset & 3) * 8;
|
|
||||||
uint oldValue, newValue;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
oldValue = $STORAGE_MEM$[index].data[wordOffset];
|
|
||||||
newValue = bitfieldInsert(oldValue, value, bitOffset, 8);
|
|
||||||
} while (atomicCompSwap($STORAGE_MEM$[index].data[wordOffset], oldValue, newValue) != oldValue);
|
|
||||||
}
|
|
@@ -68,33 +68,45 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
|
|
||||||
string args = string.Empty;
|
string args = string.Empty;
|
||||||
|
|
||||||
for (int argIndex = 0; argIndex < arity; argIndex++)
|
if (atomic && operation.StorageKind == StorageKind.StorageBuffer)
|
||||||
{
|
{
|
||||||
|
args = GenerateLoadOrStore(context, operation, isStore: false);
|
||||||
|
|
||||||
|
AggregateType dstType = operation.Inst == Instruction.AtomicMaxS32 || operation.Inst == Instruction.AtomicMinS32
|
||||||
|
? AggregateType.S32
|
||||||
|
: AggregateType.U32;
|
||||||
|
|
||||||
|
for (int argIndex = operation.SourcesCount - arity + 2; argIndex < operation.SourcesCount; argIndex++)
|
||||||
|
{
|
||||||
|
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.
|
// 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.
|
// 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 storage, both inputs are consumed when the argument index is 0, so we should skip it here.
|
||||||
if (argIndex == 1 && (atomic || operation.StorageKind == StorageKind.SharedMemory))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argIndex != 0)
|
for (int argIndex = 2; argIndex < arity; argIndex++)
|
||||||
{
|
{
|
||||||
args += ", ";
|
args += ", ";
|
||||||
}
|
|
||||||
|
|
||||||
if (argIndex == 0 && atomic)
|
AggregateType dstType = GetSrcVarType(inst, argIndex);
|
||||||
|
|
||||||
|
args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int argIndex = 0; argIndex < arity; argIndex++)
|
||||||
{
|
{
|
||||||
switch (operation.StorageKind)
|
if (argIndex != 0)
|
||||||
{
|
{
|
||||||
case StorageKind.SharedMemory: args += LoadShared(context, operation); break;
|
args += ", ";
|
||||||
case StorageKind.StorageBuffer: args += LoadStorage(context, operation); break;
|
|
||||||
|
|
||||||
default: throw new InvalidOperationException($"Invalid storage kind \"{operation.StorageKind}\".");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AggregateType dstType = GetSrcVarType(inst, argIndex);
|
AggregateType dstType = GetSrcVarType(inst, argIndex);
|
||||||
|
|
||||||
args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
|
args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
|
||||||
@@ -173,9 +185,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
case Instruction.LoadShared:
|
case Instruction.LoadShared:
|
||||||
return LoadShared(context, operation);
|
return LoadShared(context, operation);
|
||||||
|
|
||||||
case Instruction.LoadStorage:
|
|
||||||
return LoadStorage(context, operation);
|
|
||||||
|
|
||||||
case Instruction.Lod:
|
case Instruction.Lod:
|
||||||
return Lod(context, operation);
|
return Lod(context, operation);
|
||||||
|
|
||||||
@@ -203,15 +212,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
case Instruction.StoreShared8:
|
case Instruction.StoreShared8:
|
||||||
return StoreShared8(context, operation);
|
return StoreShared8(context, operation);
|
||||||
|
|
||||||
case Instruction.StoreStorage:
|
|
||||||
return StoreStorage(context, operation);
|
|
||||||
|
|
||||||
case Instruction.StoreStorage16:
|
|
||||||
return StoreStorage16(context, operation);
|
|
||||||
|
|
||||||
case Instruction.StoreStorage8:
|
|
||||||
return StoreStorage8(context, operation);
|
|
||||||
|
|
||||||
case Instruction.TextureSample:
|
case Instruction.TextureSample:
|
||||||
return TextureSample(context, operation);
|
return TextureSample(context, operation);
|
||||||
|
|
||||||
|
@@ -85,7 +85,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
Add(Instruction.Load, InstType.Special);
|
Add(Instruction.Load, InstType.Special);
|
||||||
Add(Instruction.LoadLocal, InstType.Special);
|
Add(Instruction.LoadLocal, InstType.Special);
|
||||||
Add(Instruction.LoadShared, InstType.Special);
|
Add(Instruction.LoadShared, InstType.Special);
|
||||||
Add(Instruction.LoadStorage, 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);
|
||||||
@@ -123,9 +122,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
Add(Instruction.StoreShared, InstType.Special);
|
Add(Instruction.StoreShared, InstType.Special);
|
||||||
Add(Instruction.StoreShared16, InstType.Special);
|
Add(Instruction.StoreShared16, InstType.Special);
|
||||||
Add(Instruction.StoreShared8, InstType.Special);
|
Add(Instruction.StoreShared8, InstType.Special);
|
||||||
Add(Instruction.StoreStorage, InstType.Special);
|
|
||||||
Add(Instruction.StoreStorage16, InstType.Special);
|
|
||||||
Add(Instruction.StoreStorage8, 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);
|
||||||
|
@@ -210,17 +210,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
return $"{arrayName}[{offsetExpr}]";
|
return $"{arrayName}[{offsetExpr}]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string LoadStorage(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
IAstNode src1 = operation.GetSource(0);
|
|
||||||
IAstNode src2 = operation.GetSource(1);
|
|
||||||
|
|
||||||
string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
|
||||||
string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
|
|
||||||
|
|
||||||
return GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string Lod(CodeGenContext context, AstOperation operation)
|
public static string Lod(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||||
@@ -326,60 +315,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
return $"{HelperFunctionNames.StoreShared8}({offsetExpr}, {src})";
|
return $"{HelperFunctionNames.StoreShared8}({offsetExpr}, {src})";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string StoreStorage(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
IAstNode src1 = operation.GetSource(0);
|
|
||||||
IAstNode src2 = operation.GetSource(1);
|
|
||||||
IAstNode src3 = operation.GetSource(2);
|
|
||||||
|
|
||||||
string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
|
||||||
string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
|
|
||||||
|
|
||||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src3);
|
|
||||||
|
|
||||||
string src = TypeConversion.ReinterpretCast(context, src3, srcType, AggregateType.U32);
|
|
||||||
|
|
||||||
string sb = GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
|
|
||||||
|
|
||||||
return $"{sb} = {src}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string StoreStorage16(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
IAstNode src1 = operation.GetSource(0);
|
|
||||||
IAstNode src2 = operation.GetSource(1);
|
|
||||||
IAstNode src3 = operation.GetSource(2);
|
|
||||||
|
|
||||||
string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
|
||||||
string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
|
|
||||||
|
|
||||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src3);
|
|
||||||
|
|
||||||
string src = TypeConversion.ReinterpretCast(context, src3, srcType, AggregateType.U32);
|
|
||||||
|
|
||||||
string sb = GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
|
|
||||||
|
|
||||||
return $"{HelperFunctionNames.StoreStorage16}({indexExpr}, {offsetExpr}, {src})";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string StoreStorage8(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
IAstNode src1 = operation.GetSource(0);
|
|
||||||
IAstNode src2 = operation.GetSource(1);
|
|
||||||
IAstNode src3 = operation.GetSource(2);
|
|
||||||
|
|
||||||
string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
|
||||||
string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
|
|
||||||
|
|
||||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src3);
|
|
||||||
|
|
||||||
string src = TypeConversion.ReinterpretCast(context, src3, srcType, AggregateType.U32);
|
|
||||||
|
|
||||||
string sb = GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
|
|
||||||
|
|
||||||
return $"{HelperFunctionNames.StoreStorage8}({indexExpr}, {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;
|
||||||
@@ -701,25 +636,34 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GenerateLoadOrStore(CodeGenContext context, AstOperation operation, bool isStore)
|
public static string GenerateLoadOrStore(CodeGenContext context, AstOperation operation, bool isStore)
|
||||||
{
|
{
|
||||||
StorageKind storageKind = operation.StorageKind;
|
StorageKind storageKind = operation.StorageKind;
|
||||||
|
|
||||||
string varName;
|
string varName;
|
||||||
AggregateType varType;
|
AggregateType varType;
|
||||||
int srcIndex = 0;
|
int srcIndex = 0;
|
||||||
int inputsCount = isStore ? operation.SourcesCount - 1 : operation.SourcesCount;
|
bool isStoreOrAtomic = operation.Inst == Instruction.Store || operation.Inst.IsAtomic();
|
||||||
|
int inputsCount = isStoreOrAtomic ? operation.SourcesCount - 1 : operation.SourcesCount;
|
||||||
|
|
||||||
|
if (operation.Inst == Instruction.AtomicCompareAndSwap)
|
||||||
|
{
|
||||||
|
inputsCount--;
|
||||||
|
}
|
||||||
|
|
||||||
switch (storageKind)
|
switch (storageKind)
|
||||||
{
|
{
|
||||||
case StorageKind.ConstantBuffer:
|
case StorageKind.ConstantBuffer:
|
||||||
|
case StorageKind.StorageBuffer:
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
if (!(operation.GetSource(srcIndex++) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int binding = bindingIndex.Value;
|
int binding = bindingIndex.Value;
|
||||||
BufferDefinition buffer = context.Config.Properties.ConstantBuffers[binding];
|
BufferDefinition buffer = storageKind == StorageKind.ConstantBuffer
|
||||||
|
? context.Config.Properties.ConstantBuffers[binding]
|
||||||
|
: context.Config.Properties.StorageBuffers[binding];
|
||||||
|
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
|
if (!(operation.GetSource(srcIndex++) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
@@ -825,15 +769,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
return varName;
|
return varName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetStorageBufferAccessor(string slotExpr, string offsetExpr, ShaderStage stage)
|
|
||||||
{
|
|
||||||
string sbName = OperandManager.GetShaderStagePrefix(stage);
|
|
||||||
|
|
||||||
sbName += "_" + DefaultNames.StorageNamePrefix;
|
|
||||||
|
|
||||||
return $"{sbName}[{slotExpr}].{DefaultNames.DataName}[{offsetExpr}]";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetMask(int index)
|
private static string GetMask(int index)
|
||||||
{
|
{
|
||||||
return $".{"rgba".AsSpan(index, 1)}";
|
return $".{"rgba".AsSpan(index, 1)}";
|
||||||
|
@@ -118,6 +118,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
switch (operation.StorageKind)
|
switch (operation.StorageKind)
|
||||||
{
|
{
|
||||||
case StorageKind.ConstantBuffer:
|
case StorageKind.ConstantBuffer:
|
||||||
|
case StorageKind.StorageBuffer:
|
||||||
if (!(operation.GetSource(0) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
if (!(operation.GetSource(0) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||||
@@ -128,7 +129,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferDefinition buffer = context.Config.Properties.ConstantBuffers[bindingIndex.Value];
|
BufferDefinition buffer = operation.StorageKind == StorageKind.ConstantBuffer
|
||||||
|
? context.Config.Properties.ConstantBuffers[bindingIndex.Value]
|
||||||
|
: context.Config.Properties.StorageBuffers[bindingIndex.Value];
|
||||||
StructureField field = buffer.Type.Fields[fieldIndex.Value];
|
StructureField field = buffer.Type.Fields[fieldIndex.Value];
|
||||||
|
|
||||||
return field.Type & AggregateType.ElementTypeMask;
|
return field.Type & AggregateType.ElementTypeMask;
|
||||||
|
@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
public int InputVertices { get; }
|
public int InputVertices { get; }
|
||||||
|
|
||||||
public Dictionary<int, Instruction> ConstantBuffers { get; } = new Dictionary<int, Instruction>();
|
public Dictionary<int, Instruction> ConstantBuffers { get; } = new Dictionary<int, Instruction>();
|
||||||
public Instruction StorageBuffersArray { get; set; }
|
public Dictionary<int, Instruction> StorageBuffers { get; } = new Dictionary<int, Instruction>();
|
||||||
public Instruction LocalMemory { get; set; }
|
public Instruction LocalMemory { get; set; }
|
||||||
public Instruction SharedMemory { get; set; }
|
public Instruction SharedMemory { get; set; }
|
||||||
public Dictionary<TextureMeta, SamplerType> SamplersTypes { get; } = new Dictionary<TextureMeta, SamplerType>();
|
public Dictionary<TextureMeta, SamplerType> SamplersTypes { get; } = new Dictionary<TextureMeta, SamplerType>();
|
||||||
@@ -76,6 +76,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 +111,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();
|
||||||
@@ -308,7 +313,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
if ((type & AggregateType.Array) != 0)
|
if ((type & AggregateType.Array) != 0)
|
||||||
{
|
{
|
||||||
return TypeArray(GetType(type & ~AggregateType.Array), Constant(TypeU32(), length));
|
if (length > 0)
|
||||||
|
{
|
||||||
|
return TypeArray(GetType(type & ~AggregateType.Array), Constant(TypeU32(), length));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return TypeRuntimeArray(GetType(type & ~AggregateType.Array));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ((type & AggregateType.ElementCountMask) != 0)
|
else if ((type & AggregateType.ElementCountMask) != 0)
|
||||||
{
|
{
|
||||||
|
@@ -5,6 +5,7 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||||||
using Spv.Generator;
|
using Spv.Generator;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using static Spv.Specification;
|
using static Spv.Specification;
|
||||||
@@ -99,7 +100,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
|
|
||||||
DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
|
DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
|
||||||
DeclareStorageBuffers(context, context.Config.GetStorageBufferDescriptors());
|
DeclareStorageBuffers(context, context.Config.Properties.StorageBuffers.Values);
|
||||||
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);
|
||||||
@@ -127,6 +128,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void DeclareConstantBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
|
private static void DeclareConstantBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
|
||||||
|
{
|
||||||
|
DeclareBuffers(context, buffers, isBuffer: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DeclareStorageBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
|
||||||
|
{
|
||||||
|
DeclareBuffers(context, buffers, isBuffer: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DeclareBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers, bool isBuffer)
|
||||||
{
|
{
|
||||||
HashSet<SpvInstruction> decoratedTypes = new HashSet<SpvInstruction>();
|
HashSet<SpvInstruction> decoratedTypes = new HashSet<SpvInstruction>();
|
||||||
|
|
||||||
@@ -155,6 +166,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
context.Decorate(structFieldTypes[fieldIndex], Decoration.ArrayStride, (LiteralInteger)fieldSize);
|
context.Decorate(structFieldTypes[fieldIndex], Decoration.ArrayStride, (LiteralInteger)fieldSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Zero lengths are assumed to be a "runtime array" (which does not have a explicit length
|
||||||
|
// specified on the shader, and instead assumes the bound buffer length).
|
||||||
|
// It is only valid as the last struct element.
|
||||||
|
|
||||||
|
Debug.Assert(field.ArrayLength > 0 || fieldIndex == buffer.Type.Fields.Length - 1);
|
||||||
|
|
||||||
offset += fieldSize * field.ArrayLength;
|
offset += fieldSize * field.ArrayLength;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -163,56 +180,37 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ubStructType = context.TypeStruct(false, structFieldTypes);
|
var structType = context.TypeStruct(false, structFieldTypes);
|
||||||
|
|
||||||
if (decoratedTypes.Add(ubStructType))
|
if (decoratedTypes.Add(structType))
|
||||||
{
|
{
|
||||||
context.Decorate(ubStructType, Decoration.Block);
|
context.Decorate(structType, isBuffer ? Decoration.BufferBlock : Decoration.Block);
|
||||||
|
|
||||||
for (int fieldIndex = 0; fieldIndex < structFieldOffsets.Length; fieldIndex++)
|
for (int fieldIndex = 0; fieldIndex < structFieldOffsets.Length; fieldIndex++)
|
||||||
{
|
{
|
||||||
context.MemberDecorate(ubStructType, fieldIndex, Decoration.Offset, (LiteralInteger)structFieldOffsets[fieldIndex]);
|
context.MemberDecorate(structType, fieldIndex, Decoration.Offset, (LiteralInteger)structFieldOffsets[fieldIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ubPointerType = context.TypePointer(StorageClass.Uniform, ubStructType);
|
var pointerType = context.TypePointer(StorageClass.Uniform, structType);
|
||||||
var ubVariable = context.Variable(ubPointerType, StorageClass.Uniform);
|
var variable = context.Variable(pointerType, StorageClass.Uniform);
|
||||||
|
|
||||||
context.Name(ubVariable, buffer.Name);
|
context.Name(variable, buffer.Name);
|
||||||
context.Decorate(ubVariable, Decoration.DescriptorSet, (LiteralInteger)buffer.Set);
|
context.Decorate(variable, Decoration.DescriptorSet, (LiteralInteger)buffer.Set);
|
||||||
context.Decorate(ubVariable, Decoration.Binding, (LiteralInteger)buffer.Binding);
|
context.Decorate(variable, Decoration.Binding, (LiteralInteger)buffer.Binding);
|
||||||
context.AddGlobalVariable(ubVariable);
|
context.AddGlobalVariable(variable);
|
||||||
context.ConstantBuffers.Add(buffer.Binding, ubVariable);
|
|
||||||
|
if (isBuffer)
|
||||||
|
{
|
||||||
|
context.StorageBuffers.Add(buffer.Binding, variable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.ConstantBuffers.Add(buffer.Binding, variable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DeclareStorageBuffers(CodeGenContext context, BufferDescriptor[] descriptors)
|
|
||||||
{
|
|
||||||
if (descriptors.Length == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? 1 : 0;
|
|
||||||
int count = descriptors.Max(x => x.Slot) + 1;
|
|
||||||
|
|
||||||
var sbArrayType = context.TypeRuntimeArray(context.TypeU32());
|
|
||||||
context.Decorate(sbArrayType, Decoration.ArrayStride, (LiteralInteger)4);
|
|
||||||
var sbStructType = context.TypeStruct(true, sbArrayType);
|
|
||||||
context.Decorate(sbStructType, Decoration.BufferBlock);
|
|
||||||
context.MemberDecorate(sbStructType, 0, Decoration.Offset, (LiteralInteger)0);
|
|
||||||
var sbStructArrayType = context.TypeArray(sbStructType, context.Constant(context.TypeU32(), count));
|
|
||||||
var sbPointerType = context.TypePointer(StorageClass.Uniform, sbStructArrayType);
|
|
||||||
var sbVariable = context.Variable(sbPointerType, StorageClass.Uniform);
|
|
||||||
|
|
||||||
context.Name(sbVariable, $"{GetStagePrefix(context.Config.Stage)}_s");
|
|
||||||
context.Decorate(sbVariable, Decoration.DescriptorSet, (LiteralInteger)setIndex);
|
|
||||||
context.Decorate(sbVariable, Decoration.Binding, (LiteralInteger)context.Config.FirstStorageBufferBinding);
|
|
||||||
context.AddGlobalVariable(sbVariable);
|
|
||||||
|
|
||||||
context.StorageBuffersArray = sbVariable;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DeclareSamplers(CodeGenContext context, TextureDescriptor[] descriptors)
|
private static void DeclareSamplers(CodeGenContext context, TextureDescriptor[] descriptors)
|
||||||
{
|
{
|
||||||
foreach (var descriptor in descriptors)
|
foreach (var descriptor in descriptors)
|
||||||
|
@@ -99,7 +99,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Add(Instruction.Load, GenerateLoad);
|
Add(Instruction.Load, GenerateLoad);
|
||||||
Add(Instruction.LoadLocal, GenerateLoadLocal);
|
Add(Instruction.LoadLocal, GenerateLoadLocal);
|
||||||
Add(Instruction.LoadShared, GenerateLoadShared);
|
Add(Instruction.LoadShared, GenerateLoadShared);
|
||||||
Add(Instruction.LoadStorage, GenerateLoadStorage);
|
|
||||||
Add(Instruction.Lod, GenerateLod);
|
Add(Instruction.Lod, GenerateLod);
|
||||||
Add(Instruction.LogarithmB2, GenerateLogarithmB2);
|
Add(Instruction.LogarithmB2, GenerateLogarithmB2);
|
||||||
Add(Instruction.LogicalAnd, GenerateLogicalAnd);
|
Add(Instruction.LogicalAnd, GenerateLogicalAnd);
|
||||||
@@ -137,9 +136,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Add(Instruction.StoreShared, GenerateStoreShared);
|
Add(Instruction.StoreShared, GenerateStoreShared);
|
||||||
Add(Instruction.StoreShared16, GenerateStoreShared16);
|
Add(Instruction.StoreShared16, GenerateStoreShared16);
|
||||||
Add(Instruction.StoreShared8, GenerateStoreShared8);
|
Add(Instruction.StoreShared8, GenerateStoreShared8);
|
||||||
Add(Instruction.StoreStorage, GenerateStoreStorage);
|
|
||||||
Add(Instruction.StoreStorage16, GenerateStoreStorage16);
|
|
||||||
Add(Instruction.StoreStorage8, GenerateStoreStorage8);
|
|
||||||
Add(Instruction.Subtract, GenerateSubtract);
|
Add(Instruction.Subtract, GenerateSubtract);
|
||||||
Add(Instruction.SwizzleAdd, GenerateSwizzleAdd);
|
Add(Instruction.SwizzleAdd, GenerateSwizzleAdd);
|
||||||
Add(Instruction.TextureSample, GenerateTextureSample);
|
Add(Instruction.TextureSample, GenerateTextureSample);
|
||||||
@@ -246,6 +242,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),
|
||||||
@@ -889,14 +895,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
return new OperationResult(AggregateType.U32, value);
|
return new OperationResult(AggregateType.U32, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateLoadStorage(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
var elemPointer = GetStorageElemPointer(context, operation);
|
|
||||||
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;
|
||||||
@@ -1104,6 +1102,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)));
|
||||||
@@ -1307,28 +1307,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
return OperationResult.Invalid;
|
return OperationResult.Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateStoreStorage(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
var elemPointer = GetStorageElemPointer(context, operation);
|
|
||||||
context.Store(elemPointer, context.Get(AggregateType.U32, operation.GetSource(2)));
|
|
||||||
|
|
||||||
return OperationResult.Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateStoreStorage16(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
GenerateStoreStorageSmallInt(context, operation, 16);
|
|
||||||
|
|
||||||
return OperationResult.Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateStoreStorage8(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
GenerateStoreStorageSmallInt(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);
|
||||||
@@ -1849,13 +1827,13 @@ 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(2));
|
var value = context.GetU32(operation.GetSource(operation.SourcesCount - 1));
|
||||||
|
|
||||||
SpvInstruction elemPointer;
|
SpvInstruction elemPointer;
|
||||||
|
|
||||||
if (operation.StorageKind == StorageKind.StorageBuffer)
|
if (operation.StorageKind == StorageKind.StorageBuffer)
|
||||||
{
|
{
|
||||||
elemPointer = GetStorageElemPointer(context, operation);
|
elemPointer = GetStoragePointer(context, operation, out _);
|
||||||
}
|
}
|
||||||
else if (operation.StorageKind == StorageKind.SharedMemory)
|
else if (operation.StorageKind == StorageKind.SharedMemory)
|
||||||
{
|
{
|
||||||
@@ -1875,14 +1853,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateAtomicMemoryCas(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateAtomicMemoryCas(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var value0 = context.GetU32(operation.GetSource(2));
|
var value0 = context.GetU32(operation.GetSource(operation.SourcesCount - 2));
|
||||||
var value1 = context.GetU32(operation.GetSource(3));
|
var value1 = context.GetU32(operation.GetSource(operation.SourcesCount - 1));
|
||||||
|
|
||||||
SpvInstruction elemPointer;
|
SpvInstruction elemPointer;
|
||||||
|
|
||||||
if (operation.StorageKind == StorageKind.StorageBuffer)
|
if (operation.StorageKind == StorageKind.StorageBuffer)
|
||||||
{
|
{
|
||||||
elemPointer = GetStorageElemPointer(context, operation);
|
elemPointer = GetStoragePointer(context, operation, out _);
|
||||||
}
|
}
|
||||||
else if (operation.StorageKind == StorageKind.SharedMemory)
|
else if (operation.StorageKind == StorageKind.SharedMemory)
|
||||||
{
|
{
|
||||||
@@ -1901,17 +1879,33 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateLoadOrStore(CodeGenContext context, AstOperation operation, bool isStore)
|
private static OperationResult GenerateLoadOrStore(CodeGenContext context, AstOperation operation, bool isStore)
|
||||||
|
{
|
||||||
|
SpvInstruction pointer = GetStoragePointer(context, operation, out AggregateType varType);
|
||||||
|
|
||||||
|
if (isStore)
|
||||||
|
{
|
||||||
|
context.Store(pointer, context.Get(varType, operation.GetSource(operation.SourcesCount - 1)));
|
||||||
|
return OperationResult.Invalid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var result = context.Load(context.GetType(varType), pointer);
|
||||||
|
return new OperationResult(varType, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SpvInstruction GetStoragePointer(CodeGenContext context, AstOperation operation, out AggregateType varType)
|
||||||
{
|
{
|
||||||
StorageKind storageKind = operation.StorageKind;
|
StorageKind storageKind = operation.StorageKind;
|
||||||
|
|
||||||
StorageClass storageClass;
|
StorageClass storageClass;
|
||||||
SpvInstruction baseObj;
|
SpvInstruction baseObj;
|
||||||
AggregateType varType;
|
|
||||||
int srcIndex = 0;
|
int srcIndex = 0;
|
||||||
|
|
||||||
switch (storageKind)
|
switch (storageKind)
|
||||||
{
|
{
|
||||||
case StorageKind.ConstantBuffer:
|
case StorageKind.ConstantBuffer:
|
||||||
|
case StorageKind.StorageBuffer:
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
if (!(operation.GetSource(srcIndex++) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
@@ -1922,12 +1916,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferDefinition buffer = context.Config.Properties.ConstantBuffers[bindingIndex.Value];
|
BufferDefinition buffer = storageKind == StorageKind.ConstantBuffer
|
||||||
|
? context.Config.Properties.ConstantBuffers[bindingIndex.Value]
|
||||||
|
: context.Config.Properties.StorageBuffers[bindingIndex.Value];
|
||||||
StructureField field = buffer.Type.Fields[fieldIndex.Value];
|
StructureField field = buffer.Type.Fields[fieldIndex.Value];
|
||||||
|
|
||||||
storageClass = StorageClass.Uniform;
|
storageClass = StorageClass.Uniform;
|
||||||
varType = field.Type & AggregateType.ElementTypeMask;
|
varType = field.Type & AggregateType.ElementTypeMask;
|
||||||
baseObj = context.ConstantBuffers[bindingIndex.Value];
|
baseObj = storageKind == StorageKind.ConstantBuffer
|
||||||
|
? context.ConstantBuffers[bindingIndex.Value]
|
||||||
|
: context.StorageBuffers[bindingIndex.Value];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StorageKind.Input:
|
case StorageKind.Input:
|
||||||
@@ -1993,7 +1991,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
throw new InvalidOperationException($"Invalid storage kind {storageKind}.");
|
throw new InvalidOperationException($"Invalid storage kind {storageKind}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int inputsCount = (isStore ? operation.SourcesCount - 1 : operation.SourcesCount) - srcIndex;
|
bool isStoreOrAtomic = operation.Inst == Instruction.Store || operation.Inst.IsAtomic();
|
||||||
|
int inputsCount = (isStoreOrAtomic ? operation.SourcesCount - 1 : operation.SourcesCount) - srcIndex;
|
||||||
|
|
||||||
|
if (operation.Inst == Instruction.AtomicCompareAndSwap)
|
||||||
|
{
|
||||||
|
inputsCount--;
|
||||||
|
}
|
||||||
|
|
||||||
SpvInstruction e0, e1, e2;
|
SpvInstruction e0, e1, e2;
|
||||||
SpvInstruction pointer;
|
SpvInstruction pointer;
|
||||||
|
|
||||||
@@ -2030,16 +2035,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStore)
|
return pointer;
|
||||||
{
|
|
||||||
context.Store(pointer, context.Get(varType, operation.GetSource(srcIndex)));
|
|
||||||
return OperationResult.Invalid;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var result = context.Load(context.GetType(varType), pointer);
|
|
||||||
return new OperationResult(varType, result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SpvInstruction GetScalarInput(CodeGenContext context, IoVariable ioVariable)
|
private static SpvInstruction GetScalarInput(CodeGenContext context, IoVariable ioVariable)
|
||||||
@@ -2068,25 +2064,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
GenerateStoreSmallInt(context, elemPointer, bitOffset, value, bitSize);
|
GenerateStoreSmallInt(context, elemPointer, bitOffset, value, bitSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateStoreStorageSmallInt(CodeGenContext context, AstOperation operation, int bitSize)
|
|
||||||
{
|
|
||||||
var i0 = context.Get(AggregateType.S32, operation.GetSource(0));
|
|
||||||
var offset = context.Get(AggregateType.U32, operation.GetSource(1));
|
|
||||||
var value = context.Get(AggregateType.U32, operation.GetSource(2));
|
|
||||||
|
|
||||||
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 sbVariable = context.StorageBuffersArray;
|
|
||||||
|
|
||||||
var i1 = context.Constant(context.TypeS32(), 0);
|
|
||||||
|
|
||||||
var elemPointer = context.AccessChain(context.TypePointer(StorageClass.Uniform, context.TypeU32()), sbVariable, i0, i1, wordOffset);
|
|
||||||
|
|
||||||
GenerateStoreSmallInt(context, elemPointer, bitOffset, value, bitSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void GenerateStoreSmallInt(
|
private static void GenerateStoreSmallInt(
|
||||||
CodeGenContext context,
|
CodeGenContext context,
|
||||||
SpvInstruction elemPointer,
|
SpvInstruction elemPointer,
|
||||||
@@ -2173,16 +2150,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SpvInstruction GetStorageElemPointer(CodeGenContext context, AstOperation operation)
|
|
||||||
{
|
|
||||||
var sbVariable = context.StorageBuffersArray;
|
|
||||||
var i0 = context.Get(AggregateType.S32, operation.GetSource(0));
|
|
||||||
var i1 = context.Constant(context.TypeS32(), 0);
|
|
||||||
var i2 = context.Get(AggregateType.S32, operation.GetSource(1));
|
|
||||||
|
|
||||||
return context.AccessChain(context.TypePointer(StorageClass.Uniform, context.TypeU32()), sbVariable, i0, i1, i2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateUnary(
|
private static OperationResult GenerateUnary(
|
||||||
CodeGenContext context,
|
CodeGenContext context,
|
||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -11,6 +11,10 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
public const int NvnBaseInstanceByteOffset = 0x644;
|
public const int NvnBaseInstanceByteOffset = 0x644;
|
||||||
public const int NvnDrawIndexByteOffset = 0x648;
|
public const int NvnDrawIndexByteOffset = 0x648;
|
||||||
|
|
||||||
public const int StorageAlignment = 16;
|
// Transform Feedback emulation.
|
||||||
|
|
||||||
|
public const int TfeInfoBinding = 0;
|
||||||
|
public const int TfeBufferBaseBinding = 1;
|
||||||
|
public const int TfeBuffersCount = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Decoders
|
namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
{
|
{
|
||||||
|
[Flags]
|
||||||
enum InstProps : ushort
|
enum InstProps : ushort
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user