GpuAccessor.cs 9.8 KB

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