1 /* 2 * Copyright (C) 2017 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 26 // For each type, define 4 kernels, one per vector variant, that walk an 27 // allocation and validate each cell. The value in a cell must be gStart + 28 // "index-of-the-cell-starting-from-zero". For vector types, the 'x' field 29 // must have this value. The expected values for 'y', 'z' and 'w' follow the 30 // 'x' value in increments of one. 31 // 32 // 'z' will be zero for 2D and 1D allocations. 'y' will be zero for 1D 33 // allocations. 34 35 // TODO When the requirement that kernels must return an output to be launched 36 // using rsForEach is relaxed, make the kernel not return its input. 37 #define VERIFY_KERNEL(CT) \ 38 CT RS_KERNEL verify_##CT(CT in, int x, int y, int z) { \ 39 int val = (gStart + x + y * gDimX + z * gDimY * gDimX); \ 40 _RS_ASSERT_EQU(in, (CT) val); \ 41 return in; \ 42 } \ 43 CT##2 RS_KERNEL verify_##CT##2(CT##2 in, int x, int y, int z) { \ 44 int val = (gStart + x + y * gDimX + z * gDimY * gDimX); \ 45 _RS_ASSERT_EQU(in.x, (CT) val); \ 46 _RS_ASSERT_EQU(in.y, (CT) (val + 1)); \ 47 return in; \ 48 } \ 49 CT##3 RS_KERNEL verify_##CT##3(CT##3 in, int x, int y, int z) { \ 50 int val = (gStart + x + y * gDimX + z * gDimY * gDimX); \ 51 _RS_ASSERT_EQU(in.x, (CT) val); \ 52 _RS_ASSERT_EQU(in.y, (CT) (val + 1)); \ 53 _RS_ASSERT_EQU(in.z, (CT) (val + 2)); \ 54 return in; \ 55 } \ 56 CT##4 RS_KERNEL verify_##CT##4(CT##4 in, int x, int y, int z) { \ 57 int val = (gStart + x + y * gDimX + z * gDimY * gDimX); \ 58 _RS_ASSERT_EQU(in.x, (CT) val); \ 59 _RS_ASSERT_EQU(in.y, (CT) (val + 1)); \ 60 _RS_ASSERT_EQU(in.z, (CT) (val + 2)); \ 61 _RS_ASSERT_EQU(in.w, (CT) (val + 3)); \ 62 return in; \ 63 } \ 64 65 #ifndef RSTEST_COMPAT 66 VERIFY_KERNEL(half) 67 #endif 68 VERIFY_KERNEL(float) 69 VERIFY_KERNEL(double) 70 VERIFY_KERNEL(char) 71 VERIFY_KERNEL(short) 72 VERIFY_KERNEL(int) 73 VERIFY_KERNEL(long) 74 VERIFY_KERNEL(uchar) 75 VERIFY_KERNEL(ushort) 76 VERIFY_KERNEL(uint) 77 VERIFY_KERNEL(ulong) 78 79 80 // Store to an allocation based on the vector size and dimensionality being 81 // tested. SETLEMENTAT, STORE_TO_ALLOC capture the following variables from 82 // the context where they get instantiated: 83 // vecSize, gAlloc, val, x, y, z 84 85 #define SETELEMENTAT(CT) \ 86 if (gDimZ != 0) { \ 87 rsSetElementAt_##CT(gAlloc, storeVal, x, y, z); \ 88 } \ 89 else if (gDimY != 0) { \ 90 rsSetElementAt_##CT(gAlloc, storeVal, x, y); \ 91 } \ 92 else { \ 93 rsSetElementAt_##CT(gAlloc, storeVal, x); \ 94 } 95 96 #define STORE_TO_ALLOC(RST, CT) \ 97 case RST: \ 98 switch (vecSize) { \ 99 case 1: { \ 100 CT storeVal = (CT) val; \ 101 SETELEMENTAT(CT); \ 102 } \ 103 break; \ 104 case 2: { \ 105 CT##2 storeVal = {(CT) val, (CT) (val + 1)}; \ 106 SETELEMENTAT(CT##2); \ 107 } \ 108 break; \ 109 case 3: { \ 110 CT##3 storeVal = {(CT) val, (CT) (val + 1), (CT) (val + 2)}; \ 111 SETELEMENTAT(CT##3); \ 112 } \ 113 break; \ 114 case 4: { \ 115 CT##4 storeVal = {(CT) val, (CT) (val + 1), (CT) (val + 2), \ 116 (CT) (val + 3)}; \ 117 SETELEMENTAT(CT##4); \ 118 } \ 119 break; \ 120 } \ 121 break; \ 122 123 124 // Launch the verify_kernel based on the appropriate type and vector size. 125 #define LAUNCH_VERIFY_KERNEL(RST, CT) \ 126 case RST: \ 127 if (vecSize == 1) rsForEach(verify_##CT, gAlloc, gAlloc); \ 128 else if (vecSize == 2) rsForEach(verify_##CT##2, gAlloc, gAlloc); \ 129 else if (vecSize == 3) rsForEach(verify_##CT##3, gAlloc, gAlloc); \ 130 else if (vecSize == 4) rsForEach(verify_##CT##4, gAlloc, gAlloc); \ 131 break; 132 133 void CreateAndTestAlloc(int dataType, int vecSize) { 134 if (gDimZ != 0 && gDimY == 0) { 135 _RS_ASSERT(false); // Invalid test 136 return; 137 } 138 if (gDimX == 0) { 139 _RS_ASSERT(false); // Invalid test 140 return; 141 } 142 143 rs_data_type dt = (rs_data_type) dataType; 144 145 rs_element element; 146 rs_type type; 147 rs_allocation gAlloc; 148 149 // Create and validate the rs_element object 150 if (vecSize == 1) 151 element = rsCreateElement((rs_data_type) dt); 152 else 153 element = rsCreateVectorElement((rs_data_type) dt, vecSize); 154 _RS_ASSERT(rsIsObject(element)); 155 if (!rsIsObject(element)) 156 return; 157 158 // Create and validate the rs_type object 159 type = rsCreateType(element, gDimX, gDimY, gDimZ); 160 _RS_ASSERT(rsIsObject(type)); 161 if (!rsIsObject(type)) 162 return; 163 164 // Create and validate the rs_allocation object 165 gAlloc = rsCreateAllocation(type); 166 if (!rsIsObject(gAlloc)) 167 return; 168 169 // Handle RenderScript's distinction between Y or Z dimension being absent 170 // and having a size of 1 171 int zEnd = (gDimZ != 0) ? gDimZ: 1; 172 int yEnd = (gDimY != 0) ? gDimY: 1; 173 for (int z = 0; z < zEnd; z ++) { 174 for (int y = 0; y < yEnd; y ++) { 175 for (int x = 0; x < gDimX; x ++) { 176 int val = gStart + (x + y * gDimX + z * gDimY * gDimX); 177 178 // Store to a cell based on the type, vector size and 179 // dimensionality 180 switch (dt) { 181 #ifndef RSTEST_COMPAT 182 STORE_TO_ALLOC(RS_TYPE_FLOAT_16, half); 183 #else 184 // support lib doesn't support f16, skip 185 case RS_TYPE_FLOAT_16: break; 186 #endif 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 #ifndef RSTEST_COMPAT 209 LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_16, half); 210 #else 211 // support lib doesn't support f16, skip 212 case RS_TYPE_FLOAT_16: break; 213 #endif 214 LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_32, float); 215 LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_64, double); 216 LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_8, char); 217 LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_16, short); 218 LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_32, int); 219 LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_64, long); 220 LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_8, uchar); 221 LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_16, ushort); 222 LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_32, uint); 223 LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_64, ulong); 224 225 default: 226 // Invalid test 227 _RS_ASSERT(false); 228 break; 229 } 230 } 231 232 #define TEST_DATA_TYPE(dt, allowSimple, allowVector, allowPixel) { \ 233 if (allowSimple) \ 234 _RS_ASSERT(rsIsObject(rsCreateElement(dt))); \ 235 else \ 236 _RS_ASSERT(!rsIsObject(rsCreateElement(dt))); \ 237 if (allowVector) \ 238 _RS_ASSERT(rsIsObject(rsCreateVectorElement(dt, 3))); \ 239 else \ 240 _RS_ASSERT(!rsIsObject(rsCreateVectorElement(dt, 3))); \ 241 if (allowPixel) \ 242 _RS_ASSERT(rsIsObject(rsCreatePixelElement(dt, RS_KIND_PIXEL_DEPTH))); \ 243 else \ 244 _RS_ASSERT(!rsIsObject(rsCreatePixelElement(dt, RS_KIND_PIXEL_DEPTH)));\ 245 } 246 247 #define TEST_SUPPORTED_PIXEL(dt, dk) { \ 248 _RS_ASSERT(rsIsObject(rsCreatePixelElement(dt, dk))); \ 249 } 250 251 #define TEST_UNSUPPORTED_PIXEL(dt, dk) { \ 252 _RS_ASSERT(!rsIsObject(rsCreatePixelElement(dt, dk))); \ 253 } 254 255 #define TEST_HELPER(suffix) { \ 256 _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3))); \ 257 _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3, 4))); \ 258 _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3, 4, 5))); \ 259 } 260 261 #define TEST_HELPERS(CT) { \ 262 TEST_HELPER(CT); \ 263 TEST_HELPER(CT##2); \ 264 TEST_HELPER(CT##3); \ 265 TEST_HELPER(CT##4); \ 266 } 267 268 void TestAllCases() { 269 // vector_width must be at least 2 270 rs_element oneElt = rsCreateVectorElement(RS_TYPE_SIGNED_32, 1); 271 _RS_ASSERT(!rsIsObject(oneElt)); 272 273 // vector_width must be at most 4 274 rs_element fiveElt = rsCreateVectorElement(RS_TYPE_SIGNED_32, 5); 275 _RS_ASSERT(!rsIsObject(fiveElt)); 276 277 ///////////////////////////////////////////////////////////////// 278 // Element validation 279 ///////////////////////////////////////////////////////////////// 280 // These types are valid for scalar and vectors, but don't support pixel 281 TEST_DATA_TYPE(RS_TYPE_BOOLEAN, true, true, false); 282 TEST_DATA_TYPE(RS_TYPE_FLOAT_32, true, true, false); 283 TEST_DATA_TYPE(RS_TYPE_FLOAT_64, true, true, false); 284 TEST_DATA_TYPE(RS_TYPE_SIGNED_8, true, true, false); 285 TEST_DATA_TYPE(RS_TYPE_SIGNED_16, true, true, false); 286 TEST_DATA_TYPE(RS_TYPE_SIGNED_32, true, true, false); 287 TEST_DATA_TYPE(RS_TYPE_SIGNED_64, true, true, false); 288 TEST_DATA_TYPE(RS_TYPE_UNSIGNED_32, true, true, false); 289 TEST_DATA_TYPE(RS_TYPE_UNSIGNED_64, true, true, false); 290 291 // These types are valid only for scalars 292 TEST_DATA_TYPE(RS_TYPE_MATRIX_4X4, true, false, false); 293 TEST_DATA_TYPE(RS_TYPE_MATRIX_3X3, true, false, false); 294 TEST_DATA_TYPE(RS_TYPE_MATRIX_2X2, true, false, false); 295 TEST_DATA_TYPE(RS_TYPE_ELEMENT, true, false, false); 296 TEST_DATA_TYPE(RS_TYPE_TYPE, true, false, false); 297 TEST_DATA_TYPE(RS_TYPE_ALLOCATION, true, false, false); 298 TEST_DATA_TYPE(RS_TYPE_SCRIPT, true, false, false); 299 300 // U8, U16 are valid for scalar, vector and pixel 301 TEST_DATA_TYPE(RS_TYPE_UNSIGNED_8, true, true, true); 302 TEST_DATA_TYPE(RS_TYPE_UNSIGNED_16, true, true, true); 303 304 // These data types are only for pixels and a particular data_kind 305 TEST_SUPPORTED_PIXEL (RS_TYPE_UNSIGNED_5_6_5, RS_KIND_PIXEL_RGB); 306 TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_5_6_5, RS_KIND_PIXEL_L); 307 TEST_SUPPORTED_PIXEL (RS_TYPE_UNSIGNED_5_5_5_1, RS_KIND_PIXEL_RGBA); 308 TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_5_5_5_1, RS_KIND_PIXEL_L); 309 TEST_SUPPORTED_PIXEL (RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_RGBA); 310 TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_L); 311 TEST_SUPPORTED_PIXEL (RS_TYPE_UNSIGNED_16, RS_KIND_PIXEL_DEPTH); 312 TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_L); 313 314 // These data types are not supported from single-source 315 TEST_DATA_TYPE(RS_TYPE_NONE, false, false, false); 316 TEST_DATA_TYPE(RS_TYPE_SAMPLER, false, false, false); 317 TEST_DATA_TYPE(RS_TYPE_MESH, false, false, false); 318 TEST_DATA_TYPE(RS_TYPE_PROGRAM_FRAGMENT, false, false, false); 319 TEST_DATA_TYPE(RS_TYPE_PROGRAM_VERTEX, false, false, false); 320 TEST_DATA_TYPE(RS_TYPE_PROGRAM_RASTER, false, false, false); 321 TEST_DATA_TYPE(RS_TYPE_PROGRAM_STORE, false, false, false); 322 TEST_DATA_TYPE(RS_TYPE_FONT, false, false, false); 323 TEST_DATA_TYPE(RS_TYPE_INVALID, false, false, false); 324 325 ///////////////////////////////////////////////////////////////// 326 // Test rs_type creation 327 ///////////////////////////////////////////////////////////////// 328 rs_element I32_3 = rsCreateVectorElement(RS_TYPE_SIGNED_32, 3); 329 330 // Create 1D, 2D, 3D types 331 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3))); 332 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4))); 333 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 5))); 334 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 0))); // x = 0 is allowed 335 336 // Invalid dimensionality 337 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 0, 4))); // x is 0 but y isn't 338 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 0, 4, 5))); // x is 0 but z isn't 339 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 5))); // y is 0 but z isn't 340 341 // shape attributes 342 // Valid yuv_format 343 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false, 344 RS_YUV_NONE))); 345 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false, 346 RS_YUV_YV12))); 347 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false, 348 RS_YUV_NV21))); 349 _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false, 350 RS_YUV_420_888))); 351 352 // Invalid yuv_format 353 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, false, 1024))); 354 // yuv_format with 1D or 3D is invalid 355 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, false, false, 356 RS_YUV_YV12))); 357 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, false, 358 RS_YUV_YV12))); 359 360 // yuv_format with mipmaps or cubemap is invalid 361 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, true, 362 RS_YUV_YV12))); 363 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 0, true, false, 364 RS_YUV_YV12))); 365 366 // mipmaps with 1D or 3D is invalid 367 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, true, false, 368 RS_YUV_NONE))); 369 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, true, false, 370 RS_YUV_NONE))); 371 372 // cubemap with 1D or 3D is invalid 373 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, false, true, 374 RS_YUV_NONE))); 375 _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, true, 376 RS_YUV_NONE))); 377 378 ///////////////////////////////////////////////////////////////// 379 // Test rs_allocation creation 380 ///////////////////////////////////////////////////////////////// 381 rs_type I32_3_2D = rsCreateType(I32_3, 3, 4); 382 383 // Valid uses 384 _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D))); 385 _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,\ 386 (uint32_t) RS_ALLOCATION_USAGE_SCRIPT))); 387 _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,\ 388 (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE))); 389 _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D, 390 (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE | 391 RS_ALLOCATION_USAGE_SCRIPT))); 392 393 // Invalid uses 394 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 395 (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_VERTEX))); 396 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 397 (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS))); 398 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 399 (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET))); 400 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 401 (uint32_t) RS_ALLOCATION_USAGE_IO_INPUT))); 402 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 403 (uint32_t) RS_ALLOCATION_USAGE_IO_OUTPUT))); 404 _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D, 405 (uint32_t) RS_ALLOCATION_USAGE_SHARED))); 406 407 #ifndef RSTEST_COMPAT 408 TEST_HELPER(half); 409 #endif 410 TEST_HELPERS(float); 411 TEST_HELPERS(double); 412 TEST_HELPERS(char); 413 TEST_HELPERS(short); 414 TEST_HELPERS(int); 415 TEST_HELPERS(long); 416 TEST_HELPERS(uchar); 417 TEST_HELPERS(ushort); 418 TEST_HELPERS(uint); 419 TEST_HELPERS(ulong); 420 } 421 422 void single_source_alloc_test() { 423 if (failed) { 424 rsDebug("Single Source Alloc Test Failed", 0); 425 rsSendToClientBlocking(RS_MSG_TEST_FAILED); 426 } 427 else { 428 rsDebug("Single Source Alloc Test Passed", 0); 429 rsSendToClientBlocking(RS_MSG_TEST_PASSED); 430 } 431 } 432