123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648 |
- #include "rs_core.rsh"
- #include "rs_structs.h"
- // 565 Conversion bits taken from SkBitmap
- #define SK_R16_BITS 5
- #define SK_G16_BITS 6
- #define SK_B16_BITS 5
- #define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS)
- #define SK_G16_SHIFT (SK_B16_BITS)
- #define SK_B16_SHIFT 0
- #define SK_R16_MASK ((1 << SK_R16_BITS) - 1)
- #define SK_G16_MASK ((1 << SK_G16_BITS) - 1)
- #define SK_B16_MASK ((1 << SK_B16_BITS) - 1)
- #define SkGetPackedR16(color) (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
- #define SkGetPackedG16(color) (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
- #define SkGetPackedB16(color) (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
- static inline unsigned SkR16ToR32(unsigned r) {
- return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
- }
- static inline unsigned SkG16ToG32(unsigned g) {
- return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
- }
- static inline unsigned SkB16ToB32(unsigned b) {
- return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
- }
- #define SkPacked16ToR32(c) SkR16ToR32(SkGetPackedR16(c))
- #define SkPacked16ToG32(c) SkG16ToG32(SkGetPackedG16(c))
- #define SkPacked16ToB32(c) SkB16ToB32(SkGetPackedB16(c))
- static float3 getFrom565(uint16_t color) {
- float3 result;
- result.x = (float)SkPacked16ToR32(color);
- result.y = (float)SkPacked16ToG32(color);
- result.z = (float)SkPacked16ToB32(color);
- return result;
- }
- /**
- * Allocation sampling
- */
- static inline float __attribute__((overloadable))
- getElementAt1(const uint8_t *p, int32_t x) {
- float r = p[x];
- return r;
- }
- static inline float2 __attribute__((overloadable))
- getElementAt2(const uint8_t *p, int32_t x) {
- x *= 2;
- float2 r = {p[x], p[x+1]};
- return r;
- }
- static inline float3 __attribute__((overloadable))
- getElementAt3(const uint8_t *p, int32_t x) {
- x *= 4;
- float3 r = {p[x], p[x+1], p[x+2]};
- return r;
- }
- static inline float4 __attribute__((overloadable))
- getElementAt4(const uint8_t *p, int32_t x) {
- x *= 4;
- const uchar4 *p2 = (const uchar4 *)&p[x];
- return convert_float4(p2[0]);
- }
- static inline float3 __attribute__((overloadable))
- getElementAt565(const uint8_t *p, int32_t x) {
- x *= 2;
- float3 r = getFrom565(((const uint16_t *)p)[0]);
- return r;
- }
- static inline float __attribute__((overloadable))
- getElementAt1(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
- p += y * stride;
- float r = p[x];
- return r;
- }
- static inline float2 __attribute__((overloadable))
- getElementAt2(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
- p += y * stride;
- x *= 2;
- float2 r = {p[x], p[x+1]};
- return r;
- }
- static inline float3 __attribute__((overloadable))
- getElementAt3(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
- p += y * stride;
- x *= 4;
- float3 r = {p[x], p[x+1], p[x+2]};
- return r;
- }
- static inline float4 __attribute__((overloadable))
- getElementAt4(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
- p += y * stride;
- x *= 4;
- float4 r = {p[x], p[x+1], p[x+2], p[x+3]};
- return r;
- }
- static inline float3 __attribute__((overloadable))
- getElementAt565(const uint8_t *p, size_t stride, int32_t x, int32_t y) {
- p += y * stride;
- x *= 2;
- float3 r = getFrom565(((const uint16_t *)p)[0]);
- return r;
- }
- static float4 __attribute__((overloadable))
- getSample_A(const uint8_t *p, int32_t iPixel,
- int32_t next, float w0, float w1) {
- float p0 = getElementAt1(p, iPixel);
- float p1 = getElementAt1(p, next);
- float r = p0 * w0 + p1 * w1;
- r *= (1.f / 255.f);
- float4 ret = {0.f, 0.f, 0.f, r};
- return ret;
- }
- static float4 __attribute__((overloadable))
- getSample_L(const uint8_t *p, int32_t iPixel,
- int32_t next, float w0, float w1) {
- float p0 = getElementAt1(p, iPixel);
- float p1 = getElementAt1(p, next);
- float r = p0 * w0 + p1 * w1;
- r *= (1.f / 255.f);
- float4 ret = {r, r, r, 1.f};
- return ret;
- }
- static float4 __attribute__((overloadable))
- getSample_LA(const uint8_t *p, int32_t iPixel,
- int32_t next, float w0, float w1) {
- float2 p0 = getElementAt2(p, iPixel);
- float2 p1 = getElementAt2(p, next);
- float2 r = p0 * w0 + p1 * w1;
- r *= (1.f / 255.f);
- float4 ret = {r.x, r.x, r.x, r.y};
- return ret;
- }
- static float4 __attribute__((overloadable))
- getSample_RGB(const uint8_t *p, int32_t iPixel,
- int32_t next, float w0, float w1) {
- float3 p0 = getElementAt3(p, iPixel);
- float3 p1 = getElementAt3(p, next);
- float3 r = p0 * w0 + p1 * w1;
- r *= (1.f / 255.f);
- float4 ret = {r.x, r.x, r.z, 1.f};
- return ret;
- }
- static float4 __attribute__((overloadable))
- getSample_565(const uint8_t *p, int32_t iPixel,
- int32_t next, float w0, float w1) {
- float3 p0 = getElementAt565(p, iPixel);
- float3 p1 = getElementAt565(p, next);
- float3 r = p0 * w0 + p1 * w1;
- r *= (1.f / 255.f);
- float4 ret = {r.x, r.x, r.z, 1.f};
- return ret;
- }
- static float4 __attribute__((overloadable))
- getSample_RGBA(const uint8_t *p, int32_t iPixel,
- int32_t next, float w0, float w1) {
- float4 p0 = getElementAt4(p, iPixel);
- float4 p1 = getElementAt4(p, next);
- float4 r = p0 * w0 + p1 * w1;
- r *= (1.f / 255.f);
- return r;
- }
- 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) {
- float p0 = getElementAt1(p, stride, locX, locY);
- float p1 = getElementAt1(p, stride, nextX, locY);
- float p2 = getElementAt1(p, stride, locX, nextY);
- float p3 = getElementAt1(p, stride, nextX, nextY);
- float r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
- r *= (1.f / 255.f);
- float4 ret = {0.f, 0.f, 0.f, r};
- return ret;
- }
- 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) {
- float p0 = getElementAt1(p, stride, locX, locY);
- float p1 = getElementAt1(p, stride, nextX, locY);
- float p2 = getElementAt1(p, stride, locX, nextY);
- float p3 = getElementAt1(p, stride, nextX, nextY);
- float r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
- r *= (1.f / 255.f);
- float4 ret = {r, r, r, 1.f};
- return ret;
- }
- 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) {
- float2 p0 = getElementAt2(p, stride, locX, locY);
- float2 p1 = getElementAt2(p, stride, nextX, locY);
- float2 p2 = getElementAt2(p, stride, locX, nextY);
- float2 p3 = getElementAt2(p, stride, nextX, nextY);
- float2 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
- r *= (1.f / 255.f);
- float4 ret = {r.x, r.x, r.x, r.y};
- return ret;
- }
- 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) {
- float4 p0 = getElementAt4(p, stride, locX, locY);
- float4 p1 = getElementAt4(p, stride, nextX, locY);
- float4 p2 = getElementAt4(p, stride, locX, nextY);
- float4 p3 = getElementAt4(p, stride, nextX, nextY);
- float4 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
- r *= (1.f / 255.f);
- float4 ret = {r.x, r.y, r.z, 1.f};
- return ret;
- }
- 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) {
- float4 p0 = getElementAt4(p, stride, locX, locY);
- float4 p1 = getElementAt4(p, stride, nextX, locY);
- float4 p2 = getElementAt4(p, stride, locX, nextY);
- float4 p3 = getElementAt4(p, stride, nextX, nextY);
- float4 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
- r *= (1.f / 255.f);
- return r;
- }
- 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) {
- float3 p0 = getElementAt565(p, stride, locX, locY);
- float3 p1 = getElementAt565(p, stride, nextX, locY);
- float3 p2 = getElementAt565(p, stride, locX, nextY);
- float3 p3 = getElementAt565(p, stride, nextX, nextY);
- float3 r = p0 * w0 + p1 * w1 + p2 * w2 + p3 * w3;
- r *= (1.f / 255.f);
- float4 ret;
- ret.rgb = r;
- ret.w = 1.f;
- return ret;
- }
- 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) {
- const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
- switch(dk) {
- case RS_KIND_PIXEL_RGBA:
- return getSample_RGBA(p, iPixel, next, weights.x, weights.y);
- case RS_KIND_PIXEL_A:
- return getSample_A(p, iPixel, next, weights.x, weights.y);
- case RS_KIND_PIXEL_RGB:
- if (dt == RS_TYPE_UNSIGNED_5_6_5) {
- return getSample_565(p, iPixel, next, weights.x, weights.y);
- }
- return getSample_RGB(p, iPixel, next, weights.x, weights.y);
- case RS_KIND_PIXEL_L:
- return getSample_L(p, iPixel, next, weights.x, weights.y);
- case RS_KIND_PIXEL_LA:
- return getSample_LA(p, iPixel, next, weights.x, weights.y);
- default:
- //__builtin_unreachable();
- break;
- }
- //__builtin_unreachable();
- return 0.f;
- }
- static uint32_t wrapI(rs_sampler_value wrap, int32_t coord, int32_t size) {
- if (wrap == RS_SAMPLER_WRAP) {
- coord = coord % size;
- if (coord < 0) {
- coord += size;
- }
- }
- if (wrap == RS_SAMPLER_MIRRORED_REPEAT) {
- coord = coord % (size * 2);
- if (coord < 0) {
- coord = (size * 2) + coord;
- }
- if (coord >= size) {
- coord = (size * 2 - 1) - coord;
- }
- }
- return (uint32_t)max(0, min(coord, size - 1));
- }
- 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) {
- const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
- size_t stride = alloc->mHal.drvState.lod[lod].stride;
- switch(dk) {
- case RS_KIND_PIXEL_RGBA:
- return getSample_RGBA(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
- case RS_KIND_PIXEL_A:
- return getSample_A(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
- case RS_KIND_PIXEL_LA:
- return getSample_LA(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
- case RS_KIND_PIXEL_RGB:
- if (dt == RS_TYPE_UNSIGNED_5_6_5) {
- return getSample_565(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
- }
- return getSample_RGB(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
- case RS_KIND_PIXEL_L:
- return getSample_L(p, stride, lx, ly, nx, ny, w0, w1, w2, w3);
- default:
- break;
- }
- return 0.f;
- }
- static float4 __attribute__((overloadable))
- getNearestSample(const Allocation_t *alloc, uint32_t iPixel, rs_data_kind dk,
- rs_data_type dt, uint32_t lod) {
- const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
- float4 result = {0.f, 0.f, 0.f, 255.f};
- switch(dk) {
- case RS_KIND_PIXEL_RGBA:
- result = getElementAt4(p, iPixel);
- break;
- case RS_KIND_PIXEL_A:
- result.w = getElementAt1(p, iPixel);
- break;
- case RS_KIND_PIXEL_LA:
- result.zw = getElementAt2(p, iPixel);
- result.xy = result.z;
- break;
- case RS_KIND_PIXEL_RGB:
- if (dt == RS_TYPE_UNSIGNED_5_6_5) {
- result.xyz = getElementAt565(p, iPixel);
- } else {
- result.xyz = getElementAt3(p, iPixel);
- }
- break;
- case RS_KIND_PIXEL_L:
- result.xyz = getElementAt1(p, iPixel);
- default:
- //__builtin_unreachable();
- break;
- }
- return result * 0.003921569f;
- }
- static float4 __attribute__((overloadable))
- getNearestSample(const Allocation_t *alloc, uint2 iPixel, rs_data_kind dk,
- rs_data_type dt, uint32_t lod) {
- const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
- size_t stride = alloc->mHal.drvState.lod[lod].stride;
- float4 result = {0.f, 0.f, 0.f, 255.f};
- switch(dk) {
- case RS_KIND_PIXEL_RGBA:
- result = getElementAt4(p, stride, iPixel.x, iPixel.y);
- break;
- case RS_KIND_PIXEL_A:
- result.w = getElementAt1(p, stride, iPixel.x, iPixel.y);
- break;
- case RS_KIND_PIXEL_LA:
- result.zw = getElementAt2(p, stride, iPixel.x, iPixel.y);
- result.xy = result.z;
- break;
- case RS_KIND_PIXEL_RGB:
- if (dt == RS_TYPE_UNSIGNED_5_6_5) {
- result.xyz = getElementAt565(p, stride, iPixel.x, iPixel.y);
- } else {
- result.xyz = getElementAt3(p, stride, iPixel.x, iPixel.y);
- }
- break;
- default:
- //__builtin_unreachable();
- break;
- }
- return result * 0.003921569f;
- }
- 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) {
- int32_t sourceW = alloc->mHal.drvState.lod[lod].dimX;
- float pixelUV = uv * (float)(sourceW);
- int32_t iPixel = floor(pixelUV);
- float frac = pixelUV - (float)iPixel;
- if (frac < 0.5f) {
- iPixel -= 1;
- frac += 0.5f;
- } else {
- frac -= 0.5f;
- }
- float oneMinusFrac = 1.0f - frac;
- float2 weights;
- weights.x = oneMinusFrac;
- weights.y = frac;
- uint32_t next = wrapI(wrapS, iPixel + 1, sourceW);
- uint32_t location = wrapI(wrapS, iPixel, sourceW);
- return getBilinearSample1D(alloc, weights, location, next, dk, dt, lod);
- }
- 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) {
- int32_t sourceW = alloc->mHal.drvState.lod[lod].dimX;
- int32_t iPixel = floor(uv * (float)(sourceW));
- uint32_t location = wrapI(wrapS, iPixel, sourceW);
- return getNearestSample(alloc, location, dk, dt, lod);
- }
- 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) {
- int sourceW = alloc->mHal.drvState.lod[lod].dimX;
- int sourceH = alloc->mHal.drvState.lod[lod].dimY;
- float pixelU = uv.x * sourceW;
- float pixelV = uv.y * sourceH;
- int iPixelU = floor(pixelU);
- int iPixelV = floor(pixelV);
- float fracU = pixelU - iPixelU;
- float fracV = pixelV - iPixelV;
- if (fracU < 0.5f) {
- iPixelU -= 1;
- fracU += 0.5f;
- } else {
- fracU -= 0.5f;
- }
- if (fracV < 0.5f) {
- iPixelV -= 1;
- fracV += 0.5f;
- } else {
- fracV -= 0.5f;
- }
- float oneMinusFracU = 1.0f - fracU;
- float oneMinusFracV = 1.0f - fracV;
- float w0 = oneMinusFracU * oneMinusFracV;
- float w1 = fracU * oneMinusFracV;
- float w2 = oneMinusFracU * fracV;
- float w3 = fracU * fracV;
- int nx = wrapI(wrapS, iPixelU + 1, sourceW);
- int ny = wrapI(wrapT, iPixelV + 1, sourceH);
- int lx = wrapI(wrapS, iPixelU, sourceW);
- int ly = wrapI(wrapT, iPixelV, sourceH);
- return getBilinearSample2D(alloc, w0, w1, w2, w3, lx, ly, nx, ny, dk, dt, lod);
- }
- 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) {
- int sourceW = alloc->mHal.drvState.lod[lod].dimX;
- int sourceH = alloc->mHal.drvState.lod[lod].dimY;
- float2 dimF;
- dimF.x = (float)(sourceW);
- dimF.y = (float)(sourceH);
- int2 iPixel = convert_int2(floor(uv * dimF));
- uint2 location;
- location.x = wrapI(wrapS, iPixel.x, sourceW);
- location.y = wrapI(wrapT, iPixel.y, sourceH);
- return getNearestSample(alloc, location, dk, dt, lod);
- }
- extern float4 __attribute__((overloadable))
- rsSample(rs_allocation a, rs_sampler s, float uv, float lod) {
- const Allocation_t *alloc = (const Allocation_t *)a.p;
- const Sampler_t *prog = (Sampler_t *)s.p;
- const Type_t *type = (Type_t *)alloc->mHal.state.type;
- const Element_t *elem = type->mHal.state.element;
- rs_data_kind dk = elem->mHal.state.dataKind;
- rs_data_type dt = elem->mHal.state.dataType;
- rs_sampler_value sampleMin = prog->mHal.state.minFilter;
- rs_sampler_value sampleMag = prog->mHal.state.magFilter;
- rs_sampler_value wrapS = prog->mHal.state.wrapS;
- if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
- return 0.f;
- }
- if (lod <= 0.0f) {
- if (sampleMag == RS_SAMPLER_NEAREST) {
- return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, uv, 0);
- }
- return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, 0);
- }
- if (sampleMin == RS_SAMPLER_LINEAR_MIP_NEAREST) {
- uint32_t maxLOD = type->mHal.state.lodCount - 1;
- lod = min(lod, (float)maxLOD);
- uint32_t nearestLOD = (uint32_t)round(lod);
- return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, nearestLOD);
- }
- if (sampleMin == RS_SAMPLER_LINEAR_MIP_LINEAR) {
- uint32_t lod0 = (uint32_t)floor(lod);
- uint32_t lod1 = (uint32_t)ceil(lod);
- uint32_t maxLOD = type->mHal.state.lodCount - 1;
- lod0 = min(lod0, maxLOD);
- lod1 = min(lod1, maxLOD);
- float4 sample0 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, lod0);
- float4 sample1 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, uv, lod1);
- float frac = lod - (float)lod0;
- return sample0 * (1.0f - frac) + sample1 * frac;
- }
- return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, uv, 0);
- }
- extern float4 __attribute__((overloadable))
- rsSample(rs_allocation a, rs_sampler s, float location) {
- return rsSample(a, s, location, 0);
- }
- extern float4 __attribute__((overloadable))
- rsSample(rs_allocation a, rs_sampler s, float2 uv, float lod) {
- const Allocation_t *alloc = (const Allocation_t *)a.p;
- const Sampler_t *prog = (Sampler_t *)s.p;
- const Type_t *type = (Type_t *)alloc->mHal.state.type;
- const Element_t *elem = type->mHal.state.element;
- rs_data_kind dk = elem->mHal.state.dataKind;
- rs_data_type dt = elem->mHal.state.dataType;
- rs_sampler_value sampleMin = prog->mHal.state.minFilter;
- rs_sampler_value sampleMag = prog->mHal.state.magFilter;
- rs_sampler_value wrapS = prog->mHal.state.wrapS;
- rs_sampler_value wrapT = prog->mHal.state.wrapT;
- if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
- return 0.f;
- }
- if (lod <= 0.0f) {
- if (sampleMag == RS_SAMPLER_NEAREST) {
- return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
- }
- return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
- }
- if (sampleMin == RS_SAMPLER_LINEAR_MIP_NEAREST) {
- uint32_t maxLOD = type->mHal.state.lodCount - 1;
- lod = min(lod, (float)maxLOD);
- uint32_t nearestLOD = (uint32_t)round(lod);
- return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, nearestLOD);
- }
- if (sampleMin == RS_SAMPLER_LINEAR_MIP_LINEAR) {
- uint32_t lod0 = (uint32_t)floor(lod);
- uint32_t lod1 = (uint32_t)ceil(lod);
- uint32_t maxLOD = type->mHal.state.lodCount - 1;
- lod0 = min(lod0, maxLOD);
- lod1 = min(lod1, maxLOD);
- float4 sample0 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, lod0);
- float4 sample1 = sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, lod1);
- float frac = lod - (float)lod0;
- return sample0 * (1.0f - frac) + sample1 * frac;
- }
- return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
- }
- extern float4 __attribute__((overloadable))
- rsSample(rs_allocation a, rs_sampler s, float2 uv) {
- const Allocation_t *alloc = (const Allocation_t *)a.p;
- const Sampler_t *prog = (Sampler_t *)s.p;
- const Type_t *type = (Type_t *)alloc->mHal.state.type;
- const Element_t *elem = type->mHal.state.element;
- rs_data_kind dk = elem->mHal.state.dataKind;
- rs_data_type dt = elem->mHal.state.dataType;
- rs_sampler_value wrapS = prog->mHal.state.wrapS;
- rs_sampler_value wrapT = prog->mHal.state.wrapT;
- if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)) {
- return 0.f;
- }
- if (prog->mHal.state.magFilter == RS_SAMPLER_NEAREST) {
- return sample_LOD_NearestPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
- }
- return sample_LOD_LinearPixel(alloc, dk, dt, wrapS, wrapT, uv, 0);
- }
|