aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs')
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs126
1 files changed, 83 insertions, 43 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
index 022e3a44..f667d080 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
@@ -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;
+ }
}
} \ No newline at end of file