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 = 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
56static 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
65uint8_t*
66rsOffset(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
78uint8_t*
79rsOffsetNs(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
172ELEMENT_AT_IMPL_TYPE(char)
173ELEMENT_AT_IMPL_TYPE(uchar)
174ELEMENT_AT_IMPL_TYPE(short)
175ELEMENT_AT_IMPL_TYPE(ushort)
176ELEMENT_AT_IMPL_TYPE(int)
177ELEMENT_AT_IMPL_TYPE(uint)
178ELEMENT_AT_IMPL_TYPE(long)
179ELEMENT_AT_IMPL_TYPE(ulong)
180ELEMENT_AT_IMPL_TYPE(half)
181ELEMENT_AT_IMPL_TYPE(float)
182ELEMENT_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
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    local_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    local_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    local_memcpy((void*)&p[(eSize * x) + (y * stride) + (z * stride * dimY)], ptr, eSize);
304}
305
306ELEMENT_AT(char)
307ELEMENT_AT(char2)
308ELEMENT_AT(char3)
309ELEMENT_AT(char4)
310ELEMENT_AT(uchar)
311ELEMENT_AT(uchar2)
312ELEMENT_AT(uchar3)
313ELEMENT_AT(uchar4)
314ELEMENT_AT(short)
315ELEMENT_AT(short2)
316ELEMENT_AT(short3)
317ELEMENT_AT(short4)
318ELEMENT_AT(ushort)
319ELEMENT_AT(ushort2)
320ELEMENT_AT(ushort3)
321ELEMENT_AT(ushort4)
322ELEMENT_AT(int)
323ELEMENT_AT(int2)
324ELEMENT_AT(int3)
325ELEMENT_AT(int4)
326ELEMENT_AT(uint)
327ELEMENT_AT(uint2)
328ELEMENT_AT(uint3)
329ELEMENT_AT(uint4)
330ELEMENT_AT(long)
331ELEMENT_AT(long2)
332ELEMENT_AT(long3)
333ELEMENT_AT(long4)
334ELEMENT_AT(ulong)
335ELEMENT_AT(ulong2)
336ELEMENT_AT(ulong3)
337ELEMENT_AT(ulong4)
338ELEMENT_AT(half)
339ELEMENT_AT(half2)
340ELEMENT_AT(half3)
341ELEMENT_AT(half4)
342ELEMENT_AT(float)
343ELEMENT_AT(float2)
344ELEMENT_AT(float3)
345ELEMENT_AT(float4)
346ELEMENT_AT(double)
347ELEMENT_AT(double2)
348ELEMENT_AT(double3)
349ELEMENT_AT(double4)
350
351typedef unsigned long long ull;
352typedef unsigned long long ull2 __attribute__((ext_vector_type(2)));
353typedef unsigned long long ull3 __attribute__((ext_vector_type(3)));
354typedef unsigned long long ull4 __attribute__((ext_vector_type(4)));
355
356#ifndef RS_DEBUG_RUNTIME
357SET_ELEMENT_AT_TYPE_IMPL(ull, ulong)
358SET_ELEMENT_AT_TYPE_IMPL(ull2, ulong2)
359SET_ELEMENT_AT_TYPE_IMPL(ull3, ulong3)
360SET_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
372extern 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
377extern 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
391extern 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
461VOP(char2)
462VOP(char3)
463VOP(char4)
464VOP(uchar2)
465VOP(uchar3)
466VOP(uchar4)
467VOP(short2)
468VOP(short3)
469VOP(short4)
470VOP(ushort2)
471VOP(ushort3)
472VOP(ushort4)
473VOP(int2)
474VOP(int3)
475VOP(int4)
476VOP(uint2)
477VOP(uint3)
478VOP(uint4)
479VOP(long2)
480VOP(long3)
481VOP(long4)
482VOP(ulong2)
483VOP(ulong3)
484VOP(ulong4)
485VOP(float2)
486VOP(float3)
487VOP(float4)
488VOP(double2)
489VOP(double3)
490VOP(double4)
491
492#undef VOP_IMPL
493#undef VOP_DEF
494#undef VOP
495
496static const rs_element kInvalidElement = RS_NULL_OBJ;
497
498extern rs_element __attribute__((overloadable)) rsCreateElement(
499        int32_t dt, int32_t dk, bool isNormalized, uint32_t vecSize);
500
501extern 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
505extern rs_allocation __attribute__((overloadable)) rsCreateAllocation(
506        rs_type type, rs_allocation_mipmap_control mipmaps, uint32_t usages,
507        void *ptr);
508
509rs_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
539rs_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
566rs_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
630rs_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
636rs_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
642rs_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
647rs_allocation __attribute__((overloadable)) rsCreateAllocation(rs_type type,
648                                                               uint32_t usage) {
649    return rsCreateAllocation(type, RS_ALLOCATION_MIPMAP_NONE, usage, NULL);
650}
651
652rs_allocation __attribute__((overloadable)) rsCreateAllocation(rs_type type) {
653    return rsCreateAllocation(type, RS_ALLOCATION_MIPMAP_NONE,
654                              RS_ALLOCATION_USAGE_SCRIPT, NULL);
655}
656