Argument Buffers (#24)
* Stuff * More arg buffer stuff * Fixes * Rebase * Pass storage buffers to inline functions * Fix binding * Fix typo + Fix a couple shaders * Enforce ids * Dispose * Mark used buffers as resident * Update depth clear shader * Fix non-contiguous struct defs * Update ChangeBufferStride * Fix StorageBuffer assignments * Fix odyssey crash * Retain buffer bindings * Pad Std140 * Set texture data with safe buffers * Clone buffers * Always declare vert in * Stop clears from breaking OpenGL games * Fix depth clear * Use invariant position * Horribly inefficient texture & sampler arg buffers * Fix missing struct access * Minimise rebinds as much as possible * Build arg buffers on staging buffer
This commit is contained in:
committed by
Evan Husted
parent
a1ab7fe6a2
commit
dae0f3cded
@@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
public const string Tab = " ";
|
||||
|
||||
// The number of additional arguments that every function (except for the main one) must have (for instance support_buffer)
|
||||
public const int AdditionalArgCount = 1;
|
||||
public const int AdditionalArgCount = 2;
|
||||
|
||||
public StructuredFunction CurrentFunction { get; set; }
|
||||
|
||||
|
||||
@@ -56,8 +56,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
context.AppendLine();
|
||||
DeclareOutputAttributes(context, info.IoDefinitions.Where(x => x.StorageKind == StorageKind.Output));
|
||||
context.AppendLine();
|
||||
DeclareBufferStructures(context, context.Properties.ConstantBuffers.Values);
|
||||
DeclareBufferStructures(context, context.Properties.StorageBuffers.Values);
|
||||
DeclareBufferStructures(context, context.Properties.ConstantBuffers.Values, true);
|
||||
DeclareBufferStructures(context, context.Properties.StorageBuffers.Values, false);
|
||||
DeclareTextures(context, context.Properties.Textures.Values);
|
||||
|
||||
if ((info.HelperFunctionsMask & HelperFunctionsMask.FindLSB) != 0)
|
||||
{
|
||||
@@ -112,11 +113,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
{
|
||||
string name = context.OperandManager.DeclareLocal(decl);
|
||||
|
||||
context.AppendLine(GetVarTypeName(context, decl.VarType) + " " + name + ";");
|
||||
context.AppendLine(GetVarTypeName(decl.VarType) + " " + name + ";");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetVarTypeName(CodeGenContext context, AggregateType type, bool atomic = false)
|
||||
public static string GetVarTypeName(AggregateType type, bool atomic = false)
|
||||
{
|
||||
var s32 = atomic ? "atomic_int" : "int";
|
||||
var u32 = atomic ? "atomic_uint" : "uint";
|
||||
@@ -155,21 +156,36 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
{
|
||||
arraySize = $"[{memory.ArrayLength}]";
|
||||
}
|
||||
var typeName = GetVarTypeName(context, memory.Type & ~AggregateType.Array);
|
||||
var typeName = GetVarTypeName(memory.Type & ~AggregateType.Array);
|
||||
context.AppendLine($"{prefix}{typeName} {memory.Name}{arraySize};");
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeclareBufferStructures(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
|
||||
private static void DeclareBufferStructures(CodeGenContext context, IEnumerable<BufferDefinition> buffers, bool constant)
|
||||
{
|
||||
var name = constant ? "ConstantBuffers" : "StorageBuffers";
|
||||
var count = constant ? Defaults.MaxUniformBuffersPerStage : Defaults.MaxStorageBuffersPerStage;
|
||||
var addressSpace = constant ? "constant" : "device";
|
||||
|
||||
var argBufferPointers = new string[count];
|
||||
|
||||
foreach (BufferDefinition buffer in buffers)
|
||||
{
|
||||
context.AppendLine($"struct {DefaultNames.StructPrefix}_{buffer.Name}");
|
||||
var needsPadding = buffer.Layout == BufferLayout.Std140;
|
||||
|
||||
argBufferPointers[buffer.Binding] = $"{addressSpace} {Defaults.StructPrefix}_{buffer.Name}* {buffer.Name};";
|
||||
|
||||
context.AppendLine($"struct {Defaults.StructPrefix}_{buffer.Name}");
|
||||
context.EnterScope();
|
||||
|
||||
foreach (StructureField field in buffer.Type.Fields)
|
||||
{
|
||||
string typeName = GetVarTypeName(context, field.Type & ~AggregateType.Array);
|
||||
var type = field.Type;
|
||||
type |= (needsPadding && (field.Type & AggregateType.Array) != 0) ? AggregateType.Vector4 : AggregateType.Invalid;
|
||||
|
||||
type &= ~AggregateType.Array;
|
||||
|
||||
string typeName = GetVarTypeName(type);
|
||||
string arraySuffix = "";
|
||||
|
||||
if (field.Type.HasFlag(AggregateType.Array))
|
||||
@@ -191,6 +207,62 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
context.LeaveScope(";");
|
||||
context.AppendLine();
|
||||
}
|
||||
|
||||
context.AppendLine($"struct {name}");
|
||||
context.EnterScope();
|
||||
|
||||
for (int i = 0; i < argBufferPointers.Length; i++)
|
||||
{
|
||||
if (argBufferPointers[i] == null)
|
||||
{
|
||||
// We need to pad the struct definition in order to read
|
||||
// non-contiguous resources correctly.
|
||||
context.AppendLine($"ulong padding_{i};");
|
||||
}
|
||||
else
|
||||
{
|
||||
context.AppendLine(argBufferPointers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
context.LeaveScope(";");
|
||||
context.AppendLine();
|
||||
}
|
||||
|
||||
private static void DeclareTextures(CodeGenContext context, IEnumerable<TextureDefinition> textures)
|
||||
{
|
||||
context.AppendLine("struct Textures");
|
||||
context.EnterScope();
|
||||
|
||||
var argBufferPointers = new string[Defaults.MaxTexturesPerStage * 2];
|
||||
|
||||
foreach (TextureDefinition texture in textures)
|
||||
{
|
||||
var textureTypeName = texture.Type.ToMslTextureType();
|
||||
argBufferPointers[texture.Binding] = $"{textureTypeName} tex_{texture.Name};";
|
||||
|
||||
if (!texture.Separate)
|
||||
{
|
||||
argBufferPointers[Defaults.MaxTexturesPerStage + texture.Binding] = $"sampler samp_{texture.Name};";
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < argBufferPointers.Length; i++)
|
||||
{
|
||||
if (argBufferPointers[i] == null)
|
||||
{
|
||||
// We need to pad the struct definition in order to read
|
||||
// non-contiguous resources correctly.
|
||||
context.AppendLine($"ulong padding_{i};");
|
||||
}
|
||||
else
|
||||
{
|
||||
context.AppendLine(argBufferPointers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
context.LeaveScope(";");
|
||||
context.AppendLine();
|
||||
}
|
||||
|
||||
private static void DeclareInputAttributes(CodeGenContext context, IEnumerable<IoDefinition> inputs)
|
||||
@@ -201,7 +273,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inputs.Any() || context.Definitions.Stage == ShaderStage.Fragment)
|
||||
if (inputs.Any() || context.Definitions.Stage != ShaderStage.Compute)
|
||||
{
|
||||
string prefix = "";
|
||||
|
||||
@@ -220,7 +292,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
if (context.Definitions.Stage == ShaderStage.Fragment)
|
||||
{
|
||||
// TODO: check if it's needed
|
||||
context.AppendLine("float4 position [[position]];");
|
||||
context.AppendLine("float4 position [[position, invariant]];");
|
||||
context.AppendLine("bool front_facing [[front_facing]];");
|
||||
}
|
||||
|
||||
@@ -233,7 +305,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
IoVariable.VertexId => "uint",
|
||||
IoVariable.VertexIndex => "uint",
|
||||
IoVariable.PointCoord => "float2",
|
||||
_ => GetVarTypeName(context, context.Definitions.GetUserDefinedType(ioDefinition.Location, isOutput: false))
|
||||
_ => GetVarTypeName(context.Definitions.GetUserDefinedType(ioDefinition.Location, isOutput: false))
|
||||
};
|
||||
string name = ioDefinition.IoVariable switch
|
||||
{
|
||||
@@ -242,11 +314,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
IoVariable.VertexId => "vertex_id",
|
||||
IoVariable.VertexIndex => "vertex_index",
|
||||
IoVariable.PointCoord => "point_coord",
|
||||
_ => $"{DefaultNames.IAttributePrefix}{ioDefinition.Location}"
|
||||
_ => $"{Defaults.IAttributePrefix}{ioDefinition.Location}"
|
||||
};
|
||||
string suffix = ioDefinition.IoVariable switch
|
||||
{
|
||||
// IoVariable.Position => "[[position]]",
|
||||
// IoVariable.Position => "[[position, invariant]]",
|
||||
IoVariable.GlobalId => "[[thread_position_in_grid]]",
|
||||
IoVariable.VertexId => "[[vertex_id]]",
|
||||
// TODO: Avoid potential redeclaration
|
||||
@@ -297,9 +369,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
{
|
||||
IoVariable.Position => "float4",
|
||||
IoVariable.PointSize => "float",
|
||||
IoVariable.FragmentOutputColor => GetVarTypeName(context, context.Definitions.GetFragmentOutputColorType(ioDefinition.Location)),
|
||||
IoVariable.FragmentOutputColor => GetVarTypeName(context.Definitions.GetFragmentOutputColorType(ioDefinition.Location)),
|
||||
IoVariable.FragmentOutputDepth => "float",
|
||||
_ => GetVarTypeName(context, context.Definitions.GetUserDefinedType(ioDefinition.Location, isOutput: true))
|
||||
_ => GetVarTypeName(context.Definitions.GetUserDefinedType(ioDefinition.Location, isOutput: true))
|
||||
};
|
||||
string name = ioDefinition.IoVariable switch
|
||||
{
|
||||
@@ -307,11 +379,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
IoVariable.PointSize => "point_size",
|
||||
IoVariable.FragmentOutputColor => $"color{ioDefinition.Location}",
|
||||
IoVariable.FragmentOutputDepth => "depth",
|
||||
_ => $"{DefaultNames.OAttributePrefix}{ioDefinition.Location}"
|
||||
_ => $"{Defaults.OAttributePrefix}{ioDefinition.Location}"
|
||||
};
|
||||
string suffix = ioDefinition.IoVariable switch
|
||||
{
|
||||
IoVariable.Position => "[[position]]",
|
||||
IoVariable.Position => "[[position, invariant]]",
|
||||
IoVariable.PointSize => "[[point_size]]",
|
||||
IoVariable.UserDefined => $"[[user(loc{ioDefinition.Location})]]",
|
||||
IoVariable.FragmentOutputColor => $"[[color({ioDefinition.Location})]]",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
{
|
||||
static class DefaultNames
|
||||
static class Defaults
|
||||
{
|
||||
public const string LocalNamePrefix = "temp";
|
||||
|
||||
@@ -13,5 +13,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
public const string ArgumentNamePrefix = "a";
|
||||
|
||||
public const string UndefinedName = "0";
|
||||
|
||||
public const int MaxUniformBuffersPerStage = 18;
|
||||
public const int MaxStorageBuffersPerStage = 16;
|
||||
public const int MaxTexturesPerStage = 64;
|
||||
|
||||
public const uint ConstantBuffersIndex = 20;
|
||||
public const uint StorageBuffersIndex = 21;
|
||||
public const uint TexturesIndex = 22;
|
||||
}
|
||||
}
|
||||
@@ -49,8 +49,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
? AggregateType.S32
|
||||
: AggregateType.U32;
|
||||
|
||||
builder.Append($"(device {Declarations.GetVarTypeName(context, dstType, true)}*)&{GenerateLoadOrStore(context, operation, isStore: false)}");
|
||||
|
||||
builder.Append($"(device {Declarations.GetVarTypeName(dstType, true)}*)&{GenerateLoadOrStore(context, operation, isStore: false)}");
|
||||
|
||||
for (int argIndex = operation.SourcesCount - arity + 2; argIndex < operation.SourcesCount; argIndex++)
|
||||
{
|
||||
|
||||
@@ -21,11 +21,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
if (context.Definitions.Stage != ShaderStage.Compute)
|
||||
{
|
||||
args[0] = "in";
|
||||
args[1] = "support_buffer";
|
||||
args[1] = "constant_buffers";
|
||||
args[2] = "storage_buffers";
|
||||
}
|
||||
else
|
||||
{
|
||||
args[0] = "support_buffer";
|
||||
args[0] = "constant_buffers";
|
||||
args[1] = "storage_buffers";
|
||||
}
|
||||
|
||||
int argIndex = additionalArgCount;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
int srcIndex = 0;
|
||||
bool isStoreOrAtomic = operation.Inst == Instruction.Store || operation.Inst.IsAtomic();
|
||||
int inputsCount = isStoreOrAtomic ? operation.SourcesCount - 1 : operation.SourcesCount;
|
||||
bool fieldHasPadding = false;
|
||||
|
||||
if (operation.Inst == Instruction.AtomicCompareAndSwap)
|
||||
{
|
||||
@@ -46,7 +47,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
}
|
||||
|
||||
StructureField field = buffer.Type.Fields[fieldIndex.Value];
|
||||
varName = buffer.Name;
|
||||
|
||||
fieldHasPadding = buffer.Layout == BufferLayout.Std140
|
||||
&& ((field.Type & AggregateType.Vector4) == 0)
|
||||
&& ((field.Type & AggregateType.Array) != 0);
|
||||
|
||||
varName = storageKind == StorageKind.ConstantBuffer
|
||||
? "constant_buffers"
|
||||
: "storage_buffers";
|
||||
varName += "." + buffer.Name;
|
||||
varName += "->" + field.Name;
|
||||
varType = field.Type;
|
||||
break;
|
||||
@@ -130,6 +139,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
}
|
||||
}
|
||||
varName += fieldName;
|
||||
varName += fieldHasPadding ? ".x" : "";
|
||||
|
||||
if (isStore)
|
||||
{
|
||||
@@ -173,7 +183,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
coordsExpr = GetSourceExpr(context, texOp.GetSource(coordsIndex), AggregateType.FP32);
|
||||
}
|
||||
|
||||
return $"tex_{samplerName}.calculate_unclamped_lod(samp_{samplerName}, {coordsExpr}){GetMaskMultiDest(texOp.Index)}";
|
||||
return $"textures.tex_{samplerName}.calculate_unclamped_lod(textures.samp_{samplerName}, {coordsExpr}){GetMaskMultiDest(texOp.Index)}";
|
||||
}
|
||||
|
||||
public static string Store(CodeGenContext context, AstOperation operation)
|
||||
@@ -199,7 +209,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
bool colorIsVector = isGather || !isShadow;
|
||||
|
||||
string samplerName = GetSamplerName(context.Properties, texOp);
|
||||
string texCall = $"tex_{samplerName}";
|
||||
string texCall = $"textures.tex_{samplerName}";
|
||||
texCall += ".";
|
||||
|
||||
int srcIndex = 0;
|
||||
@@ -229,7 +239,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
texCall += "_compare";
|
||||
}
|
||||
|
||||
texCall += $"(samp_{samplerName}, ";
|
||||
texCall += $"(textures.samp_{samplerName}, ";
|
||||
}
|
||||
|
||||
int coordsCount = texOp.Type.GetDimensions();
|
||||
@@ -385,7 +395,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
}
|
||||
|
||||
string samplerName = GetSamplerName(context.Properties, texOp);
|
||||
string textureName = $"tex_{samplerName}";
|
||||
string textureName = $"textures.tex_{samplerName}";
|
||||
string texCall = textureName + ".";
|
||||
texCall += "get_num_samples()";
|
||||
|
||||
@@ -397,7 +407,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||
|
||||
string samplerName = GetSamplerName(context.Properties, texOp);
|
||||
string textureName = $"tex_{samplerName}";
|
||||
string textureName = $"textures.tex_{samplerName}";
|
||||
string texCall = textureName + ".";
|
||||
|
||||
if (texOp.Index == 3)
|
||||
|
||||
@@ -60,8 +60,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
private static (string, AggregateType) GetUserDefinedVariableName(ShaderDefinitions definitions, int location, int component, bool isOutput, bool isPerPatch)
|
||||
{
|
||||
string name = isPerPatch
|
||||
? DefaultNames.PerPatchAttributePrefix
|
||||
: (isOutput ? DefaultNames.OAttributePrefix : DefaultNames.IAttributePrefix);
|
||||
? Defaults.PerPatchAttributePrefix
|
||||
: (isOutput ? Defaults.OAttributePrefix : Defaults.IAttributePrefix);
|
||||
|
||||
if (location < 0)
|
||||
{
|
||||
|
||||
@@ -73,18 +73,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
if (stage != ShaderStage.Compute)
|
||||
{
|
||||
args[0] = stage == ShaderStage.Vertex ? "VertexIn in" : "FragmentIn in";
|
||||
args[1] = $"constant {DefaultNames.StructPrefix}_support_buffer* support_buffer";
|
||||
args[1] = "constant ConstantBuffers &constant_buffers";
|
||||
args[2] = "device StorageBuffers &storage_buffers";
|
||||
}
|
||||
else
|
||||
{
|
||||
args[0] = $"constant {DefaultNames.StructPrefix}_support_buffer* support_buffer";
|
||||
args[0] = "constant ConstantBuffers &constant_buffers";
|
||||
args[1] = "device StorageBuffers &storage_buffers";
|
||||
}
|
||||
}
|
||||
|
||||
int argIndex = additionalArgCount;
|
||||
for (int i = 0; i < function.InArguments.Length; i++)
|
||||
{
|
||||
args[argIndex++] = $"{Declarations.GetVarTypeName(context, function.InArguments[i])} {OperandManager.GetArgumentName(i)}";
|
||||
args[argIndex++] = $"{Declarations.GetVarTypeName(function.InArguments[i])} {OperandManager.GetArgumentName(i)}";
|
||||
}
|
||||
|
||||
for (int i = 0; i < function.OutArguments.Length; i++)
|
||||
@@ -92,12 +94,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
int j = i + function.InArguments.Length;
|
||||
|
||||
// Likely need to be made into pointers
|
||||
args[argIndex++] = $"out {Declarations.GetVarTypeName(context, function.OutArguments[i])} {OperandManager.GetArgumentName(j)}";
|
||||
args[argIndex++] = $"out {Declarations.GetVarTypeName(function.OutArguments[i])} {OperandManager.GetArgumentName(j)}";
|
||||
}
|
||||
|
||||
string funcKeyword = "inline";
|
||||
string funcName = null;
|
||||
string returnType = Declarations.GetVarTypeName(context, function.ReturnType);
|
||||
string returnType = Declarations.GetVarTypeName(function.ReturnType);
|
||||
|
||||
if (isMainFunc)
|
||||
{
|
||||
@@ -122,10 +124,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
|
||||
if (stage == ShaderStage.Vertex)
|
||||
{
|
||||
if (context.AttributeUsage.UsedInputAttributes != 0)
|
||||
{
|
||||
args = args.Prepend("VertexIn in [[stage_in]]").ToArray();
|
||||
}
|
||||
args = args.Prepend("VertexIn in [[stage_in]]").ToArray();
|
||||
}
|
||||
else if (stage == ShaderStage.Fragment)
|
||||
{
|
||||
@@ -148,27 +147,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
args = args.Append("uint thread_index_in_simdgroup [[thread_index_in_simdgroup]]").ToArray();
|
||||
}
|
||||
|
||||
foreach (var constantBuffer in context.Properties.ConstantBuffers.Values)
|
||||
{
|
||||
args = args.Append($"constant {DefaultNames.StructPrefix}_{constantBuffer.Name}* {constantBuffer.Name} [[buffer({constantBuffer.Binding})]]").ToArray();
|
||||
}
|
||||
|
||||
foreach (var storageBuffers in context.Properties.StorageBuffers.Values)
|
||||
{
|
||||
// Offset the binding by 15 to avoid clashing with the constant buffers
|
||||
args = args.Append($"device {DefaultNames.StructPrefix}_{storageBuffers.Name}* {storageBuffers.Name} [[buffer({storageBuffers.Binding + 15})]]").ToArray();
|
||||
}
|
||||
|
||||
foreach (var texture in context.Properties.Textures.Values)
|
||||
{
|
||||
var textureTypeName = texture.Type.ToMslTextureType();
|
||||
args = args.Append($"{textureTypeName} tex_{texture.Name} [[texture({texture.Binding})]]").ToArray();
|
||||
// If the texture is not separate, we need to declare a sampler
|
||||
if (!texture.Separate)
|
||||
{
|
||||
args = args.Append($"sampler samp_{texture.Name} [[sampler({texture.Binding})]]").ToArray();
|
||||
}
|
||||
}
|
||||
args = args.Append($"constant ConstantBuffers &constant_buffers [[buffer({Defaults.ConstantBuffersIndex})]]").ToArray();
|
||||
args = args.Append($"device StorageBuffers &storage_buffers [[buffer({Defaults.StorageBuffersIndex})]]").ToArray();
|
||||
args = args.Append($"constant Textures &textures [[buffer({Defaults.TexturesIndex})]]").ToArray();
|
||||
}
|
||||
|
||||
var funcPrefix = $"{funcKeyword} {returnType} {funcName ?? function.Name}(";
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
|
||||
public string DeclareLocal(AstOperand operand)
|
||||
{
|
||||
string name = $"{DefaultNames.LocalNamePrefix}_{_locals.Count}";
|
||||
string name = $"{Defaults.LocalNamePrefix}_{_locals.Count}";
|
||||
|
||||
_locals.Add(operand, name);
|
||||
|
||||
@@ -34,14 +34,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
OperandType.Argument => GetArgumentName(operand.Value),
|
||||
OperandType.Constant => NumberFormatter.FormatInt(operand.Value),
|
||||
OperandType.LocalVariable => _locals[operand],
|
||||
OperandType.Undefined => DefaultNames.UndefinedName,
|
||||
OperandType.Undefined => Defaults.UndefinedName,
|
||||
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetArgumentName(int argIndex)
|
||||
{
|
||||
return $"{DefaultNames.ArgumentNamePrefix}{argIndex}";
|
||||
return $"{Defaults.ArgumentNamePrefix}{argIndex}";
|
||||
}
|
||||
|
||||
public static AggregateType GetNodeDestType(CodeGenContext context, IAstNode node)
|
||||
|
||||
Reference in New Issue
Block a user