Reland "uniform Ptr (UPtr) is a sub class of Ptr"
This is a reland of cef047a490
Fix strides in SkVMTest to be the right size.
Original change's description:
> uniform Ptr (UPtr) is a sub class of Ptr
>
> A pointer for a Uniform (UPtr) is a sub type of a Ptr. Everywhere you
> can use a Ptr a UPtr will work, but you can't use Ptr where you need
> a UPtr. All the UPtr instructions uniformF, gather32, etc are expected
> to be hoisted and therefore loaded only once. While the varyings
> instructions like load32, etc. are expected to remain in the body
> of the loop, and be evaluated each time through the loop.
>
> Change-Id: I4fe6458c2a4614872ed67cda1e81b05ea8a9e69e
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/436297
> Commit-Queue: Herb Derby <herb@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>
Change-Id: I858fa1224452ec801b6186fede353849edc895b5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/436564
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
cc04b6f0bf
commit
ea17e2499d
@ -146,7 +146,7 @@ void SkParticleEffectParams::prepare(const skresources::ResourceProvider* resour
|
||||
// and after it's populated, the values never need to be touched again.
|
||||
// The second uniform arg is for things declared as 'uniform' in the SkSL (including the
|
||||
// built-in declarations of 'dt' and 'effect').
|
||||
skvm::Uniforms efUniforms(skvm::Ptr{0}, 0);
|
||||
skvm::Uniforms efUniforms(skvm::UPtr{0}, 0);
|
||||
auto alloc = std::make_unique<SkArenaAlloc>(0);
|
||||
|
||||
std::vector<std::unique_ptr<SkSL::ExternalFunction>> externalFns;
|
||||
@ -178,8 +178,8 @@ void SkParticleEffectParams::prepare(const skresources::ResourceProvider* resour
|
||||
}
|
||||
|
||||
skvm::Builder b;
|
||||
skvm::Ptr efUniformPtr = b.uniform(), // aka efUniforms.base
|
||||
skslUniformPtr = b.uniform();
|
||||
skvm::UPtr efUniformPtr = b.uniform(), // aka efUniforms.base
|
||||
skslUniformPtr = b.uniform();
|
||||
(void)efUniformPtr;
|
||||
|
||||
std::vector<skvm::Val> uniformIDs;
|
||||
|
@ -658,7 +658,8 @@ std::unique_ptr<SkFilterColorProgram> SkFilterColorProgram::Make(const SkRuntime
|
||||
/*sampleBlender=*/nullptr);
|
||||
|
||||
// Then store the result to the *third* arg ptr
|
||||
p.store({skvm::PixelFormat::FLOAT, 32, 32, 32, 32, 0, 32, 64, 96}, p.arg(16), result);
|
||||
p.store({skvm::PixelFormat::FLOAT, 32, 32, 32, 32, 0, 32, 64, 96},
|
||||
p.varying<skvm::F32>(), result);
|
||||
|
||||
if (!allSampleCallsSupported) {
|
||||
return nullptr;
|
||||
|
@ -610,22 +610,22 @@ namespace skvm {
|
||||
return {this, push(Op::load128, NA,NA,NA,NA, ptr.ix,lane) };
|
||||
}
|
||||
|
||||
I32 Builder::gather8 (Ptr ptr, int offset, I32 index) {
|
||||
I32 Builder::gather8 (UPtr ptr, int offset, I32 index) {
|
||||
return {this, push(Op::gather8 , index.id,NA,NA,NA, ptr.ix,offset)};
|
||||
}
|
||||
I32 Builder::gather16(Ptr ptr, int offset, I32 index) {
|
||||
I32 Builder::gather16(UPtr ptr, int offset, I32 index) {
|
||||
return {this, push(Op::gather16, index.id,NA,NA,NA, ptr.ix,offset)};
|
||||
}
|
||||
I32 Builder::gather32(Ptr ptr, int offset, I32 index) {
|
||||
I32 Builder::gather32(UPtr ptr, int offset, I32 index) {
|
||||
return {this, push(Op::gather32, index.id,NA,NA,NA, ptr.ix,offset)};
|
||||
}
|
||||
|
||||
I32 Builder::uniform32(Ptr ptr, int offset) {
|
||||
I32 Builder::uniform32(UPtr ptr, int offset) {
|
||||
return {this, push(Op::uniform32, NA,NA,NA,NA, ptr.ix, offset)};
|
||||
}
|
||||
|
||||
// Note: this converts the array index into a byte offset for the op.
|
||||
I32 Builder::array32 (Ptr ptr, int offset, int index) {
|
||||
I32 Builder::array32 (UPtr ptr, int offset, int index) {
|
||||
return {this, push(Op::array32, NA,NA,NA,NA, ptr.ix, offset, index * sizeof(int))};
|
||||
}
|
||||
|
||||
@ -1178,7 +1178,7 @@ namespace skvm {
|
||||
return {};
|
||||
}
|
||||
|
||||
Color Builder::gather(PixelFormat f, Ptr ptr, int offset, I32 index) {
|
||||
Color Builder::gather(PixelFormat f, UPtr ptr, int offset, I32 index) {
|
||||
switch (byte_size(f)) {
|
||||
case 1: return unpack(f, gather8 (ptr, offset, index));
|
||||
case 2: return unpack(f, gather16(ptr, offset, index));
|
||||
|
@ -478,7 +478,12 @@ namespace skvm {
|
||||
// NA meaning none, n/a, null, nil, etc.
|
||||
static const Val NA = -1;
|
||||
|
||||
// Ptr and UPtr are an index into the registers args[]. The two styles of using args are
|
||||
// varyings and uniforms. Varyings use Ptr, have a stride associated with them, and are
|
||||
// evaluated everytime through the loop. Uniforms use UPtr, don't have a stride, and are
|
||||
// usually hoisted above the loop.
|
||||
struct Ptr { int ix; };
|
||||
struct UPtr : public Ptr {};
|
||||
|
||||
bool operator!=(Ptr a, Ptr b);
|
||||
|
||||
@ -515,14 +520,14 @@ namespace skvm {
|
||||
};
|
||||
|
||||
struct Uniform {
|
||||
Ptr ptr;
|
||||
UPtr ptr;
|
||||
int offset;
|
||||
};
|
||||
struct Uniforms {
|
||||
Ptr base;
|
||||
UPtr base;
|
||||
std::vector<int> buf;
|
||||
|
||||
Uniforms(Ptr ptr, int init) : base(ptr), buf(init) {}
|
||||
Uniforms(UPtr ptr, int init) : base(ptr), buf(init) {}
|
||||
|
||||
Uniform push(int val) {
|
||||
buf.push_back(val);
|
||||
@ -600,14 +605,11 @@ namespace skvm {
|
||||
std::vector<Instruction> program() const { return fProgram; }
|
||||
std::vector<OptimizedInstruction> optimize() const;
|
||||
|
||||
// Declare an argument with given stride (use stride=0 for uniforms).
|
||||
// TODO: different types for varying and uniforms?
|
||||
Ptr arg(int stride);
|
||||
|
||||
// Convenience arg() wrappers for most common strides, sizeof(T) and 0.
|
||||
template <typename T>
|
||||
Ptr varying() { return this->arg(sizeof(T)); }
|
||||
Ptr uniform() { return this->arg(0); }
|
||||
Ptr varying(int stride) { SkASSERT(stride > 0); return this->arg(stride); }
|
||||
UPtr uniform() { Ptr p = this->arg(0); return UPtr{{p.ix}}; }
|
||||
|
||||
// TODO: allow uniform (i.e. Ptr) offsets to store* and load*?
|
||||
// TODO: sign extension (signed types) for <32-bit loads?
|
||||
@ -638,13 +640,13 @@ namespace skvm {
|
||||
I32 load128(Ptr ptr, int lane); // Load 32-bit lane 0-3 of 128-bit value.
|
||||
|
||||
// Load i32/f32 uniform with byte-count offset.
|
||||
I32 uniform32(Ptr ptr, int offset);
|
||||
F32 uniformF (Ptr ptr, int offset) { return pun_to_F32(uniform32(ptr,offset)); }
|
||||
I32 uniform32(UPtr ptr, int offset);
|
||||
F32 uniformF (UPtr ptr, int offset) { return pun_to_F32(uniform32(ptr,offset)); }
|
||||
|
||||
// Load i32/f32 uniform with byte-count offset and an c-style array index. The address of
|
||||
// the element is (*(ptr + byte-count offset))[index].
|
||||
I32 array32 (Ptr ptr, int offset, int index);
|
||||
F32 arrayF (Ptr ptr, int offset, int index) {
|
||||
I32 array32 (UPtr ptr, int offset, int index);
|
||||
F32 arrayF (UPtr ptr, int offset, int index) {
|
||||
return pun_to_F32(array32(ptr, offset, index));
|
||||
}
|
||||
|
||||
@ -652,10 +654,10 @@ namespace skvm {
|
||||
Color uniformColor(SkColor4f, Uniforms*);
|
||||
|
||||
// Gather u8,u16,i32 with varying element-count index from *(ptr + byte-count offset).
|
||||
I32 gather8 (Ptr ptr, int offset, I32 index);
|
||||
I32 gather16(Ptr ptr, int offset, I32 index);
|
||||
I32 gather32(Ptr ptr, int offset, I32 index);
|
||||
F32 gatherF (Ptr ptr, int offset, I32 index) {
|
||||
I32 gather8 (UPtr ptr, int offset, I32 index);
|
||||
I32 gather16(UPtr ptr, int offset, I32 index);
|
||||
I32 gather32(UPtr ptr, int offset, I32 index);
|
||||
F32 gatherF (UPtr ptr, int offset, I32 index) {
|
||||
return pun_to_F32(gather32(ptr, offset, index));
|
||||
}
|
||||
|
||||
@ -905,7 +907,7 @@ namespace skvm {
|
||||
|
||||
Color load(PixelFormat, Ptr ptr);
|
||||
void store(PixelFormat, Ptr ptr, Color);
|
||||
Color gather(PixelFormat, Ptr ptr, int offset, I32 index);
|
||||
Color gather(PixelFormat, UPtr ptr, int offset, I32 index);
|
||||
Color gather(PixelFormat f, Uniform u, I32 index) {
|
||||
return gather(f, u.ptr, u.offset, index);
|
||||
}
|
||||
@ -957,6 +959,9 @@ namespace skvm {
|
||||
}
|
||||
|
||||
private:
|
||||
// Declare an argument with given stride (use stride=0 for uniforms).
|
||||
Ptr arg(int stride);
|
||||
|
||||
Val push(
|
||||
Op op, Val x=NA, Val y=NA, Val z=NA, Val w=NA, int immA=0, int immB=0, int immC=0) {
|
||||
return this->push(Instruction{op, x,y,z,w, immA,immB,immC});
|
||||
@ -1171,10 +1176,10 @@ namespace skvm {
|
||||
SI void store64 (Ptr ptr, I32 lo, I32 hi) { lo ->store64 (ptr, lo,hi); }
|
||||
SI void store128(Ptr ptr, I32 x, I32 y, I32 z, I32 w) { x ->store128(ptr, x,y,z,w); }
|
||||
|
||||
SI I32 gather8 (Ptr ptr, int off, I32 ix) { return ix->gather8 (ptr, off, ix); }
|
||||
SI I32 gather16(Ptr ptr, int off, I32 ix) { return ix->gather16(ptr, off, ix); }
|
||||
SI I32 gather32(Ptr ptr, int off, I32 ix) { return ix->gather32(ptr, off, ix); }
|
||||
SI F32 gatherF (Ptr ptr, int off, I32 ix) { return ix->gatherF (ptr, off, ix); }
|
||||
SI I32 gather8 (UPtr ptr, int off, I32 ix) { return ix->gather8 (ptr, off, ix); }
|
||||
SI I32 gather16(UPtr ptr, int off, I32 ix) { return ix->gather16(ptr, off, ix); }
|
||||
SI I32 gather32(UPtr ptr, int off, I32 ix) { return ix->gather32(ptr, off, ix); }
|
||||
SI F32 gatherF (UPtr ptr, int off, I32 ix) { return ix->gatherF (ptr, off, ix); }
|
||||
|
||||
SI I32 gather8 (Uniform u, I32 ix) { return ix->gather8 (u, ix); }
|
||||
SI I32 gather16(Uniform u, I32 ix) { return ix->gather16(u, ix); }
|
||||
@ -1287,8 +1292,8 @@ namespace skvm {
|
||||
|
||||
SI void store(PixelFormat f, Ptr p, Color c) { return c->store(f,p,c); }
|
||||
|
||||
SI Color gather(PixelFormat f, Ptr p, int off, I32 ix) { return ix->gather(f,p,off,ix); }
|
||||
SI Color gather(PixelFormat f, Uniform u , I32 ix) { return ix->gather(f,u,ix); }
|
||||
SI Color gather(PixelFormat f, UPtr p, int off, I32 ix) { return ix->gather(f,p,off,ix); }
|
||||
SI Color gather(PixelFormat f, Uniform u , I32 ix) { return ix->gather(f,u,ix); }
|
||||
|
||||
SI void premul(F32* r, F32* g, F32* b, F32 a) { a-> premul(r,g,b,a); }
|
||||
SI void unpremul(F32* r, F32* g, F32* b, F32 a) { a->unpremul(r,g,b,a); }
|
||||
|
@ -78,7 +78,7 @@ namespace {
|
||||
|
||||
skvm::PixelFormat fmt = skvm::SkColorType_to_PixelFormat(ct);
|
||||
|
||||
skvm::Color c = p->load(fmt, p->arg(SkColorTypeBytesPerPixel(ct)));
|
||||
skvm::Color c = p->load(fmt, p->varying(SkColorTypeBytesPerPixel(ct)));
|
||||
|
||||
return SkColorSpaceXformSteps{fSprite, dst}.program(p, uniforms, c);
|
||||
}
|
||||
@ -289,7 +289,7 @@ SkVMBlitter::Params SkVMBlitter::EffectiveParams(const SkPixmap& device,
|
||||
|
||||
skvm::Color SkVMBlitter::DstColor(skvm::Builder* p, const Params& params) {
|
||||
skvm::PixelFormat dstFormat = skvm::SkColorType_to_PixelFormat(params.dst.colorType());
|
||||
skvm::Ptr dst_ptr = p->arg(SkColorTypeBytesPerPixel(params.dst.colorType()));
|
||||
skvm::Ptr dst_ptr = p->varying(SkColorTypeBytesPerPixel(params.dst.colorType()));
|
||||
return p->load(dstFormat, dst_ptr);
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ void SkVMBlitter::BuildProgram(skvm::Builder* p, const Params& params,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc* alloc) {
|
||||
// First two arguments are always uniforms and the destination buffer.
|
||||
uniforms->base = p->uniform();
|
||||
skvm::Ptr dst_ptr = p->arg(SkColorTypeBytesPerPixel(params.dst.colorType()));
|
||||
skvm::Ptr dst_ptr = p->varying(SkColorTypeBytesPerPixel(params.dst.colorType()));
|
||||
// A SpriteShader (in this file) may next use one argument as its varying source.
|
||||
// Subsequent arguments depend on params.coverage:
|
||||
// - Full: (no more arguments)
|
||||
@ -556,7 +556,7 @@ SkVMBlitter::SkVMBlitter(const SkPixmap& device,
|
||||
bool* ok)
|
||||
: fDevice(device), fSprite(sprite ? *sprite : SkPixmap{})
|
||||
, fSpriteOffset(spriteOffset)
|
||||
, fUniforms(skvm::Ptr{0}, kBlitterUniformsCount)
|
||||
, fUniforms(skvm::UPtr{{0}}, kBlitterUniformsCount)
|
||||
, fParams(EffectiveParams(device, sprite, paint, matrices, std::move(clip)))
|
||||
, fKey(CacheKey(fParams, &fUniforms, &fAlloc, ok)) {}
|
||||
|
||||
|
@ -527,7 +527,7 @@ DEF_TEST(SkSLInterpreterCompound, r) {
|
||||
|
||||
auto build = [&](const SkSL::FunctionDefinition* fn) {
|
||||
skvm::Builder b;
|
||||
skvm::Ptr uniformPtr = b.uniform();
|
||||
skvm::UPtr uniformPtr = b.uniform();
|
||||
skvm::Val uniforms[16];
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
uniforms[i] = b.uniform32(uniformPtr, i * sizeof(int)).id;
|
||||
|
@ -138,8 +138,8 @@ DEF_TEST(SkVM_LoopCounts, r) {
|
||||
DEF_TEST(SkVM_gather32, r) {
|
||||
skvm::Builder b;
|
||||
{
|
||||
skvm::Ptr uniforms = b.uniform(),
|
||||
buf = b.varying<int>();
|
||||
skvm::UPtr uniforms = b.uniform();
|
||||
skvm::Ptr buf = b.varying<int>();
|
||||
skvm::I32 x = b.load32(buf);
|
||||
b.store32(buf, b.gather32(uniforms,0, b.bit_and(x, b.splat(7))));
|
||||
}
|
||||
@ -186,8 +186,8 @@ DEF_TEST(SkVM_gather32, r) {
|
||||
DEF_TEST(SkVM_gathers, r) {
|
||||
skvm::Builder b;
|
||||
{
|
||||
skvm::Ptr uniforms = b.uniform(),
|
||||
buf32 = b.varying<int>(),
|
||||
skvm::UPtr uniforms = b.uniform();
|
||||
skvm::Ptr buf32 = b.varying<int>(),
|
||||
buf16 = b.varying<uint16_t>(),
|
||||
buf8 = b.varying<uint8_t>();
|
||||
|
||||
@ -244,8 +244,8 @@ DEF_TEST(SkVM_gathers, r) {
|
||||
DEF_TEST(SkVM_gathers2, r) {
|
||||
skvm::Builder b;
|
||||
{
|
||||
skvm::Ptr uniforms = b.uniform(),
|
||||
buf32 = b.varying<int>(),
|
||||
skvm::UPtr uniforms = b.uniform();
|
||||
skvm::Ptr buf32 = b.varying<int>(),
|
||||
buf16 = b.varying<uint16_t>(),
|
||||
buf8 = b.varying<uint8_t>();
|
||||
|
||||
@ -714,8 +714,8 @@ DEF_TEST(SkVM_NewOps, r) {
|
||||
// Exercise a somewhat arbitrary set of new ops.
|
||||
skvm::Builder b;
|
||||
{
|
||||
skvm::Ptr buf = b.varying<int16_t>(),
|
||||
uniforms = b.uniform();
|
||||
skvm::Ptr buf = b.varying<int16_t>();
|
||||
skvm::UPtr uniforms = b.uniform();
|
||||
|
||||
skvm::I32 x = b.load16(buf);
|
||||
|
||||
@ -2331,8 +2331,8 @@ DEF_TEST(SkVM_128bit, r) {
|
||||
{ // Convert RGBA F32 to RGBA 8888, testing 128-bit loads.
|
||||
skvm::Builder b;
|
||||
{
|
||||
skvm::Ptr dst = b.arg( 4),
|
||||
src = b.arg(16);
|
||||
skvm::Ptr dst = b.varying(4),
|
||||
src = b.varying(16);
|
||||
|
||||
skvm::Color c = b.load(rgba_ffff, src);
|
||||
b.store(rgba_8888, dst, c);
|
||||
@ -2350,8 +2350,8 @@ DEF_TEST(SkVM_128bit, r) {
|
||||
{ // Convert RGBA 8888 to RGBA F32, testing 128-bit stores.
|
||||
skvm::Builder b;
|
||||
{
|
||||
skvm::Ptr dst = b.arg(16),
|
||||
src = b.arg( 4);
|
||||
skvm::Ptr dst = b.varying(16),
|
||||
src = b.varying(4);
|
||||
|
||||
skvm::Color c = b.load(rgba_8888, src);
|
||||
b.store(rgba_ffff, dst, c);
|
||||
@ -2425,8 +2425,8 @@ DEF_TEST(SkVM_badpack, reporter) {
|
||||
// originally with a bad arm64 implementation of pack().
|
||||
skvm::Builder p;
|
||||
{
|
||||
skvm::Ptr uniforms = p.uniform(),
|
||||
dst = p.varying<uint16_t>();
|
||||
skvm::UPtr uniforms = p.uniform();
|
||||
skvm::Ptr dst = p.varying<uint16_t>();
|
||||
|
||||
skvm::I32 r = round(p.uniformF(uniforms, 8) * 15),
|
||||
a = p.splat(0xf);
|
||||
@ -2484,8 +2484,8 @@ DEF_TEST(SkVM_gather_can_hoist, r) {
|
||||
// First a typical gather scenario with varying index.
|
||||
{
|
||||
skvm::Builder b;
|
||||
skvm::Ptr uniforms = b.uniform(),
|
||||
buf = b.varying<int>();
|
||||
skvm::UPtr uniforms = b.uniform();
|
||||
skvm::Ptr buf = b.varying<int>();
|
||||
skvm::I32 ix = b.load32(buf);
|
||||
b.store32(buf, b.gather32(uniforms,0, ix));
|
||||
|
||||
@ -2504,8 +2504,8 @@ DEF_TEST(SkVM_gather_can_hoist, r) {
|
||||
// Now the same but with a uniform index instead.
|
||||
{
|
||||
skvm::Builder b;
|
||||
skvm::Ptr uniforms = b.uniform(),
|
||||
buf = b.varying<int>();
|
||||
skvm::UPtr uniforms = b.uniform();
|
||||
skvm::Ptr buf = b.varying<int>();
|
||||
skvm::I32 ix = b.uniform32(uniforms,8);
|
||||
b.store32(buf, b.gather32(uniforms,0, ix));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user