Support dummy root() and re-ordering in presence of non-root kernels.
BUG=6000538
Change-Id: Ib3ed249916d36acf68ab32e9216804ae1da5e991
diff --git a/slang_rs_context.cpp b/slang_rs_context.cpp
index 5d4f26d..242ecb1 100644
--- a/slang_rs_context.cpp
+++ b/slang_rs_context.cpp
@@ -183,6 +183,42 @@
return (ET != NULL);
}
+
+// Possibly re-order ForEach exports (maybe generating a dummy "root" function).
+// We require "root" to be listed as slot 0 of our exported compute kernels,
+// so this only needs to be created if we have other non-root kernels.
+void RSContext::cleanupForEach() {
+ bool foundNonRoot = false;
+ ExportForEachList::iterator begin = mExportForEach.begin();
+
+ for (ExportForEachList::iterator I = begin, E = mExportForEach.end();
+ I != E;
+ I++) {
+ RSExportForEach *EFE = *I;
+ if (!EFE->getName().compare("root")) {
+ if (I == begin) {
+ // Nothing to do, since it is the first function
+ return;
+ }
+
+ mExportForEach.erase(I);
+ mExportForEach.push_front(EFE);
+ return;
+ } else {
+ foundNonRoot = true;
+ }
+ }
+
+ // If we found a non-root kernel, but no root() function, we need to add a
+ // dummy version (so that script->script calls of rsForEach don't behave
+ // erratically).
+ if (foundNonRoot) {
+ RSExportForEach *DummyRoot = RSExportForEach::CreateDummyRoot(this);
+ mExportForEach.push_front(DummyRoot);
+ }
+}
+
+
bool RSContext::processExport() {
bool valid = true;
@@ -214,6 +250,10 @@
}
}
+ if (valid) {
+ cleanupForEach();
+ }
+
// Finally, export type forcely set to be exported by user
for (NeedExportTypeSet::const_iterator EI = mNeedExportTypes.begin(),
EE = mNeedExportTypes.end();
diff --git a/slang_rs_context.h b/slang_rs_context.h
index 030338b..4024300 100644
--- a/slang_rs_context.h
+++ b/slang_rs_context.h
@@ -89,6 +89,8 @@
bool processExportFunc(const clang::FunctionDecl *FD);
bool processExportType(const llvm::StringRef &Name);
+ void cleanupForEach();
+
ExportVarList mExportVars;
ExportFuncList mExportFuncs;
ExportForEachList mExportForEach;
diff --git a/slang_rs_export_foreach.cpp b/slang_rs_export_foreach.cpp
index 7e3b5bb..3b759b4 100644
--- a/slang_rs_export_foreach.cpp
+++ b/slang_rs_export_foreach.cpp
@@ -224,7 +224,7 @@
slangAssert(!Name.empty() && "Function must have a name");
- FE = new RSExportForEach(Context, Name, FD);
+ FE = new RSExportForEach(Context, Name);
if (!FE->validateAndConstructParams(Context, FD)) {
return NULL;
@@ -303,6 +303,14 @@
return FE;
}
+RSExportForEach *RSExportForEach::CreateDummyRoot(RSContext *Context) {
+ slangAssert(Context);
+ llvm::StringRef Name = "root";
+ RSExportForEach *FE = new RSExportForEach(Context, Name);
+ FE->mDummyRoot = true;
+ return FE;
+}
+
bool RSExportForEach::isGraphicsRootRSFunc(int targetAPI,
const clang::FunctionDecl *FD) {
if (!isRootRSFunc(FD)) {
diff --git a/slang_rs_export_foreach.h b/slang_rs_export_foreach.h
index 0d6409c..c8b1dd0 100644
--- a/slang_rs_export_foreach.h
+++ b/slang_rs_export_foreach.h
@@ -53,14 +53,15 @@
const clang::ParmVarDecl *mZ;
const clang::ParmVarDecl *mAr;
+ bool mDummyRoot;
+
// TODO(all): Add support for LOD/face when we have them
- RSExportForEach(RSContext *Context, const llvm::StringRef &Name,
- const clang::FunctionDecl *FD)
+ RSExportForEach(RSContext *Context, const llvm::StringRef &Name)
: RSExportable(Context, RSExportable::EX_FOREACH),
mName(Name.data(), Name.size()), mParamPacketType(NULL), mInType(NULL),
mOutType(NULL), numParams(0), mSignatureMetadata(0),
mIn(NULL), mOut(NULL), mUsrData(NULL),
- mX(NULL), mY(NULL), mZ(NULL), mAr(NULL) {
+ mX(NULL), mY(NULL), mZ(NULL), mAr(NULL), mDummyRoot(false) {
return;
}
@@ -71,6 +72,8 @@
static RSExportForEach *Create(RSContext *Context,
const clang::FunctionDecl *FD);
+ static RSExportForEach *CreateDummyRoot(RSContext *Context);
+
inline const std::string &getName() const {
return mName;
}
@@ -107,6 +110,10 @@
return mSignatureMetadata;
}
+ inline bool isDummyRoot() const {
+ return mDummyRoot;
+ }
+
typedef RSExportRecordType::const_field_iterator const_param_iterator;
inline const_param_iterator params_begin() const {
diff --git a/slang_rs_reflection.cpp b/slang_rs_reflection.cpp
index 4b2a04c..259931b 100644
--- a/slang_rs_reflection.cpp
+++ b/slang_rs_reflection.cpp
@@ -977,6 +977,15 @@
}
void RSReflection::genExportForEach(Context &C, const RSExportForEach *EF) {
+ if (EF->isDummyRoot()) {
+ // Skip reflection for dummy root() kernels. Note that we have to
+ // advance the next slot number for ForEach, however.
+ C.indent() << "//private final static int "RS_EXPORT_FOREACH_INDEX_PREFIX
+ << EF->getName() << " = " << C.getNextExportForEachSlot() << ";"
+ << std::endl;
+ return;
+ }
+
C.indent() << "private final static int "RS_EXPORT_FOREACH_INDEX_PREFIX
<< EF->getName() << " = " << C.getNextExportForEachSlot() << ";"
<< std::endl;
diff --git a/tests/P_dummy_root/dummy_root.rs b/tests/P_dummy_root/dummy_root.rs
new file mode 100644
index 0000000..7731d94
--- /dev/null
+++ b/tests/P_dummy_root/dummy_root.rs
@@ -0,0 +1,5 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void foo (int *p) {
+}
diff --git a/tests/P_dummy_root/stderr.txt.expect b/tests/P_dummy_root/stderr.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/P_dummy_root/stderr.txt.expect
diff --git a/tests/P_dummy_root/stdout.txt.expect b/tests/P_dummy_root/stdout.txt.expect
new file mode 100644
index 0000000..cbcf1f9
--- /dev/null
+++ b/tests/P_dummy_root/stdout.txt.expect
@@ -0,0 +1 @@
+Generating ScriptC_dummy_root.java ...
diff --git a/tests/P_ooo_compute/ooo_compute.rs b/tests/P_ooo_compute/ooo_compute.rs
new file mode 100644
index 0000000..961bcd2
--- /dev/null
+++ b/tests/P_ooo_compute/ooo_compute.rs
@@ -0,0 +1,13 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void bar(int i, float f) {
+}
+
+void foo (int *p) {
+}
+
+void root(const int *ain, int *aout, const void *usrData,
+ uint32_t x, uint32_t y) {
+}
+
diff --git a/tests/P_ooo_compute/stderr.txt.expect b/tests/P_ooo_compute/stderr.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/P_ooo_compute/stderr.txt.expect
diff --git a/tests/P_ooo_compute/stdout.txt.expect b/tests/P_ooo_compute/stdout.txt.expect
new file mode 100644
index 0000000..48de3ac
--- /dev/null
+++ b/tests/P_ooo_compute/stdout.txt.expect
@@ -0,0 +1 @@
+Generating ScriptC_ooo_compute.java ...