diff options
Diffstat (limited to 'Ryujinx.Graphics.Shader')
12 files changed, 108 insertions, 7 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs index 4f2751b1..b2eeb5f5 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs @@ -46,6 +46,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl } else { + if (context.Config.Stage == ShaderStage.Vertex) + { + context.AppendLine("#extension GL_ARB_shader_draw_parameters : enable"); + } + context.AppendLine("#extension GL_ARB_shader_viewport_layer_array : enable"); } diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs index 031b1c44..b7891426 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs @@ -48,10 +48,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { AttributeConsts.TessCoordY, new BuiltInAttribute("gl_TessCoord.y", VariableType.F32) }, { AttributeConsts.InstanceId, new BuiltInAttribute("gl_InstanceID", VariableType.S32) }, { AttributeConsts.VertexId, new BuiltInAttribute("gl_VertexID", VariableType.S32) }, - { AttributeConsts.BaseInstance, new BuiltInAttribute("gl_BaseInstance", VariableType.S32) }, - { AttributeConsts.BaseVertex, new BuiltInAttribute("gl_BaseVertex", VariableType.S32) }, + { AttributeConsts.BaseInstance, new BuiltInAttribute("gl_BaseInstanceARB", VariableType.S32) }, + { AttributeConsts.BaseVertex, new BuiltInAttribute("gl_BaseVertexARB", VariableType.S32) }, { AttributeConsts.InstanceIndex, new BuiltInAttribute("gl_InstanceIndex", VariableType.S32) }, { AttributeConsts.VertexIndex, new BuiltInAttribute("gl_VertexIndex", VariableType.S32) }, + { AttributeConsts.DrawIndex, new BuiltInAttribute("gl_DrawIDARB", VariableType.S32) }, { AttributeConsts.FrontFacing, new BuiltInAttribute("gl_FrontFacing", VariableType.Bool) }, // Special. diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs index fafb917d..54b00708 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs @@ -743,6 +743,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv AttributeConsts.BaseVertex => BuiltIn.BaseVertex, AttributeConsts.InstanceIndex => BuiltIn.InstanceIndex, AttributeConsts.VertexIndex => BuiltIn.VertexIndex, + AttributeConsts.DrawIndex => BuiltIn.DrawIndex, AttributeConsts.FrontFacing => BuiltIn.FrontFacing, AttributeConsts.FragmentOutputDepth => BuiltIn.FragDepth, AttributeConsts.ThreadKill => BuiltIn.HelperInvocation, diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs index 69283b0a..95df077b 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs @@ -89,6 +89,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv { context.AddCapability(Capability.Tessellation); } + else if (config.Stage == ShaderStage.Vertex) + { + context.AddCapability(Capability.DrawParameters); + } context.AddExtension("SPV_KHR_shader_ballot"); context.AddExtension("SPV_KHR_subgroup_vote"); diff --git a/Ryujinx.Graphics.Shader/Constants.cs b/Ryujinx.Graphics.Shader/Constants.cs index 86af48cf..7f1445ed 100644 --- a/Ryujinx.Graphics.Shader/Constants.cs +++ b/Ryujinx.Graphics.Shader/Constants.cs @@ -6,5 +6,9 @@ namespace Ryujinx.Graphics.Shader public const int MaxAttributes = 16; public const int AllAttributesMask = (int)(uint.MaxValue >> (32 - MaxAttributes)); + + public const int NvnBaseVertexByteOffset = 0x640; + public const int NvnBaseInstanceByteOffset = 0x644; + public const int NvnDrawIndexByteOffset = 0x648; } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/Ryujinx.Graphics.Shader/IGpuAccessor.cs index 2cdc81fb..4f800a14 100644 --- a/Ryujinx.Graphics.Shader/IGpuAccessor.cs +++ b/Ryujinx.Graphics.Shader/IGpuAccessor.cs @@ -169,6 +169,15 @@ namespace Ryujinx.Graphics.Shader } /// <summary> + /// Queries whenever the current draw has written the base vertex and base instance into Constant Buffer 0. + /// </summary> + /// <returns>True if the shader translator can assume that the constant buffer contains the base IDs, false otherwise</returns> + bool QueryHasConstantBufferDrawParameters() + { + return false; + } + + /// <summary> /// Queries host about the presence of the FrontFacing built-in variable bug. /// </summary> /// <returns>True if the bug is present on the host device used, false otherwise</returns> diff --git a/Ryujinx.Graphics.Shader/ShaderProgramInfo.cs b/Ryujinx.Graphics.Shader/ShaderProgramInfo.cs index 659f6167..bb75b10a 100644 --- a/Ryujinx.Graphics.Shader/ShaderProgramInfo.cs +++ b/Ryujinx.Graphics.Shader/ShaderProgramInfo.cs @@ -12,6 +12,7 @@ namespace Ryujinx.Graphics.Shader public ShaderStage Stage { get; } public bool UsesInstanceId { get; } + public bool UsesDrawParameters { get; } public bool UsesRtLayer { get; } public byte ClipDistancesWritten { get; } public int FragmentOutputMap { get; } @@ -23,6 +24,7 @@ namespace Ryujinx.Graphics.Shader TextureDescriptor[] images, ShaderStage stage, bool usesInstanceId, + bool usesDrawParameters, bool usesRtLayer, byte clipDistancesWritten, int fragmentOutputMap) @@ -34,6 +36,7 @@ namespace Ryujinx.Graphics.Shader Stage = stage; UsesInstanceId = usesInstanceId; + UsesDrawParameters = usesDrawParameters; UsesRtLayer = usesRtLayer; ClipDistancesWritten = clipDistancesWritten; FragmentOutputMap = fragmentOutputMap; diff --git a/Ryujinx.Graphics.Shader/Translation/AttributeConsts.cs b/Ryujinx.Graphics.Shader/Translation/AttributeConsts.cs index 47367f89..863e19a0 100644 --- a/Ryujinx.Graphics.Shader/Translation/AttributeConsts.cs +++ b/Ryujinx.Graphics.Shader/Translation/AttributeConsts.cs @@ -100,5 +100,6 @@ namespace Ryujinx.Graphics.Shader.Translation public const int BaseVertex = 0x2000054; public const int InstanceIndex = 0x2000058; public const int VertexIndex = 0x200005c; + public const int DrawIndex = 0x2000060; } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/Translation/AttributeInfo.cs b/Ryujinx.Graphics.Shader/Translation/AttributeInfo.cs index 6e95722f..839edbe9 100644 --- a/Ryujinx.Graphics.Shader/Translation/AttributeInfo.cs +++ b/Ryujinx.Graphics.Shader/Translation/AttributeInfo.cs @@ -31,6 +31,7 @@ namespace Ryujinx.Graphics.Shader.Translation { AttributeConsts.BaseVertex, new AttributeInfo(AttributeConsts.BaseVertex, 0, 1, AggregateType.S32) }, { AttributeConsts.InstanceIndex, new AttributeInfo(AttributeConsts.InstanceIndex, 0, 1, AggregateType.S32) }, { AttributeConsts.VertexIndex, new AttributeInfo(AttributeConsts.VertexIndex, 0, 1, AggregateType.S32) }, + { AttributeConsts.DrawIndex, new AttributeInfo(AttributeConsts.DrawIndex, 0, 1, AggregateType.S32) }, { AttributeConsts.FrontFacing, new AttributeInfo(AttributeConsts.FrontFacing, 0, 1, AggregateType.Bool) }, // Special. diff --git a/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs b/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs index a2363fcb..c035f212 100644 --- a/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs +++ b/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs @@ -17,10 +17,11 @@ namespace Ryujinx.Graphics.Shader.Translation Bindless = 1 << 2, InstanceId = 1 << 3, - RtLayer = 1 << 4, - CbIndexing = 1 << 5, - IaIndexing = 1 << 6, - OaIndexing = 1 << 7, - FixedFuncAttr = 1 << 8 + DrawParameters = 1 << 4, + RtLayer = 1 << 5, + CbIndexing = 1 << 6, + IaIndexing = 1 << 7, + OaIndexing = 1 << 8, + FixedFuncAttr = 1 << 9 } } diff --git a/Ryujinx.Graphics.Shader/Translation/Rewriter.cs b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs index 4d66597f..640717f9 100644 --- a/Ryujinx.Graphics.Shader/Translation/Rewriter.cs +++ b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs @@ -12,6 +12,9 @@ namespace Ryujinx.Graphics.Shader.Translation { public static void RunPass(BasicBlock[] blocks, ShaderConfig config) { + bool isVertexShader = config.Stage == ShaderStage.Vertex; + bool hasConstantBufferDrawParameters = config.GpuAccessor.QueryHasConstantBufferDrawParameters(); + for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) { BasicBlock block = blocks[blkIndex]; @@ -23,6 +26,21 @@ namespace Ryujinx.Graphics.Shader.Translation continue; } + if (isVertexShader) + { + if (hasConstantBufferDrawParameters) + { + if (ReplaceConstantBufferWithDrawParameters(operation)) + { + config.SetUsedFeature(FeatureFlags.DrawParameters); + } + } + else if (HasConstantBufferDrawParameters(operation)) + { + config.SetUsedFeature(FeatureFlags.DrawParameters); + } + } + if (UsesGlobalMemory(operation.Inst)) { node = RewriteGlobalAccess(node, config); @@ -528,5 +546,57 @@ namespace Ryujinx.Graphics.Shader.Translation return node; } + + private static bool ReplaceConstantBufferWithDrawParameters(Operation operation) + { + bool modified = false; + + for (int srcIndex = 0; srcIndex < operation.SourcesCount; srcIndex++) + { + Operand src = operation.GetSource(srcIndex); + + if (src.Type == OperandType.ConstantBuffer && src.GetCbufSlot() == 0) + { + switch (src.GetCbufOffset()) + { + case Constants.NvnBaseVertexByteOffset / 4: + operation.SetSource(srcIndex, Attribute(AttributeConsts.BaseVertex)); + modified = true; + break; + case Constants.NvnBaseInstanceByteOffset / 4: + operation.SetSource(srcIndex, Attribute(AttributeConsts.BaseInstance)); + modified = true; + break; + case Constants.NvnDrawIndexByteOffset / 4: + operation.SetSource(srcIndex, Attribute(AttributeConsts.DrawIndex)); + modified = true; + break; + } + } + } + + return modified; + } + + private static bool HasConstantBufferDrawParameters(Operation operation) + { + for (int srcIndex = 0; srcIndex < operation.SourcesCount; srcIndex++) + { + Operand src = operation.GetSource(srcIndex); + + if (src.Type == OperandType.ConstantBuffer && src.GetCbufSlot() == 0) + { + switch (src.GetCbufOffset()) + { + case Constants.NvnBaseVertexByteOffset / 4: + case Constants.NvnBaseInstanceByteOffset / 4: + case Constants.NvnDrawIndexByteOffset / 4: + return true; + } + } + } + + return false; + } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs index 8741f848..58a934c7 100644 --- a/Ryujinx.Graphics.Shader/Translation/Translator.cs +++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs @@ -86,6 +86,7 @@ namespace Ryujinx.Graphics.Shader.Translation config.GetImageDescriptors(), config.Stage, config.UsedFeatures.HasFlag(FeatureFlags.InstanceId), + config.UsedFeatures.HasFlag(FeatureFlags.DrawParameters), config.UsedFeatures.HasFlag(FeatureFlags.RtLayer), config.ClipDistancesWritten, config.OmapTargets); |
