skeleton for float <-> half optimized procs
Nothing fancy yet, just calls the serial code in a loop. I will try to folow this up with at least some of: - SSE2 version of serial code - NEON version of serial code - NEON version using vcvt.f32.f16/vcvt.f16.f32 - F16C (between AVX and AVX2) version using vcvtph2ps/vcvtps2ph The last two are fastest but need runtime detection. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1686543003 Review URL: https://codereview.chromium.org/1686543003
This commit is contained in:
parent
eba209a8fc
commit
a525cb151b
48
bench/HalfBench.cpp
Normal file
48
bench/HalfBench.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "Benchmark.h"
|
||||
#include "SkOpts.h"
|
||||
#include "SkRandom.h"
|
||||
|
||||
struct FloatToHalfBench : public Benchmark {
|
||||
const char* onGetName() override { return "float_to_half"; }
|
||||
bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
|
||||
|
||||
void onDraw(int loops, SkCanvas* canvas) override {
|
||||
SkRandom rand;
|
||||
float fs[1023];
|
||||
for (float& f : fs) {
|
||||
f = rand.nextF();
|
||||
}
|
||||
|
||||
uint16_t hs[1023];
|
||||
while (loops --> 0) {
|
||||
SkOpts::float_to_half(hs, fs, 1023);
|
||||
}
|
||||
}
|
||||
};
|
||||
DEF_BENCH(return new FloatToHalfBench;)
|
||||
|
||||
struct HalfToFloatBench : public Benchmark {
|
||||
const char* onGetName() override { return "half_to_float"; }
|
||||
bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
|
||||
|
||||
void onDraw(int loops, SkCanvas* canvas) override {
|
||||
SkRandom rand;
|
||||
uint16_t hs[1023];
|
||||
for (uint16_t& h : hs) {
|
||||
h = rand.nextU16();
|
||||
}
|
||||
|
||||
float fs[1023];
|
||||
while (loops --> 0) {
|
||||
SkOpts::half_to_float(fs, hs, 1023);
|
||||
}
|
||||
}
|
||||
};
|
||||
DEF_BENCH(return new HalfToFloatBench;)
|
@ -5,6 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkHalf.h"
|
||||
#include "SkOnce.h"
|
||||
#include "SkOpts.h"
|
||||
|
||||
@ -20,6 +21,19 @@
|
||||
#include "SkUtils_opts.h"
|
||||
#include "SkXfermode_opts.h"
|
||||
|
||||
namespace SK_OPTS_NS {
|
||||
static void float_to_half(uint16_t dst[], const float src[], int n) {
|
||||
while (n-->0) {
|
||||
*dst++ = SkFloatToHalf(*src++);
|
||||
}
|
||||
}
|
||||
static void half_to_float(float dst[], const uint16_t src[], int n) {
|
||||
while (n-->0) {
|
||||
*dst++ = SkHalfToFloat(*src++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS)
|
||||
#if defined(SK_BUILD_FOR_WIN32)
|
||||
#include <intrin.h>
|
||||
@ -90,6 +104,9 @@ namespace SkOpts {
|
||||
decltype(inverted_CMYK_to_RGB1) inverted_CMYK_to_RGB1 = sk_default::inverted_CMYK_to_RGB1;
|
||||
decltype(inverted_CMYK_to_BGR1) inverted_CMYK_to_BGR1 = sk_default::inverted_CMYK_to_BGR1;
|
||||
|
||||
decltype(half_to_float) half_to_float = sk_default::half_to_float;
|
||||
decltype(float_to_half) float_to_half = sk_default::float_to_half;
|
||||
|
||||
// Each Init_foo() is defined in src/opts/SkOpts_foo.cpp.
|
||||
void Init_ssse3();
|
||||
void Init_sse41();
|
||||
|
@ -67,6 +67,9 @@ namespace SkOpts {
|
||||
grayA_to_rgbA, // i.e. expand to color channels and premultiply
|
||||
inverted_CMYK_to_RGB1, // i.e. convert color space
|
||||
inverted_CMYK_to_BGR1; // i.e. convert color space
|
||||
|
||||
extern void (*half_to_float)(float[], const uint16_t[], int);
|
||||
extern void (*float_to_half)(uint16_t[], const float[], int);
|
||||
}
|
||||
|
||||
#endif//SkOpts_DEFINED
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Test.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkHalf.h"
|
||||
#include "SkOpts.h"
|
||||
#include "SkPixmap.h"
|
||||
|
||||
static bool eq_within_half_float(float a, float b) {
|
||||
@ -50,3 +51,16 @@ DEF_TEST(color_half_float, reporter) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEF_TEST(float_to_half, reporter) {
|
||||
const float fs[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 };
|
||||
const uint16_t hs[] = { 0x3c00, 0x4000, 0x4200, 0x4400, 0x4500, 0x4600, 0x4700 };
|
||||
|
||||
uint16_t hscratch[7];
|
||||
SkOpts::float_to_half(hscratch, fs, 7);
|
||||
REPORTER_ASSERT(reporter, 0 == memcmp(hscratch, hs, sizeof(hs)));
|
||||
|
||||
float fscratch[7];
|
||||
SkOpts::half_to_float(fscratch, hs, 7);
|
||||
REPORTER_ASSERT(reporter, 0 == memcmp(fscratch, fs, sizeof(fs)));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user