diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs | 249 |
1 files changed, 106 insertions, 143 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs index a5c7575f..192467b7 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs @@ -1,5 +1,5 @@ using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Shader; using System; using System.Runtime.InteropServices; @@ -9,19 +9,12 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <summary> /// Represents a GPU state and memory accessor. /// </summary> - class GpuAccessor : TextureDescriptorCapableGpuAccessor, IGpuAccessor + class GpuAccessor : GpuAccessorBase, IGpuAccessor { private readonly GpuChannel _channel; private readonly GpuAccessorState _state; private readonly int _stageIndex; private readonly bool _compute; - private readonly int _localSizeX; - private readonly int _localSizeY; - private readonly int _localSizeZ; - private readonly int _localMemorySize; - private readonly int _sharedMemorySize; - - public int Cb1DataSize { get; private set; } /// <summary> /// Creates a new instance of the GPU state accessor for graphics shader translation. @@ -43,43 +36,16 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> /// <param name="state">Current GPU state</param> - /// <param name="localSizeX">Local group size X of the compute shader</param> - /// <param name="localSizeY">Local group size Y of the compute shader</param> - /// <param name="localSizeZ">Local group size Z of the compute shader</param> - /// <param name="localMemorySize">Local memory size of the compute shader</param> - /// <param name="sharedMemorySize">Shared memory size of the compute shader</param> - public GpuAccessor( - GpuContext context, - GpuChannel channel, - GpuAccessorState state, - int localSizeX, - int localSizeY, - int localSizeZ, - int localMemorySize, - int sharedMemorySize) : base(context) + public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state) : base(context) { _channel = channel; _state = state; _compute = true; - _localSizeX = localSizeX; - _localSizeY = localSizeY; - _localSizeZ = localSizeZ; - _localMemorySize = localMemorySize; - _sharedMemorySize = sharedMemorySize; } - /// <summary> - /// Reads data from the constant buffer 1. - /// </summary> - /// <param name="offset">Offset in bytes to read from</param> - /// <returns>Value at the given offset</returns> + /// <inheritdoc/> public uint ConstantBuffer1Read(int offset) { - if (Cb1DataSize < offset + 4) - { - Cb1DataSize = offset + 4; - } - ulong baseAddress = _compute ? _channel.BufferManager.GetComputeUniformBufferAddress(1) : _channel.BufferManager.GetGraphicsUniformBufferAddress(_stageIndex, 1); @@ -87,111 +53,115 @@ namespace Ryujinx.Graphics.Gpu.Shader return _channel.MemoryManager.Physical.Read<uint>(baseAddress + (ulong)offset); } - /// <summary> - /// Prints a log message. - /// </summary> - /// <param name="message">Message to print</param> + /// <inheritdoc/> public void Log(string message) { Logger.Warning?.Print(LogClass.Gpu, $"Shader translator: {message}"); } - /// <summary> - /// Gets a span of the specified memory location, containing shader code. - /// </summary> - /// <param name="address">GPU virtual address of the data</param> - /// <param name="minimumSize">Minimum size that the returned span may have</param> - /// <returns>Span of the memory location</returns> - public override ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize) + /// <inheritdoc/> + public ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize) { int size = Math.Max(minimumSize, 0x1000 - (int)(address & 0xfff)); return MemoryMarshal.Cast<byte, ulong>(_channel.MemoryManager.GetSpan(address, size)); } - /// <summary> - /// Queries Local Size X for compute shaders. - /// </summary> - /// <returns>Local Size X</returns> - public int QueryComputeLocalSizeX() => _localSizeX; + /// <inheritdoc/> + public int QueryBindingConstantBuffer(int index) + { + return _state.ResourceCounts.UniformBuffersCount++; + } - /// <summary> - /// Queries Local Size Y for compute shaders. - /// </summary> - /// <returns>Local Size Y</returns> - public int QueryComputeLocalSizeY() => _localSizeY; + /// <inheritdoc/> + public int QueryBindingStorageBuffer(int index) + { + return _state.ResourceCounts.StorageBuffersCount++; + } - /// <summary> - /// Queries Local Size Z for compute shaders. - /// </summary> - /// <returns>Local Size Z</returns> - public int QueryComputeLocalSizeZ() => _localSizeZ; + /// <inheritdoc/> + public int QueryBindingTexture(int index) + { + return _state.ResourceCounts.TexturesCount++; + } - /// <summary> - /// Queries Local Memory size in bytes for compute shaders. - /// </summary> - /// <returns>Local Memory size in bytes</returns> - public int QueryComputeLocalMemorySize() => _localMemorySize; + /// <inheritdoc/> + public int QueryBindingImage(int index) + { + return _state.ResourceCounts.ImagesCount++; + } - /// <summary> - /// Queries Shared Memory size in bytes for compute shaders. - /// </summary> - /// <returns>Shared Memory size in bytes</returns> - public int QueryComputeSharedMemorySize() => _sharedMemorySize; + /// <inheritdoc/> + public int QueryComputeLocalSizeX() => _state.ComputeState.LocalSizeX; - /// <summary> - /// Queries Constant Buffer usage information. - /// </summary> - /// <returns>A mask where each bit set indicates a bound constant buffer</returns> + /// <inheritdoc/> + public int QueryComputeLocalSizeY() => _state.ComputeState.LocalSizeY; + + /// <inheritdoc/> + public int QueryComputeLocalSizeZ() => _state.ComputeState.LocalSizeZ; + + /// <inheritdoc/> + public int QueryComputeLocalMemorySize() => _state.ComputeState.LocalMemorySize; + + /// <inheritdoc/> + public int QueryComputeSharedMemorySize() => _state.ComputeState.SharedMemorySize; + + /// <inheritdoc/> public uint QueryConstantBufferUse() { - return _compute + uint useMask = _compute ? _channel.BufferManager.GetComputeUniformBufferUseMask() : _channel.BufferManager.GetGraphicsUniformBufferUseMask(_stageIndex); + + _state.SpecializationState?.RecordConstantBufferUse(_stageIndex, useMask); + return useMask; } - /// <summary> - /// Queries current primitive topology for geometry shaders. - /// </summary> - /// <returns>Current primitive topology</returns> + /// <inheritdoc/> public InputTopology QueryPrimitiveTopology() { - return _state.Topology switch - { - PrimitiveTopology.Points => InputTopology.Points, - PrimitiveTopology.Lines or - PrimitiveTopology.LineLoop or - PrimitiveTopology.LineStrip => InputTopology.Lines, - PrimitiveTopology.LinesAdjacency or - PrimitiveTopology.LineStripAdjacency => InputTopology.LinesAdjacency, - PrimitiveTopology.Triangles or - PrimitiveTopology.TriangleStrip or - PrimitiveTopology.TriangleFan => InputTopology.Triangles, - PrimitiveTopology.TrianglesAdjacency or - PrimitiveTopology.TriangleStripAdjacency => InputTopology.TrianglesAdjacency, - PrimitiveTopology.Patches => _state.TessellationMode.UnpackPatchType() == TessPatchType.Isolines - ? InputTopology.Lines - : InputTopology.Triangles, - _ => InputTopology.Points - }; + _state.SpecializationState?.RecordPrimitiveTopology(); + return ConvertToInputTopology(_state.GraphicsState.Topology, _state.GraphicsState.TessellationMode); } - /// <summary> - /// Queries the tessellation evaluation shader primitive winding order. - /// </summary> - /// <returns>True if the primitive winding order is clockwise, false if counter-clockwise</returns> - public bool QueryTessCw() => _state.TessellationMode.UnpackCw(); + /// <inheritdoc/> + public bool QueryTessCw() + { + return _state.GraphicsState.TessellationMode.UnpackCw(); + } - /// <summary> - /// Queries the tessellation evaluation shader abstract patch type. - /// </summary> - /// <returns>Abstract patch type</returns> - public TessPatchType QueryTessPatchType() => _state.TessellationMode.UnpackPatchType(); + /// <inheritdoc/> + public TessPatchType QueryTessPatchType() + { + return _state.GraphicsState.TessellationMode.UnpackPatchType(); + } - /// <summary> - /// Queries the tessellation evaluation shader spacing between tessellated vertices of the patch. - /// </summary> - /// <returns>Spacing between tessellated vertices of the patch</returns> - public TessSpacing QueryTessSpacing() => _state.TessellationMode.UnpackSpacing(); + /// <inheritdoc/> + public TessSpacing QueryTessSpacing() + { + return _state.GraphicsState.TessellationMode.UnpackSpacing(); + } + + //// <inheritdoc/> + public TextureFormat QueryTextureFormat(int handle, int cbufSlot) + { + _state.SpecializationState?.RecordTextureFormat(_stageIndex, handle, cbufSlot); + var descriptor = GetTextureDescriptor(handle, cbufSlot); + return ConvertToTextureFormat(descriptor.UnpackFormat(), descriptor.UnpackSrgb()); + } + + /// <inheritdoc/> + public SamplerType QuerySamplerType(int handle, int cbufSlot) + { + _state.SpecializationState?.RecordTextureSamplerType(_stageIndex, handle, cbufSlot); + return GetTextureDescriptor(handle, cbufSlot).UnpackTextureTarget().ConvertSamplerType(); + } + + /// <inheritdoc/> + public bool QueryTextureCoordNormalized(int handle, int cbufSlot) + { + _state.SpecializationState?.RecordTextureCoordNormalized(_stageIndex, handle, cbufSlot); + return GetTextureDescriptor(handle, cbufSlot).UnpackTextureCoordNormalized(); + } /// <summary> /// Gets the texture descriptor for a given texture on the pool. @@ -199,65 +169,58 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param> /// <param name="cbufSlot">Constant buffer slot for the texture handle</param> /// <returns>Texture descriptor</returns> - public override Image.ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot) + private Image.TextureDescriptor GetTextureDescriptor(int handle, int cbufSlot) { if (_compute) { return _channel.TextureManager.GetComputeTextureDescriptor( - _state.TexturePoolGpuVa, - _state.TextureBufferIndex, - _state.TexturePoolMaximumId, + _state.PoolState.TexturePoolGpuVa, + _state.PoolState.TextureBufferIndex, + _state.PoolState.TexturePoolMaximumId, handle, cbufSlot); } else { return _channel.TextureManager.GetGraphicsTextureDescriptor( - _state.TexturePoolGpuVa, - _state.TextureBufferIndex, - _state.TexturePoolMaximumId, + _state.PoolState.TexturePoolGpuVa, + _state.PoolState.TextureBufferIndex, + _state.PoolState.TexturePoolMaximumId, _stageIndex, handle, cbufSlot); } } - /// <summary> - /// Queries transform feedback enable state. - /// </summary> - /// <returns>True if the shader uses transform feedback, false otherwise</returns> + /// <inheritdoc/> public bool QueryTransformFeedbackEnabled() { return _state.TransformFeedbackDescriptors != null; } - /// <summary> - /// Queries the varying locations that should be written to the transform feedback buffer. - /// </summary> - /// <param name="bufferIndex">Index of the transform feedback buffer</param> - /// <returns>Varying locations for the specified buffer</returns> + /// <inheritdoc/> public ReadOnlySpan<byte> QueryTransformFeedbackVaryingLocations(int bufferIndex) { - return _state.TransformFeedbackDescriptors[bufferIndex].VaryingLocations; + return _state.TransformFeedbackDescriptors[bufferIndex].AsSpan(); } - /// <summary> - /// Queries the stride (in bytes) of the per vertex data written into the transform feedback buffer. - /// </summary> - /// <param name="bufferIndex">Index of the transform feedback buffer</param> - /// <returns>Stride for the specified buffer</returns> + /// <inheritdoc/> public int QueryTransformFeedbackStride(int bufferIndex) { return _state.TransformFeedbackDescriptors[bufferIndex].Stride; } - /// <summary> - /// Queries if host state forces early depth testing. - /// </summary> - /// <returns>True if early depth testing is forced</returns> + /// <inheritdoc/> public bool QueryEarlyZForce() { - return _state.EarlyZForce; + _state.SpecializationState?.RecordEarlyZForce(); + return _state.GraphicsState.EarlyZForce; + } + + /// <inheritdoc/> + public void RegisterTexture(int handle, int cbufSlot) + { + _state.SpecializationState?.RegisterTexture(_stageIndex, handle, cbufSlot, GetTextureDescriptor(handle, cbufSlot)); } } } |