mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2025-06-28 15:00:48 -07:00
Replace constant buffer access on shader with new Load instruction (#4646)
This commit is contained in:
@ -15,9 +15,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
|
||||
public int Value { get; }
|
||||
|
||||
public int CbufSlot { get; }
|
||||
public int CbufOffset { get; }
|
||||
|
||||
private AstOperand()
|
||||
{
|
||||
Defs = new HashSet<IAstNode>();
|
||||
@ -29,16 +26,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
public AstOperand(Operand operand) : this()
|
||||
{
|
||||
Type = operand.Type;
|
||||
|
||||
if (Type == OperandType.ConstantBuffer)
|
||||
{
|
||||
CbufSlot = operand.GetCbufSlot();
|
||||
CbufOffset = operand.GetCbufOffset();
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = operand.Value;
|
||||
}
|
||||
Value = operand.Value;
|
||||
}
|
||||
|
||||
public AstOperand(OperandType type, int value = 0) : this()
|
||||
|
20
src/Ryujinx.Graphics.Shader/StructuredIr/BufferDefinition.cs
Normal file
20
src/Ryujinx.Graphics.Shader/StructuredIr/BufferDefinition.cs
Normal file
@ -0,0 +1,20 @@
|
||||
namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
{
|
||||
readonly struct BufferDefinition
|
||||
{
|
||||
public BufferLayout Layout { get; }
|
||||
public int Set { get; }
|
||||
public int Binding { get; }
|
||||
public string Name { get; }
|
||||
public StructureType Type { get; }
|
||||
|
||||
public BufferDefinition(BufferLayout layout, int set, int binding, string name, StructureType type)
|
||||
{
|
||||
Layout = layout;
|
||||
Set = set;
|
||||
Binding = binding;
|
||||
Name = name;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
}
|
8
src/Ryujinx.Graphics.Shader/StructuredIr/BufferLayout.cs
Normal file
8
src/Ryujinx.Graphics.Shader/StructuredIr/BufferLayout.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
{
|
||||
enum BufferLayout
|
||||
{
|
||||
Std140,
|
||||
Std430
|
||||
}
|
||||
}
|
@ -90,7 +90,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
Add(Instruction.ImageAtomic, AggregateType.S32);
|
||||
Add(Instruction.IsNan, AggregateType.Bool, AggregateType.Scalar);
|
||||
Add(Instruction.Load, AggregateType.FP32);
|
||||
Add(Instruction.LoadConstant, AggregateType.FP32, AggregateType.S32, AggregateType.S32);
|
||||
Add(Instruction.LoadGlobal, AggregateType.U32, AggregateType.S32, AggregateType.S32);
|
||||
Add(Instruction.LoadLocal, AggregateType.U32, AggregateType.S32);
|
||||
Add(Instruction.LoadShared, AggregateType.U32, AggregateType.S32);
|
||||
|
@ -24,7 +24,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
{
|
||||
OperandType.Argument => AggregateType.S32,
|
||||
OperandType.Constant => AggregateType.S32,
|
||||
OperandType.ConstantBuffer => AggregateType.FP32,
|
||||
OperandType.Undefined => AggregateType.S32,
|
||||
_ => throw new ArgumentException($"Invalid operand type \"{type}\".")
|
||||
};
|
||||
|
21
src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs
Normal file
21
src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
{
|
||||
class ShaderProperties
|
||||
{
|
||||
private readonly Dictionary<int, BufferDefinition> _constantBuffers;
|
||||
|
||||
public IReadOnlyDictionary<int, BufferDefinition> ConstantBuffers => _constantBuffers;
|
||||
|
||||
public ShaderProperties()
|
||||
{
|
||||
_constantBuffers = new Dictionary<int, BufferDefinition>();
|
||||
}
|
||||
|
||||
public void AddConstantBuffer(int binding, BufferDefinition definition)
|
||||
{
|
||||
_constantBuffers[binding] = definition;
|
||||
}
|
||||
}
|
||||
}
|
28
src/Ryujinx.Graphics.Shader/StructuredIr/StructureType.cs
Normal file
28
src/Ryujinx.Graphics.Shader/StructuredIr/StructureType.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
{
|
||||
struct StructureField
|
||||
{
|
||||
public AggregateType Type { get; }
|
||||
public string Name { get; }
|
||||
public int ArrayLength { get; }
|
||||
|
||||
public StructureField(AggregateType type, string name, int arrayLength = 1)
|
||||
{
|
||||
Type = type;
|
||||
Name = name;
|
||||
ArrayLength = arrayLength;
|
||||
}
|
||||
}
|
||||
|
||||
class StructureType
|
||||
{
|
||||
public StructureField[] Fields { get; }
|
||||
|
||||
public StructureType(StructureField[] fields)
|
||||
{
|
||||
Fields = fields;
|
||||
}
|
||||
}
|
||||
}
|
@ -73,27 +73,34 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
Instruction inst = operation.Inst;
|
||||
StorageKind storageKind = operation.StorageKind;
|
||||
|
||||
if ((inst == Instruction.Load || inst == Instruction.Store) && storageKind.IsInputOrOutput())
|
||||
if (inst == Instruction.Load || inst == Instruction.Store)
|
||||
{
|
||||
IoVariable ioVariable = (IoVariable)operation.GetSource(0).Value;
|
||||
bool isOutput = storageKind.IsOutput();
|
||||
bool perPatch = storageKind.IsPerPatch();
|
||||
int location = 0;
|
||||
int component = 0;
|
||||
|
||||
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
||||
if (storageKind.IsInputOrOutput())
|
||||
{
|
||||
location = operation.GetSource(1).Value;
|
||||
IoVariable ioVariable = (IoVariable)operation.GetSource(0).Value;
|
||||
bool isOutput = storageKind.IsOutput();
|
||||
bool perPatch = storageKind.IsPerPatch();
|
||||
int location = 0;
|
||||
int component = 0;
|
||||
|
||||
if (operation.SourcesCount > 2 &&
|
||||
operation.GetSource(2).Type == OperandType.Constant &&
|
||||
context.Config.HasPerLocationInputOrOutputComponent(ioVariable, location, operation.GetSource(2).Value, isOutput))
|
||||
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
||||
{
|
||||
component = operation.GetSource(2).Value;
|
||||
}
|
||||
}
|
||||
location = operation.GetSource(1).Value;
|
||||
|
||||
context.Info.IoDefinitions.Add(new IoDefinition(storageKind, ioVariable, location, component));
|
||||
if (operation.SourcesCount > 2 &&
|
||||
operation.GetSource(2).Type == OperandType.Constant &&
|
||||
context.Config.HasPerLocationInputOrOutputComponent(ioVariable, location, operation.GetSource(2).Value, isOutput))
|
||||
{
|
||||
component = operation.GetSource(2).Value;
|
||||
}
|
||||
}
|
||||
|
||||
context.Info.IoDefinitions.Add(new IoDefinition(storageKind, ioVariable, location, component));
|
||||
}
|
||||
else if (storageKind == StorageKind.ConstantBuffer && operation.GetSource(0).Type == OperandType.Constant)
|
||||
{
|
||||
context.Config.ResourceManager.SetUsedConstantBufferBinding(operation.GetSource(0).Value);
|
||||
}
|
||||
}
|
||||
|
||||
bool vectorDest = IsVectorDestInst(inst);
|
||||
@ -105,7 +112,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
|
||||
for (int index = 0; index < operation.SourcesCount; index++)
|
||||
{
|
||||
sources[index] = context.GetOperand(operation.GetSource(index));
|
||||
sources[index] = context.GetOperandOrCbLoad(operation.GetSource(index));
|
||||
}
|
||||
|
||||
for (int index = 0; index < outDestsCount; index++)
|
||||
|
@ -298,6 +298,33 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
return newTemp;
|
||||
}
|
||||
|
||||
public IAstNode GetOperandOrCbLoad(Operand operand)
|
||||
{
|
||||
if (operand.Type == OperandType.ConstantBuffer)
|
||||
{
|
||||
int cbufSlot = operand.GetCbufSlot();
|
||||
int cbufOffset = operand.GetCbufOffset();
|
||||
|
||||
int binding = Config.ResourceManager.GetConstantBufferBinding(cbufSlot);
|
||||
int vecIndex = cbufOffset >> 2;
|
||||
int elemIndex = cbufOffset & 3;
|
||||
|
||||
Config.ResourceManager.SetUsedConstantBufferBinding(binding);
|
||||
|
||||
IAstNode[] sources = new IAstNode[]
|
||||
{
|
||||
new AstOperand(OperandType.Constant, binding),
|
||||
new AstOperand(OperandType.Constant, 0),
|
||||
new AstOperand(OperandType.Constant, vecIndex),
|
||||
new AstOperand(OperandType.Constant, elemIndex)
|
||||
};
|
||||
|
||||
return new AstOperation(Instruction.Load, StorageKind.ConstantBuffer, sources, sources.Length);
|
||||
}
|
||||
|
||||
return GetOperand(operand);
|
||||
}
|
||||
|
||||
public AstOperand GetOperand(Operand operand)
|
||||
{
|
||||
if (operand == null)
|
||||
@ -307,11 +334,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
|
||||
if (operand.Type != OperandType.LocalVariable)
|
||||
{
|
||||
if (operand.Type == OperandType.ConstantBuffer)
|
||||
{
|
||||
Config.SetUsedConstantBuffer(operand.GetCbufSlot());
|
||||
}
|
||||
|
||||
return new AstOperand(operand);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user