tweak gathers in skvm interpreter

- simplify 1-stride gathers by using broadcasts
  - use map() for base-case full-stride gathers

  - TODO: use vpgatherdd for full-stride gathers when possible

Change-Id: Icedcea17ae8fa4ad7344cd2604358fd710921af2
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317648
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Klein 2020-09-17 08:54:08 -05:00 committed by Skia Commit-Bot
parent ec598d5b00
commit feb4d10f7b

View File

@ -151,43 +151,37 @@ namespace SK_OPTS_NS {
// - memcpy() loads the gather base and into a pointer of the right type.
// After all that we have an ordinary (uniform) pointer `ptr` to load from,
// and we then gather from it using the varying indices in r[x].
STRIDE_1(Op::gather8):
for (int i = 0; i < K; i++) {
const uint8_t* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32[i] = (i==0) ? ptr[ r[x].i32[i] ] : 0;
} break;
STRIDE_1(Op::gather16):
for (int i = 0; i < K; i++) {
const uint16_t* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32[i] = (i==0) ? ptr[ r[x].i32[i] ] : 0;
} break;
STRIDE_1(Op::gather32):
for (int i = 0; i < K; i++) {
const int* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32[i] = (i==0) ? ptr[ r[x].i32[i] ] : 0;
} break;
STRIDE_1(Op::gather8): {
const uint8_t* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32 = ptr[ r[x].i32[0] ];
} break;
STRIDE_1(Op::gather16): {
const uint16_t* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32 = ptr[ r[x].i32[0] ];
} break;
STRIDE_1(Op::gather32): {
const int* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32 = ptr[ r[x].i32[0] ];
} break;
STRIDE_K(Op::gather8):
for (int i = 0; i < K; i++) {
const uint8_t* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32[i] = ptr[ r[x].i32[i] ];
} break;
STRIDE_K(Op::gather16):
for (int i = 0; i < K; i++) {
const uint16_t* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32[i] = ptr[ r[x].i32[i] ];
} break;
STRIDE_K(Op::gather32):
for (int i = 0; i < K; i++) {
const int* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32[i] = ptr[ r[x].i32[i] ];
} break;
STRIDE_K(Op::gather8): {
const uint8_t* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32 = map(r[x].i32, [&](int ix) { return (int)ptr[ix]; });
} break;
STRIDE_K(Op::gather16): {
const uint16_t* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32 = map(r[x].i32, [&](int ix) { return (int)ptr[ix]; });
} break;
STRIDE_K(Op::gather32): {
const int* ptr;
memcpy(&ptr, (const uint8_t*)args[immy] + immz, sizeof(ptr));
r[d].i32 = map(r[x].i32, [&](int ix) { return ptr[ix]; });
} break;
#undef STRIDE_1
#undef STRIDE_K