Refactor attribute handling on the shader generator (#4565)

* Refactor attribute handling on the shader generator

* Implement gl_ViewportMask[]

* Add back the Intel FrontFacing bug workaround

* Fix GLSL transform feedback outputs mistmatch with fragment stage

* Shader cache version bump

* Fix geometry shader recognition

* PR feedback

* Delete GetOperandDef and GetOperandUse

* Remove replacements that are no longer needed on GLSL compilation on Vulkan

* Fix incorrect load for per-patch outputs

* Fix build
This commit is contained in:
gdkchan 2023-04-25 19:51:07 -03:00 committed by GitHub
parent 097562bc6c
commit 9f12e50a54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
56 changed files with 1967 additions and 1746 deletions

View file

@ -59,6 +59,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
context.AppendLine("#extension GL_NV_geometry_shader_passthrough : enable");
}
if (context.Config.GpuAccessor.QueryHostSupportsViewportMask())
{
context.AppendLine("#extension GL_NV_viewport_array2 : enable");
}
context.AppendLine("#pragma optionNV(fastmath off)");
context.AppendLine();
@ -215,7 +220,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline)
{
var tfOutput = context.Info.GetTransformFeedbackOutput(AttributeConsts.PositionX);
var tfOutput = context.Config.GetTransformFeedbackOutput(AttributeConsts.PositionX);
if (tfOutput.Valid)
{
context.AppendLine($"layout (xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}) out gl_PerVertex");
@ -552,7 +557,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
private static void DeclareInputAttribute(CodeGenContext context, StructuredProgramInfo info, int attr)
{
string suffix = AttributeInfo.IsArrayAttributeGlsl(context.Config.Stage, isOutAttr: false) ? "[]" : string.Empty;
string suffix = IsArrayAttributeGlsl(context.Config.Stage, isOutAttr: false) ? "[]" : string.Empty;
string iq = string.Empty;
if (context.Config.Stage == ShaderStage.Fragment)
@ -569,8 +574,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
if (context.Config.TransformFeedbackEnabled && context.Config.Stage == ShaderStage.Fragment)
{
int attrOffset = AttributeConsts.UserAttributeBase + attr * 16;
int components = context.Info.GetTransformFeedbackOutputComponents(attrOffset);
int components = context.Config.GetTransformFeedbackOutputComponents(attr, 0);
if (components > 1)
{
@ -652,13 +656,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
private static void DeclareOutputAttribute(CodeGenContext context, int attr)
{
string suffix = AttributeInfo.IsArrayAttributeGlsl(context.Config.Stage, isOutAttr: true) ? "[]" : string.Empty;
string suffix = IsArrayAttributeGlsl(context.Config.Stage, isOutAttr: true) ? "[]" : string.Empty;
string name = $"{DefaultNames.OAttributePrefix}{attr}{suffix}";
if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline)
{
int attrOffset = AttributeConsts.UserAttributeBase + attr * 16;
int components = context.Info.GetTransformFeedbackOutputComponents(attrOffset);
int components = context.Config.GetTransformFeedbackOutputComponents(attr, 0);
if (components > 1)
{
@ -672,7 +675,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
string xfb = string.Empty;
var tfOutput = context.Info.GetTransformFeedbackOutput(attrOffset);
var tfOutput = context.Config.GetTransformFeedbackOutput(attr, 0);
if (tfOutput.Valid)
{
xfb = $", xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}";
@ -687,7 +690,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
string xfb = string.Empty;
var tfOutput = context.Info.GetTransformFeedbackOutput(attrOffset + c * 4);
var tfOutput = context.Config.GetTransformFeedbackOutput(attr, c);
if (tfOutput.Valid)
{
xfb = $", xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}";
@ -726,6 +729,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
context.AppendLine($"layout (location = {attr}, index = 1) out vec4 {name2};");
}
private static bool IsArrayAttributeGlsl(ShaderStage stage, bool isOutAttr)
{
if (isOutAttr)
{
return stage == ShaderStage.TessellationControl;
}
else
{
return stage == ShaderStage.TessellationControl ||
stage == ShaderStage.TessellationEvaluation ||
stage == ShaderStage.Geometry;
}
}
private static void DeclareUsedOutputAttributesPerPatch(CodeGenContext context, HashSet<int> attrs)
{
foreach (int attr in attrs.Order())