[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
|
@ -9,6 +9,6 @@ namespace Ryujinx.Graphics.Shader
|
|||
Greater,
|
||||
NotEqual,
|
||||
GreaterOrEqual,
|
||||
Always
|
||||
Always,
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
// Generic types.
|
||||
Float,
|
||||
Sint,
|
||||
Uint
|
||||
Uint,
|
||||
}
|
||||
|
||||
static class AttributeTypeExtensions
|
||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
AttributeType.Float => "vec4",
|
||||
AttributeType.Sint => "ivec4",
|
||||
AttributeType.Uint => "uvec4",
|
||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
AttributeType.Float => AggregateType.FP32,
|
||||
AttributeType.Sint => AggregateType.S32,
|
||||
AttributeType.Uint => AggregateType.U32,
|
||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\"."),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,6 @@ namespace Ryujinx.Graphics.Shader
|
|||
/// <summary>
|
||||
/// Buffer is written to.
|
||||
/// </summary>
|
||||
Write = 1 << 0
|
||||
Write = 1 << 0,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ 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),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,10 +74,8 @@ 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);
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
pushOpInfo.Consumers.Add(rightBlock, local);
|
||||
}
|
||||
|
||||
foreach ((ulong key, SyncTarget value) in SyncTargets)
|
||||
foreach ((ulong key, SyncTarget value) in SyncTargets)
|
||||
{
|
||||
rightBlock.SyncTargets.Add(key, value);
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
{
|
||||
if (OpCodes.Count != 0)
|
||||
{
|
||||
return OpCodes[OpCodes.Count - 1];
|
||||
return OpCodes[^1];
|
||||
}
|
||||
|
||||
return default;
|
||||
|
|
|
@ -3,7 +3,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
|
@ -12,8 +11,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
{
|
||||
public static DecodedProgram Decode(ShaderConfig config, ulong startAddress)
|
||||
{
|
||||
Queue<DecodedFunction> functionsQueue = new Queue<DecodedFunction>();
|
||||
Dictionary<ulong, DecodedFunction> functionsVisited = new Dictionary<ulong, DecodedFunction>();
|
||||
Queue<DecodedFunction> functionsQueue = new();
|
||||
Dictionary<ulong, DecodedFunction> functionsVisited = new();
|
||||
|
||||
DecodedFunction EnqueueFunction(ulong address)
|
||||
{
|
||||
|
@ -30,9 +29,9 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
|
||||
while (functionsQueue.TryDequeue(out DecodedFunction currentFunction))
|
||||
{
|
||||
List<Block> blocks = new List<Block>();
|
||||
Queue<Block> workQueue = new Queue<Block>();
|
||||
Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>();
|
||||
List<Block> blocks = new();
|
||||
Queue<Block> workQueue = new();
|
||||
Dictionary<ulong, Block> visited = new();
|
||||
|
||||
Block GetBlock(ulong blkAddress)
|
||||
{
|
||||
|
@ -168,7 +167,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
{
|
||||
index = 0;
|
||||
|
||||
int left = 0;
|
||||
int left = 0;
|
||||
int right = blocks.Count - 1;
|
||||
|
||||
while (left <= right)
|
||||
|
@ -273,12 +272,12 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
int offset;
|
||||
int count = 1;
|
||||
bool isStore = false;
|
||||
bool indexed = false;
|
||||
bool indexed;
|
||||
bool perPatch = false;
|
||||
|
||||
if (name == InstName.Ast)
|
||||
{
|
||||
InstAst opAst = new InstAst(opCode);
|
||||
InstAst opAst = new(opCode);
|
||||
count = (int)opAst.AlSize + 1;
|
||||
offset = opAst.Imm11;
|
||||
indexed = opAst.Phys;
|
||||
|
@ -287,7 +286,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
}
|
||||
else if (name == InstName.Ald)
|
||||
{
|
||||
InstAld opAld = new InstAld(opCode);
|
||||
InstAld opAld = new(opCode);
|
||||
count = (int)opAld.AlSize + 1;
|
||||
offset = opAld.Imm11;
|
||||
indexed = opAld.Phys;
|
||||
|
@ -296,7 +295,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
}
|
||||
else /* if (name == InstName.Ipa) */
|
||||
{
|
||||
InstIpa opIpa = new InstIpa(opCode);
|
||||
InstIpa opIpa = new(opCode);
|
||||
offset = opIpa.Imm10;
|
||||
indexed = opIpa.Idx;
|
||||
}
|
||||
|
@ -370,7 +369,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
|
||||
private static bool IsUnconditional(ref InstOp op)
|
||||
{
|
||||
InstConditional condOp = new InstConditional(op.RawOpCode);
|
||||
InstConditional condOp = new(op.RawOpCode);
|
||||
|
||||
if ((op.Name == InstName.Bra || op.Name == InstName.Exit) && condOp.Ccc != Ccc.T)
|
||||
{
|
||||
|
@ -391,9 +390,9 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
|
||||
if (lastOp.Name == InstName.Brx && block.Successors.Count == (hasNext ? 1 : 0))
|
||||
{
|
||||
HashSet<ulong> visited = new HashSet<ulong>();
|
||||
HashSet<ulong> visited = new();
|
||||
|
||||
InstBrx opBrx = new InstBrx(lastOp.RawOpCode);
|
||||
InstBrx opBrx = new(lastOp.RawOpCode);
|
||||
ulong baseOffset = lastOp.GetAbsoluteAddress();
|
||||
|
||||
// An indirect branch could go anywhere,
|
||||
|
@ -437,7 +436,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
// On a successful match, "BaseOffset" is the offset in bytes where the jump offsets are
|
||||
// located on the constant buffer, and "UpperBound" is the total number of offsets for the BRX, minus 1.
|
||||
|
||||
HashSet<Block> visited = new HashSet<Block>();
|
||||
HashSet<Block> visited = new();
|
||||
|
||||
var ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg);
|
||||
if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index].Name != InstName.Ldc)
|
||||
|
@ -507,7 +506,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
|
||||
private static BlockLocation FindFirstRegWrite(HashSet<Block> visited, BlockLocation location, int regIndex)
|
||||
{
|
||||
Queue<BlockLocation> toVisit = new Queue<BlockLocation>();
|
||||
Queue<BlockLocation> toVisit = new();
|
||||
toVisit.Enqueue(location);
|
||||
visited.Add(location.Block);
|
||||
|
||||
|
@ -554,10 +553,10 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
{
|
||||
Brk,
|
||||
Cont,
|
||||
Sync
|
||||
Sync,
|
||||
}
|
||||
|
||||
private struct PathBlockState
|
||||
private readonly struct PathBlockState
|
||||
{
|
||||
public Block Block { get; }
|
||||
|
||||
|
@ -565,37 +564,37 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
{
|
||||
None,
|
||||
PopPushOp,
|
||||
PushBranchOp
|
||||
PushBranchOp,
|
||||
}
|
||||
|
||||
private RestoreType _restoreType;
|
||||
private readonly RestoreType _restoreType;
|
||||
|
||||
private ulong _restoreValue;
|
||||
private MergeType _restoreMergeType;
|
||||
private readonly ulong _restoreValue;
|
||||
private readonly MergeType _restoreMergeType;
|
||||
|
||||
public bool ReturningFromVisit => _restoreType != RestoreType.None;
|
||||
|
||||
public PathBlockState(Block block)
|
||||
{
|
||||
Block = block;
|
||||
_restoreType = RestoreType.None;
|
||||
_restoreValue = 0;
|
||||
Block = block;
|
||||
_restoreType = RestoreType.None;
|
||||
_restoreValue = 0;
|
||||
_restoreMergeType = default;
|
||||
}
|
||||
|
||||
public PathBlockState(int oldStackSize)
|
||||
{
|
||||
Block = null;
|
||||
_restoreType = RestoreType.PopPushOp;
|
||||
_restoreValue = (ulong)oldStackSize;
|
||||
Block = null;
|
||||
_restoreType = RestoreType.PopPushOp;
|
||||
_restoreValue = (ulong)oldStackSize;
|
||||
_restoreMergeType = default;
|
||||
}
|
||||
|
||||
public PathBlockState(ulong syncAddress, MergeType mergeType)
|
||||
{
|
||||
Block = null;
|
||||
_restoreType = RestoreType.PushBranchOp;
|
||||
_restoreValue = syncAddress;
|
||||
Block = null;
|
||||
_restoreType = RestoreType.PushBranchOp;
|
||||
_restoreValue = syncAddress;
|
||||
_restoreMergeType = mergeType;
|
||||
}
|
||||
|
||||
|
@ -622,9 +621,9 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
|
||||
Block target = blocks[pushOp.GetAbsoluteAddress()];
|
||||
|
||||
Stack<PathBlockState> workQueue = new Stack<PathBlockState>();
|
||||
HashSet<Block> visited = new HashSet<Block>();
|
||||
Stack<(ulong, MergeType)> branchStack = new Stack<(ulong, MergeType)>();
|
||||
Stack<PathBlockState> workQueue = new();
|
||||
HashSet<Block> visited = new();
|
||||
Stack<(ulong, MergeType)> branchStack = new();
|
||||
|
||||
void Push(PathBlockState pbs)
|
||||
{
|
||||
|
@ -759,7 +758,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
{
|
||||
InstName.Pbk => MergeType.Brk,
|
||||
InstName.Pcnt => MergeType.Cont,
|
||||
_ => MergeType.Sync
|
||||
_ => MergeType.Sync,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -769,7 +768,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
{
|
||||
InstName.Brk => MergeType.Brk,
|
||||
InstName.Cont => MergeType.Cont,
|
||||
_ => MergeType.Sync
|
||||
_ => MergeType.Sync,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -26,6 +26,6 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
Tex = 1 << 12,
|
||||
TexB = 1 << 13,
|
||||
Bra = 1 << 14,
|
||||
NoPred = 1 << 15
|
||||
NoPred = 1 << 15,
|
||||
}
|
||||
}
|
|
@ -24,13 +24,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
}
|
||||
}
|
||||
|
||||
private static TableEntry[] _opCodes;
|
||||
private static readonly TableEntry[] _opCodes;
|
||||
|
||||
static InstTable()
|
||||
{
|
||||
_opCodes = new TableEntry[1 << EncodingBits];
|
||||
|
||||
#region Instructions
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
Add("1110111110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Al2p, InstEmit.Al2p, InstProps.Rd | InstProps.Ra);
|
||||
Add("1110111111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ald, InstEmit.Ald, InstProps.Rd | InstProps.Ra);
|
||||
Add("1110111111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ast, InstEmit.Ast, InstProps.Ra | InstProps.Rb2 | InstProps.Rc);
|
||||
|
@ -325,6 +326,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
Add("0011011x00xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
|
||||
Add("0100111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
|
||||
Add("010100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
|
||||
#pragma warning restore IDE0055
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -357,7 +359,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
|
||||
xMask = ~xMask;
|
||||
|
||||
TableEntry entry = new TableEntry(name, emitter, props, xBits);
|
||||
TableEntry entry = new(name, emitter, props, xBits);
|
||||
|
||||
for (int index = 0; index < (1 << xBits); index++)
|
||||
{
|
||||
|
|
|
@ -8,13 +8,13 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
|
||||
public RegisterType Type { get; }
|
||||
|
||||
public bool IsRZ => Type == RegisterType.Gpr && Index == RegisterConsts.RegisterZeroIndex;
|
||||
public bool IsRZ => Type == RegisterType.Gpr && Index == RegisterConsts.RegisterZeroIndex;
|
||||
public bool IsPT => Type == RegisterType.Predicate && Index == RegisterConsts.PredicateTrueIndex;
|
||||
|
||||
public Register(int index, RegisterType type)
|
||||
{
|
||||
Index = index;
|
||||
Type = type;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
public bool Equals(Register other)
|
||||
{
|
||||
return other.Index == Index &&
|
||||
other.Type == Type;
|
||||
other.Type == Type;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,12 +2,12 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
{
|
||||
static class RegisterConsts
|
||||
{
|
||||
public const int GprsCount = 255;
|
||||
public const int GprsCount = 255;
|
||||
public const int PredsCount = 7;
|
||||
public const int FlagsCount = 4;
|
||||
public const int TotalCount = GprsCount + PredsCount + FlagsCount;
|
||||
|
||||
public const int RegisterZeroIndex = GprsCount;
|
||||
public const int RegisterZeroIndex = GprsCount;
|
||||
public const int PredicateTrueIndex = PredsCount;
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
Lines,
|
||||
LinesAdjacency,
|
||||
Triangles,
|
||||
TrianglesAdjacency
|
||||
TrianglesAdjacency,
|
||||
}
|
||||
|
||||
static class InputTopologyExtensions
|
||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
InputTopology.LinesAdjacency => "lines_adjacency",
|
||||
InputTopology.Triangles => "triangles",
|
||||
InputTopology.TrianglesAdjacency => "triangles_adjacency",
|
||||
_ => "points"
|
||||
_ => "points",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
InputTopology.LinesAdjacency => 2,
|
||||
InputTopology.Triangles or
|
||||
InputTopology.TrianglesAdjacency => 3,
|
||||
_ => 1
|
||||
_ => 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
@ -21,10 +20,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
Tessellation = TessellationControl | TessellationEvaluation,
|
||||
VertexTessellationGeometry = Vertex | Tessellation | Geometry,
|
||||
TessellationGeometryFragment = Tessellation | Geometry | Fragment,
|
||||
AllGraphics = Vertex | Tessellation | Geometry | Fragment
|
||||
AllGraphics = Vertex | Tessellation | Geometry | Fragment,
|
||||
}
|
||||
|
||||
private struct AttributeEntry
|
||||
private readonly struct AttributeEntry
|
||||
{
|
||||
public int BaseOffset { get; }
|
||||
public AggregateType Type { get; }
|
||||
|
@ -344,7 +343,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
AggregateType.Vector2 => 2,
|
||||
AggregateType.Vector3 => 3,
|
||||
AggregateType.Vector4 => 4,
|
||||
_ => 1
|
||||
_ => 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,350 +7,350 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
public static void AtomCas(EmitterContext context)
|
||||
{
|
||||
InstAtomCas op = context.GetOp<InstAtomCas>();
|
||||
context.GetOp<InstAtomCas>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction AtomCas is not implemented.");
|
||||
}
|
||||
|
||||
public static void AtomsCas(EmitterContext context)
|
||||
{
|
||||
InstAtomsCas op = context.GetOp<InstAtomsCas>();
|
||||
context.GetOp<InstAtomsCas>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction AtomsCas is not implemented.");
|
||||
}
|
||||
|
||||
public static void B2r(EmitterContext context)
|
||||
{
|
||||
InstB2r op = context.GetOp<InstB2r>();
|
||||
context.GetOp<InstB2r>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction B2r is not implemented.");
|
||||
}
|
||||
|
||||
public static void Bpt(EmitterContext context)
|
||||
{
|
||||
InstBpt op = context.GetOp<InstBpt>();
|
||||
context.GetOp<InstBpt>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Bpt is not implemented.");
|
||||
}
|
||||
|
||||
public static void Cctl(EmitterContext context)
|
||||
{
|
||||
InstCctl op = context.GetOp<InstCctl>();
|
||||
context.GetOp<InstCctl>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Cctl is not implemented.");
|
||||
}
|
||||
|
||||
public static void Cctll(EmitterContext context)
|
||||
{
|
||||
InstCctll op = context.GetOp<InstCctll>();
|
||||
context.GetOp<InstCctll>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Cctll is not implemented.");
|
||||
}
|
||||
|
||||
public static void Cctlt(EmitterContext context)
|
||||
{
|
||||
InstCctlt op = context.GetOp<InstCctlt>();
|
||||
context.GetOp<InstCctlt>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Cctlt is not implemented.");
|
||||
}
|
||||
|
||||
public static void Cs2r(EmitterContext context)
|
||||
{
|
||||
InstCs2r op = context.GetOp<InstCs2r>();
|
||||
context.GetOp<InstCs2r>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Cs2r is not implemented.");
|
||||
}
|
||||
|
||||
public static void FchkR(EmitterContext context)
|
||||
{
|
||||
InstFchkR op = context.GetOp<InstFchkR>();
|
||||
context.GetOp<InstFchkR>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction FchkR is not implemented.");
|
||||
}
|
||||
|
||||
public static void FchkI(EmitterContext context)
|
||||
{
|
||||
InstFchkI op = context.GetOp<InstFchkI>();
|
||||
context.GetOp<InstFchkI>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction FchkI is not implemented.");
|
||||
}
|
||||
|
||||
public static void FchkC(EmitterContext context)
|
||||
{
|
||||
InstFchkC op = context.GetOp<InstFchkC>();
|
||||
context.GetOp<InstFchkC>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction FchkC is not implemented.");
|
||||
}
|
||||
|
||||
public static void Getcrsptr(EmitterContext context)
|
||||
{
|
||||
InstGetcrsptr op = context.GetOp<InstGetcrsptr>();
|
||||
context.GetOp<InstGetcrsptr>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Getcrsptr is not implemented.");
|
||||
}
|
||||
|
||||
public static void Getlmembase(EmitterContext context)
|
||||
{
|
||||
InstGetlmembase op = context.GetOp<InstGetlmembase>();
|
||||
context.GetOp<InstGetlmembase>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Getlmembase is not implemented.");
|
||||
}
|
||||
|
||||
public static void Ide(EmitterContext context)
|
||||
{
|
||||
InstIde op = context.GetOp<InstIde>();
|
||||
context.GetOp<InstIde>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Ide is not implemented.");
|
||||
}
|
||||
|
||||
public static void IdpR(EmitterContext context)
|
||||
{
|
||||
InstIdpR op = context.GetOp<InstIdpR>();
|
||||
context.GetOp<InstIdpR>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction IdpR is not implemented.");
|
||||
}
|
||||
|
||||
public static void IdpC(EmitterContext context)
|
||||
{
|
||||
InstIdpC op = context.GetOp<InstIdpC>();
|
||||
context.GetOp<InstIdpC>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction IdpC is not implemented.");
|
||||
}
|
||||
|
||||
public static void ImadspR(EmitterContext context)
|
||||
{
|
||||
InstImadspR op = context.GetOp<InstImadspR>();
|
||||
context.GetOp<InstImadspR>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction ImadspR is not implemented.");
|
||||
}
|
||||
|
||||
public static void ImadspI(EmitterContext context)
|
||||
{
|
||||
InstImadspI op = context.GetOp<InstImadspI>();
|
||||
context.GetOp<InstImadspI>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction ImadspI is not implemented.");
|
||||
}
|
||||
|
||||
public static void ImadspC(EmitterContext context)
|
||||
{
|
||||
InstImadspC op = context.GetOp<InstImadspC>();
|
||||
context.GetOp<InstImadspC>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction ImadspC is not implemented.");
|
||||
}
|
||||
|
||||
public static void ImadspRc(EmitterContext context)
|
||||
{
|
||||
InstImadspRc op = context.GetOp<InstImadspRc>();
|
||||
context.GetOp<InstImadspRc>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction ImadspRc is not implemented.");
|
||||
}
|
||||
|
||||
public static void Jcal(EmitterContext context)
|
||||
{
|
||||
InstJcal op = context.GetOp<InstJcal>();
|
||||
context.GetOp<InstJcal>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Jcal is not implemented.");
|
||||
}
|
||||
|
||||
public static void Jmp(EmitterContext context)
|
||||
{
|
||||
InstJmp op = context.GetOp<InstJmp>();
|
||||
context.GetOp<InstJmp>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Jmp is not implemented.");
|
||||
}
|
||||
|
||||
public static void Jmx(EmitterContext context)
|
||||
{
|
||||
InstJmx op = context.GetOp<InstJmx>();
|
||||
context.GetOp<InstJmx>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Jmx is not implemented.");
|
||||
}
|
||||
|
||||
public static void Ld(EmitterContext context)
|
||||
{
|
||||
InstLd op = context.GetOp<InstLd>();
|
||||
context.GetOp<InstLd>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Ld is not implemented.");
|
||||
}
|
||||
|
||||
public static void Lepc(EmitterContext context)
|
||||
{
|
||||
InstLepc op = context.GetOp<InstLepc>();
|
||||
context.GetOp<InstLepc>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Lepc is not implemented.");
|
||||
}
|
||||
|
||||
public static void Longjmp(EmitterContext context)
|
||||
{
|
||||
InstLongjmp op = context.GetOp<InstLongjmp>();
|
||||
context.GetOp<InstLongjmp>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Longjmp is not implemented.");
|
||||
}
|
||||
|
||||
public static void Pexit(EmitterContext context)
|
||||
{
|
||||
InstPexit op = context.GetOp<InstPexit>();
|
||||
context.GetOp<InstPexit>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Pexit is not implemented.");
|
||||
}
|
||||
|
||||
public static void Pixld(EmitterContext context)
|
||||
{
|
||||
InstPixld op = context.GetOp<InstPixld>();
|
||||
context.GetOp<InstPixld>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Pixld is not implemented.");
|
||||
}
|
||||
|
||||
public static void Plongjmp(EmitterContext context)
|
||||
{
|
||||
InstPlongjmp op = context.GetOp<InstPlongjmp>();
|
||||
context.GetOp<InstPlongjmp>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Plongjmp is not implemented.");
|
||||
}
|
||||
|
||||
public static void Pret(EmitterContext context)
|
||||
{
|
||||
InstPret op = context.GetOp<InstPret>();
|
||||
context.GetOp<InstPret>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Pret is not implemented.");
|
||||
}
|
||||
|
||||
public static void PrmtR(EmitterContext context)
|
||||
{
|
||||
InstPrmtR op = context.GetOp<InstPrmtR>();
|
||||
context.GetOp<InstPrmtR>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction PrmtR is not implemented.");
|
||||
}
|
||||
|
||||
public static void PrmtI(EmitterContext context)
|
||||
{
|
||||
InstPrmtI op = context.GetOp<InstPrmtI>();
|
||||
context.GetOp<InstPrmtI>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction PrmtI is not implemented.");
|
||||
}
|
||||
|
||||
public static void PrmtC(EmitterContext context)
|
||||
{
|
||||
InstPrmtC op = context.GetOp<InstPrmtC>();
|
||||
context.GetOp<InstPrmtC>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction PrmtC is not implemented.");
|
||||
}
|
||||
|
||||
public static void PrmtRc(EmitterContext context)
|
||||
{
|
||||
InstPrmtRc op = context.GetOp<InstPrmtRc>();
|
||||
context.GetOp<InstPrmtRc>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction PrmtRc is not implemented.");
|
||||
}
|
||||
|
||||
public static void R2b(EmitterContext context)
|
||||
{
|
||||
InstR2b op = context.GetOp<InstR2b>();
|
||||
context.GetOp<InstR2b>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction R2b is not implemented.");
|
||||
}
|
||||
|
||||
public static void Ram(EmitterContext context)
|
||||
{
|
||||
InstRam op = context.GetOp<InstRam>();
|
||||
context.GetOp<InstRam>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Ram is not implemented.");
|
||||
}
|
||||
|
||||
public static void Rtt(EmitterContext context)
|
||||
{
|
||||
InstRtt op = context.GetOp<InstRtt>();
|
||||
context.GetOp<InstRtt>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Rtt is not implemented.");
|
||||
}
|
||||
|
||||
public static void Sam(EmitterContext context)
|
||||
{
|
||||
InstSam op = context.GetOp<InstSam>();
|
||||
context.GetOp<InstSam>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Sam is not implemented.");
|
||||
}
|
||||
|
||||
public static void Setcrsptr(EmitterContext context)
|
||||
{
|
||||
InstSetcrsptr op = context.GetOp<InstSetcrsptr>();
|
||||
context.GetOp<InstSetcrsptr>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Setcrsptr is not implemented.");
|
||||
}
|
||||
|
||||
public static void Setlmembase(EmitterContext context)
|
||||
{
|
||||
InstSetlmembase op = context.GetOp<InstSetlmembase>();
|
||||
context.GetOp<InstSetlmembase>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Setlmembase is not implemented.");
|
||||
}
|
||||
|
||||
public static void St(EmitterContext context)
|
||||
{
|
||||
InstSt op = context.GetOp<InstSt>();
|
||||
context.GetOp<InstSt>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction St is not implemented.");
|
||||
}
|
||||
|
||||
public static void Stp(EmitterContext context)
|
||||
{
|
||||
InstStp op = context.GetOp<InstStp>();
|
||||
context.GetOp<InstStp>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Stp is not implemented.");
|
||||
}
|
||||
|
||||
public static void Txa(EmitterContext context)
|
||||
{
|
||||
InstTxa op = context.GetOp<InstTxa>();
|
||||
context.GetOp<InstTxa>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Txa is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vabsdiff(EmitterContext context)
|
||||
{
|
||||
InstVabsdiff op = context.GetOp<InstVabsdiff>();
|
||||
context.GetOp<InstVabsdiff>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vabsdiff is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vabsdiff4(EmitterContext context)
|
||||
{
|
||||
InstVabsdiff4 op = context.GetOp<InstVabsdiff4>();
|
||||
context.GetOp<InstVabsdiff4>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vabsdiff4 is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vadd(EmitterContext context)
|
||||
{
|
||||
InstVadd op = context.GetOp<InstVadd>();
|
||||
context.GetOp<InstVadd>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vadd is not implemented.");
|
||||
}
|
||||
|
||||
public static void Votevtg(EmitterContext context)
|
||||
{
|
||||
InstVotevtg op = context.GetOp<InstVotevtg>();
|
||||
context.GetOp<InstVotevtg>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Votevtg is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vset(EmitterContext context)
|
||||
{
|
||||
InstVset op = context.GetOp<InstVset>();
|
||||
context.GetOp<InstVset>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vset is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vshl(EmitterContext context)
|
||||
{
|
||||
InstVshl op = context.GetOp<InstVshl>();
|
||||
context.GetOp<InstVshl>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vshl is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vshr(EmitterContext context)
|
||||
{
|
||||
InstVshr op = context.GetOp<InstVshr>();
|
||||
context.GetOp<InstVshr>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vshr is not implemented.");
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.Decoders;
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
|
@ -18,7 +17,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
IDstFmt.S16 => short.MinValue,
|
||||
IDstFmt.U32 => uint.MinValue,
|
||||
IDstFmt.S32 => int.MinValue,
|
||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
|
||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,7 +29,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
IDstFmt.S16 => short.MaxValue,
|
||||
IDstFmt.U32 => uint.MaxValue,
|
||||
IDstFmt.S32 => int.MaxValue,
|
||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
|
||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -44,7 +43,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
ISrcDstFmt.S16 => short.MinValue,
|
||||
ISrcDstFmt.U32 => uint.MinValue,
|
||||
ISrcDstFmt.S32 => int.MinValue,
|
||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
|
||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -58,7 +57,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
ISrcDstFmt.S16 => short.MaxValue,
|
||||
ISrcDstFmt.U32 => uint.MaxValue,
|
||||
ISrcDstFmt.S32 => int.MaxValue,
|
||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
|
||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -69,7 +68,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
BoolOp.And => context.BitwiseAnd(input, pred),
|
||||
BoolOp.Or => context.BitwiseOr(input, pred),
|
||||
BoolOp.Xor => context.BitwiseExclusiveOr(input, pred),
|
||||
_ => input
|
||||
_ => input,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -89,7 +88,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
VectorSelect.S8B3 => SignExtendTo32(context, context.ShiftRightU32(src, Const(24)), 8),
|
||||
VectorSelect.S16H0 => SignExtendTo32(context, context.ShiftRightU32(src, Const(0)), 16),
|
||||
VectorSelect.S16H1 => SignExtendTo32(context, context.ShiftRightU32(src, Const(16)), 16),
|
||||
_ => src
|
||||
_ => src,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -134,7 +133,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
|
||||
context.Copy(GetZF(), context.FPCompareEqual(dest, zero, fpType));
|
||||
context.Copy(GetNF(), context.FPCompareLess (dest, zero, fpType));
|
||||
context.Copy(GetNF(), context.FPCompareLess(dest, zero, fpType));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
for (int index = 0; index < (int)op.AlSize + 1; index++)
|
||||
{
|
||||
Register rd = new Register(op.Dest + index, RegisterType.Gpr);
|
||||
Register rd = new(op.Dest + index, RegisterType.Gpr);
|
||||
|
||||
if (rd.IsRZ)
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
break;
|
||||
}
|
||||
|
||||
Register rd = new Register(op.SrcB + index, RegisterType.Gpr);
|
||||
Register rd = new(op.SrcB + index, RegisterType.Gpr);
|
||||
|
||||
if (op.Phys)
|
||||
{
|
||||
|
|
|
@ -22,7 +22,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
public static void Depbar(EmitterContext context)
|
||||
{
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
InstDepbar op = context.GetOp<InstDepbar>();
|
||||
#pragma warning restore IDE0059
|
||||
|
||||
// No operation.
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.Decoders;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
@ -80,7 +79,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
Ccc.Oft => GetVF(),
|
||||
Ccc.Rle => context.BitwiseOr(GetNF(), GetZF()),
|
||||
Ccc.Rgt => context.BitwiseNot(context.BitwiseOr(GetNF(), GetZF())),
|
||||
_ => Const(defaultCond)
|
||||
_ => Const(defaultCond),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.Decoders;
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
@ -140,7 +139,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
IntegerRound.Floor => context.FPFloor(srcB, srcType.ToInstFPType()),
|
||||
IntegerRound.Ceil => context.FPCeiling(srcB, srcType.ToInstFPType()),
|
||||
IntegerRound.Trunc => context.FPTruncate(srcB, srcType.ToInstFPType()),
|
||||
_ => srcB
|
||||
_ => srcB,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -191,7 +190,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
RoundMode2.Floor => context.FPFloor(srcB, fpType),
|
||||
RoundMode2.Ceil => context.FPCeiling(srcB, fpType),
|
||||
RoundMode2.Trunc => context.FPTruncate(srcB, fpType),
|
||||
_ => srcB
|
||||
_ => srcB,
|
||||
};
|
||||
|
||||
if (!isSignedInt)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.Decoders;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
@ -458,7 +457,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
MultiplyScale.M2 => ConstF(2f),
|
||||
MultiplyScale.M4 => ConstF(4f),
|
||||
MultiplyScale.M8 => ConstF(8f),
|
||||
_ => ConstF(1f) // Invalid, behave as if it had no scale.
|
||||
_ => ConstF(1f), // Invalid, behave as if it had no scale.
|
||||
};
|
||||
|
||||
if (scaleConst.AsFloat() == 1f)
|
||||
|
|
|
@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.Decoders;
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
@ -484,8 +483,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
Operand low = context.BitwiseAnd(res[0], Const(0xffff));
|
||||
Operand high = context.ShiftLeft (res[1], Const(16));
|
||||
Operand low = context.BitwiseAnd(res[0], Const(0xffff));
|
||||
Operand high = context.ShiftLeft(res[1], Const(16));
|
||||
|
||||
Operand packed = context.BitwiseOr(low, high);
|
||||
|
||||
|
@ -546,20 +545,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
Instruction inst;
|
||||
|
||||
switch (cond & ~FComp.Nan)
|
||||
var inst = (cond & ~FComp.Nan) switch
|
||||
{
|
||||
case FComp.Lt: inst = Instruction.CompareLess; break;
|
||||
case FComp.Eq: inst = Instruction.CompareEqual; break;
|
||||
case FComp.Le: inst = Instruction.CompareLessOrEqual; break;
|
||||
case FComp.Gt: inst = Instruction.CompareGreater; break;
|
||||
case FComp.Ne: inst = Instruction.CompareNotEqual; break;
|
||||
case FComp.Ge: inst = Instruction.CompareGreaterOrEqual; break;
|
||||
|
||||
default: throw new ArgumentException($"Unexpected condition \"{cond}\".");
|
||||
}
|
||||
|
||||
FComp.Lt => Instruction.CompareLess,
|
||||
FComp.Eq => Instruction.CompareEqual,
|
||||
FComp.Le => Instruction.CompareLessOrEqual,
|
||||
FComp.Gt => Instruction.CompareGreater,
|
||||
FComp.Ne => Instruction.CompareNotEqual,
|
||||
FComp.Ge => Instruction.CompareGreaterOrEqual,
|
||||
_ => throw new ArgumentException($"Unexpected condition \"{cond}\"."),
|
||||
};
|
||||
res = context.Add(inst | fpType, Local(), srcA, srcB);
|
||||
|
||||
if ((cond & FComp.Nan) != 0)
|
||||
|
|
|
@ -3,8 +3,6 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
|||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
@ -13,14 +11,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
public static void Bra(EmitterContext context)
|
||||
{
|
||||
InstBra op = context.GetOp<InstBra>();
|
||||
context.GetOp<InstBra>();
|
||||
|
||||
EmitBranch(context, context.CurrBlock.Successors[^1].Address);
|
||||
}
|
||||
|
||||
public static void Brk(EmitterContext context)
|
||||
{
|
||||
InstBrk op = context.GetOp<InstBrk>();
|
||||
context.GetOp<InstBrk>();
|
||||
|
||||
EmitBrkContSync(context);
|
||||
}
|
||||
|
@ -123,7 +121,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
public static void Cal(EmitterContext context)
|
||||
{
|
||||
InstCal op = context.GetOp<InstCal>();
|
||||
context.GetOp<InstCal>();
|
||||
|
||||
DecodedFunction function = context.Program.GetFunctionByAddress(context.CurrOp.GetAbsoluteAddress());
|
||||
|
||||
|
@ -147,7 +145,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
public static void Cont(EmitterContext context)
|
||||
{
|
||||
InstCont op = context.GetOp<InstCont>();
|
||||
context.GetOp<InstCont>();
|
||||
|
||||
EmitBrkContSync(context);
|
||||
}
|
||||
|
@ -185,28 +183,28 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
public static void Kil(EmitterContext context)
|
||||
{
|
||||
InstKil op = context.GetOp<InstKil>();
|
||||
context.GetOp<InstKil>();
|
||||
|
||||
context.Discard();
|
||||
}
|
||||
|
||||
public static void Pbk(EmitterContext context)
|
||||
{
|
||||
InstPbk op = context.GetOp<InstPbk>();
|
||||
context.GetOp<InstPbk>();
|
||||
|
||||
EmitPbkPcntSsy(context);
|
||||
}
|
||||
|
||||
public static void Pcnt(EmitterContext context)
|
||||
{
|
||||
InstPcnt op = context.GetOp<InstPcnt>();
|
||||
context.GetOp<InstPcnt>();
|
||||
|
||||
EmitPbkPcntSsy(context);
|
||||
}
|
||||
|
||||
public static void Ret(EmitterContext context)
|
||||
{
|
||||
InstRet op = context.GetOp<InstRet>();
|
||||
context.GetOp<InstRet>();
|
||||
|
||||
if (context.IsNonMain)
|
||||
{
|
||||
|
@ -220,14 +218,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
public static void Ssy(EmitterContext context)
|
||||
{
|
||||
InstSsy op = context.GetOp<InstSsy>();
|
||||
context.GetOp<InstSsy>();
|
||||
|
||||
EmitPbkPcntSsy(context);
|
||||
}
|
||||
|
||||
public static void Sync(EmitterContext context)
|
||||
{
|
||||
InstSync op = context.GetOp<InstSync>();
|
||||
context.GetOp<InstSync>();
|
||||
|
||||
EmitBrkContSync(context);
|
||||
}
|
||||
|
@ -275,7 +273,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
private static void EmitBranch(EmitterContext context, ulong address)
|
||||
{
|
||||
InstOp op = context.CurrOp;
|
||||
InstConditional opCond = new InstConditional(op.RawOpCode);
|
||||
InstConditional opCond = new(op.RawOpCode);
|
||||
|
||||
// If we're branching to the next instruction, then the branch
|
||||
// is useless and we can ignore it.
|
||||
|
|
|
@ -3,7 +3,6 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
|||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
@ -111,7 +110,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return new Operand[]
|
||||
{
|
||||
ConstF((float)Unsafe.As<ushort, Half>(ref low)),
|
||||
ConstF((float)Unsafe.As<ushort, Half>(ref high))
|
||||
ConstF((float)Unsafe.As<ushort, Half>(ref high)),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -123,7 +122,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return new Operand[]
|
||||
{
|
||||
ConstF((float)Unsafe.As<ushort, Half>(ref low)),
|
||||
ConstF((float)Unsafe.As<ushort, Half>(ref high))
|
||||
ConstF((float)Unsafe.As<ushort, Half>(ref high)),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -139,56 +138,51 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
public static Operand[] GetHalfUnpacked(EmitterContext context, Operand src, HalfSwizzle swizzle)
|
||||
{
|
||||
switch (swizzle)
|
||||
return swizzle switch
|
||||
{
|
||||
case HalfSwizzle.F16:
|
||||
return new Operand[]
|
||||
{
|
||||
HalfSwizzle.F16 => new Operand[]
|
||||
{
|
||||
context.UnpackHalf2x16Low (src),
|
||||
context.UnpackHalf2x16High(src)
|
||||
};
|
||||
|
||||
case HalfSwizzle.F32: return new Operand[] { src, src };
|
||||
|
||||
case HalfSwizzle.H0H0:
|
||||
return new Operand[]
|
||||
context.UnpackHalf2x16High(src),
|
||||
},
|
||||
HalfSwizzle.F32 => new Operand[] { src, src },
|
||||
HalfSwizzle.H0H0 => new Operand[]
|
||||
{
|
||||
context.UnpackHalf2x16Low(src),
|
||||
context.UnpackHalf2x16Low(src)
|
||||
};
|
||||
|
||||
case HalfSwizzle.H1H1:
|
||||
return new Operand[]
|
||||
context.UnpackHalf2x16Low(src),
|
||||
},
|
||||
HalfSwizzle.H1H1 => new Operand[]
|
||||
{
|
||||
context.UnpackHalf2x16High(src),
|
||||
context.UnpackHalf2x16High(src)
|
||||
};
|
||||
}
|
||||
|
||||
throw new ArgumentException($"Invalid swizzle \"{swizzle}\".");
|
||||
context.UnpackHalf2x16High(src),
|
||||
},
|
||||
_ => throw new ArgumentException($"Invalid swizzle \"{swizzle}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
public static Operand GetHalfPacked(EmitterContext context, OFmt swizzle, Operand[] results, int rd)
|
||||
{
|
||||
switch (swizzle)
|
||||
{
|
||||
case OFmt.F16: return context.PackHalf2x16(results[0], results[1]);
|
||||
case OFmt.F16:
|
||||
return context.PackHalf2x16(results[0], results[1]);
|
||||
|
||||
case OFmt.F32: return results[0];
|
||||
case OFmt.F32:
|
||||
return results[0];
|
||||
|
||||
case OFmt.MrgH0:
|
||||
{
|
||||
Operand h1 = GetHalfDest(context, rd, isHigh: true);
|
||||
{
|
||||
Operand h1 = GetHalfDest(context, rd, isHigh: true);
|
||||
|
||||
return context.PackHalf2x16(results[0], h1);
|
||||
}
|
||||
return context.PackHalf2x16(results[0], h1);
|
||||
}
|
||||
|
||||
case OFmt.MrgH1:
|
||||
{
|
||||
Operand h0 = GetHalfDest(context, rd, isHigh: false);
|
||||
{
|
||||
Operand h0 = GetHalfDest(context, rd, isHigh: false);
|
||||
|
||||
return context.PackHalf2x16(h0, results[1]);
|
||||
}
|
||||
return context.PackHalf2x16(h0, results[1]);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException($"Invalid swizzle \"{swizzle}\".");
|
||||
|
|
|
@ -510,7 +510,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
aLow = context.BitwiseNot(aLow);
|
||||
aHigh = context.BitwiseNot(aHigh);
|
||||
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
aLow = AddWithCarry(context, aLow, Const(1), out Operand aLowCOut);
|
||||
#pragma warning restore IDE0059
|
||||
aHigh = context.IAdd(aHigh, aLowCOut);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.Decoders;
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
@ -220,7 +219,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
else
|
||||
{
|
||||
res = context.ISubtract(srcA, srcB);
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
res = context.IAdd(res, context.BitwiseNot(GetCF()));
|
||||
#pragma warning restore IDE0059
|
||||
|
||||
switch (cond)
|
||||
{
|
||||
|
@ -287,17 +288,25 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
IComp.Gt => Instruction.CompareGreaterU32,
|
||||
IComp.Ne => Instruction.CompareNotEqual,
|
||||
IComp.Ge => Instruction.CompareGreaterOrEqualU32,
|
||||
_ => throw new InvalidOperationException($"Unexpected condition \"{cond}\".")
|
||||
_ => throw new InvalidOperationException($"Unexpected condition \"{cond}\"."),
|
||||
};
|
||||
|
||||
if (isSigned)
|
||||
{
|
||||
switch (cond)
|
||||
{
|
||||
case IComp.Lt: inst = Instruction.CompareLess; break;
|
||||
case IComp.Le: inst = Instruction.CompareLessOrEqual; break;
|
||||
case IComp.Gt: inst = Instruction.CompareGreater; break;
|
||||
case IComp.Ge: inst = Instruction.CompareGreaterOrEqual; break;
|
||||
case IComp.Lt:
|
||||
inst = Instruction.CompareLess;
|
||||
break;
|
||||
case IComp.Le:
|
||||
inst = Instruction.CompareLessOrEqual;
|
||||
break;
|
||||
case IComp.Gt:
|
||||
inst = Instruction.CompareGreater;
|
||||
break;
|
||||
case IComp.Ge:
|
||||
inst = Instruction.CompareGreaterOrEqual;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.Decoders;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
@ -103,10 +102,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
Operand res = logicOp switch
|
||||
{
|
||||
LogicOp.And => res = context.BitwiseAnd(srcA, srcB),
|
||||
LogicOp.Or => res = context.BitwiseOr(srcA, srcB),
|
||||
LogicOp.Xor => res = context.BitwiseExclusiveOr(srcA, srcB),
|
||||
_ => srcB
|
||||
LogicOp.And => context.BitwiseAnd(srcA, srcB),
|
||||
LogicOp.Or => context.BitwiseOr(srcA, srcB),
|
||||
LogicOp.Xor => context.BitwiseExclusiveOr(srcA, srcB),
|
||||
_ => srcB,
|
||||
};
|
||||
|
||||
EmitLopPredWrite(context, res, predOp, destPred);
|
||||
|
|
|
@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.Decoders;
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System.Numerics;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
|
@ -48,7 +47,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
AtomsSize.S32 => AtomSize.S32,
|
||||
AtomsSize.U64 => AtomSize.U64,
|
||||
AtomsSize.S64 => AtomSize.S64,
|
||||
_ => AtomSize.U32
|
||||
_ => AtomSize.U32,
|
||||
};
|
||||
|
||||
Operand id = Const(context.Config.ResourceManager.SharedMemoryId);
|
||||
|
@ -85,7 +84,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
Register dest = new Register(op.Dest + index, RegisterType.Gpr);
|
||||
Register dest = new(op.Dest + index, RegisterType.Gpr);
|
||||
|
||||
if (dest.IsRZ)
|
||||
{
|
||||
|
@ -309,14 +308,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
LsSize2.B64 => 2,
|
||||
LsSize2.B128 => 4,
|
||||
_ => 1
|
||||
_ => 1,
|
||||
};
|
||||
|
||||
Operand baseOffset = context.Copy(srcA);
|
||||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
Register dest = new Register(rd + index, RegisterType.Gpr);
|
||||
Register dest = new(rd + index, RegisterType.Gpr);
|
||||
|
||||
if (dest.IsRZ)
|
||||
{
|
||||
|
@ -354,7 +353,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
Register dest = new Register(rd + index, RegisterType.Gpr);
|
||||
Register dest = new(rd + index, RegisterType.Gpr);
|
||||
|
||||
if (dest.IsRZ)
|
||||
{
|
||||
|
@ -390,7 +389,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
LsSize2.B64 => 2,
|
||||
LsSize2.B128 => 4,
|
||||
_ => 1
|
||||
_ => 1,
|
||||
};
|
||||
|
||||
Operand baseOffset = context.Copy(srcA);
|
||||
|
@ -476,22 +475,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
LsSize.S8 => StorageKind.GlobalMemoryS8,
|
||||
LsSize.U16 => StorageKind.GlobalMemoryU16,
|
||||
LsSize.S16 => StorageKind.GlobalMemoryS16,
|
||||
_ => StorageKind.GlobalMemory
|
||||
_ => StorageKind.GlobalMemory,
|
||||
};
|
||||
}
|
||||
|
||||
private static int GetVectorCount(LsSize size)
|
||||
{
|
||||
switch (size)
|
||||
return size switch
|
||||
{
|
||||
case LsSize.B64:
|
||||
return 2;
|
||||
case LsSize.B128:
|
||||
case LsSize.UB128:
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 1;
|
||||
LsSize.B64 => 2,
|
||||
LsSize.B128 or LsSize.UB128 => 4,
|
||||
_ => 1,
|
||||
};
|
||||
}
|
||||
|
||||
private static (Operand, Operand) Get40BitsAddress(
|
||||
|
@ -544,10 +539,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
switch (size)
|
||||
{
|
||||
case LsSize.U8: value = ZeroExtendTo32(context, value, 8); break;
|
||||
case LsSize.U16: value = ZeroExtendTo32(context, value, 16); break;
|
||||
case LsSize.S8: value = SignExtendTo32(context, value, 8); break;
|
||||
case LsSize.S16: value = SignExtendTo32(context, value, 16); break;
|
||||
case LsSize.U8:
|
||||
value = ZeroExtendTo32(context, value, 8);
|
||||
break;
|
||||
case LsSize.U16:
|
||||
value = ZeroExtendTo32(context, value, 16);
|
||||
break;
|
||||
case LsSize.S8:
|
||||
value = SignExtendTo32(context, value, 8);
|
||||
break;
|
||||
case LsSize.S16:
|
||||
value = SignExtendTo32(context, value, 16);
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
public static void Nop(EmitterContext context)
|
||||
{
|
||||
InstNop op = context.GetOp<InstNop>();
|
||||
context.GetOp<InstNop>();
|
||||
|
||||
// No operation.
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
|
@ -221,7 +220,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
Operand destOperand = dest != RegisterConsts.RegisterZeroIndex ? Register(dest, RegisterType.Gpr) : null;
|
||||
|
||||
List<Operand> sourcesList = new List<Operand>();
|
||||
List<Operand> sourcesList = new();
|
||||
|
||||
if (isBindless)
|
||||
{
|
||||
|
@ -325,7 +324,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return context.Copy(Register(srcA++, RegisterType.Gpr));
|
||||
}
|
||||
|
||||
List<Operand> sourcesList = new List<Operand>();
|
||||
List<Operand> sourcesList = new();
|
||||
|
||||
if (isBindless)
|
||||
{
|
||||
|
@ -445,10 +444,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
switch (size)
|
||||
{
|
||||
case SuSize.U8: context.Copy(dests[0], ZeroExtendTo32(context, dests[0], 8)); break;
|
||||
case SuSize.U16: context.Copy(dests[0], ZeroExtendTo32(context, dests[0], 16)); break;
|
||||
case SuSize.S8: context.Copy(dests[0], SignExtendTo32(context, dests[0], 8)); break;
|
||||
case SuSize.S16: context.Copy(dests[0], SignExtendTo32(context, dests[0], 16)); break;
|
||||
case SuSize.U8:
|
||||
context.Copy(dests[0], ZeroExtendTo32(context, dests[0], 8));
|
||||
break;
|
||||
case SuSize.U16:
|
||||
context.Copy(dests[0], ZeroExtendTo32(context, dests[0], 16));
|
||||
break;
|
||||
case SuSize.S8:
|
||||
context.Copy(dests[0], SignExtendTo32(context, dests[0], 8));
|
||||
break;
|
||||
case SuSize.S16:
|
||||
context.Copy(dests[0], SignExtendTo32(context, dests[0], 16));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -493,7 +500,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return context.Copy(Register(srcB++, RegisterType.Gpr));
|
||||
}
|
||||
|
||||
List<Operand> sourcesList = new List<Operand>();
|
||||
List<Operand> sourcesList = new();
|
||||
|
||||
if (isBindless)
|
||||
{
|
||||
|
@ -600,7 +607,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return context.Copy(Register(srcB++, RegisterType.Gpr));
|
||||
}
|
||||
|
||||
List<Operand> sourcesList = new List<Operand>();
|
||||
List<Operand> sourcesList = new();
|
||||
|
||||
if (isBindless)
|
||||
{
|
||||
|
@ -699,7 +706,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
SuatomSize.S64 => 3,
|
||||
SuatomSize.Sd32 => 2,
|
||||
SuatomSize.Sd64 => 3,
|
||||
_ => 2
|
||||
_ => 2,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -715,7 +722,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
SuatomSize.S64 => TextureFormat.R32G32Uint,
|
||||
SuatomSize.Sd32 => TextureFormat.R32Uint,
|
||||
SuatomSize.Sd64 => TextureFormat.R32G32Uint,
|
||||
_ => TextureFormat.R32Uint
|
||||
_ => TextureFormat.R32Uint,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -732,7 +739,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
SuatomOp.Or => TextureFlags.BitwiseOr,
|
||||
SuatomOp.Xor => TextureFlags.BitwiseXor,
|
||||
SuatomOp.Exch => TextureFlags.Swap,
|
||||
_ => TextureFlags.Add
|
||||
_ => TextureFlags.Add,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -743,7 +750,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
SuSize.B64 => 2,
|
||||
SuSize.B128 => 4,
|
||||
SuSize.UB128 => 4,
|
||||
_ => 1
|
||||
_ => 1,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -759,7 +766,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
SuSize.B64 => 3,
|
||||
SuSize.B128 => 4,
|
||||
SuSize.UB128 => 4,
|
||||
_ => 2
|
||||
_ => 2,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -775,7 +782,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
SuSize.B64 => TextureFormat.R32G32Uint,
|
||||
SuSize.B128 => TextureFormat.R32G32B32A32Uint,
|
||||
SuSize.UB128 => TextureFormat.R32G32B32A32Uint,
|
||||
_ => TextureFormat.R32Uint
|
||||
_ => TextureFormat.R32Uint,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -789,7 +796,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
SuDim._2d => SamplerType.Texture2D,
|
||||
SuDim._2dArray => SamplerType.Texture2D | SamplerType.Array,
|
||||
SuDim._3d => SamplerType.Texture3D,
|
||||
_ => SamplerType.None
|
||||
_ => SamplerType.None,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
@ -14,7 +13,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
private static readonly int[,] _maskLut = new int[,]
|
||||
{
|
||||
{ 0b0001, 0b0010, 0b0100, 0b1000, 0b0011, 0b1001, 0b1010, 0b1100 },
|
||||
{ 0b0111, 0b1011, 0b1101, 0b1110, 0b1111, 0b0000, 0b0000, 0b0000 }
|
||||
{ 0b0111, 0b1011, 0b1101, 0b1110, 0b1111, 0b0000, 0b0000, 0b0000 },
|
||||
};
|
||||
|
||||
public const bool Sample1DAs2D = true;
|
||||
|
@ -23,7 +22,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
Texs,
|
||||
Tlds,
|
||||
Tld4s
|
||||
Tld4s,
|
||||
}
|
||||
|
||||
public static void Tex(EmitterContext context)
|
||||
|
@ -207,7 +206,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
Operand arrayIndex = isArray ? Ra() : null;
|
||||
|
||||
List<Operand> sourcesList = new List<Operand>();
|
||||
List<Operand> sourcesList = new();
|
||||
|
||||
if (isBindless)
|
||||
{
|
||||
|
@ -353,7 +352,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return;
|
||||
}
|
||||
|
||||
List<Operand> sourcesList = new List<Operand>();
|
||||
List<Operand> sourcesList = new();
|
||||
|
||||
Operand Ra()
|
||||
{
|
||||
|
@ -722,7 +721,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
Operand arrayIndex = isArray ? Ra() : null;
|
||||
|
||||
List<Operand> sourcesList = new List<Operand>();
|
||||
List<Operand> sourcesList = new();
|
||||
|
||||
SamplerType type = ConvertSamplerType(dimensions);
|
||||
TextureFlags flags = TextureFlags.Gather;
|
||||
|
@ -864,7 +863,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
TextureFlags flags = TextureFlags.None;
|
||||
|
||||
List<Operand> sourcesList = new List<Operand>();
|
||||
List<Operand> sourcesList = new();
|
||||
|
||||
if (isBindless)
|
||||
{
|
||||
|
@ -996,7 +995,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
TextureFlags flags = TextureFlags.Derivatives;
|
||||
|
||||
List<Operand> sourcesList = new List<Operand>();
|
||||
List<Operand> sourcesList = new();
|
||||
|
||||
if (isBindless)
|
||||
{
|
||||
|
@ -1126,7 +1125,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return context.Copy(Register(srcA++, RegisterType.Gpr));
|
||||
}
|
||||
|
||||
List<Operand> sourcesList = new List<Operand>();
|
||||
List<Operand> sourcesList = new();
|
||||
|
||||
if (isBindless)
|
||||
{
|
||||
|
@ -1195,7 +1194,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
TexDim.Array3d => SamplerType.Texture3D | SamplerType.Array,
|
||||
TexDim.Cube => SamplerType.TextureCube,
|
||||
TexDim.ArrayCube => SamplerType.TextureCube | SamplerType.Array,
|
||||
_ => throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\".")
|
||||
_ => throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.Decoders;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
|
@ -77,7 +76,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
VideoScale.Shr7 => 7,
|
||||
VideoScale.Shr15 => 15,
|
||||
_ => 0
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
if (shift != 0)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.Decoders;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
|
@ -39,7 +38,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
ShflMode.Up => context.ShuffleUp(srcA, srcB, srcC),
|
||||
ShflMode.Down => context.ShuffleDown(srcA, srcB, srcC),
|
||||
ShflMode.Bfly => context.ShuffleXor(srcA, srcB, srcC),
|
||||
_ => (null, null)
|
||||
_ => (null, null),
|
||||
};
|
||||
|
||||
context.Copy(GetDest(op.Dest), res);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
@ -9,27 +8,27 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
private enum TruthTable : byte
|
||||
{
|
||||
False = 0x00, // false
|
||||
True = 0xff, // true
|
||||
In = 0xf0, // a
|
||||
And2 = 0xc0, // a & b
|
||||
Or2 = 0xfc, // a | b
|
||||
Xor2 = 0x3c, // a ^ b
|
||||
And3 = 0x80, // a & b & c
|
||||
Or3 = 0xfe, // a | b | c
|
||||
XorAnd = 0x60, // a & (b ^ c)
|
||||
XorOr = 0xf6, // a | (b ^ c)
|
||||
OrAnd = 0xe0, // a & (b | c)
|
||||
AndOr = 0xf8, // a | (b & c)
|
||||
Onehot = 0x16, // (a & !b & !c) | (!a & b & !c) | (!a & !b & c) - Only one value is true.
|
||||
Majority = 0xe8, // Popcount(a, b, c) >= 2
|
||||
Gamble = 0x81, // (a & b & c) | (!a & !b & !c) - All on or all off
|
||||
False = 0x00, // false
|
||||
True = 0xff, // true
|
||||
In = 0xf0, // a
|
||||
And2 = 0xc0, // a & b
|
||||
Or2 = 0xfc, // a | b
|
||||
Xor2 = 0x3c, // a ^ b
|
||||
And3 = 0x80, // a & b & c
|
||||
Or3 = 0xfe, // a | b | c
|
||||
XorAnd = 0x60, // a & (b ^ c)
|
||||
XorOr = 0xf6, // a | (b ^ c)
|
||||
OrAnd = 0xe0, // a & (b | c)
|
||||
AndOr = 0xf8, // a | (b & c)
|
||||
Onehot = 0x16, // (a & !b & !c) | (!a & b & !c) | (!a & !b & c) - Only one value is true.
|
||||
Majority = 0xe8, // Popcount(a, b, c) >= 2
|
||||
Gamble = 0x81, // (a & b & c) | (!a & !b & !c) - All on or all off
|
||||
InverseGamble = 0x7e, // Inverse of Gamble
|
||||
Dot = 0x1a, // a ^ (c | (a & b))
|
||||
Mux = 0xca, // a ? b : c
|
||||
AndXor = 0x78, // a ^ (b & c)
|
||||
OrXor = 0x1e, // a ^ (b | c)
|
||||
Xor3 = 0x96, // a ^ b ^ c
|
||||
Dot = 0x1a, // a ^ (c | (a & b))
|
||||
Mux = 0xca, // a ? b : c
|
||||
AndXor = 0x78, // a ^ (b & c)
|
||||
OrXor = 0x1e, // a ^ (b | c)
|
||||
Xor3 = 0x96, // a ^ b ^ c
|
||||
}
|
||||
|
||||
public static Operand GetFromTruthTable(EmitterContext context, Operand srcA, Operand srcB, Operand srcC, int imm)
|
||||
|
@ -98,6 +97,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
return imm switch
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
TruthTable.False => Const(0),
|
||||
TruthTable.True => Const(-1),
|
||||
TruthTable.In => x,
|
||||
|
@ -118,7 +118,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
TruthTable.AndXor => context.BitwiseExclusiveOr(x, context.BitwiseAnd(y, z)),
|
||||
TruthTable.OrXor => context.BitwiseExclusiveOr(x, context.BitwiseOr(y, z)),
|
||||
TruthTable.Xor3 => context.BitwiseExclusiveOr(x, context.BitwiseExclusiveOr(y, z)),
|
||||
_ => null
|
||||
_ => null,
|
||||
#pragma warning restore IDE0055
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -83,9 +83,9 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
case Instruction.Discard:
|
||||
case Instruction.Return:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
||||
{
|
||||
[Flags]
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
enum Instruction
|
||||
{
|
||||
Absolute = 1,
|
||||
|
@ -130,7 +132,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
FP32 = 1 << 16,
|
||||
FP64 = 1 << 17,
|
||||
|
||||
Mask = 0xffff
|
||||
Mask = 0xffff,
|
||||
}
|
||||
|
||||
static class InstructionExtensions
|
||||
|
|
|
@ -43,6 +43,6 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
VertexId,
|
||||
VertexIndex,
|
||||
ViewportIndex,
|
||||
ViewportMask
|
||||
ViewportMask,
|
||||
}
|
||||
}
|
|
@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
static class IrConsts
|
||||
{
|
||||
public const int False = 0;
|
||||
public const int True = -1;
|
||||
public const int True = -1;
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
class Operand
|
||||
{
|
||||
private const int CbufSlotBits = 5;
|
||||
private const int CbufSlotLsb = 32 - CbufSlotBits;
|
||||
private const int CbufSlotLsb = 32 - CbufSlotBits;
|
||||
private const int CbufSlotMask = (1 << CbufSlotBits) - 1;
|
||||
|
||||
public OperandType Type { get; }
|
||||
|
@ -30,19 +30,19 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
|
||||
public Operand(OperandType type, int value) : this()
|
||||
{
|
||||
Type = type;
|
||||
Type = type;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public Operand(Register reg) : this()
|
||||
{
|
||||
Type = OperandType.Register;
|
||||
Type = OperandType.Register;
|
||||
Value = PackRegInfo(reg.Index, reg.Type);
|
||||
}
|
||||
|
||||
public Operand(int slot, int offset) : this()
|
||||
{
|
||||
Type = OperandType.ConstantBuffer;
|
||||
Type = OperandType.ConstantBuffer;
|
||||
Value = PackCbufInfo(slot, offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,6 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
Label,
|
||||
LocalVariable,
|
||||
Register,
|
||||
Undefined
|
||||
Undefined,
|
||||
}
|
||||
}
|
|
@ -62,7 +62,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
|
||||
public Operation(Instruction inst, int index, Operand[] dests, Operand[] sources) : this(sources)
|
||||
{
|
||||
Inst = inst;
|
||||
Inst = inst;
|
||||
Index = index;
|
||||
|
||||
if (dests != null)
|
||||
|
|
|
@ -15,21 +15,21 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
|
||||
public int DestsCount => _dest != null ? 1 : 0;
|
||||
|
||||
private HashSet<BasicBlock> _blocks;
|
||||
private readonly HashSet<BasicBlock> _blocks;
|
||||
|
||||
private class PhiSource
|
||||
{
|
||||
public BasicBlock Block { get; }
|
||||
public Operand Operand { get; set; }
|
||||
public BasicBlock Block { get; }
|
||||
public Operand Operand { get; set; }
|
||||
|
||||
public PhiSource(BasicBlock block, Operand operand)
|
||||
{
|
||||
Block = block;
|
||||
Block = block;
|
||||
Operand = operand;
|
||||
}
|
||||
}
|
||||
|
||||
private List<PhiSource> _sources;
|
||||
private readonly List<PhiSource> _sources;
|
||||
|
||||
public int SourcesCount => _sources.Count;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
GlobalMemoryS8, // TODO: Remove this and store type as a field on the Operation class itself.
|
||||
GlobalMemoryS16, // TODO: Remove this and store type as a field on the Operation class itself.
|
||||
GlobalMemoryU8, // TODO: Remove this and store type as a field on the Operation class itself.
|
||||
GlobalMemoryU16 // TODO: Remove this and store type as a field on the Operation class itself.
|
||||
GlobalMemoryU16, // TODO: Remove this and store type as a field on the Operation class itself.
|
||||
}
|
||||
|
||||
static class StorageKindExtensions
|
||||
|
|
|
@ -1,32 +1,34 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
||||
{
|
||||
[Flags]
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
enum TextureFlags
|
||||
{
|
||||
None = 0,
|
||||
Bindless = 1 << 0,
|
||||
Gather = 1 << 1,
|
||||
None = 0,
|
||||
Bindless = 1 << 0,
|
||||
Gather = 1 << 1,
|
||||
Derivatives = 1 << 2,
|
||||
IntCoords = 1 << 3,
|
||||
LodBias = 1 << 4,
|
||||
LodLevel = 1 << 5,
|
||||
Offset = 1 << 6,
|
||||
Offsets = 1 << 7,
|
||||
Coherent = 1 << 8,
|
||||
IntCoords = 1 << 3,
|
||||
LodBias = 1 << 4,
|
||||
LodLevel = 1 << 5,
|
||||
Offset = 1 << 6,
|
||||
Offsets = 1 << 7,
|
||||
Coherent = 1 << 8,
|
||||
|
||||
AtomicMask = 15 << 16,
|
||||
AtomicMask = 15 << 16,
|
||||
|
||||
Add = 0 << 16,
|
||||
Minimum = 1 << 16,
|
||||
Maximum = 2 << 16,
|
||||
Increment = 3 << 16,
|
||||
Decrement = 4 << 16,
|
||||
BitwiseAnd = 5 << 16,
|
||||
BitwiseOr = 6 << 16,
|
||||
BitwiseXor = 7 << 16,
|
||||
Swap = 8 << 16,
|
||||
CAS = 9 << 16
|
||||
Add = 0 << 16,
|
||||
Minimum = 1 << 16,
|
||||
Maximum = 2 << 16,
|
||||
Increment = 3 << 16,
|
||||
Decrement = 4 << 16,
|
||||
BitwiseAnd = 5 << 16,
|
||||
BitwiseOr = 6 << 16,
|
||||
BitwiseXor = 7 << 16,
|
||||
Swap = 8 << 16,
|
||||
CAS = 9 << 16,
|
||||
}
|
||||
}
|
|
@ -2,23 +2,22 @@ namespace Ryujinx.Graphics.Shader
|
|||
{
|
||||
enum OutputTopology
|
||||
{
|
||||
PointList = 1,
|
||||
LineStrip = 6,
|
||||
TriangleStrip = 7
|
||||
PointList = 1,
|
||||
LineStrip = 6,
|
||||
TriangleStrip = 7,
|
||||
}
|
||||
|
||||
static class OutputTopologyExtensions
|
||||
{
|
||||
public static string ToGlslString(this OutputTopology topology)
|
||||
{
|
||||
switch (topology)
|
||||
return topology switch
|
||||
{
|
||||
case OutputTopology.LineStrip: return "line_strip";
|
||||
case OutputTopology.PointList: return "points";
|
||||
case OutputTopology.TriangleStrip: return "triangle_strip";
|
||||
}
|
||||
|
||||
return "points";
|
||||
OutputTopology.LineStrip => "line_strip",
|
||||
OutputTopology.PointList => "points",
|
||||
OutputTopology.TriangleStrip => "triangle_strip",
|
||||
_ => "points",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,10 +15,10 @@ namespace Ryujinx.Graphics.Shader
|
|||
|
||||
Mask = 0xff,
|
||||
|
||||
Array = 1 << 8,
|
||||
Indexed = 1 << 9,
|
||||
Array = 1 << 8,
|
||||
Indexed = 1 << 9,
|
||||
Multisample = 1 << 10,
|
||||
Shadow = 1 << 11
|
||||
Shadow = 1 << 11,
|
||||
}
|
||||
|
||||
static class SamplerTypeExtensions
|
||||
|
@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
SamplerType.Texture2D => 2,
|
||||
SamplerType.Texture3D => 3,
|
||||
SamplerType.TextureCube => 3,
|
||||
_ => throw new ArgumentException($"Invalid sampler type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid sampler type \"{type}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
SamplerType.Texture2D => "sampler2D",
|
||||
SamplerType.Texture3D => "sampler3D",
|
||||
SamplerType.TextureCube => "samplerCube",
|
||||
_ => throw new ArgumentException($"Invalid sampler type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid sampler type \"{type}\"."),
|
||||
};
|
||||
|
||||
if ((type & SamplerType.Multisample) != 0)
|
||||
|
@ -75,7 +75,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
SamplerType.Texture2D => "image2D",
|
||||
SamplerType.Texture3D => "image3D",
|
||||
SamplerType.TextureCube => "imageCube",
|
||||
_ => throw new ArgumentException($"Invalid sampler type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid sampler type \"{type}\"."),
|
||||
};
|
||||
|
||||
if ((type & SamplerType.Multisample) != 0)
|
||||
|
@ -90,8 +90,12 @@ namespace Ryujinx.Graphics.Shader
|
|||
|
||||
switch (componentType)
|
||||
{
|
||||
case AggregateType.U32: typeName = 'u' + typeName; break;
|
||||
case AggregateType.S32: typeName = 'i' + typeName; break;
|
||||
case AggregateType.U32:
|
||||
typeName = 'u' + typeName;
|
||||
break;
|
||||
case AggregateType.S32:
|
||||
typeName = 'i' + typeName;
|
||||
break;
|
||||
}
|
||||
|
||||
return typeName;
|
||||
|
|
|
@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.Shader
|
|||
public enum ShaderIdentification
|
||||
{
|
||||
None,
|
||||
GeometryLayerPassthrough
|
||||
GeometryLayerPassthrough,
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
Geometry,
|
||||
Fragment,
|
||||
|
||||
Count
|
||||
Count,
|
||||
}
|
||||
|
||||
public static class ShaderStageExtensions
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
public AstAssignment(IAstNode destination, IAstNode source)
|
||||
{
|
||||
Destination = destination;
|
||||
Source = source;
|
||||
Source = source;
|
||||
|
||||
AddDef(destination, this);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
}
|
||||
}
|
||||
|
||||
private LinkedList<IAstNode> _nodes;
|
||||
private readonly LinkedList<IAstNode> _nodes;
|
||||
|
||||
public IAstNode First => _nodes.First?.Value;
|
||||
public IAstNode Last => _nodes.Last?.Value;
|
||||
|
@ -38,7 +38,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
public AstBlock(AstBlockType type, IAstNode condition = null)
|
||||
{
|
||||
Type = type;
|
||||
Type = type;
|
||||
Condition = condition;
|
||||
|
||||
_nodes = new LinkedList<IAstNode>();
|
||||
|
|
|
@ -7,6 +7,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
Else,
|
||||
ElseIf,
|
||||
Main,
|
||||
While
|
||||
While,
|
||||
}
|
||||
}
|
|
@ -49,9 +49,10 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
public static AstOperand Local(AggregateType type)
|
||||
{
|
||||
AstOperand local = new AstOperand(OperandType.LocalVariable);
|
||||
|
||||
local.VarType = type;
|
||||
AstOperand local = new(OperandType.LocalVariable)
|
||||
{
|
||||
VarType = type,
|
||||
};
|
||||
|
||||
return local;
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
Value = operand.Value;
|
||||
}
|
||||
|
||||
public AstOperand(OperandType type, int value = 0) : this()
|
||||
public AstOperand(OperandType type, int value = 0) : this()
|
||||
{
|
||||
Type = type;
|
||||
Type = type;
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
public int Index { get; }
|
||||
|
||||
private IAstNode[] _sources;
|
||||
private readonly IAstNode[] _sources;
|
||||
|
||||
public int SourcesCount => _sources.Length;
|
||||
|
||||
|
@ -77,9 +77,15 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
switch (componentsCount)
|
||||
{
|
||||
case 2: type |= AggregateType.Vector2; break;
|
||||
case 3: type |= AggregateType.Vector3; break;
|
||||
case 4: type |= AggregateType.Vector4; break;
|
||||
case 2:
|
||||
type |= AggregateType.Vector2;
|
||||
break;
|
||||
case 3:
|
||||
type |= AggregateType.Vector3;
|
||||
break;
|
||||
case 4:
|
||||
type |= AggregateType.Vector4;
|
||||
break;
|
||||
}
|
||||
|
||||
return type;
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
// (this makes comparison with the disassembly easier).
|
||||
if (!context.Config.Options.Flags.HasFlag(TranslationFlags.DebugMode))
|
||||
{
|
||||
AstBlockVisitor visitor = new AstBlockVisitor(mainBlock);
|
||||
AstBlockVisitor visitor = new(mainBlock);
|
||||
|
||||
foreach (IAstNode node in visitor.Visit())
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
private static bool IsWorthPropagating(IAstNode source)
|
||||
{
|
||||
if (!(source is AstOperation srcOp))
|
||||
if (source is not AstOperation srcOp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
private static void RemoveEmptyBlocks(AstBlock mainBlock)
|
||||
{
|
||||
Queue<AstBlock> pending = new Queue<AstBlock>();
|
||||
Queue<AstBlock> pending = new();
|
||||
|
||||
pending.Enqueue(mainBlock);
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
enum BufferLayout
|
||||
{
|
||||
Std140,
|
||||
Std430
|
||||
Std430,
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
|
@ -110,16 +109,16 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
if (lLevel > rLevel)
|
||||
{
|
||||
block = lBlock;
|
||||
block = lBlock;
|
||||
blockLvl = lLevel;
|
||||
other = rBlock;
|
||||
other = rBlock;
|
||||
otherLvl = rLevel;
|
||||
}
|
||||
else /* if (rLevel > lLevel) */
|
||||
{
|
||||
block = rBlock;
|
||||
block = rBlock;
|
||||
blockLvl = rLevel;
|
||||
other = lBlock;
|
||||
other = lBlock;
|
||||
otherLvl = lLevel;
|
||||
}
|
||||
|
||||
|
@ -144,7 +143,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
AstBlock[] path = BackwardsPath(block, ParentBlock(stmt.Label));
|
||||
|
||||
AstBlock loopFirstStmt = path[path.Length - 1];
|
||||
AstBlock loopFirstStmt = path[^1];
|
||||
|
||||
if (loopFirstStmt.Type == AstBlockType.Else)
|
||||
{
|
||||
|
@ -194,7 +193,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
loopBlock.AddAfter(child, stmt.Goto);
|
||||
|
||||
block = loopBlock;
|
||||
block = loopBlock;
|
||||
gLevel = loopLevel;
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +251,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
for (int index = path.Length - 1; index >= 0; index--)
|
||||
{
|
||||
AstBlock child = path[index];
|
||||
AstBlock last = child;
|
||||
AstBlock last = child;
|
||||
|
||||
if (child.Type == AstBlockType.If)
|
||||
{
|
||||
|
@ -265,7 +264,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
else if (child.Type == AstBlockType.Else)
|
||||
{
|
||||
// Modify the matching if condition to force the else to be entered by the goto.
|
||||
if (!(Previous(child) is AstBlock ifBlock) || ifBlock.Type != AstBlockType.If)
|
||||
if (Previous(child) is not AstBlock ifBlock || ifBlock.Type != AstBlockType.If)
|
||||
{
|
||||
throw new InvalidOperationException("Found an else without a matching if.");
|
||||
}
|
||||
|
@ -332,7 +331,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
{
|
||||
AstBlock block = ParentBlock(stmt.Goto);
|
||||
|
||||
AstBlock newBlock = new AstBlock(AstBlockType.If, stmt.Condition);
|
||||
AstBlock newBlock = new(AstBlockType.If, stmt.Condition);
|
||||
|
||||
block.AddAfter(stmt.Goto, newBlock);
|
||||
|
||||
|
@ -340,11 +339,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
}
|
||||
|
||||
private static AstBlock Enclose(
|
||||
AstBlock block,
|
||||
AstBlock block,
|
||||
AstBlockType type,
|
||||
IAstNode cond,
|
||||
IAstNode first,
|
||||
IAstNode last = null)
|
||||
IAstNode cond,
|
||||
IAstNode first,
|
||||
IAstNode last = null)
|
||||
{
|
||||
if (first == last)
|
||||
{
|
||||
|
@ -367,7 +366,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
return first as AstBlock;
|
||||
}
|
||||
|
||||
AstBlock newBlock = new AstBlock(type, cond);
|
||||
AstBlock newBlock = new(type, cond);
|
||||
|
||||
block.AddBefore(first, newBlock);
|
||||
|
||||
|
@ -387,7 +386,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
private static bool BlockMatches(IAstNode node, AstBlockType type, IAstNode cond)
|
||||
{
|
||||
if (!(node is AstBlock block))
|
||||
if (node is not AstBlock block)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -399,7 +398,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
{
|
||||
if (lCond is AstOperation lCondOp && lCondOp.Inst == Instruction.LogicalNot)
|
||||
{
|
||||
if (!(rCond is AstOperation rCondOp) || rCondOp.Inst != lCondOp.Inst)
|
||||
if (rCond is not AstOperation rCondOp || rCondOp.Inst != lCondOp.Inst)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -418,7 +417,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
return block.Parent;
|
||||
}
|
||||
|
||||
while (!(node is AstBlock))
|
||||
while (node is not AstBlock)
|
||||
{
|
||||
node = node.Parent;
|
||||
}
|
||||
|
@ -430,7 +429,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
{
|
||||
AstBlock block = bottom;
|
||||
|
||||
List<AstBlock> path = new List<AstBlock>();
|
||||
List<AstBlock> path = new();
|
||||
|
||||
while (block != top)
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
{
|
||||
class GotoStatement
|
||||
{
|
||||
public AstOperation Goto { get; }
|
||||
public AstOperation Goto { get; }
|
||||
public AstAssignment Label { get; }
|
||||
|
||||
public IAstNode Condition => Label.Destination;
|
||||
|
@ -15,8 +15,8 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
public GotoStatement(AstOperation branch, AstAssignment label, bool isLoop)
|
||||
{
|
||||
Goto = branch;
|
||||
Label = label;
|
||||
Goto = branch;
|
||||
Label = label;
|
||||
IsLoop = isLoop;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
{
|
||||
MultiplyHighS32 = 1 << 2,
|
||||
MultiplyHighU32 = 1 << 3,
|
||||
Shuffle = 1 << 4,
|
||||
ShuffleDown = 1 << 5,
|
||||
ShuffleUp = 1 << 6,
|
||||
ShuffleXor = 1 << 7,
|
||||
SwizzleAdd = 1 << 10,
|
||||
FSI = 1 << 11
|
||||
Shuffle = 1 << 4,
|
||||
ShuffleDown = 1 << 5,
|
||||
ShuffleUp = 1 << 6,
|
||||
ShuffleXor = 1 << 7,
|
||||
SwizzleAdd = 1 << 10,
|
||||
FSI = 1 << 11,
|
||||
}
|
||||
}
|
|
@ -19,12 +19,13 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
}
|
||||
}
|
||||
|
||||
private static InstInfo[] _infoTbl;
|
||||
private static readonly InstInfo[] _infoTbl;
|
||||
|
||||
static InstructionInfo()
|
||||
{
|
||||
_infoTbl = new InstInfo[(int)Instruction.Count];
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
// Inst Destination type Source 1 type Source 2 type Source 3 type Source 4 type
|
||||
Add(Instruction.AtomicAdd, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32);
|
||||
Add(Instruction.AtomicAnd, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32);
|
||||
|
@ -130,6 +131,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
Add(Instruction.VoteAll, AggregateType.Bool, AggregateType.Bool);
|
||||
Add(Instruction.VoteAllEqual, AggregateType.Bool, AggregateType.Bool);
|
||||
Add(Instruction.VoteAny, AggregateType.Bool, AggregateType.Bool);
|
||||
#pragma warning restore IDE0055v
|
||||
}
|
||||
|
||||
private static void Add(Instruction inst, AggregateType destType, params AggregateType[] srcTypes)
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
OperandType.Argument => AggregateType.S32,
|
||||
OperandType.Constant => AggregateType.S32,
|
||||
OperandType.Undefined => AggregateType.S32,
|
||||
_ => throw new ArgumentException($"Invalid operand type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid operand type \"{type}\"."),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
BasicBlock srcBlock = phi.GetBlock(index);
|
||||
|
||||
Operation copyOp = new Operation(Instruction.Copy, phi.Dest, src);
|
||||
Operation copyOp = new(Instruction.Copy, phi.Dest, src);
|
||||
|
||||
srcBlock.Append(copyOp);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||
|
||||
namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
{
|
||||
struct StructureField
|
||||
readonly struct StructureField
|
||||
{
|
||||
public AggregateType Type { get; }
|
||||
public string Name { get; }
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
{
|
||||
public static StructuredProgramInfo MakeStructuredProgram(IReadOnlyList<Function> functions, ShaderConfig config)
|
||||
{
|
||||
StructuredProgramContext context = new StructuredProgramContext(config);
|
||||
StructuredProgramContext context = new(config);
|
||||
|
||||
for (int funcIndex = 0; funcIndex < functions.Count; funcIndex++)
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
AggregateType returnType = function.ReturnsValue ? AggregateType.S32 : AggregateType.Void;
|
||||
|
||||
AggregateType[] inArguments = new AggregateType[function.InArgumentsCount];
|
||||
AggregateType[] inArguments = new AggregateType[function.InArgumentsCount];
|
||||
AggregateType[] outArguments = new AggregateType[function.OutArgumentsCount];
|
||||
|
||||
for (int i = 0; i < inArguments.Length; i++)
|
||||
|
@ -79,7 +79,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
{
|
||||
IoVariable ioVariable = (IoVariable)operation.GetSource(0).Value;
|
||||
bool isOutput = storageKind.IsOutput();
|
||||
bool perPatch = storageKind.IsPerPatch();
|
||||
int location = 0;
|
||||
int component = 0;
|
||||
|
||||
|
@ -169,9 +168,15 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
switch (componentsCount)
|
||||
{
|
||||
case 2: destType |= AggregateType.Vector2; break;
|
||||
case 3: destType |= AggregateType.Vector3; break;
|
||||
case 4: destType |= AggregateType.Vector4; break;
|
||||
case 2:
|
||||
destType |= AggregateType.Vector2;
|
||||
break;
|
||||
case 3:
|
||||
destType |= AggregateType.Vector3;
|
||||
break;
|
||||
case 4:
|
||||
destType |= AggregateType.Vector4;
|
||||
break;
|
||||
}
|
||||
|
||||
AstOperand destVec = context.NewTemp(destType);
|
||||
|
@ -181,7 +186,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
for (int i = 0; i < operation.DestsCount; i++)
|
||||
{
|
||||
AstOperand dest = context.GetOperand(operation.GetDest(i));
|
||||
AstOperand index = new AstOperand(OperandType.Constant, i);
|
||||
AstOperand index = new(OperandType.Constant, i);
|
||||
|
||||
dest.VarType = destElemType;
|
||||
|
||||
|
@ -202,7 +207,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
}
|
||||
|
||||
bool isCondSel = inst == Instruction.ConditionalSelect;
|
||||
bool isCopy = inst == Instruction.Copy;
|
||||
bool isCopy = inst == Instruction.Copy;
|
||||
|
||||
if (isCondSel || isCopy)
|
||||
{
|
||||
|
@ -304,9 +309,9 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
private static AggregateType GetVarTypeFromUses(Operand dest)
|
||||
{
|
||||
HashSet<Operand> visited = new HashSet<Operand>();
|
||||
HashSet<Operand> visited = new();
|
||||
|
||||
Queue<Operand> pending = new Queue<Operand>();
|
||||
Queue<Operand> pending = new();
|
||||
|
||||
bool Enqueue(Operand operand)
|
||||
{
|
||||
|
@ -385,7 +390,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
{
|
||||
Instruction.ImageLoad or
|
||||
Instruction.TextureSample => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -396,7 +401,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
Instruction.Branch or
|
||||
Instruction.BranchIfFalse or
|
||||
Instruction.BranchIfTrue => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -408,7 +413,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
Instruction.BitwiseExclusiveOr or
|
||||
Instruction.BitwiseNot or
|
||||
Instruction.BitwiseOr => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -420,7 +425,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
Instruction.BitwiseExclusiveOr => Instruction.LogicalExclusiveOr,
|
||||
Instruction.BitwiseNot => Instruction.LogicalNot,
|
||||
Instruction.BitwiseOr => Instruction.LogicalOr,
|
||||
_ => throw new ArgumentException($"Unexpected instruction \"{inst}\".")
|
||||
_ => throw new ArgumentException($"Unexpected instruction \"{inst}\"."),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
|
@ -165,7 +164,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
// this is not valid as the loop condition would be evaluated,
|
||||
// and it could erroneously jump back to the start of the loop.
|
||||
bool inRange =
|
||||
block.Branch.Index < _currEndIndex ||
|
||||
block.Branch.Index < _currEndIndex ||
|
||||
(block.Branch.Index == _currEndIndex && block.Branch.Index < _loopEndIndex);
|
||||
|
||||
bool isLoop = block.Branch.Index <= block.Index;
|
||||
|
@ -184,11 +183,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
AddNode(Assign(gotoTempAsg.Destination, cond));
|
||||
|
||||
AstOperation branch = new AstOperation(branchOp.Inst);
|
||||
AstOperation branch = new(branchOp.Inst);
|
||||
|
||||
AddNode(branch);
|
||||
|
||||
GotoStatement gotoStmt = new GotoStatement(branch, gotoTempAsg, isLoop);
|
||||
GotoStatement gotoStmt = new(branch, gotoTempAsg, isLoop);
|
||||
|
||||
_gotos.Add(gotoStmt);
|
||||
}
|
||||
|
@ -236,13 +235,13 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
|
||||
private void NewBlock(AstBlockType type, IAstNode cond, int endIndex)
|
||||
{
|
||||
AstBlock childBlock = new AstBlock(type, cond);
|
||||
AstBlock childBlock = new(type, cond);
|
||||
|
||||
AddNode(childBlock);
|
||||
|
||||
_blockStack.Push((_currBlock, _currEndIndex, _loopEndIndex));
|
||||
|
||||
_currBlock = childBlock;
|
||||
_currBlock = childBlock;
|
||||
_currEndIndex = endIndex;
|
||||
|
||||
if (type == AstBlockType.DoWhile)
|
||||
|
@ -316,7 +315,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
new AstOperand(OperandType.Constant, binding),
|
||||
new AstOperand(OperandType.Constant, 0),
|
||||
new AstOperand(OperandType.Constant, vecIndex),
|
||||
new AstOperand(OperandType.Constant, elemIndex)
|
||||
new AstOperand(OperandType.Constant, elemIndex),
|
||||
};
|
||||
|
||||
return new AstOperation(Instruction.Load, StorageKind.ConstantBuffer, false, sources, sources.Length);
|
||||
|
|
|
@ -20,22 +20,22 @@ namespace Ryujinx.Graphics.Shader
|
|||
FragmentIsBgra,
|
||||
ViewportInverse,
|
||||
FragmentRenderScaleCount,
|
||||
RenderScale
|
||||
RenderScale,
|
||||
}
|
||||
|
||||
public struct SupportBuffer
|
||||
{
|
||||
internal const int Binding = 0;
|
||||
|
||||
public static int FieldSize;
|
||||
public static int RequiredSize;
|
||||
public static readonly int FieldSize;
|
||||
public static readonly int RequiredSize;
|
||||
|
||||
public static int FragmentAlphaTestOffset;
|
||||
public static int FragmentIsBgraOffset;
|
||||
public static int ViewportInverseOffset;
|
||||
public static int FragmentRenderScaleCountOffset;
|
||||
public static int GraphicsRenderScaleOffset;
|
||||
public static int ComputeRenderScaleOffset;
|
||||
public static readonly int FragmentAlphaTestOffset;
|
||||
public static readonly int FragmentIsBgraOffset;
|
||||
public static readonly int ViewportInverseOffset;
|
||||
public static readonly int FragmentRenderScaleCountOffset;
|
||||
public static readonly int GraphicsRenderScaleOffset;
|
||||
public static readonly int ComputeRenderScaleOffset;
|
||||
|
||||
public const int FragmentIsBgraCount = 8;
|
||||
// One for the render target, 64 for the textures, and 8 for the images.
|
||||
|
@ -51,7 +51,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
FieldSize = Unsafe.SizeOf<Vector4<float>>();
|
||||
RequiredSize = Unsafe.SizeOf<SupportBuffer>();
|
||||
|
||||
SupportBuffer instance = new SupportBuffer();
|
||||
SupportBuffer instance = new();
|
||||
|
||||
FragmentAlphaTestOffset = OffsetOf(ref instance, ref instance.FragmentAlphaTest);
|
||||
FragmentIsBgraOffset = OffsetOf(ref instance, ref instance.FragmentIsBgra);
|
||||
|
@ -69,7 +69,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
new StructureField(AggregateType.Array | AggregateType.U32, "s_is_bgra", FragmentIsBgraCount),
|
||||
new StructureField(AggregateType.Vector4 | AggregateType.FP32, "s_viewport_inverse"),
|
||||
new StructureField(AggregateType.S32, "s_frag_scale_count"),
|
||||
new StructureField(AggregateType.Array | AggregateType.FP32, "s_render_scale", RenderScaleMaxCount)
|
||||
new StructureField(AggregateType.Array | AggregateType.FP32, "s_render_scale", RenderScaleMaxCount),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
{
|
||||
Isolines = 0,
|
||||
Triangles = 1,
|
||||
Quads = 2
|
||||
Quads = 2,
|
||||
}
|
||||
|
||||
static class TessPatchTypeExtensions
|
||||
|
@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
{
|
||||
TessPatchType.Isolines => "isolines",
|
||||
TessPatchType.Quads => "quads",
|
||||
_ => "triangles"
|
||||
_ => "triangles",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
{
|
||||
EqualSpacing = 0,
|
||||
FractionalEventSpacing = 1,
|
||||
FractionalOddSpacing = 2
|
||||
FractionalOddSpacing = 2,
|
||||
}
|
||||
|
||||
static class TessSpacingExtensions
|
||||
|
@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
{
|
||||
TessSpacing.FractionalEventSpacing => "fractional_even_spacing",
|
||||
TessSpacing.FractionalOddSpacing => "fractional_odd_spacing",
|
||||
_ => "equal_spacing"
|
||||
_ => "equal_spacing",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,12 @@ namespace Ryujinx.Graphics.Shader
|
|||
|
||||
public TextureDescriptor(int binding, SamplerType type, TextureFormat format, int cbufSlot, int handleIndex)
|
||||
{
|
||||
Binding = binding;
|
||||
Type = type;
|
||||
Format = format;
|
||||
CbufSlot = cbufSlot;
|
||||
Binding = binding;
|
||||
Type = type;
|
||||
Format = format;
|
||||
CbufSlot = cbufSlot;
|
||||
HandleIndex = handleIndex;
|
||||
Flags = TextureUsageFlags.None;
|
||||
Flags = TextureUsageFlags.None;
|
||||
}
|
||||
|
||||
public TextureDescriptor SetFlag(TextureUsageFlags flag)
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
R32G32B32A32Sint,
|
||||
R10G10B10A2Unorm,
|
||||
R10G10B10A2Uint,
|
||||
R11G11B10Float
|
||||
R11G11B10Float,
|
||||
}
|
||||
|
||||
static class TextureFormatExtensions
|
||||
|
@ -52,6 +52,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
{
|
||||
return format switch
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
TextureFormat.R8Unorm => "r8",
|
||||
TextureFormat.R8Snorm => "r8_snorm",
|
||||
TextureFormat.R8Uint => "r8ui",
|
||||
|
@ -91,7 +92,8 @@ namespace Ryujinx.Graphics.Shader
|
|||
TextureFormat.R10G10B10A2Unorm => "rgb10_a2",
|
||||
TextureFormat.R10G10B10A2Uint => "rgb10_a2ui",
|
||||
TextureFormat.R11G11B10Float => "r11f_g11f_b10f",
|
||||
_ => string.Empty
|
||||
_ => string.Empty,
|
||||
#pragma warning restore IDE0055
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
CombinedSampler = 0, // Must be 0.
|
||||
SeparateSamplerHandle = 1,
|
||||
SeparateSamplerId = 2,
|
||||
SeparateConstantSamplerHandle = 3
|
||||
SeparateConstantSamplerHandle = 3,
|
||||
}
|
||||
|
||||
public static class TextureHandle
|
||||
|
|
|
@ -14,6 +14,6 @@ namespace Ryujinx.Graphics.Shader
|
|||
ResScaleUnsupported = 1 << 0,
|
||||
NeedsScaleValue = 1 << 1,
|
||||
ImageStore = 1 << 2,
|
||||
ImageCoherent = 1 << 3
|
||||
ImageCoherent = 1 << 3,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Translation
|
||||
{
|
||||
[Flags]
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
enum AggregateType
|
||||
{
|
||||
Invalid,
|
||||
|
@ -23,7 +25,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
Vector3 = 2 << ElementCountShift,
|
||||
Vector4 = 3 << ElementCountShift,
|
||||
|
||||
Array = 1 << 10
|
||||
Array = 1 << 10,
|
||||
}
|
||||
|
||||
static class AggregateTypeExtensions
|
||||
|
@ -37,7 +39,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
AggregateType.S32 or
|
||||
AggregateType.U32 => 4,
|
||||
AggregateType.FP64 => 8,
|
||||
_ => 0
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
switch (type & AggregateType.ElementCountMask)
|
||||
|
|
|
@ -13,11 +13,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
Blocks = blocks;
|
||||
|
||||
HashSet<BasicBlock> visited = new HashSet<BasicBlock>();
|
||||
HashSet<BasicBlock> visited = new();
|
||||
|
||||
Stack<BasicBlock> blockStack = new Stack<BasicBlock>();
|
||||
Stack<BasicBlock> blockStack = new();
|
||||
|
||||
List<BasicBlock> postOrderBlocks = new List<BasicBlock>(blocks.Length);
|
||||
List<BasicBlock> postOrderBlocks = new(blocks.Length);
|
||||
|
||||
PostOrderMap = new int[blocks.Length];
|
||||
|
||||
|
@ -50,9 +50,9 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
public static ControlFlowGraph Create(Operation[] operations)
|
||||
{
|
||||
Dictionary<Operand, BasicBlock> labels = new Dictionary<Operand, BasicBlock>();
|
||||
Dictionary<Operand, BasicBlock> labels = new();
|
||||
|
||||
List<BasicBlock> blocks = new List<BasicBlock>();
|
||||
List<BasicBlock> blocks = new();
|
||||
|
||||
BasicBlock currentBlock = null;
|
||||
|
||||
|
@ -68,7 +68,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
void NewNextBlock()
|
||||
{
|
||||
BasicBlock block = new BasicBlock(blocks.Count);
|
||||
BasicBlock block = new(blocks.Count);
|
||||
|
||||
blocks.Add(block);
|
||||
|
||||
|
@ -110,7 +110,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
currentBlock.Operations.AddLast(operation);
|
||||
}
|
||||
|
||||
needsNewBlock = operation.Inst == Instruction.Branch ||
|
||||
needsNewBlock = operation.Inst == Instruction.Branch ||
|
||||
operation.Inst == Instruction.BranchIfTrue ||
|
||||
operation.Inst == Instruction.BranchIfFalse;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Translation
|
||||
|
@ -84,7 +83,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
public Operand Add(Instruction inst, Operand dest = null, params Operand[] sources)
|
||||
{
|
||||
Operation operation = new Operation(inst, dest, sources);
|
||||
Operation operation = new(inst, dest, sources);
|
||||
|
||||
_operations.Add(operation);
|
||||
|
||||
|
@ -93,7 +92,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
public Operand Add(Instruction inst, StorageKind storageKind, Operand dest = null, params Operand[] sources)
|
||||
{
|
||||
Operation operation = new Operation(inst, storageKind, dest, sources);
|
||||
Operation operation = new(inst, storageKind, dest, sources);
|
||||
|
||||
_operations.Add(operation);
|
||||
|
||||
|
@ -104,7 +103,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
Operand[] dests = new[] { dest.Item1, dest.Item2 };
|
||||
|
||||
Operation operation = new Operation(inst, 0, dests, sources);
|
||||
Operation operation = new(inst, 0, dests, sources);
|
||||
|
||||
Add(operation);
|
||||
|
||||
|
@ -430,7 +429,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
AlphaTestOp.Less => Instruction.CompareLess,
|
||||
AlphaTestOp.LessOrEqual => Instruction.CompareLessOrEqual,
|
||||
AlphaTestOp.NotEqual => Instruction.CompareNotEqual,
|
||||
_ => 0
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
Debug.Assert(comparator != 0, $"Invalid alpha test operation \"{alphaTestOp}\".");
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
// Affected by resolution scaling.
|
||||
IntegerSampling = 1 << 0,
|
||||
FragCoordXY = 1 << 1,
|
||||
FragCoordXY = 1 << 1,
|
||||
|
||||
Bindless = 1 << 2,
|
||||
InstanceId = 1 << 3,
|
||||
|
@ -23,6 +23,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
OaIndexing = 1 << 8,
|
||||
FixedFuncAttr = 1 << 9,
|
||||
LocalMemory = 1 << 10,
|
||||
SharedMemory = 1 << 11
|
||||
SharedMemory = 1 << 11,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
static class FunctionMatch
|
||||
{
|
||||
private static IPatternTreeNode[] _fsiGetAddressTree = PatternTrees.GetFsiGetAddress();
|
||||
private static IPatternTreeNode[] _fsiGetAddressV2Tree = PatternTrees.GetFsiGetAddressV2();
|
||||
private static IPatternTreeNode[] _fsiIsLastWarpThreadPatternTree = PatternTrees.GetFsiIsLastWarpThread();
|
||||
private static IPatternTreeNode[] _fsiBeginPatternTree = PatternTrees.GetFsiBeginPattern();
|
||||
private static IPatternTreeNode[] _fsiEndPatternTree = PatternTrees.GetFsiEndPattern();
|
||||
private static readonly IPatternTreeNode[] _fsiGetAddressTree = PatternTrees.GetFsiGetAddress();
|
||||
private static readonly IPatternTreeNode[] _fsiGetAddressV2Tree = PatternTrees.GetFsiGetAddressV2();
|
||||
private static readonly IPatternTreeNode[] _fsiIsLastWarpThreadPatternTree = PatternTrees.GetFsiIsLastWarpThread();
|
||||
private static readonly IPatternTreeNode[] _fsiBeginPatternTree = PatternTrees.GetFsiBeginPattern();
|
||||
private static readonly IPatternTreeNode[] _fsiEndPatternTree = PatternTrees.GetFsiEndPattern();
|
||||
|
||||
public static void RunPass(DecodedProgram program)
|
||||
{
|
||||
|
@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
private enum TreeNodeType : byte
|
||||
{
|
||||
Op,
|
||||
Label
|
||||
Label,
|
||||
}
|
||||
|
||||
private class TreeNode
|
||||
|
@ -150,9 +150,9 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
private static TreeNode[] BuildTree(Block[] blocks)
|
||||
{
|
||||
List<TreeNode> nodes = new List<TreeNode>();
|
||||
List<TreeNode> nodes = new();
|
||||
|
||||
Dictionary<ulong, TreeNode> labels = new Dictionary<ulong, TreeNode>();
|
||||
Dictionary<ulong, TreeNode> labels = new();
|
||||
|
||||
TreeNodeUse[] predDefs = new TreeNodeUse[RegisterConsts.PredsCount];
|
||||
TreeNodeUse[] gprDefs = new TreeNodeUse[RegisterConsts.GprsCount];
|
||||
|
@ -223,7 +223,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
if (block.Predecessors.Count > 1)
|
||||
{
|
||||
TreeNode label = new TreeNode(order++);
|
||||
TreeNode label = new(order++);
|
||||
nodes.Add(label);
|
||||
labels.Add(block.Address, label);
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
InstOp op = block.OpCodes[opIndex];
|
||||
|
||||
TreeNode node = new TreeNode(op, IsOrderDependant(op.Name) ? order : (byte)0);
|
||||
TreeNode node = new(op, IsOrderDependant(op.Name) ? order : (byte)0);
|
||||
|
||||
// Add uses.
|
||||
|
||||
|
@ -288,7 +288,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
InstProps.SPd => 30,
|
||||
InstProps.TPd => 51,
|
||||
InstProps.VPd => 45,
|
||||
_ => throw new InvalidOperationException($"Table has unknown predicate destination {pdType}.")
|
||||
_ => throw new InvalidOperationException($"Table has unknown predicate destination {pdType}."),
|
||||
};
|
||||
|
||||
byte predIndex = (byte)((op.RawOpCode >> bit) & 7);
|
||||
|
@ -350,7 +350,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
public IPatternTreeNode Node { get; }
|
||||
public int Index { get; }
|
||||
public bool Inverted { get; }
|
||||
public PatternTreeNodeUse Inv => new PatternTreeNodeUse(Index, !Inverted, Node);
|
||||
public PatternTreeNodeUse Inv => new(Index, !Inverted, Node);
|
||||
|
||||
private PatternTreeNodeUse(int index, bool inverted, IPatternTreeNode node)
|
||||
{
|
||||
|
@ -373,7 +373,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
public TreeNodeType Type { get; }
|
||||
public byte Order { get; }
|
||||
public bool IsImm { get; }
|
||||
public PatternTreeNodeUse Out => new PatternTreeNodeUse(0, this);
|
||||
public PatternTreeNodeUse Out => new(0, this);
|
||||
|
||||
public PatternTreeNode(InstName name, Func<T, bool> match, TreeNodeType type = TreeNodeType.Op, byte order = 0, bool isImm = false)
|
||||
{
|
||||
|
@ -435,7 +435,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
}
|
||||
|
||||
DecodedFunction callTarget = program.GetFunctionByAddress(callOp.GetAbsoluteAddress());
|
||||
TreeNode[] callTargetTree = null;
|
||||
TreeNode[] callTargetTree;
|
||||
|
||||
if (callTarget == null || !Matches(_fsiIsLastWarpThreadPatternTree, callTargetTree = BuildTree(callTarget.Blocks)))
|
||||
{
|
||||
|
@ -548,7 +548,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
.Use(PT)
|
||||
.Use(orderingTicketValue).Out),
|
||||
Iadd(x: true, 0, 405).Use(PT).Use(RZ),
|
||||
Ret().Use(PT)
|
||||
Ret().Use(PT),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -576,7 +576,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
.Use(PT)
|
||||
.Use(orderingTicketValue).Out).Out),
|
||||
Iadd(x: true, 0, 405).Use(PT).Use(RZ),
|
||||
Ret().Use(PT)
|
||||
Ret().Use(PT),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -603,7 +603,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
.Use(threadKillValue).OutAt(1))
|
||||
.Use(RZ).Out).OutAt(1)).Out)
|
||||
.Use(laneIdValue),
|
||||
Ret().Use(PT)
|
||||
Ret().Use(PT),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -638,7 +638,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
.Use(PT)
|
||||
.Use(addressLowValue).Out).Inv)
|
||||
.Use(label.Out),
|
||||
Ret().Use(PT)
|
||||
Ret().Use(PT),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -684,7 +684,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
.Use(incrementValue)
|
||||
.Use(popcResult)
|
||||
.Use(RZ).Out).Out),
|
||||
Ret().Use(PT)
|
||||
Ret().Use(PT),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -806,7 +806,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
private static PatternTreeNodeUse PT => PTOrRZ();
|
||||
private static PatternTreeNodeUse RZ => PTOrRZ();
|
||||
private static PatternTreeNodeUse Undef => new PatternTreeNodeUse(0, null);
|
||||
|
||||
private static PatternTreeNodeUse CallArg(int index)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Translation
|
||||
|
@ -65,13 +64,13 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
HelperFunctionName.ConvertFloatToDouble => GenerateConvertFloatToDoubleFunction(),
|
||||
HelperFunctionName.TexelFetchScale => GenerateTexelFetchScaleFunction(),
|
||||
HelperFunctionName.TextureSizeUnscale => GenerateTextureSizeUnscaleFunction(),
|
||||
_ => throw new ArgumentException($"Invalid function name {functionName}")
|
||||
_ => throw new ArgumentException($"Invalid function name {functionName}"),
|
||||
};
|
||||
}
|
||||
|
||||
private Function GenerateConvertDoubleToFloatFunction()
|
||||
private static Function GenerateConvertDoubleToFloatFunction()
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
EmitterContext context = new();
|
||||
|
||||
Operand valueLow = Argument(0);
|
||||
Operand valueHigh = Argument(1);
|
||||
|
@ -119,9 +118,9 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
return new Function(ControlFlowGraph.Create(context.GetOperations()).Blocks, "ConvertDoubleToFloat", true, 2, 0);
|
||||
}
|
||||
|
||||
private Function GenerateConvertFloatToDoubleFunction()
|
||||
private static Function GenerateConvertFloatToDoubleFunction()
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
EmitterContext context = new();
|
||||
|
||||
Operand value = Argument(0);
|
||||
|
||||
|
@ -164,13 +163,13 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
HelperFunctionName.SharedAtomicMinS32 => GenerateSharedAtomicSigned(id, isMin: true),
|
||||
HelperFunctionName.SharedStore8 => GenerateSharedStore8(id),
|
||||
HelperFunctionName.SharedStore16 => GenerateSharedStore16(id),
|
||||
_ => throw new ArgumentException($"Invalid function name {functionName}")
|
||||
_ => throw new ArgumentException($"Invalid function name {functionName}"),
|
||||
};
|
||||
}
|
||||
|
||||
private static Function GenerateSharedAtomicSigned(int id, bool isMin)
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
EmitterContext context = new();
|
||||
|
||||
Operand wordOffset = Argument(0);
|
||||
Operand value = Argument(1);
|
||||
|
@ -199,7 +198,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
private static Function GenerateSharedStore(int id, int bitSize)
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
EmitterContext context = new();
|
||||
|
||||
Operand offset = Argument(0);
|
||||
Operand value = Argument(1);
|
||||
|
@ -219,7 +218,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
private Function GenerateTexelFetchScaleFunction()
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
EmitterContext context = new();
|
||||
|
||||
Operand input = Argument(0);
|
||||
Operand samplerIndex = Argument(1);
|
||||
|
@ -270,7 +269,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
private Function GenerateTextureSizeUnscaleFunction()
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
EmitterContext context = new();
|
||||
|
||||
Operand input = Argument(0);
|
||||
Operand samplerIndex = Argument(1);
|
||||
|
|
|
@ -9,6 +9,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
SharedStore8,
|
||||
SharedStore16,
|
||||
TexelFetchScale,
|
||||
TextureSizeUnscale
|
||||
TextureSizeUnscale,
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
// - Both sources of the OR operation comes from a constant buffer.
|
||||
for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
|
||||
{
|
||||
if (!(node.Value is TextureOperation texOp))
|
||||
if (node.Value is not TextureOperation texOp)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!(bindlessHandle.AsgOp is Operation handleCombineOp))
|
||||
if (bindlessHandle.AsgOp is not Operation handleCombineOp)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -66,9 +66,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
// and having a "canonical" representation simplifies some checks below.
|
||||
if (src0.Type == OperandType.Constant && src1.Type != OperandType.Constant)
|
||||
{
|
||||
Operand temp = src1;
|
||||
src1 = src0;
|
||||
src0 = temp;
|
||||
(src0, src1) = (src1, src0);
|
||||
}
|
||||
|
||||
TextureHandleType handleType = TextureHandleType.SeparateSamplerHandle;
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
// The base offset of the array of handles on the constant buffer is the constant offset.
|
||||
for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
|
||||
{
|
||||
if (!(node.Value is TextureOperation texOp))
|
||||
if (node.Value is not TextureOperation texOp)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!(texOp.GetSource(0).AsgOp is Operation handleAsgOp))
|
||||
if (texOp.GetSource(0).AsgOp is not Operation handleAsgOp)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -64,17 +64,17 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
// Plus this whole transform is fundamentally flawed as-is since we have no way to know the array size.
|
||||
// Eventually, this should be entirely removed in favor of a implementation that supports true bindless
|
||||
// texture access.
|
||||
if (!(ldcSrc2.AsgOp is Operation shrOp) || shrOp.Inst != Instruction.ShiftRightU32)
|
||||
if (ldcSrc2.AsgOp is not Operation shrOp || shrOp.Inst != Instruction.ShiftRightU32)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(shrOp.GetSource(0).AsgOp is Operation shrOp2) || shrOp2.Inst != Instruction.ShiftRightU32)
|
||||
if (shrOp.GetSource(0).AsgOp is not Operation shrOp2 || shrOp2.Inst != Instruction.ShiftRightU32)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(shrOp2.GetSource(0).AsgOp is Operation addOp) || addOp.Inst != Instruction.Add)
|
||||
if (shrOp2.GetSource(0).AsgOp is not Operation addOp || addOp.Inst != Instruction.Add)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
|
||||
Operand source = addOp.GetSource(0);
|
||||
|
||||
Operation shrBy3 = new Operation(Instruction.ShiftRightU32, index, source, Const(3));
|
||||
Operation shrBy3 = new(Instruction.ShiftRightU32, index, source, Const(3));
|
||||
|
||||
block.Operations.AddBefore(node, shrBy3);
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(nextBlock.Operations.First?.Value is Operation next))
|
||||
if (nextBlock.Operations.First?.Value is not Operation next)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using System;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
|
@ -262,8 +261,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
|
||||
private static int GetBitfieldExtractValue(Operation operation)
|
||||
{
|
||||
int value = operation.GetSource(0).Value;
|
||||
int lsb = operation.GetSource(1).Value;
|
||||
int value = operation.GetSource(0).Value;
|
||||
int lsb = operation.GetSource(1).Value;
|
||||
int length = operation.GetSource(2).Value;
|
||||
|
||||
return value.Extract(lsb, length);
|
||||
|
@ -278,13 +277,6 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
operation.TurnIntoCopy(ConstF((float)BitConverter.UInt16BitsToHalf((ushort)value)));
|
||||
}
|
||||
|
||||
private static void FPNegate(Operation operation)
|
||||
{
|
||||
float value = operation.GetSource(0).AsFloat();
|
||||
|
||||
operation.TurnIntoCopy(ConstF(-value));
|
||||
}
|
||||
|
||||
private static void EvaluateUnary(Operation operation, Func<int, int> op)
|
||||
{
|
||||
int x = operation.GetSource(0).Value;
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
{
|
||||
for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
|
||||
{
|
||||
if (node.Value is not Operation operation)
|
||||
if (node.Value is not Operation)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue