Delete ShaderConfig and organize shader resources/definitions better (#5509)

* Move some properties out of ShaderConfig

* Stop using ShaderConfig on backends

* Replace ShaderConfig usages on Translator and passes

* Move remaining properties out of ShaderConfig and delete ShaderConfig

* Remove ResourceManager property from TranslatorContext

* Move Rewriter passes to separate transform pass files

* Fix TransformPasses.RunPass on cases where a node is removed

* Move remaining ClipDistancePrimitivesWritten and UsedFeatures updates to decode stage

* Reduce excessive parameter passing a bit by using structs more

* Remove binding parameter from ShaderProperties methods since it is redundant

* Replace decoder instruction checks with switch statement

* Put GLSL on the same plan as SPIR-V for input/output declaration

* Stop mutating TranslatorContext state when Translate is called

* Pass most of the graphics state using a struct instead of individual query methods

* Auto-format

* Auto-format

* Add backend logging interface

* Auto-format

* Remove unnecessary use of interpolated strings

* Remove more modifications of AttributeUsage after decode

* PR feedback

* gl_Layer is not supported on compute
This commit is contained in:
gdkchan 2023-08-13 22:26:42 -03:00 committed by GitHub
parent 8edfb2bc7b
commit b423197619
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 2653 additions and 2407 deletions

View file

@ -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);

View file

@ -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()
public void AddOrUpdateConstantBuffer(BufferDefinition definition)
{
OriginUpperLeft = originUpperLeft;
_constantBuffers[definition.Binding] = definition;
}
public void AddOrUpdateConstantBuffer(int binding, BufferDefinition definition)
public void AddOrUpdateStorageBuffer(BufferDefinition definition)
{
_constantBuffers[binding] = definition;
_storageBuffers[definition.Binding] = definition;
}
public void AddOrUpdateStorageBuffer(int binding, BufferDefinition definition)
public void AddOrUpdateTexture(TextureDefinition definition)
{
_storageBuffers[binding] = definition;
_textures[definition.Binding] = definition;
}
public void AddOrUpdateTexture(int binding, TextureDefinition descriptor)
public void AddOrUpdateImage(TextureDefinition definition)
{
_textures[binding] = descriptor;
}
public void AddOrUpdateImage(int binding, TextureDefinition descriptor)
{
_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;
}
}
}

View file

@ -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);
}
}

View file

@ -28,17 +28,25 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
public StructuredProgramInfo Info { get; }
public ShaderConfig Config { get; }
public ShaderDefinitions Definitions { get; }
public ResourceManager ResourceManager { get; }
public bool DebugMode { get; }
public StructuredProgramContext(ShaderConfig config)
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[]
{

View file

@ -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; }