Program.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. using Ryujinx.Graphics.GAL;
  2. using Ryujinx.Graphics.Shader;
  3. using OpenTK.Graphics.OpenGL;
  4. namespace Ryujinx.Graphics.OpenGL
  5. {
  6. class Program : IProgram
  7. {
  8. private const int StageShift = 5;
  9. private const int SbStageShift = 4;
  10. public int Handle { get; private set; }
  11. public bool IsLinked { get; private set; }
  12. private int[] _ubBindingPoints;
  13. private int[] _sbBindingPoints;
  14. private int[] _textureUnits;
  15. public Program(IShader[] shaders)
  16. {
  17. _ubBindingPoints = new int[32 * 6];
  18. _sbBindingPoints = new int[16 * 6];
  19. _textureUnits = new int[32 * 6];
  20. for (int index = 0; index < _ubBindingPoints.Length; index++)
  21. {
  22. _ubBindingPoints[index] = -1;
  23. }
  24. for (int index = 0; index < _sbBindingPoints.Length; index++)
  25. {
  26. _sbBindingPoints[index] = -1;
  27. }
  28. for (int index = 0; index < _textureUnits.Length; index++)
  29. {
  30. _textureUnits[index] = -1;
  31. }
  32. Handle = GL.CreateProgram();
  33. for (int index = 0; index < shaders.Length; index++)
  34. {
  35. int shaderHandle = ((Shader)shaders[index]).Handle;
  36. GL.AttachShader(Handle, shaderHandle);
  37. }
  38. GL.LinkProgram(Handle);
  39. CheckProgramLink();
  40. Bind();
  41. int extraBlockindex = GL.GetUniformBlockIndex(Handle, "Extra");
  42. if (extraBlockindex >= 0)
  43. {
  44. GL.UniformBlockBinding(Handle, extraBlockindex, 0);
  45. }
  46. int ubBindingPoint = 1;
  47. int sbBindingPoint = 0;
  48. int textureUnit = 0;
  49. for (int index = 0; index < shaders.Length; index++)
  50. {
  51. Shader shader = (Shader)shaders[index];
  52. foreach (BufferDescriptor descriptor in shader.Info.CBuffers)
  53. {
  54. int location = GL.GetUniformBlockIndex(Handle, descriptor.Name);
  55. if (location < 0)
  56. {
  57. continue;
  58. }
  59. GL.UniformBlockBinding(Handle, location, ubBindingPoint);
  60. int bpIndex = (int)shader.Stage << StageShift | descriptor.Slot;
  61. _ubBindingPoints[bpIndex] = ubBindingPoint;
  62. ubBindingPoint++;
  63. }
  64. foreach (BufferDescriptor descriptor in shader.Info.SBuffers)
  65. {
  66. int location = GL.GetProgramResourceIndex(Handle, ProgramInterface.ShaderStorageBlock, descriptor.Name);
  67. if (location < 0)
  68. {
  69. continue;
  70. }
  71. GL.ShaderStorageBlockBinding(Handle, location, sbBindingPoint);
  72. int bpIndex = (int)shader.Stage << SbStageShift | descriptor.Slot;
  73. _sbBindingPoints[bpIndex] = sbBindingPoint;
  74. sbBindingPoint++;
  75. }
  76. int samplerIndex = 0;
  77. foreach (TextureDescriptor descriptor in shader.Info.Textures)
  78. {
  79. int location = GL.GetUniformLocation(Handle, descriptor.Name);
  80. if (location < 0)
  81. {
  82. continue;
  83. }
  84. GL.Uniform1(location, textureUnit);
  85. int uIndex = (int)shader.Stage << StageShift | samplerIndex++;
  86. _textureUnits[uIndex] = textureUnit;
  87. textureUnit++;
  88. }
  89. }
  90. }
  91. public void Bind()
  92. {
  93. GL.UseProgram(Handle);
  94. }
  95. public int GetUniformBufferBindingPoint(ShaderStage stage, int index)
  96. {
  97. return _ubBindingPoints[(int)stage << StageShift | index];
  98. }
  99. public int GetStorageBufferBindingPoint(ShaderStage stage, int index)
  100. {
  101. return _sbBindingPoints[(int)stage << SbStageShift | index];
  102. }
  103. public int GetTextureUnit(ShaderStage stage, int index)
  104. {
  105. return _textureUnits[(int)stage << StageShift | index];
  106. }
  107. private void CheckProgramLink()
  108. {
  109. int status = 0;
  110. GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out status);
  111. if (status == 0)
  112. {
  113. // throw new System.Exception(GL.GetProgramInfoLog(Handle));
  114. }
  115. else
  116. {
  117. IsLinked = true;
  118. }
  119. }
  120. public void Dispose()
  121. {
  122. if (Handle != 0)
  123. {
  124. GL.DeleteProgram(Handle);
  125. Handle = 0;
  126. }
  127. }
  128. }
  129. }