diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs new file mode 100644 index 00000000..5f1458fa --- /dev/null +++ b/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs @@ -0,0 +1,154 @@ +using Ryujinx.Common.Logging; +using Ryujinx.Graphics.Gpu.Shader.Cache.Definition; +using Ryujinx.Graphics.Shader; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Ryujinx.Graphics.Gpu.Shader +{ + class CachedGpuAccessor : TextureDescriptorCapableGpuAccessor, IGpuAccessor + { + private readonly GpuContext _context; + private readonly ReadOnlyMemory<byte> _data; + private readonly GuestGpuAccessorHeader _header; + private readonly Dictionary<int, Image.TextureDescriptor> _textureDescriptors; + + /// <summary> + /// Creates a new instance of the cached GPU state accessor for shader translation. + /// </summary> + /// <param name="context">GPU context</param> + /// <param name="data">The data of the shader</param> + /// <param name="header">The cache of the GPU accessor</param> + /// <param name="guestTextureDescriptors">The cache of the texture descriptors</param> + public CachedGpuAccessor(GpuContext context, ReadOnlyMemory<byte> data, GuestGpuAccessorHeader header, Dictionary<int, GuestTextureDescriptor> guestTextureDescriptors) + { + _context = context; + _data = data; + _header = header; + _textureDescriptors = new Dictionary<int, Image.TextureDescriptor>(); + + foreach (KeyValuePair<int, GuestTextureDescriptor> guestTextureDescriptor in guestTextureDescriptors) + { + _textureDescriptors.Add(guestTextureDescriptor.Key, guestTextureDescriptor.Value.Descriptor); + } + } + + /// <summary> + /// Prints a log message. + /// </summary> + /// <param name="message">Message to print</param> + public void Log(string message) + { + Logger.Warning?.Print(LogClass.Gpu, $"Shader translator: {message}"); + } + + /// <summary> + /// Reads data from GPU memory. + /// </summary> + /// <typeparam name="T">Type of the data to be read</typeparam> + /// <param name="address">GPU virtual address of the data</param> + /// <returns>Data at the memory location</returns> + public override T MemoryRead<T>(ulong address) + { + return MemoryMarshal.Cast<byte, T>(_data.Span.Slice((int)address))[0]; + } + + /// <summary> + /// Checks if a given memory address is mapped. + /// </summary> + /// <param name="address">GPU virtual address to be checked</param> + /// <returns>True if the address is mapped, false otherwise</returns> + public bool MemoryMapped(ulong address) + { + return address < (ulong)_data.Length; + } + + /// <summary> + /// Queries Local Size X for compute shaders. + /// </summary> + /// <returns>Local Size X</returns> + public int QueryComputeLocalSizeX() + { + return _header.ComputeLocalSizeX; + } + + /// <summary> + /// Queries Local Size Y for compute shaders. + /// </summary> + /// <returns>Local Size Y</returns> + public int QueryComputeLocalSizeY() + { + return _header.ComputeLocalSizeY; + } + + /// <summary> + /// Queries Local Size Z for compute shaders. + /// </summary> + /// <returns>Local Size Z</returns> + public int QueryComputeLocalSizeZ() + { + return _header.ComputeLocalSizeZ; + } + + /// <summary> + /// Queries Local Memory size in bytes for compute shaders. + /// </summary> + /// <returns>Local Memory size in bytes</returns> + public int QueryComputeLocalMemorySize() + { + return _header.ComputeLocalMemorySize; + } + + /// <summary> + /// Queries Shared Memory size in bytes for compute shaders. + /// </summary> + /// <returns>Shared Memory size in bytes</returns> + public int QueryComputeSharedMemorySize() + { + return _header.ComputeSharedMemorySize; + } + + /// <summary> + /// Queries current primitive topology for geometry shaders. + /// </summary> + /// <returns>Current primitive topology</returns> + public InputTopology QueryPrimitiveTopology() + { + return _header.PrimitiveTopology; + } + + /// <summary> + /// Queries host storage buffer alignment required. + /// </summary> + /// <returns>Host storage buffer alignment in bytes</returns> + public int QueryStorageBufferOffsetAlignment() => _context.Capabilities.StorageBufferOffsetAlignment; + + /// <summary> + /// Queries host support for readable images without a explicit format declaration on the shader. + /// </summary> + /// <returns>True if formatted image load is supported, false otherwise</returns> + public bool QuerySupportsImageLoadFormatted() => _context.Capabilities.SupportsImageLoadFormatted; + + /// <summary> + /// Queries host GPU non-constant texture offset support. + /// </summary> + /// <returns>True if the GPU and driver supports non-constant texture offsets, false otherwise</returns> + public bool QuerySupportsNonConstantTextureOffset() => _context.Capabilities.SupportsNonConstantTextureOffset; + + /// <summary> + /// Gets the texture descriptor for a given texture on the pool. + /// </summary> + /// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param> + /// <returns>Texture descriptor</returns> + public override Image.TextureDescriptor GetTextureDescriptor(int handle) + { + if (!_textureDescriptors.TryGetValue(handle, out Image.TextureDescriptor textureDescriptor)) + { + throw new ArgumentException(); + } + + return textureDescriptor; + } + } +} |