diff options
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/CodeGen')
27 files changed, 219 insertions, 234 deletions
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs index 9eb20f6f..551e5cef 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs @@ -92,4 +92,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl return indentation; } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs index 08e8eb19..94b850e7 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs @@ -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(); } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs index e909dcf0..842228ed 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs @@ -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"; } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs index fe0d275b..0140c1b9 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs @@ -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); } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs index 21c43547..22180272 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs @@ -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"; } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs index b2577a99..9208ceea 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs @@ -197,4 +197,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions throw new InvalidOperationException($"Unexpected instruction type \"{info.Type}\"."); } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenBallot.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenBallot.cs index 68793c5d..9a2bfef0 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenBallot.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenBallot.cs @@ -24,4 +24,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions } } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenCall.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenCall.cs index 2df6960d..0618ba8a 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenCall.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenCall.cs @@ -26,4 +26,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions return $"{function.Name}({string.Join(", ", args)})"; } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenFSI.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenFSI.cs index f61a53cb..a3d68028 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenFSI.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenFSI.cs @@ -26,4 +26,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions return null; } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs index 8b0b744a..c3d52b2c 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs @@ -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; } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs index 99376ffb..e0faed29 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs @@ -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 isArray = (texOp.Type & SamplerType.Array) != 0; - bool isIndexed = (texOp.Type & SamplerType.Indexed) != 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 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; } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenPacking.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenPacking.cs index 5a888e9c..ad84c485 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenPacking.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenPacking.cs @@ -53,4 +53,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions return $".{"xy".AsSpan(index, 1)}"; } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenVector.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenVector.cs index f09ea2e8..70174a5b 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenVector.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenVector.cs @@ -29,4 +29,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions } } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstInfo.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstInfo.cs index 7b2a6b46..a784e2bb 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstInfo.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstInfo.cs @@ -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; } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstType.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstType.cs index 84e36cdd..56985ae0 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstType.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstType.cs @@ -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, } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/IoMap.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/IoMap.cs index 2a73b8b0..3f88d2b3 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/IoMap.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/IoMap.cs @@ -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)); } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/NumberFormatter.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/NumberFormatter.cs index eb27e9bf..28e44c90 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/NumberFormatter.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/NumberFormatter.cs @@ -101,4 +101,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl return "0x" + value.ToString("X", CultureInfo.InvariantCulture) + "u"; } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs index 4f6ca642..0ca3b55f 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs @@ -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 } } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs index 22c8623c..3d7d0d0c 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs @@ -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})"; } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs index a4daaa67..9956e90a 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs @@ -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)); diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs index 59acea4f..da1e385a 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs @@ -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]; } } } diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/EnumConversion.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/EnumConversion.cs index 72541774..2bb7e836 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/EnumConversion.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/EnumConversion.cs @@ -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}\"."), }; } } diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs index b451f7a4..a53b40b2 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs @@ -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 isArray = (texOp.Type & SamplerType.Array) != 0; - bool isIndexed = (texOp.Type & SamplerType.Indexed) != 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 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))); diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/IoMap.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/IoMap.cs index d2ff0085..8a610323 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/IoMap.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/IoMap.cs @@ -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; } } -}
\ No newline at end of file +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/OperationResult.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/OperationResult.cs index f80c8110..a6e8e91f 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/OperationResult.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/OperationResult.cs @@ -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; } diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs index 5c736b60..c8fcd75a 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs @@ -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); diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/TextureMeta.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/TextureMeta.cs index 4de05603..56ea9a2a 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/TextureMeta.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/TextureMeta.cs @@ -1,4 +1,4 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv { readonly record struct TextureMeta(int CbufSlot, int Handle, TextureFormat Format); -}
\ No newline at end of file +} |