@@ -38,69 +38,134 @@ static int32_t wrapI(rs_sampler_value wrap, int32_t coord, int32_t size) {
3838 return max(0, min(coord, size - 1));
3939}
4040
41- static float2 wrap(rs_sampler_value wrapS, rs_sampler_value wrapT, float2 coord) {
42- float2 wrappedCoord;
43- float temp;
44- if (wrapS == RS_SAMPLER_WRAP) {
45- wrappedCoord.x = fract(coord.x, &temp);
46- // Make sure that non zero integer uv's map to one
47- if (wrappedCoord.x == 0.0f && coord.x != 0.0f) {
48- wrappedCoord.x = 1.0f;
41+ #define convert_float(v) (float)v
42+ #define SAMPLE_1D_FUNC(vecsize) \
43+ static float##vecsize get1DSample##vecsize(rs_allocation a, float2 weights, \
44+ int iPixel, int next) { \
45+ uchar##vecsize *p0c = (uchar##vecsize*)rsGetElementAt(a, iPixel); \
46+ uchar##vecsize *p1c = (uchar##vecsize*)rsGetElementAt(a, next); \
47+ float##vecsize p0 = convert_float##vecsize(*p0c); \
48+ float##vecsize p1 = convert_float##vecsize(*p1c); \
49+ return p0 * weights.x + p1 * weights.y; \
4950 }
50- if (wrappedCoord.x < 0.0f) {
51- wrappedCoord.x += 1.0f;
51+ #define SAMPLE_2D_FUNC(vecsize) \
52+ static float##vecsize get2DSample##vecsize(rs_allocation a, float4 weights, \
53+ int2 iPixel, int nextX, int nextY) { \
54+ uchar##vecsize *p0c = (uchar##vecsize*)rsGetElementAt(a, iPixel.x, iPixel.y); \
55+ uchar##vecsize *p1c = (uchar##vecsize*)rsGetElementAt(a, nextX, iPixel.y); \
56+ uchar##vecsize *p2c = (uchar##vecsize*)rsGetElementAt(a, iPixel.x, nextY); \
57+ uchar##vecsize *p3c = (uchar##vecsize*)rsGetElementAt(a, nextX, nextY); \
58+ float##vecsize p0 = convert_float##vecsize(*p0c); \
59+ float##vecsize p1 = convert_float##vecsize(*p1c); \
60+ float##vecsize p2 = convert_float##vecsize(*p2c); \
61+ float##vecsize p3 = convert_float##vecsize(*p3c); \
62+ return p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w; \
5263 }
53- } else {
54- wrappedCoord.x = max(0.0f, min(coord.x, 1.0f));
64+
65+ SAMPLE_1D_FUNC()
66+ SAMPLE_1D_FUNC(2)
67+ SAMPLE_1D_FUNC(3)
68+ SAMPLE_1D_FUNC(4)
69+
70+ SAMPLE_2D_FUNC()
71+ SAMPLE_2D_FUNC(2)
72+ SAMPLE_2D_FUNC(3)
73+ SAMPLE_2D_FUNC(4)
74+
75+ static float4 getBilinearSample565(rs_allocation a, float4 weights,
76+ int2 iPixel, int nextX, int nextY) {
77+ float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
78+ return zero;
79+ }
80+
81+ static float4 getBilinearSample(rs_allocation a, float4 weights,
82+ int2 iPixel, int nextX, int nextY,
83+ uint32_t vecSize, rs_data_type dt) {
84+ if (dt == RS_TYPE_UNSIGNED_5_6_5) {
85+ return getBilinearSample565(a, weights, iPixel, nextX, nextY);
5586 }
5687
57- if (wrapT == RS_SAMPLER_WRAP) {
58- wrappedCoord.y = fract(coord.y, &temp);
59- // Make sure that non zero integer uv's map to one
60- if (wrappedCoord.y == 0.0f && coord.y != 0.0f) {
61- wrappedCoord.y = 1.0f;
62- }
63- if (wrappedCoord.y < 0.0f) {
64- wrappedCoord.y += 1.0f;
65- }
66- } else {
67- wrappedCoord.y = max(0.0f, min(coord.y, 1.0f));
88+ float4 result;
89+ switch(vecSize) {
90+ case 1:
91+ result.x = get2DSample(a, weights, iPixel, nextX, nextY);
92+ result.yzw = 0.0f;
93+ break;
94+ case 2:
95+ result.xy = get2DSample2(a, weights, iPixel, nextX, nextY);
96+ result.zw = 0.0f;
97+ break;
98+ case 3:
99+ result.xyz = get2DSample3(a, weights, iPixel, nextX, nextY);
100+ result.w = 0.0f;
101+ break;
102+ case 4:
103+ result = get2DSample4(a, weights, iPixel, nextX, nextY);
104+ break;
68105 }
69- return wrappedCoord;
106+
107+ return result;
70108}
71109
110+ static float4 getNearestSample(rs_allocation a, int2 iPixel, uint32_t vecSize, rs_data_type dt) {
111+ if (dt == RS_TYPE_UNSIGNED_5_6_5) {
112+ float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
113+ return zero;
114+ }
115+
116+ float4 result;
117+ switch(vecSize) {
118+ case 1:
119+ result.x = convert_float(*((uchar*)rsGetElementAt(a, iPixel.x, iPixel.y)));
120+ result.yzw = 0.0f;
121+ case 2:
122+ result.xy = convert_float2(*((uchar2*)rsGetElementAt(a, iPixel.x, iPixel.y)));
123+ result.zw = 0.0f;
124+ case 3:
125+ result.xyz = convert_float3(*((uchar3*)rsGetElementAt(a, iPixel.x, iPixel.y)));
126+ result.w = 0.0f;
127+ case 4:
128+ result = convert_float4(*((uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y)));
129+ }
130+
131+ return result;
132+ }
133+
134+
72135// Naive implementation of texture filtering for prototyping purposes
73136static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
137+
138+ // Find out what kind of input data we are sampling
139+ rs_element elem = rsAllocationGetElement(a);
140+ uint32_t vecSize = rsElementGetVectorSize(elem);
141+ rs_data_kind dk = rsElementGetDataKind(elem);
142+ rs_data_type dt = rsElementGetDataType(elem);
143+
144+ if (dk == RS_KIND_USER || (dt != RS_TYPE_UNSIGNED_8 && dt != RS_TYPE_UNSIGNED_5_6_5)) {
145+ float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
146+ return zero;
147+ }
74148 //rsDebug("*****************************************", 0);
75149 rs_sampler_value wrapS = rsgSamplerGetWrapS(s);
76150 rs_sampler_value wrapT = rsgSamplerGetWrapT(s);
77151
78152 rs_sampler_value sampleMin = rsgSamplerGetMinification(s);
79153 rs_sampler_value sampleMag = rsgSamplerGetMagnification(s);
80154
81- uv = wrap(wrapS, wrapT, uv);
82-
83155 int32_t sourceW = rsAllocationGetDimX(a);
84156 int32_t sourceH = rsAllocationGetDimY(a);
85157
86- /*rsDebug("uv", uv);
87- rsDebug("sourceW", sourceW);
88- rsDebug("sourceH", sourceH);*/
89-
90158 float2 dimF;
91159 dimF.x = (float)(sourceW);
92160 dimF.y = (float)(sourceH);
93161 float2 pixelUV = uv * dimF;
94162 int2 iPixel = convert_int2(pixelUV);
95- /*rsDebug("iPixelX initial", iPixel.x);
96- rsDebug("iPixelY initial", iPixel.y);*/
97163
98164 if (sampleMin == RS_SAMPLER_NEAREST ||
99165 sampleMag == RS_SAMPLER_NEAREST) {
100166 iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
101167 iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
102- uchar4 *nearestSample = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
103- return convert_float4(*nearestSample);
168+ return getNearestSample(a, iPixel, vecSize, dt);
104169 }
105170
106171 float2 frac = pixelUV - convert_float2(iPixel);
@@ -125,36 +190,12 @@ static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
125190 weights.z = oneMinusFrac.x * frac.y;
126191 weights.w = frac.x * frac.y;
127192
128- uint32_t nextX = wrapI(wrapS, iPixel.x + 1, sourceW);
129- uint32_t nextY = wrapI(wrapT, iPixel.y + 1, sourceH);
193+ int32_t nextX = wrapI(wrapS, iPixel.x + 1, sourceW);
194+ int32_t nextY = wrapI(wrapT, iPixel.y + 1, sourceH);
130195 iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
131196 iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
132- /*rsDebug("iPixelX wrapped", iPixel.x);
133- rsDebug("iPixelY wrapped", iPixel.y);*/
134-
135- uchar4 *p0c = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
136- uchar4 *p1c = (uchar4*)rsGetElementAt(a, nextX, iPixel.y);
137- uchar4 *p2c = (uchar4*)rsGetElementAt(a, iPixel.x, nextY);
138- uchar4 *p3c = (uchar4*)rsGetElementAt(a, nextX, nextY);
139-
140- float4 p0 = convert_float4(*p0c);
141- float4 p1 = convert_float4(*p1c);
142- float4 p2 = convert_float4(*p2c);
143- float4 p3 = convert_float4(*p3c);
144-
145- float4 result = p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w;
146-
147- /*rsDebug("pixelUV", pixelUV);
148- rsDebug("frac", frac);
149- rsDebug("oneMinusFrac", oneMinusFrac);
150- rsDebug("p0", p0);
151- rsDebug("p1", p1);
152- rsDebug("p2", p2);
153- rsDebug("p3", p3);
154- rsDebug("w", weights);
155- rsDebug("result", result);*/
156197
157- return result ;
198+ return getBilinearSample(a, weights, iPixel, nextX, nextY, vecSize, dt) ;
158199}
159200
160201void root(uchar4 *out, uint32_t x, uint32_t y) {
0 commit comments