IoMap.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  2. using Ryujinx.Graphics.Shader.Translation;
  3. using System.Globalization;
  4. namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
  5. {
  6. static class IoMap
  7. {
  8. public static (string, AggregateType) GetGlslVariable(
  9. ShaderConfig config,
  10. IoVariable ioVariable,
  11. int location,
  12. int component,
  13. bool isOutput,
  14. bool isPerPatch)
  15. {
  16. return ioVariable switch
  17. {
  18. IoVariable.BackColorDiffuse => ("gl_BackColor", AggregateType.Vector4 | AggregateType.FP32), // Deprecated.
  19. IoVariable.BackColorSpecular => ("gl_BackSecondaryColor", AggregateType.Vector4 | AggregateType.FP32), // Deprecated.
  20. IoVariable.BaseInstance => ("gl_BaseInstanceARB", AggregateType.S32),
  21. IoVariable.BaseVertex => ("gl_BaseVertexARB", AggregateType.S32),
  22. IoVariable.ClipDistance => ("gl_ClipDistance", AggregateType.Array | AggregateType.FP32),
  23. IoVariable.CtaId => ("gl_WorkGroupID", AggregateType.Vector3 | AggregateType.U32),
  24. IoVariable.DrawIndex => ("gl_DrawIDARB", AggregateType.S32),
  25. IoVariable.FogCoord => ("gl_FogFragCoord", AggregateType.FP32), // Deprecated.
  26. IoVariable.FragmentCoord => ("gl_FragCoord", AggregateType.Vector4 | AggregateType.FP32),
  27. IoVariable.FragmentOutputColor => GetFragmentOutputColorVariableName(config, location),
  28. IoVariable.FragmentOutputDepth => ("gl_FragDepth", AggregateType.FP32),
  29. IoVariable.FragmentOutputIsBgra => (DefaultNames.SupportBlockIsBgraName, AggregateType.Array | AggregateType.Bool),
  30. IoVariable.FrontColorDiffuse => ("gl_FrontColor", AggregateType.Vector4 | AggregateType.FP32), // Deprecated.
  31. IoVariable.FrontColorSpecular => ("gl_FrontSecondaryColor", AggregateType.Vector4 | AggregateType.FP32), // Deprecated.
  32. IoVariable.FrontFacing => ("gl_FrontFacing", AggregateType.Bool),
  33. IoVariable.InstanceId => ("gl_InstanceID", AggregateType.S32),
  34. IoVariable.InstanceIndex => ("gl_InstanceIndex", AggregateType.S32),
  35. IoVariable.InvocationId => ("gl_InvocationID", AggregateType.S32),
  36. IoVariable.Layer => ("gl_Layer", AggregateType.S32),
  37. IoVariable.PatchVertices => ("gl_PatchVerticesIn", AggregateType.S32),
  38. IoVariable.PointCoord => ("gl_PointCoord", AggregateType.Vector2 | AggregateType.FP32),
  39. IoVariable.PointSize => ("gl_PointSize", AggregateType.FP32),
  40. IoVariable.Position => ("gl_Position", AggregateType.Vector4 | AggregateType.FP32),
  41. IoVariable.PrimitiveId => GetPrimitiveIdVariableName(config.Stage, isOutput),
  42. IoVariable.SubgroupEqMask => GetSubgroupMaskVariableName(config, "Eq"),
  43. IoVariable.SubgroupGeMask => GetSubgroupMaskVariableName(config, "Ge"),
  44. IoVariable.SubgroupGtMask => GetSubgroupMaskVariableName(config, "Gt"),
  45. IoVariable.SubgroupLaneId => GetSubgroupInvocationIdVariableName(config),
  46. IoVariable.SubgroupLeMask => GetSubgroupMaskVariableName(config, "Le"),
  47. IoVariable.SubgroupLtMask => GetSubgroupMaskVariableName(config, "Lt"),
  48. IoVariable.SupportBlockRenderScale => (DefaultNames.SupportBlockRenderScaleName, AggregateType.Array | AggregateType.FP32),
  49. IoVariable.SupportBlockViewInverse => (DefaultNames.SupportBlockViewportInverse, AggregateType.Vector2 | AggregateType.FP32),
  50. IoVariable.TessellationCoord => ("gl_TessCoord", AggregateType.Vector3 | AggregateType.FP32),
  51. IoVariable.TessellationLevelInner => ("gl_TessLevelInner", AggregateType.Array | AggregateType.FP32),
  52. IoVariable.TessellationLevelOuter => ("gl_TessLevelOuter", AggregateType.Array | AggregateType.FP32),
  53. IoVariable.TextureCoord => ("gl_TexCoord", AggregateType.Array | AggregateType.Vector4 | AggregateType.FP32), // Deprecated.
  54. IoVariable.ThreadId => ("gl_LocalInvocationID", AggregateType.Vector3 | AggregateType.U32),
  55. IoVariable.ThreadKill => ("gl_HelperInvocation", AggregateType.Bool),
  56. IoVariable.UserDefined => GetUserDefinedVariableName(config, location, component, isOutput, isPerPatch),
  57. IoVariable.VertexId => ("gl_VertexID", AggregateType.S32),
  58. IoVariable.VertexIndex => ("gl_VertexIndex", AggregateType.S32),
  59. IoVariable.ViewportIndex => ("gl_ViewportIndex", AggregateType.S32),
  60. IoVariable.ViewportMask => ("gl_ViewportMask", AggregateType.Array | AggregateType.S32),
  61. _ => (null, AggregateType.Invalid)
  62. };
  63. }
  64. public static bool IsPerVertexBuiltIn(ShaderStage stage, IoVariable ioVariable, bool isOutput)
  65. {
  66. switch (ioVariable)
  67. {
  68. case IoVariable.Layer:
  69. case IoVariable.ViewportIndex:
  70. case IoVariable.PointSize:
  71. case IoVariable.Position:
  72. case IoVariable.ClipDistance:
  73. case IoVariable.PointCoord:
  74. case IoVariable.ViewportMask:
  75. if (isOutput)
  76. {
  77. return stage == ShaderStage.TessellationControl;
  78. }
  79. else
  80. {
  81. return stage == ShaderStage.TessellationControl ||
  82. stage == ShaderStage.TessellationEvaluation ||
  83. stage == ShaderStage.Geometry;
  84. }
  85. }
  86. return false;
  87. }
  88. private static (string, AggregateType) GetFragmentOutputColorVariableName(ShaderConfig config, int location)
  89. {
  90. if (location < 0)
  91. {
  92. return (DefaultNames.OAttributePrefix, config.GetFragmentOutputColorType(0));
  93. }
  94. string name = DefaultNames.OAttributePrefix + location.ToString(CultureInfo.InvariantCulture);
  95. return (name, config.GetFragmentOutputColorType(location));
  96. }
  97. private static (string, AggregateType) GetPrimitiveIdVariableName(ShaderStage stage, bool isOutput)
  98. {
  99. // The geometry stage has an additional gl_PrimitiveIDIn variable.
  100. return (isOutput || stage != ShaderStage.Geometry ? "gl_PrimitiveID" : "gl_PrimitiveIDIn", AggregateType.S32);
  101. }
  102. private static (string, AggregateType) GetSubgroupMaskVariableName(ShaderConfig config, string cc)
  103. {
  104. return config.GpuAccessor.QueryHostSupportsShaderBallot()
  105. ? ($"unpackUint2x32(gl_SubGroup{cc}MaskARB)", AggregateType.Vector2 | AggregateType.U32)
  106. : ($"gl_Subgroup{cc}Mask", AggregateType.Vector4 | AggregateType.U32);
  107. }
  108. private static (string, AggregateType) GetSubgroupInvocationIdVariableName(ShaderConfig config)
  109. {
  110. return config.GpuAccessor.QueryHostSupportsShaderBallot()
  111. ? ("gl_SubGroupInvocationARB", AggregateType.U32)
  112. : ("gl_SubgroupInvocationID", AggregateType.U32);
  113. }
  114. private static (string, AggregateType) GetUserDefinedVariableName(ShaderConfig config, int location, int component, bool isOutput, bool isPerPatch)
  115. {
  116. string name = isPerPatch
  117. ? DefaultNames.PerPatchAttributePrefix
  118. : (isOutput ? DefaultNames.OAttributePrefix : DefaultNames.IAttributePrefix);
  119. if (location < 0)
  120. {
  121. return (name, config.GetUserDefinedType(0, isOutput));
  122. }
  123. name += location.ToString(CultureInfo.InvariantCulture);
  124. if (config.HasPerLocationInputOrOutputComponent(IoVariable.UserDefined, location, component, isOutput))
  125. {
  126. name += "_" + "xyzw"[component & 3];
  127. }
  128. return (name, config.GetUserDefinedType(location, isOutput));
  129. }
  130. }
  131. }