Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
a6a67a2b7a | |||
c6d05301aa | |||
647de4cd31 | |||
f82309fa2d | |||
7d8e198c33 | |||
3d98e1361b | |||
141cf61ff7 | |||
3fe3598d41 | |||
59cdf310bd | |||
4e34170a84 | |||
d540af5dc0 | |||
f7c7b66fc0 | |||
28ba55598d | |||
9719b6a112 | |||
f70236f947 | |||
eafadf10c7 | |||
9b06ee7736 | |||
baba2c2467 | |||
286e5d39b2 | |||
dc529c1181 | |||
c7cf1cbc35 | |||
d8e487d018 | |||
5fdc46ac7f | |||
1e5b45f580 | |||
62585755fd | |||
56621615b1 | |||
2099a3e84b | |||
7d26e4ac7b | |||
8d41402fa6 |
24
.github/dependabot.yml
vendored
Normal file
24
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
labels:
|
||||||
|
- "infra"
|
||||||
|
reviewers:
|
||||||
|
- marysaka
|
||||||
|
commit-message:
|
||||||
|
prefix: "ci"
|
||||||
|
|
||||||
|
- package-ecosystem: nuget
|
||||||
|
directory: /
|
||||||
|
open-pull-requests-limit: 5
|
||||||
|
schedule:
|
||||||
|
interval: daily
|
||||||
|
labels:
|
||||||
|
- "infra"
|
||||||
|
reviewers:
|
||||||
|
- marysaka
|
||||||
|
commit-message:
|
||||||
|
prefix: nuget
|
17
.github/workflows/build.yml
vendored
17
.github/workflows/build.yml
vendored
@ -48,21 +48,22 @@ jobs:
|
|||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
RYUJINX_BASE_VERSION: "1.1.0"
|
RYUJINX_BASE_VERSION: "1.1.0"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-dotnet@v1
|
- uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 6.0.x
|
dotnet-version: 7.0.x
|
||||||
- name: Ensure NuGet Source
|
- name: Ensure NuGet Source
|
||||||
uses: fabriciomurta/ensure-nuget-source@v1
|
uses: fabriciomurta/ensure-nuget-source@v1
|
||||||
- name: Get git short hash
|
- name: Get git short hash
|
||||||
id: git_short_hash
|
id: git_short_hash
|
||||||
run: echo "::set-output name=result::$(git rev-parse --short "${{ github.sha }}")"
|
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
- name: Clear
|
- name: Clear
|
||||||
run: dotnet clean && dotnet nuget locals all --clear
|
run: dotnet clean && dotnet nuget locals all --clear
|
||||||
- name: Build
|
- name: Build
|
||||||
run: dotnet build -c "${{ matrix.configuration }}" /p:Version="${{ env.RYUJINX_BASE_VERSION }}" /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER
|
run: dotnet build -c "${{ matrix.configuration }}" /p:Version="${{ env.RYUJINX_BASE_VERSION }}" /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER
|
||||||
- name: Test
|
- name: Test
|
||||||
run: dotnet test -c "${{ matrix.configuration }}"
|
run: dotnet test --no-build -c "${{ matrix.configuration }}"
|
||||||
- name: Publish Ryujinx
|
- name: Publish Ryujinx
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish /p:Version="${{ env.RYUJINX_BASE_VERSION }}" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx --self-contained
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish /p:Version="${{ env.RYUJINX_BASE_VERSION }}" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx --self-contained
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
@ -73,19 +74,19 @@ jobs:
|
|||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava /p:Version="1.0.0" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Ava
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava /p:Version="1.0.0" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Ava
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
- name: Upload Ryujinx artifact
|
- name: Upload Ryujinx artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
||||||
path: publish
|
path: publish
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
- name: Upload Ryujinx.Headless.SDL2 artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
||||||
path: publish_sdl2_headless
|
path: publish_sdl2_headless
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
- name: Upload Ryujinx.Ava artifact
|
- name: Upload Ryujinx.Ava artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
||||||
path: publish_ava
|
path: publish_ava
|
||||||
|
12
.github/workflows/nightly_pr_comment.yml
vendored
12
.github/workflows/nightly_pr_comment.yml
vendored
@ -8,7 +8,7 @@ jobs:
|
|||||||
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
|
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/github-script@v3
|
- uses: actions/github-script@v6
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const {owner, repo} = context.repo;
|
const {owner, repo} = context.repo;
|
||||||
@ -16,7 +16,7 @@ jobs:
|
|||||||
const pull_head_sha = '${{github.event.workflow_run.head_sha}}';
|
const pull_head_sha = '${{github.event.workflow_run.head_sha}}';
|
||||||
|
|
||||||
const issue_number = await (async () => {
|
const issue_number = await (async () => {
|
||||||
const pulls = await github.pulls.list({owner, repo});
|
const pulls = await github.rest.pulls.list({owner, repo});
|
||||||
for await (const {data} of github.paginate.iterator(pulls)) {
|
for await (const {data} of github.paginate.iterator(pulls)) {
|
||||||
for (const pull of data) {
|
for (const pull of data) {
|
||||||
if (pull.head.sha === pull_head_sha) {
|
if (pull.head.sha === pull_head_sha) {
|
||||||
@ -31,7 +31,7 @@ jobs:
|
|||||||
return core.error(`No matching pull request found`);
|
return core.error(`No matching pull request found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {data: {artifacts}} = await github.actions.listWorkflowRunArtifacts({owner, repo, run_id});
|
const {data: {artifacts}} = await github.rest.actions.listWorkflowRunArtifacts({owner, repo, run_id});
|
||||||
if (!artifacts.length) {
|
if (!artifacts.length) {
|
||||||
return core.error(`No artifacts found`);
|
return core.error(`No artifacts found`);
|
||||||
}
|
}
|
||||||
@ -57,12 +57,12 @@ jobs:
|
|||||||
body += hidden_headless_artifacts;
|
body += hidden_headless_artifacts;
|
||||||
body += hidden_debug_artifacts;
|
body += hidden_debug_artifacts;
|
||||||
|
|
||||||
const {data: comments} = await github.issues.listComments({repo, owner, issue_number});
|
const {data: comments} = await github.rest.issues.listComments({repo, owner, issue_number});
|
||||||
const existing_comment = comments.find((c) => c.user.login === 'github-actions[bot]');
|
const existing_comment = comments.find((c) => c.user.login === 'github-actions[bot]');
|
||||||
if (existing_comment) {
|
if (existing_comment) {
|
||||||
core.info(`Updating comment ${existing_comment.id}`);
|
core.info(`Updating comment ${existing_comment.id}`);
|
||||||
await github.issues.updateComment({repo, owner, comment_id: existing_comment.id, body});
|
await github.rest.issues.updateComment({repo, owner, comment_id: existing_comment.id, body});
|
||||||
} else {
|
} else {
|
||||||
core.info(`Creating a comment`);
|
core.info(`Creating a comment`);
|
||||||
await github.issues.createComment({repo, owner, issue_number, body});
|
await github.rest.issues.createComment({repo, owner, issue_number, body});
|
||||||
}
|
}
|
||||||
|
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@ -25,10 +25,10 @@ jobs:
|
|||||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "release-channel-master"
|
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "release-channel-master"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-dotnet@v1
|
- uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 6.0.x
|
dotnet-version: 7.0.x
|
||||||
- name: Ensure NuGet Source
|
- name: Ensure NuGet Source
|
||||||
uses: fabriciomurta/ensure-nuget-source@v1
|
uses: fabriciomurta/ensure-nuget-source@v1
|
||||||
- name: Clear
|
- name: Clear
|
||||||
@ -36,8 +36,8 @@ jobs:
|
|||||||
- name: Get version info
|
- name: Get version info
|
||||||
id: version_info
|
id: version_info
|
||||||
run: |
|
run: |
|
||||||
echo "::set-output name=build_version::${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}"
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
echo "::set-output name=git_short_hash::$(git rev-parse --short "${{ github.sha }}")"
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
shell: bash
|
shell: bash
|
||||||
- name: Configure for release
|
- name: Configure for release
|
||||||
run: |
|
run: |
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
44
ARMeilleure/Decoders/OpCode32SimdCvtTB.cs
Normal file
44
ARMeilleure/Decoders/OpCode32SimdCvtTB.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
class OpCode32SimdCvtTB : OpCode32, IOpCode32Simd
|
||||||
|
{
|
||||||
|
public int Vd { get; }
|
||||||
|
public int Vm { get; }
|
||||||
|
public bool Op { get; } // Convert to Half / Convert from Half
|
||||||
|
public bool T { get; } // Top / Bottom
|
||||||
|
public int Size { get; } // Double / Single
|
||||||
|
|
||||||
|
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtTB(inst, address, opCode, false);
|
||||||
|
public static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtTB(inst, address, opCode, true);
|
||||||
|
|
||||||
|
public OpCode32SimdCvtTB(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
|
||||||
|
{
|
||||||
|
IsThumb = isThumb;
|
||||||
|
|
||||||
|
Op = ((opCode >> 16) & 0x1) != 0;
|
||||||
|
T = ((opCode >> 7) & 0x1) != 0;
|
||||||
|
Size = ((opCode >> 8) & 0x1);
|
||||||
|
|
||||||
|
RegisterSize = Size == 1 ? RegisterSize.Int64 : RegisterSize.Int32;
|
||||||
|
|
||||||
|
if (Size == 1)
|
||||||
|
{
|
||||||
|
if (Op)
|
||||||
|
{
|
||||||
|
Vm = ((opCode >> 1) & 0x10) | ((opCode >> 0) & 0xf);
|
||||||
|
Vd = ((opCode >> 22) & 0x1) | ((opCode >> 11) & 0x1e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vm = ((opCode >> 5) & 0x1) | ((opCode << 1) & 0x1e);
|
||||||
|
Vd = ((opCode >> 18) & 0x10) | ((opCode >> 12) & 0xf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vm = ((opCode >> 5) & 0x1) | ((opCode << 1) & 0x1e);
|
||||||
|
Vd = ((opCode >> 22) & 0x1) | ((opCode >> 11) & 0x1e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -828,6 +828,7 @@ namespace ARMeilleure.Decoders
|
|||||||
SetVfp("<<<<11101x11110xxxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create, OpCode32SimdCvtFI.CreateT32); // FP32 to int.
|
SetVfp("<<<<11101x11110xxxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create, OpCode32SimdCvtFI.CreateT32); // FP32 to int.
|
||||||
SetVfp("<<<<11101x111000xxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create, OpCode32SimdCvtFI.CreateT32); // Int to FP32.
|
SetVfp("<<<<11101x111000xxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create, OpCode32SimdCvtFI.CreateT32); // Int to FP32.
|
||||||
SetVfp("111111101x1111xxxxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_RM, OpCode32SimdCvtFI.Create, OpCode32SimdCvtFI.CreateT32); // The many FP32 to int encodings (fp).
|
SetVfp("111111101x1111xxxxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_RM, OpCode32SimdCvtFI.Create, OpCode32SimdCvtFI.CreateT32); // The many FP32 to int encodings (fp).
|
||||||
|
SetVfp("<<<<11101x11001xxxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_TB, OpCode32SimdCvtTB.Create, OpCode32SimdCvtTB.CreateT32);
|
||||||
SetVfp("<<<<11101x00xxxxxxxx101xx0x0xxxx", InstName.Vdiv, InstEmit32.Vdiv_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
SetVfp("<<<<11101x00xxxxxxxx101xx0x0xxxx", InstName.Vdiv, InstEmit32.Vdiv_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||||
SetVfp("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, OpCode32SimdDupGP.Create, OpCode32SimdDupGP.CreateT32);
|
SetVfp("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, OpCode32SimdDupGP.Create, OpCode32SimdDupGP.CreateT32);
|
||||||
SetVfp("<<<<11101x10xxxxxxxx101xx0x0xxxx", InstName.Vfma, InstEmit32.Vfma_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
SetVfp("<<<<11101x10xxxxxxxx101xx0x0xxxx", InstName.Vfma, InstEmit32.Vfma_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||||
|
@ -261,6 +261,74 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Vcvt_TB(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
OpCode32SimdCvtTB op = (OpCode32SimdCvtTB)context.CurrOp;
|
||||||
|
|
||||||
|
if (Optimizations.UseF16c)
|
||||||
|
{
|
||||||
|
Debug.Assert(!Optimizations.ForceLegacySse);
|
||||||
|
|
||||||
|
if (op.Op)
|
||||||
|
{
|
||||||
|
Operand res = ExtractScalar(context, op.Size == 1 ? OperandType.FP64 : OperandType.FP32, op.Vm);
|
||||||
|
if (op.Size == 1)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.X86Cvtsd2ss, context.VectorZero(), res);
|
||||||
|
}
|
||||||
|
res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest)));
|
||||||
|
res = context.VectorExtract16(res, 0);
|
||||||
|
InsertScalar16(context, op.Vd, op.T, res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Operand res = context.VectorCreateScalar(ExtractScalar16(context, op.Vm, op.T));
|
||||||
|
res = context.AddIntrinsic(Intrinsic.X86Vcvtph2ps, res);
|
||||||
|
if (op.Size == 1)
|
||||||
|
{
|
||||||
|
res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res);
|
||||||
|
}
|
||||||
|
res = context.VectorExtract(op.Size == 1 ? OperandType.I64 : OperandType.I32, res, 0);
|
||||||
|
InsertScalar(context, op.Vd, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (op.Op)
|
||||||
|
{
|
||||||
|
// Convert to half.
|
||||||
|
|
||||||
|
Operand src = ExtractScalar(context, op.Size == 1 ? OperandType.FP64 : OperandType.FP32, op.Vm);
|
||||||
|
|
||||||
|
MethodInfo method = op.Size == 1
|
||||||
|
? typeof(SoftFloat64_16).GetMethod(nameof(SoftFloat64_16.FPConvert))
|
||||||
|
: typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert));
|
||||||
|
|
||||||
|
context.StoreToContext();
|
||||||
|
Operand res = context.Call(method, src);
|
||||||
|
context.LoadFromContext();
|
||||||
|
|
||||||
|
InsertScalar16(context, op.Vd, op.T, res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Convert from half.
|
||||||
|
|
||||||
|
Operand src = ExtractScalar16(context, op.Vm, op.T);
|
||||||
|
|
||||||
|
MethodInfo method = op.Size == 1
|
||||||
|
? typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert))
|
||||||
|
: typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert));
|
||||||
|
|
||||||
|
context.StoreToContext();
|
||||||
|
Operand res = context.Call(method, src);
|
||||||
|
context.LoadFromContext();
|
||||||
|
|
||||||
|
InsertScalar(context, op.Vd, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// VRINTA/M/N/P (floating-point).
|
// VRINTA/M/N/P (floating-point).
|
||||||
public static void Vrint_RM(ArmEmitterContext context)
|
public static void Vrint_RM(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
|
@ -70,6 +70,22 @@ namespace ARMeilleure.Instructions
|
|||||||
context.Copy(vec, insert);
|
context.Copy(vec, insert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Operand ExtractScalar16(ArmEmitterContext context, int reg, bool top)
|
||||||
|
{
|
||||||
|
return context.VectorExtract16(GetVecA32(reg >> 2), ((reg & 3) << 1) | (top ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InsertScalar16(ArmEmitterContext context, int reg, bool top, Operand value)
|
||||||
|
{
|
||||||
|
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.I32);
|
||||||
|
|
||||||
|
Operand vec, insert;
|
||||||
|
vec = GetVecA32(reg >> 2);
|
||||||
|
insert = context.VectorInsert16(vec, value, ((reg & 3) << 1) | (top ? 1 : 0));
|
||||||
|
|
||||||
|
context.Copy(vec, insert);
|
||||||
|
}
|
||||||
|
|
||||||
public static Operand ExtractElement(ArmEmitterContext context, int reg, int size, bool signed)
|
public static Operand ExtractElement(ArmEmitterContext context, int reg, int size, bool signed)
|
||||||
{
|
{
|
||||||
return EmitVectorExtract32(context, reg >> (4 - size), reg & ((16 >> size) - 1), size, signed);
|
return EmitVectorExtract32(context, reg >> (4 - size), reg & ((16 >> size) - 1), size, signed);
|
||||||
|
@ -455,13 +455,16 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
public void InvalidateJitCacheRegion(ulong address, ulong size)
|
public void InvalidateJitCacheRegion(ulong address, ulong size)
|
||||||
{
|
{
|
||||||
// If rejit is running, stop it as it may be trying to rejit a function on the invalidated region.
|
|
||||||
ClearRejitQueue(allowRequeue: true);
|
|
||||||
|
|
||||||
ulong[] overlapAddresses = Array.Empty<ulong>();
|
ulong[] overlapAddresses = Array.Empty<ulong>();
|
||||||
|
|
||||||
int overlapsCount = Functions.GetOverlaps(address, size, ref overlapAddresses);
|
int overlapsCount = Functions.GetOverlaps(address, size, ref overlapAddresses);
|
||||||
|
|
||||||
|
if (overlapsCount != 0)
|
||||||
|
{
|
||||||
|
// If rejit is running, stop it as it may be trying to rejit a function on the invalidated region.
|
||||||
|
ClearRejitQueue(allowRequeue: true);
|
||||||
|
}
|
||||||
|
|
||||||
for (int index = 0; index < overlapsCount; index++)
|
for (int index = 0; index < overlapsCount; index++)
|
||||||
{
|
{
|
||||||
ulong overlapAddress = overlapAddresses[index];
|
ulong overlapAddress = overlapAddresses[index];
|
||||||
|
@ -36,8 +36,8 @@
|
|||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
As of October 2022, Ryujinx has been tested on approximately 3,600 titles; over 3,500 boot past menus and into gameplay, with roughly 3,000 of those being considered playable. You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues).
|
As of October 2022, Ryujinx has been tested on approximately 3,700 titles; over 3,500 boot past menus and into gameplay, with roughly 3,000 of those being considered playable.
|
||||||
Anyone is free to submit a new game test or update an existing game test entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already!
|
You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues). Anyone is free to submit a new game test or update an existing game test entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already!
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ The latest automatic build for Windows, macOS, and Linux can be found on the [Of
|
|||||||
If you wish to build the emulator yourself, follow these steps:
|
If you wish to build the emulator yourself, follow these steps:
|
||||||
|
|
||||||
### Step 1
|
### Step 1
|
||||||
Install the X64 version of [.NET 6.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/6.0).
|
Install the X64 version of [.NET 7.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/7.0).
|
||||||
|
|
||||||
### Step 2
|
### Step 2
|
||||||
Either use `git clone https://github.com/Ryujinx/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
Either use `git clone https://github.com/Ryujinx/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
||||||
@ -90,7 +90,7 @@ Ryujinx system files are stored in the `Ryujinx` folder. This folder is located
|
|||||||
|
|
||||||
- **GPU**
|
- **GPU**
|
||||||
|
|
||||||
The GPU emulator emulates the Switch's Maxwell GPU using the OpenGL API (version 4.5 minimum) through a custom build of OpenTK. There are currently four graphics enhancements available to the end user in Ryujinx: disk shader caching, resolution scaling, aspect ratio adjustment and anisotropic filtering. These enhancements can be adjusted or toggled as desired in the GUI.
|
The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum) or Vulkan APIs through a custom build of OpenTK or Silk.NET respectively. There are currently four graphics enhancements available to the end user in Ryujinx: Disk Shader Caching, Resolution Scaling, Aspect Ratio Adjustment, and Anisotropic Filtering. These enhancements can be adjusted or toggled as desired in the GUI.
|
||||||
|
|
||||||
- **Input**
|
- **Input**
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<RuntimeIdentifiers>win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -150,7 +150,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="inputHeader">The splitter header.</param>
|
/// <param name="inputHeader">The splitter header.</param>
|
||||||
/// <param name="input">The raw data after the splitter header.</param>
|
/// <param name="input">The raw data after the splitter header.</param>
|
||||||
private void UpdateState(ref SplitterInParameterHeader inputHeader, ref ReadOnlySpan<byte> input)
|
private void UpdateState(scoped ref SplitterInParameterHeader inputHeader, ref ReadOnlySpan<byte> input)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < inputHeader.SplitterCount; i++)
|
for (int i = 0; i < inputHeader.SplitterCount; i++)
|
||||||
{
|
{
|
||||||
@ -177,7 +177,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="inputHeader">The splitter header.</param>
|
/// <param name="inputHeader">The splitter header.</param>
|
||||||
/// <param name="input">The raw data after the splitter header.</param>
|
/// <param name="input">The raw data after the splitter header.</param>
|
||||||
private void UpdateData(ref SplitterInParameterHeader inputHeader, ref ReadOnlySpan<byte> input)
|
private void UpdateData(scoped ref SplitterInParameterHeader inputHeader, ref ReadOnlySpan<byte> input)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < inputHeader.SplitterDestinationCount; i++)
|
for (int i = 0; i < inputHeader.SplitterDestinationCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -49,8 +49,8 @@
|
|||||||
"GameListContextMenuManageTitleUpdatesToolTip": "Apre la finestra di gestione aggiornamenti del gioco",
|
"GameListContextMenuManageTitleUpdatesToolTip": "Apre la finestra di gestione aggiornamenti del gioco",
|
||||||
"GameListContextMenuManageDlc": "Gestici DLC",
|
"GameListContextMenuManageDlc": "Gestici DLC",
|
||||||
"GameListContextMenuManageDlcToolTip": "Apre la finestra di gestione DLC",
|
"GameListContextMenuManageDlcToolTip": "Apre la finestra di gestione DLC",
|
||||||
"GameListContextMenuOpenModsDirectory": "Apri cartella delle mods",
|
"GameListContextMenuOpenModsDirectory": "Apri cartella delle mod",
|
||||||
"GameListContextMenuOpenModsDirectoryToolTip": "Apre la cartella che contiene le mods dell'applicazione",
|
"GameListContextMenuOpenModsDirectoryToolTip": "Apre la cartella che contiene le mod dell'applicazione",
|
||||||
"GameListContextMenuCacheManagement": "Gestione della cache",
|
"GameListContextMenuCacheManagement": "Gestione della cache",
|
||||||
"GameListContextMenuCacheManagementPurgePptc": "Pulisci PPTC cache",
|
"GameListContextMenuCacheManagementPurgePptc": "Pulisci PPTC cache",
|
||||||
"GameListContextMenuCacheManagementPurgePptcToolTip": "Elimina la PPTC cache dell'applicazione",
|
"GameListContextMenuCacheManagementPurgePptcToolTip": "Elimina la PPTC cache dell'applicazione",
|
||||||
@ -81,7 +81,7 @@
|
|||||||
"SettingsTabGeneralRemove": "Rimuovi",
|
"SettingsTabGeneralRemove": "Rimuovi",
|
||||||
"SettingsTabSystem": "Sistema",
|
"SettingsTabSystem": "Sistema",
|
||||||
"SettingsTabSystemCore": "Core",
|
"SettingsTabSystemCore": "Core",
|
||||||
"SettingsTabSystemSystemRegion": "Regione di sistema:",
|
"SettingsTabSystemSystemRegion": "Regione del sistema:",
|
||||||
"SettingsTabSystemSystemRegionJapan": "Giappone",
|
"SettingsTabSystemSystemRegionJapan": "Giappone",
|
||||||
"SettingsTabSystemSystemRegionUSA": "Stati Uniti d'America",
|
"SettingsTabSystemSystemRegionUSA": "Stati Uniti d'America",
|
||||||
"SettingsTabSystemSystemRegionEurope": "Europa",
|
"SettingsTabSystemSystemRegionEurope": "Europa",
|
||||||
@ -89,7 +89,7 @@
|
|||||||
"SettingsTabSystemSystemRegionChina": "Cina",
|
"SettingsTabSystemSystemRegionChina": "Cina",
|
||||||
"SettingsTabSystemSystemRegionKorea": "Corea",
|
"SettingsTabSystemSystemRegionKorea": "Corea",
|
||||||
"SettingsTabSystemSystemRegionTaiwan": "Taiwan",
|
"SettingsTabSystemSystemRegionTaiwan": "Taiwan",
|
||||||
"SettingsTabSystemSystemLanguage": "Lingua di sistema:",
|
"SettingsTabSystemSystemLanguage": "Lingua del sistema:",
|
||||||
"SettingsTabSystemSystemLanguageJapanese": "Giapponese",
|
"SettingsTabSystemSystemLanguageJapanese": "Giapponese",
|
||||||
"SettingsTabSystemSystemLanguageAmericanEnglish": "Inglese americano",
|
"SettingsTabSystemSystemLanguageAmericanEnglish": "Inglese americano",
|
||||||
"SettingsTabSystemSystemLanguageFrench": "Francese",
|
"SettingsTabSystemSystemLanguageFrench": "Francese",
|
||||||
@ -107,8 +107,8 @@
|
|||||||
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Spagnolo latino americano",
|
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Spagnolo latino americano",
|
||||||
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Cinese semplificato",
|
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Cinese semplificato",
|
||||||
"SettingsTabSystemSystemLanguageTraditionalChinese": "Cinese tradizionale",
|
"SettingsTabSystemSystemLanguageTraditionalChinese": "Cinese tradizionale",
|
||||||
"SettingsTabSystemSystemTimeZone": "Fuso orario di sistema:",
|
"SettingsTabSystemSystemTimeZone": "Fuso orario del sistema:",
|
||||||
"SettingsTabSystemSystemTime": "Data e ora di sistema:",
|
"SettingsTabSystemSystemTime": "Data e ora del sistema:",
|
||||||
"SettingsTabSystemEnableVsync": "Attiva VSync",
|
"SettingsTabSystemEnableVsync": "Attiva VSync",
|
||||||
"SettingsTabSystemEnablePptc": "Attiva PPTC (Profiled Persistent Translation Cache)",
|
"SettingsTabSystemEnablePptc": "Attiva PPTC (Profiled Persistent Translation Cache)",
|
||||||
"SettingsTabSystemEnableFsIntegrityChecks": "Attiva controlli d'integrità FS",
|
"SettingsTabSystemEnableFsIntegrityChecks": "Attiva controlli d'integrità FS",
|
||||||
@ -155,7 +155,7 @@
|
|||||||
"SettingsTabLoggingEnableTraceLogs": "Attiva Trace Logs",
|
"SettingsTabLoggingEnableTraceLogs": "Attiva Trace Logs",
|
||||||
"SettingsTabLoggingEnableGuestLogs": "Attiva Guest Logs",
|
"SettingsTabLoggingEnableGuestLogs": "Attiva Guest Logs",
|
||||||
"SettingsTabLoggingEnableFsAccessLogs": "Attiva Fs Access Logs",
|
"SettingsTabLoggingEnableFsAccessLogs": "Attiva Fs Access Logs",
|
||||||
"SettingsTabLoggingFsGlobalAccessLogMode": "Modalità di log accesso globale Fs:",
|
"SettingsTabLoggingFsGlobalAccessLogMode": "Modalità log accesso globale Fs:",
|
||||||
"SettingsTabLoggingDeveloperOptions": "Opzioni da sviluppatore (AVVISO: Ridurrà le prestazioni)",
|
"SettingsTabLoggingDeveloperOptions": "Opzioni da sviluppatore (AVVISO: Ridurrà le prestazioni)",
|
||||||
"SettingsTabLoggingOpenglLogLevel": "Livello di log OpenGL:",
|
"SettingsTabLoggingOpenglLogLevel": "Livello di log OpenGL:",
|
||||||
"SettingsTabLoggingOpenglLogLevelNone": "Nessuno",
|
"SettingsTabLoggingOpenglLogLevelNone": "Nessuno",
|
||||||
@ -240,7 +240,7 @@
|
|||||||
"ControllerSettingsRightSR": "SR",
|
"ControllerSettingsRightSR": "SR",
|
||||||
"ControllerSettingsExtraButtonsLeft": "Tasto sinitro",
|
"ControllerSettingsExtraButtonsLeft": "Tasto sinitro",
|
||||||
"ControllerSettingsExtraButtonsRight": "Tasto destro",
|
"ControllerSettingsExtraButtonsRight": "Tasto destro",
|
||||||
"ControllerSettingsMisc": "Miscellanee",
|
"ControllerSettingsMisc": "Varie",
|
||||||
"ControllerSettingsTriggerThreshold": "Sensibilità dei grilletti:",
|
"ControllerSettingsTriggerThreshold": "Sensibilità dei grilletti:",
|
||||||
"ControllerSettingsMotion": "Movimento",
|
"ControllerSettingsMotion": "Movimento",
|
||||||
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "Usa sensore compatibile con CemuHook",
|
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "Usa sensore compatibile con CemuHook",
|
||||||
@ -261,7 +261,7 @@
|
|||||||
"UserProfilesClose": "Chiudi",
|
"UserProfilesClose": "Chiudi",
|
||||||
"ProfileImageSelectionTitle": "Selezione dell'immagine profilo",
|
"ProfileImageSelectionTitle": "Selezione dell'immagine profilo",
|
||||||
"ProfileImageSelectionHeader": "Scegli un'immagine profilo",
|
"ProfileImageSelectionHeader": "Scegli un'immagine profilo",
|
||||||
"ProfileImageSelectionNote": "Puoi importare un'immagine profilo personalizzata o selezionare un avatar dal firmware di sistema",
|
"ProfileImageSelectionNote": "Puoi importare un'immagine profilo personalizzata o selezionare un avatar dal firmware del sistema",
|
||||||
"ProfileImageSelectionImportImage": "Importa file immagine",
|
"ProfileImageSelectionImportImage": "Importa file immagine",
|
||||||
"ProfileImageSelectionSelectAvatar": "Seleziona avatar dal firmware",
|
"ProfileImageSelectionSelectAvatar": "Seleziona avatar dal firmware",
|
||||||
"InputDialogTitle": "Input Dialog",
|
"InputDialogTitle": "Input Dialog",
|
||||||
@ -293,7 +293,7 @@
|
|||||||
"ControllerSettingsRumbleStrongMultiplier": "Moltiplicatore vibrazione forte",
|
"ControllerSettingsRumbleStrongMultiplier": "Moltiplicatore vibrazione forte",
|
||||||
"ControllerSettingsRumbleWeakMultiplier": "Moltiplicatore vibrazione debole",
|
"ControllerSettingsRumbleWeakMultiplier": "Moltiplicatore vibrazione debole",
|
||||||
"DialogMessageSaveNotAvailableMessage": "Non ci sono dati di salvataggio per {0} [{1:x16}]",
|
"DialogMessageSaveNotAvailableMessage": "Non ci sono dati di salvataggio per {0} [{1:x16}]",
|
||||||
"DialogMessageSaveNotAvailableCreateSaveMessage": "Vuoi creare dei dat di salvataggio per questo gioco?",
|
"DialogMessageSaveNotAvailableCreateSaveMessage": "Vuoi creare dei dati di salvataggio per questo gioco?",
|
||||||
"DialogConfirmationTitle": "Ryujinx - Conferma",
|
"DialogConfirmationTitle": "Ryujinx - Conferma",
|
||||||
"DialogUpdaterTitle": "Ryujinx - Updater",
|
"DialogUpdaterTitle": "Ryujinx - Updater",
|
||||||
"DialogErrorTitle": "Ryujinx - Errore",
|
"DialogErrorTitle": "Ryujinx - Errore",
|
||||||
@ -318,7 +318,7 @@
|
|||||||
"DialogUpdaterDownloadingMessage": "Download dell'aggiornamento...",
|
"DialogUpdaterDownloadingMessage": "Download dell'aggiornamento...",
|
||||||
"DialogUpdaterExtractionMessage": "Estrazione dell'aggiornamento...",
|
"DialogUpdaterExtractionMessage": "Estrazione dell'aggiornamento...",
|
||||||
"DialogUpdaterRenamingMessage": "Rinominazione dell'aggiornamento...",
|
"DialogUpdaterRenamingMessage": "Rinominazione dell'aggiornamento...",
|
||||||
"DialogUpdaterAddingFilesMessage": "Aggiunta nuovo aggiornamento...",
|
"DialogUpdaterAddingFilesMessage": "Aggiunta del nuovo aggiornamento...",
|
||||||
"DialogUpdaterCompleteMessage": "Aggiornamento completato!",
|
"DialogUpdaterCompleteMessage": "Aggiornamento completato!",
|
||||||
"DialogUpdaterRestartMessage": "Vuoi riavviare Ryujinx adesso?",
|
"DialogUpdaterRestartMessage": "Vuoi riavviare Ryujinx adesso?",
|
||||||
"DialogUpdaterArchNotSupportedMessage": "Non stai usando un'architettura di sistema supportata!",
|
"DialogUpdaterArchNotSupportedMessage": "Non stai usando un'architettura di sistema supportata!",
|
||||||
@ -331,7 +331,7 @@
|
|||||||
"DialogThemeRestartMessage": "Il tema è stato salvato. E' richiesto un riavvio per applicare un tema.",
|
"DialogThemeRestartMessage": "Il tema è stato salvato. E' richiesto un riavvio per applicare un tema.",
|
||||||
"DialogThemeRestartSubMessage": "Vuoi riavviare?",
|
"DialogThemeRestartSubMessage": "Vuoi riavviare?",
|
||||||
"DialogFirmwareInstallEmbeddedMessage": "Vuoi installare il firmware incorporato in questo gioco? (Firmware {0})",
|
"DialogFirmwareInstallEmbeddedMessage": "Vuoi installare il firmware incorporato in questo gioco? (Firmware {0})",
|
||||||
"DialogFirmwareInstallEmbeddedSuccessMessage": "Non è stato trovato alcun firmware installato, ma Ryujinx è riuscito di installare il firmware {0} dal gioco fornito.\nL'emulatore si avvierà adesso.",
|
"DialogFirmwareInstallEmbeddedSuccessMessage": "Non è stato trovato alcun firmware installato, ma Ryujinx è riuscito ad installare il firmware {0} dal gioco fornito.\nL'emulatore si avvierà adesso.",
|
||||||
"DialogFirmwareNoFirmwareInstalledMessage": "Nessun firmware installato",
|
"DialogFirmwareNoFirmwareInstalledMessage": "Nessun firmware installato",
|
||||||
"DialogFirmwareInstalledMessage": "Il firmware {0} è stato installato",
|
"DialogFirmwareInstalledMessage": "Il firmware {0} è stato installato",
|
||||||
"DialogOpenSettingsWindowLabel": "Apri finestra delle impostazioni",
|
"DialogOpenSettingsWindowLabel": "Apri finestra delle impostazioni",
|
||||||
@ -355,14 +355,14 @@
|
|||||||
"DialogShaderDeletionMessage": "Stai per eliminare la Shader cache per :\n\n{0}\n\nSei sicuro di voler proseguire?",
|
"DialogShaderDeletionMessage": "Stai per eliminare la Shader cache per :\n\n{0}\n\nSei sicuro di voler proseguire?",
|
||||||
"DialogShaderDeletionErrorMessage": "Errore nell'eliminazione della Shader cache a {0}: {1}",
|
"DialogShaderDeletionErrorMessage": "Errore nell'eliminazione della Shader cache a {0}: {1}",
|
||||||
"DialogRyujinxErrorMessage": "Ryujinx ha incontrato un errore",
|
"DialogRyujinxErrorMessage": "Ryujinx ha incontrato un errore",
|
||||||
"DialogInvalidTitleIdErrorMessage": "Errore UI: Il gioco selezionato non ha un title ID valido",
|
"DialogInvalidTitleIdErrorMessage": "Errore UI: Il gioco selezionato non ha un ID titolo valido",
|
||||||
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "Un firmware di sistema valido non è stato trovato in {0}.",
|
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "Un firmware del sistema valido non è stato trovato in {0}.",
|
||||||
"DialogFirmwareInstallerFirmwareInstallTitle": "Installa firmware {0}",
|
"DialogFirmwareInstallerFirmwareInstallTitle": "Installa firmware {0}",
|
||||||
"DialogFirmwareInstallerFirmwareInstallMessage": "La versione di sistema {0} sarà installata.",
|
"DialogFirmwareInstallerFirmwareInstallMessage": "La versione del sistema {0} sarà installata.",
|
||||||
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nQuesta sostituirà l'attuale versione di sistema {0}.",
|
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nQuesta sostituirà l'attuale versione di sistema {0}.",
|
||||||
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nVuoi continuare?",
|
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nVuoi continuare?",
|
||||||
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Installazione del firmware...",
|
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Installazione del firmware...",
|
||||||
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "La versione di sistema {0} è stata installata.",
|
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "La versione del sistema {0} è stata installata.",
|
||||||
"DialogUserProfileDeletionWarningMessage": "Non ci sarebbero altri profili da aprire se il profilo selezionato viene cancellato",
|
"DialogUserProfileDeletionWarningMessage": "Non ci sarebbero altri profili da aprire se il profilo selezionato viene cancellato",
|
||||||
"DialogUserProfileDeletionConfirmMessage": "Vuoi eliminare il profilo selezionato?",
|
"DialogUserProfileDeletionConfirmMessage": "Vuoi eliminare il profilo selezionato?",
|
||||||
"DialogControllerSettingsModifiedConfirmMessage": "Le attuali impostazioni del controller sono state aggiornate.",
|
"DialogControllerSettingsModifiedConfirmMessage": "Le attuali impostazioni del controller sono state aggiornate.",
|
||||||
@ -557,4 +557,40 @@
|
|||||||
"SettingsXamlThemeFile" : "File del tema xaml",
|
"SettingsXamlThemeFile" : "File del tema xaml",
|
||||||
"SettingsTabHotkeysResScaleUpHotkey": "Aumentare la risoluzione:",
|
"SettingsTabHotkeysResScaleUpHotkey": "Aumentare la risoluzione:",
|
||||||
"SettingsTabHotkeysResScaleDownHotkey": "Diminuire la risoluzione:"
|
"SettingsTabHotkeysResScaleDownHotkey": "Diminuire la risoluzione:"
|
||||||
|
"AvatarWindowTitle": "Gestisci account - Avatar"
|
||||||
|
"Amiibo": "Amiibo",
|
||||||
|
"Unknown": "Sconosciuto",
|
||||||
|
"Usage": "Utilizzo",
|
||||||
|
"Writable": "Scrivibile",
|
||||||
|
"SelectDlcDialogTitle": "Seleziona file dei DLC",
|
||||||
|
"SelectUpdateDialogTitle": "Seleziona file di aggiornamento",
|
||||||
|
"UserProfileWindowTitle": "Gestisci profili degli utenti",
|
||||||
|
"CheatWindowTitle": "Gestisci cheat dei giochi",
|
||||||
|
"DlcWindowTitle": "Gestisci DLC dei giochi",
|
||||||
|
"UpdateWindowTitle": "Gestisci aggiornamenti dei giochi",
|
||||||
|
"CheatWindowHeading": "Cheat disponibiili per {0} [{1}]",
|
||||||
|
"DlcWindowHeading": "DLC disponibili per {0} [{1}]",
|
||||||
|
"UserProfilesEditProfile": "Modifica selezionati",
|
||||||
|
"Cancel": "Annulla",
|
||||||
|
"Save": "Salva",
|
||||||
|
"Discard": "Scarta",
|
||||||
|
"UserProfilesSetProfileImage": "Imposta immagine profilo",
|
||||||
|
"UserProfileEmptyNameError": "È richiesto un nome",
|
||||||
|
"UserProfileNoImageError": "Dev'essere impostata un'immagine profilo",
|
||||||
|
"GameUpdateWindowHeading": "Aggiornamenti disponibili per {0} [{1}]",
|
||||||
|
"UserProfilesName": "Name:",
|
||||||
|
"UserProfilesUserId": "User Id:",
|
||||||
|
"SettingsTabGraphicsBackend": "Backend grafica",
|
||||||
|
"SettingsTabGraphicsBackendTooltip": "Backend grafica da usare",
|
||||||
|
"SettingsEnableTextureRecompression": "Abilita Ricompressione Texture",
|
||||||
|
"SettingsEnableTextureRecompressionTooltip": "Comprime alcune texture per ridurre l'utilizzo della VRAM.\n\nL'utilizzo è consigliato con GPU con meno di 4GB di VRAM.\n\nLascia su OFF se non sei sicuro.",
|
||||||
|
"SettingsTabGraphicsPreferredGpu": "GPU preferita",
|
||||||
|
"SettingsTabGraphicsPreferredGpuTooltip": "Seleziona la scheda grafica che verrà usata con la backend grafica Vulkan.\n\nNon influenza la GPU che userà OpenGL.\n\nImposta la GPU contrassegnata come \"dGPU\" se non sei sicuro. Se non ce n'è una, lascia intatta quest'impostazione.",
|
||||||
|
"SettingsAppRequiredRestartMessage": "È richiesto un riavvio di Ryujinx",
|
||||||
|
"SettingsGpuBackendRestartMessage": "Le impostazioni della backend grafica o della GPU sono state modificate. Questo richiederà un riavvio perché le modifiche siano applicate",
|
||||||
|
"SettingsGpuBackendRestartSubMessage": "Vuoi riavviare ora?",
|
||||||
|
"RyujinxUpdaterMessage": "Vuoi aggiornare Ryujinx all'ultima versione?",
|
||||||
|
"SettingsTabHotkeysVolumeUpHotkey": "Aumentare il volume:",
|
||||||
|
"SettingsTabHotkeysVolumeDownHotkey": "Diminuire il volume:",
|
||||||
|
"VolumeShort": "Vol"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<RuntimeIdentifiers>win10-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win10-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
@ -8,11 +8,13 @@
|
|||||||
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
|
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
|
||||||
<RootNamespace>Ryujinx.Ava</RootNamespace>
|
<RootNamespace>Ryujinx.Ava</RootNamespace>
|
||||||
<ApplicationIcon>Ryujinx.ico</ApplicationIcon>
|
<ApplicationIcon>Ryujinx.ico</ApplicationIcon>
|
||||||
|
<TieredPGO>true</TieredPGO>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
|
<PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
|
||||||
<PublishSingleFile>true</PublishSingleFile>
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
<PublishTrimmed>true</PublishTrimmed>
|
<PublishTrimmed>true</PublishTrimmed>
|
||||||
|
<TrimMode>partial</TrimMode>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -34,7 +36,7 @@
|
|||||||
<PackageReference Include="Silk.NET.Vulkan" Version="2.10.1" />
|
<PackageReference Include="Silk.NET.Vulkan" Version="2.10.1" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.10.1" />
|
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.10.1" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.10.1" />
|
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.10.1" />
|
||||||
<PackageReference Include="SPB" Version="0.0.4-build24" />
|
<PackageReference Include="SPB" Version="0.0.4-build27" />
|
||||||
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -4,6 +4,7 @@ using Avalonia.Controls.ApplicationLifetimes;
|
|||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using FluentAvalonia.Core;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Ui.Models;
|
using Ryujinx.Ava.Ui.Models;
|
||||||
@ -27,7 +28,10 @@ namespace Ryujinx.Ava.Ui.Controls
|
|||||||
string secondaryButton,
|
string secondaryButton,
|
||||||
string closeButton,
|
string closeButton,
|
||||||
int iconSymbol,
|
int iconSymbol,
|
||||||
UserResult primaryButtonResult = UserResult.Ok)
|
UserResult primaryButtonResult = UserResult.Ok,
|
||||||
|
ManualResetEvent deferResetEvent = null,
|
||||||
|
Func<Window, Task> doWhileDeferred = null,
|
||||||
|
TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> deferCloseAction = null)
|
||||||
{
|
{
|
||||||
UserResult result = UserResult.None;
|
UserResult result = UserResult.None;
|
||||||
|
|
||||||
@ -110,12 +114,19 @@ namespace Ryujinx.Ava.Ui.Controls
|
|||||||
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
|
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
|
||||||
{
|
{
|
||||||
result = UserResult.No;
|
result = UserResult.No;
|
||||||
|
contentDialog.PrimaryButtonClick -= deferCloseAction;
|
||||||
});
|
});
|
||||||
contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
|
contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
|
||||||
{
|
{
|
||||||
result = UserResult.Cancel;
|
result = UserResult.Cancel;
|
||||||
|
contentDialog.PrimaryButtonClick -= deferCloseAction;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (deferResetEvent != null)
|
||||||
|
{
|
||||||
|
contentDialog.PrimaryButtonClick += deferCloseAction;
|
||||||
|
}
|
||||||
|
|
||||||
await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
|
await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
|
||||||
|
|
||||||
overlay?.Close();
|
overlay?.Close();
|
||||||
@ -143,35 +154,20 @@ namespace Ryujinx.Ava.Ui.Controls
|
|||||||
Func<Window, Task> doWhileDeferred = null)
|
Func<Window, Task> doWhileDeferred = null)
|
||||||
{
|
{
|
||||||
bool startedDeferring = false;
|
bool startedDeferring = false;
|
||||||
|
|
||||||
UserResult result = UserResult.None;
|
UserResult result = UserResult.None;
|
||||||
|
|
||||||
ContentDialog contentDialog = new ContentDialog
|
return await ShowContentDialog(
|
||||||
{
|
title,
|
||||||
Title = title,
|
primaryText,
|
||||||
PrimaryButtonText = primaryButton,
|
secondaryText,
|
||||||
SecondaryButtonText = secondaryButton,
|
primaryButton,
|
||||||
CloseButtonText = closeButton,
|
secondaryButton,
|
||||||
Content = CreateDialogTextContent(primaryText, secondaryText, iconSymbol),
|
closeButton,
|
||||||
PrimaryButtonCommand = MiniCommand.Create(() =>
|
iconSymbol,
|
||||||
{
|
primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok,
|
||||||
result = primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok;
|
deferResetEvent,
|
||||||
}),
|
doWhileDeferred,
|
||||||
};
|
DeferClose);
|
||||||
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
|
|
||||||
{
|
|
||||||
contentDialog.PrimaryButtonClick -= DeferClose;
|
|
||||||
result = UserResult.No;
|
|
||||||
});
|
|
||||||
contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
|
|
||||||
{
|
|
||||||
contentDialog.PrimaryButtonClick -= DeferClose;
|
|
||||||
result = UserResult.Cancel;
|
|
||||||
});
|
|
||||||
contentDialog.PrimaryButtonClick += DeferClose;
|
|
||||||
await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
async void DeferClose(ContentDialog sender, ContentDialogButtonClickEventArgs args)
|
async void DeferClose(ContentDialog sender, ContentDialogButtonClickEventArgs args)
|
||||||
{
|
{
|
||||||
@ -180,7 +176,7 @@ namespace Ryujinx.Ava.Ui.Controls
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
contentDialog.PrimaryButtonClick -= DeferClose;
|
sender.PrimaryButtonClick -= DeferClose;
|
||||||
|
|
||||||
startedDeferring = true;
|
startedDeferring = true;
|
||||||
|
|
||||||
@ -188,7 +184,7 @@ namespace Ryujinx.Ava.Ui.Controls
|
|||||||
|
|
||||||
result = primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok;
|
result = primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok;
|
||||||
|
|
||||||
contentDialog.PrimaryButtonClick -= DeferClose;
|
sender.PrimaryButtonClick -= DeferClose;
|
||||||
|
|
||||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
|
@ -53,5 +53,11 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
writer.Write(data);
|
writer.Write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Write(this BinaryWriter writer, UInt128 value)
|
||||||
|
{
|
||||||
|
writer.Write((ulong)value);
|
||||||
|
writer.Write((ulong)(value >> 64));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -7,19 +7,19 @@ namespace Ryujinx.Common.Utilities
|
|||||||
public static class SpanHelpers
|
public static class SpanHelpers
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Span<T> CreateSpan<T>(ref T reference, int length)
|
public static Span<T> CreateSpan<T>(scoped ref T reference, int length)
|
||||||
{
|
{
|
||||||
return MemoryMarshal.CreateSpan(ref reference, length);
|
return MemoryMarshal.CreateSpan(ref reference, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Span<T> AsSpan<T>(ref T reference) where T : unmanaged
|
public static Span<T> AsSpan<T>(scoped ref T reference) where T : unmanaged
|
||||||
{
|
{
|
||||||
return CreateSpan(ref reference, 1);
|
return CreateSpan(ref reference, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Span<TSpan> AsSpan<TStruct, TSpan>(ref TStruct reference)
|
public static Span<TSpan> AsSpan<TStruct, TSpan>(scoped ref TStruct reference)
|
||||||
where TStruct : unmanaged where TSpan : unmanaged
|
where TStruct : unmanaged where TSpan : unmanaged
|
||||||
{
|
{
|
||||||
return CreateSpan(ref Unsafe.As<TStruct, TSpan>(ref reference),
|
return CreateSpan(ref Unsafe.As<TStruct, TSpan>(ref reference),
|
||||||
@ -27,25 +27,25 @@ namespace Ryujinx.Common.Utilities
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Span<byte> AsByteSpan<T>(ref T reference) where T : unmanaged
|
public static Span<byte> AsByteSpan<T>(scoped ref T reference) where T : unmanaged
|
||||||
{
|
{
|
||||||
return CreateSpan(ref Unsafe.As<T, byte>(ref reference), Unsafe.SizeOf<T>());
|
return CreateSpan(ref Unsafe.As<T, byte>(ref reference), Unsafe.SizeOf<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ReadOnlySpan<T> CreateReadOnlySpan<T>(ref T reference, int length)
|
public static ReadOnlySpan<T> CreateReadOnlySpan<T>(scoped ref T reference, int length)
|
||||||
{
|
{
|
||||||
return MemoryMarshal.CreateReadOnlySpan(ref reference, length);
|
return MemoryMarshal.CreateReadOnlySpan(ref reference, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ReadOnlySpan<T> AsReadOnlySpan<T>(ref T reference) where T : unmanaged
|
public static ReadOnlySpan<T> AsReadOnlySpan<T>(scoped ref T reference) where T : unmanaged
|
||||||
{
|
{
|
||||||
return CreateReadOnlySpan(ref reference, 1);
|
return CreateReadOnlySpan(ref reference, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ReadOnlySpan<TSpan> AsReadOnlySpan<TStruct, TSpan>(ref TStruct reference)
|
public static ReadOnlySpan<TSpan> AsReadOnlySpan<TStruct, TSpan>(scoped ref TStruct reference)
|
||||||
where TStruct : unmanaged where TSpan : unmanaged
|
where TStruct : unmanaged where TSpan : unmanaged
|
||||||
{
|
{
|
||||||
return CreateReadOnlySpan(ref Unsafe.As<TStruct, TSpan>(ref reference),
|
return CreateReadOnlySpan(ref Unsafe.As<TStruct, TSpan>(ref reference),
|
||||||
@ -53,7 +53,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ReadOnlySpan<byte> AsReadOnlyByteSpan<T>(ref T reference) where T : unmanaged
|
public static ReadOnlySpan<byte> AsReadOnlyByteSpan<T>(scoped ref T reference) where T : unmanaged
|
||||||
{
|
{
|
||||||
return CreateReadOnlySpan(ref Unsafe.As<T, byte>(ref reference), Unsafe.SizeOf<T>());
|
return CreateReadOnlySpan(ref Unsafe.As<T, byte>(ref reference), Unsafe.SizeOf<T>());
|
||||||
}
|
}
|
||||||
|
17
Ryujinx.Common/Utilities/UInt128Utils.cs
Normal file
17
Ryujinx.Common/Utilities/UInt128Utils.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Utilities
|
||||||
|
{
|
||||||
|
public static class UInt128Utils
|
||||||
|
{
|
||||||
|
public static UInt128 FromHex(string hex)
|
||||||
|
{
|
||||||
|
return new UInt128((ulong)Convert.ToInt64(hex.Substring(0, 16), 16), (ulong)Convert.ToInt64(hex.Substring(16), 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UInt128 CreateRandom()
|
||||||
|
{
|
||||||
|
return new UInt128((ulong)Random.Shared.NextInt64(), (ulong)Random.Shared.NextInt64());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
|
@ -94,6 +94,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
{
|
{
|
||||||
var memoryManager = _channel.MemoryManager;
|
var memoryManager = _channel.MemoryManager;
|
||||||
|
|
||||||
|
// Since we're going to change the state, make sure any pending instanced draws are done.
|
||||||
|
_3dEngine.PerformDeferredDraws();
|
||||||
|
|
||||||
|
// Make sure all pending uniform buffer data is written to memory.
|
||||||
_3dEngine.FlushUboDirty();
|
_3dEngine.FlushUboDirty();
|
||||||
|
|
||||||
uint qmdAddress = _state.State.SendPcasA;
|
uint qmdAddress = _state.State.SendPcasA;
|
||||||
|
@ -708,11 +708,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool dataMatches = _currentData != null && data.SequenceEqual(_currentData);
|
bool dataMatches = _currentData != null && data.SequenceEqual(_currentData);
|
||||||
_currentData = data.ToArray();
|
|
||||||
if (dataMatches)
|
if (dataMatches)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_currentData = data.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,10 +413,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void UpdateCachedBuffer(
|
private void UpdateCachedBuffer(
|
||||||
int stageIndex,
|
int stageIndex,
|
||||||
ref int cachedTextureBufferIndex,
|
scoped ref int cachedTextureBufferIndex,
|
||||||
ref int cachedSamplerBufferIndex,
|
scoped ref int cachedSamplerBufferIndex,
|
||||||
ref ReadOnlySpan<int> cachedTextureBuffer,
|
scoped ref ReadOnlySpan<int> cachedTextureBuffer,
|
||||||
ref ReadOnlySpan<int> cachedSamplerBuffer,
|
scoped ref ReadOnlySpan<int> cachedSamplerBuffer,
|
||||||
int textureBufferIndex,
|
int textureBufferIndex,
|
||||||
int samplerBufferIndex)
|
int samplerBufferIndex)
|
||||||
{
|
{
|
||||||
|
@ -710,7 +710,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
break;
|
break;
|
||||||
case Target.Texture2DMultisample:
|
case Target.Texture2DMultisample:
|
||||||
case Target.Texture2DMultisampleArray:
|
case Target.Texture2DMultisampleArray:
|
||||||
if (rhs.Target == Target.Texture2D || rhs.Target == Target.Texture2DArray)
|
// We don't support copy between multisample and non-multisample depth-stencil textures
|
||||||
|
// because there's no way to emulate that since most GPUs don't support writing a
|
||||||
|
// custom stencil value into the texture, among several other API limitations.
|
||||||
|
|
||||||
|
if ((rhs.Target == Target.Texture2D || rhs.Target == Target.Texture2DArray) &&
|
||||||
|
!rhs.FormatInfo.Format.IsDepthOrStencil())
|
||||||
{
|
{
|
||||||
return TextureViewCompatibility.CopyOnly;
|
return TextureViewCompatibility.CopyOnly;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
private const ushort FileFormatVersionMajor = 1;
|
private const ushort FileFormatVersionMajor = 1;
|
||||||
private const ushort FileFormatVersionMinor = 2;
|
private const ushort FileFormatVersionMinor = 2;
|
||||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||||
private const uint CodeGenVersion = 3759;
|
private const uint CodeGenVersion = 3807;
|
||||||
|
|
||||||
private const string SharedTocFileName = "shared.toc";
|
private const string SharedTocFileName = "shared.toc";
|
||||||
private const string SharedDataFileName = "shared.data";
|
private const string SharedDataFileName = "shared.data";
|
||||||
|
@ -350,7 +350,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.HashTable
|
|||||||
/// <param name="item">The item on the table, if found, otherwise unmodified</param>
|
/// <param name="item">The item on the table, if found, otherwise unmodified</param>
|
||||||
/// <param name="data">The data on the table, if found, otherwise unmodified</param>
|
/// <param name="data">The data on the table, if found, otherwise unmodified</param>
|
||||||
/// <returns>Table lookup result</returns>
|
/// <returns>Table lookup result</returns>
|
||||||
public SearchResult TryFindItem(ref SmartDataAccessor dataAccessor, int size, ref T item, ref byte[] data)
|
public SearchResult TryFindItem(scoped ref SmartDataAccessor dataAccessor, int size, scoped ref T item, scoped ref byte[] data)
|
||||||
{
|
{
|
||||||
if (_count == 0)
|
if (_count == 0)
|
||||||
{
|
{
|
||||||
|
@ -91,7 +91,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.HashTable
|
|||||||
/// <param name="item">The item on the table, if found, otherwise unmodified</param>
|
/// <param name="item">The item on the table, if found, otherwise unmodified</param>
|
||||||
/// <param name="data">The data on the table, if found, otherwise unmodified</param>
|
/// <param name="data">The data on the table, if found, otherwise unmodified</param>
|
||||||
/// <returns>Table lookup result</returns>
|
/// <returns>Table lookup result</returns>
|
||||||
public PartitionHashTable<T>.SearchResult TryFindItem(ref SmartDataAccessor dataAccessor, ref T item, ref byte[] data)
|
public PartitionHashTable<T>.SearchResult TryFindItem(scoped ref SmartDataAccessor dataAccessor, scoped ref T item, scoped ref byte[] data)
|
||||||
{
|
{
|
||||||
return _table.TryFindItem(ref dataAccessor, Size, ref item, ref data);
|
return _table.TryFindItem(ref dataAccessor, Size, ref item, ref data);
|
||||||
}
|
}
|
||||||
|
@ -552,11 +552,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
private static void UpdateCachedBuffer(
|
private static void UpdateCachedBuffer(
|
||||||
GpuChannel channel,
|
GpuChannel channel,
|
||||||
bool isCompute,
|
bool isCompute,
|
||||||
ref int cachedTextureBufferIndex,
|
scoped ref int cachedTextureBufferIndex,
|
||||||
ref int cachedSamplerBufferIndex,
|
scoped ref int cachedSamplerBufferIndex,
|
||||||
ref ReadOnlySpan<int> cachedTextureBuffer,
|
scoped ref ReadOnlySpan<int> cachedTextureBuffer,
|
||||||
ref ReadOnlySpan<int> cachedSamplerBuffer,
|
scoped ref ReadOnlySpan<int> cachedSamplerBuffer,
|
||||||
ref int cachedStageIndex,
|
scoped ref int cachedStageIndex,
|
||||||
int textureBufferIndex,
|
int textureBufferIndex,
|
||||||
int samplerBufferIndex,
|
int samplerBufferIndex,
|
||||||
int stageIndex)
|
int stageIndex)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -7,7 +7,9 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
|||||||
{
|
{
|
||||||
unsafe class FFmpegContext : IDisposable
|
unsafe class FFmpegContext : IDisposable
|
||||||
{
|
{
|
||||||
private readonly FFCodec.AVCodec_decode _decodeFrame;
|
private unsafe delegate int AVCodec_decode(AVCodecContext* avctx, void* outdata, int* got_frame_ptr, AVPacket* avpkt);
|
||||||
|
|
||||||
|
private readonly AVCodec_decode _decodeFrame;
|
||||||
private static readonly FFmpegApi.av_log_set_callback_callback _logFunc;
|
private static readonly FFmpegApi.av_log_set_callback_callback _logFunc;
|
||||||
private readonly AVCodec* _codec;
|
private readonly AVCodec* _codec;
|
||||||
private AVPacket* _packet;
|
private AVPacket* _packet;
|
||||||
@ -53,17 +55,17 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
|||||||
// libavcodec 59.24 changed AvCodec to move its private API and also move the codec function to an union.
|
// libavcodec 59.24 changed AvCodec to move its private API and also move the codec function to an union.
|
||||||
if (avCodecMajorVersion > 59 || (avCodecMajorVersion == 59 && avCodecMinorVersion > 24))
|
if (avCodecMajorVersion > 59 || (avCodecMajorVersion == 59 && avCodecMinorVersion > 24))
|
||||||
{
|
{
|
||||||
_decodeFrame = Marshal.GetDelegateForFunctionPointer<FFCodec.AVCodec_decode>(((FFCodec*)_codec)->CodecCallback);
|
_decodeFrame = Marshal.GetDelegateForFunctionPointer<AVCodec_decode>(((FFCodec<AVCodec>*)_codec)->CodecCallback);
|
||||||
}
|
}
|
||||||
// libavcodec 59.x changed AvCodec private API layout.
|
// libavcodec 59.x changed AvCodec private API layout.
|
||||||
else if (avCodecMajorVersion == 59)
|
else if (avCodecMajorVersion == 59)
|
||||||
{
|
{
|
||||||
_decodeFrame = Marshal.GetDelegateForFunctionPointer<FFCodec.AVCodec_decode>(((FFCodecLegacy<AVCodec>*)_codec)->Decode);
|
_decodeFrame = Marshal.GetDelegateForFunctionPointer<AVCodec_decode>(((FFCodecLegacy<AVCodec501>*)_codec)->Decode);
|
||||||
}
|
}
|
||||||
// libavcodec 58.x and lower
|
// libavcodec 58.x and lower
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_decodeFrame = Marshal.GetDelegateForFunctionPointer<FFCodec.AVCodec_decode>(((FFCodecLegacy<AVCodecLegacy>*)_codec)->Decode);
|
_decodeFrame = Marshal.GetDelegateForFunctionPointer<AVCodec_decode>(((FFCodecLegacy<AVCodec>*)_codec)->Decode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
|||||||
public unsafe IntPtr PrivClass;
|
public unsafe IntPtr PrivClass;
|
||||||
public IntPtr Profiles;
|
public IntPtr Profiles;
|
||||||
public unsafe byte* WrapperName;
|
public unsafe byte* WrapperName;
|
||||||
|
public IntPtr ChLayouts;
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
{
|
{
|
||||||
struct AVCodecLegacy
|
struct AVCodec501
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
public unsafe byte* Name;
|
public unsafe byte* Name;
|
||||||
@ -20,7 +20,6 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
|||||||
public unsafe IntPtr PrivClass;
|
public unsafe IntPtr PrivClass;
|
||||||
public IntPtr Profiles;
|
public IntPtr Profiles;
|
||||||
public unsafe byte* WrapperName;
|
public unsafe byte* WrapperName;
|
||||||
public IntPtr ChLayouts;
|
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
|||||||
public unsafe IntPtr AvClass;
|
public unsafe IntPtr AvClass;
|
||||||
public int LogLevelOffset;
|
public int LogLevelOffset;
|
||||||
public int CodecType;
|
public int CodecType;
|
||||||
public unsafe AVCodecLegacy* Codec;
|
public unsafe AVCodec* Codec;
|
||||||
public AVCodecID CodecId;
|
public AVCodecID CodecId;
|
||||||
public uint CodecTag;
|
public uint CodecTag;
|
||||||
public IntPtr PrivData;
|
public IntPtr PrivData;
|
||||||
|
@ -2,12 +2,10 @@
|
|||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
{
|
{
|
||||||
struct FFCodec
|
struct FFCodec<T> where T: struct
|
||||||
{
|
{
|
||||||
public unsafe delegate int AVCodec_decode(AVCodecContext* avctx, void* outdata, int* got_frame_ptr, AVPacket* avpkt);
|
|
||||||
|
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
public AVCodec Base;
|
public T Base;
|
||||||
public int CapsInternalOrCbType;
|
public int CapsInternalOrCbType;
|
||||||
public int PrivDataSize;
|
public int PrivDataSize;
|
||||||
public IntPtr UpdateThreadContext;
|
public IntPtr UpdateThreadContext;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -34,5 +34,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||||||
GL.ActiveTexture(TextureUnit.Texture0 + unit);
|
GL.ActiveTexture(TextureUnit.Texture0 + unit);
|
||||||
GL.BindTexture(target, Handle);
|
GL.BindTexture(target, Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ClearBinding(int unit)
|
||||||
|
{
|
||||||
|
GL.ActiveTexture(TextureUnit.Texture0 + unit);
|
||||||
|
GL.BindTextureUnit(unit, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||||||
|
|
||||||
if (!destinationView.Target.IsMultisample() && Target.IsMultisample())
|
if (!destinationView.Target.IsMultisample() && Target.IsMultisample())
|
||||||
{
|
{
|
||||||
_renderer.TextureCopyMS.CopyMSToNonMS(this, destinationView, srcLayer, dstLayer,1);
|
_renderer.TextureCopyMS.CopyMSToNonMS(this, destinationView, srcLayer, dstLayer, 1);
|
||||||
}
|
}
|
||||||
else if (destinationView.Target.IsMultisample() && !Target.IsMultisample())
|
else if (destinationView.Target.IsMultisample() && !Target.IsMultisample())
|
||||||
{
|
{
|
||||||
|
@ -919,6 +919,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
|
|
||||||
if (texture == null)
|
if (texture == null)
|
||||||
{
|
{
|
||||||
|
GL.BindImageTexture(binding, 0, 0, true, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1275,6 +1276,10 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
((TextureBase)texture).Bind(binding);
|
((TextureBase)texture).Bind(binding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TextureBase.ClearBinding(binding);
|
||||||
|
}
|
||||||
|
|
||||||
Sampler glSampler = (Sampler)sampler;
|
Sampler glSampler = (Sampler)sampler;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -262,6 +262,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
Instruction ioVariable, elemIndex;
|
Instruction ioVariable, elemIndex;
|
||||||
|
|
||||||
|
Instruction invocationId = null;
|
||||||
|
|
||||||
|
if (Config.Stage == ShaderStage.TessellationControl && isOutAttr)
|
||||||
|
{
|
||||||
|
invocationId = Load(TypeS32(), Inputs[AttributeConsts.InvocationId]);
|
||||||
|
}
|
||||||
|
|
||||||
bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd;
|
bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd;
|
||||||
|
|
||||||
if (isUserAttr &&
|
if (isUserAttr &&
|
||||||
@ -273,7 +280,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex());
|
elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex());
|
||||||
var vecIndex = Constant(TypeU32(), (attr - AttributeConsts.UserAttributeBase) >> 4);
|
var vecIndex = Constant(TypeU32(), (attr - AttributeConsts.UserAttributeBase) >> 4);
|
||||||
|
|
||||||
if (AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr))
|
bool isArray = AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr);
|
||||||
|
|
||||||
|
if (invocationId != null && isArray)
|
||||||
|
{
|
||||||
|
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index, vecIndex, elemIndex);
|
||||||
|
}
|
||||||
|
else if (invocationId != null)
|
||||||
|
{
|
||||||
|
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, vecIndex, elemIndex);
|
||||||
|
}
|
||||||
|
else if (isArray)
|
||||||
{
|
{
|
||||||
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, vecIndex, elemIndex);
|
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, vecIndex, elemIndex);
|
||||||
}
|
}
|
||||||
@ -308,12 +325,29 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
if ((type & (AggregateType.Array | AggregateType.Vector)) == 0)
|
if ((type & (AggregateType.Array | AggregateType.Vector)) == 0)
|
||||||
{
|
{
|
||||||
return isIndexed ? AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index) : ioVariable;
|
if (invocationId != null)
|
||||||
|
{
|
||||||
|
return isIndexed
|
||||||
|
? AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index)
|
||||||
|
: AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return isIndexed ? AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index) : ioVariable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex());
|
elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex());
|
||||||
|
|
||||||
if (isIndexed)
|
if (invocationId != null && isIndexed)
|
||||||
|
{
|
||||||
|
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index, elemIndex);
|
||||||
|
}
|
||||||
|
else if (invocationId != null)
|
||||||
|
{
|
||||||
|
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, elemIndex);
|
||||||
|
}
|
||||||
|
else if (isIndexed)
|
||||||
{
|
{
|
||||||
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, elemIndex);
|
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, elemIndex);
|
||||||
}
|
}
|
||||||
@ -327,12 +361,29 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input;
|
var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input;
|
||||||
|
|
||||||
|
Instruction invocationId = null;
|
||||||
|
|
||||||
|
if (Config.Stage == ShaderStage.TessellationControl && isOutAttr)
|
||||||
|
{
|
||||||
|
invocationId = Load(TypeS32(), Inputs[AttributeConsts.InvocationId]);
|
||||||
|
}
|
||||||
|
|
||||||
elemType = AggregateType.FP32;
|
elemType = AggregateType.FP32;
|
||||||
var ioVariable = isOutAttr ? OutputsArray : InputsArray;
|
var ioVariable = isOutAttr ? OutputsArray : InputsArray;
|
||||||
var vecIndex = ShiftRightLogical(TypeS32(), attrIndex, Constant(TypeS32(), 2));
|
var vecIndex = ShiftRightLogical(TypeS32(), attrIndex, Constant(TypeS32(), 2));
|
||||||
var elemIndex = BitwiseAnd(TypeS32(), attrIndex, Constant(TypeS32(), 3));
|
var elemIndex = BitwiseAnd(TypeS32(), attrIndex, Constant(TypeS32(), 3));
|
||||||
|
|
||||||
if (AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr))
|
bool isArray = AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr);
|
||||||
|
|
||||||
|
if (invocationId != null && isArray)
|
||||||
|
{
|
||||||
|
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index, vecIndex, elemIndex);
|
||||||
|
}
|
||||||
|
else if (invocationId != null)
|
||||||
|
{
|
||||||
|
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, vecIndex, elemIndex);
|
||||||
|
}
|
||||||
|
else if (isArray)
|
||||||
{
|
{
|
||||||
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, vecIndex, elemIndex);
|
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, vecIndex, elemIndex);
|
||||||
}
|
}
|
||||||
|
@ -473,6 +473,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
var attrType = context.TypeVector(context.TypeFP32(), (LiteralInteger)4);
|
var attrType = context.TypeVector(context.TypeFP32(), (LiteralInteger)4);
|
||||||
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)MaxAttributes));
|
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)MaxAttributes));
|
||||||
|
|
||||||
|
if (context.Config.Stage == ShaderStage.TessellationControl)
|
||||||
|
{
|
||||||
|
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), context.Config.ThreadsPerInputPrimitive));
|
||||||
|
}
|
||||||
|
|
||||||
var spvType = context.TypePointer(StorageClass.Output, attrType);
|
var spvType = context.TypePointer(StorageClass.Output, attrType);
|
||||||
var spvVar = context.Variable(spvType, StorageClass.Output);
|
var spvVar = context.Variable(spvType, StorageClass.Output);
|
||||||
|
|
||||||
@ -543,6 +548,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.Config.Stage == ShaderStage.TessellationControl && isOutAttr && !perPatch)
|
||||||
|
{
|
||||||
|
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), context.Config.ThreadsPerInputPrimitive));
|
||||||
|
}
|
||||||
|
|
||||||
var spvType = context.TypePointer(storageClass, attrType);
|
var spvType = context.TypePointer(storageClass, attrType);
|
||||||
var spvVar = context.Variable(spvType, storageClass);
|
var spvVar = context.Variable(spvType, storageClass);
|
||||||
|
|
||||||
@ -634,6 +644,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)arraySize));
|
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)arraySize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.Config.Stage == ShaderStage.TessellationControl && isOutAttr)
|
||||||
|
{
|
||||||
|
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), context.Config.ThreadsPerInputPrimitive));
|
||||||
|
}
|
||||||
|
|
||||||
var spvType = context.TypePointer(storageClass, attrType);
|
var spvType = context.TypePointer(storageClass, attrType);
|
||||||
var spvVar = context.Variable(spvType, storageClass);
|
var spvVar = context.Variable(spvType, storageClass);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -37,7 +37,12 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
Config = config;
|
Config = config;
|
||||||
|
|
||||||
if (config.GpPassthrough)
|
if (config.Stage == ShaderStage.TessellationControl)
|
||||||
|
{
|
||||||
|
// Required to index outputs.
|
||||||
|
Info.Inputs.Add(AttributeConsts.InvocationId);
|
||||||
|
}
|
||||||
|
else if (config.GpPassthrough)
|
||||||
{
|
{
|
||||||
int passthroughAttributes = config.PassthroughAttributes;
|
int passthroughAttributes = config.PassthroughAttributes;
|
||||||
while (passthroughAttributes != 0)
|
while (passthroughAttributes != 0)
|
||||||
|
@ -254,7 +254,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
UsedInputAttributes |= mask;
|
UsedInputAttributes |= mask;
|
||||||
_thisUsedInputAttributes |= mask;
|
_thisUsedInputAttributes |= mask;
|
||||||
ThisInputAttributesComponents |= UInt128.Pow2(index * 4 + component);
|
ThisInputAttributesComponents |= UInt128.One << (index * 4 + component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetInputUserAttributePerPatch(int index)
|
public void SetInputUserAttributePerPatch(int index)
|
||||||
@ -306,7 +306,10 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
config._perPatchAttributeLocations = locationsMap;
|
config._perPatchAttributeLocations = locationsMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.Stage != ShaderStage.Fragment)
|
// We don't consider geometry shaders using the geometry shader passthrough feature
|
||||||
|
// as being the last because when this feature is used, it can't actually modify any of the outputs,
|
||||||
|
// so the stage that comes before it is the last one that can do modifications.
|
||||||
|
if (config.Stage != ShaderStage.Fragment && (config.Stage != ShaderStage.Geometry || !config.GpPassthrough))
|
||||||
{
|
{
|
||||||
LastInVertexPipeline = false;
|
LastInVertexPipeline = false;
|
||||||
}
|
}
|
||||||
|
@ -190,10 +190,10 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
UInt128 usedAttributes = context.Config.NextInputAttributesComponents;
|
UInt128 usedAttributes = context.Config.NextInputAttributesComponents;
|
||||||
while (usedAttributes != UInt128.Zero)
|
while (usedAttributes != UInt128.Zero)
|
||||||
{
|
{
|
||||||
int index = usedAttributes.TrailingZeroCount();
|
int index = (int)UInt128.TrailingZeroCount(usedAttributes);
|
||||||
int vecIndex = index / 4;
|
int vecIndex = index / 4;
|
||||||
|
|
||||||
usedAttributes &= ~UInt128.Pow2(index);
|
usedAttributes &= ~(UInt128.One << index);
|
||||||
|
|
||||||
// We don't need to initialize passthrough attributes.
|
// We don't need to initialize passthrough attributes.
|
||||||
if ((context.Config.PassthroughAttributes & (1 << vecIndex)) != 0)
|
if ((context.Config.PassthroughAttributes & (1 << vecIndex)) != 0)
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Translation
|
|
||||||
{
|
|
||||||
struct UInt128 : IEquatable<UInt128>
|
|
||||||
{
|
|
||||||
public static UInt128 Zero => new UInt128() { _v0 = 0, _v1 = 0 };
|
|
||||||
|
|
||||||
private ulong _v0;
|
|
||||||
private ulong _v1;
|
|
||||||
|
|
||||||
public UInt128(ulong low, ulong high)
|
|
||||||
{
|
|
||||||
_v0 = low;
|
|
||||||
_v1 = high;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int TrailingZeroCount()
|
|
||||||
{
|
|
||||||
int count = BitOperations.TrailingZeroCount(_v0);
|
|
||||||
if (count == 64)
|
|
||||||
{
|
|
||||||
count += BitOperations.TrailingZeroCount(_v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UInt128 Pow2(int x)
|
|
||||||
{
|
|
||||||
if (x >= 64)
|
|
||||||
{
|
|
||||||
return new UInt128(0, 1UL << (x - 64));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UInt128(1UL << x, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UInt128 operator ~(UInt128 x)
|
|
||||||
{
|
|
||||||
return new UInt128(~x._v0, ~x._v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UInt128 operator &(UInt128 x, UInt128 y)
|
|
||||||
{
|
|
||||||
return new UInt128(x._v0 & y._v0, x._v1 & y._v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UInt128 operator |(UInt128 x, UInt128 y)
|
|
||||||
{
|
|
||||||
return new UInt128(x._v0 | y._v0, x._v1 | y._v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UInt128 operator <<(UInt128 x, int shift)
|
|
||||||
{
|
|
||||||
if (shift == 0)
|
|
||||||
{
|
|
||||||
return new UInt128(x._v0, x._v1);
|
|
||||||
}
|
|
||||||
else if (shift >= 64)
|
|
||||||
{
|
|
||||||
return new UInt128(0, x._v0 << (shift - 64));
|
|
||||||
}
|
|
||||||
|
|
||||||
ulong shiftOut = x._v0 >> (64 - shift);
|
|
||||||
|
|
||||||
return new UInt128(x._v0 << shift, (x._v1 << shift) | shiftOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UInt128 operator >>(UInt128 x, int shift)
|
|
||||||
{
|
|
||||||
if (shift == 0)
|
|
||||||
{
|
|
||||||
return new UInt128(x._v0, x._v1);
|
|
||||||
}
|
|
||||||
else if (shift >= 64)
|
|
||||||
{
|
|
||||||
return new UInt128(x._v1 >> (shift - 64), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ulong shiftOut = x._v1 & ((1UL << shift) - 1);
|
|
||||||
|
|
||||||
return new UInt128((x._v0 >> shift) | (shiftOut << (64 - shift)), x._v1 >> shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator ==(UInt128 x, UInt128 y)
|
|
||||||
{
|
|
||||||
return x.Equals(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(UInt128 x, UInt128 y)
|
|
||||||
{
|
|
||||||
return !x.Equals(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
return obj is UInt128 other && Equals(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(UInt128 other)
|
|
||||||
{
|
|
||||||
return _v0 == other._v0 && _v1 == other._v1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return HashCode.Combine(_v0, _v1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -229,8 +229,8 @@ namespace Ryujinx.Graphics.Vic.Image
|
|||||||
|
|
||||||
private static RentedBuffer ReadBuffer(
|
private static RentedBuffer ReadBuffer(
|
||||||
ResourceManager rm,
|
ResourceManager rm,
|
||||||
ref SlotConfig config,
|
scoped ref SlotConfig config,
|
||||||
ref Array8<PlaneOffsets> offsets,
|
scoped ref Array8<PlaneOffsets> offsets,
|
||||||
bool linear,
|
bool linear,
|
||||||
int plane,
|
int plane,
|
||||||
int width,
|
int width,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -12,13 +12,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private const int MaxUpdateBufferSize = 0x10000;
|
private const int MaxUpdateBufferSize = 0x10000;
|
||||||
|
|
||||||
public const AccessFlags DefaultAccessFlags =
|
public const AccessFlags DefaultAccessFlags =
|
||||||
|
AccessFlags.AccessIndirectCommandReadBit |
|
||||||
AccessFlags.AccessShaderReadBit |
|
AccessFlags.AccessShaderReadBit |
|
||||||
AccessFlags.AccessShaderWriteBit |
|
AccessFlags.AccessShaderWriteBit |
|
||||||
AccessFlags.AccessTransferReadBit |
|
AccessFlags.AccessTransferReadBit |
|
||||||
AccessFlags.AccessTransferWriteBit |
|
AccessFlags.AccessTransferWriteBit |
|
||||||
AccessFlags.AccessUniformReadBit |
|
AccessFlags.AccessUniformReadBit;
|
||||||
AccessFlags.AccessShaderReadBit |
|
|
||||||
AccessFlags.AccessShaderWriteBit;
|
|
||||||
|
|
||||||
private readonly VulkanRenderer _gd;
|
private readonly VulkanRenderer _gd;
|
||||||
private readonly Device _device;
|
private readonly Device _device;
|
||||||
|
@ -138,11 +138,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void SetImage(int binding, ITexture image, GAL.Format imageFormat)
|
public void SetImage(int binding, ITexture image, GAL.Format imageFormat)
|
||||||
{
|
{
|
||||||
if (image == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image is TextureBuffer imageBuffer)
|
if (image is TextureBuffer imageBuffer)
|
||||||
{
|
{
|
||||||
_bufferImageRefs[binding] = imageBuffer;
|
_bufferImageRefs[binding] = imageBuffer;
|
||||||
@ -152,6 +147,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
_imageRefs[binding] = view.GetView(imageFormat).GetIdentityImageView();
|
_imageRefs[binding] = view.GetView(imageFormat).GetIdentityImageView();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_imageRefs[binding] = null;
|
||||||
|
_bufferImageRefs[binding] = null;
|
||||||
|
_bufferImageFormats[binding] = default;
|
||||||
|
}
|
||||||
|
|
||||||
SignalDirty(DirtyFlags.Image);
|
SignalDirty(DirtyFlags.Image);
|
||||||
}
|
}
|
||||||
@ -215,24 +216,23 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void SetTextureAndSampler(CommandBufferScoped cbs, ShaderStage stage, int binding, ITexture texture, ISampler sampler)
|
public void SetTextureAndSampler(CommandBufferScoped cbs, ShaderStage stage, int binding, ITexture texture, ISampler sampler)
|
||||||
{
|
{
|
||||||
if (texture == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texture is TextureBuffer textureBuffer)
|
if (texture is TextureBuffer textureBuffer)
|
||||||
{
|
{
|
||||||
_bufferTextureRefs[binding] = textureBuffer;
|
_bufferTextureRefs[binding] = textureBuffer;
|
||||||
}
|
}
|
||||||
else
|
else if (texture is TextureView view)
|
||||||
{
|
{
|
||||||
TextureView view = (TextureView)texture;
|
|
||||||
|
|
||||||
view.Storage.InsertBarrier(cbs, AccessFlags.AccessShaderReadBit, stage.ConvertToPipelineStageFlags());
|
view.Storage.InsertBarrier(cbs, AccessFlags.AccessShaderReadBit, stage.ConvertToPipelineStageFlags());
|
||||||
|
|
||||||
_textureRefs[binding] = view.GetImageView();
|
_textureRefs[binding] = view.GetImageView();
|
||||||
_samplerRefs[binding] = ((SamplerHolder)sampler)?.GetSampler();
|
_samplerRefs[binding] = ((SamplerHolder)sampler)?.GetSampler();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_textureRefs[binding] = null;
|
||||||
|
_samplerRefs[binding] = null;
|
||||||
|
_bufferTextureRefs[binding] = null;
|
||||||
|
}
|
||||||
|
|
||||||
SignalDirty(DirtyFlags.Texture);
|
SignalDirty(DirtyFlags.Texture);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private readonly IProgram _programColorBlitClearAlpha;
|
private readonly IProgram _programColorBlitClearAlpha;
|
||||||
private readonly IProgram _programColorClear;
|
private readonly IProgram _programColorClear;
|
||||||
private readonly IProgram _programStrideChange;
|
private readonly IProgram _programStrideChange;
|
||||||
|
private readonly IProgram _programColorCopyBetweenMsNonMs;
|
||||||
|
|
||||||
public HelperShader(VulkanRenderer gd, Device device)
|
public HelperShader(VulkanRenderer gd, Device device)
|
||||||
{
|
{
|
||||||
@ -73,6 +74,20 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ChangeBufferStrideShaderSource, strideChangeBindings, ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ChangeBufferStrideShaderSource, strideChangeBindings, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var colorCopyMSBindings = new ShaderBindings(
|
||||||
|
new[] { 0 },
|
||||||
|
Array.Empty<int>(),
|
||||||
|
new[] { 0 },
|
||||||
|
new[] { 0 });
|
||||||
|
|
||||||
|
_programColorCopyBetweenMsNonMs = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
|
{
|
||||||
|
new ShaderSource(ShaderBinaries.ColorCopyBetweenMsNonMs, colorCopyMSBindings, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
|
}, new[]
|
||||||
|
{
|
||||||
|
new SpecDescription((0, SpecConstType.Int32))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Blit(
|
public void Blit(
|
||||||
@ -136,11 +151,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
|
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
|
||||||
|
|
||||||
Span<BufferRange> bufferRanges = stackalloc BufferRange[1];
|
_pipeline.SetUniformBuffers(1, stackalloc[] { new BufferRange(bufferHandle, 0, RegionBufferSize) });
|
||||||
|
|
||||||
bufferRanges[0] = new BufferRange(bufferHandle, 0, RegionBufferSize);
|
|
||||||
|
|
||||||
_pipeline.SetUniformBuffers(1, bufferRanges);
|
|
||||||
|
|
||||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||||
|
|
||||||
@ -203,11 +214,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
gd.BufferManager.SetData<float>(bufferHandle, 0, clearColor);
|
gd.BufferManager.SetData<float>(bufferHandle, 0, clearColor);
|
||||||
|
|
||||||
Span<BufferRange> bufferRanges = stackalloc BufferRange[1];
|
_pipeline.SetUniformBuffers(1, stackalloc[] { new BufferRange(bufferHandle, 0, ClearColorBufferSize) });
|
||||||
|
|
||||||
bufferRanges[0] = new BufferRange(bufferHandle, 0, ClearColorBufferSize);
|
|
||||||
|
|
||||||
_pipeline.SetUniformBuffers(1, bufferRanges);
|
|
||||||
|
|
||||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||||
|
|
||||||
@ -269,11 +276,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
|
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
|
||||||
|
|
||||||
Span<BufferRange> bufferRanges = stackalloc BufferRange[1];
|
pipeline.SetUniformBuffers(1, stackalloc[] { new BufferRange(bufferHandle, 0, RegionBufferSize) });
|
||||||
|
|
||||||
bufferRanges[0] = new BufferRange(bufferHandle, 0, RegionBufferSize);
|
|
||||||
|
|
||||||
pipeline.SetUniformBuffers(1, bufferRanges);
|
|
||||||
|
|
||||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||||
|
|
||||||
@ -351,11 +354,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
_pipeline.SetCommandBuffer(cbs);
|
_pipeline.SetCommandBuffer(cbs);
|
||||||
|
|
||||||
Span<BufferRange> cbRanges = stackalloc BufferRange[1];
|
_pipeline.SetUniformBuffers(0, stackalloc[] { new BufferRange(bufferHandle, 0, ParamsBufferSize) });
|
||||||
|
|
||||||
cbRanges[0] = new BufferRange(bufferHandle, 0, ParamsBufferSize);
|
|
||||||
|
|
||||||
_pipeline.SetUniformBuffers(0, cbRanges);
|
|
||||||
|
|
||||||
Span<Auto<DisposableBuffer>> sbRanges = new Auto<DisposableBuffer>[2];
|
Span<Auto<DisposableBuffer>> sbRanges = new Auto<DisposableBuffer>[2];
|
||||||
|
|
||||||
@ -480,12 +479,207 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
convertedCount * outputIndexSize);
|
convertedCount * outputIndexSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CopyMSToNonMS(VulkanRenderer gd, CommandBufferScoped cbs, TextureView src, TextureView dst, int srcLayer, int dstLayer, int depth)
|
||||||
|
{
|
||||||
|
CopyMS(gd, cbs, src, dst, srcLayer, dstLayer, depth, src.Info.Samples, dst.Info.Width, dst.Info.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyNonMSToMS(VulkanRenderer gd, CommandBufferScoped cbs, TextureView src, TextureView dst, int srcLayer, int dstLayer, int depth)
|
||||||
|
{
|
||||||
|
CopyMS(gd, cbs, src, dst, srcLayer, dstLayer, depth, dst.Info.Samples, src.Info.Width, src.Info.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CopyMS(
|
||||||
|
VulkanRenderer gd,
|
||||||
|
CommandBufferScoped cbs,
|
||||||
|
TextureView src,
|
||||||
|
TextureView dst,
|
||||||
|
int srcLayer,
|
||||||
|
int dstLayer,
|
||||||
|
int depth,
|
||||||
|
int samples,
|
||||||
|
int nonMSWidth,
|
||||||
|
int nonMSHeight)
|
||||||
|
{
|
||||||
|
const int ParamsBufferSize = 16;
|
||||||
|
|
||||||
|
Span<int> shaderParams = stackalloc int[ParamsBufferSize / sizeof(int)];
|
||||||
|
|
||||||
|
// X and Y are the expected texture samples.
|
||||||
|
// Z and W are the actual texture samples used.
|
||||||
|
// They may differ if the GPU does not support the samples count requested and we had to use a lower amount.
|
||||||
|
(shaderParams[0], shaderParams[1]) = GetSampleCountXYLog2(samples);
|
||||||
|
(shaderParams[2], shaderParams[3]) = GetSampleCountXYLog2((int)TextureStorage.ConvertToSampleCountFlags((uint)samples));
|
||||||
|
|
||||||
|
var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ParamsBufferSize, false);
|
||||||
|
|
||||||
|
gd.BufferManager.SetData<int>(bufferHandle, 0, shaderParams);
|
||||||
|
|
||||||
|
TextureView.InsertImageBarrier(
|
||||||
|
gd.Api,
|
||||||
|
cbs.CommandBuffer,
|
||||||
|
src.GetImage().Get(cbs).Value,
|
||||||
|
TextureStorage.DefaultAccessMask,
|
||||||
|
AccessFlags.AccessShaderReadBit,
|
||||||
|
PipelineStageFlags.PipelineStageAllCommandsBit,
|
||||||
|
PipelineStageFlags.PipelineStageComputeShaderBit,
|
||||||
|
ImageAspectFlags.ImageAspectColorBit,
|
||||||
|
src.FirstLayer + srcLayer,
|
||||||
|
src.FirstLevel,
|
||||||
|
depth,
|
||||||
|
1);
|
||||||
|
|
||||||
|
_pipeline.SetCommandBuffer(cbs);
|
||||||
|
|
||||||
|
_pipeline.SetProgram(_programColorCopyBetweenMsNonMs);
|
||||||
|
|
||||||
|
var format = GetFormat(src.Info.BytesPerPixel);
|
||||||
|
|
||||||
|
int dispatchX = (nonMSWidth + 31) / 32;
|
||||||
|
int dispatchY = (nonMSHeight + 31) / 32;
|
||||||
|
|
||||||
|
// Specialize shader.
|
||||||
|
bool srcIsMs = src.Info.Target.IsMultisample();
|
||||||
|
int conversionType = srcIsMs ? src.Info.BytesPerPixel : -src.Info.BytesPerPixel;
|
||||||
|
_pipeline.Specialize(conversionType);
|
||||||
|
|
||||||
|
_pipeline.SetUniformBuffers(0, stackalloc[] { new BufferRange(bufferHandle, 0, ParamsBufferSize) });
|
||||||
|
|
||||||
|
if (src.Info.Target == Target.Texture2DMultisampleArray ||
|
||||||
|
dst.Info.Target == Target.Texture2DMultisampleArray)
|
||||||
|
{
|
||||||
|
for (int z = 0; z < depth; z++)
|
||||||
|
{
|
||||||
|
var srcView = Create2DLayerView(src, srcLayer + z, format);
|
||||||
|
var dstView = Create2DLayerView(dst, dstLayer + z);
|
||||||
|
|
||||||
|
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 0, srcView, null);
|
||||||
|
_pipeline.SetImage(0, dstView, format);
|
||||||
|
|
||||||
|
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||||
|
|
||||||
|
srcView.Release();
|
||||||
|
dstView.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var srcView = Create2DLayerView(src, srcLayer, format);
|
||||||
|
|
||||||
|
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 0, srcView, null);
|
||||||
|
_pipeline.SetImage(0, dst, format);
|
||||||
|
|
||||||
|
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||||
|
|
||||||
|
srcView.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
gd.BufferManager.Delete(bufferHandle);
|
||||||
|
|
||||||
|
_pipeline.Finish(gd, cbs);
|
||||||
|
|
||||||
|
TextureView.InsertImageBarrier(
|
||||||
|
gd.Api,
|
||||||
|
cbs.CommandBuffer,
|
||||||
|
dst.GetImage().Get(cbs).Value,
|
||||||
|
AccessFlags.AccessShaderWriteBit,
|
||||||
|
TextureStorage.DefaultAccessMask,
|
||||||
|
PipelineStageFlags.PipelineStageComputeShaderBit,
|
||||||
|
PipelineStageFlags.PipelineStageAllCommandsBit,
|
||||||
|
ImageAspectFlags.ImageAspectColorBit,
|
||||||
|
dst.FirstLayer + dstLayer,
|
||||||
|
dst.FirstLevel,
|
||||||
|
depth,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static (int, int) GetSampleCountXYLog2(int samples)
|
||||||
|
{
|
||||||
|
int samplesInXLog2 = 0;
|
||||||
|
int samplesInYLog2 = 0;
|
||||||
|
|
||||||
|
switch (samples)
|
||||||
|
{
|
||||||
|
case 2: // 2x1
|
||||||
|
samplesInXLog2 = 1;
|
||||||
|
break;
|
||||||
|
case 4: // 2x2
|
||||||
|
samplesInXLog2 = 1;
|
||||||
|
samplesInYLog2 = 1;
|
||||||
|
break;
|
||||||
|
case 8: // 4x2
|
||||||
|
samplesInXLog2 = 2;
|
||||||
|
samplesInYLog2 = 1;
|
||||||
|
break;
|
||||||
|
case 16: // 4x4
|
||||||
|
samplesInXLog2 = 2;
|
||||||
|
samplesInYLog2 = 2;
|
||||||
|
break;
|
||||||
|
case 32: // 8x4
|
||||||
|
samplesInXLog2 = 3;
|
||||||
|
samplesInYLog2 = 2;
|
||||||
|
break;
|
||||||
|
case 64: // 8x8
|
||||||
|
samplesInXLog2 = 3;
|
||||||
|
samplesInYLog2 = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (samplesInXLog2, samplesInYLog2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ITexture Create2DLayerView(TextureView from, int layer, GAL.Format? format = null)
|
||||||
|
{
|
||||||
|
var target = from.Info.Target switch
|
||||||
|
{
|
||||||
|
Target.Texture1DArray => Target.Texture1D,
|
||||||
|
Target.Texture2DArray => Target.Texture2D,
|
||||||
|
Target.Texture2DMultisampleArray => Target.Texture2DMultisample,
|
||||||
|
_ => from.Info.Target
|
||||||
|
};
|
||||||
|
|
||||||
|
var info = new TextureCreateInfo(
|
||||||
|
from.Info.Width,
|
||||||
|
from.Info.Height,
|
||||||
|
from.Info.Depth,
|
||||||
|
1,
|
||||||
|
from.Info.Samples,
|
||||||
|
from.Info.BlockWidth,
|
||||||
|
from.Info.BlockHeight,
|
||||||
|
from.Info.BytesPerPixel,
|
||||||
|
format ?? from.Info.Format,
|
||||||
|
from.Info.DepthStencilMode,
|
||||||
|
target,
|
||||||
|
from.Info.SwizzleR,
|
||||||
|
from.Info.SwizzleG,
|
||||||
|
from.Info.SwizzleB,
|
||||||
|
from.Info.SwizzleA);
|
||||||
|
|
||||||
|
return from.CreateView(info, layer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GAL.Format GetFormat(int bytesPerPixel)
|
||||||
|
{
|
||||||
|
return bytesPerPixel switch
|
||||||
|
{
|
||||||
|
1 => GAL.Format.R8Uint,
|
||||||
|
2 => GAL.Format.R16Uint,
|
||||||
|
4 => GAL.Format.R32Uint,
|
||||||
|
8 => GAL.Format.R32G32Uint,
|
||||||
|
16 => GAL.Format.R32G32B32A32Uint,
|
||||||
|
_ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}.")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
_programColorBlitClearAlpha.Dispose();
|
_programColorBlitClearAlpha.Dispose();
|
||||||
_programColorBlit.Dispose();
|
_programColorBlit.Dispose();
|
||||||
|
_programColorClear.Dispose();
|
||||||
|
_programStrideChange.Dispose();
|
||||||
|
_programColorCopyBetweenMsNonMs.Dispose();
|
||||||
_samplerNearest.Dispose();
|
_samplerNearest.Dispose();
|
||||||
_samplerLinear.Dispose();
|
_samplerLinear.Dispose();
|
||||||
_pipeline.Dispose();
|
_pipeline.Dispose();
|
||||||
|
@ -3,6 +3,8 @@ using Ryujinx.Graphics.Shader;
|
|||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
@ -228,10 +230,26 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CommandBufferBarrier()
|
public unsafe void CommandBufferBarrier()
|
||||||
{
|
{
|
||||||
// TODO: More specific barrier?
|
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
||||||
Barrier();
|
{
|
||||||
|
SType = StructureType.MemoryBarrier,
|
||||||
|
SrcAccessMask = BufferHolder.DefaultAccessFlags,
|
||||||
|
DstAccessMask = AccessFlags.AccessIndirectCommandReadBit
|
||||||
|
};
|
||||||
|
|
||||||
|
Gd.Api.CmdPipelineBarrier(
|
||||||
|
CommandBuffer,
|
||||||
|
PipelineStageFlags.PipelineStageAllCommandsBit,
|
||||||
|
PipelineStageFlags.PipelineStageDrawIndirectBit,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
memoryBarrier,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
|
public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
|
||||||
@ -535,10 +553,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
vkBlend = new PipelineColorBlendAttachmentState();
|
vkBlend = new PipelineColorBlendAttachmentState();
|
||||||
}
|
}
|
||||||
|
|
||||||
_newState.BlendConstantR = blend.BlendConstant.Red;
|
DynamicState.SetBlendConstants(
|
||||||
_newState.BlendConstantG = blend.BlendConstant.Green;
|
blend.BlendConstant.Red,
|
||||||
_newState.BlendConstantB = blend.BlendConstant.Blue;
|
blend.BlendConstant.Green,
|
||||||
_newState.BlendConstantA = blend.BlendConstant.Alpha;
|
blend.BlendConstant.Blue,
|
||||||
|
blend.BlendConstant.Alpha);
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
@ -680,6 +699,18 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Specialize<T>(in T data) where T : unmanaged
|
||||||
|
{
|
||||||
|
var dataSpan = MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in data), 1));
|
||||||
|
|
||||||
|
if (!dataSpan.SequenceEqual(_newState.SpecializationData.Span))
|
||||||
|
{
|
||||||
|
_newState.SpecializationData = new SpecData(dataSpan);
|
||||||
|
|
||||||
|
SignalStateChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void SignalAttachmentChange()
|
protected virtual void SignalAttachmentChange()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -823,7 +854,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (range.Handle != BufferHandle.Null)
|
if (range.Handle != BufferHandle.Null)
|
||||||
{
|
{
|
||||||
_transformFeedbackBuffers[i] =
|
_transformFeedbackBuffers[i] =
|
||||||
new BufferState(Gd.BufferManager.GetBuffer(CommandBuffer, range.Handle, range.Offset, range.Size, true), range.Offset, range.Size);
|
new BufferState(Gd.BufferManager.GetBuffer(CommandBuffer, range.Handle, range.Offset, range.Size, true), range.Offset, range.Size);
|
||||||
_transformFeedbackBuffers[i].BindTransformFeedbackBuffer(Gd, Cbs, (uint)i);
|
_transformFeedbackBuffers[i].BindTransformFeedbackBuffer(Gd, Cbs, (uint)i);
|
||||||
}
|
}
|
||||||
@ -1171,14 +1202,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var subpassDependency = new SubpassDependency(
|
var subpassDependency = PipelineConverter.CreateSubpassDependency();
|
||||||
0,
|
|
||||||
0,
|
|
||||||
PipelineStageFlags.PipelineStageAllGraphicsBit,
|
|
||||||
PipelineStageFlags.PipelineStageAllGraphicsBit,
|
|
||||||
AccessFlags.AccessMemoryReadBit | AccessFlags.AccessMemoryWriteBit | AccessFlags.AccessColorAttachmentWriteBit,
|
|
||||||
AccessFlags.AccessMemoryReadBit | AccessFlags.AccessMemoryWriteBit | AccessFlags.AccessShaderReadBit,
|
|
||||||
0);
|
|
||||||
|
|
||||||
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
static class PipelineConverter
|
static class PipelineConverter
|
||||||
{
|
{
|
||||||
|
private const AccessFlags SubpassSrcAccessMask = AccessFlags.AccessMemoryReadBit | AccessFlags.AccessMemoryWriteBit | AccessFlags.AccessColorAttachmentWriteBit;
|
||||||
|
private const AccessFlags SubpassDstAccessMask = AccessFlags.AccessMemoryReadBit | AccessFlags.AccessMemoryWriteBit | AccessFlags.AccessShaderReadBit;
|
||||||
|
|
||||||
public static unsafe DisposableRenderPass ToRenderPass(this ProgramPipelineState state, VulkanRenderer gd, Device device)
|
public static unsafe DisposableRenderPass ToRenderPass(this ProgramPipelineState state, VulkanRenderer gd, Device device)
|
||||||
{
|
{
|
||||||
const int MaxAttachments = Constants.MaxRenderTargets + 1;
|
const int MaxAttachments = Constants.MaxRenderTargets + 1;
|
||||||
@ -100,14 +103,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var subpassDependency = new SubpassDependency(
|
var subpassDependency = CreateSubpassDependency();
|
||||||
0,
|
|
||||||
0,
|
|
||||||
PipelineStageFlags.PipelineStageAllGraphicsBit,
|
|
||||||
PipelineStageFlags.PipelineStageAllGraphicsBit,
|
|
||||||
AccessFlags.AccessMemoryReadBit | AccessFlags.AccessMemoryWriteBit,
|
|
||||||
AccessFlags.AccessMemoryReadBit | AccessFlags.AccessMemoryWriteBit,
|
|
||||||
0);
|
|
||||||
|
|
||||||
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
||||||
{
|
{
|
||||||
@ -128,6 +124,32 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SubpassDependency CreateSubpassDependency()
|
||||||
|
{
|
||||||
|
return new SubpassDependency(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
PipelineStageFlags.PipelineStageAllGraphicsBit,
|
||||||
|
PipelineStageFlags.PipelineStageAllGraphicsBit,
|
||||||
|
SubpassSrcAccessMask,
|
||||||
|
SubpassDstAccessMask,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe static SubpassDependency2 CreateSubpassDependency2()
|
||||||
|
{
|
||||||
|
return new SubpassDependency2(
|
||||||
|
StructureType.SubpassDependency2,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
PipelineStageFlags.PipelineStageAllGraphicsBit,
|
||||||
|
PipelineStageFlags.PipelineStageAllGraphicsBit,
|
||||||
|
SubpassSrcAccessMask,
|
||||||
|
SubpassDstAccessMask,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
public static PipelineState ToVulkanPipelineState(this ProgramPipelineState state, VulkanRenderer gd)
|
public static PipelineState ToVulkanPipelineState(this ProgramPipelineState state, VulkanRenderer gd)
|
||||||
{
|
{
|
||||||
PipelineState pipeline = new PipelineState();
|
PipelineState pipeline = new PipelineState();
|
||||||
@ -135,11 +157,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
// It is assumed that Dynamic State is enabled when this conversion is used.
|
// It is assumed that Dynamic State is enabled when this conversion is used.
|
||||||
|
|
||||||
pipeline.BlendConstantA = state.BlendDescriptors[0].BlendConstant.Alpha;
|
|
||||||
pipeline.BlendConstantB = state.BlendDescriptors[0].BlendConstant.Blue;
|
|
||||||
pipeline.BlendConstantG = state.BlendDescriptors[0].BlendConstant.Green;
|
|
||||||
pipeline.BlendConstantR = state.BlendDescriptors[0].BlendConstant.Red;
|
|
||||||
|
|
||||||
pipeline.CullMode = state.CullEnable ? state.CullMode.Convert() : CullModeFlags.CullModeNone;
|
pipeline.CullMode = state.CullEnable ? state.CullMode.Convert() : CullModeFlags.CullModeNone;
|
||||||
|
|
||||||
pipeline.DepthBoundsTestEnable = false; // Not implemented.
|
pipeline.DepthBoundsTestEnable = false; // Not implemented.
|
||||||
|
@ -19,21 +19,34 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private uint _frontWriteMask;
|
private uint _frontWriteMask;
|
||||||
private uint _frontReference;
|
private uint _frontReference;
|
||||||
|
|
||||||
|
private Array4<float> _blendConstants;
|
||||||
|
|
||||||
public int ViewportsCount;
|
public int ViewportsCount;
|
||||||
public Array16<Viewport> Viewports;
|
public Array16<Viewport> Viewports;
|
||||||
|
|
||||||
private enum DirtyFlags
|
private enum DirtyFlags
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
DepthBias = 1 << 0,
|
Blend = 1 << 0,
|
||||||
Scissor = 1 << 1,
|
DepthBias = 1 << 1,
|
||||||
Stencil = 1 << 2,
|
Scissor = 1 << 2,
|
||||||
Viewport = 1 << 3,
|
Stencil = 1 << 3,
|
||||||
All = DepthBias | Scissor | Stencil | Viewport
|
Viewport = 1 << 4,
|
||||||
|
All = Blend | DepthBias | Scissor | Stencil | Viewport
|
||||||
}
|
}
|
||||||
|
|
||||||
private DirtyFlags _dirty;
|
private DirtyFlags _dirty;
|
||||||
|
|
||||||
|
public void SetBlendConstants(float r, float g, float b, float a)
|
||||||
|
{
|
||||||
|
_blendConstants[0] = r;
|
||||||
|
_blendConstants[1] = g;
|
||||||
|
_blendConstants[2] = b;
|
||||||
|
_blendConstants[3] = a;
|
||||||
|
|
||||||
|
_dirty |= DirtyFlags.Blend;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetDepthBias(float slopeFactor, float constantFactor, float clamp)
|
public void SetDepthBias(float slopeFactor, float constantFactor, float clamp)
|
||||||
{
|
{
|
||||||
_depthBiasSlopeFactor = slopeFactor;
|
_depthBiasSlopeFactor = slopeFactor;
|
||||||
@ -87,6 +100,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void ReplayIfDirty(Vk api, CommandBuffer commandBuffer)
|
public void ReplayIfDirty(Vk api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
|
if (_dirty.HasFlag(DirtyFlags.Blend))
|
||||||
|
{
|
||||||
|
RecordBlend(api, commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
if (_dirty.HasFlag(DirtyFlags.DepthBias))
|
if (_dirty.HasFlag(DirtyFlags.DepthBias))
|
||||||
{
|
{
|
||||||
RecordDepthBias(api, commandBuffer);
|
RecordDepthBias(api, commandBuffer);
|
||||||
@ -110,6 +128,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_dirty = DirtyFlags.None;
|
_dirty = DirtyFlags.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RecordBlend(Vk api, CommandBuffer commandBuffer)
|
||||||
|
{
|
||||||
|
api.CmdSetBlendConstants(commandBuffer, _blendConstants.AsSpan());
|
||||||
|
}
|
||||||
|
|
||||||
private void RecordDepthBias(Vk api, CommandBuffer commandBuffer)
|
private void RecordDepthBias(Vk api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor);
|
api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor);
|
||||||
|
@ -81,237 +81,214 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
set => Internal.Id5 = (Internal.Id5 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
set => Internal.Id5 = (Internal.Id5 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float BlendConstantR
|
|
||||||
{
|
|
||||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id6 >> 0) & 0xFFFFFFFF));
|
|
||||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float BlendConstantG
|
|
||||||
{
|
|
||||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id6 >> 32) & 0xFFFFFFFF));
|
|
||||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float BlendConstantB
|
|
||||||
{
|
|
||||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id7 >> 0) & 0xFFFFFFFF));
|
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float BlendConstantA
|
|
||||||
{
|
|
||||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id7 >> 32) & 0xFFFFFFFF));
|
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PolygonMode PolygonMode
|
public PolygonMode PolygonMode
|
||||||
{
|
{
|
||||||
get => (PolygonMode)((Internal.Id8 >> 0) & 0x3FFFFFFF);
|
get => (PolygonMode)((Internal.Id6 >> 0) & 0x3FFFFFFF);
|
||||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFFC0000000) | ((ulong)value << 0);
|
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFFFC0000000) | ((ulong)value << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint StagesCount
|
public uint StagesCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id8 >> 30) & 0xFF);
|
get => (byte)((Internal.Id6 >> 30) & 0xFF);
|
||||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFC03FFFFFFF) | ((ulong)value << 30);
|
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFC03FFFFFFF) | ((ulong)value << 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint VertexAttributeDescriptionsCount
|
public uint VertexAttributeDescriptionsCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id8 >> 38) & 0xFF);
|
get => (byte)((Internal.Id6 >> 38) & 0xFF);
|
||||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFC03FFFFFFFFF) | ((ulong)value << 38);
|
set => Internal.Id6 = (Internal.Id6 & 0xFFFFC03FFFFFFFFF) | ((ulong)value << 38);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint VertexBindingDescriptionsCount
|
public uint VertexBindingDescriptionsCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id8 >> 46) & 0xFF);
|
get => (byte)((Internal.Id6 >> 46) & 0xFF);
|
||||||
set => Internal.Id8 = (Internal.Id8 & 0xFFC03FFFFFFFFFFF) | ((ulong)value << 46);
|
set => Internal.Id6 = (Internal.Id6 & 0xFFC03FFFFFFFFFFF) | ((ulong)value << 46);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint ViewportsCount
|
public uint ViewportsCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id8 >> 54) & 0xFF);
|
get => (byte)((Internal.Id6 >> 54) & 0xFF);
|
||||||
set => Internal.Id8 = (Internal.Id8 & 0xC03FFFFFFFFFFFFF) | ((ulong)value << 54);
|
set => Internal.Id6 = (Internal.Id6 & 0xC03FFFFFFFFFFFFF) | ((ulong)value << 54);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint ScissorsCount
|
public uint ScissorsCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id9 >> 0) & 0xFF);
|
get => (byte)((Internal.Id7 >> 0) & 0xFF);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFF00) | ((ulong)value << 0);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFFFFF00) | ((ulong)value << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint ColorBlendAttachmentStateCount
|
public uint ColorBlendAttachmentStateCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id9 >> 8) & 0xFF);
|
get => (byte)((Internal.Id7 >> 8) & 0xFF);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFF00FF) | ((ulong)value << 8);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFFF00FF) | ((ulong)value << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrimitiveTopology Topology
|
public PrimitiveTopology Topology
|
||||||
{
|
{
|
||||||
get => (PrimitiveTopology)((Internal.Id9 >> 16) & 0xF);
|
get => (PrimitiveTopology)((Internal.Id7 >> 16) & 0xF);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFF0FFFF) | ((ulong)value << 16);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFF0FFFF) | ((ulong)value << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LogicOp LogicOp
|
public LogicOp LogicOp
|
||||||
{
|
{
|
||||||
get => (LogicOp)((Internal.Id9 >> 20) & 0xF);
|
get => (LogicOp)((Internal.Id7 >> 20) & 0xF);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFF0FFFFF) | ((ulong)value << 20);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFF0FFFFF) | ((ulong)value << 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompareOp DepthCompareOp
|
public CompareOp DepthCompareOp
|
||||||
{
|
{
|
||||||
get => (CompareOp)((Internal.Id9 >> 24) & 0x7);
|
get => (CompareOp)((Internal.Id7 >> 24) & 0x7);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFF8FFFFFF) | ((ulong)value << 24);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFF8FFFFFF) | ((ulong)value << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilFrontFailOp
|
public StencilOp StencilFrontFailOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id9 >> 27) & 0x7);
|
get => (StencilOp)((Internal.Id7 >> 27) & 0x7);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFC7FFFFFF) | ((ulong)value << 27);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFC7FFFFFF) | ((ulong)value << 27);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilFrontPassOp
|
public StencilOp StencilFrontPassOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id9 >> 30) & 0x7);
|
get => (StencilOp)((Internal.Id7 >> 30) & 0x7);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFE3FFFFFFF) | ((ulong)value << 30);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFE3FFFFFFF) | ((ulong)value << 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilFrontDepthFailOp
|
public StencilOp StencilFrontDepthFailOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id9 >> 33) & 0x7);
|
get => (StencilOp)((Internal.Id7 >> 33) & 0x7);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFF1FFFFFFFF) | ((ulong)value << 33);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFF1FFFFFFFF) | ((ulong)value << 33);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompareOp StencilFrontCompareOp
|
public CompareOp StencilFrontCompareOp
|
||||||
{
|
{
|
||||||
get => (CompareOp)((Internal.Id9 >> 36) & 0x7);
|
get => (CompareOp)((Internal.Id7 >> 36) & 0x7);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFF8FFFFFFFFF) | ((ulong)value << 36);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFF8FFFFFFFFF) | ((ulong)value << 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilBackFailOp
|
public StencilOp StencilBackFailOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id9 >> 39) & 0x7);
|
get => (StencilOp)((Internal.Id7 >> 39) & 0x7);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFC7FFFFFFFFF) | ((ulong)value << 39);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFC7FFFFFFFFF) | ((ulong)value << 39);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilBackPassOp
|
public StencilOp StencilBackPassOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id9 >> 42) & 0x7);
|
get => (StencilOp)((Internal.Id7 >> 42) & 0x7);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFE3FFFFFFFFFF) | ((ulong)value << 42);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFE3FFFFFFFFFF) | ((ulong)value << 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilBackDepthFailOp
|
public StencilOp StencilBackDepthFailOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id9 >> 45) & 0x7);
|
get => (StencilOp)((Internal.Id7 >> 45) & 0x7);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFF1FFFFFFFFFFF) | ((ulong)value << 45);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFF1FFFFFFFFFFF) | ((ulong)value << 45);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompareOp StencilBackCompareOp
|
public CompareOp StencilBackCompareOp
|
||||||
{
|
{
|
||||||
get => (CompareOp)((Internal.Id9 >> 48) & 0x7);
|
get => (CompareOp)((Internal.Id7 >> 48) & 0x7);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFF8FFFFFFFFFFFF) | ((ulong)value << 48);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFF8FFFFFFFFFFFF) | ((ulong)value << 48);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CullModeFlags CullMode
|
public CullModeFlags CullMode
|
||||||
{
|
{
|
||||||
get => (CullModeFlags)((Internal.Id9 >> 51) & 0x3);
|
get => (CullModeFlags)((Internal.Id7 >> 51) & 0x3);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFE7FFFFFFFFFFFF) | ((ulong)value << 51);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFE7FFFFFFFFFFFF) | ((ulong)value << 51);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool PrimitiveRestartEnable
|
public bool PrimitiveRestartEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 53) & 0x1) != 0UL;
|
get => ((Internal.Id7 >> 53) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFDFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 53);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFDFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 53);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthClampEnable
|
public bool DepthClampEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 54) & 0x1) != 0UL;
|
get => ((Internal.Id7 >> 54) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFBFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 54);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFBFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 54);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RasterizerDiscardEnable
|
public bool RasterizerDiscardEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 55) & 0x1) != 0UL;
|
get => ((Internal.Id7 >> 55) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFF7FFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 55);
|
set => Internal.Id7 = (Internal.Id7 & 0xFF7FFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 55);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FrontFace FrontFace
|
public FrontFace FrontFace
|
||||||
{
|
{
|
||||||
get => (FrontFace)((Internal.Id9 >> 56) & 0x1);
|
get => (FrontFace)((Internal.Id7 >> 56) & 0x1);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFEFFFFFFFFFFFFFF) | ((ulong)value << 56);
|
set => Internal.Id7 = (Internal.Id7 & 0xFEFFFFFFFFFFFFFF) | ((ulong)value << 56);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthBiasEnable
|
public bool DepthBiasEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 57) & 0x1) != 0UL;
|
get => ((Internal.Id7 >> 57) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFDFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 57);
|
set => Internal.Id7 = (Internal.Id7 & 0xFDFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 57);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthTestEnable
|
public bool DepthTestEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 58) & 0x1) != 0UL;
|
get => ((Internal.Id7 >> 58) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFBFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 58);
|
set => Internal.Id7 = (Internal.Id7 & 0xFBFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 58);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthWriteEnable
|
public bool DepthWriteEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 59) & 0x1) != 0UL;
|
get => ((Internal.Id7 >> 59) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xF7FFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 59);
|
set => Internal.Id7 = (Internal.Id7 & 0xF7FFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 59);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthBoundsTestEnable
|
public bool DepthBoundsTestEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 60) & 0x1) != 0UL;
|
get => ((Internal.Id7 >> 60) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xEFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 60);
|
set => Internal.Id7 = (Internal.Id7 & 0xEFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StencilTestEnable
|
public bool StencilTestEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 61) & 0x1) != 0UL;
|
get => ((Internal.Id7 >> 61) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xDFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 61);
|
set => Internal.Id7 = (Internal.Id7 & 0xDFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 61);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LogicOpEnable
|
public bool LogicOpEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 62) & 0x1) != 0UL;
|
get => ((Internal.Id7 >> 62) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xBFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 62);
|
set => Internal.Id7 = (Internal.Id7 & 0xBFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 62);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasDepthStencil
|
public bool HasDepthStencil
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 63) & 0x1) != 0UL;
|
get => ((Internal.Id7 >> 63) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0x7FFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 63);
|
set => Internal.Id7 = (Internal.Id7 & 0x7FFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 63);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint PatchControlPoints
|
public uint PatchControlPoints
|
||||||
{
|
{
|
||||||
get => (uint)((Internal.Id10 >> 0) & 0xFFFFFFFF);
|
get => (uint)((Internal.Id8 >> 0) & 0xFFFFFFFF);
|
||||||
set => Internal.Id10 = (Internal.Id10 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint SamplesCount
|
public uint SamplesCount
|
||||||
{
|
{
|
||||||
get => (uint)((Internal.Id10 >> 32) & 0xFFFFFFFF);
|
get => (uint)((Internal.Id8 >> 32) & 0xFFFFFFFF);
|
||||||
set => Internal.Id10 = (Internal.Id10 & 0xFFFFFFFF) | ((ulong)value << 32);
|
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AlphaToCoverageEnable
|
public bool AlphaToCoverageEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id11 >> 0) & 0x1) != 0UL;
|
get => ((Internal.Id9 >> 0) & 0x1) != 0UL;
|
||||||
set => Internal.Id11 = (Internal.Id11 & 0xFFFFFFFFFFFFFFFE) | ((value ? 1UL : 0UL) << 0);
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFE) | ((value ? 1UL : 0UL) << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AlphaToOneEnable
|
public bool AlphaToOneEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id11 >> 1) & 0x1) != 0UL;
|
get => ((Internal.Id9 >> 1) & 0x1) != 0UL;
|
||||||
set => Internal.Id11 = (Internal.Id11 & 0xFFFFFFFFFFFFFFFD) | ((value ? 1UL : 0UL) << 1);
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFD) | ((value ? 1UL : 0UL) << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NativeArray<PipelineShaderStageCreateInfo> Stages;
|
public NativeArray<PipelineShaderStageCreateInfo> Stages;
|
||||||
public NativeArray<PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT> StageRequiredSubgroupSizes;
|
public NativeArray<PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT> StageRequiredSubgroupSizes;
|
||||||
public PipelineLayout PipelineLayout;
|
public PipelineLayout PipelineLayout;
|
||||||
|
public SpecData SpecializationData;
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
@ -334,7 +311,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ShaderCollection program,
|
ShaderCollection program,
|
||||||
PipelineCache cache)
|
PipelineCache cache)
|
||||||
{
|
{
|
||||||
if (program.TryGetComputePipeline(out var pipeline))
|
if (program.TryGetComputePipeline(ref SpecializationData, out var pipeline))
|
||||||
{
|
{
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
@ -354,20 +331,36 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Pipeline pipelineHandle = default;
|
Pipeline pipelineHandle = default;
|
||||||
|
|
||||||
gd.Api.CreateComputePipelines(device, cache, 1, &pipelineCreateInfo, null, &pipelineHandle).ThrowOnError();
|
bool hasSpec = program.SpecDescriptions != null;
|
||||||
|
|
||||||
|
var desc = hasSpec ? program.SpecDescriptions[0] : SpecDescription.Empty;
|
||||||
|
|
||||||
|
if (hasSpec && SpecializationData.Length < (int)desc.Info.DataSize)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Specialization data size does not match description");
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed (SpecializationInfo* info = &desc.Info)
|
||||||
|
fixed (SpecializationMapEntry* map = desc.Map)
|
||||||
|
fixed (byte* data = SpecializationData.Span)
|
||||||
|
{
|
||||||
|
if (hasSpec)
|
||||||
|
{
|
||||||
|
info->PMapEntries = map;
|
||||||
|
info->PData = data;
|
||||||
|
pipelineCreateInfo.Stage.PSpecializationInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
gd.Api.CreateComputePipelines(device, cache, 1, &pipelineCreateInfo, null, &pipelineHandle).ThrowOnError();
|
||||||
|
}
|
||||||
|
|
||||||
pipeline = new Auto<DisposablePipeline>(new DisposablePipeline(gd.Api, device, pipelineHandle));
|
pipeline = new Auto<DisposablePipeline>(new DisposablePipeline(gd.Api, device, pipelineHandle));
|
||||||
|
|
||||||
program.AddComputePipeline(pipeline);
|
program.AddComputePipeline(ref SpecializationData, pipeline);
|
||||||
|
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void DestroyComputePipeline(ShaderCollection program)
|
|
||||||
{
|
|
||||||
program.RemoveComputePipeline();
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe Auto<DisposablePipeline> CreateGraphicsPipeline(
|
public unsafe Auto<DisposablePipeline> CreateGraphicsPipeline(
|
||||||
VulkanRenderer gd,
|
VulkanRenderer gd,
|
||||||
Device device,
|
Device device,
|
||||||
@ -493,13 +486,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PAttachments = pColorBlendAttachmentState
|
PAttachments = pColorBlendAttachmentState
|
||||||
};
|
};
|
||||||
|
|
||||||
colorBlendState.BlendConstants[0] = BlendConstantR;
|
|
||||||
colorBlendState.BlendConstants[1] = BlendConstantG;
|
|
||||||
colorBlendState.BlendConstants[2] = BlendConstantB;
|
|
||||||
colorBlendState.BlendConstants[3] = BlendConstantA;
|
|
||||||
|
|
||||||
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
|
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
|
||||||
int dynamicStatesCount = supportsExtDynamicState ? 8 : 7;
|
int dynamicStatesCount = supportsExtDynamicState ? 9 : 8;
|
||||||
|
|
||||||
DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount];
|
DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount];
|
||||||
|
|
||||||
@ -510,10 +498,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dynamicStates[4] = DynamicState.StencilCompareMask;
|
dynamicStates[4] = DynamicState.StencilCompareMask;
|
||||||
dynamicStates[5] = DynamicState.StencilWriteMask;
|
dynamicStates[5] = DynamicState.StencilWriteMask;
|
||||||
dynamicStates[6] = DynamicState.StencilReference;
|
dynamicStates[6] = DynamicState.StencilReference;
|
||||||
|
dynamicStates[7] = DynamicState.BlendConstants;
|
||||||
|
|
||||||
if (supportsExtDynamicState)
|
if (supportsExtDynamicState)
|
||||||
{
|
{
|
||||||
dynamicStates[7] = DynamicState.VertexInputBindingStrideExt;
|
dynamicStates[8] = DynamicState.VertexInputBindingStrideExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo()
|
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo()
|
||||||
|
@ -21,15 +21,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public ulong Id8;
|
public ulong Id8;
|
||||||
public ulong Id9;
|
public ulong Id9;
|
||||||
public ulong Id10;
|
|
||||||
public ulong Id11;
|
|
||||||
|
|
||||||
private uint VertexAttributeDescriptionsCount => (byte)((Id8 >> 38) & 0xFF);
|
private uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
||||||
private uint VertexBindingDescriptionsCount => (byte)((Id8 >> 46) & 0xFF);
|
private uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
||||||
private uint ViewportsCount => (byte)((Id8 >> 54) & 0xFF);
|
private uint ViewportsCount => (byte)((Id6 >> 54) & 0xFF);
|
||||||
private uint ScissorsCount => (byte)((Id9 >> 0) & 0xFF);
|
private uint ScissorsCount => (byte)((Id7 >> 0) & 0xFF);
|
||||||
private uint ColorBlendAttachmentStateCount => (byte)((Id9 >> 8) & 0xFF);
|
private uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
||||||
private bool HasDepthStencil => ((Id9 >> 63) & 0x1) != 0UL;
|
private bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
||||||
|
|
||||||
public Array32<VertexInputAttributeDescription> VertexAttributeDescriptions;
|
public Array32<VertexInputAttributeDescription> VertexAttributeDescriptions;
|
||||||
public Array33<VertexInputBindingDescription> VertexBindingDescriptions;
|
public Array33<VertexInputBindingDescription> VertexBindingDescriptions;
|
||||||
@ -47,7 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (!Unsafe.As<ulong, Vector256<byte>>(ref Id0).Equals(Unsafe.As<ulong, Vector256<byte>>(ref other.Id0)) ||
|
if (!Unsafe.As<ulong, Vector256<byte>>(ref Id0).Equals(Unsafe.As<ulong, Vector256<byte>>(ref other.Id0)) ||
|
||||||
!Unsafe.As<ulong, Vector256<byte>>(ref Id4).Equals(Unsafe.As<ulong, Vector256<byte>>(ref other.Id4)) ||
|
!Unsafe.As<ulong, Vector256<byte>>(ref Id4).Equals(Unsafe.As<ulong, Vector256<byte>>(ref other.Id4)) ||
|
||||||
!Unsafe.As<ulong, Vector256<byte>>(ref Id8).Equals(Unsafe.As<ulong, Vector256<byte>>(ref other.Id8)))
|
!Unsafe.As<ulong, Vector128<byte>>(ref Id8).Equals(Unsafe.As<ulong, Vector128<byte>>(ref other.Id8)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -91,9 +89,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Id6 * 23 ^
|
Id6 * 23 ^
|
||||||
Id7 * 23 ^
|
Id7 * 23 ^
|
||||||
Id8 * 23 ^
|
Id8 * 23 ^
|
||||||
Id9 * 23 ^
|
Id9 * 23;
|
||||||
Id10 * 23 ^
|
|
||||||
Id11 * 23;
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)VertexAttributeDescriptionsCount; i++)
|
for (int i = 0; i < (int)VertexAttributeDescriptionsCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
|
@ -26,6 +26,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public ProgramLinkStatus LinkStatus { get; private set; }
|
public ProgramLinkStatus LinkStatus { get; private set; }
|
||||||
|
|
||||||
|
public readonly SpecDescription[] SpecDescriptions;
|
||||||
|
|
||||||
public bool IsLinked
|
public bool IsLinked
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -40,7 +42,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
|
|
||||||
private HashTableSlim<PipelineUid, Auto<DisposablePipeline>> _graphicsPipelineCache;
|
private HashTableSlim<PipelineUid, Auto<DisposablePipeline>> _graphicsPipelineCache;
|
||||||
private Auto<DisposablePipeline> _computePipeline;
|
private HashTableSlim<SpecData, Auto<DisposablePipeline>> _computePipelineCache;
|
||||||
|
|
||||||
private VulkanRenderer _gd;
|
private VulkanRenderer _gd;
|
||||||
private Device _device;
|
private Device _device;
|
||||||
@ -52,17 +54,24 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private Task _compileTask;
|
private Task _compileTask;
|
||||||
private bool _firstBackgroundUse;
|
private bool _firstBackgroundUse;
|
||||||
|
|
||||||
public ShaderCollection(VulkanRenderer gd, Device device, ShaderSource[] shaders, bool isMinimal = false)
|
public ShaderCollection(VulkanRenderer gd, Device device, ShaderSource[] shaders, SpecDescription[] specDescription = null, bool isMinimal = false)
|
||||||
{
|
{
|
||||||
_gd = gd;
|
_gd = gd;
|
||||||
_device = device;
|
_device = device;
|
||||||
|
|
||||||
|
if (specDescription != null && specDescription.Length != shaders.Length)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"{nameof(specDescription)} array length must match {nameof(shaders)} array if provided");
|
||||||
|
}
|
||||||
|
|
||||||
gd.Shaders.Add(this);
|
gd.Shaders.Add(this);
|
||||||
|
|
||||||
var internalShaders = new Shader[shaders.Length];
|
var internalShaders = new Shader[shaders.Length];
|
||||||
|
|
||||||
_infos = new PipelineShaderStageCreateInfo[shaders.Length];
|
_infos = new PipelineShaderStageCreateInfo[shaders.Length];
|
||||||
|
|
||||||
|
SpecDescriptions = specDescription;
|
||||||
|
|
||||||
LinkStatus = ProgramLinkStatus.Incomplete;
|
LinkStatus = ProgramLinkStatus.Incomplete;
|
||||||
|
|
||||||
uint stages = 0;
|
uint stages = 0;
|
||||||
@ -314,14 +323,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddComputePipeline(Auto<DisposablePipeline> pipeline)
|
public void AddComputePipeline(ref SpecData key, Auto<DisposablePipeline> pipeline)
|
||||||
{
|
{
|
||||||
_computePipeline = pipeline;
|
(_computePipelineCache ??= new()).Add(ref key, pipeline);
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveComputePipeline()
|
|
||||||
{
|
|
||||||
_computePipeline = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddGraphicsPipeline(ref PipelineUid key, Auto<DisposablePipeline> pipeline)
|
public void AddGraphicsPipeline(ref PipelineUid key, Auto<DisposablePipeline> pipeline)
|
||||||
@ -329,10 +333,20 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
(_graphicsPipelineCache ??= new()).Add(ref key, pipeline);
|
(_graphicsPipelineCache ??= new()).Add(ref key, pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetComputePipeline(out Auto<DisposablePipeline> pipeline)
|
public bool TryGetComputePipeline(ref SpecData key, out Auto<DisposablePipeline> pipeline)
|
||||||
{
|
{
|
||||||
pipeline = _computePipeline;
|
if (_computePipelineCache == null)
|
||||||
return pipeline != null;
|
{
|
||||||
|
pipeline = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_computePipelineCache.TryGetValue(ref key, out pipeline))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetGraphicsPipeline(ref PipelineUid key, out Auto<DisposablePipeline> pipeline)
|
public bool TryGetGraphicsPipeline(ref PipelineUid key, out Auto<DisposablePipeline> pipeline)
|
||||||
@ -390,7 +404,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_computePipeline?.Dispose();
|
if (_computePipelineCache != null)
|
||||||
|
{
|
||||||
|
foreach (Auto<DisposablePipeline> pipeline in _computePipelineCache.Values)
|
||||||
|
{
|
||||||
|
pipeline.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_dummyRenderPass.Value.Handle != 0)
|
if (_dummyRenderPass.Value.Handle != 0)
|
||||||
{
|
{
|
||||||
_dummyRenderPass.Dispose();
|
_dummyRenderPass.Dispose();
|
||||||
|
89
Ryujinx.Graphics.Vulkan/Shaders/ColorCopyBetweenMsNonMs.comp
Normal file
89
Ryujinx.Graphics.Vulkan/Shaders/ColorCopyBetweenMsNonMs.comp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#version 450 core
|
||||||
|
|
||||||
|
// +ve for MsToNonMs, -ve for reverse
|
||||||
|
layout (constant_id = 0) const int convType = 0;
|
||||||
|
|
||||||
|
layout (std140, binding = 0) uniform sample_counts_log2_in
|
||||||
|
{
|
||||||
|
ivec4 sample_counts_log2;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define R8_ID 1
|
||||||
|
#define R16_ID 2
|
||||||
|
#define R32_ID 4
|
||||||
|
#define RG32_ID 8
|
||||||
|
#define RGBA32_ID 16
|
||||||
|
|
||||||
|
#define R8_TYPE r8ui
|
||||||
|
#define R16_TYPE r16ui
|
||||||
|
#define R32_TYPE r32ui
|
||||||
|
#define RG32_TYPE rg32ui
|
||||||
|
#define RGBA32_TYPE rgba32ui
|
||||||
|
|
||||||
|
#define DECLARE_BINDINGS(type) layout (set = 3, binding = 0, type##_TYPE) uniform uimage2DMS dstMS ## type; \
|
||||||
|
layout (set = 3, binding = 0, type##_TYPE) uniform uimage2D dst ## type;
|
||||||
|
|
||||||
|
#define CASE_SIZE(type) case type##_ID: imageSz = imageSize(dst ## type); break;
|
||||||
|
|
||||||
|
#define CASE_CONVERT(type) case type##_ID: imageStore(dst ## type, ivec2(coords), texelFetch(srcMS, shiftedCoords, sampleIdx)); break; \
|
||||||
|
case -type##_ID: imageStore(dstMS ## type, shiftedCoords, sampleIdx, texelFetch(src, ivec2(coords), 0)); break;
|
||||||
|
|
||||||
|
// src tex
|
||||||
|
layout (set = 2, binding = 0) uniform usampler2DMS srcMS;
|
||||||
|
layout (set = 2, binding = 0) uniform usampler2D src;
|
||||||
|
|
||||||
|
// dst img
|
||||||
|
DECLARE_BINDINGS(R8)
|
||||||
|
DECLARE_BINDINGS(R16)
|
||||||
|
DECLARE_BINDINGS(R32)
|
||||||
|
DECLARE_BINDINGS(RG32)
|
||||||
|
DECLARE_BINDINGS(RGBA32)
|
||||||
|
|
||||||
|
layout (local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
uvec2 coords = gl_GlobalInvocationID.xy;
|
||||||
|
|
||||||
|
ivec2 imageSz = ivec2(0, 0);
|
||||||
|
|
||||||
|
switch (convType)
|
||||||
|
{
|
||||||
|
case 0: break;
|
||||||
|
CASE_SIZE(R8 )
|
||||||
|
CASE_SIZE(R16 )
|
||||||
|
CASE_SIZE(R32 )
|
||||||
|
CASE_SIZE(RG32 )
|
||||||
|
CASE_SIZE(RGBA32)
|
||||||
|
default:
|
||||||
|
imageSz = textureSize(src, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int(coords.x) >= imageSz.x || int(coords.y) >= imageSz.y)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int deltaX = sample_counts_log2.x - sample_counts_log2.z;
|
||||||
|
int deltaY = sample_counts_log2.y - sample_counts_log2.w;
|
||||||
|
int samplesInXLog2 = sample_counts_log2.z;
|
||||||
|
int samplesInYLog2 = sample_counts_log2.w;
|
||||||
|
int samplesInX = 1 << samplesInXLog2;
|
||||||
|
int samplesInY = 1 << samplesInYLog2;
|
||||||
|
int sampleIdx = ((int(coords.x) >> deltaX) & (samplesInX - 1)) | (((int(coords.y) >> deltaY) & (samplesInY - 1)) << samplesInXLog2);
|
||||||
|
|
||||||
|
samplesInXLog2 = sample_counts_log2.x;
|
||||||
|
samplesInYLog2 = sample_counts_log2.y;
|
||||||
|
|
||||||
|
ivec2 shiftedCoords = ivec2(int(coords.x) >> samplesInXLog2, int(coords.y) >> samplesInYLog2);
|
||||||
|
|
||||||
|
switch (convType)
|
||||||
|
{
|
||||||
|
CASE_CONVERT(R8 )
|
||||||
|
CASE_CONVERT(R16 )
|
||||||
|
CASE_CONVERT(R32 )
|
||||||
|
CASE_CONVERT(RG32 )
|
||||||
|
CASE_CONVERT(RGBA32)
|
||||||
|
}
|
||||||
|
}
|
@ -551,5 +551,324 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
|||||||
0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
|
0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
|
||||||
0x35, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x35, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static readonly byte[] ColorCopyBetweenMsNonMs = new byte[]
|
||||||
|
{
|
||||||
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x2D, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
|
0x1B, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x31, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
|
0x32, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||||
|
0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x03, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||||
|
0x10, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0xC2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x47,
|
||||||
|
0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x49, 0x6E, 0x76, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x49,
|
||||||
|
0x44, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x63, 0x6F, 0x6E, 0x76,
|
||||||
|
0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x64, 0x73, 0x74, 0x52, 0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00,
|
||||||
|
0x64, 0x73, 0x74, 0x52, 0x31, 0x36, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x2D, 0x00, 0x00, 0x00,
|
||||||
|
0x64, 0x73, 0x74, 0x52, 0x33, 0x32, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x33, 0x00, 0x00, 0x00,
|
||||||
|
0x64, 0x73, 0x74, 0x52, 0x47, 0x33, 0x32, 0x00, 0x05, 0x00, 0x05, 0x00, 0x39, 0x00, 0x00, 0x00,
|
||||||
|
0x64, 0x73, 0x74, 0x52, 0x47, 0x42, 0x41, 0x33, 0x32, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
|
||||||
|
0x40, 0x00, 0x00, 0x00, 0x73, 0x72, 0x63, 0x00, 0x05, 0x00, 0x08, 0x00, 0x60, 0x00, 0x00, 0x00,
|
||||||
|
0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x5F, 0x63, 0x6F, 0x75, 0x6E, 0x74, 0x73, 0x5F, 0x6C, 0x6F,
|
||||||
|
0x67, 0x32, 0x5F, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x60, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x5F, 0x63, 0x6F, 0x75, 0x6E, 0x74,
|
||||||
|
0x73, 0x5F, 0x6C, 0x6F, 0x67, 0x32, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x62, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0xB3, 0x00, 0x00, 0x00, 0x73, 0x72, 0x63, 0x4D,
|
||||||
|
0x53, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x64, 0x73, 0x74, 0x4D,
|
||||||
|
0x53, 0x52, 0x38, 0x00, 0x05, 0x00, 0x05, 0x00, 0xD2, 0x00, 0x00, 0x00, 0x64, 0x73, 0x74, 0x4D,
|
||||||
|
0x53, 0x52, 0x31, 0x36, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0xE7, 0x00, 0x00, 0x00,
|
||||||
|
0x64, 0x73, 0x74, 0x4D, 0x53, 0x52, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
|
||||||
|
0xFC, 0x00, 0x00, 0x00, 0x64, 0x73, 0x74, 0x4D, 0x53, 0x52, 0x47, 0x33, 0x32, 0x00, 0x00, 0x00,
|
||||||
|
0x05, 0x00, 0x05, 0x00, 0x11, 0x01, 0x00, 0x00, 0x64, 0x73, 0x74, 0x4D, 0x53, 0x52, 0x47, 0x42,
|
||||||
|
0x41, 0x33, 0x32, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
|
||||||
|
0x1C, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x33, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x33, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x39, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x39, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x60, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x62, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x62, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xB3, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xB3, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xD2, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xD2, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xE7, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xE7, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x11, 0x01, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x11, 0x01, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1D, 0x01, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
|
||||||
|
0x19, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||||
|
0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||||
|
0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00,
|
||||||
|
0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||||
|
0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x32, 0x00, 0x04, 0x00,
|
||||||
|
0x0F, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00,
|
||||||
|
0x1F, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
|
||||||
|
0x3B, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x19, 0x00, 0x09, 0x00, 0x25, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x26, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x25, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x2C, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x2C, 0x00, 0x00, 0x00,
|
||||||
|
0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x31, 0x00, 0x00, 0x00,
|
||||||
|
0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||||
|
0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||||
|
0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00,
|
||||||
|
0x37, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x00, 0x04, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
|
||||||
|
0x3B, 0x00, 0x04, 0x00, 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x19, 0x00, 0x09, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x00, 0x04, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||||
|
0x3B, 0x00, 0x04, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x02, 0x00, 0x46, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x53, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x5F, 0x00, 0x00, 0x00,
|
||||||
|
0x0F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x03, 0x00, 0x60, 0x00, 0x00, 0x00,
|
||||||
|
0x5F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x60, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x61, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x0F, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6D, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00, 0xB1, 0x00, 0x00, 0x00,
|
||||||
|
0xB0, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xB1, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0xB2, 0x00, 0x00, 0x00, 0xB3, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xBC, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0xBC, 0x00, 0x00, 0x00,
|
||||||
|
0xBD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0xD0, 0x00, 0x00, 0x00,
|
||||||
|
0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||||
|
0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||||
|
0xD1, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00,
|
||||||
|
0xE5, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x00, 0x04, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE5, 0x00, 0x00, 0x00,
|
||||||
|
0x3B, 0x00, 0x04, 0x00, 0xE6, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x19, 0x00, 0x09, 0x00, 0xFA, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x23, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xFA, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0xFB, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x10, 0x01, 0x00, 0x00,
|
||||||
|
0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x1C, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||||
|
0x1D, 0x01, 0x00, 0x00, 0x1C, 0x01, 0x00, 0x00, 0x1C, 0x01, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00,
|
||||||
|
0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00,
|
||||||
|
0x1E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0x00, 0x03, 0x00, 0x47, 0x00, 0x00, 0x00,
|
||||||
|
0x1F, 0x01, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x1F, 0x01, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x07, 0x00,
|
||||||
|
0x07, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xFB, 0x00, 0x0F, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
|
||||||
|
0xF8, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||||
|
0x41, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x3D, 0x00, 0x00, 0x00,
|
||||||
|
0x42, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x67, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x43, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0x1D, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x16, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0x1D, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x1F, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x68, 0x00, 0x04, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0x1D, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x18, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x25, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x68, 0x00, 0x04, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0x1D, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x2B, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x68, 0x00, 0x04, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0x1D, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x31, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x68, 0x00, 0x04, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0x1D, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x37, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x68, 0x00, 0x04, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0x1D, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x1D, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x11, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
|
||||||
|
0x29, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
|
||||||
|
0x35, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
|
||||||
|
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00,
|
||||||
|
0x4A, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x00,
|
||||||
|
0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x05, 0x00, 0x46, 0x00, 0x00, 0x00,
|
||||||
|
0x4F, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x04, 0x00,
|
||||||
|
0x46, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00,
|
||||||
|
0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x50, 0x00, 0x00, 0x00,
|
||||||
|
0x51, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x51, 0x00, 0x00, 0x00,
|
||||||
|
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
|
||||||
|
0x55, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
|
||||||
|
0x2C, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x05, 0x00, 0x46, 0x00, 0x00, 0x00,
|
||||||
|
0x59, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0x52, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x52, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x07, 0x00,
|
||||||
|
0x46, 0x00, 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||||
|
0x59, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x5C, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00,
|
||||||
|
0x5C, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x5B, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0x1E, 0x01, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
|
||||||
|
0x63, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
|
||||||
|
0x47, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
|
||||||
|
0x64, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x63, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00,
|
||||||
|
0x62, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x0F, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x82, 0x00, 0x05, 0x00,
|
||||||
|
0x0F, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
|
||||||
|
0x41, 0x00, 0x06, 0x00, 0x63, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
|
||||||
|
0x13, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||||
|
0x6C, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x63, 0x00, 0x00, 0x00,
|
||||||
|
0x6E, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6D, 0x00, 0x00, 0x00,
|
||||||
|
0x3D, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00,
|
||||||
|
0x82, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||||
|
0x6F, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00,
|
||||||
|
0x78, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||||
|
0x7D, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x05, 0x00,
|
||||||
|
0x0F, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00,
|
||||||
|
0x82, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00,
|
||||||
|
0x78, 0x00, 0x00, 0x00, 0xC7, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00,
|
||||||
|
0x83, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x88, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00,
|
||||||
|
0x0F, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x05, 0x00,
|
||||||
|
0x0F, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||||
|
0x82, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00,
|
||||||
|
0x78, 0x00, 0x00, 0x00, 0xC7, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x00,
|
||||||
|
0x8B, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||||
|
0x90, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0xC5, 0x00, 0x05, 0x00,
|
||||||
|
0x0F, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,
|
||||||
|
0xC3, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x9B, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00,
|
||||||
|
0x65, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00,
|
||||||
|
0x89, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0xA1, 0x00, 0x00, 0x00, 0x9B, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00,
|
||||||
|
0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0x00, 0x17, 0x00, 0x15, 0x00, 0x00, 0x00,
|
||||||
|
0xAC, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xA3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xA5, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xA6, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xA7, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xA9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xAB, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0xA2, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x1F, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0xB1, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0xB3, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00,
|
||||||
|
0xB0, 0x00, 0x00, 0x00, 0xB7, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00,
|
||||||
|
0xB8, 0x00, 0x00, 0x00, 0xB9, 0x00, 0x00, 0x00, 0xB7, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00,
|
||||||
|
0x40, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x63, 0x00, 0x04, 0x00, 0xAD, 0x00, 0x00, 0x00,
|
||||||
|
0xAF, 0x00, 0x00, 0x00, 0xB9, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0xAC, 0x00, 0x00, 0x00,
|
||||||
|
0xF8, 0x00, 0x02, 0x00, 0xA3, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0xBB, 0x00, 0x00, 0x00,
|
||||||
|
0xBE, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||||
|
0xC1, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0xC3, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x3D, 0x00, 0x00, 0x00,
|
||||||
|
0xC4, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00, 0xB8, 0x00, 0x00, 0x00,
|
||||||
|
0xC5, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x13, 0x00, 0x00, 0x00, 0x63, 0x00, 0x06, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00,
|
||||||
|
0xC5, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0xAC, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0xA4, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x25, 0x00, 0x00, 0x00, 0xC7, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0xC9, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0xB1, 0x00, 0x00, 0x00, 0xCA, 0x00, 0x00, 0x00, 0xB3, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00,
|
||||||
|
0xB0, 0x00, 0x00, 0x00, 0xCD, 0x00, 0x00, 0x00, 0xCA, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00,
|
||||||
|
0xB8, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0xCD, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00,
|
||||||
|
0x40, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x63, 0x00, 0x04, 0x00, 0xC7, 0x00, 0x00, 0x00,
|
||||||
|
0xC9, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0xAC, 0x00, 0x00, 0x00,
|
||||||
|
0xF8, 0x00, 0x02, 0x00, 0xA5, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0xD0, 0x00, 0x00, 0x00,
|
||||||
|
0xD3, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||||
|
0xD6, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0xD8, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x3D, 0x00, 0x00, 0x00,
|
||||||
|
0xD9, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00, 0xB8, 0x00, 0x00, 0x00,
|
||||||
|
0xDA, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x13, 0x00, 0x00, 0x00, 0x63, 0x00, 0x06, 0x00, 0xD3, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00,
|
||||||
|
0xDA, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0xAC, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0xA6, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x2B, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0xB1, 0x00, 0x00, 0x00, 0xDF, 0x00, 0x00, 0x00, 0xB3, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00,
|
||||||
|
0xB0, 0x00, 0x00, 0x00, 0xE2, 0x00, 0x00, 0x00, 0xDF, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00,
|
||||||
|
0xB8, 0x00, 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0xE2, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00,
|
||||||
|
0x40, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x63, 0x00, 0x04, 0x00, 0xDC, 0x00, 0x00, 0x00,
|
||||||
|
0xDE, 0x00, 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0xAC, 0x00, 0x00, 0x00,
|
||||||
|
0xF8, 0x00, 0x02, 0x00, 0xA7, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0xE5, 0x00, 0x00, 0x00,
|
||||||
|
0xE8, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||||
|
0xEB, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0xED, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x3D, 0x00, 0x00, 0x00,
|
||||||
|
0xEE, 0x00, 0x00, 0x00, 0xEB, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00, 0xB8, 0x00, 0x00, 0x00,
|
||||||
|
0xEF, 0x00, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00, 0xED, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x13, 0x00, 0x00, 0x00, 0x63, 0x00, 0x06, 0x00, 0xE8, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00,
|
||||||
|
0xEF, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0xAC, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x31, 0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0xF3, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0xB1, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00, 0xB3, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00,
|
||||||
|
0xB0, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00,
|
||||||
|
0xB8, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00,
|
||||||
|
0x40, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x63, 0x00, 0x04, 0x00, 0xF1, 0x00, 0x00, 0x00,
|
||||||
|
0xF3, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0xAC, 0x00, 0x00, 0x00,
|
||||||
|
0xF8, 0x00, 0x02, 0x00, 0xA9, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0xFA, 0x00, 0x00, 0x00,
|
||||||
|
0xFD, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x01, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x3D, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00, 0xB8, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x13, 0x00, 0x00, 0x00, 0x63, 0x00, 0x06, 0x00, 0xFD, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0xAC, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0x37, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||||
|
0xB1, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0xB3, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00,
|
||||||
|
0xB0, 0x00, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00,
|
||||||
|
0xB8, 0x00, 0x00, 0x00, 0x0D, 0x01, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00,
|
||||||
|
0x40, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x63, 0x00, 0x04, 0x00, 0x06, 0x01, 0x00, 0x00,
|
||||||
|
0x08, 0x01, 0x00, 0x00, 0x0D, 0x01, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0xAC, 0x00, 0x00, 0x00,
|
||||||
|
0xF8, 0x00, 0x02, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x00,
|
||||||
|
0x12, 0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||||
|
0x15, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x17, 0x01, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x3D, 0x00, 0x00, 0x00,
|
||||||
|
0x18, 0x01, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00, 0xB8, 0x00, 0x00, 0x00,
|
||||||
|
0x19, 0x01, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x17, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x13, 0x00, 0x00, 0x00, 0x63, 0x00, 0x06, 0x00, 0x12, 0x01, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00,
|
||||||
|
0x19, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0xAC, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0xAC, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
|
0x1E, 0x01, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x1E, 0x01, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00,
|
||||||
|
0x38, 0x00, 0x01, 0x00,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
103
Ryujinx.Graphics.Vulkan/SpecInfo.cs
Normal file
103
Ryujinx.Graphics.Vulkan/SpecInfo.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
using Silk.NET.Vulkan;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
|
{
|
||||||
|
public enum SpecConstType
|
||||||
|
{
|
||||||
|
Bool32,
|
||||||
|
Int16,
|
||||||
|
Int32,
|
||||||
|
Int64,
|
||||||
|
Float16,
|
||||||
|
Float32,
|
||||||
|
Float64
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class SpecDescription
|
||||||
|
{
|
||||||
|
public readonly SpecializationInfo Info;
|
||||||
|
public readonly SpecializationMapEntry[] Map;
|
||||||
|
|
||||||
|
// For mapping a simple packed struct or single entry
|
||||||
|
public SpecDescription(params (uint Id, SpecConstType Type)[] description)
|
||||||
|
{
|
||||||
|
int count = description.Length;
|
||||||
|
Map = new SpecializationMapEntry[count];
|
||||||
|
|
||||||
|
uint structSize = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
var typeSize = SizeOf(description[i].Type);
|
||||||
|
Map[i] = new SpecializationMapEntry(description[i].Id, structSize, typeSize);
|
||||||
|
structSize += typeSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info = new SpecializationInfo()
|
||||||
|
{
|
||||||
|
DataSize = structSize,
|
||||||
|
MapEntryCount = (uint)count
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// For advanced mapping with overlapping or staggered fields
|
||||||
|
public SpecDescription(SpecializationMapEntry[] map)
|
||||||
|
{
|
||||||
|
int count = map.Length;
|
||||||
|
Map = map;
|
||||||
|
|
||||||
|
uint structSize = 0;
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
structSize = Math.Max(structSize, map[i].Offset + (uint)map[i].Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info = new SpecializationInfo()
|
||||||
|
{
|
||||||
|
DataSize = structSize,
|
||||||
|
MapEntryCount = (uint)map.Length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint SizeOf(SpecConstType type) => type switch
|
||||||
|
{
|
||||||
|
SpecConstType.Int16 or SpecConstType.Float16 => 2,
|
||||||
|
SpecConstType.Bool32 or SpecConstType.Int32 or SpecConstType.Float32 => 4,
|
||||||
|
SpecConstType.Int64 or SpecConstType.Float64 => 8,
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||||
|
};
|
||||||
|
|
||||||
|
private SpecDescription()
|
||||||
|
{
|
||||||
|
Info = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly SpecDescription Empty = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly struct SpecData : IRefEquatable<SpecData>
|
||||||
|
{
|
||||||
|
private readonly byte[] _data;
|
||||||
|
private readonly int _hash;
|
||||||
|
|
||||||
|
public int Length => _data.Length;
|
||||||
|
public ReadOnlySpan<byte> Span => _data.AsSpan();
|
||||||
|
public override int GetHashCode() => _hash;
|
||||||
|
|
||||||
|
public SpecData(ReadOnlySpan<byte> data)
|
||||||
|
{
|
||||||
|
_data = new byte[data.Length];
|
||||||
|
data.CopyTo(_data);
|
||||||
|
|
||||||
|
var hc = new HashCode();
|
||||||
|
hc.AddBytes(data);
|
||||||
|
_hash = hc.ToHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj) => obj is SpecData other && Equals(other);
|
||||||
|
public bool Equals(ref SpecData other) => _data.AsSpan().SequenceEqual(other._data);
|
||||||
|
}
|
||||||
|
}
|
@ -355,5 +355,122 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dstLayers,
|
dstLayers,
|
||||||
levels);
|
levels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public unsafe static void ResolveDepthStencil(
|
||||||
|
VulkanRenderer gd,
|
||||||
|
Device device,
|
||||||
|
CommandBufferScoped cbs,
|
||||||
|
TextureView src,
|
||||||
|
TextureView dst)
|
||||||
|
{
|
||||||
|
var dsAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 0, ImageLayout.General);
|
||||||
|
var dsResolveAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 1, ImageLayout.General);
|
||||||
|
|
||||||
|
var subpassDsResolve = new SubpassDescriptionDepthStencilResolve()
|
||||||
|
{
|
||||||
|
SType = StructureType.SubpassDescriptionDepthStencilResolve,
|
||||||
|
PDepthStencilResolveAttachment = &dsResolveAttachmentReference,
|
||||||
|
DepthResolveMode = ResolveModeFlags.ResolveModeSampleZeroBit,
|
||||||
|
StencilResolveMode = ResolveModeFlags.ResolveModeSampleZeroBit
|
||||||
|
};
|
||||||
|
|
||||||
|
var subpass = new SubpassDescription2()
|
||||||
|
{
|
||||||
|
SType = StructureType.SubpassDescription2,
|
||||||
|
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||||
|
PDepthStencilAttachment = &dsAttachmentReference,
|
||||||
|
PNext = &subpassDsResolve
|
||||||
|
};
|
||||||
|
|
||||||
|
AttachmentDescription2[] attachmentDescs = new AttachmentDescription2[2];
|
||||||
|
|
||||||
|
attachmentDescs[0] = new AttachmentDescription2(
|
||||||
|
StructureType.AttachmentDescription2,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
src.VkFormat,
|
||||||
|
TextureStorage.ConvertToSampleCountFlags((uint)src.Info.Samples),
|
||||||
|
AttachmentLoadOp.Load,
|
||||||
|
AttachmentStoreOp.Store,
|
||||||
|
AttachmentLoadOp.Load,
|
||||||
|
AttachmentStoreOp.Store,
|
||||||
|
ImageLayout.General,
|
||||||
|
ImageLayout.General);
|
||||||
|
|
||||||
|
attachmentDescs[1] = new AttachmentDescription2(
|
||||||
|
StructureType.AttachmentDescription2,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
dst.VkFormat,
|
||||||
|
TextureStorage.ConvertToSampleCountFlags((uint)dst.Info.Samples),
|
||||||
|
AttachmentLoadOp.Load,
|
||||||
|
AttachmentStoreOp.Store,
|
||||||
|
AttachmentLoadOp.Load,
|
||||||
|
AttachmentStoreOp.Store,
|
||||||
|
ImageLayout.General,
|
||||||
|
ImageLayout.General);
|
||||||
|
|
||||||
|
var subpassDependency = PipelineConverter.CreateSubpassDependency2();
|
||||||
|
|
||||||
|
fixed (AttachmentDescription2* pAttachmentDescs = attachmentDescs)
|
||||||
|
{
|
||||||
|
var renderPassCreateInfo = new RenderPassCreateInfo2()
|
||||||
|
{
|
||||||
|
SType = StructureType.RenderPassCreateInfo2,
|
||||||
|
PAttachments = pAttachmentDescs,
|
||||||
|
AttachmentCount = (uint)attachmentDescs.Length,
|
||||||
|
PSubpasses = &subpass,
|
||||||
|
SubpassCount = 1,
|
||||||
|
PDependencies = &subpassDependency,
|
||||||
|
DependencyCount = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
gd.Api.CreateRenderPass2(device, renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
||||||
|
|
||||||
|
using var rp = new Auto<DisposableRenderPass>(new DisposableRenderPass(gd.Api, device, renderPass));
|
||||||
|
|
||||||
|
ImageView* attachments = stackalloc ImageView[2];
|
||||||
|
|
||||||
|
var srcView = src.GetImageViewForAttachment();
|
||||||
|
var dstView = dst.GetImageViewForAttachment();
|
||||||
|
|
||||||
|
attachments[0] = srcView.Get(cbs).Value;
|
||||||
|
attachments[1] = dstView.Get(cbs).Value;
|
||||||
|
|
||||||
|
var framebufferCreateInfo = new FramebufferCreateInfo()
|
||||||
|
{
|
||||||
|
SType = StructureType.FramebufferCreateInfo,
|
||||||
|
RenderPass = rp.Get(cbs).Value,
|
||||||
|
AttachmentCount = 2,
|
||||||
|
PAttachments = attachments,
|
||||||
|
Width = (uint)src.Width,
|
||||||
|
Height = (uint)src.Height,
|
||||||
|
Layers = (uint)src.Layers
|
||||||
|
};
|
||||||
|
|
||||||
|
gd.Api.CreateFramebuffer(device, framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
|
||||||
|
using var fb = new Auto<DisposableFramebuffer>(new DisposableFramebuffer(gd.Api, device, framebuffer), null, new[] { srcView, dstView });
|
||||||
|
|
||||||
|
var renderArea = new Rect2D(null, new Extent2D((uint)src.Info.Width, (uint)src.Info.Height));
|
||||||
|
var clearValue = new ClearValue();
|
||||||
|
|
||||||
|
var renderPassBeginInfo = new RenderPassBeginInfo()
|
||||||
|
{
|
||||||
|
SType = StructureType.RenderPassBeginInfo,
|
||||||
|
RenderPass = rp.Get(cbs).Value,
|
||||||
|
Framebuffer = fb.Get(cbs).Value,
|
||||||
|
RenderArea = renderArea,
|
||||||
|
PClearValues = &clearValue,
|
||||||
|
ClearValueCount = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// The resolve operation happens at the end of the subpass, so let's just do a begin/end
|
||||||
|
// to resolve the depth-stencil texture.
|
||||||
|
// TODO: Do speculative resolve and part of the same render pass as the draw to avoid
|
||||||
|
// ending the current render pass?
|
||||||
|
gd.Api.CmdBeginRenderPass(cbs.CommandBuffer, renderPassBeginInfo, SubpassContents.Inline);
|
||||||
|
gd.Api.CmdEndRenderPass(cbs.CommandBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,12 +169,15 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
var srcImage = src.GetImage().Get(cbs).Value;
|
var srcImage = src.GetImage().Get(cbs).Value;
|
||||||
var dstImage = dst.GetImage().Get(cbs).Value;
|
var dstImage = dst.GetImage().Get(cbs).Value;
|
||||||
|
|
||||||
if (src.Info.Target.IsMultisample())
|
if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample())
|
||||||
{
|
{
|
||||||
int depth = Math.Min(src.Info.Depth, dst.Info.Depth - firstLayer);
|
int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer);
|
||||||
int levels = Math.Min(src.Info.Levels, dst.Info.Levels - firstLevel);
|
_gd.HelperShader.CopyMSToNonMS(_gd, cbs, src, dst, 0, firstLayer, layers);
|
||||||
|
}
|
||||||
CopyMSToNonMS(_gd, cbs, src, dst, srcImage, dstImage, 0, firstLayer, 0, firstLevel, depth, levels);
|
else if (dst.Info.Target.IsMultisample() && !Info.Target.IsMultisample())
|
||||||
|
{
|
||||||
|
int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer);
|
||||||
|
_gd.HelperShader.CopyNonMSToMS(_gd, cbs, src, dst, 0, firstLayer, layers);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -213,9 +216,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
var srcImage = src.GetImage().Get(cbs).Value;
|
var srcImage = src.GetImage().Get(cbs).Value;
|
||||||
var dstImage = dst.GetImage().Get(cbs).Value;
|
var dstImage = dst.GetImage().Get(cbs).Value;
|
||||||
|
|
||||||
if (src.Info.Target.IsMultisample())
|
if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample())
|
||||||
{
|
{
|
||||||
CopyMSToNonMS(_gd, cbs, src, dst, srcImage, dstImage, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1);
|
_gd.HelperShader.CopyMSToNonMS(_gd, cbs, src, dst, srcLayer, dstLayer, 1);
|
||||||
|
}
|
||||||
|
else if (dst.Info.Target.IsMultisample() && !Info.Target.IsMultisample())
|
||||||
|
{
|
||||||
|
_gd.HelperShader.CopyNonMSToMS(_gd, cbs, src, dst, srcLayer, dstLayer, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -239,142 +246,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CopyMSToNonMS(
|
|
||||||
VulkanRenderer gd,
|
|
||||||
CommandBufferScoped cbs,
|
|
||||||
TextureView src,
|
|
||||||
TextureView dst,
|
|
||||||
Image srcImage,
|
|
||||||
Image dstImage,
|
|
||||||
int srcLayer,
|
|
||||||
int dstLayer,
|
|
||||||
int srcLevel,
|
|
||||||
int dstLevel,
|
|
||||||
int layers,
|
|
||||||
int levels)
|
|
||||||
{
|
|
||||||
bool differentFormats = src.Info.Format != dst.Info.Format;
|
|
||||||
|
|
||||||
var target = src.Info.Target switch
|
|
||||||
{
|
|
||||||
Target.Texture2D => Target.Texture2DMultisample,
|
|
||||||
Target.Texture2DArray => Target.Texture2DMultisampleArray,
|
|
||||||
Target.Texture2DMultisampleArray => Target.Texture2DArray,
|
|
||||||
_ => Target.Texture2D
|
|
||||||
};
|
|
||||||
|
|
||||||
var intermmediateTarget = differentFormats ? dst.Info.Target : target;
|
|
||||||
using var intermmediate = CreateIntermmediateTexture(gd, src, ref dst._info, intermmediateTarget, layers, levels);
|
|
||||||
var intermmediateImage = intermmediate.GetImage().Get(cbs).Value;
|
|
||||||
|
|
||||||
if (differentFormats)
|
|
||||||
{
|
|
||||||
// If the formats are different, the resolve would perform format conversion.
|
|
||||||
// So we need yet another intermmediate texture and do a copy to reinterpret the
|
|
||||||
// data into the correct (destination) format, without doing any sort of conversion.
|
|
||||||
using var intermmediate2 = CreateIntermmediateTexture(gd, src, ref src._info, target, layers, levels);
|
|
||||||
var intermmediate2Image = intermmediate2.GetImage().Get(cbs).Value;
|
|
||||||
|
|
||||||
TextureCopy.Copy(
|
|
||||||
gd.Api,
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
srcImage,
|
|
||||||
intermmediate2Image,
|
|
||||||
src.Info,
|
|
||||||
intermmediate2.Info,
|
|
||||||
src.FirstLayer,
|
|
||||||
0,
|
|
||||||
src.FirstLevel,
|
|
||||||
0,
|
|
||||||
srcLayer,
|
|
||||||
0,
|
|
||||||
srcLevel,
|
|
||||||
0,
|
|
||||||
layers,
|
|
||||||
levels);
|
|
||||||
|
|
||||||
TextureCopy.Copy(
|
|
||||||
gd.Api,
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
intermmediate2Image,
|
|
||||||
intermmediateImage,
|
|
||||||
intermmediate2.Info,
|
|
||||||
intermmediate.Info,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
layers,
|
|
||||||
levels);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TextureCopy.Copy(
|
|
||||||
gd.Api,
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
srcImage,
|
|
||||||
intermmediateImage,
|
|
||||||
src.Info,
|
|
||||||
intermmediate.Info,
|
|
||||||
src.FirstLayer,
|
|
||||||
0,
|
|
||||||
src.FirstLevel,
|
|
||||||
0,
|
|
||||||
srcLayer,
|
|
||||||
0,
|
|
||||||
srcLevel,
|
|
||||||
0,
|
|
||||||
layers,
|
|
||||||
levels);
|
|
||||||
}
|
|
||||||
|
|
||||||
var srcRegion = new Extents2D(0, 0, src.Width, src.Height);
|
|
||||||
var dstRegion = new Extents2D(0, 0, dst.Width, dst.Height);
|
|
||||||
|
|
||||||
TextureCopy.Blit(
|
|
||||||
gd.Api,
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
intermmediateImage,
|
|
||||||
dstImage,
|
|
||||||
intermmediate.Info,
|
|
||||||
dst.Info,
|
|
||||||
srcRegion,
|
|
||||||
dstRegion,
|
|
||||||
0,
|
|
||||||
dst.FirstLevel + dstLevel,
|
|
||||||
0,
|
|
||||||
dst.FirstLayer + dstLayer,
|
|
||||||
layers,
|
|
||||||
levels,
|
|
||||||
true,
|
|
||||||
ImageAspectFlags.ImageAspectColorBit,
|
|
||||||
ImageAspectFlags.ImageAspectColorBit);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TextureView CreateIntermmediateTexture(VulkanRenderer gd, TextureView src, ref TextureCreateInfo formatInfo, Target target, int depth, int levels)
|
|
||||||
{
|
|
||||||
return gd.CreateTextureView(new GAL.TextureCreateInfo(
|
|
||||||
src.Width,
|
|
||||||
src.Height,
|
|
||||||
depth,
|
|
||||||
levels,
|
|
||||||
1,
|
|
||||||
formatInfo.BlockWidth,
|
|
||||||
formatInfo.BlockHeight,
|
|
||||||
formatInfo.BytesPerPixel,
|
|
||||||
formatInfo.Format,
|
|
||||||
DepthStencilMode.Depth,
|
|
||||||
target,
|
|
||||||
SwizzleComponent.Red,
|
|
||||||
SwizzleComponent.Green,
|
|
||||||
SwizzleComponent.Blue,
|
|
||||||
SwizzleComponent.Alpha), 1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
|
public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
|
||||||
{
|
{
|
||||||
var dst = (TextureView)destination;
|
var dst = (TextureView)destination;
|
||||||
@ -422,23 +293,32 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
src.Height == dst.Height &&
|
src.Height == dst.Height &&
|
||||||
src.VkFormat == dst.VkFormat)
|
src.VkFormat == dst.VkFormat)
|
||||||
{
|
{
|
||||||
TextureCopy.Copy(
|
if (src.Info.Samples > 1 && src.Info.Samples != dst.Info.Samples && src.Info.Format.IsDepthOrStencil())
|
||||||
_gd.Api,
|
{
|
||||||
cbs.CommandBuffer,
|
// CmdResolveImage does not support depth-stencil resolve, so we need to use an alternative path
|
||||||
src.GetImage().Get(cbs).Value,
|
// for those textures.
|
||||||
dst.GetImage().Get(cbs).Value,
|
TextureCopy.ResolveDepthStencil(_gd, _device, cbs, src, dst);
|
||||||
src.Info,
|
}
|
||||||
dst.Info,
|
else
|
||||||
src.FirstLayer,
|
{
|
||||||
dst.FirstLayer,
|
TextureCopy.Copy(
|
||||||
src.FirstLevel,
|
_gd.Api,
|
||||||
dst.FirstLevel,
|
cbs.CommandBuffer,
|
||||||
0,
|
src.GetImage().Get(cbs).Value,
|
||||||
0,
|
dst.GetImage().Get(cbs).Value,
|
||||||
0,
|
src.Info,
|
||||||
0,
|
dst.Info,
|
||||||
layers,
|
src.FirstLayer,
|
||||||
levels);
|
dst.FirstLayer,
|
||||||
|
src.FirstLevel,
|
||||||
|
dst.FirstLevel,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
layers,
|
||||||
|
levels);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
"VUID-VkSubpassDependency-srcSubpass-00867"
|
"VUID-VkSubpassDependency-srcSubpass-00867"
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static Instance CreateInstance(Vk api, GraphicsDebugLevel logLevel, string[] requiredExtensions, out ExtDebugReport debugReport, out DebugReportCallbackEXT debugReportCallback)
|
internal static Instance CreateInstance(Vk api, GraphicsDebugLevel logLevel, string[] requiredExtensions, out ExtDebugUtils debugUtils, out DebugUtilsMessengerEXT debugUtilsMessenger)
|
||||||
{
|
{
|
||||||
var enabledLayers = new List<string>();
|
var enabledLayers = new List<string>();
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
AddAvailableLayer("VK_LAYER_KHRONOS_validation");
|
AddAvailableLayer("VK_LAYER_KHRONOS_validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
var enabledExtensions = requiredExtensions.Append(ExtDebugReport.ExtensionName).ToArray();
|
var enabledExtensions = requiredExtensions.Append(ExtDebugUtils.ExtensionName).ToArray();
|
||||||
|
|
||||||
var appName = Marshal.StringToHGlobalAnsi(AppName);
|
var appName = Marshal.StringToHGlobalAnsi(AppName);
|
||||||
|
|
||||||
@ -139,22 +139,18 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Marshal.FreeHGlobal(ppEnabledLayers[i]);
|
Marshal.FreeHGlobal(ppEnabledLayers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateDebugCallbacks(api, logLevel, instance, out debugReport, out debugReportCallback);
|
CreateDebugMessenger(api, logLevel, instance, out debugUtils, out debugUtilsMessenger);
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe static uint DebugReport(
|
private unsafe static uint DebugMessenger(
|
||||||
uint flags,
|
DebugUtilsMessageSeverityFlagsEXT messageSeverity,
|
||||||
DebugReportObjectTypeEXT objectType,
|
DebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||||
ulong @object,
|
DebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||||
nuint location,
|
void* pUserData)
|
||||||
int messageCode,
|
|
||||||
byte* layerPrefix,
|
|
||||||
byte* message,
|
|
||||||
void* userData)
|
|
||||||
{
|
{
|
||||||
var msg = Marshal.PtrToStringAnsi((IntPtr)message);
|
var msg = Marshal.PtrToStringAnsi((IntPtr)pCallbackData->PMessage);
|
||||||
|
|
||||||
foreach (string excludedMessagePart in _excludedMessages)
|
foreach (string excludedMessagePart in _excludedMessages)
|
||||||
{
|
{
|
||||||
@ -164,26 +160,20 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugReportFlagsEXT debugFlags = (DebugReportFlagsEXT)flags;
|
if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt))
|
||||||
|
|
||||||
if (debugFlags.HasFlag(DebugReportFlagsEXT.DebugReportErrorBitExt))
|
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Gpu, msg);
|
Logger.Error?.Print(LogClass.Gpu, msg);
|
||||||
//throw new Exception(msg);
|
//throw new Exception(msg);
|
||||||
}
|
}
|
||||||
else if (debugFlags.HasFlag(DebugReportFlagsEXT.DebugReportWarningBitExt))
|
else if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityWarningBitExt))
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Gpu, msg);
|
Logger.Warning?.Print(LogClass.Gpu, msg);
|
||||||
}
|
}
|
||||||
else if (debugFlags.HasFlag(DebugReportFlagsEXT.DebugReportInformationBitExt))
|
else if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityInfoBitExt))
|
||||||
{
|
{
|
||||||
Logger.Info?.Print(LogClass.Gpu, msg);
|
Logger.Info?.Print(LogClass.Gpu, msg);
|
||||||
}
|
}
|
||||||
else if (debugFlags.HasFlag(DebugReportFlagsEXT.DebugReportPerformanceWarningBitExt))
|
else // if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityVerboseBitExt))
|
||||||
{
|
|
||||||
Logger.Warning?.Print(LogClass.Gpu, msg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Logger.Debug?.Print(LogClass.Gpu, msg);
|
Logger.Debug?.Print(LogClass.Gpu, msg);
|
||||||
}
|
}
|
||||||
@ -403,6 +393,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ShaderClipDistance = true,
|
ShaderClipDistance = true,
|
||||||
ShaderFloat64 = supportedFeatures.ShaderFloat64,
|
ShaderFloat64 = supportedFeatures.ShaderFloat64,
|
||||||
ShaderImageGatherExtended = true,
|
ShaderImageGatherExtended = true,
|
||||||
|
ShaderStorageImageMultisample = supportedFeatures.ShaderStorageImageMultisample,
|
||||||
// ShaderStorageImageReadWithoutFormat = true,
|
// ShaderStorageImageReadWithoutFormat = true,
|
||||||
// ShaderStorageImageWriteWithoutFormat = true,
|
// ShaderStorageImageWriteWithoutFormat = true,
|
||||||
TessellationShader = true,
|
TessellationShader = true,
|
||||||
@ -551,46 +542,59 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return new CommandBufferPool(api, device, queue, queueLock, queueFamilyIndex);
|
return new CommandBufferPool(api, device, queue, queueLock, queueFamilyIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal unsafe static void CreateDebugCallbacks(
|
internal unsafe static void CreateDebugMessenger(
|
||||||
Vk api,
|
Vk api,
|
||||||
GraphicsDebugLevel logLevel,
|
GraphicsDebugLevel logLevel,
|
||||||
Instance instance,
|
Instance instance,
|
||||||
out ExtDebugReport debugReport,
|
out ExtDebugUtils debugUtils,
|
||||||
out DebugReportCallbackEXT debugReportCallback)
|
out DebugUtilsMessengerEXT debugUtilsMessenger)
|
||||||
{
|
{
|
||||||
debugReport = default;
|
debugUtils = default;
|
||||||
|
|
||||||
if (logLevel != GraphicsDebugLevel.None)
|
if (logLevel != GraphicsDebugLevel.None)
|
||||||
{
|
{
|
||||||
if (!api.TryGetInstanceExtension(instance, out debugReport))
|
if (!api.TryGetInstanceExtension(instance, out debugUtils))
|
||||||
{
|
{
|
||||||
debugReportCallback = default;
|
debugUtilsMessenger = default;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = logLevel switch
|
var filterLogType = logLevel switch
|
||||||
{
|
{
|
||||||
GraphicsDebugLevel.Error => DebugReportFlagsEXT.DebugReportErrorBitExt,
|
GraphicsDebugLevel.Error => DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt,
|
||||||
GraphicsDebugLevel.Slowdowns => DebugReportFlagsEXT.DebugReportErrorBitExt | DebugReportFlagsEXT.DebugReportPerformanceWarningBitExt,
|
GraphicsDebugLevel.Slowdowns => DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt |
|
||||||
GraphicsDebugLevel.All => DebugReportFlagsEXT.DebugReportInformationBitExt |
|
DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypePerformanceBitExt,
|
||||||
DebugReportFlagsEXT.DebugReportWarningBitExt |
|
GraphicsDebugLevel.All => DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeGeneralBitExt |
|
||||||
DebugReportFlagsEXT.DebugReportPerformanceWarningBitExt |
|
DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt |
|
||||||
DebugReportFlagsEXT.DebugReportErrorBitExt |
|
DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypePerformanceBitExt,
|
||||||
DebugReportFlagsEXT.DebugReportDebugBitExt,
|
|
||||||
_ => throw new ArgumentException($"Invalid log level \"{logLevel}\".")
|
_ => throw new ArgumentException($"Invalid log level \"{logLevel}\".")
|
||||||
};
|
};
|
||||||
var debugReportCallbackCreateInfo = new DebugReportCallbackCreateInfoEXT()
|
|
||||||
|
var filterLogSeverity = logLevel switch
|
||||||
{
|
{
|
||||||
SType = StructureType.DebugReportCallbackCreateInfoExt,
|
GraphicsDebugLevel.Error => DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt,
|
||||||
Flags = flags,
|
GraphicsDebugLevel.Slowdowns => DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt |
|
||||||
PfnCallback = new PfnDebugReportCallbackEXT(DebugReport)
|
DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityWarningBitExt,
|
||||||
|
GraphicsDebugLevel.All => DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityInfoBitExt |
|
||||||
|
DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityWarningBitExt |
|
||||||
|
DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityVerboseBitExt |
|
||||||
|
DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt,
|
||||||
|
_ => throw new ArgumentException($"Invalid log level \"{logLevel}\".")
|
||||||
};
|
};
|
||||||
|
|
||||||
debugReport.CreateDebugReportCallback(instance, in debugReportCallbackCreateInfo, null, out debugReportCallback).ThrowOnError();
|
var debugUtilsMessengerCreateInfo = new DebugUtilsMessengerCreateInfoEXT()
|
||||||
|
{
|
||||||
|
SType = StructureType.DebugUtilsMessengerCreateInfoExt,
|
||||||
|
MessageType = filterLogType,
|
||||||
|
MessageSeverity = filterLogSeverity,
|
||||||
|
PfnUserCallback = new PfnDebugUtilsMessengerCallbackEXT(DebugMessenger)
|
||||||
|
};
|
||||||
|
|
||||||
|
debugUtils.CreateDebugUtilsMessenger(instance, in debugUtilsMessengerCreateInfo, null, out debugUtilsMessenger).ThrowOnError();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debugReportCallback = default;
|
debugUtilsMessenger = default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
internal KhrPushDescriptor PushDescriptorApi { get; private set; }
|
internal KhrPushDescriptor PushDescriptorApi { get; private set; }
|
||||||
internal ExtTransformFeedback TransformFeedbackApi { get; private set; }
|
internal ExtTransformFeedback TransformFeedbackApi { get; private set; }
|
||||||
internal KhrDrawIndirectCount DrawIndirectCountApi { get; private set; }
|
internal KhrDrawIndirectCount DrawIndirectCountApi { get; private set; }
|
||||||
internal ExtDebugReport DebugReportApi { get; private set; }
|
internal ExtDebugUtils DebugUtilsApi { get; private set; }
|
||||||
|
|
||||||
internal uint QueueFamilyIndex { get; private set; }
|
internal uint QueueFamilyIndex { get; private set; }
|
||||||
internal Queue Queue { get; private set; }
|
internal Queue Queue { get; private set; }
|
||||||
@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private SyncManager _syncManager;
|
private SyncManager _syncManager;
|
||||||
|
|
||||||
private PipelineFull _pipeline;
|
private PipelineFull _pipeline;
|
||||||
private DebugReportCallbackEXT _debugReportCallback;
|
private DebugUtilsMessengerEXT _debugUtilsMessenger;
|
||||||
|
|
||||||
internal HelperShader HelperShader { get; private set; }
|
internal HelperShader HelperShader { get; private set; }
|
||||||
internal PipelineFull PipelineInternal => _pipeline;
|
internal PipelineFull PipelineInternal => _pipeline;
|
||||||
@ -237,9 +237,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Api = api;
|
Api = api;
|
||||||
|
|
||||||
_instance = VulkanInitialization.CreateInstance(api, logLevel, _getRequiredExtensions(), out ExtDebugReport debugReport, out _debugReportCallback);
|
_instance = VulkanInitialization.CreateInstance(api, logLevel, _getRequiredExtensions(), out ExtDebugUtils debugUtils, out _debugUtilsMessenger);
|
||||||
|
|
||||||
DebugReportApi = debugReport;
|
DebugUtilsApi = debugUtils;
|
||||||
|
|
||||||
if (api.TryGetInstanceExtension(_instance, out KhrSurface surfaceApi))
|
if (api.TryGetInstanceExtension(_instance, out KhrSurface surfaceApi))
|
||||||
{
|
{
|
||||||
@ -287,9 +287,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ShaderCollection CreateProgramWithMinimalLayout(ShaderSource[] sources)
|
internal ShaderCollection CreateProgramWithMinimalLayout(ShaderSource[] sources, SpecDescription[] specDescription = null)
|
||||||
{
|
{
|
||||||
return new ShaderCollection(this, _device, sources, isMinimal: true);
|
return new ShaderCollection(this, _device, sources, specDescription: specDescription, isMinimal: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISampler CreateSampler(GAL.SamplerCreateInfo info)
|
public ISampler CreateSampler(GAL.SamplerCreateInfo info)
|
||||||
@ -584,9 +584,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
MemoryAllocator.Dispose();
|
MemoryAllocator.Dispose();
|
||||||
|
|
||||||
if (_debugReportCallback.Handle != 0)
|
if (_debugUtilsMessenger.Handle != 0)
|
||||||
{
|
{
|
||||||
DebugReportApi.DestroyDebugReportCallback(_instance, _debugReportCallback, null);
|
DebugUtilsApi.DestroyDebugUtilsMessenger(_instance, _debugUtilsMessenger, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var shader in Shaders)
|
foreach (var shader in Shaders)
|
||||||
|
@ -9,10 +9,10 @@ using LibHac.Tools.FsSystem;
|
|||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
using LibHac.Tools.Ncm;
|
using LibHac.Tools.Ncm;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.Exceptions;
|
using Ryujinx.HLE.Exceptions;
|
||||||
using Ryujinx.HLE.HOS.Services.Ssl;
|
using Ryujinx.HLE.HOS.Services.Ssl;
|
||||||
using Ryujinx.HLE.HOS.Services.Time;
|
using Ryujinx.HLE.HOS.Services.Time;
|
||||||
using Ryujinx.HLE.Utilities;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -293,7 +293,7 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
aocStorage = new Nca(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage()).OpenStorage(NcaSectionType.Data, integrityCheckLevel);
|
aocStorage = new Nca(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage()).OpenStorage(NcaSectionType.Data, integrityCheckLevel);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +354,7 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
{
|
{
|
||||||
if (_contentDictionary.ContainsKey((titleId, contentType)))
|
if (_contentDictionary.ContainsKey((titleId, contentType)))
|
||||||
{
|
{
|
||||||
return new UInt128(_contentDictionary[(titleId, contentType)]);
|
return UInt128Utils.FromHex(_contentDictionary[(titleId, contentType)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +407,7 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string installedPath = _virtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
|
string installedPath = _virtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(installedPath))
|
if (!string.IsNullOrWhiteSpace(installedPath))
|
||||||
|
@ -10,6 +10,7 @@ using Ryujinx.Audio.Integration;
|
|||||||
using Ryujinx.Audio.Output;
|
using Ryujinx.Audio.Output;
|
||||||
using Ryujinx.Audio.Renderer.Device;
|
using Ryujinx.Audio.Renderer.Device;
|
||||||
using Ryujinx.Audio.Renderer.Server;
|
using Ryujinx.Audio.Renderer.Server;
|
||||||
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Cpu;
|
using Ryujinx.Cpu;
|
||||||
using Ryujinx.Cpu.Jit;
|
using Ryujinx.Cpu.Jit;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
@ -35,7 +36,6 @@ using Ryujinx.HLE.HOS.Services.SurfaceFlinger;
|
|||||||
using Ryujinx.HLE.HOS.Services.Time.Clock;
|
using Ryujinx.HLE.HOS.Services.Time.Clock;
|
||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using Ryujinx.HLE.Loaders.Executables;
|
using Ryujinx.HLE.Loaders.Executables;
|
||||||
using Ryujinx.HLE.Utilities;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -201,7 +201,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
|
|
||||||
// TODO: use set:sys (and get external clock source id from settings)
|
// TODO: use set:sys (and get external clock source id from settings)
|
||||||
// TODO: use "time!standard_steady_clock_rtc_update_interval_minutes" and implement a worker thread to be accurate.
|
// TODO: use "time!standard_steady_clock_rtc_update_interval_minutes" and implement a worker thread to be accurate.
|
||||||
UInt128 clockSourceId = new UInt128(Guid.NewGuid().ToByteArray());
|
UInt128 clockSourceId = UInt128Utils.CreateRandom();
|
||||||
IRtcManager.GetExternalRtcValue(out ulong rtcValue);
|
IRtcManager.GetExternalRtcValue(out ulong rtcValue);
|
||||||
|
|
||||||
// We assume the rtc is system time.
|
// We assume the rtc is system time.
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using LibHac.Account;
|
using LibHac.Account;
|
||||||
using Ryujinx.HLE.Utilities;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -83,7 +82,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||||||
|
|
||||||
public readonly UInt128 ToUInt128()
|
public readonly UInt128 ToUInt128()
|
||||||
{
|
{
|
||||||
return new UInt128(Low, High);
|
return new UInt128((ulong)High, (ulong)Low);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,6 +32,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
|||||||
private bool _handlesRequestToDisplay = false;
|
private bool _handlesRequestToDisplay = false;
|
||||||
private bool _autoSleepDisabled = false;
|
private bool _autoSleepDisabled = false;
|
||||||
private bool _albumImageTakenNotificationEnabled = false;
|
private bool _albumImageTakenNotificationEnabled = false;
|
||||||
|
private bool _recordVolumeMuted = false;
|
||||||
|
|
||||||
private uint _screenShotImageOrientation = 0;
|
private uint _screenShotImageOrientation = 0;
|
||||||
private uint _idleTimeDetectionExtension = 0;
|
private uint _idleTimeDetectionExtension = 0;
|
||||||
@ -389,5 +390,18 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
|||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CommandHipc(130)] // 13.0.0+
|
||||||
|
// SetRecordVolumeMuted(b8)
|
||||||
|
public ResultCode SetRecordVolumeMuted(ServiceCtx context)
|
||||||
|
{
|
||||||
|
bool recordVolumeMuted = context.RequestData.ReadBoolean();
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceAm, new { recordVolumeMuted });
|
||||||
|
|
||||||
|
_recordVolumeMuted = recordVolumeMuted;
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,6 +203,18 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
|
|||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CommandHipc(318)] // 4.0.0+
|
||||||
|
// StopImageProcessorAsync(nn::irsensor::IrCameraHandle, nn::applet::AppletResourceUserId, pid)
|
||||||
|
public ResultCode StopImageProcessorAsync(ServiceCtx context)
|
||||||
|
{
|
||||||
|
int irCameraHandle = context.RequestData.ReadInt32();
|
||||||
|
long appletResourceUserId = context.RequestData.ReadInt64();
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId, irCameraHandle });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
[CommandHipc(319)] // 4.0.0+
|
[CommandHipc(319)] // 4.0.0+
|
||||||
// ActivateIrsensorWithFunctionLevel(nn::applet::AppletResourceUserId, nn::irsensor::PackedFunctionLevel, pid)
|
// ActivateIrsensorWithFunctionLevel(nn::applet::AppletResourceUserId, nn::irsensor::PackedFunctionLevel, pid)
|
||||||
public ResultCode ActivateIrsensorWithFunctionLevel(ServiceCtx context)
|
public ResultCode ActivateIrsensorWithFunctionLevel(ServiceCtx context)
|
||||||
@ -225,4 +237,4 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
|
|||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Ryujinx.HLE.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
|||||||
public static UInt128 GetDeviceId()
|
public static UInt128 GetDeviceId()
|
||||||
{
|
{
|
||||||
// FIXME: call set:sys GetMiiAuthorId
|
// FIXME: call set:sys GetMiiAuthorId
|
||||||
return new UInt128("5279754d69694e780000000000000000"); // RyuMiiNx
|
return UInt128Utils.FromHex("5279754d69694e780000000000000000"); // RyuMiiNx
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ReadOnlySpan<byte> Ver3FacelineColorTable => new byte[] { 0, 1, 2, 3, 4, 5 };
|
public static ReadOnlySpan<byte> Ver3FacelineColorTable => new byte[] { 0, 1, 2, 3, 4, 5 };
|
||||||
|
@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Mii.Types
|
namespace Ryujinx.HLE.HOS.Services.Mii.Types
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Size = 0x58)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0x58)]
|
||||||
struct CharInfo : IStoredData<CharInfo>
|
struct CharInfo : IStoredData<CharInfo>
|
||||||
{
|
{
|
||||||
public CreateId CreateId;
|
public CreateId CreateId;
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
using Ryujinx.HLE.Utilities;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Mii.Types
|
namespace Ryujinx.HLE.HOS.Services.Mii.Types
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Size = 0x10)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0x10)]
|
||||||
struct CreateId : IEquatable<CreateId>
|
struct CreateId : IEquatable<CreateId>
|
||||||
{
|
{
|
||||||
public UInt128 Raw;
|
public UInt128 Raw;
|
||||||
|
|
||||||
public bool IsNull => Raw.IsNull;
|
public bool IsNull => Raw == UInt128.Zero;
|
||||||
public bool IsValid => !IsNull && (Raw.High & 0xC0) == 0x80;
|
public bool IsValid => !IsNull && ((Raw >> 64) & 0xC0) == 0x80;
|
||||||
|
|
||||||
public CreateId(byte[] data)
|
public CreateId(UInt128 raw)
|
||||||
{
|
{
|
||||||
Raw = new UInt128(data);
|
Raw = raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator ==(CreateId x, CreateId y)
|
public static bool operator ==(CreateId x, CreateId y)
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using Ryujinx.HLE.Utilities;
|
using Ryujinx.HLE.Utilities;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Mii.Types
|
namespace Ryujinx.HLE.HOS.Services.Mii.Types
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = Size)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = Size)]
|
||||||
struct StoreData : IStoredData<StoreData>
|
struct StoreData : IStoredData<StoreData>
|
||||||
{
|
{
|
||||||
public const int Size = 0x44;
|
public const int Size = 0x44;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Ryujinx.Cpu;
|
using Ryujinx.Common.Utilities;
|
||||||
|
using Ryujinx.Cpu;
|
||||||
using Ryujinx.HLE.HOS.Services.Mii.Types;
|
using Ryujinx.HLE.HOS.Services.Mii.Types;
|
||||||
using Ryujinx.HLE.HOS.Services.Time;
|
using Ryujinx.HLE.HOS.Services.Time;
|
||||||
using Ryujinx.HLE.HOS.Services.Time.Clock;
|
using Ryujinx.HLE.HOS.Services.Time.Clock;
|
||||||
@ -62,7 +63,13 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
|||||||
|
|
||||||
public CreateId MakeCreateId()
|
public CreateId MakeCreateId()
|
||||||
{
|
{
|
||||||
return new CreateId(Guid.NewGuid().ToByteArray());
|
UInt128 value = UInt128Utils.CreateRandom();
|
||||||
|
|
||||||
|
// Ensure the random ID generated is valid as a create id.
|
||||||
|
value &= ~new UInt128(0xC0, 0);
|
||||||
|
value |= new UInt128(0x80, 0);
|
||||||
|
|
||||||
|
return new CreateId(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,22 +5,48 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.NfcManager
|
|||||||
class INfc : IpcService
|
class INfc : IpcService
|
||||||
{
|
{
|
||||||
private NfcPermissionLevel _permissionLevel;
|
private NfcPermissionLevel _permissionLevel;
|
||||||
|
private State _state;
|
||||||
|
|
||||||
public INfc(NfcPermissionLevel permissionLevel)
|
public INfc(NfcPermissionLevel permissionLevel)
|
||||||
{
|
{
|
||||||
_permissionLevel = permissionLevel;
|
_permissionLevel = permissionLevel;
|
||||||
|
_state = State.NonInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandHipc(0)]
|
[CommandHipc(0)]
|
||||||
[CommandHipc(400)] // 4.0.0+
|
[CommandHipc(400)] // 4.0.0+
|
||||||
// Initialize()
|
// Initialize(u64, u64, pid, buffer<unknown, 5>)
|
||||||
public ResultCode Initialize(ServiceCtx context)
|
public ResultCode Initialize(ServiceCtx context)
|
||||||
{
|
{
|
||||||
|
_state = State.Initialized;
|
||||||
|
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceNfc, new { _permissionLevel });
|
Logger.Stub?.PrintStub(LogClass.ServiceNfc, new { _permissionLevel });
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CommandHipc(1)]
|
||||||
|
[CommandHipc(401)] // 4.0.0+
|
||||||
|
// Finalize()
|
||||||
|
public ResultCode Finalize(ServiceCtx context)
|
||||||
|
{
|
||||||
|
_state = State.NonInitialized;
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceNfc, new { _permissionLevel });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CommandHipc(2)]
|
||||||
|
[CommandHipc(402)] // 4.0.0+
|
||||||
|
// GetState() -> u32
|
||||||
|
public ResultCode GetState(ServiceCtx context)
|
||||||
|
{
|
||||||
|
context.ResponseData.Write((int)_state);
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
[CommandHipc(3)]
|
[CommandHipc(3)]
|
||||||
[CommandHipc(403)] // 4.0.0+
|
[CommandHipc(403)] // 4.0.0+
|
||||||
// IsNfcEnabled() -> b8
|
// IsNfcEnabled() -> b8
|
||||||
|
8
Ryujinx.HLE/HOS/Services/Nfc/NfcManager/Types/State.cs
Normal file
8
Ryujinx.HLE/HOS/Services/Nfc/NfcManager/Types/State.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Ryujinx.HLE.HOS.Services.Nfc.NfcManager
|
||||||
|
{
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
NonInitialized,
|
||||||
|
Initialized
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService;
|
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService;
|
||||||
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types;
|
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types;
|
||||||
using Ryujinx.HLE.Utilities;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@ -78,7 +78,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
|||||||
|
|
||||||
NetworkProfileData networkProfile = new NetworkProfileData
|
NetworkProfileData networkProfile = new NetworkProfileData
|
||||||
{
|
{
|
||||||
Uuid = new UInt128(Guid.NewGuid().ToByteArray())
|
Uuid = UInt128Utils.CreateRandom()
|
||||||
};
|
};
|
||||||
|
|
||||||
networkProfile.IpSettingData.IpAddressSetting = new IpAddressSetting(interfaceProperties, unicastAddress);
|
networkProfile.IpSettingData.IpAddressSetting = new IpAddressSetting(interfaceProperties, unicastAddress);
|
||||||
|
@ -14,14 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
|||||||
|
|
||||||
public DnsSetting(IPInterfaceProperties interfaceProperties)
|
public DnsSetting(IPInterfaceProperties interfaceProperties)
|
||||||
{
|
{
|
||||||
try
|
IsDynamicDnsEnabled = OperatingSystem.IsWindows() && interfaceProperties.IsDynamicDnsEnabled;
|
||||||
{
|
|
||||||
IsDynamicDnsEnabled = interfaceProperties.IsDynamicDnsEnabled;
|
|
||||||
}
|
|
||||||
catch (PlatformNotSupportedException)
|
|
||||||
{
|
|
||||||
IsDynamicDnsEnabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interfaceProperties.DnsAddresses.Count == 0)
|
if (interfaceProperties.DnsAddresses.Count == 0)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Net.NetworkInformation;
|
using System;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
||||||
@ -14,7 +15,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
|||||||
|
|
||||||
public IpAddressSetting(IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastIPAddressInformation)
|
public IpAddressSetting(IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastIPAddressInformation)
|
||||||
{
|
{
|
||||||
IsDhcpEnabled = interfaceProperties.DhcpServerAddresses.Count != 0;
|
IsDhcpEnabled = !OperatingSystem.IsMacOS() && interfaceProperties.DhcpServerAddresses.Count != 0;
|
||||||
Address = new IpV4Address(unicastIPAddressInformation.Address);
|
Address = new IpV4Address(unicastIPAddressInformation.Address);
|
||||||
IPv4Mask = new IpV4Address(unicastIPAddressInformation.IPv4Mask);
|
IPv4Mask = new IpV4Address(unicastIPAddressInformation.IPv4Mask);
|
||||||
GatewayAddress = new IpV4Address(interfaceProperties.GatewayAddresses[0].Address);
|
GatewayAddress = new IpV4Address(interfaceProperties.GatewayAddresses[0].Address);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.HLE.Utilities;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
||||||
|
@ -5,9 +5,9 @@ using LibHac.Fs.Fsa;
|
|||||||
using LibHac.FsSystem;
|
using LibHac.FsSystem;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using Ryujinx.HLE.Utilities;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -290,9 +290,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings
|
|||||||
// NOTE: If miiAuthorId is null ResultCode.NullMiiAuthorIdBuffer is returned.
|
// NOTE: If miiAuthorId is null ResultCode.NullMiiAuthorIdBuffer is returned.
|
||||||
// Doesn't occur in our case.
|
// Doesn't occur in our case.
|
||||||
|
|
||||||
UInt128 miiAuthorId = Mii.Helper.GetDeviceId();
|
context.ResponseData.Write(Mii.Helper.GetDeviceId());
|
||||||
|
|
||||||
miiAuthorId.Write(context.ResponseData);
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,11 @@ namespace Ryujinx.HLE.HOS.Services.Ssl.SslService
|
|||||||
// GetSessionCacheMode() -> nn::ssl::sf::SessionCacheMode
|
// GetSessionCacheMode() -> nn::ssl::sf::SessionCacheMode
|
||||||
public ResultCode GetSessionCacheMode(ServiceCtx context)
|
public ResultCode GetSessionCacheMode(ServiceCtx context)
|
||||||
{
|
{
|
||||||
throw new ServiceNotImplementedException(this, context);
|
context.ResponseData.Write((uint)_sessionCacheMode);
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { _sessionCacheMode });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandHipc(19)]
|
[CommandHipc(19)]
|
||||||
|
@ -66,6 +66,8 @@ namespace Ryujinx.HLE.HOS.Services.Ssl.SslService
|
|||||||
EndSslOperation();
|
EndSslOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: We silence warnings about TLS 1.0 and 1.1 as games will likely use it.
|
||||||
|
#pragma warning disable SYSLIB0039
|
||||||
private static SslProtocols TranslateSslVersion(SslVersion version)
|
private static SslProtocols TranslateSslVersion(SslVersion version)
|
||||||
{
|
{
|
||||||
switch (version & SslVersion.VersionMask)
|
switch (version & SslVersion.VersionMask)
|
||||||
@ -84,6 +86,7 @@ namespace Ryujinx.HLE.HOS.Services.Ssl.SslService
|
|||||||
throw new NotImplementedException(version.ToString());
|
throw new NotImplementedException(version.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#pragma warning restore SYSLIB0039
|
||||||
|
|
||||||
public ResultCode Handshake(string hostName)
|
public ResultCode Handshake(string hostName)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using Ryujinx.Cpu;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.Utilities;
|
using Ryujinx.Cpu;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||||
@ -12,7 +12,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
|||||||
|
|
||||||
public SteadyClockCore()
|
public SteadyClockCore()
|
||||||
{
|
{
|
||||||
_clockSourceId = new UInt128(Guid.NewGuid().ToByteArray());
|
_clockSourceId = UInt128Utils.CreateRandom();
|
||||||
_isRtcResetDetected = false;
|
_isRtcResetDetected = false;
|
||||||
_isInitialized = false;
|
_isInitialized = false;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
using Ryujinx.HLE.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
struct SteadyClockTimePoint
|
struct SteadyClockTimePoint
|
||||||
{
|
{
|
||||||
public long TimePoint;
|
public long TimePoint;
|
||||||
@ -36,7 +36,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
|||||||
return new SteadyClockTimePoint
|
return new SteadyClockTimePoint
|
||||||
{
|
{
|
||||||
TimePoint = 0,
|
TimePoint = 0,
|
||||||
ClockSourceId = new UInt128(Guid.NewGuid().ToByteArray())
|
ClockSourceId = UInt128Utils.CreateRandom()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
struct SystemClockContext
|
struct SystemClockContext
|
||||||
{
|
{
|
||||||
public long Offset;
|
public long Offset;
|
||||||
|
@ -3,7 +3,7 @@ using Ryujinx.HLE.Exceptions;
|
|||||||
using Ryujinx.HLE.HOS.Kernel.Memory;
|
using Ryujinx.HLE.HOS.Kernel.Memory;
|
||||||
using Ryujinx.HLE.HOS.Services.Time.Clock;
|
using Ryujinx.HLE.HOS.Services.Time.Clock;
|
||||||
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
|
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
|
||||||
using Ryujinx.HLE.Utilities;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Time
|
namespace Ryujinx.HLE.HOS.Services.Time
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.HLE.HOS.Services.Time.Clock;
|
using Ryujinx.HLE.HOS.Services.Time.Clock;
|
||||||
using Ryujinx.HLE.Utilities;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user