aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Decoders
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2021-08-11 17:27:00 -0300
committerGitHub <noreply@github.com>2021-08-11 22:27:00 +0200
commited754af8d5046d2fd7218c742521e38ab17cbcfe (patch)
treed47eda40349a7b4b3fc34d9db9ddeea8f2d0676a /Ryujinx.Graphics.Shader/Decoders
parent10d649e6d3ad3e4af32d2b41e718bb0a2924da67 (diff)
Make sure attributes used on subsequent shader stages are initialized (#2538)
Diffstat (limited to 'Ryujinx.Graphics.Shader/Decoders')
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/Decoder.cs49
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs8
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs2
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs3
4 files changed, 45 insertions, 17 deletions
diff --git a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
index c916935e..12b49d35 100644
--- a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
@@ -1,4 +1,5 @@
using Ryujinx.Graphics.Shader.Instructions;
+using Ryujinx.Graphics.Shader.Translation;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,10 +10,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
static class Decoder
{
- public static Block[][] Decode(IGpuAccessor gpuAccessor, ulong startAddress, out bool hasBindless)
+ public static Block[][] Decode(ShaderConfig config, ulong startAddress)
{
- hasBindless = false;
-
List<Block[]> funcs = new List<Block[]>();
Queue<ulong> funcQueue = new Queue<ulong>();
@@ -90,8 +89,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
}
}
- FillBlock(gpuAccessor, currBlock, limitAddress, startAddress, out bool blockHasBindless);
- hasBindless |= blockHasBindless;
+ FillBlock(config, currBlock, limitAddress, startAddress);
if (currBlock.OpCodes.Count != 0)
{
@@ -168,7 +166,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
for (int i = 0; i < cbOffsetsCount; i++)
{
- uint targetOffset = gpuAccessor.ConstantBuffer1Read(cbBaseOffset + i * 4);
+ uint targetOffset = config.GpuAccessor.ConstantBuffer1Read(cbBaseOffset + i * 4);
Block target = GetBlock(baseOffset + targetOffset);
opBrIndir.PossibleTargets.Add(target);
target.Predecessors.Add(block);
@@ -224,15 +222,11 @@ namespace Ryujinx.Graphics.Shader.Decoders
return false;
}
- private static void FillBlock(
- IGpuAccessor gpuAccessor,
- Block block,
- ulong limitAddress,
- ulong startAddress,
- out bool hasBindless)
+ private static void FillBlock(ShaderConfig config, Block block, ulong limitAddress, ulong startAddress)
{
+ IGpuAccessor gpuAccessor = config.GpuAccessor;
+
ulong address = block.Address;
- hasBindless = false;
do
{
@@ -274,13 +268,38 @@ namespace Ryujinx.Graphics.Shader.Decoders
OpCode op = makeOp(emitter, opAddress, opCode);
// We check these patterns to figure out the presence of bindless access
- hasBindless |= (op is OpCodeImage image && image.IsBindless) ||
+ if ((op is OpCodeImage image && image.IsBindless) ||
(op is OpCodeTxd txd && txd.IsBindless) ||
(op is OpCodeTld4B) ||
(emitter == InstEmit.TexB) ||
(emitter == InstEmit.TldB) ||
(emitter == InstEmit.TmmlB) ||
- (emitter == InstEmit.TxqB);
+ (emitter == InstEmit.TxqB))
+ {
+ config.SetUsedFeature(FeatureFlags.Bindless);
+ }
+
+ // Populate used attributes.
+ if (op is IOpCodeAttribute opAttr)
+ {
+ for (int elemIndex = 0; elemIndex < opAttr.Count; elemIndex++)
+ {
+ int attr = opAttr.AttributeOffset + elemIndex * 4;
+ if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd)
+ {
+ int index = (attr - AttributeConsts.UserAttributeBase) / 16;
+
+ if (op.Emitter == InstEmit.Ast)
+ {
+ config.SetOutputUserAttribute(index);
+ }
+ else
+ {
+ config.SetInputUserAttribute(index);
+ }
+ }
+ }
+ }
block.OpCodes.Add(op);
}
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs
new file mode 100644
index 00000000..b5b16f1b
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+ interface IOpCodeAttribute
+ {
+ int AttributeOffset { get; }
+ int Count { get; }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs
index 1457b602..f9119665 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs
@@ -2,7 +2,7 @@ using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
- class OpCodeAttribute : OpCodeAluReg
+ class OpCodeAttribute : OpCodeAluReg, IOpCodeAttribute
{
public int AttributeOffset { get; }
public int Count { get; }
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs
index 51138a1d..dc4e03e3 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs
@@ -2,9 +2,10 @@ using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
- class OpCodeIpa : OpCodeAluReg
+ class OpCodeIpa : OpCodeAluReg, IOpCodeAttribute
{
public int AttributeOffset { get; }
+ public int Count => 1;
public InterpolationMode Mode { get; }