1/*
2* Copyright (C) 2016 The Android Open Source Project
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8*      http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
17#include <RenderScript.h>
18
19#include "ScriptC_allocs.h"
20
21sp<RS> mRS;
22sp<Allocation> mBoolAllocation;  // boolean
23
24sp<Allocation> mCharAllocation;  // char
25sp<Allocation> mChar2Allocation;   // char2
26sp<Allocation> mChar3Allocation;   // char3
27sp<Allocation> mChar4Allocation;   // char4
28
29sp<Allocation> mUCharAllocation;   // uchar
30sp<Allocation> mUChar2Allocation;  // uchar2
31sp<Allocation> mUChar3Allocation;  // uchar3
32sp<Allocation> mUChar4Allocation;  // uchar4
33
34sp<Allocation> mShortAllocation;   // short
35sp<Allocation> mShort2Allocation;  // short2
36sp<Allocation> mShort3Allocation;  // short3
37sp<Allocation> mShort4Allocation;  // short4
38
39sp<Allocation> mUShortAllocation;  // ushort
40sp<Allocation> mUShort2Allocation; // ushort2
41sp<Allocation> mUShort3Allocation; // ushort3
42sp<Allocation> mUShort4Allocation; // ushort4
43
44sp<Allocation> mIntAllocation;   // int
45sp<Allocation> mInt2Allocation;  // int2
46sp<Allocation> mInt3Allocation;  // int3
47sp<Allocation> mInt4Allocation;  // int4
48
49sp<Allocation> mUIntAllocation;  // uint
50sp<Allocation> mUInt2Allocation;   // uint2
51sp<Allocation> mUInt3Allocation;   // uint3
52sp<Allocation> mUInt4Allocation;   // uint4
53
54sp<Allocation> mLongAllocation;  // long
55sp<Allocation> mLong2Allocation;   // long2
56sp<Allocation> mLong3Allocation;   // long3
57sp<Allocation> mLong4Allocation;   // long4
58
59sp<Allocation> mULongAllocation;   // ulong
60sp<Allocation> mULong2Allocation;  // ulong2
61sp<Allocation> mULong3Allocation;  // ulong3
62sp<Allocation> mULong4Allocation;  // ulong4
63
64sp<Allocation> mHalfAllocation;  // half
65sp<Allocation> mHalf2Allocation;   // half2
66sp<Allocation> mHalf3Allocation;   // half3
67sp<Allocation> mHalf4Allocation;   // half4
68
69sp<Allocation> mFloatAllocation;   // float
70sp<Allocation> mFloat2Allocation;  // float2
71sp<Allocation> mFloat3Allocation;  // float3
72sp<Allocation> mFloat4Allocation;  // float4
73
74sp<Allocation> mDoubleAllocation;  // double
75sp<Allocation> mDouble2Allocation; // double2
76sp<Allocation> mDouble3Allocation; // double3
77sp<Allocation> mDouble4Allocation; // double4
78
79const int mAllocSize = 24; // Needs to be < CHAR_MAX and divisible by 4.
80const int mBitmapSize = 64;
81
82void createSignedAllocations() {
83    Type::Builder typeI8Builder(mRS, Element::I8(mRS));
84    typeI8Builder.setX(1); // One element here to test 16 byte memory alignment
85    typeI8Builder.setY(3);
86    typeI8Builder.setZ(8);
87
88    mCharAllocation = Allocation::createTyped(mRS, typeI8Builder.create());
89    mChar2Allocation = Allocation::createSized(mRS, Element::I8_2(mRS), mAllocSize / 2);
90    mChar3Allocation = Allocation::createSized(mRS, Element::I8_3(mRS), mAllocSize / 4);
91    mChar4Allocation = Allocation::createSized(mRS, Element::I8_4(mRS), mAllocSize / 4);
92
93    Type::Builder typeI16_2Builder(mRS, Element::I16_2(mRS));
94    typeI16_2Builder.setX(6);
95    typeI16_2Builder.setY(1);
96    typeI16_2Builder.setZ(2);
97
98    mShortAllocation = Allocation::createSized(mRS, Element::I16(mRS), mAllocSize);
99    mShort2Allocation = Allocation::createTyped(mRS, typeI16_2Builder.create());
100    mShort3Allocation = Allocation::createSized(mRS, Element::I16_3(mRS), mAllocSize / 4);
101    mShort4Allocation = Allocation::createSized(mRS, Element::I16_4(mRS), mAllocSize / 4);
102
103    Type::Builder typeI32_3Builder(mRS, Element::I32_3(mRS));
104    typeI32_3Builder.setX(3);
105    typeI32_3Builder.setY(2);
106
107    mIntAllocation = Allocation::createSized(mRS, Element::I32(mRS), mAllocSize);
108    mInt2Allocation = Allocation::createSized(mRS, Element::I32_2(mRS), mAllocSize / 2);
109    mInt3Allocation = Allocation::createTyped(mRS, typeI32_3Builder.create());
110    mInt4Allocation = Allocation::createSized(mRS, Element::I32_4(mRS), mAllocSize / 4);
111
112    Type::Builder typeI64_4Builder(mRS, Element::I64_4(mRS));
113    typeI64_4Builder.setX(1);
114    typeI64_4Builder.setY(6);
115
116    mLongAllocation = Allocation::createSized(mRS, Element::I64(mRS), mAllocSize);
117    mLong2Allocation = Allocation::createSized(mRS, Element::I64_2(mRS), mAllocSize / 2);
118    mLong3Allocation = Allocation::createSized(mRS, Element::I64_3(mRS), mAllocSize / 4);
119    mLong4Allocation = Allocation::createTyped(mRS, typeI64_4Builder.create());
120
121    mBoolAllocation = Allocation::createSized(mRS, Element::BOOLEAN(mRS), mAllocSize);
122}
123
124void initSignedAllocations() {
125    char *buffer_char = new char[mAllocSize];
126    short *buffer_short = new short[mAllocSize];
127    int *buffer_int = new int[mAllocSize];
128    int64_t *buffer_long = new int64_t[mAllocSize];
129    char *buffer_bool = new char[mAllocSize];
130
131    for(int i = 0; i < mAllocSize; ++i) {
132        buffer_char[i] = (char) i;
133        buffer_short[i] = (short) i;
134        buffer_int[i] = (int) i;
135        buffer_long[i] = (int64_t) i;
136        buffer_bool[i] =  (char) (0x01 & i);
137    }
138
139    mCharAllocation->copy3DRangeFrom(0, 0, 0, 1, 3, 8, buffer_char);
140    mChar2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_char);
141    mChar3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char);
142    mChar4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char);
143
144    delete [] buffer_char;
145
146    mShortAllocation->copy1DRangeFrom(0, mAllocSize, buffer_short);
147    mShort2Allocation->copy3DRangeFrom(0, 0, 0, 6, 1, 2, buffer_short);
148    mShort3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_short);
149    mShort4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_short);
150
151    delete [] buffer_short;
152
153    mIntAllocation->copy1DRangeFrom(0, mAllocSize, buffer_int);
154    mInt2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_int);
155    mInt3Allocation->copy2DRangeFrom(0, 0, 3, 2, buffer_int);
156    mInt4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_int);
157
158    delete [] buffer_int;
159
160    mLongAllocation->copy1DRangeFrom(0, mAllocSize, buffer_long);
161    mLong2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_long);
162    mLong3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_long);
163    mLong4Allocation->copy2DRangeFrom(0, 0, 1, 6, buffer_long);
164
165    delete [] buffer_long;
166
167    mBoolAllocation->copy1DRangeFrom(0, mAllocSize, buffer_bool);
168
169    delete [] buffer_bool;
170}
171
172void createUnsignedAllocations() {
173    Type::Builder typeU8_2Builder(mRS, Element::U8_2(mRS));
174    typeU8_2Builder.setX(2);
175    typeU8_2Builder.setY(6);
176
177    mUCharAllocation = Allocation::createSized(mRS, Element::U8(mRS), mAllocSize);
178    mUChar2Allocation = Allocation::createTyped(mRS, typeU8_2Builder.create());
179    mUChar3Allocation = Allocation::createSized(mRS, Element::U8_3(mRS), mAllocSize / 4);
180    mUChar4Allocation = Allocation::createSized(mRS, Element::U8_4(mRS), mAllocSize / 4);
181
182    Type::Builder typeU16_3Builder(mRS, Element::U16_3(mRS));
183    typeU16_3Builder.setX(1);
184    typeU16_3Builder.setY(6);
185
186    mUShortAllocation = Allocation::createSized(mRS, Element::U16(mRS), mAllocSize);
187    mUShort2Allocation = Allocation::createSized(mRS, Element::U16_2(mRS), mAllocSize / 2);
188    mUShort3Allocation = Allocation::createTyped(mRS, typeU16_3Builder.create());
189    mUShort4Allocation = Allocation::createSized(mRS, Element::U16_4(mRS), mAllocSize / 4);
190
191    Type::Builder typeU32_4Builder(mRS, Element::U32_4(mRS));
192    typeU32_4Builder.setX(1);
193    typeU32_4Builder.setY(1);
194    typeU32_4Builder.setZ(6);
195
196    mUIntAllocation = Allocation::createSized(mRS, Element::U32(mRS), mAllocSize);
197    mUInt2Allocation = Allocation::createSized(mRS, Element::U32_2(mRS), mAllocSize / 2);
198    mUInt3Allocation = Allocation::createSized(mRS, Element::U32_3(mRS), mAllocSize / 4);
199    mUInt4Allocation = Allocation::createTyped(mRS, typeU32_4Builder.create());
200
201    Type::Builder typeU64Builder(mRS, Element::U64(mRS));
202    typeU64Builder.setX(4);
203    typeU64Builder.setY(3);
204    typeU64Builder.setZ(2);
205
206    mULongAllocation = Allocation::createTyped(mRS, typeU64Builder.create());
207    mULong2Allocation = Allocation::createSized(mRS, Element::U64_2(mRS), mAllocSize / 2);
208    mULong3Allocation = Allocation::createSized(mRS, Element::U64_3(mRS), mAllocSize / 4);
209    mULong4Allocation = Allocation::createSized(mRS, Element::U64_4(mRS), mAllocSize / 4);
210}
211
212void initUnsignedAllocations() {
213    char *buffer_char = new char[mAllocSize];
214    short *buffer_short = new short[mAllocSize];
215    int *buffer_int = new int[mAllocSize];
216    uint64_t *buffer_long = new uint64_t[mAllocSize];
217
218    for(int i = 0; i < mAllocSize; ++i) {
219        buffer_char[i] = (char) i;
220        buffer_short[i] = (short) i;
221        buffer_int[i] = (int) i;
222        buffer_long[i] = (uint64_t) i;
223    }
224
225    mUCharAllocation->copy1DRangeFrom(0, mAllocSize, buffer_char);
226    mUChar2Allocation->copy2DRangeFrom(0, 0, 2, 6, buffer_char);
227    mUChar3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char);
228    mUChar4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char);
229
230    delete [] buffer_char;
231
232    mUShortAllocation->copy1DRangeFrom(0, mAllocSize, buffer_short);
233    mUShort2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_short);
234    mUShort3Allocation->copy2DRangeFrom(0, 0, 1, 6, buffer_short);
235    mUShort4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_short);
236
237    delete [] buffer_short;
238
239    mUIntAllocation->copy1DRangeFrom(0, mAllocSize, buffer_int);
240    mUInt2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_int);
241    mUInt3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_int);
242    mUInt4Allocation->copy3DRangeFrom(0, 0, 0, 1, 1, 6, buffer_int);
243
244    delete [] buffer_int;
245
246    mULongAllocation->copy3DRangeFrom(0, 0, 0, 4, 3, 2, buffer_long);
247    mULong2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_long);
248    mULong3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_long);
249    mULong4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_long);
250
251    delete [] buffer_long;
252}
253
254void createFloatAllocations() {
255    Type::Builder typeF16_3Builder(mRS, Element::F16_3(mRS));
256    typeF16_3Builder.setX(1);
257    typeF16_3Builder.setY(6);
258
259    mHalfAllocation = Allocation::createSized(mRS, Element::F16(mRS), mAllocSize);
260    mHalf2Allocation = Allocation::createSized(mRS, Element::F16_2(mRS), mAllocSize / 2);
261    mHalf3Allocation = Allocation::createTyped(mRS, typeF16_3Builder.create());
262    mHalf4Allocation = Allocation::createSized(mRS, Element::F16_4(mRS), mAllocSize / 4);
263
264    Type::Builder typeF32_4Builder(mRS, Element::F32_4(mRS));
265    typeF32_4Builder.setX(3);
266    typeF32_4Builder.setY(2);
267
268    mFloatAllocation = Allocation::createSized(mRS, Element::F32(mRS), mAllocSize);
269    mFloat2Allocation = Allocation::createSized(mRS, Element::F32_2(mRS), mAllocSize / 2);
270    mFloat3Allocation = Allocation::createSized(mRS, Element::F32_3(mRS), mAllocSize / 4);
271    mFloat4Allocation = Allocation::createTyped(mRS, typeF32_4Builder.create());
272
273    Type::Builder typeF64_2Builder(mRS, Element::F64_2(mRS));
274    typeF64_2Builder.setX(4);
275    typeF64_2Builder.setY(1);
276    typeF64_2Builder.setZ(3);
277
278    mDoubleAllocation = Allocation::createSized(mRS, Element::F64(mRS), mAllocSize);
279    mDouble2Allocation = Allocation::createTyped(mRS, typeF64_2Builder.create());
280
281    Type::Builder typeF64_3Builder(mRS, Element::F64_3(mRS));
282    typeF64_3Builder.setX(1);
283    typeF64_3Builder.setY(2);
284    typeF64_3Builder.setZ(3);
285
286    Type::Builder typeF64_4Builder(mRS, Element::F64_4(mRS));
287    typeF64_4Builder.setX(1);
288    typeF64_4Builder.setY(2);
289    typeF64_4Builder.setZ(3);
290
291    mDouble3Allocation = Allocation::createTyped(mRS, typeF64_3Builder.create());
292    mDouble4Allocation = Allocation::createTyped(mRS, typeF64_4Builder.create());
293}
294
295void initFloatAllocations() {
296    __fp16 *buffer_half = new __fp16[mAllocSize];
297    float *buffer_float = new float[mAllocSize];
298    double *buffer_double = new double[mAllocSize];
299
300    for(int i = 0; i < mAllocSize; ++i) {
301        buffer_half[i] = (__fp16) 1 / i;
302        buffer_float[i] = (float) 1 / i;
303        buffer_double[i] = (double) 1 / i;
304    }
305
306    mHalfAllocation->copy1DRangeFrom(0, mAllocSize, buffer_half);
307    mHalf2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_half);
308    mHalf3Allocation->copy2DRangeFrom(0, 0, 1, 6, buffer_half);
309    mHalf4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_half);
310
311    delete [] buffer_half;
312
313    mFloatAllocation->copy1DRangeFrom(0, mAllocSize, buffer_float);
314    mFloat2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_float);
315    mFloat3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_float);
316    mFloat4Allocation->copy2DRangeFrom(0, 0, 3, 2, buffer_float);
317
318    delete [] buffer_float;
319
320    mDoubleAllocation->copy1DRangeFrom(0, mAllocSize, buffer_double);
321    mDouble2Allocation->copy3DRangeFrom(0, 0, 0, 4, 1, 3, buffer_double);
322    mDouble3Allocation->copy3DRangeFrom(0, 0, 0, 1, 2, 3, buffer_double);
323    mDouble4Allocation->copy3DRangeFrom(0, 0, 0, 1, 2, 3, buffer_double);
324
325    delete [] buffer_double;
326}
327
328int main()
329{
330    mRS = new RS();
331
332    mRS->init("/data/rscache", RS_INIT_LOW_LATENCY | RS_INIT_WAIT_FOR_ATTACH);
333
334    sp<ScriptC_allocs> mScript = new ScriptC_allocs(mRS);
335
336    Type::Builder typeRGBA_888Builder(mRS, Element::RGBA_8888(mRS));
337    typeRGBA_888Builder.setX(mBitmapSize);
338    typeRGBA_888Builder.setY(mBitmapSize);
339
340    sp<Allocation> mInAllocation = Allocation::createTyped(mRS, typeRGBA_888Builder.create());
341
342    const int image_area = mBitmapSize*mBitmapSize;
343    const int image_size = image_area*sizeof(int);
344
345    char *zero_buffer = new char[image_size];
346    memset(zero_buffer, 0, image_size);
347    mInAllocation->copy1DRangeFrom(0, image_area, zero_buffer);
348    delete [] zero_buffer;
349
350    sp<Allocation> mOutAllocation = Allocation::createTyped(mRS, typeRGBA_888Builder.create());
351    createSignedAllocations();
352    initSignedAllocations();
353
354    mRS->finish();
355    mScript->forEach_swizzle_kernel(mInAllocation, mOutAllocation);
356    mRS->finish();
357
358    mCharAllocation.clear();
359    mChar2Allocation.clear();
360    mChar3Allocation.clear();
361    mChar4Allocation.clear();
362
363    mShort2Allocation.clear();
364    mShort3Allocation.clear();
365    mShort4Allocation.clear();
366
367    mIntAllocation.clear();
368    mInt2Allocation.clear();
369    mInt3Allocation.clear();
370    mInt4Allocation.clear();
371
372    mLongAllocation.clear();
373    mLong2Allocation.clear();
374    mLong3Allocation.clear();
375    mLong4Allocation.clear();
376
377    mBoolAllocation.clear();
378
379    createUnsignedAllocations();
380    initUnsignedAllocations();
381
382    mInAllocation = mUShortAllocation; // Host side assignment
383
384    mRS->finish();
385    mScript->forEach_square_kernel(mInAllocation, mUIntAllocation);
386    mRS->finish();
387
388    mUCharAllocation.clear();
389    mUChar2Allocation.clear();
390    mUChar3Allocation.clear();
391    mUChar4Allocation.clear();
392
393    mUShortAllocation.clear();
394    mUShort2Allocation.clear();
395    mUShort3Allocation.clear();
396    mUShort4Allocation.clear();
397
398    mUInt2Allocation.clear();
399    mUInt3Allocation.clear();
400    mUInt4Allocation.clear();
401
402    mULongAllocation.clear();
403    mULong2Allocation.clear();
404    mULong3Allocation.clear();
405    mULong4Allocation.clear();
406
407    createFloatAllocations();
408    initFloatAllocations();
409
410    mRS->finish();
411    mScript->forEach_add_half_kernel(mDouble4Allocation, mDouble3Allocation);
412    mRS->finish();
413
414    return 0;
415}
416
417