blob: 247f4dc163affb0a63ed7f14bfa60287af3beda0 [file] [log] [blame]
Jason Samsbad80742011-03-16 16:29:28 -07001/*
Jason Sams4b3de472011-04-06 17:52:23 -07002 * Copyright (C) 2011 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
17#include "rsdCore.h"
Jason Samseb4fe182011-05-26 16:33:01 -070018#include "rsdAllocation.h"
Jason Samsbad80742011-03-16 16:29:28 -070019#include "rsdBcc.h"
Jason Sams4b3de472011-04-06 17:52:23 -070020#include "rsdGL.h"
Jason Sams8feea4e2011-03-18 15:03:25 -070021#include "rsdProgramStore.h"
Jason Sams721acc42011-04-06 11:23:54 -070022#include "rsdProgramRaster.h"
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070023#include "rsdProgramVertex.h"
24#include "rsdProgramFragment.h"
25#include "rsdMesh.h"
Alex Sakhartchouk7f126c72011-05-05 16:56:27 -070026#include "rsdSampler.h"
Alex Sakhartchoukda6d34a2011-05-13 14:53:34 -070027#include "rsdFrameBuffer.h"
Jason Samsbad80742011-03-16 16:29:28 -070028
29#include <malloc.h>
30#include "rsContext.h"
31
Jason Samscdfdb8f2011-03-17 16:12:47 -070032#include <sys/types.h>
33#include <sys/resource.h>
34#include <sched.h>
35#include <cutils/properties.h>
36#include <cutils/sched_policy.h>
37#include <sys/syscall.h>
38#include <string.h>
Alex Sakhartchoukb81a0eb2011-06-03 10:18:01 -070039#include <bcc/bcc.h>
Jason Samscdfdb8f2011-03-17 16:12:47 -070040
Jason Samsbad80742011-03-16 16:29:28 -070041using namespace android;
42using namespace android::renderscript;
43
Jason Samscdfdb8f2011-03-17 16:12:47 -070044static void Shutdown(Context *rsc);
45static void SetPriority(const Context *rsc, int32_t priority);
Stephen Hines3815bad2011-08-18 19:33:01 -070046static void initForEach(outer_foreach_t* forEachLaunch);
Jason Samscdfdb8f2011-03-17 16:12:47 -070047
Jason Samsbad80742011-03-16 16:29:28 -070048static RsdHalFunctions FunctionTable = {
Jason Sams4b3de472011-04-06 17:52:23 -070049 rsdGLInit,
50 rsdGLShutdown,
51 rsdGLSetSurface,
52 rsdGLSwap,
53
Jason Samscdfdb8f2011-03-17 16:12:47 -070054 Shutdown,
Jason Samsbad80742011-03-16 16:29:28 -070055 NULL,
Jason Samscdfdb8f2011-03-17 16:12:47 -070056 SetPriority,
Jason Samsbad80742011-03-16 16:29:28 -070057 {
58 rsdScriptInit,
59 rsdScriptInvokeFunction,
60 rsdScriptInvokeRoot,
Jason Samscdfdb8f2011-03-17 16:12:47 -070061 rsdScriptInvokeForEach,
Jason Samsbad80742011-03-16 16:29:28 -070062 rsdScriptInvokeInit,
Stephen Hines4ee16ff2011-08-31 17:41:39 -070063 rsdScriptInvokeFreeChildren,
Jason Samsbad80742011-03-16 16:29:28 -070064 rsdScriptSetGlobalVar,
65 rsdScriptSetGlobalBind,
66 rsdScriptSetGlobalObj,
67 rsdScriptDestroy
Jason Sams8feea4e2011-03-18 15:03:25 -070068 },
69
Jason Samseb4fe182011-05-26 16:33:01 -070070 {
71 rsdAllocationInit,
72 rsdAllocationDestroy,
73 rsdAllocationResize,
74 rsdAllocationSyncAll,
75 rsdAllocationMarkDirty,
76 rsdAllocationData1D,
77 rsdAllocationData2D,
78 rsdAllocationData3D,
Alex Sakhartchouk74a82792011-06-14 11:13:19 -070079 rsdAllocationData1D_alloc,
80 rsdAllocationData2D_alloc,
81 rsdAllocationData3D_alloc,
Jason Samseb4fe182011-05-26 16:33:01 -070082 rsdAllocationElementData1D,
83 rsdAllocationElementData2D
84 },
85
Jason Sams8feea4e2011-03-18 15:03:25 -070086
87 {
88 rsdProgramStoreInit,
89 rsdProgramStoreSetActive,
90 rsdProgramStoreDestroy
Jason Sams721acc42011-04-06 11:23:54 -070091 },
92
93 {
94 rsdProgramRasterInit,
95 rsdProgramRasterSetActive,
96 rsdProgramRasterDestroy
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070097 },
98
99 {
100 rsdProgramVertexInit,
101 rsdProgramVertexSetActive,
102 rsdProgramVertexDestroy
103 },
104
105 {
106 rsdProgramFragmentInit,
107 rsdProgramFragmentSetActive,
108 rsdProgramFragmentDestroy
109 },
110
111 {
112 rsdMeshInit,
113 rsdMeshDraw,
114 rsdMeshDestroy
Alex Sakhartchouk7f126c72011-05-05 16:56:27 -0700115 },
116
117 {
118 rsdSamplerInit,
119 rsdSamplerDestroy
120 },
Jason Sams8feea4e2011-03-18 15:03:25 -0700121
Alex Sakhartchoukda6d34a2011-05-13 14:53:34 -0700122 {
123 rsdFrameBufferInit,
124 rsdFrameBufferSetActive,
125 rsdFrameBufferDestroy
126 },
127
Jason Samsbad80742011-03-16 16:29:28 -0700128};
129
Jason Sams83c451a2011-04-21 11:46:50 -0700130pthread_key_t rsdgThreadTLSKey = 0;
131uint32_t rsdgThreadTLSKeyCount = 0;
132pthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
Jason Samsbad80742011-03-16 16:29:28 -0700133
Jason Samscdfdb8f2011-03-17 16:12:47 -0700134
135static void * HelperThreadProc(void *vrsc) {
136 Context *rsc = static_cast<Context *>(vrsc);
Jason Sams87fe59a2011-04-20 15:09:01 -0700137 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Samscdfdb8f2011-03-17 16:12:47 -0700138
139
140 uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
141
142 //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
143
144 dc->mWorkers.mLaunchSignals[idx].init();
145 dc->mWorkers.mNativeThreadId[idx] = gettid();
146
Jason Sams83c451a2011-04-21 11:46:50 -0700147 int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
148 if (status) {
149 LOGE("pthread_setspecific %i", status);
150 }
151
Jason Samscdfdb8f2011-03-17 16:12:47 -0700152#if 0
153 typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
154 cpu_set_t cpuset;
155 memset(&cpuset, 0, sizeof(cpuset));
156 cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
157 int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
158 sizeof(cpuset), &cpuset);
159 LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
160#endif
161
Jason Samscdfdb8f2011-03-17 16:12:47 -0700162 while (!dc->mExit) {
163 dc->mWorkers.mLaunchSignals[idx].wait();
164 if (dc->mWorkers.mLaunchCallback) {
165 dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
166 }
167 android_atomic_dec(&dc->mWorkers.mRunningCount);
168 dc->mWorkers.mCompleteSignal.set();
169 }
170
171 //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
172 return NULL;
173}
174
175void rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700176 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Samscdfdb8f2011-03-17 16:12:47 -0700177
178 dc->mWorkers.mLaunchData = data;
179 dc->mWorkers.mLaunchCallback = cbk;
180 android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
181 for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
182 dc->mWorkers.mLaunchSignals[ct].set();
183 }
184 while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
185 dc->mWorkers.mCompleteSignal.wait();
186 }
187}
188
Jason Samsbad80742011-03-16 16:29:28 -0700189bool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) {
190 rsc->mHal.funcs = FunctionTable;
191
Jason Sams87fe59a2011-04-20 15:09:01 -0700192 RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal));
Jason Sams2cfe51e2011-03-18 17:08:54 -0700193 if (!dc) {
194 LOGE("Calloc for driver hal failed.");
Jason Samsbad80742011-03-16 16:29:28 -0700195 return false;
196 }
Jason Samscdfdb8f2011-03-17 16:12:47 -0700197 rsc->mHal.drv = dc;
Jason Samsbad80742011-03-16 16:29:28 -0700198
Jason Sams83c451a2011-04-21 11:46:50 -0700199 pthread_mutex_lock(&rsdgInitMutex);
200 if (!rsdgThreadTLSKeyCount) {
201 int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
202 if (status) {
203 LOGE("Failed to init thread tls key.");
204 pthread_mutex_unlock(&rsdgInitMutex);
205 return false;
206 }
207 }
208 rsdgThreadTLSKeyCount++;
209 pthread_mutex_unlock(&rsdgInitMutex);
210
Stephen Hines3815bad2011-08-18 19:33:01 -0700211 initForEach(dc->mForEachLaunch);
212
Jason Sams83c451a2011-04-21 11:46:50 -0700213 dc->mTlsStruct.mContext = rsc;
214 dc->mTlsStruct.mScript = NULL;
215 int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
216 if (status) {
217 LOGE("pthread_setspecific %i", status);
218 }
219
Jason Samscdfdb8f2011-03-17 16:12:47 -0700220
221 int cpu = sysconf(_SC_NPROCESSORS_ONLN);
Jason Sams86d842a2011-09-20 16:59:22 -0700222 LOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
Jason Samscdfdb8f2011-03-17 16:12:47 -0700223 if (cpu < 2) cpu = 0;
224
225 dc->mWorkers.mCount = (uint32_t)cpu;
226 dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
227 dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
228 dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
229 dc->mWorkers.mLaunchCallback = NULL;
230
231 dc->mWorkers.mCompleteSignal.init();
232
233 android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
234 android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
235
Jason Samscdfdb8f2011-03-17 16:12:47 -0700236 pthread_attr_t threadAttr;
237 status = pthread_attr_init(&threadAttr);
238 if (status) {
239 LOGE("Failed to init thread attribute.");
240 return false;
241 }
242
243 for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
244 status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
245 if (status) {
246 dc->mWorkers.mCount = ct;
247 LOGE("Created fewer than expected number of RS threads.");
248 break;
249 }
250 }
251 while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
252 usleep(100);
253 }
254
255 pthread_attr_destroy(&threadAttr);
Jason Samsbad80742011-03-16 16:29:28 -0700256 return true;
257}
258
Jason Samscdfdb8f2011-03-17 16:12:47 -0700259
260void SetPriority(const Context *rsc, int32_t priority) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700261 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Samscdfdb8f2011-03-17 16:12:47 -0700262 for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
263 setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
264 }
265}
266
267void Shutdown(Context *rsc) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700268 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Samscdfdb8f2011-03-17 16:12:47 -0700269
270 dc->mExit = true;
271 dc->mWorkers.mLaunchData = NULL;
272 dc->mWorkers.mLaunchCallback = NULL;
273 android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
274 for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
275 dc->mWorkers.mLaunchSignals[ct].set();
276 }
277 int status;
278 void *res;
279 for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
280 status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
281 }
282 rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
Jason Sams83c451a2011-04-21 11:46:50 -0700283
284 // Global structure cleanup.
285 pthread_mutex_lock(&rsdgInitMutex);
286 --rsdgThreadTLSKeyCount;
287 if (!rsdgThreadTLSKeyCount) {
288 pthread_key_delete(rsdgThreadTLSKey);
289 }
290 pthread_mutex_unlock(&rsdgInitMutex);
291
Jason Samscdfdb8f2011-03-17 16:12:47 -0700292}
293
Stephen Hines3815bad2011-08-18 19:33:01 -0700294static void rsdForEach17(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700295 const android::renderscript::RsForEachStubParamStruct *p,
296 uint32_t x1, uint32_t x2,
297 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700298 typedef void (*fe)(const void *, uint32_t);
299 (*(fe*)vRoot)(p->in, p->y);
300}
301
302static void rsdForEach18(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700303 const android::renderscript::RsForEachStubParamStruct *p,
304 uint32_t x1, uint32_t x2,
305 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700306 typedef void (*fe)(void *, uint32_t);
307 (*(fe*)vRoot)(p->out, p->y);
308}
309
310static void rsdForEach19(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700311 const android::renderscript::RsForEachStubParamStruct *p,
312 uint32_t x1, uint32_t x2,
313 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700314 typedef void (*fe)(const void *, void *, uint32_t);
315 (*(fe*)vRoot)(p->in, p->out, p->y);
316}
317
318static void rsdForEach21(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700319 const android::renderscript::RsForEachStubParamStruct *p,
320 uint32_t x1, uint32_t x2,
321 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700322 typedef void (*fe)(const void *, const void *, uint32_t);
323 (*(fe*)vRoot)(p->in, p->usr, p->y);
324}
325
326static void rsdForEach22(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700327 const android::renderscript::RsForEachStubParamStruct *p,
328 uint32_t x1, uint32_t x2,
329 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700330 typedef void (*fe)(void *, const void *, uint32_t);
331 (*(fe*)vRoot)(p->out, p->usr, p->y);
332}
333
334static void rsdForEach23(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700335 const android::renderscript::RsForEachStubParamStruct *p,
336 uint32_t x1, uint32_t x2,
337 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700338 typedef void (*fe)(const void *, void *, const void *, uint32_t);
339 (*(fe*)vRoot)(p->in, p->out, p->usr, p->y);
340}
341
342static void rsdForEach25(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700343 const android::renderscript::RsForEachStubParamStruct *p,
344 uint32_t x1, uint32_t x2,
345 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700346 typedef void (*fe)(const void *, uint32_t, uint32_t);
Jason Sams70415112011-10-11 18:44:05 -0700347 const uint8_t *pin = (const uint8_t *)p->in;
348 uint32_t y = p->y;
349 for (uint32_t x = x1; x < x2; x++) {
350 (*(fe*)vRoot)(pin, x, y);
351 pin += instep;
352 }
Stephen Hines3815bad2011-08-18 19:33:01 -0700353}
354
355static void rsdForEach26(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700356 const android::renderscript::RsForEachStubParamStruct *p,
357 uint32_t x1, uint32_t x2,
358 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700359 typedef void (*fe)(void *, uint32_t, uint32_t);
Jason Sams70415112011-10-11 18:44:05 -0700360 uint8_t *pout = (uint8_t *)p->out;
361 uint32_t y = p->y;
362 for (uint32_t x = x1; x < x2; x++) {
363 (*(fe*)vRoot)(pout, x, y);
364 pout += outstep;
365 }
Stephen Hines3815bad2011-08-18 19:33:01 -0700366}
367
368static void rsdForEach27(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700369 const android::renderscript::RsForEachStubParamStruct *p,
370 uint32_t x1, uint32_t x2,
371 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700372 typedef void (*fe)(const void *, void *, uint32_t, uint32_t);
Jason Sams70415112011-10-11 18:44:05 -0700373 uint8_t *pout = (uint8_t *)p->out;
374 const uint8_t *pin = (const uint8_t *)p->in;
375 uint32_t y = p->y;
376 for (uint32_t x = x1; x < x2; x++) {
377 (*(fe*)vRoot)(pin, pout, x, y);
378 pin += instep;
379 pout += outstep;
380 }
Stephen Hines3815bad2011-08-18 19:33:01 -0700381}
382
383static void rsdForEach29(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700384 const android::renderscript::RsForEachStubParamStruct *p,
385 uint32_t x1, uint32_t x2,
386 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700387 typedef void (*fe)(const void *, const void *, uint32_t, uint32_t);
Jason Sams70415112011-10-11 18:44:05 -0700388 const uint8_t *pin = (const uint8_t *)p->in;
389 const void *usr = p->usr;
390 const uint32_t y = p->y;
391 for (uint32_t x = x1; x < x2; x++) {
392 (*(fe*)vRoot)(pin, usr, x, y);
393 pin += instep;
394 }
Stephen Hines3815bad2011-08-18 19:33:01 -0700395}
396
397static void rsdForEach30(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700398 const android::renderscript::RsForEachStubParamStruct *p,
399 uint32_t x1, uint32_t x2,
400 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700401 typedef void (*fe)(void *, const void *, uint32_t, uint32_t);
Jason Sams70415112011-10-11 18:44:05 -0700402 uint8_t *pout = (uint8_t *)p->out;
403 const void *usr = p->usr;
404 const uint32_t y = p->y;
405 for (uint32_t x = x1; x < x2; x++) {
406 (*(fe*)vRoot)(pout, usr, x, y);
407 pout += outstep;
408 }
Stephen Hines3815bad2011-08-18 19:33:01 -0700409}
410
411static void rsdForEach31(const void *vRoot,
Jason Sams70415112011-10-11 18:44:05 -0700412 const android::renderscript::RsForEachStubParamStruct *p,
413 uint32_t x1, uint32_t x2,
414 uint32_t instep, uint32_t outstep) {
Stephen Hines3815bad2011-08-18 19:33:01 -0700415 typedef void (*fe)(const void *, void *, const void *, uint32_t, uint32_t);
Jason Sams70415112011-10-11 18:44:05 -0700416 uint8_t *pout = (uint8_t *)p->out;
417 const uint8_t *pin = (const uint8_t *)p->in;
418 const void *usr = p->usr;
419 const uint32_t y = p->y;
420 for (uint32_t x = x1; x < x2; x++) {
421 (*(fe*)vRoot)(pin, pout, usr, x, y);
422 pin += instep;
423 pout += outstep;
424 }
Stephen Hines3815bad2011-08-18 19:33:01 -0700425}
426
427
428static void initForEach(outer_foreach_t* forEachLaunch) {
429 rsAssert(forEachLaunch);
430 forEachLaunch[0x00] = NULL;
431 forEachLaunch[0x01] = rsdForEach31; // in
432 forEachLaunch[0x02] = rsdForEach30; // out
433 forEachLaunch[0x03] = rsdForEach31; // in, out
434 forEachLaunch[0x04] = NULL;
435 forEachLaunch[0x05] = rsdForEach29; // in, usr
436 forEachLaunch[0x06] = rsdForEach30; // out, usr
437 forEachLaunch[0x07] = rsdForEach31; // in, out, usr
438 forEachLaunch[0x08] = NULL;
439 forEachLaunch[0x09] = rsdForEach25; // in, x
440 forEachLaunch[0x0a] = rsdForEach26; // out, x
441 forEachLaunch[0x0b] = rsdForEach27; // in, out, x
442 forEachLaunch[0x0c] = NULL;
443 forEachLaunch[0x0d] = rsdForEach29; // in, usr, x
444 forEachLaunch[0x0e] = rsdForEach30; // out, usr, x
445 forEachLaunch[0x0f] = rsdForEach31; // in, out, usr, x
446 forEachLaunch[0x10] = NULL;
447 forEachLaunch[0x11] = rsdForEach17; // in y
448 forEachLaunch[0x12] = rsdForEach18; // out, y
449 forEachLaunch[0x13] = rsdForEach19; // in, out, y
450 forEachLaunch[0x14] = NULL;
451 forEachLaunch[0x15] = rsdForEach21; // in, usr, y
452 forEachLaunch[0x16] = rsdForEach22; // out, usr, y
453 forEachLaunch[0x17] = rsdForEach23; // in, out, usr, y
454 forEachLaunch[0x18] = NULL;
455 forEachLaunch[0x19] = rsdForEach25; // in, x, y
456 forEachLaunch[0x1a] = rsdForEach26; // out, x, y
457 forEachLaunch[0x1b] = rsdForEach27; // in, out, x, y
458 forEachLaunch[0x1c] = NULL;
459 forEachLaunch[0x1d] = rsdForEach29; // in, usr, x, y
460 forEachLaunch[0x1e] = rsdForEach30; // out, usr, x, y
461 forEachLaunch[0x1f] = rsdForEach31; // in, out, usr, x, y
462}
Jason Samscdfdb8f2011-03-17 16:12:47 -0700463