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:
parent
bb9fbe057a
commit
5ec9c4e763
@ -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};
|
||||
|
@ -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: {
|
||||
|
@ -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);
|
||||
|
@ -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); }
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
}
|
||||
|
||||
|
@ -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)),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user