diff options
author | gdkchan <gab.dark.100@gmail.com> | 2022-11-12 20:20:40 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-12 20:20:40 -0300 |
commit | 9daf029f356898336de1ad0c63b6c36e261e4f9b (patch) | |
tree | d8e6c2edffa5babbb1486801b081cd367cec5c4b /Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs | |
parent | 51a27032f01826e0cec56c53da4359fd2c38c8f3 (diff) |
Use vector transform feedback outputs if possible (#3832)1.1.342
Diffstat (limited to 'Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs')
-rw-r--r-- | Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs | 87 |
1 files changed, 60 insertions, 27 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs index c007b9a2..fafb917d 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs @@ -440,11 +440,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv { PixelImap iq = PixelImap.Unused; - if (context.Config.Stage == ShaderStage.Fragment && - attr >= AttributeConsts.UserAttributeBase && - attr < AttributeConsts.UserAttributeEnd) + if (context.Config.Stage == ShaderStage.Fragment) { - iq = context.Config.ImapTypes[(attr - AttributeConsts.UserAttributeBase) / 16].GetFirstUsedType(); + if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd) + { + iq = context.Config.ImapTypes[(attr - AttributeConsts.UserAttributeBase) / 16].GetFirstUsedType(); + } + else + { + AttributeInfo attrInfo = AttributeInfo.From(context.Config, attr, isOutAttr: false); + AggregateType elemType = attrInfo.Type & AggregateType.ElementTypeMask; + + if (attrInfo.IsBuiltin && (elemType == AggregateType.S32 || elemType == AggregateType.U32)) + { + iq = PixelImap.Constant; + } + } } DeclareInputOrOutput(context, attr, perPatch, isOutAttr: false, iq); @@ -516,7 +527,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv ((isOutAttr && context.Config.LastInVertexPipeline) || (!isOutAttr && context.Config.Stage == ShaderStage.Fragment))) { - DeclareInputOrOutput(context, attr, (attr >> 2) & 3, isOutAttr, iq); + DeclareTransformFeedbackInputOrOutput(context, attr, isOutAttr, iq); return; } @@ -572,7 +583,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline && isOutAttr) { - var tfOutput = context.GetTransformFeedbackOutput(attrInfo.BaseValue); + var tfOutput = context.Info.GetTransformFeedbackOutput(attrInfo.BaseValue); if (tfOutput.Valid) { context.Decorate(spvVar, Decoration.XfbBuffer, (LiteralInteger)tfOutput.Buffer); @@ -595,24 +606,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv context.Decorate(spvVar, Decoration.Location, (LiteralInteger)location); - if (!isOutAttr) + if (!isOutAttr && + !perPatch && + (context.Config.PassthroughAttributes & (1 << location)) != 0 && + context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough()) { - if (!perPatch && - (context.Config.PassthroughAttributes & (1 << location)) != 0 && - context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough()) - { - context.Decorate(spvVar, Decoration.PassthroughNV); - } - - switch (iq) - { - case PixelImap.Constant: - context.Decorate(spvVar, Decoration.Flat); - break; - case PixelImap.ScreenLinear: - context.Decorate(spvVar, Decoration.NoPerspective); - break; - } + context.Decorate(spvVar, Decoration.PassthroughNV); } } else if (attr >= AttributeConsts.FragmentOutputColorBase && attr < AttributeConsts.FragmentOutputColorEnd) @@ -621,22 +620,52 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv context.Decorate(spvVar, Decoration.Location, (LiteralInteger)location); } + if (!isOutAttr) + { + switch (iq) + { + case PixelImap.Constant: + context.Decorate(spvVar, Decoration.Flat); + break; + case PixelImap.ScreenLinear: + context.Decorate(spvVar, Decoration.NoPerspective); + break; + } + } + context.AddGlobalVariable(spvVar); dict.Add(attrInfo.BaseValue, spvVar); } - private static void DeclareInputOrOutput(CodeGenContext context, int attr, int component, bool isOutAttr, PixelImap iq = PixelImap.Unused) + private static void DeclareTransformFeedbackInputOrOutput(CodeGenContext context, int attr, bool isOutAttr, PixelImap iq = PixelImap.Unused) { var dict = isOutAttr ? context.Outputs : context.Inputs; var attrInfo = AttributeInfo.From(context.Config, attr, isOutAttr); + bool hasComponent = true; + int component = (attr >> 2) & 3; + int components = 1; + var type = attrInfo.Type & AggregateType.ElementTypeMask; + + if (context.Config.LastInPipeline && isOutAttr) + { + components = context.Info.GetTransformFeedbackOutputComponents(attr); + + if (components > 1) + { + attr &= ~0xf; + type = AggregateType.Vector | AggregateType.FP32; + hasComponent = false; + } + } + if (dict.ContainsKey(attr)) { return; } var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input; - var attrType = context.GetType(attrInfo.Type & AggregateType.ElementTypeMask); + var attrType = context.GetType(type, components); if (AttributeInfo.IsArrayAttributeSpirv(context.Config.Stage, isOutAttr) && (!attrInfo.IsBuiltin || AttributeInfo.IsArrayBuiltIn(attr))) { @@ -656,11 +685,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv int location = (attr - AttributeConsts.UserAttributeBase) / 16; context.Decorate(spvVar, Decoration.Location, (LiteralInteger)location); - context.Decorate(spvVar, Decoration.Component, (LiteralInteger)component); + + if (hasComponent) + { + context.Decorate(spvVar, Decoration.Component, (LiteralInteger)component); + } if (isOutAttr) { - var tfOutput = context.GetTransformFeedbackOutput(location, component); + var tfOutput = context.Info.GetTransformFeedbackOutput(attr); if (tfOutput.Valid) { context.Decorate(spvVar, Decoration.XfbBuffer, (LiteralInteger)tfOutput.Buffer); |