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