blob: a7923de763a3d1221b0266e096a0051f09676662 [file] [log] [blame]
Alex Sakhartchouk7f126c72011-05-05 16:56:27 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18#include "rsdCore.h"
19#include "rsdSampler.h"
20
21#include "rsContext.h"
22#include "rsSampler.h"
Jason Sams93eacc72012-12-18 14:26:57 -080023
24#ifndef RS_COMPATIBILITY_LIB
Alex Sakhartchouk7f126c72011-05-05 16:56:27 -070025#include "rsProgramVertex.h"
26#include "rsProgramFragment.h"
27
28#include <GLES/gl.h>
29#include <GLES/glext.h>
Jason Sams93eacc72012-12-18 14:26:57 -080030#endif
Alex Sakhartchouk7f126c72011-05-05 16:56:27 -070031
Jason Samsfe3697b2013-03-27 14:31:19 -070032using namespace android;
33using namespace android::renderscript;
34
35#if 0
36
Jason Sams06b0f7d2013-03-22 13:43:01 -070037typedef float float2 __attribute__((ext_vector_type(2)));
38typedef float float3 __attribute__((ext_vector_type(3)));
39typedef float float4 __attribute__((ext_vector_type(4)));
40typedef uint8_t uchar4 __attribute__((ext_vector_type(4)));
41
Alex Sakhartchouk7f126c72011-05-05 16:56:27 -070042
Jason Sams06b0f7d2013-03-22 13:43:01 -070043#if defined(ARCH_ARM_HAVE_VFP)
44 #define LOCAL_CALL __attribute__((pcs("aapcs-vfp")))
45#else
46 #define LOCAL_CALL
47#endif
48
Jason Samsfe3697b2013-03-27 14:31:19 -070049extern "C" {
50 typedef float4 Sampler2DFn(const uint8_t *p, size_t stride,
51 int lx, int ly, int nx, int ny,
52 float w0, float w1, float w2, float w3) LOCAL_CALL;
53
54 Sampler2DFn rsdCpuGetSample2D_L_k;
55 Sampler2DFn rsdCpuGetSample2D_A_k;
56 Sampler2DFn rsdCpuGetSample2D_LA_k;
57 Sampler2DFn rsdCpuGetSample2D_RGB_k;
58 Sampler2DFn rsdCpuGetSample2D_RGBA_k;
59}
60
Jason Sams06b0f7d2013-03-22 13:43:01 -070061// 565 Conversion bits taken from SkBitmap
62#define SK_R16_BITS 5
63#define SK_G16_BITS 6
64#define SK_B16_BITS 5
65
66#define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS)
67#define SK_G16_SHIFT (SK_B16_BITS)
68#define SK_B16_SHIFT 0
69
70#define SK_R16_MASK ((1 << SK_R16_BITS) - 1)
71#define SK_G16_MASK ((1 << SK_G16_BITS) - 1)
72#define SK_B16_MASK ((1 << SK_B16_BITS) - 1)
73
74static inline unsigned SkR16ToR32(unsigned r) {
75 return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
76}
77
78static inline unsigned SkG16ToG32(unsigned g) {
79 return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
80}
81
82static inline unsigned SkB16ToB32(unsigned b) {
83 return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
84}
85
86#define SkPacked16ToR32(c) SkR16ToR32(SkGetPackedR16(c))
87#define SkPacked16ToG32(c) SkG16ToG32(SkGetPackedG16(c))
88#define SkPacked16ToB32(c) SkB16ToB32(SkGetPackedB16(c))
89
90#define SkGetPackedR16(color) (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
91#define SkGetPackedG16(color) (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
92#define SkGetPackedB16(color) (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
93
94static float3 getFrom565(uint16_t color) {
95 float3 result;
96 result.x = (float)SkPacked16ToR32(color);
97 result.y = (float)SkPacked16ToG32(color);
98 result.z = (float)SkPacked16ToB32(color);
99 return result;
100}
101
102
103
104/**
105* Allocation sampling
106*/
107static inline float getElementAt1(const uint8_t *p, int32_t x) {
108 float r = p[x];
109 return r;
110}
111
112static inline float2 getElementAt2(const uint8_t *p, int32_t x) {
113 x *= 2;
114 float2 r = {p[x], p[x+1]};
115 return r;
116}
117
118static inline float3 getElementAt3(const uint8_t *p, int32_t x) {
119 x *= 4;
120 float3 r = {p[x], p[x+1], p[x+2]};
121 return r;
122}
123
124static inline float4 getElementAt4(const uint8_t *p, int32_t x) {
125 x *= 4;
126 float4 r = {p[x], p[x+1], p[x+2], p[x+3]};
127 return r;
128}
129
130static inline float3 getElementAt565(const uint8_t *p, int32_t x) {
131 x *= 2;
132 float3 r = getFrom565(((const uint16_t *)p)[0]);
133 return r;
134}
135
136static inline float getElementAt1(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
137 p += y * stride;
138 float r = p[x];
139 return r;
140}
141
142static inline float2 getElementAt2(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
143 p += y * stride;
144 x *= 2;
145 float2 r = {p[x], p[x+1]};
146 return r;
147}
148
149static inline float3 getElementAt3(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
150 p += y * stride;
151 x *= 4;
152 float3 r = {p[x], p[x+1], p[x+2]};
153 return r;
154}
155
156static inline float4 getElementAt4(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
157 p += y * stride;
158 x *= 4;
159 float4 r = {p[x], p[x+1], p[x+2], p[x+3]};
160 return r;
161}
162
163static inline float3 getElementAt565(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
164 p += y * stride;
165 x *= 2;
166 float3 r = getFrom565(((const uint16_t *)p)[0]);
167 return r;
168}
169
170
171
172
173
174static float4 LOCAL_CALL
175 getSample1D_A(const uint8_t *p, int32_t iPixel,
176 int32_t next, float w0, float w1) {
177 float p0 = getElementAt1(p, iPixel);
178 float p1 = getElementAt1(p, next);
179 float r = p0 * w0 + p1 * w1;
180 r *= (1.f / 255.f);
181 float4 ret = {0.f, 0.f, 0.f, r};
182 return ret;
183}
184static float4 LOCAL_CALL
185 getSample1D_L(const uint8_t *p, int32_t iPixel,
186 int32_t next, float w0, float w1) {
187 float p0 = getElementAt1(p, iPixel);
188 float p1 = getElementAt1(p, next);
189 float r = p0 * w0 + p1 * w1;
190 r *= (1.f / 255.f);
191 float4 ret = {r, r, r, 1.f};
192 return ret;
193}
194static float4 LOCAL_CALL
195 getSample1D_LA(const uint8_t *p, int32_t iPixel,
196 int32_t next, float w0, float w1) {
197 float2 p0 = getElementAt2(p, iPixel);
198 float2 p1 = getElementAt2(p, next);
199 float2 r = p0 * w0 + p1 * w1;
200 r *= (1.f / 255.f);
201 float4 ret = {r.x, r.x, r.x, r.y};
202 return ret;
203}
204static float4 LOCAL_CALL
205 getSample1D_RGB(const uint8_t *p, int32_t iPixel,
206 int32_t next, float w0, float w1) {
207 float3 p0 = getElementAt3(p, iPixel);
208 float3 p1 = getElementAt3(p, next);
209 float3 r = p0 * w0 + p1 * w1;
210 r *= (1.f / 255.f);
211 float4 ret = {r.x, r.x, r.z, 1.f};
212 return ret;
213}
214static float4 LOCAL_CALL
215 getSample1D_565(const uint8_t *p, int32_t iPixel,
216 int32_t next, float w0, float w1) {
217 float3 p0 = getElementAt565(p, iPixel);
218 float3 p1 = getElementAt565(p, next);
219 float3 r = p0 * w0 + p1 * w1;
220 r *= (1.f / 255.f);
221 float4 ret = {r.x, r.x, r.z, 1.f};
222 return ret;
223}
224static float4 LOCAL_CALL
225 getSample1D_RGBA(const uint8_t *p, int32_t iPixel,
226 int32_t next, float w0, float w1) {
227 float4 p0 = getElementAt4(p, iPixel);
228 float4 p1 = getElementAt4(p, next);
229 float4 r = p0 * w0 + p1 * w1;
230 r *= (1.f / 255.f);
231 return r;
232}
233
234
Jason Samsfe3697b2013-03-27 14:31:19 -0700235#if 1
Jason Sams06b0f7d2013-03-22 13:43:01 -0700236static float4 LOCAL_CALL
237 getSample2D_A(const uint8_t *p, size_t stride,
238 int locX, int locY, int nextX, int nextY,
239 float w0, float w1, float w2, float w3) {
240 float p0 = getElementAt1(p, stride, locX, locY);
241 float p1 = getElementAt1(p, stride, nextX, locY);
242 float p2 = getElementAt1(p, stride, locX, nextY);
243 float p3 = getElementAt1(p, stride, nextX, nextY);
244 float r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
245 r *= (1.f / 255.f);
246 float4 ret = {0.f, 0.f, 0.f, r};
247 return ret;
248}
249static float4 LOCAL_CALL
250 getSample2D_L(const uint8_t *p, size_t stride,
251 int locX, int locY, int nextX, int nextY,
252 float w0, float w1, float w2, float w3) {
253 float p0 = getElementAt1(p, stride, locX, locY);
254 float p1 = getElementAt1(p, stride, nextX, locY);
255 float p2 = getElementAt1(p, stride, locX, nextY);
256 float p3 = getElementAt1(p, stride, nextX, nextY);
257 float r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
258 r *= (1.f / 255.f);
259 float4 ret = {r, r, r, 1.f};
260 return ret;
261}
262static float4 LOCAL_CALL
263 getSample2D_LA(const uint8_t *p, size_t stride,
264 int locX, int locY, int nextX, int nextY,
265 float w0, float w1, float w2, float w3) {
266 float2 p0 = getElementAt2(p, stride, locX, locY);
267 float2 p1 = getElementAt2(p, stride, nextX, locY);
268 float2 p2 = getElementAt2(p, stride, locX, nextY);
269 float2 p3 = getElementAt2(p, stride, nextX, nextY);
270 float2 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
271 r *= (1.f / 255.f);
272 float4 ret = {r.x, r.x, r.x, r.y};
273 return ret;
274}
275static float4 LOCAL_CALL
276 getSample2D_RGB(const uint8_t *p, size_t stride,
277 int locX, int locY, int nextX, int nextY,
278 float w0, float w1, float w2, float w3) {
279 float4 p0 = getElementAt4(p, stride, locX, locY);
280 float4 p1 = getElementAt4(p, stride, nextX, locY);
281 float4 p2 = getElementAt4(p, stride, locX, nextY);
282 float4 p3 = getElementAt4(p, stride, nextX, nextY);
283 float4 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
284 r *= (1.f / 255.f);
285 float4 ret = {r.x, r.y, r.z, 1.f};
286 return ret;
287}
288static float4 LOCAL_CALL
289 getSample2D_RGBA(const uint8_t *p, size_t stride,
290 int locX, int locY, int nextX, int nextY,
291 float w0, float w1, float w2, float w3) {
292 float4 p0 = getElementAt4(p, stride, locX, locY);
293 float4 p1 = getElementAt4(p, stride, nextX, locY);
294 float4 p2 = getElementAt4(p, stride, locX, nextY);
295 float4 p3 = getElementAt4(p, stride, nextX, nextY);
296 float4 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
297 r *= (1.f / 255.f);
298 return r;
299}
Jason Samsfe3697b2013-03-27 14:31:19 -0700300#endif
Jason Sams06b0f7d2013-03-22 13:43:01 -0700301static float4 getSample2D_565(const uint8_t *p, size_t stride,
302 int locX, int locY, int nextX, int nextY,
303 float w0, float w1, float w2, float w3) {
304 float3 p0 = getElementAt565(p, stride, locX, locY);
305 float3 p1 = getElementAt565(p, stride, nextX, locY);
306 float3 p2 = getElementAt565(p, stride, locX, nextY);
307 float3 p3 = getElementAt565(p, stride, nextX, nextY);
308 float3 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
309 r *= (1.f / 255.f);
310 float4 ret = {r.x, r.y, r.z, 1.f};
311 return ret;
312}
313
314
Jason Sams06b0f7d2013-03-22 13:43:01 -0700315#if 0
316static Sampler2DFn* GetBilinearSampleTable2D[] = {
317 0, 0, 0, 0, 0, 0, 0,
318 0,//rsdCpuGetSample2D_L_k,
319 0,//rsdCpuGetSample2D_A_k,
320 0,//rsdCpuGetSample2D_LA_k,
321 0,//rsdCpuGetSample2D_RGB_k,
322 rsdCpuGetSample2D_RGBA_k
323};
324
325#else
326static Sampler2DFn* GetBilinearSampleTable2D[] = {
327 0, 0, 0, 0, 0, 0, 0,
328 &getSample2D_L,
329 &getSample2D_A,
330 &getSample2D_LA,
331 &getSample2D_RGB,
332 &getSample2D_RGBA,
333};
334#endif
335
336
337static int applyWrapMode(RsSamplerValue mode, int coord, int size) {
338 switch (mode) {
339 case RS_SAMPLER_WRAP:
340 coord = coord % size;
341 if (coord < 0) {
342 coord += size;
343 }
344 break;
345
346 case RS_SAMPLER_CLAMP:
347 coord = rsMax(0, rsMin(coord, size - 1));
348 break;
349
350 case RS_SAMPLER_MIRRORED_REPEAT:
351 coord = coord % (size * 2);
352 if (coord < 0) {
353 coord = (size * 2) + coord;
354 }
355 if (coord >= size) {
356 coord = (size * 2) - coord;
357 }
358 break;
359
360 default:
361 coord = 0;
362 rsAssert(0);
363 }
364 return coord;
365}
366
367static float4
368 sample_LOD_LinearPixel(Allocation *a, const Type *type,
369 RsDataKind dk, RsDataType dt,
370 Sampler *s,
371 float uv, int32_t lod) {
372 RsSamplerValue wrapS = s->mHal.state.wrapS;
373 int32_t sourceW = type->mHal.state.lodDimX[lod];
374 float pixelUV = uv * (float)(sourceW);
375 int32_t iPixel = (int32_t)(pixelUV);
376 float frac = pixelUV - (float)iPixel;
377
378 if (frac < 0.5f) {
379 iPixel -= 1;
380 frac += 0.5f;
381 } else {
382 frac -= 0.5f;
383 }
384
385 float oneMinusFrac = 1.0f - frac;
386
387 int32_t next = applyWrapMode(wrapS, iPixel + 1, sourceW);
388 int32_t loc = applyWrapMode(wrapS, iPixel, sourceW);
389
390 const uint8_t *ptr = (const uint8_t *)a->mHal.drvState.lod[lod].mallocPtr;
391
392 if (dt == RS_TYPE_UNSIGNED_5_6_5) {
393 return getSample1D_565(ptr, loc, next, next, frac);
394 }
395
396 switch(dk) {
397 case RS_KIND_PIXEL_L:
398 return getSample1D_L(ptr, loc, next, next, frac);
399 case RS_KIND_PIXEL_A:
400 return getSample1D_A(ptr, loc, next, next, frac);
401 case RS_KIND_PIXEL_LA:
402 return getSample1D_LA(ptr, loc, next, next, frac);
403 case RS_KIND_PIXEL_RGB:
404 return getSample1D_RGB(ptr, loc, next, next, frac);
405 case RS_KIND_PIXEL_RGBA:
406 return getSample1D_RGBA(ptr, loc, next, next, frac);
407
408 case RS_KIND_PIXEL_YUV:
409 case RS_KIND_USER:
410 case RS_KIND_INVALID:
411 case RS_KIND_PIXEL_DEPTH:
412 rsAssert(0);
413 break;
414 }
415
416 return 0.f;
417}
418
419static float4
420 sample_LOD_NearestPixel(Allocation *a, const Type *type,
421 RsDataKind dk, RsDataType dt,
422 Sampler *s, float uv, int32_t lod) {
423 RsSamplerValue wrapS = s->mHal.state.wrapS;
424 int32_t sourceW = type->mHal.state.lodDimX[lod];
425 int32_t iPixel = (int32_t)(uv * (float)(sourceW));
426 int32_t location = applyWrapMode(wrapS, iPixel, sourceW);
427
428
429 const uint8_t *ptr = (const uint8_t *)a->mHal.drvState.lod[lod].mallocPtr;
430
431 float4 result = {0.f, 0.f, 0.f, 1.f};
432 if (dt == RS_TYPE_UNSIGNED_5_6_5) {
433 result.xyz = getElementAt565(ptr, iPixel);
434 return result;
435 }
436
437 switch(dk) {
438 case RS_KIND_PIXEL_L:
439 {
440 float t = getElementAt1(ptr, iPixel);
441 result.xyz = t;
442 }
443 break;
444 case RS_KIND_PIXEL_A:
445 result.w = getElementAt1(ptr, iPixel);
446 break;
447 case RS_KIND_PIXEL_LA:
448 {
449 float2 t = getElementAt2(ptr, iPixel);
450 result.xyz = t.x;
451 result.w = t.y;
452 }
453 break;
454 case RS_KIND_PIXEL_RGB:
455 result.xyz = getElementAt3(ptr, iPixel);
456 break;
457 case RS_KIND_PIXEL_RGBA:
458 result = getElementAt4(ptr, iPixel);
459 break;
460
461 case RS_KIND_PIXEL_YUV:
462 case RS_KIND_USER:
463 case RS_KIND_INVALID:
464 case RS_KIND_PIXEL_DEPTH:
465 rsAssert(0);
466 break;
467 }
468
469 return result * (1.f / 255.f);
470}
471
472
473static float4
474 sample_LOD_LinearPixel(Allocation *a, const Type *type,
475 RsDataKind dk, RsDataType dt,
476 Sampler *s, float u, float v, int32_t lod) {
477 const RsSamplerValue wrapS = s->mHal.state.wrapS;
478 const RsSamplerValue wrapT = s->mHal.state.wrapT;
479 const int sourceW = type->mHal.state.lodDimX[lod];
480 const int sourceH = type->mHal.state.lodDimY[lod];
481
482 float pixelU = u * (float)sourceW;
483 float pixelV = v * (float)sourceH;
484 int iPixelU = (int)pixelU;
485 int iPixelV = (int)pixelV;
486
487 float fracU = pixelU - iPixelU;
488 float fracV = pixelV - iPixelV;
489
490 if (fracU < 0.5f) {
491 iPixelU -= 1;
492 fracU += 0.5f;
493 } else {
494 fracU -= 0.5f;
495 }
496 if (fracV < 0.5f) {
497 iPixelV -= 1;
498 fracV += 0.5f;
499 } else {
500 fracV -= 0.5f;
501 }
502 float oneMinusFracU = 1.0f - fracU;
503 float oneMinusFracV = 1.0f - fracV;
504
505 float w1 = oneMinusFracU * oneMinusFracV;
506 float w2 = fracU * oneMinusFracV;
507 float w3 = oneMinusFracU * fracV;
508 float w4 = fracU * fracV;
509
510 int nextX = applyWrapMode(wrapS, iPixelU + 1, sourceW);
511 int nextY = applyWrapMode(wrapT, iPixelV + 1, sourceH);
512 int locX = applyWrapMode(wrapS, iPixelU, sourceW);
513 int locY = applyWrapMode(wrapT, iPixelV, sourceH);
514
515 const uint8_t *ptr = (const uint8_t *)a->mHal.drvState.lod[lod].mallocPtr;
516 size_t stride = a->mHal.drvState.lod[lod].stride;
517
518 if (dt == RS_TYPE_UNSIGNED_5_6_5) {
519 return getSample2D_565(ptr, stride, locX, locY, nextX, nextY, w1, w2, w3, w4);
520 }
521
522 return GetBilinearSampleTable2D[dk](ptr, stride, locX, locY, nextX, nextY, w1, w2, w3, w4);
523}
524
525static float4
Jason Samsfe3697b2013-03-27 14:31:19 -0700526 sample_LOD_LinearPixel_Clamp(Allocation *a, const Type *type,
527 RsDataKind dk, RsDataType dt,
528 Sampler *s, float u, float v, int32_t lod) {
529 const RsSamplerValue wrapS = s->mHal.state.wrapS;
530 const RsSamplerValue wrapT = s->mHal.state.wrapT;
531 const int sourceW = type->mHal.state.lodDimX[lod];
532 const int sourceH = type->mHal.state.lodDimY[lod];
533
534 float pixelU = u * (float)sourceW;
535 float pixelV = v * (float)sourceH;
536 int iPixelU = (int)pixelU;
537 int iPixelV = (int)pixelV;
538
539 float fracU = pixelU - iPixelU;
540 float fracV = pixelV - iPixelV;
541
542 if (fracU < 0.5f) {
543 iPixelU -= 1;
544 fracU += 0.5f;
545 } else {
546 fracU -= 0.5f;
547 }
548 if (fracV < 0.5f) {
549 iPixelV -= 1;
550 fracV += 0.5f;
551 } else {
552 fracV -= 0.5f;
553 }
554 float oneMinusFracU = 1.0f - fracU;
555 float oneMinusFracV = 1.0f - fracV;
556
557 float w1 = oneMinusFracU * oneMinusFracV;
558 float w2 = fracU * oneMinusFracV;
559 float w3 = oneMinusFracU * fracV;
560 float w4 = fracU * fracV;
561
562 int nextX = rsMax(0, rsMin(iPixelU + 1, sourceW - 1));
563 int nextY = rsMax(0, rsMin(iPixelV + 1, sourceH - 1));
564 int locX = rsMax(0, rsMin(iPixelU, sourceW - 1));
565 int locY = rsMax(0, rsMin(iPixelV, sourceH - 1));
566
567 const uint8_t *ptr = (const uint8_t *)a->mHal.drvState.lod[lod].mallocPtr;
568 size_t stride = a->mHal.drvState.lod[lod].stride;
569
570 return GetBilinearSampleTable2D[dk](ptr, stride, locX, locY, nextX, nextY, w1, w2, w3, w4);
571}
572
573static float4
Jason Sams06b0f7d2013-03-22 13:43:01 -0700574 sample_LOD_NearestPixel(Allocation *a, const Type *type,
575 RsDataKind dk, RsDataType dt,
576 Sampler *s,
577 float u, float v, int32_t lod) {
578 RsSamplerValue wrapS = s->mHal.state.wrapS;
579 RsSamplerValue wrapT = s->mHal.state.wrapT;
580
581 int32_t sourceW = type->mHal.state.lodDimX[lod];
582 int32_t sourceH = type->mHal.state.lodDimY[lod];
583
584 int locX = applyWrapMode(wrapS, u * sourceW, sourceW);
585 int locY = applyWrapMode(wrapT, v * sourceH, sourceH);
586
587
588 const uint8_t *ptr = (const uint8_t *)a->mHal.drvState.lod[lod].mallocPtr;
589 size_t stride = a->mHal.drvState.lod[lod].stride;
590
591 float4 result = {0.f, 0.f, 0.f, 1.f};
592 if (dt == RS_TYPE_UNSIGNED_5_6_5) {
593 result.xyz = getElementAt565(ptr, stride, locX, locY);
594 return result;
595 }
596
597 switch(dk) {
598 case RS_KIND_PIXEL_L:
599 {
600 float t = getElementAt1(ptr, stride, locX, locY);
601 result.xyz = t;
602 }
603 break;
604 case RS_KIND_PIXEL_A:
605 result.w = getElementAt1(ptr, stride, locX, locY);
606 break;
607 case RS_KIND_PIXEL_LA:
608 {
609 float2 t = getElementAt2(ptr, stride, locX, locY);
610 result.xyz = t.x;
611 result.w = t.y;
612 }
613 break;
614 case RS_KIND_PIXEL_RGB:
615 result.xyz = getElementAt3(ptr, stride, locX, locY);
616 break;
617 case RS_KIND_PIXEL_RGBA:
618 result = getElementAt4(ptr, stride, locX, locY);
619 break;
620
621
622 case RS_KIND_PIXEL_YUV:
623 case RS_KIND_USER:
624 case RS_KIND_INVALID:
625 case RS_KIND_PIXEL_DEPTH:
626 rsAssert(0);
627 break;
628 }
629
630 return result * (1.f / 255.f);
631}
632
633
634
635static float4 GenericSample1D(Allocation *a, Sampler *s, float u, float lod) {
636 const Type *type = a->getType();
637 const Element *elem = type->getElement();
638 const RsDataKind dk = elem->getKind();
639 const RsDataType dt = elem->getType();
640
641 if (dk == RS_KIND_USER || (dt != RS_TYPE_UNSIGNED_8 && dt != RS_TYPE_UNSIGNED_5_6_5)) {
642 return 0.f;
643 }
644
645 if (!(a->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
646 const Context *rsc = RsdCpuReference::getTlsContext();
647 rsc->setError(RS_ERROR_BAD_VALUE, "Sampling from texture witout USAGE_GRAPHICS_TEXTURE.");
648 return 0.f;
649 }
650
651 if (lod <= 0.0f) {
652 if (s->mHal.state.magFilter == RS_SAMPLER_NEAREST) {
653 return sample_LOD_NearestPixel(a, type, dk, dt, s, u, 0);
654 }
655 return sample_LOD_LinearPixel(a, type, dk, dt, s, u, 0);
656 }
657
658 if (s->mHal.state.minFilter == RS_SAMPLER_LINEAR_MIP_NEAREST) {
659 int32_t maxLOD = type->mHal.state.lodCount - 1;
660 lod = rsMin(lod, (float)maxLOD);
661 int32_t nearestLOD = (int32_t)round(lod);
662 return sample_LOD_LinearPixel(a, type, dk, dt, s, u, nearestLOD);
663 }
664
665 if (s->mHal.state.minFilter == RS_SAMPLER_LINEAR_MIP_LINEAR) {
666 int32_t lod0 = (int32_t)floor(lod);
667 int32_t lod1 = (int32_t)ceil(lod);
668 int32_t maxLOD = type->mHal.state.lodCount - 1;
669 lod0 = rsMin(lod0, maxLOD);
670 lod1 = rsMin(lod1, maxLOD);
671 float4 sample0 = sample_LOD_LinearPixel(a, type, dk, dt, s, u, lod0);
672 float4 sample1 = sample_LOD_LinearPixel(a, type, dk, dt, s, u, lod1);
673 float frac = lod - (float)lod0;
674 return sample0 * (1.0f - frac) + sample1 * frac;
675 }
676
677 return sample_LOD_NearestPixel(a, type, dk, dt, s, u, 0);
678}
679
680static float4 GenericSample2D(Allocation *a, Sampler *s, float u, float v, float lod) {
681 const Type *type = a->getType();
682 const Element *elem = type->getElement();
683 const RsDataKind dk = elem->getKind();
684 const RsDataType dt = elem->getType();
685
686 if (dk == RS_KIND_USER || (dt != RS_TYPE_UNSIGNED_8 && dt != RS_TYPE_UNSIGNED_5_6_5)) {
687 return 0.f;
688 }
689
690 if (!(a->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
691 const Context *rsc = RsdCpuReference::getTlsContext();
692 rsc->setError(RS_ERROR_BAD_VALUE, "Sampling from texture witout USAGE_GRAPHICS_TEXTURE.");
693 return 0.f;
694 }
695
696 if (lod <= 0.0f) {
697 if (s->mHal.state.magFilter == RS_SAMPLER_NEAREST) {
698 return sample_LOD_NearestPixel(a, type, dk, dt, s, u, v, 0);
699 }
700 return sample_LOD_LinearPixel(a, type, dk, dt, s, u, v, 0);
701 }
702
703 if (s->mHal.state.minFilter == RS_SAMPLER_LINEAR_MIP_NEAREST) {
704 int32_t maxLOD = type->mHal.state.lodCount - 1;
705 lod = rsMin(lod, (float)maxLOD);
706 int32_t nearestLOD = (int32_t)round(lod);
707 return sample_LOD_LinearPixel(a, type, dk, dt, s, u, v, nearestLOD);
708 }
709
710 if (s->mHal.state.minFilter == RS_SAMPLER_LINEAR_MIP_LINEAR) {
711 int32_t lod0 = (int32_t)floor(lod);
712 int32_t lod1 = (int32_t)ceil(lod);
713 int32_t maxLOD = type->mHal.state.lodCount - 1;
714 lod0 = rsMin(lod0, maxLOD);
715 lod1 = rsMin(lod1, maxLOD);
716 float4 sample0 = sample_LOD_LinearPixel(a, type, dk, dt, s, u, v, lod0);
717 float4 sample1 = sample_LOD_LinearPixel(a, type, dk, dt, s, u, v, lod1);
718 float frac = lod - (float)lod0;
719 return sample0 * (1.0f - frac) + sample1 * frac;
720 }
721
722 return sample_LOD_NearestPixel(a, type, dk, dt, s, u, v, 0);
723}
724
725
Jason Samsfe3697b2013-03-27 14:31:19 -0700726static float4 GenericSample2D_Clamp(Allocation *a, Sampler *s, float u, float v, float lod) {
727 const Type *type = a->getType();
728 const Element *elem = type->getElement();
729 const RsDataKind dk = elem->getKind();
730 const RsDataType dt = elem->getType();
731
732 if (!(a->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
733 const Context *rsc = RsdCpuReference::getTlsContext();
734 rsc->setError(RS_ERROR_BAD_VALUE, "Sampling from texture witout USAGE_GRAPHICS_TEXTURE.");
735 return 0.f;
736 }
737
738 if (lod <= 0.0f) {
739 if (s->mHal.state.magFilter == RS_SAMPLER_NEAREST) {
740 return sample_LOD_NearestPixel(a, type, dk, dt, s, u, v, 0);
741 }
742 return sample_LOD_LinearPixel_Clamp(a, type, dk, dt, s, u, v, 0);
743 }
744
745 if (s->mHal.state.minFilter == RS_SAMPLER_LINEAR_MIP_NEAREST) {
746 int32_t maxLOD = type->mHal.state.lodCount - 1;
747 lod = rsMin(lod, (float)maxLOD);
748 int32_t nearestLOD = (int32_t)round(lod);
749 return sample_LOD_LinearPixel_Clamp(a, type, dk, dt, s, u, v, nearestLOD);
750 }
751
752 if (s->mHal.state.minFilter == RS_SAMPLER_LINEAR_MIP_LINEAR) {
753 int32_t lod0 = (int32_t)floor(lod);
754 int32_t lod1 = (int32_t)ceil(lod);
755 int32_t maxLOD = type->mHal.state.lodCount - 1;
756 lod0 = rsMin(lod0, maxLOD);
757 lod1 = rsMin(lod1, maxLOD);
758 float4 sample0 = sample_LOD_LinearPixel_Clamp(a, type, dk, dt, s, u, v, lod0);
759 float4 sample1 = sample_LOD_LinearPixel_Clamp(a, type, dk, dt, s, u, v, lod1);
760 float frac = lod - (float)lod0;
761 return sample0 * (1.0f - frac) + sample1 * frac;
762 }
763
764 return sample_LOD_NearestPixel(a, type, dk, dt, s, u, v, 0);
765}
766
Jason Sams06b0f7d2013-03-22 13:43:01 -0700767
768
769// Must match pixel kind in rsDefines.h
770static void * NearestWrap[] = {
771 (void *) GenericSample1D, // L,
772 (void *) GenericSample1D, // A,
773 (void *) GenericSample1D, // LA,
774 (void *) GenericSample1D, // RGB,
775 (void *) GenericSample1D, // RGBA,
776 0,
777 (void *) GenericSample1D, // YUV
778
779 (void *) GenericSample2D, // L,
780 (void *) GenericSample2D, // A,
781 (void *) GenericSample2D, // LA,
782 (void *) GenericSample2D, // RGB,
783 (void *) GenericSample2D, // RGBA,
784 0,
785 (void *) GenericSample2D, // YUV
786};
787
788static void * NearestClamp[] = {
789 (void *) GenericSample1D, // L,
790 (void *) GenericSample1D, // A,
791 (void *) GenericSample1D, // LA,
792 (void *) GenericSample1D, // RGB,
793 (void *) GenericSample1D, // RGBA,
794 0,
795 (void *) GenericSample1D, // YUV
796
797 (void *) GenericSample2D, // L,
798 (void *) GenericSample2D, // A,
799 (void *) GenericSample2D, // LA,
800 (void *) GenericSample2D, // RGB,
801 (void *) GenericSample2D, // RGBA,
802 0,
803 (void *) GenericSample2D, // YUV
804};
805
806static void * NearestMirroredRepeat[] = {
807 (void *) GenericSample1D, // L,
808 (void *) GenericSample1D, // A,
809 (void *) GenericSample1D, // LA,
810 (void *) GenericSample1D, // RGB,
811 (void *) GenericSample1D, // RGBA,
812 0,
813 (void *) GenericSample1D, // YUV
814
815 (void *) GenericSample2D, // L,
816 (void *) GenericSample2D, // A,
817 (void *) GenericSample2D, // LA,
818 (void *) GenericSample2D, // RGB,
819 (void *) GenericSample2D, // RGBA,
820 0,
821 (void *) GenericSample2D, // YUV
822};
823
824// Must match pixel kind in rsDefines.h
825static void * LinearWrap[] = {
826 (void *) GenericSample1D, // L,
827 (void *) GenericSample1D, // A,
828 (void *) GenericSample1D, // LA,
829 (void *) GenericSample1D, // RGB,
830 (void *) GenericSample1D, // RGBA,
831 0,
832 (void *) GenericSample1D, // YUV
833
834 (void *) GenericSample2D, // L,
835 (void *) GenericSample2D, // A,
836 (void *) GenericSample2D, // LA,
837 (void *) GenericSample2D, // RGB,
838 (void *) GenericSample2D, // RGBA,
839 0,
840 (void *) GenericSample2D, // YUV
841};
842
843// Must match pixel kind in rsDefines.h
844static void * LinearClamp[] = {
845 (void *) GenericSample1D, // L,
846 (void *) GenericSample1D, // A,
847 (void *) GenericSample1D, // LA,
848 (void *) GenericSample1D, // RGB,
849 (void *) GenericSample1D, // RGBA,
850 0,
851 (void *) GenericSample1D, // YUV
852
Jason Samsfe3697b2013-03-27 14:31:19 -0700853 (void *) GenericSample2D_Clamp, // L,
854 (void *) GenericSample2D_Clamp, // A,
855 (void *) GenericSample2D_Clamp, // LA,
Jason Sams06b0f7d2013-03-22 13:43:01 -0700856 (void *) GenericSample2D, // RGB,
Jason Samsfe3697b2013-03-27 14:31:19 -0700857 (void *) GenericSample2D_Clamp, // RGBA,
Jason Sams06b0f7d2013-03-22 13:43:01 -0700858 0,
859 (void *) GenericSample2D, // YUV
860};
861
862// Must match pixel kind in rsDefines.h
863static void * LinearMirroredRepeat[] = {
864 (void *) GenericSample1D, // L,
865 (void *) GenericSample1D, // A,
866 (void *) GenericSample1D, // LA,
867 (void *) GenericSample1D, // RGB,
868 (void *) GenericSample1D, // RGBA,
869 0,
870 (void *) GenericSample1D, // YUV
871
872 (void *) GenericSample2D, // L,
873 (void *) GenericSample2D, // A,
874 (void *) GenericSample2D, // LA,
875 (void *) GenericSample2D, // RGB,
876 (void *) GenericSample2D, // RGBA,
877 0,
878 (void *) GenericSample2D, // YUV
879};
880
881// Must match pixel kind in rsDefines.h
882static void * Generic[] = {
883 (void *) GenericSample1D, // L,
884 (void *) GenericSample1D, // A,
885 (void *) GenericSample1D, // LA,
886 (void *) GenericSample1D, // RGB,
887 (void *) GenericSample1D, // RGBA,
888 0,
889 (void *) GenericSample1D, // YUV
890
891 (void *) GenericSample2D, // L,
892 (void *) GenericSample2D, // A,
893 (void *) GenericSample2D, // LA,
894 (void *) GenericSample2D, // RGB,
895 (void *) GenericSample2D, // RGBA,
896 0,
897 (void *) GenericSample2D, // YUV
898};
Jason Samsfe3697b2013-03-27 14:31:19 -0700899#endif
Jason Sams06b0f7d2013-03-22 13:43:01 -0700900
901bool rsdSamplerInit(const Context *, const Sampler *s) {
Jason Samsfe3697b2013-03-27 14:31:19 -0700902#if 0
Jason Sams06b0f7d2013-03-22 13:43:01 -0700903 s->mHal.drv = Generic;
904
905 if ((s->mHal.state.minFilter == s->mHal.state.magFilter) &&
906 (s->mHal.state.wrapS == s->mHal.state.wrapT)) {
907 // We have fast paths for these.
908
909 switch(s->mHal.state.minFilter) {
910 case RS_SAMPLER_NEAREST:
911 switch(s->mHal.state.wrapS) {
912 case RS_SAMPLER_WRAP:
913 s->mHal.drv = NearestWrap;
914 break;
915 case RS_SAMPLER_CLAMP:
916 s->mHal.drv = NearestClamp;
917 break;
918 case RS_SAMPLER_MIRRORED_REPEAT:
919 s->mHal.drv = NearestMirroredRepeat;
920 break;
921 default:
922 break;
923 }
924 break;
925 case RS_SAMPLER_LINEAR:
926 switch(s->mHal.state.wrapS) {
927 case RS_SAMPLER_WRAP:
928 s->mHal.drv = LinearWrap;
929 break;
930 case RS_SAMPLER_CLAMP:
931 s->mHal.drv = LinearClamp;
932 break;
933 case RS_SAMPLER_MIRRORED_REPEAT:
934 s->mHal.drv = LinearMirroredRepeat;
935 break;
936 default:
937 break;
938 }
939 break;
940 case RS_SAMPLER_LINEAR_MIP_LINEAR:
941 switch(s->mHal.state.wrapS) {
942 case RS_SAMPLER_WRAP:
943 s->mHal.drv = LinearWrap;
944 break;
945 case RS_SAMPLER_CLAMP:
946 s->mHal.drv = LinearClamp;
947 break;
948 case RS_SAMPLER_MIRRORED_REPEAT:
949 s->mHal.drv = LinearMirroredRepeat;
950 break;
951 default:
952 break;
953 }
954 break;
955 default:
956 rsAssert(0);
957 break;
958 }
959
960 }
Jason Samsfe3697b2013-03-27 14:31:19 -0700961#endif
Alex Sakhartchouk7f126c72011-05-05 16:56:27 -0700962 return true;
963}
964
965void rsdSamplerDestroy(const android::renderscript::Context *rsc,
966 const android::renderscript::Sampler *s) {
967}