diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2022-07-05 19:58:36 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-05 19:58:36 -0300 |
| commit | b46b63e06a36845175f68331edb5ddeeb34de27b (patch) | |
| tree | 1ca8adf9541d1f68e420feb853a612413d690725 /Ryujinx.Graphics.Shader | |
| parent | 594246ea4727c9377b1c916934d9b257a1b5d0d0 (diff) | |
Add support for alpha to coverage dithering (#3069)
* Add support for alpha to coverage dithering
* Shader cache version bump
* Fix wrong alpha register
* Ensure support buffer is cleared
* New shader specialization based approach
Diffstat (limited to 'Ryujinx.Graphics.Shader')
| -rw-r--r-- | Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/IGpuAccessor.cs | 9 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Translation/EmitterContext.cs | 31 |
3 files changed, 41 insertions, 1 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs index 59a7ccdc..54578b79 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs @@ -615,7 +615,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl private static void DeclareSupportUniformBlock(CodeGenContext context, ShaderStage stage, int scaleElements) { - bool needsSupportBlock = stage == ShaderStage.Fragment || + bool needsSupportBlock = stage == ShaderStage.Fragment || (context.Config.LastInVertexPipeline && context.Config.GpuAccessor.QueryViewportTransformDisable()); if (!needsSupportBlock && scaleElements == 0) diff --git a/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/Ryujinx.Graphics.Shader/IGpuAccessor.cs index 42f210a5..878c7180 100644 --- a/Ryujinx.Graphics.Shader/IGpuAccessor.cs +++ b/Ryujinx.Graphics.Shader/IGpuAccessor.cs @@ -35,6 +35,15 @@ namespace Ryujinx.Graphics.Shader ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize); /// <summary> + /// Queries whenever the alpha-to-coverage dithering feature is enabled. + /// </summary> + /// <returns>True if the feature is enabled, false otherwise</returns> + bool QueryAlphaToCoverageDitherEnable() + { + return false; + } + + /// <summary> /// Queries the binding number of a constant buffer. /// </summary> /// <param name="index">Constant buffer index</param> diff --git a/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs b/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs index ba3b551d..332b3e02 100644 --- a/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs +++ b/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs @@ -205,6 +205,8 @@ namespace Ryujinx.Graphics.Shader.Translation } else if (Config.Stage == ShaderStage.Fragment) { + GenerateAlphaToCoverageDitherDiscard(); + if (Config.OmapDepth) { Operand dest = Attribute(AttributeConsts.FragmentOutputDepth); @@ -266,6 +268,35 @@ namespace Ryujinx.Graphics.Shader.Translation } } + private void GenerateAlphaToCoverageDitherDiscard() + { + // If the feature is disabled, or alpha is not written, then we're done. + if (!Config.GpuAccessor.QueryAlphaToCoverageDitherEnable() || (Config.OmapTargets & 8) == 0) + { + return; + } + + // 11 11 11 10 10 10 10 00 + // 11 01 01 01 01 00 00 00 + Operand ditherMask = Const(unchecked((int)0xfbb99110u)); + + Operand x = this.BitwiseAnd(this.FP32ConvertToU32(Attribute(AttributeConsts.PositionX)), Const(1)); + Operand y = this.BitwiseAnd(this.FP32ConvertToU32(Attribute(AttributeConsts.PositionY)), Const(1)); + Operand xy = this.BitwiseOr(x, this.ShiftLeft(y, Const(1))); + + Operand alpha = Register(3, RegisterType.Gpr); + Operand scaledAlpha = this.FPMultiply(this.FPSaturate(alpha), ConstF(8)); + Operand quantizedAlpha = this.IMinimumU32(this.FP32ConvertToU32(scaledAlpha), Const(7)); + Operand shift = this.BitwiseOr(this.ShiftLeft(quantizedAlpha, Const(2)), xy); + Operand opaque = this.BitwiseAnd(this.ShiftRightU32(ditherMask, shift), Const(1)); + + Operand a2cDitherEndLabel = Label(); + + this.BranchIfTrue(a2cDitherEndLabel, opaque); + this.Discard(); + this.MarkLabel(a2cDitherEndLabel); + } + public Operation[] GetOperations() { return _operations.ToArray(); |
