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

[Impeller] support half precision uniforms and half precision samplers #40590

Merged
merged 28 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
02ccd58
[Impeller] support f16vec4 in shaders and use in solid color uniform
jonahwilliams Mar 24, 2023
3c00839
use compiler intrinsic
jonahwilliams Mar 24, 2023
43ff491
++
jonahwilliams Mar 24, 2023
68b1009
++
jonahwilliams Mar 24, 2023
b6e6f81
++
jonahwilliams Mar 24, 2023
d739b58
Merge branch 'master' of github.com:flutter/engine into support-half-…
jonahwilliams Mar 24, 2023
f1919b4
++
jonahwilliams Mar 24, 2023
a98fa07
fix licenses
jonahwilliams Mar 24, 2023
7dca490
make half a wrapper type
jonahwilliams Mar 25, 2023
9599b62
use hardware supported conversion
jonahwilliams Mar 25, 2023
4bdc197
disable for windows and add more conversion tests
jonahwilliams Mar 26, 2023
a8b80ed
compile
jonahwilliams Mar 26, 2023
8e9892b
++
jonahwilliams Mar 26, 2023
1bce547
Merge branch 'main' into support-half-vec4
jonahwilliams Mar 27, 2023
22a0bd1
test
jonahwilliams Mar 27, 2023
c802c7c
Merge branch 'support-half-vec4' of github.com:jonahwilliams/engine i…
jonahwilliams Mar 27, 2023
251564b
++
jonahwilliams Mar 27, 2023
51d7bb7
++
jonahwilliams Mar 27, 2023
9001fe1
Update geometry_unittests.cc
jonahwilliams Mar 27, 2023
11f0c9f
Update geometry_unittests.cc
jonahwilliams Mar 27, 2023
6998f76
++
jonahwilliams Mar 27, 2023
205db32
Merge branch 'support-half-vec4' of github.com:jonahwilliams/engine i…
jonahwilliams Mar 27, 2023
736a3e5
make this unreachable
jonahwilliams Mar 27, 2023
0af6ab9
++
jonahwilliams Mar 28, 2023
31cf48a
Merge branch 'main' into support-half-vec4
jonahwilliams Mar 28, 2023
c9ffbc5
++
jonahwilliams Mar 28, 2023
b2996a8
Merge branch 'support-half-vec4' of github.com:jonahwilliams/engine i…
jonahwilliams Mar 28, 2023
2f1f5c3
++
jonahwilliams Mar 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,7 @@ ORIGIN: ../../../flutter/impeller/geometry/constants.h + ../../../flutter/LICENS
ORIGIN: ../../../flutter/impeller/geometry/geometry_benchmarks.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/gradient.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/gradient.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/half.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/matrix.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/matrix.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/matrix_decomposition.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -3851,6 +3852,7 @@ FILE: ../../../flutter/impeller/geometry/constants.h
FILE: ../../../flutter/impeller/geometry/geometry_benchmarks.cc
FILE: ../../../flutter/impeller/geometry/gradient.cc
FILE: ../../../flutter/impeller/geometry/gradient.h
FILE: ../../../flutter/impeller/geometry/half.h
FILE: ../../../flutter/impeller/geometry/matrix.cc
FILE: ../../../flutter/impeller/geometry/matrix.h
FILE: ../../../flutter/impeller/geometry/matrix_decomposition.cc
Expand Down
75 changes: 75 additions & 0 deletions impeller/compiler/reflector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "impeller/compiler/code_gen_template.h"
#include "impeller/compiler/uniform_sorter.h"
#include "impeller/compiler/utilities.h"
#include "impeller/geometry/half.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/scalar.h"

Expand Down Expand Up @@ -534,6 +535,11 @@ static std::optional<KnownType> ReadKnownScalarType(
.name = "Scalar",
.byte_size = sizeof(Scalar),
};
case spirv_cross::SPIRType::BaseType::Half:
return KnownType{
.name = "Half",
.byte_size = sizeof(Half),
};
case spirv_cross::SPIRType::BaseType::UInt:
return KnownType{
.name = "uint32_t",
Expand Down Expand Up @@ -767,6 +773,75 @@ std::vector<StructMember> Reflector::ReadStructMembers(
continue;
}

// Tightly packed half Point (vec2).
if (member.basetype == spirv_cross::SPIRType::BaseType::Half && //
member.width == sizeof(Half) * 8 && //
member.columns == 1 && //
member.vecsize == 2 //
) {
uint32_t stride =
GetArrayStride<sizeof(HalfVector2)>(struct_type, member, i);
uint32_t element_padding = stride - sizeof(HalfVector2);
result.emplace_back(StructMember{
"HalfVector2", // type
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Argument comments are of the format /*arg_name=*/: https://google.github.io/styleguide/cppguide.html#Function_Argument_Comments

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is following the style of the rest of the file.

Copy link
Member Author

@jonahwilliams jonahwilliams Mar 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...also this is a struct, not a function call.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use /*field_name=*/ we can use the linter to verify that their name is correct. I turned this on years ago. I don't know if it still runs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a function call, but with C++20, you can use aggregate initialization and do this without comments: {.type = "HalfVector2"}.

BaseTypeToString(member.basetype), // basetype
GetMemberNameAtIndex(struct_type, i), // name
struct_member_offset, // offset
sizeof(HalfVector2), // size
stride * array_elements.value_or(1), // byte_length
array_elements, // array_elements
element_padding, // element_padding
});
current_byte_offset += stride * array_elements.value_or(1);
continue;
}

// Tightly packed Half Float Vector3.
if (member.basetype == spirv_cross::SPIRType::BaseType::Half && //
member.width == sizeof(Half) * 8 && //
member.columns == 1 && //
member.vecsize == 3 //
) {
uint32_t stride =
GetArrayStride<sizeof(HalfVector3)>(struct_type, member, i);
uint32_t element_padding = stride - sizeof(HalfVector3);
result.emplace_back(StructMember{
"HalfVector3", // type
BaseTypeToString(member.basetype), // basetype
GetMemberNameAtIndex(struct_type, i), // name
struct_member_offset, // offset
sizeof(HalfVector3), // size
stride * array_elements.value_or(1), // byte_length
array_elements, // array_elements
element_padding, // element_padding
});
current_byte_offset += stride * array_elements.value_or(1);
continue;
}

// Tightly packed Half Float Vector4.
if (member.basetype == spirv_cross::SPIRType::BaseType::Half && //
member.width == sizeof(Half) * 8 && //
member.columns == 1 && //
member.vecsize == 4 //
) {
uint32_t stride =
GetArrayStride<sizeof(HalfVector4)>(struct_type, member, i);
uint32_t element_padding = stride - sizeof(HalfVector4);
result.emplace_back(StructMember{
"HalfVector4", // type
BaseTypeToString(member.basetype), // basetype
GetMemberNameAtIndex(struct_type, i), // name
struct_member_offset, // offset
sizeof(HalfVector4), // size
stride * array_elements.value_or(1), // byte_length
array_elements, // array_elements
element_padding, // element_padding
});
current_byte_offset += stride * array_elements.value_or(1);
continue;
}

// Other isolated scalars (like bool, int, float/Scalar, etc..).
{
auto maybe_known_type = ReadKnownScalarType(member.basetype);
Expand Down
5 changes: 4 additions & 1 deletion impeller/compiler/shader_lib/impeller/types.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
#define TYPES_GLSL_

#extension GL_AMD_gpu_shader_half_float : enable
#extension GL_AMD_gpu_shader_half_float_fetch : enable
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable

#ifndef IMPELLER_TARGET_METAL
#ifndef IMPELLER_TARGET_METAL_IOS

precision mediump sampler2D;
precision mediump float;
Expand All @@ -17,6 +19,7 @@ precision mediump float;
#define f16vec3 vec3
#define f16vec4 vec4
#define f16mat4 mat4
#define f16sampler2D sampler2D

#endif // IMPELLER_TARGET_METAL

Expand Down
4 changes: 2 additions & 2 deletions impeller/entity/shaders/solid_fill.frag
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
#include <impeller/types.glsl>

uniform FragInfo {
vec4 color;
f16vec4 color;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this require #extension GL_EXT_shader_16bit_storage : require up top?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not, I'm not actually using a f16vec4 on glsl, here is the compiled shader:

#version 100
precision mediump float;
precision highp int;

struct FragInfo
{
    vec4 color;
};

uniform FragInfo frag_info;

void main()
{
    gl_FragData[0] = frag_info.color;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh - but this is all in types.glsl too

}
frag_info;

out vec4 frag_color;
out f16vec4 frag_color;

void main() {
frag_color = frag_info.color;
Expand Down
2 changes: 2 additions & 0 deletions impeller/fixtures/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@ impeller_shaders("shader_fixtures") {
"simple.vert",
"test_texture.frag",
"test_texture.vert",
"half.frag",
]

if (impeller_enable_opengles) {
gles_exclusions = [
"sample.comp",
"stage1.comp",
"stage2.comp",
"half.frag",
]
}
}
Expand Down
21 changes: 21 additions & 0 deletions impeller/fixtures/half.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#extension GL_AMD_gpu_shader_half_float : enable
#extension GL_AMD_gpu_shader_half_float_fetch : enable
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable

uniform FragInfo {
float16_t half_1;
f16vec2 half_2;
f16vec3 half_3;
f16vec4 half_4;
}
frag_info;

out vec4 frag_color;

void main() {
frag_color = vec4(0);
}
1 change: 1 addition & 0 deletions impeller/geometry/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ impeller_component("geometry") {
"constants.h",
"gradient.cc",
"gradient.h",
"half.h",
"matrix.cc",
"matrix.h",
"matrix_decomposition.cc",
Expand Down
36 changes: 36 additions & 0 deletions impeller/geometry/geometry_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
#include <limits>
#include <sstream>

#include "flutter/fml/build_config.h"
#include "flutter/testing/testing.h"
#include "impeller/geometry/constants.h"
#include "impeller/geometry/gradient.h"
#include "impeller/geometry/half.h"
#include "impeller/geometry/path.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/geometry/path_component.h"
Expand Down Expand Up @@ -2090,5 +2092,39 @@ TEST(GeometryTest, Gradient) {
}
}

TEST(GeometryTest, HalfConversions) {
#ifdef FML_OS_WIN
GTEST_SKIP() << "Half-precision floats (IEEE 754) are not portable and "
"unavailable on Windows.";
#else
ASSERT_EQ(ScalarToHalf(0.0), 0.0f16);
ASSERT_EQ(ScalarToHalf(0.05), 0.05f16);
ASSERT_EQ(ScalarToHalf(2.43), 2.43f16);
ASSERT_EQ(ScalarToHalf(-1.45), -1.45f16);

// 65504 is the largest possible half.
ASSERT_EQ(ScalarToHalf(65504.0f), 65504.0f16);
ASSERT_EQ(ScalarToHalf(65504.0f + 1), 65504.0f16);

// Colors
ASSERT_EQ(HalfVector4(Color::Red()),
HalfVector4(1.0f16, 0.0f16, 0.0f16, 1.0f16));
ASSERT_EQ(HalfVector4(Color::Green()),
HalfVector4(0.0f16, 1.0f16, 0.0f16, 1.0f16));
ASSERT_EQ(HalfVector4(Color::Blue()),
HalfVector4(0.0f16, 0.0f16, 1.0f16, 1.0f16));
ASSERT_EQ(HalfVector4(Color::Black().WithAlpha(0)),
HalfVector4(0.0f16, 0.0f16, 0.0f16, 0.0f16));

ASSERT_EQ(HalfVector3(Vector3(4.0, 6.0, -1.0)),
HalfVector3(4.0f16, 6.0f16, -1.0f16));
ASSERT_EQ(HalfVector2(Vector2(4.0, 6.0)), HalfVector2(4.0f16, 6.0f16));

ASSERT_EQ(Half(0.5f), Half(0.5f16));
ASSERT_EQ(Half(0.5), Half(0.5f16));
ASSERT_EQ(Half(5), Half(5.0f16));
#endif // FML_OS_WIN
}

} // namespace testing
} // namespace impeller
Loading