Declarations.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. using Ryujinx.Graphics.Gal;
  2. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  3. using Ryujinx.Graphics.Shader.StructuredIr;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
  8. {
  9. static class Declarations
  10. {
  11. public static void Declare(CodeGenContext context, StructuredProgramInfo info)
  12. {
  13. context.AppendLine("#version 420 core");
  14. context.AppendLine();
  15. context.AppendLine($"const int {DefaultNames.UndefinedName} = 0;");
  16. context.AppendLine();
  17. if (context.Config.Type == GalShaderType.Geometry)
  18. {
  19. context.AppendLine("layout (points) in;");
  20. context.AppendLine("layout (triangle_strip, max_vertices = 4) out;");
  21. context.AppendLine();
  22. }
  23. context.AppendLine("layout (std140) uniform Extra");
  24. context.EnterScope();
  25. context.AppendLine("vec2 flip;");
  26. context.AppendLine("int instance;");
  27. context.LeaveScope(";");
  28. context.AppendLine();
  29. if (info.CBuffers.Count != 0)
  30. {
  31. DeclareUniforms(context, info);
  32. context.AppendLine();
  33. }
  34. if (info.Samplers.Count != 0)
  35. {
  36. DeclareSamplers(context, info);
  37. context.AppendLine();
  38. }
  39. if (info.IAttributes.Count != 0)
  40. {
  41. DeclareInputAttributes(context, info);
  42. context.AppendLine();
  43. }
  44. if (info.OAttributes.Count != 0)
  45. {
  46. DeclareOutputAttributes(context, info);
  47. context.AppendLine();
  48. }
  49. }
  50. public static void DeclareLocals(CodeGenContext context, StructuredProgramInfo info)
  51. {
  52. foreach (AstOperand decl in info.Locals)
  53. {
  54. string name = context.OperandManager.DeclareLocal(decl);
  55. context.AppendLine(GetVarTypeName(decl.VarType) + " " + name + ";");
  56. }
  57. }
  58. private static string GetVarTypeName(VariableType type)
  59. {
  60. switch (type)
  61. {
  62. case VariableType.Bool: return "bool";
  63. case VariableType.F32: return "float";
  64. case VariableType.S32: return "int";
  65. case VariableType.U32: return "uint";
  66. }
  67. throw new ArgumentException($"Invalid variable type \"{type}\".");
  68. }
  69. private static void DeclareUniforms(CodeGenContext context, StructuredProgramInfo info)
  70. {
  71. foreach (int cbufSlot in info.CBuffers.OrderBy(x => x))
  72. {
  73. string ubName = OperandManager.GetShaderStagePrefix(context.Config.Type);
  74. ubName += "_" + DefaultNames.UniformNamePrefix + cbufSlot;
  75. context.CBufferDescriptors.Add(new CBufferDescriptor(ubName, cbufSlot));
  76. context.AppendLine("layout (std140) uniform " + ubName);
  77. context.EnterScope();
  78. string ubSize = "[" + NumberFormatter.FormatInt(context.Config.MaxCBufferSize / 16) + "]";
  79. context.AppendLine("vec4 " + OperandManager.GetUbName(context.Config.Type, cbufSlot) + ubSize + ";");
  80. context.LeaveScope(";");
  81. }
  82. }
  83. private static void DeclareSamplers(CodeGenContext context, StructuredProgramInfo info)
  84. {
  85. Dictionary<string, AstTextureOperation> samplers = new Dictionary<string, AstTextureOperation>();
  86. foreach (AstTextureOperation texOp in info.Samplers.OrderBy(x => x.Handle))
  87. {
  88. string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp);
  89. if (!samplers.TryAdd(samplerName, texOp))
  90. {
  91. continue;
  92. }
  93. string samplerTypeName = GetSamplerTypeName(texOp.Type);
  94. context.AppendLine("uniform " + samplerTypeName + " " + samplerName + ";");
  95. }
  96. foreach (KeyValuePair<string, AstTextureOperation> kv in samplers)
  97. {
  98. string samplerName = kv.Key;
  99. AstTextureOperation texOp = kv.Value;
  100. TextureDescriptor desc;
  101. if ((texOp.Flags & TextureFlags.Bindless) != 0)
  102. {
  103. AstOperand operand = texOp.GetSource(0) as AstOperand;
  104. desc = new TextureDescriptor(samplerName, operand.CbufSlot, operand.CbufOffset);
  105. }
  106. else
  107. {
  108. desc = new TextureDescriptor(samplerName, texOp.Handle);
  109. }
  110. context.TextureDescriptors.Add(desc);
  111. }
  112. }
  113. private static void DeclareInputAttributes(CodeGenContext context, StructuredProgramInfo info)
  114. {
  115. string suffix = context.Config.Type == GalShaderType.Geometry ? "[]" : string.Empty;
  116. foreach (int attr in info.IAttributes.OrderBy(x => x))
  117. {
  118. context.AppendLine($"layout (location = {attr}) in vec4 {DefaultNames.IAttributePrefix}{attr}{suffix};");
  119. }
  120. }
  121. private static void DeclareOutputAttributes(CodeGenContext context, StructuredProgramInfo info)
  122. {
  123. foreach (int attr in info.OAttributes.OrderBy(x => x))
  124. {
  125. context.AppendLine($"layout (location = {attr}) out vec4 {DefaultNames.OAttributePrefix}{attr};");
  126. }
  127. }
  128. private static string GetSamplerTypeName(TextureType type)
  129. {
  130. string typeName;
  131. switch (type & TextureType.Mask)
  132. {
  133. case TextureType.Texture1D: typeName = "sampler1D"; break;
  134. case TextureType.Texture2D: typeName = "sampler2D"; break;
  135. case TextureType.Texture3D: typeName = "sampler3D"; break;
  136. case TextureType.TextureCube: typeName = "samplerCube"; break;
  137. default: throw new ArgumentException($"Invalid sampler type \"{type}\".");
  138. }
  139. if ((type & TextureType.Multisample) != 0)
  140. {
  141. typeName += "MS";
  142. }
  143. if ((type & TextureType.Array) != 0)
  144. {
  145. typeName += "Array";
  146. }
  147. if ((type & TextureType.Shadow) != 0)
  148. {
  149. typeName += "Shadow";
  150. }
  151. return typeName;
  152. }
  153. }
  154. }