1#include "rs_core.rsh"
2#include "rs_structs.h"
3
4// Opaque Allocation type operations
5extern 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
11extern 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
17extern 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
23extern 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
29extern 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
36extern 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
51static void 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
106uint8_t*
107rsOffset(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
122uint8_t*
123rsOffsetNs(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
173ELEMENT_AT_IMPL_TYPE(char)
174ELEMENT_AT_IMPL_TYPE(uchar)
175ELEMENT_AT_IMPL_TYPE(short)
176ELEMENT_AT_IMPL_TYPE(ushort)
177ELEMENT_AT_IMPL_TYPE(int)
178ELEMENT_AT_IMPL_TYPE(uint)
179ELEMENT_AT_IMPL_TYPE(long)
180ELEMENT_AT_IMPL_TYPE(ulong)
181ELEMENT_AT_IMPL_TYPE(half)
182ELEMENT_AT_IMPL_TYPE(float)
183ELEMENT_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
253extern 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
261extern 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
270extern 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}
279extern 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    memcpy((void*)&p[eSize * x], ptr, eSize);
285}
286
287extern 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    memcpy((void*)&p[(eSize * x) + (y * stride)], ptr, eSize);
294}
295
296extern 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    memcpy((void*)&p[(eSize * x) + (y * stride) + (z * stride * dimY)], ptr, eSize);
304}
305#endif // RS_DEBUG_RUNTIME
306
307ELEMENT_AT(char)
308ELEMENT_AT(char2)
309ELEMENT_AT(char3)
310ELEMENT_AT(char4)
311ELEMENT_AT(uchar)
312ELEMENT_AT(uchar2)
313ELEMENT_AT(uchar3)
314ELEMENT_AT(uchar4)
315ELEMENT_AT(short)
316ELEMENT_AT(short2)
317ELEMENT_AT(short3)
318ELEMENT_AT(short4)
319ELEMENT_AT(ushort)
320ELEMENT_AT(ushort2)
321ELEMENT_AT(ushort3)
322ELEMENT_AT(ushort4)
323ELEMENT_AT(int)
324ELEMENT_AT(int2)
325ELEMENT_AT(int3)
326ELEMENT_AT(int4)
327ELEMENT_AT(uint)
328ELEMENT_AT(uint2)
329ELEMENT_AT(uint3)
330ELEMENT_AT(uint4)
331ELEMENT_AT(long)
332ELEMENT_AT(long2)
333ELEMENT_AT(long3)
334ELEMENT_AT(long4)
335ELEMENT_AT(ulong)
336ELEMENT_AT(ulong2)
337ELEMENT_AT(ulong3)
338ELEMENT_AT(ulong4)
339ELEMENT_AT(half)
340ELEMENT_AT(half2)
341ELEMENT_AT(half3)
342ELEMENT_AT(half4)
343ELEMENT_AT(float)
344ELEMENT_AT(float2)
345ELEMENT_AT(float3)
346ELEMENT_AT(float4)
347ELEMENT_AT(double)
348ELEMENT_AT(double2)
349ELEMENT_AT(double3)
350ELEMENT_AT(double4)
351
352typedef unsigned long long ull;
353typedef unsigned long long ull2 __attribute__((ext_vector_type(2)));
354typedef unsigned long long ull3 __attribute__((ext_vector_type(3)));
355typedef unsigned long long ull4 __attribute__((ext_vector_type(4)));
356
357#ifndef RS_DEBUG_RUNTIME
358SET_ELEMENT_AT_TYPE_IMPL(ull, ulong)
359SET_ELEMENT_AT_TYPE_IMPL(ull2, ulong2)
360SET_ELEMENT_AT_TYPE_IMPL(ull3, ulong3)
361SET_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
373extern 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
378extern 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
392extern 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        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        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
462VOP(char2)
463VOP(char3)
464VOP(char4)
465VOP(uchar2)
466VOP(uchar3)
467VOP(uchar4)
468VOP(short2)
469VOP(short3)
470VOP(short4)
471VOP(ushort2)
472VOP(ushort3)
473VOP(ushort4)
474VOP(int2)
475VOP(int3)
476VOP(int4)
477VOP(uint2)
478VOP(uint3)
479VOP(uint4)
480VOP(long2)
481VOP(long3)
482VOP(long4)
483VOP(ulong2)
484VOP(ulong3)
485VOP(ulong4)
486VOP(float2)
487VOP(float3)
488VOP(float4)
489VOP(double2)
490VOP(double3)
491VOP(double4)
492
493#undef VOP_IMPL
494#undef VOP_DEF
495#undef VOP
496
497static const rs_element kInvalidElement = {0};
498
499extern rs_element __attribute__((overloadable)) rsCreateElement(
500        int32_t dt, int32_t dk, bool isNormalized, uint32_t vecSize);
501
502extern 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
506extern rs_allocation __attribute__((overloadable)) rsCreateAllocation(
507        rs_type type, rs_allocation_mipmap_control mipmaps, uint32_t usages,
508        void *ptr);
509
510rs_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
540rs_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
567rs_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
631rs_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
637rs_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
643rs_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
648rs_allocation __attribute__((overloadable)) rsCreateAllocation(rs_type type,
649                                                               uint32_t usage) {
650    return rsCreateAllocation(type, RS_ALLOCATION_MIPMAP_NONE, usage, NULL);
651}
652
653rs_allocation __attribute__((overloadable)) rsCreateAllocation(rs_type type) {
654    return rsCreateAllocation(type, RS_ALLOCATION_MIPMAP_NONE,
655                              RS_ALLOCATION_USAGE_SCRIPT, NULL);
656}
657