CachedGpuAccessor.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. using Ryujinx.Common.Logging;
  2. using Ryujinx.Graphics.Gpu.Shader.Cache.Definition;
  3. using Ryujinx.Graphics.Shader;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Runtime.InteropServices;
  7. namespace Ryujinx.Graphics.Gpu.Shader
  8. {
  9. class CachedGpuAccessor : TextureDescriptorCapableGpuAccessor, IGpuAccessor
  10. {
  11. private readonly ReadOnlyMemory<byte> _data;
  12. private readonly ReadOnlyMemory<byte> _cb1Data;
  13. private readonly GuestGpuAccessorHeader _header;
  14. private readonly Dictionary<int, GuestTextureDescriptor> _textureDescriptors;
  15. /// <summary>
  16. /// Creates a new instance of the cached GPU state accessor for shader translation.
  17. /// </summary>
  18. /// <param name="context">GPU context</param>
  19. /// <param name="data">The data of the shader</param>
  20. /// <param name="cb1Data">The constant buffer 1 data of the shader</param>
  21. /// <param name="header">The cache of the GPU accessor</param>
  22. /// <param name="guestTextureDescriptors">The cache of the texture descriptors</param>
  23. public CachedGpuAccessor(
  24. GpuContext context,
  25. ReadOnlyMemory<byte> data,
  26. ReadOnlyMemory<byte> cb1Data,
  27. GuestGpuAccessorHeader header,
  28. IReadOnlyDictionary<int, GuestTextureDescriptor> guestTextureDescriptors) : base(context)
  29. {
  30. _data = data;
  31. _cb1Data = cb1Data;
  32. _header = header;
  33. _textureDescriptors = new Dictionary<int, GuestTextureDescriptor>();
  34. foreach (KeyValuePair<int, GuestTextureDescriptor> guestTextureDescriptor in guestTextureDescriptors)
  35. {
  36. _textureDescriptors.Add(guestTextureDescriptor.Key, guestTextureDescriptor.Value);
  37. }
  38. }
  39. /// <summary>
  40. /// Reads data from the constant buffer 1.
  41. /// </summary>
  42. /// <param name="offset">Offset in bytes to read from</param>
  43. /// <returns>Value at the given offset</returns>
  44. public uint ConstantBuffer1Read(int offset)
  45. {
  46. return MemoryMarshal.Cast<byte, uint>(_cb1Data.Span.Slice(offset))[0];
  47. }
  48. /// <summary>
  49. /// Prints a log message.
  50. /// </summary>
  51. /// <param name="message">Message to print</param>
  52. public void Log(string message)
  53. {
  54. Logger.Warning?.Print(LogClass.Gpu, $"Shader translator: {message}");
  55. }
  56. /// <summary>
  57. /// Gets a span of the specified memory location, containing shader code.
  58. /// </summary>
  59. /// <param name="address">GPU virtual address of the data</param>
  60. /// <param name="minimumSize">Minimum size that the returned span may have</param>
  61. /// <returns>Span of the memory location</returns>
  62. public override ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
  63. {
  64. return MemoryMarshal.Cast<byte, ulong>(_data.Span.Slice((int)address));
  65. }
  66. /// <summary>
  67. /// Checks if a given memory address is mapped.
  68. /// </summary>
  69. /// <param name="address">GPU virtual address to be checked</param>
  70. /// <returns>True if the address is mapped, false otherwise</returns>
  71. public bool MemoryMapped(ulong address)
  72. {
  73. return address < (ulong)_data.Length;
  74. }
  75. /// <summary>
  76. /// Queries Local Size X for compute shaders.
  77. /// </summary>
  78. /// <returns>Local Size X</returns>
  79. public int QueryComputeLocalSizeX()
  80. {
  81. return _header.ComputeLocalSizeX;
  82. }
  83. /// <summary>
  84. /// Queries Local Size Y for compute shaders.
  85. /// </summary>
  86. /// <returns>Local Size Y</returns>
  87. public int QueryComputeLocalSizeY()
  88. {
  89. return _header.ComputeLocalSizeY;
  90. }
  91. /// <summary>
  92. /// Queries Local Size Z for compute shaders.
  93. /// </summary>
  94. /// <returns>Local Size Z</returns>
  95. public int QueryComputeLocalSizeZ()
  96. {
  97. return _header.ComputeLocalSizeZ;
  98. }
  99. /// <summary>
  100. /// Queries Local Memory size in bytes for compute shaders.
  101. /// </summary>
  102. /// <returns>Local Memory size in bytes</returns>
  103. public int QueryComputeLocalMemorySize()
  104. {
  105. return _header.ComputeLocalMemorySize;
  106. }
  107. /// <summary>
  108. /// Queries Shared Memory size in bytes for compute shaders.
  109. /// </summary>
  110. /// <returns>Shared Memory size in bytes</returns>
  111. public int QueryComputeSharedMemorySize()
  112. {
  113. return _header.ComputeSharedMemorySize;
  114. }
  115. /// <summary>
  116. /// Queries current primitive topology for geometry shaders.
  117. /// </summary>
  118. /// <returns>Current primitive topology</returns>
  119. public InputTopology QueryPrimitiveTopology()
  120. {
  121. return _header.PrimitiveTopology;
  122. }
  123. /// <summary>
  124. /// Queries the tessellation evaluation shader primitive winding order.
  125. /// </summary>
  126. /// <returns>True if the primitive winding order is clockwise, false if counter-clockwise</returns>
  127. public bool QueryTessCw()
  128. {
  129. return (_header.TessellationModePacked & 0x10) != 0;
  130. }
  131. /// <summary>
  132. /// Queries the tessellation evaluation shader abstract patch type.
  133. /// </summary>
  134. /// <returns>Abstract patch type</returns>
  135. public TessPatchType QueryTessPatchType()
  136. {
  137. return (TessPatchType)(_header.TessellationModePacked & 3);
  138. }
  139. /// <summary>
  140. /// Queries the tessellation evaluation shader spacing between tessellated vertices of the patch.
  141. /// </summary>
  142. /// <returns>Spacing between tessellated vertices of the patch</returns>
  143. public TessSpacing QueryTessSpacing()
  144. {
  145. return (TessSpacing)((_header.TessellationModePacked >> 2) & 3);
  146. }
  147. /// <summary>
  148. /// Gets the texture descriptor for a given texture on the pool.
  149. /// </summary>
  150. /// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param>
  151. /// <param name="cbufSlot">Constant buffer slot for the texture handle</param>
  152. /// <returns>Texture descriptor</returns>
  153. public override Image.ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot)
  154. {
  155. if (!_textureDescriptors.TryGetValue(handle, out GuestTextureDescriptor textureDescriptor))
  156. {
  157. throw new ArgumentException();
  158. }
  159. return textureDescriptor;
  160. }
  161. /// <summary>
  162. /// Queries if host state forces early depth testing.
  163. /// </summary>
  164. /// <returns>True if early depth testing is forced</returns>
  165. public bool QueryEarlyZForce()
  166. {
  167. return (_header.StateFlags & GuestGpuStateFlags.EarlyZForce) != 0;
  168. }
  169. }
  170. }