aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-11-12 20:20:40 -0300
committerGitHub <noreply@github.com>2022-11-12 20:20:40 -0300
commit9daf029f356898336de1ad0c63b6c36e261e4f9b (patch)
treed8e6c2edffa5babbb1486801b081cd367cec5c4b /Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
parent51a27032f01826e0cec56c53da4359fd2c38c8f3 (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.cs87
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);