xref: /aosp_15_r20/frameworks/rs/driver/runtime/rs_sample.c (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker #include "rs_core.rsh"
2*e1eccf28SAndroid Build Coastguard Worker #include "rs_structs.h"
3*e1eccf28SAndroid Build Coastguard Worker 
4*e1eccf28SAndroid Build Coastguard Worker 
5*e1eccf28SAndroid Build Coastguard Worker // 565 Conversion bits taken from SkBitmap
6*e1eccf28SAndroid Build Coastguard Worker #define SK_R16_BITS     5
7*e1eccf28SAndroid Build Coastguard Worker #define SK_G16_BITS     6
8*e1eccf28SAndroid Build Coastguard Worker #define SK_B16_BITS     5
9*e1eccf28SAndroid Build Coastguard Worker 
10*e1eccf28SAndroid Build Coastguard Worker #define SK_R16_SHIFT    (SK_B16_BITS + SK_G16_BITS)
11*e1eccf28SAndroid Build Coastguard Worker #define SK_G16_SHIFT    (SK_B16_BITS)
12*e1eccf28SAndroid Build Coastguard Worker #define SK_B16_SHIFT    0
13*e1eccf28SAndroid Build Coastguard Worker 
14*e1eccf28SAndroid Build Coastguard Worker #define SK_R16_MASK     ((1 << SK_R16_BITS) - 1)
15*e1eccf28SAndroid Build Coastguard Worker #define SK_G16_MASK     ((1 << SK_G16_BITS) - 1)
16*e1eccf28SAndroid Build Coastguard Worker #define SK_B16_MASK     ((1 << SK_B16_BITS) - 1)
17*e1eccf28SAndroid Build Coastguard Worker 
18*e1eccf28SAndroid Build Coastguard Worker #define SkGetPackedR16(color)   (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
19*e1eccf28SAndroid Build Coastguard Worker #define SkGetPackedG16(color)   (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
20*e1eccf28SAndroid Build Coastguard Worker #define SkGetPackedB16(color)   (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
21*e1eccf28SAndroid Build Coastguard Worker 
SkR16ToR32(unsigned r)22*e1eccf28SAndroid Build Coastguard Worker static inline unsigned SkR16ToR32(unsigned r) {
23*e1eccf28SAndroid Build Coastguard Worker     return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
24*e1eccf28SAndroid Build Coastguard Worker }
25*e1eccf28SAndroid Build Coastguard Worker 
SkG16ToG32(unsigned g)26*e1eccf28SAndroid Build Coastguard Worker static inline unsigned SkG16ToG32(unsigned g) {
27*e1eccf28SAndroid Build Coastguard Worker     return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
28*e1eccf28SAndroid Build Coastguard Worker }
29*e1eccf28SAndroid Build Coastguard Worker 
SkB16ToB32(unsigned b)30*e1eccf28SAndroid Build Coastguard Worker static inline unsigned SkB16ToB32(unsigned b) {
31*e1eccf28SAndroid Build Coastguard Worker     return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
32*e1eccf28SAndroid Build Coastguard Worker }
33*e1eccf28SAndroid Build Coastguard Worker 
34*e1eccf28SAndroid Build Coastguard Worker #define SkPacked16ToR32(c)      SkR16ToR32(SkGetPackedR16(c))
35*e1eccf28SAndroid Build Coastguard Worker #define SkPacked16ToG32(c)      SkG16ToG32(SkGetPackedG16(c))
36*e1eccf28SAndroid Build Coastguard Worker #define SkPacked16ToB32(c)      SkB16ToB32(SkGetPackedB16(c))
37*e1eccf28SAndroid Build Coastguard Worker 
getFrom565(uint16_t color)38*e1eccf28SAndroid Build Coastguard Worker static float3 getFrom565(uint16_t color) {
39*e1eccf28SAndroid Build Coastguard Worker     float3 result;
40*e1eccf28SAndroid Build Coastguard Worker     result.x = (float)SkPacked16ToR32(color);
41*e1eccf28SAndroid Build Coastguard Worker     result.y = (float)SkPacked16ToG32(color);
42*e1eccf28SAndroid Build Coastguard Worker     result.z = (float)SkPacked16ToB32(color);
43*e1eccf28SAndroid Build Coastguard Worker     return result;
44*e1eccf28SAndroid Build Coastguard Worker }
45*e1eccf28SAndroid Build Coastguard Worker 
46*e1eccf28SAndroid Build Coastguard Worker /**
47*e1eccf28SAndroid Build Coastguard Worker * Allocation sampling
48*e1eccf28SAndroid Build Coastguard Worker */
49*e1eccf28SAndroid Build Coastguard Worker static inline float __attribute__((overloadable))
getElementAt1(const uint8_t * p,int32_t x)50*e1eccf28SAndroid Build Coastguard Worker         getElementAt1(const uint8_t *p, int32_t x) {
51*e1eccf28SAndroid Build Coastguard Worker     float r = p[x];
52*e1eccf28SAndroid Build Coastguard Worker     return r;
53*e1eccf28SAndroid Build Coastguard Worker }
54*e1eccf28SAndroid Build Coastguard Worker 
55*e1eccf28SAndroid Build Coastguard Worker static inline float2 __attribute__((overloadable))
getElementAt2(const uint8_t * p,int32_t x)56*e1eccf28SAndroid Build Coastguard Worker         getElementAt2(const uint8_t *p, int32_t x) {
57*e1eccf28SAndroid Build Coastguard Worker     x *= 2;
58*e1eccf28SAndroid Build Coastguard Worker     float2 r = {p[x], p[x+1]};
59*e1eccf28SAndroid Build Coastguard Worker     return r;
60*e1eccf28SAndroid Build Coastguard Worker }
61*e1eccf28SAndroid Build Coastguard Worker 
62*e1eccf28SAndroid Build Coastguard Worker static inline float3 __attribute__((overloadable))
getElementAt3(const uint8_t * p,int32_t x)63*e1eccf28SAndroid Build Coastguard Worker         getElementAt3(const uint8_t *p, int32_t x) {
64*e1eccf28SAndroid Build Coastguard Worker     x *= 4;
65*e1eccf28SAndroid Build Coastguard Worker     float3 r = {p[x], p[x+1], p[x+2]};
66*e1eccf28SAndroid Build Coastguard Worker     return r;
67*e1eccf28SAndroid Build Coastguard Worker }
68*e1eccf28SAndroid Build Coastguard Worker 
69*e1eccf28SAndroid Build Coastguard Worker static inline float4 __attribute__((overloadable))
getElementAt4(const uint8_t * p,int32_t x)70*e1eccf28SAndroid Build Coastguard Worker         getElementAt4(const uint8_t *p, int32_t x) {
71*e1eccf28SAndroid Build Coastguard Worker     x *= 4;
72*e1eccf28SAndroid Build Coastguard Worker     const uchar4 *p2 = (const uchar4 *)&p[x];
73*e1eccf28SAndroid Build Coastguard Worker     return convert_float4(p2[0]);
74*e1eccf28SAndroid Build Coastguard Worker }
75*e1eccf28SAndroid Build Coastguard Worker 
76*e1eccf28SAndroid Build Coastguard Worker static inline float3 __attribute__((overloadable))
getElementAt565(const uint8_t * p,int32_t x)77*e1eccf28SAndroid Build Coastguard Worker         getElementAt565(const uint8_t *p, int32_t x) {
78*e1eccf28SAndroid Build Coastguard Worker     x *= 2;
79*e1eccf28SAndroid Build Coastguard Worker     float3 r = getFrom565(((const uint16_t *)p)[0]);
80*e1eccf28SAndroid Build Coastguard Worker     return r;
81*e1eccf28SAndroid Build Coastguard Worker }
82*e1eccf28SAndroid Build Coastguard Worker 
83*e1eccf28SAndroid Build Coastguard Worker static inline float __attribute__((overloadable))
getElementAt1(const uint8_t * p,size_t stride,int32_t x,int32_t y)84*e1eccf28SAndroid Build Coastguard Worker         getElementAt1(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
85*e1eccf28SAndroid Build Coastguard Worker     p += y * stride;
86*e1eccf28SAndroid Build Coastguard Worker     float r = p[x];
87*e1eccf28SAndroid Build Coastguard Worker     return r;
88*e1eccf28SAndroid Build Coastguard Worker }
89*e1eccf28SAndroid Build Coastguard Worker 
90*e1eccf28SAndroid Build Coastguard Worker static inline float2 __attribute__((overloadable))
getElementAt2(const uint8_t * p,size_t stride,int32_t x,int32_t y)91*e1eccf28SAndroid Build Coastguard Worker         getElementAt2(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
92*e1eccf28SAndroid Build Coastguard Worker     p += y * stride;
93*e1eccf28SAndroid Build Coastguard Worker     x *= 2;
94*e1eccf28SAndroid Build Coastguard Worker     float2 r = {p[x], p[x+1]};
95*e1eccf28SAndroid Build Coastguard Worker     return r;
96*e1eccf28SAndroid Build Coastguard Worker }
97*e1eccf28SAndroid Build Coastguard Worker 
98*e1eccf28SAndroid Build Coastguard Worker static inline float3 __attribute__((overloadable))
getElementAt3(const uint8_t * p,size_t stride,int32_t x,int32_t y)99*e1eccf28SAndroid Build Coastguard Worker         getElementAt3(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
100*e1eccf28SAndroid Build Coastguard Worker     p += y * stride;
101*e1eccf28SAndroid Build Coastguard Worker     x *= 4;
102*e1eccf28SAndroid Build Coastguard Worker     float3 r = {p[x], p[x+1], p[x+2]};
103*e1eccf28SAndroid Build Coastguard Worker     return r;
104*e1eccf28SAndroid Build Coastguard Worker }
105*e1eccf28SAndroid Build Coastguard Worker 
106*e1eccf28SAndroid Build Coastguard Worker static inline float4 __attribute__((overloadable))
getElementAt4(const uint8_t * p,size_t stride,int32_t x,int32_t y)107*e1eccf28SAndroid Build Coastguard Worker         getElementAt4(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
108*e1eccf28SAndroid Build Coastguard Worker     p += y * stride;
109*e1eccf28SAndroid Build Coastguard Worker     x *= 4;
110*e1eccf28SAndroid Build Coastguard Worker     float4 r = {p[x], p[x+1], p[x+2], p[x+3]};
111*e1eccf28SAndroid Build Coastguard Worker     return r;
112*e1eccf28SAndroid Build Coastguard Worker }
113*e1eccf28SAndroid Build Coastguard Worker 
114*e1eccf28SAndroid Build Coastguard Worker static inline float3 __attribute__((overloadable))
getElementAt565(const uint8_t * p,size_t stride,int32_t x,int32_t y)115*e1eccf28SAndroid Build Coastguard Worker         getElementAt565(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
116*e1eccf28SAndroid Build Coastguard Worker     p += y * stride;
117*e1eccf28SAndroid Build Coastguard Worker     x *= 2;
118*e1eccf28SAndroid Build Coastguard Worker     float3 r = getFrom565(((const uint16_t *)p)[0]);
119*e1eccf28SAndroid Build Coastguard Worker     return r;
120*e1eccf28SAndroid Build Coastguard Worker }
121*e1eccf28SAndroid Build Coastguard Worker 
122*e1eccf28SAndroid Build Coastguard Worker 
123*e1eccf28SAndroid Build Coastguard Worker 
124*e1eccf28SAndroid Build Coastguard Worker 
125*e1eccf28SAndroid Build Coastguard Worker 
126*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_A(const uint8_t * p,int32_t iPixel,int32_t next,float w0,float w1)127*e1eccf28SAndroid Build Coastguard Worker             getSample_A(const uint8_t *p, int32_t iPixel,
128*e1eccf28SAndroid Build Coastguard Worker                           int32_t next, float w0, float w1) {
129*e1eccf28SAndroid Build Coastguard Worker     float p0 = getElementAt1(p, iPixel);
130*e1eccf28SAndroid Build Coastguard Worker     float p1 = getElementAt1(p, next);
131*e1eccf28SAndroid Build Coastguard Worker     float r = p0 * w0 + p1 * w1;
132*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
133*e1eccf28SAndroid Build Coastguard Worker     float4 ret = {0.f, 0.f, 0.f, r};
134*e1eccf28SAndroid Build Coastguard Worker     return ret;
135*e1eccf28SAndroid Build Coastguard Worker }
136*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_L(const uint8_t * p,int32_t iPixel,int32_t next,float w0,float w1)137*e1eccf28SAndroid Build Coastguard Worker             getSample_L(const uint8_t *p, int32_t iPixel,
138*e1eccf28SAndroid Build Coastguard Worker                           int32_t next, float w0, float w1) {
139*e1eccf28SAndroid Build Coastguard Worker     float p0 = getElementAt1(p, iPixel);
140*e1eccf28SAndroid Build Coastguard Worker     float p1 = getElementAt1(p, next);
141*e1eccf28SAndroid Build Coastguard Worker     float r = p0 * w0 + p1 * w1;
142*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
143*e1eccf28SAndroid Build Coastguard Worker     float4 ret = {r, r, r, 1.f};
144*e1eccf28SAndroid Build Coastguard Worker     return ret;
145*e1eccf28SAndroid Build Coastguard Worker }
146*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_LA(const uint8_t * p,int32_t iPixel,int32_t next,float w0,float w1)147*e1eccf28SAndroid Build Coastguard Worker             getSample_LA(const uint8_t *p, int32_t iPixel,
148*e1eccf28SAndroid Build Coastguard Worker                            int32_t next, float w0, float w1) {
149*e1eccf28SAndroid Build Coastguard Worker     float2 p0 = getElementAt2(p, iPixel);
150*e1eccf28SAndroid Build Coastguard Worker     float2 p1 = getElementAt2(p, next);
151*e1eccf28SAndroid Build Coastguard Worker     float2 r = p0 * w0 + p1 * w1;
152*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
153*e1eccf28SAndroid Build Coastguard Worker     float4 ret = {r.x, r.x, r.x, r.y};
154*e1eccf28SAndroid Build Coastguard Worker     return ret;
155*e1eccf28SAndroid Build Coastguard Worker }
156*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_RGB(const uint8_t * p,int32_t iPixel,int32_t next,float w0,float w1)157*e1eccf28SAndroid Build Coastguard Worker             getSample_RGB(const uint8_t *p, int32_t iPixel,
158*e1eccf28SAndroid Build Coastguard Worker                             int32_t next, float w0, float w1) {
159*e1eccf28SAndroid Build Coastguard Worker     float3 p0 = getElementAt3(p, iPixel);
160*e1eccf28SAndroid Build Coastguard Worker     float3 p1 = getElementAt3(p, next);
161*e1eccf28SAndroid Build Coastguard Worker     float3 r = p0 * w0 + p1 * w1;
162*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
163*e1eccf28SAndroid Build Coastguard Worker     float4 ret = {r.x, r.x, r.z, 1.f};
164*e1eccf28SAndroid Build Coastguard Worker     return ret;
165*e1eccf28SAndroid Build Coastguard Worker }
166*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_565(const uint8_t * p,int32_t iPixel,int32_t next,float w0,float w1)167*e1eccf28SAndroid Build Coastguard Worker             getSample_565(const uint8_t *p, int32_t iPixel,
168*e1eccf28SAndroid Build Coastguard Worker                            int32_t next, float w0, float w1) {
169*e1eccf28SAndroid Build Coastguard Worker     float3 p0 = getElementAt565(p, iPixel);
170*e1eccf28SAndroid Build Coastguard Worker     float3 p1 = getElementAt565(p, next);
171*e1eccf28SAndroid Build Coastguard Worker     float3 r = p0 * w0 + p1 * w1;
172*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
173*e1eccf28SAndroid Build Coastguard Worker     float4 ret = {r.x, r.x, r.z, 1.f};
174*e1eccf28SAndroid Build Coastguard Worker     return ret;
175*e1eccf28SAndroid Build Coastguard Worker }
176*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_RGBA(const uint8_t * p,int32_t iPixel,int32_t next,float w0,float w1)177*e1eccf28SAndroid Build Coastguard Worker             getSample_RGBA(const uint8_t *p, int32_t iPixel,
178*e1eccf28SAndroid Build Coastguard Worker                              int32_t next, float w0, float w1) {
179*e1eccf28SAndroid Build Coastguard Worker     float4 p0 = getElementAt4(p, iPixel);
180*e1eccf28SAndroid Build Coastguard Worker     float4 p1 = getElementAt4(p, next);
181*e1eccf28SAndroid Build Coastguard Worker     float4 r = p0 * w0 + p1 * w1;
182*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
183*e1eccf28SAndroid Build Coastguard Worker     return r;
184*e1eccf28SAndroid Build Coastguard Worker }
185*e1eccf28SAndroid Build Coastguard Worker 
186*e1eccf28SAndroid Build Coastguard Worker 
187*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_A(const uint8_t * p,size_t stride,int locX,int locY,int nextX,int nextY,float w0,float w1,float w2,float w3)188*e1eccf28SAndroid Build Coastguard Worker             getSample_A(const uint8_t *p, size_t stride,
189*e1eccf28SAndroid Build Coastguard Worker                           int locX, int locY, int nextX, int nextY,
190*e1eccf28SAndroid Build Coastguard Worker                           float w0, float w1, float w2, float w3) {
191*e1eccf28SAndroid Build Coastguard Worker     float p0 = getElementAt1(p, stride, locX, locY);
192*e1eccf28SAndroid Build Coastguard Worker     float p1 = getElementAt1(p, stride, nextX, locY);
193*e1eccf28SAndroid Build Coastguard Worker     float p2 = getElementAt1(p, stride, locX, nextY);
194*e1eccf28SAndroid Build Coastguard Worker     float p3 = getElementAt1(p, stride, nextX, nextY);
195*e1eccf28SAndroid Build Coastguard Worker     float r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
196*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
197*e1eccf28SAndroid Build Coastguard Worker     float4 ret = {0.f, 0.f, 0.f, r};
198*e1eccf28SAndroid Build Coastguard Worker     return ret;
199*e1eccf28SAndroid Build Coastguard Worker }
200*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_L(const uint8_t * p,size_t stride,int locX,int locY,int nextX,int nextY,float w0,float w1,float w2,float w3)201*e1eccf28SAndroid Build Coastguard Worker             getSample_L(const uint8_t *p, size_t stride,
202*e1eccf28SAndroid Build Coastguard Worker                          int locX, int locY, int nextX, int nextY,
203*e1eccf28SAndroid Build Coastguard Worker                          float w0, float w1, float w2, float w3) {
204*e1eccf28SAndroid Build Coastguard Worker     float p0 = getElementAt1(p, stride, locX, locY);
205*e1eccf28SAndroid Build Coastguard Worker     float p1 = getElementAt1(p, stride, nextX, locY);
206*e1eccf28SAndroid Build Coastguard Worker     float p2 = getElementAt1(p, stride, locX, nextY);
207*e1eccf28SAndroid Build Coastguard Worker     float p3 = getElementAt1(p, stride, nextX, nextY);
208*e1eccf28SAndroid Build Coastguard Worker     float r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
209*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
210*e1eccf28SAndroid Build Coastguard Worker     float4 ret = {r, r, r, 1.f};
211*e1eccf28SAndroid Build Coastguard Worker     return ret;
212*e1eccf28SAndroid Build Coastguard Worker }
213*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_LA(const uint8_t * p,size_t stride,int locX,int locY,int nextX,int nextY,float w0,float w1,float w2,float w3)214*e1eccf28SAndroid Build Coastguard Worker             getSample_LA(const uint8_t *p, size_t stride,
215*e1eccf28SAndroid Build Coastguard Worker                          int locX, int locY, int nextX, int nextY,
216*e1eccf28SAndroid Build Coastguard Worker                          float w0, float w1, float w2, float w3) {
217*e1eccf28SAndroid Build Coastguard Worker     float2 p0 = getElementAt2(p, stride, locX, locY);
218*e1eccf28SAndroid Build Coastguard Worker     float2 p1 = getElementAt2(p, stride, nextX, locY);
219*e1eccf28SAndroid Build Coastguard Worker     float2 p2 = getElementAt2(p, stride, locX, nextY);
220*e1eccf28SAndroid Build Coastguard Worker     float2 p3 = getElementAt2(p, stride, nextX, nextY);
221*e1eccf28SAndroid Build Coastguard Worker     float2 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
222*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
223*e1eccf28SAndroid Build Coastguard Worker     float4 ret = {r.x, r.x, r.x, r.y};
224*e1eccf28SAndroid Build Coastguard Worker     return ret;
225*e1eccf28SAndroid Build Coastguard Worker }
226*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_RGB(const uint8_t * p,size_t stride,int locX,int locY,int nextX,int nextY,float w0,float w1,float w2,float w3)227*e1eccf28SAndroid Build Coastguard Worker             getSample_RGB(const uint8_t *p, size_t stride,
228*e1eccf28SAndroid Build Coastguard Worker                          int locX, int locY, int nextX, int nextY,
229*e1eccf28SAndroid Build Coastguard Worker                          float w0, float w1, float w2, float w3) {
230*e1eccf28SAndroid Build Coastguard Worker     float4 p0 = getElementAt4(p, stride, locX, locY);
231*e1eccf28SAndroid Build Coastguard Worker     float4 p1 = getElementAt4(p, stride, nextX, locY);
232*e1eccf28SAndroid Build Coastguard Worker     float4 p2 = getElementAt4(p, stride, locX, nextY);
233*e1eccf28SAndroid Build Coastguard Worker     float4 p3 = getElementAt4(p, stride, nextX, nextY);
234*e1eccf28SAndroid Build Coastguard Worker     float4 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
235*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
236*e1eccf28SAndroid Build Coastguard Worker     float4 ret = {r.x, r.y, r.z, 1.f};
237*e1eccf28SAndroid Build Coastguard Worker     return ret;
238*e1eccf28SAndroid Build Coastguard Worker }
239*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_RGBA(const uint8_t * p,size_t stride,int locX,int locY,int nextX,int nextY,float w0,float w1,float w2,float w3)240*e1eccf28SAndroid Build Coastguard Worker             getSample_RGBA(const uint8_t *p, size_t stride,
241*e1eccf28SAndroid Build Coastguard Worker                          int locX, int locY, int nextX, int nextY,
242*e1eccf28SAndroid Build Coastguard Worker                          float w0, float w1, float w2, float w3) {
243*e1eccf28SAndroid Build Coastguard Worker     float4 p0 = getElementAt4(p, stride, locX, locY);
244*e1eccf28SAndroid Build Coastguard Worker     float4 p1 = getElementAt4(p, stride, nextX, locY);
245*e1eccf28SAndroid Build Coastguard Worker     float4 p2 = getElementAt4(p, stride, locX, nextY);
246*e1eccf28SAndroid Build Coastguard Worker     float4 p3 = getElementAt4(p, stride, nextX, nextY);
247*e1eccf28SAndroid Build Coastguard Worker     float4 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
248*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
249*e1eccf28SAndroid Build Coastguard Worker     return r;
250*e1eccf28SAndroid Build Coastguard Worker }
251*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getSample_565(const uint8_t * p,size_t stride,int locX,int locY,int nextX,int nextY,float w0,float w1,float w2,float w3)252*e1eccf28SAndroid Build Coastguard Worker             getSample_565(const uint8_t *p, size_t stride,
253*e1eccf28SAndroid Build Coastguard Worker                          int locX, int locY, int nextX, int nextY,
254*e1eccf28SAndroid Build Coastguard Worker                          float w0, float w1, float w2, float w3) {
255*e1eccf28SAndroid Build Coastguard Worker     float3 p0 = getElementAt565(p, stride, locX, locY);
256*e1eccf28SAndroid Build Coastguard Worker     float3 p1 = getElementAt565(p, stride, nextX, locY);
257*e1eccf28SAndroid Build Coastguard Worker     float3 p2 = getElementAt565(p, stride, locX, nextY);
258*e1eccf28SAndroid Build Coastguard Worker     float3 p3 = getElementAt565(p, stride, nextX, nextY);
259*e1eccf28SAndroid Build Coastguard Worker     float3 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
260*e1eccf28SAndroid Build Coastguard Worker     r *= (1.f / 255.f);
261*e1eccf28SAndroid Build Coastguard Worker     float4 ret;
262*e1eccf28SAndroid Build Coastguard Worker     ret.rgb = r;
263*e1eccf28SAndroid Build Coastguard Worker     ret.w = 1.f;
264*e1eccf28SAndroid Build Coastguard Worker     return ret;
265*e1eccf28SAndroid Build Coastguard Worker }
266*e1eccf28SAndroid Build Coastguard Worker 
267*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getBilinearSample1D(const Allocation_t * alloc,float2 weights,uint32_t iPixel,uint32_t next,rs_data_kind dk,rs_data_type dt,uint32_t lod)268*e1eccf28SAndroid Build Coastguard Worker         getBilinearSample1D(const Allocation_t *alloc, float2 weights,
269*e1eccf28SAndroid Build Coastguard Worker                           uint32_t iPixel, uint32_t next,
270*e1eccf28SAndroid Build Coastguard Worker                           rs_data_kind dk, rs_data_type dt, uint32_t lod) {
271*e1eccf28SAndroid Build Coastguard Worker 
272*e1eccf28SAndroid Build Coastguard Worker      const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
273*e1eccf28SAndroid Build Coastguard Worker 
274*e1eccf28SAndroid Build Coastguard Worker      switch(dk) {
275*e1eccf28SAndroid Build Coastguard Worker      case RS_KIND_PIXEL_RGBA:
276*e1eccf28SAndroid Build Coastguard Worker          return getSample_RGBA(p, iPixel, next, weights.x, weights.y);
277*e1eccf28SAndroid Build Coastguard Worker      case RS_KIND_PIXEL_A:
278*e1eccf28SAndroid Build Coastguard Worker          return getSample_A(p, iPixel, next, weights.x, weights.y);
279*e1eccf28SAndroid Build Coastguard Worker      case RS_KIND_PIXEL_RGB:
280*e1eccf28SAndroid Build Coastguard Worker          if (dt == RS_TYPE_UNSIGNED_5_6_5) {
281*e1eccf28SAndroid Build Coastguard Worker              return getSample_565(p, iPixel, next, weights.x, weights.y);
282*e1eccf28SAndroid Build Coastguard Worker          }
283*e1eccf28SAndroid Build Coastguard Worker          return getSample_RGB(p, iPixel, next, weights.x, weights.y);
284*e1eccf28SAndroid Build Coastguard Worker      case RS_KIND_PIXEL_L:
285*e1eccf28SAndroid Build Coastguard Worker          return getSample_L(p, iPixel, next, weights.x, weights.y);
286*e1eccf28SAndroid Build Coastguard Worker      case RS_KIND_PIXEL_LA:
287*e1eccf28SAndroid Build Coastguard Worker          return getSample_LA(p, iPixel, next, weights.x, weights.y);
288*e1eccf28SAndroid Build Coastguard Worker 
289*e1eccf28SAndroid Build Coastguard Worker      default:
290*e1eccf28SAndroid Build Coastguard Worker          //__builtin_unreachable();
291*e1eccf28SAndroid Build Coastguard Worker          break;
292*e1eccf28SAndroid Build Coastguard Worker      }
293*e1eccf28SAndroid Build Coastguard Worker 
294*e1eccf28SAndroid Build Coastguard Worker      //__builtin_unreachable();
295*e1eccf28SAndroid Build Coastguard Worker      return 0.f;
296*e1eccf28SAndroid Build Coastguard Worker }
297*e1eccf28SAndroid Build Coastguard Worker 
wrapI(rs_sampler_value wrap,int32_t coord,int32_t size)298*e1eccf28SAndroid Build Coastguard Worker static uint32_t wrapI(rs_sampler_value wrap, int32_t coord, int32_t size) {
299*e1eccf28SAndroid Build Coastguard Worker     if (wrap == RS_SAMPLER_WRAP) {
300*e1eccf28SAndroid Build Coastguard Worker         coord = coord % size;
301*e1eccf28SAndroid Build Coastguard Worker         if (coord < 0) {
302*e1eccf28SAndroid Build Coastguard Worker             coord += size;
303*e1eccf28SAndroid Build Coastguard Worker         }
304*e1eccf28SAndroid Build Coastguard Worker     }
305*e1eccf28SAndroid Build Coastguard Worker     if (wrap == RS_SAMPLER_MIRRORED_REPEAT) {
306*e1eccf28SAndroid Build Coastguard Worker         coord = coord % (size * 2);
307*e1eccf28SAndroid Build Coastguard Worker         if (coord < 0) {
308*e1eccf28SAndroid Build Coastguard Worker             coord = (size * 2) + coord;
309*e1eccf28SAndroid Build Coastguard Worker         }
310*e1eccf28SAndroid Build Coastguard Worker         if (coord >= size) {
311*e1eccf28SAndroid Build Coastguard Worker             coord = (size * 2 - 1) - coord;
312*e1eccf28SAndroid Build Coastguard Worker         }
313*e1eccf28SAndroid Build Coastguard Worker     }
314*e1eccf28SAndroid Build Coastguard Worker     return (uint32_t)max(0, min(coord, size - 1));
315*e1eccf28SAndroid Build Coastguard Worker }
316*e1eccf28SAndroid Build Coastguard Worker 
317*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
getBilinearSample2D(const Allocation_t * alloc,float w0,float w1,float w2,float w3,int lx,int ly,int nx,int ny,rs_data_kind dk,rs_data_type dt,uint32_t lod)318*e1eccf28SAndroid Build Coastguard Worker         getBilinearSample2D(const Allocation_t *alloc, float w0, float w1, float w2, float w3,
319*e1eccf28SAndroid Build Coastguard Worker                           int lx, int ly, int nx, int ny,
320*e1eccf28SAndroid Build Coastguard Worker                           rs_data_kind dk, rs_data_type dt, uint32_t lod) {
321*e1eccf28SAndroid Build Coastguard Worker 
322*e1eccf28SAndroid Build Coastguard Worker     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
323*e1eccf28SAndroid Build Coastguard Worker     size_t stride = alloc->mHal.drvState.lod[lod].stride;
324*e1eccf28SAndroid Build Coastguard Worker 
325*e1eccf28SAndroid Build Coastguard Worker     switch(dk) {
326*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_RGBA:
327*e1eccf28SAndroid Build Coastguard Worker         return getSample_RGBA(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
328*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_A:
329*e1eccf28SAndroid Build Coastguard Worker         return getSample_A(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
330*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_LA:
331*e1eccf28SAndroid Build Coastguard Worker         return getSample_LA(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
332*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_RGB:
333*e1eccf28SAndroid Build Coastguard Worker         if (dt == RS_TYPE_UNSIGNED_5_6_5) {
334*e1eccf28SAndroid Build Coastguard Worker             return getSample_565(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
335*e1eccf28SAndroid Build Coastguard Worker         }
336*e1eccf28SAndroid Build Coastguard Worker         return getSample_RGB(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
337*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_L:
338*e1eccf28SAndroid Build Coastguard Worker         return getSample_L(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
339*e1eccf28SAndroid Build Coastguard Worker 
340*e1eccf28SAndroid Build Coastguard Worker     default:
341*e1eccf28SAndroid Build Coastguard Worker         break;
342*e1eccf28SAndroid Build Coastguard Worker     }
343*e1eccf28SAndroid Build Coastguard Worker 
344*e1eccf28SAndroid Build Coastguard Worker     return 0.f;
345*e1eccf28SAndroid Build Coastguard Worker }
346*e1eccf28SAndroid Build Coastguard Worker 
347*e1eccf28SAndroid Build Coastguard Worker static float4  __attribute__((overloadable))
getNearestSample(const Allocation_t * alloc,uint32_t iPixel,rs_data_kind dk,rs_data_type dt,uint32_t lod)348*e1eccf28SAndroid Build Coastguard Worker         getNearestSample(const Allocation_t *alloc, uint32_t iPixel, rs_data_kind dk,
349*e1eccf28SAndroid Build Coastguard Worker                          rs_data_type dt, uint32_t lod) {
350*e1eccf28SAndroid Build Coastguard Worker 
351*e1eccf28SAndroid Build Coastguard Worker     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
352*e1eccf28SAndroid Build Coastguard Worker 
353*e1eccf28SAndroid Build Coastguard Worker     float4 result = {0.f, 0.f, 0.f, 255.f};
354*e1eccf28SAndroid Build Coastguard Worker 
355*e1eccf28SAndroid Build Coastguard Worker     switch(dk) {
356*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_RGBA:
357*e1eccf28SAndroid Build Coastguard Worker         result = getElementAt4(p, iPixel);
358*e1eccf28SAndroid Build Coastguard Worker         break;
359*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_A:
360*e1eccf28SAndroid Build Coastguard Worker         result.w = getElementAt1(p, iPixel);
361*e1eccf28SAndroid Build Coastguard Worker         break;
362*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_LA:
363*e1eccf28SAndroid Build Coastguard Worker         result.zw = getElementAt2(p, iPixel);
364*e1eccf28SAndroid Build Coastguard Worker         result.xy = result.z;
365*e1eccf28SAndroid Build Coastguard Worker         break;
366*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_RGB:
367*e1eccf28SAndroid Build Coastguard Worker         if (dt == RS_TYPE_UNSIGNED_5_6_5) {
368*e1eccf28SAndroid Build Coastguard Worker             result.xyz = getElementAt565(p, iPixel);
369*e1eccf28SAndroid Build Coastguard Worker         } else {
370*e1eccf28SAndroid Build Coastguard Worker             result.xyz = getElementAt3(p, iPixel);
371*e1eccf28SAndroid Build Coastguard Worker         }
372*e1eccf28SAndroid Build Coastguard Worker         break;
373*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_L:
374*e1eccf28SAndroid Build Coastguard Worker         result.xyz = getElementAt1(p, iPixel);
375*e1eccf28SAndroid Build Coastguard Worker 
376*e1eccf28SAndroid Build Coastguard Worker     default:
377*e1eccf28SAndroid Build Coastguard Worker         //__builtin_unreachable();
378*e1eccf28SAndroid Build Coastguard Worker         break;
379*e1eccf28SAndroid Build Coastguard Worker     }
380*e1eccf28SAndroid Build Coastguard Worker 
381*e1eccf28SAndroid Build Coastguard Worker     return result * 0.003921569f;
382*e1eccf28SAndroid Build Coastguard Worker }
383*e1eccf28SAndroid Build Coastguard Worker 
384*e1eccf28SAndroid Build Coastguard Worker static float4  __attribute__((overloadable))
getNearestSample(const Allocation_t * alloc,uint2 iPixel,rs_data_kind dk,rs_data_type dt,uint32_t lod)385*e1eccf28SAndroid Build Coastguard Worker         getNearestSample(const Allocation_t *alloc, uint2 iPixel, rs_data_kind dk,
386*e1eccf28SAndroid Build Coastguard Worker                          rs_data_type dt, uint32_t lod) {
387*e1eccf28SAndroid Build Coastguard Worker 
388*e1eccf28SAndroid Build Coastguard Worker     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
389*e1eccf28SAndroid Build Coastguard Worker     size_t stride = alloc->mHal.drvState.lod[lod].stride;
390*e1eccf28SAndroid Build Coastguard Worker 
391*e1eccf28SAndroid Build Coastguard Worker     float4 result = {0.f, 0.f, 0.f, 255.f};
392*e1eccf28SAndroid Build Coastguard Worker 
393*e1eccf28SAndroid Build Coastguard Worker     switch(dk) {
394*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_RGBA:
395*e1eccf28SAndroid Build Coastguard Worker         result = getElementAt4(p, stride, iPixel.x, iPixel.y);
396*e1eccf28SAndroid Build Coastguard Worker         break;
397*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_A:
398*e1eccf28SAndroid Build Coastguard Worker         result.w = getElementAt1(p, stride, iPixel.x, iPixel.y);
399*e1eccf28SAndroid Build Coastguard Worker         break;
400*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_LA:
401*e1eccf28SAndroid Build Coastguard Worker         result.zw = getElementAt2(p, stride, iPixel.x, iPixel.y);
402*e1eccf28SAndroid Build Coastguard Worker         result.xy = result.z;
403*e1eccf28SAndroid Build Coastguard Worker         break;
404*e1eccf28SAndroid Build Coastguard Worker     case RS_KIND_PIXEL_RGB:
405*e1eccf28SAndroid Build Coastguard Worker         if (dt == RS_TYPE_UNSIGNED_5_6_5) {
406*e1eccf28SAndroid Build Coastguard Worker             result.xyz = getElementAt565(p, stride, iPixel.x, iPixel.y);
407*e1eccf28SAndroid Build Coastguard Worker         } else {
408*e1eccf28SAndroid Build Coastguard Worker             result.xyz = getElementAt3(p, stride, iPixel.x, iPixel.y);
409*e1eccf28SAndroid Build Coastguard Worker         }
410*e1eccf28SAndroid Build Coastguard Worker         break;
411*e1eccf28SAndroid Build Coastguard Worker 
412*e1eccf28SAndroid Build Coastguard Worker     default:
413*e1eccf28SAndroid Build Coastguard Worker         //__builtin_unreachable();
414*e1eccf28SAndroid Build Coastguard Worker         break;
415*e1eccf28SAndroid Build Coastguard Worker     }
416*e1eccf28SAndroid Build Coastguard Worker 
417*e1eccf28SAndroid Build Coastguard Worker     return result * 0.003921569f;
418*e1eccf28SAndroid Build Coastguard Worker }
419*e1eccf28SAndroid Build Coastguard Worker 
420*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
sample_LOD_LinearPixel(const Allocation_t * alloc,rs_data_kind dk,rs_data_type dt,rs_sampler_value wrapS,float uv,uint32_t lod)421*e1eccf28SAndroid Build Coastguard Worker         sample_LOD_LinearPixel(const Allocation_t *alloc,
422*e1eccf28SAndroid Build Coastguard Worker                                rs_data_kind dk, rs_data_type dt,
423*e1eccf28SAndroid Build Coastguard Worker                                rs_sampler_value wrapS,
424*e1eccf28SAndroid Build Coastguard Worker                                float uv, uint32_t lod) {
425*e1eccf28SAndroid Build Coastguard Worker 
426*e1eccf28SAndroid Build Coastguard Worker     int32_t sourceW = alloc->mHal.drvState.lod[lod].dimX;
427*e1eccf28SAndroid Build Coastguard Worker     float pixelUV = uv * (float)(sourceW);
428*e1eccf28SAndroid Build Coastguard Worker     int32_t iPixel = floor(pixelUV);
429*e1eccf28SAndroid Build Coastguard Worker     float frac = pixelUV - (float)iPixel;
430*e1eccf28SAndroid Build Coastguard Worker 
431*e1eccf28SAndroid Build Coastguard Worker     if (frac < 0.5f) {
432*e1eccf28SAndroid Build Coastguard Worker         iPixel -= 1;
433*e1eccf28SAndroid Build Coastguard Worker         frac += 0.5f;
434*e1eccf28SAndroid Build Coastguard Worker     } else {
435*e1eccf28SAndroid Build Coastguard Worker         frac -= 0.5f;
436*e1eccf28SAndroid Build Coastguard Worker     }
437*e1eccf28SAndroid Build Coastguard Worker 
438*e1eccf28SAndroid Build Coastguard Worker     float oneMinusFrac = 1.0f - frac;
439*e1eccf28SAndroid Build Coastguard Worker 
440*e1eccf28SAndroid Build Coastguard Worker     float2 weights;
441*e1eccf28SAndroid Build Coastguard Worker     weights.x = oneMinusFrac;
442*e1eccf28SAndroid Build Coastguard Worker     weights.y = frac;
443*e1eccf28SAndroid Build Coastguard Worker 
444*e1eccf28SAndroid Build Coastguard Worker     uint32_t next = wrapI(wrapS, iPixel + 1, sourceW);
445*e1eccf28SAndroid Build Coastguard Worker     uint32_t location = wrapI(wrapS, iPixel, sourceW);
446*e1eccf28SAndroid Build Coastguard Worker 
447*e1eccf28SAndroid Build Coastguard Worker     return getBilinearSample1D(alloc, weights, location, next, dk, dt, lod);
448*e1eccf28SAndroid Build Coastguard Worker }
449*e1eccf28SAndroid Build Coastguard Worker 
450*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
sample_LOD_NearestPixel(const Allocation_t * alloc,rs_data_kind dk,rs_data_type dt,rs_sampler_value wrapS,float uv,uint32_t lod)451*e1eccf28SAndroid Build Coastguard Worker         sample_LOD_NearestPixel(const Allocation_t *alloc,
452*e1eccf28SAndroid Build Coastguard Worker                                 rs_data_kind dk, rs_data_type dt,
453*e1eccf28SAndroid Build Coastguard Worker                                 rs_sampler_value wrapS,
454*e1eccf28SAndroid Build Coastguard Worker                                 float uv, uint32_t lod) {
455*e1eccf28SAndroid Build Coastguard Worker 
456*e1eccf28SAndroid Build Coastguard Worker     int32_t sourceW = alloc->mHal.drvState.lod[lod].dimX;
457*e1eccf28SAndroid Build Coastguard Worker     int32_t iPixel = floor(uv * (float)(sourceW));
458*e1eccf28SAndroid Build Coastguard Worker     uint32_t location = wrapI(wrapS, iPixel, sourceW);
459*e1eccf28SAndroid Build Coastguard Worker 
460*e1eccf28SAndroid Build Coastguard Worker     return getNearestSample(alloc, location, dk, dt, lod);
461*e1eccf28SAndroid Build Coastguard Worker }
462*e1eccf28SAndroid Build Coastguard Worker 
463*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
sample_LOD_LinearPixel(const Allocation_t * alloc,rs_data_kind dk,rs_data_type dt,rs_sampler_value wrapS,rs_sampler_value wrapT,float2 uv,uint32_t lod)464*e1eccf28SAndroid Build Coastguard Worker         sample_LOD_LinearPixel(const Allocation_t *alloc,
465*e1eccf28SAndroid Build Coastguard Worker                                rs_data_kind dk, rs_data_type dt,
466*e1eccf28SAndroid Build Coastguard Worker                                rs_sampler_value wrapS,
467*e1eccf28SAndroid Build Coastguard Worker                                rs_sampler_value wrapT,
468*e1eccf28SAndroid Build Coastguard Worker                                float2 uv, uint32_t lod) {
469*e1eccf28SAndroid Build Coastguard Worker 
470*e1eccf28SAndroid Build Coastguard Worker     int sourceW = alloc->mHal.drvState.lod[lod].dimX;
471*e1eccf28SAndroid Build Coastguard Worker     int sourceH = alloc->mHal.drvState.lod[lod].dimY;
472*e1eccf28SAndroid Build Coastguard Worker 
473*e1eccf28SAndroid Build Coastguard Worker     float pixelU = uv.x * sourceW;
474*e1eccf28SAndroid Build Coastguard Worker     float pixelV = uv.y * sourceH;
475*e1eccf28SAndroid Build Coastguard Worker     int iPixelU = floor(pixelU);
476*e1eccf28SAndroid Build Coastguard Worker     int iPixelV = floor(pixelV);
477*e1eccf28SAndroid Build Coastguard Worker     float fracU = pixelU - iPixelU;
478*e1eccf28SAndroid Build Coastguard Worker     float fracV = pixelV - iPixelV;
479*e1eccf28SAndroid Build Coastguard Worker 
480*e1eccf28SAndroid Build Coastguard Worker     if (fracU < 0.5f) {
481*e1eccf28SAndroid Build Coastguard Worker         iPixelU -= 1;
482*e1eccf28SAndroid Build Coastguard Worker         fracU += 0.5f;
483*e1eccf28SAndroid Build Coastguard Worker     } else {
484*e1eccf28SAndroid Build Coastguard Worker         fracU -= 0.5f;
485*e1eccf28SAndroid Build Coastguard Worker     }
486*e1eccf28SAndroid Build Coastguard Worker     if (fracV < 0.5f) {
487*e1eccf28SAndroid Build Coastguard Worker         iPixelV -= 1;
488*e1eccf28SAndroid Build Coastguard Worker         fracV += 0.5f;
489*e1eccf28SAndroid Build Coastguard Worker     } else {
490*e1eccf28SAndroid Build Coastguard Worker         fracV -= 0.5f;
491*e1eccf28SAndroid Build Coastguard Worker     }
492*e1eccf28SAndroid Build Coastguard Worker     float oneMinusFracU = 1.0f - fracU;
493*e1eccf28SAndroid Build Coastguard Worker     float oneMinusFracV = 1.0f - fracV;
494*e1eccf28SAndroid Build Coastguard Worker 
495*e1eccf28SAndroid Build Coastguard Worker     float w0 = oneMinusFracU * oneMinusFracV;
496*e1eccf28SAndroid Build Coastguard Worker     float w1 = fracU * oneMinusFracV;
497*e1eccf28SAndroid Build Coastguard Worker     float w2 = oneMinusFracU * fracV;
498*e1eccf28SAndroid Build Coastguard Worker     float w3 = fracU * fracV;
499*e1eccf28SAndroid Build Coastguard Worker 
500*e1eccf28SAndroid Build Coastguard Worker     int nx = wrapI(wrapS, iPixelU + 1, sourceW);
501*e1eccf28SAndroid Build Coastguard Worker     int ny = wrapI(wrapT, iPixelV + 1, sourceH);
502*e1eccf28SAndroid Build Coastguard Worker     int lx = wrapI(wrapS, iPixelU, sourceW);
503*e1eccf28SAndroid Build Coastguard Worker     int ly = wrapI(wrapT, iPixelV, sourceH);
504*e1eccf28SAndroid Build Coastguard Worker 
505*e1eccf28SAndroid Build Coastguard Worker     return getBilinearSample2D(alloc, w0, w1, w2, w3, lx, ly, nx, ny, dk, dt, lod);
506*e1eccf28SAndroid Build Coastguard Worker 
507*e1eccf28SAndroid Build Coastguard Worker }
508*e1eccf28SAndroid Build Coastguard Worker 
509*e1eccf28SAndroid Build Coastguard Worker static float4 __attribute__((overloadable))
sample_LOD_NearestPixel(const Allocation_t * alloc,rs_data_kind dk,rs_data_type dt,rs_sampler_value wrapS,rs_sampler_value wrapT,float2 uv,uint32_t lod)510*e1eccf28SAndroid Build Coastguard Worker         sample_LOD_NearestPixel(const Allocation_t *alloc,
511*e1eccf28SAndroid Build Coastguard Worker                                 rs_data_kind dk, rs_data_type dt,
512*e1eccf28SAndroid Build Coastguard Worker                                 rs_sampler_value wrapS,
513*e1eccf28SAndroid Build Coastguard Worker                                 rs_sampler_value wrapT,
514*e1eccf28SAndroid Build Coastguard Worker                                 float2 uv, uint32_t lod) {
515*e1eccf28SAndroid Build Coastguard Worker     int sourceW = alloc->mHal.drvState.lod[lod].dimX;
516*e1eccf28SAndroid Build Coastguard Worker     int sourceH = alloc->mHal.drvState.lod[lod].dimY;
517*e1eccf28SAndroid Build Coastguard Worker 
518*e1eccf28SAndroid Build Coastguard Worker     float2 dimF;
519*e1eccf28SAndroid Build Coastguard Worker     dimF.x = (float)(sourceW);
520*e1eccf28SAndroid Build Coastguard Worker     dimF.y = (float)(sourceH);
521*e1eccf28SAndroid Build Coastguard Worker     int2 iPixel = convert_int2(floor(uv * dimF));
522*e1eccf28SAndroid Build Coastguard Worker 
523*e1eccf28SAndroid Build Coastguard Worker     uint2 location;
524*e1eccf28SAndroid Build Coastguard Worker     location.x = wrapI(wrapS, iPixel.x, sourceW);
525*e1eccf28SAndroid Build Coastguard Worker     location.y = wrapI(wrapT, iPixel.y, sourceH);
526*e1eccf28SAndroid Build Coastguard Worker     return getNearestSample(alloc, location, dk, dt, lod);
527*e1eccf28SAndroid Build Coastguard Worker }
528*e1eccf28SAndroid Build Coastguard Worker 
529*e1eccf28SAndroid Build Coastguard Worker extern float4 __attribute__((overloadable))
rsSample(rs_allocation a,rs_sampler s,float uv,float lod)530*e1eccf28SAndroid Build Coastguard Worker         rsSample(rs_allocation a, rs_sampler s, float uv, float lod) {
531*e1eccf28SAndroid Build Coastguard Worker 
532*e1eccf28SAndroid Build Coastguard Worker     const Allocation_t *alloc = (const Allocation_t *)a.p;
533*e1eccf28SAndroid Build Coastguard Worker     const Sampler_t *prog = (Sampler_t *)s.p;
534*e1eccf28SAndroid Build Coastguard Worker     const Type_t *type = (Type_t *)alloc->mHal.state.type;
535*e1eccf28SAndroid Build Coastguard Worker     const Element_t *elem = type->mHal.state.element;
536*e1eccf28SAndroid Build Coastguard Worker     rs_data_kind dk = elem->mHal.state.dataKind;
537*e1eccf28SAndroid Build Coastguard Worker     rs_data_type dt = elem->mHal.state.dataType;
538*e1eccf28SAndroid Build Coastguard Worker     rs_sampler_value sampleMin = prog->mHal.state.minFilter;
539*e1eccf28SAndroid Build Coastguard Worker     rs_sampler_value sampleMag = prog->mHal.state.magFilter;
540*e1eccf28SAndroid Build Coastguard Worker     rs_sampler_value wrapS = prog->mHal.state.wrapS;
541*e1eccf28SAndroid Build Coastguard Worker 
542*e1eccf28SAndroid Build Coastguard Worker     if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
543*e1eccf28SAndroid Build Coastguard Worker         return 0.f;
544*e1eccf28SAndroid Build Coastguard Worker     }
545*e1eccf28SAndroid Build Coastguard Worker 
546*e1eccf28SAndroid Build Coastguard Worker     if (lod <= 0.0f) {
547*e1eccf28SAndroid Build Coastguard Worker         if (sampleMag == RS_SAMPLER_NEAREST) {
548*e1eccf28SAndroid Build Coastguard Worker             return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, uv, 0);
549*e1eccf28SAndroid Build Coastguard Worker         }
550*e1eccf28SAndroid Build Coastguard Worker         return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, 0);
551*e1eccf28SAndroid Build Coastguard Worker     }
552*e1eccf28SAndroid Build Coastguard Worker 
553*e1eccf28SAndroid Build Coastguard Worker     if (sampleMin == RS_SAMPLER_LINEAR_MIP_NEAREST) {
554*e1eccf28SAndroid Build Coastguard Worker         uint32_t maxLOD = type->mHal.state.lodCount - 1;
555*e1eccf28SAndroid Build Coastguard Worker         lod = min(lod, (float)maxLOD);
556*e1eccf28SAndroid Build Coastguard Worker         uint32_t nearestLOD = (uint32_t)round(lod);
557*e1eccf28SAndroid Build Coastguard Worker         return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, nearestLOD);
558*e1eccf28SAndroid Build Coastguard Worker     }
559*e1eccf28SAndroid Build Coastguard Worker 
560*e1eccf28SAndroid Build Coastguard Worker     if (sampleMin == RS_SAMPLER_LINEAR_MIP_LINEAR) {
561*e1eccf28SAndroid Build Coastguard Worker         uint32_t lod0 = (uint32_t)floor(lod);
562*e1eccf28SAndroid Build Coastguard Worker         uint32_t lod1 = (uint32_t)ceil(lod);
563*e1eccf28SAndroid Build Coastguard Worker         uint32_t maxLOD = type->mHal.state.lodCount - 1;
564*e1eccf28SAndroid Build Coastguard Worker         lod0 = min(lod0, maxLOD);
565*e1eccf28SAndroid Build Coastguard Worker         lod1 = min(lod1, maxLOD);
566*e1eccf28SAndroid Build Coastguard Worker         float4 sample0 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, lod0);
567*e1eccf28SAndroid Build Coastguard Worker         float4 sample1 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, lod1);
568*e1eccf28SAndroid Build Coastguard Worker         float frac = lod - (float)lod0;
569*e1eccf28SAndroid Build Coastguard Worker         return sample0 * (1.0f - frac) + sample1 * frac;
570*e1eccf28SAndroid Build Coastguard Worker     }
571*e1eccf28SAndroid Build Coastguard Worker 
572*e1eccf28SAndroid Build Coastguard Worker     return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, uv, 0);
573*e1eccf28SAndroid Build Coastguard Worker }
574*e1eccf28SAndroid Build Coastguard Worker 
575*e1eccf28SAndroid Build Coastguard Worker extern float4 __attribute__((overloadable))
rsSample(rs_allocation a,rs_sampler s,float location)576*e1eccf28SAndroid Build Coastguard Worker         rsSample(rs_allocation a, rs_sampler s, float location) {
577*e1eccf28SAndroid Build Coastguard Worker     return rsSample(a, s, location, 0);
578*e1eccf28SAndroid Build Coastguard Worker }
579*e1eccf28SAndroid Build Coastguard Worker 
580*e1eccf28SAndroid Build Coastguard Worker 
581*e1eccf28SAndroid Build Coastguard Worker extern float4 __attribute__((overloadable))
rsSample(rs_allocation a,rs_sampler s,float2 uv,float lod)582*e1eccf28SAndroid Build Coastguard Worker         rsSample(rs_allocation a, rs_sampler s, float2 uv, float lod) {
583*e1eccf28SAndroid Build Coastguard Worker 
584*e1eccf28SAndroid Build Coastguard Worker     const Allocation_t *alloc = (const Allocation_t *)a.p;
585*e1eccf28SAndroid Build Coastguard Worker     const Sampler_t *prog = (Sampler_t *)s.p;
586*e1eccf28SAndroid Build Coastguard Worker     const Type_t *type = (Type_t *)alloc->mHal.state.type;
587*e1eccf28SAndroid Build Coastguard Worker     const Element_t *elem = type->mHal.state.element;
588*e1eccf28SAndroid Build Coastguard Worker     rs_data_kind dk = elem->mHal.state.dataKind;
589*e1eccf28SAndroid Build Coastguard Worker     rs_data_type dt = elem->mHal.state.dataType;
590*e1eccf28SAndroid Build Coastguard Worker     rs_sampler_value sampleMin = prog->mHal.state.minFilter;
591*e1eccf28SAndroid Build Coastguard Worker     rs_sampler_value sampleMag = prog->mHal.state.magFilter;
592*e1eccf28SAndroid Build Coastguard Worker     rs_sampler_value wrapS = prog->mHal.state.wrapS;
593*e1eccf28SAndroid Build Coastguard Worker     rs_sampler_value wrapT = prog->mHal.state.wrapT;
594*e1eccf28SAndroid Build Coastguard Worker 
595*e1eccf28SAndroid Build Coastguard Worker     if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
596*e1eccf28SAndroid Build Coastguard Worker         return 0.f;
597*e1eccf28SAndroid Build Coastguard Worker     }
598*e1eccf28SAndroid Build Coastguard Worker 
599*e1eccf28SAndroid Build Coastguard Worker     if (lod <= 0.0f) {
600*e1eccf28SAndroid Build Coastguard Worker         if (sampleMag == RS_SAMPLER_NEAREST) {
601*e1eccf28SAndroid Build Coastguard Worker             return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
602*e1eccf28SAndroid Build Coastguard Worker         }
603*e1eccf28SAndroid Build Coastguard Worker         return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
604*e1eccf28SAndroid Build Coastguard Worker     }
605*e1eccf28SAndroid Build Coastguard Worker 
606*e1eccf28SAndroid Build Coastguard Worker     if (sampleMin == RS_SAMPLER_LINEAR_MIP_NEAREST) {
607*e1eccf28SAndroid Build Coastguard Worker         uint32_t maxLOD = type->mHal.state.lodCount - 1;
608*e1eccf28SAndroid Build Coastguard Worker         lod = min(lod, (float)maxLOD);
609*e1eccf28SAndroid Build Coastguard Worker         uint32_t nearestLOD = (uint32_t)round(lod);
610*e1eccf28SAndroid Build Coastguard Worker         return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, nearestLOD);
611*e1eccf28SAndroid Build Coastguard Worker     }
612*e1eccf28SAndroid Build Coastguard Worker 
613*e1eccf28SAndroid Build Coastguard Worker     if (sampleMin == RS_SAMPLER_LINEAR_MIP_LINEAR) {
614*e1eccf28SAndroid Build Coastguard Worker         uint32_t lod0 = (uint32_t)floor(lod);
615*e1eccf28SAndroid Build Coastguard Worker         uint32_t lod1 = (uint32_t)ceil(lod);
616*e1eccf28SAndroid Build Coastguard Worker         uint32_t maxLOD = type->mHal.state.lodCount - 1;
617*e1eccf28SAndroid Build Coastguard Worker         lod0 = min(lod0, maxLOD);
618*e1eccf28SAndroid Build Coastguard Worker         lod1 = min(lod1, maxLOD);
619*e1eccf28SAndroid Build Coastguard Worker         float4 sample0 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, lod0);
620*e1eccf28SAndroid Build Coastguard Worker         float4 sample1 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, lod1);
621*e1eccf28SAndroid Build Coastguard Worker         float frac = lod - (float)lod0;
622*e1eccf28SAndroid Build Coastguard Worker         return sample0 * (1.0f - frac) + sample1 * frac;
623*e1eccf28SAndroid Build Coastguard Worker     }
624*e1eccf28SAndroid Build Coastguard Worker 
625*e1eccf28SAndroid Build Coastguard Worker     return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
626*e1eccf28SAndroid Build Coastguard Worker }
627*e1eccf28SAndroid Build Coastguard Worker 
628*e1eccf28SAndroid Build Coastguard Worker extern float4 __attribute__((overloadable))
rsSample(rs_allocation a,rs_sampler s,float2 uv)629*e1eccf28SAndroid Build Coastguard Worker         rsSample(rs_allocation a, rs_sampler s, float2 uv) {
630*e1eccf28SAndroid Build Coastguard Worker 
631*e1eccf28SAndroid Build Coastguard Worker     const Allocation_t *alloc = (const Allocation_t *)a.p;
632*e1eccf28SAndroid Build Coastguard Worker     const Sampler_t *prog = (Sampler_t *)s.p;
633*e1eccf28SAndroid Build Coastguard Worker     const Type_t *type = (Type_t *)alloc->mHal.state.type;
634*e1eccf28SAndroid Build Coastguard Worker     const Element_t *elem = type->mHal.state.element;
635*e1eccf28SAndroid Build Coastguard Worker     rs_data_kind dk = elem->mHal.state.dataKind;
636*e1eccf28SAndroid Build Coastguard Worker     rs_data_type dt = elem->mHal.state.dataType;
637*e1eccf28SAndroid Build Coastguard Worker     rs_sampler_value wrapS = prog->mHal.state.wrapS;
638*e1eccf28SAndroid Build Coastguard Worker     rs_sampler_value wrapT = prog->mHal.state.wrapT;
639*e1eccf28SAndroid Build Coastguard Worker 
640*e1eccf28SAndroid Build Coastguard Worker     if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
641*e1eccf28SAndroid Build Coastguard Worker         return 0.f;
642*e1eccf28SAndroid Build Coastguard Worker     }
643*e1eccf28SAndroid Build Coastguard Worker 
644*e1eccf28SAndroid Build Coastguard Worker     if (prog->mHal.state.magFilter == RS_SAMPLER_NEAREST) {
645*e1eccf28SAndroid Build Coastguard Worker         return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
646*e1eccf28SAndroid Build Coastguard Worker     }
647*e1eccf28SAndroid Build Coastguard Worker     return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
648*e1eccf28SAndroid Build Coastguard Worker }
649