Stop using glTransformFeedbackVaryings and use explicit layout on the shader (#3012)

* Stop using glTransformFeedbackVarying and use explicit layout on the shader

* This is no longer needed

* Shader cache version bump

* Fix gl_PerVertex output for tessellation control shaders
This commit is contained in:
gdkchan 2022-01-21 12:35:21 -03:00 committed by GitHub
parent 0e59573f2b
commit 7e967d796c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 192 additions and 164 deletions

View file

@ -103,6 +103,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
return _info.Functions[id];
}
public TransformFeedbackOutput GetTransformFeedbackOutput(int location, int component)
{
int index = (AttributeConsts.UserAttributeBase / 4) + location * 4 + component;
return _info.TransformFeedbackOutputs[index];
}
public TransformFeedbackOutput GetTransformFeedbackOutput(int location)
{
int index = location / 4;
return _info.TransformFeedbackOutputs[index];
}
private void UpdateIndentation()
{
_indentation = GetIndentation(_level);

View file

@ -191,6 +191,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
context.AppendLine();
}
if (context.Config.Stage != ShaderStage.Compute &&
context.Config.Stage != ShaderStage.Fragment &&
context.Config.TransformFeedbackEnabled)
{
var tfOutput = context.GetTransformFeedbackOutput(AttributeConsts.PositionX);
if (tfOutput.Valid)
{
context.AppendLine($"layout (xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}) out gl_PerVertex");
context.EnterScope();
context.AppendLine("vec4 gl_Position;");
context.LeaveScope(context.Config.Stage == ShaderStage.TessellationControl ? " gl_out[];" : ";");
}
}
}
else
{
@ -514,7 +528,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
string pass = (context.Config.PassthroughAttributes & (1 << attr)) != 0 ? "passthrough, " : string.Empty;
string name = $"{DefaultNames.IAttributePrefix}{attr}";
if ((context.Config.Options.Flags & TranslationFlags.Feedback) != 0)
if (context.Config.TransformFeedbackEnabled && context.Config.Stage != ShaderStage.Vertex)
{
for (int c = 0; c < 4; c++)
{
@ -559,13 +573,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
string suffix = OperandManager.IsArrayAttribute(context.Config.Stage, isOutAttr: true) ? "[]" : string.Empty;
string name = $"{DefaultNames.OAttributePrefix}{attr}{suffix}";
if ((context.Config.Options.Flags & TranslationFlags.Feedback) != 0)
if (context.Config.TransformFeedbackEnabled && context.Config.Stage != ShaderStage.Fragment)
{
for (int c = 0; c < 4; c++)
{
char swzMask = "xyzw"[c];
context.AppendLine($"layout (location = {attr}, component = {c}) out float {name}_{swzMask};");
string xfb = string.Empty;
var tfOutput = context.GetTransformFeedbackOutput(attr, c);
if (tfOutput.Valid)
{
xfb = $", xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}";
}
context.AppendLine($"layout (location = {attr}, component = {c}{xfb}) out float {name}_{swzMask};");
}
}
else

View file

@ -194,7 +194,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
return name + $"[{(value >> 4)}]." + swzMask;
}
else if (config.Options.Flags.HasFlag(TranslationFlags.Feedback))
else if (config.TransformFeedbackEnabled && (config.Stage != ShaderStage.Vertex || isOutAttr))
{
string name = $"{prefix}{(value >> 4)}_{swzMask}";

View file

@ -1,69 +0,0 @@
using Ryujinx.Graphics.Shader.Translation;
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
public static class Varying
{
public static string GetName(int offset)
{
offset <<= 2;
if (offset >= AttributeConsts.UserAttributeBase &&
offset < AttributeConsts.UserAttributeEnd)
{
offset -= AttributeConsts.UserAttributeBase;
string name = $"{ DefaultNames.OAttributePrefix}{(offset >> 4)}";
name += "_" + "xyzw"[(offset >> 2) & 3];
return name;
}
switch (offset)
{
case AttributeConsts.PositionX:
case AttributeConsts.PositionY:
case AttributeConsts.PositionZ:
case AttributeConsts.PositionW:
return "gl_Position";
case AttributeConsts.PointSize:
return "gl_PointSize";
case AttributeConsts.ClipDistance0:
return "gl_ClipDistance[0]";
case AttributeConsts.ClipDistance1:
return "gl_ClipDistance[1]";
case AttributeConsts.ClipDistance2:
return "gl_ClipDistance[2]";
case AttributeConsts.ClipDistance3:
return "gl_ClipDistance[3]";
case AttributeConsts.ClipDistance4:
return "gl_ClipDistance[4]";
case AttributeConsts.ClipDistance5:
return "gl_ClipDistance[5]";
case AttributeConsts.ClipDistance6:
return "gl_ClipDistance[6]";
case AttributeConsts.ClipDistance7:
return "gl_ClipDistance[7]";
case AttributeConsts.VertexId:
return "gl_VertexID";
}
return null;
}
public static int GetSize(int offset)
{
switch (offset << 2)
{
case AttributeConsts.PositionX:
case AttributeConsts.PositionY:
case AttributeConsts.PositionZ:
case AttributeConsts.PositionW:
return 4;
}
return 1;
}
}
}