diff options
Diffstat (limited to 'Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs')
-rw-r--r-- | Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs | 126 |
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 |