• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//
2// Copyright 2019 The ANGLE Project. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// blit.metal: Implements blitting texture content to current frame buffer.
7
8#include "common.h"
9
10
11struct BlitParams
12{
13    // 0: lower left, 1: lower right, 2: upper left
14    float2 srcTexCoords[3];
15    int srcLevel;
16    bool srcLuminance; // source texture is luminance texture
17    bool dstFlipViewportY;
18    bool dstLuminance; // destination texture is luminance;
19};
20
21struct BlitVSOut
22{
23    float4 position [[position]];
24    float2 texCoords [[user(locn1)]];
25};
26
27vertex BlitVSOut blitVS(unsigned int vid [[ vertex_id ]],
28                         constant BlitParams &options [[buffer(0)]])
29{
30    BlitVSOut output;
31    output.position  = float4(gCorners[vid], 0.0, 1.0);
32    output.texCoords = options.srcTexCoords[vid];
33
34    if (!options.dstFlipViewportY)
35    {
36        // If viewport is not flipped, we have to flip Y in normalized device coordinates.
37        // Since NDC has Y is opposite direction of viewport coodrinates.
38        output.position.y = -output.position.y;
39    }
40
41    return output;
42}
43
44float4 blitSampleTexture(texture2d<float> srcTexture,
45                     float2 texCoords,
46                     constant BlitParams &options)
47{
48    constexpr sampler textureSampler(mag_filter::linear,
49                                     min_filter::linear);
50    float4 output = srcTexture.sample(textureSampler, texCoords, level(options.srcLevel));
51
52    if (options.srcLuminance)
53    {
54        output.gb = float2(output.r, output.r);
55    }
56
57    return output;
58}
59
60float4 blitOutput(float4 color, constant BlitParams &options)
61{
62    float4 ret = color;
63
64    if (options.dstLuminance)
65    {
66        ret.r = ret.g = ret.b = color.r;
67    }
68
69    return ret;
70}
71
72fragment float4 blitFS(BlitVSOut input [[stage_in]],
73                       texture2d<float> srcTexture [[texture(0)]],
74                       constant BlitParams &options [[buffer(0)]])
75{
76    return blitOutput(blitSampleTexture(srcTexture, input.texCoords, options), options);
77}
78
79fragment float4 blitPremultiplyAlphaFS(BlitVSOut input [[stage_in]],
80                                       texture2d<float> srcTexture [[texture(0)]],
81                                       constant BlitParams &options [[buffer(0)]])
82{
83    float4 output = blitSampleTexture(srcTexture, input.texCoords, options);
84    output.xyz *= output.a;
85    return blitOutput(output, options);
86}
87
88fragment float4 blitUnmultiplyAlphaFS(BlitVSOut input [[stage_in]],
89                                      texture2d<float> srcTexture [[texture(0)]],
90                                      constant BlitParams &options [[buffer(0)]])
91{
92    float4 output = blitSampleTexture(srcTexture, input.texCoords, options);
93    if (output.a != 0.0)
94    {
95        output.xyz *= 1.0 / output.a;
96    }
97    return blitOutput(output, options);
98}
99