Use vector outputs for texture operations (#3939)
* Change AggregateType to include vector type counts * Replace VariableType uses with AggregateType and delete VariableType * Support new local vector types on SPIR-V and GLSL * Start using vector outputs for texture operations * Use vectors on more texture operations * Use vector output for ImageLoad operations * Replace all uses of single destination texture constructors with multi destination ones * Update textureGatherOffsets replacement to split vector operations * Shader cache version bump Co-authored-by: Ac_K <Acoustik666@gmail.com>
This commit is contained in:
parent
52c115a1f8
commit
9dfe81770a
37 changed files with 1100 additions and 747 deletions
|
@ -350,19 +350,33 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
}
|
||||
}
|
||||
|
||||
public static string GetVarTypeName(VariableType type)
|
||||
public static string GetVarTypeName(AggregateType type, bool precise = true)
|
||||
{
|
||||
switch (type)
|
||||
return type switch
|
||||
{
|
||||
case VariableType.Bool: return "bool";
|
||||
case VariableType.F32: return "precise float";
|
||||
case VariableType.F64: return "double";
|
||||
case VariableType.None: return "void";
|
||||
case VariableType.S32: return "int";
|
||||
case VariableType.U32: return "uint";
|
||||
}
|
||||
|
||||
throw new ArgumentException($"Invalid variable type \"{type}\".");
|
||||
AggregateType.Void => "void",
|
||||
AggregateType.Bool => "bool",
|
||||
AggregateType.FP32 => precise ? "precise float" : "float",
|
||||
AggregateType.FP64 => "double",
|
||||
AggregateType.S32 => "int",
|
||||
AggregateType.U32 => "uint",
|
||||
AggregateType.Vector2 | AggregateType.Bool => "bvec2",
|
||||
AggregateType.Vector2 | AggregateType.FP32 => precise ? "precise vec2" : "vec2",
|
||||
AggregateType.Vector2 | AggregateType.FP64 => "dvec2",
|
||||
AggregateType.Vector2 | AggregateType.S32 => "ivec2",
|
||||
AggregateType.Vector2 | AggregateType.U32 => "uvec2",
|
||||
AggregateType.Vector3 | AggregateType.Bool => "bvec3",
|
||||
AggregateType.Vector3 | AggregateType.FP32 => precise ? "precise vec3" : "vec3",
|
||||
AggregateType.Vector3 | AggregateType.FP64 => "dvec3",
|
||||
AggregateType.Vector3 | AggregateType.S32 => "ivec3",
|
||||
AggregateType.Vector3 | AggregateType.U32 => "uvec3",
|
||||
AggregateType.Vector4 | AggregateType.Bool => "bvec4",
|
||||
AggregateType.Vector4 | AggregateType.FP32 => precise ? "precise vec4" : "vec4",
|
||||
AggregateType.Vector4 | AggregateType.FP64 => "dvec4",
|
||||
AggregateType.Vector4 | AggregateType.S32 => "ivec4",
|
||||
AggregateType.Vector4 | AggregateType.U32 => "uvec4",
|
||||
_ => throw new ArgumentException($"Invalid variable type \"{type}\".")
|
||||
};
|
||||
}
|
||||
|
||||
private static void DeclareUniforms(CodeGenContext context, BufferDescriptor[] descriptors)
|
||||
|
|
|
@ -126,8 +126,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
}
|
||||
else if (node is AstAssignment assignment)
|
||||
{
|
||||
VariableType srcType = OperandManager.GetNodeDestType(context, assignment.Source);
|
||||
VariableType dstType = OperandManager.GetNodeDestType(context, assignment.Destination, isAsgDest: true);
|
||||
AggregateType srcType = OperandManager.GetNodeDestType(context, assignment.Source);
|
||||
AggregateType dstType = OperandManager.GetNodeDestType(context, assignment.Destination, isAsgDest: true);
|
||||
|
||||
string dest;
|
||||
|
||||
|
@ -158,9 +158,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
private static string GetCondExpr(CodeGenContext context, IAstNode cond)
|
||||
{
|
||||
VariableType srcType = OperandManager.GetNodeDestType(context, cond);
|
||||
AggregateType srcType = OperandManager.GetNodeDestType(context, cond);
|
||||
|
||||
return ReinterpretCast(context, cond, srcType, VariableType.Bool);
|
||||
return ReinterpretCast(context, cond, srcType, AggregateType.Bool);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenBallot;
|
||||
|
@ -8,6 +9,7 @@ using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenFSI;
|
|||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenMemory;
|
||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenPacking;
|
||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenVector;
|
||||
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||
|
@ -32,12 +34,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
IAstNode src = operation.GetSource(0);
|
||||
|
||||
VariableType type = GetSrcVarType(operation.Inst, 0);
|
||||
AggregateType type = GetSrcVarType(operation.Inst, 0);
|
||||
|
||||
string srcExpr = GetSoureExpr(context, src, type);
|
||||
string zero;
|
||||
|
||||
if (type == VariableType.F64)
|
||||
if (type == AggregateType.FP64)
|
||||
{
|
||||
zero = "0.0";
|
||||
}
|
||||
|
@ -95,7 +97,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
VariableType dstType = GetSrcVarType(inst, argIndex);
|
||||
AggregateType dstType = GetSrcVarType(inst, argIndex);
|
||||
|
||||
args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
|
||||
}
|
||||
|
@ -226,6 +228,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
case Instruction.UnpackHalf2x16:
|
||||
return UnpackHalf2x16(context, operation);
|
||||
|
||||
case Instruction.VectorExtract:
|
||||
return VectorExtract(context, operation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
||||
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
||||
|
@ -9,7 +10,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
public static string Ballot(CodeGenContext context, AstOperation operation)
|
||||
{
|
||||
VariableType dstType = GetSrcVarType(operation.Inst, 0);
|
||||
AggregateType dstType = GetSrcVarType(operation.Inst, 0);
|
||||
|
||||
string arg = GetSoureExpr(context, operation.GetSource(0), dstType);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.TypeConversion;
|
||||
|
||||
|
@ -7,11 +8,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
static class InstGenHelper
|
||||
{
|
||||
private static readonly InstInfo[] InfoTable;
|
||||
private static readonly InstInfo[] _infoTable;
|
||||
|
||||
static InstGenHelper()
|
||||
{
|
||||
InfoTable = new InstInfo[(int)Instruction.Count];
|
||||
_infoTable = new InstInfo[(int)Instruction.Count];
|
||||
|
||||
Add(Instruction.AtomicAdd, InstType.AtomicBinary, "atomicAdd");
|
||||
Add(Instruction.AtomicAnd, InstType.AtomicBinary, "atomicAnd");
|
||||
|
@ -132,6 +133,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
Add(Instruction.Truncate, InstType.CallUnary, "trunc");
|
||||
Add(Instruction.UnpackDouble2x32, InstType.Special);
|
||||
Add(Instruction.UnpackHalf2x16, InstType.Special);
|
||||
Add(Instruction.VectorExtract, InstType.Special);
|
||||
Add(Instruction.VoteAll, InstType.CallUnary, "allInvocationsARB");
|
||||
Add(Instruction.VoteAllEqual, InstType.CallUnary, "allInvocationsEqualARB");
|
||||
Add(Instruction.VoteAny, InstType.CallUnary, "anyInvocationARB");
|
||||
|
@ -139,15 +141,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
private static void Add(Instruction inst, InstType flags, string opName = null, int precedence = 0)
|
||||
{
|
||||
InfoTable[(int)inst] = new InstInfo(flags, opName, precedence);
|
||||
_infoTable[(int)inst] = new InstInfo(flags, opName, precedence);
|
||||
}
|
||||
|
||||
public static InstInfo GetInstructionInfo(Instruction inst)
|
||||
{
|
||||
return InfoTable[(int)(inst & Instruction.Mask)];
|
||||
return _infoTable[(int)(inst & Instruction.Mask)];
|
||||
}
|
||||
|
||||
public static string GetSoureExpr(CodeGenContext context, IAstNode node, VariableType dstType)
|
||||
public static string GetSoureExpr(CodeGenContext context, IAstNode node, AggregateType dstType)
|
||||
{
|
||||
return ReinterpretCast(context, node, OperandManager.GetNodeDestType(context, node), dstType);
|
||||
}
|
||||
|
@ -191,7 +193,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
return false;
|
||||
}
|
||||
|
||||
InstInfo info = InfoTable[(int)(operation.Inst & Instruction.Mask)];
|
||||
InstInfo info = _infoTable[(int)(operation.Inst & Instruction.Mask)];
|
||||
|
||||
if ((info.Type & (InstType.Call | InstType.Special)) != 0)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
||||
|
@ -23,7 +24,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
case Instruction.ImageStore:
|
||||
return "// imageStore(bindless)";
|
||||
case Instruction.ImageLoad:
|
||||
NumberFormatter.TryFormat(0, texOp.Format.GetComponentType(), out string imageConst);
|
||||
AggregateType componentType = texOp.Format.GetComponentType();
|
||||
|
||||
NumberFormatter.TryFormat(0, componentType, out string imageConst);
|
||||
|
||||
AggregateType outputType = texOp.GetVectorType(componentType);
|
||||
|
||||
if ((outputType & AggregateType.ElementCountMask) != 0)
|
||||
{
|
||||
return $"{Declarations.GetVarTypeName(outputType, precise: false)}({imageConst})";
|
||||
}
|
||||
|
||||
return imageConst;
|
||||
default:
|
||||
return NumberFormatter.FormatInt(0);
|
||||
|
@ -58,7 +69,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
int srcIndex = isBindless ? 1 : 0;
|
||||
|
||||
string Src(VariableType type)
|
||||
string Src(AggregateType type)
|
||||
{
|
||||
return GetSoureExpr(context, texOp.GetSource(srcIndex++), type);
|
||||
}
|
||||
|
@ -67,7 +78,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
if (isIndexed)
|
||||
{
|
||||
indexExpr = Src(VariableType.S32);
|
||||
indexExpr = Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
string imageName = OperandManager.GetImageName(context.Config.Stage, texOp, indexExpr);
|
||||
|
@ -113,19 +124,19 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
for (int index = 0; index < pCount; index++)
|
||||
{
|
||||
elems[index] = Src(VariableType.S32);
|
||||
elems[index] = Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
Append(ApplyScaling("ivec" + pCount + "(" + string.Join(", ", elems) + ")"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Append(Src(VariableType.S32));
|
||||
Append(Src(AggregateType.S32));
|
||||
}
|
||||
|
||||
if (texOp.Inst == Instruction.ImageStore)
|
||||
{
|
||||
VariableType type = texOp.Format.GetComponentType();
|
||||
AggregateType type = texOp.Format.GetComponentType();
|
||||
|
||||
string[] cElems = new string[4];
|
||||
|
||||
|
@ -139,8 +150,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
cElems[index] = type switch
|
||||
{
|
||||
VariableType.S32 => NumberFormatter.FormatInt(0),
|
||||
VariableType.U32 => NumberFormatter.FormatUint(0),
|
||||
AggregateType.S32 => NumberFormatter.FormatInt(0),
|
||||
AggregateType.U32 => NumberFormatter.FormatUint(0),
|
||||
_ => NumberFormatter.FormatFloat(0)
|
||||
};
|
||||
}
|
||||
|
@ -148,8 +159,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
string prefix = type switch
|
||||
{
|
||||
VariableType.S32 => "i",
|
||||
VariableType.U32 => "u",
|
||||
AggregateType.S32 => "i",
|
||||
AggregateType.U32 => "u",
|
||||
_ => string.Empty
|
||||
};
|
||||
|
||||
|
@ -158,7 +169,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
if (texOp.Inst == Instruction.ImageAtomic)
|
||||
{
|
||||
VariableType type = texOp.Format.GetComponentType();
|
||||
AggregateType type = texOp.Format.GetComponentType();
|
||||
|
||||
if ((texOp.Flags & TextureFlags.AtomicMask) == TextureFlags.CAS)
|
||||
{
|
||||
|
@ -176,14 +187,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
texCall += ")";
|
||||
|
||||
if (type != VariableType.S32)
|
||||
if (type != AggregateType.S32)
|
||||
{
|
||||
texCall = "int(" + texCall + ")";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texCall += ")" + (texOp.Inst == Instruction.ImageLoad ? GetMask(texOp.Index) : "");
|
||||
texCall += ")" + (texOp.Inst == Instruction.ImageLoad ? GetMaskMultiDest(texOp.Index) : "");
|
||||
}
|
||||
|
||||
return texCall;
|
||||
|
@ -288,7 +299,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
if (isIndexed)
|
||||
{
|
||||
indexExpr = GetSoureExpr(context, texOp.GetSource(0), VariableType.S32);
|
||||
indexExpr = GetSoureExpr(context, texOp.GetSource(0), AggregateType.S32);
|
||||
}
|
||||
|
||||
string samplerName = OperandManager.GetSamplerName(context.Config.Stage, texOp, indexExpr);
|
||||
|
@ -303,14 +314,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
for (int index = 0; index < coordsCount; index++)
|
||||
{
|
||||
elems[index] = GetSoureExpr(context, texOp.GetSource(coordsIndex + index), VariableType.F32);
|
||||
elems[index] = GetSoureExpr(context, texOp.GetSource(coordsIndex + index), AggregateType.FP32);
|
||||
}
|
||||
|
||||
coordsExpr = "vec" + coordsCount + "(" + string.Join(", ", elems) + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
coordsExpr = GetSoureExpr(context, texOp.GetSource(coordsIndex), VariableType.F32);
|
||||
coordsExpr = GetSoureExpr(context, texOp.GetSource(coordsIndex), AggregateType.FP32);
|
||||
}
|
||||
|
||||
return $"textureQueryLod({samplerName}, {coordsExpr}){GetMask(texOp.Index)}";
|
||||
|
@ -362,9 +373,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
string offsetExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
||||
|
||||
VariableType srcType = OperandManager.GetNodeDestType(context, src2);
|
||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src2);
|
||||
|
||||
string src = TypeConversion.ReinterpretCast(context, src2, srcType, VariableType.U32);
|
||||
string src = TypeConversion.ReinterpretCast(context, src2, srcType, AggregateType.U32);
|
||||
|
||||
return $"{arrayName}[{offsetExpr}] = {src}";
|
||||
}
|
||||
|
@ -376,9 +387,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
string offsetExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
||||
|
||||
VariableType srcType = OperandManager.GetNodeDestType(context, src2);
|
||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src2);
|
||||
|
||||
string src = TypeConversion.ReinterpretCast(context, src2, srcType, VariableType.U32);
|
||||
string src = TypeConversion.ReinterpretCast(context, src2, srcType, AggregateType.U32);
|
||||
|
||||
return $"{HelperFunctionNames.StoreShared16}({offsetExpr}, {src})";
|
||||
}
|
||||
|
@ -390,9 +401,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
string offsetExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
||||
|
||||
VariableType srcType = OperandManager.GetNodeDestType(context, src2);
|
||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src2);
|
||||
|
||||
string src = TypeConversion.ReinterpretCast(context, src2, srcType, VariableType.U32);
|
||||
string src = TypeConversion.ReinterpretCast(context, src2, srcType, AggregateType.U32);
|
||||
|
||||
return $"{HelperFunctionNames.StoreShared8}({offsetExpr}, {src})";
|
||||
}
|
||||
|
@ -406,9 +417,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
||||
string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
|
||||
|
||||
VariableType srcType = OperandManager.GetNodeDestType(context, src3);
|
||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src3);
|
||||
|
||||
string src = TypeConversion.ReinterpretCast(context, src3, srcType, VariableType.U32);
|
||||
string src = TypeConversion.ReinterpretCast(context, src3, srcType, AggregateType.U32);
|
||||
|
||||
string sb = GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
|
||||
|
||||
|
@ -424,9 +435,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
||||
string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
|
||||
|
||||
VariableType srcType = OperandManager.GetNodeDestType(context, src3);
|
||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src3);
|
||||
|
||||
string src = TypeConversion.ReinterpretCast(context, src3, srcType, VariableType.U32);
|
||||
string src = TypeConversion.ReinterpretCast(context, src3, srcType, AggregateType.U32);
|
||||
|
||||
string sb = GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
|
||||
|
||||
|
@ -442,9 +453,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
||||
string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
|
||||
|
||||
VariableType srcType = OperandManager.GetNodeDestType(context, src3);
|
||||
AggregateType srcType = OperandManager.GetNodeDestType(context, src3);
|
||||
|
||||
string src = TypeConversion.ReinterpretCast(context, src3, srcType, VariableType.U32);
|
||||
string src = TypeConversion.ReinterpretCast(context, src3, srcType, AggregateType.U32);
|
||||
|
||||
string sb = GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
|
||||
|
||||
|
@ -469,6 +480,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
bool isMultisample = (texOp.Type & SamplerType.Multisample) != 0;
|
||||
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
|
||||
|
||||
bool colorIsVector = isGather || !isShadow;
|
||||
|
||||
SamplerType type = texOp.Type & SamplerType.Mask;
|
||||
|
||||
bool is2D = type == SamplerType.Texture2D;
|
||||
|
@ -492,7 +505,19 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
// TODO: Bindless texture support. For now we just return 0.
|
||||
if (isBindless)
|
||||
{
|
||||
return NumberFormatter.FormatFloat(0);
|
||||
string scalarValue = NumberFormatter.FormatFloat(0);
|
||||
|
||||
if (colorIsVector)
|
||||
{
|
||||
AggregateType outputType = texOp.GetVectorType(AggregateType.FP32);
|
||||
|
||||
if ((outputType & AggregateType.ElementCountMask) != 0)
|
||||
{
|
||||
return $"{Declarations.GetVarTypeName(outputType, precise: false)}({scalarValue})";
|
||||
}
|
||||
}
|
||||
|
||||
return scalarValue;
|
||||
}
|
||||
|
||||
string texCall = intCoords ? "texelFetch" : "texture";
|
||||
|
@ -521,7 +546,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
int srcIndex = isBindless ? 1 : 0;
|
||||
|
||||
string Src(VariableType type)
|
||||
string Src(AggregateType type)
|
||||
{
|
||||
return GetSoureExpr(context, texOp.GetSource(srcIndex++), type);
|
||||
}
|
||||
|
@ -530,7 +555,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
if (isIndexed)
|
||||
{
|
||||
indexExpr = Src(VariableType.S32);
|
||||
indexExpr = Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
string samplerName = OperandManager.GetSamplerName(context.Config.Stage, texOp, indexExpr);
|
||||
|
@ -578,7 +603,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
texCall += ", " + str;
|
||||
}
|
||||
|
||||
VariableType coordType = intCoords ? VariableType.S32 : VariableType.F32;
|
||||
AggregateType coordType = intCoords ? AggregateType.S32 : AggregateType.FP32;
|
||||
|
||||
string AssemblePVector(int count)
|
||||
{
|
||||
|
@ -590,7 +615,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
if (arrayIndexElem == index)
|
||||
{
|
||||
elems[index] = Src(VariableType.S32);
|
||||
elems[index] = Src(AggregateType.S32);
|
||||
|
||||
if (!intCoords)
|
||||
{
|
||||
|
@ -652,20 +677,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
elems[index] = Src(VariableType.F32);
|
||||
elems[index] = Src(AggregateType.FP32);
|
||||
}
|
||||
|
||||
return "vec" + count + "(" + string.Join(", ", elems) + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
return Src(VariableType.F32);
|
||||
return Src(AggregateType.FP32);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasExtraCompareArg)
|
||||
{
|
||||
Append(Src(VariableType.F32));
|
||||
Append(Src(AggregateType.FP32));
|
||||
}
|
||||
|
||||
if (hasDerivatives)
|
||||
|
@ -676,7 +701,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
if (isMultisample)
|
||||
{
|
||||
Append(Src(VariableType.S32));
|
||||
Append(Src(AggregateType.S32));
|
||||
}
|
||||
else if (hasLodLevel)
|
||||
{
|
||||
|
@ -691,14 +716,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
elems[index] = Src(VariableType.S32);
|
||||
elems[index] = Src(AggregateType.S32);
|
||||
}
|
||||
|
||||
return "ivec" + count + "(" + string.Join(", ", elems) + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
return Src(VariableType.S32);
|
||||
return Src(AggregateType.S32);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -718,17 +743,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
if (hasLodBias)
|
||||
{
|
||||
Append(Src(VariableType.F32));
|
||||
Append(Src(AggregateType.FP32));
|
||||
}
|
||||
|
||||
// textureGather* optional extra component index,
|
||||
// not needed for shadow samplers.
|
||||
if (isGather && !isShadow)
|
||||
{
|
||||
Append(Src(VariableType.S32));
|
||||
Append(Src(AggregateType.S32));
|
||||
}
|
||||
|
||||
texCall += ")" + (isGather || !isShadow ? GetMask(texOp.Index) : "");
|
||||
texCall += ")" + (colorIsVector ? GetMaskMultiDest(texOp.Index) : "");
|
||||
|
||||
return texCall;
|
||||
}
|
||||
|
@ -751,7 +776,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
if (isIndexed)
|
||||
{
|
||||
indexExpr = GetSoureExpr(context, texOp.GetSource(0), VariableType.S32);
|
||||
indexExpr = GetSoureExpr(context, texOp.GetSource(0), AggregateType.S32);
|
||||
}
|
||||
|
||||
string samplerName = OperandManager.GetSamplerName(context.Config.Stage, texOp, indexExpr);
|
||||
|
@ -804,5 +829,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
{
|
||||
return '.' + "rgba".Substring(index, 1);
|
||||
}
|
||||
|
||||
private static string GetMaskMultiDest(int mask)
|
||||
{
|
||||
string swizzle = ".";
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if ((mask & (1 << i)) != 0)
|
||||
{
|
||||
swizzle += "xyzw"[i];
|
||||
}
|
||||
}
|
||||
|
||||
return swizzle;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
||||
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||
{
|
||||
static class InstGenVector
|
||||
{
|
||||
public static string VectorExtract(CodeGenContext context, AstOperation operation)
|
||||
{
|
||||
IAstNode vector = operation.GetSource(0);
|
||||
IAstNode index = operation.GetSource(1);
|
||||
|
||||
string vectorExpr = GetSoureExpr(context, vector, OperandManager.GetNodeDestType(context, vector));
|
||||
|
||||
if (index is AstOperand indexOperand && indexOperand.Type == OperandType.Constant)
|
||||
{
|
||||
char elem = "xyzw"[indexOperand.Value];
|
||||
|
||||
return $"{vectorExpr}.{elem}";
|
||||
}
|
||||
else
|
||||
{
|
||||
string indexExpr = GetSoureExpr(context, index, GetSrcVarType(operation.Inst, 1));
|
||||
|
||||
return $"{vectorExpr}[{indexExpr}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
|
@ -8,21 +8,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
{
|
||||
private const int MaxDecimal = 256;
|
||||
|
||||
public static bool TryFormat(int value, VariableType dstType, out string formatted)
|
||||
public static bool TryFormat(int value, AggregateType dstType, out string formatted)
|
||||
{
|
||||
if (dstType == VariableType.F32)
|
||||
if (dstType == AggregateType.FP32)
|
||||
{
|
||||
return TryFormatFloat(BitConverter.Int32BitsToSingle(value), out formatted);
|
||||
}
|
||||
else if (dstType == VariableType.S32)
|
||||
else if (dstType == AggregateType.S32)
|
||||
{
|
||||
formatted = FormatInt(value);
|
||||
}
|
||||
else if (dstType == VariableType.U32)
|
||||
else if (dstType == AggregateType.U32)
|
||||
{
|
||||
formatted = FormatUint((uint)value);
|
||||
}
|
||||
else if (dstType == VariableType.Bool)
|
||||
else if (dstType == AggregateType.Bool)
|
||||
{
|
||||
formatted = value != 0 ? "true" : "false";
|
||||
}
|
||||
|
@ -65,13 +65,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
return true;
|
||||
}
|
||||
|
||||
public static string FormatInt(int value, VariableType dstType)
|
||||
public static string FormatInt(int value, AggregateType dstType)
|
||||
{
|
||||
if (dstType == VariableType.S32)
|
||||
if (dstType == AggregateType.S32)
|
||||
{
|
||||
return FormatInt(value);
|
||||
}
|
||||
else if (dstType == VariableType.U32)
|
||||
else if (dstType == AggregateType.U32)
|
||||
{
|
||||
return FormatUint((uint)value);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
||||
|
||||
|
@ -17,9 +18,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
{
|
||||
public string Name { get; }
|
||||
|
||||
public VariableType Type { get; }
|
||||
public AggregateType Type { get; }
|
||||
|
||||
public BuiltInAttribute(string name, VariableType type)
|
||||
public BuiltInAttribute(string name, AggregateType type)
|
||||
{
|
||||
Name = name;
|
||||
Type = type;
|
||||
|
@ -28,64 +29,64 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
private static Dictionary<int, BuiltInAttribute> _builtInAttributes = new Dictionary<int, BuiltInAttribute>()
|
||||
{
|
||||
{ AttributeConsts.Layer, new BuiltInAttribute("gl_Layer", VariableType.S32) },
|
||||
{ AttributeConsts.PointSize, new BuiltInAttribute("gl_PointSize", VariableType.F32) },
|
||||
{ AttributeConsts.PositionX, new BuiltInAttribute("gl_Position.x", VariableType.F32) },
|
||||
{ AttributeConsts.PositionY, new BuiltInAttribute("gl_Position.y", VariableType.F32) },
|
||||
{ AttributeConsts.PositionZ, new BuiltInAttribute("gl_Position.z", VariableType.F32) },
|
||||
{ AttributeConsts.PositionW, new BuiltInAttribute("gl_Position.w", VariableType.F32) },
|
||||
{ AttributeConsts.ClipDistance0, new BuiltInAttribute("gl_ClipDistance[0]", VariableType.F32) },
|
||||
{ AttributeConsts.ClipDistance1, new BuiltInAttribute("gl_ClipDistance[1]", VariableType.F32) },
|
||||
{ AttributeConsts.ClipDistance2, new BuiltInAttribute("gl_ClipDistance[2]", VariableType.F32) },
|
||||
{ AttributeConsts.ClipDistance3, new BuiltInAttribute("gl_ClipDistance[3]", VariableType.F32) },
|
||||
{ AttributeConsts.ClipDistance4, new BuiltInAttribute("gl_ClipDistance[4]", VariableType.F32) },
|
||||
{ AttributeConsts.ClipDistance5, new BuiltInAttribute("gl_ClipDistance[5]", VariableType.F32) },
|
||||
{ AttributeConsts.ClipDistance6, new BuiltInAttribute("gl_ClipDistance[6]", VariableType.F32) },
|
||||
{ AttributeConsts.ClipDistance7, new BuiltInAttribute("gl_ClipDistance[7]", VariableType.F32) },
|
||||
{ AttributeConsts.PointCoordX, new BuiltInAttribute("gl_PointCoord.x", VariableType.F32) },
|
||||
{ AttributeConsts.PointCoordY, new BuiltInAttribute("gl_PointCoord.y", VariableType.F32) },
|
||||
{ AttributeConsts.TessCoordX, new BuiltInAttribute("gl_TessCoord.x", VariableType.F32) },
|
||||
{ AttributeConsts.TessCoordY, new BuiltInAttribute("gl_TessCoord.y", VariableType.F32) },
|
||||
{ AttributeConsts.InstanceId, new BuiltInAttribute("gl_InstanceID", VariableType.S32) },
|
||||
{ AttributeConsts.VertexId, new BuiltInAttribute("gl_VertexID", VariableType.S32) },
|
||||
{ AttributeConsts.BaseInstance, new BuiltInAttribute("gl_BaseInstanceARB", VariableType.S32) },
|
||||
{ AttributeConsts.BaseVertex, new BuiltInAttribute("gl_BaseVertexARB", VariableType.S32) },
|
||||
{ AttributeConsts.InstanceIndex, new BuiltInAttribute("gl_InstanceIndex", VariableType.S32) },
|
||||
{ AttributeConsts.VertexIndex, new BuiltInAttribute("gl_VertexIndex", VariableType.S32) },
|
||||
{ AttributeConsts.DrawIndex, new BuiltInAttribute("gl_DrawIDARB", VariableType.S32) },
|
||||
{ AttributeConsts.FrontFacing, new BuiltInAttribute("gl_FrontFacing", VariableType.Bool) },
|
||||
{ AttributeConsts.Layer, new BuiltInAttribute("gl_Layer", AggregateType.S32) },
|
||||
{ AttributeConsts.PointSize, new BuiltInAttribute("gl_PointSize", AggregateType.FP32) },
|
||||
{ AttributeConsts.PositionX, new BuiltInAttribute("gl_Position.x", AggregateType.FP32) },
|
||||
{ AttributeConsts.PositionY, new BuiltInAttribute("gl_Position.y", AggregateType.FP32) },
|
||||
{ AttributeConsts.PositionZ, new BuiltInAttribute("gl_Position.z", AggregateType.FP32) },
|
||||
{ AttributeConsts.PositionW, new BuiltInAttribute("gl_Position.w", AggregateType.FP32) },
|
||||
{ AttributeConsts.ClipDistance0, new BuiltInAttribute("gl_ClipDistance[0]", AggregateType.FP32) },
|
||||
{ AttributeConsts.ClipDistance1, new BuiltInAttribute("gl_ClipDistance[1]", AggregateType.FP32) },
|
||||
{ AttributeConsts.ClipDistance2, new BuiltInAttribute("gl_ClipDistance[2]", AggregateType.FP32) },
|
||||
{ AttributeConsts.ClipDistance3, new BuiltInAttribute("gl_ClipDistance[3]", AggregateType.FP32) },
|
||||
{ AttributeConsts.ClipDistance4, new BuiltInAttribute("gl_ClipDistance[4]", AggregateType.FP32) },
|
||||
{ AttributeConsts.ClipDistance5, new BuiltInAttribute("gl_ClipDistance[5]", AggregateType.FP32) },
|
||||
{ AttributeConsts.ClipDistance6, new BuiltInAttribute("gl_ClipDistance[6]", AggregateType.FP32) },
|
||||
{ AttributeConsts.ClipDistance7, new BuiltInAttribute("gl_ClipDistance[7]", AggregateType.FP32) },
|
||||
{ AttributeConsts.PointCoordX, new BuiltInAttribute("gl_PointCoord.x", AggregateType.FP32) },
|
||||
{ AttributeConsts.PointCoordY, new BuiltInAttribute("gl_PointCoord.y", AggregateType.FP32) },
|
||||
{ AttributeConsts.TessCoordX, new BuiltInAttribute("gl_TessCoord.x", AggregateType.FP32) },
|
||||
{ AttributeConsts.TessCoordY, new BuiltInAttribute("gl_TessCoord.y", AggregateType.FP32) },
|
||||
{ AttributeConsts.InstanceId, new BuiltInAttribute("gl_InstanceID", AggregateType.S32) },
|
||||
{ AttributeConsts.VertexId, new BuiltInAttribute("gl_VertexID", AggregateType.S32) },
|
||||
{ AttributeConsts.BaseInstance, new BuiltInAttribute("gl_BaseInstanceARB", AggregateType.S32) },
|
||||
{ AttributeConsts.BaseVertex, new BuiltInAttribute("gl_BaseVertexARB", AggregateType.S32) },
|
||||
{ AttributeConsts.InstanceIndex, new BuiltInAttribute("gl_InstanceIndex", AggregateType.S32) },
|
||||
{ AttributeConsts.VertexIndex, new BuiltInAttribute("gl_VertexIndex", AggregateType.S32) },
|
||||
{ AttributeConsts.DrawIndex, new BuiltInAttribute("gl_DrawIDARB", AggregateType.S32) },
|
||||
{ AttributeConsts.FrontFacing, new BuiltInAttribute("gl_FrontFacing", AggregateType.Bool) },
|
||||
|
||||
// Special.
|
||||
{ AttributeConsts.FragmentOutputDepth, new BuiltInAttribute("gl_FragDepth", VariableType.F32) },
|
||||
{ AttributeConsts.ThreadKill, new BuiltInAttribute("gl_HelperInvocation", VariableType.Bool) },
|
||||
{ AttributeConsts.ThreadIdX, new BuiltInAttribute("gl_LocalInvocationID.x", VariableType.U32) },
|
||||
{ AttributeConsts.ThreadIdY, new BuiltInAttribute("gl_LocalInvocationID.y", VariableType.U32) },
|
||||
{ AttributeConsts.ThreadIdZ, new BuiltInAttribute("gl_LocalInvocationID.z", VariableType.U32) },
|
||||
{ AttributeConsts.CtaIdX, new BuiltInAttribute("gl_WorkGroupID.x", VariableType.U32) },
|
||||
{ AttributeConsts.CtaIdY, new BuiltInAttribute("gl_WorkGroupID.y", VariableType.U32) },
|
||||
{ AttributeConsts.CtaIdZ, new BuiltInAttribute("gl_WorkGroupID.z", VariableType.U32) },
|
||||
{ AttributeConsts.LaneId, new BuiltInAttribute(null, VariableType.U32) },
|
||||
{ AttributeConsts.InvocationId, new BuiltInAttribute("gl_InvocationID", VariableType.S32) },
|
||||
{ AttributeConsts.PrimitiveId, new BuiltInAttribute("gl_PrimitiveID", VariableType.S32) },
|
||||
{ AttributeConsts.PatchVerticesIn, new BuiltInAttribute("gl_PatchVerticesIn", VariableType.S32) },
|
||||
{ AttributeConsts.EqMask, new BuiltInAttribute(null, VariableType.U32) },
|
||||
{ AttributeConsts.GeMask, new BuiltInAttribute(null, VariableType.U32) },
|
||||
{ AttributeConsts.GtMask, new BuiltInAttribute(null, VariableType.U32) },
|
||||
{ AttributeConsts.LeMask, new BuiltInAttribute(null, VariableType.U32) },
|
||||
{ AttributeConsts.LtMask, new BuiltInAttribute(null, VariableType.U32) },
|
||||
{ AttributeConsts.FragmentOutputDepth, new BuiltInAttribute("gl_FragDepth", AggregateType.FP32) },
|
||||
{ AttributeConsts.ThreadKill, new BuiltInAttribute("gl_HelperInvocation", AggregateType.Bool) },
|
||||
{ AttributeConsts.ThreadIdX, new BuiltInAttribute("gl_LocalInvocationID.x", AggregateType.U32) },
|
||||
{ AttributeConsts.ThreadIdY, new BuiltInAttribute("gl_LocalInvocationID.y", AggregateType.U32) },
|
||||
{ AttributeConsts.ThreadIdZ, new BuiltInAttribute("gl_LocalInvocationID.z", AggregateType.U32) },
|
||||
{ AttributeConsts.CtaIdX, new BuiltInAttribute("gl_WorkGroupID.x", AggregateType.U32) },
|
||||
{ AttributeConsts.CtaIdY, new BuiltInAttribute("gl_WorkGroupID.y", AggregateType.U32) },
|
||||
{ AttributeConsts.CtaIdZ, new BuiltInAttribute("gl_WorkGroupID.z", AggregateType.U32) },
|
||||
{ AttributeConsts.LaneId, new BuiltInAttribute(null, AggregateType.U32) },
|
||||
{ AttributeConsts.InvocationId, new BuiltInAttribute("gl_InvocationID", AggregateType.S32) },
|
||||
{ AttributeConsts.PrimitiveId, new BuiltInAttribute("gl_PrimitiveID", AggregateType.S32) },
|
||||
{ AttributeConsts.PatchVerticesIn, new BuiltInAttribute("gl_PatchVerticesIn", AggregateType.S32) },
|
||||
{ AttributeConsts.EqMask, new BuiltInAttribute(null, AggregateType.U32) },
|
||||
{ AttributeConsts.GeMask, new BuiltInAttribute(null, AggregateType.U32) },
|
||||
{ AttributeConsts.GtMask, new BuiltInAttribute(null, AggregateType.U32) },
|
||||
{ AttributeConsts.LeMask, new BuiltInAttribute(null, AggregateType.U32) },
|
||||
{ AttributeConsts.LtMask, new BuiltInAttribute(null, AggregateType.U32) },
|
||||
|
||||
// Support uniforms.
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 0, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[0]", VariableType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 4, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[1]", VariableType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 8, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[2]", VariableType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 12, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[3]", VariableType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 16, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[4]", VariableType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 20, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[5]", VariableType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 24, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[6]", VariableType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 28, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[7]", VariableType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 0, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[0]", AggregateType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 4, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[1]", AggregateType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 8, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[2]", AggregateType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 12, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[3]", AggregateType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 16, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[4]", AggregateType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 20, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[5]", AggregateType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 24, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[6]", AggregateType.Bool) },
|
||||
{ AttributeConsts.FragmentOutputIsBgraBase + 28, new BuiltInAttribute($"{DefaultNames.SupportBlockIsBgraName}[7]", AggregateType.Bool) },
|
||||
|
||||
{ AttributeConsts.SupportBlockViewInverseX, new BuiltInAttribute($"{DefaultNames.SupportBlockViewportInverse}.x", VariableType.F32) },
|
||||
{ AttributeConsts.SupportBlockViewInverseY, new BuiltInAttribute($"{DefaultNames.SupportBlockViewportInverse}.y", VariableType.F32) }
|
||||
{ AttributeConsts.SupportBlockViewInverseX, new BuiltInAttribute($"{DefaultNames.SupportBlockViewportInverse}.x", AggregateType.FP32) },
|
||||
{ AttributeConsts.SupportBlockViewInverseY, new BuiltInAttribute($"{DefaultNames.SupportBlockViewportInverse}.y", AggregateType.FP32) }
|
||||
};
|
||||
|
||||
private Dictionary<AstOperand, string> _locals;
|
||||
|
@ -329,7 +330,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
{
|
||||
if (cbIndexable)
|
||||
{
|
||||
return GetUbName(stage, NumberFormatter.FormatInt(slot, VariableType.S32));
|
||||
return GetUbName(stage, NumberFormatter.FormatInt(slot, AggregateType.S32));
|
||||
}
|
||||
|
||||
return $"{GetShaderStagePrefix(stage)}_{DefaultNames.UniformNamePrefix}{slot}_{DefaultNames.UniformNameSuffix}";
|
||||
|
@ -404,7 +405,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
return $"{DefaultNames.ArgumentNamePrefix}{argIndex}";
|
||||
}
|
||||
|
||||
public static VariableType GetNodeDestType(CodeGenContext context, IAstNode node, bool isAsgDest = false)
|
||||
public static AggregateType GetNodeDestType(CodeGenContext context, IAstNode node, bool isAsgDest = false)
|
||||
{
|
||||
if (node is AstOperation operation)
|
||||
{
|
||||
|
@ -431,12 +432,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
return context.GetFunction(funcId.Value).ReturnType;
|
||||
}
|
||||
else if (operation is AstTextureOperation texOp &&
|
||||
(texOp.Inst == Instruction.ImageLoad ||
|
||||
texOp.Inst == Instruction.ImageStore ||
|
||||
texOp.Inst == Instruction.ImageAtomic))
|
||||
else if (operation.Inst == Instruction.VectorExtract)
|
||||
{
|
||||
return texOp.Format.GetComponentType();
|
||||
return GetNodeDestType(context, operation.GetSource(0)) & ~AggregateType.ElementCountMask;
|
||||
}
|
||||
else if (operation is AstTextureOperation texOp)
|
||||
{
|
||||
if (texOp.Inst == Instruction.ImageLoad ||
|
||||
texOp.Inst == Instruction.ImageStore ||
|
||||
texOp.Inst == Instruction.ImageAtomic)
|
||||
{
|
||||
return texOp.GetVectorType(texOp.Format.GetComponentType());
|
||||
}
|
||||
else if (texOp.Inst == Instruction.TextureSample)
|
||||
{
|
||||
return texOp.GetVectorType(GetDestVarType(operation.Inst));
|
||||
}
|
||||
}
|
||||
|
||||
return GetDestVarType(operation.Inst);
|
||||
|
@ -458,7 +469,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
}
|
||||
}
|
||||
|
||||
private static VariableType GetOperandVarType(CodeGenContext context, AstOperand operand, bool isAsgDest = false)
|
||||
private static AggregateType GetOperandVarType(CodeGenContext context, AstOperand operand, bool isAsgDest = false)
|
||||
{
|
||||
if (operand.Type == OperandType.Attribute)
|
||||
{
|
||||
|
@ -474,7 +485,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
|
||||
AttributeType type = context.Config.GpuAccessor.QueryAttributeType(location);
|
||||
|
||||
return type.ToVariableType();
|
||||
return type.ToAggregateType();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
|
@ -10,8 +11,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
public static string ReinterpretCast(
|
||||
CodeGenContext context,
|
||||
IAstNode node,
|
||||
VariableType srcType,
|
||||
VariableType dstType)
|
||||
AggregateType srcType,
|
||||
AggregateType dstType)
|
||||
{
|
||||
if (node is AstOperand operand && operand.Type == OperandType.Constant)
|
||||
{
|
||||
|
@ -26,46 +27,46 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
return ReinterpretCast(expr, node, srcType, dstType);
|
||||
}
|
||||
|
||||
private static string ReinterpretCast(string expr, IAstNode node, VariableType srcType, VariableType dstType)
|
||||
private static string ReinterpretCast(string expr, IAstNode node, AggregateType srcType, AggregateType dstType)
|
||||
{
|
||||
if (srcType == dstType)
|
||||
{
|
||||
return expr;
|
||||
}
|
||||
|
||||
if (srcType == VariableType.F32)
|
||||
if (srcType == AggregateType.FP32)
|
||||
{
|
||||
switch (dstType)
|
||||
{
|
||||
case VariableType.Bool: return $"(floatBitsToInt({expr}) != 0)";
|
||||
case VariableType.S32: return $"floatBitsToInt({expr})";
|
||||
case VariableType.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 == VariableType.F32)
|
||||
else if (dstType == AggregateType.FP32)
|
||||
{
|
||||
switch (srcType)
|
||||
{
|
||||
case VariableType.Bool: return $"intBitsToFloat({ReinterpretBoolToInt(expr, node, VariableType.S32)})";
|
||||
case VariableType.S32: return $"intBitsToFloat({expr})";
|
||||
case VariableType.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 == VariableType.Bool)
|
||||
else if (srcType == AggregateType.Bool)
|
||||
{
|
||||
return ReinterpretBoolToInt(expr, node, dstType);
|
||||
}
|
||||
else if (dstType == VariableType.Bool)
|
||||
else if (dstType == AggregateType.Bool)
|
||||
{
|
||||
expr = InstGenHelper.Enclose(expr, node, Instruction.CompareNotEqual, isLhs: true);
|
||||
|
||||
return $"({expr} != 0)";
|
||||
}
|
||||
else if (dstType == VariableType.S32)
|
||||
else if (dstType == AggregateType.S32)
|
||||
{
|
||||
return $"int({expr})";
|
||||
}
|
||||
else if (dstType == VariableType.U32)
|
||||
else if (dstType == AggregateType.U32)
|
||||
{
|
||||
return $"uint({expr})";
|
||||
}
|
||||
|
@ -73,7 +74,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
throw new ArgumentException($"Invalid reinterpret cast from \"{srcType}\" to \"{dstType}\".");
|
||||
}
|
||||
|
||||
private static string ReinterpretBoolToInt(string expr, IAstNode node, VariableType dstType)
|
||||
private static string ReinterpretBoolToInt(string expr, IAstNode node, AggregateType dstType)
|
||||
{
|
||||
string trueExpr = NumberFormatter.FormatInt(IrConsts.True, dstType);
|
||||
string falseExpr = NumberFormatter.FormatInt(IrConsts.False, dstType);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue