Support running ForEach on non-root functions.
BUG=6000538
Change-Id: Ie2b16893b150cc5955ee4b9d028c988f69a82744
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index bec6ffff..dd78684 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-
#include "rsdCore.h"
#include "rsdBcc.h"
#include "rsdRuntime.h"
@@ -30,7 +29,6 @@
#include "libdex/ZipArchive.h"
}
-
using namespace android;
using namespace android::renderscript;
@@ -45,6 +43,7 @@
bcinfo::MetadataExtractor *ME;
InvokeFunc_t *mInvokeFunctions;
+ ForEachFunc_t *mForEachFunctions;
void ** mFieldAddress;
bool * mFieldIsObject;
const uint32_t *mExportForEachSignatureList;
@@ -162,8 +161,16 @@
}
exportForEachSignatureCount = drv->ME->getExportForEachSignatureCount();
- rsAssert(exportForEachSignatureCount <= 1);
drv->mExportForEachSignatureList = drv->ME->getExportForEachSignatureList();
+ if (exportForEachSignatureCount > 0) {
+ drv->mForEachFunctions =
+ (ForEachFunc_t*) calloc(exportForEachSignatureCount,
+ sizeof(ForEachFunc_t));
+ bccGetExportForEachList(drv->mBccScript, exportForEachSignatureCount,
+ (void **) drv->mForEachFunctions);
+ } else {
+ drv->mForEachFunctions = NULL;
+ }
// Copy info over to runtime
script->mHal.info.exportedFunctionCount = drv->ME->getExportFuncCount();
@@ -196,6 +203,7 @@
typedef struct {
Context *rsc;
Script *script;
+ ForEachFunc_t kernel;
uint32_t sig;
const Allocation * ain;
Allocation * aout;
@@ -235,7 +243,7 @@
RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
uint32_t sig = mtls->sig;
- outer_foreach_t fn = (outer_foreach_t) mtls->script->mHal.info.root;
+ outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
while (1) {
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
@@ -265,7 +273,7 @@
RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
uint32_t sig = mtls->sig;
- outer_foreach_t fn = (outer_foreach_t) mtls->script->mHal.info.root;
+ outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
while (1) {
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
@@ -299,8 +307,8 @@
memset(&mtls, 0, sizeof(mtls));
DrvScript *drv = (DrvScript *)s->mHal.drv;
- // We only support slot 0 (root) at this point in time.
- rsAssert(slot == 0);
+ mtls.kernel = drv->mForEachFunctions[slot];
+ rsAssert(mtls.kernel != NULL);
mtls.sig = 0x1f; // temp fix for old apps, full table in slang_rs_export_foreach.cpp
if (drv->mExportForEachSignatureList) {
mtls.sig = drv->mExportForEachSignatureList[slot];
@@ -391,7 +399,7 @@
uint32_t sig = mtls.sig;
//ALOGE("launch 3");
- outer_foreach_t fn = (outer_foreach_t) mtls.script->mHal.info.root;
+ outer_foreach_t fn = (outer_foreach_t) mtls.kernel;
for (p.ar[0] = mtls.arrayStart; p.ar[0] < mtls.arrayEnd; p.ar[0]++) {
for (p.z = mtls.zStart; p.z < mtls.zEnd; p.z++) {
for (p.y = mtls.yStart; p.y < mtls.yEnd; p.y++) {
@@ -517,6 +525,11 @@
drv->mInvokeFunctions = NULL;
}
+ if (drv->mForEachFunctions) {
+ free(drv->mForEachFunctions);
+ drv->mForEachFunctions = NULL;
+ }
+
delete drv->ME;
drv->ME = NULL;
diff --git a/libs/rs/driver/rsdCore.h b/libs/rs/driver/rsdCore.h
index 168bdf3..05ca13b 100644
--- a/libs/rs/driver/rsdCore.h
+++ b/libs/rs/driver/rsdCore.h
@@ -25,6 +25,7 @@
#include "rsdGL.h"
typedef void (* InvokeFunc_t)(void);
+typedef void (* ForEachFunc_t)(void);
typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
typedef struct RsdSymbolTableRec {
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index 357dbe3..6a3bd4b 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -113,7 +113,7 @@
RsAllocation vain, RsAllocation vaout,
const void *params, size_t paramLen) {
Script *s = static_cast<Script *>(vs);
- s->runForEach(rsc,
+ s->runForEach(rsc, slot,
static_cast<const Allocation *>(vain), static_cast<Allocation *>(vaout),
params, paramLen);
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 99dceaf..7879ea6 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -74,6 +74,7 @@
virtual bool freeChildren();
virtual void runForEach(Context *rsc,
+ uint32_t slot,
const Allocation * ain,
Allocation * aout,
const void * usr,
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index b4eb995..79725b97 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -128,6 +128,7 @@
void ScriptC::runForEach(Context *rsc,
+ uint32_t slot,
const Allocation * ain,
Allocation * aout,
const void * usr,
@@ -138,7 +139,7 @@
setupGLState(rsc);
setupScript(rsc);
- rsc->mHal.funcs.script.invokeForEach(rsc, this, 0, ain, aout, usr, usrBytes, sc);
+ rsc->mHal.funcs.script.invokeForEach(rsc, this, slot, ain, aout, usr, usrBytes, sc);
}
void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, size_t len) {
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index c65a5bf..c89d9b1 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,6 +47,7 @@
virtual uint32_t run(Context *);
virtual void runForEach(Context *rsc,
+ uint32_t slot,
const Allocation * ain,
Allocation * aout,
const void * usr,
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 183e207..a5a0fae 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -157,7 +157,7 @@
Allocation *in, Allocation *out,
const void *usr, uint32_t usrBytes,
const RsScriptCall *call) {
- target->runForEach(rsc, in, out, usr, usrBytes, call);
+ target->runForEach(rsc, /* root slot */ 0, in, out, usr, usrBytes, call);
}
void rsrAllocationSyncAll(Context *rsc, Script *sc, Allocation *a, RsAllocationUsageType usage) {
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index c7bd809..6f56223 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -64,11 +64,6 @@
unitTests = new ArrayList<UnitTest>();
- unitTests.add(new UT_mesh(this, mRes, mCtx));
- unitTests.add(new UT_element(this, mRes, mCtx));
- unitTests.add(new UT_sampler(this, mRes, mCtx));
- unitTests.add(new UT_program_store(this, mRes, mCtx));
- unitTests.add(new UT_program_raster(this, mRes, mCtx));
unitTests.add(new UT_primitives(this, mRes, mCtx));
unitTests.add(new UT_constant(this, mRes, mCtx));
unitTests.add(new UT_vector(this, mRes, mCtx));
@@ -79,10 +74,17 @@
unitTests.add(new UT_alloc(this, mRes, mCtx));
unitTests.add(new UT_refcount(this, mRes, mCtx));
unitTests.add(new UT_foreach(this, mRes, mCtx));
+ unitTests.add(new UT_noroot(this, mRes, mCtx));
unitTests.add(new UT_atomic(this, mRes, mCtx));
unitTests.add(new UT_struct(this, mRes, mCtx));
unitTests.add(new UT_math(this, mRes, mCtx));
+ unitTests.add(new UT_mesh(this, mRes, mCtx));
+ unitTests.add(new UT_element(this, mRes, mCtx));
+ unitTests.add(new UT_sampler(this, mRes, mCtx));
+ unitTests.add(new UT_program_store(this, mRes, mCtx));
+ unitTests.add(new UT_program_raster(this, mRes, mCtx));
unitTests.add(new UT_fp_mad(this, mRes, mCtx));
+
/*
unitTests.add(new UnitTest(null, "<Pass>", 1));
unitTests.add(new UnitTest());
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java
index 1d2555e..04e9270 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,6 +48,9 @@
pRS.setMessageHandler(mRsMessage);
initializeGlobals(pRS, s);
s.forEach_root(A);
+ s.invoke_verify_root();
+ s.forEach_foo(A, A);
+ s.invoke_verify_foo();
s.invoke_foreach_test();
pRS.finish();
waitForMessage();
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java
new file mode 100644
index 0000000..c660fc5
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011-2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class UT_noroot extends UnitTest {
+ private Resources mRes;
+ private Allocation A;
+
+ protected UT_noroot(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "ForEach (no root)", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_noroot s) {
+ Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ int X = 5;
+ int Y = 7;
+ s.set_dimX(X);
+ s.set_dimY(Y);
+ typeBuilder.setX(X).setY(Y);
+ A = Allocation.createTyped(RS, typeBuilder.create());
+ s.bind_a(A);
+
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_noroot s = new ScriptC_noroot(pRS, mRes, R.raw.noroot);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.forEach_foo(A, A);
+ s.invoke_verify_foo();
+ s.invoke_noroot_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs
index 3ba3eef..ac527b5 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs
@@ -3,12 +3,19 @@
int *a;
int dimX;
int dimY;
+static bool failed = false;
void root(int *out, uint32_t x, uint32_t y) {
*out = x + y * dimX;
}
-static bool test_foreach_output() {
+void foo(const int *in, int *out, uint32_t x, uint32_t y) {
+ _RS_ASSERT(*in == (x + y * dimX));
+ *out = 99 + x + y * dimX;
+ _RS_ASSERT(*out == (99 + x + y * dimX));
+}
+
+static bool test_root_output() {
bool failed = false;
int i, j;
@@ -19,19 +26,44 @@
}
if (failed) {
- rsDebug("test_foreach_output FAILED", 0);
+ rsDebug("test_root_output FAILED", 0);
}
else {
- rsDebug("test_foreach_output PASSED", 0);
+ rsDebug("test_root_output PASSED", 0);
}
return failed;
}
-void foreach_test() {
+static bool test_foo_output() {
bool failed = false;
- failed |= test_foreach_output();
+ int i, j;
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ _RS_ASSERT(a[i + j * dimX] == (99 + i + j * dimX));
+ }
+ }
+
+ if (failed) {
+ rsDebug("test_foo_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_foo_output PASSED", 0);
+ }
+
+ return failed;
+}
+
+void verify_root() {
+ failed |= test_root_output();
+}
+
+void verify_foo() {
+ failed |= test_foo_output();
+}
+
+void foreach_test() {
if (failed) {
rsSendToClientBlocking(RS_MSG_TEST_FAILED);
}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs
new file mode 100644
index 0000000..33944aa
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs
@@ -0,0 +1,44 @@
+#include "shared.rsh"
+
+int *a;
+int dimX;
+int dimY;
+static bool failed = false;
+
+void foo(const int *in, int *out, uint32_t x, uint32_t y) {
+ *out = 99 + x + y * dimX;
+}
+
+static bool test_foo_output() {
+ bool failed = false;
+ int i, j;
+
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ _RS_ASSERT(a[i + j * dimX] == (99 + i + j * dimX));
+ }
+ }
+
+ if (failed) {
+ rsDebug("test_foo_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_foo_output PASSED", 0);
+ }
+
+ return failed;
+}
+
+void verify_foo() {
+ failed |= test_foo_output();
+}
+
+void noroot_test() {
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+