0
0
Fork 0

Remove output interpolation qualifier (#1070)

This commit is contained in:
gdkchan 2020-04-01 22:24:55 -03:00 committed by GitHub
parent 45c7424f7c
commit 5b5239ab5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 14 additions and 71 deletions

View file

@ -145,8 +145,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
gpShaders.Shaders[3] = TranslateGraphicsShader(state, ShaderStage.Geometry, addresses.Geometry); gpShaders.Shaders[3] = TranslateGraphicsShader(state, ShaderStage.Geometry, addresses.Geometry);
gpShaders.Shaders[4] = TranslateGraphicsShader(state, ShaderStage.Fragment, addresses.Fragment); gpShaders.Shaders[4] = TranslateGraphicsShader(state, ShaderStage.Fragment, addresses.Fragment);
BackpropQualifiers(gpShaders);
List<IShader> hostShaders = new List<IShader>(); List<IShader> hostShaders = new List<IShader>();
for (int stage = 0; stage < gpShaders.Shaders.Length; stage++) for (int stage = 0; stage < gpShaders.Shaders.Length; stage++)
@ -375,45 +373,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
return new CachedShader(program, codeCached); return new CachedShader(program, codeCached);
} }
/// <summary>
/// Performs backwards propagation of interpolation qualifiers or later shader stages input,
/// to ealier shader stages output.
/// This is required by older versions of OpenGL (pre-4.3).
/// </summary>
/// <param name="program">Graphics shader cached code</param>
private void BackpropQualifiers(GraphicsShader program)
{
ShaderProgram fragmentShader = program.Shaders[4]?.Program;
bool isFirst = true;
for (int stage = 3; stage >= 0; stage--)
{
if (program.Shaders[stage] == null)
{
continue;
}
// We need to iterate backwards, since we do name replacement,
// and it would otherwise replace a subset of the longer names.
for (int attr = 31; attr >= 0; attr--)
{
string iq = fragmentShader?.Info.InterpolationQualifiers[attr].ToGlslQualifier() ?? string.Empty;
if (isFirst && !string.IsNullOrEmpty(iq))
{
program.Shaders[stage].Program.Replace($"{DefineNames.OutQualifierPrefixName}{attr}", iq);
}
else
{
program.Shaders[stage].Program.Replace($"{DefineNames.OutQualifierPrefixName}{attr} ", string.Empty);
}
}
isFirst = false;
}
}
/// <summary> /// <summary>
/// Gets the primitive topology for the current draw. /// Gets the primitive topology for the current draw.
/// This is required by geometry shaders. /// This is required by geometry shaders.

View file

@ -400,9 +400,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{ {
for (int attr = 0; attr < MaxAttributes; attr++) for (int attr = 0; attr < MaxAttributes; attr++)
{ {
string iq = $"{DefineNames.OutQualifierPrefixName}{attr} "; context.AppendLine($"layout (location = {attr}) out vec4 {DefaultNames.OAttributePrefix}{attr};");
context.AppendLine($"layout (location = {attr}) {iq}out vec4 {DefaultNames.OAttributePrefix}{attr};");
} }
foreach (int attr in info.OAttributes.OrderBy(x => x).Where(x => x >= MaxAttributes)) foreach (int attr in info.OAttributes.OrderBy(x => x).Where(x => x >= MaxAttributes))

View file

@ -1,7 +0,0 @@
namespace Ryujinx.Graphics.Shader
{
public static class DefineNames
{
public const string OutQualifierPrefixName = "S_OUT_QUALIFIER";
}
}

View file

@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Graphics.Shader namespace Ryujinx.Graphics.Shader
{ {
[Flags] [Flags]
public enum InterpolationQualifier enum InterpolationQualifier
{ {
None = 0, None = 0,
@ -17,18 +17,17 @@ namespace Ryujinx.Graphics.Shader
FlagsMask = Centroid | Sample FlagsMask = Centroid | Sample
} }
public static class InterpolationQualifierExtensions static class InterpolationQualifierExtensions
{ {
public static string ToGlslQualifier(this InterpolationQualifier iq) public static string ToGlslQualifier(this InterpolationQualifier iq)
{ {
string output = string.Empty; string output = (iq & ~InterpolationQualifier.FlagsMask) switch
switch (iq & ~InterpolationQualifier.FlagsMask)
{ {
case InterpolationQualifier.Flat: output = "flat"; break; InterpolationQualifier.Flat => "flat",
case InterpolationQualifier.NoPerspective: output = "noperspective"; break; InterpolationQualifier.NoPerspective => "noperspective",
case InterpolationQualifier.Smooth: output = "smooth"; break; InterpolationQualifier.Smooth => "smooth",
} _ => string.Empty
};
if ((iq & InterpolationQualifier.Centroid) != 0) if ((iq & InterpolationQualifier.Centroid) != 0)
{ {

View file

@ -10,25 +10,20 @@ namespace Ryujinx.Graphics.Shader
public ReadOnlyCollection<TextureDescriptor> Textures { get; } public ReadOnlyCollection<TextureDescriptor> Textures { get; }
public ReadOnlyCollection<TextureDescriptor> Images { get; } public ReadOnlyCollection<TextureDescriptor> Images { get; }
public ReadOnlyCollection<InterpolationQualifier> InterpolationQualifiers { get; }
public bool UsesInstanceId { get; } public bool UsesInstanceId { get; }
internal ShaderProgramInfo( internal ShaderProgramInfo(
BufferDescriptor[] cBuffers, BufferDescriptor[] cBuffers,
BufferDescriptor[] sBuffers, BufferDescriptor[] sBuffers,
TextureDescriptor[] textures, TextureDescriptor[] textures,
TextureDescriptor[] images, TextureDescriptor[] images,
InterpolationQualifier[] interpolationQualifiers, bool usesInstanceId)
bool usesInstanceId)
{ {
CBuffers = Array.AsReadOnly(cBuffers); CBuffers = Array.AsReadOnly(cBuffers);
SBuffers = Array.AsReadOnly(sBuffers); SBuffers = Array.AsReadOnly(sBuffers);
Textures = Array.AsReadOnly(textures); Textures = Array.AsReadOnly(textures);
Images = Array.AsReadOnly(images); Images = Array.AsReadOnly(images);
InterpolationQualifiers = Array.AsReadOnly(interpolationQualifiers);
UsesInstanceId = usesInstanceId; UsesInstanceId = usesInstanceId;
} }
} }

View file

@ -79,7 +79,6 @@ namespace Ryujinx.Graphics.Shader.Translation
program.SBufferDescriptors, program.SBufferDescriptors,
program.TextureDescriptors, program.TextureDescriptors,
program.ImageDescriptors, program.ImageDescriptors,
sInfo.InterpolationQualifiers,
sInfo.UsesInstanceId); sInfo.UsesInstanceId);
string glslCode = program.Code; string glslCode = program.Code;