Hash :
c0c938af
Author :
Date :
2020-05-11T00:50:00
Metal: draw 1 triangle instead of 2 for fullscreen shaders. Reference article in favour of one big triangle instead of 2: https://michaldrobot.com/2014/04/01/gcn-execution-patterns-in-full-screen-passes/ According to this article, the performance could be increased by ~10% for fullscreen shaders. Bug: angleproject:2634 Change-Id: Ia5b04c40f0587e3cb8680c0f30f7b68d9d7a3efe Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2193192 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org>
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 87 88 89 90 91 92 93 94 95 96 97 98
//
// Copyright 2019 The ANGLE Project. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// blit.metal: Implements blitting texture content to current frame buffer.
#include "common.h"
struct BlitParams
{
// 0: lower left, 1: lower right, 2: upper left
float2 srcTexCoords[3];
int srcLevel;
bool srcLuminance; // source texture is luminance texture
bool dstFlipViewportY;
bool dstLuminance; // destination texture is luminance;
};
struct BlitVSOut
{
float4 position [[position]];
float2 texCoords [[user(locn1)]];
};
vertex BlitVSOut blitVS(unsigned int vid [[ vertex_id ]],
constant BlitParams &options [[buffer(0)]])
{
BlitVSOut output;
output.position = float4(gCorners[vid], 0.0, 1.0);
output.texCoords = options.srcTexCoords[vid];
if (!options.dstFlipViewportY)
{
// If viewport is not flipped, we have to flip Y in normalized device coordinates.
// Since NDC has Y is opposite direction of viewport coodrinates.
output.position.y = -output.position.y;
}
return output;
}
float4 blitSampleTexture(texture2d<float> srcTexture,
float2 texCoords,
constant BlitParams &options)
{
constexpr sampler textureSampler(mag_filter::linear,
min_filter::linear);
float4 output = srcTexture.sample(textureSampler, texCoords, level(options.srcLevel));
if (options.srcLuminance)
{
output.gb = float2(output.r, output.r);
}
return output;
}
float4 blitOutput(float4 color, constant BlitParams &options)
{
float4 ret = color;
if (options.dstLuminance)
{
ret.r = ret.g = ret.b = color.r;
}
return ret;
}
fragment float4 blitFS(BlitVSOut input [[stage_in]],
texture2d<float> srcTexture [[texture(0)]],
constant BlitParams &options [[buffer(0)]])
{
return blitOutput(blitSampleTexture(srcTexture, input.texCoords, options), options);
}
fragment float4 blitPremultiplyAlphaFS(BlitVSOut input [[stage_in]],
texture2d<float> srcTexture [[texture(0)]],
constant BlitParams &options [[buffer(0)]])
{
float4 output = blitSampleTexture(srcTexture, input.texCoords, options);
output.xyz *= output.a;
return blitOutput(output, options);
}
fragment float4 blitUnmultiplyAlphaFS(BlitVSOut input [[stage_in]],
texture2d<float> srcTexture [[texture(0)]],
constant BlitParams &options [[buffer(0)]])
{
float4 output = blitSampleTexture(srcTexture, input.texCoords, options);
if (output.a != 0.0)
{
output.xyz *= 1.0 / output.a;
}
return blitOutput(output, options);
}