Program.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. using OpenTK.Graphics.OpenGL;
  2. using Ryujinx.Common.Logging;
  3. using Ryujinx.Graphics.GAL;
  4. using Ryujinx.Graphics.Shader;
  5. namespace Ryujinx.Graphics.OpenGL
  6. {
  7. class Program : IProgram
  8. {
  9. private const int ShaderStages = 6;
  10. private const int UbStageShift = 5;
  11. private const int SbStageShift = 4;
  12. private const int TexStageShift = 5;
  13. private const int ImgStageShift = 3;
  14. private const int UbsPerStage = 1 << UbStageShift;
  15. private const int SbsPerStage = 1 << SbStageShift;
  16. private const int TexsPerStage = 1 << TexStageShift;
  17. private const int ImgsPerStage = 1 << ImgStageShift;
  18. public int Handle { get; private set; }
  19. public int FragmentRenderScaleUniform { get; }
  20. public int ComputeRenderScaleUniform { get; }
  21. public bool IsLinked { get; private set; }
  22. private int[] _ubBindingPoints;
  23. private int[] _sbBindingPoints;
  24. private int[] _textureUnits;
  25. private int[] _imageUnits;
  26. public Program(IShader[] shaders)
  27. {
  28. _ubBindingPoints = new int[UbsPerStage * ShaderStages];
  29. _sbBindingPoints = new int[SbsPerStage * ShaderStages];
  30. _textureUnits = new int[TexsPerStage * ShaderStages];
  31. _imageUnits = new int[ImgsPerStage * ShaderStages];
  32. for (int index = 0; index < _ubBindingPoints.Length; index++)
  33. {
  34. _ubBindingPoints[index] = -1;
  35. }
  36. for (int index = 0; index < _sbBindingPoints.Length; index++)
  37. {
  38. _sbBindingPoints[index] = -1;
  39. }
  40. for (int index = 0; index < _textureUnits.Length; index++)
  41. {
  42. _textureUnits[index] = -1;
  43. }
  44. for (int index = 0; index < _imageUnits.Length; index++)
  45. {
  46. _imageUnits[index] = -1;
  47. }
  48. Handle = GL.CreateProgram();
  49. for (int index = 0; index < shaders.Length; index++)
  50. {
  51. int shaderHandle = ((Shader)shaders[index]).Handle;
  52. GL.AttachShader(Handle, shaderHandle);
  53. }
  54. GL.LinkProgram(Handle);
  55. for (int index = 0; index < shaders.Length; index++)
  56. {
  57. int shaderHandle = ((Shader)shaders[index]).Handle;
  58. GL.DetachShader(Handle, shaderHandle);
  59. }
  60. CheckProgramLink();
  61. Bind();
  62. int ubBindingPoint = 0;
  63. int sbBindingPoint = 0;
  64. int textureUnit = 0;
  65. int imageUnit = 0;
  66. for (int index = 0; index < shaders.Length; index++)
  67. {
  68. Shader shader = (Shader)shaders[index];
  69. foreach (BufferDescriptor descriptor in shader.Info.CBuffers)
  70. {
  71. int location = GL.GetUniformBlockIndex(Handle, descriptor.Name);
  72. if (location < 0)
  73. {
  74. continue;
  75. }
  76. GL.UniformBlockBinding(Handle, location, ubBindingPoint);
  77. int bpIndex = (int)shader.Stage << UbStageShift | descriptor.Slot;
  78. _ubBindingPoints[bpIndex] = ubBindingPoint;
  79. ubBindingPoint++;
  80. }
  81. foreach (BufferDescriptor descriptor in shader.Info.SBuffers)
  82. {
  83. int location = GL.GetProgramResourceIndex(Handle, ProgramInterface.ShaderStorageBlock, descriptor.Name);
  84. if (location < 0)
  85. {
  86. continue;
  87. }
  88. GL.ShaderStorageBlockBinding(Handle, location, sbBindingPoint);
  89. int bpIndex = (int)shader.Stage << SbStageShift | descriptor.Slot;
  90. _sbBindingPoints[bpIndex] = sbBindingPoint;
  91. sbBindingPoint++;
  92. }
  93. int samplerIndex = 0;
  94. foreach (TextureDescriptor descriptor in shader.Info.Textures)
  95. {
  96. int location = GL.GetUniformLocation(Handle, descriptor.Name);
  97. if (location < 0)
  98. {
  99. continue;
  100. }
  101. GL.Uniform1(location, textureUnit);
  102. int uIndex = (int)shader.Stage << TexStageShift | samplerIndex++;
  103. _textureUnits[uIndex] = textureUnit;
  104. textureUnit++;
  105. }
  106. int imageIndex = 0;
  107. foreach (TextureDescriptor descriptor in shader.Info.Images)
  108. {
  109. int location = GL.GetUniformLocation(Handle, descriptor.Name);
  110. if (location < 0)
  111. {
  112. continue;
  113. }
  114. GL.Uniform1(location, imageUnit);
  115. int uIndex = (int)shader.Stage << ImgStageShift | imageIndex++;
  116. _imageUnits[uIndex] = imageUnit;
  117. imageUnit++;
  118. }
  119. }
  120. FragmentRenderScaleUniform = GL.GetUniformLocation(Handle, "fp_renderScale");
  121. ComputeRenderScaleUniform = GL.GetUniformLocation(Handle, "cp_renderScale");
  122. }
  123. public void Bind()
  124. {
  125. GL.UseProgram(Handle);
  126. }
  127. public int GetUniformBufferBindingPoint(ShaderStage stage, int index)
  128. {
  129. return _ubBindingPoints[(int)stage << UbStageShift | index];
  130. }
  131. public int GetStorageBufferBindingPoint(ShaderStage stage, int index)
  132. {
  133. return _sbBindingPoints[(int)stage << SbStageShift | index];
  134. }
  135. public int GetTextureUnit(ShaderStage stage, int index)
  136. {
  137. return _textureUnits[(int)stage << TexStageShift | index];
  138. }
  139. public int GetImageUnit(ShaderStage stage, int index)
  140. {
  141. return _imageUnits[(int)stage << ImgStageShift | index];
  142. }
  143. private void CheckProgramLink()
  144. {
  145. GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out int status);
  146. if (status == 0)
  147. {
  148. // Use GL.GetProgramInfoLog(Handle), it may be too long to print on the log.
  149. Logger.PrintDebug(LogClass.Gpu, "Shader linking failed.");
  150. }
  151. else
  152. {
  153. IsLinked = true;
  154. }
  155. }
  156. public void Dispose()
  157. {
  158. if (Handle != 0)
  159. {
  160. GL.DeleteProgram(Handle);
  161. Handle = 0;
  162. }
  163. }
  164. }
  165. }