CachedGpuAccessor.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. /// Reads data from GPU memory.
  58. /// </summary>
  59. /// <typeparam name="T">Type of the data to be read</typeparam>
  60. /// <param name="address">GPU virtual address of the data</param>
  61. /// <returns>Data at the memory location</returns>
  62. public override T MemoryRead<T>(ulong address)
  63. {
  64. return MemoryMarshal.Cast<byte, T>(_data.Span.Slice((int)address))[0];
  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. /// Gets the texture descriptor for a given texture on the pool.
  125. /// </summary>
  126. /// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param>
  127. /// <param name="cbufSlot">Constant buffer slot for the texture handle</param>
  128. /// <returns>Texture descriptor</returns>
  129. public override Image.ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot)
  130. {
  131. if (!_textureDescriptors.TryGetValue(handle, out GuestTextureDescriptor textureDescriptor))
  132. {
  133. throw new ArgumentException();
  134. }
  135. return textureDescriptor;
  136. }
  137. /// <summary>
  138. /// Queries if host state forces early depth testing.
  139. /// </summary>
  140. /// <returns>True if early depth testing is forced</returns>
  141. public bool QueryEarlyZForce()
  142. {
  143. return (_header.StateFlags & GuestGpuStateFlags.EarlyZForce) != 0;
  144. }
  145. }
  146. }