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