diff options
Diffstat (limited to 'Ryujinx.Graphics.GAL')
26 files changed, 421 insertions, 143 deletions
diff --git a/Ryujinx.Graphics.GAL/Capabilities.cs b/Ryujinx.Graphics.GAL/Capabilities.cs index af8541fb..60f5f1f0 100644 --- a/Ryujinx.Graphics.GAL/Capabilities.cs +++ b/Ryujinx.Graphics.GAL/Capabilities.cs @@ -11,19 +11,29 @@ namespace Ryujinx.Graphics.GAL public readonly bool HasVectorIndexingBug; public readonly bool SupportsAstcCompression; + public readonly bool SupportsBc123Compression; + public readonly bool SupportsBc45Compression; + public readonly bool SupportsBc67Compression; public readonly bool Supports3DTextureCompression; public readonly bool SupportsBgraFormat; public readonly bool SupportsR4G4Format; public readonly bool SupportsFragmentShaderInterlock; public readonly bool SupportsFragmentShaderOrderingIntel; + public readonly bool SupportsGeometryShaderPassthrough; public readonly bool SupportsImageLoadFormatted; public readonly bool SupportsMismatchingViewFormat; + public readonly bool SupportsCubemapView; public readonly bool SupportsNonConstantTextureOffset; public readonly bool SupportsShaderBallot; public readonly bool SupportsTextureShadowLod; public readonly bool SupportsViewportSwizzle; public readonly bool SupportsIndirectParameters; + public readonly uint MaximumUniformBuffersPerStage; + public readonly uint MaximumStorageBuffersPerStage; + public readonly uint MaximumTexturesPerStage; + public readonly uint MaximumImagesPerStage; + public readonly int MaximumComputeSharedMemorySize; public readonly float MaximumSupportedAnisotropy; public readonly int StorageBufferOffsetAlignment; @@ -34,18 +44,27 @@ namespace Ryujinx.Graphics.GAL bool hasFrontFacingBug, bool hasVectorIndexingBug, bool supportsAstcCompression, + bool supportsBc123Compression, + bool supportsBc45Compression, + bool supportsBc67Compression, bool supports3DTextureCompression, bool supportsBgraFormat, bool supportsR4G4Format, bool supportsFragmentShaderInterlock, bool supportsFragmentShaderOrderingIntel, + bool supportsGeometryShaderPassthrough, bool supportsImageLoadFormatted, bool supportsMismatchingViewFormat, + bool supportsCubemapView, bool supportsNonConstantTextureOffset, bool supportsShaderBallot, bool supportsTextureShadowLod, bool supportsViewportSwizzle, bool supportsIndirectParameters, + uint maximumUniformBuffersPerStage, + uint maximumStorageBuffersPerStage, + uint maximumTexturesPerStage, + uint maximumImagesPerStage, int maximumComputeSharedMemorySize, float maximumSupportedAnisotropy, int storageBufferOffsetAlignment) @@ -55,18 +74,27 @@ namespace Ryujinx.Graphics.GAL HasFrontFacingBug = hasFrontFacingBug; HasVectorIndexingBug = hasVectorIndexingBug; SupportsAstcCompression = supportsAstcCompression; + SupportsBc123Compression = supportsBc123Compression; + SupportsBc45Compression = supportsBc45Compression; + SupportsBc67Compression = supportsBc67Compression; Supports3DTextureCompression = supports3DTextureCompression; SupportsBgraFormat = supportsBgraFormat; SupportsR4G4Format = supportsR4G4Format; SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock; SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel; + SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough; SupportsImageLoadFormatted = supportsImageLoadFormatted; SupportsMismatchingViewFormat = supportsMismatchingViewFormat; + SupportsCubemapView = supportsCubemapView; SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset; SupportsShaderBallot = supportsShaderBallot; SupportsTextureShadowLod = supportsTextureShadowLod; SupportsViewportSwizzle = supportsViewportSwizzle; SupportsIndirectParameters = supportsIndirectParameters; + MaximumUniformBuffersPerStage = maximumUniformBuffersPerStage; + MaximumStorageBuffersPerStage = maximumStorageBuffersPerStage; + MaximumTexturesPerStage = maximumTexturesPerStage; + MaximumImagesPerStage = maximumImagesPerStage; MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize; MaximumSupportedAnisotropy = maximumSupportedAnisotropy; StorageBufferOffsetAlignment = storageBufferOffsetAlignment; diff --git a/Ryujinx.Graphics.GAL/DeviceInfo.cs b/Ryujinx.Graphics.GAL/DeviceInfo.cs new file mode 100644 index 00000000..c525eb60 --- /dev/null +++ b/Ryujinx.Graphics.GAL/DeviceInfo.cs @@ -0,0 +1,18 @@ +namespace Ryujinx.Graphics.GAL +{ + public struct DeviceInfo + { + public readonly string Id; + public readonly string Vendor; + public readonly string Name; + public readonly bool IsDiscrete; + + public DeviceInfo(string id, string vendor, string name, bool isDiscrete) + { + Id = id; + Vendor = vendor; + Name = name; + IsDiscrete = isDiscrete; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics.GAL/Format.cs b/Ryujinx.Graphics.GAL/Format.cs index 50cc6d40..db944844 100644 --- a/Ryujinx.Graphics.GAL/Format.cs +++ b/Ryujinx.Graphics.GAL/Format.cs @@ -166,6 +166,120 @@ namespace Ryujinx.Graphics.GAL public static class FormatExtensions { /// <summary> + /// Checks if the texture format is valid to use as image format. + /// </summary> + /// <param name="format">Texture format</param> + /// <returns>True if the texture can be used as image, false otherwise</returns> + public static bool IsImageCompatible(this Format format) + { + switch (format) + { + case Format.R8Unorm: + case Format.R8Snorm: + case Format.R8Uint: + case Format.R8Sint: + case Format.R16Float: + case Format.R16Unorm: + case Format.R16Snorm: + case Format.R16Uint: + case Format.R16Sint: + case Format.R32Float: + case Format.R32Uint: + case Format.R32Sint: + case Format.R8G8Unorm: + case Format.R8G8Snorm: + case Format.R8G8Uint: + case Format.R8G8Sint: + case Format.R16G16Float: + case Format.R16G16Unorm: + case Format.R16G16Snorm: + case Format.R16G16Uint: + case Format.R16G16Sint: + case Format.R32G32Float: + case Format.R32G32Uint: + case Format.R32G32Sint: + case Format.R8G8B8A8Unorm: + case Format.R8G8B8A8Snorm: + case Format.R8G8B8A8Uint: + case Format.R8G8B8A8Sint: + case Format.R16G16B16A16Float: + case Format.R16G16B16A16Unorm: + case Format.R16G16B16A16Snorm: + case Format.R16G16B16A16Uint: + case Format.R16G16B16A16Sint: + case Format.R32G32B32A32Float: + case Format.R32G32B32A32Uint: + case Format.R32G32B32A32Sint: + case Format.R10G10B10A2Unorm: + case Format.R10G10B10A2Uint: + case Format.R11G11B10Float: + return true; + } + + return false; + } + + /// <summary> + /// Checks if the texture format is valid to use as render target color format. + /// </summary> + /// <param name="format">Texture format</param> + /// <returns>True if the texture can be used as render target, false otherwise</returns> + public static bool IsRtColorCompatible(this Format format) + { + switch (format) + { + case Format.R32G32B32A32Float: + case Format.R32G32B32A32Sint: + case Format.R32G32B32A32Uint: + case Format.R16G16B16A16Unorm: + case Format.R16G16B16A16Snorm: + case Format.R16G16B16A16Sint: + case Format.R16G16B16A16Uint: + case Format.R16G16B16A16Float: + case Format.R32G32Float: + case Format.R32G32Sint: + case Format.R32G32Uint: + case Format.B8G8R8A8Unorm: + case Format.B8G8R8A8Srgb: + case Format.R10G10B10A2Unorm: + case Format.R10G10B10A2Uint: + case Format.R8G8B8A8Unorm: + case Format.R8G8B8A8Srgb: + case Format.R8G8B8A8Snorm: + case Format.R8G8B8A8Sint: + case Format.R8G8B8A8Uint: + case Format.R16G16Unorm: + case Format.R16G16Snorm: + case Format.R16G16Sint: + case Format.R16G16Uint: + case Format.R16G16Float: + case Format.R11G11B10Float: + case Format.R32Sint: + case Format.R32Uint: + case Format.R32Float: + case Format.B5G6R5Unorm: + case Format.B5G5R5A1Unorm: + case Format.R8G8Unorm: + case Format.R8G8Snorm: + case Format.R8G8Sint: + case Format.R8G8Uint: + case Format.R16Unorm: + case Format.R16Snorm: + case Format.R16Sint: + case Format.R16Uint: + case Format.R16Float: + case Format.R8Unorm: + case Format.R8Snorm: + case Format.R8Sint: + case Format.R8Uint: + case Format.B5G5R5X1Unorm: + return true; + } + + return false; + } + + /// <summary> /// Checks if the texture format is an ASTC format. /// </summary> /// <param name="format">Texture format</param> diff --git a/Ryujinx.Graphics.GAL/HardwareInfo.cs b/Ryujinx.Graphics.GAL/HardwareInfo.cs new file mode 100644 index 00000000..0c247074 --- /dev/null +++ b/Ryujinx.Graphics.GAL/HardwareInfo.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ryujinx.Graphics.GAL +{ + public struct HardwareInfo + { + public string GpuVendor { get; } + public string GpuModel { get; } + + public HardwareInfo(string gpuVendor, string gpuModel) + { + GpuVendor = gpuVendor; + GpuModel = gpuModel; + } + } +} diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs index da04362d..9d0da269 100644 --- a/Ryujinx.Graphics.GAL/IPipeline.cs +++ b/Ryujinx.Graphics.GAL/IPipeline.cs @@ -1,3 +1,4 @@ +using Ryujinx.Graphics.Shader; using System; namespace Ryujinx.Graphics.GAL @@ -79,15 +80,13 @@ namespace Ryujinx.Graphics.GAL void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMask); void SetRenderTargets(ITexture[] colors, ITexture depthStencil); - void SetSampler(int binding, ISampler sampler); - - void SetScissor(int index, bool enable, int x, int y, int width, int height); + void SetScissors(ReadOnlySpan<Rectangle<int>> regions); void SetStencilTest(StencilTestDescriptor stencilTest); void SetStorageBuffers(int first, ReadOnlySpan<BufferRange> buffers); - void SetTexture(int binding, ITexture texture); + void SetTextureAndSampler(ShaderStage stage, int binding, ITexture texture, ISampler sampler); void SetTransformFeedbackBuffers(ReadOnlySpan<BufferRange> buffers); void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers); @@ -97,7 +96,7 @@ namespace Ryujinx.Graphics.GAL void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs); void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers); - void SetViewports(int first, ReadOnlySpan<Viewport> viewports, bool disableTransform); + void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform); void TextureBarrier(); void TextureBarrierTiled(); diff --git a/Ryujinx.Graphics.GAL/IRenderer.cs b/Ryujinx.Graphics.GAL/IRenderer.cs index b051e9dc..8e48738d 100644 --- a/Ryujinx.Graphics.GAL/IRenderer.cs +++ b/Ryujinx.Graphics.GAL/IRenderer.cs @@ -30,6 +30,7 @@ namespace Ryujinx.Graphics.GAL ReadOnlySpan<byte> GetBufferData(BufferHandle buffer, int offset, int size); Capabilities GetCapabilities(); + HardwareInfo GetHardwareInfo(); IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info); diff --git a/Ryujinx.Graphics.GAL/IShader.cs b/Ryujinx.Graphics.GAL/IShader.cs deleted file mode 100644 index be24adcd..00000000 --- a/Ryujinx.Graphics.GAL/IShader.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.GAL -{ - public interface IShader : IDisposable { } -} diff --git a/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs b/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs index 95b33bc6..ea4d049f 100644 --- a/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs +++ b/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs @@ -201,14 +201,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading SetRenderTargetScaleCommand.Run(ref GetCommand<SetRenderTargetScaleCommand>(memory), threaded, renderer); _lookup[(int)CommandType.SetRenderTargets] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) => SetRenderTargetsCommand.Run(ref GetCommand<SetRenderTargetsCommand>(memory), threaded, renderer); - _lookup[(int)CommandType.SetSampler] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) => - SetSamplerCommand.Run(ref GetCommand<SetSamplerCommand>(memory), threaded, renderer); _lookup[(int)CommandType.SetScissor] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) => - SetScissorCommand.Run(ref GetCommand<SetScissorCommand>(memory), threaded, renderer); + SetScissorsCommand.Run(ref GetCommand<SetScissorsCommand>(memory), threaded, renderer); _lookup[(int)CommandType.SetStencilTest] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) => SetStencilTestCommand.Run(ref GetCommand<SetStencilTestCommand>(memory), threaded, renderer); - _lookup[(int)CommandType.SetTexture] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) => - SetTextureCommand.Run(ref GetCommand<SetTextureCommand>(memory), threaded, renderer); + _lookup[(int)CommandType.SetTextureAndSampler] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) => + SetTextureAndSamplerCommand.Run(ref GetCommand<SetTextureAndSamplerCommand>(memory), threaded, renderer); _lookup[(int)CommandType.SetUserClipDistance] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) => SetUserClipDistanceCommand.Run(ref GetCommand<SetUserClipDistanceCommand>(memory), threaded, renderer); _lookup[(int)CommandType.SetVertexAttribs] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) => diff --git a/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs b/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs index 8f0a0095..8c3ad844 100644 --- a/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs +++ b/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs @@ -82,10 +82,9 @@ SetRenderTargetColorMasks, SetRenderTargetScale, SetRenderTargets, - SetSampler, SetScissor, SetStencilTest, - SetTexture, + SetTextureAndSampler, SetUserClipDistance, SetVertexAttribs, SetVertexBuffers, diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetSamplerCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetSamplerCommand.cs deleted file mode 100644 index f3be24db..00000000 --- a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetSamplerCommand.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; -using Ryujinx.Graphics.GAL.Multithreading.Resources; - -namespace Ryujinx.Graphics.GAL.Multithreading.Commands -{ - struct SetSamplerCommand : IGALCommand - { - public CommandType CommandType => CommandType.SetSampler; - private int _index; - private TableRef<ISampler> _sampler; - - public void Set(int index, TableRef<ISampler> sampler) - { - _index = index; - _sampler = sampler; - } - - public static void Run(ref SetSamplerCommand command, ThreadedRenderer threaded, IRenderer renderer) - { - renderer.Pipeline.SetSampler(command._index, command._sampler.GetAs<ThreadedSampler>(threaded)?.Base); - } - } -} diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetScissorCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetScissorCommand.cs deleted file mode 100644 index 6c95d096..00000000 --- a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetScissorCommand.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands -{ - struct SetScissorCommand : IGALCommand - { - public CommandType CommandType => CommandType.SetScissor; - private int _index; - private bool _enable; - private int _x; - private int _y; - private int _width; - private int _height; - - public void Set(int index, bool enable, int x, int y, int width, int height) - { - _index = index; - _enable = enable; - _x = x; - _y = y; - _width = width; - _height = height; - } - - public static void Run(ref SetScissorCommand command, ThreadedRenderer threaded, IRenderer renderer) - { - renderer.Pipeline.SetScissor(command._index, command._enable, command._x, command._y, command._width, command._height); - } - } -} diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetScissorsCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetScissorsCommand.cs new file mode 100644 index 00000000..6966df6d --- /dev/null +++ b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetScissorsCommand.cs @@ -0,0 +1,22 @@ +using Ryujinx.Graphics.GAL.Multithreading.Model; + +namespace Ryujinx.Graphics.GAL.Multithreading.Commands +{ + struct SetScissorsCommand : IGALCommand + { + public CommandType CommandType => CommandType.SetScissor; + private SpanRef<Rectangle<int>> _scissors; + + public void Set(SpanRef<Rectangle<int>> scissors) + { + _scissors = scissors; + } + + public static void Run(ref SetScissorsCommand command, ThreadedRenderer threaded, IRenderer renderer) + { + renderer.Pipeline.SetScissors(command._scissors.Get(threaded)); + + command._scissors.Dispose(threaded); + } + } +} diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureAndSamplerCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureAndSamplerCommand.cs new file mode 100644 index 00000000..7ef58c3d --- /dev/null +++ b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureAndSamplerCommand.cs @@ -0,0 +1,28 @@ +using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Resources; +using Ryujinx.Graphics.Shader; + +namespace Ryujinx.Graphics.GAL.Multithreading.Commands +{ + struct SetTextureAndSamplerCommand : IGALCommand + { + public CommandType CommandType => CommandType.SetTextureAndSampler; + private ShaderStage _stage; + private int _binding; + private TableRef<ITexture> _texture; + private TableRef<ISampler> _sampler; + + public void Set(ShaderStage stage, int binding, TableRef<ITexture> texture, TableRef<ISampler> sampler) + { + _stage = stage; + _binding = binding; + _texture = texture; + _sampler = sampler; + } + + public static void Run(ref SetTextureAndSamplerCommand command, ThreadedRenderer threaded, IRenderer renderer) + { + renderer.Pipeline.SetTextureAndSampler(command._stage, command._binding, command._texture.GetAs<ThreadedTexture>(threaded)?.Base, command._sampler.GetAs<ThreadedSampler>(threaded)?.Base); + } + } +} diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureCommand.cs deleted file mode 100644 index e86f512b..00000000 --- a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureCommand.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; -using Ryujinx.Graphics.GAL.Multithreading.Resources; - -namespace Ryujinx.Graphics.GAL.Multithreading.Commands -{ - struct SetTextureCommand : IGALCommand - { - public CommandType CommandType => CommandType.SetTexture; - private int _binding; - private TableRef<ITexture> _texture; - - public void Set(int binding, TableRef<ITexture> texture) - { - _binding = binding; - _texture = texture; - } - - public static void Run(ref SetTextureCommand command, ThreadedRenderer threaded, IRenderer renderer) - { - renderer.Pipeline.SetTexture(command._binding, command._texture.GetAs<ThreadedTexture>(threaded)?.Base); - } - } -} diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs index b208d9fe..61861f4d 100644 --- a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs +++ b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs @@ -7,13 +7,11 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands struct SetViewportsCommand : IGALCommand { public CommandType CommandType => CommandType.SetViewports; - private int _first; private SpanRef<Viewport> _viewports; private bool _disableTransform; - public void Set(int first, SpanRef<Viewport> viewports, bool disableTransform) + public void Set(SpanRef<Viewport> viewports, bool disableTransform) { - _first = first; _viewports = viewports; _disableTransform = disableTransform; } @@ -21,7 +19,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands public static void Run(ref SetViewportsCommand command, ThreadedRenderer threaded, IRenderer renderer) { ReadOnlySpan<Viewport> viewports = command._viewports.Get(threaded); - renderer.Pipeline.SetViewports(command._first, viewports, command._disableTransform); + renderer.Pipeline.SetViewports(viewports, command._disableTransform); command._viewports.Dispose(threaded); } } diff --git a/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs b/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs index aebf210d..c462c559 100644 --- a/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs +++ b/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs @@ -1,6 +1,7 @@ using Ryujinx.Graphics.GAL.Multithreading.Commands; using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; +using Ryujinx.Graphics.Shader; using System; using System.Linq; @@ -250,15 +251,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetSampler(int binding, ISampler sampler) + public void SetScissors(ReadOnlySpan<Rectangle<int>> scissors) { - _renderer.New<SetSamplerCommand>().Set(binding, Ref(sampler)); - _renderer.QueueCommand(); - } - - public void SetScissor(int index, bool enable, int x, int y, int width, int height) - { - _renderer.New<SetScissorCommand>().Set(index, enable, x, y, width, height); + _renderer.New<SetScissorsCommand>().Set(_renderer.CopySpan(scissors)); _renderer.QueueCommand(); } @@ -274,9 +269,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetTexture(int binding, ITexture texture) + public void SetTextureAndSampler(ShaderStage stage, int binding, ITexture texture, ISampler sampler) { - _renderer.New<SetTextureCommand>().Set(binding, Ref(texture)); + _renderer.New<SetTextureAndSamplerCommand>().Set(stage, binding, Ref(texture), Ref(sampler)); _renderer.QueueCommand(); } @@ -310,9 +305,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetViewports(int first, ReadOnlySpan<Viewport> viewports, bool disableTransform) + public void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform) { - _renderer.New<SetViewportsCommand>().Set(first, _renderer.CopySpan(viewports), disableTransform); + _renderer.New<SetViewportsCommand>().Set(_renderer.CopySpan(viewports), disableTransform); _renderer.QueueCommand(); } diff --git a/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs b/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs index 63b668ba..f05f37c9 100644 --- a/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs +++ b/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs @@ -76,7 +76,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading renderer.ScreenCaptured += (object sender, ScreenCaptureImageInfo info) => ScreenCaptured?.Invoke(this, info); Pipeline = new ThreadedPipeline(this, renderer.Pipeline); - Window = new ThreadedWindow(this, renderer.Window); + Window = new ThreadedWindow(this, renderer); Buffers = new BufferMap(); Sync = new SyncMap(); Programs = new ProgramQueue(renderer); @@ -262,7 +262,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info) { var program = new ThreadedProgram(this); + SourceProgramRequest request = new SourceProgramRequest(program, shaders, info); + Programs.Add(request); New<CreateProgramCommand>().Set(Ref((IProgramRequest)request)); @@ -337,6 +339,11 @@ namespace Ryujinx.Graphics.GAL.Multithreading return box.Result; } + public HardwareInfo GetHardwareInfo() + { + return _baseRenderer.GetHardwareInfo(); + } + /// <summary> /// Initialize the base renderer. Must be called on the render thread. /// </summary> diff --git a/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs b/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs index dc0b4dc5..c8045502 100644 --- a/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs +++ b/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs @@ -8,12 +8,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading public class ThreadedWindow : IWindow { private ThreadedRenderer _renderer; - private IWindow _impl; + private IRenderer _impl; - public ThreadedWindow(ThreadedRenderer renderer, IWindow window) + public ThreadedWindow(ThreadedRenderer renderer, IRenderer impl) { _renderer = renderer; - _impl = window; + _impl = impl; } public void Present(ITexture texture, ImageCrop crop, Action<object> swapBuffersCallback) @@ -28,7 +28,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading public void SetSize(int width, int height) { - _impl.SetSize(width, height); + _impl.Window.SetSize(width, height); } } } diff --git a/Ryujinx.Graphics.GAL/ProgramPipelineState.cs b/Ryujinx.Graphics.GAL/ProgramPipelineState.cs new file mode 100644 index 00000000..10a4164e --- /dev/null +++ b/Ryujinx.Graphics.GAL/ProgramPipelineState.cs @@ -0,0 +1,78 @@ +using Ryujinx.Common.Memory; +using System; + +namespace Ryujinx.Graphics.GAL +{ + /// <summary> + /// Descriptor for a pipeline buffer binding. + /// </summary> + public struct BufferPipelineDescriptor + { + public bool Enable { get; } + public int Stride { get; } + public int Divisor { get; } + + public BufferPipelineDescriptor(bool enable, int stride, int divisor) + { + Enable = enable; + Stride = stride; + Divisor = divisor; + } + } + + /// <summary> + /// State required for a program to compile shaders. + /// </summary> + public struct ProgramPipelineState + { + // Some state is considered always dynamic and should not be included: + // - Viewports/Scissors + // - Bias values (not enable) + + public int SamplesCount; + public Array8<bool> AttachmentEnable; + public Array8<Format> AttachmentFormats; + public bool DepthStencilEnable; + public Format DepthStencilFormat; + + public bool LogicOpEnable; + public LogicalOp LogicOp; + public Array8<BlendDescriptor> BlendDescriptors; + public Array8<uint> ColorWriteMask; + + public int VertexAttribCount; + public Array32<VertexAttribDescriptor> VertexAttribs; + + public int VertexBufferCount; + public Array32<BufferPipelineDescriptor> VertexBuffers; + + // TODO: Min/max depth bounds. + public DepthTestDescriptor DepthTest; + public StencilTestDescriptor StencilTest; + public FrontFace FrontFace; + public Face CullMode; + public bool CullEnable; + + public PolygonModeMask BiasEnable; + + public float LineWidth; + // TODO: Polygon mode. + public bool DepthClampEnable; + public bool RasterizerDiscard; + public PrimitiveTopology Topology; + public bool PrimitiveRestartEnable; + public uint PatchControlPoints; + + public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs) + { + VertexAttribCount = vertexAttribs.Length; + vertexAttribs.CopyTo(VertexAttribs.ToSpan()); + } + + public void SetLogicOpState(bool enable, LogicalOp op) + { + LogicOp = op; + LogicOpEnable = enable; + } + } +} diff --git a/Ryujinx.Graphics.GAL/Rectangle.cs b/Ryujinx.Graphics.GAL/Rectangle.cs new file mode 100644 index 00000000..1e207926 --- /dev/null +++ b/Ryujinx.Graphics.GAL/Rectangle.cs @@ -0,0 +1,18 @@ +namespace Ryujinx.Graphics.GAL +{ + public struct Rectangle<T> where T : unmanaged + { + public T X { get; } + public T Y { get; } + public T Width { get; } + public T Height { get; } + + public Rectangle(T x, T y, T width, T height) + { + X = x; + Y = y; + Width = width; + Height = height; + } + } +} diff --git a/Ryujinx.Graphics.GAL/RectangleF.cs b/Ryujinx.Graphics.GAL/RectangleF.cs deleted file mode 100644 index cf166781..00000000 --- a/Ryujinx.Graphics.GAL/RectangleF.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Graphics.GAL -{ - public struct RectangleF - { - public float X { get; } - public float Y { get; } - public float Width { get; } - public float Height { get; } - - public RectangleF(float x, float y, float width, float height) - { - X = x; - Y = y; - Width = width; - Height = height; - } - } -} diff --git a/Ryujinx.Graphics.GAL/SamplerCreateInfo.cs b/Ryujinx.Graphics.GAL/SamplerCreateInfo.cs index 7a68450e..fe711c3a 100644 --- a/Ryujinx.Graphics.GAL/SamplerCreateInfo.cs +++ b/Ryujinx.Graphics.GAL/SamplerCreateInfo.cs @@ -50,5 +50,23 @@ namespace Ryujinx.Graphics.GAL MipLodBias = mipLodBias; MaxAnisotropy = maxAnisotropy; } + + public static SamplerCreateInfo Create(MinFilter minFilter, MagFilter magFilter) + { + return new SamplerCreateInfo( + minFilter, + magFilter, + false, + AddressMode.ClampToEdge, + AddressMode.ClampToEdge, + AddressMode.ClampToEdge, + CompareMode.None, + GAL.CompareOp.Always, + new ColorF(0f, 0f, 0f, 0f), + 0f, + 0f, + 0f, + 1f); + } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.GAL/ShaderBindings.cs b/Ryujinx.Graphics.GAL/ShaderBindings.cs new file mode 100644 index 00000000..ea8e1749 --- /dev/null +++ b/Ryujinx.Graphics.GAL/ShaderBindings.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; + +namespace Ryujinx.Graphics.GAL +{ + public struct ShaderBindings + { + public IReadOnlyCollection<int> UniformBufferBindings { get; } + public IReadOnlyCollection<int> StorageBufferBindings { get; } + public IReadOnlyCollection<int> TextureBindings { get; } + public IReadOnlyCollection<int> ImageBindings { get; } + + public ShaderBindings( + IReadOnlyCollection<int> uniformBufferBindings, + IReadOnlyCollection<int> storageBufferBindings, + IReadOnlyCollection<int> textureBindings, + IReadOnlyCollection<int> imageBindings) + { + UniformBufferBindings = uniformBufferBindings; + StorageBufferBindings = storageBufferBindings; + TextureBindings = textureBindings; + ImageBindings = imageBindings; + } + } +} diff --git a/Ryujinx.Graphics.GAL/ShaderInfo.cs b/Ryujinx.Graphics.GAL/ShaderInfo.cs index 0c187e06..b4c87117 100644 --- a/Ryujinx.Graphics.GAL/ShaderInfo.cs +++ b/Ryujinx.Graphics.GAL/ShaderInfo.cs @@ -3,10 +3,21 @@ namespace Ryujinx.Graphics.GAL public struct ShaderInfo { public int FragmentOutputMap { get; } + public ProgramPipelineState? State { get; } + public bool FromCache { get; set; } - public ShaderInfo(int fragmentOutputMap) + public ShaderInfo(int fragmentOutputMap, ProgramPipelineState state, bool fromCache = false) { FragmentOutputMap = fragmentOutputMap; + State = state; + FromCache = fromCache; + } + + public ShaderInfo(int fragmentOutputMap, bool fromCache = false) + { + FragmentOutputMap = fragmentOutputMap; + State = null; + FromCache = fromCache; } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.GAL/ShaderSource.cs b/Ryujinx.Graphics.GAL/ShaderSource.cs index 13b92f20..c68ba80d 100644 --- a/Ryujinx.Graphics.GAL/ShaderSource.cs +++ b/Ryujinx.Graphics.GAL/ShaderSource.cs @@ -7,22 +7,24 @@ namespace Ryujinx.Graphics.GAL { public string Code { get; } public byte[] BinaryCode { get; } + public ShaderBindings Bindings { get; } public ShaderStage Stage { get; } public TargetLanguage Language { get; } - public ShaderSource(string code, byte[] binaryCode, ShaderStage stage, TargetLanguage language) + public ShaderSource(string code, byte[] binaryCode, ShaderBindings bindings, ShaderStage stage, TargetLanguage language) { Code = code; BinaryCode = binaryCode; + Bindings = bindings; Stage = stage; Language = language; } - public ShaderSource(string code, ShaderStage stage, TargetLanguage language) : this(code, null, stage, language) + public ShaderSource(string code, ShaderBindings bindings, ShaderStage stage, TargetLanguage language) : this(code, null, bindings, stage, language) { } - public ShaderSource(byte[] binaryCode, ShaderStage stage, TargetLanguage language) : this(null, binaryCode, stage, language) + public ShaderSource(byte[] binaryCode, ShaderBindings bindings, ShaderStage stage, TargetLanguage language) : this(null, binaryCode, bindings, stage, language) { } } diff --git a/Ryujinx.Graphics.GAL/Viewport.cs b/Ryujinx.Graphics.GAL/Viewport.cs index d9d6e20a..58135db2 100644 --- a/Ryujinx.Graphics.GAL/Viewport.cs +++ b/Ryujinx.Graphics.GAL/Viewport.cs @@ -2,7 +2,7 @@ namespace Ryujinx.Graphics.GAL { public struct Viewport { - public RectangleF Region { get; } + public Rectangle<float> Region { get; } public ViewportSwizzle SwizzleX { get; } public ViewportSwizzle SwizzleY { get; } @@ -13,13 +13,13 @@ namespace Ryujinx.Graphics.GAL public float DepthFar { get; } public Viewport( - RectangleF region, - ViewportSwizzle swizzleX, - ViewportSwizzle swizzleY, - ViewportSwizzle swizzleZ, - ViewportSwizzle swizzleW, - float depthNear, - float depthFar) + Rectangle<float> region, + ViewportSwizzle swizzleX, + ViewportSwizzle swizzleY, + ViewportSwizzle swizzleZ, + ViewportSwizzle swizzleW, + float depthNear, + float depthFar) { Region = region; SwizzleX = swizzleX; |