summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-01-10 14:35:12 -0800
committerThiago Macieira <thiago.macieira@intel.com>2023-01-11 17:38:06 -0800
commit272d0789265fcb13523cc5b25ceef18c6306305d (patch)
tree3316b4f79afae3803c755bd18f5afed04cda5b94 /src/gui/painting
parent59d5a52c2278f2e8c1d715509dfbacc4a29a492d (diff)
QRgbaFloat: add support for multiplying & comparing as FP16
AVX512FP16 expanded FP16 support on x86 to all operations (addition, multiplication, comparison, etc.), so make use of them. Each operation takes just as many cycles as an FP32 operation, but we avoid converting between FP16 and PF32 for those operations. Change-Id: Ide4dbd0777a44ed0870efffd17391370e1638c7a Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qrgbafloat.h44
1 files changed, 28 insertions, 16 deletions
diff --git a/src/gui/painting/qrgbafloat.h b/src/gui/painting/qrgbafloat.h
index d5ca4cd8c9..160623eb1e 100644
--- a/src/gui/painting/qrgbafloat.h
+++ b/src/gui/painting/qrgbafloat.h
@@ -19,7 +19,13 @@ class alignas(sizeof(F) * 4) QRgbaFloat
static_assert(std::is_same<F, qfloat16>::value || std::is_same<F, float>::value);
public:
using Type = F;
+#if defined(__AVX512FP16__) && QFLOAT16_IS_NATIVE
+ // AVX512FP16 has multiplication instructions
+ using FastType = F;
+#else
+ // use FP32 for multiplications
using FastType = float;
+#endif
F r;
F g;
F b;
@@ -28,7 +34,7 @@ public:
static constexpr
QRgbaFloat fromRgba64(quint16 red, quint16 green, quint16 blue, quint16 alpha)
{
- constexpr FastType scale = 1.0f / 65535.0f;
+ constexpr FastType scale = FastType(1.0f / 65535.0f);
return QRgbaFloat{
F(red * scale),
F(green * scale),
@@ -39,7 +45,7 @@ public:
static constexpr
QRgbaFloat fromRgba(quint8 red, quint8 green, quint8 blue, quint8 alpha)
{
- constexpr FastType scale = 1.0f / 255.0f;
+ constexpr FastType scale = FastType(1.0f / 255.0f);
return QRgbaFloat{
F(red * scale),
F(green * scale),
@@ -52,8 +58,8 @@ public:
return fromRgba(quint8(rgb >> 16), quint8(rgb >> 8), quint8(rgb), quint8(rgb >> 24));
}
- constexpr bool isOpaque() const { return a >= 1.0f; }
- constexpr bool isTransparent() const { return a <= 0.0f; }
+ constexpr bool isOpaque() const { return a >= FastType(1.0f); }
+ constexpr bool isTransparent() const { return a <= FastType(0.0f); }
constexpr FastType red() const { return r; }
constexpr FastType green() const { return g; }
@@ -64,24 +70,24 @@ public:
void setBlue(FastType _blue) { b = F(_blue); }
void setAlpha(FastType _alpha) { a = F(_alpha); }
- constexpr FastType redNormalized() const { return std::clamp(static_cast<FastType>(r), 0.0f, 1.0f); }
- constexpr FastType greenNormalized() const { return std::clamp(static_cast<FastType>(g), 0.0f, 1.0f); }
- constexpr FastType blueNormalized() const { return std::clamp(static_cast<FastType>(b), 0.0f, 1.0f); }
- constexpr FastType alphaNormalized() const { return std::clamp(static_cast<FastType>(a), 0.0f, 1.0f); }
+ constexpr FastType redNormalized() const { return clamp01(r); }
+ constexpr FastType greenNormalized() const { return clamp01(g); }
+ constexpr FastType blueNormalized() const { return clamp01(b); }
+ constexpr FastType alphaNormalized() const { return clamp01(a); }
- constexpr quint8 red8() const { return std::lround(redNormalized() * 255.0f); }
- constexpr quint8 green8() const { return std::lround(greenNormalized() * 255.0f); }
- constexpr quint8 blue8() const { return std::lround(blueNormalized() * 255.0f); }
- constexpr quint8 alpha8() const { return std::lround(alphaNormalized() * 255.0f); }
+ constexpr quint8 red8() const { return qRound(redNormalized() * FastType(255.0f)); }
+ constexpr quint8 green8() const { return qRound(greenNormalized() * FastType(255.0f)); }
+ constexpr quint8 blue8() const { return qRound(blueNormalized() * FastType(255.0f)); }
+ constexpr quint8 alpha8() const { return qRound(alphaNormalized() * FastType(255.0f)); }
constexpr uint toArgb32() const
{
return uint((alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8());
}
- constexpr quint16 red16() const { return std::lround(redNormalized() * 65535.0f); }
- constexpr quint16 green16() const { return std::lround(greenNormalized() * 65535.0f); }
- constexpr quint16 blue16() const { return std::lround(blueNormalized() * 65535.0f); }
- constexpr quint16 alpha16() const { return std::lround(alphaNormalized() * 65535.0f); }
+ constexpr quint16 red16() const { return qRound(redNormalized() * FastType(65535.0f)); }
+ constexpr quint16 green16() const { return qRound(greenNormalized() * FastType(65535.0f)); }
+ constexpr quint16 blue16() const { return qRound(blueNormalized() * FastType(65535.0f)); }
+ constexpr quint16 alpha16() const { return qRound(alphaNormalized() * FastType(65535.0f)); }
constexpr Q_ALWAYS_INLINE QRgbaFloat premultiplied() const
{
@@ -104,6 +110,12 @@ public:
{
return !(*this == f);
}
+
+private:
+ constexpr static FastType clamp01(Type f)
+ {
+ return std::clamp(FastType(f), FastType(0.0f), FastType(1.0f));
+ }
};
typedef QRgbaFloat<qfloat16> QRgbaFloat16;