mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-01-13 14:19:12 +00:00
Merge branch 'master' into per-profile-favorites-playtime
This commit is contained in:
commit
121809c242
163 changed files with 1784 additions and 757 deletions
8
.github/assign/audio.yml
vendored
Normal file
8
.github/assign/audio.yml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- marysaka
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- audio
|
11
.github/assign/cpu.yml
vendored
Normal file
11
.github/assign/cpu.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- gdkchan
|
||||
- riperiperi
|
||||
- marysaka
|
||||
- LDj3SNuD
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- cpu
|
4
.github/assign/global.yml
vendored
Normal file
4
.github/assign/global.yml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- Ryujinx/developers
|
10
.github/assign/gpu.yml
vendored
Normal file
10
.github/assign/gpu.yml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- gdkchan
|
||||
- riperiperi
|
||||
- marysaka
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- gpu
|
11
.github/assign/gui.yml
vendored
Normal file
11
.github/assign/gui.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- Ack77
|
||||
- emmauss
|
||||
- TSRBerry
|
||||
- marysaka
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- gui
|
11
.github/assign/horizon.yml
vendored
Normal file
11
.github/assign/horizon.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- gdkchan
|
||||
- Ack77
|
||||
- marysaka
|
||||
- TSRBerry
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- horizon
|
9
.github/assign/infra.yml
vendored
Normal file
9
.github/assign/infra.yml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- marysaka
|
||||
- TSRBerry
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- infra
|
33
.github/labeler.yml
vendored
Normal file
33
.github/labeler.yml
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
audio: 'src/Ryujinx.Audio*/**'
|
||||
|
||||
cpu:
|
||||
- 'src/ARMeilleure/**'
|
||||
- 'src/Ryujinx.Cpu/**'
|
||||
- 'src/Ryujinx.Memory/**'
|
||||
|
||||
gpu:
|
||||
- 'src/Ryujinx.Graphics.*/**'
|
||||
- 'src/Spv.Generator/**'
|
||||
- 'src/Ryujinx.ShaderTools/**'
|
||||
|
||||
'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/**'
|
||||
'graphics-backend:vulkan':
|
||||
- 'src/Ryujinx.Graphics.Vulkan/**'
|
||||
- 'src/Spv.Generator/**'
|
||||
|
||||
gui:
|
||||
- 'src/Ryujinx/**'
|
||||
- 'src/Ryujinx.Ui.Common/**'
|
||||
- 'src/Ryujinx.Ui.LocaleGenerator/**'
|
||||
- 'src/Ryujinx.Ava/**'
|
||||
|
||||
horizon:
|
||||
- 'src/Ryujinx.HLE/**'
|
||||
- 'src/Ryujinx.Horizon*/**'
|
||||
|
||||
kernel: 'src/Ryujinx.HLE/HOS/Kernel/**'
|
||||
|
||||
infra:
|
||||
- '.github/**'
|
||||
- 'distribution/**'
|
||||
- 'Directory.Packages.props'
|
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
|
@ -3,19 +3,13 @@ name: Build job
|
|||
on:
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
#push:
|
||||
# branches: [ master ]
|
||||
# paths-ignore:
|
||||
# - '.github/*'
|
||||
# - '.github/ISSUE_TEMPLATE/**'
|
||||
# - '*.yml'
|
||||
# - 'README.md'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- '.github/*'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.github/**'
|
||||
- '*.yml'
|
||||
- '*.json'
|
||||
- '*.config'
|
||||
- 'README.md'
|
||||
|
||||
concurrency:
|
||||
|
|
54
.github/workflows/pr_triage.yml
vendored
Normal file
54
.github/workflows/pr_triage.yml
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
name: "Pull Request Triage"
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, ready_for_review]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Update labels based on changes
|
||||
uses: actions/labeler@v4
|
||||
with:
|
||||
sync-labels: true
|
||||
dot: true
|
||||
|
||||
- name: Auto Assign [Audio]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/audio.yml'
|
||||
|
||||
- name: Auto Assign [CPU]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/cpu.yml'
|
||||
|
||||
- name: Auto Assign [GPU]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/gpu.yml'
|
||||
|
||||
- name: Auto Assign [GUI]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/gui.yml'
|
||||
|
||||
- name: Auto Assign [Horizon]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/horizon.yml'
|
||||
|
||||
- name: Auto Assign [Infra]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/infra.yml'
|
||||
|
||||
- name: Auto Assign [Global]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/global.yml'
|
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
|
@ -6,9 +6,10 @@ on:
|
|||
push:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- '.github/*'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.github/**'
|
||||
- '*.yml'
|
||||
- '*.json'
|
||||
- '*.config'
|
||||
- 'README.md'
|
||||
|
||||
concurrency: release
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<PackageVersion Include="LibHac" Version="0.18.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
|
||||
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
|
||||
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
|
||||
<PackageVersion Include="NUnit" Version="3.13.3" />
|
||||
|
@ -44,9 +44,9 @@
|
|||
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
|
||||
<PackageVersion Include="SPB" Version="0.0.4-build28" />
|
||||
<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.Management" Version="7.0.1" />
|
||||
<PackageVersion Include="System.Management" Version="7.0.2" />
|
||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -168,8 +168,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||
|
||||
Logger.StartPass(PassName.CodeGeneration);
|
||||
|
||||
//Console.Error.WriteLine(IRDumper.GetDump(cfg));
|
||||
|
||||
bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0;
|
||||
|
||||
CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable);
|
||||
|
|
|
@ -179,6 +179,35 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||
(uint)operation.GetSource(2).AsInt32());
|
||||
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:
|
||||
GenerateVectorUnary(
|
||||
context,
|
||||
|
|
|
@ -19,8 +19,8 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||
Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary));
|
||||
Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary));
|
||||
Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary));
|
||||
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128BinaryRd));
|
||||
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128BinaryRd));
|
||||
Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise));
|
||||
|
|
|
@ -23,6 +23,10 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||
ScalarTernaryShlRd,
|
||||
ScalarTernaryShrRd,
|
||||
|
||||
Vector128Unary,
|
||||
Vector128Binary,
|
||||
Vector128BinaryRd,
|
||||
|
||||
VectorUnary,
|
||||
VectorUnaryBitwise,
|
||||
VectorUnaryByElem,
|
||||
|
@ -50,9 +54,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||
VectorTernaryShlRd,
|
||||
VectorTernaryShrRd,
|
||||
|
||||
Vector128Unary,
|
||||
Vector128Binary,
|
||||
|
||||
GetRegister,
|
||||
SetRegister
|
||||
}
|
||||
|
|
|
@ -746,6 +746,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||
info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
|
||||
info.Type == IntrinsicType.ScalarTernaryShlRd ||
|
||||
info.Type == IntrinsicType.ScalarTernaryShrRd ||
|
||||
info.Type == IntrinsicType.Vector128BinaryRd ||
|
||||
info.Type == IntrinsicType.VectorBinaryRd ||
|
||||
info.Type == IntrinsicType.VectorInsertByElem ||
|
||||
info.Type == IntrinsicType.VectorTernaryRd ||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
enum OpCode32SimdSelMode : int
|
||||
enum OpCode32SimdSelMode
|
||||
{
|
||||
Eq = 0,
|
||||
Vs,
|
||||
|
|
|
@ -17,7 +17,11 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
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());
|
||||
}
|
||||
|
@ -38,7 +42,11 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
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());
|
||||
}
|
||||
|
@ -58,7 +66,11 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
||||
}
|
||||
|
@ -78,7 +90,11 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
Operand roundKey = context.VectorZero();
|
||||
|
||||
|
|
|
@ -17,7 +17,11 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
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());
|
||||
}
|
||||
|
@ -38,7 +42,11 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
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());
|
||||
}
|
||||
|
@ -58,7 +66,11 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
||||
}
|
||||
|
@ -78,7 +90,11 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
Operand roundKey = context.VectorZero();
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
Operand m = GetVecA32(op.Vm >> 1);
|
||||
|
||||
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, doubleSize);
|
||||
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
|
||||
|
||||
Intrinsic inst = (unsigned ? Intrinsic.Arm64FcvtzuGp : Intrinsic.Arm64FcvtzsGp) | Intrinsic.Arm64VDouble;
|
||||
|
||||
|
@ -175,7 +175,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS);
|
||||
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS, false);
|
||||
}
|
||||
}
|
||||
else if (!roundWithFpscr && Optimizations.UseSse41)
|
||||
|
@ -260,28 +260,64 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
if (Optimizations.UseAdvSimd)
|
||||
{
|
||||
if (unsigned)
|
||||
bool doubleSize = floatSize == OperandType.FP64;
|
||||
|
||||
if (doubleSize)
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtauS,
|
||||
0b01 => Intrinsic.Arm64FcvtnuS,
|
||||
0b10 => Intrinsic.Arm64FcvtpuS,
|
||||
0b11 => Intrinsic.Arm64FcvtmuS,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
Operand m = GetVecA32(op.Vm >> 1);
|
||||
|
||||
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
|
||||
|
||||
if (unsigned)
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtauGp,
|
||||
0b01 => Intrinsic.Arm64FcvtnuGp,
|
||||
0b10 => Intrinsic.Arm64FcvtpuGp,
|
||||
0b11 => Intrinsic.Arm64FcvtmuGp,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtasGp,
|
||||
0b01 => Intrinsic.Arm64FcvtnsGp,
|
||||
0b10 => Intrinsic.Arm64FcvtpsGp,
|
||||
0b11 => Intrinsic.Arm64FcvtmsGp,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
}
|
||||
|
||||
Operand asInteger = context.AddIntrinsicInt(inst | Intrinsic.Arm64VDouble, toConvert);
|
||||
|
||||
InsertScalar(context, op.Vd, asInteger);
|
||||
}
|
||||
else
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtasS,
|
||||
0b01 => Intrinsic.Arm64FcvtnsS,
|
||||
0b10 => Intrinsic.Arm64FcvtpsS,
|
||||
0b11 => Intrinsic.Arm64FcvtmsS,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
}
|
||||
if (unsigned)
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtauS,
|
||||
0b01 => Intrinsic.Arm64FcvtnuS,
|
||||
0b10 => Intrinsic.Arm64FcvtpuS,
|
||||
0b11 => Intrinsic.Arm64FcvtmuS,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtasS,
|
||||
0b01 => Intrinsic.Arm64FcvtnsS,
|
||||
0b10 => Intrinsic.Arm64FcvtpsS,
|
||||
0b11 => Intrinsic.Arm64FcvtmsS,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
}
|
||||
|
||||
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
|
||||
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
|
||||
}
|
||||
}
|
||||
else if (Optimizations.UseSse41)
|
||||
{
|
||||
|
|
|
@ -192,11 +192,10 @@ namespace ARMeilleure.Instructions
|
|||
EmitVectorTernaryOpSimd32(context, (d, n, m) => context.AddIntrinsic(inst, d, n, m));
|
||||
}
|
||||
|
||||
public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc)
|
||||
public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc, bool doubleSize)
|
||||
{
|
||||
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
|
||||
|
||||
bool doubleSize = (op.Size & 1) != 0;
|
||||
int shift = doubleSize ? 1 : 2;
|
||||
Operand m = GetVecA32(op.Vm >> shift);
|
||||
Operand d = GetVecA32(op.Vd >> shift);
|
||||
|
@ -215,8 +214,13 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
|
||||
|
||||
inst |= ((op.Size & 1) != 0 ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128;
|
||||
EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m));
|
||||
EmitScalarUnaryOpF32(context, inst, (op.Size & 1) != 0);
|
||||
}
|
||||
|
||||
public static void EmitScalarUnaryOpF32(ArmEmitterContext context, Intrinsic inst, bool doubleSize)
|
||||
{
|
||||
inst |= (doubleSize ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128;
|
||||
EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m), doubleSize);
|
||||
}
|
||||
|
||||
public static void EmitScalarBinaryOpSimd32(ArmEmitterContext context, Func2I scalarFunc)
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
using System;
|
||||
|
||||
namespace ARMeilleure.IntermediateRepresentation
|
||||
{
|
||||
[Flags]
|
||||
enum Intrinsic : ushort
|
||||
{
|
||||
// X86 (SSE and AVX)
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace ARMeilleure
|
|||
public static bool UseUnmanagedDispatchLoop { 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 UseSseIfAvailable { get; set; } = true;
|
||||
|
@ -41,6 +42,7 @@ namespace ARMeilleure
|
|||
}
|
||||
|
||||
internal static bool UseAdvSimd => UseAdvSimdIfAvailable && Arm64HardwareCapabilities.SupportsAdvSimd;
|
||||
internal static bool UseArm64Aes => UseArm64AesIfAvailable && Arm64HardwareCapabilities.SupportsAes;
|
||||
internal static bool UseArm64Pmull => UseArm64PmullIfAvailable && Arm64HardwareCapabilities.SupportsPmull;
|
||||
|
||||
internal static bool UseSse => UseSseIfAvailable && X86HardwareCapabilities.SupportsSse;
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace ARMeilleure.Signal
|
|||
private static IntPtr _signalHandlerPtr;
|
||||
private static IntPtr _signalHandlerHandle;
|
||||
|
||||
private static readonly object _lock = new object();
|
||||
private static readonly object _lock = new();
|
||||
private static bool _initialized;
|
||||
|
||||
static NativeSignalHandler()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace ARMeilleure.State
|
||||
{
|
||||
enum ExecutionMode : int
|
||||
enum ExecutionMode
|
||||
{
|
||||
Aarch32Arm = 0,
|
||||
Aarch32Thumb = 1,
|
||||
|
|
|
@ -2,6 +2,7 @@ using ARMeilleure.CodeGen;
|
|||
using ARMeilleure.CodeGen.Unwinding;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.Native;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
@ -12,8 +13,8 @@ namespace ARMeilleure.Translation.Cache
|
|||
{
|
||||
static partial class JitCache
|
||||
{
|
||||
private const int PageSize = 4 * 1024;
|
||||
private const int PageMask = PageSize - 1;
|
||||
private static readonly int PageSize = (int)MemoryBlock.GetPageSize();
|
||||
private static readonly int PageMask = PageSize - 1;
|
||||
|
||||
private const int CodeAlignment = 4; // Bytes.
|
||||
private const int CacheSize = 2047 * 1024 * 1024;
|
||||
|
@ -25,7 +26,7 @@ namespace ARMeilleure.Translation.Cache
|
|||
|
||||
private static readonly List<CacheEntry> _cacheEntries = new List<CacheEntry>();
|
||||
|
||||
private static readonly object _lock = new object();
|
||||
private static readonly object _lock = new();
|
||||
private static bool _initialized;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC
|
|||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||
|
||||
private const uint InternalVersion = 4661; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
private const uint InternalVersion = 5292; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
|
|||
private Queue<OpenALAudioBuffer> _queuedBuffers;
|
||||
private ulong _playedSampleCount;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
public OpenALHardwareDeviceSession(OpenALHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.Audio.Backends.SoundIo.Native
|
||||
{
|
||||
public enum SoundIoBackend : int
|
||||
public enum SoundIoBackend
|
||||
{
|
||||
None = 0,
|
||||
Jack = 1,
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace Ryujinx.Audio
|
|||
/// <summary>
|
||||
/// Lock used to control the waiters registration.
|
||||
/// </summary>
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Events signaled when the driver played audio buffers.
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Ryujinx.Audio.Backends.Common
|
|||
{
|
||||
private const int RingBufferAlignment = 2048;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private byte[] _buffer;
|
||||
private int _size;
|
||||
|
|
|
@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Input
|
|||
/// </summary>
|
||||
public class AudioInputManager : IDisposable
|
||||
{
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Lock used for session allocation.
|
||||
/// </summary>
|
||||
private object _sessionLock = new object();
|
||||
private readonly object _sessionLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// The session ids allocation table.
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Input
|
|||
/// <summary>
|
||||
/// The lock of the parent.
|
||||
/// </summary>
|
||||
private object _parentLock;
|
||||
private readonly object _parentLock;
|
||||
|
||||
/// <summary>
|
||||
/// The dispose state.
|
||||
|
|
|
@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Output
|
|||
/// </summary>
|
||||
public class AudioOutputManager : IDisposable
|
||||
{
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Lock used for session allocation.
|
||||
/// </summary>
|
||||
private object _sessionLock = new object();
|
||||
private readonly object _sessionLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// The session ids allocation table.
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Output
|
|||
/// <summary>
|
||||
/// THe lock of the parent.
|
||||
/// </summary>
|
||||
private object _parentLock;
|
||||
private readonly object _parentLock;
|
||||
|
||||
/// <summary>
|
||||
/// The dispose state.
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
{
|
||||
public class AudioRenderSystem : IDisposable
|
||||
{
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private AudioRendererRenderingDevice _renderingDevice;
|
||||
private AudioRendererExecutionMode _executionMode;
|
||||
|
|
|
@ -19,12 +19,12 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
/// <summary>
|
||||
/// Lock used for session allocation.
|
||||
/// </summary>
|
||||
private object _sessionLock = new object();
|
||||
private readonly object _sessionLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Lock used to control the <see cref="AudioProcessor"/> running state.
|
||||
/// </summary>
|
||||
private object _audioProcessorLock = new object();
|
||||
private readonly object _audioProcessorLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// The session ids allocation table.
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
|
|||
/// <summary>
|
||||
/// Global lock of the object.
|
||||
/// </summary>
|
||||
private object Lock = new object();
|
||||
private readonly object Lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// The upsamplers instances.
|
||||
|
|
|
@ -40,6 +40,7 @@ using SixLabors.ImageSharp;
|
|||
using SixLabors.ImageSharp.Formats.Png;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SPB.Graphics.Exceptions;
|
||||
using SPB.Graphics.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -475,11 +476,20 @@ namespace Ryujinx.Ava
|
|||
_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)
|
||||
|
@ -930,7 +940,7 @@ namespace Ryujinx.Ava
|
|||
_gpuDoneEvent.Set();
|
||||
});
|
||||
|
||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);
|
||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true);
|
||||
}
|
||||
|
||||
public void UpdateStatus()
|
||||
|
@ -1044,7 +1054,7 @@ namespace Ryujinx.Ava
|
|||
ScreenshotRequested = true;
|
||||
break;
|
||||
case KeyboardHotkeyState.ShowUi:
|
||||
_viewModel.ShowMenuAndStatusBar = true;
|
||||
_viewModel.ShowMenuAndStatusBar = !_viewModel.ShowMenuAndStatusBar;
|
||||
break;
|
||||
case KeyboardHotkeyState.Pause:
|
||||
if (_viewModel.IsPaused)
|
||||
|
|
|
@ -545,7 +545,7 @@
|
|||
"SwkbdMinRangeCharacters": "Must be {0}-{1} characters long",
|
||||
"SoftwareKeyboard": "Software Keyboard",
|
||||
"SoftwareKeyboardModeNumbersOnly": "Must be numbers only",
|
||||
"SoftwareKeyboardModeAlphabet": "Must be alphabets 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.",
|
||||
"DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
|
||||
|
|
|
@ -741,7 +741,7 @@ namespace Ryujinx.Modules
|
|||
var files = Directory.EnumerateFiles(HomeDir); // All files directly in base dir.
|
||||
|
||||
// Determine and exclude user files only when the updater is running, not when cleaning old files
|
||||
if (_running)
|
||||
if (_running && !OperatingSystem.IsMacOS())
|
||||
{
|
||||
// Compare the loose files in base directory against the loose files from the incoming update, and store foreign ones in a user list.
|
||||
var oldFiles = Directory.EnumerateFiles(HomeDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName);
|
||||
|
|
|
@ -146,7 +146,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
case KeyboardMode.Alphabet:
|
||||
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet);
|
||||
validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
|
||||
_checkInput = text => text.All(char.IsAsciiLetter);
|
||||
_checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value));
|
||||
break;
|
||||
case KeyboardMode.ASCII:
|
||||
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeASCII);
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||
}
|
||||
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;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using SPB.Graphics;
|
||||
using SPB.Graphics.Exceptions;
|
||||
using SPB.Graphics.OpenGL;
|
||||
using SPB.Platform;
|
||||
using SPB.Platform.WGL;
|
||||
|
@ -18,8 +20,6 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||
|
||||
public OpenGLContextBase Context { get; set; }
|
||||
|
||||
public EmbeddedWindowOpenGL() { }
|
||||
|
||||
protected override void OnWindowDestroying()
|
||||
{
|
||||
Context.Dispose();
|
||||
|
@ -62,14 +62,21 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||
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)
|
||||
{
|
||||
Context?.MakeCurrent(window);
|
||||
Logger.Warning?.Print(LogClass.Ui, $"Failed to {(!unbind ? "bind" : "unbind")} OpenGL context: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
public void SwapBuffers()
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace Ryujinx.Common.Configuration
|
|||
if (OperatingSystem.IsMacOS() && Mode == LaunchMode.UserProfile)
|
||||
{
|
||||
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);
|
||||
Directory.Delete(oldConfigPath, true);
|
||||
|
@ -115,6 +115,14 @@ namespace Ryujinx.Common.Configuration
|
|||
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)
|
||||
{
|
||||
var dir = new DirectoryInfo(sourceDir);
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Ryujinx.Common.Configuration.Hid
|
|||
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
||||
[Flags]
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<ControllerType>))]
|
||||
public enum ControllerType : int
|
||||
public enum ControllerType
|
||||
{
|
||||
None,
|
||||
ProController = 1 << 0,
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Ryujinx.Common.Configuration.Hid
|
|||
{
|
||||
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<PlayerIndex>))]
|
||||
public enum PlayerIndex : int
|
||||
public enum PlayerIndex
|
||||
{
|
||||
Player1 = 0,
|
||||
Player2 = 1,
|
||||
|
|
|
@ -24,6 +24,24 @@ namespace Ryujinx.Common.Memory
|
|||
return value;
|
||||
}
|
||||
|
||||
public bool TryRead<T>(out T value) where T : unmanaged
|
||||
{
|
||||
int valueSize = Unsafe.SizeOf<T>();
|
||||
|
||||
if (valueSize > _input.Length)
|
||||
{
|
||||
value = default;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
value = MemoryMarshal.Cast<byte, T>(_input)[0];
|
||||
|
||||
_input = _input.Slice(valueSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> GetSpan(int size)
|
||||
{
|
||||
ReadOnlySpan<byte> data = _input.Slice(0, size);
|
||||
|
|
|
@ -28,12 +28,15 @@ namespace Ryujinx.Graphics.GAL
|
|||
public readonly bool SupportsFragmentShaderOrderingIntel;
|
||||
public readonly bool SupportsGeometryShader;
|
||||
public readonly bool SupportsGeometryShaderPassthrough;
|
||||
public readonly bool SupportsTransformFeedback;
|
||||
public readonly bool SupportsImageLoadFormatted;
|
||||
public readonly bool SupportsLayerVertexTessellation;
|
||||
public readonly bool SupportsMismatchingViewFormat;
|
||||
public readonly bool SupportsCubemapView;
|
||||
public readonly bool SupportsNonConstantTextureOffset;
|
||||
public readonly bool SupportsShaderBallot;
|
||||
public readonly bool SupportsShaderBarrierDivergence;
|
||||
public readonly bool SupportsShaderFloat64;
|
||||
public readonly bool SupportsTextureShadowLod;
|
||||
public readonly bool SupportsViewportIndexVertexTessellation;
|
||||
public readonly bool SupportsViewportMask;
|
||||
|
@ -75,12 +78,15 @@ namespace Ryujinx.Graphics.GAL
|
|||
bool supportsFragmentShaderOrderingIntel,
|
||||
bool supportsGeometryShader,
|
||||
bool supportsGeometryShaderPassthrough,
|
||||
bool supportsTransformFeedback,
|
||||
bool supportsImageLoadFormatted,
|
||||
bool supportsLayerVertexTessellation,
|
||||
bool supportsMismatchingViewFormat,
|
||||
bool supportsCubemapView,
|
||||
bool supportsNonConstantTextureOffset,
|
||||
bool supportsShaderBallot,
|
||||
bool supportsShaderBarrierDivergence,
|
||||
bool supportsShaderFloat64,
|
||||
bool supportsTextureShadowLod,
|
||||
bool supportsViewportIndexVertexTessellation,
|
||||
bool supportsViewportMask,
|
||||
|
@ -118,12 +124,15 @@ namespace Ryujinx.Graphics.GAL
|
|||
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
||||
SupportsGeometryShader = supportsGeometryShader;
|
||||
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
||||
SupportsTransformFeedback = supportsTransformFeedback;
|
||||
SupportsImageLoadFormatted = supportsImageLoadFormatted;
|
||||
SupportsLayerVertexTessellation = supportsLayerVertexTessellation;
|
||||
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
|
||||
SupportsCubemapView = supportsCubemapView;
|
||||
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
|
||||
SupportsShaderBallot = supportsShaderBallot;
|
||||
SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence;
|
||||
SupportsShaderFloat64 = supportsShaderFloat64;
|
||||
SupportsTextureShadowLod = supportsTextureShadowLod;
|
||||
SupportsViewportIndexVertexTessellation = supportsViewportIndexVertexTessellation;
|
||||
SupportsViewportMask = supportsViewportMask;
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
private int _refConsumerPtr;
|
||||
|
||||
private Action _interruptAction;
|
||||
private object _interruptLock = new();
|
||||
private readonly object _interruptLock = new();
|
||||
|
||||
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
||||
|
||||
|
|
|
@ -100,22 +100,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
{
|
||||
#pragma warning disable CS0649
|
||||
public uint SetObject;
|
||||
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
|
||||
public int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||
public fixed uint Reserved04[63];
|
||||
public uint NoOperation;
|
||||
public uint SetNotifyA;
|
||||
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
|
||||
public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0xFF);
|
||||
public uint SetNotifyB;
|
||||
public uint Notify;
|
||||
public NotifyType NotifyType => (NotifyType)(Notify);
|
||||
public uint WaitForIdle;
|
||||
public fixed uint Reserved114[7];
|
||||
public uint SetGlobalRenderEnableA;
|
||||
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
|
||||
public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
|
||||
public uint SetGlobalRenderEnableB;
|
||||
public uint SetGlobalRenderEnableC;
|
||||
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
|
||||
public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
|
||||
public uint SendGoIdle;
|
||||
public uint PmTrigger;
|
||||
public uint PmTriggerWfi;
|
||||
|
@ -126,11 +126,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public uint LineLengthIn;
|
||||
public uint LineCount;
|
||||
public uint OffsetOutUpper;
|
||||
public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
|
||||
public int OffsetOutUpperValue => (int)(OffsetOutUpper & 0xFF);
|
||||
public uint OffsetOut;
|
||||
public uint PitchOut;
|
||||
public uint SetDstBlockSize;
|
||||
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
|
||||
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)(SetDstBlockSize & 0xF);
|
||||
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
||||
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
||||
public uint SetDstWidth;
|
||||
|
@ -138,11 +138,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public uint SetDstDepth;
|
||||
public uint SetDstLayer;
|
||||
public uint SetDstOriginBytesX;
|
||||
public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
|
||||
public int SetDstOriginBytesXV => (int)(SetDstOriginBytesX & 0xFFFFF);
|
||||
public uint SetDstOriginSamplesY;
|
||||
public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
|
||||
public int SetDstOriginSamplesYV => (int)(SetDstOriginSamplesY & 0xFFFF);
|
||||
public uint LaunchDma;
|
||||
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
|
||||
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)(LaunchDma & 0x1);
|
||||
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
|
||||
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
|
||||
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
|
||||
|
@ -153,7 +153,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public uint LoadInlineData;
|
||||
public fixed uint Reserved1B8[9];
|
||||
public uint SetI2mSemaphoreA;
|
||||
public int SetI2mSemaphoreAOffsetUpper => (int)((SetI2mSemaphoreA >> 0) & 0xFF);
|
||||
public int SetI2mSemaphoreAOffsetUpper => (int)(SetI2mSemaphoreA & 0xFF);
|
||||
public uint SetI2mSemaphoreB;
|
||||
public uint SetI2mSemaphoreC;
|
||||
public fixed uint Reserved1E8[2];
|
||||
|
@ -162,7 +162,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public uint SetI2mSpareNoop02;
|
||||
public uint SetI2mSpareNoop03;
|
||||
public uint SetValidSpanOverflowAreaA;
|
||||
public int SetValidSpanOverflowAreaAAddressUpper => (int)((SetValidSpanOverflowAreaA >> 0) & 0xFF);
|
||||
public int SetValidSpanOverflowAreaAAddressUpper => (int)(SetValidSpanOverflowAreaA & 0xFF);
|
||||
public uint SetValidSpanOverflowAreaB;
|
||||
public uint SetValidSpanOverflowAreaC;
|
||||
public uint SetCoalesceWaitingPeriodUnit;
|
||||
|
@ -185,12 +185,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public uint SetReservedSwMethod06;
|
||||
public uint SetReservedSwMethod07;
|
||||
public uint SetCwdControl;
|
||||
public SetCwdControlSmSelection SetCwdControlSmSelection => (SetCwdControlSmSelection)((SetCwdControl >> 0) & 0x1);
|
||||
public SetCwdControlSmSelection SetCwdControlSmSelection => (SetCwdControlSmSelection)(SetCwdControl & 0x1);
|
||||
public uint InvalidateTextureHeaderCacheNoWfi;
|
||||
public InvalidateCacheLines InvalidateTextureHeaderCacheNoWfiLines => (InvalidateCacheLines)((InvalidateTextureHeaderCacheNoWfi >> 0) & 0x1);
|
||||
public InvalidateCacheLines InvalidateTextureHeaderCacheNoWfiLines => (InvalidateCacheLines)(InvalidateTextureHeaderCacheNoWfi & 0x1);
|
||||
public int InvalidateTextureHeaderCacheNoWfiTag => (int)((InvalidateTextureHeaderCacheNoWfi >> 4) & 0x3FFFFF);
|
||||
public uint SetCwdRefCounter;
|
||||
public int SetCwdRefCounterSelect => (int)((SetCwdRefCounter >> 0) & 0x3F);
|
||||
public int SetCwdRefCounterSelect => (int)(SetCwdRefCounter & 0x3F);
|
||||
public int SetCwdRefCounterValue => (int)((SetCwdRefCounter >> 8) & 0xFFFF);
|
||||
public uint SetReservedSwMethod08;
|
||||
public uint SetReservedSwMethod09;
|
||||
|
@ -201,28 +201,28 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public uint SetReservedSwMethod14;
|
||||
public uint SetReservedSwMethod15;
|
||||
public uint SetGwcScgType;
|
||||
public SetGwcScgTypeScgType SetGwcScgTypeScgType => (SetGwcScgTypeScgType)((SetGwcScgType >> 0) & 0x1);
|
||||
public SetGwcScgTypeScgType SetGwcScgTypeScgType => (SetGwcScgTypeScgType)(SetGwcScgType & 0x1);
|
||||
public uint SetScgControl;
|
||||
public int SetScgControlCompute1MaxSmCount => (int)((SetScgControl >> 0) & 0x1FF);
|
||||
public int SetScgControlCompute1MaxSmCount => (int)(SetScgControl & 0x1FF);
|
||||
public uint InvalidateConstantBufferCacheA;
|
||||
public int InvalidateConstantBufferCacheAAddressUpper => (int)((InvalidateConstantBufferCacheA >> 0) & 0xFF);
|
||||
public int InvalidateConstantBufferCacheAAddressUpper => (int)(InvalidateConstantBufferCacheA & 0xFF);
|
||||
public uint InvalidateConstantBufferCacheB;
|
||||
public uint InvalidateConstantBufferCacheC;
|
||||
public int InvalidateConstantBufferCacheCByteCount => (int)((InvalidateConstantBufferCacheC >> 0) & 0x1FFFF);
|
||||
public int InvalidateConstantBufferCacheCByteCount => (int)(InvalidateConstantBufferCacheC & 0x1FFFF);
|
||||
public bool InvalidateConstantBufferCacheCThruL2 => (InvalidateConstantBufferCacheC & 0x80000000) != 0;
|
||||
public uint SetComputeClassVersion;
|
||||
public int SetComputeClassVersionCurrent => (int)((SetComputeClassVersion >> 0) & 0xFFFF);
|
||||
public int SetComputeClassVersionCurrent => (int)(SetComputeClassVersion & 0xFFFF);
|
||||
public int SetComputeClassVersionOldestSupported => (int)((SetComputeClassVersion >> 16) & 0xFFFF);
|
||||
public uint CheckComputeClassVersion;
|
||||
public int CheckComputeClassVersionCurrent => (int)((CheckComputeClassVersion >> 0) & 0xFFFF);
|
||||
public int CheckComputeClassVersionCurrent => (int)(CheckComputeClassVersion & 0xFFFF);
|
||||
public int CheckComputeClassVersionOldestSupported => (int)((CheckComputeClassVersion >> 16) & 0xFFFF);
|
||||
public uint SetQmdVersion;
|
||||
public int SetQmdVersionCurrent => (int)((SetQmdVersion >> 0) & 0xFFFF);
|
||||
public int SetQmdVersionCurrent => (int)(SetQmdVersion & 0xFFFF);
|
||||
public int SetQmdVersionOldestSupported => (int)((SetQmdVersion >> 16) & 0xFFFF);
|
||||
public uint SetWfiConfig;
|
||||
public bool SetWfiConfigEnableScgTypeWfi => (SetWfiConfig & 0x1) != 0;
|
||||
public uint CheckQmdVersion;
|
||||
public int CheckQmdVersionCurrent => (int)((CheckQmdVersion >> 0) & 0xFFFF);
|
||||
public int CheckQmdVersionCurrent => (int)(CheckQmdVersion & 0xFFFF);
|
||||
public int CheckQmdVersionOldestSupported => (int)((CheckQmdVersion >> 16) & 0xFFFF);
|
||||
public uint WaitForIdleScgType;
|
||||
public uint InvalidateSkedCaches;
|
||||
|
@ -231,28 +231,28 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public bool SetScgRenderEnableControlCompute1UsesRenderEnable => (SetScgRenderEnableControl & 0x1) != 0;
|
||||
public fixed uint Reserved2A0[4];
|
||||
public uint SetCwdSlotCount;
|
||||
public int SetCwdSlotCountV => (int)((SetCwdSlotCount >> 0) & 0xFF);
|
||||
public int SetCwdSlotCountV => (int)(SetCwdSlotCount & 0xFF);
|
||||
public uint SendPcasA;
|
||||
public uint SendPcasB;
|
||||
public int SendPcasBFrom => (int)((SendPcasB >> 0) & 0xFFFFFF);
|
||||
public int SendPcasBFrom => (int)(SendPcasB & 0xFFFFFF);
|
||||
public int SendPcasBDelta => (int)((SendPcasB >> 24) & 0xFF);
|
||||
public uint SendSignalingPcasB;
|
||||
public bool SendSignalingPcasBInvalidate => (SendSignalingPcasB & 0x1) != 0;
|
||||
public bool SendSignalingPcasBSchedule => (SendSignalingPcasB & 0x2) != 0;
|
||||
public fixed uint Reserved2C0[9];
|
||||
public uint SetShaderLocalMemoryNonThrottledA;
|
||||
public int SetShaderLocalMemoryNonThrottledASizeUpper => (int)((SetShaderLocalMemoryNonThrottledA >> 0) & 0xFF);
|
||||
public int SetShaderLocalMemoryNonThrottledASizeUpper => (int)(SetShaderLocalMemoryNonThrottledA & 0xFF);
|
||||
public uint SetShaderLocalMemoryNonThrottledB;
|
||||
public uint SetShaderLocalMemoryNonThrottledC;
|
||||
public int SetShaderLocalMemoryNonThrottledCMaxSmCount => (int)((SetShaderLocalMemoryNonThrottledC >> 0) & 0x1FF);
|
||||
public int SetShaderLocalMemoryNonThrottledCMaxSmCount => (int)(SetShaderLocalMemoryNonThrottledC & 0x1FF);
|
||||
public uint SetShaderLocalMemoryThrottledA;
|
||||
public int SetShaderLocalMemoryThrottledASizeUpper => (int)((SetShaderLocalMemoryThrottledA >> 0) & 0xFF);
|
||||
public int SetShaderLocalMemoryThrottledASizeUpper => (int)(SetShaderLocalMemoryThrottledA & 0xFF);
|
||||
public uint SetShaderLocalMemoryThrottledB;
|
||||
public uint SetShaderLocalMemoryThrottledC;
|
||||
public int SetShaderLocalMemoryThrottledCMaxSmCount => (int)((SetShaderLocalMemoryThrottledC >> 0) & 0x1FF);
|
||||
public int SetShaderLocalMemoryThrottledCMaxSmCount => (int)(SetShaderLocalMemoryThrottledC & 0x1FF);
|
||||
public fixed uint Reserved2FC[5];
|
||||
public uint SetSpaVersion;
|
||||
public int SetSpaVersionMinor => (int)((SetSpaVersion >> 0) & 0xFF);
|
||||
public int SetSpaVersionMinor => (int)(SetSpaVersion & 0xFF);
|
||||
public int SetSpaVersionMajor => (int)((SetSpaVersion >> 8) & 0xFF);
|
||||
public fixed uint Reserved314[123];
|
||||
public uint SetFalcon00;
|
||||
|
@ -291,14 +291,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public uint SetShaderLocalMemoryWindow;
|
||||
public fixed uint Reserved780[4];
|
||||
public uint SetShaderLocalMemoryA;
|
||||
public int SetShaderLocalMemoryAAddressUpper => (int)((SetShaderLocalMemoryA >> 0) & 0xFF);
|
||||
public int SetShaderLocalMemoryAAddressUpper => (int)(SetShaderLocalMemoryA & 0xFF);
|
||||
public uint SetShaderLocalMemoryB;
|
||||
public fixed uint Reserved798[383];
|
||||
public uint SetShaderCacheControl;
|
||||
public bool SetShaderCacheControlIcachePrefetchEnable => (SetShaderCacheControl & 0x1) != 0;
|
||||
public fixed uint ReservedD98[19];
|
||||
public uint SetSmTimeoutInterval;
|
||||
public int SetSmTimeoutIntervalCounterBit => (int)((SetSmTimeoutInterval >> 0) & 0x3F);
|
||||
public int SetSmTimeoutIntervalCounterBit => (int)(SetSmTimeoutInterval & 0x3F);
|
||||
public fixed uint ReservedDE8[87];
|
||||
public uint SetSpareNoop12;
|
||||
public uint SetSpareNoop13;
|
||||
|
@ -324,48 +324,48 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public bool InvalidateTextureHeaderCacheAllV => (InvalidateTextureHeaderCacheAll & 0x1) != 0;
|
||||
public fixed uint Reserved1214[29];
|
||||
public uint InvalidateTextureDataCacheNoWfi;
|
||||
public InvalidateCacheLines InvalidateTextureDataCacheNoWfiLines => (InvalidateCacheLines)((InvalidateTextureDataCacheNoWfi >> 0) & 0x1);
|
||||
public InvalidateCacheLines InvalidateTextureDataCacheNoWfiLines => (InvalidateCacheLines)(InvalidateTextureDataCacheNoWfi & 0x1);
|
||||
public int InvalidateTextureDataCacheNoWfiTag => (int)((InvalidateTextureDataCacheNoWfi >> 4) & 0x3FFFFF);
|
||||
public fixed uint Reserved128C[7];
|
||||
public uint ActivatePerfSettingsForComputeContext;
|
||||
public bool ActivatePerfSettingsForComputeContextAll => (ActivatePerfSettingsForComputeContext & 0x1) != 0;
|
||||
public fixed uint Reserved12AC[33];
|
||||
public uint InvalidateSamplerCache;
|
||||
public InvalidateCacheLines InvalidateSamplerCacheLines => (InvalidateCacheLines)((InvalidateSamplerCache >> 0) & 0x1);
|
||||
public InvalidateCacheLines InvalidateSamplerCacheLines => (InvalidateCacheLines)(InvalidateSamplerCache & 0x1);
|
||||
public int InvalidateSamplerCacheTag => (int)((InvalidateSamplerCache >> 4) & 0x3FFFFF);
|
||||
public uint InvalidateTextureHeaderCache;
|
||||
public InvalidateCacheLines InvalidateTextureHeaderCacheLines => (InvalidateCacheLines)((InvalidateTextureHeaderCache >> 0) & 0x1);
|
||||
public InvalidateCacheLines InvalidateTextureHeaderCacheLines => (InvalidateCacheLines)(InvalidateTextureHeaderCache & 0x1);
|
||||
public int InvalidateTextureHeaderCacheTag => (int)((InvalidateTextureHeaderCache >> 4) & 0x3FFFFF);
|
||||
public uint InvalidateTextureDataCache;
|
||||
public InvalidateCacheLines InvalidateTextureDataCacheLines => (InvalidateCacheLines)((InvalidateTextureDataCache >> 0) & 0x1);
|
||||
public InvalidateCacheLines InvalidateTextureDataCacheLines => (InvalidateCacheLines)(InvalidateTextureDataCache & 0x1);
|
||||
public int InvalidateTextureDataCacheTag => (int)((InvalidateTextureDataCache >> 4) & 0x3FFFFF);
|
||||
public fixed uint Reserved133C[58];
|
||||
public uint InvalidateSamplerCacheNoWfi;
|
||||
public InvalidateCacheLines InvalidateSamplerCacheNoWfiLines => (InvalidateCacheLines)((InvalidateSamplerCacheNoWfi >> 0) & 0x1);
|
||||
public InvalidateCacheLines InvalidateSamplerCacheNoWfiLines => (InvalidateCacheLines)(InvalidateSamplerCacheNoWfi & 0x1);
|
||||
public int InvalidateSamplerCacheNoWfiTag => (int)((InvalidateSamplerCacheNoWfi >> 4) & 0x3FFFFF);
|
||||
public fixed uint Reserved1428[64];
|
||||
public uint SetShaderExceptions;
|
||||
public bool SetShaderExceptionsEnable => (SetShaderExceptions & 0x1) != 0;
|
||||
public fixed uint Reserved152C[9];
|
||||
public uint SetRenderEnableA;
|
||||
public int SetRenderEnableAOffsetUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
|
||||
public int SetRenderEnableAOffsetUpper => (int)(SetRenderEnableA & 0xFF);
|
||||
public uint SetRenderEnableB;
|
||||
public uint SetRenderEnableC;
|
||||
public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
|
||||
public int SetRenderEnableCMode => (int)(SetRenderEnableC & 0x7);
|
||||
public uint SetTexSamplerPoolA;
|
||||
public int SetTexSamplerPoolAOffsetUpper => (int)((SetTexSamplerPoolA >> 0) & 0xFF);
|
||||
public int SetTexSamplerPoolAOffsetUpper => (int)(SetTexSamplerPoolA & 0xFF);
|
||||
public uint SetTexSamplerPoolB;
|
||||
public uint SetTexSamplerPoolC;
|
||||
public int SetTexSamplerPoolCMaximumIndex => (int)((SetTexSamplerPoolC >> 0) & 0xFFFFF);
|
||||
public int SetTexSamplerPoolCMaximumIndex => (int)(SetTexSamplerPoolC & 0xFFFFF);
|
||||
public fixed uint Reserved1568[3];
|
||||
public uint SetTexHeaderPoolA;
|
||||
public int SetTexHeaderPoolAOffsetUpper => (int)((SetTexHeaderPoolA >> 0) & 0xFF);
|
||||
public int SetTexHeaderPoolAOffsetUpper => (int)(SetTexHeaderPoolA & 0xFF);
|
||||
public uint SetTexHeaderPoolB;
|
||||
public uint SetTexHeaderPoolC;
|
||||
public int SetTexHeaderPoolCMaximumIndex => (int)((SetTexHeaderPoolC >> 0) & 0x3FFFFF);
|
||||
public int SetTexHeaderPoolCMaximumIndex => (int)(SetTexHeaderPoolC & 0x3FFFFF);
|
||||
public fixed uint Reserved1580[34];
|
||||
public uint SetProgramRegionA;
|
||||
public int SetProgramRegionAAddressUpper => (int)((SetProgramRegionA >> 0) & 0xFF);
|
||||
public int SetProgramRegionAAddressUpper => (int)(SetProgramRegionA & 0xFF);
|
||||
public uint SetProgramRegionB;
|
||||
public fixed uint Reserved1610[34];
|
||||
public uint InvalidateShaderCachesNoWfi;
|
||||
|
@ -374,7 +374,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public bool InvalidateShaderCachesNoWfiConstant => (InvalidateShaderCachesNoWfi & 0x1000) != 0;
|
||||
public fixed uint Reserved169C[170];
|
||||
public uint SetRenderEnableOverride;
|
||||
public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)((SetRenderEnableOverride >> 0) & 0x3);
|
||||
public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)(SetRenderEnableOverride & 0x3);
|
||||
public fixed uint Reserved1948[57];
|
||||
public uint PipeNop;
|
||||
public uint SetSpare00;
|
||||
|
@ -383,11 +383,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public uint SetSpare03;
|
||||
public fixed uint Reserved1A40[48];
|
||||
public uint SetReportSemaphoreA;
|
||||
public int SetReportSemaphoreAOffsetUpper => (int)((SetReportSemaphoreA >> 0) & 0xFF);
|
||||
public int SetReportSemaphoreAOffsetUpper => (int)(SetReportSemaphoreA & 0xFF);
|
||||
public uint SetReportSemaphoreB;
|
||||
public uint SetReportSemaphoreC;
|
||||
public uint SetReportSemaphoreD;
|
||||
public SetReportSemaphoreDOperation SetReportSemaphoreDOperation => (SetReportSemaphoreDOperation)((SetReportSemaphoreD >> 0) & 0x3);
|
||||
public SetReportSemaphoreDOperation SetReportSemaphoreDOperation => (SetReportSemaphoreDOperation)(SetReportSemaphoreD & 0x3);
|
||||
public bool SetReportSemaphoreDAwakenEnable => (SetReportSemaphoreD & 0x100000) != 0;
|
||||
public SetReportSemaphoreDStructureSize SetReportSemaphoreDStructureSize => (SetReportSemaphoreDStructureSize)((SetReportSemaphoreD >> 28) & 0x1);
|
||||
public bool SetReportSemaphoreDFlushDisable => (SetReportSemaphoreD & 0x4) != 0;
|
||||
|
@ -396,7 +396,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public SetReportSemaphoreDReductionFormat SetReportSemaphoreDReductionFormat => (SetReportSemaphoreDReductionFormat)((SetReportSemaphoreD >> 17) & 0x3);
|
||||
public fixed uint Reserved1B10[702];
|
||||
public uint SetBindlessTexture;
|
||||
public int SetBindlessTextureConstantBufferSlotSelect => (int)((SetBindlessTexture >> 0) & 0x7);
|
||||
public int SetBindlessTextureConstantBufferSlotSelect => (int)(SetBindlessTexture & 0x7);
|
||||
public uint SetTrapHandler;
|
||||
public fixed uint Reserved2610[843];
|
||||
public Array8<uint> SetShaderPerformanceCounterValueUpper;
|
||||
|
@ -423,11 +423,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||
public bool SetShaderPerformanceCounterControlBWindowed(int i) => (SetShaderPerformanceCounterControlB[i] & 0x8) != 0;
|
||||
public int SetShaderPerformanceCounterControlBFunc(int i) => (int)((SetShaderPerformanceCounterControlB[i] >> 4) & 0xFFFF);
|
||||
public uint SetShaderPerformanceCounterTrapControl;
|
||||
public int SetShaderPerformanceCounterTrapControlMask => (int)((SetShaderPerformanceCounterTrapControl >> 0) & 0xFF);
|
||||
public int SetShaderPerformanceCounterTrapControlMask => (int)(SetShaderPerformanceCounterTrapControl & 0xFF);
|
||||
public uint StartShaderPerformanceCounter;
|
||||
public int StartShaderPerformanceCounterCounterMask => (int)((StartShaderPerformanceCounter >> 0) & 0xFF);
|
||||
public int StartShaderPerformanceCounterCounterMask => (int)(StartShaderPerformanceCounter & 0xFF);
|
||||
public uint StopShaderPerformanceCounter;
|
||||
public int StopShaderPerformanceCounterCounterMask => (int)((StopShaderPerformanceCounter >> 0) & 0xFF);
|
||||
public int StopShaderPerformanceCounterCounterMask => (int)(StopShaderPerformanceCounter & 0xFF);
|
||||
public fixed uint Reserved33E8[6];
|
||||
public MmeShadowScratch SetMmeShadowScratch;
|
||||
#pragma warning restore CS0649
|
||||
|
|
|
@ -186,22 +186,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||
public uint PmTrigger;
|
||||
public fixed uint Reserved144[63];
|
||||
public uint SetSemaphoreA;
|
||||
public int SetSemaphoreAUpper => (int)((SetSemaphoreA >> 0) & 0xFF);
|
||||
public int SetSemaphoreAUpper => (int)(SetSemaphoreA & 0xFF);
|
||||
public uint SetSemaphoreB;
|
||||
public uint SetSemaphorePayload;
|
||||
public fixed uint Reserved24C[2];
|
||||
public uint SetRenderEnableA;
|
||||
public int SetRenderEnableAUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
|
||||
public int SetRenderEnableAUpper => (int)(SetRenderEnableA & 0xFF);
|
||||
public uint SetRenderEnableB;
|
||||
public uint SetRenderEnableC;
|
||||
public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
|
||||
public int SetRenderEnableCMode => (int)(SetRenderEnableC & 0x7);
|
||||
public uint SetSrcPhysMode;
|
||||
public SetPhysModeTarget SetSrcPhysModeTarget => (SetPhysModeTarget)((SetSrcPhysMode >> 0) & 0x3);
|
||||
public SetPhysModeTarget SetSrcPhysModeTarget => (SetPhysModeTarget)(SetSrcPhysMode & 0x3);
|
||||
public uint SetDstPhysMode;
|
||||
public SetPhysModeTarget SetDstPhysModeTarget => (SetPhysModeTarget)((SetDstPhysMode >> 0) & 0x3);
|
||||
public SetPhysModeTarget SetDstPhysModeTarget => (SetPhysModeTarget)(SetDstPhysMode & 0x3);
|
||||
public fixed uint Reserved268[38];
|
||||
public uint LaunchDma;
|
||||
public LaunchDmaDataTransferType LaunchDmaDataTransferType => (LaunchDmaDataTransferType)((LaunchDma >> 0) & 0x3);
|
||||
public LaunchDmaDataTransferType LaunchDmaDataTransferType => (LaunchDmaDataTransferType)(LaunchDma & 0x3);
|
||||
public bool LaunchDmaFlushEnable => (LaunchDma & 0x4) != 0;
|
||||
public LaunchDmaSemaphoreType LaunchDmaSemaphoreType => (LaunchDmaSemaphoreType)((LaunchDma >> 3) & 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 fixed uint Reserved304[63];
|
||||
public uint OffsetInUpper;
|
||||
public int OffsetInUpperUpper => (int)((OffsetInUpper >> 0) & 0xFF);
|
||||
public int OffsetInUpperUpper => (int)(OffsetInUpper & 0xFF);
|
||||
public uint OffsetInLower;
|
||||
public uint OffsetOutUpper;
|
||||
public int OffsetOutUpperUpper => (int)((OffsetOutUpper >> 0) & 0xFF);
|
||||
public int OffsetOutUpperUpper => (int)(OffsetOutUpper & 0xFF);
|
||||
public uint OffsetOutLower;
|
||||
public uint PitchIn;
|
||||
public uint PitchOut;
|
||||
|
@ -231,7 +231,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||
public uint SetRemapConstA;
|
||||
public uint SetRemapConstB;
|
||||
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 SetRemapComponentsDstZ => (SetRemapComponentsDst)((SetRemapComponents >> 8) & 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 SetRemapComponentsNumDstComponents => (SetRemapComponentsNumComponents)((SetRemapComponents >> 24) & 0x3);
|
||||
public uint SetDstBlockSize;
|
||||
public SetBlockSizeWidth SetDstBlockSizeWidth => (SetBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
|
||||
public SetBlockSizeWidth SetDstBlockSizeWidth => (SetBlockSizeWidth)(SetDstBlockSize & 0xF);
|
||||
public SetBlockSizeHeight SetDstBlockSizeHeight => (SetBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
||||
public SetBlockSizeDepth SetDstBlockSizeDepth => (SetBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
||||
public SetBlockSizeGobHeight SetDstBlockSizeGobHeight => (SetBlockSizeGobHeight)((SetDstBlockSize >> 12) & 0xF);
|
||||
|
@ -248,11 +248,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||
public uint SetDstDepth;
|
||||
public uint SetDstLayer;
|
||||
public uint SetDstOrigin;
|
||||
public int SetDstOriginX => (int)((SetDstOrigin >> 0) & 0xFFFF);
|
||||
public int SetDstOriginX => (int)(SetDstOrigin & 0xFFFF);
|
||||
public int SetDstOriginY => (int)((SetDstOrigin >> 16) & 0xFFFF);
|
||||
public uint Reserved724;
|
||||
public uint SetSrcBlockSize;
|
||||
public SetBlockSizeWidth SetSrcBlockSizeWidth => (SetBlockSizeWidth)((SetSrcBlockSize >> 0) & 0xF);
|
||||
public SetBlockSizeWidth SetSrcBlockSizeWidth => (SetBlockSizeWidth)(SetSrcBlockSize & 0xF);
|
||||
public SetBlockSizeHeight SetSrcBlockSizeHeight => (SetBlockSizeHeight)((SetSrcBlockSize >> 4) & 0xF);
|
||||
public SetBlockSizeDepth SetSrcBlockSizeDepth => (SetBlockSizeDepth)((SetSrcBlockSize >> 8) & 0xF);
|
||||
public SetBlockSizeGobHeight SetSrcBlockSizeGobHeight => (SetBlockSizeGobHeight)((SetSrcBlockSize >> 12) & 0xF);
|
||||
|
@ -261,7 +261,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||
public uint SetSrcDepth;
|
||||
public uint SetSrcLayer;
|
||||
public uint SetSrcOrigin;
|
||||
public int SetSrcOriginX => (int)((SetSrcOrigin >> 0) & 0xFFFF);
|
||||
public int SetSrcOriginX => (int)(SetSrcOrigin & 0xFFFF);
|
||||
public int SetSrcOriginY => (int)((SetSrcOrigin >> 16) & 0xFFFF);
|
||||
public fixed uint Reserved740[629];
|
||||
public uint PmTriggerEnd;
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||
public uint Method;
|
||||
#pragma warning restore CS0649
|
||||
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 MethodSubchannel => (int)((Method >> 13) & 0x7);
|
||||
public TertOp TertOp => (TertOp)((Method >> 16) & 0x3);
|
||||
|
|
|
@ -39,17 +39,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||
#pragma warning disable CS0649
|
||||
public uint Entry0;
|
||||
#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 Entry0Operand => (int)(Entry0);
|
||||
#pragma warning disable CS0649
|
||||
public uint Entry1;
|
||||
#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 Entry1Level Entry1Level => (Entry1Level)((Entry1 >> 9) & 0x1);
|
||||
public int Entry1Length => (int)((Entry1 >> 10) & 0x1FFFFF);
|
||||
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
|
||||
public uint SetObject;
|
||||
public int SetObjectNvclass => (int)((SetObject >> 0) & 0xFFFF);
|
||||
public int SetObjectNvclass => (int)(SetObject & 0xFFFF);
|
||||
public int SetObjectEngine => (int)((SetObject >> 16) & 0x1F);
|
||||
public uint Illegal;
|
||||
public int IllegalHandle => (int)(Illegal);
|
||||
|
@ -161,13 +161,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||
public int NopHandle => (int)(Nop);
|
||||
public uint Reserved0C;
|
||||
public uint Semaphorea;
|
||||
public int SemaphoreaOffsetUpper => (int)((Semaphorea >> 0) & 0xFF);
|
||||
public int SemaphoreaOffsetUpper => (int)(Semaphorea & 0xFF);
|
||||
public uint Semaphoreb;
|
||||
public int SemaphorebOffsetLower => (int)((Semaphoreb >> 2) & 0x3FFFFFFF);
|
||||
public uint Semaphorec;
|
||||
public int SemaphorecPayload => (int)(Semaphorec);
|
||||
public uint Semaphored;
|
||||
public SemaphoredOperation SemaphoredOperation => (SemaphoredOperation)((Semaphored >> 0) & 0x1F);
|
||||
public SemaphoredOperation SemaphoredOperation => (SemaphoredOperation)(Semaphored & 0x1F);
|
||||
public SemaphoredAcquireSwitch SemaphoredAcquireSwitch => (SemaphoredAcquireSwitch)((Semaphored >> 12) & 0x1);
|
||||
public SemaphoredReleaseWfi SemaphoredReleaseWfi => (SemaphoredReleaseWfi)((Semaphored >> 20) & 0x1);
|
||||
public SemaphoredReleaseSize SemaphoredReleaseSize => (SemaphoredReleaseSize)((Semaphored >> 24) & 0x1);
|
||||
|
@ -181,14 +181,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||
public uint Reserved2C;
|
||||
public uint MemOpC;
|
||||
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 MemOpCTlbInvalidateTarget MemOpCTlbInvalidateTarget => (MemOpCTlbInvalidateTarget)((MemOpC >> 10) & 0x3);
|
||||
public int MemOpCTlbInvalidateAddrLo => (int)((MemOpC >> 12) & 0xFFFFF);
|
||||
public uint MemOpD;
|
||||
public int MemOpDOperandHigh => (int)((MemOpD >> 0) & 0xFF);
|
||||
public int MemOpDOperandHigh => (int)(MemOpD & 0xFF);
|
||||
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 Reserved3C;
|
||||
public uint Reserved40;
|
||||
|
@ -207,15 +207,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
|||
public uint Syncpointa;
|
||||
public int SyncpointaPayload => (int)(Syncpointa);
|
||||
public uint Syncpointb;
|
||||
public SyncpointbOperation SyncpointbOperation => (SyncpointbOperation)((Syncpointb >> 0) & 0x1);
|
||||
public SyncpointbOperation SyncpointbOperation => (SyncpointbOperation)(Syncpointb & 0x1);
|
||||
public SyncpointbWaitSwitch SyncpointbWaitSwitch => (SyncpointbWaitSwitch)((Syncpointb >> 4) & 0x1);
|
||||
public int SyncpointbSyncptIndex => (int)((Syncpointb >> 8) & 0xFFF);
|
||||
public uint Wfi;
|
||||
public WfiScope WfiScope => (WfiScope)((Wfi >> 0) & 0x1);
|
||||
public WfiScope WfiScope => (WfiScope)(Wfi & 0x1);
|
||||
public uint CrcCheck;
|
||||
public int CrcCheckValue => (int)(CrcCheck);
|
||||
public uint Yield;
|
||||
public YieldOp YieldOp => (YieldOp)((Yield >> 0) & 0x3);
|
||||
public YieldOp YieldOp => (YieldOp)(Yield & 0x3);
|
||||
// TODO: Eventually move this to per-engine state.
|
||||
public Array31<uint> Reserved84;
|
||||
public uint NoOperation;
|
||||
|
|
|
@ -113,22 +113,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||
{
|
||||
#pragma warning disable CS0649
|
||||
public uint SetObject;
|
||||
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
|
||||
public int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||
public fixed uint Reserved04[63];
|
||||
public uint NoOperation;
|
||||
public uint SetNotifyA;
|
||||
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
|
||||
public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0xFF);
|
||||
public uint SetNotifyB;
|
||||
public uint Notify;
|
||||
public NotifyType NotifyType => (NotifyType)(Notify);
|
||||
public uint WaitForIdle;
|
||||
public fixed uint Reserved114[7];
|
||||
public uint SetGlobalRenderEnableA;
|
||||
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
|
||||
public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
|
||||
public uint SetGlobalRenderEnableB;
|
||||
public uint SetGlobalRenderEnableC;
|
||||
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
|
||||
public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
|
||||
public uint SendGoIdle;
|
||||
public uint PmTrigger;
|
||||
public uint PmTriggerWfi;
|
||||
|
@ -139,11 +139,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||
public uint LineLengthIn;
|
||||
public uint LineCount;
|
||||
public uint OffsetOutUpper;
|
||||
public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
|
||||
public int OffsetOutUpperValue => (int)(OffsetOutUpper & 0xFF);
|
||||
public uint OffsetOut;
|
||||
public uint PitchOut;
|
||||
public uint SetDstBlockSize;
|
||||
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
|
||||
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)(SetDstBlockSize & 0xF);
|
||||
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
||||
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
||||
public uint SetDstWidth;
|
||||
|
@ -151,11 +151,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||
public uint SetDstDepth;
|
||||
public uint SetDstLayer;
|
||||
public uint SetDstOriginBytesX;
|
||||
public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
|
||||
public int SetDstOriginBytesXV => (int)(SetDstOriginBytesX & 0xFFFFF);
|
||||
public uint SetDstOriginSamplesY;
|
||||
public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
|
||||
public int SetDstOriginSamplesYV => (int)(SetDstOriginSamplesY & 0xFFFF);
|
||||
public uint LaunchDma;
|
||||
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
|
||||
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)(LaunchDma & 0x1);
|
||||
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
|
||||
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
|
||||
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
|
||||
|
@ -166,7 +166,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||
public uint LoadInlineData;
|
||||
public fixed uint Reserved1B8[9];
|
||||
public uint SetI2mSemaphoreA;
|
||||
public int SetI2mSemaphoreAOffsetUpper => (int)((SetI2mSemaphoreA >> 0) & 0xFF);
|
||||
public int SetI2mSemaphoreAOffsetUpper => (int)(SetI2mSemaphoreA & 0xFF);
|
||||
public uint SetI2mSemaphoreB;
|
||||
public uint SetI2mSemaphoreC;
|
||||
public fixed uint Reserved1E8[2];
|
||||
|
|
|
@ -539,6 +539,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
|
||||
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)
|
||||
{
|
||||
_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.SetInstancedDrawVertexCount(_instancedIndexCount);
|
||||
|
||||
_context.Renderer.Pipeline.DrawIndexed(
|
||||
_instancedIndexCount,
|
||||
_instanceIndex + 1,
|
||||
|
@ -685,6 +695,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
}
|
||||
else
|
||||
{
|
||||
_channel.BufferManager.SetInstancedDrawVertexCount(_instancedDrawStateCount);
|
||||
|
||||
_context.Renderer.Pipeline.Draw(
|
||||
_instancedDrawStateCount,
|
||||
_instanceIndex + 1,
|
||||
|
|
|
@ -269,7 +269,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
_prevFirstVertex = _state.State.FirstVertex;
|
||||
}
|
||||
|
||||
bool tfEnable = _state.State.TfEnable;
|
||||
bool tfEnable = _state.State.TfEnable && _context.Capabilities.SupportsTransformFeedback;
|
||||
|
||||
if (!tfEnable && _prevTfEnable)
|
||||
{
|
||||
|
@ -1367,6 +1367,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
_vsUsesDrawParameters = gs.Shaders[1]?.Info.UsesDrawParameters ?? false;
|
||||
_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)
|
||||
{
|
||||
UpdateUserClipState();
|
||||
|
|
|
@ -746,12 +746,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
{
|
||||
#pragma warning disable CS0649
|
||||
public uint SetObject;
|
||||
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
|
||||
public int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||
public fixed uint Reserved04[63];
|
||||
public uint NoOperation;
|
||||
public uint SetNotifyA;
|
||||
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
|
||||
public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0xFF);
|
||||
public uint SetNotifyB;
|
||||
public uint Notify;
|
||||
public NotifyType NotifyType => (NotifyType)(Notify);
|
||||
|
@ -761,13 +761,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
public uint LoadMmeStartAddressRamPointer;
|
||||
public uint LoadMmeStartAddressRam;
|
||||
public uint SetMmeShadowRamControl;
|
||||
public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)((SetMmeShadowRamControl >> 0) & 0x3);
|
||||
public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)(SetMmeShadowRamControl & 0x3);
|
||||
public fixed uint Reserved128[2];
|
||||
public uint SetGlobalRenderEnableA;
|
||||
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
|
||||
public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
|
||||
public uint SetGlobalRenderEnableB;
|
||||
public uint SetGlobalRenderEnableC;
|
||||
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
|
||||
public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
|
||||
public uint SendGoIdle;
|
||||
public uint PmTrigger;
|
||||
public uint PmTriggerWfi;
|
||||
|
@ -778,11 +778,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
public uint LineLengthIn;
|
||||
public uint LineCount;
|
||||
public uint OffsetOutUpper;
|
||||
public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
|
||||
public int OffsetOutUpperValue => (int)(OffsetOutUpper & 0xFF);
|
||||
public uint OffsetOut;
|
||||
public uint PitchOut;
|
||||
public uint SetDstBlockSize;
|
||||
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
|
||||
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)(SetDstBlockSize & 0xF);
|
||||
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
|
||||
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
|
||||
public uint SetDstWidth;
|
||||
|
@ -790,11 +790,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
public uint SetDstDepth;
|
||||
public uint SetDstLayer;
|
||||
public uint SetDstOriginBytesX;
|
||||
public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
|
||||
public int SetDstOriginBytesXV => (int)(SetDstOriginBytesX & 0xFFFFF);
|
||||
public uint SetDstOriginSamplesY;
|
||||
public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
|
||||
public int SetDstOriginSamplesYV => (int)(SetDstOriginSamplesY & 0xFFFF);
|
||||
public uint LaunchDma;
|
||||
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
|
||||
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)(LaunchDma & 0x1);
|
||||
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
|
||||
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
|
||||
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
|
||||
|
|
|
@ -499,12 +499,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||
{
|
||||
#pragma warning disable CS0649
|
||||
public uint SetObject;
|
||||
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
|
||||
public int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||
public fixed uint Reserved04[63];
|
||||
public uint NoOperation;
|
||||
public uint SetNotifyA;
|
||||
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0x1FFFFFF);
|
||||
public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0x1FFFFFF);
|
||||
public uint SetNotifyB;
|
||||
public uint Notify;
|
||||
public NotifyType NotifyType => (NotifyType)(Notify);
|
||||
|
@ -514,13 +514,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||
public uint LoadMmeStartAddressRamPointer;
|
||||
public uint LoadMmeStartAddressRam;
|
||||
public uint SetMmeShadowRamControl;
|
||||
public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)((SetMmeShadowRamControl >> 0) & 0x3);
|
||||
public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)(SetMmeShadowRamControl & 0x3);
|
||||
public fixed uint Reserved128[2];
|
||||
public uint SetGlobalRenderEnableA;
|
||||
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
|
||||
public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
|
||||
public uint SetGlobalRenderEnableB;
|
||||
public uint SetGlobalRenderEnableC;
|
||||
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
|
||||
public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
|
||||
public uint SendGoIdle;
|
||||
public uint PmTrigger;
|
||||
public fixed uint Reserved144[3];
|
||||
|
@ -533,9 +533,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||
public int SetMmeSwitchStateRestoreMacro => (int)((SetMmeSwitchState >> 12) & 0xFF);
|
||||
public fixed uint Reserved1F0[4];
|
||||
public uint SetDstFormat;
|
||||
public SetDstFormatV SetDstFormatV => (SetDstFormatV)((SetDstFormat >> 0) & 0xFF);
|
||||
public SetDstFormatV SetDstFormatV => (SetDstFormatV)(SetDstFormat & 0xFF);
|
||||
public uint SetDstMemoryLayout;
|
||||
public SetDstMemoryLayoutV SetDstMemoryLayoutV => (SetDstMemoryLayoutV)((SetDstMemoryLayout >> 0) & 0x1);
|
||||
public SetDstMemoryLayoutV SetDstMemoryLayoutV => (SetDstMemoryLayoutV)(SetDstMemoryLayout & 0x1);
|
||||
public uint SetDstBlockSize;
|
||||
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0x7);
|
||||
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0x7);
|
||||
|
@ -545,37 +545,37 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||
public uint SetDstWidth;
|
||||
public uint SetDstHeight;
|
||||
public uint SetDstOffsetUpper;
|
||||
public int SetDstOffsetUpperV => (int)((SetDstOffsetUpper >> 0) & 0xFF);
|
||||
public int SetDstOffsetUpperV => (int)(SetDstOffsetUpper & 0xFF);
|
||||
public uint SetDstOffsetLower;
|
||||
public uint FlushAndInvalidateRopMiniCache;
|
||||
public bool FlushAndInvalidateRopMiniCacheV => (FlushAndInvalidateRopMiniCache & 0x1) != 0;
|
||||
public uint SetSpareNoop06;
|
||||
public uint SetSrcFormat;
|
||||
public SetSrcFormatV SetSrcFormatV => (SetSrcFormatV)((SetSrcFormat >> 0) & 0xFF);
|
||||
public SetSrcFormatV SetSrcFormatV => (SetSrcFormatV)(SetSrcFormat & 0xFF);
|
||||
public uint SetSrcMemoryLayout;
|
||||
public SetSrcMemoryLayoutV SetSrcMemoryLayoutV => (SetSrcMemoryLayoutV)((SetSrcMemoryLayout >> 0) & 0x1);
|
||||
public SetSrcMemoryLayoutV SetSrcMemoryLayoutV => (SetSrcMemoryLayoutV)(SetSrcMemoryLayout & 0x1);
|
||||
public uint SetSrcBlockSize;
|
||||
public SetSrcBlockSizeHeight SetSrcBlockSizeHeight => (SetSrcBlockSizeHeight)((SetSrcBlockSize >> 4) & 0x7);
|
||||
public SetSrcBlockSizeDepth SetSrcBlockSizeDepth => (SetSrcBlockSizeDepth)((SetSrcBlockSize >> 8) & 0x7);
|
||||
public uint SetSrcDepth;
|
||||
public uint TwodInvalidateTextureDataCache;
|
||||
public TwodInvalidateTextureDataCacheV TwodInvalidateTextureDataCacheV => (TwodInvalidateTextureDataCacheV)((TwodInvalidateTextureDataCache >> 0) & 0x3);
|
||||
public TwodInvalidateTextureDataCacheV TwodInvalidateTextureDataCacheV => (TwodInvalidateTextureDataCacheV)(TwodInvalidateTextureDataCache & 0x3);
|
||||
public uint SetSrcPitch;
|
||||
public uint SetSrcWidth;
|
||||
public uint SetSrcHeight;
|
||||
public uint SetSrcOffsetUpper;
|
||||
public int SetSrcOffsetUpperV => (int)((SetSrcOffsetUpper >> 0) & 0xFF);
|
||||
public int SetSrcOffsetUpperV => (int)(SetSrcOffsetUpper & 0xFF);
|
||||
public uint SetSrcOffsetLower;
|
||||
public uint SetPixelsFromMemorySectorPromotion;
|
||||
public SetPixelsFromMemorySectorPromotionV SetPixelsFromMemorySectorPromotionV => (SetPixelsFromMemorySectorPromotionV)((SetPixelsFromMemorySectorPromotion >> 0) & 0x3);
|
||||
public SetPixelsFromMemorySectorPromotionV SetPixelsFromMemorySectorPromotionV => (SetPixelsFromMemorySectorPromotionV)(SetPixelsFromMemorySectorPromotion & 0x3);
|
||||
public uint SetSpareNoop12;
|
||||
public uint SetNumProcessingClusters;
|
||||
public SetNumProcessingClustersV SetNumProcessingClustersV => (SetNumProcessingClustersV)((SetNumProcessingClusters >> 0) & 0x1);
|
||||
public SetNumProcessingClustersV SetNumProcessingClustersV => (SetNumProcessingClustersV)(SetNumProcessingClusters & 0x1);
|
||||
public uint SetRenderEnableA;
|
||||
public int SetRenderEnableAOffsetUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
|
||||
public int SetRenderEnableAOffsetUpper => (int)(SetRenderEnableA & 0xFF);
|
||||
public uint SetRenderEnableB;
|
||||
public uint SetRenderEnableC;
|
||||
public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
|
||||
public int SetRenderEnableCMode => (int)(SetRenderEnableC & 0x7);
|
||||
public uint SetSpareNoop08;
|
||||
public uint SetSpareNoop01;
|
||||
public uint SetSpareNoop11;
|
||||
|
@ -587,25 +587,25 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||
public uint SetClipEnable;
|
||||
public bool SetClipEnableV => (SetClipEnable & 0x1) != 0;
|
||||
public uint SetColorKeyFormat;
|
||||
public SetColorKeyFormatV SetColorKeyFormatV => (SetColorKeyFormatV)((SetColorKeyFormat >> 0) & 0x7);
|
||||
public SetColorKeyFormatV SetColorKeyFormatV => (SetColorKeyFormatV)(SetColorKeyFormat & 0x7);
|
||||
public uint SetColorKey;
|
||||
public uint SetColorKeyEnable;
|
||||
public bool SetColorKeyEnableV => (SetColorKeyEnable & 0x1) != 0;
|
||||
public uint SetRop;
|
||||
public int SetRopV => (int)((SetRop >> 0) & 0xFF);
|
||||
public int SetRopV => (int)(SetRop & 0xFF);
|
||||
public uint SetBeta1;
|
||||
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 SetBeta4R => (int)((SetBeta4 >> 16) & 0xFF);
|
||||
public int SetBeta4A => (int)((SetBeta4 >> 24) & 0xFF);
|
||||
public uint SetOperation;
|
||||
public SetOperationV SetOperationV => (SetOperationV)((SetOperation >> 0) & 0x7);
|
||||
public SetOperationV SetOperationV => (SetOperationV)(SetOperation & 0x7);
|
||||
public uint SetPatternOffset;
|
||||
public int SetPatternOffsetX => (int)((SetPatternOffset >> 0) & 0x3F);
|
||||
public int SetPatternOffsetX => (int)(SetPatternOffset & 0x3F);
|
||||
public int SetPatternOffsetY => (int)((SetPatternOffset >> 8) & 0x3F);
|
||||
public uint SetPatternSelect;
|
||||
public SetPatternSelectV SetPatternSelectV => (SetPatternSelectV)((SetPatternSelect >> 0) & 0x3);
|
||||
public SetPatternSelectV SetPatternSelectV => (SetPatternSelectV)(SetPatternSelect & 0x3);
|
||||
public uint SetDstColorRenderToZetaSurface;
|
||||
public bool SetDstColorRenderToZetaSurfaceV => (SetDstColorRenderToZetaSurface & 0x1) != 0;
|
||||
public uint SetSpareNoop04;
|
||||
|
@ -618,15 +618,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||
public bool SetCompressionEnable => (SetCompression & 0x1) != 0;
|
||||
public uint SetSpareNoop09;
|
||||
public uint SetRenderEnableOverride;
|
||||
public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)((SetRenderEnableOverride >> 0) & 0x3);
|
||||
public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)(SetRenderEnableOverride & 0x3);
|
||||
public uint SetPixelsFromMemoryDirection;
|
||||
public SetPixelsFromMemoryDirectionHorizontal SetPixelsFromMemoryDirectionHorizontal => (SetPixelsFromMemoryDirectionHorizontal)((SetPixelsFromMemoryDirection >> 0) & 0x3);
|
||||
public SetPixelsFromMemoryDirectionHorizontal SetPixelsFromMemoryDirectionHorizontal => (SetPixelsFromMemoryDirectionHorizontal)(SetPixelsFromMemoryDirection & 0x3);
|
||||
public SetPixelsFromMemoryDirectionVertical SetPixelsFromMemoryDirectionVertical => (SetPixelsFromMemoryDirectionVertical)((SetPixelsFromMemoryDirection >> 4) & 0x3);
|
||||
public uint SetSpareNoop10;
|
||||
public uint SetMonochromePatternColorFormat;
|
||||
public SetMonochromePatternColorFormatV SetMonochromePatternColorFormatV => (SetMonochromePatternColorFormatV)((SetMonochromePatternColorFormat >> 0) & 0x7);
|
||||
public SetMonochromePatternColorFormatV SetMonochromePatternColorFormatV => (SetMonochromePatternColorFormatV)(SetMonochromePatternColorFormat & 0x7);
|
||||
public uint SetMonochromePatternFormat;
|
||||
public SetMonochromePatternFormatV SetMonochromePatternFormatV => (SetMonochromePatternFormatV)((SetMonochromePatternFormat >> 0) & 0x1);
|
||||
public SetMonochromePatternFormatV SetMonochromePatternFormatV => (SetMonochromePatternFormatV)(SetMonochromePatternFormat & 0x1);
|
||||
public uint SetMonochromePatternColor0;
|
||||
public uint SetMonochromePatternColor1;
|
||||
public uint SetMonochromePattern0;
|
||||
|
@ -662,26 +662,26 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||
public uint SetRenderSolidPrimColor2;
|
||||
public uint SetRenderSolidPrimColor3;
|
||||
public uint SetMmeMemAddressA;
|
||||
public int SetMmeMemAddressAUpper => (int)((SetMmeMemAddressA >> 0) & 0x1FFFFFF);
|
||||
public int SetMmeMemAddressAUpper => (int)(SetMmeMemAddressA & 0x1FFFFFF);
|
||||
public uint SetMmeMemAddressB;
|
||||
public uint SetMmeDataRamAddress;
|
||||
public uint MmeDmaRead;
|
||||
public uint MmeDmaReadFifoed;
|
||||
public uint MmeDmaWrite;
|
||||
public uint MmeDmaReduction;
|
||||
public MmeDmaReductionReductionOp MmeDmaReductionReductionOp => (MmeDmaReductionReductionOp)((MmeDmaReduction >> 0) & 0x7);
|
||||
public MmeDmaReductionReductionOp MmeDmaReductionReductionOp => (MmeDmaReductionReductionOp)(MmeDmaReduction & 0x7);
|
||||
public MmeDmaReductionReductionFormat MmeDmaReductionReductionFormat => (MmeDmaReductionReductionFormat)((MmeDmaReduction >> 4) & 0x3);
|
||||
public MmeDmaReductionReductionSize MmeDmaReductionReductionSize => (MmeDmaReductionReductionSize)((MmeDmaReduction >> 8) & 0x1);
|
||||
public uint MmeDmaSysmembar;
|
||||
public bool MmeDmaSysmembarV => (MmeDmaSysmembar & 0x1) != 0;
|
||||
public uint MmeDmaSync;
|
||||
public uint SetMmeDataFifoConfig;
|
||||
public SetMmeDataFifoConfigFifoSize SetMmeDataFifoConfigFifoSize => (SetMmeDataFifoConfigFifoSize)((SetMmeDataFifoConfig >> 0) & 0x7);
|
||||
public SetMmeDataFifoConfigFifoSize SetMmeDataFifoConfigFifoSize => (SetMmeDataFifoConfigFifoSize)(SetMmeDataFifoConfig & 0x7);
|
||||
public fixed uint Reserved578[2];
|
||||
public uint RenderSolidPrimMode;
|
||||
public RenderSolidPrimModeV RenderSolidPrimModeV => (RenderSolidPrimModeV)((RenderSolidPrimMode >> 0) & 0x7);
|
||||
public RenderSolidPrimModeV RenderSolidPrimModeV => (RenderSolidPrimModeV)(RenderSolidPrimMode & 0x7);
|
||||
public uint SetRenderSolidPrimColorFormat;
|
||||
public SetRenderSolidPrimColorFormatV SetRenderSolidPrimColorFormatV => (SetRenderSolidPrimColorFormatV)((SetRenderSolidPrimColorFormat >> 0) & 0xFF);
|
||||
public SetRenderSolidPrimColorFormatV SetRenderSolidPrimColorFormatV => (SetRenderSolidPrimColorFormatV)(SetRenderSolidPrimColorFormat & 0xFF);
|
||||
public uint SetRenderSolidPrimColor;
|
||||
public uint SetRenderSolidLineTieBreakBits;
|
||||
public bool SetRenderSolidLineTieBreakBitsXmajXincYinc => (SetRenderSolidLineTieBreakBits & 0x1) != 0;
|
||||
|
@ -690,24 +690,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||
public bool SetRenderSolidLineTieBreakBitsYmajXdecYinc => (SetRenderSolidLineTieBreakBits & 0x1000) != 0;
|
||||
public fixed uint Reserved590[20];
|
||||
public uint RenderSolidPrimPointXY;
|
||||
public int RenderSolidPrimPointXYX => (int)((RenderSolidPrimPointXY >> 0) & 0xFFFF);
|
||||
public int RenderSolidPrimPointXYX => (int)(RenderSolidPrimPointXY & 0xFFFF);
|
||||
public int RenderSolidPrimPointXYY => (int)((RenderSolidPrimPointXY >> 16) & 0xFFFF);
|
||||
public fixed uint Reserved5E4[7];
|
||||
public Array64<RenderSolidPrimPoint> RenderSolidPrimPoint;
|
||||
public uint SetPixelsFromCpuDataType;
|
||||
public SetPixelsFromCpuDataTypeV SetPixelsFromCpuDataTypeV => (SetPixelsFromCpuDataTypeV)((SetPixelsFromCpuDataType >> 0) & 0x1);
|
||||
public SetPixelsFromCpuDataTypeV SetPixelsFromCpuDataTypeV => (SetPixelsFromCpuDataTypeV)(SetPixelsFromCpuDataType & 0x1);
|
||||
public uint SetPixelsFromCpuColorFormat;
|
||||
public SetPixelsFromCpuColorFormatV SetPixelsFromCpuColorFormatV => (SetPixelsFromCpuColorFormatV)((SetPixelsFromCpuColorFormat >> 0) & 0xFF);
|
||||
public SetPixelsFromCpuColorFormatV SetPixelsFromCpuColorFormatV => (SetPixelsFromCpuColorFormatV)(SetPixelsFromCpuColorFormat & 0xFF);
|
||||
public uint SetPixelsFromCpuIndexFormat;
|
||||
public SetPixelsFromCpuIndexFormatV SetPixelsFromCpuIndexFormatV => (SetPixelsFromCpuIndexFormatV)((SetPixelsFromCpuIndexFormat >> 0) & 0x3);
|
||||
public SetPixelsFromCpuIndexFormatV SetPixelsFromCpuIndexFormatV => (SetPixelsFromCpuIndexFormatV)(SetPixelsFromCpuIndexFormat & 0x3);
|
||||
public uint SetPixelsFromCpuMonoFormat;
|
||||
public SetPixelsFromCpuMonoFormatV SetPixelsFromCpuMonoFormatV => (SetPixelsFromCpuMonoFormatV)((SetPixelsFromCpuMonoFormat >> 0) & 0x1);
|
||||
public SetPixelsFromCpuMonoFormatV SetPixelsFromCpuMonoFormatV => (SetPixelsFromCpuMonoFormatV)(SetPixelsFromCpuMonoFormat & 0x1);
|
||||
public uint SetPixelsFromCpuWrap;
|
||||
public SetPixelsFromCpuWrapV SetPixelsFromCpuWrapV => (SetPixelsFromCpuWrapV)((SetPixelsFromCpuWrap >> 0) & 0x3);
|
||||
public SetPixelsFromCpuWrapV SetPixelsFromCpuWrapV => (SetPixelsFromCpuWrapV)(SetPixelsFromCpuWrap & 0x3);
|
||||
public uint SetPixelsFromCpuColor0;
|
||||
public uint SetPixelsFromCpuColor1;
|
||||
public uint SetPixelsFromCpuMonoOpacity;
|
||||
public SetPixelsFromCpuMonoOpacityV SetPixelsFromCpuMonoOpacityV => (SetPixelsFromCpuMonoOpacityV)((SetPixelsFromCpuMonoOpacity >> 0) & 0x1);
|
||||
public SetPixelsFromCpuMonoOpacityV SetPixelsFromCpuMonoOpacityV => (SetPixelsFromCpuMonoOpacityV)(SetPixelsFromCpuMonoOpacity & 0x1);
|
||||
public fixed uint Reserved820[6];
|
||||
public uint SetPixelsFromCpuSrcWidth;
|
||||
public uint SetPixelsFromCpuSrcHeight;
|
||||
|
@ -753,13 +753,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||
public bool SetBigEndianControlOverride => (SetBigEndianControl & 0x10000000) != 0;
|
||||
public fixed uint Reserved874[3];
|
||||
public uint SetPixelsFromMemoryBlockShape;
|
||||
public SetPixelsFromMemoryBlockShapeV SetPixelsFromMemoryBlockShapeV => (SetPixelsFromMemoryBlockShapeV)((SetPixelsFromMemoryBlockShape >> 0) & 0x7);
|
||||
public SetPixelsFromMemoryBlockShapeV SetPixelsFromMemoryBlockShapeV => (SetPixelsFromMemoryBlockShapeV)(SetPixelsFromMemoryBlockShape & 0x7);
|
||||
public uint SetPixelsFromMemoryCorralSize;
|
||||
public int SetPixelsFromMemoryCorralSizeV => (int)((SetPixelsFromMemoryCorralSize >> 0) & 0x3FF);
|
||||
public int SetPixelsFromMemoryCorralSizeV => (int)(SetPixelsFromMemoryCorralSize & 0x3FF);
|
||||
public uint SetPixelsFromMemorySafeOverlap;
|
||||
public bool SetPixelsFromMemorySafeOverlapV => (SetPixelsFromMemorySafeOverlap & 0x1) != 0;
|
||||
public uint SetPixelsFromMemorySampleMode;
|
||||
public SetPixelsFromMemorySampleModeOrigin SetPixelsFromMemorySampleModeOrigin => (SetPixelsFromMemorySampleModeOrigin)((SetPixelsFromMemorySampleMode >> 0) & 0x1);
|
||||
public SetPixelsFromMemorySampleModeOrigin SetPixelsFromMemorySampleModeOrigin => (SetPixelsFromMemorySampleModeOrigin)(SetPixelsFromMemorySampleMode & 0x1);
|
||||
public SetPixelsFromMemorySampleModeFilter SetPixelsFromMemorySampleModeFilter => (SetPixelsFromMemorySampleModeFilter)((SetPixelsFromMemorySampleMode >> 4) & 0x1);
|
||||
public fixed uint Reserved890[8];
|
||||
public uint SetPixelsFromMemoryDstX0;
|
||||
|
|
|
@ -6,6 +6,7 @@ using Ryujinx.Graphics.Shader;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
|
@ -14,12 +15,17 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
/// </summary>
|
||||
class BufferManager
|
||||
{
|
||||
private const int TfInfoVertexCountOffset = Constants.TotalTransformFeedbackBuffers * sizeof(int);
|
||||
private const int TfInfoBufferSize = TfInfoVertexCountOffset + sizeof(int);
|
||||
|
||||
private readonly GpuContext _context;
|
||||
private readonly GpuChannel _channel;
|
||||
|
||||
private int _unalignedStorageBuffers;
|
||||
public bool HasUnalignedStorageBuffers => _unalignedStorageBuffers > 0;
|
||||
|
||||
public bool HasTransformFeedbackOutputs { get; set; }
|
||||
|
||||
private IndexBuffer _indexBuffer;
|
||||
private readonly VertexBuffer[] _vertexBuffers;
|
||||
private readonly BufferBounds[] _transformFeedbackBuffers;
|
||||
|
@ -98,6 +104,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
private readonly BuffersPerStage[] _gpStorageBuffers;
|
||||
private readonly BuffersPerStage[] _gpUniformBuffers;
|
||||
|
||||
private BufferHandle _tfInfoBuffer;
|
||||
private int[] _tfInfoData;
|
||||
|
||||
private bool _gpStorageBuffersDirty;
|
||||
private bool _gpUniformBuffersDirty;
|
||||
|
||||
|
@ -137,6 +146,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
_bufferTextures = new List<BufferTextureBinding>();
|
||||
|
||||
_ranges = new BufferAssignment[Constants.TotalGpUniformBuffers * Constants.ShaderStages];
|
||||
|
||||
if (!context.Capabilities.SupportsTransformFeedback)
|
||||
{
|
||||
_tfInfoData = new int[Constants.TotalTransformFeedbackBuffers];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -319,6 +333,31 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
_gpUniformBuffersDirty = true;
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// Sets the binding points for the storage buffers bound on the compute pipeline.
|
||||
/// </summary>
|
||||
|
@ -537,22 +576,75 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
{
|
||||
_transformFeedbackBuffersDirty = false;
|
||||
|
||||
Span<BufferRange> tfbs = stackalloc BufferRange[Constants.TotalTransformFeedbackBuffers];
|
||||
|
||||
for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
|
||||
if (_context.Capabilities.SupportsTransformFeedback)
|
||||
{
|
||||
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;
|
||||
continue;
|
||||
BufferBounds tfb = _transformFeedbackBuffers[index];
|
||||
|
||||
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
|
||||
{
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
private List<BufferMigration> _sources;
|
||||
private BufferMigration _migrationTarget;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Whether the modified range list has any entries or not.
|
||||
|
@ -125,7 +125,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
BufferModifiedRange overlap = overlaps[i];
|
||||
|
||||
|
||||
if (overlap.Address > address)
|
||||
{
|
||||
// The start of the remaining region is uncovered by this overlap. Call the action for it.
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
ShaderSpecializationState oldSpecState,
|
||||
ShaderSpecializationState newSpecState,
|
||||
ResourceCounts counts,
|
||||
int stageIndex) : base(context, counts, stageIndex)
|
||||
int stageIndex) : base(context, counts, stageIndex, oldSpecState.TransformFeedbackDescriptors != null)
|
||||
{
|
||||
_data = data;
|
||||
_cb1Data = cb1Data;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
private const ushort FileFormatVersionMajor = 1;
|
||||
private const ushort FileFormatVersionMinor = 2;
|
||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||
private const uint CodeGenVersion = 4992;
|
||||
private const uint CodeGenVersion = 5080;
|
||||
|
||||
private const string SharedTocFileName = "shared.toc";
|
||||
private const string SharedDataFileName = "shared.data";
|
||||
|
@ -368,7 +368,11 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
|
||||
if (hostCode != null)
|
||||
{
|
||||
ShaderInfo shaderInfo = ShaderInfoBuilder.BuildForCache(context, shaders, specState.PipelineState);
|
||||
ShaderInfo shaderInfo = ShaderInfoBuilder.BuildForCache(
|
||||
context,
|
||||
shaders,
|
||||
specState.PipelineState,
|
||||
specState.TransformFeedbackDescriptors != null);
|
||||
|
||||
IProgram hostProgram;
|
||||
|
||||
|
|
|
@ -491,7 +491,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
{
|
||||
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++)
|
||||
{
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
GpuContext context,
|
||||
GpuChannel channel,
|
||||
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;
|
||||
_channel = channel;
|
||||
|
@ -44,7 +44,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <param name="context">GPU context</param>
|
||||
/// <param name="channel">GPU channel</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;
|
||||
_state = state;
|
||||
|
|
|
@ -17,40 +17,56 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
private readonly ResourceCounts _resourceCounts;
|
||||
private readonly int _stageIndex;
|
||||
|
||||
private readonly int _reservedConstantBuffers;
|
||||
private readonly int _reservedStorageBuffers;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new GPU accessor.
|
||||
/// </summary>
|
||||
/// <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;
|
||||
_resourceCounts = resourceCounts;
|
||||
_stageIndex = stageIndex;
|
||||
|
||||
_reservedConstantBuffers = 1; // For the support buffer.
|
||||
_reservedStorageBuffers = !context.Capabilities.SupportsTransformFeedback && tfEnabled ? 5 : 0;
|
||||
}
|
||||
|
||||
public int QueryBindingConstantBuffer(int index)
|
||||
{
|
||||
int binding;
|
||||
|
||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||
{
|
||||
// We need to start counting from 1 since binding 0 is reserved for the support uniform buffer.
|
||||
return GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer") + 1;
|
||||
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer");
|
||||
}
|
||||
else
|
||||
{
|
||||
return _resourceCounts.UniformBuffersCount++;
|
||||
binding = _resourceCounts.UniformBuffersCount++;
|
||||
}
|
||||
|
||||
return binding + _reservedConstantBuffers;
|
||||
}
|
||||
|
||||
public int QueryBindingStorageBuffer(int index)
|
||||
{
|
||||
int binding;
|
||||
|
||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||
{
|
||||
return GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
|
||||
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
|
||||
}
|
||||
else
|
||||
{
|
||||
return _resourceCounts.StorageBuffersCount++;
|
||||
binding = _resourceCounts.StorageBuffersCount++;
|
||||
}
|
||||
|
||||
return binding + _reservedStorageBuffers;
|
||||
}
|
||||
|
||||
public int QueryBindingTexture(int index, bool isBuffer)
|
||||
|
@ -141,10 +157,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
|
||||
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 QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
|
||||
|
||||
public bool QueryHostSupportsTransformFeedback() => _context.Capabilities.SupportsTransformFeedback;
|
||||
|
||||
public bool QueryHostSupportsViewportIndexVertexTessellation() => _context.Capabilities.SupportsViewportIndexVertexTessellation;
|
||||
|
||||
public bool QueryHostSupportsViewportMask() => _context.Capabilities.SupportsViewportMask;
|
||||
|
|
|
@ -24,13 +24,5 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// Total of images used by the shaders.
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
ShaderInfoBuilder infoBuilder = new ShaderInfoBuilder(_context);
|
||||
ShaderInfoBuilder infoBuilder = new ShaderInfoBuilder(_context, transformFeedbackDescriptors != null);
|
||||
|
||||
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 ImageSetIndex = 3;
|
||||
|
||||
private const ResourceStages SupportBufferStags =
|
||||
private const ResourceStages SupportBufferStages =
|
||||
ResourceStages.Compute |
|
||||
ResourceStages.Vertex |
|
||||
ResourceStages.Fragment;
|
||||
|
||||
private const ResourceStages VtgStages =
|
||||
ResourceStages.Vertex |
|
||||
ResourceStages.TessellationControl |
|
||||
ResourceStages.TessellationEvaluation |
|
||||
ResourceStages.Geometry;
|
||||
|
||||
private readonly GpuContext _context;
|
||||
|
||||
private int _fragmentOutputMap;
|
||||
|
||||
private readonly int _reservedConstantBuffers;
|
||||
private readonly int _reservedStorageBuffers;
|
||||
|
||||
private readonly List<ResourceDescriptor>[] _resourceDescriptors;
|
||||
private readonly List<ResourceUsage>[] _resourceUsages;
|
||||
|
||||
|
@ -32,7 +41,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// Creates a new shader info builder.
|
||||
/// </summary>
|
||||
/// <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;
|
||||
|
||||
|
@ -47,7 +57,22 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
_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>
|
||||
|
@ -86,8 +111,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
int texturesPerStage = (int)_context.Capabilities.MaximumTexturesPerStage;
|
||||
int imagesPerStage = (int)_context.Capabilities.MaximumImagesPerStage;
|
||||
|
||||
int uniformBinding = 1 + stageIndex * uniformsPerStage;
|
||||
int storageBinding = stageIndex * storagesPerStage;
|
||||
int uniformBinding = _reservedConstantBuffers + stageIndex * uniformsPerStage;
|
||||
int storageBinding = _reservedStorageBuffers + stageIndex * storagesPerStage;
|
||||
int textureBinding = stageIndex * texturesPerStage * 2;
|
||||
int imageBinding = stageIndex * imagesPerStage * 2;
|
||||
|
||||
|
@ -133,6 +158,23 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
AddDescriptor(stages, type2, setIndex, binding + count, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds buffer usage information to the list of usages.
|
||||
/// </summary>
|
||||
/// <param name="stages">Shader stages where the resource is used</param>
|
||||
/// <param name="type">Type of the resource</param>
|
||||
/// <param name="access">How the resource is accessed by the shader stages where it is used</param>
|
||||
/// <param name="setIndex">Descriptor set number where the resource will be bound</param>
|
||||
/// <param name="binding">Binding number where the resource will be bound</param>
|
||||
/// <param name="count">Number of resources bound at the binding location</param>
|
||||
private void AddUsage(ResourceStages stages, ResourceType type, ResourceAccess access, int setIndex, int binding, int count)
|
||||
{
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
_resourceUsages[setIndex].Add(new ResourceUsage(binding + index, type, stages, access));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds buffer usage information to the list of usages.
|
||||
/// </summary>
|
||||
|
@ -212,10 +254,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <param name="context">GPU context that owns the shaders</param>
|
||||
/// <param name="programs">Shaders from the disk cache</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>
|
||||
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)
|
||||
{
|
||||
|
@ -237,7 +284,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <returns>Shader information</returns>
|
||||
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);
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
public Capabilities GetCapabilities()
|
||||
{
|
||||
bool intelWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows;
|
||||
bool intelUnix = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelUnix;
|
||||
bool amdWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.AmdWindows;
|
||||
|
||||
return new Capabilities(
|
||||
|
@ -152,12 +153,15 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
||||
supportsGeometryShader: true,
|
||||
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
|
||||
supportsTransformFeedback: true,
|
||||
supportsImageLoadFormatted: HwCapabilities.SupportsImageLoadFormatted,
|
||||
supportsLayerVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
||||
supportsMismatchingViewFormat: HwCapabilities.SupportsMismatchingViewFormat,
|
||||
supportsCubemapView: true,
|
||||
supportsNonConstantTextureOffset: HwCapabilities.SupportsNonConstantTextureOffset,
|
||||
supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
|
||||
supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
|
||||
supportsShaderFloat64: true,
|
||||
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
|
||||
supportsViewportIndexVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
||||
supportsViewportMask: HwCapabilities.SupportsViewportArray2,
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
private ulong _accumulatedCounter;
|
||||
private int _waiterCount;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private Queue<BufferedQuery> _queryPool;
|
||||
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
private bool _hostAccessReserved = false;
|
||||
private int _refCount = 1; // Starts with a reference from the counter queue.
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
private ulong _result = ulong.MaxValue;
|
||||
private double _divisor = 1f;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
private const int DisposedLiveFrames = 2;
|
||||
|
||||
private readonly object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new Dictionary<TextureCreateInfo, List<DisposedTexture>>();
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -28,18 +28,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
for (int i = 1; i < info.Functions.Count; i++)
|
||||
{
|
||||
PrintFunction(context, info, info.Functions[i]);
|
||||
PrintFunction(context, info.Functions[i]);
|
||||
|
||||
context.AppendLine();
|
||||
}
|
||||
}
|
||||
|
||||
PrintFunction(context, info, info.Functions[0], MainFunctionName);
|
||||
PrintFunction(context, info.Functions[0], MainFunctionName);
|
||||
|
||||
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;
|
||||
|
||||
|
@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
Declarations.DeclareLocals(context, function);
|
||||
|
||||
PrintBlock(context, function.MainBlock);
|
||||
PrintBlock(context, function.MainBlock, funcName == MainFunctionName);
|
||||
|
||||
context.LeaveScope();
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
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);
|
||||
|
||||
|
@ -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())
|
||||
{
|
||||
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);
|
||||
|
||||
if (expr != null)
|
||||
|
|
|
@ -76,6 +76,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
public SpirvDelegates Delegates { get; }
|
||||
|
||||
public bool IsMainFunction { get; private set; }
|
||||
public bool MayHaveReturned { get; set; }
|
||||
|
||||
public CodeGenContext(
|
||||
StructuredProgramInfo info,
|
||||
ShaderConfig config,
|
||||
|
@ -108,8 +111,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
Delegates = new SpirvDelegates(this);
|
||||
}
|
||||
|
||||
public void StartFunction()
|
||||
public void StartFunction(bool isMainFunction)
|
||||
{
|
||||
IsMainFunction = isMainFunction;
|
||||
MayHaveReturned = false;
|
||||
_locals.Clear();
|
||||
_localForArgs.Clear();
|
||||
_funcArgs.Clear();
|
||||
|
|
|
@ -242,6 +242,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
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.Constant(context.TypeU32(), Scope.Workgroup),
|
||||
context.Constant(context.TypeU32(), Scope.Workgroup),
|
||||
|
@ -1092,6 +1102,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
private static OperationResult GenerateReturn(CodeGenContext context, AstOperation operation)
|
||||
{
|
||||
context.MayHaveReturned = true;
|
||||
|
||||
if (operation.SourcesCount != 0)
|
||||
{
|
||||
context.ReturnValue(context.Get(context.CurrentFunction.ReturnType, operation.GetSource(0)));
|
||||
|
|
|
@ -148,7 +148,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
context.CurrentFunction = function;
|
||||
context.AddFunction(spvFunc);
|
||||
context.StartFunction();
|
||||
context.StartFunction(isMainFunction: funcIndex == 0);
|
||||
|
||||
Declarations.DeclareParameters(context, function);
|
||||
|
||||
|
|
|
@ -10,5 +10,11 @@ namespace Ryujinx.Graphics.Shader
|
|||
public const int NvnBaseVertexByteOffset = 0x640;
|
||||
public const int NvnBaseInstanceByteOffset = 0x644;
|
||||
public const int NvnDrawIndexByteOffset = 0x648;
|
||||
|
||||
// Transform Feedback emulation.
|
||||
|
||||
public const int TfeInfoBinding = 0;
|
||||
public const int TfeBufferBaseBinding = 1;
|
||||
public const int TfeBuffersCount = 4;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,8 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
[Flags]
|
||||
enum InstProps : ushort
|
||||
{
|
||||
None = 0,
|
||||
|
|
|
@ -331,6 +331,24 @@ namespace Ryujinx.Graphics.Shader
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries host GPU shader support for barrier instructions on divergent control flow paths.
|
||||
/// </summary>
|
||||
/// <returns>True if the GPU supports barriers on divergent control flow paths, false otherwise</returns>
|
||||
bool QueryHostSupportsShaderBarrierDivergence()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries host GPU support for 64-bit floating point (double precision) operations on the shader.
|
||||
/// </summary>
|
||||
/// <returns>True if the GPU and driver supports double operations, false otherwise</returns>
|
||||
bool QueryHostSupportsShaderFloat64()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries host GPU support for signed normalized buffer texture formats.
|
||||
/// </summary>
|
||||
|
@ -349,6 +367,15 @@ namespace Ryujinx.Graphics.Shader
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries host GPU transform feedback support.
|
||||
/// </summary>
|
||||
/// <returns>True if the GPU and driver supports transform feedback, false otherwise</returns>
|
||||
bool QueryHostSupportsTransformFeedback()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries host support for writes to the viewport index from vertex or tessellation shader stages.
|
||||
/// </summary>
|
||||
|
|
|
@ -255,5 +255,35 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
|
||||
_sources = new Operand[] { source };
|
||||
}
|
||||
|
||||
public void TurnDoubleIntoFloat()
|
||||
{
|
||||
if ((Inst & ~Instruction.Mask) == Instruction.FP64)
|
||||
{
|
||||
Inst = (Inst & Instruction.Mask) | Instruction.FP32;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Inst)
|
||||
{
|
||||
case Instruction.ConvertFP32ToFP64:
|
||||
case Instruction.ConvertFP64ToFP32:
|
||||
Inst = Instruction.Copy;
|
||||
break;
|
||||
case Instruction.ConvertFP64ToS32:
|
||||
Inst = Instruction.ConvertFP32ToS32;
|
||||
break;
|
||||
case Instruction.ConvertFP64ToU32:
|
||||
Inst = Instruction.ConvertFP32ToU32;
|
||||
break;
|
||||
case Instruction.ConvertS32ToFP64:
|
||||
Inst = Instruction.ConvertS32ToFP32;
|
||||
break;
|
||||
case Instruction.ConvertU32ToFP64:
|
||||
Inst = Instruction.ConvertU32ToFP32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int UnpackTextureId(int packedId)
|
||||
{
|
||||
return (packedId >> 0) & 0xfffff;
|
||||
return packedId & 0xfffff;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
namespace Ryujinx.Graphics.Shader.Translation
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Translation
|
||||
{
|
||||
[Flags]
|
||||
enum AggregateType
|
||||
{
|
||||
Invalid,
|
||||
|
|
|
@ -234,6 +234,45 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
public void PrepareForVertexReturn()
|
||||
{
|
||||
if (!Config.GpuAccessor.QueryHostSupportsTransformFeedback() && Config.GpuAccessor.QueryTransformFeedbackEnabled())
|
||||
{
|
||||
Operand vertexCount = this.Load(StorageKind.StorageBuffer, Constants.TfeInfoBinding, Const(1));
|
||||
|
||||
for (int tfbIndex = 0; tfbIndex < Constants.TfeBuffersCount; tfbIndex++)
|
||||
{
|
||||
var locations = Config.GpuAccessor.QueryTransformFeedbackVaryingLocations(tfbIndex);
|
||||
var stride = Config.GpuAccessor.QueryTransformFeedbackStride(tfbIndex);
|
||||
|
||||
Operand baseOffset = this.Load(StorageKind.StorageBuffer, Constants.TfeInfoBinding, Const(0), Const(tfbIndex));
|
||||
Operand baseVertex = this.Load(StorageKind.Input, IoVariable.BaseVertex);
|
||||
Operand baseInstance = this.Load(StorageKind.Input, IoVariable.BaseInstance);
|
||||
Operand vertexIndex = this.Load(StorageKind.Input, IoVariable.VertexIndex);
|
||||
Operand instanceIndex = this.Load(StorageKind.Input, IoVariable.InstanceIndex);
|
||||
|
||||
Operand outputVertexOffset = this.ISubtract(vertexIndex, baseVertex);
|
||||
Operand outputInstanceOffset = this.ISubtract(instanceIndex, baseInstance);
|
||||
|
||||
Operand outputBaseVertex = this.IMultiply(outputInstanceOffset, vertexCount);
|
||||
|
||||
Operand vertexOffset = this.IMultiply(this.IAdd(outputBaseVertex, outputVertexOffset), Const(stride / 4));
|
||||
baseOffset = this.IAdd(baseOffset, vertexOffset);
|
||||
|
||||
for (int j = 0; j < locations.Length; j++)
|
||||
{
|
||||
byte location = locations[j];
|
||||
if (location == 0xff)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Operand offset = this.IAdd(baseOffset, Const(j));
|
||||
Operand value = Instructions.AttributeMap.GenerateAttributeLoad(this, null, location * 4, isOutput: true, isPerPatch: false);
|
||||
|
||||
this.Store(StorageKind.StorageBuffer, Constants.TfeBufferBaseBinding + tfbIndex, Const(0), offset, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.GpuAccessor.QueryViewportTransformDisable())
|
||||
{
|
||||
Operand x = this.Load(StorageKind.Output, IoVariable.Position, null, Const(0));
|
||||
|
|
|
@ -45,12 +45,101 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
return functionName switch
|
||||
{
|
||||
HelperFunctionName.ConvertDoubleToFloat => GenerateConvertDoubleToFloatFunction(),
|
||||
HelperFunctionName.ConvertFloatToDouble => GenerateConvertFloatToDoubleFunction(),
|
||||
HelperFunctionName.TexelFetchScale => GenerateTexelFetchScaleFunction(),
|
||||
HelperFunctionName.TextureSizeUnscale => GenerateTextureSizeUnscaleFunction(),
|
||||
_ => throw new ArgumentException($"Invalid function name {functionName}")
|
||||
};
|
||||
}
|
||||
|
||||
private Function GenerateConvertDoubleToFloatFunction()
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
|
||||
Operand valueLow = Argument(0);
|
||||
Operand valueHigh = Argument(1);
|
||||
|
||||
Operand mantissaLow = context.BitwiseAnd(valueLow, Const(((1 << 22) - 1)));
|
||||
Operand mantissa = context.ShiftRightU32(valueLow, Const(22));
|
||||
|
||||
mantissa = context.BitwiseOr(mantissa, context.ShiftLeft(context.BitwiseAnd(valueHigh, Const(0xfffff)), Const(10)));
|
||||
mantissa = context.BitwiseOr(mantissa, context.ConditionalSelect(mantissaLow, Const(1), Const(0)));
|
||||
|
||||
Operand exp = context.BitwiseAnd(context.ShiftRightU32(valueHigh, Const(20)), Const(0x7ff));
|
||||
Operand sign = context.ShiftRightS32(valueHigh, Const(31));
|
||||
|
||||
Operand resultSign = context.ShiftLeft(sign, Const(31));
|
||||
|
||||
Operand notZero = context.BitwiseOr(mantissa, exp);
|
||||
|
||||
Operand lblNotZero = Label();
|
||||
|
||||
context.BranchIfTrue(lblNotZero, notZero);
|
||||
|
||||
context.Return(resultSign);
|
||||
|
||||
context.MarkLabel(lblNotZero);
|
||||
|
||||
Operand notNaNOrInf = context.ICompareNotEqual(exp, Const(0x7ff));
|
||||
|
||||
mantissa = context.BitwiseOr(mantissa, Const(0x40000000));
|
||||
exp = context.ISubtract(exp, Const(0x381));
|
||||
|
||||
// Note: Overflow cases are not handled here and might produce incorrect results.
|
||||
|
||||
Operand roundBits = context.BitwiseAnd(mantissa, Const(0x7f));
|
||||
Operand roundBitsXor64 = context.BitwiseExclusiveOr(roundBits, Const(0x40));
|
||||
mantissa = context.ShiftRightU32(context.IAdd(mantissa, Const(0x40)), Const(7));
|
||||
mantissa = context.BitwiseAnd(mantissa, context.ConditionalSelect(roundBitsXor64, Const(~0), Const(~1)));
|
||||
|
||||
exp = context.ConditionalSelect(mantissa, exp, Const(0));
|
||||
exp = context.ConditionalSelect(notNaNOrInf, exp, Const(0xff));
|
||||
|
||||
Operand result = context.IAdd(context.IAdd(mantissa, context.ShiftLeft(exp, Const(23))), resultSign);
|
||||
|
||||
context.Return(result);
|
||||
|
||||
return new Function(ControlFlowGraph.Create(context.GetOperations()).Blocks, "ConvertDoubleToFloat", true, 2, 0);
|
||||
}
|
||||
|
||||
private Function GenerateConvertFloatToDoubleFunction()
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
|
||||
Operand value = Argument(0);
|
||||
|
||||
Operand mantissa = context.BitwiseAnd(value, Const(0x7fffff));
|
||||
Operand exp = context.BitwiseAnd(context.ShiftRightU32(value, Const(23)), Const(0xff));
|
||||
Operand sign = context.ShiftRightS32(value, Const(31));
|
||||
|
||||
Operand notNaNOrInf = context.ICompareNotEqual(exp, Const(0xff));
|
||||
Operand expNotZero = context.ICompareNotEqual(exp, Const(0));
|
||||
Operand notDenorm = context.BitwiseOr(expNotZero, context.ICompareEqual(mantissa, Const(0)));
|
||||
|
||||
exp = context.IAdd(exp, Const(0x380));
|
||||
|
||||
Operand shiftDist = context.ISubtract(Const(32), context.FindMSBU32(mantissa));
|
||||
Operand normExp = context.ISubtract(context.ISubtract(Const(1), shiftDist), Const(1));
|
||||
Operand normMant = context.ShiftLeft(mantissa, shiftDist);
|
||||
|
||||
exp = context.ConditionalSelect(notNaNOrInf, exp, Const(0x7ff));
|
||||
exp = context.ConditionalSelect(notDenorm, exp, normExp);
|
||||
mantissa = context.ConditionalSelect(expNotZero, mantissa, normMant);
|
||||
|
||||
Operand resultLow = context.ShiftLeft(mantissa, Const(29));
|
||||
Operand resultHigh = context.ShiftRightU32(mantissa, Const(3));
|
||||
|
||||
resultHigh = context.IAdd(resultHigh, context.ShiftLeft(exp, Const(20)));
|
||||
resultHigh = context.IAdd(resultHigh, context.ShiftLeft(sign, Const(31)));
|
||||
|
||||
context.Copy(Argument(1), resultLow);
|
||||
context.Copy(Argument(2), resultHigh);
|
||||
context.Return();
|
||||
|
||||
return new Function(ControlFlowGraph.Create(context.GetOperations()).Blocks, "ConvertFloatToDouble", false, 1, 2);
|
||||
}
|
||||
|
||||
private Function GenerateTexelFetchScaleFunction()
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Translation
|
||||
{
|
||||
enum HelperFunctionName
|
||||
{
|
||||
ConvertDoubleToFloat,
|
||||
ConvertFloatToDouble,
|
||||
TexelFetchScale,
|
||||
TextureSizeUnscale
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
{
|
||||
static class DoubleToFloat
|
||||
{
|
||||
public static void RunPass(HelperFunctionManager hfm, BasicBlock block)
|
||||
{
|
||||
for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
|
||||
{
|
||||
if (node.Value is not Operation operation)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
node = InsertSoftFloat64(hfm, node);
|
||||
}
|
||||
}
|
||||
|
||||
private static LinkedListNode<INode> InsertSoftFloat64(HelperFunctionManager hfm, LinkedListNode<INode> node)
|
||||
{
|
||||
Operation operation = (Operation)node.Value;
|
||||
|
||||
if (operation.Inst == Instruction.PackDouble2x32)
|
||||
{
|
||||
int functionId = hfm.GetOrCreateFunctionId(HelperFunctionName.ConvertDoubleToFloat);
|
||||
|
||||
Operand[] callArgs = new Operand[] { Const(functionId), operation.GetSource(0), operation.GetSource(1) };
|
||||
|
||||
Operand floatValue = operation.Dest;
|
||||
|
||||
operation.Dest = null;
|
||||
|
||||
LinkedListNode<INode> newNode = node.List.AddBefore(node, new Operation(Instruction.Call, 0, floatValue, callArgs));
|
||||
|
||||
Utils.DeleteNode(node, operation);
|
||||
|
||||
return newNode;
|
||||
}
|
||||
else if (operation.Inst == Instruction.UnpackDouble2x32)
|
||||
{
|
||||
int functionId = hfm.GetOrCreateFunctionId(HelperFunctionName.ConvertFloatToDouble);
|
||||
|
||||
// TODO: Allow UnpackDouble2x32 to produce two outputs and get rid of "operation.Index".
|
||||
|
||||
Operand resultLow = operation.Index == 0 ? operation.Dest : Local();
|
||||
Operand resultHigh = operation.Index == 1 ? operation.Dest : Local();
|
||||
|
||||
operation.Dest = null;
|
||||
|
||||
Operand[] callArgs = new Operand[] { Const(functionId), operation.GetSource(0), resultLow, resultHigh };
|
||||
|
||||
LinkedListNode<INode> newNode = node.List.AddBefore(node, new Operation(Instruction.Call, 0, (Operand)null, callArgs));
|
||||
|
||||
Utils.DeleteNode(node, operation);
|
||||
|
||||
return newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
operation.TurnDoubleIntoFloat();
|
||||
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,8 +11,12 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
{
|
||||
RunOptimizationPasses(blocks, config);
|
||||
|
||||
// TODO: Some of those are not optimizations and shouldn't be here.
|
||||
|
||||
GlobalToStorage.RunPass(hfm, blocks, config);
|
||||
|
||||
bool hostSupportsShaderFloat64 = config.GpuAccessor.QueryHostSupportsShaderFloat64();
|
||||
|
||||
// Those passes are looking for specific patterns and only needs to run once.
|
||||
for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
|
||||
{
|
||||
|
@ -24,6 +28,12 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
{
|
||||
EliminateMultiplyByFragmentCoordW(blocks[blkIndex]);
|
||||
}
|
||||
|
||||
// If the host does not support double operations, we need to turn them into float operations.
|
||||
if (!hostSupportsShaderFloat64)
|
||||
{
|
||||
DoubleToFloat.RunPass(hfm, blocks[blkIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
// Run optimizations one last time to remove any code that is now optimizable after above passes.
|
||||
|
|
|
@ -132,6 +132,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
_transformFeedbackDefinitions = new Dictionary<TransformFeedbackVariable, TransformFeedbackOutput>();
|
||||
|
||||
TransformFeedbackEnabled =
|
||||
stage != ShaderStage.Compute &&
|
||||
gpuAccessor.QueryTransformFeedbackEnabled() &&
|
||||
gpuAccessor.QueryHostSupportsTransformFeedback();
|
||||
|
||||
UsedInputAttributesPerPatch = new HashSet<int>();
|
||||
UsedOutputAttributesPerPatch = new HashSet<int>();
|
||||
|
||||
|
@ -139,6 +144,31 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
_usedImages = new Dictionary<TextureInfo, TextureMeta>();
|
||||
|
||||
ResourceManager = new ResourceManager(stage, gpuAccessor, new ShaderProperties());
|
||||
|
||||
if (!gpuAccessor.QueryHostSupportsTransformFeedback() && gpuAccessor.QueryTransformFeedbackEnabled())
|
||||
{
|
||||
StructureType tfeInfoStruct = new StructureType(new StructureField[]
|
||||
{
|
||||
new StructureField(AggregateType.Array | AggregateType.U32, "base_offset", 4),
|
||||
new StructureField(AggregateType.U32, "vertex_count")
|
||||
});
|
||||
|
||||
BufferDefinition tfeInfoBuffer = new BufferDefinition(BufferLayout.Std430, 1, Constants.TfeInfoBinding, "tfe_info", tfeInfoStruct);
|
||||
|
||||
Properties.AddStorageBuffer(Constants.TfeInfoBinding, tfeInfoBuffer);
|
||||
|
||||
StructureType tfeDataStruct = new StructureType(new StructureField[]
|
||||
{
|
||||
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0)
|
||||
});
|
||||
|
||||
for (int i = 0; i < Constants.TfeBuffersCount; i++)
|
||||
{
|
||||
int binding = Constants.TfeBufferBaseBinding + i;
|
||||
BufferDefinition tfeDataBuffer = new BufferDefinition(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct);
|
||||
Properties.AddStorageBuffer(binding, tfeDataBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ShaderConfig(
|
||||
|
@ -151,7 +181,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
ThreadsPerInputPrimitive = 1;
|
||||
OutputTopology = outputTopology;
|
||||
MaxOutputVertices = maxOutputVertices;
|
||||
TransformFeedbackEnabled = gpuAccessor.QueryTransformFeedbackEnabled();
|
||||
}
|
||||
|
||||
public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationOptions options) : this(header.Stage, gpuAccessor, options)
|
||||
|
@ -165,7 +194,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
OmapTargets = header.OmapTargets;
|
||||
OmapSampleMask = header.OmapSampleMask;
|
||||
OmapDepth = header.OmapDepth;
|
||||
TransformFeedbackEnabled = gpuAccessor.QueryTransformFeedbackEnabled();
|
||||
LastInVertexPipeline = header.Stage < ShaderStage.Fragment;
|
||||
}
|
||||
|
||||
|
@ -726,7 +754,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
var descriptors = new TextureDescriptor[dict.Count];
|
||||
|
||||
int i = 0;
|
||||
foreach (var kv in dict.OrderBy(x => x.Key.Indexed).OrderBy(x => x.Key.Handle))
|
||||
foreach (var kv in dict.OrderBy(x => x.Key.Indexed).ThenBy(x => x.Key.Handle))
|
||||
{
|
||||
var info = kv.Key;
|
||||
var meta = kv.Value;
|
||||
|
@ -824,4 +852,4 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
OmapTargets);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
_descriptorSets = descriptorSets;
|
||||
}
|
||||
|
||||
public void InitializeBuffers(int setIndex, int baseBinding, int countPerUnit, DescriptorType type, VkBuffer dummyBuffer)
|
||||
public void InitializeBuffers(int setIndex, int baseBinding, int count, DescriptorType type, VkBuffer dummyBuffer)
|
||||
{
|
||||
Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[countPerUnit];
|
||||
Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[count];
|
||||
|
||||
infos.Fill(new DescriptorBufferInfo()
|
||||
{
|
||||
|
|
|
@ -596,36 +596,19 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void Initialize(CommandBufferScoped cbs, int setIndex, DescriptorSetCollection dsc)
|
||||
{
|
||||
// We don't support clearing texture descriptors currently.
|
||||
if (setIndex != PipelineBase.UniformSetIndex && setIndex != PipelineBase.StorageSetIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dummyBuffer = _dummyBuffer?.GetBuffer().Get(cbs).Value ?? default;
|
||||
|
||||
uint stages = _program.Stages;
|
||||
|
||||
while (stages != 0)
|
||||
foreach (ResourceBindingSegment segment in _program.ClearSegments[setIndex])
|
||||
{
|
||||
int stage = BitOperations.TrailingZeroCount(stages);
|
||||
stages &= ~(1u << stage);
|
||||
|
||||
if (setIndex == PipelineBase.UniformSetIndex)
|
||||
{
|
||||
dsc.InitializeBuffers(
|
||||
0,
|
||||
1 + stage * Constants.MaxUniformBuffersPerStage,
|
||||
Constants.MaxUniformBuffersPerStage,
|
||||
DescriptorType.UniformBuffer,
|
||||
dummyBuffer);
|
||||
}
|
||||
else if (setIndex == PipelineBase.StorageSetIndex)
|
||||
{
|
||||
dsc.InitializeBuffers(
|
||||
0,
|
||||
stage * Constants.MaxStorageBuffersPerStage,
|
||||
Constants.MaxStorageBuffersPerStage,
|
||||
DescriptorType.StorageBuffer,
|
||||
dummyBuffer);
|
||||
}
|
||||
dsc.InitializeBuffers(0, segment.Binding, segment.Count, segment.Type.Convert(), dummyBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
public readonly bool SupportsFragmentShaderInterlock;
|
||||
public readonly bool SupportsGeometryShaderPassthrough;
|
||||
public readonly bool SupportsSubgroupSizeControl;
|
||||
public readonly bool SupportsShaderFloat64;
|
||||
public readonly bool SupportsShaderInt8;
|
||||
public readonly bool SupportsShaderStencilExport;
|
||||
public readonly bool SupportsShaderStorageImageMultisample;
|
||||
|
@ -63,6 +64,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
bool supportsFragmentShaderInterlock,
|
||||
bool supportsGeometryShaderPassthrough,
|
||||
bool supportsSubgroupSizeControl,
|
||||
bool supportsShaderFloat64,
|
||||
bool supportsShaderInt8,
|
||||
bool supportsShaderStencilExport,
|
||||
bool supportsShaderStorageImageMultisample,
|
||||
|
@ -99,6 +101,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
||||
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
||||
SupportsSubgroupSizeControl = supportsSubgroupSizeControl;
|
||||
SupportsShaderFloat64 = supportsShaderFloat64;
|
||||
SupportsShaderInt8 = supportsShaderInt8;
|
||||
SupportsShaderStencilExport = supportsShaderStencilExport;
|
||||
SupportsShaderStorageImageMultisample = supportsShaderStorageImageMultisample;
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
{
|
||||
enum MVKConfigLogLevel : int
|
||||
enum MVKConfigLogLevel
|
||||
{
|
||||
None = 0,
|
||||
Error = 1,
|
||||
|
@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
|||
Debug = 4
|
||||
}
|
||||
|
||||
enum MVKConfigTraceVulkanCalls : int
|
||||
enum MVKConfigTraceVulkanCalls
|
||||
{
|
||||
None = 0,
|
||||
Enter = 1,
|
||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
|||
Duration = 3
|
||||
}
|
||||
|
||||
enum MVKConfigAutoGPUCaptureScope : int
|
||||
enum MVKConfigAutoGPUCaptureScope
|
||||
{
|
||||
None = 0,
|
||||
Device = 1,
|
||||
|
@ -28,7 +28,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
|||
}
|
||||
|
||||
[Flags]
|
||||
enum MVKConfigAdvertiseExtensions : int
|
||||
enum MVKConfigAdvertiseExtensions
|
||||
{
|
||||
All = 0x00000001,
|
||||
MoltenVK = 0x00000002,
|
||||
|
@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
|||
Portability = 0x00000008
|
||||
}
|
||||
|
||||
enum MVKVkSemaphoreSupportStyle : int
|
||||
enum MVKVkSemaphoreSupportStyle
|
||||
{
|
||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE = 0,
|
||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE = 1,
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
private uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
||||
private uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
||||
private uint ViewportsCount => (byte)((Id6 >> 54) & 0xFF);
|
||||
private uint ScissorsCount => (byte)((Id7 >> 0) & 0xFF);
|
||||
private uint ScissorsCount => (byte)(Id7 & 0xFF);
|
||||
private uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
||||
private bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||
private ulong _accumulatedCounter;
|
||||
private int _waiterCount;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private Queue<BufferedQuery> _queryPool;
|
||||
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||
private bool _hostAccessReserved = false;
|
||||
private int _refCount = 1; // Starts with a reference from the counter queue.
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
private ulong _result = ulong.MaxValue;
|
||||
private double _divisor = 1f;
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public uint Stages { get; }
|
||||
|
||||
public ResourceBindingSegment[][] ClearSegments { get; }
|
||||
public ResourceBindingSegment[][] BindingSegments { get; }
|
||||
|
||||
public ProgramLinkStatus LinkStatus { get; private set; }
|
||||
|
@ -115,6 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
Stages = stages;
|
||||
|
||||
ClearSegments = BuildClearSegments(resourceLayout.Sets);
|
||||
BindingSegments = BuildBindingSegments(resourceLayout.SetUsages);
|
||||
|
||||
_compileTask = Task.CompletedTask;
|
||||
|
@ -135,6 +137,60 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
_firstBackgroundUse = !fromCache;
|
||||
}
|
||||
|
||||
private static ResourceBindingSegment[][] BuildClearSegments(ReadOnlyCollection<ResourceDescriptorCollection> sets)
|
||||
{
|
||||
ResourceBindingSegment[][] segments = new ResourceBindingSegment[sets.Count][];
|
||||
|
||||
for (int setIndex = 0; setIndex < sets.Count; setIndex++)
|
||||
{
|
||||
List<ResourceBindingSegment> currentSegments = new List<ResourceBindingSegment>();
|
||||
|
||||
ResourceDescriptor currentDescriptor = default;
|
||||
int currentCount = 0;
|
||||
|
||||
for (int index = 0; index < sets[setIndex].Descriptors.Count; index++)
|
||||
{
|
||||
ResourceDescriptor descriptor = sets[setIndex].Descriptors[index];
|
||||
|
||||
if (currentDescriptor.Binding + currentCount != descriptor.Binding ||
|
||||
currentDescriptor.Type != descriptor.Type ||
|
||||
currentDescriptor.Stages != descriptor.Stages)
|
||||
{
|
||||
if (currentCount != 0)
|
||||
{
|
||||
currentSegments.Add(new ResourceBindingSegment(
|
||||
currentDescriptor.Binding,
|
||||
currentCount,
|
||||
currentDescriptor.Type,
|
||||
currentDescriptor.Stages,
|
||||
ResourceAccess.ReadWrite));
|
||||
}
|
||||
|
||||
currentDescriptor = descriptor;
|
||||
currentCount = descriptor.Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentCount += descriptor.Count;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentCount != 0)
|
||||
{
|
||||
currentSegments.Add(new ResourceBindingSegment(
|
||||
currentDescriptor.Binding,
|
||||
currentCount,
|
||||
currentDescriptor.Type,
|
||||
currentDescriptor.Stages,
|
||||
ResourceAccess.ReadWrite));
|
||||
}
|
||||
|
||||
segments[setIndex] = currentSegments.ToArray();
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
private static ResourceBindingSegment[][] BuildBindingSegments(ReadOnlyCollection<ResourceUsageCollection> setUsages)
|
||||
{
|
||||
ResourceBindingSegment[][] segments = new ResourceBindingSegment[setUsages.Count][];
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue