1 #include "rs_core.rsh"
2 #include "rs_structs.h"
3 
4 /* Function declarations from libRS */
5 extern float4 __attribute__((overloadable)) convert_float4(uchar4 c);
6 
7 /* Implementation of Core Runtime */
8 
9 
10 /////////////////////////////////////////////////////
11 // Matrix ops
12 /////////////////////////////////////////////////////
13 
14 
15 extern void __attribute__((overloadable))
rsMatrixLoadIdentity(rs_matrix4x4 * m)16 rsMatrixLoadIdentity(rs_matrix4x4 *m) {
17     m->m[0] = 1.f;
18     m->m[1] = 0.f;
19     m->m[2] = 0.f;
20     m->m[3] = 0.f;
21     m->m[4] = 0.f;
22     m->m[5] = 1.f;
23     m->m[6] = 0.f;
24     m->m[7] = 0.f;
25     m->m[8] = 0.f;
26     m->m[9] = 0.f;
27     m->m[10] = 1.f;
28     m->m[11] = 0.f;
29     m->m[12] = 0.f;
30     m->m[13] = 0.f;
31     m->m[14] = 0.f;
32     m->m[15] = 1.f;
33 }
34 
35 extern void __attribute__((overloadable))
rsMatrixLoadIdentity(rs_matrix3x3 * m)36 rsMatrixLoadIdentity(rs_matrix3x3 *m) {
37     m->m[0] = 1.f;
38     m->m[1] = 0.f;
39     m->m[2] = 0.f;
40     m->m[3] = 0.f;
41     m->m[4] = 1.f;
42     m->m[5] = 0.f;
43     m->m[6] = 0.f;
44     m->m[7] = 0.f;
45     m->m[8] = 1.f;
46 }
47 extern void __attribute__((overloadable))
rsMatrixLoadIdentity(rs_matrix2x2 * m)48 rsMatrixLoadIdentity(rs_matrix2x2 *m) {
49     m->m[0] = 1.f;
50     m->m[1] = 0.f;
51     m->m[2] = 0.f;
52     m->m[3] = 1.f;
53 }
54 
55 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 * m,const float * f)56 rsMatrixLoad(rs_matrix4x4 *m, const float *f) {
57     m->m[0] = f[0];
58     m->m[1] = f[1];
59     m->m[2] = f[2];
60     m->m[3] = f[3];
61     m->m[4] = f[4];
62     m->m[5] = f[5];
63     m->m[6] = f[6];
64     m->m[7] = f[7];
65     m->m[8] = f[8];
66     m->m[9] = f[9];
67     m->m[10] = f[10];
68     m->m[11] = f[11];
69     m->m[12] = f[12];
70     m->m[13] = f[13];
71     m->m[14] = f[14];
72     m->m[15] = f[15];
73 }
74 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix3x3 * m,const float * f)75 rsMatrixLoad(rs_matrix3x3 *m, const float *f) {
76     m->m[0] = f[0];
77     m->m[1] = f[1];
78     m->m[2] = f[2];
79     m->m[3] = f[3];
80     m->m[4] = f[4];
81     m->m[5] = f[5];
82     m->m[6] = f[6];
83     m->m[7] = f[7];
84     m->m[8] = f[8];
85 }
86 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix2x2 * m,const float * f)87 rsMatrixLoad(rs_matrix2x2 *m, const float *f) {
88     m->m[0] = f[0];
89     m->m[1] = f[1];
90     m->m[2] = f[2];
91     m->m[3] = f[3];
92 }
93 
94 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 * m,const rs_matrix4x4 * s)95 rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *s) {
96     m->m[0] = s->m[0];
97     m->m[1] = s->m[1];
98     m->m[2] = s->m[2];
99     m->m[3] = s->m[3];
100     m->m[4] = s->m[4];
101     m->m[5] = s->m[5];
102     m->m[6] = s->m[6];
103     m->m[7] = s->m[7];
104     m->m[8] = s->m[8];
105     m->m[9] = s->m[9];
106     m->m[10] = s->m[10];
107     m->m[11] = s->m[11];
108     m->m[12] = s->m[12];
109     m->m[13] = s->m[13];
110     m->m[14] = s->m[14];
111     m->m[15] = s->m[15];
112 }
113 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 * m,const rs_matrix3x3 * v)114 rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v) {
115     m->m[0] = v->m[0];
116     m->m[1] = v->m[1];
117     m->m[2] = v->m[2];
118     m->m[3] = 0.f;
119     m->m[4] = v->m[3];
120     m->m[5] = v->m[4];
121     m->m[6] = v->m[5];
122     m->m[7] = 0.f;
123     m->m[8] = v->m[6];
124     m->m[9] = v->m[7];
125     m->m[10] = v->m[8];
126     m->m[11] = 0.f;
127     m->m[12] = 0.f;
128     m->m[13] = 0.f;
129     m->m[14] = 0.f;
130     m->m[15] = 1.f;
131 }
132 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 * m,const rs_matrix2x2 * v)133 rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v) {
134     m->m[0] = v->m[0];
135     m->m[1] = v->m[1];
136     m->m[2] = 0.f;
137     m->m[3] = 0.f;
138     m->m[4] = v->m[2];
139     m->m[5] = v->m[3];
140     m->m[6] = 0.f;
141     m->m[7] = 0.f;
142     m->m[8] = 0.f;
143     m->m[9] = 0.f;
144     m->m[10] = 1.f;
145     m->m[11] = 0.f;
146     m->m[12] = 0.f;
147     m->m[13] = 0.f;
148     m->m[14] = 0.f;
149     m->m[15] = 1.f;
150 }
151 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix3x3 * m,const rs_matrix3x3 * s)152 rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *s) {
153     m->m[0] = s->m[0];
154     m->m[1] = s->m[1];
155     m->m[2] = s->m[2];
156     m->m[3] = s->m[3];
157     m->m[4] = s->m[4];
158     m->m[5] = s->m[5];
159     m->m[6] = s->m[6];
160     m->m[7] = s->m[7];
161     m->m[8] = s->m[8];
162 }
163 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix2x2 * m,const rs_matrix2x2 * s)164 rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *s) {
165     m->m[0] = s->m[0];
166     m->m[1] = s->m[1];
167     m->m[2] = s->m[2];
168     m->m[3] = s->m[3];
169 }
170 
171 
172 extern void __attribute__((overloadable))
rsMatrixSet(rs_matrix4x4 * m,uint32_t col,uint32_t row,float v)173 rsMatrixSet(rs_matrix4x4 *m, uint32_t col, uint32_t row, float v) {
174     m->m[col * 4 + row] = v;
175 }
176 
177 extern float __attribute__((overloadable))
rsMatrixGet(const rs_matrix4x4 * m,uint32_t col,uint32_t row)178 rsMatrixGet(const rs_matrix4x4 *m, uint32_t col, uint32_t row) {
179     return m->m[col * 4 + row];
180 }
181 
182 extern void __attribute__((overloadable))
rsMatrixSet(rs_matrix3x3 * m,uint32_t col,uint32_t row,float v)183 rsMatrixSet(rs_matrix3x3 *m, uint32_t col, uint32_t row, float v) {
184     m->m[col * 3 + row] = v;
185 }
186 
187 extern float __attribute__((overloadable))
rsMatrixGet(const rs_matrix3x3 * m,uint32_t col,uint32_t row)188 rsMatrixGet(const rs_matrix3x3 *m, uint32_t col, uint32_t row) {
189     return m->m[col * 3 + row];
190 }
191 
192 extern void __attribute__((overloadable))
rsMatrixSet(rs_matrix2x2 * m,uint32_t col,uint32_t row,float v)193 rsMatrixSet(rs_matrix2x2 *m, uint32_t col, uint32_t row, float v) {
194     m->m[col * 2 + row] = v;
195 }
196 
197 extern float __attribute__((overloadable))
rsMatrixGet(const rs_matrix2x2 * m,uint32_t col,uint32_t row)198 rsMatrixGet(const rs_matrix2x2 *m, uint32_t col, uint32_t row) {
199     return m->m[col * 2 + row];
200 }
201 
202 extern float2 __attribute__((overloadable))
rsMatrixMultiply(const rs_matrix2x2 * m,float2 in)203 rsMatrixMultiply(const rs_matrix2x2 *m, float2 in) {
204     float2 ret;
205     ret.x = (m->m[0] * in.x) + (m->m[2] * in.y);
206     ret.y = (m->m[1] * in.x) + (m->m[3] * in.y);
207     return ret;
208 }
209 extern float2 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix2x2 * m,float2 in)210 rsMatrixMultiply(rs_matrix2x2 *m, float2 in) {
211     return rsMatrixMultiply((const rs_matrix2x2 *)m, in);
212 }
213 
214 extern float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * m,float4 in)215 rsMatrixMultiply(rs_matrix4x4 *m, float4 in) {
216     return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
217 }
218 
219 extern float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * m,float3 in)220 rsMatrixMultiply(rs_matrix4x4 *m, float3 in) {
221     return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
222 }
223 
224 extern float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * m,float2 in)225 rsMatrixMultiply(rs_matrix4x4 *m, float2 in) {
226     return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
227 }
228 
229 extern float3 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 * m,float3 in)230 rsMatrixMultiply(rs_matrix3x3 *m, float3 in) {
231     return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
232 }
233 
234 extern float3 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 * m,float2 in)235 rsMatrixMultiply(rs_matrix3x3 *m, float2 in) {
236     return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
237 }
238 
239 extern void __attribute__((overloadable))
rsMatrixLoadMultiply(rs_matrix4x4 * ret,const rs_matrix4x4 * lhs,const rs_matrix4x4 * rhs)240 rsMatrixLoadMultiply(rs_matrix4x4 *ret, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
241     // Use a temporary variable to support the case where one of the inputs
242     // is also the destination, e.g. rsMatrixLoadMultiply(&left, &left, &right);
243     rs_matrix4x4 result;
244     for (int i=0 ; i<4 ; i++) {
245         float ri0 = 0;
246         float ri1 = 0;
247         float ri2 = 0;
248         float ri3 = 0;
249         for (int j=0 ; j<4 ; j++) {
250             const float rhs_ij = rsMatrixGet(rhs, i, j);
251             ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
252             ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
253             ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij;
254             ri3 += rsMatrixGet(lhs, j, 3) * rhs_ij;
255         }
256         rsMatrixSet(&result, i, 0, ri0);
257         rsMatrixSet(&result, i, 1, ri1);
258         rsMatrixSet(&result, i, 2, ri2);
259         rsMatrixSet(&result, i, 3, ri3);
260     }
261     rsMatrixLoad(ret, &result);
262 }
263 
264 extern void __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * lhs,const rs_matrix4x4 * rhs)265 rsMatrixMultiply(rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
266     rsMatrixLoadMultiply(lhs, lhs, rhs);
267 }
268 
269 extern void __attribute__((overloadable))
rsMatrixLoadMultiply(rs_matrix3x3 * ret,const rs_matrix3x3 * lhs,const rs_matrix3x3 * rhs)270 rsMatrixLoadMultiply(rs_matrix3x3 *ret, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
271     // Use a temporary variable to support the case where one of the inputs
272     // is also the destination, e.g. rsMatrixLoadMultiply(&left, &left, &right);
273     rs_matrix3x3 result;
274     for (int i=0 ; i<3 ; i++) {
275         float ri0 = 0;
276         float ri1 = 0;
277         float ri2 = 0;
278         for (int j=0 ; j<3 ; j++) {
279             const float rhs_ij = rsMatrixGet(rhs, i, j);
280             ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
281             ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
282             ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij;
283         }
284         rsMatrixSet(&result, i, 0, ri0);
285         rsMatrixSet(&result, i, 1, ri1);
286         rsMatrixSet(&result, i, 2, ri2);
287     }
288     rsMatrixLoad(ret, &result);
289 }
290 
291 extern void __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 * lhs,const rs_matrix3x3 * rhs)292 rsMatrixMultiply(rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
293     rsMatrixLoadMultiply(lhs, lhs, rhs);
294 }
295 
296 extern void __attribute__((overloadable))
rsMatrixLoadMultiply(rs_matrix2x2 * ret,const rs_matrix2x2 * lhs,const rs_matrix2x2 * rhs)297 rsMatrixLoadMultiply(rs_matrix2x2 *ret, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
298     // Use a temporary variable to support the case where one of the inputs
299     // is also the destination, e.g. rsMatrixLoadMultiply(&left, &left, &right);
300     rs_matrix2x2 result;
301     for (int i=0 ; i<2 ; i++) {
302         float ri0 = 0;
303         float ri1 = 0;
304         for (int j=0 ; j<2 ; j++) {
305             const float rhs_ij = rsMatrixGet(rhs, i, j);
306             ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
307             ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
308         }
309         rsMatrixSet(&result, i, 0, ri0);
310         rsMatrixSet(&result, i, 1, ri1);
311     }
312     rsMatrixLoad(ret, &result);
313 }
314 
315 extern void __attribute__((overloadable))
rsMatrixMultiply(rs_matrix2x2 * lhs,const rs_matrix2x2 * rhs)316 rsMatrixMultiply(rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
317     rsMatrixLoadMultiply(lhs, lhs, rhs);
318 }
319 
320