GpuAccessor.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. using Ryujinx.Common.Logging;
  2. using Ryujinx.Graphics.GAL;
  3. using Ryujinx.Graphics.Gpu.State;
  4. using Ryujinx.Graphics.Shader;
  5. namespace Ryujinx.Graphics.Gpu.Shader
  6. {
  7. /// <summary>
  8. /// Represents a GPU state and memory accessor.
  9. /// </summary>
  10. class GpuAccessor : TextureDescriptorCapableGpuAccessor, IGpuAccessor
  11. {
  12. private readonly GpuContext _context;
  13. private readonly GpuState _state;
  14. private readonly int _stageIndex;
  15. private readonly bool _compute;
  16. private readonly int _localSizeX;
  17. private readonly int _localSizeY;
  18. private readonly int _localSizeZ;
  19. private readonly int _localMemorySize;
  20. private readonly int _sharedMemorySize;
  21. /// <summary>
  22. /// Creates a new instance of the GPU state accessor for graphics shader translation.
  23. /// </summary>
  24. /// <param name="context">GPU context</param>
  25. /// <param name="state">Current GPU state</param>
  26. /// <param name="stageIndex">Graphics shader stage index (0 = Vertex, 4 = Fragment)</param>
  27. public GpuAccessor(GpuContext context, GpuState state, int stageIndex)
  28. {
  29. _context = context;
  30. _state = state;
  31. _stageIndex = stageIndex;
  32. }
  33. /// <summary>
  34. /// Creates a new instance of the GPU state accessor for compute shader translation.
  35. /// </summary>
  36. /// <param name="context">GPU context</param>
  37. /// <param name="state">Current GPU state</param>
  38. /// <param name="localSizeX">Local group size X of the compute shader</param>
  39. /// <param name="localSizeY">Local group size Y of the compute shader</param>
  40. /// <param name="localSizeZ">Local group size Z of the compute shader</param>
  41. /// <param name="localMemorySize">Local memory size of the compute shader</param>
  42. /// <param name="sharedMemorySize">Shared memory size of the compute shader</param>
  43. public GpuAccessor(
  44. GpuContext context,
  45. GpuState state,
  46. int localSizeX,
  47. int localSizeY,
  48. int localSizeZ,
  49. int localMemorySize,
  50. int sharedMemorySize)
  51. {
  52. _context = context;
  53. _state = state;
  54. _compute = true;
  55. _localSizeX = localSizeX;
  56. _localSizeY = localSizeY;
  57. _localSizeZ = localSizeZ;
  58. _localMemorySize = localMemorySize;
  59. _sharedMemorySize = sharedMemorySize;
  60. }
  61. /// <summary>
  62. /// Prints a log message.
  63. /// </summary>
  64. /// <param name="message">Message to print</param>
  65. public void Log(string message)
  66. {
  67. Logger.Warning?.Print(LogClass.Gpu, $"Shader translator: {message}");
  68. }
  69. /// <summary>
  70. /// Reads data from GPU memory.
  71. /// </summary>
  72. /// <typeparam name="T">Type of the data to be read</typeparam>
  73. /// <param name="address">GPU virtual address of the data</param>
  74. /// <returns>Data at the memory location</returns>
  75. public override T MemoryRead<T>(ulong address)
  76. {
  77. return _context.MemoryManager.Read<T>(address);
  78. }
  79. /// <summary>
  80. /// Checks if a given memory address is mapped.
  81. /// </summary>
  82. /// <param name="address">GPU virtual address to be checked</param>
  83. /// <returns>True if the address is mapped, false otherwise</returns>
  84. public bool MemoryMapped(ulong address)
  85. {
  86. return _context.MemoryManager.IsMapped(address);
  87. }
  88. /// <summary>
  89. /// Queries Local Size X for compute shaders.
  90. /// </summary>
  91. /// <returns>Local Size X</returns>
  92. public int QueryComputeLocalSizeX() => _localSizeX;
  93. /// <summary>
  94. /// Queries Local Size Y for compute shaders.
  95. /// </summary>
  96. /// <returns>Local Size Y</returns>
  97. public int QueryComputeLocalSizeY() => _localSizeY;
  98. /// <summary>
  99. /// Queries Local Size Z for compute shaders.
  100. /// </summary>
  101. /// <returns>Local Size Z</returns>
  102. public int QueryComputeLocalSizeZ() => _localSizeZ;
  103. /// <summary>
  104. /// Queries Local Memory size in bytes for compute shaders.
  105. /// </summary>
  106. /// <returns>Local Memory size in bytes</returns>
  107. public int QueryComputeLocalMemorySize() => _localMemorySize;
  108. /// <summary>
  109. /// Queries Shared Memory size in bytes for compute shaders.
  110. /// </summary>
  111. /// <returns>Shared Memory size in bytes</returns>
  112. public int QueryComputeSharedMemorySize() => _sharedMemorySize;
  113. /// <summary>
  114. /// Queries Constant Buffer usage information.
  115. /// </summary>
  116. /// <returns>A mask where each bit set indicates a bound constant buffer</returns>
  117. public uint QueryConstantBufferUse()
  118. {
  119. return _compute
  120. ? _context.Methods.BufferManager.GetComputeUniformBufferUseMask()
  121. : _context.Methods.BufferManager.GetGraphicsUniformBufferUseMask(_stageIndex);
  122. }
  123. /// <summary>
  124. /// Queries current primitive topology for geometry shaders.
  125. /// </summary>
  126. /// <returns>Current primitive topology</returns>
  127. public InputTopology QueryPrimitiveTopology()
  128. {
  129. switch (_context.Methods.Topology)
  130. {
  131. case PrimitiveTopology.Points:
  132. return InputTopology.Points;
  133. case PrimitiveTopology.Lines:
  134. case PrimitiveTopology.LineLoop:
  135. case PrimitiveTopology.LineStrip:
  136. return InputTopology.Lines;
  137. case PrimitiveTopology.LinesAdjacency:
  138. case PrimitiveTopology.LineStripAdjacency:
  139. return InputTopology.LinesAdjacency;
  140. case PrimitiveTopology.Triangles:
  141. case PrimitiveTopology.TriangleStrip:
  142. case PrimitiveTopology.TriangleFan:
  143. return InputTopology.Triangles;
  144. case PrimitiveTopology.TrianglesAdjacency:
  145. case PrimitiveTopology.TriangleStripAdjacency:
  146. return InputTopology.TrianglesAdjacency;
  147. }
  148. return InputTopology.Points;
  149. }
  150. /// <summary>
  151. /// Queries host storage buffer alignment required.
  152. /// </summary>
  153. /// <returns>Host storage buffer alignment in bytes</returns>
  154. public int QueryStorageBufferOffsetAlignment() => _context.Capabilities.StorageBufferOffsetAlignment;
  155. /// <summary>
  156. /// Queries host support for readable images without a explicit format declaration on the shader.
  157. /// </summary>
  158. /// <returns>True if formatted image load is supported, false otherwise</returns>
  159. public bool QuerySupportsImageLoadFormatted() => _context.Capabilities.SupportsImageLoadFormatted;
  160. /// <summary>
  161. /// Queries host GPU non-constant texture offset support.
  162. /// </summary>
  163. /// <returns>True if the GPU and driver supports non-constant texture offsets, false otherwise</returns>
  164. public bool QuerySupportsNonConstantTextureOffset() => _context.Capabilities.SupportsNonConstantTextureOffset;
  165. /// <summary>
  166. /// Gets the texture descriptor for a given texture on the pool.
  167. /// </summary>
  168. /// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param>
  169. /// <returns>Texture descriptor</returns>
  170. public override Image.ITextureDescriptor GetTextureDescriptor(int handle)
  171. {
  172. if (_compute)
  173. {
  174. return _context.Methods.TextureManager.GetComputeTextureDescriptor(_state, handle);
  175. }
  176. else
  177. {
  178. return _context.Methods.TextureManager.GetGraphicsTextureDescriptor(_state, _stageIndex, handle);
  179. }
  180. }
  181. /// <summary>
  182. /// Queries if host state forces early depth testing.
  183. /// </summary>
  184. /// <returns>True if early depth testing is forced</returns>
  185. public bool QueryEarlyZForce()
  186. {
  187. return _state.Get<bool>(MethodOffset.EarlyZForce);
  188. }
  189. }
  190. }