Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 37ea80f

Browse files
author
Jonah Williams
authored
[Impeller] convert blend shaders to half precision (#40897)
[Impeller] convert blend shaders to half precision
1 parent 2a7b34a commit 37ea80f

37 files changed

+291
-232
lines changed

impeller/compiler/shader_lib/impeller/blending.glsl

Lines changed: 71 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -7,46 +7,48 @@
77

88
#include <impeller/branching.glsl>
99
#include <impeller/constants.glsl>
10+
#include <impeller/types.glsl>
1011

1112
//------------------------------------------------------------------------------
1213
/// HSV utilities.
1314
///
1415

15-
float IPLuminosity(vec3 color) {
16-
return color.r * 0.3 + color.g * 0.59 + color.b * 0.11;
16+
float16_t IPLuminosity(f16vec3 color) {
17+
return color.r * 0.3hf + color.g * 0.59hf + color.b * 0.11hf;
1718
}
1819

1920
/// Scales the color's luma by the amount necessary to place the color
2021
/// components in a 1-0 range.
21-
vec3 IPClipColor(vec3 color) {
22-
float lum = IPLuminosity(color);
23-
float mn = min(min(color.r, color.g), color.b);
24-
float mx = max(max(color.r, color.g), color.b);
22+
f16vec3 IPClipColor(f16vec3 color) {
23+
float16_t lum = IPLuminosity(color);
24+
float16_t mn = min(min(color.r, color.g), color.b);
25+
float16_t mx = max(max(color.r, color.g), color.b);
2526
// `lum - mn` and `mx - lum` will always be >= 0 in the following conditions,
2627
// so adding a tiny value is enough to make these divisions safe.
27-
if (mn < 0) {
28-
color = lum + (((color - lum) * lum) / (lum - mn + kEhCloseEnough));
28+
if (mn < 0.0hf) {
29+
color = lum + (((color - lum) * lum) / (lum - mn + kEhCloseEnoughHalf));
2930
}
30-
if (mx > 1) {
31-
color = lum + (((color - lum) * (1 - lum)) / (mx - lum + kEhCloseEnough));
31+
if (mx > 1.0hf) {
32+
color = lum +
33+
(((color - lum) * (1.0hf - lum)) / (mx - lum + kEhCloseEnoughHalf));
3234
}
3335
return color;
3436
}
3537

36-
vec3 IPSetLuminosity(vec3 color, float luminosity) {
37-
float relative_lum = luminosity - IPLuminosity(color);
38+
f16vec3 IPSetLuminosity(f16vec3 color, float16_t luminosity) {
39+
float16_t relative_lum = luminosity - IPLuminosity(color);
3840
return IPClipColor(color + relative_lum);
3941
}
4042

41-
float IPSaturation(vec3 color) {
43+
float16_t IPSaturation(f16vec3 color) {
4244
return max(max(color.r, color.g), color.b) -
4345
min(min(color.r, color.g), color.b);
4446
}
4547

46-
vec3 IPSetSaturation(vec3 color, float saturation) {
47-
float mn = min(min(color.r, color.g), color.b);
48-
float mx = max(max(color.r, color.g), color.b);
49-
return (mn < mx) ? ((color - mn) * saturation) / (mx - mn) : vec3(0);
48+
f16vec3 IPSetSaturation(f16vec3 color, float16_t saturation) {
49+
float16_t mn = min(min(color.r, color.g), color.b);
50+
float16_t mx = max(max(color.r, color.g), color.b);
51+
return (mn < mx) ? ((color - mn) * saturation) / (mx - mn) : f16vec3(0.0hf);
5052
}
5153

5254
//------------------------------------------------------------------------------
@@ -58,134 +60,136 @@ vec3 IPSetSaturation(vec3 color, float saturation) {
5860
/// applied to the destination using `SourceOver` alpha compositing.
5961
///
6062

61-
vec3 IPBlendScreen(vec3 dst, vec3 src) {
63+
f16vec3 IPBlendScreen(f16vec3 dst, f16vec3 src) {
6264
// https://www.w3.org/TR/compositing-1/#blendingscreen
6365
return dst + src - (dst * src);
6466
}
6567

66-
vec3 IPBlendHardLight(vec3 dst, vec3 src) {
68+
f16vec3 IPBlendHardLight(f16vec3 dst, f16vec3 src) {
6769
// https://www.w3.org/TR/compositing-1/#blendinghardlight
68-
return IPVec3Choose(dst * (2 * src), IPBlendScreen(dst, 2 * src - 1), src);
70+
return IPHalfVec3Choose(dst * (2.0hf * src),
71+
IPBlendScreen(dst, 2.0hf * src - 1.0hf), src);
6972
}
7073

71-
vec3 IPBlendOverlay(vec3 dst, vec3 src) {
74+
f16vec3 IPBlendOverlay(f16vec3 dst, f16vec3 src) {
7275
// https://www.w3.org/TR/compositing-1/#blendingoverlay
7376
// HardLight, but with reversed parameters.
7477
return IPBlendHardLight(src, dst);
7578
}
7679

77-
vec3 IPBlendDarken(vec3 dst, vec3 src) {
80+
f16vec3 IPBlendDarken(f16vec3 dst, f16vec3 src) {
7881
// https://www.w3.org/TR/compositing-1/#blendingdarken
7982
return min(dst, src);
8083
}
8184

82-
vec3 IPBlendLighten(vec3 dst, vec3 src) {
85+
f16vec3 IPBlendLighten(f16vec3 dst, f16vec3 src) {
8386
// https://www.w3.org/TR/compositing-1/#blendinglighten
8487
return max(dst, src);
8588
}
8689

87-
vec3 IPBlendColorDodge(vec3 dst, vec3 src) {
90+
f16vec3 IPBlendColorDodge(f16vec3 dst, f16vec3 src) {
8891
// https://www.w3.org/TR/compositing-1/#blendingcolordodge
8992

90-
vec3 color = min(vec3(1), dst / (1 - src));
93+
f16vec3 color = min(f16vec3(1.0hf), dst / (1.0hf - src));
9194

92-
if (dst.r < kEhCloseEnough) {
93-
color.r = 0;
95+
if (dst.r < kEhCloseEnoughHalf) {
96+
color.r = 0.0hf;
9497
}
95-
if (dst.g < kEhCloseEnough) {
96-
color.g = 0;
98+
if (dst.g < kEhCloseEnoughHalf) {
99+
color.g = 0.0hf;
97100
}
98-
if (dst.b < kEhCloseEnough) {
99-
color.b = 0;
101+
if (dst.b < kEhCloseEnoughHalf) {
102+
color.b = 0.0hf;
100103
}
101104

102-
if (1 - src.r < kEhCloseEnough) {
103-
color.r = 1;
105+
if (1.0hf - src.r < kEhCloseEnoughHalf) {
106+
color.r = 1.0hf;
104107
}
105-
if (1 - src.g < kEhCloseEnough) {
106-
color.g = 1;
108+
if (1.0hf - src.g < kEhCloseEnoughHalf) {
109+
color.g = 1.0hf;
107110
}
108-
if (1 - src.b < kEhCloseEnough) {
109-
color.b = 1;
111+
if (1.0hf - src.b < kEhCloseEnoughHalf) {
112+
color.b = 1.0hf;
110113
}
111114

112115
return color;
113116
}
114117

115-
vec3 IPBlendColorBurn(vec3 dst, vec3 src) {
118+
f16vec3 IPBlendColorBurn(f16vec3 dst, f16vec3 src) {
116119
// https://www.w3.org/TR/compositing-1/#blendingcolorburn
117120

118-
vec3 color = 1 - min(vec3(1), (1 - dst) / src);
121+
f16vec3 color = 1.0hf - min(f16vec3(1.0hf), (1.0hf - dst) / src);
119122

120-
if (1 - dst.r < kEhCloseEnough) {
121-
color.r = 1;
123+
if (1.0hf - dst.r < kEhCloseEnoughHalf) {
124+
color.r = 1.0hf;
122125
}
123-
if (1 - dst.g < kEhCloseEnough) {
124-
color.g = 1;
126+
if (1.0hf - dst.g < kEhCloseEnoughHalf) {
127+
color.g = 1.0hf;
125128
}
126-
if (1 - dst.b < kEhCloseEnough) {
127-
color.b = 1;
129+
if (1.0hf - dst.b < kEhCloseEnoughHalf) {
130+
color.b = 1.0hf;
128131
}
129132

130-
if (src.r < kEhCloseEnough) {
131-
color.r = 0;
133+
if (src.r < kEhCloseEnoughHalf) {
134+
color.r = 0.0hf;
132135
}
133-
if (src.g < kEhCloseEnough) {
134-
color.g = 0;
136+
if (src.g < kEhCloseEnoughHalf) {
137+
color.g = 0.0hf;
135138
}
136-
if (src.b < kEhCloseEnough) {
137-
color.b = 0;
139+
if (src.b < kEhCloseEnoughHalf) {
140+
color.b = 0.0hf;
138141
}
139142

140143
return color;
141144
}
142145

143-
vec3 IPBlendSoftLight(vec3 dst, vec3 src) {
146+
f16vec3 IPBlendSoftLight(f16vec3 dst, f16vec3 src) {
144147
// https://www.w3.org/TR/compositing-1/#blendingsoftlight
145148

146-
vec3 D = IPVec3ChooseCutoff(((16 * dst - 12) * dst + 4) * dst, //
147-
sqrt(dst), //
148-
dst, //
149-
0.25);
149+
f16vec3 D =
150+
IPHalfVec3ChooseCutoff(((16.0hf * dst - 12.0hf) * dst + 4.0hf) * dst, //
151+
sqrt(dst), //
152+
dst, //
153+
0.25hf);
150154

151-
return IPVec3Choose(dst - (1 - 2 * src) * dst * (1 - dst), //
152-
dst + (2 * src - 1) * (D - dst), //
153-
src);
155+
return IPHalfVec3Choose(dst - (1.0hf - 2.0hf * src) * dst * (1.0hf - dst), //
156+
dst + (2.0hf * src - 1.0hf) * (D - dst), //
157+
src);
154158
}
155159

156-
vec3 IPBlendDifference(vec3 dst, vec3 src) {
160+
f16vec3 IPBlendDifference(f16vec3 dst, f16vec3 src) {
157161
// https://www.w3.org/TR/compositing-1/#blendingdifference
158162
return abs(dst - src);
159163
}
160164

161-
vec3 IPBlendExclusion(vec3 dst, vec3 src) {
165+
f16vec3 IPBlendExclusion(f16vec3 dst, f16vec3 src) {
162166
// https://www.w3.org/TR/compositing-1/#blendingexclusion
163-
return dst + src - 2 * dst * src;
167+
return dst + src - 2.0hf * dst * src;
164168
}
165169

166-
vec3 IPBlendMultiply(vec3 dst, vec3 src) {
170+
f16vec3 IPBlendMultiply(f16vec3 dst, f16vec3 src) {
167171
// https://www.w3.org/TR/compositing-1/#blendingmultiply
168172
return dst * src;
169173
}
170174

171-
vec3 IPBlendHue(vec3 dst, vec3 src) {
175+
f16vec3 IPBlendHue(f16vec3 dst, f16vec3 src) {
172176
// https://www.w3.org/TR/compositing-1/#blendinghue
173177
return IPSetLuminosity(IPSetSaturation(src, IPSaturation(dst)),
174178
IPLuminosity(dst));
175179
}
176180

177-
vec3 IPBlendSaturation(vec3 dst, vec3 src) {
181+
f16vec3 IPBlendSaturation(f16vec3 dst, f16vec3 src) {
178182
// https://www.w3.org/TR/compositing-1/#blendingsaturation
179183
return IPSetLuminosity(IPSetSaturation(dst, IPSaturation(src)),
180184
IPLuminosity(dst));
181185
}
182186

183-
vec3 IPBlendColor(vec3 dst, vec3 src) {
187+
f16vec3 IPBlendColor(f16vec3 dst, f16vec3 src) {
184188
// https://www.w3.org/TR/compositing-1/#blendingcolor
185189
return IPSetLuminosity(src, IPLuminosity(dst));
186190
}
187191

188-
vec3 IPBlendLuminosity(vec3 dst, vec3 src) {
192+
f16vec3 IPBlendLuminosity(f16vec3 dst, f16vec3 src) {
189193
// https://www.w3.org/TR/compositing-1/#blendingluminosity
190194
return IPSetLuminosity(dst, IPLuminosity(src));
191195
}

impeller/compiler/shader_lib/impeller/branching.glsl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,24 @@ vec3 IPVec3Choose(vec3 a, vec3 b, vec3 value) {
4949
return IPVec3ChooseCutoff(a, b, value, 0.5);
5050
}
5151

52+
/// Perform a branchless greater than check for each vec3 component.
53+
///
54+
/// Returns 1.0 if x > y, otherwise 0.0.
55+
f16vec3 IPHalfVec3IsGreaterThan(f16vec3 x, f16vec3 y) {
56+
return max(sign(x - y), float16_t(0.0hf));
57+
}
58+
59+
/// For each vec3 component, if value > cutoff, return b, otherwise return a.
60+
f16vec3 IPHalfVec3ChooseCutoff(f16vec3 a,
61+
f16vec3 b,
62+
f16vec3 value,
63+
float16_t cutoff) {
64+
return mix(a, b, IPHalfVec3IsGreaterThan(value, f16vec3(cutoff)));
65+
}
66+
67+
/// For each vec3 component, if value > 0.5, return b, otherwise return a.
68+
f16vec3 IPHalfVec3Choose(f16vec3 a, f16vec3 b, f16vec3 value) {
69+
return IPHalfVec3ChooseCutoff(a, b, value, float16_t(0.5hf));
70+
}
71+
5272
#endif

impeller/compiler/shader_lib/impeller/constants.glsl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@
55
#ifndef CONSTANTS_GLSL_
66
#define CONSTANTS_GLSL_
77

8+
#include <impeller/types.glsl>
9+
810
const float kEhCloseEnough = 0.000001;
911

12+
// 1/1024.
13+
const float16_t kEhCloseEnoughHalf = 0.0009765625hf;
14+
1015
// 1 / (2 * pi)
1116
const float k1Over2Pi = 0.1591549430918;
1217

impeller/entity/shaders/blending/advanced_blend.glsl

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,21 @@
88
#include <impeller/types.glsl>
99

1010
uniform BlendInfo {
11-
float dst_input_alpha;
12-
float color_factor;
13-
vec4 color; // This color input is expected to be unpremultiplied.
11+
float16_t dst_input_alpha;
12+
float16_t color_factor;
13+
f16vec4 color; // This color input is expected to be unpremultiplied.
1414
}
1515
blend_info;
1616

17-
uniform sampler2D texture_sampler_dst;
18-
uniform sampler2D texture_sampler_src;
17+
uniform f16sampler2D texture_sampler_dst;
18+
uniform f16sampler2D texture_sampler_src;
1919

2020
in vec2 v_dst_texture_coords;
2121
in vec2 v_src_texture_coords;
2222

23-
out vec4 frag_color;
23+
out f16vec4 frag_color;
2424

25-
vec4 Sample(sampler2D texture_sampler, vec2 texture_coords) {
25+
f16vec4 Sample(f16sampler2D texture_sampler, vec2 texture_coords) {
2626
// gles 2.0 is the only backend without native decal support.
2727
#ifdef IMPELLER_TARGET_OPENGLES
2828
return IPSampleDecal(texture_sampler, texture_coords);
@@ -32,20 +32,20 @@ vec4 Sample(sampler2D texture_sampler, vec2 texture_coords) {
3232
}
3333

3434
void main() {
35-
vec4 dst_sample = Sample(texture_sampler_dst, // sampler
36-
v_dst_texture_coords // texture coordinates
37-
) *
38-
blend_info.dst_input_alpha;
39-
40-
vec4 dst = IPUnpremultiply(dst_sample);
41-
vec4 src =
42-
blend_info.color_factor > 0
43-
? blend_info.color
44-
: IPUnpremultiply(Sample(texture_sampler_src, // sampler
45-
v_src_texture_coords // texture coordinates
46-
));
47-
48-
vec4 blended = vec4(Blend(dst.rgb, src.rgb), 1) * dst.a;
35+
f16vec4 dst_sample = Sample(texture_sampler_dst, // sampler
36+
v_dst_texture_coords // texture coordinates
37+
) *
38+
blend_info.dst_input_alpha;
39+
40+
f16vec4 dst = IPHalfUnpremultiply(dst_sample);
41+
f16vec4 src = blend_info.color_factor > 0.0hf
42+
? blend_info.color
43+
: IPHalfUnpremultiply(Sample(
44+
texture_sampler_src, // sampler
45+
v_src_texture_coords // texture coordinates
46+
));
47+
48+
f16vec4 blended = f16vec4(Blend(dst.rgb, src.rgb), 1.0hf) * dst.a;
4949

5050
frag_color = mix(dst_sample, blended, src.a);
5151
}

impeller/entity/shaders/blending/advanced_blend_color.frag

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
// found in the LICENSE file.
44

55
#include <impeller/blending.glsl>
6+
#include <impeller/types.glsl>
67

7-
vec3 Blend(vec3 dst, vec3 src) {
8+
f16vec3 Blend(f16vec3 dst, f16vec3 src) {
89
return IPBlendColor(dst, src);
910
}
1011

impeller/entity/shaders/blending/advanced_blend_colorburn.frag

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
// found in the LICENSE file.
44

55
#include <impeller/blending.glsl>
6+
#include <impeller/types.glsl>
67

7-
vec3 Blend(vec3 dst, vec3 src) {
8+
f16vec3 Blend(f16vec3 dst, f16vec3 src) {
89
return IPBlendColorBurn(dst, src);
910
}
1011

impeller/entity/shaders/blending/advanced_blend_colordodge.frag

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
// found in the LICENSE file.
44

55
#include <impeller/blending.glsl>
6+
#include <impeller/types.glsl>
67

7-
vec3 Blend(vec3 dst, vec3 src) {
8+
f16vec3 Blend(f16vec3 dst, f16vec3 src) {
89
return IPBlendColorDodge(dst, src);
910
}
1011

impeller/entity/shaders/blending/advanced_blend_darken.frag

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
// found in the LICENSE file.
44

55
#include <impeller/blending.glsl>
6+
#include <impeller/types.glsl>
67

7-
vec3 Blend(vec3 dst, vec3 src) {
8+
f16vec3 Blend(f16vec3 dst, f16vec3 src) {
89
return IPBlendDarken(dst, src);
910
}
1011

0 commit comments

Comments
 (0)