aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/CodeGen/Spirv
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/CodeGen/Spirv')
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs51
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs82
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs34
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs69
4 files changed, 131 insertions, 105 deletions
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs
index d4f49045..d385782a 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs
@@ -20,21 +20,29 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
public StructuredProgramInfo Info { get; }
- public ShaderConfig Config { get; }
+ public AttributeUsage AttributeUsage { get; }
+ public ShaderDefinitions Definitions { get; }
+ public ShaderProperties Properties { get; }
+ public HostCapabilities HostCapabilities { get; }
+ public ILogger Logger { get; }
+ public TargetApi TargetApi { get; }
public int InputVertices { get; }
- public Dictionary<int, Instruction> ConstantBuffers { get; } = new Dictionary<int, Instruction>();
- public Dictionary<int, Instruction> StorageBuffers { get; } = new Dictionary<int, Instruction>();
- public Dictionary<int, Instruction> LocalMemories { get; } = new Dictionary<int, Instruction>();
- public Dictionary<int, Instruction> SharedMemories { get; } = new Dictionary<int, Instruction>();
- public Dictionary<int, SamplerType> SamplersTypes { get; } = new Dictionary<int, SamplerType>();
- public Dictionary<int, (Instruction, Instruction, Instruction)> Samplers { get; } = new Dictionary<int, (Instruction, Instruction, Instruction)>();
- public Dictionary<int, (Instruction, Instruction)> Images { get; } = new Dictionary<int, (Instruction, Instruction)>();
- public Dictionary<IoDefinition, Instruction> Inputs { get; } = new Dictionary<IoDefinition, Instruction>();
- public Dictionary<IoDefinition, Instruction> Outputs { get; } = new Dictionary<IoDefinition, Instruction>();
- public Dictionary<IoDefinition, Instruction> InputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>();
- public Dictionary<IoDefinition, Instruction> OutputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>();
+ public Dictionary<int, Instruction> ConstantBuffers { get; } = new();
+ public Dictionary<int, Instruction> StorageBuffers { get; } = new();
+
+ public Dictionary<int, Instruction> LocalMemories { get; } = new();
+ public Dictionary<int, Instruction> SharedMemories { get; } = new();
+
+ public Dictionary<int, SamplerType> SamplersTypes { get; } = new();
+ public Dictionary<int, (Instruction, Instruction, Instruction)> Samplers { get; } = new();
+ public Dictionary<int, (Instruction, Instruction)> Images { get; } = new();
+
+ public Dictionary<IoDefinition, Instruction> Inputs { get; } = new();
+ public Dictionary<IoDefinition, Instruction> Outputs { get; } = new();
+ public Dictionary<IoDefinition, Instruction> InputsPerPatch { get; } = new();
+ public Dictionary<IoDefinition, Instruction> OutputsPerPatch { get; } = new();
public StructuredFunction CurrentFunction { get; set; }
private readonly Dictionary<AstOperand, Instruction> _locals = new();
@@ -81,25 +89,28 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
public CodeGenContext(
StructuredProgramInfo info,
- ShaderConfig config,
+ CodeGenParameters parameters,
GeneratorPool<Instruction> instPool,
GeneratorPool<LiteralInteger> integerPool) : base(SpirvVersionPacked, instPool, integerPool)
{
Info = info;
- Config = config;
-
- if (config.Stage == ShaderStage.Geometry)
+ AttributeUsage = parameters.AttributeUsage;
+ Definitions = parameters.Definitions;
+ Properties = parameters.Properties;
+ HostCapabilities = parameters.HostCapabilities;
+ Logger = parameters.Logger;
+ TargetApi = parameters.TargetApi;
+
+ if (parameters.Definitions.Stage == ShaderStage.Geometry)
{
- InputTopology inPrimitive = config.GpuAccessor.QueryPrimitiveTopology();
-
- InputVertices = inPrimitive switch
+ InputVertices = parameters.Definitions.InputTopology switch
{
InputTopology.Points => 1,
InputTopology.Lines => 2,
InputTopology.LinesAdjacency => 2,
InputTopology.Triangles => 3,
InputTopology.TrianglesAdjacency => 3,
- _ => throw new InvalidOperationException($"Invalid input topology \"{inPrimitive}\"."),
+ _ => throw new InvalidOperationException($"Invalid input topology \"{parameters.Definitions.InputTopology}\"."),
};
}
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
index b14fead8..f3a083c3 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
@@ -5,7 +5,6 @@ using Spv.Generator;
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Numerics;
using static Spv.Specification;
using SpvInstruction = Spv.Generator.Instruction;
@@ -66,12 +65,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
public static void DeclareAll(CodeGenContext context, StructuredProgramInfo info)
{
- DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
- DeclareStorageBuffers(context, context.Config.Properties.StorageBuffers.Values);
- DeclareMemories(context, context.Config.Properties.LocalMemories, context.LocalMemories, StorageClass.Private);
- DeclareMemories(context, context.Config.Properties.SharedMemories, context.SharedMemories, StorageClass.Workgroup);
- DeclareSamplers(context, context.Config.Properties.Textures.Values);
- DeclareImages(context, context.Config.Properties.Images.Values);
+ DeclareConstantBuffers(context, context.Properties.ConstantBuffers.Values);
+ DeclareStorageBuffers(context, context.Properties.StorageBuffers.Values);
+ DeclareMemories(context, context.Properties.LocalMemories, context.LocalMemories, StorageClass.Private);
+ DeclareMemories(context, context.Properties.SharedMemories, context.SharedMemories, StorageClass.Workgroup);
+ DeclareSamplers(context, context.Properties.Textures.Values);
+ DeclareImages(context, context.Properties.Images.Values);
DeclareInputsAndOutputs(context, info);
}
@@ -108,7 +107,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
foreach (BufferDefinition buffer in buffers)
{
- int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? buffer.Set : 0;
+ int setIndex = context.TargetApi == TargetApi.Vulkan ? buffer.Set : 0;
int alignment = buffer.Layout == BufferLayout.Std140 ? 16 : 4;
int alignmentMask = alignment - 1;
int offset = 0;
@@ -181,7 +180,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
foreach (var sampler in samplers)
{
- int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? sampler.Set : 0;
+ int setIndex = context.TargetApi == TargetApi.Vulkan ? sampler.Set : 0;
var dim = (sampler.Type & SamplerType.Mask) switch
{
@@ -220,7 +219,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
foreach (var image in images)
{
- int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? image.Set : 0;
+ int setIndex = context.TargetApi == TargetApi.Vulkan ? image.Set : 0;
var dim = GetDim(image.Type);
@@ -314,16 +313,29 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
private static void DeclareInputsAndOutputs(CodeGenContext context, StructuredProgramInfo info)
{
+ int firstLocation = int.MaxValue;
+
+ if (context.Definitions.Stage == ShaderStage.Fragment && context.Definitions.DualSourceBlend)
+ {
+ foreach (var ioDefinition in info.IoDefinitions)
+ {
+ if (ioDefinition.IoVariable == IoVariable.FragmentOutputColor && ioDefinition.Location < firstLocation)
+ {
+ firstLocation = ioDefinition.Location;
+ }
+ }
+ }
+
foreach (var ioDefinition in info.IoDefinitions)
{
PixelImap iq = PixelImap.Unused;
- if (context.Config.Stage == ShaderStage.Fragment)
+ if (context.Definitions.Stage == ShaderStage.Fragment)
{
var ioVariable = ioDefinition.IoVariable;
if (ioVariable == IoVariable.UserDefined)
{
- iq = context.Config.ImapTypes[ioDefinition.Location].GetFirstUsedType();
+ iq = context.Definitions.ImapTypes[ioDefinition.Location].GetFirstUsedType();
}
else
{
@@ -340,11 +352,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
bool isOutput = ioDefinition.StorageKind.IsOutput();
bool isPerPatch = ioDefinition.StorageKind.IsPerPatch();
- DeclareInputOrOutput(context, ioDefinition, isOutput, isPerPatch, iq);
+ DeclareInputOrOutput(context, ioDefinition, isOutput, isPerPatch, iq, firstLocation);
}
}
- private static void DeclareInputOrOutput(CodeGenContext context, IoDefinition ioDefinition, bool isOutput, bool isPerPatch, PixelImap iq = PixelImap.Unused)
+ private static void DeclareInputOrOutput(
+ CodeGenContext context,
+ IoDefinition ioDefinition,
+ bool isOutput,
+ bool isPerPatch,
+ PixelImap iq = PixelImap.Unused,
+ int firstLocation = 0)
{
IoVariable ioVariable = ioDefinition.IoVariable;
var storageClass = isOutput ? StorageClass.Output : StorageClass.Input;
@@ -355,12 +373,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
if (ioVariable == IoVariable.UserDefined)
{
- varType = context.Config.GetUserDefinedType(ioDefinition.Location, isOutput);
+ varType = context.Definitions.GetUserDefinedType(ioDefinition.Location, isOutput);
isBuiltIn = false;
}
else if (ioVariable == IoVariable.FragmentOutputColor)
{
- varType = context.Config.GetFragmentOutputColorType(ioDefinition.Location);
+ varType = context.Definitions.GetFragmentOutputColorType(ioDefinition.Location);
isBuiltIn = false;
}
else
@@ -374,16 +392,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
}
}
- bool hasComponent = context.Config.HasPerLocationInputOrOutputComponent(ioVariable, ioDefinition.Location, ioDefinition.Component, isOutput);
+ bool hasComponent = context.Definitions.HasPerLocationInputOrOutputComponent(ioVariable, ioDefinition.Location, ioDefinition.Component, isOutput);
if (hasComponent)
{
varType &= AggregateType.ElementTypeMask;
}
- else if (ioVariable == IoVariable.UserDefined && context.Config.HasTransformFeedbackOutputs(isOutput))
+ else if (ioVariable == IoVariable.UserDefined && context.Definitions.HasTransformFeedbackOutputs(isOutput))
{
varType &= AggregateType.ElementTypeMask;
- varType |= context.Config.GetTransformFeedbackOutputComponents(ioDefinition.Location, ioDefinition.Component) switch
+ varType |= context.Definitions.GetTransformFeedbackOutputComponents(ioDefinition.Location, ioDefinition.Component) switch
{
2 => AggregateType.Vector2,
3 => AggregateType.Vector3,
@@ -395,20 +413,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
var spvType = context.GetType(varType, IoMap.GetSpirvBuiltInArrayLength(ioVariable));
bool builtInPassthrough = false;
- if (!isPerPatch && IoMap.IsPerVertex(ioVariable, context.Config.Stage, isOutput))
+ if (!isPerPatch && IoMap.IsPerVertex(ioVariable, context.Definitions.Stage, isOutput))
{
- int arraySize = context.Config.Stage == ShaderStage.Geometry ? context.InputVertices : 32;
+ int arraySize = context.Definitions.Stage == ShaderStage.Geometry ? context.InputVertices : 32;
spvType = context.TypeArray(spvType, context.Constant(context.TypeU32(), arraySize));
- if (context.Config.GpPassthrough && context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough())
+ if (context.Definitions.GpPassthrough && context.HostCapabilities.SupportsGeometryShaderPassthrough)
{
builtInPassthrough = true;
}
}
- if (context.Config.Stage == ShaderStage.TessellationControl && isOutput && !isPerPatch)
+ if (context.Definitions.Stage == ShaderStage.TessellationControl && isOutput && !isPerPatch)
{
- spvType = context.TypeArray(spvType, context.Constant(context.TypeU32(), context.Config.ThreadsPerInputPrimitive));
+ spvType = context.TypeArray(spvType, context.Constant(context.TypeU32(), context.Definitions.ThreadsPerInputPrimitive));
}
var spvPointerType = context.TypePointer(storageClass, spvType);
@@ -426,7 +444,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
context.Decorate(spvVar, Decoration.Patch);
}
- if (context.Config.GpuAccessor.QueryHostReducedPrecision() && ioVariable == IoVariable.Position)
+ if (context.HostCapabilities.ReducedPrecision && ioVariable == IoVariable.Position)
{
context.Decorate(spvVar, Decoration.Invariant);
}
@@ -439,7 +457,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
if (ioVariable == IoVariable.UserDefined)
{
- int location = context.Config.GetPerPatchAttributeLocation(ioDefinition.Location);
+ int location = context.AttributeUsage.GetPerPatchAttributeLocation(ioDefinition.Location);
context.Decorate(spvVar, Decoration.Location, (LiteralInteger)location);
}
@@ -455,8 +473,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
if (!isOutput &&
!isPerPatch &&
- (context.Config.PassthroughAttributes & (1 << ioDefinition.Location)) != 0 &&
- context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough())
+ (context.AttributeUsage.PassthroughAttributes & (1 << ioDefinition.Location)) != 0 &&
+ context.HostCapabilities.SupportsGeometryShaderPassthrough)
{
context.Decorate(spvVar, Decoration.PassthroughNV);
}
@@ -465,13 +483,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
int location = ioDefinition.Location;
- if (context.Config.Stage == ShaderStage.Fragment && context.Config.GpuAccessor.QueryDualSourceBlendEnable())
+ if (context.Definitions.Stage == ShaderStage.Fragment && context.Definitions.DualSourceBlend)
{
- int firstLocation = BitOperations.TrailingZeroCount(context.Config.UsedOutputAttributes);
int index = location - firstLocation;
- int mask = 3 << firstLocation;
- if ((uint)index < 2 && (context.Config.UsedOutputAttributes & mask) == mask)
+ if ((uint)index < 2)
{
context.Decorate(spvVar, Decoration.Location, (LiteralInteger)firstLocation);
context.Decorate(spvVar, Decoration.Index, (LiteralInteger)index);
@@ -499,7 +515,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
break;
}
}
- else if (context.Config.TryGetTransformFeedbackOutput(
+ else if (context.Definitions.TryGetTransformFeedbackOutput(
ioVariable,
ioDefinition.Location,
ioDefinition.Component,
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
index 9489397b..30ce7f8b 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
@@ -240,10 +240,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
// Barrier on divergent control flow paths may cause the GPU to hang,
// so skip emitting the barrier for those cases.
- if (!context.Config.GpuAccessor.QueryHostSupportsShaderBarrierDivergence() &&
+ if (!context.HostCapabilities.SupportsShaderBarrierDivergence &&
(context.CurrentBlock.Type != AstBlockType.Main || context.MayHaveReturned || !context.IsMainFunction))
{
- context.Config.GpuAccessor.Log($"Shader has barrier on potentially divergent block, the barrier will be removed.");
+ context.Logger.Log("Shader has barrier on potentially divergent block, the barrier will be removed.");
return OperationResult.Invalid;
}
@@ -546,7 +546,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
private static OperationResult GenerateFSIBegin(CodeGenContext context, AstOperation operation)
{
- if (context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
+ if (context.HostCapabilities.SupportsFragmentShaderInterlock)
{
context.BeginInvocationInterlockEXT();
}
@@ -556,7 +556,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
private static OperationResult GenerateFSIEnd(CodeGenContext context, AstOperation operation)
{
- if (context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
+ if (context.HostCapabilities.SupportsFragmentShaderInterlock)
{
context.EndInvocationInterlockEXT();
}
@@ -1446,7 +1446,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
lodBias = Src(AggregateType.FP32);
}
- if (!isGather && !intCoords && !isMultisample && !hasLodLevel && !hasDerivatives && context.Config.Stage != ShaderStage.Fragment)
+ if (!isGather && !intCoords && !isMultisample && !hasLodLevel && !hasDerivatives && context.Definitions.Stage != ShaderStage.Fragment)
{
// Implicit LOD is only valid on fragment.
// Use the LOD bias as explicit LOD if available.
@@ -1804,8 +1804,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
}
BufferDefinition buffer = storageKind == StorageKind.ConstantBuffer
- ? context.Config.Properties.ConstantBuffers[bindingIndex.Value]
- : context.Config.Properties.StorageBuffers[bindingIndex.Value];
+ ? context.Properties.ConstantBuffers[bindingIndex.Value]
+ : context.Properties.StorageBuffers[bindingIndex.Value];
StructureField field = buffer.Type.Fields[fieldIndex.Value];
storageClass = StorageClass.Uniform;
@@ -1825,13 +1825,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
if (storageKind == StorageKind.LocalMemory)
{
storageClass = StorageClass.Private;
- varType = context.Config.Properties.LocalMemories[bindingId.Value].Type & AggregateType.ElementTypeMask;
+ varType = context.Properties.LocalMemories[bindingId.Value].Type & AggregateType.ElementTypeMask;
baseObj = context.LocalMemories[bindingId.Value];
}
else
{
storageClass = StorageClass.Workgroup;
- varType = context.Config.Properties.SharedMemories[bindingId.Value].Type & AggregateType.ElementTypeMask;
+ varType = context.Properties.SharedMemories[bindingId.Value].Type & AggregateType.ElementTypeMask;
baseObj = context.SharedMemories[bindingId.Value];
}
break;
@@ -1851,7 +1851,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
int location = 0;
int component = 0;
- if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
+ if (context.Definitions.HasPerLocationInputOrOutput(ioVariable, isOutput))
{
if (operation.GetSource(srcIndex++) is not AstOperand vecIndex || vecIndex.Type != OperandType.Constant)
{
@@ -1863,7 +1863,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
if (operation.SourcesCount > srcIndex &&
operation.GetSource(srcIndex) is AstOperand elemIndex &&
elemIndex.Type == OperandType.Constant &&
- context.Config.HasPerLocationInputOrOutputComponent(ioVariable, location, elemIndex.Value, isOutput))
+ context.Definitions.HasPerLocationInputOrOutputComponent(ioVariable, location, elemIndex.Value, isOutput))
{
component = elemIndex.Value;
srcIndex++;
@@ -1872,11 +1872,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
if (ioVariable == IoVariable.UserDefined)
{
- varType = context.Config.GetUserDefinedType(location, isOutput);
+ varType = context.Definitions.GetUserDefinedType(location, isOutput);
}
else if (ioVariable == IoVariable.FragmentOutputColor)
{
- varType = context.Config.GetFragmentOutputColorType(location);
+ varType = context.Definitions.GetFragmentOutputColorType(location);
}
else
{
@@ -2076,7 +2076,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
var result = emitF(context.TypeFP64(), context.GetFP64(src1), context.GetFP64(src2));
- if (!context.Config.GpuAccessor.QueryHostReducedPrecision() || operation.ForcePrecise)
+ if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
{
context.Decorate(result, Decoration.NoContraction);
}
@@ -2087,7 +2087,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
var result = emitF(context.TypeFP32(), context.GetFP32(src1), context.GetFP32(src2));
- if (!context.Config.GpuAccessor.QueryHostReducedPrecision() || operation.ForcePrecise)
+ if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
{
context.Decorate(result, Decoration.NoContraction);
}
@@ -2147,7 +2147,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
var result = emitF(context.TypeFP64(), context.GetFP64(src1), context.GetFP64(src2), context.GetFP64(src3));
- if (!context.Config.GpuAccessor.QueryHostReducedPrecision() || operation.ForcePrecise)
+ if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
{
context.Decorate(result, Decoration.NoContraction);
}
@@ -2158,7 +2158,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
var result = emitF(context.TypeFP32(), context.GetFP32(src1), context.GetFP32(src2), context.GetFP32(src3));
- if (!context.Config.GpuAccessor.QueryHostReducedPrecision() || operation.ForcePrecise)
+ if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
{
context.Decorate(result, Decoration.NoContraction);
}
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs
index 21797975..5eee888e 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs
@@ -35,7 +35,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
HelperFunctionsMask.ShuffleXor |
HelperFunctionsMask.SwizzleAdd;
- public static byte[] Generate(StructuredProgramInfo info, ShaderConfig config)
+ public static byte[] Generate(StructuredProgramInfo info, CodeGenParameters parameters)
{
SpvInstructionPool instPool;
SpvLiteralIntegerPool integerPool;
@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
integerPool = _integerPool.Allocate();
}
- CodeGenContext context = new(info, config, instPool, integerPool);
+ CodeGenContext context = new(info, parameters, instPool, integerPool);
context.AddCapability(Capability.GroupNonUniformBallot);
context.AddCapability(Capability.GroupNonUniformShuffle);
@@ -56,39 +56,40 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
context.AddCapability(Capability.ImageQuery);
context.AddCapability(Capability.SampledBuffer);
- if (config.TransformFeedbackEnabled && config.LastInVertexPipeline)
+ if (parameters.Definitions.TransformFeedbackEnabled && parameters.Definitions.LastInVertexPipeline)
{
context.AddCapability(Capability.TransformFeedback);
}
- if (config.Stage == ShaderStage.Fragment)
+ if (parameters.Definitions.Stage == ShaderStage.Fragment)
{
if (context.Info.IoDefinitions.Contains(new IoDefinition(StorageKind.Input, IoVariable.Layer)))
{
context.AddCapability(Capability.Geometry);
}
- if (context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
+ if (context.HostCapabilities.SupportsFragmentShaderInterlock)
{
context.AddCapability(Capability.FragmentShaderPixelInterlockEXT);
context.AddExtension("SPV_EXT_fragment_shader_interlock");
}
}
- else if (config.Stage == ShaderStage.Geometry)
+ else if (parameters.Definitions.Stage == ShaderStage.Geometry)
{
context.AddCapability(Capability.Geometry);
- if (config.GpPassthrough && context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough())
+ if (parameters.Definitions.GpPassthrough && context.HostCapabilities.SupportsGeometryShaderPassthrough)
{
context.AddExtension("SPV_NV_geometry_shader_passthrough");
context.AddCapability(Capability.GeometryShaderPassthroughNV);
}
}
- else if (config.Stage == ShaderStage.TessellationControl || config.Stage == ShaderStage.TessellationEvaluation)
+ else if (parameters.Definitions.Stage == ShaderStage.TessellationControl ||
+ parameters.Definitions.Stage == ShaderStage.TessellationEvaluation)
{
context.AddCapability(Capability.Tessellation);
}
- else if (config.Stage == ShaderStage.Vertex)
+ else if (parameters.Definitions.Stage == ShaderStage.Vertex)
{
context.AddCapability(Capability.DrawParameters);
}
@@ -170,15 +171,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
if (funcIndex == 0)
{
- context.AddEntryPoint(context.Config.Stage.Convert(), spvFunc, "main", context.GetMainInterface());
+ context.AddEntryPoint(context.Definitions.Stage.Convert(), spvFunc, "main", context.GetMainInterface());
- if (context.Config.Stage == ShaderStage.TessellationControl)
+ if (context.Definitions.Stage == ShaderStage.TessellationControl)
{
- context.AddExecutionMode(spvFunc, ExecutionMode.OutputVertices, (SpvLiteralInteger)context.Config.ThreadsPerInputPrimitive);
+ context.AddExecutionMode(spvFunc, ExecutionMode.OutputVertices, (SpvLiteralInteger)context.Definitions.ThreadsPerInputPrimitive);
}
- else if (context.Config.Stage == ShaderStage.TessellationEvaluation)
+ else if (context.Definitions.Stage == ShaderStage.TessellationEvaluation)
{
- switch (context.Config.GpuAccessor.QueryTessPatchType())
+ switch (context.Definitions.TessPatchType)
{
case TessPatchType.Isolines:
context.AddExecutionMode(spvFunc, ExecutionMode.Isolines);
@@ -191,7 +192,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
break;
}
- switch (context.Config.GpuAccessor.QueryTessSpacing())
+ switch (context.Definitions.TessSpacing)
{
case TessSpacing.EqualSpacing:
context.AddExecutionMode(spvFunc, ExecutionMode.SpacingEqual);
@@ -204,9 +205,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
break;
}
- bool tessCw = context.Config.GpuAccessor.QueryTessCw();
+ bool tessCw = context.Definitions.TessCw;
- if (context.Config.Options.TargetApi == TargetApi.Vulkan)
+ if (context.TargetApi == TargetApi.Vulkan)
{
// We invert the front face on Vulkan backend, so we need to do that here as well.
tessCw = !tessCw;
@@ -221,37 +222,35 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
context.AddExecutionMode(spvFunc, ExecutionMode.VertexOrderCcw);
}
}
- else if (context.Config.Stage == ShaderStage.Geometry)
+ else if (context.Definitions.Stage == ShaderStage.Geometry)
{
- InputTopology inputTopology = context.Config.GpuAccessor.QueryPrimitiveTopology();
-
- context.AddExecutionMode(spvFunc, inputTopology switch
+ context.AddExecutionMode(spvFunc, context.Definitions.InputTopology switch
{
InputTopology.Points => ExecutionMode.InputPoints,
InputTopology.Lines => ExecutionMode.InputLines,
InputTopology.LinesAdjacency => ExecutionMode.InputLinesAdjacency,
InputTopology.Triangles => ExecutionMode.Triangles,
InputTopology.TrianglesAdjacency => ExecutionMode.InputTrianglesAdjacency,
- _ => throw new InvalidOperationException($"Invalid input topology \"{inputTopology}\"."),
+ _ => throw new InvalidOperationException($"Invalid input topology \"{context.Definitions.InputTopology}\"."),
});
- context.AddExecutionMode(spvFunc, ExecutionMode.Invocations, (SpvLiteralInteger)context.Config.ThreadsPerInputPrimitive);
+ context.AddExecutionMode(spvFunc, ExecutionMode.Invocations, (SpvLiteralInteger)context.Definitions.ThreadsPerInputPrimitive);
- context.AddExecutionMode(spvFunc, context.Config.OutputTopology switch
+ context.AddExecutionMode(spvFunc, context.Definitions.OutputTopology switch
{
OutputTopology.PointList => ExecutionMode.OutputPoints,
OutputTopology.LineStrip => ExecutionMode.OutputLineStrip,
OutputTopology.TriangleStrip => ExecutionMode.OutputTriangleStrip,
- _ => throw new InvalidOperationException($"Invalid output topology \"{context.Config.OutputTopology}\"."),
+ _ => throw new InvalidOperationException($"Invalid output topology \"{context.Definitions.OutputTopology}\"."),
});
- int maxOutputVertices = context.Config.GpPassthrough ? context.InputVertices : context.Config.MaxOutputVertices;
+ int maxOutputVertices = context.Definitions.GpPassthrough ? context.InputVertices : context.Definitions.MaxOutputVertices;
context.AddExecutionMode(spvFunc, ExecutionMode.OutputVertices, (SpvLiteralInteger)maxOutputVertices);
}
- else if (context.Config.Stage == ShaderStage.Fragment)
+ else if (context.Definitions.Stage == ShaderStage.Fragment)
{
- context.AddExecutionMode(spvFunc, context.Config.Properties.OriginUpperLeft
+ context.AddExecutionMode(spvFunc, context.Definitions.OriginUpperLeft
? ExecutionMode.OriginUpperLeft
: ExecutionMode.OriginLowerLeft);
@@ -260,22 +259,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
context.AddExecutionMode(spvFunc, ExecutionMode.DepthReplacing);
}
- if (context.Config.GpuAccessor.QueryEarlyZForce())
+ if (context.Definitions.EarlyZForce)
{
context.AddExecutionMode(spvFunc, ExecutionMode.EarlyFragmentTests);
}
if ((info.HelperFunctionsMask & HelperFunctionsMask.FSI) != 0 &&
- context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
+ context.HostCapabilities.SupportsFragmentShaderInterlock)
{
context.AddExecutionMode(spvFunc, ExecutionMode.PixelInterlockOrderedEXT);
}
}
- else if (context.Config.Stage == ShaderStage.Compute)
+ else if (context.Definitions.Stage == ShaderStage.Compute)
{
- var localSizeX = (SpvLiteralInteger)context.Config.GpuAccessor.QueryComputeLocalSizeX();
- var localSizeY = (SpvLiteralInteger)context.Config.GpuAccessor.QueryComputeLocalSizeY();
- var localSizeZ = (SpvLiteralInteger)context.Config.GpuAccessor.QueryComputeLocalSizeZ();
+ var localSizeX = (SpvLiteralInteger)context.Definitions.ComputeLocalSizeX;
+ var localSizeY = (SpvLiteralInteger)context.Definitions.ComputeLocalSizeY;
+ var localSizeZ = (SpvLiteralInteger)context.Definitions.ComputeLocalSizeZ;
context.AddExecutionMode(
spvFunc,
@@ -285,7 +284,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
localSizeZ);
}
- if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline)
+ if (context.Definitions.TransformFeedbackEnabled && context.Definitions.LastInVertexPipeline)
{
context.AddExecutionMode(spvFunc, ExecutionMode.Xfb);
}