aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/StructuredIr
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/StructuredIr')
-rw-r--r--src/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs2
-rw-r--r--src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs66
-rw-r--r--src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs15
-rw-r--r--src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs29
-rw-r--r--src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs16
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; }