add array to the Uniforms
Note: I have changed from using a byte offset for index to an ordinary array index at the builder interface, but the builder converts this to a byte offset for the instruction. This makes the API easier to use. I've added pushArray, and pushArrayF to the Uniforms, and convenience methods on the builder to take Uniforms. I've expanded the tests to use the new API. Change-Id: Id538e826a96d4d242ae6482acc711d84c9041239 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/432036 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
294d687b69
commit
a4953515af
@ -624,8 +624,9 @@ namespace skvm {
|
||||
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) {
|
||||
return {this, push(Op::array32, NA,NA,NA,NA, ptr.ix, offset, index)};
|
||||
return {this, push(Op::array32, NA,NA,NA,NA, ptr.ix, offset, index * sizeof(int))};
|
||||
}
|
||||
|
||||
I32 Builder::splat(int n) { return {this, push(Op::splat, NA,NA,NA,NA, n) }; }
|
||||
|
@ -544,6 +544,14 @@ namespace skvm {
|
||||
}
|
||||
return {base, (int)( sizeof(int)*(buf.size() - SK_ARRAY_COUNT(ints)) )};
|
||||
}
|
||||
|
||||
Uniform pushArray(int32_t a[]) {
|
||||
return this->pushPtr(a);
|
||||
}
|
||||
|
||||
Uniform pushArrayF(float a[]) {
|
||||
return this->pushPtr(a);
|
||||
}
|
||||
};
|
||||
|
||||
struct PixelFormat {
|
||||
@ -633,8 +641,12 @@ namespace skvm {
|
||||
I32 uniform32(Ptr ptr, int offset);
|
||||
F32 uniformF (Ptr ptr, int offset) { return pun_to_F32(uniform32(ptr,offset)); }
|
||||
|
||||
// Load i32/f32 uniform with byte-count offset and index.
|
||||
// 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) {
|
||||
return pun_to_F32(array32(ptr, offset, index));
|
||||
}
|
||||
|
||||
// Push and load this color as a uniform.
|
||||
Color uniformColor(SkColor4f, Uniforms*);
|
||||
@ -655,6 +667,11 @@ namespace skvm {
|
||||
I32 gather32 (Uniform u, I32 index) { return this->gather32 (u.ptr, u.offset, index); }
|
||||
F32 gatherF (Uniform u, I32 index) { return this->gatherF (u.ptr, u.offset, index); }
|
||||
|
||||
// Convenience methods for working with array pointers in skvm::Uniforms. Index is an
|
||||
// array index and not a byte offset. The array pointer is stored at u.
|
||||
I32 array32 (Uniform a, int index) { return this->array32 (a.ptr, a.offset, index); }
|
||||
F32 arrayF (Uniform a, int index) { return this->arrayF (a.ptr, a.offset, index); }
|
||||
|
||||
// Load an immediate constant.
|
||||
I32 splat(int n);
|
||||
I32 splat(unsigned u) { return splat((int)u); }
|
||||
|
@ -770,42 +770,63 @@ DEF_TEST(SkVM_NewOps, r) {
|
||||
}
|
||||
|
||||
DEF_TEST(SKVM_array32, r) {
|
||||
|
||||
|
||||
|
||||
skvm::Builder b;
|
||||
skvm::Uniforms uniforms(b.uniform(), 0);
|
||||
// Take up the first slot, so other uniforms are not at 0 offset.
|
||||
uniforms.push(0);
|
||||
int i[] = {3, 7};
|
||||
skvm::Uniform array = uniforms.pushArray(i);
|
||||
float f[] = {5, 9};
|
||||
skvm::Uniform arrayF = uniforms.pushArrayF(f);
|
||||
{
|
||||
skvm::Ptr buf0 = b.varying<int32_t>(),
|
||||
buf1 = b.varying<int32_t>(),
|
||||
uniforms = b.uniform();
|
||||
buf2 = b.varying<int32_t>();
|
||||
|
||||
skvm::I32 x = b.array32(uniforms, 0, 0);
|
||||
b.store32(buf0, x);
|
||||
skvm::I32 y = b.array32(uniforms, 0, 4);
|
||||
b.store32(buf1, y);
|
||||
skvm::I32 j = b.array32(array, 0);
|
||||
b.store32(buf0, j);
|
||||
skvm::I32 k = b.array32(array, 1);
|
||||
b.store32(buf1, k);
|
||||
|
||||
skvm::F32 x = b.arrayF(arrayF, 0);
|
||||
skvm::F32 y = b.arrayF(arrayF, 1);
|
||||
b.store32(buf2, b.trunc(b.add(x, y)));
|
||||
}
|
||||
|
||||
test_jit_and_interpreter(b, [&](const skvm::Program& program) {
|
||||
const int K = 20;
|
||||
int i[2] = {3, 7};
|
||||
struct {
|
||||
int* g;
|
||||
} uniforms{i};
|
||||
int32_t buf0[K];
|
||||
int32_t buf1[K];
|
||||
const int K = 10;
|
||||
int32_t buf0[K],
|
||||
buf1[K],
|
||||
buf2[K];
|
||||
|
||||
program.eval(K, buf0, buf1, &uniforms);
|
||||
// reset the i[0] for the two tests.
|
||||
i[0] = 3;
|
||||
f[1] = 9;
|
||||
program.eval(K, uniforms.buf.data(), buf0, buf1, buf2);
|
||||
for (auto v : buf0) {
|
||||
REPORTER_ASSERT(r, v == 3);
|
||||
}
|
||||
for (auto v : buf1) {
|
||||
REPORTER_ASSERT(r, v == 7);
|
||||
}
|
||||
for (auto v : buf2) {
|
||||
REPORTER_ASSERT(r, v == 14);
|
||||
}
|
||||
i[0] = 4;
|
||||
program.eval(K, buf0, buf1, &uniforms);
|
||||
f[1] = 10;
|
||||
program.eval(K, uniforms.buf.data(), buf0, buf1, buf2);
|
||||
for (auto v : buf0) {
|
||||
REPORTER_ASSERT(r, v == 4);
|
||||
}
|
||||
for (auto v : buf1) {
|
||||
REPORTER_ASSERT(r, v == 7);
|
||||
}
|
||||
for (auto v : buf2) {
|
||||
REPORTER_ASSERT(r, v == 15);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user