Home | History | Annotate | Download | only in runtime
      1 #include "rs_core.rsh"
      2 #include "rs_structs.h"
      3 
      4 // Opaque Allocation type operations
      5 extern uint32_t __attribute__((overloadable))
      6     rsAllocationGetDimX(rs_allocation a) {
      7     Allocation_t *alloc = (Allocation_t *)a.p;
      8     return alloc->mHal.drvState.lod[0].dimX;
      9 }
     10 
     11 extern uint32_t __attribute__((overloadable))
     12         rsAllocationGetDimY(rs_allocation a) {
     13     Allocation_t *alloc = (Allocation_t *)a.p;
     14     return alloc->mHal.drvState.lod[0].dimY;
     15 }
     16 
     17 extern uint32_t __attribute__((overloadable))
     18         rsAllocationGetDimZ(rs_allocation a) {
     19     Allocation_t *alloc = (Allocation_t *)a.p;
     20     return alloc->mHal.drvState.lod[0].dimZ;
     21 }
     22 
     23 extern uint32_t __attribute__((overloadable))
     24         rsAllocationGetDimLOD(rs_allocation a) {
     25     Allocation_t *alloc = (Allocation_t *)a.p;
     26     return alloc->mHal.state.hasMipmaps;
     27 }
     28 
     29 extern uint32_t __attribute__((overloadable))
     30         rsAllocationGetDimFaces(rs_allocation a) {
     31     Allocation_t *alloc = (Allocation_t *)a.p;
     32     return alloc->mHal.state.hasFaces;
     33 }
     34 
     35 
     36 extern rs_element __attribute__((overloadable))
     37         rsAllocationGetElement(rs_allocation a) {
     38     Allocation_t *alloc = (Allocation_t *)a.p;
     39     if (alloc == NULL) {
     40         rs_element nullElem = {0};
     41         return nullElem;
     42     }
     43     Type_t *type = (Type_t *)alloc->mHal.state.type;
     44     rs_element returnElem = {type->mHal.state.element};
     45     rs_element rs_retval = {0};
     46     rsSetObject(&rs_retval, returnElem);
     47     return rs_retval;
     48 }
     49 
     50 // TODO: this needs to be optimized, obviously
     51 static void local_memcpy(void* dst, const void* src, size_t size) {
     52     char* dst_c = (char*) dst;
     53     const char* src_c = (const char*) src;
     54     for (; size > 0; size--) {
     55         *dst_c++ = *src_c++;
     56     }
     57 }
     58 
     59 #ifdef RS_DEBUG_RUNTIME
     60 #define ELEMENT_AT(T)                                                   \
     61     extern void __attribute__((overloadable))                           \
     62         rsSetElementAt_##T(rs_allocation a, const T *val, uint32_t x);  \
     63     extern void __attribute__((overloadable))                           \
     64         rsSetElementAt_##T(rs_allocation a, const T *val, uint32_t x, uint32_t y); \
     65     extern void __attribute__((overloadable))                           \
     66         rsSetElementAt_##T(rs_allocation a, const T *val, uint32_t x, uint32_t y, uint32_t z); \
     67     extern void __attribute__((overloadable))                           \
     68         rsGetElementAt_##T(rs_allocation a, T *val, uint32_t x);  \
     69     extern void __attribute__((overloadable))                           \
     70         rsGetElementAt_##T(rs_allocation a, T *val, uint32_t x, uint32_t y); \
     71     extern void __attribute__((overloadable))                           \
     72         rsGetElementAt_##T(rs_allocation a, T *val, uint32_t x, uint32_t y, uint32_t z); \
     73                                                                         \
     74     extern void __attribute__((overloadable))                           \
     75     rsSetElementAt_##T(rs_allocation a, T val, uint32_t x) {            \
     76         rsSetElementAt_##T(a, &val, x);                                 \
     77     }                                                                   \
     78     extern void __attribute__((overloadable))                           \
     79     rsSetElementAt_##T(rs_allocation a, T val, uint32_t x, uint32_t y) { \
     80         rsSetElementAt_##T(a, &val, x, y);                              \
     81     }                                                                   \
     82     extern void __attribute__((overloadable))                           \
     83     rsSetElementAt_##T(rs_allocation a, T val, uint32_t x, uint32_t y, uint32_t z) { \
     84         rsSetElementAt_##T(a, &val, x, y, z);                           \
     85     }                                                                   \
     86     extern T __attribute__((overloadable))                              \
     87     rsGetElementAt_##T(rs_allocation a, uint32_t x) {                   \
     88         T tmp;                                                          \
     89         rsGetElementAt_##T(a, &tmp, x);                                 \
     90         return tmp;                                                     \
     91     }                                                                   \
     92     extern T __attribute__((overloadable))                              \
     93     rsGetElementAt_##T(rs_allocation a, uint32_t x, uint32_t y) {       \
     94         T tmp;                                                          \
     95         rsGetElementAt_##T(a, &tmp, x, y);                              \
     96         return tmp;                                                     \
     97     }                                                                   \
     98     extern T __attribute__((overloadable))                              \
     99     rsGetElementAt_##T(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) { \
    100         T tmp;                                                          \
    101         rsGetElementAt_##T(a, &tmp, x, y, z);                           \
    102         return tmp;                                                     \
    103     }
    104 #else
    105 
    106 uint8_t*
    107 rsOffset(rs_allocation a, uint32_t sizeOf, uint32_t x, uint32_t y,
    108          uint32_t z) {
    109     Allocation_t *alloc = (Allocation_t *)a.p;
    110     //#ifdef __LP64__
    111     //    uint8_t *p = (uint8_t *)a.r;
    112     //#else
    113     uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
    114     //#endif
    115     const uint32_t stride = (uint32_t)alloc->mHal.drvState.lod[0].stride;
    116     const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
    117     uint8_t *dp = &p[(sizeOf * x) + (y * stride) +
    118                      (z * stride * dimY)];
    119     return dp;
    120 }
    121 
    122 uint8_t*
    123 rsOffsetNs(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
    124     Allocation_t *alloc = (Allocation_t *)a.p;
    125     //#ifdef __LP64__
    126     //    uint8_t *p = (uint8_t *)a.r;
    127     //#else
    128     uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
    129     //#endif
    130     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
    131     const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
    132     const uint32_t sizeOf = alloc->mHal.state.elementSizeBytes;;
    133     uint8_t *dp = &p[(sizeOf * x) + (y * stride) +
    134                      (z * stride * dimY)];
    135     return dp;
    136 }
    137 
    138 // The functions rsSetElementAtImpl_T and rsGetElementAtImpl_T are implemented in bitcode
    139 // in ll32/allocation.ll and ll64/allocation.ll. To be able to provide debug info for
    140 // these functions define them here instead, if we are linking with the debug library.
    141 #ifdef RS_G_RUNTIME
    142 
    143 #define SET_ELEMENT_AT_IMPL_TYPE_SIZE(typename, size)                               \
    144      void rsSetElementAtImpl_##typename                                             \
    145             (rs_allocation a, typename val, uint32_t x, uint32_t y, uint32_t z) {   \
    146         typename* val_ptr = (typename*)rsOffset(a, size, x, y, z);                  \
    147         *val_ptr = val;                                                             \
    148     }
    149 
    150 #define GET_ELEMENT_AT_IMPL_TYPE_SIZE(typename, size)                               \
    151      typename rsGetElementAtImpl_##typename                                         \
    152             (rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {                 \
    153         typename *val_ptr = (typename*)rsOffset(a, size, x, y, z);                  \
    154         return *val_ptr;                                                            \
    155     }
    156 
    157 #define SET_ELEMENT_AT_IMPL_TYPE(typename)          \
    158     SET_ELEMENT_AT_IMPL_TYPE_SIZE(typename, sizeof(typename))        \
    159     SET_ELEMENT_AT_IMPL_TYPE_SIZE(typename##2, sizeof(typename)*2)   \
    160     SET_ELEMENT_AT_IMPL_TYPE_SIZE(typename##3, sizeof(typename)*4)   \
    161     SET_ELEMENT_AT_IMPL_TYPE_SIZE(typename##4, sizeof(typename)*4)
    162 
    163 #define GET_ELEMENT_AT_IMPL_TYPE(typename)          \
    164     GET_ELEMENT_AT_IMPL_TYPE_SIZE(typename, sizeof(typename))        \
    165     GET_ELEMENT_AT_IMPL_TYPE_SIZE(typename##2, sizeof(typename)*2)   \
    166     GET_ELEMENT_AT_IMPL_TYPE_SIZE(typename##3, sizeof(typename)*4)   \
    167     GET_ELEMENT_AT_IMPL_TYPE_SIZE(typename##4, sizeof(typename)*4)
    168 
    169 #define ELEMENT_AT_IMPL_TYPE(typename)  \
    170     SET_ELEMENT_AT_IMPL_TYPE(typename)  \
    171     GET_ELEMENT_AT_IMPL_TYPE(typename)
    172 
    173 ELEMENT_AT_IMPL_TYPE(char)
    174 ELEMENT_AT_IMPL_TYPE(uchar)
    175 ELEMENT_AT_IMPL_TYPE(short)
    176 ELEMENT_AT_IMPL_TYPE(ushort)
    177 ELEMENT_AT_IMPL_TYPE(int)
    178 ELEMENT_AT_IMPL_TYPE(uint)
    179 ELEMENT_AT_IMPL_TYPE(long)
    180 ELEMENT_AT_IMPL_TYPE(ulong)
    181 ELEMENT_AT_IMPL_TYPE(half)
    182 ELEMENT_AT_IMPL_TYPE(float)
    183 ELEMENT_AT_IMPL_TYPE(double)
    184 
    185 #undef ELEMENT_AT_IMPL_TYPE
    186 #undef GET_ELEMENT_AT_IMPL_TYPE
    187 #undef SET_ELEMENT_AT_IMPL_TYPE
    188 #undef GET_ELEMENT_AT_IMPL_TYPE_SIZE
    189 #undef SET_ELEMENT_AT_IMPL_TYPE_SIZE
    190 
    191 #define SET_ELEMENT_AT_TYPE_IMPL(T, typename) /* nothing */
    192 #define GET_ELEMENT_AT_TYPE_IMPL(T, typename) /* nothing */
    193 
    194 #else
    195 
    196 #define SET_ELEMENT_AT_TYPE_IMPL(T, typename)                                    \
    197     void                                                                \
    198     rsSetElementAtImpl_##typename(rs_allocation a, typename val, uint32_t x,   \
    199                                   uint32_t y, uint32_t z);
    200 
    201 #define GET_ELEMENT_AT_TYPE_IMPL(T, typename)                                \
    202     typename                                                            \
    203     rsGetElementAtImpl_##typename(rs_allocation a, uint32_t x, uint32_t y, \
    204                                   uint32_t z);
    205 
    206 #endif //RS_G_RUNTIME
    207 
    208 #define SET_ELEMENT_AT_TYPE_DEF(T, typename)                                    \
    209     extern void __attribute__((overloadable))                           \
    210     rsSetElementAt_##typename(rs_allocation a, T val, uint32_t x) {     \
    211         rsSetElementAtImpl_##typename(a, (typename)val, x, 0, 0);              \
    212     }                                                                   \
    213                                                                         \
    214     extern void __attribute__((overloadable))                           \
    215     rsSetElementAt_##typename(rs_allocation a, T val, uint32_t x,       \
    216                               uint32_t y) {                             \
    217         rsSetElementAtImpl_##typename(a, (typename)val, x, y, 0);              \
    218     }                                                                   \
    219                                                                         \
    220     extern void __attribute__((overloadable))                           \
    221     rsSetElementAt_##typename(rs_allocation a, T val, uint32_t x, uint32_t y, \
    222                               uint32_t z) {                             \
    223         rsSetElementAtImpl_##typename(a, (typename)val, x, y, z);              \
    224     }
    225 
    226 #define GET_ELEMENT_AT_TYPE_DEF(T, typename)                                \
    227     extern typename __attribute__((overloadable))                       \
    228     rsGetElementAt_##typename(rs_allocation a, uint32_t x) {            \
    229         return (typename)rsGetElementAtImpl_##typename(a, x, 0, 0);     \
    230     }                                                                   \
    231                                                                         \
    232     extern typename __attribute__((overloadable))                       \
    233     rsGetElementAt_##typename(rs_allocation a, uint32_t x, uint32_t y) { \
    234         return (typename)rsGetElementAtImpl_##typename(a, x, y, 0);     \
    235     }                                                                   \
    236                                                                         \
    237     extern typename __attribute__((overloadable))                       \
    238     rsGetElementAt_##typename(rs_allocation a, uint32_t x, uint32_t y,  \
    239                               uint32_t z) {                             \
    240         return (typename)rsGetElementAtImpl_##typename(a, x, y, z);     \
    241     }
    242 
    243 #define SET_ELEMENT_AT(T) SET_ELEMENT_AT_TYPE_IMPL(T, T) \
    244     SET_ELEMENT_AT_TYPE_DEF(T, T)
    245 #define GET_ELEMENT_AT(T) GET_ELEMENT_AT_TYPE_IMPL(T, T) \
    246     GET_ELEMENT_AT_TYPE_DEF(T, T)
    247 
    248 #define ELEMENT_AT(T)                           \
    249     SET_ELEMENT_AT(T)                           \
    250     GET_ELEMENT_AT(T)
    251 
    252 
    253 extern const void * __attribute__((overloadable))
    254         rsGetElementAt(rs_allocation a, uint32_t x) {
    255     Allocation_t *alloc = (Allocation_t *)a.p;
    256     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
    257     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
    258     return &p[eSize * x];
    259 }
    260 
    261 extern const void * __attribute__((overloadable))
    262         rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y) {
    263     Allocation_t *alloc = (Allocation_t *)a.p;
    264     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
    265     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
    266     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
    267     return &p[(eSize * x) + (y * stride)];
    268 }
    269 
    270 extern const void * __attribute__((overloadable))
    271         rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
    272     Allocation_t *alloc = (Allocation_t *)a.p;
    273     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
    274     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
    275     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
    276     const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
    277     return &p[(eSize * x) + (y * stride) + (z * stride * dimY)];
    278 }
    279 extern void __attribute__((overloadable))
    280         rsSetElementAt(rs_allocation a, void* ptr, uint32_t x) {
    281     Allocation_t *alloc = (Allocation_t *)a.p;
    282     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
    283     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
    284     local_memcpy((void*)&p[eSize * x], ptr, eSize);
    285 }
    286 
    287 extern void __attribute__((overloadable))
    288         rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y) {
    289     Allocation_t *alloc = (Allocation_t *)a.p;
    290     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
    291     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
    292     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
    293     local_memcpy((void*)&p[(eSize * x) + (y * stride)], ptr, eSize);
    294 }
    295 
    296 extern void __attribute__((overloadable))
    297         rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y, uint32_t z) {
    298     Allocation_t *alloc = (Allocation_t *)a.p;
    299     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
    300     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
    301     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
    302     const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
    303     local_memcpy((void*)&p[(eSize * x) + (y * stride) + (z * stride * dimY)], ptr, eSize);
    304 }
    305 #endif // RS_DEBUG_RUNTIME
    306 
    307 ELEMENT_AT(char)
    308 ELEMENT_AT(char2)
    309 ELEMENT_AT(char3)
    310 ELEMENT_AT(char4)
    311 ELEMENT_AT(uchar)
    312 ELEMENT_AT(uchar2)
    313 ELEMENT_AT(uchar3)
    314 ELEMENT_AT(uchar4)
    315 ELEMENT_AT(short)
    316 ELEMENT_AT(short2)
    317 ELEMENT_AT(short3)
    318 ELEMENT_AT(short4)
    319 ELEMENT_AT(ushort)
    320 ELEMENT_AT(ushort2)
    321 ELEMENT_AT(ushort3)
    322 ELEMENT_AT(ushort4)
    323 ELEMENT_AT(int)
    324 ELEMENT_AT(int2)
    325 ELEMENT_AT(int3)
    326 ELEMENT_AT(int4)
    327 ELEMENT_AT(uint)
    328 ELEMENT_AT(uint2)
    329 ELEMENT_AT(uint3)
    330 ELEMENT_AT(uint4)
    331 ELEMENT_AT(long)
    332 ELEMENT_AT(long2)
    333 ELEMENT_AT(long3)
    334 ELEMENT_AT(long4)
    335 ELEMENT_AT(ulong)
    336 ELEMENT_AT(ulong2)
    337 ELEMENT_AT(ulong3)
    338 ELEMENT_AT(ulong4)
    339 ELEMENT_AT(half)
    340 ELEMENT_AT(half2)
    341 ELEMENT_AT(half3)
    342 ELEMENT_AT(half4)
    343 ELEMENT_AT(float)
    344 ELEMENT_AT(float2)
    345 ELEMENT_AT(float3)
    346 ELEMENT_AT(float4)
    347 ELEMENT_AT(double)
    348 ELEMENT_AT(double2)
    349 ELEMENT_AT(double3)
    350 ELEMENT_AT(double4)
    351 
    352 typedef unsigned long long ull;
    353 typedef unsigned long long ull2 __attribute__((ext_vector_type(2)));
    354 typedef unsigned long long ull3 __attribute__((ext_vector_type(3)));
    355 typedef unsigned long long ull4 __attribute__((ext_vector_type(4)));
    356 
    357 #ifndef RS_DEBUG_RUNTIME
    358 SET_ELEMENT_AT_TYPE_IMPL(ull, ulong)
    359 SET_ELEMENT_AT_TYPE_IMPL(ull2, ulong2)
    360 SET_ELEMENT_AT_TYPE_IMPL(ull3, ulong3)
    361 SET_ELEMENT_AT_TYPE_IMPL(ull4, ulong4)
    362 
    363 #undef SET_ELEMENT_AT_TYPE_DEF
    364 #undef GET_ELEMENT_AT_TYPE_DEF
    365 #undef SET_ELEMENT_AT_TYPE_IMPL
    366 #undef GET_ELEMENT_AT_TYPE_IMPL
    367 #undef ELEMENT_AT_TYPE
    368 #endif
    369 
    370 #undef ELEMENT_AT
    371 
    372 
    373 extern uchar __attribute__((overloadable))
    374         rsGetElementAtYuv_uchar_Y(rs_allocation a, uint32_t x, uint32_t y) {
    375     return rsGetElementAt_uchar(a, x, y);
    376 }
    377 
    378 extern uchar __attribute__((overloadable))
    379         rsGetElementAtYuv_uchar_U(rs_allocation a, uint32_t x, uint32_t y) {
    380 
    381     Allocation_t *alloc = (Allocation_t *)a.p;
    382 
    383     const size_t cstep = alloc->mHal.drvState.yuv.step;
    384     const size_t shift = alloc->mHal.drvState.yuv.shift;
    385     const size_t stride = alloc->mHal.drvState.lod[1].stride;
    386 
    387     const uchar *pin = (const uchar *)alloc->mHal.drvState.lod[1].mallocPtr;
    388 
    389     return pin[((x >> shift) * cstep) + ((y >> shift) * stride)];
    390 }
    391 
    392 extern uchar __attribute__((overloadable))
    393         rsGetElementAtYuv_uchar_V(rs_allocation a, uint32_t x, uint32_t y) {
    394 
    395     Allocation_t *alloc = (Allocation_t *)a.p;
    396 
    397     const size_t cstep = alloc->mHal.drvState.yuv.step;
    398     const size_t shift = alloc->mHal.drvState.yuv.shift;
    399     const size_t stride = alloc->mHal.drvState.lod[2].stride;
    400 
    401     const uchar *pin = (const uchar *)alloc->mHal.drvState.lod[2].mallocPtr;
    402 
    403     return pin[((x >> shift) * cstep) + ((y >> shift) * stride)];
    404 }
    405 
    406 // The functions rsAllocationVLoadXImpl_T and rsAllocationVStoreXImpl_T are implemented in
    407 // bitcode in ll32/allocation.ll and ll64/allocation.ll. To be able to provide debug info
    408 // for these functions define them here instead, if we are linking with the debug library.
    409 #ifdef RS_G_RUNTIME
    410 
    411 #define VOP_IMPL(T)                                                             \
    412     void __rsAllocationVStoreXImpl_##T                                          \
    413             (rs_allocation a, const T val, uint32_t x, uint32_t y, uint32_t z) {\
    414         T *val_ptr = (T*)rsOffsetNs(a, x, y, z);                                \
    415         local_memcpy(val_ptr, &val, sizeof(T));                                       \
    416     }                                                                           \
    417     T __rsAllocationVLoadXImpl_##T                                              \
    418             (rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {             \
    419         T result = {};                                                          \
    420         T* val_ptr = (T*)rsOffsetNs(a, x, y, z);                                \
    421         local_memcpy(&result, val_ptr, sizeof(T));                                    \
    422         return result;                                                          \
    423     }
    424 
    425 #else
    426 
    427 #define VOP_IMPL(T)                                                          \
    428     extern void __rsAllocationVStoreXImpl_##T(rs_allocation a, const T val, uint32_t x, uint32_t y, uint32_t z); \
    429     extern T __rsAllocationVLoadXImpl_##T(rs_allocation a, uint32_t x, uint32_t y, uint32_t z);
    430 
    431 #endif // RS_G_RUNTIME
    432 
    433 #define VOP_DEF(T)                                                      \
    434     extern void __attribute__((overloadable))                           \
    435     rsAllocationVStoreX_##T(rs_allocation a, T val, uint32_t x) {       \
    436         __rsAllocationVStoreXImpl_##T(a, val, x, 0, 0);                 \
    437     }                                                                   \
    438     extern void __attribute__((overloadable))                           \
    439     rsAllocationVStoreX_##T(rs_allocation a, T val, uint32_t x, uint32_t y) { \
    440         __rsAllocationVStoreXImpl_##T(a, val, x, y, 0);                 \
    441     }                                                                   \
    442     extern void __attribute__((overloadable))                           \
    443     rsAllocationVStoreX_##T(rs_allocation a, T val, uint32_t x, uint32_t y, uint32_t z) { \
    444         __rsAllocationVStoreXImpl_##T(a, val, x, y, z);                 \
    445     }                                                                   \
    446     extern T __attribute__((overloadable))                              \
    447     rsAllocationVLoadX_##T(rs_allocation a, uint32_t x) {               \
    448         return __rsAllocationVLoadXImpl_##T(a, x, 0, 0);                \
    449     }                                                                   \
    450     extern T __attribute__((overloadable))                              \
    451     rsAllocationVLoadX_##T(rs_allocation a, uint32_t x, uint32_t y) {   \
    452         return __rsAllocationVLoadXImpl_##T(a, x, y, 0);                \
    453     }                                                                   \
    454     extern T __attribute__((overloadable))                              \
    455     rsAllocationVLoadX_##T(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) { \
    456         return __rsAllocationVLoadXImpl_##T(a, x, y, z);                \
    457     }
    458 
    459 #define VOP(T) VOP_IMPL(T) \
    460     VOP_DEF(T)
    461 
    462 VOP(char2)
    463 VOP(char3)
    464 VOP(char4)
    465 VOP(uchar2)
    466 VOP(uchar3)
    467 VOP(uchar4)
    468 VOP(short2)
    469 VOP(short3)
    470 VOP(short4)
    471 VOP(ushort2)
    472 VOP(ushort3)
    473 VOP(ushort4)
    474 VOP(int2)
    475 VOP(int3)
    476 VOP(int4)
    477 VOP(uint2)
    478 VOP(uint3)
    479 VOP(uint4)
    480 VOP(long2)
    481 VOP(long3)
    482 VOP(long4)
    483 VOP(ulong2)
    484 VOP(ulong3)
    485 VOP(ulong4)
    486 VOP(float2)
    487 VOP(float3)
    488 VOP(float4)
    489 VOP(double2)
    490 VOP(double3)
    491 VOP(double4)
    492 
    493 #undef VOP_IMPL
    494 #undef VOP_DEF
    495 #undef VOP
    496 
    497 static const rs_element kInvalidElement = {0};
    498 
    499 extern rs_element __attribute__((overloadable)) rsCreateElement(
    500         int32_t dt, int32_t dk, bool isNormalized, uint32_t vecSize);
    501 
    502 extern rs_type __attribute__((overloadable)) rsCreateType(
    503     rs_element element, uint32_t dimX, uint32_t dimY, uint32_t dimZ,
    504     bool mipmaps, bool faces, rs_yuv_format yuv_format);
    505 
    506 extern rs_allocation __attribute__((overloadable)) rsCreateAllocation(
    507         rs_type type, rs_allocation_mipmap_control mipmaps, uint32_t usages,
    508         void *ptr);
    509 
    510 rs_element __attribute__((overloadable)) rsCreateElement(
    511         rs_data_type data_type) {
    512 
    513     switch (data_type) {
    514         case RS_TYPE_BOOLEAN:
    515         case RS_TYPE_FLOAT_16:
    516         case RS_TYPE_FLOAT_32:
    517         case RS_TYPE_FLOAT_64:
    518         case RS_TYPE_SIGNED_8:
    519         case RS_TYPE_SIGNED_16:
    520         case RS_TYPE_SIGNED_32:
    521         case RS_TYPE_SIGNED_64:
    522         case RS_TYPE_UNSIGNED_8:
    523         case RS_TYPE_UNSIGNED_16:
    524         case RS_TYPE_UNSIGNED_32:
    525         case RS_TYPE_UNSIGNED_64:
    526         case RS_TYPE_MATRIX_4X4:
    527         case RS_TYPE_MATRIX_3X3:
    528         case RS_TYPE_MATRIX_2X2:
    529         case RS_TYPE_ELEMENT:
    530         case RS_TYPE_TYPE:
    531         case RS_TYPE_ALLOCATION:
    532         case RS_TYPE_SCRIPT:
    533             return rsCreateElement(data_type, RS_KIND_USER, false, 1);
    534         default:
    535             rsDebug("Invalid data_type", data_type);
    536             return kInvalidElement;
    537     }
    538 }
    539 
    540 rs_element __attribute__((overloadable)) rsCreateVectorElement(
    541         rs_data_type data_type, uint32_t vector_width) {
    542     if (vector_width < 2 || vector_width > 4) {
    543         rsDebug("Invalid vector_width", vector_width);
    544         return kInvalidElement;
    545     }
    546     switch (data_type) {
    547         case RS_TYPE_BOOLEAN:
    548         case RS_TYPE_FLOAT_16:
    549         case RS_TYPE_FLOAT_32:
    550         case RS_TYPE_FLOAT_64:
    551         case RS_TYPE_SIGNED_8:
    552         case RS_TYPE_SIGNED_16:
    553         case RS_TYPE_SIGNED_32:
    554         case RS_TYPE_SIGNED_64:
    555         case RS_TYPE_UNSIGNED_8:
    556         case RS_TYPE_UNSIGNED_16:
    557         case RS_TYPE_UNSIGNED_32:
    558         case RS_TYPE_UNSIGNED_64:
    559             return rsCreateElement(data_type, RS_KIND_USER, false,
    560                                    vector_width);
    561         default:
    562             rsDebug("Invalid data_type for vector element", data_type);
    563             return kInvalidElement;
    564     }
    565 }
    566 
    567 rs_element __attribute__((overloadable)) rsCreatePixelElement(
    568         rs_data_type data_type, rs_data_kind data_kind) {
    569     if (data_type != RS_TYPE_UNSIGNED_8 &&
    570         data_type != RS_TYPE_UNSIGNED_16 &&
    571         data_type != RS_TYPE_UNSIGNED_5_6_5 &&
    572         data_type != RS_TYPE_UNSIGNED_4_4_4_4 &&
    573         data_type != RS_TYPE_UNSIGNED_5_5_5_1) {
    574 
    575         rsDebug("Invalid data_type for pixel element", data_type);
    576         return kInvalidElement;
    577     }
    578     if (data_kind != RS_KIND_PIXEL_L &&
    579         data_kind != RS_KIND_PIXEL_A &&
    580         data_kind != RS_KIND_PIXEL_LA &&
    581         data_kind != RS_KIND_PIXEL_RGB &&
    582         data_kind != RS_KIND_PIXEL_RGBA &&
    583         data_kind != RS_KIND_PIXEL_DEPTH &&
    584         data_kind != RS_KIND_PIXEL_YUV) {
    585 
    586         rsDebug("Invalid data_kind for pixel element", data_type);
    587         return kInvalidElement;
    588     }
    589     if (data_type == RS_TYPE_UNSIGNED_5_6_5 && data_kind != RS_KIND_PIXEL_RGB) {
    590         rsDebug("Bad data_type and data_kind combo", data_type, data_kind);
    591         return kInvalidElement;
    592     }
    593     if (data_type == RS_TYPE_UNSIGNED_5_5_5_1 &&
    594         data_kind != RS_KIND_PIXEL_RGBA) {
    595 
    596         rsDebug("Bad data_type and data_kind combo", data_type, data_kind);
    597         return kInvalidElement;
    598     }
    599     if (data_type == RS_TYPE_UNSIGNED_4_4_4_4 &&
    600         data_kind != RS_KIND_PIXEL_RGBA) {
    601 
    602         rsDebug("Bad data_type and data_kind combo", data_type, data_kind);
    603         return kInvalidElement;
    604     }
    605     if (data_type == RS_TYPE_UNSIGNED_16 && data_kind != RS_KIND_PIXEL_DEPTH) {
    606         rsDebug("Bad data_type and data_kind combo", data_type, data_kind);
    607         return kInvalidElement;
    608     }
    609 
    610     int vector_width = 1;
    611     switch (data_kind) {
    612         case RS_KIND_PIXEL_LA:
    613             vector_width = 2;
    614             break;
    615         case RS_KIND_PIXEL_RGB:
    616             vector_width = 3;
    617             break;
    618         case RS_KIND_PIXEL_RGBA:
    619             vector_width = 4;
    620             break;
    621         case RS_KIND_PIXEL_DEPTH:
    622             vector_width = 2;
    623             break;
    624         default:
    625             break;
    626     }
    627 
    628     return rsCreateElement(data_type, data_kind, true, vector_width);
    629 }
    630 
    631 rs_type __attribute__((overloadable)) rsCreateType(rs_element element,
    632                                                    uint32_t dimX, uint32_t dimY,
    633                                                    uint32_t dimZ) {
    634     return rsCreateType(element, dimX, dimY, dimZ, false, false, RS_YUV_NONE);
    635 }
    636 
    637 rs_type __attribute__((overloadable)) rsCreateType(rs_element element,
    638                                                    uint32_t dimX,
    639                                                    uint32_t dimY) {
    640     return rsCreateType(element, dimX, dimY, 0, false, false, RS_YUV_NONE);
    641 }
    642 
    643 rs_type __attribute__((overloadable)) rsCreateType(rs_element element,
    644                                                    uint32_t dimX) {
    645     return rsCreateType(element, dimX, 0, 0, false, false, RS_YUV_NONE);
    646 }
    647 
    648 rs_allocation __attribute__((overloadable)) rsCreateAllocation(rs_type type,
    649                                                                uint32_t usage) {
    650     return rsCreateAllocation(type, RS_ALLOCATION_MIPMAP_NONE, usage, NULL);
    651 }
    652 
    653 rs_allocation __attribute__((overloadable)) rsCreateAllocation(rs_type type) {
    654     return rsCreateAllocation(type, RS_ALLOCATION_MIPMAP_NONE,
    655                               RS_ALLOCATION_USAGE_SCRIPT, NULL);
    656 }
    657