Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
74 changes: 74 additions & 0 deletions impeller/compiler/reflector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,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 +772,75 @@ std::vector<StructMember> Reflector::ReadStructMembers(
continue;
}

// Tightly packed half Point (vec2).
if (member.basetype == spirv_cross::SPIRType::BaseType::Half && //
member.width == sizeof(float) * 4 && //
Comment thread
gaaclarke marked this conversation as resolved.
Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you double check this? The member width doesn't make sense for half base types. I may be misunderstanding.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ah, this was a hack I left in. Should be sizeof(Half) * 8

member.columns == 1 && //
member.vecsize == 2 //
) {
uint32_t stride =
GetArrayStride<sizeof(HalfPoint)>(struct_type, member, i);
uint32_t element_padding = stride - sizeof(HalfPoint);
result.emplace_back(StructMember{
"HalfPoint", // type
BaseTypeToString(member.basetype), // basetype
GetMemberNameAtIndex(struct_type, i), // name
struct_member_offset, // offset
sizeof(HalfPoint), // 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(float) * 4 && //
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(float) * 4 && //
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
3 changes: 3 additions & 0 deletions impeller/compiler/shader_lib/impeller/types.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#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

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
2 changes: 1 addition & 1 deletion impeller/entity/contents/scene_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ bool SceneContents::Render(const ContentContext& renderer,
contents.SetGeometry(GetGeometry());
contents.SetTexture(subpass_target.GetRenderTargetTexture());
contents.SetEffectTransform(
Matrix::MakeScale(1 / entity.GetTransformation().GetScale()));
Matrix::MakeScale(1.0f / entity.GetTransformation().GetScale()));
return contents.Render(renderer, entity, pass);
}

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
Copy Markdown
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
Copy Markdown
Contributor 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
Copy Markdown
Contributor 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
1 change: 1 addition & 0 deletions impeller/geometry/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ impeller_component("geometry") {
"quaternion.h",
"rect.cc",
"rect.h",
"scalar.cc",
"scalar.h",
"shear.cc",
"shear.h",
Expand Down
5 changes: 4 additions & 1 deletion impeller/geometry/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
namespace impeller {

struct ColorHSB;
struct Vector4;

template <typename T>
struct TVector4;
using Vector4 = TVector4<Scalar>;

enum class YUVColorSpace { kBT601LimitedRange, kBT601FullRange };

Expand Down
2 changes: 2 additions & 0 deletions impeller/geometry/point.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ using IPoint = TPoint<int64_t>;
using IPoint32 = TPoint<int32_t>;
using UintPoint32 = TPoint<uint32_t>;
using Vector2 = Point;
using HalfPoint = TPoint<Half>;
using HalfVector2 = TPoint<Half>;

} // namespace impeller

Expand Down
43 changes: 43 additions & 0 deletions impeller/geometry/scalar.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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.

#include "scalar.h"

namespace impeller {

uint16_t ScalarToHalf(Scalar f) {
// __fp16 foo = f;
Comment thread
jonahwilliams marked this conversation as resolved.
Outdated
// return foo;

uint32_t x = *reinterpret_cast<const uint32_t*>(&f);
uint32_t sign = (uint16_t)(x >> 31);
uint32_t mantissa;
uint32_t exp;
uint16_t hf;

mantissa = x & ((1 << 23) - 1);
exp = x & (0xFF << 23);
if (exp >= 0x47800000) {
// check if the original number is a NaN
if (mantissa && (exp == (0xFF << 23))) {
// single precision NaN
mantissa = (1 << 23) - 1;
} else {
// half-float will be Inf
mantissa = 0;
}
hf = (((uint16_t)sign) << 15) | (uint16_t)((0x1F << 10)) |
(uint16_t)(mantissa >> 13);
}
// check if exponent is <= -15
else if (exp <= 0x38000000) {
hf = 0; // too small to be represented
} else {
hf = (((uint16_t)sign) << 15) | (uint16_t)((exp - 0x38000000) >> 13) |
(uint16_t)(mantissa >> 13);
}
return hf;
}

} // namespace impeller
9 changes: 9 additions & 0 deletions impeller/geometry/scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include <cfloat>
#include <cstdint>
#include <type_traits>
#include <valarray>

Expand All @@ -13,6 +14,7 @@
namespace impeller {

using Scalar = float;
using Half = uint16_t;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How is this different from the _Float16 C11 extension? I also see __fp16.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

TIL


template <class T, class = std::enable_if_t<std::is_arithmetic_v<T>>>
constexpr T Absolute(const T& val) {
Expand Down Expand Up @@ -52,4 +54,11 @@ struct Degrees {
};
};

/// @brief Convert a scalar to a half precision float.
///
/// Can express numbers in the range of 2^-14 to 65504.
/// Adapted from
/// https://developer.android.com/games/optimize/vertex-data-management .

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should document the behavior of this and how it handles precision loss, and add some tests that assert it.

Specifically:

  • What happens when the f is greater than the max finite value or less than the lowest finite value of a half float?
  • What happens when f is infinity/-infinity/nan?
  • What happens to very tiny values of f?

Half ScalarToHalf(Scalar f);

} // namespace impeller
20 changes: 11 additions & 9 deletions impeller/geometry/vector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@
// found in the LICENSE file.

#include "vector.h"
#include <sstream>

namespace impeller {

std::string Vector3::ToString() const {
std::stringstream stream;
stream << "{" << x << ", " << y << ", " << z << "}";
return stream.str();
template <>
Half Cast<Half, Scalar>(const Scalar& s) {
return ScalarToHalf(s);
}

std::string Vector4::ToString() const {
std::stringstream stream;
stream << "{" << x << ", " << y << ", " << z << ", " << w << "}";
return stream.str();
template <>
Half Cast<Half, Half>(const Half& s) {
return s;
}

template <>
Scalar Cast<Scalar, Scalar>(const Scalar& s) {
return s;
}

} // namespace impeller
Loading