diff options
author | gdkchan <gab.dark.100@gmail.com> | 2021-08-11 17:27:00 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-11 22:27:00 +0200 |
commit | ed754af8d5046d2fd7218c742521e38ab17cbcfe (patch) | |
tree | d47eda40349a7b4b3fc34d9db9ddeea8f2d0676a /Ryujinx.Graphics.Shader/Decoders/Decoder.cs | |
parent | 10d649e6d3ad3e4af32d2b41e718bb0a2924da67 (diff) |
Make sure attributes used on subsequent shader stages are initialized (#2538)
Diffstat (limited to 'Ryujinx.Graphics.Shader/Decoders/Decoder.cs')
-rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/Decoder.cs | 49 |
1 files changed, 34 insertions, 15 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); } |