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

Commit 3287e2b

Browse files
[Impeller] support half precision uniforms and half precision samplers (#40590)
[Impeller] support half precision uniforms and half precision samplers
1 parent 1d506df commit 3287e2b

File tree

10 files changed

+332
-3
lines changed

10 files changed

+332
-3
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,7 @@ ORIGIN: ../../../flutter/impeller/geometry/constants.h + ../../../flutter/LICENS
12881288
ORIGIN: ../../../flutter/impeller/geometry/geometry_benchmarks.cc + ../../../flutter/LICENSE
12891289
ORIGIN: ../../../flutter/impeller/geometry/gradient.cc + ../../../flutter/LICENSE
12901290
ORIGIN: ../../../flutter/impeller/geometry/gradient.h + ../../../flutter/LICENSE
1291+
ORIGIN: ../../../flutter/impeller/geometry/half.h + ../../../flutter/LICENSE
12911292
ORIGIN: ../../../flutter/impeller/geometry/matrix.cc + ../../../flutter/LICENSE
12921293
ORIGIN: ../../../flutter/impeller/geometry/matrix.h + ../../../flutter/LICENSE
12931294
ORIGIN: ../../../flutter/impeller/geometry/matrix_decomposition.cc + ../../../flutter/LICENSE
@@ -3851,6 +3852,7 @@ FILE: ../../../flutter/impeller/geometry/constants.h
38513852
FILE: ../../../flutter/impeller/geometry/geometry_benchmarks.cc
38523853
FILE: ../../../flutter/impeller/geometry/gradient.cc
38533854
FILE: ../../../flutter/impeller/geometry/gradient.h
3855+
FILE: ../../../flutter/impeller/geometry/half.h
38543856
FILE: ../../../flutter/impeller/geometry/matrix.cc
38553857
FILE: ../../../flutter/impeller/geometry/matrix.h
38563858
FILE: ../../../flutter/impeller/geometry/matrix_decomposition.cc

impeller/compiler/reflector.cc

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "impeller/compiler/code_gen_template.h"
1919
#include "impeller/compiler/uniform_sorter.h"
2020
#include "impeller/compiler/utilities.h"
21+
#include "impeller/geometry/half.h"
2122
#include "impeller/geometry/matrix.h"
2223
#include "impeller/geometry/scalar.h"
2324

@@ -534,6 +535,11 @@ static std::optional<KnownType> ReadKnownScalarType(
534535
.name = "Scalar",
535536
.byte_size = sizeof(Scalar),
536537
};
538+
case spirv_cross::SPIRType::BaseType::Half:
539+
return KnownType{
540+
.name = "Half",
541+
.byte_size = sizeof(Half),
542+
};
537543
case spirv_cross::SPIRType::BaseType::UInt:
538544
return KnownType{
539545
.name = "uint32_t",
@@ -767,6 +773,75 @@ std::vector<StructMember> Reflector::ReadStructMembers(
767773
continue;
768774
}
769775

776+
// Tightly packed half Point (vec2).
777+
if (member.basetype == spirv_cross::SPIRType::BaseType::Half && //
778+
member.width == sizeof(Half) * 8 && //
779+
member.columns == 1 && //
780+
member.vecsize == 2 //
781+
) {
782+
uint32_t stride =
783+
GetArrayStride<sizeof(HalfVector2)>(struct_type, member, i);
784+
uint32_t element_padding = stride - sizeof(HalfVector2);
785+
result.emplace_back(StructMember{
786+
"HalfVector2", // type
787+
BaseTypeToString(member.basetype), // basetype
788+
GetMemberNameAtIndex(struct_type, i), // name
789+
struct_member_offset, // offset
790+
sizeof(HalfVector2), // size
791+
stride * array_elements.value_or(1), // byte_length
792+
array_elements, // array_elements
793+
element_padding, // element_padding
794+
});
795+
current_byte_offset += stride * array_elements.value_or(1);
796+
continue;
797+
}
798+
799+
// Tightly packed Half Float Vector3.
800+
if (member.basetype == spirv_cross::SPIRType::BaseType::Half && //
801+
member.width == sizeof(Half) * 8 && //
802+
member.columns == 1 && //
803+
member.vecsize == 3 //
804+
) {
805+
uint32_t stride =
806+
GetArrayStride<sizeof(HalfVector3)>(struct_type, member, i);
807+
uint32_t element_padding = stride - sizeof(HalfVector3);
808+
result.emplace_back(StructMember{
809+
"HalfVector3", // type
810+
BaseTypeToString(member.basetype), // basetype
811+
GetMemberNameAtIndex(struct_type, i), // name
812+
struct_member_offset, // offset
813+
sizeof(HalfVector3), // size
814+
stride * array_elements.value_or(1), // byte_length
815+
array_elements, // array_elements
816+
element_padding, // element_padding
817+
});
818+
current_byte_offset += stride * array_elements.value_or(1);
819+
continue;
820+
}
821+
822+
// Tightly packed Half Float Vector4.
823+
if (member.basetype == spirv_cross::SPIRType::BaseType::Half && //
824+
member.width == sizeof(Half) * 8 && //
825+
member.columns == 1 && //
826+
member.vecsize == 4 //
827+
) {
828+
uint32_t stride =
829+
GetArrayStride<sizeof(HalfVector4)>(struct_type, member, i);
830+
uint32_t element_padding = stride - sizeof(HalfVector4);
831+
result.emplace_back(StructMember{
832+
"HalfVector4", // type
833+
BaseTypeToString(member.basetype), // basetype
834+
GetMemberNameAtIndex(struct_type, i), // name
835+
struct_member_offset, // offset
836+
sizeof(HalfVector4), // size
837+
stride * array_elements.value_or(1), // byte_length
838+
array_elements, // array_elements
839+
element_padding, // element_padding
840+
});
841+
current_byte_offset += stride * array_elements.value_or(1);
842+
continue;
843+
}
844+
770845
// Other isolated scalars (like bool, int, float/Scalar, etc..).
771846
{
772847
auto maybe_known_type = ReadKnownScalarType(member.basetype);

impeller/compiler/shader_lib/impeller/types.glsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
#define TYPES_GLSL_
77

88
#extension GL_AMD_gpu_shader_half_float : enable
9+
#extension GL_AMD_gpu_shader_half_float_fetch : enable
10+
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable
911

10-
#ifndef IMPELLER_TARGET_METAL
12+
#ifndef IMPELLER_TARGET_METAL_IOS
1113

1214
precision mediump sampler2D;
1315
precision mediump float;
@@ -17,6 +19,7 @@ precision mediump float;
1719
#define f16vec3 vec3
1820
#define f16vec4 vec4
1921
#define f16mat4 mat4
22+
#define f16sampler2D sampler2D
2023

2124
#endif // IMPELLER_TARGET_METAL
2225

impeller/entity/shaders/solid_fill.frag

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
#include <impeller/types.glsl>
66

77
uniform FragInfo {
8-
vec4 color;
8+
f16vec4 color;
99
}
1010
frag_info;
1111

12-
out vec4 frag_color;
12+
out f16vec4 frag_color;
1313

1414
void main() {
1515
frag_color = frag_info.color;

impeller/fixtures/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@ impeller_shaders("shader_fixtures") {
4848
"simple.vert",
4949
"test_texture.frag",
5050
"test_texture.vert",
51+
"half.frag",
5152
]
5253

5354
if (impeller_enable_opengles) {
5455
gles_exclusions = [
5556
"sample.comp",
5657
"stage1.comp",
5758
"stage2.comp",
59+
"half.frag",
5860
]
5961
}
6062
}

impeller/fixtures/half.frag

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#extension GL_AMD_gpu_shader_half_float : enable
6+
#extension GL_AMD_gpu_shader_half_float_fetch : enable
7+
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable
8+
9+
uniform FragInfo {
10+
float16_t half_1;
11+
f16vec2 half_2;
12+
f16vec3 half_3;
13+
f16vec4 half_4;
14+
}
15+
frag_info;
16+
17+
out vec4 frag_color;
18+
19+
void main() {
20+
frag_color = vec4(0);
21+
}

impeller/geometry/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ impeller_component("geometry") {
1212
"constants.h",
1313
"gradient.cc",
1414
"gradient.h",
15+
"half.h",
1516
"matrix.cc",
1617
"matrix.h",
1718
"matrix_decomposition.cc",

impeller/geometry/geometry_unittests.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
#include <limits>
88
#include <sstream>
99

10+
#include "flutter/fml/build_config.h"
1011
#include "flutter/testing/testing.h"
1112
#include "impeller/geometry/constants.h"
1213
#include "impeller/geometry/gradient.h"
14+
#include "impeller/geometry/half.h"
1315
#include "impeller/geometry/path.h"
1416
#include "impeller/geometry/path_builder.h"
1517
#include "impeller/geometry/path_component.h"
@@ -2090,5 +2092,39 @@ TEST(GeometryTest, Gradient) {
20902092
}
20912093
}
20922094

2095+
TEST(GeometryTest, HalfConversions) {
2096+
#ifdef FML_OS_WIN
2097+
GTEST_SKIP() << "Half-precision floats (IEEE 754) are not portable and "
2098+
"unavailable on Windows.";
2099+
#else
2100+
ASSERT_EQ(ScalarToHalf(0.0), 0.0f16);
2101+
ASSERT_EQ(ScalarToHalf(0.05), 0.05f16);
2102+
ASSERT_EQ(ScalarToHalf(2.43), 2.43f16);
2103+
ASSERT_EQ(ScalarToHalf(-1.45), -1.45f16);
2104+
2105+
// 65504 is the largest possible half.
2106+
ASSERT_EQ(ScalarToHalf(65504.0f), 65504.0f16);
2107+
ASSERT_EQ(ScalarToHalf(65504.0f + 1), 65504.0f16);
2108+
2109+
// Colors
2110+
ASSERT_EQ(HalfVector4(Color::Red()),
2111+
HalfVector4(1.0f16, 0.0f16, 0.0f16, 1.0f16));
2112+
ASSERT_EQ(HalfVector4(Color::Green()),
2113+
HalfVector4(0.0f16, 1.0f16, 0.0f16, 1.0f16));
2114+
ASSERT_EQ(HalfVector4(Color::Blue()),
2115+
HalfVector4(0.0f16, 0.0f16, 1.0f16, 1.0f16));
2116+
ASSERT_EQ(HalfVector4(Color::Black().WithAlpha(0)),
2117+
HalfVector4(0.0f16, 0.0f16, 0.0f16, 0.0f16));
2118+
2119+
ASSERT_EQ(HalfVector3(Vector3(4.0, 6.0, -1.0)),
2120+
HalfVector3(4.0f16, 6.0f16, -1.0f16));
2121+
ASSERT_EQ(HalfVector2(Vector2(4.0, 6.0)), HalfVector2(4.0f16, 6.0f16));
2122+
2123+
ASSERT_EQ(Half(0.5f), Half(0.5f16));
2124+
ASSERT_EQ(Half(0.5), Half(0.5f16));
2125+
ASSERT_EQ(Half(5), Half(5.0f16));
2126+
#endif // FML_OS_WIN
2127+
}
2128+
20932129
} // namespace testing
20942130
} // namespace impeller

0 commit comments

Comments
 (0)