blob: baf3e7a1ddf166522ed360756035e741497ded17 [file] [log] [blame]
Jason Samsbad80742011-03-16 16:29:28 -07001/*
Stephen Hinesee7aa2e2012-01-12 18:56:23 -08002 * Copyright (C) 2011-2012 The Android Open Source Project
Jason Samsbad80742011-03-16 16:29:28 -07003 *
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
Jason Samsbad80742011-03-16 16:29:28 -070017#include "rsdCore.h"
Jason Samsbad80742011-03-16 16:29:28 -070018
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -070019#include <bcc/BCCContext.h>
Stephen Hines378d30b2012-07-27 18:11:03 -070020#include <bcc/Renderscript/RSCompilerDriver.h>
21#include <bcc/Renderscript/RSExecutable.h>
22#include <bcc/Renderscript/RSInfo.h>
Stephen Hines689821f2011-07-18 17:24:11 -070023
Jason Samsdbe66d62012-09-17 13:54:41 -070024#include "rsdBcc.h"
25#include "rsdRuntime.h"
26#include "rsdAllocation.h"
27#include "rsdIntrinsics.h"
28
Jason Samsbad80742011-03-16 16:29:28 -070029#include "rsContext.h"
Stephen Hines2980f072012-04-09 18:26:29 -070030#include "rsElement.h"
Jason Samsbad80742011-03-16 16:29:28 -070031#include "rsScriptC.h"
32
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -070033#include "utils/Vector.h"
Jason Samsbad80742011-03-16 16:29:28 -070034#include "utils/Timers.h"
35#include "utils/StopWatch.h"
Jason Samsbad80742011-03-16 16:29:28 -070036
Jason Samsbad80742011-03-16 16:29:28 -070037using namespace android;
38using namespace android::renderscript;
39
Jason Sams83c451a2011-04-21 11:46:50 -070040
Jason Samscdfdb8f2011-03-17 16:12:47 -070041static Script * setTLS(Script *sc) {
Jason Sams83c451a2011-04-21 11:46:50 -070042 ScriptTLSStruct * tls = (ScriptTLSStruct *)pthread_getspecific(rsdgThreadTLSKey);
Jason Samscdfdb8f2011-03-17 16:12:47 -070043 rsAssert(tls);
44 Script *old = tls->mScript;
45 tls->mScript = sc;
46 return old;
47}
48
49
Jason Samsbad80742011-03-16 16:29:28 -070050bool rsdScriptInit(const Context *rsc,
51 ScriptC *script,
52 char const *resName,
53 char const *cacheDir,
54 uint8_t const *bitcode,
55 size_t bitcodeSize,
Jason Sams87fe59a2011-04-20 15:09:01 -070056 uint32_t flags) {
Steve Blockaf12ac62012-01-06 19:20:56 +000057 //ALOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc);
Jason Sams0ab9f9f2012-06-15 16:10:17 -070058 //ALOGE("rsdScriptInit %p %p", rsc, script);
Jason Samsbad80742011-03-16 16:29:28 -070059
Jason Sams83c451a2011-04-21 11:46:50 -070060 pthread_mutex_lock(&rsdgInitMutex);
Logan Chien1415ca42011-11-27 08:41:23 +080061
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -070062 bcc::RSExecutable *exec;
63 const bcc::RSInfo *info;
Jason Samsbad80742011-03-16 16:29:28 -070064 DrvScript *drv = (DrvScript *)calloc(1, sizeof(DrvScript));
65 if (drv == NULL) {
Jason Sams83c451a2011-04-21 11:46:50 -070066 goto error;
Jason Samsbad80742011-03-16 16:29:28 -070067 }
68 script->mHal.drv = drv;
69
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -070070 drv->mCompilerContext = NULL;
71 drv->mCompilerDriver = NULL;
72 drv->mExecutable = NULL;
Jason Samsbad80742011-03-16 16:29:28 -070073
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -070074 drv->mCompilerContext = new bcc::BCCContext();
75 if (drv->mCompilerContext == NULL) {
76 ALOGE("bcc: FAILS to create compiler context (out of memory)");
Jason Samsbad80742011-03-16 16:29:28 -070077 goto error;
78 }
79
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -070080 drv->mCompilerDriver = new bcc::RSCompilerDriver();
81 if (drv->mCompilerDriver == NULL) {
82 ALOGE("bcc: FAILS to create compiler driver (out of memory)");
Stephen Hines070cb232012-05-03 12:33:35 -070083 goto error;
Jason Samsbad80742011-03-16 16:29:28 -070084 }
85
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -070086 script->mHal.info.isThreadable = true;
87
88 drv->mCompilerDriver->setRSRuntimeLookupFunction(rsdLookupRuntimeStub);
89 drv->mCompilerDriver->setRSRuntimeLookupContext(script);
90
91 exec = drv->mCompilerDriver->build(*drv->mCompilerContext,
92 cacheDir, resName,
93 (const char *)bitcode, bitcodeSize);
94
95 if (exec == NULL) {
96 ALOGE("bcc: FAILS to prepare executable for '%s'", resName);
Stephen Hines070cb232012-05-03 12:33:35 -070097 goto error;
98 }
Jason Samsbad80742011-03-16 16:29:28 -070099
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700100 drv->mExecutable = exec;
101
102 exec->setThreadable(script->mHal.info.isThreadable);
103 if (!exec->syncInfo()) {
104 ALOGW("bcc: FAILS to synchronize the RS info file to the disk");
Stephen Hines070cb232012-05-03 12:33:35 -0700105 }
106
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700107 drv->mRoot = reinterpret_cast<int (*)()>(exec->getSymbolAddress("root"));
108 drv->mRootExpand =
109 reinterpret_cast<int (*)()>(exec->getSymbolAddress("root.expand"));
110 drv->mInit = reinterpret_cast<void (*)()>(exec->getSymbolAddress("init"));
111 drv->mFreeChildren =
112 reinterpret_cast<void (*)()>(exec->getSymbolAddress(".rs.dtor"));
Stephen Hines070cb232012-05-03 12:33:35 -0700113
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700114 info = &drv->mExecutable->getInfo();
Jason Samsbad80742011-03-16 16:29:28 -0700115 // Copy info over to runtime
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700116 script->mHal.info.exportedFunctionCount = info->getExportFuncNames().size();
117 script->mHal.info.exportedVariableCount = info->getExportVarNames().size();
118 script->mHal.info.exportedPragmaCount = info->getPragmas().size();
119 script->mHal.info.exportedPragmaKeyList =
120 const_cast<const char**>(exec->getPragmaKeys().array());
121 script->mHal.info.exportedPragmaValueList =
122 const_cast<const char**>(exec->getPragmaValues().array());
Stephen Hinesee7aa2e2012-01-12 18:56:23 -0800123
124 if (drv->mRootExpand) {
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700125 script->mHal.info.root = drv->mRootExpand;
Stephen Hinesee7aa2e2012-01-12 18:56:23 -0800126 } else {
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700127 script->mHal.info.root = drv->mRoot;
Stephen Hinesee7aa2e2012-01-12 18:56:23 -0800128 }
Jason Samsbad80742011-03-16 16:29:28 -0700129
Jason Sams807fdc42012-07-25 17:55:39 -0700130 if (script->mHal.info.exportedVariableCount) {
131 drv->mBoundAllocs = new Allocation *[script->mHal.info.exportedVariableCount];
132 memset(drv->mBoundAllocs, 0, sizeof(void *) * script->mHal.info.exportedVariableCount);
133 }
134
Jason Sams83c451a2011-04-21 11:46:50 -0700135 pthread_mutex_unlock(&rsdgInitMutex);
Jason Samsbad80742011-03-16 16:29:28 -0700136 return true;
137
138error:
139
Jason Sams83c451a2011-04-21 11:46:50 -0700140 pthread_mutex_unlock(&rsdgInitMutex);
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700141 if (drv) {
142 delete drv->mCompilerContext;
143 delete drv->mCompilerDriver;
144 delete drv->mExecutable;
Jason Sams807fdc42012-07-25 17:55:39 -0700145 delete[] drv->mBoundAllocs;
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700146 free(drv);
Stephen Hinescbb0b8a2011-08-01 15:02:34 -0700147 }
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700148 script->mHal.drv = NULL;
Jason Samsbad80742011-03-16 16:29:28 -0700149 return false;
150
151}
152
Stephen Hines41d6c762012-08-21 17:07:38 -0700153bool rsdInitIntrinsic(const Context *rsc, Script *s, RsScriptIntrinsicID iid, Element *e) {
Jason Sams8eaba4f2012-08-14 14:38:05 -0700154 pthread_mutex_lock(&rsdgInitMutex);
155
156 DrvScript *drv = (DrvScript *)calloc(1, sizeof(DrvScript));
157 if (drv == NULL) {
158 goto error;
159 }
160 s->mHal.drv = drv;
161 drv->mIntrinsicID = iid;
Jason Samse1e08b42012-09-04 16:49:19 -0700162 drv->mIntrinsicData = rsdIntrinsic_Init(rsc, s, iid, &drv->mIntrinsicFuncs);
Jason Sams8eaba4f2012-08-14 14:38:05 -0700163
164 pthread_mutex_unlock(&rsdgInitMutex);
165 return true;
166
167error:
168 pthread_mutex_unlock(&rsdgInitMutex);
169 return false;
170}
171
Stephen Hines3815bad2011-08-18 19:33:01 -0700172typedef void (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
Jason Samscdfdb8f2011-03-17 16:12:47 -0700173
174static void wc_xy(void *usr, uint32_t idx) {
175 MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
Jason Sams451cf2e2011-08-17 13:46:46 -0700176 RsForEachStubParamStruct p;
Jason Sams8eaba4f2012-08-14 14:38:05 -0700177 memcpy(&p, &mtls->fep, sizeof(p));
Stephen Hines3815bad2011-08-18 19:33:01 -0700178 RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
179 uint32_t sig = mtls->sig;
Jason Samscdfdb8f2011-03-17 16:12:47 -0700180
Stephen Hines44199772012-02-21 20:13:12 -0800181 outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
Jason Samscdfdb8f2011-03-17 16:12:47 -0700182 while (1) {
183 uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
184 uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
185 uint32_t yEnd = yStart + mtls->mSliceSize;
186 yEnd = rsMin(yEnd, mtls->yEnd);
187 if (yEnd <= yStart) {
188 return;
189 }
190
Steve Blockaf12ac62012-01-06 19:20:56 +0000191 //ALOGE("usr idx %i, x %i,%i y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
192 //ALOGE("usr ptr in %p, out %p", mtls->ptrIn, mtls->ptrOut);
Jason Sams451cf2e2011-08-17 13:46:46 -0700193 for (p.y = yStart; p.y < yEnd; p.y++) {
Jason Sams8eaba4f2012-08-14 14:38:05 -0700194 p.out = mtls->fep.ptrOut + (mtls->fep.yStrideOut * p.y);
195 p.in = mtls->fep.ptrIn + (mtls->fep.yStrideIn * p.y);
196 fn(&p, mtls->xStart, mtls->xEnd, mtls->fep.eStrideIn, mtls->fep.eStrideOut);
Jason Samscdfdb8f2011-03-17 16:12:47 -0700197 }
198 }
Jason Samsbad80742011-03-16 16:29:28 -0700199}
200
Jason Samscdfdb8f2011-03-17 16:12:47 -0700201static void wc_x(void *usr, uint32_t idx) {
202 MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
Jason Sams451cf2e2011-08-17 13:46:46 -0700203 RsForEachStubParamStruct p;
Jason Sams8eaba4f2012-08-14 14:38:05 -0700204 memcpy(&p, &mtls->fep, sizeof(p));
Stephen Hines3815bad2011-08-18 19:33:01 -0700205 RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
206 uint32_t sig = mtls->sig;
Jason Samscdfdb8f2011-03-17 16:12:47 -0700207
Stephen Hines44199772012-02-21 20:13:12 -0800208 outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
Jason Samscdfdb8f2011-03-17 16:12:47 -0700209 while (1) {
210 uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
211 uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
212 uint32_t xEnd = xStart + mtls->mSliceSize;
213 xEnd = rsMin(xEnd, mtls->xEnd);
214 if (xEnd <= xStart) {
215 return;
216 }
217
Steve Blockaf12ac62012-01-06 19:20:56 +0000218 //ALOGE("usr slice %i idx %i, x %i,%i", slice, idx, xStart, xEnd);
219 //ALOGE("usr ptr in %p, out %p", mtls->ptrIn, mtls->ptrOut);
Jason Sams96cd1362011-10-12 18:33:01 -0700220
Jason Sams8eaba4f2012-08-14 14:38:05 -0700221 p.out = mtls->fep.ptrOut + (mtls->fep.eStrideOut * xStart);
222 p.in = mtls->fep.ptrIn + (mtls->fep.eStrideIn * xStart);
223 fn(&p, xStart, xEnd, mtls->fep.eStrideIn, mtls->fep.eStrideOut);
Jason Samscdfdb8f2011-03-17 16:12:47 -0700224 }
225}
226
Jason Samsdbe66d62012-09-17 13:54:41 -0700227void rsdScriptInvokeForEachMtlsSetup(const Context *rsc,
228 const Allocation * ain,
229 Allocation * aout,
230 const void * usr,
231 uint32_t usrLen,
232 const RsScriptCall *sc,
233 MTLaunchStruct *mtls) {
234
235 memset(mtls, 0, sizeof(MTLaunchStruct));
236
237 if (ain) {
238 mtls->fep.dimX = ain->getType()->getDimX();
239 mtls->fep.dimY = ain->getType()->getDimY();
240 mtls->fep.dimZ = ain->getType()->getDimZ();
241 //mtls->dimArray = ain->getType()->getDimArray();
242 } else if (aout) {
243 mtls->fep.dimX = aout->getType()->getDimX();
244 mtls->fep.dimY = aout->getType()->getDimY();
245 mtls->fep.dimZ = aout->getType()->getDimZ();
246 //mtls->dimArray = aout->getType()->getDimArray();
247 } else {
248 rsc->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
249 return;
250 }
251
252 if (!sc || (sc->xEnd == 0)) {
253 mtls->xEnd = mtls->fep.dimX;
254 } else {
255 rsAssert(sc->xStart < mtls->fep.dimX);
256 rsAssert(sc->xEnd <= mtls->fep.dimX);
257 rsAssert(sc->xStart < sc->xEnd);
258 mtls->xStart = rsMin(mtls->fep.dimX, sc->xStart);
259 mtls->xEnd = rsMin(mtls->fep.dimX, sc->xEnd);
260 if (mtls->xStart >= mtls->xEnd) return;
261 }
262
263 if (!sc || (sc->yEnd == 0)) {
264 mtls->yEnd = mtls->fep.dimY;
265 } else {
266 rsAssert(sc->yStart < mtls->fep.dimY);
267 rsAssert(sc->yEnd <= mtls->fep.dimY);
268 rsAssert(sc->yStart < sc->yEnd);
269 mtls->yStart = rsMin(mtls->fep.dimY, sc->yStart);
270 mtls->yEnd = rsMin(mtls->fep.dimY, sc->yEnd);
271 if (mtls->yStart >= mtls->yEnd) return;
272 }
273
274 mtls->xEnd = rsMax((uint32_t)1, mtls->xEnd);
275 mtls->yEnd = rsMax((uint32_t)1, mtls->yEnd);
276 mtls->zEnd = rsMax((uint32_t)1, mtls->zEnd);
277 mtls->arrayEnd = rsMax((uint32_t)1, mtls->arrayEnd);
278
279 rsAssert(!ain || (ain->getType()->getDimZ() == 0));
280
281 Context *mrsc = (Context *)rsc;
282 mtls->rsc = mrsc;
283 mtls->ain = ain;
284 mtls->aout = aout;
285 mtls->fep.usr = usr;
286 mtls->fep.usrLen = usrLen;
287 mtls->mSliceSize = 10;
288 mtls->mSliceNum = 0;
289
290 mtls->fep.ptrIn = NULL;
291 mtls->fep.eStrideIn = 0;
292 if (ain) {
293 DrvAllocation *aindrv = (DrvAllocation *)ain->mHal.drv;
294 mtls->fep.ptrIn = (const uint8_t *)aindrv->lod[0].mallocPtr;
295 mtls->fep.eStrideIn = ain->getType()->getElementSizeBytes();
296 mtls->fep.yStrideIn = aindrv->lod[0].stride;
297 }
298
299 mtls->fep.ptrOut = NULL;
300 mtls->fep.eStrideOut = 0;
301 if (aout) {
302 DrvAllocation *aoutdrv = (DrvAllocation *)aout->mHal.drv;
303 mtls->fep.ptrOut = (uint8_t *)aoutdrv->lod[0].mallocPtr;
304 mtls->fep.eStrideOut = aout->getType()->getElementSizeBytes();
305 mtls->fep.yStrideOut = aoutdrv->lod[0].stride;
306 }
307}
308
309void rsdScriptLaunchThreads(const Context *rsc,
310 Script *s,
311 uint32_t slot,
312 const Allocation * ain,
313 Allocation * aout,
314 const void * usr,
315 uint32_t usrLen,
316 const RsScriptCall *sc,
317 MTLaunchStruct *mtls) {
318
319 Script * oldTLS = setTLS(s);
320 Context *mrsc = (Context *)rsc;
321 RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
322
323 if ((dc->mWorkers.mCount > 1) && s->mHal.info.isThreadable && !dc->mInForEach) {
324 dc->mInForEach = true;
325 if (mtls->fep.dimY > 1) {
326 mtls->mSliceSize = mtls->fep.dimY / (dc->mWorkers.mCount * 4);
327 if(mtls->mSliceSize < 1) {
328 mtls->mSliceSize = 1;
329 }
330
331 rsdLaunchThreads(mrsc, wc_xy, mtls);
332 } else {
333 mtls->mSliceSize = mtls->fep.dimX / (dc->mWorkers.mCount * 4);
334 if(mtls->mSliceSize < 1) {
335 mtls->mSliceSize = 1;
336 }
337
338 rsdLaunchThreads(mrsc, wc_x, mtls);
339 }
340 dc->mInForEach = false;
341
342 //ALOGE("launch 1");
343 } else {
344 RsForEachStubParamStruct p;
345 memcpy(&p, &mtls->fep, sizeof(p));
346 uint32_t sig = mtls->sig;
347
348 //ALOGE("launch 3");
349 outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
350 for (p.ar[0] = mtls->arrayStart; p.ar[0] < mtls->arrayEnd; p.ar[0]++) {
351 for (p.z = mtls->zStart; p.z < mtls->zEnd; p.z++) {
352 for (p.y = mtls->yStart; p.y < mtls->yEnd; p.y++) {
353 uint32_t offset = mtls->fep.dimY * mtls->fep.dimZ * p.ar[0] +
354 mtls->fep.dimY * p.z + p.y;
355 p.out = mtls->fep.ptrOut + (mtls->fep.yStrideOut * offset);
356 p.in = mtls->fep.ptrIn + (mtls->fep.yStrideIn * offset);
357 fn(&p, mtls->xStart, mtls->xEnd, mtls->fep.eStrideIn, mtls->fep.eStrideOut);
358 }
359 }
360 }
361 }
362
363 setTLS(oldTLS);
364}
365
Jason Samscdfdb8f2011-03-17 16:12:47 -0700366void rsdScriptInvokeForEach(const Context *rsc,
367 Script *s,
Jason Sams35e429e2011-07-13 11:26:26 -0700368 uint32_t slot,
Jason Samscdfdb8f2011-03-17 16:12:47 -0700369 const Allocation * ain,
370 Allocation * aout,
371 const void * usr,
372 uint32_t usrLen,
373 const RsScriptCall *sc) {
374
Jason Sams87fe59a2011-04-20 15:09:01 -0700375 RsdHal * dc = (RsdHal *)rsc->mHal.drv;
Jason Samscdfdb8f2011-03-17 16:12:47 -0700376
377 MTLaunchStruct mtls;
Jason Samsdbe66d62012-09-17 13:54:41 -0700378 rsdScriptInvokeForEachMtlsSetup(rsc, ain, aout, usr, usrLen, sc, &mtls);
379 mtls.script = s;
Jason Sams0ab9f9f2012-06-15 16:10:17 -0700380
Stephen Hines3815bad2011-08-18 19:33:01 -0700381 DrvScript *drv = (DrvScript *)s->mHal.drv;
Jason Sams8eaba4f2012-08-14 14:38:05 -0700382 if (drv->mIntrinsicID) {
Jason Sams17f03fc2012-08-21 18:30:01 -0700383 mtls.kernel = (void (*)())drv->mIntrinsicFuncs.root;
Jason Samsdbe66d62012-09-17 13:54:41 -0700384 mtls.fep.usr = drv->mIntrinsicData;
Jason Sams8eaba4f2012-08-14 14:38:05 -0700385 } else {
386 rsAssert(slot < drv->mExecutable->getExportForeachFuncAddrs().size());
387 mtls.kernel = reinterpret_cast<ForEachFunc_t>(
388 drv->mExecutable->getExportForeachFuncAddrs()[slot]);
389 rsAssert(mtls.kernel != NULL);
390 mtls.sig = drv->mExecutable->getInfo().getExportForeachFuncs()[slot].second;
391 }
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700392
Jason Samscdfdb8f2011-03-17 16:12:47 -0700393
Jason Samsdbe66d62012-09-17 13:54:41 -0700394 rsdScriptLaunchThreads(rsc, s, slot, ain, aout, usr, usrLen, sc, &mtls);
Jason Samscdfdb8f2011-03-17 16:12:47 -0700395}
396
397
398int rsdScriptInvokeRoot(const Context *dc, Script *script) {
399 DrvScript *drv = (DrvScript *)script->mHal.drv;
400
401 Script * oldTLS = setTLS(script);
402 int ret = drv->mRoot();
403 setTLS(oldTLS);
404
405 return ret;
406}
407
408void rsdScriptInvokeInit(const Context *dc, Script *script) {
Jason Samsbad80742011-03-16 16:29:28 -0700409 DrvScript *drv = (DrvScript *)script->mHal.drv;
410
411 if (drv->mInit) {
412 drv->mInit();
413 }
414}
415
Stephen Hines4ee16ff2011-08-31 17:41:39 -0700416void rsdScriptInvokeFreeChildren(const Context *dc, Script *script) {
417 DrvScript *drv = (DrvScript *)script->mHal.drv;
418
419 if (drv->mFreeChildren) {
420 drv->mFreeChildren();
421 }
422}
Jason Samsbad80742011-03-16 16:29:28 -0700423
Jason Samscdfdb8f2011-03-17 16:12:47 -0700424void rsdScriptInvokeFunction(const Context *dc, Script *script,
Jason Samsbad80742011-03-16 16:29:28 -0700425 uint32_t slot,
426 const void *params,
427 size_t paramLength) {
428 DrvScript *drv = (DrvScript *)script->mHal.drv;
Steve Blockaf12ac62012-01-06 19:20:56 +0000429 //ALOGE("invoke %p %p %i %p %i", dc, script, slot, params, paramLength);
Jason Samsbad80742011-03-16 16:29:28 -0700430
Jason Samscdfdb8f2011-03-17 16:12:47 -0700431 Script * oldTLS = setTLS(script);
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700432 reinterpret_cast<void (*)(const void *, uint32_t)>(
433 drv->mExecutable->getExportFuncAddrs()[slot])(params, paramLength);
Jason Samscdfdb8f2011-03-17 16:12:47 -0700434 setTLS(oldTLS);
Jason Samsbad80742011-03-16 16:29:28 -0700435}
436
437void rsdScriptSetGlobalVar(const Context *dc, const Script *script,
438 uint32_t slot, void *data, size_t dataLength) {
439 DrvScript *drv = (DrvScript *)script->mHal.drv;
440 //rsAssert(!script->mFieldIsObject[slot]);
Steve Blockaf12ac62012-01-06 19:20:56 +0000441 //ALOGE("setGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength);
Jason Samsbad80742011-03-16 16:29:28 -0700442
Jason Sams8eaba4f2012-08-14 14:38:05 -0700443 if (drv->mIntrinsicID) {
Jason Samse1e08b42012-09-04 16:49:19 -0700444 drv->mIntrinsicFuncs.setVar(dc, script, drv->mIntrinsicData, slot, data, dataLength);
Jason Sams8eaba4f2012-08-14 14:38:05 -0700445 return;
446 }
447
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700448 int32_t *destPtr = reinterpret_cast<int32_t *>(
449 drv->mExecutable->getExportVarAddrs()[slot]);
Jason Samsbad80742011-03-16 16:29:28 -0700450 if (!destPtr) {
Steve Block65982012011-10-20 11:56:00 +0100451 //ALOGV("Calling setVar on slot = %i which is null", slot);
Jason Samsbad80742011-03-16 16:29:28 -0700452 return;
453 }
454
455 memcpy(destPtr, data, dataLength);
456}
457
Stephen Hines2980f072012-04-09 18:26:29 -0700458void rsdScriptSetGlobalVarWithElemDims(
459 const android::renderscript::Context *dc,
460 const android::renderscript::Script *script,
461 uint32_t slot, void *data, size_t dataLength,
462 const android::renderscript::Element *elem,
463 const size_t *dims, size_t dimLength) {
464 DrvScript *drv = (DrvScript *)script->mHal.drv;
465
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700466 int32_t *destPtr = reinterpret_cast<int32_t *>(
467 drv->mExecutable->getExportVarAddrs()[slot]);
Stephen Hines2980f072012-04-09 18:26:29 -0700468 if (!destPtr) {
469 //ALOGV("Calling setVar on slot = %i which is null", slot);
470 return;
471 }
472
473 // We want to look at dimension in terms of integer components,
474 // but dimLength is given in terms of bytes.
475 dimLength /= sizeof(int);
476
477 // Only a single dimension is currently supported.
478 rsAssert(dimLength == 1);
479 if (dimLength == 1) {
480 // First do the increment loop.
481 size_t stride = elem->getSizeBytes();
482 char *cVal = reinterpret_cast<char *>(data);
483 for (size_t i = 0; i < dims[0]; i++) {
484 elem->incRefs(cVal);
485 cVal += stride;
486 }
487
488 // Decrement loop comes after (to prevent race conditions).
489 char *oldVal = reinterpret_cast<char *>(destPtr);
490 for (size_t i = 0; i < dims[0]; i++) {
491 elem->decRefs(oldVal);
492 oldVal += stride;
493 }
494 }
495
496 memcpy(destPtr, data, dataLength);
497}
498
Jason Sams807fdc42012-07-25 17:55:39 -0700499void rsdScriptSetGlobalBind(const Context *dc, const Script *script, uint32_t slot, Allocation *data) {
Jason Samsbad80742011-03-16 16:29:28 -0700500 DrvScript *drv = (DrvScript *)script->mHal.drv;
Jason Sams807fdc42012-07-25 17:55:39 -0700501
Jason Samsbad80742011-03-16 16:29:28 -0700502 //rsAssert(!script->mFieldIsObject[slot]);
Steve Blockaf12ac62012-01-06 19:20:56 +0000503 //ALOGE("setGlobalBind %p %p %i %p", dc, script, slot, data);
Jason Samsbad80742011-03-16 16:29:28 -0700504
Jason Sams17f03fc2012-08-21 18:30:01 -0700505 if (drv->mIntrinsicID) {
Jason Samse1e08b42012-09-04 16:49:19 -0700506 drv->mIntrinsicFuncs.bind(dc, script, drv->mIntrinsicData, slot, data);
Jason Sams17f03fc2012-08-21 18:30:01 -0700507 return;
508 }
509
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700510 int32_t *destPtr = reinterpret_cast<int32_t *>(
511 drv->mExecutable->getExportVarAddrs()[slot]);
Jason Samsbad80742011-03-16 16:29:28 -0700512 if (!destPtr) {
Steve Block65982012011-10-20 11:56:00 +0100513 //ALOGV("Calling setVar on slot = %i which is null", slot);
Jason Samsbad80742011-03-16 16:29:28 -0700514 return;
515 }
516
Jason Sams807fdc42012-07-25 17:55:39 -0700517 void *ptr = NULL;
518 drv->mBoundAllocs[slot] = data;
519 if(data) {
520 DrvAllocation *allocDrv = (DrvAllocation *)data->mHal.drv;
521 ptr = allocDrv->lod[0].mallocPtr;
522 }
523 memcpy(destPtr, &ptr, sizeof(void *));
Jason Samsbad80742011-03-16 16:29:28 -0700524}
525
526void rsdScriptSetGlobalObj(const Context *dc, const Script *script, uint32_t slot, ObjectBase *data) {
527 DrvScript *drv = (DrvScript *)script->mHal.drv;
528 //rsAssert(script->mFieldIsObject[slot]);
Steve Blockaf12ac62012-01-06 19:20:56 +0000529 //ALOGE("setGlobalObj %p %p %i %p", dc, script, slot, data);
Jason Samsbad80742011-03-16 16:29:28 -0700530
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700531 int32_t *destPtr = reinterpret_cast<int32_t *>(
532 drv->mExecutable->getExportVarAddrs()[slot]);
Jason Samsbad80742011-03-16 16:29:28 -0700533 if (!destPtr) {
Steve Block65982012011-10-20 11:56:00 +0100534 //ALOGV("Calling setVar on slot = %i which is null", slot);
Jason Samsbad80742011-03-16 16:29:28 -0700535 return;
536 }
537
Jason Sams87fe59a2011-04-20 15:09:01 -0700538 rsrSetObject(dc, script, (ObjectBase **)destPtr, data);
Jason Samsbad80742011-03-16 16:29:28 -0700539}
540
541void rsdScriptDestroy(const Context *dc, Script *script) {
542 DrvScript *drv = (DrvScript *)script->mHal.drv;
543
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700544 if (drv == NULL) {
545 return;
546 }
547
548 if (drv->mExecutable) {
549 Vector<void *>::const_iterator var_addr_iter =
550 drv->mExecutable->getExportVarAddrs().begin();
551 Vector<void *>::const_iterator var_addr_end =
552 drv->mExecutable->getExportVarAddrs().end();
553
554 bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_iter =
555 drv->mExecutable->getInfo().getObjectSlots().begin();
556 bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_end =
557 drv->mExecutable->getInfo().getObjectSlots().end();
558
559 while ((var_addr_iter != var_addr_end) &&
560 (is_object_iter != is_object_end)) {
561 // The field address can be NULL if the script-side has optimized
562 // the corresponding global variable away.
563 ObjectBase **obj_addr =
564 reinterpret_cast<ObjectBase **>(*var_addr_iter);
565 if (*is_object_iter) {
566 if (*var_addr_iter != NULL) {
567 rsrClearObject(dc, script, obj_addr);
Stephen Hines8d43eaf2011-03-24 20:03:49 -0700568 }
Jason Samsbad80742011-03-16 16:29:28 -0700569 }
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700570 var_addr_iter++;
571 is_object_iter++;
Jason Samsbad80742011-03-16 16:29:28 -0700572 }
Jason Samsbad80742011-03-16 16:29:28 -0700573 }
Stephen Hines689821f2011-07-18 17:24:11 -0700574
Shih-wei Liaoa3af2cd2012-04-25 04:18:31 -0700575 delete drv->mCompilerContext;
576 delete drv->mCompilerDriver;
577 delete drv->mExecutable;
Jason Sams807fdc42012-07-25 17:55:39 -0700578 delete[] drv->mBoundAllocs;
Jason Samsbad80742011-03-16 16:29:28 -0700579 free(drv);
580 script->mHal.drv = NULL;
Jason Samsbad80742011-03-16 16:29:28 -0700581}
Jason Sams807fdc42012-07-25 17:55:39 -0700582
583Allocation * rsdScriptGetAllocationForPointer(const android::renderscript::Context *dc,
584 const android::renderscript::Script *sc,
585 const void *ptr) {
586 DrvScript *drv = (DrvScript *)sc->mHal.drv;
587 if (!ptr) {
588 return NULL;
589 }
590
591 for (uint32_t ct=0; ct < sc->mHal.info.exportedVariableCount; ct++) {
592 Allocation *a = drv->mBoundAllocs[ct];
593 if (!a) continue;
594 DrvAllocation *adrv = (DrvAllocation *)a->mHal.drv;
595 if (adrv->lod[0].mallocPtr == ptr) {
596 return a;
597 }
598 }
599 ALOGE("rsGetAllocation, failed to find %p", ptr);
600 return NULL;
601}
602