finish up constants

For whatever reason, if I swap the condition in the if_then_else tests
from < to >= and swap the then/else values, I can use constants in
hsl_to_rgb.  Still don't understand why, but I'll take it.  I suspect it
has something to do with SSE, IEEE, and NaN, but I don't care enough to
speculate any more concretely.

This does that, removes C() and _f, updates some comments, and adds a
guard in build_stages.py to yell if it sees trouble like LCPI40_4...

This reminds me to try -ffast-math soon.  I think that was mostly held
back by constants.

Change-Id: I3f8a37a4d4642f77422ce3261b750061e9e604a3
Reviewed-on: https://skia-review.googlesource.com/14942
Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
Mike Klein 2017-05-01 16:01:38 -04:00
parent 879a08ac14
commit 5664e65eb1
6 changed files with 3894 additions and 3833 deletions

View File

@ -48,17 +48,6 @@
#include <stdint.h> #include <stdint.h>
#endif #endif
// SkJumper_stages.cpp has some unusual constraints on what constants it can use.
//
// If the constant is baked into the instruction, that's ok.
// If the constant is synthesized through code, that's ok.
// If the constant is loaded from memory, that's no good.
//
// We offer a couple facilities to get at any other constants you need:
// - the C() function usually constrains constants to be directly baked into an instruction; or
// - the _i and _f user-defined literal operators call C() for you in a prettier way; or
// - you can load values from this struct.
static const int SkJumper_kMaxStride = 8; static const int SkJumper_kMaxStride = 8;
struct SkJumper_constants { struct SkJumper_constants {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -36,17 +36,4 @@ SI Dst widen_cast(const Src& src) {
return dst; return dst;
} }
// A couple functions for embedding constants directly into code,
// so that no .const or .literal4 section is created.
SI float C(float f) {
int x = bit_cast<int>(f);
#if defined(JUMPER) && defined(__x86_64__)
// Move x-the-compile-time-constant as a literal into x-the-register.
asm("mov %1, %0" : "=r"(x) : "i"(x));
#endif
return bit_cast<float>(x);
}
// Syntax sugar to make C() easy to use for constant literals.
SI float operator "" _f(long double f) { return C((float)f); }
#endif//SkJumper_misc_DEFINED #endif//SkJumper_misc_DEFINED

View File

@ -6,7 +6,7 @@
*/ */
#include "SkJumper.h" #include "SkJumper.h"
#include "SkJumper_misc.h" // SI, unaligned_load(), bit_cast(), C(), operator"" and _f. #include "SkJumper_misc.h" // SI, unaligned_load(), bit_cast()
#include "SkJumper_vectors.h" // F, I32, U32, U16, U8, cast(), expand() #include "SkJumper_vectors.h" // F, I32, U32, U16, U8, cast(), expand()
// Our fundamental vector depth is our pixel stride. // Our fundamental vector depth is our pixel stride.
@ -17,9 +17,7 @@ static const size_t kStride = sizeof(F) / sizeof(float);
// and that F, I32, etc. are kStride-deep ext_vector_types of the appropriate type. // and that F, I32, etc. are kStride-deep ext_vector_types of the appropriate type.
// Otherwise, F, I32, etc. just alias the basic scalar types (and so kStride == 1). // Otherwise, F, I32, etc. just alias the basic scalar types (and so kStride == 1).
// Another reminder: // You can use most constants in this file, but in a few rare exceptions we read from this struct.
// You can't generally use constants in this file except via C() or operator"" _f.
// Not all constants can be generated using C() or _f. Stages read the rest from this struct.
using K = const SkJumper_constants; using K = const SkJumper_constants;
@ -504,16 +502,17 @@ STAGE(hsl_to_rgb) {
s = g, s = g,
l = b; l = b;
F q = l + if_then_else(l < 0.5_f, l*s F q = l + if_then_else(l >= 0.5f, s - l*s, l*s),
, s - l*s); p = 2.0f*l - q;
F p = 2.0f*l - q;
auto hue_to_rgb = [&](F t) { auto hue_to_rgb = [&](F t) {
t = fract(t); t = fract(t);
return if_then_else(t < C(1/6.0f), p + (q-p)*( 6.0f*t),
if_then_else(t < C(3/6.0f), q, F r = p;
if_then_else(t < C(4/6.0f), p + (q-p)*(4.0f - 6.0f*t), r = if_then_else(t >= 4/6.0f, r, p + (q-p)*(4.0f - 6.0f*t));
p))); r = if_then_else(t >= 3/6.0f, r, q);
r = if_then_else(t >= 1/6.0f, r, p + (q-p)*( 6.0f*t));
return r;
}; };
r = if_then_else(s == 0, l, hue_to_rgb(h + (1/3.0f))); r = if_then_else(s == 0, l, hue_to_rgb(h + (1/3.0f)));

View File

@ -115,6 +115,9 @@ def parse_object_file(dot_o, directive, target=None):
print sym.replace('.literal', align) print sym.replace('.literal', align)
elif sym.startswith('.const'): # 32-byte constants elif sym.startswith('.const'): # 32-byte constants
print align + '32' print align + '32'
elif not sym.startswith('sk_'):
print >>sys.stderr, "build_stages.py can't handle '%s' (yet?)." % sym
assert sym.startswith('sk_')
else: # a stage function else: # a stage function
if hidden: if hidden:
print hidden + ' _' + sym print hidden + ' _' + sym