Home | History | Annotate | Download | only in unittest
      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