[Ryujinx.Graphics.Shader] Address dotnet-format issues (#5373)
* dotnet format style --severity info Some changes were manually reverted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0052 warnings * Silence dotnet format IDE0059 warnings * Address or silence dotnet format CA1069 warnings * Address or silence dotnet format CA2211 warnings * Address review comments * Fix formatting for switch expressions * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Format if-blocks correctly * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Fix naming rule violation, Convert shader properties to auto-property and convert values to const * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Run dotnet format after rebase * Address IDE0251 warnings * Address a few disabled IDE0060 warnings * Silence IDE0060 in .editorconfig * Run dotnet format after rebase * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Fix naming rule violations * Add trailing commas * Remove unused members and most unnecessary value assignments * Remove more unnecessary assignments * Remove NRE suppressor
This commit is contained in:
parent
e055217292
commit
9becbd7d72
162 changed files with 1611 additions and 1627 deletions
|
@ -92,4 +92,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
return indentation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,16 +244,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
}
|
||||
}
|
||||
|
||||
private static string GetTfLayout(TransformFeedbackOutput tfOutput)
|
||||
{
|
||||
if (tfOutput.Valid)
|
||||
{
|
||||
return $"layout (xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}) ";
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static void DeclareLocals(CodeGenContext context, StructuredFunction function)
|
||||
{
|
||||
foreach (AstOperand decl in function.Locals)
|
||||
|
@ -294,7 +284,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
AggregateType.Vector4 | AggregateType.FP64 => "dvec4",
|
||||
AggregateType.Vector4 | AggregateType.S32 => "ivec4",
|
||||
AggregateType.Vector4 | AggregateType.U32 => "uvec4",
|
||||
_ => throw new ArgumentException($"Invalid variable type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid variable type \"{type}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -315,7 +305,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
string layout = buffer.Layout switch
|
||||
{
|
||||
BufferLayout.Std140 => "std140",
|
||||
_ => "std430"
|
||||
_ => "std430",
|
||||
};
|
||||
|
||||
string set = string.Empty;
|
||||
|
@ -507,7 +497,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
{
|
||||
PixelImap.Constant => "flat ",
|
||||
PixelImap.ScreenLinear => "noperspective ",
|
||||
_ => string.Empty
|
||||
_ => string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -524,7 +514,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
2 => "vec2",
|
||||
3 => "vec3",
|
||||
4 => "vec4",
|
||||
_ => "float"
|
||||
_ => "float",
|
||||
};
|
||||
|
||||
context.AppendLine($"layout (location = {attr}) in {type} {name};");
|
||||
|
@ -611,7 +601,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
2 => "vec2",
|
||||
3 => "vec3",
|
||||
4 => "vec4",
|
||||
_ => "float"
|
||||
_ => "float",
|
||||
};
|
||||
|
||||
string xfb = string.Empty;
|
||||
|
@ -647,7 +637,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
{
|
||||
AttributeType.Sint => "ivec4",
|
||||
AttributeType.Uint => "uvec4",
|
||||
_ => "vec4"
|
||||
_ => "vec4",
|
||||
};
|
||||
|
||||
if (context.Config.GpuAccessor.QueryHostReducedPrecision() && context.Config.Stage == ShaderStage.Vertex && attr == 0)
|
||||
|
@ -721,4 +711,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
context.AppendLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
public const string LocalNamePrefix = "temp";
|
||||
|
||||
public const string SamplerNamePrefix = "tex";
|
||||
public const string ImageNamePrefix = "img";
|
||||
public const string ImageNamePrefix = "img";
|
||||
|
||||
public const string PerPatchAttributePrefix = "patch_attr_";
|
||||
public const string IAttributePrefix = "in_attr";
|
||||
|
@ -15,4 +15,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
public const string UndefinedName = "undef";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
public static string Generate(StructuredProgramInfo info, ShaderConfig config)
|
||||
{
|
||||
CodeGenContext context = new CodeGenContext(info, config);
|
||||
CodeGenContext context = new(info, config);
|
||||
|
||||
Declarations.Declare(context, info);
|
||||
|
||||
|
@ -74,7 +74,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
private static void PrintBlock(CodeGenContext context, AstBlock block, bool isMainFunction)
|
||||
{
|
||||
AstBlockVisitor visitor = new AstBlockVisitor(block);
|
||||
AstBlockVisitor visitor = new(block);
|
||||
|
||||
visitor.BlockEntered += (sender, e) =>
|
||||
{
|
||||
|
@ -96,7 +96,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
context.AppendLine($"if ({GetCondExpr(context, e.Block.Condition)})");
|
||||
break;
|
||||
|
||||
default: throw new InvalidOperationException($"Found unexpected block type \"{e.Block.Type}\".");
|
||||
default:
|
||||
throw new InvalidOperationException($"Found unexpected block type \"{e.Block.Type}\".");
|
||||
}
|
||||
|
||||
context.EnterScope();
|
||||
|
@ -173,4 +174,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
return ReinterpretCast(context, cond, srcType, AggregateType.Bool);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
public static string MultiplyHighS32 = "Helper_MultiplyHighS32";
|
||||
public static string MultiplyHighU32 = "Helper_MultiplyHighU32";
|
||||
|
||||
public static string Shuffle = "Helper_Shuffle";
|
||||
public static string Shuffle = "Helper_Shuffle";
|
||||
public static string ShuffleDown = "Helper_ShuffleDown";
|
||||
public static string ShuffleUp = "Helper_ShuffleUp";
|
||||
public static string ShuffleXor = "Helper_ShuffleXor";
|
||||
public static string SwizzleAdd = "Helper_SwizzleAdd";
|
||||
public static string ShuffleUp = "Helper_ShuffleUp";
|
||||
public static string ShuffleXor = "Helper_ShuffleXor";
|
||||
public static string SwizzleAdd = "Helper_SwizzleAdd";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,4 +197,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
throw new InvalidOperationException($"Unexpected instruction type \"{info.Type}\".");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,4 +24,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,4 +26,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
return $"{function.Name}({string.Join(", ", args)})";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,4 +26,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
_infoTable = new InstInfo[(int)Instruction.Count];
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
Add(Instruction.AtomicAdd, InstType.AtomicBinary, "atomicAdd");
|
||||
Add(Instruction.AtomicAnd, InstType.AtomicBinary, "atomicAnd");
|
||||
Add(Instruction.AtomicCompareAndSwap, InstType.AtomicTernary, "atomicCompSwap");
|
||||
|
@ -125,6 +126,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
Add(Instruction.VoteAll, InstType.CallUnary, "allInvocationsARB");
|
||||
Add(Instruction.VoteAllEqual, InstType.CallUnary, "allInvocationsEqualARB");
|
||||
Add(Instruction.VoteAny, InstType.CallUnary, "anyInvocationARB");
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
private static void Add(Instruction inst, InstType flags, string opName = null, int precedence = 0)
|
||||
|
@ -163,7 +165,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
// If the node isn't a operation, then it can only be a operand,
|
||||
// and those never needs to be surrounded in parenthesis.
|
||||
if (!(node is AstOperation operation))
|
||||
if (node is not AstOperation operation)
|
||||
{
|
||||
// This is sort of a special case, if this is a negative constant,
|
||||
// and it is consumed by a unary operation, we need to put on the parenthesis,
|
||||
|
@ -208,7 +210,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
private static bool IsNegativeConst(IAstNode node)
|
||||
{
|
||||
if (!(node is AstOperand operand))
|
||||
if (node is not AstOperand operand)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -216,4 +218,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
return operand.Type == OperandType.Constant && operand.Value < 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ using Ryujinx.Graphics.Shader.StructuredIr;
|
|||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
||||
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
||||
|
||||
|
@ -42,14 +41,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||
|
||||
var texCallBuilder = new StringBuilder();
|
||||
|
||||
if (texOp.Inst == Instruction.ImageAtomic)
|
||||
{
|
||||
texCallBuilder.Append((texOp.Flags & TextureFlags.AtomicMask) switch {
|
||||
texCallBuilder.Append((texOp.Flags & TextureFlags.AtomicMask) switch
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
TextureFlags.Add => "imageAtomicAdd",
|
||||
TextureFlags.Minimum => "imageAtomicMin",
|
||||
TextureFlags.Maximum => "imageAtomicMax",
|
||||
|
@ -61,6 +62,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
TextureFlags.Swap => "imageAtomicExchange",
|
||||
TextureFlags.CAS => "imageAtomicCompSwap",
|
||||
_ => "imageAtomicAdd",
|
||||
#pragma warning restore IDE0055
|
||||
});
|
||||
}
|
||||
else
|
||||
|
@ -131,7 +133,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
AggregateType.S32 => NumberFormatter.FormatInt(0),
|
||||
AggregateType.U32 => NumberFormatter.FormatUint(0),
|
||||
_ => NumberFormatter.FormatFloat(0)
|
||||
_ => NumberFormatter.FormatFloat(0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +142,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
AggregateType.S32 => "i",
|
||||
AggregateType.U32 => "u",
|
||||
_ => string.Empty
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
Append($"{prefix}vec4({string.Join(", ", cElems)})");
|
||||
|
@ -159,7 +161,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
TextureFlags.Increment => NumberFormatter.FormatInt(1, type), // TODO: Clamp value
|
||||
TextureFlags.Decrement => NumberFormatter.FormatInt(-1, type), // TODO: Clamp value
|
||||
_ => Src(type)
|
||||
_ => Src(type),
|
||||
};
|
||||
|
||||
Append(value);
|
||||
|
@ -248,25 +250,25 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||
|
||||
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
|
||||
bool isGather = (texOp.Flags & TextureFlags.Gather) != 0;
|
||||
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
|
||||
bool isGather = (texOp.Flags & TextureFlags.Gather) != 0;
|
||||
bool hasDerivatives = (texOp.Flags & TextureFlags.Derivatives) != 0;
|
||||
bool intCoords = (texOp.Flags & TextureFlags.IntCoords) != 0;
|
||||
bool hasLodBias = (texOp.Flags & TextureFlags.LodBias) != 0;
|
||||
bool hasLodLevel = (texOp.Flags & TextureFlags.LodLevel) != 0;
|
||||
bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0;
|
||||
bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0;
|
||||
bool intCoords = (texOp.Flags & TextureFlags.IntCoords) != 0;
|
||||
bool hasLodBias = (texOp.Flags & TextureFlags.LodBias) != 0;
|
||||
bool hasLodLevel = (texOp.Flags & TextureFlags.LodLevel) != 0;
|
||||
bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0;
|
||||
bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0;
|
||||
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||
bool isMultisample = (texOp.Type & SamplerType.Multisample) != 0;
|
||||
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
|
||||
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
|
||||
|
||||
bool colorIsVector = isGather || !isShadow;
|
||||
|
||||
SamplerType type = texOp.Type & SamplerType.Mask;
|
||||
|
||||
bool is2D = type == SamplerType.Texture2D;
|
||||
bool is2D = type == SamplerType.Texture2D;
|
||||
bool isCube = type == SamplerType.TextureCube;
|
||||
|
||||
// 2D Array and Cube shadow samplers with LOD level or bias requires an extension.
|
||||
|
@ -500,14 +502,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
if (hasLodBias)
|
||||
{
|
||||
Append(Src(AggregateType.FP32));
|
||||
Append(Src(AggregateType.FP32));
|
||||
}
|
||||
|
||||
// textureGather* optional extra component index,
|
||||
// not needed for shadow samplers.
|
||||
if (isGather && !isShadow)
|
||||
{
|
||||
Append(Src(AggregateType.S32));
|
||||
Append(Src(AggregateType.S32));
|
||||
}
|
||||
|
||||
texCall += ")" + (colorIsVector ? GetMaskMultiDest(texOp.Index) : "");
|
||||
|
@ -584,7 +586,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
case StorageKind.ConstantBuffer:
|
||||
case StorageKind.StorageBuffer:
|
||||
if (!(operation.GetSource(srcIndex++) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
||||
if (operation.GetSource(srcIndex++) is not AstOperand bindingIndex || bindingIndex.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -594,7 +596,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
? context.Config.Properties.ConstantBuffers[binding]
|
||||
: context.Config.Properties.StorageBuffers[binding];
|
||||
|
||||
if (!(operation.GetSource(srcIndex++) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
|
||||
if (operation.GetSource(srcIndex++) is not AstOperand fieldIndex || fieldIndex.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -606,7 +608,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
case StorageKind.LocalMemory:
|
||||
case StorageKind.SharedMemory:
|
||||
if (!(operation.GetSource(srcIndex++) is AstOperand bindingId) || bindingId.Type != OperandType.Constant)
|
||||
if (operation.GetSource(srcIndex++) is not AstOperand { Type: OperandType.Constant } bindingId)
|
||||
{
|
||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -623,7 +625,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
case StorageKind.InputPerPatch:
|
||||
case StorageKind.Output:
|
||||
case StorageKind.OutputPerPatch:
|
||||
if (!(operation.GetSource(srcIndex++) is AstOperand varId) || varId.Type != OperandType.Constant)
|
||||
if (operation.GetSource(srcIndex++) is not AstOperand varId || varId.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -636,7 +638,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
||||
{
|
||||
if (!(operation.GetSource(srcIndex++) is AstOperand vecIndex) || vecIndex.Type != OperandType.Constant)
|
||||
if (operation.GetSource(srcIndex++) is not AstOperand vecIndex || vecIndex.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -733,4 +735,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
return swizzle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,4 +53,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
return $".{"xy".AsSpan(index, 1)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,4 +29,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
public InstInfo(InstType type, string opName, int precedence)
|
||||
{
|
||||
Type = type;
|
||||
OpName = opName;
|
||||
Type = type;
|
||||
OpName = opName;
|
||||
Precedence = precedence;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,35 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||
{
|
||||
[Flags]
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
enum InstType
|
||||
{
|
||||
OpNullary = Op | 0,
|
||||
OpUnary = Op | 1,
|
||||
OpBinary = Op | 2,
|
||||
OpNullary = Op | 0,
|
||||
OpUnary = Op | 1,
|
||||
OpBinary = Op | 2,
|
||||
OpBinaryCom = Op | 2 | Commutative,
|
||||
OpTernary = Op | 3,
|
||||
OpTernary = Op | 3,
|
||||
|
||||
CallNullary = Call | 0,
|
||||
CallUnary = Call | 1,
|
||||
CallBinary = Call | 2,
|
||||
CallTernary = Call | 3,
|
||||
CallNullary = Call | 0,
|
||||
CallUnary = Call | 1,
|
||||
CallBinary = Call | 2,
|
||||
CallTernary = Call | 3,
|
||||
CallQuaternary = Call | 4,
|
||||
|
||||
// The atomic instructions have one extra operand,
|
||||
// for the storage slot and offset pair.
|
||||
AtomicBinary = Call | Atomic | 3,
|
||||
AtomicBinary = Call | Atomic | 3,
|
||||
AtomicTernary = Call | Atomic | 4,
|
||||
|
||||
Commutative = 1 << 8,
|
||||
Op = 1 << 9,
|
||||
Call = 1 << 10,
|
||||
Atomic = 1 << 11,
|
||||
Special = 1 << 12,
|
||||
Op = 1 << 9,
|
||||
Call = 1 << 10,
|
||||
Atomic = 1 << 11,
|
||||
Special = 1 << 12,
|
||||
|
||||
ArityMask = 0xff
|
||||
ArityMask = 0xff,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
IoVariable.FragmentOutputColor => GetFragmentOutputColorVariableName(config, location),
|
||||
IoVariable.FragmentOutputDepth => ("gl_FragDepth", AggregateType.FP32),
|
||||
IoVariable.FrontColorDiffuse => ("gl_FrontColor", AggregateType.Vector4 | AggregateType.FP32), // Deprecated.
|
||||
IoVariable.FrontColorSpecular => ("gl_FrontSecondaryColor", AggregateType.Vector4 | AggregateType.FP32), // Deprecated.
|
||||
IoVariable.FrontColorSpecular => ("gl_FrontSecondaryColor", AggregateType.Vector4 | AggregateType.FP32), // Deprecated.
|
||||
IoVariable.FrontFacing => ("gl_FrontFacing", AggregateType.Bool),
|
||||
IoVariable.InstanceId => ("gl_InstanceID", AggregateType.S32),
|
||||
IoVariable.InstanceIndex => ("gl_InstanceIndex", AggregateType.S32),
|
||||
|
@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
IoVariable.VertexIndex => ("gl_VertexIndex", AggregateType.S32),
|
||||
IoVariable.ViewportIndex => ("gl_ViewportIndex", AggregateType.S32),
|
||||
IoVariable.ViewportMask => ("gl_ViewportMask", AggregateType.Array | AggregateType.S32),
|
||||
_ => (null, AggregateType.Invalid)
|
||||
_ => (null, AggregateType.Invalid),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -139,4 +139,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
return (name, config.GetUserDefinedType(location, isOutput));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,4 +101,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
return "0x" + value.ToString("X", CultureInfo.InvariantCulture) + "u";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
|
@ -14,7 +13,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
{
|
||||
private static readonly string[] _stagePrefixes = new string[] { "cp", "vp", "tcp", "tep", "gp", "fp" };
|
||||
|
||||
private Dictionary<AstOperand, string> _locals;
|
||||
private readonly Dictionary<AstOperand, string> _locals;
|
||||
|
||||
public OperandManager()
|
||||
{
|
||||
|
@ -38,7 +37,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
OperandType.Constant => NumberFormatter.FormatInt(operand.Value),
|
||||
OperandType.LocalVariable => _locals[operand],
|
||||
OperandType.Undefined => DefaultNames.UndefinedName,
|
||||
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\".")
|
||||
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -96,11 +95,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
return _stagePrefixes[index];
|
||||
}
|
||||
|
||||
private static char GetSwizzleMask(int value)
|
||||
{
|
||||
return "xyzw"[value];
|
||||
}
|
||||
|
||||
public static string GetArgumentName(int argIndex)
|
||||
{
|
||||
return $"{DefaultNames.ArgumentNamePrefix}{argIndex}";
|
||||
|
@ -119,12 +113,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
{
|
||||
case StorageKind.ConstantBuffer:
|
||||
case StorageKind.StorageBuffer:
|
||||
if (!(operation.GetSource(0) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
||||
if (operation.GetSource(0) is not AstOperand bindingIndex || bindingIndex.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
||||
if (!(operation.GetSource(1) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
|
||||
if (operation.GetSource(1) is not AstOperand fieldIndex || fieldIndex.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -138,7 +132,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
case StorageKind.LocalMemory:
|
||||
case StorageKind.SharedMemory:
|
||||
if (!(operation.GetSource(0) is AstOperand bindingId) || bindingId.Type != OperandType.Constant)
|
||||
if (operation.GetSource(0) is not AstOperand { Type: OperandType.Constant } bindingId)
|
||||
{
|
||||
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -153,7 +147,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
case StorageKind.InputPerPatch:
|
||||
case StorageKind.Output:
|
||||
case StorageKind.OutputPerPatch:
|
||||
if (!(operation.GetSource(0) is AstOperand varId) || varId.Type != OperandType.Constant)
|
||||
if (operation.GetSource(0) is not AstOperand varId || varId.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -166,7 +160,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
||||
{
|
||||
if (!(operation.GetSource(1) is AstOperand vecIndex) || vecIndex.Type != OperandType.Constant)
|
||||
if (operation.GetSource(1) is not AstOperand vecIndex || vecIndex.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -232,4 +226,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
{
|
||||
public static string ReinterpretCast(
|
||||
CodeGenContext context,
|
||||
IAstNode node,
|
||||
AggregateType srcType,
|
||||
AggregateType dstType)
|
||||
IAstNode node,
|
||||
AggregateType srcType,
|
||||
AggregateType dstType)
|
||||
{
|
||||
if (node is AstOperand operand && operand.Type == OperandType.Constant)
|
||||
{
|
||||
|
@ -38,18 +38,24 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
{
|
||||
switch (dstType)
|
||||
{
|
||||
case AggregateType.Bool: return $"(floatBitsToInt({expr}) != 0)";
|
||||
case AggregateType.S32: return $"floatBitsToInt({expr})";
|
||||
case AggregateType.U32: return $"floatBitsToUint({expr})";
|
||||
case AggregateType.Bool:
|
||||
return $"(floatBitsToInt({expr}) != 0)";
|
||||
case AggregateType.S32:
|
||||
return $"floatBitsToInt({expr})";
|
||||
case AggregateType.U32:
|
||||
return $"floatBitsToUint({expr})";
|
||||
}
|
||||
}
|
||||
else if (dstType == AggregateType.FP32)
|
||||
{
|
||||
switch (srcType)
|
||||
{
|
||||
case AggregateType.Bool: return $"intBitsToFloat({ReinterpretBoolToInt(expr, node, AggregateType.S32)})";
|
||||
case AggregateType.S32: return $"intBitsToFloat({expr})";
|
||||
case AggregateType.U32: return $"uintBitsToFloat({expr})";
|
||||
case AggregateType.Bool:
|
||||
return $"intBitsToFloat({ReinterpretBoolToInt(expr, node, AggregateType.S32)})";
|
||||
case AggregateType.S32:
|
||||
return $"intBitsToFloat({expr})";
|
||||
case AggregateType.U32:
|
||||
return $"uintBitsToFloat({expr})";
|
||||
}
|
||||
}
|
||||
else if (srcType == AggregateType.Bool)
|
||||
|
@ -76,7 +82,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
private static string ReinterpretBoolToInt(string expr, IAstNode node, AggregateType dstType)
|
||||
{
|
||||
string trueExpr = NumberFormatter.FormatInt(IrConsts.True, dstType);
|
||||
string trueExpr = NumberFormatter.FormatInt(IrConsts.True, dstType);
|
||||
string falseExpr = NumberFormatter.FormatInt(IrConsts.False, dstType);
|
||||
|
||||
expr = InstGenHelper.Enclose(expr, node, Instruction.ConditionalSelect, isLhs: false);
|
||||
|
@ -84,4 +90,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
return $"({expr} ? {trueExpr} : {falseExpr})";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using Spv.Generator;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static Spv.Specification;
|
||||
using Instruction = Spv.Generator.Instruction;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
{
|
||||
using IrConsts = IntermediateRepresentation.IrConsts;
|
||||
using IrOperandType = IntermediateRepresentation.OperandType;
|
||||
|
||||
partial class CodeGenContext : Module
|
||||
|
@ -36,15 +37,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
public Dictionary<IoDefinition, Instruction> OutputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>();
|
||||
|
||||
public StructuredFunction CurrentFunction { get; set; }
|
||||
private readonly Dictionary<AstOperand, Instruction> _locals = new Dictionary<AstOperand, Instruction>();
|
||||
private readonly Dictionary<int, Instruction[]> _localForArgs = new Dictionary<int, Instruction[]>();
|
||||
private readonly Dictionary<int, Instruction> _funcArgs = new Dictionary<int, Instruction>();
|
||||
private readonly Dictionary<int, (StructuredFunction, Instruction)> _functions = new Dictionary<int, (StructuredFunction, Instruction)>();
|
||||
private readonly Dictionary<AstOperand, Instruction> _locals = new();
|
||||
private readonly Dictionary<int, Instruction[]> _localForArgs = new();
|
||||
private readonly Dictionary<int, Instruction> _funcArgs = new();
|
||||
private readonly Dictionary<int, (StructuredFunction, Instruction)> _functions = new();
|
||||
|
||||
private class BlockState
|
||||
{
|
||||
private int _entryCount;
|
||||
private readonly List<Instruction> _labels = new List<Instruction>();
|
||||
private readonly List<Instruction> _labels = new();
|
||||
|
||||
public Instruction GetNextLabel(CodeGenContext context)
|
||||
{
|
||||
|
@ -67,7 +68,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<AstBlock, BlockState> _labels = new Dictionary<AstBlock, BlockState>();
|
||||
private readonly Dictionary<AstBlock, BlockState> _labels = new();
|
||||
|
||||
public Dictionary<AstBlock, (Instruction, Instruction)> LoopTargets { get; set; }
|
||||
|
||||
|
@ -98,7 +99,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
InputTopology.LinesAdjacency => 2,
|
||||
InputTopology.Triangles => 3,
|
||||
InputTopology.TrianglesAdjacency => 3,
|
||||
_ => throw new InvalidOperationException($"Invalid input topology \"{inPrimitive}\".")
|
||||
_ => throw new InvalidOperationException($"Invalid input topology \"{inPrimitive}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -222,7 +223,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
IrOperandType.Constant => GetConstant(type, operand),
|
||||
IrOperandType.LocalVariable => GetLocal(type, operand),
|
||||
IrOperandType.Undefined => GetUndefined(type),
|
||||
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\".")
|
||||
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -259,7 +260,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
AggregateType.Bool => ConstantFalse(TypeBool()),
|
||||
AggregateType.FP32 => Constant(TypeFP32(), 0f),
|
||||
AggregateType.FP64 => Constant(TypeFP64(), 0d),
|
||||
_ => Constant(GetType(type), 0)
|
||||
_ => Constant(GetType(type), 0),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -272,7 +273,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
AggregateType.FP64 => Constant(TypeFP64(), (double)BitConverter.Int32BitsToSingle(operand.Value)),
|
||||
AggregateType.S32 => Constant(TypeS32(), operand.Value),
|
||||
AggregateType.U32 => Constant(TypeU32(), (uint)operand.Value),
|
||||
_ => throw new ArgumentException($"Invalid type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid type \"{type}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -328,7 +329,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
AggregateType.Vector2 => 2,
|
||||
AggregateType.Vector3 => 3,
|
||||
AggregateType.Vector4 => 4,
|
||||
_ => 1
|
||||
_ => 1,
|
||||
};
|
||||
|
||||
return TypeVector(GetType(type & ~AggregateType.ElementCountMask), vectorLength);
|
||||
|
@ -342,7 +343,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
AggregateType.FP64 => TypeFP64(),
|
||||
AggregateType.S32 => TypeS32(),
|
||||
AggregateType.U32 => TypeU32(),
|
||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -359,7 +360,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
}
|
||||
else if (srcType == AggregateType.Bool)
|
||||
{
|
||||
var intTrue = Constant(TypeS32(), IrConsts.True);
|
||||
var intTrue = Constant(TypeS32(), IrConsts.True);
|
||||
var intFalse = Constant(TypeS32(), IrConsts.False);
|
||||
|
||||
return BitcastIfNeeded(dstType, AggregateType.S32, Select(TypeS32(), value, intTrue, intFalse));
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using Spv.Generator;
|
||||
|
@ -14,7 +13,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
{
|
||||
static class Declarations
|
||||
{
|
||||
private static readonly string[] StagePrefixes = new string[] { "cp", "vp", "tcp", "tep", "gp", "fp" };
|
||||
private static readonly string[] _stagePrefixes = { "cp", "vp", "tcp", "tep", "gp", "fp" };
|
||||
|
||||
public static void DeclareParameters(CodeGenContext context, StructuredFunction function)
|
||||
{
|
||||
|
@ -107,7 +106,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
private static void DeclareBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers, bool isBuffer)
|
||||
{
|
||||
HashSet<SpvInstruction> decoratedTypes = new HashSet<SpvInstruction>();
|
||||
HashSet<SpvInstruction> decoratedTypes = new();
|
||||
|
||||
foreach (BufferDefinition buffer in buffers)
|
||||
{
|
||||
|
@ -199,7 +198,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
SamplerType.Texture3D => Dim.Dim3D,
|
||||
SamplerType.TextureCube => Dim.Cube,
|
||||
SamplerType.TextureBuffer => Dim.Buffer,
|
||||
_ => throw new InvalidOperationException($"Invalid sampler type \"{descriptor.Type & SamplerType.Mask}\".")
|
||||
_ => throw new InvalidOperationException($"Invalid sampler type \"{descriptor.Type & SamplerType.Mask}\"."),
|
||||
};
|
||||
|
||||
var imageType = context.TypeImage(
|
||||
|
@ -282,7 +281,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
SamplerType.Texture3D => Dim.Dim3D,
|
||||
SamplerType.TextureCube => Dim.Cube,
|
||||
SamplerType.TextureBuffer => Dim.Buffer,
|
||||
_ => throw new ArgumentException($"Invalid sampler type \"{type & SamplerType.Mask}\".")
|
||||
_ => throw new ArgumentException($"Invalid sampler type \"{type & SamplerType.Mask}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -330,7 +329,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
TextureFormat.R10G10B10A2Unorm => ImageFormat.Rgb10A2,
|
||||
TextureFormat.R10G10B10A2Uint => ImageFormat.Rgb10a2ui,
|
||||
TextureFormat.R11G11B10Float => ImageFormat.R11fG11fB10f,
|
||||
_ => throw new ArgumentException($"Invalid texture format \"{format}\".")
|
||||
_ => throw new ArgumentException($"Invalid texture format \"{format}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -352,7 +351,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
(_, AggregateType varType) = IoMap.GetSpirvBuiltIn(ioVariable);
|
||||
AggregateType elemType = varType & AggregateType.ElementTypeMask;
|
||||
|
||||
if (elemType == AggregateType.S32 || elemType == AggregateType.U32)
|
||||
if (elemType is AggregateType.S32 or AggregateType.U32)
|
||||
{
|
||||
iq = PixelImap.Constant;
|
||||
}
|
||||
|
@ -410,7 +409,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
2 => AggregateType.Vector2,
|
||||
3 => AggregateType.Vector3,
|
||||
4 => AggregateType.Vector4,
|
||||
_ => AggregateType.Invalid
|
||||
_ => AggregateType.Invalid,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -420,7 +419,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
if (!isPerPatch && IoMap.IsPerVertex(ioVariable, context.Config.Stage, isOutput))
|
||||
{
|
||||
int arraySize = context.Config.Stage == ShaderStage.Geometry ? context.InputVertices : 32;
|
||||
spvType = context.TypeArray(spvType, context.Constant(context.TypeU32(), (LiteralInteger)arraySize));
|
||||
spvType = context.TypeArray(spvType, context.Constant(context.TypeU32(), arraySize));
|
||||
|
||||
if (context.Config.GpPassthrough && context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough())
|
||||
{
|
||||
|
@ -542,7 +541,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
private static string GetStagePrefix(ShaderStage stage)
|
||||
{
|
||||
return StagePrefixes[(int)stage];
|
||||
return _stagePrefixes[(int)stage];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
ShaderStage.TessellationEvaluation => ExecutionModel.TessellationEvaluation,
|
||||
ShaderStage.Geometry => ExecutionModel.Geometry,
|
||||
ShaderStage.Fragment => ExecutionModel.Fragment,
|
||||
_ => throw new ArgumentException($"Invalid shader stage \"{stage}\".")
|
||||
_ => throw new ArgumentException($"Invalid shader stage \"{stage}\"."),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,19 +14,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
static class Instructions
|
||||
{
|
||||
private const MemorySemanticsMask DefaultMemorySemantics =
|
||||
private const MemorySemanticsMask DefaultMemorySemantics =
|
||||
MemorySemanticsMask.ImageMemory |
|
||||
MemorySemanticsMask.AtomicCounterMemory |
|
||||
MemorySemanticsMask.WorkgroupMemory |
|
||||
MemorySemanticsMask.UniformMemory |
|
||||
MemorySemanticsMask.AcquireRelease;
|
||||
|
||||
private static readonly Func<CodeGenContext, AstOperation, OperationResult>[] InstTable;
|
||||
private static readonly Func<CodeGenContext, AstOperation, OperationResult>[] _instTable;
|
||||
|
||||
static Instructions()
|
||||
{
|
||||
InstTable = new Func<CodeGenContext, AstOperation, OperationResult>[(int)Instruction.Count];
|
||||
_instTable = new Func<CodeGenContext, AstOperation, OperationResult>[(int)Instruction.Count];
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
Add(Instruction.Absolute, GenerateAbsolute);
|
||||
Add(Instruction.Add, GenerateAdd);
|
||||
Add(Instruction.AtomicAdd, GenerateAtomicAdd);
|
||||
|
@ -141,16 +142,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
Add(Instruction.VoteAll, GenerateVoteAll);
|
||||
Add(Instruction.VoteAllEqual, GenerateVoteAllEqual);
|
||||
Add(Instruction.VoteAny, GenerateVoteAny);
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
private static void Add(Instruction inst, Func<CodeGenContext, AstOperation, OperationResult> handler)
|
||||
{
|
||||
InstTable[(int)(inst & Instruction.Mask)] = handler;
|
||||
_instTable[(int)(inst & Instruction.Mask)] = handler;
|
||||
}
|
||||
|
||||
public static OperationResult Generate(CodeGenContext context, AstOperation operation)
|
||||
{
|
||||
var handler = InstTable[(int)(operation.Inst & Instruction.Mask)];
|
||||
var handler = _instTable[(int)(operation.Inst & Instruction.Mask)];
|
||||
if (handler != null)
|
||||
{
|
||||
return handler(context, operation);
|
||||
|
@ -305,7 +307,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
Debug.Assert(funcId.Type == OperandType.Constant);
|
||||
|
||||
(var function, var spvFunc) = context.GetFunction(funcId.Value);
|
||||
var (function, spvFunc) = context.GetFunction(funcId.Value);
|
||||
|
||||
var args = new SpvInstruction[operation.SourcesCount - 1];
|
||||
var spvLocals = context.GetLocalForArgsPointers(funcId.Value);
|
||||
|
@ -615,7 +617,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
});
|
||||
}
|
||||
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||
|
||||
int srcIndex = isBindless ? 1 : 0;
|
||||
|
@ -625,11 +627,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
return context.Get(type, texOp.GetSource(srcIndex++));
|
||||
}
|
||||
|
||||
SpvInstruction index = null;
|
||||
|
||||
if (isIndexed)
|
||||
{
|
||||
index = Src(AggregateType.S32);
|
||||
Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
int coordsCount = texOp.Type.GetDimensions();
|
||||
|
@ -657,9 +657,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
SpvInstruction value = Src(componentType);
|
||||
|
||||
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
||||
(SpvInstruction imageType, SpvInstruction imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
||||
|
||||
var image = context.Load(imageType, imageVariable);
|
||||
context.Load(imageType, imageVariable);
|
||||
|
||||
SpvInstruction resultType = context.GetType(componentType);
|
||||
SpvInstruction imagePointerType = context.TypePointer(StorageClass.Image, resultType);
|
||||
|
@ -670,21 +670,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
var result = (texOp.Flags & TextureFlags.AtomicMask) switch
|
||||
{
|
||||
TextureFlags.Add => context.AtomicIAdd(resultType, pointer, one, zero, value),
|
||||
TextureFlags.Minimum => componentType == AggregateType.S32
|
||||
TextureFlags.Add => context.AtomicIAdd(resultType, pointer, one, zero, value),
|
||||
TextureFlags.Minimum => componentType == AggregateType.S32
|
||||
? context.AtomicSMin(resultType, pointer, one, zero, value)
|
||||
: context.AtomicUMin(resultType, pointer, one, zero, value),
|
||||
TextureFlags.Maximum => componentType == AggregateType.S32
|
||||
TextureFlags.Maximum => componentType == AggregateType.S32
|
||||
? context.AtomicSMax(resultType, pointer, one, zero, value)
|
||||
: context.AtomicUMax(resultType, pointer, one, zero, value),
|
||||
TextureFlags.Increment => context.AtomicIIncrement(resultType, pointer, one, zero),
|
||||
TextureFlags.Decrement => context.AtomicIDecrement(resultType, pointer, one, zero),
|
||||
TextureFlags.Increment => context.AtomicIIncrement(resultType, pointer, one, zero),
|
||||
TextureFlags.Decrement => context.AtomicIDecrement(resultType, pointer, one, zero),
|
||||
TextureFlags.BitwiseAnd => context.AtomicAnd(resultType, pointer, one, zero, value),
|
||||
TextureFlags.BitwiseOr => context.AtomicOr(resultType, pointer, one, zero, value),
|
||||
TextureFlags.BitwiseOr => context.AtomicOr(resultType, pointer, one, zero, value),
|
||||
TextureFlags.BitwiseXor => context.AtomicXor(resultType, pointer, one, zero, value),
|
||||
TextureFlags.Swap => context.AtomicExchange(resultType, pointer, one, zero, value),
|
||||
TextureFlags.CAS => context.AtomicCompareExchange(resultType, pointer, one, zero, zero, Src(componentType), value),
|
||||
_ => context.AtomicIAdd(resultType, pointer, one, zero, value),
|
||||
TextureFlags.Swap => context.AtomicExchange(resultType, pointer, one, zero, value),
|
||||
TextureFlags.CAS => context.AtomicCompareExchange(resultType, pointer, one, zero, zero, Src(componentType), value),
|
||||
_ => context.AtomicIAdd(resultType, pointer, one, zero, value),
|
||||
};
|
||||
|
||||
return new OperationResult(componentType, result);
|
||||
|
@ -704,7 +704,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
return GetZeroOperationResult(context, texOp, componentType, isVector: true);
|
||||
}
|
||||
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||
|
||||
int srcIndex = isBindless ? 1 : 0;
|
||||
|
@ -714,11 +714,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
return context.Get(type, texOp.GetSource(srcIndex++));
|
||||
}
|
||||
|
||||
SpvInstruction index = null;
|
||||
|
||||
if (isIndexed)
|
||||
{
|
||||
index = Src(AggregateType.S32);
|
||||
Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
int coordsCount = texOp.Type.GetDimensions();
|
||||
|
@ -744,7 +742,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
pCoords = Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
||||
var (imageType, imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
||||
|
||||
var image = context.Load(imageType, imageVariable);
|
||||
var imageComponentType = context.GetType(componentType);
|
||||
|
@ -768,7 +766,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
return OperationResult.Invalid;
|
||||
}
|
||||
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||
|
||||
int srcIndex = isBindless ? 1 : 0;
|
||||
|
@ -778,11 +776,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
return context.Get(type, texOp.GetSource(srcIndex++));
|
||||
}
|
||||
|
||||
SpvInstruction index = null;
|
||||
|
||||
if (isIndexed)
|
||||
{
|
||||
index = Src(AggregateType.S32);
|
||||
Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
int coordsCount = texOp.Type.GetDimensions();
|
||||
|
@ -833,7 +829,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
var texel = context.CompositeConstruct(context.TypeVector(context.GetType(componentType), ComponentsCount), cElems);
|
||||
|
||||
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
||||
var (imageType, imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
||||
|
||||
var image = context.Load(imageType, imageVariable);
|
||||
|
||||
|
@ -886,11 +882,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
return context.Get(type, texOp.GetSource(srcIndex++));
|
||||
}
|
||||
|
||||
SpvInstruction index = null;
|
||||
|
||||
if (isIndexed)
|
||||
{
|
||||
index = Src(AggregateType.S32);
|
||||
Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
int pCount = texOp.Type.GetDimensions();
|
||||
|
@ -916,7 +910,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
|
||||
|
||||
(_, var sampledImageType, var sampledImageVariable) = context.Samplers[meta];
|
||||
var (_, sampledImageType, sampledImageVariable) = context.Samplers[meta];
|
||||
|
||||
var image = context.Load(sampledImageType, sampledImageVariable);
|
||||
|
||||
|
@ -973,7 +967,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
loopBlock = loopBlock.Parent;
|
||||
}
|
||||
|
||||
(var loopTarget, var continueTarget) = context.LoopTargets[loopBlock];
|
||||
(_, SpvInstruction continueTarget) = context.LoopTargets[loopBlock];
|
||||
|
||||
context.Branch(continueTarget);
|
||||
|
||||
|
@ -1278,19 +1272,19 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
{
|
||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||
|
||||
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
|
||||
bool isGather = (texOp.Flags & TextureFlags.Gather) != 0;
|
||||
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
|
||||
bool isGather = (texOp.Flags & TextureFlags.Gather) != 0;
|
||||
bool hasDerivatives = (texOp.Flags & TextureFlags.Derivatives) != 0;
|
||||
bool intCoords = (texOp.Flags & TextureFlags.IntCoords) != 0;
|
||||
bool hasLodBias = (texOp.Flags & TextureFlags.LodBias) != 0;
|
||||
bool hasLodLevel = (texOp.Flags & TextureFlags.LodLevel) != 0;
|
||||
bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0;
|
||||
bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0;
|
||||
bool intCoords = (texOp.Flags & TextureFlags.IntCoords) != 0;
|
||||
bool hasLodBias = (texOp.Flags & TextureFlags.LodBias) != 0;
|
||||
bool hasLodLevel = (texOp.Flags & TextureFlags.LodLevel) != 0;
|
||||
bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0;
|
||||
bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0;
|
||||
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||
bool isMultisample = (texOp.Type & SamplerType.Multisample) != 0;
|
||||
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
|
||||
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
|
||||
|
||||
bool colorIsVector = isGather || !isShadow;
|
||||
|
||||
|
@ -1307,11 +1301,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
return context.Get(type, texOp.GetSource(srcIndex++));
|
||||
}
|
||||
|
||||
SpvInstruction index = null;
|
||||
|
||||
if (isIndexed)
|
||||
{
|
||||
index = Src(AggregateType.S32);
|
||||
Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
int coordsCount = texOp.Type.GetDimensions();
|
||||
|
@ -1395,7 +1387,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
derivatives = new[]
|
||||
{
|
||||
AssembleDerivativesVector(coordsCount), // dPdx
|
||||
AssembleDerivativesVector(coordsCount) // dPdy
|
||||
AssembleDerivativesVector(coordsCount), // dPdy
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1445,7 +1437,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
AssembleOffsetVector(coordsCount),
|
||||
AssembleOffsetVector(coordsCount),
|
||||
AssembleOffsetVector(coordsCount),
|
||||
AssembleOffsetVector(coordsCount)
|
||||
AssembleOffsetVector(coordsCount),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1474,7 +1466,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
// not needed for shadow samplers.
|
||||
if (isGather && !isShadow)
|
||||
{
|
||||
compIdx = Src(AggregateType.S32);
|
||||
compIdx = Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
var operandsList = new List<SpvInstruction>();
|
||||
|
@ -1521,7 +1513,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
|
||||
|
||||
(var imageType, var sampledImageType, var sampledImageVariable) = context.Samplers[meta];
|
||||
var (imageType, sampledImageType, sampledImageVariable) = context.Samplers[meta];
|
||||
|
||||
var image = context.Load(sampledImageType, sampledImageVariable);
|
||||
|
||||
|
@ -1595,16 +1587,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||
|
||||
SpvInstruction index = null;
|
||||
|
||||
if (isIndexed)
|
||||
{
|
||||
index = context.GetS32(texOp.GetSource(0));
|
||||
context.GetS32(texOp.GetSource(0));
|
||||
}
|
||||
|
||||
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
|
||||
|
||||
(var imageType, var sampledImageType, var sampledImageVariable) = context.Samplers[meta];
|
||||
(SpvInstruction imageType, SpvInstruction sampledImageType, SpvInstruction sampledImageVariable) = context.Samplers[meta];
|
||||
|
||||
var image = context.Load(sampledImageType, sampledImageVariable);
|
||||
image = context.Image(imageType, image);
|
||||
|
@ -1809,12 +1799,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
{
|
||||
case StorageKind.ConstantBuffer:
|
||||
case StorageKind.StorageBuffer:
|
||||
if (!(operation.GetSource(srcIndex++) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
||||
if (operation.GetSource(srcIndex++) is not AstOperand bindingIndex || bindingIndex.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
||||
if (!(operation.GetSource(srcIndex) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
|
||||
if (operation.GetSource(srcIndex) is not AstOperand fieldIndex || fieldIndex.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -1833,7 +1823,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
case StorageKind.LocalMemory:
|
||||
case StorageKind.SharedMemory:
|
||||
if (!(operation.GetSource(srcIndex++) is AstOperand bindingId) || bindingId.Type != OperandType.Constant)
|
||||
if (operation.GetSource(srcIndex++) is not AstOperand { Type: OperandType.Constant } bindingId)
|
||||
{
|
||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -1856,7 +1846,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
case StorageKind.InputPerPatch:
|
||||
case StorageKind.Output:
|
||||
case StorageKind.OutputPerPatch:
|
||||
if (!(operation.GetSource(srcIndex++) is AstOperand varId) || varId.Type != OperandType.Constant)
|
||||
if (operation.GetSource(srcIndex++) is not AstOperand varId || varId.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -1869,7 +1859,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
||||
{
|
||||
if (!(operation.GetSource(srcIndex++) is AstOperand vecIndex) || vecIndex.Type != OperandType.Constant)
|
||||
if (operation.GetSource(srcIndex++) is not AstOperand vecIndex || vecIndex.Type != OperandType.Constant)
|
||||
{
|
||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||
}
|
||||
|
@ -1964,7 +1954,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
private static SpvInstruction GetScalarInput(CodeGenContext context, IoVariable ioVariable)
|
||||
{
|
||||
(_, var varType) = IoMap.GetSpirvBuiltIn(ioVariable);
|
||||
var (_, varType) = IoMap.GetSpirvBuiltIn(ioVariable);
|
||||
varType &= AggregateType.ElementTypeMask;
|
||||
|
||||
var ioDefinition = new IoDefinition(StorageKind.Input, ioVariable);
|
||||
|
@ -2061,10 +2051,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
return new OperationResult(AggregateType.Bool, emitB(context.TypeBool(), context.Get(AggregateType.Bool, source)));
|
||||
}
|
||||
|
||||
private static OperationResult GenerateUnaryFP32(
|
||||
CodeGenContext context,
|
||||
AstOperation operation,
|
||||
Func<SpvInstruction, SpvInstruction, SpvInstruction> emit)
|
||||
private static OperationResult GenerateUnaryFP32(
|
||||
CodeGenContext context,
|
||||
AstOperation operation,
|
||||
Func<SpvInstruction, SpvInstruction, SpvInstruction> emit)
|
||||
{
|
||||
var source = operation.GetSource(0);
|
||||
return new OperationResult(AggregateType.FP32, emit(context.TypeFP32(), context.GetFP32(source)));
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
IoVariable.VertexIndex => (BuiltIn.VertexIndex, AggregateType.S32),
|
||||
IoVariable.ViewportIndex => (BuiltIn.ViewportIndex, AggregateType.S32),
|
||||
IoVariable.ViewportMask => (BuiltIn.ViewportMaskNV, AggregateType.Array | AggregateType.S32),
|
||||
_ => (default, AggregateType.Invalid)
|
||||
_ => (default, AggregateType.Invalid),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
IoVariable.TessellationLevelOuter => 4,
|
||||
IoVariable.ViewportMask => 1,
|
||||
IoVariable.UserDefined => MaxAttributes,
|
||||
_ => 1
|
||||
_ => 1,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -74,13 +74,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
case IoVariable.ClipDistance:
|
||||
case IoVariable.PointCoord:
|
||||
case IoVariable.ViewportMask:
|
||||
return !isOutput &&
|
||||
(stage == ShaderStage.TessellationControl ||
|
||||
stage == ShaderStage.TessellationEvaluation ||
|
||||
stage == ShaderStage.Geometry);
|
||||
return !isOutput &&
|
||||
stage is ShaderStage.TessellationControl or ShaderStage.TessellationEvaluation or ShaderStage.Geometry;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
{
|
||||
readonly struct OperationResult
|
||||
{
|
||||
public static OperationResult Invalid => new OperationResult(AggregateType.Invalid, null);
|
||||
public static OperationResult Invalid => new(AggregateType.Invalid, null);
|
||||
|
||||
public AggregateType Type { get; }
|
||||
public Instruction Value { get; }
|
||||
|
|
|
@ -17,15 +17,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
{
|
||||
// Resource pools for Spirv generation. Note: Increase count when more threads are being used.
|
||||
private const int GeneratorPoolCount = 1;
|
||||
private static ObjectPool<SpvInstructionPool> InstructionPool;
|
||||
private static ObjectPool<SpvLiteralIntegerPool> IntegerPool;
|
||||
private static object PoolLock;
|
||||
private static readonly ObjectPool<SpvInstructionPool> _instructionPool;
|
||||
private static readonly ObjectPool<SpvLiteralIntegerPool> _integerPool;
|
||||
private static readonly object _poolLock;
|
||||
|
||||
static SpirvGenerator()
|
||||
{
|
||||
InstructionPool = new (() => new SpvInstructionPool(), GeneratorPoolCount);
|
||||
IntegerPool = new (() => new SpvLiteralIntegerPool(), GeneratorPoolCount);
|
||||
PoolLock = new object();
|
||||
_instructionPool = new(() => new SpvInstructionPool(), GeneratorPoolCount);
|
||||
_integerPool = new(() => new SpvLiteralIntegerPool(), GeneratorPoolCount);
|
||||
_poolLock = new object();
|
||||
}
|
||||
|
||||
private const HelperFunctionsMask NeedsInvocationIdMask =
|
||||
|
@ -40,13 +40,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
SpvInstructionPool instPool;
|
||||
SpvLiteralIntegerPool integerPool;
|
||||
|
||||
lock (PoolLock)
|
||||
lock (_poolLock)
|
||||
{
|
||||
instPool = InstructionPool.Allocate();
|
||||
integerPool = IntegerPool.Allocate();
|
||||
instPool = _instructionPool.Allocate();
|
||||
integerPool = _integerPool.Allocate();
|
||||
}
|
||||
|
||||
CodeGenContext context = new CodeGenContext(info, config, instPool, integerPool);
|
||||
CodeGenContext context = new(info, config, instPool, integerPool);
|
||||
|
||||
context.AddCapability(Capability.GroupNonUniformBallot);
|
||||
context.AddCapability(Capability.GroupNonUniformShuffle);
|
||||
|
@ -133,10 +133,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
byte[] result = context.Generate();
|
||||
|
||||
lock (PoolLock)
|
||||
lock (_poolLock)
|
||||
{
|
||||
InstructionPool.Release(instPool);
|
||||
IntegerPool.Release(integerPool);
|
||||
_instructionPool.Release(instPool);
|
||||
_integerPool.Release(integerPool);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -144,7 +144,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
private static void Generate(CodeGenContext context, StructuredProgramInfo info, int funcIndex)
|
||||
{
|
||||
(var function, var spvFunc) = context.GetFunction(funcIndex);
|
||||
var (function, spvFunc) = context.GetFunction(funcIndex);
|
||||
|
||||
context.CurrentFunction = function;
|
||||
context.AddFunction(spvFunc);
|
||||
|
@ -160,7 +160,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
Generate(context, function.MainBlock);
|
||||
|
||||
// Functions must always end with a return.
|
||||
if (!(function.MainBlock.Last is AstOperation operation) ||
|
||||
if (function.MainBlock.Last is not AstOperation operation ||
|
||||
(operation.Inst != Instruction.Return && operation.Inst != Instruction.Discard))
|
||||
{
|
||||
context.Return();
|
||||
|
@ -232,7 +232,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
InputTopology.LinesAdjacency => ExecutionMode.InputLinesAdjacency,
|
||||
InputTopology.Triangles => ExecutionMode.Triangles,
|
||||
InputTopology.TrianglesAdjacency => ExecutionMode.InputTrianglesAdjacency,
|
||||
_ => throw new InvalidOperationException($"Invalid input topology \"{inputTopology}\".")
|
||||
_ => throw new InvalidOperationException($"Invalid input topology \"{inputTopology}\"."),
|
||||
});
|
||||
|
||||
context.AddExecutionMode(spvFunc, ExecutionMode.Invocations, (SpvLiteralInteger)context.Config.ThreadsPerInputPrimitive);
|
||||
|
@ -242,7 +242,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
OutputTopology.PointList => ExecutionMode.OutputPoints,
|
||||
OutputTopology.LineStrip => ExecutionMode.OutputLineStrip,
|
||||
OutputTopology.TriangleStrip => ExecutionMode.OutputTriangleStrip,
|
||||
_ => throw new InvalidOperationException($"Invalid output topology \"{context.Config.OutputTopology}\".")
|
||||
_ => throw new InvalidOperationException($"Invalid output topology \"{context.Config.OutputTopology}\"."),
|
||||
});
|
||||
|
||||
int maxOutputVertices = context.Config.GpPassthrough ? context.InputVertices : context.Config.MaxOutputVertices;
|
||||
|
@ -294,7 +294,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
private static void Generate(CodeGenContext context, AstBlock block)
|
||||
{
|
||||
AstBlockVisitor visitor = new AstBlockVisitor(block);
|
||||
AstBlockVisitor visitor = new(block);
|
||||
|
||||
var loopTargets = new Dictionary<AstBlock, (SpvInstruction, SpvInstruction)>();
|
||||
|
||||
|
@ -346,7 +346,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
// if the condition is true.
|
||||
AstBlock mergeBlock = e.Block.Parent;
|
||||
|
||||
(var loopTarget, var continueTarget) = loopTargets[e.Block];
|
||||
var (loopTarget, continueTarget) = loopTargets[e.Block];
|
||||
|
||||
context.Branch(continueTarget);
|
||||
context.AddLabel(continueTarget);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
{
|
||||
readonly record struct TextureMeta(int CbufSlot, int Handle, TextureFormat Format);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue