diff options
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/StructuredIr')
5 files changed, 78 insertions, 50 deletions
diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs index 4fb5d02b..5d46ab49 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs @@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr // When debug mode is enabled, we disable expression propagation // (this makes comparison with the disassembly easier). - if (!context.Config.Options.Flags.HasFlag(TranslationFlags.DebugMode)) + if (!context.DebugMode) { AstBlockVisitor visitor = new(mainBlock); diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs index b7e379c6..8c12c2aa 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs @@ -18,8 +18,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr public IReadOnlyDictionary<int, MemoryDefinition> LocalMemories => _localMemories; public IReadOnlyDictionary<int, MemoryDefinition> SharedMemories => _sharedMemories; - public readonly bool OriginUpperLeft; - public ShaderProperties() { _constantBuffers = new Dictionary<int, BufferDefinition>(); @@ -30,29 +28,24 @@ namespace Ryujinx.Graphics.Shader.StructuredIr _sharedMemories = new Dictionary<int, MemoryDefinition>(); } - public ShaderProperties(bool originUpperLeft) : this() - { - OriginUpperLeft = originUpperLeft; - } - - public void AddOrUpdateConstantBuffer(int binding, BufferDefinition definition) + public void AddOrUpdateConstantBuffer(BufferDefinition definition) { - _constantBuffers[binding] = definition; + _constantBuffers[definition.Binding] = definition; } - public void AddOrUpdateStorageBuffer(int binding, BufferDefinition definition) + public void AddOrUpdateStorageBuffer(BufferDefinition definition) { - _storageBuffers[binding] = definition; + _storageBuffers[definition.Binding] = definition; } - public void AddOrUpdateTexture(int binding, TextureDefinition descriptor) + public void AddOrUpdateTexture(TextureDefinition definition) { - _textures[binding] = descriptor; + _textures[definition.Binding] = definition; } - public void AddOrUpdateImage(int binding, TextureDefinition descriptor) + public void AddOrUpdateImage(TextureDefinition definition) { - _images[binding] = descriptor; + _images[definition.Binding] = definition; } public int AddLocalMemory(MemoryDefinition definition) @@ -70,5 +63,48 @@ namespace Ryujinx.Graphics.Shader.StructuredIr return id; } + + public static TextureFormat GetTextureFormat(IGpuAccessor gpuAccessor, int handle, int cbufSlot = -1) + { + // When the formatted load extension is supported, we don't need to + // specify a format, we can just declare it without a format and the GPU will handle it. + if (gpuAccessor.QueryHostSupportsImageLoadFormatted()) + { + return TextureFormat.Unknown; + } + + var format = gpuAccessor.QueryTextureFormat(handle, cbufSlot); + + if (format == TextureFormat.Unknown) + { + gpuAccessor.Log($"Unknown format for texture {handle}."); + + format = TextureFormat.R8G8B8A8Unorm; + } + + return format; + } + + private static bool FormatSupportsAtomic(TextureFormat format) + { + return format == TextureFormat.R32Sint || format == TextureFormat.R32Uint; + } + + public static TextureFormat GetTextureFormatAtomic(IGpuAccessor gpuAccessor, int handle, int cbufSlot = -1) + { + // Atomic image instructions do not support GL_EXT_shader_image_load_formatted, + // and must have a type specified. Default to R32Sint if not available. + + var format = gpuAccessor.QueryTextureFormat(handle, cbufSlot); + + if (!FormatSupportsAtomic(format)) + { + gpuAccessor.Log($"Unsupported format for texture {handle}: {format}."); + + format = TextureFormat.R32Sint; + } + + return format; + } } } diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs index 87acedf6..862fef12 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs @@ -8,9 +8,14 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { static class StructuredProgram { - public static StructuredProgramInfo MakeStructuredProgram(IReadOnlyList<Function> functions, ShaderConfig config) + public static StructuredProgramInfo MakeStructuredProgram( + IReadOnlyList<Function> functions, + AttributeUsage attributeUsage, + ShaderDefinitions definitions, + ResourceManager resourceManager, + bool debugMode) { - StructuredProgramContext context = new(config); + StructuredProgramContext context = new(attributeUsage, definitions, resourceManager, debugMode); for (int funcIndex = 0; funcIndex < functions.Count; funcIndex++) { @@ -82,13 +87,13 @@ namespace Ryujinx.Graphics.Shader.StructuredIr int location = 0; int component = 0; - if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput)) + if (context.Definitions.HasPerLocationInputOrOutput(ioVariable, isOutput)) { location = operation.GetSource(1).Value; if (operation.SourcesCount > 2 && operation.GetSource(2).Type == OperandType.Constant && - context.Config.HasPerLocationInputOrOutputComponent(ioVariable, location, operation.GetSource(2).Value, isOutput)) + context.Definitions.HasPerLocationInputOrOutputComponent(ioVariable, location, operation.GetSource(2).Value, isOutput)) { component = operation.GetSource(2).Value; } @@ -98,7 +103,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr } else if (storageKind == StorageKind.ConstantBuffer && operation.GetSource(0).Type == OperandType.Constant) { - context.Config.ResourceManager.SetUsedConstantBufferBinding(operation.GetSource(0).Value); + context.ResourceManager.SetUsedConstantBufferBinding(operation.GetSource(0).Value); } } diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs index 019fc332..045662a1 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs @@ -28,17 +28,25 @@ namespace Ryujinx.Graphics.Shader.StructuredIr public StructuredProgramInfo Info { get; } - public ShaderConfig Config { get; } - - public StructuredProgramContext(ShaderConfig config) + public ShaderDefinitions Definitions { get; } + public ResourceManager ResourceManager { get; } + public bool DebugMode { get; } + + public StructuredProgramContext( + AttributeUsage attributeUsage, + ShaderDefinitions definitions, + ResourceManager resourceManager, + bool debugMode) { Info = new StructuredProgramInfo(); - Config = config; + Definitions = definitions; + ResourceManager = resourceManager; + DebugMode = debugMode; - if (config.GpPassthrough) + if (definitions.GpPassthrough) { - int passthroughAttributes = config.PassthroughAttributes; + int passthroughAttributes = attributeUsage.PassthroughAttributes; while (passthroughAttributes != 0) { int index = BitOperations.TrailingZeroCount(passthroughAttributes); @@ -52,11 +60,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr Info.IoDefinitions.Add(new IoDefinition(StorageKind.Input, IoVariable.PointSize)); Info.IoDefinitions.Add(new IoDefinition(StorageKind.Input, IoVariable.ClipDistance)); } - else if (config.Stage == ShaderStage.Fragment) - { - // Potentially used for texture coordinate scaling. - Info.IoDefinitions.Add(new IoDefinition(StorageKind.Input, IoVariable.FragmentCoord)); - } } public void EnterFunction( @@ -304,11 +307,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr int cbufSlot = operand.GetCbufSlot(); int cbufOffset = operand.GetCbufOffset(); - int binding = Config.ResourceManager.GetConstantBufferBinding(cbufSlot); + int binding = ResourceManager.GetConstantBufferBinding(cbufSlot); int vecIndex = cbufOffset >> 2; int elemIndex = cbufOffset & 3; - Config.ResourceManager.SetUsedConstantBufferBinding(binding); + ResourceManager.SetUsedConstantBufferBinding(binding); IAstNode[] sources = new IAstNode[] { diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs index 4f18c7fd..ded2f2a8 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs @@ -2,22 +2,6 @@ using System.Collections.Generic; namespace Ryujinx.Graphics.Shader.StructuredIr { - readonly struct TransformFeedbackOutput - { - public readonly bool Valid; - public readonly int Buffer; - public readonly int Offset; - public readonly int Stride; - - public TransformFeedbackOutput(int buffer, int offset, int stride) - { - Valid = true; - Buffer = buffer; - Offset = offset; - Stride = stride; - } - } - class StructuredProgramInfo { public List<StructuredFunction> Functions { get; } |