1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/private/SkHalf.h" 9cb93a386Sopenharmony_ci#include "include/private/SkTo.h" 10cb93a386Sopenharmony_ci#include "src/core/SkRasterPipeline.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrSwizzle.h" 12cb93a386Sopenharmony_ci#include "tests/Test.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ciDEF_TEST(SkRasterPipeline, r) { 15cb93a386Sopenharmony_ci // Build and run a simple pipeline to exercise SkRasterPipeline, 16cb93a386Sopenharmony_ci // drawing 50% transparent blue over opaque red in half-floats. 17cb93a386Sopenharmony_ci uint64_t red = 0x3c00000000003c00ull, 18cb93a386Sopenharmony_ci blue = 0x3800380000000000ull, 19cb93a386Sopenharmony_ci result; 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx load_s_ctx = { &blue, 0 }, 22cb93a386Sopenharmony_ci load_d_ctx = { &red, 0 }, 23cb93a386Sopenharmony_ci store_ctx = { &result, 0 }; 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 26cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_f16, &load_s_ctx); 27cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_f16_dst, &load_d_ctx); 28cb93a386Sopenharmony_ci p.append(SkRasterPipeline::srcover); 29cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_f16, &store_ctx); 30cb93a386Sopenharmony_ci p.run(0,0,1,1); 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci // We should see half-intensity magenta. 33cb93a386Sopenharmony_ci REPORTER_ASSERT(r, ((result >> 0) & 0xffff) == 0x3800); 34cb93a386Sopenharmony_ci REPORTER_ASSERT(r, ((result >> 16) & 0xffff) == 0x0000); 35cb93a386Sopenharmony_ci REPORTER_ASSERT(r, ((result >> 32) & 0xffff) == 0x3800); 36cb93a386Sopenharmony_ci REPORTER_ASSERT(r, ((result >> 48) & 0xffff) == 0x3c00); 37cb93a386Sopenharmony_ci} 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ciDEF_TEST(SkRasterPipeline_empty, r) { 40cb93a386Sopenharmony_ci // No asserts... just a test that this is safe to run. 41cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 42cb93a386Sopenharmony_ci p.run(0,0,20,1); 43cb93a386Sopenharmony_ci} 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ciDEF_TEST(SkRasterPipeline_nonsense, r) { 46cb93a386Sopenharmony_ci // No asserts... just a test that this is safe to run and terminates. 47cb93a386Sopenharmony_ci // srcover() calls st->next(); this makes sure we've always got something there to call. 48cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 49cb93a386Sopenharmony_ci p.append(SkRasterPipeline::srcover); 50cb93a386Sopenharmony_ci p.run(0,0,20,1); 51cb93a386Sopenharmony_ci} 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ciDEF_TEST(SkRasterPipeline_JIT, r) { 54cb93a386Sopenharmony_ci // This tests a couple odd corners that a JIT backend can stumble over. 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci uint32_t buf[72] = { 57cb93a386Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58cb93a386Sopenharmony_ci 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 59cb93a386Sopenharmony_ci 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 60cb93a386Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61cb93a386Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62cb93a386Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63cb93a386Sopenharmony_ci }; 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { buf + 0, 0 }, 66cb93a386Sopenharmony_ci dst = { buf + 36, 0 }; 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci // Copy buf[x] to buf[x+36] for x in [15,35). 69cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 70cb93a386Sopenharmony_ci p.append(SkRasterPipeline:: load_8888, &src); 71cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_8888, &dst); 72cb93a386Sopenharmony_ci p.run(15,0, 20,1); 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci for (int i = 0; i < 36; i++) { 75cb93a386Sopenharmony_ci if (i < 15 || i == 35) { 76cb93a386Sopenharmony_ci REPORTER_ASSERT(r, buf[i+36] == 0); 77cb93a386Sopenharmony_ci } else { 78cb93a386Sopenharmony_ci REPORTER_ASSERT(r, buf[i+36] == (uint32_t)(i - 11)); 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci} 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_cistatic uint16_t h(float f) { 84cb93a386Sopenharmony_ci // Remember, a float is 1-8-23 (sign-exponent-mantissa) with 127 exponent bias. 85cb93a386Sopenharmony_ci uint32_t sem; 86cb93a386Sopenharmony_ci memcpy(&sem, &f, sizeof(sem)); 87cb93a386Sopenharmony_ci uint32_t s = sem & 0x80000000, 88cb93a386Sopenharmony_ci em = sem ^ s; 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ci // Convert to 1-5-10 half with 15 bias, flushing denorm halfs (including zero) to zero. 91cb93a386Sopenharmony_ci auto denorm = (int32_t)em < 0x38800000; // I32 comparison is often quicker, and always safe 92cb93a386Sopenharmony_ci // here. 93cb93a386Sopenharmony_ci return denorm ? SkTo<uint16_t>(0) 94cb93a386Sopenharmony_ci : SkTo<uint16_t>((s>>16) + (em>>13) - ((127-15)<<10)); 95cb93a386Sopenharmony_ci} 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ciDEF_TEST(SkRasterPipeline_tail, r) { 98cb93a386Sopenharmony_ci { 99cb93a386Sopenharmony_ci float data[][4] = { 100cb93a386Sopenharmony_ci {00, 01, 02, 03}, 101cb93a386Sopenharmony_ci {10, 11, 12, 13}, 102cb93a386Sopenharmony_ci {20, 21, 22, 23}, 103cb93a386Sopenharmony_ci {30, 31, 32, 33}, 104cb93a386Sopenharmony_ci }; 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ci float buffer[4][4]; 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0][0], 0 }, 109cb93a386Sopenharmony_ci dst = { &buffer[0][0], 0 }; 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 112cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 113cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 114cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_f32, &src); 115cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_f32, &dst); 116cb93a386Sopenharmony_ci p.run(0,0, i,1); 117cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 118cb93a386Sopenharmony_ci for (unsigned k = 0; k < 4; k++) { 119cb93a386Sopenharmony_ci if (buffer[j][k] != data[j][k]) { 120cb93a386Sopenharmony_ci ERRORF(r, "(%u, %u) - a: %g r: %g\n", j, k, data[j][k], buffer[j][k]); 121cb93a386Sopenharmony_ci } 122cb93a386Sopenharmony_ci } 123cb93a386Sopenharmony_ci } 124cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 125cb93a386Sopenharmony_ci for (auto f : buffer[j]) { 126cb93a386Sopenharmony_ci REPORTER_ASSERT(r, SkScalarIsNaN(f)); 127cb93a386Sopenharmony_ci } 128cb93a386Sopenharmony_ci } 129cb93a386Sopenharmony_ci } 130cb93a386Sopenharmony_ci } 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_ci { 133cb93a386Sopenharmony_ci float data[][2] = { 134cb93a386Sopenharmony_ci {00, 01}, 135cb93a386Sopenharmony_ci {10, 11}, 136cb93a386Sopenharmony_ci {20, 21}, 137cb93a386Sopenharmony_ci {30, 31}, 138cb93a386Sopenharmony_ci }; 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci float buffer[4][4]; 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0][0], 0 }, 143cb93a386Sopenharmony_ci dst = { &buffer[0][0], 0 }; 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 146cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 147cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 148cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_rgf32, &src); 149cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_f32, &dst); 150cb93a386Sopenharmony_ci p.run(0,0, i,1); 151cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 152cb93a386Sopenharmony_ci for (unsigned k = 0; k < 2; k++) { 153cb93a386Sopenharmony_ci if (buffer[j][k] != data[j][k]) { 154cb93a386Sopenharmony_ci ERRORF(r, "(%u, %u) - a: %g r: %g\n", j, k, data[j][k], buffer[j][k]); 155cb93a386Sopenharmony_ci } 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci if (buffer[j][2] != 0) { 158cb93a386Sopenharmony_ci ERRORF(r, "(%u, 2) - a: 0 r: %g\n", j, buffer[j][2]); 159cb93a386Sopenharmony_ci } 160cb93a386Sopenharmony_ci if (buffer[j][3] != 1) { 161cb93a386Sopenharmony_ci ERRORF(r, "(%u, 3) - a: 1 r: %g\n", j, buffer[j][3]); 162cb93a386Sopenharmony_ci } 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 165cb93a386Sopenharmony_ci for (auto f : buffer[j]) { 166cb93a386Sopenharmony_ci REPORTER_ASSERT(r, SkScalarIsNaN(f)); 167cb93a386Sopenharmony_ci } 168cb93a386Sopenharmony_ci } 169cb93a386Sopenharmony_ci } 170cb93a386Sopenharmony_ci } 171cb93a386Sopenharmony_ci 172cb93a386Sopenharmony_ci { 173cb93a386Sopenharmony_ci float data[][4] = { 174cb93a386Sopenharmony_ci {00, 01, 02, 03}, 175cb93a386Sopenharmony_ci {10, 11, 12, 13}, 176cb93a386Sopenharmony_ci {20, 21, 22, 23}, 177cb93a386Sopenharmony_ci {30, 31, 32, 33}, 178cb93a386Sopenharmony_ci }; 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_ci float buffer[4][2]; 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0][0], 0 }, 183cb93a386Sopenharmony_ci dst = { &buffer[0][0], 0 }; 184cb93a386Sopenharmony_ci 185cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 186cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 187cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 188cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_f32, &src); 189cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_rgf32, &dst); 190cb93a386Sopenharmony_ci p.run(0,0, i,1); 191cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 192cb93a386Sopenharmony_ci for (unsigned k = 0; k < 2; k++) { 193cb93a386Sopenharmony_ci if (buffer[j][k] != data[j][k]) { 194cb93a386Sopenharmony_ci ERRORF(r, "(%u, %u) - a: %g r: %g\n", j, k, data[j][k], buffer[j][k]); 195cb93a386Sopenharmony_ci } 196cb93a386Sopenharmony_ci } 197cb93a386Sopenharmony_ci } 198cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 199cb93a386Sopenharmony_ci for (auto f : buffer[j]) { 200cb93a386Sopenharmony_ci REPORTER_ASSERT(r, SkScalarIsNaN(f)); 201cb93a386Sopenharmony_ci } 202cb93a386Sopenharmony_ci } 203cb93a386Sopenharmony_ci } 204cb93a386Sopenharmony_ci } 205cb93a386Sopenharmony_ci 206cb93a386Sopenharmony_ci { 207cb93a386Sopenharmony_ci alignas(8) uint16_t data[][4] = { 208cb93a386Sopenharmony_ci {h(00), h(01), h(02), h(03)}, 209cb93a386Sopenharmony_ci {h(10), h(11), h(12), h(13)}, 210cb93a386Sopenharmony_ci {h(20), h(21), h(22), h(23)}, 211cb93a386Sopenharmony_ci {h(30), h(31), h(32), h(33)}, 212cb93a386Sopenharmony_ci }; 213cb93a386Sopenharmony_ci alignas(8) uint16_t buffer[4][4]; 214cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0][0], 0 }, 215cb93a386Sopenharmony_ci dst = { &buffer[0][0], 0 }; 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 218cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 219cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 220cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_f16, &src); 221cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_f16, &dst); 222cb93a386Sopenharmony_ci p.run(0,0, i,1); 223cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 224cb93a386Sopenharmony_ci for (int k = 0; k < 4; k++) { 225cb93a386Sopenharmony_ci REPORTER_ASSERT(r, buffer[j][k] == data[j][k]); 226cb93a386Sopenharmony_ci } 227cb93a386Sopenharmony_ci } 228cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 229cb93a386Sopenharmony_ci for (auto f : buffer[j]) { 230cb93a386Sopenharmony_ci REPORTER_ASSERT(r, f == 0xffff); 231cb93a386Sopenharmony_ci } 232cb93a386Sopenharmony_ci } 233cb93a386Sopenharmony_ci } 234cb93a386Sopenharmony_ci } 235cb93a386Sopenharmony_ci 236cb93a386Sopenharmony_ci { 237cb93a386Sopenharmony_ci alignas(8) uint16_t data[]= { 238cb93a386Sopenharmony_ci h(00), 239cb93a386Sopenharmony_ci h(10), 240cb93a386Sopenharmony_ci h(20), 241cb93a386Sopenharmony_ci h(30), 242cb93a386Sopenharmony_ci }; 243cb93a386Sopenharmony_ci alignas(8) uint16_t buffer[4][4]; 244cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0], 0 }, 245cb93a386Sopenharmony_ci dst = { &buffer[0][0], 0 }; 246cb93a386Sopenharmony_ci 247cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 248cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 249cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 250cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_af16, &src); 251cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_f16, &dst); 252cb93a386Sopenharmony_ci p.run(0,0, i,1); 253cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 254cb93a386Sopenharmony_ci uint16_t expected[] = {0, 0, 0, data[j]}; 255cb93a386Sopenharmony_ci REPORTER_ASSERT(r, !memcmp(expected, &buffer[j][0], sizeof(buffer[j]))); 256cb93a386Sopenharmony_ci } 257cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 258cb93a386Sopenharmony_ci for (auto f : buffer[j]) { 259cb93a386Sopenharmony_ci REPORTER_ASSERT(r, f == 0xffff); 260cb93a386Sopenharmony_ci } 261cb93a386Sopenharmony_ci } 262cb93a386Sopenharmony_ci } 263cb93a386Sopenharmony_ci } 264cb93a386Sopenharmony_ci 265cb93a386Sopenharmony_ci { 266cb93a386Sopenharmony_ci alignas(8) uint16_t data[][4] = { 267cb93a386Sopenharmony_ci {h(00), h(01), h(02), h(03)}, 268cb93a386Sopenharmony_ci {h(10), h(11), h(12), h(13)}, 269cb93a386Sopenharmony_ci {h(20), h(21), h(22), h(23)}, 270cb93a386Sopenharmony_ci {h(30), h(31), h(32), h(33)}, 271cb93a386Sopenharmony_ci }; 272cb93a386Sopenharmony_ci alignas(8) uint16_t buffer[4]; 273cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0][0], 0 }, 274cb93a386Sopenharmony_ci dst = { &buffer[0], 0 }; 275cb93a386Sopenharmony_ci 276cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 277cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 278cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 279cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_f16, &src); 280cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_af16, &dst); 281cb93a386Sopenharmony_ci p.run(0,0, i,1); 282cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 283cb93a386Sopenharmony_ci REPORTER_ASSERT(r, !memcmp(&data[j][3], &buffer[j], sizeof(buffer[j]))); 284cb93a386Sopenharmony_ci } 285cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 286cb93a386Sopenharmony_ci REPORTER_ASSERT(r, buffer[j] == 0xffff); 287cb93a386Sopenharmony_ci } 288cb93a386Sopenharmony_ci } 289cb93a386Sopenharmony_ci } 290cb93a386Sopenharmony_ci 291cb93a386Sopenharmony_ci { 292cb93a386Sopenharmony_ci alignas(8) uint16_t data[][4] = { 293cb93a386Sopenharmony_ci {h(00), h(01), h(02), h(03)}, 294cb93a386Sopenharmony_ci {h(10), h(11), h(12), h(13)}, 295cb93a386Sopenharmony_ci {h(20), h(21), h(22), h(23)}, 296cb93a386Sopenharmony_ci {h(30), h(31), h(32), h(33)}, 297cb93a386Sopenharmony_ci }; 298cb93a386Sopenharmony_ci alignas(8) uint16_t buffer[4][2]; 299cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0][0], 0 }, 300cb93a386Sopenharmony_ci dst = { &buffer[0][0], 0 }; 301cb93a386Sopenharmony_ci 302cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 303cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 304cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 305cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_f16, &src); 306cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_rgf16, &dst); 307cb93a386Sopenharmony_ci p.run(0,0, i,1); 308cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 309cb93a386Sopenharmony_ci REPORTER_ASSERT(r, !memcmp(&buffer[j], &data[j], 2 * sizeof(uint16_t))); 310cb93a386Sopenharmony_ci } 311cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 312cb93a386Sopenharmony_ci for (auto h : buffer[j]) { 313cb93a386Sopenharmony_ci REPORTER_ASSERT(r, h == 0xffff); 314cb93a386Sopenharmony_ci } 315cb93a386Sopenharmony_ci } 316cb93a386Sopenharmony_ci } 317cb93a386Sopenharmony_ci } 318cb93a386Sopenharmony_ci 319cb93a386Sopenharmony_ci { 320cb93a386Sopenharmony_ci alignas(8) uint16_t data[][2] = { 321cb93a386Sopenharmony_ci {h(00), h(01)}, 322cb93a386Sopenharmony_ci {h(10), h(11)}, 323cb93a386Sopenharmony_ci {h(20), h(21)}, 324cb93a386Sopenharmony_ci {h(30), h(31)}, 325cb93a386Sopenharmony_ci }; 326cb93a386Sopenharmony_ci alignas(8) uint16_t buffer[4][4]; 327cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0][0], 0 }, 328cb93a386Sopenharmony_ci dst = { &buffer[0][0], 0 }; 329cb93a386Sopenharmony_ci 330cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 331cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 332cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 333cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_rgf16, &src); 334cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_f16, &dst); 335cb93a386Sopenharmony_ci p.run(0,0, i,1); 336cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 337cb93a386Sopenharmony_ci uint16_t expected[] = {data[j][0], data[j][1], h(0), h(1)}; 338cb93a386Sopenharmony_ci REPORTER_ASSERT(r, !memcmp(&buffer[j], expected, sizeof(expected))); 339cb93a386Sopenharmony_ci } 340cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 341cb93a386Sopenharmony_ci for (auto h : buffer[j]) { 342cb93a386Sopenharmony_ci REPORTER_ASSERT(r, h == 0xffff); 343cb93a386Sopenharmony_ci } 344cb93a386Sopenharmony_ci } 345cb93a386Sopenharmony_ci } 346cb93a386Sopenharmony_ci } 347cb93a386Sopenharmony_ci} 348cb93a386Sopenharmony_ci 349cb93a386Sopenharmony_ciDEF_TEST(SkRasterPipeline_u16, r) { 350cb93a386Sopenharmony_ci { 351cb93a386Sopenharmony_ci alignas(8) uint16_t data[][2] = { 352cb93a386Sopenharmony_ci {0x0000, 0x0111}, 353cb93a386Sopenharmony_ci {0x1010, 0x1111}, 354cb93a386Sopenharmony_ci {0x2020, 0x2121}, 355cb93a386Sopenharmony_ci {0x3030, 0x3131}, 356cb93a386Sopenharmony_ci }; 357cb93a386Sopenharmony_ci uint8_t buffer[4][4]; 358cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0][0], 0 }, 359cb93a386Sopenharmony_ci dst = { &buffer[0][0], 0 }; 360cb93a386Sopenharmony_ci 361cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 362cb93a386Sopenharmony_ci memset(buffer, 0xab, sizeof(buffer)); 363cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 364cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_rg1616, &src); 365cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_8888, &dst); 366cb93a386Sopenharmony_ci p.run(0,0, i,1); 367cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 368cb93a386Sopenharmony_ci uint8_t expected[] = { 369cb93a386Sopenharmony_ci SkToU8(data[j][0] >> 8), 370cb93a386Sopenharmony_ci SkToU8(data[j][1] >> 8), 371cb93a386Sopenharmony_ci 000, 372cb93a386Sopenharmony_ci 0xff 373cb93a386Sopenharmony_ci }; 374cb93a386Sopenharmony_ci REPORTER_ASSERT(r, !memcmp(&buffer[j], expected, sizeof(expected))); 375cb93a386Sopenharmony_ci } 376cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 377cb93a386Sopenharmony_ci for (auto b : buffer[j]) { 378cb93a386Sopenharmony_ci REPORTER_ASSERT(r, b == 0xab); 379cb93a386Sopenharmony_ci } 380cb93a386Sopenharmony_ci } 381cb93a386Sopenharmony_ci } 382cb93a386Sopenharmony_ci } 383cb93a386Sopenharmony_ci 384cb93a386Sopenharmony_ci { 385cb93a386Sopenharmony_ci alignas(8) uint16_t data[] = { 386cb93a386Sopenharmony_ci 0x0000, 387cb93a386Sopenharmony_ci 0x1010, 388cb93a386Sopenharmony_ci 0x2020, 389cb93a386Sopenharmony_ci 0x3030, 390cb93a386Sopenharmony_ci }; 391cb93a386Sopenharmony_ci uint8_t buffer[4][4]; 392cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0], 0 }, 393cb93a386Sopenharmony_ci dst = { &buffer[0][0], 0 }; 394cb93a386Sopenharmony_ci 395cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 396cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 397cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 398cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_a16, &src); 399cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_8888, &dst); 400cb93a386Sopenharmony_ci p.run(0,0, i,1); 401cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 402cb93a386Sopenharmony_ci uint8_t expected[] = {0x00, 0x00, 0x00, SkToU8(data[j] >> 8)}; 403cb93a386Sopenharmony_ci REPORTER_ASSERT(r, !memcmp(&buffer[j], expected, sizeof(expected))); 404cb93a386Sopenharmony_ci } 405cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 406cb93a386Sopenharmony_ci for (auto b : buffer[j]) { 407cb93a386Sopenharmony_ci REPORTER_ASSERT(r, b == 0xff); 408cb93a386Sopenharmony_ci } 409cb93a386Sopenharmony_ci } 410cb93a386Sopenharmony_ci } 411cb93a386Sopenharmony_ci } 412cb93a386Sopenharmony_ci 413cb93a386Sopenharmony_ci { 414cb93a386Sopenharmony_ci uint8_t data[][4] = { 415cb93a386Sopenharmony_ci {0x00, 0x01, 0x02, 0x03}, 416cb93a386Sopenharmony_ci {0x10, 0x11, 0x12, 0x13}, 417cb93a386Sopenharmony_ci {0x20, 0x21, 0x22, 0x23}, 418cb93a386Sopenharmony_ci {0x30, 0x31, 0x32, 0x33}, 419cb93a386Sopenharmony_ci }; 420cb93a386Sopenharmony_ci alignas(8) uint16_t buffer[4]; 421cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0][0], 0 }, 422cb93a386Sopenharmony_ci dst = { &buffer[0], 0 }; 423cb93a386Sopenharmony_ci 424cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 425cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 426cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 427cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_8888, &src); 428cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_a16, &dst); 429cb93a386Sopenharmony_ci p.run(0,0, i,1); 430cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 431cb93a386Sopenharmony_ci uint16_t expected = (data[j][3] << 8) | data[j][3]; 432cb93a386Sopenharmony_ci REPORTER_ASSERT(r, buffer[j] == expected); 433cb93a386Sopenharmony_ci } 434cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 435cb93a386Sopenharmony_ci REPORTER_ASSERT(r, buffer[j] == 0xffff); 436cb93a386Sopenharmony_ci } 437cb93a386Sopenharmony_ci } 438cb93a386Sopenharmony_ci } 439cb93a386Sopenharmony_ci 440cb93a386Sopenharmony_ci { 441cb93a386Sopenharmony_ci alignas(8) uint16_t data[][4] = { 442cb93a386Sopenharmony_ci {0x0000, 0x1000, 0x2000, 0x3000}, 443cb93a386Sopenharmony_ci {0x0001, 0x1001, 0x2001, 0x3001}, 444cb93a386Sopenharmony_ci {0x0002, 0x1002, 0x2002, 0x3002}, 445cb93a386Sopenharmony_ci {0x0003, 0x1003, 0x2003, 0x3003}, 446cb93a386Sopenharmony_ci }; 447cb93a386Sopenharmony_ci alignas(8) uint16_t buffer[4][4]; 448cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { &data[0][0], 0 }, 449cb93a386Sopenharmony_ci dst = { &buffer[0], 0 }; 450cb93a386Sopenharmony_ci 451cb93a386Sopenharmony_ci for (unsigned i = 1; i <= 4; i++) { 452cb93a386Sopenharmony_ci memset(buffer, 0xff, sizeof(buffer)); 453cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 454cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_16161616, &src); 455cb93a386Sopenharmony_ci p.append(SkRasterPipeline::swap_rb); 456cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_16161616, &dst); 457cb93a386Sopenharmony_ci p.run(0,0, i,1); 458cb93a386Sopenharmony_ci for (unsigned j = 0; j < i; j++) { 459cb93a386Sopenharmony_ci uint16_t expected[4] = {data[j][2], data[j][1], data[j][0], data[j][3]}; 460cb93a386Sopenharmony_ci REPORTER_ASSERT(r, !memcmp(&expected[0], &buffer[j], sizeof(expected))); 461cb93a386Sopenharmony_ci } 462cb93a386Sopenharmony_ci for (int j = i; j < 4; j++) { 463cb93a386Sopenharmony_ci for (uint16_t u16 : buffer[j]) 464cb93a386Sopenharmony_ci REPORTER_ASSERT(r, u16 == 0xffff); 465cb93a386Sopenharmony_ci } 466cb93a386Sopenharmony_ci } 467cb93a386Sopenharmony_ci } 468cb93a386Sopenharmony_ci} 469cb93a386Sopenharmony_ci 470cb93a386Sopenharmony_ciDEF_TEST(SkRasterPipeline_lowp, r) { 471cb93a386Sopenharmony_ci uint32_t rgba[64]; 472cb93a386Sopenharmony_ci for (int i = 0; i < 64; i++) { 473cb93a386Sopenharmony_ci rgba[i] = (4*i+0) << 0 474cb93a386Sopenharmony_ci | (4*i+1) << 8 475cb93a386Sopenharmony_ci | (4*i+2) << 16 476cb93a386Sopenharmony_ci | (4*i+3) << 24; 477cb93a386Sopenharmony_ci } 478cb93a386Sopenharmony_ci 479cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx ptr = { rgba, 0 }; 480cb93a386Sopenharmony_ci 481cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 482cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_8888, &ptr); 483cb93a386Sopenharmony_ci p.append(SkRasterPipeline::swap_rb); 484cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_8888, &ptr); 485cb93a386Sopenharmony_ci p.run(0,0,64,1); 486cb93a386Sopenharmony_ci 487cb93a386Sopenharmony_ci for (int i = 0; i < 64; i++) { 488cb93a386Sopenharmony_ci uint32_t want = (4*i+0) << 16 489cb93a386Sopenharmony_ci | (4*i+1) << 8 490cb93a386Sopenharmony_ci | (4*i+2) << 0 491cb93a386Sopenharmony_ci | (4*i+3) << 24; 492cb93a386Sopenharmony_ci if (rgba[i] != want) { 493cb93a386Sopenharmony_ci ERRORF(r, "got %08x, want %08x\n", rgba[i], want); 494cb93a386Sopenharmony_ci } 495cb93a386Sopenharmony_ci } 496cb93a386Sopenharmony_ci} 497cb93a386Sopenharmony_ci 498cb93a386Sopenharmony_ciDEF_TEST(SkRasterPipeline_swizzle, r) { 499cb93a386Sopenharmony_ci // This takes the lowp code path 500cb93a386Sopenharmony_ci { 501cb93a386Sopenharmony_ci uint16_t rg[64]; 502cb93a386Sopenharmony_ci for (int i = 0; i < 64; i++) { 503cb93a386Sopenharmony_ci rg[i] = (4*i+0) << 0 504cb93a386Sopenharmony_ci | (4*i+1) << 8; 505cb93a386Sopenharmony_ci } 506cb93a386Sopenharmony_ci 507cb93a386Sopenharmony_ci GrSwizzle swizzle("g1b1"); 508cb93a386Sopenharmony_ci 509cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx ptr = { rg, 0 }; 510cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 511cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_rg88, &ptr); 512cb93a386Sopenharmony_ci swizzle.apply(&p); 513cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_rg88, &ptr); 514cb93a386Sopenharmony_ci p.run(0,0,64,1); 515cb93a386Sopenharmony_ci 516cb93a386Sopenharmony_ci for (int i = 0; i < 64; i++) { 517cb93a386Sopenharmony_ci uint32_t want = 0xff << 8 518cb93a386Sopenharmony_ci | (4*i+1) << 0; 519cb93a386Sopenharmony_ci if (rg[i] != want) { 520cb93a386Sopenharmony_ci ERRORF(r, "got %08x, want %08x\n", rg[i], want); 521cb93a386Sopenharmony_ci } 522cb93a386Sopenharmony_ci } 523cb93a386Sopenharmony_ci } 524cb93a386Sopenharmony_ci // This takes the highp code path 525cb93a386Sopenharmony_ci { 526cb93a386Sopenharmony_ci float rg[64][2]; 527cb93a386Sopenharmony_ci for (int i = 0; i < 64; i++) { 528cb93a386Sopenharmony_ci rg[i][0] = i + 1; 529cb93a386Sopenharmony_ci rg[i][1] = 2 * i + 1; 530cb93a386Sopenharmony_ci } 531cb93a386Sopenharmony_ci 532cb93a386Sopenharmony_ci GrSwizzle swizzle("0gra"); 533cb93a386Sopenharmony_ci 534cb93a386Sopenharmony_ci uint16_t buffer[64][4]; 535cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx src = { rg, 0 }, 536cb93a386Sopenharmony_ci dst = { buffer, 0}; 537cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 538cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_rgf32, &src); 539cb93a386Sopenharmony_ci swizzle.apply(&p); 540cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_f16, &dst); 541cb93a386Sopenharmony_ci p.run(0,0,64,1); 542cb93a386Sopenharmony_ci 543cb93a386Sopenharmony_ci for (int i = 0; i < 64; i++) { 544cb93a386Sopenharmony_ci uint16_t want[4] { 545cb93a386Sopenharmony_ci h(0), 546cb93a386Sopenharmony_ci h(2 * i + 1), 547cb93a386Sopenharmony_ci h(i + 1), 548cb93a386Sopenharmony_ci h(1), 549cb93a386Sopenharmony_ci }; 550cb93a386Sopenharmony_ci REPORTER_ASSERT(r, !memcmp(want, buffer[i], sizeof(buffer[i]))); 551cb93a386Sopenharmony_ci } 552cb93a386Sopenharmony_ci } 553cb93a386Sopenharmony_ci} 554cb93a386Sopenharmony_ci 555cb93a386Sopenharmony_ciDEF_TEST(SkRasterPipeline_lowp_clamp01, r) { 556cb93a386Sopenharmony_ci // This may seem like a funny pipeline to create, 557cb93a386Sopenharmony_ci // but it certainly shouldn't crash when you run it. 558cb93a386Sopenharmony_ci 559cb93a386Sopenharmony_ci uint32_t rgba = 0xff00ff00; 560cb93a386Sopenharmony_ci 561cb93a386Sopenharmony_ci SkRasterPipeline_MemoryCtx ptr = { &rgba, 0 }; 562cb93a386Sopenharmony_ci 563cb93a386Sopenharmony_ci SkRasterPipeline_<256> p; 564cb93a386Sopenharmony_ci p.append(SkRasterPipeline::load_8888, &ptr); 565cb93a386Sopenharmony_ci p.append(SkRasterPipeline::swap_rb); 566cb93a386Sopenharmony_ci p.append(SkRasterPipeline::clamp_0); 567cb93a386Sopenharmony_ci p.append(SkRasterPipeline::clamp_1); 568cb93a386Sopenharmony_ci p.append(SkRasterPipeline::store_8888, &ptr); 569cb93a386Sopenharmony_ci p.run(0,0,1,1); 570cb93a386Sopenharmony_ci} 571