1#include <metal_texture>
2#include <metal_matrix>
3
4using namespace metal;
5
6struct SolidVertexInput
7{
8    float2 position [[attribute(0)]];
9};
10
11struct SolidVertexOutput
12{
13    float4 position [[position]];
14    float pointSize [[point_size]];
15};
16
17vertex SolidVertexOutput SDL_Solid_vertex(SolidVertexInput in [[stage_in]],
18                                          constant float4x4 &projection [[buffer(2)]],
19                                          constant float4x4 &transform [[buffer(3)]])
20{
21    SolidVertexOutput v;
22    v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f);
23    v.pointSize = 1.0f;
24    return v;
25}
26
27fragment float4 SDL_Solid_fragment(const device float4 &col [[buffer(0)]])
28{
29    return col;
30}
31
32struct CopyVertexInput
33{
34    float2 position [[attribute(0)]];
35    float2 texcoord [[attribute(1)]];
36};
37
38struct CopyVertexOutput
39{
40    float4 position [[position]];
41    float2 texcoord;
42};
43
44vertex CopyVertexOutput SDL_Copy_vertex(CopyVertexInput in [[stage_in]],
45                                        constant float4x4 &projection [[buffer(2)]],
46                                        constant float4x4 &transform [[buffer(3)]])
47{
48    CopyVertexOutput v;
49    v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f);
50    v.texcoord = in.texcoord;
51    return v;
52}
53
54fragment float4 SDL_Copy_fragment(CopyVertexOutput vert [[stage_in]],
55                                  const device float4 &col [[buffer(0)]],
56                                  texture2d<float> tex [[texture(0)]],
57                                  sampler s [[sampler(0)]])
58{
59    return tex.sample(s, vert.texcoord) * col;
60}
61
62struct YUVDecode
63{
64    float3 offset;
65    float3 Rcoeff;
66    float3 Gcoeff;
67    float3 Bcoeff;
68};
69
70fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]],
71                                 const device float4 &col [[buffer(0)]],
72                                 constant YUVDecode &decode [[buffer(1)]],
73                                 texture2d<float> texY [[texture(0)]],
74                                 texture2d_array<float> texUV [[texture(1)]],
75                                 sampler s [[sampler(0)]])
76{
77    float3 yuv;
78    yuv.x = texY.sample(s, vert.texcoord).r;
79    yuv.y = texUV.sample(s, vert.texcoord, 0).r;
80    yuv.z = texUV.sample(s, vert.texcoord, 1).r;
81
82    yuv += decode.offset;
83
84    return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
85}
86
87fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]],
88                                 const device float4 &col [[buffer(0)]],
89                                 constant YUVDecode &decode [[buffer(1)]],
90                                 texture2d<float> texY [[texture(0)]],
91                                 texture2d<float> texUV [[texture(1)]],
92                                 sampler s [[sampler(0)]])
93{
94    float3 yuv;
95    yuv.x = texY.sample(s, vert.texcoord).r;
96    yuv.yz = texUV.sample(s, vert.texcoord).rg;
97
98    yuv += decode.offset;
99
100    return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
101}
102
103fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]],
104                                 const device float4 &col [[buffer(0)]],
105                                 constant YUVDecode &decode [[buffer(1)]],
106                                 texture2d<float> texY [[texture(0)]],
107                                 texture2d<float> texUV [[texture(1)]],
108                                 sampler s [[sampler(0)]])
109{
110    float3 yuv;
111    yuv.x = texY.sample(s, vert.texcoord).r;
112    yuv.yz = texUV.sample(s, vert.texcoord).gr;
113
114    yuv += decode.offset;
115
116    return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
117}
118