15a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#include "rs_core.rsh"
25a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#include "rs_structs.h"
35a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
45a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
55a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines// 565 Conversion bits taken from SkBitmap
65a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SK_R16_BITS     5
75a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SK_G16_BITS     6
85a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SK_B16_BITS     5
95a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
105a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SK_R16_SHIFT    (SK_B16_BITS + SK_G16_BITS)
115a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SK_G16_SHIFT    (SK_B16_BITS)
125a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SK_B16_SHIFT    0
135a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
145a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SK_R16_MASK     ((1 << SK_R16_BITS) - 1)
155a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SK_G16_MASK     ((1 << SK_G16_BITS) - 1)
165a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SK_B16_MASK     ((1 << SK_B16_BITS) - 1)
175a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
185a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SkGetPackedR16(color)   (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
195a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SkGetPackedG16(color)   (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
205a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SkGetPackedB16(color)   (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
215a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
225a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline unsigned SkR16ToR32(unsigned r) {
235a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
245a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
255a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
265a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline unsigned SkG16ToG32(unsigned g) {
275a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
285a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
295a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
305a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline unsigned SkB16ToB32(unsigned b) {
315a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
325a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
335a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
345a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SkPacked16ToR32(c)      SkR16ToR32(SkGetPackedR16(c))
355a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SkPacked16ToG32(c)      SkG16ToG32(SkGetPackedG16(c))
365a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines#define SkPacked16ToB32(c)      SkB16ToB32(SkGetPackedB16(c))
375a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
385a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float3 getFrom565(uint16_t color) {
395a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 result;
405a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    result.x = (float)SkPacked16ToR32(color);
415a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    result.y = (float)SkPacked16ToG32(color);
425a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    result.z = (float)SkPacked16ToB32(color);
435a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return result;
445a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
455a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
465a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines/**
475a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines* Allocation sampling
485a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines*/
495a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline float __attribute__((overloadable))
505a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getElementAt1(const uint8_t *p, int32_t x) {
515a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float r = p[x];
525a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
535a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
545a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
555a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline float2 __attribute__((overloadable))
565a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getElementAt2(const uint8_t *p, int32_t x) {
575a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    x *= 2;
585a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 r = {p[x], p[x+1]};
595a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
605a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
615a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
625a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline float3 __attribute__((overloadable))
635a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getElementAt3(const uint8_t *p, int32_t x) {
645a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    x *= 4;
655a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 r = {p[x], p[x+1], p[x+2]};
665a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
675a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
685a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
695a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline float4 __attribute__((overloadable))
705a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getElementAt4(const uint8_t *p, int32_t x) {
715a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    x *= 4;
725a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const uchar4 *p2 = (const uchar4 *)&p[x];
735a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return convert_float4(p2[0]);
745a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
755a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
765a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline float3 __attribute__((overloadable))
775a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getElementAt565(const uint8_t *p, int32_t x) {
785a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    x *= 2;
795a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 r = getFrom565(((const uint16_t *)p)[0]);
805a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
815a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
825a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
835a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline float __attribute__((overloadable))
845a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getElementAt1(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
855a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    p += y * stride;
865a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float r = p[x];
875a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
885a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
895a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
905a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline float2 __attribute__((overloadable))
915a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getElementAt2(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
925a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    p += y * stride;
935a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    x *= 2;
945a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 r = {p[x], p[x+1]};
955a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
965a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
975a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
985a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline float3 __attribute__((overloadable))
995a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getElementAt3(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
1005a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    p += y * stride;
1015a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    x *= 4;
1025a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 r = {p[x], p[x+1], p[x+2]};
1035a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
1045a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
1055a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
1065a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline float4 __attribute__((overloadable))
1075a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getElementAt4(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
1085a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    p += y * stride;
1095a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    x *= 4;
1105a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 r = {p[x], p[x+1], p[x+2], p[x+3]};
1115a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
1125a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
1135a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
1145a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic inline float3 __attribute__((overloadable))
1155a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getElementAt565(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
1165a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    p += y * stride;
1175a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    x *= 2;
1185a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 r = getFrom565(((const uint16_t *)p)[0]);
1195a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
1205a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
1215a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
1225a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
1235a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
1245a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
1255a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
1265a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
1275a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_A(const uint8_t *p, int32_t iPixel,
1285a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                          int32_t next, float w0, float w1) {
1295a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p0 = getElementAt1(p, iPixel);
1305a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p1 = getElementAt1(p, next);
1315a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float r = p0 * w0 + p1 * w1;
1325a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
1335a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 ret = {0.f, 0.f, 0.f, r};
1345a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return ret;
1355a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
1365a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
1375a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_L(const uint8_t *p, int32_t iPixel,
1385a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                          int32_t next, float w0, float w1) {
1395a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p0 = getElementAt1(p, iPixel);
1405a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p1 = getElementAt1(p, next);
1415a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float r = p0 * w0 + p1 * w1;
1425a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
1435a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 ret = {r, r, r, 1.f};
1445a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return ret;
1455a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
1465a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
1475a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_LA(const uint8_t *p, int32_t iPixel,
1485a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                           int32_t next, float w0, float w1) {
1495a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 p0 = getElementAt2(p, iPixel);
1505a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 p1 = getElementAt2(p, next);
1515a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 r = p0 * w0 + p1 * w1;
1525a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
1535a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 ret = {r.x, r.x, r.x, r.y};
1545a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return ret;
1555a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
1565a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
1575a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_RGB(const uint8_t *p, int32_t iPixel,
1585a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                            int32_t next, float w0, float w1) {
1595a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 p0 = getElementAt3(p, iPixel);
1605a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 p1 = getElementAt3(p, next);
1615a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 r = p0 * w0 + p1 * w1;
1625a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
1635a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 ret = {r.x, r.x, r.z, 1.f};
1645a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return ret;
1655a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
1665a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
1675a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_565(const uint8_t *p, int32_t iPixel,
1685a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                           int32_t next, float w0, float w1) {
1695a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 p0 = getElementAt565(p, iPixel);
1705a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 p1 = getElementAt565(p, next);
1715a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 r = p0 * w0 + p1 * w1;
1725a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
1735a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 ret = {r.x, r.x, r.z, 1.f};
1745a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return ret;
1755a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
1765a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
1775a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_RGBA(const uint8_t *p, int32_t iPixel,
1785a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                             int32_t next, float w0, float w1) {
1795a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 p0 = getElementAt4(p, iPixel);
1805a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 p1 = getElementAt4(p, next);
1815a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 r = p0 * w0 + p1 * w1;
1825a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
1835a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
1845a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
1855a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
1865a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
1875a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
1885a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_A(const uint8_t *p, size_t stride,
1895a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                          int locX, int locY, int nextX, int nextY,
1905a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                          float w0, float w1, float w2, float w3) {
1915a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p0 = getElementAt1(p, stride, locX, locY);
1925a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p1 = getElementAt1(p, stride, nextX, locY);
1935a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p2 = getElementAt1(p, stride, locX, nextY);
1945a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p3 = getElementAt1(p, stride, nextX, nextY);
1955a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
1965a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
1975a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 ret = {0.f, 0.f, 0.f, r};
1985a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return ret;
1995a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
2005a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
2015a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_L(const uint8_t *p, size_t stride,
2025a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         int locX, int locY, int nextX, int nextY,
2035a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         float w0, float w1, float w2, float w3) {
2045a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p0 = getElementAt1(p, stride, locX, locY);
2055a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p1 = getElementAt1(p, stride, nextX, locY);
2065a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p2 = getElementAt1(p, stride, locX, nextY);
2075a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float p3 = getElementAt1(p, stride, nextX, nextY);
2085a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
2095a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
2105a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 ret = {r, r, r, 1.f};
2115a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return ret;
2125a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
2135a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
2145a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_LA(const uint8_t *p, size_t stride,
2155a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         int locX, int locY, int nextX, int nextY,
2165a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         float w0, float w1, float w2, float w3) {
2175a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 p0 = getElementAt2(p, stride, locX, locY);
2185a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 p1 = getElementAt2(p, stride, nextX, locY);
2195a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 p2 = getElementAt2(p, stride, locX, nextY);
2205a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 p3 = getElementAt2(p, stride, nextX, nextY);
2215a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
2225a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
2235a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 ret = {r.x, r.x, r.x, r.y};
2245a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return ret;
2255a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
2265a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
2275a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_RGB(const uint8_t *p, size_t stride,
2285a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         int locX, int locY, int nextX, int nextY,
2295a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         float w0, float w1, float w2, float w3) {
2305a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 p0 = getElementAt4(p, stride, locX, locY);
2315a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 p1 = getElementAt4(p, stride, nextX, locY);
2325a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 p2 = getElementAt4(p, stride, locX, nextY);
2335a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 p3 = getElementAt4(p, stride, nextX, nextY);
2345a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
2355a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
2365a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 ret = {r.x, r.y, r.z, 1.f};
2375a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return ret;
2385a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
2395a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
2405a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_RGBA(const uint8_t *p, size_t stride,
2415a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         int locX, int locY, int nextX, int nextY,
2425a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         float w0, float w1, float w2, float w3) {
2435a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 p0 = getElementAt4(p, stride, locX, locY);
2445a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 p1 = getElementAt4(p, stride, nextX, locY);
2455a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 p2 = getElementAt4(p, stride, locX, nextY);
2465a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 p3 = getElementAt4(p, stride, nextX, nextY);
2475a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
2485a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
2495a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return r;
2505a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
2515a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
2525a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            getSample_565(const uint8_t *p, size_t stride,
2535a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         int locX, int locY, int nextX, int nextY,
2545a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         float w0, float w1, float w2, float w3) {
2555a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 p0 = getElementAt565(p, stride, locX, locY);
2565a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 p1 = getElementAt565(p, stride, nextX, locY);
2575a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 p2 = getElementAt565(p, stride, locX, nextY);
2585a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 p3 = getElementAt565(p, stride, nextX, nextY);
2595a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float3 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
2605a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    r *= (1.f / 255.f);
2615a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 ret;
2625a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    ret.rgb = r;
2635a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    ret.w = 1.f;
2645a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return ret;
2655a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
2665a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
2675a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
2685a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getBilinearSample1D(const Allocation_t *alloc, float2 weights,
2695a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                          uint32_t iPixel, uint32_t next,
2705a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                          rs_data_kind dk, rs_data_type dt, uint32_t lod) {
2715a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
2725a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
2735a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
2745a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     switch(dk) {
2755a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     case RS_KIND_PIXEL_RGBA:
2765a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines         return getSample_RGBA(p, iPixel, next, weights.x, weights.y);
2775a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     case RS_KIND_PIXEL_A:
2785a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines         return getSample_A(p, iPixel, next, weights.x, weights.y);
2795a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     case RS_KIND_PIXEL_RGB:
2805a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines         if (dt == RS_TYPE_UNSIGNED_5_6_5) {
2815a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines             return getSample_565(p, iPixel, next, weights.x, weights.y);
2825a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines         }
2835a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines         return getSample_RGB(p, iPixel, next, weights.x, weights.y);
2845a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     case RS_KIND_PIXEL_L:
2855a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines         return getSample_L(p, iPixel, next, weights.x, weights.y);
2865a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     case RS_KIND_PIXEL_LA:
2875a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines         return getSample_LA(p, iPixel, next, weights.x, weights.y);
2885a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
2895a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     default:
2905a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines         //__builtin_unreachable();
2915a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines         break;
2925a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     }
2935a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
2945a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     //__builtin_unreachable();
2955a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines     return 0.f;
2965a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
2975a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
2985a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic uint32_t wrapI(rs_sampler_value wrap, int32_t coord, int32_t size) {
2995a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (wrap == RS_SAMPLER_WRAP) {
3005a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        coord = coord % size;
3015a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        if (coord < 0) {
3025a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            coord += size;
3035a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        }
3045a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
3055a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (wrap == RS_SAMPLER_MIRRORED_REPEAT) {
3065a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        coord = coord % (size * 2);
3075a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        if (coord < 0) {
3085a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            coord = (size * 2) + coord;
3095a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        }
3105a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        if (coord >= size) {
3115a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            coord = (size * 2) - coord;
3125a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        }
3135a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
3145a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return (uint32_t)max(0, min(coord, size - 1));
3155a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
3165a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3175a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
3185a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getBilinearSample2D(const Allocation_t *alloc, float w0, float w1, float w2, float w3,
3195a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                          int lx, int ly, int nx, int ny,
3205a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                          rs_data_kind dk, rs_data_type dt, uint32_t lod) {
3215a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3225a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
3235a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    size_t stride = alloc->mHal.drvState.lod[lod].stride;
3245a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3255a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    switch(dk) {
3265a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_RGBA:
3275a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return getSample_RGBA(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
3285a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_A:
3295a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return getSample_A(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
3305a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_LA:
3315a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return getSample_LA(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
3325a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_RGB:
3335a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        if (dt == RS_TYPE_UNSIGNED_5_6_5) {
3345a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            return getSample_565(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
3355a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        }
3365a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return getSample_RGB(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
3375a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_L:
3385a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return getSample_L(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
3395a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3405a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    default:
3415a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
3425a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
3435a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3445a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return 0.f;
3455a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
3465a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3475a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4  __attribute__((overloadable))
3485a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getNearestSample(const Allocation_t *alloc, uint32_t iPixel, rs_data_kind dk,
3495a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         rs_data_type dt, uint32_t lod) {
3505a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3515a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
3525a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3535a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 result = {0.f, 0.f, 0.f, 255.f};
3545a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3555a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    switch(dk) {
3565a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_RGBA:
3575a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        result = getElementAt4(p, iPixel);
3585a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
3595a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_A:
3605a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        result.w = getElementAt1(p, iPixel);
3615a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
3625a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_LA:
3635a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        result.zw = getElementAt2(p, iPixel);
3645a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        result.xy = result.z;
3655a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
3665a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_RGB:
3675a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        if (dt == RS_TYPE_UNSIGNED_5_6_5) {
3685a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            result.xyz = getElementAt565(p, iPixel);
3695a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        } else {
3705a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            result.xyz = getElementAt3(p, iPixel);
3715a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        }
3725a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
3735a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_L:
3745a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        result.xyz = getElementAt1(p, iPixel);
3755a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3765a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    default:
3775a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        //__builtin_unreachable();
3785a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
3795a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
3805a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3815a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return result * 0.003921569f;
3825a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
3835a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3845a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4  __attribute__((overloadable))
3855a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        getNearestSample(const Allocation_t *alloc, uint2 iPixel, rs_data_kind dk,
3865a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                         rs_data_type dt, uint32_t lod) {
3875a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3885a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
3895a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    size_t stride = alloc->mHal.drvState.lod[lod].stride;
3905a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3915a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float4 result = {0.f, 0.f, 0.f, 255.f};
3925a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
3935a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    switch(dk) {
3945a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_RGBA:
3955a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        result = getElementAt4(p, stride, iPixel.x, iPixel.y);
3965a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
3975a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_A:
3985a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        result.w = getElementAt1(p, stride, iPixel.x, iPixel.y);
3995a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
4005a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_LA:
4015a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        result.zw = getElementAt2(p, stride, iPixel.x, iPixel.y);
4025a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        result.xy = result.z;
4035a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
4045a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    case RS_KIND_PIXEL_RGB:
4055a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        if (dt == RS_TYPE_UNSIGNED_5_6_5) {
4065a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            result.xyz = getElementAt565(p, stride, iPixel.x, iPixel.y);
4075a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        } else {
4085a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            result.xyz = getElementAt3(p, stride, iPixel.x, iPixel.y);
4095a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        }
4105a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
4115a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4125a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    default:
4135a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        //__builtin_unreachable();
4145a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        break;
4155a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
4165a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4175a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return result * 0.003921569f;
4185a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
4195a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4205a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
4215a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        sample_LOD_LinearPixel(const Allocation_t *alloc,
4225a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                               rs_data_kind dk, rs_data_type dt,
4235a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                               rs_sampler_value wrapS,
4245a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                               float uv, uint32_t lod) {
4255a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4265a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
4275a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4285a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int32_t sourceW = alloc->mHal.drvState.lod[lod].dimX;
4295a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float pixelUV = uv * (float)(sourceW);
4305a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int32_t iPixel = (int32_t)(pixelUV);
4315a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float frac = pixelUV - (float)iPixel;
4325a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4335a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (frac < 0.5f) {
4345a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        iPixel -= 1;
4355a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        frac += 0.5f;
4365a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    } else {
4375a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        frac -= 0.5f;
4385a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
4395a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4405a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float oneMinusFrac = 1.0f - frac;
4415a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4425a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 weights;
4435a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    weights.x = oneMinusFrac;
4445a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    weights.y = frac;
4455a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4465a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    uint32_t next = wrapI(wrapS, iPixel + 1, sourceW);
4475a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    uint32_t location = wrapI(wrapS, iPixel, sourceW);
4485a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4495a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return getBilinearSample1D(alloc, weights, location, next, dk, dt, lod);
4505a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
4515a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4525a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
4535a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        sample_LOD_NearestPixel(const Allocation_t *alloc,
4545a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                                rs_data_kind dk, rs_data_type dt,
4555a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                                rs_sampler_value wrapS,
4565a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                                float uv, uint32_t lod) {
4575a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4585a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int32_t sourceW = alloc->mHal.drvState.lod[lod].dimX;
4595a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int32_t iPixel = (int32_t)(uv * (float)(sourceW));
4605a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    uint32_t location = wrapI(wrapS, iPixel, sourceW);
4615a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4625a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return getNearestSample(alloc, location, dk, dt, lod);
4635a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
4645a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4655a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
4665a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        sample_LOD_LinearPixel(const Allocation_t *alloc,
4675a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                               rs_data_kind dk, rs_data_type dt,
4685a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                               rs_sampler_value wrapS,
4695a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                               rs_sampler_value wrapT,
4705a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                               float2 uv, uint32_t lod) {
4715a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4725a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
4735a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4745a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int sourceW = alloc->mHal.drvState.lod[lod].dimX;
4755a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int sourceH = alloc->mHal.drvState.lod[lod].dimY;
4765a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4775a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float pixelU = uv.x * sourceW;
4785a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float pixelV = uv.y * sourceH;
4795a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int iPixelU = pixelU;
4805a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int iPixelV = pixelV;
4815a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float fracU = pixelU - iPixelU;
4825a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float fracV = pixelV - iPixelV;
4835a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4845a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (fracU < 0.5f) {
4855a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        iPixelU -= 1;
4865a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        fracU += 0.5f;
4875a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    } else {
4885a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        fracU -= 0.5f;
4895a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
4905a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (fracV < 0.5f) {
4915a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        iPixelV -= 1;
4925a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        fracV += 0.5f;
4935a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    } else {
4945a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        fracV -= 0.5f;
4955a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
4965a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float oneMinusFracU = 1.0f - fracU;
4975a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float oneMinusFracV = 1.0f - fracV;
4985a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
4995a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float w0 = oneMinusFracU * oneMinusFracV;
5005a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float w1 = fracU * oneMinusFracV;
5015a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float w2 = oneMinusFracU * fracV;
5025a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float w3 = fracU * fracV;
5035a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5045a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int nx = wrapI(wrapS, iPixelU + 1, sourceW);
5055a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int ny = wrapI(wrapT, iPixelV + 1, sourceH);
5065a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int lx = wrapI(wrapS, iPixelU, sourceW);
5075a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int ly = wrapI(wrapT, iPixelV, sourceH);
5085a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5095a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return getBilinearSample2D(alloc, w0, w1, w2, w3, lx, ly, nx, ny, dk, dt, lod);
5105a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5115a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
5125a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5135a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesstatic float4 __attribute__((overloadable))
5145a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        sample_LOD_NearestPixel(const Allocation_t *alloc,
5155a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                                rs_data_kind dk, rs_data_type dt,
5165a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                                rs_sampler_value wrapS,
5175a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                                rs_sampler_value wrapT,
5185a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines                                float2 uv, uint32_t lod) {
5195a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int sourceW = alloc->mHal.drvState.lod[lod].dimX;
5205a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int sourceH = alloc->mHal.drvState.lod[lod].dimY;
5215a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5225a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    float2 dimF;
5235a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    dimF.x = (float)(sourceW);
5245a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    dimF.y = (float)(sourceH);
5255a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    int2 iPixel = convert_int2(uv * dimF);
5265a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5275a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    uint2 location;
5285a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    location.x = wrapI(wrapS, iPixel.x, sourceW);
5295a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    location.y = wrapI(wrapT, iPixel.y, sourceH);
5305a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return getNearestSample(alloc, location, dk, dt, lod);
5315a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
5325a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5335a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesextern const float4 __attribute__((overloadable))
5345a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        rsSample(rs_allocation a, rs_sampler s, float uv, float lod) {
5355a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5365a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Allocation_t *alloc = (const Allocation_t *)a.p;
5375a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Sampler_t *prog = (Sampler_t *)s.p;
5385a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Type_t *type = (Type_t *)alloc->mHal.state.type;
5395a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Element_t *elem = type->mHal.state.element;
5405a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_data_kind dk = elem->mHal.state.dataKind;
5415a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_data_type dt = elem->mHal.state.dataType;
5425a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_sampler_value sampleMin = prog->mHal.state.minFilter;
5435a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_sampler_value sampleMag = prog->mHal.state.magFilter;
5445a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_sampler_value wrapS = prog->mHal.state.wrapS;
5455a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5465a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
5475a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return 0.f;
5485a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
5495a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5505a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (lod <= 0.0f) {
5515a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        if (sampleMag == RS_SAMPLER_NEAREST) {
5525a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, uv, 0);
5535a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        }
5545a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, 0);
5555a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
5565a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5575a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (sampleMin == RS_SAMPLER_LINEAR_MIP_NEAREST) {
5585a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        uint32_t maxLOD = type->mHal.state.lodCount - 1;
5595a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        lod = min(lod, (float)maxLOD);
5605a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        uint32_t nearestLOD = (uint32_t)round(lod);
5615a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, nearestLOD);
5625a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
5635a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5645a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (sampleMin == RS_SAMPLER_LINEAR_MIP_LINEAR) {
5655a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        uint32_t lod0 = (uint32_t)floor(lod);
5665a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        uint32_t lod1 = (uint32_t)ceil(lod);
5675a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        uint32_t maxLOD = type->mHal.state.lodCount - 1;
5685a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        lod0 = min(lod0, maxLOD);
5695a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        lod1 = min(lod1, maxLOD);
5705a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        float4 sample0 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, lod0);
5715a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        float4 sample1 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, lod1);
5725a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        float frac = lod - (float)lod0;
5735a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return sample0 * (1.0f - frac) + sample1 * frac;
5745a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
5755a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5765a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, uv, 0);
5775a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
5785a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5795a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesextern const float4 __attribute__((overloadable))
5805a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        rsSample(rs_allocation a, rs_sampler s, float location) {
5815a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return rsSample(a, s, location, 0);
5825a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
5835a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5845a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5855a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesextern const float4 __attribute__((overloadable))
5865a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        rsSample(rs_allocation a, rs_sampler s, float2 uv, float lod) {
5875a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5885a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Allocation_t *alloc = (const Allocation_t *)a.p;
5895a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Sampler_t *prog = (Sampler_t *)s.p;
5905a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Type_t *type = (Type_t *)alloc->mHal.state.type;
5915a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Element_t *elem = type->mHal.state.element;
5925a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_data_kind dk = elem->mHal.state.dataKind;
5935a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_data_type dt = elem->mHal.state.dataType;
5945a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_sampler_value sampleMin = prog->mHal.state.minFilter;
5955a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_sampler_value sampleMag = prog->mHal.state.magFilter;
5965a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_sampler_value wrapS = prog->mHal.state.wrapS;
5975a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_sampler_value wrapT = prog->mHal.state.wrapT;
5985a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
5995a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
6005a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return 0.f;
6015a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
6025a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
6035a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (lod <= 0.0f) {
6045a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        if (sampleMag == RS_SAMPLER_NEAREST) {
6055a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines            return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
6065a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        }
6075a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
6085a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
6095a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
6105a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (sampleMin == RS_SAMPLER_LINEAR_MIP_NEAREST) {
6115a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        uint32_t maxLOD = type->mHal.state.lodCount - 1;
6125a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        lod = min(lod, (float)maxLOD);
6135a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        uint32_t nearestLOD = (uint32_t)round(lod);
6145a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, nearestLOD);
6155a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
6165a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
6175a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (sampleMin == RS_SAMPLER_LINEAR_MIP_LINEAR) {
6185a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        uint32_t lod0 = (uint32_t)floor(lod);
6195a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        uint32_t lod1 = (uint32_t)ceil(lod);
6205a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        uint32_t maxLOD = type->mHal.state.lodCount - 1;
6215a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        lod0 = min(lod0, maxLOD);
6225a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        lod1 = min(lod1, maxLOD);
6235a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        float4 sample0 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, lod0);
6245a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        float4 sample1 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, lod1);
6255a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        float frac = lod - (float)lod0;
6265a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return sample0 * (1.0f - frac) + sample1 * frac;
6275a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
6285a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
6295a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
6305a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
6315a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
6325a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hinesextern const float4 __attribute__((overloadable))
6335a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        rsSample(rs_allocation a, rs_sampler s, float2 uv) {
6345a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
6355a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Allocation_t *alloc = (const Allocation_t *)a.p;
6365a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Sampler_t *prog = (Sampler_t *)s.p;
6375a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Type_t *type = (Type_t *)alloc->mHal.state.type;
6385a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    const Element_t *elem = type->mHal.state.element;
6395a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_data_kind dk = elem->mHal.state.dataKind;
6405a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_data_type dt = elem->mHal.state.dataType;
6415a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_sampler_value wrapS = prog->mHal.state.wrapS;
6425a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    rs_sampler_value wrapT = prog->mHal.state.wrapT;
6435a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
6445a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
6455a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return 0.f;
6465a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
6475a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
6485a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    if (prog->mHal.state.magFilter == RS_SAMPLER_NEAREST) {
6495a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines        return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
6505a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    }
6515a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines    return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
6525a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines}
6535a47020542c52af3e879c1cd67674ca979ff0a18Stephen Hines
654