disambiguate skvm::bit_cast()

Change-Id: If22eabb68b9293f5bc1d275535135d9760fe1ae5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/339578
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Klein 2020-12-01 10:43:46 -06:00 committed by Skia Commit-Bot
parent bb9fbe057a
commit 5ec9c4e763
8 changed files with 64 additions and 56 deletions

View File

@ -148,9 +148,9 @@ skvm::Color sk_program_transfer_fn(skvm::Builder* p, skvm::Uniforms* uniforms,
auto apply = [&](skvm::F32 v) -> skvm::F32 {
// Strip off the sign bit and save it for later.
skvm::I32 bits = bit_cast(v),
skvm::I32 bits = pun_to_I32(v),
sign = bits & 0x80000000;
v = bit_cast(bits ^ sign);
v = pun_to_F32(bits ^ sign);
switch (classify_transfer_fn(tf)) {
case Bad_TF: SkASSERT(false); break;
@ -178,7 +178,7 @@ skvm::Color sk_program_transfer_fn(skvm::Builder* p, skvm::Uniforms* uniforms,
}
// Re-apply the original sign bit on our way out the door.
return bit_cast(sign | bit_cast(v));
return pun_to_F32(sign | pun_to_I32(v));
};
return {apply(c.r), apply(c.g), apply(c.b), c.a};

View File

@ -529,7 +529,7 @@ static skvm::Color program_fn(skvm::Builder* p,
} break;
case Inst::kPushImmediate: {
push(bit_cast(p->splat(u32())));
push(pun_to_F32(p->splat(u32())));
} break;
case Inst::kDup: {
@ -632,7 +632,7 @@ static skvm::Color program_fn(skvm::Builder* p,
// in that we're only maintaining mask stack and cond stack, and don't support loops.
case Inst::kMaskPush:
cond_stack.push_back(bit_cast(pop()));
cond_stack.push_back(pun_to_I32(pop()));
mask_stack.push_back(mask_stack.back() & cond_stack.back());
break;
@ -649,39 +649,47 @@ static skvm::Color program_fn(skvm::Builder* p,
// Comparisons all should write their results to the main data stack;
// maskpush moves them from there onto the mask stack as needed.
case Inst::kCompareFEQ:
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(x==y); });
binary([](skvm::F32 x, skvm::F32 y) { return pun_to_F32(x==y); });
break;
case Inst::kCompareFNEQ:
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(x!=y); });
binary([](skvm::F32 x, skvm::F32 y) { return pun_to_F32(x!=y); });
break;
case Inst::kCompareFGT:
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(x>y); });
binary([](skvm::F32 x, skvm::F32 y) { return pun_to_F32(x>y); });
break;
case Inst::kCompareFGTEQ:
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(x>=y); });
binary([](skvm::F32 x, skvm::F32 y) { return pun_to_F32(x>=y); });
break;
case Inst::kCompareFLT:
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(x<y); });
binary([](skvm::F32 x, skvm::F32 y) { return pun_to_F32(x<y); });
break;
case Inst::kCompareFLTEQ:
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(x<=y); });
binary([](skvm::F32 x, skvm::F32 y) { return pun_to_F32(x<=y); });
break;
case Inst::kCompareIEQ:
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(bit_cast(x)==bit_cast(y)); });
binary([](skvm::F32 x, skvm::F32 y) {
return pun_to_F32(pun_to_I32(x) == pun_to_I32(y));
});
break;
case Inst::kCompareINEQ:
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(bit_cast(x)!=bit_cast(y)); });
binary([](skvm::F32 x, skvm::F32 y) {
return pun_to_F32(pun_to_I32(x) != pun_to_I32(y));
});
break;
case Inst::kAndB:
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(bit_cast(x)&bit_cast(y)); });
binary([](skvm::F32 x, skvm::F32 y) {
return pun_to_F32(pun_to_I32(x) & pun_to_I32(y));
});
break;
case Inst::kOrB:
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(bit_cast(x)|bit_cast(y)); });
binary([](skvm::F32 x, skvm::F32 y) {
return pun_to_F32(pun_to_I32(x) | pun_to_I32(y));
});
break;
case Inst::kNotB:
unary([](skvm::F32 x) { return bit_cast(~bit_cast(x)); });
unary([](skvm::F32 x) { return pun_to_F32(~pun_to_I32(x)); });
break;
case Inst::kMaskBlend: {

View File

@ -744,10 +744,10 @@ namespace skvm {
// See http://www.machinedlearnings.com/2011/06/fast-approximate-logarithm-exponential.html.
F32 Builder::approx_log2(F32 x) {
// e - 127 is a fair approximation of log2(x) in its own right...
F32 e = mul(to_F32(bit_cast(x)), splat(1.0f / (1<<23)));
F32 e = mul(to_F32(pun_to_I32(x)), splat(1.0f / (1<<23)));
// ... but using the mantissa to refine its error is _much_ better.
F32 m = bit_cast(bit_or(bit_and(bit_cast(x), 0x007fffff),
F32 m = pun_to_F32(bit_or(bit_and(pun_to_I32(x), 0x007fffff),
0x3f000000));
F32 approx = sub(e, 124.225514990f);
approx = sub(approx, mul(1.498030302f, m));
@ -762,7 +762,7 @@ namespace skvm {
approx = sub(approx, mul( 1.490129070f, f));
approx = add(approx, div(27.728023300f, sub(4.84252568f, f)));
return bit_cast(round(mul(1.0f * (1<<23), approx)));
return pun_to_F32(round(mul(1.0f * (1<<23), approx)));
}
F32 Builder::approx_powf(F32 x, F32 y) {
@ -1205,10 +1205,10 @@ namespace skvm {
case 16: {
assert_16byte_is_rgba_f32(f);
return {
bit_cast(load128(ptr, 0)),
bit_cast(load128(ptr, 1)),
bit_cast(load128(ptr, 2)),
bit_cast(load128(ptr, 3)),
pun_to_F32(load128(ptr, 0)),
pun_to_F32(load128(ptr, 1)),
pun_to_F32(load128(ptr, 2)),
pun_to_F32(load128(ptr, 3)),
};
}
default: SkUNREACHABLE;
@ -1290,8 +1290,8 @@ namespace skvm {
}
case 16: {
assert_16byte_is_rgba_f32(f);
store128(ptr, bit_cast(c.r), bit_cast(c.g), 0);
store128(ptr, bit_cast(c.b), bit_cast(c.a), 1);
store128(ptr, pun_to_I32(c.r), pun_to_I32(c.g), 0);
store128(ptr, pun_to_I32(c.b), pun_to_I32(c.a), 1);
return true;
}
default: SkUNREACHABLE;
@ -1301,7 +1301,7 @@ namespace skvm {
void Builder::unpremul(F32* r, F32* g, F32* b, F32 a) {
skvm::F32 invA = 1.0f / a,
inf = bit_cast(splat(0x7f800000));
inf = pun_to_F32(splat(0x7f800000));
// If a is 0, so are *r,*g,*b, so set invA to 0 to avoid 0*inf=NaN (instead 0*0 = 0).
invA = select(invA < inf, invA
, 0.0f);

View File

@ -614,14 +614,14 @@ namespace skvm {
// Assert cond is true, printing debug when not.
void assert_true(I32 cond, I32 debug);
void assert_true(I32 cond, F32 debug) { assert_true(cond, bit_cast(debug)); }
void assert_true(I32 cond, F32 debug) { assert_true(cond, pun_to_I32(debug)); }
void assert_true(I32 cond) { assert_true(cond, cond); }
// Store {8,16,32,64,128}-bit varying.
void store8 (Arg ptr, I32 val);
void store16 (Arg ptr, I32 val);
void store32 (Arg ptr, I32 val);
void storeF (Arg ptr, F32 val) { store32(ptr, bit_cast(val)); }
void storeF (Arg ptr, F32 val) { store32(ptr, pun_to_I32(val)); }
void store64 (Arg ptr, I32 lo, I32 hi); // *ptr = lo|(hi<<32)
void store128(Arg ptr, I32 lo, I32 hi, int lane); // 64-bit lane 0-1 at ptr = lo|(hi<<32).
@ -632,13 +632,13 @@ namespace skvm {
I32 load8 (Arg ptr);
I32 load16 (Arg ptr);
I32 load32 (Arg ptr);
F32 loadF (Arg ptr) { return bit_cast(load32(ptr)); }
F32 loadF (Arg ptr) { return pun_to_F32(load32(ptr)); }
I32 load64 (Arg ptr, int lane); // Load 32-bit lane 0-1 of 64-bit value.
I32 load128(Arg ptr, int lane); // Load 32-bit lane 0-3 of 128-bit value.
// Load i32/f32 uniform with byte-count offset.
I32 uniform32(Arg ptr, int offset);
F32 uniformF (Arg ptr, int offset) { return this->bit_cast(this->uniform32(ptr,offset)); }
F32 uniformF (Arg ptr, int offset) { return pun_to_F32(uniform32(ptr,offset)); }
// Push and load this color as a uniform.
Color uniformColor(SkColor4f, Uniforms*);
@ -648,7 +648,7 @@ namespace skvm {
I32 gather16(Arg ptr, int offset, I32 index);
I32 gather32(Arg ptr, int offset, I32 index);
F32 gatherF (Arg ptr, int offset, I32 index) {
return bit_cast(gather32(ptr, offset, index));
return pun_to_F32(gather32(ptr, offset, index));
}
// Convenience methods for working with skvm::Uniform(s).
@ -665,7 +665,7 @@ namespace skvm {
F32 splat(float f) {
int bits;
memcpy(&bits, &f, 4);
return bit_cast(splat(bits));
return pun_to_F32(splat(bits));
}
// float math, comparisons, etc.
@ -704,16 +704,16 @@ namespace skvm {
F32 clamp(F32a x, F32a lo, F32a hi) { return clamp(_(x), _(lo), _(hi)); }
F32 clamp01(F32 x) { return clamp(x, 0.0f, 1.0f); }
F32 abs(F32 x) { return bit_cast(bit_and(bit_cast(x), 0x7fff'ffff)); }
F32 abs(F32 x) { return pun_to_F32(bit_and(pun_to_I32(x), 0x7fff'ffff)); }
F32 fract(F32 x) { return sub(x, floor(x)); }
F32 ceil(F32);
F32 floor(F32);
I32 is_NaN (F32 x) { return neq(x,x); }
I32 is_finite(F32 x) { return lt(bit_and(bit_cast(x), 0x7f80'0000), 0x7f80'0000); }
I32 is_finite(F32 x) { return lt(bit_and(pun_to_I32(x), 0x7f80'0000), 0x7f80'0000); }
I32 trunc(F32 x);
I32 round(F32 x); // Round to int using current rounding mode (as if lrintf()).
I32 bit_cast(F32 x) { return {x.builder, x.id}; }
I32 pun_to_I32(F32 x) { return {x.builder, x.id}; }
I32 to_fp16(F32 x);
F32 from_fp16(I32 x);
@ -748,7 +748,7 @@ namespace skvm {
I32 gte(I32 x, I32 y); I32 gte(I32a x, I32a y) { return gte(_(x), _(y)); }
F32 to_F32(I32 x);
F32 bit_cast(I32 x) { return {x.builder, x.id}; }
F32 pun_to_F32(I32 x) { return {x.builder, x.id}; }
// Bitwise operations.
I32 bit_and (I32, I32); I32 bit_and (I32a x, I32a y) { return bit_and (_(x), _(y)); }
@ -764,8 +764,8 @@ namespace skvm {
I32 select(I32 cond, I32 t, I32 f); // cond ? t : f
F32 select(I32 cond, F32 t, F32 f) {
return bit_cast(select(cond, bit_cast(t)
, bit_cast(f)));
return pun_to_F32(select(cond, pun_to_I32(t)
, pun_to_I32(f)));
}
I32 select(I32a cond, I32a t, I32a f) { return select(_(cond), _(t), _(f)); }
F32 select(I32a cond, F32a t, F32a f) { return select(_(cond), _(t), _(f)); }
@ -1045,13 +1045,13 @@ namespace skvm {
static inline I32 is_NaN(F32 x) { return x-> is_NaN(x); }
static inline I32 is_finite(F32 x) { return x->is_finite(x); }
static inline I32 trunc(F32 x) { return x-> trunc(x); }
static inline I32 round(F32 x) { return x-> round(x); }
static inline I32 bit_cast(F32 x) { return x-> bit_cast(x); }
static inline F32 bit_cast(I32 x) { return x-> bit_cast(x); }
static inline F32 to_F32(I32 x) { return x-> to_F32(x); }
static inline I32 to_fp16(F32 x) { return x-> to_fp16(x); }
static inline F32 from_fp16(I32 x) { return x->from_fp16(x); }
static inline I32 trunc(F32 x) { return x-> trunc(x); }
static inline I32 round(F32 x) { return x-> round(x); }
static inline I32 pun_to_I32(F32 x) { return x-> pun_to_I32(x); }
static inline F32 pun_to_F32(I32 x) { return x-> pun_to_F32(x); }
static inline F32 to_F32(I32 x) { return x-> to_F32(x); }
static inline I32 to_fp16(F32 x) { return x-> to_fp16(x); }
static inline F32 from_fp16(I32 x) { return x-> from_fp16(x); }
static inline F32 lerp(F32 lo, F32a hi, F32a t) { return lo->lerp(lo,hi,t); }
static inline F32 lerp(float lo, F32 hi, F32a t) { return hi->lerp(lo,hi,t); }

View File

@ -319,8 +319,8 @@ namespace {
// An in-gamut src blended with an in-gamut dst should stay in gamut.
// Being in-gamut implies all channels are in [0,1], so no need to clamp.
// We allow one ulp error above 1.0f, and about that much (~1.2e-7) below 0.
skvm::F32 lo = bit_cast(p->splat(0xb400'0000)),
hi = bit_cast(p->splat(0x3f80'0001));
skvm::F32 lo = pun_to_F32(p->splat(0xb400'0000)),
hi = pun_to_F32(p->splat(0x3f80'0001));
assert_true(src.r == clamp(src.r, lo, hi), src.r);
assert_true(src.g == clamp(src.g, lo, hi), src.g);
assert_true(src.b == clamp(src.b, lo, hi), src.b);

View File

@ -1040,10 +1040,10 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p,
skvm::I32 mask = p->splat(~0);
if (fTileModeX == SkTileMode::kDecal) { mask &= (sx == clamped_x); }
if (fTileModeY == SkTileMode::kDecal) { mask &= (sy == clamped_y); }
c.r = bit_cast(p->bit_and(mask, bit_cast(c.r)));
c.g = bit_cast(p->bit_and(mask, bit_cast(c.g)));
c.b = bit_cast(p->bit_and(mask, bit_cast(c.b)));
c.a = bit_cast(p->bit_and(mask, bit_cast(c.a)));
c.r = pun_to_F32(p->bit_and(mask, pun_to_I32(c.r)));
c.g = pun_to_F32(p->bit_and(mask, pun_to_I32(c.g)));
c.b = pun_to_F32(p->bit_and(mask, pun_to_I32(c.b)));
c.a = pun_to_F32(p->bit_and(mask, pun_to_I32(c.a)));
// Notice that even if input_is_opaque, c.a might now be 0.
}

View File

@ -593,10 +593,10 @@ skvm::Color SkGradientShaderBase::onProgram(skvm::Builder* p,
}
return {
bit_cast(mask & bit_cast(color.r)),
bit_cast(mask & bit_cast(color.g)),
bit_cast(mask & bit_cast(color.b)),
bit_cast(mask & bit_cast(color.a)),
pun_to_F32(mask & pun_to_I32(color.r)),
pun_to_F32(mask & pun_to_I32(color.g)),
pun_to_F32(mask & pun_to_I32(color.b)),
pun_to_F32(mask & pun_to_I32(color.a)),
};
}

View File

@ -2408,7 +2408,7 @@ DEF_TEST(SkVM_badpack, r) {
skvm::Arg uniforms = p.uniform(),
dst = p.varying<uint16_t>();
skvm::I32 r = round(bit_cast(p.uniform32(uniforms, 8)) * 15),
skvm::I32 r = round(p.uniformF(uniforms, 8) * 15),
a = p.splat(0xf);
skvm::I32 _4444 = p.splat(0);