1 /* 2 * Copyright (C) 2015-2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "shared.rsh" 18 19 int gDimX; 20 int gDimY; 21 int gDimZ; 22 int gStart; 23 static bool failed = false; 24 25 // For each type, define 4 kernels, one per vector variant, that walk an 26 // allocation and validate each cell. The value in a cell must be gStart + 27 // "index-of-the-cell-starting-from-zero". For vector types, the 'x' field 28 // must have this value. The expected values for 'y', 'z' and 'w' follow the 29 // 'x' value in increments of one. 30 // 31 // 'z' will be zero for 2D and 1D allocations. 'y' will be zero for 1D 32 // allocations. 33 34 #define VERIFY_KERNEL(CT) \ 35 void RS_KERNEL verify_##CT(CT in, int x, int y, int z) { \ 36 int val = (gStart + x + y * gDimX + z * gDimY * gDimX); \ 37 _RS_ASSERT_EQU(in, (CT) val); \ 38 } \ 39 void RS_KERNEL verify_##CT##2(CT##2 in, int x, int y, int z) { \ 40 int val = (gStart + x + y * gDimX + z * gDimY * gDimX); \ 41 _RS_ASSERT_EQU(in.x, (CT) val); \ 42 _RS_ASSERT_EQU(in.y, (CT) (val + 1)); \ 43 } \ 44 void RS_KERNEL verify_##CT##3(CT##3 in, int x, int y, int z) { \ 45 int val = (gStart + x + y * gDimX + z * gDimY * gDimX); \ 46 _RS_ASSERT_EQU(in.x, (CT) val); \ 47 _RS_ASSERT_EQU(in.y, (CT) (val + 1)); \ 48 _RS_ASSERT_EQU(in.z, (CT) (val + 2)); \ 49 } \ 50 void RS_KERNEL verify_##CT##4(CT##4 in, int x, int y, int z) { \ 51 int val = (gStart + x + y * gDimX + z * gDimY * gDimX); \ 52 _RS_ASSERT_EQU(in.x, (CT) val); \ 53 _RS_ASSERT_EQU(in.y, (CT) (val + 1)); \ 54 _RS_ASSERT_EQU(in.z, (CT) (val + 2)); \ 55 _RS_ASSERT_EQU(in.w, (CT) (val + 3)); \ 56 } \ 57 58 VERIFY_KERNEL(half) 59 VERIFY_KERNEL(float) 60 VERIFY_KERNEL(double) 61 VERIFY_KERNEL(char) 62 VERIFY_KERNEL(short) 63 VERIFY_KERNEL(int) 64 VERIFY_KERNEL(long) 65 VERIFY_KERNEL(uchar) 66 VERIFY_KERNEL(ushort) 67 VERIFY_KERNEL(uint) 68 VERIFY_KERNEL(ulong) 69 70 // Store to an allocation based on the vector size and dimensionality being 71 // tested. SETELEMENTAT, STORE_TO_ALLOC capture the following variables from 72 // the context where they get instantiated: 73 // vecSize, gAlloc, val, x, y, z 74 75 #define SETELEMENTAT(CT) \ 76 if (gDimZ != 0) { \ 77 rsSetElementAt_##CT(gAlloc, storeVal, x, y, z); \ 78 } \ 79 else if (gDimY != 0) { \ 80 rsSetElementAt_##CT(gAlloc, storeVal, x, y); \ 81 } \ 82 else { \ 83 rsSetElementAt_##CT(gAlloc, storeVal, x); \ 84 } 85 86 #define STORE_TO_ALLOC(RST, CT) \ 87 case RST: \ 88 switch (vecSize) { \ 89 case 1: { \ 90 CT storeVal = (CT) val; \ 91 SETELEMENTAT(CT); \ 92 } \ 93 break; \ 94 case 2: { \ 95 CT##2 storeVal = {(CT) val, (CT) (val + 1)}; \ 96 SETELEMENTAT(CT##2); \ 97 } \ 98 break; \ 99 case 3: { \ 100 CT##3 storeVal = {(CT) val, (CT) (val + 1), (CT) (val + 2)}; \ 101 SETELEMENTAT(CT##3); \ 102 } \ 103 break; \ 104 case 4: { \ 105 CT##4 storeVal = {(CT) val, (CT) (val + 1), (CT) (val + 2), \ 106 (CT) (val + 3)}; \ 107 SETELEMENTAT(CT##4); \ 108 } \ 109 break; \ 110 } \ 111 break; \ 112 113 114 // Launch the verify_kernel based on the appropriate type and vector size. 115 #define LAUNCH_VERIFY_KERNEL(RST, CT) \ 116 case RST: \ 117 if (vecSize == 1) rsForEach(verify_##CT, gAlloc); \ 118 else if (vecSize == 2) rsForEach(verify_##CT##2, gAlloc); \ 119 else if (vecSize == 3) rsForEach(verify_##CT##3, gAlloc); \ 120 else if (vecSize == 4) rsForEach(verify_##CT##4, gAlloc); \ 121 break; 122 123 void checkAndSendResult() { 124 if (failed) { 125 rsDebug("Single Source Alloc Test Failed", 0); 126 rsSendToClientBlocking(RS_MSG_TEST_FAILED); 127 } 128 else { 129 rsDebug("Single Source Alloc Test Passed", 0); 130 rsSendToClientBlocking(RS_MSG_TEST_PASSED); 131 } 132 } 133 134 static void CreateAndTestAlloc(rs_data_type dt, int vecSize, int dimX, int dimY, int dimZ) { 135 failed = false; 136 137 if (dimZ != 0 && dimY == 0) { 138 _RS_ASSERT(false); // Invalid test 139 return; 140 } 141 142 if (dimX == 0) { 143 _RS_ASSERT(false); // Invalid test 144 return; 145 } 146 147 rs_element element; 148 rs_type type; 149 rs_allocation gAlloc; 150 151 // Create and validate the rs_element object 152 if (vecSize == 1) 153 element = rsCreateElement((rs_data_type) dt); 154 else 155 element = rsCreateVectorElement((rs_data_type) dt, vecSize); 156 _RS_ASSERT(rsIsObject(element)); 157 if (!rsIsObject(element)) { 158 return; 159 } 160 161 // Create and validate the rs_type object 162 type = rsCreateType(element, dimX, dimY, dimZ); 163 _RS_ASSERT(rsIsObject(type)); 164 if (!rsIsObject(type)) { 165 return; 166 } 167 168 // Create and validate the rs_allocation object 169 gAlloc = rsCreateAllocation(type); 170 if (!rsIsObject(gAlloc)) { 171 return; 172 } 173 174 // Handle RenderScript's distinction between Y or Z dimension being absent 175 // and having a size of 1 176 int zEnd = (dimZ != 0) ? dimZ: 1; 177 int yEnd = (dimY != 0) ? dimY: 1; 178 for (int z = 0; z < zEnd; z ++) { 179 for (int y = 0; y < yEnd; y ++) { 180 for (int x = 0; x < dimX; x ++) { 181 int val = gStart + (x + y * dimX + z * dimY * dimX); 182 183 // Store to a cell based on the type, vector size and 184 // dimensionality 185 switch (dt) { 186 STORE_TO_ALLOC(RS_TYPE_FLOAT_16, half); 187 STORE_TO_ALLOC(RS_TYPE_FLOAT_32, float); 188 STORE_TO_ALLOC(RS_TYPE_FLOAT_64, double); 189 STORE_TO_ALLOC(RS_TYPE_SIGNED_8, char); 190 STORE_TO_ALLOC(RS_TYPE_SIGNED_16, short); 191 STORE_TO_ALLOC(RS_TYPE_SIGNED_32, int); 192 STORE_TO_ALLOC(RS_TYPE_SIGNED_64, long); 193 STORE_TO_ALLOC(RS_TYPE_UNSIGNED_8, uchar); 194 STORE_TO_ALLOC(RS_TYPE_UNSIGNED_16, ushort); 195 STORE_TO_ALLOC(RS_TYPE_UNSIGNED_32, uint); 196 STORE_TO_ALLOC(RS_TYPE_UNSIGNED_64, ulong); 197 default: 198 // Invalid test 199 _RS_ASSERT(false); 200 break; 201 } 202 } 203 } 204 } 205 206 // Launch the appropriate verify_ kernel 207 switch (dt) { 208 LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_16, half); 209 LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_32, float); 210 LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_64, double); 211 LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_8, char); 212 LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_16, short); 213 LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_32, int); 214 LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_64, long); 215 LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_8, uchar); 216 LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_16, ushort); 217 LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_32, uint); 218 LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_64, ulong); 219 220 default: 221 // Invalid test 222 _RS_ASSERT(false); 223 break; 224 } 225 } 226 227 void TestAllocationCreationAndAccess() { 228 rs_data_type all_types[] = { 229 RS_TYPE_BOOLEAN, 230 RS_TYPE_FLOAT_16, 231 RS_TYPE_FLOAT_32, 232 RS_TYPE_FLOAT_64, 233 RS_TYPE_SIGNED_8, 234 RS_TYPE_SIGNED_16, 235 RS_TYPE_SIGNED_32, 236 RS_TYPE_SIGNED_64, 237 RS_TYPE_UNSIGNED_8, 238 RS_TYPE_UNSIGNED_16, 239 RS_TYPE_UNSIGNED_32, 240 RS_TYPE_UNSIGNED_64, 241 }; 242 243 for (int i = 0; i < sizeof(all_types) / sizeof(all_types[0]); i++) { 244 for (int vecSize = 1; vecSize <= 4; vecSize ++) { 245 for (int nDims = 1; nDims <= 3; nDims ++) { 246 int dimY = nDims > 1 ? gDimY : 0; 247 int dimZ = nDims > 2 ? gDimZ : 0; 248 CreateAndTestAlloc(all_types[i], vecSize, gDimX, dimY, dimZ); 249 } 250 } 251 } 252 253 checkAndSendResult(); 254 } 255 256 #define TEST_DATA_TYPE(dt, allowSimple, allowVector, allowPixel) { \ 257 if (allowSimple) \ 258 _RS_ASSERT(rsIsObject(rsCreateElement(dt))); \ 259 else \ 260 _RS_ASSERT(!rsIsObject(rsCreateElement(dt))); \ 261 if (allowVector) \ 262 _RS_ASSERT(rsIsObject(rsCreateVectorElement(dt, 3))); \ 263 else \ 264 _RS_ASSERT(!rsIsObject(rsCreateVectorElement(dt, 3))); \ 265 if (allowPixel) \ 266 _RS_ASSERT(rsIsObject(rsCreatePixelElement(dt, RS_KIND_PIXEL_DEPTH))); \ 267 else \ 268 _RS_ASSERT(!rsIsObject(rsCreatePixelElement(dt, RS_KIND_PIXEL_DEPTH)));\ 269 } 270 271 #define TEST_SUPPORTED_PIXEL(dt, dk) { \ 272 _RS_ASSERT(rsIsObject(rsCreatePixelElement(dt, dk))); \ 273 } 274 275 #define TEST_UNSUPPORTED_PIXEL(dt, dk) { \ 276 _RS_ASSERT(!rsIsObject(rsCreatePixelElement(dt, dk))); \ 277 } 278 279 #define TEST_HELPER(suffix) { \ 280 _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3))); \ 281 _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3, 4))); \ 282 _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3, 4, 5))); \ 283 } 284 285 #define TEST_HELPERS(CT) { \ 286 TEST_HELPER(CT); \ 287 TEST_HELPER(CT##2); \ 288 TEST_HELPER(CT##3); \ 289 TEST_HELPER(CT##4); \ 290 } 291 292 void TestElementCreation() { 293 failed = false; 294 295 // vector_width must be at least 2 296 rs_element oneElt = rsCreateVectorElement(RS_TYPE_SIGNED_32, 1); 297 _RS_ASSERT(!rsIsObject(oneElt)); 298 299 // vector_width must be at most 4 300 rs_element fiveElt = rsCreateVectorElement(RS_TYPE_SIGNED_32, 5); 301 _RS_ASSERT(!rsIsObject(fiveElt)); 302 303 ///////////////////////////////////////////////////////////////// 304 // Element validation 305 ///////////////////////////////////////////////////////////////// 306 // These types are valid for scalar and vectors, but don't support pixel 307 TEST_DATA_TYPE(RS_TYPE_BOOLEAN, true, true, false); 308 TEST_DATA_TYPE(RS_TYPE_FLOAT_32, true, true, false); 309 TEST_DATA_TYPE(RS_TYPE_FLOAT_64, true, true, false); 310 TEST_DATA_TYPE(RS_TYPE_SIGNED_8, true, true, false); 311 TEST_DATA_TYPE(RS_TYPE_SIGNED_16, true, true, false); 312 TEST_DATA_TYPE(RS_TYPE_SIGNED_32, true, true, false); 313 TEST_DATA_TYPE(RS_TYPE_SIGNED_64, true, true, false); 314 TEST_DATA_TYPE(RS_TYPE_UNSIGNED_32, true, true, false); 315 TEST_DATA_TYPE(RS_TYPE_UNSIGNED_64, true, true, false); 316 317 // These types are valid only for scalars 318 TEST_DATA_TYPE(RS_TYPE_MATRIX_4X4, true, false, false); 319 TEST_DATA_TYPE(RS_TYPE_MATRIX_3X3, true, false, false); 320 TEST_DATA_TYPE(RS_TYPE_MATRIX_2X2, true, false, false); 321 TEST_DATA_TYPE(RS_TYPE_ELEMENT, true, false, false); 322 TEST_DATA_TYPE(RS_TYPE_TYPE, true, false, false); 323 TEST_DATA_TYPE(RS_TYPE_ALLOCATION, true, false, false); 324 TEST_DATA_TYPE(RS_TYPE_SCRIPT, true, false, false); 325 326 // U8, U16 are valid for scalar, vector and pixel 327 TEST_DATA_TYPE(RS_TYPE_UNSIGNED_8, true, true, true); 328 TEST_DATA_TYPE(RS_TYPE_UNSIGNED_16, true, true, true); 329 330 // These data types are only for pixels and a particular data_kind 331 TEST_SUPPORTED_PIXEL (RS_TYPE_UNSIGNED_5_6_5, RS_KIND_PIXEL_RGB); 332 TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_5_6_5, RS_KIND_PIXEL_L); 333 TEST_SUPPORTED_PIXEL (RS_TYPE_UNSIGNED_5_5_5_1, RS_KIND_PIXEL_RGBA); 334 TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_5_5_5_1, RS_KIND_PIXEL_L); 335 TEST_SUPPORTED_PIXEL (RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_RGBA); 336 TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_L); 337 TEST_SUPPORTED_PIXEL (RS_TYPE_UNSIGNED_16, RS_KIND_PIXEL_DEPTH); 338 TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_L); 339 340 // These data types are not supported from single-source 341 TEST_DATA_TYPE(RS_TYPE_NONE, false, false, false); 342 TEST_DATA_TYPE(RS_TYPE_SAMPLER, false, false, false); 343 TEST_DATA_TYPE(RS_TYPE_MESH, false, false, false); 344 TEST_DATA_TYPE(RS_TYPE_PROGRAM_FRAGMENT, false, false, false); 345 TEST_DATA_TYPE(RS_TYPE_PROGRAM_VERTEX, false, false, false); 346 TEST_DATA_TYPE(RS_TYPE_PROGRAM_RASTER, false, false, false); 347 TEST_DATA_TYPE(RS_TYPE_PROGRAM_STORE, false, false, false); 348 TEST_DATA_TYPE(RS_TYPE_FONT, false, false, false); 349 TEST_DATA_TYPE(RS_TYPE_INVALID, false, false, false); 350 351 checkAndSendResult(); 352 } 353 354 void TestTypeCreation() { 355 failed = false; 356 357 ///////////////////////////////////////////////////////////////// 358 // Test rs_type creation 359 ///////////////////////////////////////////////////////////////// 360 rs_element I32_3 = rsCreateVectorElement(RS_TYPE_SIGNED_32, 3); 361 362 // Create 1D, 2D, 3D types 363 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3))); 364 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4))); 365 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 5))); 366 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 0))); // x = 0 is allowed 367 368 // Invalid dimensionality 369 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 0, 4))); // x is 0 but y isn't 370 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 0, 4, 5))); // x is 0 but z isn't 371 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 5))); // y is 0 but z isn't 372 373 // shape attributes 374 // Valid yuv_format 375 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false, 376 RS_YUV_NONE))); 377 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false, 378 RS_YUV_YV12))); 379 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false, 380 RS_YUV_NV21))); 381 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false, 382 RS_YUV_420_888))); 383 384 // Invalid yuv_format 385 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, false, 1024))); 386 // yuv_format with 1D or 3D is invalid 387 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, false, false, 388 RS_YUV_YV12))); 389 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, false, 390 RS_YUV_YV12))); 391 392 // yuv_format with mipmaps or cubemap is invalid 393 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, true, 394 RS_YUV_YV12))); 395 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 0, true, false, 396 RS_YUV_YV12))); 397 398 // mipmaps with 1D or 3D is invalid 399 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, true, false, 400 RS_YUV_NONE))); 401 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, true, false, 402 RS_YUV_NONE))); 403 404 // cubemap with 1D or 3D is invalid 405 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, false, true, 406 RS_YUV_NONE))); 407 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, true, 408 RS_YUV_NONE))); 409 410 checkAndSendResult(); 411 } 412 413 void TestAllocationCreationWithUsage() { 414 failed = false; 415 416 ///////////////////////////////////////////////////////////////// 417 // Test rs_allocation creation 418 ///////////////////////////////////////////////////////////////// 419 rs_element I32_3 = rsCreateVectorElement(RS_TYPE_SIGNED_32, 3); 420 rs_type I32_3_2D = rsCreateType(I32_3, 3, 4); 421 422 // Valid uses 423 _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D))); 424 _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,\ 425 (uint32_t) RS_ALLOCATION_USAGE_SCRIPT))); 426 _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,\ 427 (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE))); 428 _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D, 429 (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE | 430 RS_ALLOCATION_USAGE_SCRIPT))); 431 432 // Invalid uses 433 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 434 (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_VERTEX))); 435 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 436 (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS))); 437 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 438 (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET))); 439 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 440 (uint32_t) RS_ALLOCATION_USAGE_IO_INPUT))); 441 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 442 (uint32_t) RS_ALLOCATION_USAGE_IO_OUTPUT))); 443 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 444 (uint32_t) RS_ALLOCATION_USAGE_SHARED))); 445 446 checkAndSendResult(); 447 } 448 449 void TestHelperFunctions() { 450 failed = false; 451 452 TEST_HELPER(half); 453 TEST_HELPERS(float); 454 TEST_HELPERS(double); 455 TEST_HELPERS(char); 456 TEST_HELPERS(short); 457 TEST_HELPERS(int); 458 TEST_HELPERS(long); 459 TEST_HELPERS(uchar); 460 TEST_HELPERS(ushort); 461 TEST_HELPERS(uint); 462 TEST_HELPERS(ulong); 463 464 checkAndSendResult(); 465 } 466