single_source_alloc.rs revision 2f4e8395f3a544a7a15b796ec1bf071a88d991e5
1#include "shared.rsh"
2
3int gDimX;
4int gDimY;
5int gDimZ;
6int gStart;
7static bool failed = false;
8
9
10// For each type, define 4 kernels, one per vector variant, that walk an
11// allocation and validate each cell.  The value in a cell must be gStart +
12// "index-of-the-cell-starting-from-zero".  For vector types, the 'x' field
13// must have this value.  The expected values for 'y', 'z' and 'w' follow the
14// 'x' value in increments of one.
15//
16// 'z' will be zero for 2D and 1D allocations.  'y' will be zero for 1D
17// allocations.
18
19// TODO When the requirement that kernels must return an output to be launched
20// using rsForEach is relaxed, make the kernel not return its input.
21#define VERIFY_KERNEL(CT)                                                      \
22    CT RS_KERNEL verify_##CT(CT in, int x, int y, int z) {                     \
23        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
24        _RS_ASSERT_EQU(in, (CT) val);                                          \
25        return in;                                                             \
26    }                                                                          \
27    CT##2 RS_KERNEL verify_##CT##2(CT##2 in, int x, int y, int z) {            \
28        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
29        _RS_ASSERT_EQU(in.x, (CT) val);                                        \
30        _RS_ASSERT_EQU(in.y, (CT) (val + 1));                                  \
31        return in;                                                             \
32    }                                                                          \
33    CT##3 RS_KERNEL verify_##CT##3(CT##3 in, int x, int y, int z) {            \
34        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
35        _RS_ASSERT_EQU(in.x, (CT) val);                                        \
36        _RS_ASSERT_EQU(in.y, (CT) (val + 1));                                  \
37        _RS_ASSERT_EQU(in.z, (CT) (val + 2));                                  \
38        return in;                                                             \
39    }                                                                          \
40    CT##4 RS_KERNEL verify_##CT##4(CT##4 in, int x, int y, int z) {            \
41        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
42        _RS_ASSERT_EQU(in.x, (CT) val);                                        \
43        _RS_ASSERT_EQU(in.y, (CT) (val + 1));                                  \
44        _RS_ASSERT_EQU(in.z, (CT) (val + 2));                                  \
45        _RS_ASSERT_EQU(in.w, (CT) (val + 3));                                  \
46        return in;                                                             \
47    }                                                                          \
48
49VERIFY_KERNEL(float)
50VERIFY_KERNEL(double)
51VERIFY_KERNEL(char)
52VERIFY_KERNEL(short)
53VERIFY_KERNEL(int)
54VERIFY_KERNEL(long)
55VERIFY_KERNEL(uchar)
56VERIFY_KERNEL(ushort)
57VERIFY_KERNEL(uint)
58VERIFY_KERNEL(ulong)
59
60
61// Store to an allocation based on the vector size and dimensionality being
62// tested.  SETLEMENTAT, STORE_TO_ALLOC capture the following variables from
63// the context where they get instantiated:
64//     vecSize, gAlloc, val, x, y, z
65
66#define SETELEMENTAT(CT)                                                      \
67    if (gDimZ != 0) {                                                         \
68        rsSetElementAt_##CT(gAlloc, storeVal, x, y, z);                       \
69    }                                                                         \
70    else if (gDimY != 0) {                                                    \
71        rsSetElementAt_##CT(gAlloc, storeVal, x, y);                          \
72    }                                                                         \
73    else {                                                                    \
74        rsSetElementAt_##CT(gAlloc, storeVal, x);                             \
75    }
76
77#define STORE_TO_ALLOC(RST, CT)                                               \
78    case RST:                                                                 \
79        switch (vecSize) {                                                    \
80            case 1: {                                                         \
81                CT storeVal = (CT) val;                                       \
82                SETELEMENTAT(CT);                                             \
83                     }                                                        \
84                break;                                                        \
85            case 2: {                                                         \
86                CT##2 storeVal = {(CT) val, (CT) (val + 1)};                  \
87                SETELEMENTAT(CT##2);                                          \
88                    }                                                         \
89                break;                                                        \
90            case 3: {                                                         \
91                CT##3 storeVal = {(CT) val, (CT) (val + 1), (CT) (val + 2)};  \
92                SETELEMENTAT(CT##3);                                          \
93                    }                                                         \
94                break;                                                        \
95            case 4: {                                                         \
96                CT##4 storeVal = {(CT) val, (CT) (val + 1), (CT) (val + 2),   \
97                                  (CT) (val + 3)};                            \
98                SETELEMENTAT(CT##4);                                          \
99                    }                                                         \
100                break;                                                        \
101        }                                                                     \
102        break;                                                                \
103
104
105// Launch the verify_kernel based on the appropriate type and vector size.
106#define LAUNCH_VERIFY_KERNEL(RST, CT)                                         \
107    case RST:                                                                 \
108        if (vecSize == 1) rsForEach(verify_##CT, gAlloc, gAlloc);             \
109        else if (vecSize == 2) rsForEach(verify_##CT##2, gAlloc, gAlloc);     \
110        else if (vecSize == 3) rsForEach(verify_##CT##3, gAlloc, gAlloc);     \
111        else if (vecSize == 4) rsForEach(verify_##CT##4, gAlloc, gAlloc);     \
112        break;
113
114void CreateAndTestAlloc(int dataType, int vecSize) {
115    if (gDimZ != 0 && gDimY == 0) {
116        _RS_ASSERT(false); // Invalid test
117        return;
118    }
119    if (gDimX == 0) {
120        _RS_ASSERT(false); // Invalid test
121        return;
122    }
123
124    rs_data_type dt = (rs_data_type) dataType;
125
126    rs_element element;
127    rs_type type;
128    rs_allocation gAlloc;
129
130    // Create and validate the rs_element object
131    if (vecSize == 1)
132        element = rsCreateElement((rs_data_type) dt);
133    else
134        element = rsCreateVectorElement((rs_data_type) dt, vecSize);
135    _RS_ASSERT(rsIsObject(element));
136    if (!rsIsObject(element))
137        return;
138
139    // Create and validate the rs_type object
140    type = rsCreateType(element, gDimX, gDimY, gDimZ);
141    _RS_ASSERT(rsIsObject(type));
142    if (!rsIsObject(type))
143        return;
144
145    // Create and validate the rs_allocation object
146    gAlloc = rsCreateAllocation(type);
147    if (!rsIsObject(gAlloc))
148        return;
149
150    // Handle RenderScript's distinction between Y or Z dimension being absent
151    // and having a size of 1
152    int zEnd = (gDimZ != 0) ? gDimZ: 1;
153    int yEnd = (gDimY != 0) ? gDimY: 1;
154    for (int z = 0; z < zEnd; z ++) {
155        for (int y = 0; y < yEnd; y ++) {
156            for (int x = 0; x < gDimX; x ++) {
157                int val = gStart + (x + y * gDimX + z * gDimY * gDimX);
158
159                // Store to a cell based on the type, vector size and
160                // dimensionality
161                switch (dt) {
162                    STORE_TO_ALLOC(RS_TYPE_FLOAT_32, float);
163                    STORE_TO_ALLOC(RS_TYPE_FLOAT_64, double);
164                    STORE_TO_ALLOC(RS_TYPE_SIGNED_8, char);
165                    STORE_TO_ALLOC(RS_TYPE_SIGNED_16, short);
166                    STORE_TO_ALLOC(RS_TYPE_SIGNED_32, int);
167                    STORE_TO_ALLOC(RS_TYPE_SIGNED_64, long);
168                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_8, uchar);
169                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_16, ushort);
170                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_32, uint);
171                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_64, ulong);
172                    default:
173                        // Invalid test
174                        _RS_ASSERT(false);
175                        break;
176                }
177            }
178        }
179    }
180
181    // Launch the appropriate verify_ kernel
182    switch (dt) {
183        LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_32, float);
184        LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_64, double);
185        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_8, char);
186        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_16, short);
187        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_32, int);
188        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_64, long);
189        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_8, uchar);
190        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_16, ushort);
191        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_32, uint);
192        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_64, ulong);
193
194        default:
195            // Invalid test
196            _RS_ASSERT(false);
197            break;
198    }
199}
200
201#define TEST_DATA_TYPE(dt, allowSimple, allowVector, allowPixel) {             \
202    if (allowSimple)                                                           \
203        _RS_ASSERT(rsIsObject(rsCreateElement(dt)));                           \
204    else                                                                       \
205        _RS_ASSERT(!rsIsObject(rsCreateElement(dt)));                          \
206    if (allowVector)                                                           \
207        _RS_ASSERT(rsIsObject(rsCreateVectorElement(dt, 3)));                  \
208    else                                                                       \
209        _RS_ASSERT(!rsIsObject(rsCreateVectorElement(dt, 3)));                 \
210    if (allowPixel)                                                            \
211        _RS_ASSERT(rsIsObject(rsCreatePixelElement(dt, RS_KIND_PIXEL_DEPTH))); \
212    else                                                                       \
213        _RS_ASSERT(!rsIsObject(rsCreatePixelElement(dt, RS_KIND_PIXEL_DEPTH)));\
214}
215
216#define TEST_SUPPORTED_PIXEL(dt, dk) {                                         \
217    _RS_ASSERT(rsIsObject(rsCreatePixelElement(dt, dk)));                      \
218}
219
220#define TEST_UNSUPPORTED_PIXEL(dt, dk) {                                       \
221    _RS_ASSERT(!rsIsObject(rsCreatePixelElement(dt, dk)));                     \
222}
223
224#define TEST_HELPER(suffix) {                                     \
225    _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3)));       \
226    _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3, 4)));    \
227    _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3, 4, 5))); \
228    }
229
230#define TEST_HELPERS(CT) { \
231    TEST_HELPER(CT);       \
232    TEST_HELPER(CT##2);    \
233    TEST_HELPER(CT##3);    \
234    TEST_HELPER(CT##4);    \
235}
236
237void TestAllCases() {
238    // vector_width must be at least 2
239    rs_element oneElt = rsCreateVectorElement(RS_TYPE_SIGNED_32, 1);
240    _RS_ASSERT(!rsIsObject(oneElt));
241
242    // vector_width must be at most 4
243    rs_element fiveElt = rsCreateVectorElement(RS_TYPE_SIGNED_32, 5);
244    _RS_ASSERT(!rsIsObject(fiveElt));
245
246    /////////////////////////////////////////////////////////////////
247    // Element validation
248    /////////////////////////////////////////////////////////////////
249    // These types are valid for scalar and vectors, but don't support pixel
250    TEST_DATA_TYPE(RS_TYPE_BOOLEAN,     true, true, false);
251    TEST_DATA_TYPE(RS_TYPE_FLOAT_32,    true, true, false);
252    TEST_DATA_TYPE(RS_TYPE_FLOAT_64,    true, true, false);
253    TEST_DATA_TYPE(RS_TYPE_SIGNED_8,    true, true, false);
254    TEST_DATA_TYPE(RS_TYPE_SIGNED_16,   true, true, false);
255    TEST_DATA_TYPE(RS_TYPE_SIGNED_32,   true, true, false);
256    TEST_DATA_TYPE(RS_TYPE_SIGNED_64,   true, true, false);
257    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_32, true, true, false);
258    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_64, true, true, false);
259
260    // These types are valid only for scalars
261    TEST_DATA_TYPE(RS_TYPE_MATRIX_4X4, true, false, false);
262    TEST_DATA_TYPE(RS_TYPE_MATRIX_3X3, true, false, false);
263    TEST_DATA_TYPE(RS_TYPE_MATRIX_2X2, true, false, false);
264    TEST_DATA_TYPE(RS_TYPE_ELEMENT,    true, false, false);
265    TEST_DATA_TYPE(RS_TYPE_TYPE,       true, false, false);
266    TEST_DATA_TYPE(RS_TYPE_ALLOCATION, true, false, false);
267    TEST_DATA_TYPE(RS_TYPE_SCRIPT,     true, false, false);
268
269    // U8, U16 are valid for scalar, vector and pixel
270    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_8,  true, true, true);
271    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_16, true, true, true);
272
273    // These data types are only for pixels and a particular data_kind
274    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_5_6_5,   RS_KIND_PIXEL_RGB);
275    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_5_6_5,   RS_KIND_PIXEL_L);
276    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_5_5_5_1, RS_KIND_PIXEL_RGBA);
277    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_5_5_5_1, RS_KIND_PIXEL_L);
278    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_RGBA);
279    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_L);
280    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_16,      RS_KIND_PIXEL_DEPTH);
281    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_L);
282
283    // These data types are not supported from single-source
284    TEST_DATA_TYPE(RS_TYPE_NONE,             false, false, false);
285    TEST_DATA_TYPE(RS_TYPE_SAMPLER,          false, false, false);
286    TEST_DATA_TYPE(RS_TYPE_MESH,             false, false, false);
287    TEST_DATA_TYPE(RS_TYPE_PROGRAM_FRAGMENT, false, false, false);
288    TEST_DATA_TYPE(RS_TYPE_PROGRAM_VERTEX,   false, false, false);
289    TEST_DATA_TYPE(RS_TYPE_PROGRAM_RASTER,   false, false, false);
290    TEST_DATA_TYPE(RS_TYPE_PROGRAM_STORE,    false, false, false);
291    TEST_DATA_TYPE(RS_TYPE_FONT,             false, false, false);
292    TEST_DATA_TYPE(RS_TYPE_INVALID,          false, false, false);
293
294    /////////////////////////////////////////////////////////////////
295    // Test rs_type creation
296    /////////////////////////////////////////////////////////////////
297    rs_element I32_3 = rsCreateVectorElement(RS_TYPE_SIGNED_32, 3);
298
299    // Create 1D, 2D, 3D types
300    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3)));
301    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4)));
302    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 5)));
303    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 0))); // x = 0 is allowed
304
305    // Invalid dimensionality
306    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 0, 4))); // x is 0 but y isn't
307    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 0, 4, 5))); // x is 0 but z isn't
308    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 5))); // y is 0 but z isn't
309
310    // shape attributes
311    // Valid yuv_format
312    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
313                    RS_YUV_NONE)));
314    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
315                    RS_YUV_YV12)));
316    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
317                    RS_YUV_NV21)));
318    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
319                    RS_YUV_420_888)));
320
321    // Invalid yuv_format
322    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, false, 1024)));
323    // yuv_format with 1D or 3D is invalid
324    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, false, false,
325                    RS_YUV_YV12)));
326    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, false,
327                    RS_YUV_YV12)));
328
329    // yuv_format with mipmaps or cubemap is invalid
330    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, true,
331                    RS_YUV_YV12)));
332    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 0, true, false,
333                    RS_YUV_YV12)));
334
335    // mipmaps with 1D or 3D is invalid
336    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, true, false,
337                    RS_YUV_NONE)));
338    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, true, false,
339                    RS_YUV_NONE)));
340
341    // cubemap with 1D or 3D is invalid
342    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, false, true,
343                    RS_YUV_NONE)));
344    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, true,
345                    RS_YUV_NONE)));
346
347    /////////////////////////////////////////////////////////////////
348    // Test rs_allocation creation
349    /////////////////////////////////////////////////////////////////
350    rs_type I32_3_2D = rsCreateType(I32_3, 3, 4);
351
352    // Valid uses
353    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D)));
354    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,\
355                    (uint32_t) RS_ALLOCATION_USAGE_SCRIPT)));
356    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,\
357                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)));
358    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,
359                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
360                               RS_ALLOCATION_USAGE_SCRIPT)));
361
362    // Invalid uses
363    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
364                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_VERTEX)));
365    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
366                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS)));
367    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
368                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET)));
369    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
370                    (uint32_t) RS_ALLOCATION_USAGE_IO_INPUT)));
371    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
372                    (uint32_t) RS_ALLOCATION_USAGE_IO_OUTPUT)));
373    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
374                    (uint32_t) RS_ALLOCATION_USAGE_SHARED)));
375
376    // Bug: 24862914: Add half once the bug is fixed
377    TEST_HELPERS(float);
378    TEST_HELPERS(double);
379    TEST_HELPERS(char);
380    TEST_HELPERS(short);
381    TEST_HELPERS(int);
382    TEST_HELPERS(long);
383    TEST_HELPERS(uchar);
384    TEST_HELPERS(ushort);
385    TEST_HELPERS(uint);
386    TEST_HELPERS(ulong);
387}
388
389void single_source_alloc_test() {
390    if (failed) {
391        rsDebug("Single Source Alloc Test Failed", 0);
392        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
393    }
394    else {
395        rsDebug("Single Source Alloc Test Passed", 0);
396        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
397    }
398}
399