rs_allocation.c revision cbdb6480528fc374144df1ae9c604c9100d33268
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, void* src, size_t size) {
50    char* dst_c = (char*) dst, *src_c = (char*) src;
51    for (; size > 0; size--) {
52        *dst_c++ = *src_c++;
53    }
54}
55
56#ifdef RS_DEBUG_RUNTIME
57#define ELEMENT_AT(T)                                                   \
58    extern void __attribute__((overloadable))                           \
59        rsSetElementAt_##T(rs_allocation a, const T *val, uint32_t x);  \
60    extern void __attribute__((overloadable))                           \
61        rsSetElementAt_##T(rs_allocation a, const T *val, uint32_t x, uint32_t y); \
62    extern void __attribute__((overloadable))                           \
63        rsSetElementAt_##T(rs_allocation a, const T *val, uint32_t x, uint32_t y, uint32_t z); \
64    extern void __attribute__((overloadable))                           \
65        rsGetElementAt_##T(rs_allocation a, T *val, uint32_t x);  \
66    extern void __attribute__((overloadable))                           \
67        rsGetElementAt_##T(rs_allocation a, T *val, uint32_t x, uint32_t y); \
68    extern void __attribute__((overloadable))                           \
69        rsGetElementAt_##T(rs_allocation a, T *val, uint32_t x, uint32_t y, uint32_t z); \
70                                                                        \
71    extern void __attribute__((overloadable))                           \
72    rsSetElementAt_##T(rs_allocation a, T val, uint32_t x) {            \
73        rsSetElementAt_##T(a, &val, x);                                 \
74    }                                                                   \
75    extern void __attribute__((overloadable))                           \
76    rsSetElementAt_##T(rs_allocation a, T val, uint32_t x, uint32_t y) { \
77        rsSetElementAt_##T(a, &val, x, y);                              \
78    }                                                                   \
79    extern void __attribute__((overloadable))                           \
80    rsSetElementAt_##T(rs_allocation a, T val, uint32_t x, uint32_t y, uint32_t z) { \
81        rsSetElementAt_##T(a, &val, x, y, z);                           \
82    }                                                                   \
83    extern T __attribute__((overloadable))                              \
84    rsGetElementAt_##T(rs_allocation a, uint32_t x) {                   \
85        T tmp;                                                          \
86        rsGetElementAt_##T(a, &tmp, x);                                 \
87        return tmp;                                                     \
88    }                                                                   \
89    extern T __attribute__((overloadable))                              \
90    rsGetElementAt_##T(rs_allocation a, uint32_t x, uint32_t y) {       \
91        T tmp;                                                          \
92        rsGetElementAt_##T(a, &tmp, x, y);                              \
93        return tmp;                                                     \
94    }                                                                   \
95    extern T __attribute__((overloadable))                              \
96    rsGetElementAt_##T(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) { \
97        T tmp;                                                          \
98        rsGetElementAt_##T(a, &tmp, x, y, z);                           \
99        return tmp;                                                     \
100    }
101#else
102
103uint8_t*
104rsOffset(rs_allocation a, uint32_t sizeOf, uint32_t x, uint32_t y,
105         uint32_t z) {
106    Allocation_t *alloc = (Allocation_t *)a.p;
107    //#ifdef __LP64__
108    //    uint8_t *p = (uint8_t *)a.r;
109    //#else
110    uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
111    //#endif
112    const uint32_t stride = (uint32_t)alloc->mHal.drvState.lod[0].stride;
113    const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
114    uint8_t *dp = &p[(sizeOf * x) + (y * stride) +
115                     (z * stride * dimY)];
116    return dp;
117}
118
119uint8_t*
120rsOffsetNs(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
121    Allocation_t *alloc = (Allocation_t *)a.p;
122    //#ifdef __LP64__
123    //    uint8_t *p = (uint8_t *)a.r;
124    //#else
125    uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
126    //#endif
127    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
128    const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
129    const uint32_t sizeOf = alloc->mHal.state.elementSizeBytes;;
130    uint8_t *dp = &p[(sizeOf * x) + (y * stride) +
131                     (z * stride * dimY)];
132    return dp;
133}
134
135#define SET_ELEMENT_AT_TYPE(T, typename)                                    \
136                                                                        \
137    void                                                                \
138    rsSetElementAtImpl_##typename(rs_allocation a, typename val, uint32_t x,   \
139                                  uint32_t y, uint32_t z);              \
140                                                                        \
141    extern void __attribute__((overloadable))                           \
142    rsSetElementAt_##typename(rs_allocation a, T val, uint32_t x) {     \
143        rsSetElementAtImpl_##typename(a, (typename)val, x, 0, 0);              \
144    }                                                                   \
145                                                                        \
146    extern void __attribute__((overloadable))                           \
147    rsSetElementAt_##typename(rs_allocation a, T val, uint32_t x,       \
148                              uint32_t y) {                             \
149        rsSetElementAtImpl_##typename(a, (typename)val, x, y, 0);              \
150    }                                                                   \
151                                                                        \
152    extern void __attribute__((overloadable))                           \
153    rsSetElementAt_##typename(rs_allocation a, T val, uint32_t x, uint32_t y, \
154                              uint32_t z) {                             \
155        rsSetElementAtImpl_##typename(a, (typename)val, x, y, z);              \
156    }                                                                   \
157
158
159
160#define GET_ELEMENT_AT_TYPE(T, typename)                                \
161    typename                                                            \
162    rsGetElementAtImpl_##typename(rs_allocation a, uint32_t x, uint32_t y, \
163                                  uint32_t z);                          \
164                                                                        \
165    extern typename __attribute__((overloadable))                       \
166    rsGetElementAt_##typename(rs_allocation a, uint32_t x) {            \
167        return (typename)rsGetElementAtImpl_##typename(a, x, 0, 0);     \
168    }                                                                   \
169                                                                        \
170    extern typename __attribute__((overloadable))                       \
171    rsGetElementAt_##typename(rs_allocation a, uint32_t x, uint32_t y) { \
172        return (typename)rsGetElementAtImpl_##typename(a, x, y, 0);     \
173    }                                                                   \
174                                                                        \
175    extern typename __attribute__((overloadable))                       \
176    rsGetElementAt_##typename(rs_allocation a, uint32_t x, uint32_t y,  \
177                              uint32_t z) {                             \
178        return (typename)rsGetElementAtImpl_##typename(a, x, y, z);     \
179    }
180
181#define SET_ELEMENT_AT(T) SET_ELEMENT_AT_TYPE(T, T)
182#define GET_ELEMENT_AT(T) GET_ELEMENT_AT_TYPE(T, T)
183
184#define ELEMENT_AT(T)                           \
185    SET_ELEMENT_AT(T)                           \
186    GET_ELEMENT_AT(T)
187
188
189extern const void * __attribute__((overloadable))
190        rsGetElementAt(rs_allocation a, uint32_t x) {
191    Allocation_t *alloc = (Allocation_t *)a.p;
192    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
193    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
194    return &p[eSize * x];
195}
196
197extern const void * __attribute__((overloadable))
198        rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y) {
199    Allocation_t *alloc = (Allocation_t *)a.p;
200    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
201    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
202    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
203    return &p[(eSize * x) + (y * stride)];
204}
205
206extern const void * __attribute__((overloadable))
207        rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
208    Allocation_t *alloc = (Allocation_t *)a.p;
209    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
210    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
211    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
212    const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
213    return &p[(eSize * x) + (y * stride) + (z * stride * dimY)];
214}
215extern void __attribute__((overloadable))
216        rsSetElementAt(rs_allocation a, void* ptr, uint32_t x) {
217    Allocation_t *alloc = (Allocation_t *)a.p;
218    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
219    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
220    memcpy((void*)&p[eSize * x], ptr, eSize);
221}
222
223extern void __attribute__((overloadable))
224        rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y) {
225    Allocation_t *alloc = (Allocation_t *)a.p;
226    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
227    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
228    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
229    memcpy((void*)&p[(eSize * x) + (y * stride)], ptr, eSize);
230}
231
232extern void __attribute__((overloadable))
233        rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y, uint32_t z) {
234    Allocation_t *alloc = (Allocation_t *)a.p;
235    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
236    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
237    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
238    const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
239    memcpy((void*)&p[(eSize * x) + (y * stride) + (z * stride * dimY)], ptr, eSize);
240}
241#endif // RS_DEBUG_RUNTIME
242
243ELEMENT_AT(char)
244ELEMENT_AT(char2)
245ELEMENT_AT(char3)
246ELEMENT_AT(char4)
247ELEMENT_AT(uchar)
248ELEMENT_AT(uchar2)
249ELEMENT_AT(uchar3)
250ELEMENT_AT(uchar4)
251ELEMENT_AT(short)
252ELEMENT_AT(short2)
253ELEMENT_AT(short3)
254ELEMENT_AT(short4)
255ELEMENT_AT(ushort)
256ELEMENT_AT(ushort2)
257ELEMENT_AT(ushort3)
258ELEMENT_AT(ushort4)
259ELEMENT_AT(int)
260ELEMENT_AT(int2)
261ELEMENT_AT(int3)
262ELEMENT_AT(int4)
263ELEMENT_AT(uint)
264ELEMENT_AT(uint2)
265ELEMENT_AT(uint3)
266ELEMENT_AT(uint4)
267ELEMENT_AT(long)
268ELEMENT_AT(long2)
269ELEMENT_AT(long3)
270ELEMENT_AT(long4)
271ELEMENT_AT(ulong)
272ELEMENT_AT(ulong2)
273ELEMENT_AT(ulong3)
274ELEMENT_AT(ulong4)
275ELEMENT_AT(float)
276ELEMENT_AT(float2)
277ELEMENT_AT(float3)
278ELEMENT_AT(float4)
279ELEMENT_AT(double)
280ELEMENT_AT(double2)
281ELEMENT_AT(double3)
282ELEMENT_AT(double4)
283
284typedef unsigned long long ull;
285typedef unsigned long long ull2 __attribute__((ext_vector_type(2)));
286typedef unsigned long long ull3 __attribute__((ext_vector_type(3)));
287typedef unsigned long long ull4 __attribute__((ext_vector_type(4)));
288
289#ifndef RS_DEBUG_RUNTIME
290SET_ELEMENT_AT_TYPE(ull, ulong)
291SET_ELEMENT_AT_TYPE(ull2, ulong2)
292SET_ELEMENT_AT_TYPE(ull3, ulong3)
293SET_ELEMENT_AT_TYPE(ull4, ulong4)
294
295#undef SET_ELEMENT_AT_TYPE
296#undef GET_ELEMENT_AT_TYPE
297#undef ELEMENT_AT_TYPE
298#endif
299
300#undef ELEMENT_AT
301
302
303extern const uchar __attribute__((overloadable))
304        rsGetElementAtYuv_uchar_Y(rs_allocation a, uint32_t x, uint32_t y) {
305    return rsGetElementAt_uchar(a, x, y);
306}
307
308extern const uchar __attribute__((overloadable))
309        rsGetElementAtYuv_uchar_U(rs_allocation a, uint32_t x, uint32_t y) {
310
311    Allocation_t *alloc = (Allocation_t *)a.p;
312
313    const size_t cstep = alloc->mHal.drvState.yuv.step;
314    const size_t shift = alloc->mHal.drvState.yuv.shift;
315    const size_t stride = alloc->mHal.drvState.lod[1].stride;
316
317    const uchar *pin = (const uchar *)alloc->mHal.drvState.lod[1].mallocPtr;
318
319    return pin[((x >> shift) * cstep) + ((y >> shift) * stride)];
320}
321
322extern const uchar __attribute__((overloadable))
323        rsGetElementAtYuv_uchar_V(rs_allocation a, uint32_t x, uint32_t y) {
324
325    Allocation_t *alloc = (Allocation_t *)a.p;
326
327    const size_t cstep = alloc->mHal.drvState.yuv.step;
328    const size_t shift = alloc->mHal.drvState.yuv.shift;
329    const size_t stride = alloc->mHal.drvState.lod[2].stride;
330
331    const uchar *pin = (const uchar *)alloc->mHal.drvState.lod[2].mallocPtr;
332
333    return pin[((x >> shift) * cstep) + ((y >> shift) * stride)];
334}
335
336
337#define VOP(T)                                                          \
338    extern void __rsAllocationVStoreXImpl_##T(rs_allocation a, const T val, uint32_t x, uint32_t y, uint32_t z); \
339    extern T __rsAllocationVLoadXImpl_##T(rs_allocation a, uint32_t x, uint32_t y, uint32_t z); \
340                                                                        \
341    extern void __attribute__((overloadable))                           \
342    rsAllocationVStoreX_##T(rs_allocation a, T val, uint32_t x) {       \
343        __rsAllocationVStoreXImpl_##T(a, val, x, 0, 0);                 \
344    }                                                                   \
345    extern void __attribute__((overloadable))                           \
346    rsAllocationVStoreX_##T(rs_allocation a, T val, uint32_t x, uint32_t y) { \
347        __rsAllocationVStoreXImpl_##T(a, val, x, y, 0);                 \
348    }                                                                   \
349    extern void __attribute__((overloadable))                           \
350    rsAllocationVStoreX_##T(rs_allocation a, T val, uint32_t x, uint32_t y, uint32_t z) { \
351        __rsAllocationVStoreXImpl_##T(a, val, x, y, z);                 \
352    }                                                                   \
353    extern T __attribute__((overloadable))                              \
354    rsAllocationVLoadX_##T(rs_allocation a, uint32_t x) {               \
355        return __rsAllocationVLoadXImpl_##T(a, x, 0, 0);                \
356    }                                                                   \
357    extern T __attribute__((overloadable))                              \
358    rsAllocationVLoadX_##T(rs_allocation a, uint32_t x, uint32_t y) {   \
359        return __rsAllocationVLoadXImpl_##T(a, x, y, 0);                \
360    }                                                                   \
361    extern T __attribute__((overloadable))                              \
362    rsAllocationVLoadX_##T(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) { \
363        return __rsAllocationVLoadXImpl_##T(a, x, y, z);                \
364    }
365
366VOP(char2)
367VOP(char3)
368VOP(char4)
369VOP(uchar2)
370VOP(uchar3)
371VOP(uchar4)
372VOP(short2)
373VOP(short3)
374VOP(short4)
375VOP(ushort2)
376VOP(ushort3)
377VOP(ushort4)
378VOP(int2)
379VOP(int3)
380VOP(int4)
381VOP(uint2)
382VOP(uint3)
383VOP(uint4)
384VOP(long2)
385VOP(long3)
386VOP(long4)
387VOP(ulong2)
388VOP(ulong3)
389VOP(ulong4)
390VOP(float2)
391VOP(float3)
392VOP(float4)
393VOP(double2)
394VOP(double3)
395VOP(double4)
396
397#undef VOP
398