aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--slang_rs_export_foreach.cpp110
-rw-r--r--slang_rs_export_foreach.h15
-rw-r--r--slang_version.h1
3 files changed, 71 insertions, 55 deletions
diff --git a/slang_rs_export_foreach.cpp b/slang_rs_export_foreach.cpp
index b2e82af..ae4d707 100644
--- a/slang_rs_export_foreach.cpp
+++ b/slang_rs_export_foreach.cpp
@@ -57,7 +57,6 @@ bool RSExportForEach::validateAndConstructParams(
RSContext *Context, const clang::FunctionDecl *FD) {
slangAssert(Context && FD);
bool valid = true;
- clang::ASTContext &C = Context->getASTContext();
clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics();
numParams = FD->getNumParams();
@@ -77,17 +76,28 @@ bool RSExportForEach::validateAndConstructParams(
}
mResultType = FD->getResultType().getCanonicalType();
- // Compute kernel functions are required to return a void type or
- // be marked explicitly as a kernel. In the case of
- // "__attribute__((kernel))", we handle validation differently.
+ // Compute kernel functions are defined differently when the
+ // "__attribute__((kernel))" is set.
if (FD->hasAttr<clang::KernelAttr>()) {
- return validateAndConstructKernelParams(Context, FD);
+ valid |= validateAndConstructKernelParams(Context, FD);
+ } else {
+ valid |= validateAndConstructOldStyleParams(Context, FD);
}
+ valid |= setSignatureMetadata(Context, FD);
+ return valid;
+}
+bool RSExportForEach::validateAndConstructOldStyleParams(RSContext *Context,
+ const clang::FunctionDecl *FD) {
+ slangAssert(Context && FD);
// If numParams is 0, we already marked this as a graphics root().
slangAssert(numParams > 0);
- // Compute kernel functions of this type are required to return a void type.
+ bool valid = true;
+ clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics();
+
+ // Compute kernel functions of this style are required to return a void type.
+ clang::ASTContext &C = Context->getASTContext();
if (mResultType != C.VoidTy) {
DiagEngine->Report(
clang::FullSourceLoc(FD->getLocation(), DiagEngine->getSourceManager()),
@@ -194,36 +204,6 @@ bool RSExportForEach::validateAndConstructParams(
i++;
}
- mSignatureMetadata = 0;
- if (valid) {
- // Set up the bitwise metadata encoding for runtime argument passing.
- mSignatureMetadata |= (mIn ? 0x01 : 0);
- mSignatureMetadata |= (mOut ? 0x02 : 0);
- mSignatureMetadata |= (mUsrData ? 0x04 : 0);
- mSignatureMetadata |= (mX ? 0x08 : 0);
- mSignatureMetadata |= (mY ? 0x10 : 0);
- }
-
- if (Context->getTargetAPI() < SLANG_ICS_TARGET_API) {
- // APIs before ICS cannot skip between parameters. It is ok, however, for
- // them to omit further parameters (i.e. skipping X is ok if you skip Y).
- if (mSignatureMetadata != 0x1f && // In, Out, UsrData, X, Y
- mSignatureMetadata != 0x0f && // In, Out, UsrData, X
- mSignatureMetadata != 0x07 && // In, Out, UsrData
- mSignatureMetadata != 0x03 && // In, Out
- mSignatureMetadata != 0x01) { // In
- DiagEngine->Report(
- clang::FullSourceLoc(FD->getLocation(),
- DiagEngine->getSourceManager()),
- DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error,
- "Compute kernel %0() targeting SDK levels "
- "%1-%2 may not skip parameters"))
- << FD->getName() << SLANG_MINIMUM_TARGET_API
- << (SLANG_ICS_TARGET_API - 1);
- valid = false;
- }
- }
-
return valid;
}
@@ -249,10 +229,10 @@ bool RSExportForEach::validateAndConstructKernelParams(RSContext *Context,
}
// Denote that we are indeed a pass-by-value kernel.
- mKernel = true;
+ mIsKernelStyle = true;
if (mResultType != C.VoidTy) {
- mReturn = true;
+ mHasReturnType = true;
}
if (mResultType->isPointerType()) {
@@ -304,7 +284,7 @@ bool RSExportForEach::validateAndConstructKernelParams(RSContext *Context,
}
// Check that we have at least one allocation to use for dimensions.
- if (valid && !mIn && !mReturn) {
+ if (valid && !mIn && !mHasReturnType) {
DiagEngine->Report(
clang::FullSourceLoc(FD->getLocation(),
DiagEngine->getSourceManager()),
@@ -369,24 +349,54 @@ bool RSExportForEach::validateAndConstructKernelParams(RSContext *Context,
i++; // advance parameter pointer
}
+ return valid;
+}
+bool RSExportForEach::setSignatureMetadata(RSContext *Context,
+ const clang::FunctionDecl *FD) {
mSignatureMetadata = 0;
- if (valid) {
- // Set up the bitwise metadata encoding for runtime argument passing.
- mSignatureMetadata |= (mIn ? 0x01 : 0);
+ bool valid = true;
+
+ if (mIsKernelStyle) {
slangAssert(mOut == NULL);
- mSignatureMetadata |= (mReturn ? 0x02 : 0);
slangAssert(mUsrData == NULL);
- mSignatureMetadata |= (mUsrData ? 0x04 : 0);
- mSignatureMetadata |= (mX ? 0x08 : 0);
- mSignatureMetadata |= (mY ? 0x10 : 0);
- mSignatureMetadata |= (mKernel ? 0x20 : 0); // pass-by-value
+ } else {
+ slangAssert(!mHasReturnType);
}
+ // Set up the bitwise metadata encoding for runtime argument passing.
+ // TODO: If this bit field is re-used from C++ code, define the values in a header.
+ const bool HasOut = mOut || mHasReturnType;
+ mSignatureMetadata |= (mIn ? 0x01 : 0);
+ mSignatureMetadata |= (HasOut ? 0x02 : 0);
+ mSignatureMetadata |= (mUsrData ? 0x04 : 0);
+ mSignatureMetadata |= (mX ? 0x08 : 0);
+ mSignatureMetadata |= (mY ? 0x10 : 0);
+ mSignatureMetadata |= (mIsKernelStyle ? 0x20 : 0); // pass-by-value
+
+ if (Context->getTargetAPI() < SLANG_ICS_TARGET_API) {
+ // APIs before ICS cannot skip between parameters. It is ok, however, for
+ // them to omit further parameters (i.e. skipping X is ok if you skip Y).
+ if (mSignatureMetadata != 0x1f && // In, Out, UsrData, X, Y
+ mSignatureMetadata != 0x0f && // In, Out, UsrData, X
+ mSignatureMetadata != 0x07 && // In, Out, UsrData
+ mSignatureMetadata != 0x03 && // In, Out
+ mSignatureMetadata != 0x01) { // In
+ clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics();
+ DiagEngine->Report(clang::FullSourceLoc(FD->getLocation(),
+ DiagEngine->getSourceManager()),
+ DiagEngine->getCustomDiagID(
+ clang::DiagnosticsEngine::Error,
+ "Compute kernel %0() targeting SDK levels "
+ "%1-%2 may not skip parameters"))
+ << FD->getName() << SLANG_MINIMUM_TARGET_API
+ << (SLANG_ICS_TARGET_API - 1);
+ valid = false;
+ }
+ }
return valid;
}
-
RSExportForEach *RSExportForEach::Create(RSContext *Context,
const clang::FunctionDecl *FD) {
slangAssert(Context && FD);
@@ -464,12 +474,12 @@ RSExportForEach *RSExportForEach::Create(RSContext *Context,
if (FE->mIn) {
const clang::Type *T = FE->mIn->getType().getCanonicalType().getTypePtr();
FE->mInType = RSExportType::Create(Context, T);
- if (FE->mKernel) {
+ if (FE->mIsKernelStyle) {
slangAssert(FE->mInType);
}
}
- if (FE->mKernel && FE->mReturn) {
+ if (FE->mIsKernelStyle && FE->mHasReturnType) {
const clang::Type *T = FE->mResultType.getTypePtr();
FE->mOutType = RSExportType::Create(Context, T);
slangAssert(FE->mOutType);
diff --git a/slang_rs_export_foreach.h b/slang_rs_export_foreach.h
index 6cacc60..14266d5 100644
--- a/slang_rs_export_foreach.h
+++ b/slang_rs_export_foreach.h
@@ -54,8 +54,8 @@ class RSExportForEach : public RSExportable {
const clang::ParmVarDecl *mAr;
clang::QualType mResultType; // return type (if present).
- bool mReturn; // does this kernel have a return type?
- bool mKernel; // is this a pass-by-value kernel?
+ bool mHasReturnType; // does this kernel have a return type?
+ bool mIsKernelStyle; // is this a pass-by-value kernel?
bool mDummyRoot;
@@ -65,17 +65,22 @@ class RSExportForEach : public RSExportable {
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), mResultType(clang::QualType()), mReturn(false),
- mKernel(false), mDummyRoot(false) {
+ mAr(NULL), mResultType(clang::QualType()), mHasReturnType(false),
+ mIsKernelStyle(false), mDummyRoot(false) {
return;
}
bool validateAndConstructParams(RSContext *Context,
const clang::FunctionDecl *FD);
+ bool validateAndConstructOldStyleParams(RSContext *Context,
+ const clang::FunctionDecl *FD);
+
bool validateAndConstructKernelParams(RSContext *Context,
const clang::FunctionDecl *FD);
+ bool setSignatureMetadata(RSContext *Context,
+ const clang::FunctionDecl *FD);
public:
static RSExportForEach *Create(RSContext *Context,
const clang::FunctionDecl *FD);
@@ -103,7 +108,7 @@ class RSExportForEach : public RSExportable {
}
inline bool hasReturn() const {
- return mReturn;
+ return mHasReturnType;
}
inline const RSExportType *getInType() const {
diff --git a/slang_version.h b/slang_version.h
index 287dc3e..e42f1a5 100644
--- a/slang_version.h
+++ b/slang_version.h
@@ -22,6 +22,7 @@
// HC -> Honeycomb
// ICS -> Ice Cream Sandwich
// JB -> Jelly Bean
+// KK -> KitKat
enum SlangTargetAPI {
SLANG_MINIMUM_TARGET_API = 11,
SLANG_HC_TARGET_API = 11,