aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/IoMap.cs
blob: d2ff0085cd8be50339f8efc5074db94b87cd9d07 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using Ryujinx.Graphics.Shader.Translation;
using static Spv.Specification;

namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
    static class IoMap
    {
        // At least 16 attributes are guaranteed by the spec.
        private const int MaxAttributes = 16;

        public static (BuiltIn, AggregateType) GetSpirvBuiltIn(IoVariable ioVariable)
        {
            return ioVariable switch
            {
                IoVariable.BaseInstance => (BuiltIn.BaseInstance, AggregateType.S32),
                IoVariable.BaseVertex => (BuiltIn.BaseVertex, AggregateType.S32),
                IoVariable.ClipDistance => (BuiltIn.ClipDistance, AggregateType.Array | AggregateType.FP32),
                IoVariable.CtaId => (BuiltIn.WorkgroupId, AggregateType.Vector3 | AggregateType.U32),
                IoVariable.DrawIndex => (BuiltIn.DrawIndex, AggregateType.S32),
                IoVariable.FragmentCoord => (BuiltIn.FragCoord, AggregateType.Vector4 | AggregateType.FP32),
                IoVariable.FragmentOutputDepth => (BuiltIn.FragDepth, AggregateType.FP32),
                IoVariable.FrontFacing => (BuiltIn.FrontFacing, AggregateType.Bool),
                IoVariable.InstanceId => (BuiltIn.InstanceId, AggregateType.S32),
                IoVariable.InstanceIndex => (BuiltIn.InstanceIndex, AggregateType.S32),
                IoVariable.InvocationId => (BuiltIn.InvocationId, AggregateType.S32),
                IoVariable.Layer => (BuiltIn.Layer, AggregateType.S32),
                IoVariable.PatchVertices => (BuiltIn.PatchVertices, AggregateType.S32),
                IoVariable.PointCoord => (BuiltIn.PointCoord, AggregateType.Vector2 | AggregateType.FP32),
                IoVariable.PointSize => (BuiltIn.PointSize, AggregateType.FP32),
                IoVariable.Position => (BuiltIn.Position, AggregateType.Vector4 | AggregateType.FP32),
                IoVariable.PrimitiveId => (BuiltIn.PrimitiveId, AggregateType.S32),
                IoVariable.SubgroupEqMask => (BuiltIn.SubgroupEqMask, AggregateType.Vector4 | AggregateType.U32),
                IoVariable.SubgroupGeMask => (BuiltIn.SubgroupGeMask, AggregateType.Vector4 | AggregateType.U32),
                IoVariable.SubgroupGtMask => (BuiltIn.SubgroupGtMask, AggregateType.Vector4 | AggregateType.U32),
                IoVariable.SubgroupLaneId => (BuiltIn.SubgroupLocalInvocationId, AggregateType.U32),
                IoVariable.SubgroupLeMask => (BuiltIn.SubgroupLeMask, AggregateType.Vector4 | AggregateType.U32),
                IoVariable.SubgroupLtMask => (BuiltIn.SubgroupLtMask, AggregateType.Vector4 | AggregateType.U32),
                IoVariable.TessellationCoord => (BuiltIn.TessCoord, AggregateType.Vector3 | AggregateType.FP32),
                IoVariable.TessellationLevelInner => (BuiltIn.TessLevelInner, AggregateType.Array | AggregateType.FP32),
                IoVariable.TessellationLevelOuter => (BuiltIn.TessLevelOuter, AggregateType.Array | AggregateType.FP32),
                IoVariable.ThreadId => (BuiltIn.LocalInvocationId, AggregateType.Vector3 | AggregateType.U32),
                IoVariable.ThreadKill => (BuiltIn.HelperInvocation, AggregateType.Bool),
                IoVariable.VertexId => (BuiltIn.VertexId, AggregateType.S32),
                IoVariable.VertexIndex => (BuiltIn.VertexIndex, AggregateType.S32),
                IoVariable.ViewportIndex => (BuiltIn.ViewportIndex, AggregateType.S32),
                IoVariable.ViewportMask => (BuiltIn.ViewportMaskNV, AggregateType.Array | AggregateType.S32),
                _ => (default, AggregateType.Invalid)
            };
        }

        public static int GetSpirvBuiltInArrayLength(IoVariable ioVariable)
        {
            return ioVariable switch
            {
                IoVariable.ClipDistance => 8,
                IoVariable.TessellationLevelInner => 2,
                IoVariable.TessellationLevelOuter => 4,
                IoVariable.ViewportMask => 1,
                IoVariable.UserDefined => MaxAttributes,
                _ => 1
            };
        }

        public static bool IsPerVertex(IoVariable ioVariable, ShaderStage stage, bool isOutput)
        {
            switch (ioVariable)
            {
                case IoVariable.Layer:
                case IoVariable.ViewportIndex:
                case IoVariable.PointSize:
                case IoVariable.Position:
                case IoVariable.UserDefined:
                case IoVariable.ClipDistance:
                case IoVariable.PointCoord:
                case IoVariable.ViewportMask:
                return !isOutput &&
                       (stage == ShaderStage.TessellationControl ||
                       stage == ShaderStage.TessellationEvaluation ||
                       stage == ShaderStage.Geometry);
            }

            return false;
        }
    }
}