Snap for 6439596 from 9822b047aa4423932fa8dd9ace11cdf16d309d3b to qt-aml-tzdata-release
Change-Id: I54c40fa3b4bfb7d6a40ebc88977abae6a34e1657
diff --git a/Android.bp b/Android.bp
index 2742741..d90d40a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -270,6 +270,8 @@
// Treble configuration
shared_libs: [
"libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
"libutilscallstack",
"libutils",
"android.hardware.renderscript@1.0",
diff --git a/build_rs.py b/build_rs.py
index 0416109..8cdbba5 100755
--- a/build_rs.py
+++ b/build_rs.py
@@ -18,6 +18,7 @@
import argparse
import glob
+import multiprocessing
import os
import shutil
import subprocess
@@ -78,6 +79,7 @@
env['TARGET_BUILD_VARIANT'] = 'userdebug'
env['TARGET_PRODUCT'] = product
+ jobs_arg = '-j{}'.format(multiprocessing.cpu_count())
targets = [
# PHONY target specified in frameworks/rs/Android.mk.
'rs-prebuilts-full',
@@ -86,7 +88,7 @@
'android-support-v8-renderscript_intermediates/classes.jar')
]
subprocess.check_call(
- ['build/soong/soong_ui.bash', '--make-mode'] + targets, cwd=android_path(), env=env)
+ ['make', jobs_arg] + targets, cwd=android_path(), env=env)
def package_toolchain(build_dir, build_name, host, dist_dir):
diff --git a/cpp/Android.bp b/cpp/Android.bp
index 9d9041c..31cb3f8 100644
--- a/cpp/Android.bp
+++ b/cpp/Android.bp
@@ -6,9 +6,7 @@
include_dirs: [
"frameworks/rs",
- ],
- header_libs: [
- "jni_headers",
+ "libnativehelper/include_jni",
],
cflags: [
@@ -65,6 +63,7 @@
shared_libs: [
"libdl",
"liblog",
+ "libz",
],
}
@@ -72,15 +71,8 @@
name: "libRScpp",
defaults: ["libRScpp-defaults"],
- header_libs: [
- "libarect_headers",
- "libbase_headers",
- "libgui_headers",
- "libnativebase_headers",
- "libnativewindow_headers",
- ],
-
shared_libs: [
+ "libgui",
"libutils",
],
diff --git a/cpu_ref/Android.bp b/cpu_ref/Android.bp
index c409989..e929a9c 100644
--- a/cpu_ref/Android.bp
+++ b/cpu_ref/Android.bp
@@ -73,14 +73,15 @@
},
x86: {
- cflags: ["-DARCH_X86_HAVE_SSSE3"],
- srcs: ["rsCpuIntrinsics_x86.cpp"],
+ ssse3: {
+ cflags: ["-DARCH_X86_HAVE_SSSE3"],
+ srcs: ["rsCpuIntrinsics_x86.cpp"],
+ },
},
x86_64: {
- cflags: ["-DARCH_X86_HAVE_SSSE3"],
- srcs: ["rsCpuIntrinsics_x86.cpp"],
- avx2: {
- cflags: ["-DARCH_X86_HAVE_AVX2", "-mavx2", "-mfma"],
+ ssse3: {
+ cflags: ["-DARCH_X86_HAVE_SSSE3"],
+ srcs: ["rsCpuIntrinsics_x86.cpp"],
},
},
},
diff --git a/cpu_ref/rsCpuExecutable.cpp b/cpu_ref/rsCpuExecutable.cpp
index 63008ba..87c791a 100644
--- a/cpu_ref/rsCpuExecutable.cpp
+++ b/cpu_ref/rsCpuExecutable.cpp
@@ -207,39 +207,27 @@
// location for shared libraries first.
loaded = loadSOHelper(scriptSOName.c_str(), cacheDir, resName, alreadyLoaded);
- if (loaded != nullptr) {
- return loaded;
- }
- ALOGE("Unable to open shared library (%s): %s", scriptSOName.c_str(), dlerror());
+ if (loaded == nullptr) {
+ ALOGE("Unable to open shared library (%s): %s",
+ scriptSOName.c_str(), dlerror());
#ifdef RS_COMPATIBILITY_LIB
- // Re-trying without absolute path.
- // For RS support lib, the shared object may not be extracted from the apk.
- // In order to access that, we need to load the library without specifying
- // the absolute path.
- std::string scriptSONameApk("librs.");
- scriptSONameApk.append(resName);
- scriptSONameApk.append(".so");
- loaded = loadSOHelper(scriptSONameApk.c_str(), cacheDir, resName);
- if (loaded != nullptr) {
- return loaded;
- }
- ALOGE("Unable to open APK shared library (%s): %s", scriptSONameApk.c_str(), dlerror());
-
- // One final attempt to find the library in "/system/lib".
- // We do this to allow bundled applications to use the compatibility
- // library fallback path. Those applications don't have a private
- // library path, so they need to install to the system directly.
- // Note that this is really just a testing path.
- std::string scriptSONameSystem("/system/lib/librs.");
- scriptSONameSystem.append(resName);
- scriptSONameSystem.append(".so");
- loaded = loadSOHelper(scriptSONameSystem.c_str(), cacheDir, resName);
- if (loaded == nullptr) {
- ALOGE("Unable to open system shared library (%s): %s",
- scriptSONameSystem.c_str(), dlerror());
- }
+ // One final attempt to find the library in "/system/lib".
+ // We do this to allow bundled applications to use the compatibility
+ // library fallback path. Those applications don't have a private
+ // library path, so they need to install to the system directly.
+ // Note that this is really just a testing path.
+ std::string scriptSONameSystem("/system/lib/librs.");
+ scriptSONameSystem.append(resName);
+ scriptSONameSystem.append(".so");
+ loaded = loadSOHelper(scriptSONameSystem.c_str(), cacheDir,
+ resName);
+ if (loaded == nullptr) {
+ ALOGE("Unable to open system shared library (%s): %s",
+ scriptSONameSystem.c_str(), dlerror());
+ }
#endif
+ }
return loaded;
}
@@ -307,12 +295,10 @@
void *loaded = nullptr;
-#ifndef RS_COMPATIBILITY_LIB
// Skip everything if we don't even have the original library available.
if (access(origName, F_OK) != 0) {
return nullptr;
}
-#endif // RS_COMPATIBILITY_LIB
// Common path is that we have not loaded this Script/library before.
if (LoadedLibraries.find(origName) == LoadedLibraries.end()) {
diff --git a/cpu_ref/rsCpuIntrinsicResize.cpp b/cpu_ref/rsCpuIntrinsicResize.cpp
index 8a3dd1a..ff42d79 100644
--- a/cpu_ref/rsCpuIntrinsicResize.cpp
+++ b/cpu_ref/rsCpuIntrinsicResize.cpp
@@ -14,11 +14,6 @@
* limitations under the License.
*/
-#if defined(ARCH_X86_HAVE_AVX2)
-#include <stdint.h>
-#include <x86intrin.h>
-#include <xmmintrin.h>
-#endif
#include "rsCpuIntrinsic.h"
#include "rsCpuIntrinsicInlines.h"
@@ -83,20 +78,10 @@
+ x * (3.f * (p1 - p2) + p3 - p0)));
}
-
-#if defined(ARCH_X86_HAVE_AVX2)
-static float cubicInterpolate(float p0,float p1,float p2,float p3 , float x) {
- return p1 + 0.5f * x * (p2 - p0 + x * (2.f * p0 - 5.f * p1 +
- _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(4.f), _mm_set1_ps(p2),_mm_set1_ps(p3)))
- + x * (_mm_cvtss_f32(_mm_fmadd_ss (_mm_set1_ps(3.f),_mm_set1_ps(p1 - p2),_mm_set1_ps(p3 - p0))))));
-
-}
-#else
static float cubicInterpolate(float p0,float p1,float p2,float p3 , float x) {
return p1 + 0.5f * x * (p2 - p0 + x * (2.f * p0 - 5.f * p1 + 4.f * p2 - p3
+ x * (3.f * (p1 - p2) + p3 - p0)));
}
-#endif
static uchar4 OneBiCubic(const uchar4 *yp0, const uchar4 *yp1, const uchar4 *yp2, const uchar4 *yp3,
float xf, float yf, int width) {
@@ -332,14 +317,7 @@
const int srcWidth = cp->mAlloc->mHal.drvState.lod[0].dimX;
const size_t stride = cp->mAlloc->mHal.drvState.lod[0].stride;
-
-#if defined(ARCH_X86_HAVE_AVX2)
- float yf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(info->current.y + 0.5f),_mm_set1_ps(cp->scaleY), _mm_set1_ps(0.5f)));
-#else
float yf = (info->current.y + 0.5f) * cp->scaleY - 0.5f;
-#endif
-
-
int starty = (int) floor(yf - 1);
yf = yf - floor(yf);
int maxy = srcHeight - 1;
@@ -385,11 +363,7 @@
#endif
while(x1 < x2) {
-#if defined(ARCH_X86_HAVE_AVX2)
- float xf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(x1 + 0.5f) , _mm_set1_ps(cp->scaleX) , _mm_set1_ps(0.5f)));
-#else
float xf = (x1 + 0.5f) * cp->scaleX - 0.5f;
-#endif
*out = OneBiCubic(yp0, yp1, yp2, yp3, xf, yf, srcWidth);
out++;
x1++;
@@ -410,13 +384,7 @@
const int srcWidth = cp->mAlloc->mHal.drvState.lod[0].dimX;
const size_t stride = cp->mAlloc->mHal.drvState.lod[0].stride;
-
-#if defined(ARCH_X86_HAVE_AVX2)
- float yf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(info->current.y + 0.5f),_mm_set1_ps(cp->scaleY), _mm_set1_ps(0.5f)));
-#else
float yf = (info->current.y + 0.5f) * cp->scaleY - 0.5f;
-#endif
-
int starty = (int) floor(yf - 1);
yf = yf - floor(yf);
int maxy = srcHeight - 1;
@@ -462,12 +430,7 @@
#endif
while(x1 < x2) {
-
-#if defined(ARCH_X86_HAVE_AVX2)
- float xf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(x1 + 0.5f) , _mm_set1_ps(cp->scaleX) , _mm_set1_ps(0.5f)));
-#else
float xf = (x1 + 0.5f) * cp->scaleX - 0.5f;
-#endif
*out = OneBiCubic(yp0, yp1, yp2, yp3, xf, yf, srcWidth);
out++;
x1++;
@@ -488,13 +451,7 @@
const int srcWidth = cp->mAlloc->mHal.drvState.lod[0].dimX;
const size_t stride = cp->mAlloc->mHal.drvState.lod[0].stride;
-
-#if defined(ARCH_X86_HAVE_AVX2)
- float yf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(info->current.y + 0.5f),_mm_set1_ps(cp->scaleY), _mm_set1_ps(0.5f)));
-#else
float yf = (info->current.y + 0.5f) * cp->scaleY - 0.5f;
-#endif
-
int starty = (int) floor(yf - 1);
yf = yf - floor(yf);
int maxy = srcHeight - 1;
@@ -540,13 +497,7 @@
#endif
while(x1 < x2) {
-
-#if defined(ARCH_X86_HAVE_AVX2)
- float xf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(x1 + 0.5f) , _mm_set1_ps(cp->scaleX) , _mm_set1_ps(0.5f)));
-#else
float xf = (x1 + 0.5f) * cp->scaleX - 0.5f;
-#endif
-
*out = OneBiCubic(yp0, yp1, yp2, yp3, xf, yf, srcWidth);
out++;
x1++;
@@ -567,12 +518,7 @@
const int srcWidth = cp->mAlloc->mHal.drvState.lod[0].dimX;
const size_t stride = cp->mAlloc->mHal.drvState.lod[0].stride;
-#if defined(ARCH_X86_HAVE_AVX2)
- float yf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(info->current.y + 0.5f),_mm_set1_ps(cp->scaleY), _mm_set1_ps(0.5f)));
-#else
float yf = (info->current.y + 0.5f) * cp->scaleY - 0.5f;
-#endif
-
int starty = (int) floor(yf - 1);
yf = yf - floor(yf);
int maxy = srcHeight - 1;
@@ -591,13 +537,7 @@
uint32_t x2 = xend;
while(x1 < x2) {
-
-#if defined(ARCH_X86_HAVE_AVX2)
- float xf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(x1 + 0.5f) , _mm_set1_ps(cp->scaleX) , _mm_set1_ps(0.5f)));
-#else
float xf = (x1 + 0.5f) * cp->scaleX - 0.5f;
-#endif
-
*out = OneBiCubic(yp0, yp1, yp2, yp3, xf, yf, srcWidth);
out++;
x1++;
@@ -618,13 +558,7 @@
const int srcWidth = cp->mAlloc->mHal.drvState.lod[0].dimX;
const size_t stride = cp->mAlloc->mHal.drvState.lod[0].stride;
-
-#if defined(ARCH_X86_HAVE_AVX2)
- float yf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(info->current.y + 0.5f),_mm_set1_ps(cp->scaleY), _mm_set1_ps(0.5f)));
-#else
float yf = (info->current.y + 0.5f) * cp->scaleY - 0.5f;
-#endif
-
int starty = (int) floor(yf - 1);
yf = yf - floor(yf);
int maxy = srcHeight - 1;
@@ -643,13 +577,7 @@
uint32_t x2 = xend;
while(x1 < x2) {
-
-#if defined(ARCH_X86_HAVE_AVX2)
- float xf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(x1 + 0.5f) , _mm_set1_ps(cp->scaleX) , _mm_set1_ps(0.5f)));
-#else
float xf = (x1 + 0.5f) * cp->scaleX - 0.5f;
-#endif
-
*out = OneBiCubic(yp0, yp1, yp2, yp3, xf, yf, srcWidth);
out++;
x1++;
@@ -670,13 +598,7 @@
const int srcWidth = cp->mAlloc->mHal.drvState.lod[0].dimX;
const size_t stride = cp->mAlloc->mHal.drvState.lod[0].stride;
-
-#if defined(ARCH_X86_HAVE_AVX2)
- float yf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(info->current.y + 0.5f),_mm_set1_ps(cp->scaleY), _mm_set1_ps(0.5f)));
-#else
float yf = (info->current.y + 0.5f) * cp->scaleY - 0.5f;
-#endif
-
int starty = (int) floor(yf - 1);
yf = yf - floor(yf);
int maxy = srcHeight - 1;
@@ -695,13 +617,7 @@
uint32_t x2 = xend;
while(x1 < x2) {
-
-#if defined(ARCH_X86_HAVE_AVX2)
- float xf = _mm_cvtss_f32(_mm_fmsub_ss(_mm_set1_ps(x1 + 0.5f) , _mm_set1_ps(cp->scaleX) , _mm_set1_ps(0.5f)));
-#else
float xf = (x1 + 0.5f) * cp->scaleX - 0.5f;
-#endif
-
*out = OneBiCubic(yp0, yp1, yp2, yp3, xf, yf, srcWidth);
out++;
x1++;
diff --git a/cpu_ref/rsCpuRuntimeMath.cpp b/cpu_ref/rsCpuRuntimeMath.cpp
index 9f14e67..29ea658 100644
--- a/cpu_ref/rsCpuRuntimeMath.cpp
+++ b/cpu_ref/rsCpuRuntimeMath.cpp
@@ -99,7 +99,7 @@
float SC_randf2(float min, float max) {
float r = (float)rand();
- r /= (float)RAND_MAX;
+ r /= RAND_MAX;
r = r * (max - min) + min;
return r;
}
diff --git a/rsov/Android.mk b/rsov/Android.mk
new file mode 100644
index 0000000..4afbb7c
--- /dev/null
+++ b/rsov/Android.mk
@@ -0,0 +1,12 @@
+#=====================================================================
+# Include Subdirectories
+#=====================================================================
+
+# Not building RSoV modules in PDK builds, as libSPIRV is not available in PDK.
+ifneq ($(TARGET_BUILD_PDK), true)
+
+LOCAL_PATH:=$(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
+endif # TARGET_BUILD_PDK
diff --git a/rsov/compiler/.clang-format b/rsov/compiler/.clang-format
new file mode 100644
index 0000000..21c0dd4
--- /dev/null
+++ b/rsov/compiler/.clang-format
@@ -0,0 +1,95 @@
+---
+Language: Cpp
+# BasedOnStyle: LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: false
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeCategories:
+ - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
+ Priority: 2
+ - Regex: '^(<|"(gtest|isl|json)/)'
+ Priority: 3
+ - Regex: '.*'
+ Priority: 1
+IncludeIsMainRegex: '$'
+IndentCaseLabels: false
+IndentWidth: 2
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+ReflowComments: true
+SortIncludes: true
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 8
+UseTab: Never
+...
+
diff --git a/rsov/compiler/Android.bp b/rsov/compiler/Android.bp
new file mode 100644
index 0000000..61dd921
--- /dev/null
+++ b/rsov/compiler/Android.bp
@@ -0,0 +1,109 @@
+//
+// Copyright (C) 2016 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.
+//
+
+//=====================================================================
+// Unit tests for Wrapper module
+//=====================================================================
+
+cc_test_host {
+ name: "Wrapper_test",
+ defaults: [
+ "llvm-defaults",
+ "spirit_defaults",
+ ],
+
+ srcs: [
+ "Builtin.cpp",
+ "Context.cpp",
+ "GlobalAllocSPIRITPass.cpp",
+ "RSAllocationUtils.cpp",
+ "Wrapper.cpp",
+ "Wrapper_test.cpp",
+ ],
+
+ shared_libs: [
+ "libLLVM_android",
+ "libbcinfo",
+ "libspirit",
+ ],
+}
+
+//=====================================================================
+// Unit tests for Builtin module
+//=====================================================================
+
+cc_test_host {
+ name: "Builtin_test",
+ defaults: ["spirit_defaults"],
+
+ srcs: [
+ "Builtin.cpp",
+ "Builtin_test.cpp",
+ ],
+
+ shared_libs: ["libspirit"],
+}
+
+//=====================================================================
+// Host and Device Executable rs2spirv
+//=====================================================================
+
+cc_binary {
+ name: "rs2spirv",
+ defaults: [
+ "llvm-defaults",
+ "spirit_defaults",
+ ],
+ host_supported: true,
+ device_supported: false,
+
+ srcs: [
+ "rs2spirv.cpp",
+ "Builtin.cpp",
+ "Context.cpp",
+ "GlobalAllocPass.cpp",
+ "GlobalAllocSPIRITPass.cpp",
+ "GlobalMergePass.cpp",
+ "InlinePreparationPass.cpp",
+ "RemoveNonkernelsPass.cpp",
+ "RSAllocationUtils.cpp",
+ "RSSPIRVWriter.cpp",
+ "Wrapper.cpp",
+ ],
+
+ // TODO: fix the remaining warnings
+ cflags: [
+ "-D_SPIRV_LLVM_API",
+ "-Wno-error=pessimizing-move",
+ "-Wno-error=unused-variable",
+ "-Wno-error=unused-private-field",
+ "-Wno-error=unused-function",
+ "-Wno-error=dangling-else",
+ "-Wno-error=ignored-qualifiers",
+ "-Wno-error=non-virtual-dtor",
+
+ // For debug builds
+ //"-O0",
+ //"-DRS2SPIRV_DEBUG=1",
+ ],
+
+ shared_libs: [
+ "libLLVM_android",
+ "libbcinfo",
+ "libSPIRV",
+ "libspirit",
+ ],
+}
diff --git a/rsov/compiler/Builtin.cpp b/rsov/compiler/Builtin.cpp
new file mode 100644
index 0000000..02f7546
--- /dev/null
+++ b/rsov/compiler/Builtin.cpp
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "Builtin.h"
+
+#include "cxxabi.h"
+#include "spirit.h"
+#include "transformer.h"
+
+#include <stdint.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace spirit {
+
+namespace {
+
+Instruction *translateClampVector(const char *name,
+ const FunctionCallInst *call, Transformer *tr,
+ Builder *b, Module *m) {
+ int width = name[10] - '0';
+ if (width < 2 || width > 4) {
+ return nullptr;
+ }
+
+ uint32_t extOpCode = 0;
+ switch (name[strlen(name) - 1]) {
+ case 'f':
+ extOpCode = 43;
+ break; // FClamp
+ // TODO: Do we get _Z5clampDV_uuu at all? Does LLVM convert u into i?
+ case 'u':
+ extOpCode = 44;
+ break; // UClamp
+ case 'i':
+ extOpCode = 45;
+ break; // SClamp
+ default:
+ return nullptr;
+ }
+
+ std::vector<IdRef> minConstituents(width, call->mOperand2[1]);
+ std::unique_ptr<Instruction> min(
+ b->MakeCompositeConstruct(call->mResultType, minConstituents));
+ tr->insert(min.get());
+
+ std::vector<IdRef> maxConstituents(width, call->mOperand2[2]);
+ std::unique_ptr<Instruction> max(
+ b->MakeCompositeConstruct(call->mResultType, maxConstituents));
+ tr->insert(max.get());
+
+ std::vector<IdRef> extOpnds = {call->mOperand2[0], min.get(), max.get()};
+ return b->MakeExtInst(call->mResultType, m->getGLExt(), extOpCode, extOpnds);
+}
+
+Instruction *translateExtInst(const uint32_t extOpCode,
+ const FunctionCallInst *call, Builder *b,
+ Module *m) {
+ return b->MakeExtInst(call->mResultType, m->getGLExt(), extOpCode,
+ {call->mOperand2[0]});
+}
+
+} // anonymous namespace
+
+typedef std::function<Instruction *(const char *, const FunctionCallInst *,
+ Transformer *, Builder *, Module *)>
+ InstTrTy;
+
+class BuiltinLookupTable {
+public:
+ BuiltinLookupTable() {
+ for (sNameCode const *p = &mFPMathFuncOpCode[0]; p->name; p++) {
+ const char *name = p->name;
+ const uint32_t extOpCode = p->code;
+ addMapping(name, {"*"}, {{"float+"}}, {1, 2, 3, 4},
+ [extOpCode](const char *, const FunctionCallInst *call,
+ Transformer *, Builder *b, Module *m) {
+ return translateExtInst(extOpCode, call, b, m);
+ });
+ }
+
+ addMapping("abs", {"*"}, {{"int+"}, {"char+"}}, {1, 2, 3, 4},
+ [](const char *, const FunctionCallInst *call, Transformer *,
+ Builder *b, Module *m) {
+ return translateExtInst(5, call, b, m); // SAbs
+ });
+
+ addMapping("clamp", {"*"},
+ {{"int+", "int", "int"}, {"float+", "float", "float"}},
+ {1, 2, 3, 4}, [](const char *name, const FunctionCallInst *call,
+ Transformer *tr, Builder *b, Module *m) {
+ return translateClampVector(name, call, tr, b, m);
+ });
+
+ addMapping("convert", {"char+", "int+", "uchar+", "uint+"},
+ {{"char+"}, {"int+"}, {"uchar+"}, {"uint+"}}, {1, 2, 3, 4},
+ [](const char *, const FunctionCallInst *call, Transformer *,
+ Builder *b, Module *) -> Instruction * {
+ return b->MakeUConvert(call->mResultType, call->mOperand2[0]);
+ });
+
+ addMapping(
+ "convert", {"char+", "int+", "uchar+", "uint+"}, {{"float+"}},
+ {1, 2, 3, 4}, [](const char *, const FunctionCallInst *call,
+ Transformer *, Builder *b, Module *) -> Instruction * {
+ return b->MakeConvertFToU(call->mResultType, call->mOperand2[0]);
+ });
+
+ addMapping(
+ "convert", {"float+"}, {{"char+"}, {"int+"}, {"uchar+"}, {"uint+"}},
+ {1, 2, 3, 4}, [](const char *, const FunctionCallInst *call,
+ Transformer *, Builder *b, Module *) {
+ return b->MakeConvertUToF(call->mResultType, call->mOperand2[0]);
+ });
+
+ addMapping("dot", {"*"}, {{"float+"}}, {1, 2, 3, 4},
+ [](const char *, const FunctionCallInst *call, Transformer *,
+ Builder *b, Module *) {
+ return b->MakeDot(call->mResultType, call->mOperand2[0],
+ call->mOperand2[1]);
+ });
+
+ addMapping("min", {"*"}, {{"uint+"}, {"uchar+"}}, {1, 2, 3, 4},
+ [](const char *, const FunctionCallInst *call, Transformer *,
+ Builder *b, Module *m) {
+ return translateExtInst(38, call, b, m); // UMin
+ });
+
+ addMapping("min", {"*"}, {{"int+"}, {"char+"}}, {1, 2, 3, 4},
+ [](const char *, const FunctionCallInst *call, Transformer *,
+ Builder *b, Module *m) {
+ return translateExtInst(39, call, b, m); // SMin
+ });
+
+ addMapping("max", {"*"}, {{"uint+"}, {"uchar+"}}, {1, 2, 3, 4},
+ [](const char *, const FunctionCallInst *call, Transformer *,
+ Builder *b, Module *m) {
+ return translateExtInst(41, call, b, m); // UMax
+ });
+
+ addMapping("max", {"*"}, {{"int+"}, {"char+"}}, {1, 2, 3, 4},
+ [](const char *, const FunctionCallInst *call, Transformer *,
+ Builder *b, Module *m) {
+ return translateExtInst(42, call, b, m); // SMax
+ });
+
+ addMapping("rsUnpackColor8888", {"*"}, {{"uchar+"}}, {4},
+ [](const char *, const FunctionCallInst *call, Transformer *,
+ Builder *b, Module *m) {
+ auto cast = b->MakeBitcast(m->getUnsignedIntType(32),
+ call->mOperand2[0]);
+ return b->MakeExtInst(call->mResultType, m->getGLExt(), 64,
+ {cast}); // UnpackUnorm4x8
+ });
+
+ addMapping("rsPackColorTo8888", {"*"}, {{"float+"}}, {4},
+ [](const char *, const FunctionCallInst *call, Transformer *,
+ Builder *b, Module *m) {
+ // PackUnorm4x8
+ auto packed = b->MakeExtInst(call->mResultType, m->getGLExt(),
+ 55, {call->mOperand2[0]});
+ return b->MakeBitcast(
+ m->getVectorType(m->getUnsignedIntType(8), 4), packed);
+ });
+ }
+
+ static const BuiltinLookupTable &getInstance() {
+ static BuiltinLookupTable table;
+ return table;
+ }
+
+ void addMapping(const char *funcName,
+ const std::vector<std::string> &retTypes,
+ const std::vector<std::vector<std::string>> &argTypes,
+ const std::vector<uint8_t> &vecWidths, InstTrTy fp) {
+ for (auto width : vecWidths) {
+ for (auto retType : retTypes) {
+ std::string suffixed(funcName);
+ if (retType != "*") {
+ if (retType.back() == '+') {
+ retType.pop_back();
+ if (width > 1) {
+ retType.append(1, '0' + width);
+ }
+ }
+ suffixed.append("_").append(retType);
+ }
+
+ for (auto argList : argTypes) {
+ std::string args("(");
+ bool first = true;
+ for (auto argType : argList) {
+ if (first) {
+ first = false;
+ } else {
+ args.append(", ");
+ }
+ if (argType.front() == 'u') {
+ argType.replace(0, 1, "unsigned ");
+ }
+ if (argType.back() == '+') {
+ argType.pop_back();
+ if (width > 1) {
+ argType.append(" vector[");
+ argType.append(1, '0' + width);
+ argType.append("]");
+ }
+ }
+ args.append(argType);
+ }
+ args.append(")");
+ mFuncNameMap[suffixed + args] = fp;
+ }
+ }
+ }
+ }
+
+ InstTrTy lookupTranslation(const char *mangled) const {
+ const char *demangled =
+ __cxxabiv1::__cxa_demangle(mangled, nullptr, nullptr, nullptr);
+
+ if (!demangled) {
+ // All RS runtime/builtin functions are overloaded, therefore
+ // name-mangled.
+ return nullptr;
+ }
+
+ std::string strDemangled(demangled);
+
+ auto it = mFuncNameMap.find(strDemangled);
+ if (it == mFuncNameMap.end()) {
+ return nullptr;
+ }
+ return it->second;
+ }
+
+private:
+ std::map<std::string, InstTrTy> mFuncNameMap;
+
+ struct sNameCode {
+ const char *name;
+ uint32_t code;
+ };
+
+ static sNameCode constexpr mFPMathFuncOpCode[] = {
+ {"abs", 4}, {"sin", 13}, {"cos", 14}, {"tan", 15},
+ {"asin", 16}, {"acos", 17}, {"atan", 18}, {"sinh", 19},
+ {"cosh", 20}, {"tanh", 21}, {"asinh", 22}, {"acosh", 23},
+ {"atanh", 24}, {"atan2", 25}, {"pow", 26}, {"exp", 27},
+ {"log", 28}, {"exp2", 29}, {"log2", 30}, {"sqrt", 31},
+ {"modf", 35}, {"min", 37}, {"max", 40}, {"length", 66},
+ {"normalize", 69}, {nullptr, 0},
+ };
+
+}; // BuiltinLookupTable
+
+BuiltinLookupTable::sNameCode constexpr BuiltinLookupTable::mFPMathFuncOpCode[];
+
+class BuiltinTransformer : public Transformer {
+public:
+ // BEGIN: cleanup unrelated to builtin functions, but necessary for LLVM-SPIRV
+ // converter generated code.
+
+ // TODO: Move these in its own pass
+
+ std::vector<uint32_t> runAndSerialize(Module *module, int *error) override {
+ module->addExtInstImport("GLSL.std.450");
+ return Transformer::runAndSerialize(module, error);
+ }
+
+ Instruction *transform(CapabilityInst *inst) override {
+ // Remove capabilities Address, Linkage, and Kernel.
+ if (inst->mOperand1 == Capability::Addresses ||
+ inst->mOperand1 == Capability::Linkage ||
+ inst->mOperand1 == Capability::Kernel) {
+ return nullptr;
+ }
+ return inst;
+ }
+
+ Instruction *transform(ExtInstImportInst *inst) override {
+ if (inst->mOperand1.compare("OpenCL.std") == 0) {
+ return nullptr;
+ }
+ return inst;
+ }
+
+ Instruction *transform(InBoundsPtrAccessChainInst *inst) override {
+ // Transform any OpInBoundsPtrAccessChain instruction to an
+ // OpInBoundsAccessChain instruction, since the former is not allowed by
+ // the Vulkan validation rules.
+ auto newInst = mBuilder.MakeInBoundsAccessChain(inst->mResultType,
+ inst->mOperand1,
+ inst->mOperand3);
+ newInst->setId(inst->getId());
+ return newInst;
+ }
+
+ Instruction *transform(SourceInst *inst) override {
+ if (inst->mOperand1 == SourceLanguage::Unknown) {
+ return nullptr;
+ }
+ return inst;
+ }
+
+ Instruction *transform(DecorateInst *inst) override {
+ if (inst->mOperand2 == Decoration::LinkageAttributes ||
+ inst->mOperand2 == Decoration::Alignment) {
+ return nullptr;
+ }
+ return inst;
+ }
+
+ // END: cleanup unrelated to builtin functions
+
+ Instruction *transform(FunctionCallInst *call) {
+ FunctionInst *func =
+ static_cast<FunctionInst *>(call->mOperand1.mInstruction);
+ // TODO: attach name to the instruction to avoid linear search in the debug
+ // section, i.e.,
+ // const char *name = func->getName();
+ const char *name = getModule()->lookupNameByInstruction(func);
+ if (!name) {
+ return call;
+ }
+
+ // Maps name into a SPIR-V instruction
+ auto fpTranslate =
+ BuiltinLookupTable::getInstance().lookupTranslation(name);
+ if (!fpTranslate) {
+ return call;
+ }
+ Instruction *inst = fpTranslate(name, call, this, &mBuilder, getModule());
+
+ if (inst) {
+ inst->setId(call->getId());
+ }
+
+ return inst;
+ }
+
+private:
+ Builder mBuilder;
+};
+
+} // namespace spirit
+} // namespace android
+
+namespace rs2spirv {
+
+android::spirit::Pass *CreateBuiltinPass() {
+ return new android::spirit::BuiltinTransformer();
+}
+
+} // namespace rs2spirv
+
diff --git a/rsov/compiler/Builtin.h b/rsov/compiler/Builtin.h
new file mode 100644
index 0000000..2a28097
--- /dev/null
+++ b/rsov/compiler/Builtin.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef BUILTIN_H
+#define BUILTIN_H
+
+namespace android {
+namespace spirit {
+
+class Pass;
+
+} // namespace spirit
+} // namespace android
+
+namespace rs2spirv {
+
+android::spirit::Pass *CreateBuiltinPass();
+
+} // namespace rs2spirv
+
+#endif // BUILTIN_H
diff --git a/rsov/compiler/Builtin_test.cpp b/rsov/compiler/Builtin_test.cpp
new file mode 100644
index 0000000..256703b
--- /dev/null
+++ b/rsov/compiler/Builtin_test.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "Builtin.h"
+
+#include "file_utils.h"
+#include "pass_queue.h"
+#include "spirit.h"
+#include "test_utils.h"
+#include "gtest/gtest.h"
+
+namespace android {
+namespace spirit {
+
+TEST(BuiltinTest, testBuiltinTranslation) {
+ const std::string testFile("greyscale.spv");
+ const std::string testDataPath(
+ "frameworks/rs/rsov/compiler/spirit/test_data/");
+ const std::string &fullPath = getAbsolutePath(testDataPath + testFile);
+ auto words = readFile<uint32_t>(fullPath);
+
+ PassQueue passes;
+ passes.append(rs2spirv::CreateBuiltinPass());
+ auto words1 = passes.run(words);
+
+ std::unique_ptr<Module> m1(Deserialize<Module>(words1));
+
+ ASSERT_NE(nullptr, m1);
+}
+
+} // spirit
+} // android
diff --git a/rsov/compiler/Context.cpp b/rsov/compiler/Context.cpp
new file mode 100644
index 0000000..858aa8a
--- /dev/null
+++ b/rsov/compiler/Context.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "Context.h"
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <limits>
+
+#define DEBUG_TYPE "rs2spirv-context"
+
+namespace rs2spirv {
+
+Context &Context::getInstance() {
+ static Context c;
+ return c;
+}
+
+Context::Context() : mInitialized(false) {}
+
+bool Context::Initialize(std::unique_ptr<bcinfo::MetadataExtractor> ME) {
+ if (mInitialized) {
+ return true;
+ }
+
+ mMetadata = std::move(ME);
+
+ if (!mMetadata->extract()) {
+ llvm::errs() << "cannot extract metadata\n";
+ return false;
+ }
+
+ const char **varNames = mMetadata->getExportVarNameList();
+ size_t varCount = mMetadata->getExportVarCount();
+ mExportVarIndices.resize(varCount);
+
+ // Builds the lookup table from a variable name to its slot number
+ for (size_t slot = 0; slot < varCount; slot++) {
+ std::string varName(varNames[slot]);
+ mVarNameToSlot.insert(std::make_pair(varName, (uint32_t)slot));
+ }
+
+ const size_t kernelCount = mMetadata->getExportForEachSignatureCount();
+ const char **kernelNames = mMetadata->getExportForEachNameList();
+ for (size_t slot = 0; slot < kernelCount; slot++) {
+ mForEachNameToSlot.insert(std::make_pair(kernelNames[slot], slot));
+ }
+
+ mInitialized = true;
+
+ return true;
+}
+
+void Context::addExportVarIndex(const char *varName, uint32_t index) {
+ DEBUG(llvm::dbgs() << varName << " index=" << index << '\n');
+ const uint32_t slot = getSlotForExportVar(varName);
+ if (slot == std::numeric_limits<uint32_t>::max()) {
+ return;
+ }
+ addExportVarIndex(slot, index);
+}
+
+
+} // namespace rs2spirv
diff --git a/rsov/compiler/Context.h b/rsov/compiler/Context.h
new file mode 100644
index 0000000..9b38226
--- /dev/null
+++ b/rsov/compiler/Context.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef RS2SPIRV_CONTEXT_H
+#define RS2SPIRV_CONTEXT_H
+
+#include "RSAllocationUtils.h"
+#include "bcinfo/MetadataExtractor.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <stdint.h>
+
+// Declare a friend relationship in a class with a test. Used rather that
+// FRIEND_TEST to avoid globally importing gtest/gtest.h into the main
+// RSoV header files.
+#ifdef __HOST__
+#define RSOV_FRIEND_TEST(test_set_name, individual_test) \
+ friend class test_set_name##_##individual_test##_Test
+#else
+#define RSOV_FRIEND_TEST(test_set_name, individual_test)
+#endif // __HOST__
+
+namespace bcinfo {
+class MetadataExtractor;
+}
+
+namespace llvm {
+class Module;
+}
+
+namespace rs2spirv {
+
+// A singleton that keeps state during the compilation from RS LLVM bitcode to
+// SPIR-V, which provides quick lookup of metadata and shares information
+// between the passes.
+class Context {
+ RSOV_FRIEND_TEST(ContextTest, testInitialize);
+
+public:
+ static Context &getInstance();
+
+ Context();
+
+ // Initialize the internal data struture such as the slot number lookup table,
+ // etc.
+ bool Initialize(std::unique_ptr<bcinfo::MetadataExtractor> ME);
+
+ // Returns the total number of exported variables
+ uint32_t getNumExportVar() const { return mExportVarIndices.size(); }
+
+ // Adds the mapping from the slot number of an exported variable to the index
+ // of its field in the global buffer
+ void addExportVarIndex(uint32_t slot, uint32_t index) {
+ mExportVarIndices[slot] = index;
+ }
+
+ // Adds the mapping from the name of an exported variable to the index of its
+ // field in the global buffer
+ void addExportVarIndex(const char *varName, uint32_t index);
+
+ // Given the slot number of an exported variable, returns the index of its
+ // field in the global buffer
+ uint32_t getExportVarIndex(uint32_t slot) const {
+ return mExportVarIndices[slot];
+ }
+
+ void setGlobalSize(uint64_t size) {
+ mGlobalSize = size;
+ }
+
+ uint64_t getGlobalSize() const {
+ return mGlobalSize;
+ }
+
+ // Returns the total number of foreach kernels
+ uint32_t getNumForEachKernel() const { return mForEachNameToSlot.size(); }
+
+ // Checks if a name refers to a foreach kernel function
+ bool isForEachKernel(llvm::StringRef name) const {
+ return mForEachNameToSlot.count(name) != 0;
+ }
+
+ const bcinfo::MetadataExtractor &getMetadata() const { return *mMetadata; }
+
+ llvm::SmallVectorImpl<RSAllocationInfo> &getGlobalAllocs() {
+ return mGlobalAllocs;
+ }
+
+private:
+ uint32_t getSlotForExportVar(const char *varName) {
+ const llvm::StringRef strVarName(varName);
+ auto it = mVarNameToSlot.find(strVarName);
+ if (it == mVarNameToSlot.end()) {
+ return std::numeric_limits<uint32_t>::max();
+ }
+ return it->second;
+ }
+
+ bool mInitialized;
+ // RenderScript metadata embedded in the input LLVM Moduel
+ std::unique_ptr<bcinfo::MetadataExtractor> mMetadata;
+ // A map from exported variable names to their slot numbers
+ llvm::StringMap<uint32_t> mVarNameToSlot;
+ // The size of memory needed to store all global variables (static variables)
+ uint64_t mGlobalSize;
+ // A map from exported foreach kernel names to their slot numbers
+ llvm::StringMap<uint32_t> mForEachNameToSlot;
+ // These are the indices for each exported variable in the global buffer
+ llvm::SmallVector<uint32_t, 8> mExportVarIndices;
+ // For Global Allocations; carries global variable -> metadata offset
+ // mapping from an LLVM pass to a SPIRIT pass
+ llvm::SmallVector<RSAllocationInfo, 8> mGlobalAllocs;
+};
+
+} // namespace rs2spirv
+
+#endif // RS2SPIRV_CONTEXT_H
diff --git a/rsov/compiler/GlobalAllocPass.cpp b/rsov/compiler/GlobalAllocPass.cpp
new file mode 100644
index 0000000..92c441a
--- /dev/null
+++ b/rsov/compiler/GlobalAllocPass.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "GlobalAllocPass.h"
+
+#include "Context.h"
+#include "RSAllocationUtils.h"
+
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "rs2spirv-global-alloc"
+
+using namespace llvm;
+
+namespace rs2spirv {
+
+namespace {
+bool collectGlobalAllocs(Module &M,
+ SmallVectorImpl<GlobalVariable *> &GlobalAllocs) {
+ for (auto &GV : M.globals()) {
+ if (!isRSAllocation(GV))
+ continue;
+
+ DEBUG(GV.dump());
+ GlobalAllocs.push_back(&GV);
+ }
+
+ return !GlobalAllocs.empty();
+}
+
+//
+// This pass would enumerate used global rs_allocations (TBD) and
+// lowers calls to accessors of the following type:
+//
+// rsGetAllocationDimX(g)
+//
+// to
+//
+// __rsov_rsGetAllocationDimX(some uninque constant identifying g) */
+//
+// Note the __rsov_* variant is used as a marker for another SPIRIT
+// transformations (see GlobalAllocSPIRITPass.cpp) to expand them into
+// SPIR-V instructions that loads the metadata.
+//
+class GlobalAllocPass : public ModulePass {
+public:
+ static char ID;
+ GlobalAllocPass()
+ : ModulePass(ID), Allocs(Context::getInstance().getGlobalAllocs()) {}
+
+ const char *getPassName() const override { return "GlobalAllocPass"; }
+
+ bool runOnModule(Module &M) override {
+ DEBUG(dbgs() << "RS2SPIRVGlobalAllocPass\n");
+ DEBUG(M.dump());
+
+ SmallVector<GlobalVariable *, 8> GlobalAllocs;
+ const bool CollectRes = collectGlobalAllocs(M, GlobalAllocs);
+ if (!CollectRes)
+ return false; // Module not modified.
+
+ SmallVector<RSAllocationCallInfo, 8> Calls;
+ getRSAllocationInfo(M, Allocs);
+ getRSAllocAccesses(Allocs, Calls);
+
+ // Lower the found accessors
+ for (auto &C : Calls) {
+ assert(C.Kind == RSAllocAccessKind::DIMX &&
+ "Unsupported type of accessor call types");
+ solidifyRSAllocAccess(M, C);
+ }
+ // Return true, as the pass modifies module.
+ DEBUG(dbgs() << "RS2SPIRVGlobalAllocPass end\n");
+ return true;
+ }
+
+private:
+ SmallVectorImpl<RSAllocationInfo> &Allocs;
+};
+
+// A simple pass to remove all global allocations forcibly
+class RemoveAllGlobalAllocPass : public ModulePass {
+public:
+ static char ID;
+ RemoveAllGlobalAllocPass() : ModulePass(ID) {}
+ const char *getPassName() const override {
+ return "RemoveAllGlobalAllocPass";
+ }
+
+ bool runOnModule(Module &M) override {
+ DEBUG(dbgs() << "RemoveAllGlobalAllocPass\n");
+ DEBUG(M.dump());
+
+ SmallVector<GlobalVariable *, 8> GlobalAllocs;
+ const bool CollectRes = collectGlobalAllocs(M, GlobalAllocs);
+ if (!CollectRes)
+ return false; // Module not modified.
+ // Remove global allocations
+ for (auto *G : GlobalAllocs) {
+ G->eraseFromParent();
+ }
+ DEBUG(dbgs() << "RemoveAllGlobalAllocPass end\n");
+ DEBUG(M.dump());
+ // Return true, as the pass modifies module.
+ return true;
+ }
+};
+
+} // namespace
+char GlobalAllocPass::ID = 0;
+char RemoveAllGlobalAllocPass::ID = 0;
+
+ModulePass *createRemoveAllGlobalAllocPass() {
+ return new RemoveAllGlobalAllocPass();
+}
+ModulePass *createGlobalAllocPass() { return new GlobalAllocPass(); }
+
+} // namespace rs2spirv
diff --git a/rsov/compiler/GlobalAllocPass.h b/rsov/compiler/GlobalAllocPass.h
new file mode 100644
index 0000000..9312c21
--- /dev/null
+++ b/rsov/compiler/GlobalAllocPass.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef RS2SPIRV_GLOBAL_ALLOC_PASS_H
+#define RS2SPIRV_GLOBAL_ALLOC_PASS_H
+
+namespace llvm {
+class ModulePass;
+} // namespace llvm
+
+namespace rs2spirv {
+
+llvm::ModulePass *createGlobalAllocPass();
+llvm::ModulePass *createRemoveAllGlobalAllocPass();
+
+} // namespace rs2spirv
+
+#endif
diff --git a/rsov/compiler/GlobalAllocSPIRITPass.cpp b/rsov/compiler/GlobalAllocSPIRITPass.cpp
new file mode 100644
index 0000000..5d2ab15
--- /dev/null
+++ b/rsov/compiler/GlobalAllocSPIRITPass.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "GlobalAllocSPIRITPass.h"
+
+#include "Context.h"
+#include "spirit.h"
+#include "transformer.h"
+
+#include <sstream>
+
+namespace android {
+namespace spirit {
+
+namespace {
+
+// Metadata buffer for global allocations
+// struct metadata {
+// uint32_t element_size;
+// uint32_t x_size;
+// uint32_t y_size;
+// uint32_t unused
+// };
+
+VariableInst *AddGAMetadata(Builder &b, Module *m) {
+ TypeIntInst *UInt32Ty = m->getUnsignedIntType(32);
+ std::vector<Instruction *> metadata{UInt32Ty, UInt32Ty, UInt32Ty, UInt32Ty};
+ auto MetadataStructTy = m->getStructType(metadata.data(), metadata.size());
+ // FIXME: workaround on a weird OpAccessChain member offset problem. Somehow
+ // when given constant indices, OpAccessChain returns pointers that are 4
+ // bytes less than what are supposed to be (at runtime). For now workaround
+ // this with +4 the member offsets.
+ MetadataStructTy->memberDecorate(0, Decoration::Offset)->addExtraOperand(4);
+ MetadataStructTy->memberDecorate(1, Decoration::Offset)->addExtraOperand(8);
+ MetadataStructTy->memberDecorate(2, Decoration::Offset)->addExtraOperand(12);
+ MetadataStructTy->memberDecorate(3, Decoration::Offset)->addExtraOperand(16);
+ // TBD: Implement getArrayType. RuntimeArray requires buffers and hence we
+ // cannot use PushConstant underneath
+ auto MetadataBufSTy = m->getRuntimeArrayType(MetadataStructTy);
+ // Stride of metadata.
+ MetadataBufSTy->decorate(Decoration::ArrayStride)
+ ->addExtraOperand(metadata.size() * sizeof(uint32_t));
+ auto MetadataSSBO = m->getStructType(MetadataBufSTy);
+ MetadataSSBO->decorate(Decoration::BufferBlock);
+ auto MetadataPtrTy = m->getPointerType(StorageClass::Uniform, MetadataSSBO);
+
+ VariableInst *MetadataVar =
+ b.MakeVariable(MetadataPtrTy, StorageClass::Uniform);
+ MetadataVar->decorate(Decoration::DescriptorSet)->addExtraOperand(0);
+ MetadataVar->decorate(Decoration::Binding)->addExtraOperand(1);
+ m->addVariable(MetadataVar);
+
+ return MetadataVar;
+}
+
+std::string CreateGAIDMetadata(
+ const llvm::SmallVectorImpl<rs2spirv::RSAllocationInfo> &Allocs) {
+
+ std::stringstream mapping;
+ bool printed = false;
+
+ mapping << "{\"__RSoV_GA\": {";
+ for (auto &A : Allocs) {
+ // Skip unused GAs
+ if (!A.hasID()) {
+ continue;
+ }
+ if (printed)
+ mapping << ", ";
+ // "GA name" to the ID of the GA
+ mapping << "\"" << A.VarName.substr(1) << "\":" << A.ID;
+ printed = true;
+ }
+ mapping << "}}";
+
+ if (printed)
+ return mapping.str().c_str();
+ else
+ return "";
+}
+} // anonymous namespace
+
+// Replacing calls to lowered accessors, e.g., __rsov_rsAllocationGetDimX
+// which was created from rsAllocationGetDimX by replacing the allocation
+// with an ID in an earlier LLVM pass (see GlobalAllocationPass.cpp),
+// to access the global allocation metadata.
+//
+// For example, the source code may look like:
+//
+// rs_allocation g;
+// ...
+// uint32_t foo = rsAllocationGetDimX(g);
+//
+// After the GlobalAllocPass, it would look like the LLVM IR
+// equivalent of:
+//
+// uint32_t foo = __rsov_rsAllocationGetDimX(0);
+//
+// After that pass, g is removed, and references in intrinsics
+// to g would be replaced with an assigned unique id (0 here), and
+// rsAllocationGetDimX() would be replaced by __rsov_rsAllocationGetDimX()
+// where the only difference is the argument being replaced by the unique
+// ID. __rsov_rsAllocationGetDimX() does not really exist - it is used
+// as a marker for this pass to work on.
+//
+// After this GAAccessTransformer pass, it would look like (in SPIRIT):
+//
+// uint32_t foo = Metadata[0].size_x;
+//
+// where the OpFunctionCall to __rsov_rsAllocationGetDim() is replaced by
+// an OpAccessChain and OpLoad from the metadata buffer.
+
+class GAAccessorTransformer : public Transformer {
+public:
+ GAAccessorTransformer()
+ : mBuilder(), mMetadata(nullptr),
+ mAllocs(rs2spirv::Context::getInstance().getGlobalAllocs()) {}
+
+ std::vector<uint32_t> runAndSerialize(Module *module, int *error) override {
+ std::string GAMD = CreateGAIDMetadata(mAllocs);
+ if (GAMD.size() > 0) {
+ module->addString(GAMD.c_str());
+ }
+ mMetadata = AddGAMetadata(mBuilder, module);
+ return Transformer::runAndSerialize(module, error);
+ }
+
+ Instruction *transform(FunctionCallInst *call) {
+ FunctionInst *func =
+ static_cast<FunctionInst *>(call->mOperand1.mInstruction);
+ const char *name = getModule()->lookupNameByInstruction(func);
+ if (!name) {
+ return call;
+ }
+
+ Instruction *inst = nullptr;
+ // Maps name into a SPIR-V instruction
+ // TODO: generalize it to support more accessors
+ if (!strcmp(name, "__rsov_rsAllocationGetDimX")) {
+ TypeIntInst *UInt32Ty = getModule()->getUnsignedIntType(32);
+ // TODO: hardcoded layout
+ auto ConstZero = getModule()->getConstant(UInt32Ty, 0U);
+ auto ConstOne = getModule()->getConstant(UInt32Ty, 1U);
+
+ // TODO: Use constant memory later
+ auto resultPtrType =
+ getModule()->getPointerType(StorageClass::Uniform, UInt32Ty);
+ AccessChainInst *LoadPtr = mBuilder.MakeAccessChain(
+ resultPtrType, mMetadata, {ConstZero, ConstZero, ConstOne});
+ insert(LoadPtr);
+
+ inst = mBuilder.MakeLoad(UInt32Ty, LoadPtr);
+ inst->setId(call->getId());
+ } else {
+ inst = call;
+ }
+ return inst;
+ }
+
+private:
+ Builder mBuilder;
+ VariableInst *mMetadata;
+ llvm::SmallVectorImpl<rs2spirv::RSAllocationInfo> &mAllocs;
+};
+
+} // namespace spirit
+} // namespace android
+
+namespace rs2spirv {
+
+android::spirit::Pass *CreateGAPass(void) {
+ return new android::spirit::GAAccessorTransformer();
+}
+
+} // namespace rs2spirv
diff --git a/rsov/compiler/GlobalAllocSPIRITPass.h b/rsov/compiler/GlobalAllocSPIRITPass.h
new file mode 100644
index 0000000..b3a6ecb
--- /dev/null
+++ b/rsov/compiler/GlobalAllocSPIRITPass.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef GLOBALALLOCSPIRITPASS_H
+#define GLOBALALLOCSPIRITPASS_H
+
+namespace android {
+namespace spirit {
+
+class Pass;
+
+} // namespace spirit
+} // namespace android
+
+namespace rs2spirv {
+
+android::spirit::Pass *CreateGAPass();
+
+} // namespace rs2spirv
+
+#endif // GLOBALALLOCSPIRITPASS_H
diff --git a/rsov/compiler/GlobalMergePass.cpp b/rsov/compiler/GlobalMergePass.cpp
new file mode 100644
index 0000000..deb82f0
--- /dev/null
+++ b/rsov/compiler/GlobalMergePass.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2016-2017, 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.
+ */
+
+#include "GlobalMergePass.h"
+
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "Context.h"
+#include "RSAllocationUtils.h"
+
+#include <functional>
+
+#define DEBUG_TYPE "rs2spirv-global-merge"
+
+using namespace llvm;
+
+namespace rs2spirv {
+
+namespace {
+
+class GlobalMergePass : public ModulePass {
+public:
+ static char ID;
+ GlobalMergePass(bool CPU = false) : ModulePass(ID), mForCPU(CPU) {}
+ const char *getPassName() const override { return "GlobalMergePass"; }
+
+ bool runOnModule(Module &M) override {
+ DEBUG(dbgs() << "RS2SPIRVGlobalMergePass\n");
+
+ SmallVector<GlobalVariable *, 8> Globals;
+ if (!collectGlobals(M, Globals)) {
+ return false; // Module not modified.
+ }
+
+ SmallVector<Type *, 8> Tys;
+ Tys.reserve(Globals.size());
+
+ Context &RS2SPIRVCtxt = Context::getInstance();
+
+ uint32_t index = 0;
+ for (GlobalVariable *GV : Globals) {
+ Tys.push_back(GV->getValueType());
+ const char *name = GV->getName().data();
+ RS2SPIRVCtxt.addExportVarIndex(name, index);
+ index++;
+ }
+
+ LLVMContext &LLVMCtxt = M.getContext();
+
+ StructType *MergedTy = StructType::create(LLVMCtxt, "struct.__GPUBuffer");
+ MergedTy->setBody(Tys, false);
+
+ // Size calculation has to consider data layout
+ const DataLayout &DL = M.getDataLayout();
+ const uint64_t BufferSize = DL.getTypeAllocSize(MergedTy);
+ RS2SPIRVCtxt.setGlobalSize(BufferSize);
+
+ Type *BufferVarTy = mForCPU ? static_cast<Type *>(PointerType::getUnqual(
+ Type::getInt8Ty(M.getContext())))
+ : static_cast<Type *>(MergedTy);
+ GlobalVariable *MergedGV =
+ new GlobalVariable(M, BufferVarTy, false, GlobalValue::ExternalLinkage,
+ nullptr, "__GPUBlock");
+
+ // For CPU, create a constant struct for initial values, which has each of
+ // its fields initialized to the original value of the corresponding global
+ // variable.
+ // During the script initialization, the driver should copy these initial
+ // values to the global buffer.
+ if (mForCPU) {
+ CreateInitFunction(LLVMCtxt, M, MergedGV, MergedTy, BufferSize, Globals);
+ }
+
+ const bool forCPU = mForCPU;
+ IntegerType *const Int32Ty = Type::getInt32Ty(LLVMCtxt);
+ ConstantInt *const Zero = ConstantInt::get(Int32Ty, 0);
+ Value *Idx[] = {Zero, nullptr};
+
+ auto InstMaker = [forCPU, MergedGV, MergedTy,
+ &Idx](Instruction *InsertBefore) {
+ Value *Base = MergedGV;
+ if (forCPU) {
+ LoadInst *Load = new LoadInst(MergedGV, "", InsertBefore);
+ DEBUG(Load->dump());
+ Base = new BitCastInst(Load, PointerType::getUnqual(MergedTy), "",
+ InsertBefore);
+ DEBUG(Base->dump());
+ }
+ GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(
+ MergedTy, Base, Idx, "", InsertBefore);
+ DEBUG(GEP->dump());
+ return GEP;
+ };
+
+ for (size_t i = 0, e = Globals.size(); i != e; ++i) {
+ GlobalVariable *G = Globals[i];
+ Idx[1] = ConstantInt::get(Int32Ty, i);
+ ReplaceAllUsesWithNewInstructions(G, std::cref(InstMaker));
+ G->eraseFromParent();
+ }
+
+ // Return true, as the pass modifies module.
+ return true;
+ }
+
+private:
+ // In the User of Value Old, replaces all references of Old with Value New
+ static inline void ReplaceUse(User *U, Value *Old, Value *New) {
+ for (unsigned i = 0, n = U->getNumOperands(); i < n; ++i) {
+ if (U->getOperand(i) == Old) {
+ U->getOperandUse(i) = New;
+ }
+ }
+ }
+
+ // Replaces each use of V with new instructions created by
+ // funcCreateAndInsert and inserted right before that use. In the cases where
+ // the use is not an instruction, but a constant expression, recursively
+ // replaces that constant expression with a newly constructed equivalent
+ // instruction, before replacing V in that new instruction.
+ static inline void ReplaceAllUsesWithNewInstructions(
+ Value *V,
+ std::function<Instruction *(Instruction *)> funcCreateAndInsert) {
+ SmallVector<User *, 8> Users(V->user_begin(), V->user_end());
+ for (User *U : Users) {
+ if (Instruction *Inst = dyn_cast<Instruction>(U)) {
+ DEBUG(dbgs() << "\nBefore replacement:\n");
+ DEBUG(Inst->dump());
+ DEBUG(dbgs() << "----\n");
+
+ ReplaceUse(U, V, funcCreateAndInsert(Inst));
+
+ DEBUG(Inst->dump());
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
+ auto InstMaker([CE, V, &funcCreateAndInsert](Instruction *UserOfU) {
+ Instruction *Inst = CE->getAsInstruction();
+ Inst->insertBefore(UserOfU);
+ ReplaceUse(Inst, V, funcCreateAndInsert(Inst));
+
+ DEBUG(Inst->dump());
+ return Inst;
+ });
+ ReplaceAllUsesWithNewInstructions(U, InstMaker);
+ } else {
+ DEBUG(U->dump());
+ llvm_unreachable("Expecting only Instruction or ConstantExpr");
+ }
+ }
+ }
+
+ static inline void
+ CreateInitFunction(LLVMContext &LLVMCtxt, Module &M, GlobalVariable *MergedGV,
+ StructType *MergedTy, const uint64_t BufferSize,
+ const SmallVectorImpl<GlobalVariable *> &Globals) {
+ SmallVector<Constant *, 8> Initializers;
+ Initializers.reserve(Globals.size());
+ for (size_t i = 0, e = Globals.size(); i != e; ++i) {
+ GlobalVariable *G = Globals[i];
+ Initializers.push_back(G->getInitializer());
+ }
+ ArrayRef<Constant *> ArrInit(Initializers.begin(), Initializers.end());
+ Constant *MergedInitializer = ConstantStruct::get(MergedTy, ArrInit);
+ GlobalVariable *MergedInit =
+ new GlobalVariable(M, MergedTy, true, GlobalValue::InternalLinkage,
+ MergedInitializer, "__GPUBlock0");
+
+ Function *UserInit = M.getFunction("init");
+ // If there is no user-defined init() function, make the new global
+ // initialization function the init().
+ StringRef FName(UserInit ? ".rsov.global_init" : "init");
+ Function *Func;
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(LLVMCtxt), false);
+ Func = Function::Create(FTy, GlobalValue::ExternalLinkage, FName, &M);
+ BasicBlock *Blk = BasicBlock::Create(LLVMCtxt, "entry", Func);
+ IRBuilder<> LLVMIRBuilder(Blk);
+ LoadInst *Load = LLVMIRBuilder.CreateLoad(MergedGV);
+ LLVMIRBuilder.CreateMemCpy(Load, MergedInit, BufferSize, 0);
+ LLVMIRBuilder.CreateRetVoid();
+
+ // If there is a user-defined init() function, add a call to the global
+ // initialization function in the beginning of that function.
+ if (UserInit) {
+ BasicBlock &EntryBlk = UserInit->getEntryBlock();
+ CallInst::Create(Func, {}, "", &EntryBlk.front());
+ }
+ }
+
+ bool collectGlobals(Module &M, SmallVectorImpl<GlobalVariable *> &Globals) {
+ for (GlobalVariable &GV : M.globals()) {
+ assert(!GV.hasComdat() && "global variable has a comdat section");
+ assert(!GV.hasSection() && "global variable has a non-default section");
+ assert(!GV.isDeclaration() && "global variable is only a declaration");
+ assert(!GV.isThreadLocal() && "global variable is thread-local");
+ assert(GV.getType()->getAddressSpace() == 0 &&
+ "global variable has non-default address space");
+
+ // TODO: Constants accessed by kernels should be handled differently
+ if (GV.isConstant()) {
+ continue;
+ }
+
+ // Global Allocations are handled differently in separate passes
+ if (isRSAllocation(GV)) {
+ continue;
+ }
+
+ Globals.push_back(&GV);
+ }
+
+ return !Globals.empty();
+ }
+
+ bool mForCPU;
+};
+
+} // namespace
+
+char GlobalMergePass::ID = 0;
+
+ModulePass *createGlobalMergePass(bool CPU) { return new GlobalMergePass(CPU); }
+
+} // namespace rs2spirv
diff --git a/rsov/compiler/GlobalMergePass.h b/rsov/compiler/GlobalMergePass.h
new file mode 100644
index 0000000..e43ab7b
--- /dev/null
+++ b/rsov/compiler/GlobalMergePass.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016, 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.
+ */
+
+#ifndef RS2SPIRV_GLOBAL_MERGE_PASS_H
+#define RS2SPIRV_GLOBAL_MERGE_PASS_H
+
+namespace llvm {
+class ModulePass;
+} // namespace llvm
+
+namespace rs2spirv {
+
+llvm::ModulePass *createGlobalMergePass(bool CPU = false);
+
+} // namespace rs2spirv
+
+#endif
diff --git a/rsov/compiler/InlinePreparationPass.cpp b/rsov/compiler/InlinePreparationPass.cpp
new file mode 100644
index 0000000..fc1a50d
--- /dev/null
+++ b/rsov/compiler/InlinePreparationPass.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2016, 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.
+ */
+
+#include "InlinePreparationPass.h"
+
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "Context.h"
+
+#define DEBUG_TYPE "rs2spirv-inline"
+
+using namespace llvm;
+
+namespace rs2spirv {
+
+namespace {
+
+class InlinePreparationPass : public ModulePass {
+public:
+ static char ID;
+ explicit InlinePreparationPass() : ModulePass(ID) {}
+
+ const char *getPassName() const override { return "InlinePreparationPass"; }
+
+ bool runOnModule(Module &M) override {
+ DEBUG(dbgs() << "InlinePreparationPass\n");
+
+ rs2spirv::Context &Ctxt = rs2spirv::Context::getInstance();
+
+ for (auto &F : M.functions()) {
+ if (F.isDeclaration()) {
+ continue;
+ }
+
+ if (Ctxt.isForEachKernel(F.getName())) {
+ continue; // Skip kernels.
+ }
+
+ F.addFnAttr(Attribute::AlwaysInline);
+ F.setLinkage(GlobalValue::InternalLinkage);
+
+ DEBUG(dbgs() << "Marked as alwaysinline:\t" << F.getName() << '\n');
+ }
+
+ // Returns true, because this pass modifies the Module.
+ return true;
+ }
+};
+
+} // namespace
+
+char InlinePreparationPass::ID = 0;
+
+ModulePass *createInlinePreparationPass() {
+ return new InlinePreparationPass();
+}
+
+} // namespace rs2spirv
diff --git a/rsov/compiler/InlinePreparationPass.h b/rsov/compiler/InlinePreparationPass.h
new file mode 100644
index 0000000..12bbfa3
--- /dev/null
+++ b/rsov/compiler/InlinePreparationPass.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016, 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.
+ */
+
+#ifndef RS2SPIRV_INLINE_PREPARATION_PASS_H
+#define RS2SPIRV_INLINE_PREPARATION_PASS_H
+
+namespace llvm {
+class ModulePass;
+} // namespace llvm
+
+namespace rs2spirv {
+
+llvm::ModulePass *createInlinePreparationPass();
+
+} // namespace rs2spirv
+
+#endif
diff --git a/rsov/compiler/RSAllocationUtils.cpp b/rsov/compiler/RSAllocationUtils.cpp
new file mode 100644
index 0000000..8b66a6c
--- /dev/null
+++ b/rsov/compiler/RSAllocationUtils.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2016, 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.
+ */
+
+#include "RSAllocationUtils.h"
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "cxxabi.h"
+
+#include <sstream>
+#include <unordered_map>
+
+#define DEBUG_TYPE "rs2spirv-rs-allocation-utils"
+
+using namespace llvm;
+
+namespace rs2spirv {
+
+bool isRSAllocation(const GlobalVariable &GV) {
+ auto *PT = cast<PointerType>(GV.getType());
+ DEBUG(PT->dump());
+
+ auto *VT = PT->getElementType();
+ DEBUG(VT->dump());
+ std::string TypeName;
+ raw_string_ostream RSO(TypeName);
+ VT->print(RSO);
+ RSO.str(); // Force flush.
+ DEBUG(dbgs() << "TypeName: " << TypeName << '\n');
+
+ return TypeName.find("struct.rs_allocation") != std::string::npos;
+}
+
+bool getRSAllocationInfo(Module &M, SmallVectorImpl<RSAllocationInfo> &Allocs) {
+ DEBUG(dbgs() << "getRSAllocationInfo\n");
+ for (auto &GV : M.globals()) {
+ if (GV.isDeclaration() || !isRSAllocation(GV))
+ continue;
+
+ Allocs.push_back({'%' + GV.getName().str(), None, &GV, -1});
+ }
+
+ return true;
+}
+
+// Collect Allocation access calls into the Calls
+// Also update Allocs with assigned ID.
+// After calling this function, Allocs would contain the mapping from
+// GV name to the corresponding ID.
+bool getRSAllocAccesses(SmallVectorImpl<RSAllocationInfo> &Allocs,
+ SmallVectorImpl<RSAllocationCallInfo> &Calls) {
+ DEBUG(dbgs() << "getRSGEATCalls\n");
+ DEBUG(dbgs() << "\n\n~~~~~~~~~~~~~~~~~~~~~\n\n");
+
+ std::unordered_map<const Value *, const GlobalVariable *> Mapping;
+ int id_assigned = 0;
+
+ for (auto &A : Allocs) {
+ auto *GV = A.GlobalVar;
+ std::vector<User *> WorkList(GV->user_begin(), GV->user_end());
+ size_t Idx = 0;
+
+ while (Idx < WorkList.size()) {
+ auto *U = WorkList[Idx];
+ DEBUG(dbgs() << "Visiting ");
+ DEBUG(U->dump());
+ ++Idx;
+ auto It = Mapping.find(U);
+ if (It != Mapping.end()) {
+ if (It->second == GV) {
+ continue;
+ } else {
+ errs() << "Duplicate global mapping discovered!\n";
+ errs() << "\nGlobal: ";
+ GV->print(errs());
+ errs() << "\nExisting mapping: ";
+ It->second->print(errs());
+ errs() << "\nUser: ";
+ U->print(errs());
+ errs() << '\n';
+
+ return false;
+ }
+ }
+
+ Mapping[U] = GV;
+ DEBUG(dbgs() << "New mapping: ");
+ DEBUG(U->print(dbgs()));
+ DEBUG(dbgs() << " -> " << GV->getName() << '\n');
+
+ if (auto *FCall = dyn_cast<CallInst>(U)) {
+ if (auto *F = FCall->getCalledFunction()) {
+ const auto FName = F->getName();
+ DEBUG(dbgs() << "Discovered function call to : " << FName << '\n');
+ // Treat memcpy as moves for the purpose of this analysis
+ if (FName.startswith("llvm.memcpy")) {
+ assert(FCall->getNumArgOperands() > 0);
+ Value *CopyDest = FCall->getArgOperand(0);
+ // We are interested in the users of the dest operand of
+ // memcpy here
+ Value *LocalCopy = CopyDest->stripPointerCasts();
+ User *NewU = dyn_cast<User>(LocalCopy);
+ assert(NewU);
+ WorkList.push_back(NewU);
+ continue;
+ }
+
+ char *demangled = __cxxabiv1::__cxa_demangle(
+ FName.str().c_str(), nullptr, nullptr, nullptr);
+ if (!demangled)
+ continue;
+ const StringRef DemangledNameRef(demangled);
+ DEBUG(dbgs() << "Demangled name: " << DemangledNameRef << '\n');
+
+ const StringRef GEAPrefix = "rsGetElementAt_";
+ const StringRef SEAPrefix = "rsSetElementAt_";
+ const StringRef DIMXPrefix = "rsAllocationGetDimX";
+ assert(GEAPrefix.size() == SEAPrefix.size());
+
+ const bool IsGEA = DemangledNameRef.startswith(GEAPrefix);
+ const bool IsSEA = DemangledNameRef.startswith(SEAPrefix);
+ const bool IsDIMX = DemangledNameRef.startswith(DIMXPrefix);
+
+ assert(IsGEA || IsSEA || IsDIMX);
+ if (!A.hasID()) {
+ A.assignID(id_assigned++);
+ }
+
+ if (IsGEA || IsSEA) {
+ DEBUG(dbgs() << "Found rsAlloc function!\n");
+
+ const auto Kind =
+ IsGEA ? RSAllocAccessKind::GEA : RSAllocAccessKind::SEA;
+
+ const auto RSElementTy =
+ DemangledNameRef.drop_front(GEAPrefix.size());
+
+ Calls.push_back({A, FCall, Kind, RSElementTy.str()});
+ continue;
+ } else if (DemangledNameRef.startswith(GEAPrefix.drop_back()) ||
+ DemangledNameRef.startswith(SEAPrefix.drop_back())) {
+ errs() << "Untyped accesses to global rs_allocations are not "
+ "supported.\n";
+ return false;
+ } else if (IsDIMX) {
+ DEBUG(dbgs() << "Found rsAllocationGetDimX function!\n");
+ const auto Kind = RSAllocAccessKind::DIMX;
+ Calls.push_back({A, FCall, Kind, ""});
+ }
+ }
+ }
+
+ // TODO: Consider using set-like container to reduce computational
+ // complexity.
+ for (auto *NewU : U->users())
+ if (std::find(WorkList.begin(), WorkList.end(), NewU) == WorkList.end())
+ WorkList.push_back(NewU);
+ }
+ }
+
+ std::unordered_map<const GlobalVariable *, std::string> GVAccessTypes;
+
+ for (auto &Access : Calls) {
+ auto AccessElemTyIt = GVAccessTypes.find(Access.RSAlloc.GlobalVar);
+ if (AccessElemTyIt != GVAccessTypes.end() &&
+ AccessElemTyIt->second != Access.RSElementTy) {
+ errs() << "Could not infere element type for: ";
+ Access.RSAlloc.GlobalVar->print(errs());
+ errs() << '\n';
+ return false;
+ } else if (AccessElemTyIt == GVAccessTypes.end()) {
+ GVAccessTypes.emplace(Access.RSAlloc.GlobalVar, Access.RSElementTy);
+ Access.RSAlloc.RSElementType = Access.RSElementTy;
+ }
+ }
+
+ DEBUG(dbgs() << "\n\n~~~~~~~~~~~~~~~~~~~~~\n\n");
+ return true;
+}
+
+bool solidifyRSAllocAccess(Module &M, RSAllocationCallInfo CallInfo) {
+ DEBUG(dbgs() << "solidifyRSAllocAccess " << CallInfo.RSAlloc.VarName << '\n');
+ auto *FCall = CallInfo.FCall;
+ auto *Fun = FCall->getCalledFunction();
+ assert(Fun);
+
+ StringRef FName;
+ if (CallInfo.Kind == RSAllocAccessKind::DIMX)
+ FName = "rsAllocationGetDimX";
+ else
+ FName = Fun->getName();
+
+ std::ostringstream OSS;
+ OSS << "__rsov_" << FName.str();
+ // Make up uint32_t F(uint32_t)
+ Type *UInt32Ty = IntegerType::get(M.getContext(), 32);
+ auto *NewFT = FunctionType::get(UInt32Ty, ArrayRef<Type *>(UInt32Ty), false);
+
+ auto *NewF = Function::Create(NewFT, // Fun->getFunctionType(),
+ Function::ExternalLinkage, OSS.str(), &M);
+ FCall->setCalledFunction(NewF);
+ FCall->setArgOperand(0, ConstantInt::get(UInt32Ty, 0, false));
+ NewF->setAttributes(Fun->getAttributes());
+
+ DEBUG(M.dump());
+
+ return true;
+}
+
+} // namespace rs2spirv
diff --git a/rsov/compiler/RSAllocationUtils.h b/rsov/compiler/RSAllocationUtils.h
new file mode 100644
index 0000000..b25cfde
--- /dev/null
+++ b/rsov/compiler/RSAllocationUtils.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2016, 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.
+ */
+
+#ifndef RS2SPIRV_RS_ALLOCATION_UTILS_H
+#define RS2SPIRV_RS_ALLOCATION_UTILS_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+
+#include <string>
+
+namespace llvm {
+class CallInst;
+class GlobalVariable;
+class Module;
+class Type;
+} // namespace llvm
+
+namespace rs2spirv {
+
+struct RSAllocationInfo {
+ std::string VarName;
+ llvm::Optional<std::string> RSElementType;
+ llvm::GlobalVariable *GlobalVar;
+ // Assigned unique identifier for this allocation;
+ // not the slot #.
+ // Represents the index of this allocation's metadata
+ // in the global allocation metadata Vulkan buffer
+ int ID;
+ bool hasID(void) const { return ID >= 0; }
+ void assignID(int no) { ID = no; }
+};
+
+enum class RSAllocAccessKind { GEA, SEA, DIMX };
+
+struct RSAllocationCallInfo {
+ RSAllocationInfo &RSAlloc;
+ llvm::CallInst *FCall;
+ RSAllocAccessKind Kind;
+ std::string RSElementTy;
+};
+
+bool isRSAllocation(const llvm::GlobalVariable &GV);
+bool getRSAllocationInfo(llvm::Module &M,
+ llvm::SmallVectorImpl<RSAllocationInfo> &Allocs);
+bool getRSAllocAccesses(llvm::SmallVectorImpl<RSAllocationInfo> &Allocs,
+ llvm::SmallVectorImpl<RSAllocationCallInfo> &Calls);
+bool solidifyRSAllocAccess(llvm::Module &M, RSAllocationCallInfo CallInfo);
+
+} // namespace rs2spirv
+
+#endif
diff --git a/rsov/compiler/RSSPIRVWriter.cpp b/rsov/compiler/RSSPIRVWriter.cpp
new file mode 100644
index 0000000..e95db6b
--- /dev/null
+++ b/rsov/compiler/RSSPIRVWriter.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2016, 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.
+ */
+
+#include "RSSPIRVWriter.h"
+
+#include "Builtin.h"
+#include "Context.h"
+#include "GlobalAllocPass.h"
+#include "GlobalAllocSPIRITPass.h"
+#include "GlobalMergePass.h"
+#include "InlinePreparationPass.h"
+#include "RemoveNonkernelsPass.h"
+#include "SPIRVModule.h"
+#include "Wrapper.h"
+#include "bcinfo/MetadataExtractor.h"
+#include "pass_queue.h"
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/SPIRV.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Scalar.h"
+
+#define DEBUG_TYPE "rs2spirv-writer"
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace rs2spirv {
+
+void addPassesForRS2SPIRV(llvm::legacy::PassManager &PassMgr) {
+ PassMgr.add(createGlobalMergePass());
+
+ PassMgr.add(createInlinePreparationPass());
+ PassMgr.add(createAlwaysInlinerPass());
+ PassMgr.add(createRemoveNonkernelsPass());
+ // Delete unreachable globals.
+ PassMgr.add(createGlobalDCEPass());
+ // Remove dead debug info.
+ PassMgr.add(createStripDeadDebugInfoPass());
+ // Remove dead func decls.
+ PassMgr.add(createStripDeadPrototypesPass());
+ // Transform global allocations and accessors (rs[GS]etElementAt)
+ PassMgr.add(createGlobalAllocPass());
+ // Removed dead MemCpys in 64-bit targets after global alloc pass
+ PassMgr.add(createDeadStoreEliminationPass());
+ PassMgr.add(createAggressiveDCEPass());
+ // Delete unreachable globals (after removing global allocations)
+ PassMgr.add(createRemoveAllGlobalAllocPass());
+ PassMgr.add(createPromoteMemoryToRegisterPass());
+ PassMgr.add(createTransOCLMD());
+ // TODO: investigate removal of OCLTypeToSPIRV pass.
+ PassMgr.add(createOCLTypeToSPIRV());
+ PassMgr.add(createSPIRVRegularizeLLVM());
+ PassMgr.add(createSPIRVLowerConstExpr());
+ PassMgr.add(createSPIRVLowerBool());
+}
+
+bool WriteSPIRV(Context &Ctxt, Module *M,
+ llvm::raw_ostream &OS, std::string &ErrMsg) {
+ llvm::legacy::PassManager PassMgr;
+ addPassesForRS2SPIRV(PassMgr);
+
+ std::unique_ptr<SPIRVModule> BM(SPIRVModule::createSPIRVModule());
+
+ PassMgr.add(createLLVMToSPIRV(BM.get()));
+ PassMgr.run(*M);
+ DEBUG(M->dump());
+
+ if (BM->getError(ErrMsg) != SPIRVEC_Success) {
+ return false;
+ }
+
+ llvm::SmallString<4096> O;
+ llvm::raw_svector_ostream SVOS(O);
+
+ SVOS << *BM;
+
+ llvm::StringRef str = SVOS.str();
+ std::vector<uint32_t> words(str.size() / 4);
+
+ memcpy(words.data(), str.data(), str.size());
+
+ android::spirit::PassQueue spiritPasses;
+ spiritPasses.append(CreateWrapperPass(*M));
+ spiritPasses.append(CreateBuiltinPass());
+ spiritPasses.append(CreateGAPass());
+
+ int error;
+ auto wordsOut = spiritPasses.run(words, &error);
+
+ if (error != 0) {
+ OS << *BM;
+ ErrMsg = "Failed to generate wrappers for kernels";
+ return false;
+ }
+
+ OS.write(reinterpret_cast<const char *>(wordsOut.data()),
+ wordsOut.size() * 4);
+
+ return true;
+}
+
+} // namespace rs2spirv
diff --git a/rsov/compiler/RSSPIRVWriter.h b/rsov/compiler/RSSPIRVWriter.h
new file mode 100644
index 0000000..f2689fc
--- /dev/null
+++ b/rsov/compiler/RSSPIRVWriter.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2016, 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.
+ */
+
+#ifndef RS_SPIRV_WRITER_H
+#define RS_SPIRV_WRITER_H
+
+#include <string>
+
+namespace llvm {
+class Module;
+class raw_ostream;
+} // namespace llvm
+
+namespace bcinfo {
+class MetadataExtractor;
+} // namespace bcinfo
+
+namespace rs2spirv {
+
+class Context;
+
+bool WriteSPIRV(rs2spirv::Context &Ctxt, llvm::Module *M,
+ llvm::raw_ostream &OS, std::string &ErrMsg);
+
+} // namespace rs2spirv
+
+#endif
diff --git a/rsov/compiler/RemoveNonkernelsPass.cpp b/rsov/compiler/RemoveNonkernelsPass.cpp
new file mode 100644
index 0000000..82d2a30
--- /dev/null
+++ b/rsov/compiler/RemoveNonkernelsPass.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "RemoveNonkernelsPass.h"
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "Context.h"
+
+#define DEBUG_TYPE "rs2spirv-remove"
+
+using namespace llvm;
+
+namespace rs2spirv {
+
+namespace {
+
+void HandleTargetTriple(llvm::Module &M) {
+ Triple TT(M.getTargetTriple());
+ auto Arch = TT.getArch();
+
+ StringRef NewTriple;
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unrecognized architecture");
+ break;
+ case Triple::arm:
+ NewTriple = "spir-unknown-unknown";
+ break;
+ case Triple::aarch64:
+ NewTriple = "spir64-unknown-unknown";
+ break;
+ case Triple::spir:
+ case Triple::spir64:
+ DEBUG(dbgs() << "!!! Already a spir triple !!!\n");
+ }
+
+ DEBUG(dbgs() << "New triple:\t" << NewTriple << "\n");
+ M.setTargetTriple(NewTriple);
+}
+
+class RemoveNonkernelsPass : public ModulePass {
+public:
+ static char ID;
+ explicit RemoveNonkernelsPass() : ModulePass(ID) {}
+
+ const char *getPassName() const override { return "RemoveNonkernelsPass"; }
+
+ bool runOnModule(Module &M) override {
+ DEBUG(dbgs() << "RemoveNonkernelsPass\n");
+ DEBUG(M.dump());
+
+ HandleTargetTriple(M);
+
+ rs2spirv::Context &Ctxt = rs2spirv::Context::getInstance();
+
+ if (Ctxt.getNumForEachKernel() == 0) {
+ DEBUG(dbgs() << "RemoveNonkernelsPass detected no kernel\n");
+ // Returns false, since no modification is made to the Module.
+ return false;
+ }
+
+ std::vector<Function *> Functions;
+ for (auto &F : M.functions()) {
+ Functions.push_back(&F);
+ }
+
+ for (auto &F : Functions) {
+ if (F->isDeclaration())
+ continue;
+
+ if (Ctxt.isForEachKernel(F->getName())) {
+ continue; // Skip kernels.
+ }
+
+ F->replaceAllUsesWith(UndefValue::get((Type *)F->getType()));
+ F->eraseFromParent();
+
+ DEBUG(dbgs() << "Removed:\t" << F->getName() << '\n');
+ }
+
+ DEBUG(M.dump());
+ DEBUG(dbgs() << "Done removal\n");
+
+ // Returns true, because the pass modifies the Module.
+ return true;
+ }
+};
+
+} // namespace
+
+char RemoveNonkernelsPass::ID = 0;
+
+ModulePass *createRemoveNonkernelsPass() {
+ return new RemoveNonkernelsPass();
+}
+
+} // namespace rs2spirv
diff --git a/rsov/compiler/RemoveNonkernelsPass.h b/rsov/compiler/RemoveNonkernelsPass.h
new file mode 100644
index 0000000..eed2dc8
--- /dev/null
+++ b/rsov/compiler/RemoveNonkernelsPass.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef RS2SPIRV_REMOVE_NONKERNELS_PASS_H
+#define RS2SPIRV_REMOVE_NONKERNELS_PASS_H
+
+namespace llvm {
+class ModulePass;
+} // namespace llvm
+
+namespace rs2spirv {
+
+llvm::ModulePass *createRemoveNonkernelsPass();
+
+} // namespace rs2spirv
+
+#endif
diff --git a/rsov/compiler/Wrapper.cpp b/rsov/compiler/Wrapper.cpp
new file mode 100644
index 0000000..550cc46
--- /dev/null
+++ b/rsov/compiler/Wrapper.cpp
@@ -0,0 +1,427 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "Wrapper.h"
+
+#include "llvm/IR/Module.h"
+
+#include "Builtin.h"
+#include "Context.h"
+#include "GlobalAllocSPIRITPass.h"
+#include "RSAllocationUtils.h"
+#include "bcinfo/MetadataExtractor.h"
+#include "builder.h"
+#include "instructions.h"
+#include "module.h"
+#include "pass.h"
+
+#include <sstream>
+#include <vector>
+
+using bcinfo::MetadataExtractor;
+
+namespace android {
+namespace spirit {
+
+VariableInst *AddBuffer(Instruction *elementType, uint32_t binding, Builder &b,
+ Module *m) {
+ auto ArrTy = m->getRuntimeArrayType(elementType);
+ const size_t stride = m->getSize(elementType);
+ ArrTy->decorate(Decoration::ArrayStride)->addExtraOperand(stride);
+ auto StructTy = m->getStructType(ArrTy);
+ StructTy->decorate(Decoration::BufferBlock);
+ StructTy->memberDecorate(0, Decoration::Offset)->addExtraOperand(0);
+
+ auto StructPtrTy = m->getPointerType(StorageClass::Uniform, StructTy);
+
+ VariableInst *bufferVar = b.MakeVariable(StructPtrTy, StorageClass::Uniform);
+ bufferVar->decorate(Decoration::DescriptorSet)->addExtraOperand(0);
+ bufferVar->decorate(Decoration::Binding)->addExtraOperand(binding);
+ m->addVariable(bufferVar);
+
+ return bufferVar;
+}
+
+bool AddWrapper(const char *name, const uint32_t signature,
+ const uint32_t numInput, Builder &b, Module *m) {
+ FunctionDefinition *kernel = m->lookupFunctionDefinitionByName(name);
+ if (kernel == nullptr) {
+ // In the metadata for RenderScript LLVM bitcode, the first foreach kernel
+ // is always reserved for the root kernel, even though in the most recent RS
+ // apps it does not exist. Simply bypass wrapper generation here, and return
+ // true for this case.
+ // Otherwise, if a non-root kernel function cannot be found, it is a
+ // fatal internal error which is really unexpected.
+ return (strncmp(name, "root", 4) == 0);
+ }
+
+ // The following three cases are not supported
+ if (!MetadataExtractor::hasForEachSignatureKernel(signature)) {
+ // Not handling old-style kernel
+ return false;
+ }
+
+ if (MetadataExtractor::hasForEachSignatureUsrData(signature)) {
+ // Not handling the user argument
+ return false;
+ }
+
+ if (MetadataExtractor::hasForEachSignatureCtxt(signature)) {
+ // Not handling the context argument
+ return false;
+ }
+
+ TypeVoidInst *VoidTy = m->getVoidType();
+ TypeFunctionInst *FuncTy = m->getFunctionType(VoidTy, nullptr, 0);
+ FunctionDefinition *Func =
+ b.MakeFunctionDefinition(VoidTy, FunctionControl::None, FuncTy);
+ m->addFunctionDefinition(Func);
+
+ Block *Blk = b.MakeBlock();
+ Func->addBlock(Blk);
+
+ Blk->addInstruction(b.MakeLabel());
+
+ TypeIntInst *UIntTy = m->getUnsignedIntType(32);
+
+ Instruction *XValue = nullptr;
+ Instruction *YValue = nullptr;
+ Instruction *ZValue = nullptr;
+ Instruction *Index = nullptr;
+ VariableInst *InvocationId = nullptr;
+ VariableInst *NumWorkgroups = nullptr;
+
+ if (MetadataExtractor::hasForEachSignatureIn(signature) ||
+ MetadataExtractor::hasForEachSignatureOut(signature) ||
+ MetadataExtractor::hasForEachSignatureX(signature) ||
+ MetadataExtractor::hasForEachSignatureY(signature) ||
+ MetadataExtractor::hasForEachSignatureZ(signature)) {
+ TypeVectorInst *V3UIntTy = m->getVectorType(UIntTy, 3);
+ InvocationId = m->getInvocationId();
+ auto IID = b.MakeLoad(V3UIntTy, InvocationId);
+ Blk->addInstruction(IID);
+
+ XValue = b.MakeCompositeExtract(UIntTy, IID, {0});
+ Blk->addInstruction(XValue);
+
+ YValue = b.MakeCompositeExtract(UIntTy, IID, {1});
+ Blk->addInstruction(YValue);
+
+ ZValue = b.MakeCompositeExtract(UIntTy, IID, {2});
+ Blk->addInstruction(ZValue);
+
+ // TODO: Use SpecConstant for workgroup size
+ auto ConstOne = m->getConstant(UIntTy, 1U);
+ auto GroupSize =
+ m->getConstantComposite(V3UIntTy, ConstOne, ConstOne, ConstOne);
+
+ auto GroupSizeX = b.MakeCompositeExtract(UIntTy, GroupSize, {0});
+ Blk->addInstruction(GroupSizeX);
+
+ auto GroupSizeY = b.MakeCompositeExtract(UIntTy, GroupSize, {1});
+ Blk->addInstruction(GroupSizeY);
+
+ NumWorkgroups = m->getNumWorkgroups();
+ auto NumGroup = b.MakeLoad(V3UIntTy, NumWorkgroups);
+ Blk->addInstruction(NumGroup);
+
+ auto NumGroupX = b.MakeCompositeExtract(UIntTy, NumGroup, {0});
+ Blk->addInstruction(NumGroupX);
+
+ auto NumGroupY = b.MakeCompositeExtract(UIntTy, NumGroup, {1});
+ Blk->addInstruction(NumGroupY);
+
+ auto GlobalSizeX = b.MakeIMul(UIntTy, GroupSizeX, NumGroupX);
+ Blk->addInstruction(GlobalSizeX);
+
+ auto GlobalSizeY = b.MakeIMul(UIntTy, GroupSizeY, NumGroupY);
+ Blk->addInstruction(GlobalSizeY);
+
+ auto RowsAlongZ = b.MakeIMul(UIntTy, GlobalSizeY, ZValue);
+ Blk->addInstruction(RowsAlongZ);
+
+ auto NumRows = b.MakeIAdd(UIntTy, YValue, RowsAlongZ);
+ Blk->addInstruction(NumRows);
+
+ auto NumCellsFromYZ = b.MakeIMul(UIntTy, GlobalSizeX, NumRows);
+ Blk->addInstruction(NumCellsFromYZ);
+
+ Index = b.MakeIAdd(UIntTy, NumCellsFromYZ, XValue);
+ Blk->addInstruction(Index);
+ }
+
+ std::vector<IdRef> inputs;
+
+ ConstantInst *ConstZero = m->getConstant(UIntTy, 0);
+
+ for (uint32_t i = 0; i < numInput; i++) {
+ FunctionParameterInst *param = kernel->getParameter(i);
+ Instruction *elementType = param->mResultType.mInstruction;
+ VariableInst *inputBuffer = AddBuffer(elementType, i + 3, b, m);
+
+ TypePointerInst *PtrTy =
+ m->getPointerType(StorageClass::Function, elementType);
+ AccessChainInst *Ptr =
+ b.MakeAccessChain(PtrTy, inputBuffer, {ConstZero, Index});
+ Blk->addInstruction(Ptr);
+
+ Instruction *input = b.MakeLoad(elementType, Ptr);
+ Blk->addInstruction(input);
+
+ inputs.push_back(IdRef(input));
+ }
+
+ // TODO: Convert from unsigned int to signed int if that is what the kernel
+ // function takes for the coordinate parameters
+ if (MetadataExtractor::hasForEachSignatureX(signature)) {
+ inputs.push_back(XValue);
+ if (MetadataExtractor::hasForEachSignatureY(signature)) {
+ inputs.push_back(YValue);
+ if (MetadataExtractor::hasForEachSignatureZ(signature)) {
+ inputs.push_back(ZValue);
+ }
+ }
+ }
+
+ auto resultType = kernel->getReturnType();
+ auto kernelCall =
+ b.MakeFunctionCall(resultType, kernel->getInstruction(), inputs);
+ Blk->addInstruction(kernelCall);
+
+ if (MetadataExtractor::hasForEachSignatureOut(signature)) {
+ VariableInst *OutputBuffer = AddBuffer(resultType, 2, b, m);
+ auto resultPtrType = m->getPointerType(StorageClass::Function, resultType);
+ AccessChainInst *OutPtr =
+ b.MakeAccessChain(resultPtrType, OutputBuffer, {ConstZero, Index});
+ Blk->addInstruction(OutPtr);
+ Blk->addInstruction(b.MakeStore(OutPtr, kernelCall));
+ }
+
+ Blk->addInstruction(b.MakeReturn());
+
+ std::string wrapperName("entry_");
+ wrapperName.append(name);
+
+ EntryPointDefinition *entry = b.MakeEntryPointDefinition(
+ ExecutionModel::GLCompute, Func, wrapperName.c_str());
+
+ entry->setLocalSize(1, 1, 1);
+
+ if (Index != nullptr) {
+ entry->addToInterface(InvocationId);
+ entry->addToInterface(NumWorkgroups);
+ }
+
+ m->addEntryPoint(entry);
+
+ return true;
+}
+
+bool DecorateGlobalBuffer(llvm::Module &LM, Builder &b, Module *m) {
+ Instruction *inst = m->lookupByName("__GPUBlock");
+ if (inst == nullptr) {
+ return true;
+ }
+
+ VariableInst *bufferVar = static_cast<VariableInst *>(inst);
+ bufferVar->decorate(Decoration::DescriptorSet)->addExtraOperand(0);
+ bufferVar->decorate(Decoration::Binding)->addExtraOperand(0);
+
+ TypePointerInst *StructPtrTy =
+ static_cast<TypePointerInst *>(bufferVar->mResultType.mInstruction);
+ TypeStructInst *StructTy =
+ static_cast<TypeStructInst *>(StructPtrTy->mOperand2.mInstruction);
+ StructTy->decorate(Decoration::BufferBlock);
+
+ // Decorate each member with proper offsets
+
+ const auto GlobalsB = LM.globals().begin();
+ const auto GlobalsE = LM.globals().end();
+ const auto Found =
+ std::find_if(GlobalsB, GlobalsE, [](const llvm::GlobalVariable &GV) {
+ return GV.getName() == "__GPUBlock";
+ });
+
+ if (Found == GlobalsE) {
+ return true; // GPUBlock not found - not an error by itself.
+ }
+
+ const llvm::GlobalVariable &G = *Found;
+
+ rs2spirv::Context &Ctxt = rs2spirv::Context::getInstance();
+ bool IsCorrectTy = false;
+ if (const auto *LPtrTy = llvm::dyn_cast<llvm::PointerType>(G.getType())) {
+ if (auto *LStructTy =
+ llvm::dyn_cast<llvm::StructType>(LPtrTy->getElementType())) {
+ IsCorrectTy = true;
+
+ const auto &DLayout = LM.getDataLayout();
+ const auto *SLayout = DLayout.getStructLayout(LStructTy);
+ assert(SLayout);
+ if (SLayout == nullptr) {
+ std::cerr << "struct layout is null" << std::endl;
+ return false;
+ }
+ std::vector<uint32_t> offsets;
+ for (uint32_t i = 0, e = LStructTy->getNumElements(); i != e; ++i) {
+ auto decor = StructTy->memberDecorate(i, Decoration::Offset);
+ if (!decor) {
+ std::cerr << "failed creating member decoration for field " << i
+ << std::endl;
+ return false;
+ }
+ const uint32_t offset = (uint32_t)SLayout->getElementOffset(i);
+ decor->addExtraOperand(offset);
+ offsets.push_back(offset);
+ }
+ std::stringstream ssOffsets;
+ // TODO: define this string in a central place
+ ssOffsets << ".rsov.ExportedVars:";
+ for(uint32_t slot = 0; slot < Ctxt.getNumExportVar(); slot++) {
+ const uint32_t index = Ctxt.getExportVarIndex(slot);
+ const uint32_t offset = offsets[index];
+ ssOffsets << offset << ';';
+ }
+ m->addString(ssOffsets.str().c_str());
+
+ std::stringstream ssGlobalSize;
+ ssGlobalSize << ".rsov.GlobalSize:" << Ctxt.getGlobalSize();
+ m->addString(ssGlobalSize.str().c_str());
+ }
+ }
+
+ if (!IsCorrectTy) {
+ return false;
+ }
+
+ llvm::SmallVector<rs2spirv::RSAllocationInfo, 2> RSAllocs;
+ if (!getRSAllocationInfo(LM, RSAllocs)) {
+ // llvm::errs() << "Extracting rs_allocation info failed\n";
+ return true;
+ }
+
+ // TODO: clean up the binding number assignment
+ size_t BindingNum = 3;
+ for (const auto &A : RSAllocs) {
+ Instruction *inst = m->lookupByName(A.VarName.c_str());
+ if (inst == nullptr) {
+ return false;
+ }
+ VariableInst *bufferVar = static_cast<VariableInst *>(inst);
+ bufferVar->decorate(Decoration::DescriptorSet)->addExtraOperand(0);
+ bufferVar->decorate(Decoration::Binding)->addExtraOperand(BindingNum++);
+ }
+
+ return true;
+}
+
+void AddHeader(Module *m) {
+ m->addCapability(Capability::Shader);
+ m->setMemoryModel(AddressingModel::Logical, MemoryModel::GLSL450);
+
+ m->addSource(SourceLanguage::GLSL, 450);
+ m->addSourceExtension("GL_ARB_separate_shader_objects");
+ m->addSourceExtension("GL_ARB_shading_language_420pack");
+ m->addSourceExtension("GL_GOOGLE_cpp_style_line_directive");
+ m->addSourceExtension("GL_GOOGLE_include_directive");
+}
+
+namespace {
+
+class StorageClassVisitor : public DoNothingVisitor {
+public:
+ void visit(TypePointerInst *inst) override {
+ matchAndReplace(inst->mOperand1);
+ }
+
+ void visit(TypeForwardPointerInst *inst) override {
+ matchAndReplace(inst->mOperand2);
+ }
+
+ void visit(VariableInst *inst) override { matchAndReplace(inst->mOperand1); }
+
+private:
+ void matchAndReplace(StorageClass &storage) {
+ if (storage == StorageClass::Function) {
+ storage = StorageClass::Uniform;
+ }
+ }
+};
+
+void FixGlobalStorageClass(Module *m) {
+ StorageClassVisitor v;
+ m->getGlobalSection()->accept(&v);
+}
+
+} // anonymous namespace
+
+bool AddWrappers(llvm::Module &LM,
+ android::spirit::Module *m) {
+ rs2spirv::Context &Ctxt = rs2spirv::Context::getInstance();
+ const bcinfo::MetadataExtractor &metadata = Ctxt.getMetadata();
+ android::spirit::Builder b;
+
+ m->setBuilder(&b);
+
+ FixGlobalStorageClass(m);
+
+ AddHeader(m);
+
+ DecorateGlobalBuffer(LM, b, m);
+
+ const size_t numKernel = metadata.getExportForEachSignatureCount();
+ const char **kernelName = metadata.getExportForEachNameList();
+ const uint32_t *kernelSigature = metadata.getExportForEachSignatureList();
+ const uint32_t *inputCount = metadata.getExportForEachInputCountList();
+
+ for (size_t i = 0; i < numKernel; i++) {
+ bool success =
+ AddWrapper(kernelName[i], kernelSigature[i], inputCount[i], b, m);
+ if (!success) {
+ return false;
+ }
+ }
+
+ m->consolidateAnnotations();
+ return true;
+}
+
+class WrapperPass : public Pass {
+public:
+ WrapperPass(const llvm::Module &LM) : mLLVMModule(const_cast<llvm::Module&>(LM)) {}
+
+ Module *run(Module *m, int *error) override {
+ bool success = AddWrappers(mLLVMModule, m);
+ if (error) {
+ *error = success ? 0 : -1;
+ }
+ return m;
+ }
+
+private:
+ llvm::Module &mLLVMModule;
+};
+
+} // namespace spirit
+} // namespace android
+
+namespace rs2spirv {
+
+android::spirit::Pass* CreateWrapperPass(const llvm::Module &LLVMModule) {
+ return new android::spirit::WrapperPass(LLVMModule);
+}
+
+} // namespace rs2spirv
diff --git a/rsov/compiler/Wrapper.h b/rsov/compiler/Wrapper.h
new file mode 100644
index 0000000..27aaee8
--- /dev/null
+++ b/rsov/compiler/Wrapper.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef WRAPPER_H
+#define WRAPPER_H
+
+#include <stdint.h>
+
+namespace llvm {
+class Module;
+}
+
+namespace android {
+namespace spirit {
+
+class Builder;
+class Instruction;
+class Module;
+class Pass;
+class VariableInst;
+
+// TODO: avoid exposing these methods while still unit testing them
+void AddHeader(Module *m);
+VariableInst *AddBuffer(Instruction *elementType, uint32_t binding, Builder &b,
+ Module *m);
+
+bool AddWrapper(const char *name, const uint32_t signature,
+ const uint32_t numInput, Builder &b, Module *m);
+
+// Find the LLVM generated buffer for all non-allocation glboal variables, and
+// correctly decorate it and its type with annotations for binding numbers, etc.
+bool DecorateGlobalBuffer(llvm::Module &M, Builder &b, Module *m);
+
+} // namespace spirit
+} // namespace android
+
+namespace rs2spirv {
+
+android::spirit::Pass* CreateWrapperPass(const llvm::Module &LLVMModule);
+
+} // namespace rs2spirv
+
+#endif
diff --git a/rsov/compiler/Wrapper_test.cpp b/rsov/compiler/Wrapper_test.cpp
new file mode 100644
index 0000000..1be643a
--- /dev/null
+++ b/rsov/compiler/Wrapper_test.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "Wrapper.h"
+#include "bcinfo/MetadataExtractor.h"
+#include "builder.h"
+#include "file_utils.h"
+#include "instructions.h"
+#include "module.h"
+#include "test_utils.h"
+#include "gtest/gtest.h"
+
+namespace android {
+namespace spirit {
+
+class WrapperTest : public ::testing::Test {
+protected:
+ virtual void SetUp() {
+ mWordsGreyscale = readWords("greyscale.spv");
+ mWordsGreyscale2 = readWords("greyscale2.spv");
+ mWordsInvert = readWords("invert.spv");
+ }
+
+ std::vector<uint32_t> mWordsGreyscale;
+ std::vector<uint32_t> mWordsGreyscale2;
+ std::vector<uint32_t> mWordsInvert;
+
+private:
+ std::vector<uint32_t> readWords(const char *testFile) {
+ static const std::string testDataPath(
+ "frameworks/rs/rsov/compiler/spirit/test_data/");
+ const std::string &fullPath = getAbsolutePath(testDataPath + testFile);
+ return readFile<uint32_t>(fullPath);
+ }
+};
+
+TEST_F(WrapperTest, testAddBuffer) {
+ Builder b;
+ Module m(&b);
+ auto elemType = m.getIntType(32);
+ VariableInst *buffer = AddBuffer(elemType, 2, b, &m);
+ ASSERT_NE(nullptr, buffer);
+
+ GlobalSection *gs = m.getGlobalSection();
+
+ EXPECT_EQ(1, countEntity<TypeRuntimeArrayInst>(gs));
+ EXPECT_EQ(1, countEntity<TypeStructInst>(gs));
+ EXPECT_EQ(1, countEntity<VariableInst>(gs));
+}
+
+TEST_F(WrapperTest, testAddWrapper1) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m);
+
+ m->resolveIds();
+
+ Builder b;
+ m->setBuilder(&b);
+
+ constexpr uint32_t sig =
+ bcinfo::MD_SIG_Kernel | bcinfo::MD_SIG_In | bcinfo::MD_SIG_Out;
+
+ EXPECT_FALSE(AddWrapper("foo", sig, 1, b, m.get()));
+
+ EXPECT_TRUE(AddWrapper("greyscale(vf4;", sig, 1, b, m.get()));
+
+ // The input already has an entry point
+ EXPECT_EQ(2, countEntity<EntryPointDefinition>(m.get()));
+}
+
+TEST_F(WrapperTest, testAddWrapper2) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsInvert));
+
+ ASSERT_NE(nullptr, m);
+
+ m->resolveIds();
+
+ Builder b;
+ m->setBuilder(&b);
+
+ uint32_t sig = bcinfo::MD_SIG_Kernel | bcinfo::MD_SIG_In | bcinfo::MD_SIG_Out;
+
+ EXPECT_FALSE(AddWrapper("foo", sig, 1, b, m.get()));
+
+ ASSERT_TRUE(AddWrapper("invert", sig, 1, b, m.get()));
+
+ EXPECT_EQ(1, countEntity<EntryPointDefinition>(m.get()));
+}
+
+TEST_F(WrapperTest, testAddWrapperForRoot) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsInvert));
+
+ ASSERT_NE(nullptr, m);
+
+ Builder b;
+ m->setBuilder(&b);
+
+ bool success = AddWrapper("root", 0, 1, b, m.get());
+ ASSERT_TRUE(success);
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/bcc_rsov.sh b/rsov/compiler/bcc_rsov.sh
new file mode 100755
index 0000000..c09ad57
--- /dev/null
+++ b/rsov/compiler/bcc_rsov.sh
@@ -0,0 +1,57 @@
+#! /system/bin/sh
+#
+# Copyright 2016, 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.
+#
+
+function help() {
+ echo "USAGE: $0 [options] <input>"
+ echo
+ echo "OPTIONS:"
+ echo " -h Show this help message."
+ echo " -o <file> Write output to file."
+}
+
+OUTPUT_FILE=""
+
+while getopts "ho:" opt; do
+ case "$opt" in
+ h)
+ help
+ exit 0
+ ;;
+ o)
+ OUTPUT_FILE=$OPTARG
+ ;;
+ esac
+done
+
+shift $((OPTIND-1))
+
+if [[ "$#" -ne 1 ]]; then
+ help
+ exit -1
+fi
+
+INPUT_FILE=$1
+
+if [[ -z "$OUTPUT_FILE" ]]; then
+ OUTPUT_FILE="${INPUT_FILE%.*}.spv"
+fi
+
+eval rs2spirv $INPUT_FILE -o $OUTPUT_FILE
+
+#rm -f $INPUT_FILE $KERNEL $KERNEL_TXT $WRAPPER $OUTPUT_TXT
+
+exit $?
diff --git a/rsov/compiler/rs2spirv.cpp b/rsov/compiler/rs2spirv.cpp
new file mode 100644
index 0000000..059f59b
--- /dev/null
+++ b/rsov/compiler/rs2spirv.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2016, 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.
+ */
+
+#include "RSSPIRVWriter.h"
+#include "bcinfo/MetadataExtractor.h"
+#include "spirit/file_utils.h"
+
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/DataStream.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "Context.h"
+#include "GlobalMergePass.h"
+#include "RSSPIRVWriter.h"
+
+#define DEBUG_TYPE "rs2spirv"
+
+namespace kExt {
+const char SPIRVBinary[] = ".spv";
+} // namespace kExt
+
+using namespace llvm;
+
+static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
+ cl::init("-"));
+
+static cl::opt<std::string> OutputFile("o",
+ cl::desc("Override output filename"),
+ cl::value_desc("filename"));
+
+static cl::opt<std::string> OutputBitcodeFile("bc",
+ cl::desc("Override output bitcode filename"),
+ cl::value_desc("bitcode filename"));
+
+static std::string removeExt(const std::string &FileName) {
+ size_t Pos = FileName.find_last_of(".");
+ if (Pos != std::string::npos)
+ return FileName.substr(0, Pos);
+ return FileName;
+}
+
+static bool WriteBitcode(rs2spirv::Context &Ctxt, Module *M,
+ raw_ostream &OS, std::string &ErrMsg) {
+ llvm::legacy::PassManager PassMgr;
+ PassMgr.add(rs2spirv::createGlobalMergePass(true));
+ PassMgr.run(*M);
+
+ WriteBitcodeToFile(M, OS);
+
+ return true;
+}
+
+static int convertLLVMToSPIRV() {
+ LLVMContext Context;
+
+ std::string Err;
+ auto DS = getDataFileStreamer(InputFile, &Err);
+ if (!DS) {
+ errs() << "Fails to open input file: " << Err;
+ return -1;
+ }
+ ErrorOr<std::unique_ptr<Module>> MOrErr =
+ getStreamedBitcodeModule(InputFile, std::move(DS), Context);
+
+ if (std::error_code EC = MOrErr.getError()) {
+ errs() << "Fails to load bitcode: " << EC.message();
+ return -1;
+ }
+
+ std::unique_ptr<Module> M = std::move(*MOrErr);
+
+ if (std::error_code EC = M->materializeAll()) {
+ errs() << "Fails to materialize: " << EC.message();
+ return -1;
+ }
+
+ std::error_code EC;
+
+ std::vector<char> bitcode = android::spirit::readFile<char>(InputFile);
+ std::unique_ptr<bcinfo::MetadataExtractor> ME(
+ new bcinfo::MetadataExtractor(bitcode.data(), bitcode.size()));
+
+ rs2spirv::Context &Ctxt = rs2spirv::Context::getInstance();
+
+ if (!Ctxt.Initialize(std::move(ME))) {
+ return -2;
+ }
+
+ if (!OutputBitcodeFile.empty()) {
+ llvm::StringRef outBCFile(OutputBitcodeFile);
+ llvm::raw_fd_ostream OFS_BC(outBCFile, EC, llvm::sys::fs::F_None);
+ if (!WriteBitcode(Ctxt, M.get(), OFS_BC, Err)) {
+ errs() << "compiler error: " << Err << '\n';
+ return -3;
+ }
+ return 0;
+ }
+
+ if (OutputFile.empty()) {
+ if (InputFile == "-")
+ OutputFile = "-";
+ else
+ OutputFile = removeExt(InputFile) + kExt::SPIRVBinary;
+ }
+
+ llvm::StringRef outFile(OutputFile);
+ llvm::raw_fd_ostream OFS(outFile, EC, llvm::sys::fs::F_None);
+
+ if (!rs2spirv::WriteSPIRV(Ctxt, M.get(), OFS, Err)) {
+ errs() << "compiler error: " << Err << '\n';
+ return -4;
+ }
+
+ return 0;
+}
+
+int main(int ac, char **av) {
+ EnablePrettyStackTrace();
+ sys::PrintStackTraceOnErrorSignal(av[0]);
+ PrettyStackTraceProgram X(ac, av);
+
+ cl::ParseCommandLineOptions(ac, av, "RenderScript to SPIRV translator");
+
+ return convertLLVMToSPIRV();
+}
diff --git a/rsov/compiler/rs2spirv_driver.sh b/rsov/compiler/rs2spirv_driver.sh
new file mode 100755
index 0000000..7b3b63f
--- /dev/null
+++ b/rsov/compiler/rs2spirv_driver.sh
@@ -0,0 +1,75 @@
+# Copyright 2016, 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.
+
+#!/bin/bash
+
+ME=$0
+
+function usage {
+ echo >&2 "$ME: $*: Expected [-d|--dump] [-t|--trace] <SPIRV_TOOLS_PATH> <SCRIPT_NAME> <OUTPUT_DIR>)"
+ exit 2
+}
+
+function dump {
+ if [[ -z "${DUMP:-}" ]] ; then
+ return 0
+ fi
+ eval rs2spirv "$output_folder/$script.spv" -print-as-words
+ return $?
+}
+
+DUMP=
+TRACE=
+
+while [[ "${1:-}" = -* ]] ; do
+ case "$1" in
+ -d|--dump)
+ DUMP=t
+ ;;
+ -t|--trace)
+ TRACE=t
+ ;;
+ *)
+ usage "Unexpected option \"$1\""
+ ;;
+ esac
+ shift
+done
+
+if [[ $# -ne 3 ]] ; then
+ usage "Bad argument count (got $#)"
+fi
+
+if [[ -n "${TRACE:-}" ]] ; then
+ set -x
+fi
+
+AND_HOME=$ANDROID_BUILD_TOP
+SPIRV_TOOLS_PATH=$1
+
+script_name="$2"
+script=`basename ${2%.*}` # Remove enclosing directories and extension.
+
+output_folder="$3"
+mkdir -p $output_folder
+
+eval llvm-rs-cc -o "$output_folder" -S -emit-llvm -Wall -Werror -target-api 24 \
+ -I "$AND_HOME/external/clang/lib/Headers" -I "$AND_HOME/frameworks/rs/script_api/include" \
+ "$script_name" &&
+eval llvm-as "$output_folder/bc32/$script.ll" -o "$output_folder/$script.bc" &&
+eval rs2spirv "$output_folder/$script.bc" -o "$output_folder/$script.spv" &&
+dump &&
+eval "$SPIRV_TOOLS_PATH/spirv-val" "$output_folder/$script.spv" &&
+
+exit $?
diff --git a/rsov/compiler/spirit/Android.bp b/rsov/compiler/spirit/Android.bp
new file mode 100644
index 0000000..043e851
--- /dev/null
+++ b/rsov/compiler/spirit/Android.bp
@@ -0,0 +1,172 @@
+//
+// Copyright (C) 2017 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.
+//
+
+cc_defaults {
+ name: "spirit_defaults",
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ target: {
+ host: {
+ compile_multilib: "first",
+ },
+ },
+ product_variables: {
+ pdk: {
+ enabled: false,
+ },
+ unbundled_build: {
+ enabled: false,
+ },
+ },
+}
+
+python_binary_host {
+ name: "libspirit_generate_py",
+ main: "generate.py",
+ srcs: ["generate.py"],
+ version: {
+ py2: {
+ enabled: true,
+ embedded_launcher: true,
+ },
+ py3: {
+ enabled: false,
+ },
+ },
+}
+
+genrule {
+ name: "libspirit_gen",
+ tools: ["libspirit_generate_py"],
+ cmd: "$(location libspirit_generate_py) $(location :spirv.core.grammar.json-1.1) " +
+ "--instructions=$(location instructions_generated.h) " +
+ "--types=$(location types_generated.h) " +
+ "--opcodes=$(location opcodes_generated.h) " +
+ "--instruction_dispatches=$(location instruction_dispatches_generated.h) " +
+ "--enum_dispatches=$(location enum_dispatches_generated.h) " +
+ "--type_inst_dispatches=$(location type_inst_dispatches_generated.h) " +
+ "--const_inst_dispatches=$(location const_inst_dispatches_generated.h) " +
+ "--factory_methods=$(location factory_methods_generated.h)",
+ srcs: [":spirv.core.grammar.json-1.1"],
+ out: [
+ "instructions_generated.h",
+ "types_generated.h",
+ "opcodes_generated.h",
+ "instruction_dispatches_generated.h",
+ "enum_dispatches_generated.h",
+ "type_inst_dispatches_generated.h",
+ "const_inst_dispatches_generated.h",
+ "factory_methods_generated.h",
+ ],
+}
+
+//=====================================================================
+// Host and device shared library libspirit.so
+//=====================================================================
+cc_library_shared {
+ name: "libspirit",
+ defaults: ["spirit_defaults"],
+ host_supported: true,
+
+ srcs: [
+ "builder.cpp",
+ "entity.cpp",
+ "instructions.cpp",
+ "module.cpp",
+ "pass.cpp",
+ "pass_queue.cpp",
+ "transformer.cpp",
+ "visitor.cpp",
+ "word_stream.cpp",
+ "word_stream_impl.cpp",
+ ],
+
+ generated_headers: ["libspirit_gen"],
+ export_generated_headers: ["libspirit_gen"],
+
+ export_include_dirs: ["."],
+
+ target: {
+ android: {
+ cflags: ["-Wno-error=non-virtual-dtor"],
+ },
+ },
+}
+
+//=====================================================================
+// Tests for host module word_stream
+//=====================================================================
+cc_test_host {
+ name: "word_stream_test",
+ defaults: ["spirit_defaults"],
+ srcs: [
+ "word_stream.cpp",
+ "word_stream_impl.cpp",
+ "word_stream_test.cpp",
+ ],
+ generated_headers: ["libspirit_gen"],
+}
+
+//=====================================================================
+// Tests for host module instructions
+//=====================================================================
+
+cc_test_host {
+ name: "instructions_test",
+ defaults: ["spirit_defaults"],
+ srcs: [
+ "entity.cpp",
+ "instructions.cpp",
+ "instructions_test.cpp",
+ "visitor.cpp",
+ "word_stream.cpp",
+ "word_stream_impl.cpp",
+ ],
+ generated_headers: ["libspirit_gen"],
+}
+
+//=====================================================================
+// Tests for host module pass queue
+//=====================================================================
+
+cc_test_host {
+ name: "pass_queue_test",
+ defaults: ["spirit_defaults"],
+ srcs: [
+ "pass.cpp",
+ "pass_queue.cpp",
+ "pass_queue_test.cpp",
+ ],
+ shared_libs: ["libspirit"],
+}
+
+//=====================================================================
+// Tests for host shared library
+//=====================================================================
+
+cc_test_host {
+ name: "libspirit_test",
+ defaults: ["spirit_defaults"],
+ srcs: [
+ "builder_test.cpp",
+ "module_test.cpp",
+ "transformer_test.cpp",
+ ],
+ shared_libs: ["libspirit"],
+}
diff --git a/rsov/compiler/spirit/builder.cpp b/rsov/compiler/spirit/builder.cpp
new file mode 100644
index 0000000..140b554
--- /dev/null
+++ b/rsov/compiler/spirit/builder.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "builder.h"
+
+#include "module.h"
+
+namespace android {
+namespace spirit {
+
+Module *Builder::MakeModule() {
+ Module *ret = new Module(this);
+ ret->initialize();
+ return ret;
+}
+
+EntryPointDefinition *
+Builder::MakeEntryPointDefinition(ExecutionModel execModel,
+ FunctionDefinition *func, const char *name) {
+ return new EntryPointDefinition(this, execModel, func, name);
+}
+
+DebugInfoSection *Builder::MakeDebugInfoSection() {
+ return new DebugInfoSection(this);
+}
+
+FunctionDefinition *
+Builder::MakeFunctionDefinition(Instruction *retType, FunctionControl ctrl,
+ TypeFunctionInst *funcType) {
+ FunctionInst *func = MakeFunction(retType, ctrl, funcType);
+ FunctionEndInst *end = MakeFunctionEnd();
+ return new FunctionDefinition(this, func, end);
+}
+
+Block *Builder::MakeBlock() { return new Block(this); }
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/builder.h b/rsov/compiler/spirit/builder.h
new file mode 100644
index 0000000..816246d
--- /dev/null
+++ b/rsov/compiler/spirit/builder.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef BUILDER_H
+#define BUILDER_H
+
+#include "instructions.h"
+#include "module.h"
+
+namespace android {
+namespace spirit {
+
+class Builder {
+public:
+ Module *MakeModule();
+ EntryPointDefinition *MakeEntryPointDefinition(ExecutionModel execModel,
+ FunctionDefinition *func,
+ const char *name);
+ DebugInfoSection *MakeDebugInfoSection();
+ FunctionDefinition *MakeFunctionDefinition(Instruction *retType,
+ FunctionControl ctrl,
+ TypeFunctionInst *funcType);
+ Block *MakeBlock();
+
+#include "factory_methods_generated.h"
+};
+
+} // namespace spirit
+} // namespace android
+
+#endif // BUILDER_H
diff --git a/rsov/compiler/spirit/builder_test.cpp b/rsov/compiler/spirit/builder_test.cpp
new file mode 100644
index 0000000..4f21310
--- /dev/null
+++ b/rsov/compiler/spirit/builder_test.cpp
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "builder.h"
+
+#include "file_utils.h"
+#include "instructions.h"
+#include "module.h"
+#include "test_utils.h"
+#include "gtest/gtest.h"
+
+namespace android {
+namespace spirit {
+
+TEST(BuilderTest, testBuildAndSerialize) {
+ Builder b;
+
+ Module *m = b.MakeModule();
+
+ ASSERT_NE(nullptr, m);
+
+ m->addCapability(Capability::Shader);
+ m->addCapability(Capability::Addresses);
+ m->setMemoryModel(AddressingModel::Physical32, MemoryModel::GLSL450);
+
+ m->addExtInstImport("GLSL.std.450");
+
+ // Shall we explicitly create the debug info section first?
+ m->addSource(SourceLanguage::GLSL, 450);
+ m->addSourceExtension("GL_ARB_separate_shader_objects");
+ m->addSourceExtension("GL_ARB_shading_language_420pack");
+ m->addSourceExtension("GL_GOOGLE_cpp_style_line_directive");
+ m->addSourceExtension("GL_GOOGLE_include_directive");
+ m->addString("Foo Bar Baz");
+
+ auto FloatTy = m->getFloatType(32);
+ auto VF4Ty = m->getVectorType(FloatTy, 4);
+ auto ArrTy = m->getRuntimeArrayType(VF4Ty);
+ ArrTy->decorate(Decoration::ArrayStride)->addExtraOperand(16);
+ auto StructTy = m->getStructType(ArrTy);
+ StructTy->decorate(Decoration::BufferBlock);
+ StructTy->memberDecorate(0, Decoration::Offset)->addExtraOperand(0);
+
+ auto StructPtrTy = m->getPointerType(StorageClass::Uniform, StructTy);
+
+ auto InputBuffer = b.MakeVariable(StructPtrTy, StorageClass::Uniform);
+ InputBuffer->decorate(Decoration::DescriptorSet)->addExtraOperand(0);
+ InputBuffer->decorate(Decoration::Binding)->addExtraOperand(2);
+ m->addVariable(InputBuffer);
+
+ auto ArrTy2 = m->getRuntimeArrayType(VF4Ty);
+ ArrTy2->decorate(Decoration::ArrayStride)->addExtraOperand(16);
+
+ auto StructTy2 = m->getStructType(ArrTy2);
+ StructTy2->decorate(Decoration::BufferBlock);
+ StructTy2->memberDecorate(0, Decoration::Offset)->addExtraOperand(0);
+
+ auto StructPtrTy2 = m->getPointerType(StorageClass::Uniform, StructTy2);
+ auto OutputBuffer = b.MakeVariable(StructPtrTy2, StorageClass::Uniform);
+ OutputBuffer->decorate(Decoration::DescriptorSet)->addExtraOperand(0);
+ OutputBuffer->decorate(Decoration::Binding)->addExtraOperand(1);
+ m->addVariable(OutputBuffer);
+
+ auto VoidTy = m->getVoidType();
+ auto FuncTy = m->getFunctionType(VoidTy, nullptr, 0);
+
+ auto UIntTy = m->getUnsignedIntType(32);
+ auto V3UIntTy = m->getVectorType(UIntTy, 3);
+
+ auto InvocationID = m->getInvocationId();
+
+ auto ConstOne = m->getConstant(UIntTy, 1);
+#if 0
+ auto V3UIntPtrTy = m->getPointerType(StorageClass::Input, V3UIntTy);
+ auto GSize = b.MakeVariable(V3UIntPtrTy, StorageClass::Input);
+ GSize->decorate(Decoration::BuiltIn)->addExtraOperand(BuiltIn::WorkgroupSize);
+ m->addVariable(GSize);
+#endif
+
+ auto GNum = m->getNumWorkgroups();
+
+ const char *funcName = "invert";
+
+ auto Func = b.MakeFunctionDefinition(VoidTy, FunctionControl::None, FuncTy);
+ // TODO: Add method setName() to class FunctionDefinition
+ // Func->setName(funcName); // I.e., OpName %func funcName
+ m->addFunctionDefinition(Func);
+
+ auto Blk = b.MakeBlock();
+ Func->addBlock(Blk);
+
+ Blk->addInstruction(b.MakeLabel());
+
+ auto ConstZero = m->getConstant(UIntTy, 0);
+ auto UIntPtrTy = m->getPointerType(StorageClass::Input, UIntTy);
+
+ auto IID = b.MakeLoad(V3UIntTy, InvocationID);
+ Blk->addInstruction(IID);
+
+ auto XValue = b.MakeCompositeExtract(UIntTy, IID, {0});
+ Blk->addInstruction(XValue);
+
+ auto YValue = b.MakeCompositeExtract(UIntTy, IID, {1});
+ Blk->addInstruction(YValue);
+
+#if 0
+ auto PtrToGSizeX = b.MakeAccessChain(UIntPtrTy, GSize, {ConstZero});
+ Blk->addInstruction(PtrToGSizeX);
+
+ auto GSizeX = b.MakeLoad(UIntTy, PtrToGSizeX);
+ Blk->addInstruction(GSizeX);
+#else
+ auto &GSizeX = ConstOne;
+#endif
+
+ auto Tmp1 = b.MakeIMul(UIntTy, YValue, GSizeX);
+ Blk->addInstruction(Tmp1);
+
+ auto PtrToGNumX = b.MakeAccessChain(UIntPtrTy, GNum, {ConstZero});
+ Blk->addInstruction(PtrToGNumX);
+
+ auto GNumX = b.MakeLoad(UIntTy, PtrToGNumX);
+ Blk->addInstruction(GNumX);
+
+ auto OffsetY = b.MakeIMul(UIntTy, Tmp1, GNumX);
+ Blk->addInstruction(OffsetY);
+
+ auto Index = b.MakeIAdd(UIntTy, OffsetY, XValue);
+ Blk->addInstruction(Index);
+
+ auto VF4PtrTy = m->getPointerType(StorageClass::Function, VF4Ty);
+ auto Ptr = b.MakeAccessChain(VF4PtrTy, InputBuffer, {ConstZero, Index});
+ Blk->addInstruction(Ptr);
+
+ auto Value = b.MakeLoad(VF4Ty, Ptr);
+ Blk->addInstruction(Value);
+
+ // Here is the place to do something about the value. As is, this is a copy
+ // kernel.
+ auto ConstOneF = m->getConstant(FloatTy, 1.0f);
+ auto ConstOneVF4 = m->getConstantComposite(VF4Ty, ConstOneF, ConstOneF,
+ ConstOneF, ConstOneF);
+ auto Result = b.MakeFSub(VF4Ty, ConstOneVF4, Value);
+ Blk->addInstruction(Result);
+
+ auto OutPtr = b.MakeAccessChain(VF4PtrTy, OutputBuffer, {ConstZero, Index});
+ Blk->addInstruction(OutPtr);
+
+ Blk->addInstruction(b.MakeStore(OutPtr, Result));
+ Blk->addInstruction(b.MakeReturn());
+
+ m->addEntryPoint(
+ b.MakeEntryPointDefinition(ExecutionModel::GLCompute, Func, funcName)
+ ->addToInterface(InvocationID)
+ ->addToInterface(GNum)
+ // ->addToInterface(GSize)
+ ->setLocalSize(1, 1, 1));
+
+ EXPECT_EQ(1, countEntity<MemoryModelInst>(m));
+ EXPECT_EQ(1, countEntity<EntryPointInst>(m));
+ EXPECT_EQ(3, countEntity<LoadInst>(m));
+ EXPECT_EQ(1, countEntity<ReturnInst>(m));
+ EXPECT_EQ(1, countEntity<ExecutionModeInst>(m));
+ EXPECT_EQ(2, countEntity<TypeRuntimeArrayInst>(m));
+ EXPECT_EQ(2, countEntity<TypeStructInst>(m));
+ EXPECT_EQ(5, countEntity<TypePointerInst>(m));
+ EXPECT_EQ(1, countEntity<StringInst>(m));
+
+ m->consolidateAnnotations();
+
+ auto words = Serialize<Module>(m);
+
+ auto m1 = Deserialize<Module>(words);
+ ASSERT_NE(nullptr, m1);
+
+ auto words1 = Serialize<Module>(m1);
+
+ EXPECT_TRUE(words == words1);
+}
+
+TEST(BuilderTest, testLoadAndModify) {
+ static const std::string testDataPath(
+ "frameworks/rs/rsov/compiler/spirit/test_data/");
+ const std::string &fullPath = getAbsolutePath(testDataPath + "greyscale.spv");
+
+ Module *m = Deserialize<Module>(readFile<uint32_t>(fullPath.c_str()));
+
+ ASSERT_NE(nullptr, m);
+
+ std::unique_ptr<Module> mDeleter(m);
+
+ Builder b;
+
+ auto IntTy = m->getIntType(32);
+ auto FuncTy = m->getFunctionType(IntTy, {IntTy});
+
+ auto Func = b.MakeFunctionDefinition(IntTy, FunctionControl::None, FuncTy);
+ // TODO: Add method setName() to class FunctionDefinition
+ // Func->setName(funcName); // I.e., OpName %func funcName
+ m->addFunctionDefinition(Func);
+
+ auto Blk = b.MakeBlock();
+ Func->addBlock(Blk);
+
+ Blk->addInstruction(b.MakeReturn());
+
+ m->consolidateAnnotations();
+
+ auto words = Serialize<Module>(m);
+
+ auto m1 = Deserialize<Module>(words);
+ ASSERT_NE(nullptr, m1);
+
+ auto words1 = Serialize<Module>(m1);
+
+ EXPECT_TRUE(words == words1);
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/core_defs.h b/rsov/compiler/spirit/core_defs.h
new file mode 100644
index 0000000..06b1d1b
--- /dev/null
+++ b/rsov/compiler/spirit/core_defs.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef CORE_DEFS_H
+#define CORE_DEFS_H
+
+#include <string>
+
+namespace android {
+namespace spirit {
+
+class Instruction;
+
+typedef int32_t LiteralInteger;
+typedef std::string LiteralString;
+typedef union {
+ int32_t intValue;
+ int64_t longValue;
+ float floatValue;
+ double doubleValue;
+} LiteralContextDependentNumber;
+typedef uint32_t LiteralExtInstInteger;
+typedef uint32_t LiteralSpecConstantOpInteger;
+typedef uint32_t IdResult;
+
+struct IdRef {
+ IdRef() : mId(0), mInstruction(nullptr) {}
+ IdRef(Instruction *inst);
+
+ uint32_t mId;
+ mutable Instruction *mInstruction;
+};
+
+// TODO: specialize these ref types
+// TODO: should only reference type instructions
+struct IdResultType : public IdRef {
+ IdResultType() : IdRef() {}
+ IdResultType(Instruction *inst) : IdRef(inst) {}
+};
+
+// TODO: should only reference int representing memory semeantics
+struct IdMemorySemantics : public IdRef {};
+// TODO: should only reference int representing scopes
+struct IdScope : public IdRef {};
+
+struct OpCodeAndWordCount {
+ OpCodeAndWordCount() : mOpCode(0) {}
+ OpCodeAndWordCount(uint32_t codeAndCount)
+ : mOpCode((uint16_t)codeAndCount),
+ mWordCount((uint32_t)(codeAndCount >> 16)) {}
+ OpCodeAndWordCount(uint32_t opcode, uint32_t wordCount)
+ : mOpCode((uint16_t)opcode), mWordCount((uint16_t)wordCount) {}
+
+ operator uint32_t() const {
+ return ((uint32_t)mWordCount << 16) | (uint32_t)mOpCode;
+ }
+
+ uint16_t mOpCode;
+ uint16_t mWordCount;
+};
+
+} // namespace spirit
+} // namespace android
+
+#endif // CORE_DEFS_H
diff --git a/rsov/compiler/spirit/entity.cpp b/rsov/compiler/spirit/entity.cpp
new file mode 100644
index 0000000..baeb55c
--- /dev/null
+++ b/rsov/compiler/spirit/entity.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "entity.h"
+
+#include "instructions.h"
+#include "visitor.h"
+#include "word_stream.h"
+
+namespace android {
+namespace spirit {
+
+void Entity::Serialize(OutputWordStream &OS) const {
+ std::unique_ptr<IVisitor> v(CreateInstructionVisitor(
+ [&OS](Instruction *inst) -> void { inst->Serialize(OS); }));
+ v->visit(const_cast<Entity *>(this));
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/entity.h b/rsov/compiler/spirit/entity.h
new file mode 100644
index 0000000..33c112b
--- /dev/null
+++ b/rsov/compiler/spirit/entity.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef ENTITY_H
+#define ENTITY_H
+
+#include <memory>
+#include <vector>
+
+#include "word_stream.h"
+
+namespace android {
+namespace spirit {
+
+class Builder;
+class IVisitor;
+
+class Entity {
+public:
+ Entity() {}
+ Entity(Builder *b) : mBuilder(b) {}
+
+ virtual ~Entity() {}
+
+ virtual void accept(IVisitor *visitor) = 0;
+ virtual bool DeserializeInternal(InputWordStream &IS) = 0;
+ virtual void Serialize(OutputWordStream &OS) const;
+ virtual void dump() const {}
+
+ void setBuilder(Builder *builder) { mBuilder = builder; }
+
+protected:
+ Builder *mBuilder;
+};
+
+template <typename T> T *Deserialize(InputWordStream &IS) {
+ std::unique_ptr<T> entity(new T());
+ if (!entity->DeserializeInternal(IS)) {
+ return nullptr;
+ }
+ return entity.release();
+}
+
+template <typename T> T *Deserialize(const std::vector<uint32_t> &words) {
+ std::unique_ptr<InputWordStream> IS(InputWordStream::Create(words));
+ return Deserialize<T>(*IS);
+}
+
+template <class T>
+void DeserializeZeroOrMore(InputWordStream &IS, std::vector<T *> &all) {
+ while (auto entity = Deserialize<T>(IS)) {
+ all.push_back(entity);
+ }
+}
+
+template <class T>
+std::vector<uint32_t> Serialize(T* e) {
+ std::unique_ptr<OutputWordStream> OS(OutputWordStream::Create());
+ e->Serialize(*OS);
+ return OS->getWords();
+}
+
+} // namespace spirit
+} // namespace android
+
+#endif // ENTITY_H
diff --git a/rsov/compiler/spirit/file_utils.h b/rsov/compiler/spirit/file_utils.h
new file mode 100644
index 0000000..4f00c7c
--- /dev/null
+++ b/rsov/compiler/spirit/file_utils.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef FILE_UTILS_H
+#define FILE_UTILS_H
+
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <vector>
+
+namespace android {
+namespace spirit {
+
+template <typename T> std::vector<T> readFile(const char *filename) {
+ std::ifstream ifs;
+ std::filebuf *fb = ifs.rdbuf();
+ fb->open(filename, std::ios::in);
+
+ if (!fb->is_open()) {
+ std::cerr << "failed opening " << filename << std::endl;
+ return std::vector<T>();
+ }
+
+ ifs.seekg(0, ifs.end);
+ int length = ifs.tellg();
+ ifs.seekg(0, ifs.beg);
+
+ std::vector<T> ret(length / sizeof(T));
+
+ ifs.read((char *)ret.data(), length);
+
+ fb->close();
+
+ return ret;
+}
+
+template <typename T> std::vector<T> readFile(const std::string &filename) {
+ return readFile<T>(filename.c_str());
+}
+
+template <typename T>
+void writeFile(const char *filename, const std::vector<T> &data) {
+ std::ofstream ofs(filename, std::ios::out);
+
+ ofs.write(reinterpret_cast<const char *>(data.data()),
+ sizeof(T) * data.size());
+}
+
+} // namespace spirit
+} // namespace android
+
+#endif // FILE_UTILS_H
diff --git a/rsov/compiler/spirit/generate.py b/rsov/compiler/spirit/generate.py
new file mode 100755
index 0000000..22b844d
--- /dev/null
+++ b/rsov/compiler/spirit/generate.py
@@ -0,0 +1,507 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 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.
+#
+
+import getopt
+import json
+import string
+import sys
+
+def generate_header_file(filename, with_guard, printer):
+ f = open(filename, 'w')
+ orig_stdout = sys.stdout
+ sys.stdout = f
+ print '// DO NOT MODIFY. AUTO-GENERATED.\n'
+ if with_guard:
+ print "#pragma once"
+ print
+ print "namespace android {"
+ print "namespace spirit {"
+ print
+ printer()
+ if with_guard:
+ print "} // namespace spirit"
+ print "} // namespace android"
+ f.close()
+ sys.stdout = orig_stdout
+
+
+
+################################################################################
+#
+# Generate Builder class: the .h and .cpp files.
+#
+################################################################################
+
+def factory_method_name(opname, outlined):
+ if outlined:
+ return "Builder::Make%s" % opname_noprefix(opname)
+ else:
+ return "Make%s" % opname_noprefix(opname)
+
+
+
+def factory_method_prototype(inst, outlined):
+ opname = inst['opname']
+ operands = inst.get('operands')
+ str = "%s *%s(" % (class_name(opname), factory_method_name(opname, outlined))
+ first = True;
+ for type, var, quantifier, comment in generate_member_list(operands):
+ if var != "mResult":
+ param = var[1:]
+ if first:
+ first = False
+ else:
+ str += ', '
+ if quantifier == '?':
+ str += '%s *%s=nullptr' % (type, param)
+ elif quantifier == '*':
+ vecTy = "std::vector<%s>" % type
+ str += '%s %s=%s()' % (vecTy, param, vecTy)
+ else:
+ str += '%s %s' % (type, param)
+ str += ')'
+ return str
+
+
+
+def factory_method_body(inst):
+ opname = inst['opname']
+ operands = inst.get('operands')
+ clazz = class_name(opname)
+ str = "%s *ret = new %s(" % (clazz, clazz)
+ first = True
+ for type, var, quantifier, comment in generate_member_list(operands):
+ if var != "mResult" and quantifier != '*' and quantifier != '?':
+ param = var[1:]
+ if first:
+ first = False
+ else:
+ str += ', '
+ str += param
+ str += """);
+ if (!ret) {
+ return nullptr;
+ }
+"""
+ str += """
+ if (ret->hasResult()) {
+ ret->setId(Module::getCurrentModule()->nextId());
+ }
+"""
+ for type, var, quantifier, comment in generate_member_list(operands):
+ param = var[1:]
+ # TODO: use vector::swap() or move instead of copy
+ if quantifier == '?' or quantifier == '*':
+ str += " ret->%s = %s;\n" % (var, param)
+ str += " return ret;"
+ return str
+
+
+
+def print_factory_method(inst):
+ print """%s {
+ %s
+}""" % (factory_method_prototype(inst, False),
+ factory_method_body(inst))
+
+
+
+def print_factory_methods(insts):
+ for inst in insts:
+ print_factory_method(inst)
+
+
+
+################################################################################
+#
+# Generate type defintions
+#
+################################################################################
+
+def enum_enumerants(ty, enumerants):
+ str = ""
+ for enumerant in enumerants:
+ name = enumerant['enumerant']
+ val = enumerant['value']
+ if name[0].isalpha():
+ str += " %s = %sU,\n" % (name, val)
+ else:
+ str += " %s%s = %sU,\n" % (ty, name, val)
+ return str
+
+
+def generate_enum(ty):
+ typeName = ty['kind']
+ print """enum class %s : uint32_t {\n%s};
+""" % (typeName,
+ enum_enumerants(typeName, ty['enumerants']))
+
+
+def generate_composite_fields(bases):
+ str = ""
+ i = 0
+ for field in bases:
+ str += " %s mField%d;\n" % (field, i)
+ i = i + 1
+ return str
+
+
+
+def print_type_definitions(operand_kinds):
+ for ty in operand_kinds:
+ category = ty['category']
+ if category == 'BitEnum' or category == 'ValueEnum':
+ generate_enum(ty)
+ elif category == 'Composite':
+ print "struct %s {\n%s};\n" % (ty['kind'],
+ generate_composite_fields(ty['bases']))
+
+
+
+################################################################################
+#
+# Generate class defintions for all instructions
+#
+################################################################################
+
+def opname_noprefix(opname):
+ return opname[2:]
+
+def class_name(opname):
+ return "%sInst" % opname_noprefix(opname)
+
+
+
+def generate_member_list(operands):
+ members = []
+ if operands is None:
+ return members
+ index = 1
+ for operand in operands:
+ type = operand['kind']
+ if type == 'IdResultType' or type == 'IdResult':
+ varName = "m%s" % type[2:]
+ else:
+ varName = "mOperand%d" % index
+ index = index + 1
+ quantifier = operand.get('quantifier')
+ comment = operand.get('name');
+ members.append((type, varName, quantifier, comment))
+ return members
+
+def fixed_word_count(member_list):
+ wc = 1 # for the first word of opcode and word count
+ for type, var, quant, comment in member_list:
+ if quant != '?' and quant != '*':
+ wc += 1
+ return wc
+
+def string_for_members(opname, member_list):
+ if member_list == []:
+ return ""
+ member_str = "\n static constexpr OpCode mOpCode=%s;\n" % opname
+ for type, var, quantifier, comment in member_list:
+ if comment is not None and comment.find('\n') != -1:
+ member_str += " /* %s\n */\n" % comment
+ member_str += " "
+ if quantifier == '?':
+ type = type + '*';
+ elif quantifier == '*':
+ type = 'std::vector<%s>' % type;
+ member_str += "%s %s;" % (type, var)
+ if comment is not None and comment.find('\n') == -1:
+ member_str += " // %s" % comment
+ member_str += "\n"
+ return member_str
+
+def string_for_constructor(opname, opcode, members):
+ # Default constructor
+ initializer = "Instruction(%s, %d)" % (opname, fixed_word_count(members))
+ first = True
+ for type, var, quantifier, comment in members:
+ if quantifier == '?':
+ initializer += ", %s(nullptr)" % var
+ str = "%s() : %s {}" % (class_name(opname), initializer)
+
+ # Constructor with values for members
+ if members == [] or (len(members) == 1 and members[0][0]=='IdResult'):
+ return str
+ nonOptionalOperandExists = False
+ for type, var, quantifier, comment in members:
+ if quantifier is None:
+ nonOptionalOperandExists = True
+ if not nonOptionalOperandExists:
+ return str
+ params = ""
+ initializer = "Instruction(%s, %d)" % (opname, fixed_word_count(members))
+ first = True
+ for type, var, quantifier, comment in members:
+ if var != "mResult" and quantifier != '*':
+ initializer += ", "
+ if quantifier == '?':
+ initializer += "%s(nullptr)" % var
+ else:
+ if first:
+ first = False
+ else:
+ params += ", "
+ param = var[1:] # remove the prefix "m"
+ params += "%s %s" % (type, param)
+ initializer += "%s(%s)" % (var, param)
+ if params != "":
+ str += "\n %s(%s) :\n %s {}" % (class_name(opname), params, initializer)
+ str += "\n virtual ~%s() {}" % class_name(opname)
+ return str
+
+def string_for_serializer_body(opcode, members):
+ body = "setWordCount();\n"
+ body += " OS << mCodeAndCount;\n"
+ for type, var, quantifier, comment in members:
+ if quantifier == '?':
+ body += " if (%s!=nullptr) { OS << *%s; }\n" % (var, var)
+ elif quantifier == '*':
+ body += """ for (auto val : %s) { OS << val; }\n""" % var
+ else:
+ body += " OS << %s;\n" % var
+ body += " SerializeExtraOperands(OS);\n"
+ return body
+
+def string_for_deserializer_body(name, members):
+ body = "return DeserializeFirstWord(IS, %s)" % name
+ for type, var, quantifier, comment in members:
+ body += " &&\n "
+ if quantifier == '?':
+ body += "DeserializeOptionallyOne(IS, &%s)" % var
+ elif quantifier == '*':
+ body += "DeserializeZeroOrMoreOperands(IS, &%s)" % var
+ else:
+ body += "DeserializeExactlyOne(IS, &%s)" % var
+ body += " &&\n DeserializeExtraOperands(IS);\n"
+ return body
+
+def string_for_get_word_count(members):
+ str = """uint16_t getWordCount() const override {
+ uint16_t count = mFixedWordCount;\n"""
+ for type, var, quantifier, comment in members:
+ if quantifier == '?':
+ str += " if (%s) count += WordCount(*%s);\n" % (var, var)
+ elif quantifier == '*':
+ str += " if (!%s.empty()) count += WordCount(%s[0]) * %s.size();\n" % (var, var, var)
+ elif type == 'LiteralString':
+ str += " count += WordCount(%s) - 1;\n" % var
+
+ str += """ count += mExtraOperands.size();
+ return count;
+ }"""
+ return str
+
+def string_for_accept():
+ return """
+ void accept(IVisitor *v) override { v->visit(this); }
+"""
+
+def has_result(members):
+ for type, val, quantifier, comment in members:
+ if type == 'IdResult':
+ return True
+ return False
+
+
+def string_for_has_result(hasResult):
+ if hasResult:
+ retVal = "true"
+ else:
+ retVal = "false"
+ return "bool hasResult() const override { return %s; }" % retVal
+
+def string_for_get_all_refs(members):
+ str = """std::vector<const IdRef*> getAllIdRefs() const override {
+ std::vector<const IdRef*> ret = {"""
+ first = True
+ # TODO: what if references are in * operands?
+ for type, var, quantifier, comment in members:
+ if type == 'IdRef' or type == 'IdResultType' or type == 'IdMemorySemantics' or type == 'IdScope':
+ if quantifier == '*':
+ pass
+ else:
+ if first:
+ first = False
+ else:
+ str += ", "
+ if quantifier == '?':
+ str += "%s" % var
+ else:
+ str += "&%s" % var
+ str += """};
+"""
+ for type, var, quantifier, comment in members:
+ if type == 'IdRef' or type == 'IdResultType' or type == 'IdMemorySemantics' or type == 'IdScope':
+ if quantifier == '*':
+ str+="""
+ for(const auto &ref : %s) {
+ ret.push_back(&ref);
+ }
+""" % var
+ str += """
+ return ret;
+ }"""
+ return str
+
+def string_for_get_set_id(hasResult):
+ if hasResult:
+ return """IdResult getId() const override { return mResult; }
+ void setId(IdResult id) override { mResult = id; }"""
+ else:
+ retVal = "0"
+ return """IdResult getId() const override { return 0; }
+ void setId(IdResult) override {}"""
+
+
+def print_instruction_class(inst):
+ opname = inst['opname']
+ opcode = inst['opcode']
+ operands = inst.get('operands')
+ members = generate_member_list(operands)
+ hasResult = has_result(members)
+ print """class %s : public Instruction {
+ public:
+ %s
+
+ void Serialize(OutputWordStream &OS) const override {
+ %s }
+
+ bool DeserializeInternal(InputWordStream &IS) override {
+ %s }
+
+ void accept(IVisitor *v) override { v->visit(this); }
+
+ %s
+
+ %s
+
+ %s
+
+ %s
+%s};
+""" % (class_name(opname),
+ string_for_constructor(opname, opcode, members),
+ string_for_serializer_body(opcode, members),
+ string_for_deserializer_body(opname, members),
+ string_for_get_word_count(members),
+ string_for_has_result(hasResult),
+ string_for_get_set_id(hasResult),
+ string_for_get_all_refs(members),
+ string_for_members(opname, members))
+
+def print_all_instruction_classes(insts):
+ for inst in insts:
+ print_instruction_class(inst)
+
+################################################################################
+#
+# Generate opcode enum
+#
+################################################################################
+
+def print_opcode_enum(insts):
+ print "enum OpCode {"
+ for inst in insts:
+ opname = inst['opname']
+ opcode = inst['opcode']
+ print " %s = %d," % (opname, opcode)
+ print "};"
+
+
+
+################################################################################
+#
+# Generate dispatching code
+#
+################################################################################
+
+def print_dispatches(insts):
+ for inst in insts:
+ opname = inst['opname']
+ print "HANDLE_INSTRUCTION(%s,%s)" % (opname, class_name(opname))
+
+def print_type_inst_dispatches(insts):
+ for inst in insts:
+ opname = inst['opname']
+ if opname[:6] == "OpType":
+ print "HANDLE_INSTRUCTION(%s, %s)" % (opname, class_name(opname))
+
+def print_const_inst_dispatches(insts):
+ for inst in insts:
+ opname = inst['opname']
+ if opname[:10] == "OpConstant":
+ print "HANDLE_INSTRUCTION(%s, %s)" % (opname, class_name(opname))
+
+def print_enum_dispatches(operand_kinds):
+ for ty in operand_kinds:
+ category = ty['category']
+ if category == 'BitEnum' or category == 'ValueEnum':
+ print "HANDLE_ENUM(%s)" % ty['kind']
+
+
+
+################################################################################
+#
+# main
+#
+################################################################################
+
+def main():
+ try:
+ opts, args = getopt.getopt(sys.argv[2:],"h",["instructions=",
+ "types=",
+ "opcodes=",
+ "instruction_dispatches=",
+ "enum_dispatches=",
+ "type_inst_dispatches=",
+ "const_inst_dispatches=",
+ "factory_methods="])
+ except getopt.GetoptError:
+ print sys.argv[0], ''
+ sys.exit(2)
+
+ with open(sys.argv[1]) as grammar_file:
+ grammar = json.load(grammar_file)
+
+ instructions = grammar['instructions']
+
+ for opt, arg in opts:
+ if opt == "--instructions":
+ generate_header_file(arg, True, lambda: print_all_instruction_classes(instructions))
+ elif opt == "--types":
+ kinds = grammar['operand_kinds']
+ generate_header_file(arg, True, lambda: print_type_definitions(kinds))
+ elif opt == "--opcodes":
+ generate_header_file(arg, True, lambda: print_opcode_enum(instructions))
+ elif opt == "--instruction_dispatches":
+ generate_header_file(arg, False, lambda: print_dispatches(instructions))
+ elif opt == "--enum_dispatches":
+ kinds = grammar['operand_kinds']
+ generate_header_file(arg, False, lambda: print_enum_dispatches(kinds))
+ elif opt == "--type_inst_dispatches":
+ generate_header_file(arg, False, lambda: print_type_inst_dispatches(instructions))
+ elif opt == "--const_inst_dispatches":
+ generate_header_file(arg, False, lambda: print_const_inst_dispatches(instructions))
+ elif opt == "--factory_methods":
+ generate_header_file(arg, False, lambda: print_factory_methods(instructions))
+
+if __name__ == '__main__':
+ main()
diff --git a/rsov/compiler/spirit/instructions.cpp b/rsov/compiler/spirit/instructions.cpp
new file mode 100644
index 0000000..2fee620
--- /dev/null
+++ b/rsov/compiler/spirit/instructions.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "instructions.h"
+
+#include <iostream>
+
+#include "visitor.h"
+
+namespace android {
+namespace spirit {
+
+IdRef::IdRef(Instruction *inst) : mId(inst->getId()), mInstruction(inst) {}
+
+void Instruction::accept(IVisitor *v) { v->visit(this); }
+
+DecorateInst *Instruction::decorate(Decoration decor) {
+ if (mCodeAndCount.mOpCode == OpDecorate) {
+ return nullptr;
+ }
+
+ DecorateInst *decorInst = new DecorateInst(this, decor);
+
+ mDecorations.push_back(decorInst);
+
+ return decorInst;
+}
+
+MemberDecorateInst *Instruction::memberDecorate(int member, Decoration decor) {
+ if (mCodeAndCount.mOpCode != OpTypeStruct) {
+ std::cerr << "OpMemberDecorate applied to non-OpTypeStruct instructions\n";
+ return nullptr;
+ }
+
+ MemberDecorateInst *decorInst = new MemberDecorateInst(this, member, decor);
+
+ mDecorations.push_back(decorInst);
+
+ return decorInst;
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/instructions.h b/rsov/compiler/spirit/instructions.h
new file mode 100644
index 0000000..6e162a1
--- /dev/null
+++ b/rsov/compiler/spirit/instructions.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef INSTRUCTIONS_H
+#define INSTRUCTIONS_H
+
+#include <stdint.h>
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "core_defs.h"
+#include "entity.h"
+#include "opcodes_generated.h"
+#include "types_generated.h"
+#include "visitor.h"
+#include "word_stream.h"
+
+namespace android {
+namespace spirit {
+
+// Word count for a serialized operand
+template <typename T> uint16_t WordCount(T) { return 1; }
+
+inline uint16_t WordCount(PairLiteralIntegerIdRef) { return 2; }
+inline uint16_t WordCount(PairIdRefLiteralInteger) { return 2; }
+inline uint16_t WordCount(PairIdRefIdRef) { return 2; }
+inline uint16_t WordCount(const std::string &operand) {
+ return operand.length() / 4 + 1;
+}
+
+class Instruction : public Entity {
+public:
+ Instruction(uint32_t opCode) : mCodeAndCount(opCode) {}
+ Instruction(uint32_t opCode, uint32_t fixedWordCount)
+ : mCodeAndCount(opCode), mFixedWordCount(fixedWordCount) {}
+ virtual ~Instruction() {}
+
+ void accept(IVisitor *v) override;
+
+ void setWordCount() const {
+ if (mCodeAndCount.mWordCount == 0) {
+ mCodeAndCount.mWordCount = getWordCount();
+ }
+ }
+ virtual uint16_t getWordCount() const = 0;
+ virtual bool hasResult() const = 0;
+ virtual IdResult getId() const = 0;
+ virtual void setId(IdResult) = 0;
+ virtual std::vector<const IdRef *> getAllIdRefs() const = 0;
+
+ Instruction *addExtraOperand(uint32_t word) {
+ mExtraOperands.push_back(word);
+ return this;
+ }
+
+ // Adds decoration to the current instruction.
+ // Returns: the result OpDecorate instruction
+ DecorateInst *decorate(Decoration);
+ MemberDecorateInst *memberDecorate(int member, Decoration);
+
+ bool DeserializeFirstWord(InputWordStream &IS, OpCode opcode) {
+ if (IS.empty()) {
+ return false;
+ }
+
+ OpCodeAndWordCount codeAndCount(*IS);
+
+ if (codeAndCount.mOpCode != opcode) {
+ return false;
+ }
+
+ mRemainingWordCount = codeAndCount.mWordCount;
+
+ IS >> &mCodeAndCount;
+
+ mRemainingWordCount--;
+
+ return true;
+ }
+
+ template <typename T>
+ bool DeserializeExactlyOne(InputWordStream &IS, T *operand) {
+ if (IS.empty()) {
+ return false;
+ }
+
+ IS >> operand;
+
+ mRemainingWordCount -= WordCount(*operand);
+
+ return true;
+ }
+
+ template <typename T>
+ bool DeserializeOptionallyOne(InputWordStream &IS, T **operand) {
+ if (mRemainingWordCount == 0) {
+ return true;
+ }
+ *operand = new T();
+ return DeserializeExactlyOne(IS, *operand);
+ }
+
+ template <typename T>
+ bool DeserializeZeroOrMoreOperands(InputWordStream &IS,
+ std::vector<T> *operands) {
+ while (mRemainingWordCount > 0) {
+ T tmp;
+ if (!DeserializeExactlyOne(IS, &tmp)) {
+ return false;
+ }
+ operands->push_back(tmp);
+ }
+ return true;
+ }
+
+ bool DeserializeExtraOperands(InputWordStream &IS) {
+ return DeserializeZeroOrMoreOperands(IS, &mExtraOperands);
+ }
+
+ void SerializeExtraOperands(OutputWordStream &OS) const {
+ for (uint32_t w : mExtraOperands) {
+ OS << w;
+ }
+ }
+
+ const std::vector<Instruction *> &getAnnotations() const {
+ return mDecorations;
+ }
+
+ uint16_t getOpCode() const { return mCodeAndCount.mOpCode; }
+
+ mutable OpCodeAndWordCount mCodeAndCount;
+ uint16_t mFixedWordCount;
+ uint16_t mRemainingWordCount;
+ std::vector<uint32_t> mExtraOperands;
+ std::vector<Instruction *> mDecorations;
+};
+
+} // namespace spirit
+} // namespace android
+
+#include "instructions_generated.h"
+
+#endif // INSTRUCTIONS_H
diff --git a/rsov/compiler/spirit/instructions_test.cpp b/rsov/compiler/spirit/instructions_test.cpp
new file mode 100644
index 0000000..ce4325e
--- /dev/null
+++ b/rsov/compiler/spirit/instructions_test.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "instructions.h"
+
+#include "gtest/gtest.h"
+
+#include <memory>
+#include <vector>
+
+namespace android {
+namespace spirit {
+
+TEST(InstructionTest, testOpCapability) {
+ std::vector<uint32_t> words = {0x00020011, 0x00000001};
+ auto *i = Deserialize<CapabilityInst>(words);
+ EXPECT_NE(nullptr, i);
+}
+
+TEST(InstructionTest, testOpExtension) {
+ uint8_t bytes[] = {0x0a, 0x00, 0x03, 0x00, 0x41, 0x42,
+ 0x43, 0x44, 0x45, 0x46, 'G', 0x00};
+ std::vector<uint32_t> words((uint32_t *)bytes,
+ (uint32_t *)(bytes + sizeof(bytes)));
+ auto *i = Deserialize<ExtensionInst>(words);
+ ASSERT_NE(nullptr, i);
+ EXPECT_STREQ("ABCDEFG", i->mOperand1.c_str());
+}
+
+TEST(InstructionTest, testOpExtInstImport) {
+ uint8_t bytes[] = {0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64,
+ 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00};
+ std::vector<uint32_t> words((uint32_t *)bytes,
+ (uint32_t *)(bytes + sizeof(bytes)));
+ auto *i = Deserialize<ExtInstImportInst>(words);
+ ASSERT_NE(nullptr, i);
+ EXPECT_STREQ("GLSL.std.450", i->mOperand1.c_str());
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/module.cpp b/rsov/compiler/spirit/module.cpp
new file mode 100644
index 0000000..d480912
--- /dev/null
+++ b/rsov/compiler/spirit/module.cpp
@@ -0,0 +1,989 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "module.h"
+
+#include <set>
+
+#include "builder.h"
+#include "core_defs.h"
+#include "instructions.h"
+#include "types_generated.h"
+#include "word_stream.h"
+
+namespace android {
+namespace spirit {
+
+Module *Module::mInstance = nullptr;
+
+Module *Module::getCurrentModule() {
+ if (mInstance == nullptr) {
+ return mInstance = new Module();
+ }
+ return mInstance;
+}
+
+Module::Module()
+ : mNextId(1), mCapabilitiesDeleter(mCapabilities),
+ mExtensionsDeleter(mExtensions), mExtInstImportsDeleter(mExtInstImports),
+ mEntryPointInstsDeleter(mEntryPointInsts),
+ mExecutionModesDeleter(mExecutionModes),
+ mEntryPointsDeleter(mEntryPoints),
+ mFunctionDefinitionsDeleter(mFunctionDefinitions) {
+ mInstance = this;
+}
+
+Module::Module(Builder *b)
+ : Entity(b), mNextId(1), mCapabilitiesDeleter(mCapabilities),
+ mExtensionsDeleter(mExtensions), mExtInstImportsDeleter(mExtInstImports),
+ mEntryPointInstsDeleter(mEntryPointInsts),
+ mExecutionModesDeleter(mExecutionModes),
+ mEntryPointsDeleter(mEntryPoints),
+ mFunctionDefinitionsDeleter(mFunctionDefinitions) {
+ mInstance = this;
+}
+
+bool Module::resolveIds() {
+ auto &table = mIdTable;
+
+ std::unique_ptr<IVisitor> v0(
+ CreateInstructionVisitor([&table](Instruction *inst) {
+ if (inst->hasResult()) {
+ table.insert(std::make_pair(inst->getId(), inst));
+ }
+ }));
+ v0->visit(this);
+
+ mNextId = mIdTable.rbegin()->first + 1;
+
+ int err = 0;
+ std::unique_ptr<IVisitor> v(
+ CreateInstructionVisitor([&table, &err](Instruction *inst) {
+ for (auto ref : inst->getAllIdRefs()) {
+ if (ref) {
+ auto it = table.find(ref->mId);
+ if (it != table.end()) {
+ ref->mInstruction = it->second;
+ } else {
+ std::cout << "Found no instruction for id " << ref->mId
+ << std::endl;
+ err++;
+ }
+ }
+ }
+ }));
+ v->visit(this);
+ return err == 0;
+}
+
+bool Module::DeserializeInternal(InputWordStream &IS) {
+ if (IS.empty()) {
+ return false;
+ }
+
+ IS >> &mMagicNumber;
+ if (mMagicNumber != 0x07230203) {
+ errs() << "Wrong Magic Number: " << mMagicNumber;
+ return false;
+ }
+
+ if (IS.empty()) {
+ return false;
+ }
+
+ IS >> &mVersion.mWord;
+ if (mVersion.mBytes[0] != 0 || mVersion.mBytes[3] != 0) {
+ return false;
+ }
+
+ if (IS.empty()) {
+ return false;
+ }
+
+ IS >> &mGeneratorMagicNumber >> &mBound >> &mReserved;
+
+ DeserializeZeroOrMore<CapabilityInst>(IS, mCapabilities);
+ DeserializeZeroOrMore<ExtensionInst>(IS, mExtensions);
+ DeserializeZeroOrMore<ExtInstImportInst>(IS, mExtInstImports);
+
+ mMemoryModel.reset(Deserialize<MemoryModelInst>(IS));
+ if (!mMemoryModel) {
+ errs() << "Missing memory model specification.\n";
+ return false;
+ }
+
+ DeserializeZeroOrMore<EntryPointDefinition>(IS, mEntryPoints);
+ DeserializeZeroOrMore<ExecutionModeInst>(IS, mExecutionModes);
+ for (auto entry : mEntryPoints) {
+ mEntryPointInsts.push_back(entry->getInstruction());
+ for (auto mode : mExecutionModes) {
+ entry->applyExecutionMode(mode);
+ }
+ }
+
+ mDebugInfo.reset(Deserialize<DebugInfoSection>(IS));
+ mAnnotations.reset(Deserialize<AnnotationSection>(IS));
+ mGlobals.reset(Deserialize<GlobalSection>(IS));
+
+ DeserializeZeroOrMore<FunctionDefinition>(IS, mFunctionDefinitions);
+
+ if (mFunctionDefinitions.empty()) {
+ errs() << "Missing function definitions.\n";
+ for (int i = 0; i < 4; i++) {
+ uint32_t w;
+ IS >> &w;
+ std::cout << std::hex << w << " ";
+ }
+ std::cout << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+void Module::initialize() {
+ mMagicNumber = 0x07230203;
+ mVersion.mMajorMinor = {.mMinorNumber = 1, .mMajorNumber = 1};
+ mGeneratorMagicNumber = 0x00070000;
+ mBound = 0;
+ mReserved = 0;
+ mAnnotations.reset(new AnnotationSection());
+}
+
+void Module::SerializeHeader(OutputWordStream &OS) const {
+ OS << mMagicNumber;
+ OS << mVersion.mWord << mGeneratorMagicNumber;
+ if (mBound == 0) {
+ OS << mIdTable.end()->first + 1;
+ } else {
+ OS << std::max(mBound, mNextId);
+ }
+ OS << mReserved;
+}
+
+void Module::Serialize(OutputWordStream &OS) const {
+ SerializeHeader(OS);
+ Entity::Serialize(OS);
+}
+
+Module *Module::addCapability(Capability cap) {
+ mCapabilities.push_back(mBuilder->MakeCapability(cap));
+ return this;
+}
+
+Module *Module::setMemoryModel(AddressingModel am, MemoryModel mm) {
+ mMemoryModel.reset(mBuilder->MakeMemoryModel(am, mm));
+ return this;
+}
+
+Module *Module::addExtInstImport(const char *extName) {
+ ExtInstImportInst *extInst = mBuilder->MakeExtInstImport(extName);
+ mExtInstImports.push_back(extInst);
+ if (strcmp(extName, "GLSL.std.450") == 0) {
+ mGLExt = extInst;
+ }
+ return this;
+}
+
+Module *Module::addSource(SourceLanguage lang, int version) {
+ if (!mDebugInfo) {
+ mDebugInfo.reset(mBuilder->MakeDebugInfoSection());
+ }
+ mDebugInfo->addSource(lang, version);
+ return this;
+}
+
+Module *Module::addSourceExtension(const char *ext) {
+ if (!mDebugInfo) {
+ mDebugInfo.reset(mBuilder->MakeDebugInfoSection());
+ }
+ mDebugInfo->addSourceExtension(ext);
+ return this;
+}
+
+Module *Module::addString(const char *str) {
+ if (!mDebugInfo) {
+ mDebugInfo.reset(mBuilder->MakeDebugInfoSection());
+ }
+ mDebugInfo->addString(str);
+ return this;
+}
+
+Module *Module::addEntryPoint(EntryPointDefinition *entry) {
+ mEntryPoints.push_back(entry);
+ auto newModes = entry->getExecutionModes();
+ mExecutionModes.insert(mExecutionModes.end(), newModes.begin(),
+ newModes.end());
+ return this;
+}
+
+const std::string Module::findStringOfPrefix(const char *prefix) const {
+ if (!mDebugInfo) {
+ return std::string();
+ }
+ return mDebugInfo->findStringOfPrefix(prefix);
+}
+
+GlobalSection *Module::getGlobalSection() {
+ if (!mGlobals) {
+ mGlobals.reset(new GlobalSection());
+ }
+ return mGlobals.get();
+}
+
+ConstantInst *Module::getConstant(TypeIntInst *type, int32_t value) {
+ return getGlobalSection()->getConstant(type, value);
+}
+
+ConstantInst *Module::getConstant(TypeIntInst *type, uint32_t value) {
+ return getGlobalSection()->getConstant(type, value);
+}
+
+ConstantInst *Module::getConstant(TypeFloatInst *type, float value) {
+ return getGlobalSection()->getConstant(type, value);
+}
+
+ConstantCompositeInst *Module::getConstantComposite(TypeVectorInst *type,
+ ConstantInst *components[],
+ size_t width) {
+ return getGlobalSection()->getConstantComposite(type, components, width);
+}
+
+ConstantCompositeInst *Module::getConstantComposite(TypeVectorInst *type,
+ ConstantInst *comp0,
+ ConstantInst *comp1,
+ ConstantInst *comp2) {
+ // TODO: verify that component types are the same and consistent with the
+ // resulting vector type
+ ConstantInst *comps[] = {comp0, comp1, comp2};
+ return getConstantComposite(type, comps, 3);
+}
+
+ConstantCompositeInst *Module::getConstantComposite(TypeVectorInst *type,
+ ConstantInst *comp0,
+ ConstantInst *comp1,
+ ConstantInst *comp2,
+ ConstantInst *comp3) {
+ // TODO: verify that component types are the same and consistent with the
+ // resulting vector type
+ ConstantInst *comps[] = {comp0, comp1, comp2, comp3};
+ return getConstantComposite(type, comps, 4);
+}
+
+TypeVoidInst *Module::getVoidType() {
+ return getGlobalSection()->getVoidType();
+}
+
+TypeIntInst *Module::getIntType(int bits, bool isSigned) {
+ return getGlobalSection()->getIntType(bits, isSigned);
+}
+
+TypeIntInst *Module::getUnsignedIntType(int bits) {
+ return getIntType(bits, false);
+}
+
+TypeFloatInst *Module::getFloatType(int bits) {
+ return getGlobalSection()->getFloatType(bits);
+}
+
+TypeVectorInst *Module::getVectorType(Instruction *componentType, int width) {
+ return getGlobalSection()->getVectorType(componentType, width);
+}
+
+TypePointerInst *Module::getPointerType(StorageClass storage,
+ Instruction *pointeeType) {
+ return getGlobalSection()->getPointerType(storage, pointeeType);
+}
+
+TypeRuntimeArrayInst *Module::getRuntimeArrayType(Instruction *elementType) {
+ return getGlobalSection()->getRuntimeArrayType(elementType);
+}
+
+TypeStructInst *Module::getStructType(Instruction *fieldType[], int numField) {
+ return getGlobalSection()->getStructType(fieldType, numField);
+}
+
+TypeStructInst *Module::getStructType(Instruction *fieldType) {
+ return getStructType(&fieldType, 1);
+}
+
+TypeFunctionInst *Module::getFunctionType(Instruction *retType,
+ Instruction *const argType[],
+ size_t numArg) {
+ return getGlobalSection()->getFunctionType(retType, argType, numArg);
+}
+
+TypeFunctionInst *
+Module::getFunctionType(Instruction *retType,
+ const std::vector<Instruction *> &argTypes) {
+ return getGlobalSection()->getFunctionType(retType, argTypes.data(),
+ argTypes.size());
+}
+
+size_t Module::getSize(TypeVoidInst *) { return 0; }
+
+size_t Module::getSize(TypeIntInst *intTy) { return intTy->mOperand1 / 8; }
+
+size_t Module::getSize(TypeFloatInst *fpTy) { return fpTy->mOperand1 / 8; }
+
+size_t Module::getSize(TypeVectorInst *vTy) {
+ return getSize(vTy->mOperand1.mInstruction) * vTy->mOperand2;
+}
+
+size_t Module::getSize(TypePointerInst *) {
+ return 4; // TODO: or 8?
+}
+
+size_t Module::getSize(TypeStructInst *structTy) {
+ size_t sz = 0;
+ for (auto ty : structTy->mOperand1) {
+ sz += getSize(ty.mInstruction);
+ }
+ return sz;
+}
+
+size_t Module::getSize(TypeFunctionInst *) {
+ return 4; // TODO: or 8? Is this just the size of a pointer?
+}
+
+size_t Module::getSize(Instruction *inst) {
+ switch (inst->getOpCode()) {
+ case OpTypeVoid:
+ return getSize(static_cast<TypeVoidInst *>(inst));
+ case OpTypeInt:
+ return getSize(static_cast<TypeIntInst *>(inst));
+ case OpTypeFloat:
+ return getSize(static_cast<TypeFloatInst *>(inst));
+ case OpTypeVector:
+ return getSize(static_cast<TypeVectorInst *>(inst));
+ case OpTypeStruct:
+ return getSize(static_cast<TypeStructInst *>(inst));
+ case OpTypeFunction:
+ return getSize(static_cast<TypeFunctionInst *>(inst));
+ default:
+ return 0;
+ }
+}
+
+Module *Module::addFunctionDefinition(FunctionDefinition *func) {
+ mFunctionDefinitions.push_back(func);
+ return this;
+}
+
+Instruction *Module::lookupByName(const char *name) const {
+ return mDebugInfo->lookupByName(name);
+}
+
+FunctionDefinition *
+Module::getFunctionDefinitionFromInstruction(FunctionInst *inst) const {
+ for (auto fdef : mFunctionDefinitions) {
+ if (fdef->getInstruction() == inst) {
+ return fdef;
+ }
+ }
+ return nullptr;
+}
+
+FunctionDefinition *
+Module::lookupFunctionDefinitionByName(const char *name) const {
+ FunctionInst *inst = static_cast<FunctionInst *>(lookupByName(name));
+ return getFunctionDefinitionFromInstruction(inst);
+}
+
+const char *Module::lookupNameByInstruction(const Instruction *inst) const {
+ return mDebugInfo->lookupNameByInstruction(inst);
+}
+
+VariableInst *Module::getInvocationId() {
+ return getGlobalSection()->getInvocationId();
+}
+
+VariableInst *Module::getNumWorkgroups() {
+ return getGlobalSection()->getNumWorkgroups();
+}
+
+Module *Module::addStructType(TypeStructInst *structType) {
+ getGlobalSection()->addStructType(structType);
+ return this;
+}
+
+Module *Module::addVariable(VariableInst *var) {
+ getGlobalSection()->addVariable(var);
+ return this;
+}
+
+void Module::consolidateAnnotations() {
+ std::vector<Instruction *> annotations(mAnnotations->begin(),
+ mAnnotations->end());
+ std::unique_ptr<IVisitor> v(
+ CreateInstructionVisitor([&annotations](Instruction *inst) -> void {
+ const auto &ann = inst->getAnnotations();
+ annotations.insert(annotations.end(), ann.begin(), ann.end());
+ }));
+ v->visit(this);
+ mAnnotations->clear();
+ mAnnotations->addAnnotations(annotations.begin(), annotations.end());
+}
+
+EntryPointDefinition::EntryPointDefinition(Builder *builder,
+ ExecutionModel execModel,
+ FunctionDefinition *func,
+ const char *name)
+ : Entity(builder), mFunction(func->getInstruction()),
+ mExecutionModel(execModel) {
+ mName = strndup(name, strlen(name));
+ mEntryPointInst = mBuilder->MakeEntryPoint(execModel, mFunction, mName);
+ (void)mExecutionModel; // suppress unused private field warning
+}
+
+bool EntryPointDefinition::DeserializeInternal(InputWordStream &IS) {
+ if (IS.empty()) {
+ return false;
+ }
+
+ if ((mEntryPointInst = Deserialize<EntryPointInst>(IS))) {
+ return true;
+ }
+
+ return false;
+}
+
+EntryPointDefinition *
+EntryPointDefinition::applyExecutionMode(ExecutionModeInst *mode) {
+ if (mode->mOperand1.mInstruction == mFunction) {
+ addExecutionMode(mode);
+ }
+ return this;
+}
+
+EntryPointDefinition *EntryPointDefinition::addToInterface(VariableInst *var) {
+ mInterface.push_back(var);
+ mEntryPointInst->mOperand4.push_back(var);
+ return this;
+}
+
+EntryPointDefinition *EntryPointDefinition::setLocalSize(uint32_t width,
+ uint32_t height,
+ uint32_t depth) {
+ mLocalSize.mWidth = width;
+ mLocalSize.mHeight = height;
+ mLocalSize.mDepth = depth;
+
+ auto mode = mBuilder->MakeExecutionMode(mFunction, ExecutionMode::LocalSize);
+ mode->addExtraOperand(width)->addExtraOperand(height)->addExtraOperand(depth);
+
+ addExecutionMode(mode);
+
+ return this;
+}
+
+bool DebugInfoSection::DeserializeInternal(InputWordStream &IS) {
+ while (true) {
+ if (auto str = Deserialize<StringInst>(IS)) {
+ mSources.push_back(str);
+ } else if (auto src = Deserialize<SourceInst>(IS)) {
+ mSources.push_back(src);
+ } else if (auto srcExt = Deserialize<SourceExtensionInst>(IS)) {
+ mSources.push_back(srcExt);
+ } else if (auto srcCont = Deserialize<SourceContinuedInst>(IS)) {
+ mSources.push_back(srcCont);
+ } else {
+ break;
+ }
+ }
+
+ while (true) {
+ if (auto name = Deserialize<NameInst>(IS)) {
+ mNames.push_back(name);
+ } else if (auto memName = Deserialize<MemberNameInst>(IS)) {
+ mNames.push_back(memName);
+ } else {
+ break;
+ }
+ }
+
+ return true;
+}
+
+DebugInfoSection *DebugInfoSection::addSource(SourceLanguage lang,
+ int version) {
+ SourceInst *source = mBuilder->MakeSource(lang, version);
+ mSources.push_back(source);
+ return this;
+}
+
+DebugInfoSection *DebugInfoSection::addSourceExtension(const char *ext) {
+ SourceExtensionInst *inst = mBuilder->MakeSourceExtension(ext);
+ mSources.push_back(inst);
+ return this;
+}
+
+DebugInfoSection *DebugInfoSection::addString(const char *str) {
+ StringInst *source = mBuilder->MakeString(str);
+ mSources.push_back(source);
+ return this;
+}
+
+std::string DebugInfoSection::findStringOfPrefix(const char *prefix) {
+ auto it = std::find_if(
+ mSources.begin(), mSources.end(), [prefix](Instruction *inst) -> bool {
+ if (inst->getOpCode() != OpString) {
+ return false;
+ }
+ const StringInst *strInst = static_cast<const StringInst *>(inst);
+ const std::string &str = strInst->mOperand1;
+ return str.find(prefix) == 0;
+ });
+ if (it == mSources.end()) {
+ return "";
+ }
+ StringInst *strInst = static_cast<StringInst *>(*it);
+ return strInst->mOperand1;
+}
+
+Instruction *DebugInfoSection::lookupByName(const char *name) const {
+ for (auto inst : mNames) {
+ if (inst->getOpCode() == OpName) {
+ NameInst *nameInst = static_cast<NameInst *>(inst);
+ if (nameInst->mOperand2.compare(name) == 0) {
+ return nameInst->mOperand1.mInstruction;
+ }
+ }
+ // Ignore member names
+ }
+ return nullptr;
+}
+
+const char *
+DebugInfoSection::lookupNameByInstruction(const Instruction *target) const {
+ for (auto inst : mNames) {
+ if (inst->getOpCode() == OpName) {
+ NameInst *nameInst = static_cast<NameInst *>(inst);
+ if (nameInst->mOperand1.mInstruction == target) {
+ return nameInst->mOperand2.c_str();
+ }
+ }
+ // Ignore member names
+ }
+ return nullptr;
+}
+
+AnnotationSection::AnnotationSection() : mAnnotationsDeleter(mAnnotations) {}
+
+AnnotationSection::AnnotationSection(Builder *b)
+ : Entity(b), mAnnotationsDeleter(mAnnotations) {}
+
+bool AnnotationSection::DeserializeInternal(InputWordStream &IS) {
+ while (true) {
+ if (auto decor = Deserialize<DecorateInst>(IS)) {
+ mAnnotations.push_back(decor);
+ } else if (auto decor = Deserialize<MemberDecorateInst>(IS)) {
+ mAnnotations.push_back(decor);
+ } else if (auto decor = Deserialize<GroupDecorateInst>(IS)) {
+ mAnnotations.push_back(decor);
+ } else if (auto decor = Deserialize<GroupMemberDecorateInst>(IS)) {
+ mAnnotations.push_back(decor);
+ } else if (auto decor = Deserialize<DecorationGroupInst>(IS)) {
+ mAnnotations.push_back(decor);
+ } else {
+ break;
+ }
+ }
+ return true;
+}
+
+GlobalSection::GlobalSection() : mGlobalDefsDeleter(mGlobalDefs) {}
+
+GlobalSection::GlobalSection(Builder *builder)
+ : Entity(builder), mGlobalDefsDeleter(mGlobalDefs) {}
+
+namespace {
+
+template <typename T>
+T *findOrCreate(std::function<bool(T *)> criteria, std::function<T *()> factory,
+ std::vector<Instruction *> *globals) {
+ T *derived;
+ for (auto inst : *globals) {
+ if (inst->getOpCode() == T::mOpCode) {
+ T *derived = static_cast<T *>(inst);
+ if (criteria(derived)) {
+ return derived;
+ }
+ }
+ }
+ derived = factory();
+ globals->push_back(derived);
+ return derived;
+}
+
+} // anonymous namespace
+
+bool GlobalSection::DeserializeInternal(InputWordStream &IS) {
+ while (true) {
+#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) \
+ if (auto typeInst = Deserialize<INST_CLASS>(IS)) { \
+ mGlobalDefs.push_back(typeInst); \
+ continue; \
+ }
+#include "const_inst_dispatches_generated.h"
+#include "type_inst_dispatches_generated.h"
+#undef HANDLE_INSTRUCTION
+
+ if (auto globalInst = Deserialize<VariableInst>(IS)) {
+ // Check if this is function scoped
+ if (globalInst->mOperand1 == StorageClass::Function) {
+ Module::errs() << "warning: Variable (id = " << globalInst->mResult;
+ Module::errs() << ") has function scope in global section.\n";
+ // Khronos LLVM-SPIRV convertor emits "Function" storage-class globals.
+ // As a workaround, accept such SPIR-V code here, and fix it up later
+ // in the rs2spirv compiler by correcting the storage class.
+ // In a stricter deserializer, such code should be rejected, and we
+ // should return false here.
+ }
+ mGlobalDefs.push_back(globalInst);
+ continue;
+ }
+
+ if (auto globalInst = Deserialize<UndefInst>(IS)) {
+ mGlobalDefs.push_back(globalInst);
+ continue;
+ }
+ break;
+ }
+ return true;
+}
+
+ConstantInst *GlobalSection::getConstant(TypeIntInst *type, int32_t value) {
+ return findOrCreate<ConstantInst>(
+ [=](ConstantInst *c) { return c->mOperand1.intValue == value; },
+ [=]() -> ConstantInst * {
+ LiteralContextDependentNumber cdn = {.intValue = value};
+ return mBuilder->MakeConstant(type, cdn);
+ },
+ &mGlobalDefs);
+}
+
+ConstantInst *GlobalSection::getConstant(TypeIntInst *type, uint32_t value) {
+ return findOrCreate<ConstantInst>(
+ [=](ConstantInst *c) { return c->mOperand1.intValue == (int)value; },
+ [=]() -> ConstantInst * {
+ LiteralContextDependentNumber cdn = {.intValue = (int)value};
+ return mBuilder->MakeConstant(type, cdn);
+ },
+ &mGlobalDefs);
+}
+
+ConstantInst *GlobalSection::getConstant(TypeFloatInst *type, float value) {
+ return findOrCreate<ConstantInst>(
+ [=](ConstantInst *c) { return c->mOperand1.floatValue == value; },
+ [=]() -> ConstantInst * {
+ LiteralContextDependentNumber cdn = {.floatValue = value};
+ return mBuilder->MakeConstant(type, cdn);
+ },
+ &mGlobalDefs);
+}
+
+ConstantCompositeInst *
+GlobalSection::getConstantComposite(TypeVectorInst *type,
+ ConstantInst *components[], size_t width) {
+ return findOrCreate<ConstantCompositeInst>(
+ [=](ConstantCompositeInst *c) {
+ if (c->mOperand1.size() != width) {
+ return false;
+ }
+ for (size_t i = 0; i < width; i++) {
+ if (c->mOperand1[i].mInstruction != components[i]) {
+ return false;
+ }
+ }
+ return true;
+ },
+ [=]() -> ConstantCompositeInst * {
+ ConstantCompositeInst *c = mBuilder->MakeConstantComposite(type);
+ for (size_t i = 0; i < width; i++) {
+ c->mOperand1.push_back(components[i]);
+ }
+ return c;
+ },
+ &mGlobalDefs);
+}
+
+TypeVoidInst *GlobalSection::getVoidType() {
+ return findOrCreate<TypeVoidInst>(
+ [=](TypeVoidInst *) -> bool { return true; },
+ [=]() -> TypeVoidInst * { return mBuilder->MakeTypeVoid(); },
+ &mGlobalDefs);
+}
+
+TypeIntInst *GlobalSection::getIntType(int bits, bool isSigned) {
+ if (isSigned) {
+ switch (bits) {
+#define HANDLE_INT_SIZE(INT_TYPE, BITS, SIGNED) \
+ case BITS: { \
+ return findOrCreate<TypeIntInst>( \
+ [=](TypeIntInst *intTy) -> bool { \
+ return intTy->mOperand1 == BITS && intTy->mOperand2 == SIGNED; \
+ }, \
+ [=]() -> TypeIntInst * { \
+ return mBuilder->MakeTypeInt(BITS, SIGNED); \
+ }, \
+ &mGlobalDefs); \
+ }
+ HANDLE_INT_SIZE(Int, 8, 1);
+ HANDLE_INT_SIZE(Int, 16, 1);
+ HANDLE_INT_SIZE(Int, 32, 1);
+ HANDLE_INT_SIZE(Int, 64, 1);
+ default:
+ Module::errs() << "unexpected int type";
+ }
+ } else {
+ switch (bits) {
+ HANDLE_INT_SIZE(UInt, 8, 0);
+ HANDLE_INT_SIZE(UInt, 16, 0);
+ HANDLE_INT_SIZE(UInt, 32, 0);
+ HANDLE_INT_SIZE(UInt, 64, 0);
+ default:
+ Module::errs() << "unexpected int type";
+ }
+ }
+#undef HANDLE_INT_SIZE
+ return nullptr;
+}
+
+TypeFloatInst *GlobalSection::getFloatType(int bits) {
+ switch (bits) {
+#define HANDLE_FLOAT_SIZE(BITS) \
+ case BITS: { \
+ return findOrCreate<TypeFloatInst>( \
+ [=](TypeFloatInst *floatTy) -> bool { \
+ return floatTy->mOperand1 == BITS; \
+ }, \
+ [=]() -> TypeFloatInst * { return mBuilder->MakeTypeFloat(BITS); }, \
+ &mGlobalDefs); \
+ }
+ HANDLE_FLOAT_SIZE(16);
+ HANDLE_FLOAT_SIZE(32);
+ HANDLE_FLOAT_SIZE(64);
+ default:
+ Module::errs() << "unexpeced floating point type";
+ }
+#undef HANDLE_FLOAT_SIZE
+ return nullptr;
+}
+
+TypeVectorInst *GlobalSection::getVectorType(Instruction *componentType,
+ int width) {
+ // TODO: verify that componentType is basic numeric types
+
+ return findOrCreate<TypeVectorInst>(
+ [=](TypeVectorInst *vecTy) -> bool {
+ return vecTy->mOperand1.mInstruction == componentType &&
+ vecTy->mOperand2 == width;
+ },
+ [=]() -> TypeVectorInst * {
+ return mBuilder->MakeTypeVector(componentType, width);
+ },
+ &mGlobalDefs);
+}
+
+TypePointerInst *GlobalSection::getPointerType(StorageClass storage,
+ Instruction *pointeeType) {
+ return findOrCreate<TypePointerInst>(
+ [=](TypePointerInst *type) -> bool {
+ return type->mOperand1 == storage &&
+ type->mOperand2.mInstruction == pointeeType;
+ },
+ [=]() -> TypePointerInst * {
+ return mBuilder->MakeTypePointer(storage, pointeeType);
+ },
+ &mGlobalDefs);
+}
+
+TypeRuntimeArrayInst *
+GlobalSection::getRuntimeArrayType(Instruction *elemType) {
+ return findOrCreate<TypeRuntimeArrayInst>(
+ [=](TypeRuntimeArrayInst * /*type*/) -> bool {
+ // return type->mOperand1.mInstruction == elemType;
+ return false;
+ },
+ [=]() -> TypeRuntimeArrayInst * {
+ return mBuilder->MakeTypeRuntimeArray(elemType);
+ },
+ &mGlobalDefs);
+}
+
+TypeStructInst *GlobalSection::getStructType(Instruction *fieldType[],
+ int numField) {
+ TypeStructInst *structTy = mBuilder->MakeTypeStruct();
+ for (int i = 0; i < numField; i++) {
+ structTy->mOperand1.push_back(fieldType[i]);
+ }
+ mGlobalDefs.push_back(structTy);
+ return structTy;
+}
+
+TypeFunctionInst *GlobalSection::getFunctionType(Instruction *retType,
+ Instruction *const argType[],
+ size_t numArg) {
+ return findOrCreate<TypeFunctionInst>(
+ [=](TypeFunctionInst *type) -> bool {
+ if (type->mOperand1.mInstruction != retType ||
+ type->mOperand2.size() != numArg) {
+ return false;
+ }
+ for (size_t i = 0; i < numArg; i++) {
+ if (type->mOperand2[i].mInstruction != argType[i]) {
+ return false;
+ }
+ }
+ return true;
+ },
+ [=]() -> TypeFunctionInst * {
+ TypeFunctionInst *funcTy = mBuilder->MakeTypeFunction(retType);
+ for (size_t i = 0; i < numArg; i++) {
+ funcTy->mOperand2.push_back(argType[i]);
+ }
+ return funcTy;
+ },
+ &mGlobalDefs);
+}
+
+GlobalSection *GlobalSection::addStructType(TypeStructInst *structType) {
+ mGlobalDefs.push_back(structType);
+ return this;
+}
+
+GlobalSection *GlobalSection::addVariable(VariableInst *var) {
+ mGlobalDefs.push_back(var);
+ return this;
+}
+
+VariableInst *GlobalSection::getInvocationId() {
+ if (mInvocationId) {
+ return mInvocationId.get();
+ }
+
+ TypeIntInst *UIntTy = getIntType(32, false);
+ TypeVectorInst *V3UIntTy = getVectorType(UIntTy, 3);
+ TypePointerInst *V3UIntPtrTy = getPointerType(StorageClass::Input, V3UIntTy);
+
+ VariableInst *InvocationId =
+ mBuilder->MakeVariable(V3UIntPtrTy, StorageClass::Input);
+ InvocationId->decorate(Decoration::BuiltIn)
+ ->addExtraOperand(static_cast<uint32_t>(BuiltIn::GlobalInvocationId));
+
+ mInvocationId.reset(InvocationId);
+
+ return InvocationId;
+}
+
+VariableInst *GlobalSection::getNumWorkgroups() {
+ if (mNumWorkgroups) {
+ return mNumWorkgroups.get();
+ }
+
+ TypeIntInst *UIntTy = getIntType(32, false);
+ TypeVectorInst *V3UIntTy = getVectorType(UIntTy, 3);
+ TypePointerInst *V3UIntPtrTy = getPointerType(StorageClass::Input, V3UIntTy);
+
+ VariableInst *GNum = mBuilder->MakeVariable(V3UIntPtrTy, StorageClass::Input);
+ GNum->decorate(Decoration::BuiltIn)
+ ->addExtraOperand(static_cast<uint32_t>(BuiltIn::NumWorkgroups));
+
+ mNumWorkgroups.reset(GNum);
+
+ return GNum;
+}
+
+bool FunctionDeclaration::DeserializeInternal(InputWordStream &IS) {
+ if (!(mFunc = Deserialize<FunctionInst>(IS))) {
+ return false;
+ }
+
+ DeserializeZeroOrMore<FunctionParameterInst>(IS, mParams);
+
+ if (!(mFuncEnd = Deserialize<FunctionEndInst>(IS))) {
+ return false;
+ }
+
+ return true;
+}
+
+template <> Instruction *Deserialize(InputWordStream &IS) {
+ Instruction *inst;
+
+ switch ((*IS) & 0xFFFF) {
+#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) \
+ case OPCODE: \
+ inst = Deserialize<INST_CLASS>(IS); \
+ break;
+#include "instruction_dispatches_generated.h"
+#undef HANDLE_INSTRUCTION
+ default:
+ Module::errs() << "unrecognized instruction";
+ inst = nullptr;
+ }
+
+ return inst;
+}
+
+bool Block::DeserializeInternal(InputWordStream &IS) {
+ Instruction *inst;
+ while (((*IS) & 0xFFFF) != OpFunctionEnd &&
+ (inst = Deserialize<Instruction>(IS))) {
+ mInsts.push_back(inst);
+ if (inst->getOpCode() == OpBranch ||
+ inst->getOpCode() == OpBranchConditional ||
+ inst->getOpCode() == OpSwitch || inst->getOpCode() == OpKill ||
+ inst->getOpCode() == OpReturn || inst->getOpCode() == OpReturnValue ||
+ inst->getOpCode() == OpUnreachable) {
+ break;
+ }
+ }
+ return !mInsts.empty();
+}
+
+FunctionDefinition::FunctionDefinition()
+ : mParamsDeleter(mParams), mBlocksDeleter(mBlocks) {}
+
+FunctionDefinition::FunctionDefinition(Builder *builder, FunctionInst *func,
+ FunctionEndInst *end)
+ : Entity(builder), mFunc(func), mFuncEnd(end), mParamsDeleter(mParams),
+ mBlocksDeleter(mBlocks) {}
+
+bool FunctionDefinition::DeserializeInternal(InputWordStream &IS) {
+ mFunc.reset(Deserialize<FunctionInst>(IS));
+ if (!mFunc) {
+ return false;
+ }
+
+ DeserializeZeroOrMore<FunctionParameterInst>(IS, mParams);
+ DeserializeZeroOrMore<Block>(IS, mBlocks);
+
+ mFuncEnd.reset(Deserialize<FunctionEndInst>(IS));
+ if (!mFuncEnd) {
+ return false;
+ }
+
+ return true;
+}
+
+Instruction *FunctionDefinition::getReturnType() const {
+ return mFunc->mResultType.mInstruction;
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/module.h b/rsov/compiler/spirit/module.h
new file mode 100644
index 0000000..cf0b1e0
--- /dev/null
+++ b/rsov/compiler/spirit/module.h
@@ -0,0 +1,534 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef MODULE_H
+#define MODULE_H
+
+#include <iostream>
+#include <map>
+#include <vector>
+
+#include "core_defs.h"
+#include "entity.h"
+#include "instructions.h"
+#include "stl_util.h"
+#include "types_generated.h"
+#include "visitor.h"
+
+namespace android {
+namespace spirit {
+
+class Builder;
+class AnnotationSection;
+class CapabilityInst;
+class DebugInfoSection;
+class ExtensionInst;
+class ExtInstImportInst;
+class EntryPointInst;
+class ExecutionModeInst;
+class EntryPointDefinition;
+class FunctionDeclaration;
+class FunctionDefinition;
+class GlobalSection;
+class InputWordStream;
+class Instruction;
+class MemoryModelInst;
+
+union VersionNumber {
+ struct {
+ uint8_t mLowZero;
+ uint8_t mMinorNumber;
+ uint8_t mMajorNumber;
+ uint8_t mHighZero;
+ } mMajorMinor;
+ uint8_t mBytes[4];
+ uint32_t mWord;
+};
+
+class Module : public Entity {
+public:
+ static Module *getCurrentModule();
+ uint32_t nextId() { return mNextId++; }
+
+ Module();
+
+ Module(Builder *b);
+
+ virtual ~Module() {}
+
+ bool DeserializeInternal(InputWordStream &IS) override;
+
+ void Serialize(OutputWordStream &OS) const override;
+
+ void SerializeHeader(OutputWordStream &OS) const;
+
+ void registerId(uint32_t id, Instruction *inst) {
+ mIdTable.insert(std::make_pair(id, inst));
+ }
+
+ void initialize();
+
+ bool resolveIds();
+
+ void accept(IVisitor *v) override {
+ for (auto cap : mCapabilities) {
+ v->visit(cap);
+ }
+ for (auto ext : mExtensions) {
+ v->visit(ext);
+ }
+ for (auto imp : mExtInstImports) {
+ v->visit(imp);
+ }
+
+ v->visit(mMemoryModel.get());
+
+ for (auto entry : mEntryPoints) {
+ v->visit(entry);
+ }
+
+ for (auto mode : mExecutionModes) {
+ v->visit(mode);
+ }
+
+ v->visit(mDebugInfo.get());
+ if (mAnnotations) {
+ v->visit(mAnnotations.get());
+ }
+ if (mGlobals) {
+ v->visit(mGlobals.get());
+ }
+
+ for (auto def : mFunctionDefinitions) {
+ v->visit(def);
+ }
+ }
+
+ static std::ostream &errs() { return std::cerr; }
+
+ Module *addCapability(Capability cap);
+ Module *setMemoryModel(AddressingModel am, MemoryModel mm);
+ Module *addExtInstImport(const char *extName);
+ Module *addSource(SourceLanguage lang, int version);
+ Module *addSourceExtension(const char *ext);
+ Module *addString(const char *ext);
+ Module *addEntryPoint(EntryPointDefinition *entry);
+
+ ExtInstImportInst *getGLExt() const { return mGLExt; }
+
+ const std::string findStringOfPrefix(const char *prefix) const;
+
+ GlobalSection *getGlobalSection();
+
+ Instruction *lookupByName(const char *) const;
+ FunctionDefinition *
+ getFunctionDefinitionFromInstruction(FunctionInst *) const;
+ FunctionDefinition *lookupFunctionDefinitionByName(const char *name) const;
+
+ // Find the name of the instruction, e.g., the name of a function (OpFunction
+ // instruction).
+ // The returned string is owned by the OpName instruction, whose first operand
+ // is the instruction being queried on.
+ const char *lookupNameByInstruction(const Instruction *) const;
+
+ VariableInst *getInvocationId();
+ VariableInst *getNumWorkgroups();
+
+ // Adds a struct type built somewhere else.
+ Module *addStructType(TypeStructInst *structType);
+ Module *addVariable(VariableInst *var);
+
+ // Methods to look up types. Create them if not found.
+ TypeVoidInst *getVoidType();
+ TypeIntInst *getIntType(int bits, bool isSigned = true);
+ TypeIntInst *getUnsignedIntType(int bits);
+ TypeFloatInst *getFloatType(int bits);
+ TypeVectorInst *getVectorType(Instruction *componentType, int width);
+ TypePointerInst *getPointerType(StorageClass storage,
+ Instruction *pointeeType);
+ TypeRuntimeArrayInst *getRuntimeArrayType(Instruction *elementType);
+
+ // This implies that struct types are strictly structural equivalent, i.e.,
+ // two structs are equivalent i.f.f. their fields are equivalent, recursively.
+ TypeStructInst *getStructType(Instruction *fieldType[], int numField);
+ TypeStructInst *getStructType(const std::vector<Instruction *> &fieldType);
+ TypeStructInst *getStructType(Instruction *field0Type);
+ TypeStructInst *getStructType(Instruction *field0Type,
+ Instruction *field1Type);
+ TypeStructInst *getStructType(Instruction *field0Type,
+ Instruction *field1Type,
+ Instruction *field2Type);
+
+ // TODO: Can function types of different decorations be considered the same?
+ TypeFunctionInst *getFunctionType(Instruction *retType,
+ Instruction *const argType[],
+ size_t numArg);
+ TypeFunctionInst *getFunctionType(Instruction *retType,
+ const std::vector<Instruction *> &argTypes);
+
+ size_t getSize(TypeVoidInst *voidTy);
+ size_t getSize(TypeIntInst *intTy);
+ size_t getSize(TypeFloatInst *fpTy);
+ size_t getSize(TypeVectorInst *vTy);
+ size_t getSize(TypePointerInst *ptrTy);
+ size_t getSize(TypeStructInst *structTy);
+ size_t getSize(TypeFunctionInst *funcTy);
+ size_t getSize(Instruction *inst);
+
+ ConstantInst *getConstant(TypeIntInst *type, int32_t value);
+ ConstantInst *getConstant(TypeIntInst *type, uint32_t value);
+ ConstantInst *getConstant(TypeFloatInst *type, float value);
+
+ ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
+ ConstantInst *components[],
+ size_t width);
+ ConstantCompositeInst *
+ getConstantComposite(Instruction *type,
+ const std::vector<ConstantInst *> &components);
+ ConstantCompositeInst *getConstantComposite(Instruction *type,
+ ConstantInst *comp0,
+ ConstantInst *comp1);
+ ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
+ ConstantInst *comp0,
+ ConstantInst *comp1,
+ ConstantInst *comp2);
+ ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
+ ConstantInst *comp0,
+ ConstantInst *comp1,
+ ConstantInst *comp2,
+ ConstantInst *comp3);
+
+ Module *addFunctionDefinition(FunctionDefinition *func);
+
+ void consolidateAnnotations();
+
+private:
+ static Module *mInstance;
+ uint32_t mNextId;
+ std::map<uint32_t, Instruction *> mIdTable;
+
+ uint32_t mMagicNumber;
+ VersionNumber mVersion;
+ uint32_t mGeneratorMagicNumber;
+ uint32_t mBound;
+ uint32_t mReserved;
+
+ std::vector<CapabilityInst *> mCapabilities;
+ std::vector<ExtensionInst *> mExtensions;
+ std::vector<ExtInstImportInst *> mExtInstImports;
+ std::unique_ptr<MemoryModelInst> mMemoryModel;
+ std::vector<EntryPointInst *> mEntryPointInsts;
+ std::vector<ExecutionModeInst *> mExecutionModes;
+ std::vector<EntryPointDefinition *> mEntryPoints;
+ std::unique_ptr<DebugInfoSection> mDebugInfo;
+ std::unique_ptr<AnnotationSection> mAnnotations;
+ std::unique_ptr<GlobalSection> mGlobals;
+ std::vector<FunctionDefinition *> mFunctionDefinitions;
+
+ ExtInstImportInst *mGLExt;
+
+ ContainerDeleter<std::vector<CapabilityInst *>> mCapabilitiesDeleter;
+ ContainerDeleter<std::vector<ExtensionInst *>> mExtensionsDeleter;
+ ContainerDeleter<std::vector<ExtInstImportInst *>> mExtInstImportsDeleter;
+ ContainerDeleter<std::vector<EntryPointInst *>> mEntryPointInstsDeleter;
+ ContainerDeleter<std::vector<ExecutionModeInst *>> mExecutionModesDeleter;
+ ContainerDeleter<std::vector<EntryPointDefinition *>> mEntryPointsDeleter;
+ ContainerDeleter<std::vector<FunctionDefinition *>>
+ mFunctionDefinitionsDeleter;
+};
+
+struct Extent3D {
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mDepth;
+};
+
+class EntryPointDefinition : public Entity {
+public:
+ EntryPointDefinition() {}
+ EntryPointDefinition(Builder *builder, ExecutionModel execModel,
+ FunctionDefinition *func, const char *name);
+
+ virtual ~EntryPointDefinition() {
+ // Nothing to do here since ~Module() will delete entities referenced here
+ }
+
+ void accept(IVisitor *visitor) override {
+ visitor->visit(mEntryPointInst);
+ // Do not visit the ExecutionMode instructions here. They are linked here
+ // for convinience, and for convinience only. They are all grouped, stored,
+ // and serialized directly in the module in a section right after all
+ // EntryPoint instructions. Visit them from there.
+ }
+
+ bool DeserializeInternal(InputWordStream &IS) override;
+
+ EntryPointDefinition *addToInterface(VariableInst *var);
+ EntryPointDefinition *addExecutionMode(ExecutionModeInst *mode) {
+ mExecutionModeInsts.push_back(mode);
+ return this;
+ }
+ const std::vector<ExecutionModeInst *> &getExecutionModes() const {
+ return mExecutionModeInsts;
+ }
+
+ EntryPointDefinition *setLocalSize(uint32_t width, uint32_t height,
+ uint32_t depth);
+
+ EntryPointDefinition *applyExecutionMode(ExecutionModeInst *mode);
+
+ EntryPointInst *getInstruction() const { return mEntryPointInst; }
+
+private:
+ const char *mName;
+ FunctionInst *mFunction;
+ ExecutionModel mExecutionModel;
+ std::vector<VariableInst *> mInterface;
+ Extent3D mLocalSize;
+
+ EntryPointInst *mEntryPointInst;
+ std::vector<ExecutionModeInst *> mExecutionModeInsts;
+};
+
+class DebugInfoSection : public Entity {
+public:
+ DebugInfoSection() : mSourcesDeleter(mSources), mNamesDeleter(mNames) {}
+ DebugInfoSection(Builder *b)
+ : Entity(b), mSourcesDeleter(mSources), mNamesDeleter(mNames) {}
+
+ virtual ~DebugInfoSection() {}
+
+ bool DeserializeInternal(InputWordStream &IS) override;
+
+ DebugInfoSection *addSource(SourceLanguage lang, int version);
+ DebugInfoSection *addSourceExtension(const char *ext);
+ DebugInfoSection *addString(const char *str);
+
+ std::string findStringOfPrefix(const char *prefix);
+
+ Instruction *lookupByName(const char *name) const;
+ const char *lookupNameByInstruction(const Instruction *) const;
+
+ void accept(IVisitor *v) override {
+ for (auto source : mSources) {
+ v->visit(source);
+ }
+ for (auto name : mNames) {
+ v->visit(name);
+ }
+ }
+
+private:
+ // (OpString|OpSource|OpSourceExtension|OpSourceContinued)*
+ std::vector<Instruction *> mSources;
+ // (OpName|OpMemberName)*
+ std::vector<Instruction *> mNames;
+
+ ContainerDeleter<std::vector<Instruction *>> mSourcesDeleter;
+ ContainerDeleter<std::vector<Instruction *>> mNamesDeleter;
+};
+
+class AnnotationSection : public Entity {
+public:
+ AnnotationSection();
+ AnnotationSection(Builder *b);
+
+ virtual ~AnnotationSection() {}
+
+ bool DeserializeInternal(InputWordStream &IS) override;
+
+ void accept(IVisitor *v) override {
+ for (auto inst : mAnnotations) {
+ v->visit(inst);
+ }
+ }
+
+ template <typename T> void addAnnotations(T begin, T end) {
+ mAnnotations.insert<T>(std::end(mAnnotations), begin, end);
+ }
+
+ std::vector<Instruction *>::const_iterator begin() const {
+ return mAnnotations.begin();
+ }
+
+ std::vector<Instruction *>::const_iterator end() const {
+ return mAnnotations.end();
+ }
+
+ void clear() { mAnnotations.clear(); }
+
+private:
+ std::vector<Instruction *> mAnnotations; // OpDecorate, etc.
+
+ ContainerDeleter<std::vector<Instruction *>> mAnnotationsDeleter;
+};
+
+// Types, constants, and globals
+class GlobalSection : public Entity {
+public:
+ GlobalSection();
+ GlobalSection(Builder *builder);
+
+ virtual ~GlobalSection() {}
+
+ bool DeserializeInternal(InputWordStream &IS) override;
+
+ void accept(IVisitor *v) override {
+ for (auto inst : mGlobalDefs) {
+ v->visit(inst);
+ }
+
+ if (mInvocationId) {
+ v->visit(mInvocationId.get());
+ }
+
+ if (mNumWorkgroups) {
+ v->visit(mNumWorkgroups.get());
+ }
+ }
+
+ ConstantInst *getConstant(TypeIntInst *type, int32_t value);
+ ConstantInst *getConstant(TypeIntInst *type, uint32_t value);
+ ConstantInst *getConstant(TypeFloatInst *type, float value);
+ ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
+ ConstantInst *components[],
+ size_t width);
+
+ // Methods to look up types. Create them if not found.
+ TypeVoidInst *getVoidType();
+ TypeIntInst *getIntType(int bits, bool isSigned = true);
+ TypeFloatInst *getFloatType(int bits);
+ TypeVectorInst *getVectorType(Instruction *componentType, int width);
+ TypePointerInst *getPointerType(StorageClass storage,
+ Instruction *pointeeType);
+ TypeRuntimeArrayInst *getRuntimeArrayType(Instruction *elementType);
+
+ // This implies that struct types are strictly structural equivalent, i.e.,
+ // two structs are equivalent i.f.f. their fields are equivalent, recursively.
+ TypeStructInst *getStructType(Instruction *fieldType[], int numField);
+ // TypeStructInst *getStructType(const std::vector<Instruction *>
+ // &fieldTypes);
+
+ // TODO: Can function types of different decorations be considered the same?
+ TypeFunctionInst *getFunctionType(Instruction *retType,
+ Instruction *const argType[],
+ size_t numArg);
+ // TypeStructInst *addStructType(Instruction *fieldType[], int numField);
+ GlobalSection *addStructType(TypeStructInst *structType);
+ GlobalSection *addVariable(VariableInst *var);
+
+ VariableInst *getInvocationId();
+ VariableInst *getNumWorkgroups();
+
+private:
+ // TODO: Add structure to this.
+ // Separate types, constants, variables, etc.
+ std::vector<Instruction *> mGlobalDefs;
+ std::unique_ptr<VariableInst> mInvocationId;
+ std::unique_ptr<VariableInst> mNumWorkgroups;
+
+ ContainerDeleter<std::vector<Instruction *>> mGlobalDefsDeleter;
+};
+
+class FunctionDeclaration : public Entity {
+public:
+ virtual ~FunctionDeclaration() {}
+
+ bool DeserializeInternal(InputWordStream &IS) override;
+
+ void accept(IVisitor *v) override {
+ v->visit(mFunc);
+ for (auto param : mParams) {
+ v->visit(param);
+ }
+ v->visit(mFuncEnd);
+ }
+
+private:
+ FunctionInst *mFunc;
+ std::vector<FunctionParameterInst *> mParams;
+ FunctionEndInst *mFuncEnd;
+};
+
+class Block : public Entity {
+public:
+ Block() {}
+ Block(Builder *b) : Entity(b) {}
+
+ virtual ~Block() {}
+
+ bool DeserializeInternal(InputWordStream &IS) override;
+
+ void accept(IVisitor *v) override {
+ for (auto inst : mInsts) {
+ v->visit(inst);
+ }
+ }
+
+ Block *addInstruction(Instruction *inst) {
+ mInsts.push_back(inst);
+ return this;
+ }
+
+private:
+ std::vector<Instruction *> mInsts;
+};
+
+class FunctionDefinition : public Entity {
+public:
+ FunctionDefinition();
+ FunctionDefinition(Builder *builder, FunctionInst *func,
+ FunctionEndInst *end);
+
+ virtual ~FunctionDefinition() {}
+
+ bool DeserializeInternal(InputWordStream &IS) override;
+
+ void accept(IVisitor *v) override {
+ v->visit(mFunc.get());
+ for (auto param : mParams) {
+ v->visit(param);
+ }
+ for (auto block : mBlocks) {
+ v->visit(block);
+ }
+ v->visit(mFuncEnd.get());
+ }
+
+ FunctionDefinition *addBlock(Block *b) {
+ mBlocks.push_back(b);
+ return this;
+ }
+
+ FunctionInst *getInstruction() const { return mFunc.get(); }
+ FunctionParameterInst *getParameter(uint32_t i) const { return mParams[i]; }
+
+ Instruction *getReturnType() const;
+
+private:
+ std::unique_ptr<FunctionInst> mFunc;
+ std::vector<FunctionParameterInst *> mParams;
+ std::vector<Block *> mBlocks;
+ std::unique_ptr<FunctionEndInst> mFuncEnd;
+
+ ContainerDeleter<std::vector<FunctionParameterInst *>> mParamsDeleter;
+ ContainerDeleter<std::vector<Block *>> mBlocksDeleter;
+};
+
+} // namespace spirit
+} // namespace android
+
+#endif // MODULE_H
diff --git a/rsov/compiler/spirit/module_test.cpp b/rsov/compiler/spirit/module_test.cpp
new file mode 100644
index 0000000..17d3134
--- /dev/null
+++ b/rsov/compiler/spirit/module_test.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "module.h"
+
+#include "file_utils.h"
+#include "instructions.h"
+#include "test_utils.h"
+#include "gtest/gtest.h"
+
+#include <fstream>
+#include <memory>
+
+namespace android {
+namespace spirit {
+
+class ModuleTest : public ::testing::Test {
+protected:
+ virtual void SetUp() {
+ mWordsGlobal = readWords("global.spv");
+ mWordsGreyscale = readWords("greyscale.spv");
+ mWordsGreyscale2 = readWords("greyscale2.spv");
+ mWordsInvert = readWords("invert.spv");
+ }
+
+ std::vector<uint32_t> mWordsGlobal;
+ std::vector<uint32_t> mWordsGreyscale;
+ std::vector<uint32_t> mWordsGreyscale2;
+ std::vector<uint32_t> mWordsInvert;
+
+private:
+ std::vector<uint32_t> readWords(const char *testFile) {
+ static const std::string testDataPath(
+ "frameworks/rs/rsov/compiler/spirit/test_data/");
+ const std::string &fullPath = getAbsolutePath(testDataPath + testFile);
+ return readFile<uint32_t>(fullPath);
+ }
+};
+
+TEST_F(ModuleTest, testDeserialization1) {
+ auto m = Deserialize<Module>(mWordsGreyscale);
+
+ ASSERT_NE(nullptr, m);
+
+ std::unique_ptr<Module> mDeleter(m);
+
+ int count = 0;
+ std::unique_ptr<IVisitor> v(
+ CreateInstructionVisitor([&count](Instruction *) -> void { count++; }));
+ v->visit(m);
+
+ ASSERT_EQ(count, 123);
+
+ // TODO:: checkCountEntity<Instruction>() does not work correctly
+ // EXPECT_TRUE(checkCountEntity<Instruction>(m, 123));
+ EXPECT_EQ(5, countEntity<AccessChainInst>(m));
+ EXPECT_EQ(2, countEntity<BitcastInst>(m));
+ EXPECT_EQ(1, countEntity<CapabilityInst>(m));
+ EXPECT_EQ(1, countEntity<CompositeConstructInst>(m));
+ EXPECT_EQ(5, countEntity<ConstantInst>(m));
+ EXPECT_EQ(1, countEntity<ConstantCompositeInst>(m));
+ EXPECT_EQ(11, countEntity<DecorateInst>(m));
+ EXPECT_EQ(1, countEntity<DotInst>(m));
+ EXPECT_EQ(1, countEntity<EntryPointInst>(m));
+ EXPECT_EQ(1, countEntity<ExecutionModeInst>(m));
+ EXPECT_EQ(1, countEntity<ExtInstImportInst>(m));
+ EXPECT_EQ(2, countEntity<FunctionInst>(m));
+ EXPECT_EQ(1, countEntity<FunctionCallInst>(m));
+ EXPECT_EQ(2, countEntity<FunctionEndInst>(m));
+ EXPECT_EQ(1, countEntity<FunctionParameterInst>(m));
+ EXPECT_EQ(1, countEntity<IAddInst>(m));
+ EXPECT_EQ(1, countEntity<IMulInst>(m));
+ EXPECT_EQ(1, countEntity<ImageInst>(m));
+ EXPECT_EQ(1, countEntity<ImageFetchInst>(m));
+ EXPECT_EQ(2, countEntity<LabelInst>(m));
+ EXPECT_EQ(11, countEntity<LoadInst>(m));
+ EXPECT_EQ(4, countEntity<MemberDecorateInst>(m));
+ EXPECT_EQ(4, countEntity<MemberNameInst>(m));
+ EXPECT_EQ(1, countEntity<MemoryModelInst>(m));
+ EXPECT_EQ(14, countEntity<NameInst>(m));
+ EXPECT_EQ(1, countEntity<ReturnInst>(m));
+ EXPECT_EQ(1, countEntity<ReturnValueInst>(m));
+ EXPECT_EQ(1, countEntity<SourceInst>(m));
+ EXPECT_EQ(3, countEntity<SourceExtensionInst>(m));
+ EXPECT_EQ(6, countEntity<StoreInst>(m));
+ EXPECT_EQ(1, countEntity<TypeFloatInst>(m));
+ EXPECT_EQ(2, countEntity<TypeFunctionInst>(m));
+ EXPECT_EQ(1, countEntity<TypeImageInst>(m));
+ EXPECT_EQ(2, countEntity<TypeIntInst>(m));
+ EXPECT_EQ(10, countEntity<TypePointerInst>(m));
+ EXPECT_EQ(1, countEntity<TypeRuntimeArrayInst>(m));
+ EXPECT_EQ(1, countEntity<TypeSampledImageInst>(m));
+ EXPECT_EQ(2, countEntity<TypeStructInst>(m));
+ EXPECT_EQ(4, countEntity<TypeVectorInst>(m));
+ EXPECT_EQ(1, countEntity<TypeVoidInst>(m));
+ EXPECT_EQ(9, countEntity<VariableInst>(m));
+ EXPECT_EQ(1, countEntity<VectorShuffleInst>(m));
+ EXPECT_EQ(1, countEntity<EntryPointDefinition>(m));
+ EXPECT_EQ(1, countEntity<DebugInfoSection>(m));
+ EXPECT_EQ(1, countEntity<GlobalSection>(m));
+ EXPECT_EQ(2, countEntity<FunctionDefinition>(m));
+}
+
+TEST_F(ModuleTest, testDeserialization2) {
+ Module *m = Deserialize<Module>(mWordsInvert);
+ ASSERT_NE(nullptr, m);
+
+ std::unique_ptr<Module> mDeleter(m);
+
+ auto outwords = Serialize<Module>(m);
+
+ EXPECT_TRUE(mWordsInvert == outwords);
+}
+
+TEST_F(ModuleTest, testSerialization1) {
+ Module *m = Deserialize<Module>(mWordsGreyscale);
+ ASSERT_NE(nullptr, m);
+
+ std::unique_ptr<Module> mDeleter(m);
+
+ EXPECT_EQ(2, countEntity<FunctionDefinition>(m));
+
+ auto outwords = Serialize<Module>(m);
+
+ EXPECT_TRUE(mWordsGreyscale == outwords);
+}
+
+TEST_F(ModuleTest, testSerialization2) {
+ Module *m = Deserialize<Module>(mWordsGreyscale2);
+ ASSERT_NE(nullptr, m);
+
+ std::unique_ptr<Module> mDeleter(m);
+
+ EXPECT_EQ(1, countEntity<FunctionDefinition>(m));
+
+ auto outwords = Serialize<Module>(m);
+
+ EXPECT_TRUE(mWordsGreyscale2 == outwords);
+}
+
+TEST_F(ModuleTest, testLookupByName) {
+ Module *m = Deserialize<Module>(mWordsGreyscale);
+
+ ASSERT_NE(nullptr, m);
+
+ std::unique_ptr<Module> mDeleter(m);
+
+ m->resolveIds();
+
+ Instruction *mainFunc = m->lookupByName("main");
+
+ EXPECT_NE(nullptr, mainFunc);
+ EXPECT_STREQ("main", m->lookupNameByInstruction(mainFunc));
+
+ auto i = static_cast<FunctionInst *>(m->lookupByName("greyscale(vf4;"));
+ ASSERT_NE(nullptr, i);
+
+ auto kernel = m->getFunctionDefinitionFromInstruction(i);
+ ASSERT_NE(nullptr, kernel);
+
+ EXPECT_NE(nullptr, kernel->getParameter(0));
+ EXPECT_NE(nullptr, kernel->getReturnType());
+
+ EXPECT_NE(nullptr, m->lookupFunctionDefinitionByName("greyscale(vf4;"));
+}
+
+TEST_F(ModuleTest, testGetSize) {
+ std::unique_ptr<Module> m(new Module());
+ EXPECT_EQ(4UL, m->getSize(m->getIntType(32)));
+ EXPECT_EQ(4UL, m->getSize(m->getIntType(32, 0)));
+ EXPECT_EQ(4UL, m->getSize(m->getFloatType(32)));
+ EXPECT_EQ(16UL, m->getSize(m->getVectorType(m->getFloatType(32), 4)));
+}
+
+TEST_F(ModuleTest, testFindStringOfPrefix) {
+ Module *m = Deserialize<Module>(mWordsGlobal);
+
+ ASSERT_NE(nullptr, m);
+
+ std::unique_ptr<Module> mDeleter(m);
+ ASSERT_STREQ(".rsov.ExportedVars:0;",
+ m->findStringOfPrefix(".rsov.ExportedVars:").c_str());
+
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/pass.cpp b/rsov/compiler/spirit/pass.cpp
new file mode 100644
index 0000000..d8c3afe
--- /dev/null
+++ b/rsov/compiler/spirit/pass.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "pass.h"
+
+#include "module.h"
+
+namespace android {
+namespace spirit {
+
+Module *Pass::run(Module *module, int *error) {
+ int intermediateError;
+ auto words = runAndSerialize(module, &intermediateError);
+ if (intermediateError) {
+ if (error) {
+ *error = intermediateError;
+ }
+ return nullptr;
+ }
+ return Deserialize<Module>(words);
+}
+
+std::vector<uint32_t> Pass::runAndSerialize(Module *module, int *error) {
+ int intermediateError;
+ auto m1 = run(module, &intermediateError);
+ if (intermediateError) {
+ if (error) {
+ *error = intermediateError;
+ }
+ return std::vector<uint32_t>();
+ }
+ return Serialize<Module>(m1);
+}
+
+} // namespace spirit
+} // namespace android
+
diff --git a/rsov/compiler/spirit/pass.h b/rsov/compiler/spirit/pass.h
new file mode 100644
index 0000000..1d493a1
--- /dev/null
+++ b/rsov/compiler/spirit/pass.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef RSOV_COMPILER_SPIRIT_PASS_H
+#define RSOV_COMPILER_SPIRIT_PASS_H
+
+#include <stdint.h>
+
+#include <vector>
+
+namespace android {
+namespace spirit {
+
+class Module;
+
+// The base class for a pass, either an analysis or a transformation of a
+// Module. An instanace of a derived class can be added to a PassQueue and
+// applied to a Module, and produce a result Module with other passes.
+class Pass {
+public:
+ virtual ~Pass() {}
+
+ // Runs the pass on the input module and returns the result module.
+ // If argument error is not null, set the error code. On a successful run,
+ // error code is set to zero.
+ virtual Module *run(Module *module, int *error);
+
+ // Runs the pass on the input module, serializes the result module, and
+ // returns the words as a vector.
+ // If argument error is not null, set the error code. On a successful run,
+ // error code is set to zero.
+ virtual std::vector<uint32_t> runAndSerialize(Module *module, int *error);
+};
+
+} // namespace spirit
+} // namespace android
+
+#endif // RSOV_COMPILER_SPIRIT_PASS_H
diff --git a/rsov/compiler/spirit/pass_queue.cpp b/rsov/compiler/spirit/pass_queue.cpp
new file mode 100644
index 0000000..1bbdd2c
--- /dev/null
+++ b/rsov/compiler/spirit/pass_queue.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "pass_queue.h"
+
+#include "module.h"
+
+namespace android {
+namespace spirit {
+
+bool PassQueue::append(Pass *pass) {
+ mPasses.push_back(pass);
+ mPassSet.insert(pass);
+ return true;
+}
+
+Module *PassQueue::run(Module *module, int *error) {
+ if (mPasses.empty()) {
+ return module;
+ }
+
+ // A unique ptr to keep intermediate modules from leaking
+ std::unique_ptr<Module> tempModule;
+
+ for (auto pass : mPasses) {
+ int intermediateError = 0;
+ Module* newModule = pass->run(module, &intermediateError);
+ // Some passes modify the input module in place, while others create a new
+ // module. Release memory only when it is necessary.
+ if (newModule != module) {
+ tempModule.reset(newModule);
+ }
+ module = newModule;
+ if (intermediateError) {
+ if (error) {
+ *error = intermediateError;
+ }
+ return nullptr;
+ }
+ if (!module || !module->resolveIds()) {
+ if (error) {
+ *error = -1;
+ }
+ return nullptr;
+ }
+ }
+
+ if (tempModule == nullptr) {
+ return module;
+ }
+
+ return tempModule.release();
+}
+
+std::vector<uint32_t> PassQueue::run(const std::vector<uint32_t> &spirvWords,
+ int *error) {
+ if (mPasses.empty()) {
+ return spirvWords;
+ }
+
+ Module *module = Deserialize<Module>(spirvWords);
+ if (!module || !module->resolveIds()) {
+ return std::vector<uint32_t>();
+ }
+
+ return runAndSerialize(module, error);
+}
+
+std::vector<uint32_t> PassQueue::runAndSerialize(Module *module, int *error) {
+ const int n = mPasses.size();
+ if (n < 1) {
+ return Serialize<Module>(module);
+ }
+
+ // A unique ptr to keep intermediate modules from leaking
+ std::unique_ptr<Module> tempModule;
+
+ for (int i = 0; i < n - 1; i++) {
+ int intermediateError = 0;
+ Module *newModule = mPasses[i]->run(module, &intermediateError);
+ // Some passes modify the input module in place, while others create a new
+ // module. Release memory only when it is necessary.
+ if (newModule != module) {
+ tempModule.reset(newModule);
+ }
+ module = newModule;
+ if (intermediateError) {
+ if (error) {
+ *error = intermediateError;
+ }
+ return std::vector<uint32_t>();
+ }
+ if (!module || !module->resolveIds()) {
+ if (error) {
+ *error = -1;
+ }
+ return std::vector<uint32_t>();
+ }
+ }
+ return mPasses[n - 1]->runAndSerialize(module, error);
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/pass_queue.h b/rsov/compiler/spirit/pass_queue.h
new file mode 100644
index 0000000..f00dcf7
--- /dev/null
+++ b/rsov/compiler/spirit/pass_queue.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef RSOV_COMPILER_SPIRIT_PASS_QUEUE_H
+#define RSOV_COMPILER_SPIRIT_PASS_QUEUE_H
+
+#include "module.h"
+#include "pass.h"
+#include "stl_util.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <set>
+#include <vector>
+
+namespace android {
+namespace spirit {
+
+// A FIFO of passes. Passes are appended to the end of the FIFO and run in the
+// first-in first-out order. Once appended to a pass queue, Passes are owned by
+// the queue.
+class PassQueue {
+public:
+ PassQueue() : mPassesDeleter(mPassSet) {}
+
+ // Appends a pass to the end of the queue
+ bool append(Pass *pass);
+
+ // Runs all passes in the queue in the first-in first-out order on a Module.
+ // Returns the result Module after all passes have run.
+ // If argument error is not null, sets the error code. On a successful run,
+ // error code is set to zero.
+ Module *run(Module *module, int *error = nullptr);
+
+ // Deserialize the input vector of words into a Module, and runs all passes in
+ // the queue in the first-in first-out order on the Module.
+ // for a serialized Module.
+ // After all the passes have run, returns the words from the serialized result
+ // Module.
+ // If argument error is not null, sets the error code. On a successful run,
+ // error code is set to zero.
+ std::vector<uint32_t> run(const std::vector<uint32_t> &spirvWords,
+ int *error = nullptr);
+
+ // Runs all passes in the queue in the first-in first-out order on a Module.
+ // After all the passes have run, serializes the result Module, and returns
+ // the words as a vector.
+ // If argument error is not null, sets the error code. On a successful run,
+ // error code is set to zero.
+ std::vector<uint32_t> runAndSerialize(Module *module, int *error = nullptr);
+
+private:
+ std::vector<Pass *> mPasses;
+ // Keep all passes in a set so that we can delete them on destruction without
+ // worrying about duplicates
+ std::set<Pass *> mPassSet;
+ ContainerDeleter<std::set<Pass *>> mPassesDeleter;
+};
+
+} // spirit
+} // android
+
+#endif // RSOV_COMPILER_SPIRIT_PASS_QUEUE_H
diff --git a/rsov/compiler/spirit/pass_queue_test.cpp b/rsov/compiler/spirit/pass_queue_test.cpp
new file mode 100644
index 0000000..23e18e2
--- /dev/null
+++ b/rsov/compiler/spirit/pass_queue_test.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "pass_queue.h"
+
+#include "file_utils.h"
+#include "spirit.h"
+#include "test_utils.h"
+#include "transformer.h"
+#include "gtest/gtest.h"
+
+#include <stdint.h>
+
+namespace android {
+namespace spirit {
+
+namespace {
+
+class MulToAddTransformer : public Transformer {
+public:
+ Instruction *transform(IMulInst *mul) override {
+ auto ret = new IAddInst(mul->mResultType, mul->mOperand1, mul->mOperand2);
+ ret->setId(mul->getId());
+ return ret;
+ }
+};
+
+class AddToDivTransformer : public Transformer {
+public:
+ Instruction *transform(IAddInst *add) override {
+ auto ret = new SDivInst(add->mResultType, add->mOperand1, add->mOperand2);
+ ret->setId(add->getId());
+ return ret;
+ }
+};
+
+class AddMulAfterAddTransformer : public Transformer {
+public:
+ Instruction *transform(IAddInst *add) override {
+ insert(add);
+ auto ret = new IMulInst(add->mResultType, add, add);
+ ret->setId(add->getId());
+ return ret;
+ }
+};
+
+class Deleter : public Transformer {
+public:
+ Instruction *transform(IMulInst *) override { return nullptr; }
+};
+
+class InPlaceModifyingPass : public Pass {
+public:
+ Module *run(Module *m, int *error) override {
+ m->getFloatType(64);
+ if (error) {
+ *error = 0;
+ }
+ return m;
+ }
+};
+
+} // annonymous namespace
+
+class PassQueueTest : public ::testing::Test {
+protected:
+ virtual void SetUp() { mWordsGreyscale = readWords("greyscale.spv"); }
+
+ std::vector<uint32_t> mWordsGreyscale;
+
+private:
+ std::vector<uint32_t> readWords(const char *testFile) {
+ static const std::string testDataPath(
+ "frameworks/rs/rsov/compiler/spirit/test_data/");
+ const std::string &fullPath = getAbsolutePath(testDataPath + testFile);
+ return readFile<uint32_t>(fullPath);
+ }
+};
+
+TEST_F(PassQueueTest, testMulToAdd) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m);
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+
+ PassQueue passes;
+ passes.append(new MulToAddTransformer());
+ auto m1 = passes.run(m.get());
+
+ ASSERT_NE(nullptr, m1);
+
+ ASSERT_TRUE(m1->resolveIds());
+
+ EXPECT_EQ(2, countEntity<IAddInst>(m1));
+ EXPECT_EQ(0, countEntity<IMulInst>(m1));
+}
+
+TEST_F(PassQueueTest, testInPlaceModifying) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m);
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+ EXPECT_EQ(1, countEntity<TypeFloatInst>(m.get()));
+
+ PassQueue passes;
+ passes.append(new InPlaceModifyingPass());
+ auto m1 = passes.run(m.get());
+
+ ASSERT_NE(nullptr, m1);
+
+ ASSERT_TRUE(m1->resolveIds());
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m1));
+ EXPECT_EQ(1, countEntity<IMulInst>(m1));
+ EXPECT_EQ(2, countEntity<TypeFloatInst>(m1));
+}
+
+TEST_F(PassQueueTest, testDeletion) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m.get());
+
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+
+ PassQueue passes;
+ passes.append(new Deleter());
+ auto m1 = passes.run(m.get());
+
+ // One of the ids from the input module is missing now.
+ ASSERT_EQ(nullptr, m1);
+}
+
+TEST_F(PassQueueTest, testMulToAddToDiv) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m);
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+
+ PassQueue passes;
+ passes.append(new MulToAddTransformer());
+ passes.append(new AddToDivTransformer());
+ auto m1 = passes.run(m.get());
+
+ ASSERT_NE(nullptr, m1);
+
+ ASSERT_TRUE(m1->resolveIds());
+
+ EXPECT_EQ(0, countEntity<IAddInst>(m1));
+ EXPECT_EQ(0, countEntity<IMulInst>(m1));
+ EXPECT_EQ(2, countEntity<SDivInst>(m1));
+}
+
+TEST_F(PassQueueTest, testAMix) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m);
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+ EXPECT_EQ(0, countEntity<SDivInst>(m.get()));
+ EXPECT_EQ(1, countEntity<TypeFloatInst>(m.get()));
+
+ PassQueue passes;
+ passes.append(new MulToAddTransformer());
+ passes.append(new AddToDivTransformer());
+ passes.append(new InPlaceModifyingPass());
+
+ std::unique_ptr<Module> m1(passes.run(m.get()));
+
+ ASSERT_NE(nullptr, m1);
+
+ ASSERT_TRUE(m1->resolveIds());
+
+ EXPECT_EQ(0, countEntity<IAddInst>(m1.get()));
+ EXPECT_EQ(0, countEntity<IMulInst>(m1.get()));
+ EXPECT_EQ(2, countEntity<SDivInst>(m1.get()));
+ EXPECT_EQ(2, countEntity<TypeFloatInst>(m1.get()));
+}
+
+TEST_F(PassQueueTest, testAnotherMix) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m);
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+ EXPECT_EQ(0, countEntity<SDivInst>(m.get()));
+ EXPECT_EQ(1, countEntity<TypeFloatInst>(m.get()));
+
+ PassQueue passes;
+ passes.append(new InPlaceModifyingPass());
+ passes.append(new MulToAddTransformer());
+ passes.append(new AddToDivTransformer());
+ auto outputWords = passes.runAndSerialize(m.get());
+
+ std::unique_ptr<Module> m1(Deserialize<Module>(outputWords));
+
+ ASSERT_NE(nullptr, m1);
+
+ ASSERT_TRUE(m1->resolveIds());
+
+ EXPECT_EQ(0, countEntity<IAddInst>(m1.get()));
+ EXPECT_EQ(0, countEntity<IMulInst>(m1.get()));
+ EXPECT_EQ(2, countEntity<SDivInst>(m1.get()));
+ EXPECT_EQ(2, countEntity<TypeFloatInst>(m1.get()));
+}
+
+TEST_F(PassQueueTest, testMulToAddToDivFromWords) {
+ PassQueue passes;
+ passes.append(new MulToAddTransformer());
+ passes.append(new AddToDivTransformer());
+ auto outputWords = passes.run(std::move(mWordsGreyscale));
+
+ std::unique_ptr<Module> m1(Deserialize<Module>(outputWords));
+
+ ASSERT_NE(nullptr, m1);
+
+ ASSERT_TRUE(m1->resolveIds());
+
+ EXPECT_EQ(0, countEntity<IAddInst>(m1.get()));
+ EXPECT_EQ(0, countEntity<IMulInst>(m1.get()));
+ EXPECT_EQ(2, countEntity<SDivInst>(m1.get()));
+}
+
+TEST_F(PassQueueTest, testMulToAddToDivToWords) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m);
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+
+ PassQueue passes;
+ passes.append(new MulToAddTransformer());
+ passes.append(new AddToDivTransformer());
+ auto outputWords = passes.runAndSerialize(m.get());
+
+ std::unique_ptr<Module> m1(Deserialize<Module>(outputWords));
+
+ ASSERT_NE(nullptr, m1);
+
+ ASSERT_TRUE(m1->resolveIds());
+
+ EXPECT_EQ(0, countEntity<IAddInst>(m1.get()));
+ EXPECT_EQ(0, countEntity<IMulInst>(m1.get()));
+ EXPECT_EQ(2, countEntity<SDivInst>(m1.get()));
+}
+
+TEST_F(PassQueueTest, testAddMulAfterAdd) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m);
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+
+ constexpr int kNumMulToAdd = 100;
+
+ PassQueue passes;
+ for (int i = 0; i < kNumMulToAdd; i++) {
+ passes.append(new AddMulAfterAddTransformer());
+ }
+ auto outputWords = passes.runAndSerialize(m.get());
+
+ std::unique_ptr<Module> m1(Deserialize<Module>(outputWords));
+
+ ASSERT_NE(nullptr, m1);
+
+ ASSERT_TRUE(m1->resolveIds());
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m1.get()));
+ EXPECT_EQ(1 + kNumMulToAdd, countEntity<IMulInst>(m1.get()));
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript b/rsov/compiler/spirit/spirit.h
similarity index 66%
copy from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
copy to rsov/compiler/spirit/spirit.h
index b828ae0..7f631b1 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
+++ b/rsov/compiler/spirit/spirit.h
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright 2017, 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
+ * 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,
@@ -14,5 +14,12 @@
* limitations under the License.
*/
-#include "clamp.rscript"
-#pragma rs_fp_relaxed
+#ifndef SPIRIT_H
+#define SPIRIT_H
+
+#include "builder.h"
+#include "instructions.h"
+#include "module.h"
+#include "word_stream.h"
+
+#endif // SPIRIT_H
diff --git a/rsov/compiler/spirit/stl_util.h b/rsov/compiler/spirit/stl_util.h
new file mode 100644
index 0000000..0e59d05
--- /dev/null
+++ b/rsov/compiler/spirit/stl_util.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef STL_UTIL_H
+#define STL_UTIL_H
+
+namespace android {
+namespace spirit {
+
+template <class T> class ContainerDeleter {
+public:
+ ContainerDeleter(T &container) : mContainer(container) {}
+ ~ContainerDeleter() {
+ for (auto *ptr : mContainer) {
+ delete ptr;
+ }
+ }
+
+private:
+ T &mContainer;
+};
+
+} // namespace spirit
+} // namespace android
+
+#endif // STL_UTIL_H
diff --git a/rsov/compiler/spirit/test_data/greyscale.spt b/rsov/compiler/spirit/test_data/greyscale.spt
new file mode 100644
index 0000000..3cfde69
--- /dev/null
+++ b/rsov/compiler/spirit/test_data/greyscale.spt
@@ -0,0 +1,128 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 1
+; Bound: 75
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
+ OpExecutionMode %main LocalSize 4 1 1
+ OpSource GLSL 450
+ OpSourceExtension "GL_ARB_shading_language_420pack"
+ OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
+ OpSourceExtension "GL_GOOGLE_include_directive"
+ OpName %main "main"
+ OpName %greyscale_vf4_ "greyscale(vf4;"
+ OpName %p "p"
+ OpName %globalBuffer "globalBuffer"
+ OpMemberName %globalBuffer 0 "coeff"
+ OpMemberName %globalBuffer 1 "width"
+ OpMemberName %globalBuffer 2 "height"
+ OpName %globalBlock "globalBlock"
+ OpName %xy "xy"
+ OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
+ OpName %inputPixel "inputPixel"
+ OpName %inputTexture "inputTexture"
+ OpName %res "res"
+ OpName %x "x"
+ OpName %y "y"
+ OpName %outputBufferS "outputBufferS"
+ OpMemberName %outputBufferS 0 "buf"
+ OpName %outputBuffer "outputBuffer"
+ OpMemberDecorate %globalBuffer 0 Offset 0
+ OpMemberDecorate %globalBuffer 1 Offset 16
+ OpMemberDecorate %globalBuffer 2 Offset 20
+ OpDecorate %globalBuffer BufferBlock
+ OpDecorate %globalBlock DescriptorSet 0
+ OpDecorate %globalBlock Binding 2
+ OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+ OpDecorate %inputTexture DescriptorSet 0
+ OpDecorate %inputTexture Binding 0
+ OpDecorate %_runtimearr_v4float ArrayStride 16
+ OpMemberDecorate %outputBufferS 0 Offset 0
+ OpDecorate %outputBufferS BufferBlock
+ OpDecorate %outputBuffer DescriptorSet 0
+ OpDecorate %outputBuffer Binding 1
+ OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %8 = OpTypeFunction %v4float %v4float
+ %int = OpTypeInt 32 1
+%globalBuffer = OpTypeStruct %v4float %int %int
+%_ptr_Uniform_globalBuffer = OpTypePointer Uniform %globalBuffer
+%globalBlock = OpVariable %_ptr_Uniform_globalBuffer Uniform
+ %16 = OpConstant %int 0
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+ %v2int = OpTypeVector %int 2
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+ %uint = OpTypeInt 32 0
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Input_v3uint = OpTypePointer Input %v3uint
+%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %37 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %38 = OpTypeSampledImage %37
+%_ptr_UniformConstant_38 = OpTypePointer UniformConstant %38
+%inputTexture = OpVariable %_ptr_UniformConstant_38 UniformConstant
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %50 = OpConstant %uint 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+ %55 = OpConstant %uint 1
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+%outputBufferS = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_outputBufferS = OpTypePointer Uniform %outputBufferS
+%outputBuffer = OpVariable %_ptr_Uniform_outputBufferS Uniform
+ %63 = OpConstant %int 1
+%_ptr_Uniform_int = OpTypePointer Uniform %int
+ %73 = OpConstant %uint 4
+%gl_WorkGroupSize = OpConstantComposite %v3uint %73 %55 %55
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %xy = OpVariable %_ptr_Function_v2int Function
+ %inputPixel = OpVariable %_ptr_Function_v4float Function
+ %res = OpVariable %_ptr_Function_v4float Function
+ %x = OpVariable %_ptr_Function_uint Function
+ %y = OpVariable %_ptr_Function_uint Function
+ %32 = OpLoad %v3uint %gl_GlobalInvocationID
+ %33 = OpVectorShuffle %v2uint %32 %32 0 1
+ %34 = OpBitcast %v2int %33
+ OpStore %xy %34
+ %41 = OpLoad %38 %inputTexture
+ %42 = OpLoad %v2int %xy
+ %43 = OpImage %37 %41
+ %44 = OpImageFetch %v4float %43 %42 Lod %16
+ OpStore %inputPixel %44
+ %46 = OpLoad %v4float %inputPixel
+ %47 = OpFunctionCall %v4float %greyscale_vf4_ %46
+ OpStore %res %47
+ %52 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %50
+ %53 = OpLoad %uint %52
+ OpStore %x %53
+ %56 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %55
+ %57 = OpLoad %uint %56
+ OpStore %y %57
+ %62 = OpLoad %uint %y
+ %65 = OpAccessChain %_ptr_Uniform_int %globalBlock %63
+ %66 = OpLoad %int %65
+ %67 = OpBitcast %uint %66
+ %68 = OpIMul %uint %62 %67
+ %69 = OpLoad %uint %x
+ %70 = OpIAdd %uint %68 %69
+ %71 = OpLoad %v4float %res
+ %72 = OpAccessChain %_ptr_Uniform_v4float %outputBuffer %16 %70
+ OpStore %72 %71
+ OpReturn
+ OpFunctionEnd
+%greyscale_vf4_ = OpFunction %v4float None %8
+ %p = OpFunctionParameter %v4float
+ %11 = OpLabel
+ %18 = OpAccessChain %_ptr_Uniform_v4float %globalBlock %16
+ %19 = OpLoad %v4float %18
+ %20 = OpDot %float %p %19
+ %21 = OpCompositeConstruct %v4float %20 %20 %20 %20
+ OpReturnValue %21
+ OpFunctionEnd
diff --git a/rsov/compiler/spirit/test_data/greyscale.spv b/rsov/compiler/spirit/test_data/greyscale.spv
new file mode 100644
index 0000000..97e39c1
--- /dev/null
+++ b/rsov/compiler/spirit/test_data/greyscale.spv
Binary files differ
diff --git a/rsov/compiler/spirit/test_data/greyscale2.spt b/rsov/compiler/spirit/test_data/greyscale2.spt
new file mode 100644
index 0000000..51dc530
--- /dev/null
+++ b/rsov/compiler/spirit/test_data/greyscale2.spt
@@ -0,0 +1,118 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 1
+; Bound: 67
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
+ OpExecutionMode %main LocalSize 2 1 1
+ OpSource GLSL 450
+ OpSourceExtension "GL_ARB_shading_language_420pack"
+ OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
+ OpSourceExtension "GL_GOOGLE_include_directive"
+ OpName %main "main"
+ OpName %xy "xy"
+ OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
+ OpName %inputPixel "inputPixel"
+ OpName %inputTexture "inputTexture"
+ OpName %res "res"
+ OpName %globalBuffer "globalBuffer"
+ OpMemberName %globalBuffer 0 "coeff"
+ OpMemberName %globalBuffer 1 "width"
+ OpMemberName %globalBuffer 2 "height"
+ OpName %globalBlock "globalBlock"
+ OpName %x "x"
+ OpName %y "y"
+ OpName %outputBufferS "outputBufferS"
+ OpMemberName %outputBufferS 0 "buf"
+ OpName %outputBuffer "outputBuffer"
+ OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+ OpDecorate %inputTexture DescriptorSet 0
+ OpDecorate %inputTexture Binding 0
+ OpMemberDecorate %globalBuffer 0 Offset 0
+ OpMemberDecorate %globalBuffer 1 Offset 16
+ OpMemberDecorate %globalBuffer 2 Offset 20
+ OpDecorate %globalBuffer BufferBlock
+ OpDecorate %globalBlock DescriptorSet 0
+ OpDecorate %globalBlock Binding 2
+ OpDecorate %_runtimearr_v4float ArrayStride 16
+ OpMemberDecorate %outputBufferS 0 Offset 0
+ OpDecorate %outputBufferS BufferBlock
+ OpDecorate %outputBuffer DescriptorSet 0
+ OpDecorate %outputBuffer Binding 1
+ OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %v2int = OpTypeVector %int 2
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+ %uint = OpTypeInt 32 0
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Input_v3uint = OpTypePointer Input %v3uint
+%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+ %v2uint = OpTypeVector %uint 2
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %22 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %23 = OpTypeSampledImage %22
+%_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23
+%inputTexture = OpVariable %_ptr_UniformConstant_23 UniformConstant
+ %28 = OpConstant %int 0
+%globalBuffer = OpTypeStruct %v4float %int %int
+%_ptr_Uniform_globalBuffer = OpTypePointer Uniform %globalBuffer
+%globalBlock = OpVariable %_ptr_Uniform_globalBuffer Uniform
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %42 = OpConstant %uint 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+ %47 = OpConstant %uint 1
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+%outputBufferS = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_outputBufferS = OpTypePointer Uniform %outputBufferS
+%outputBuffer = OpVariable %_ptr_Uniform_outputBufferS Uniform
+ %55 = OpConstant %int 1
+%_ptr_Uniform_int = OpTypePointer Uniform %int
+ %65 = OpConstant %uint 2
+%gl_WorkGroupSize = OpConstantComposite %v3uint %65 %47 %47
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %xy = OpVariable %_ptr_Function_v2int Function
+ %inputPixel = OpVariable %_ptr_Function_v4float Function
+ %res = OpVariable %_ptr_Function_v4float Function
+ %x = OpVariable %_ptr_Function_uint Function
+ %y = OpVariable %_ptr_Function_uint Function
+ %15 = OpLoad %v3uint %gl_GlobalInvocationID
+ %16 = OpVectorShuffle %v2uint %15 %15 0 1
+ %17 = OpBitcast %v2int %16
+ OpStore %xy %17
+ %26 = OpLoad %23 %inputTexture
+ %27 = OpLoad %v2int %xy
+ %29 = OpImageFetch %v4float %26 %27 Lod %28
+ OpStore %inputPixel %29
+ %31 = OpLoad %v4float %inputPixel
+ %36 = OpAccessChain %_ptr_Uniform_v4float %globalBlock %28
+ %37 = OpLoad %v4float %36
+ %38 = OpDot %float %31 %37
+ %39 = OpCompositeConstruct %v4float %38 %38 %38 %38
+ OpStore %res %39
+ %44 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %42
+ %45 = OpLoad %uint %44
+ OpStore %x %45
+ %48 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %47
+ %49 = OpLoad %uint %48
+ OpStore %y %49
+ %54 = OpLoad %uint %y
+ %57 = OpAccessChain %_ptr_Uniform_int %globalBlock %55
+ %58 = OpLoad %int %57
+ %59 = OpBitcast %uint %58
+ %60 = OpIMul %uint %54 %59
+ %61 = OpLoad %uint %x
+ %62 = OpIAdd %uint %60 %61
+ %63 = OpLoad %v4float %res
+ %64 = OpAccessChain %_ptr_Uniform_v4float %outputBuffer %28 %62
+ OpStore %64 %63
+ OpReturn
+ OpFunctionEnd
diff --git a/rsov/compiler/spirit/test_data/greyscale2.spv b/rsov/compiler/spirit/test_data/greyscale2.spv
new file mode 100644
index 0000000..088d96c
--- /dev/null
+++ b/rsov/compiler/spirit/test_data/greyscale2.spv
Binary files differ
diff --git a/rsov/compiler/spirit/test_data/greyscale3.spt b/rsov/compiler/spirit/test_data/greyscale3.spt
new file mode 100644
index 0000000..ef60d11
--- /dev/null
+++ b/rsov/compiler/spirit/test_data/greyscale3.spt
@@ -0,0 +1,115 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 1
+; Bound: 65
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
+ OpExecutionMode %main LocalSize 1 1 1
+ OpSource GLSL 450
+ OpSourceExtension "GL_ARB_shading_language_420pack"
+ OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
+ OpSourceExtension "GL_GOOGLE_include_directive"
+ OpName %main "main"
+ OpName %xy "xy"
+ OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
+ OpName %inputPixel "inputPixel"
+ OpName %inputTexture "inputTexture"
+ OpName %res "res"
+ OpName %globalBuffer "globalBuffer"
+ OpMemberName %globalBuffer 0 "coeff"
+ OpMemberName %globalBuffer 1 "width"
+ OpMemberName %globalBuffer 2 "height"
+ OpName %globalBlock "globalBlock"
+ OpName %x "x"
+ OpName %y "y"
+ OpName %outputBufferS "outputBufferS"
+ OpMemberName %outputBufferS 0 "buf"
+ OpName %outputBuffer "outputBuffer"
+ OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+ OpDecorate %inputTexture DescriptorSet 0
+ OpDecorate %inputTexture Binding 0
+ OpMemberDecorate %globalBuffer 0 Offset 0
+ OpMemberDecorate %globalBuffer 1 Offset 16
+ OpMemberDecorate %globalBuffer 2 Offset 20
+ OpDecorate %globalBuffer BufferBlock
+ OpDecorate %globalBlock DescriptorSet 0
+ OpDecorate %globalBlock Binding 2
+ OpDecorate %_runtimearr_v4float ArrayStride 16
+ OpMemberDecorate %outputBufferS 0 Offset 0
+ OpDecorate %outputBufferS BufferBlock
+ OpDecorate %outputBuffer DescriptorSet 0
+ OpDecorate %outputBuffer Binding 1
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %v2int = OpTypeVector %int 2
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+ %uint = OpTypeInt 32 0
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Input_v3uint = OpTypePointer Input %v3uint
+%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+ %v2uint = OpTypeVector %uint 2
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %22 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %23 = OpTypeSampledImage %22
+%_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23
+%inputTexture = OpVariable %_ptr_UniformConstant_23 UniformConstant
+ %28 = OpConstant %int 0
+%globalBuffer = OpTypeStruct %v4float %int %int
+%_ptr_Uniform_globalBuffer = OpTypePointer Uniform %globalBuffer
+%globalBlock = OpVariable %_ptr_Uniform_globalBuffer Uniform
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %42 = OpConstant %uint 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+ %47 = OpConstant %uint 1
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+%outputBufferS = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_outputBufferS = OpTypePointer Uniform %outputBufferS
+%outputBuffer = OpVariable %_ptr_Uniform_outputBufferS Uniform
+ %55 = OpConstant %int 1
+%_ptr_Uniform_int = OpTypePointer Uniform %int
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %xy = OpVariable %_ptr_Function_v2int Function
+ %inputPixel = OpVariable %_ptr_Function_v4float Function
+ %res = OpVariable %_ptr_Function_v4float Function
+ %x = OpVariable %_ptr_Function_uint Function
+ %y = OpVariable %_ptr_Function_uint Function
+ %15 = OpLoad %v3uint %gl_GlobalInvocationID
+ %16 = OpVectorShuffle %v2uint %15 %15 0 1
+ %17 = OpBitcast %v2int %16
+ OpStore %xy %17
+ %26 = OpLoad %23 %inputTexture
+ %27 = OpLoad %v2int %xy
+ %29 = OpImageFetch %v4float %26 %27 Lod %28
+ OpStore %inputPixel %29
+ %31 = OpLoad %v4float %inputPixel
+ %36 = OpAccessChain %_ptr_Uniform_v4float %globalBlock %28
+ %37 = OpLoad %v4float %36
+ %38 = OpDot %float %31 %37
+ %39 = OpCompositeConstruct %v4float %38 %38 %38 %38
+ OpStore %res %39
+ %44 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %42
+ %45 = OpLoad %uint %44
+ OpStore %x %45
+ %48 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %47
+ %49 = OpLoad %uint %48
+ OpStore %y %49
+ %54 = OpLoad %uint %y
+ %57 = OpAccessChain %_ptr_Uniform_int %globalBlock %55
+ %58 = OpLoad %int %57
+ %59 = OpBitcast %uint %58
+ %60 = OpIMul %uint %54 %59
+ %61 = OpLoad %uint %x
+ %62 = OpIAdd %uint %60 %61
+ %63 = OpLoad %v4float %res
+ %64 = OpAccessChain %_ptr_Uniform_v4float %outputBuffer %28 %62
+ OpStore %64 %63
+ OpReturn
+ OpFunctionEnd
diff --git a/rsov/compiler/spirit/test_data/greyscale3.spv b/rsov/compiler/spirit/test_data/greyscale3.spv
new file mode 100644
index 0000000..5f5cc8b
--- /dev/null
+++ b/rsov/compiler/spirit/test_data/greyscale3.spv
Binary files differ
diff --git a/rsov/compiler/spirit/test_data/invert.spv b/rsov/compiler/spirit/test_data/invert.spv
new file mode 100644
index 0000000..604c589
--- /dev/null
+++ b/rsov/compiler/spirit/test_data/invert.spv
Binary files differ
diff --git a/rsov/compiler/spirit/test_utils.h b/rsov/compiler/spirit/test_utils.h
new file mode 100644
index 0000000..c255e1b
--- /dev/null
+++ b/rsov/compiler/spirit/test_utils.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef TEST_UTILS_H
+#define TEST_UTILS_H
+
+#include "gtest/gtest.h"
+
+namespace android {
+namespace spirit {
+
+template <typename T> class EntityCounter : public DoNothingVisitor {
+public:
+ EntityCounter() : mCount(0) {}
+
+ void visit(T *) override { mCount++; }
+
+ int getCount() const { return mCount; }
+
+private:
+ int mCount;
+};
+
+template <typename T> int countEntity(Entity *e) {
+ EntityCounter<T> v;
+ e->accept(&v);
+ return v.getCount();
+}
+
+// Returns a caller owned string for the full path to the relative path inside
+// the Android source tree
+static inline std::string getAbsolutePath(const std::string &relativePath) {
+ std::string full(getenv("ANDROID_BUILD_TOP"));
+ return full.append("/").append(relativePath);
+}
+
+} // namespace spirit
+} // namespace android
+
+#endif // TEST_UTILS_H
diff --git a/rsov/compiler/spirit/transformer.cpp b/rsov/compiler/spirit/transformer.cpp
new file mode 100644
index 0000000..0eb9621
--- /dev/null
+++ b/rsov/compiler/spirit/transformer.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "transformer.h"
+
+#include "module.h"
+
+namespace android {
+namespace spirit {
+
+Module *Transformer::run(Module *module, int *error) {
+ auto words = runAndSerialize(module, error);
+ return Deserialize<Module>(words);
+}
+
+std::vector<uint32_t> Transformer::runAndSerialize(Module *m, int *error) {
+ mModule = m;
+
+ // Since contents in the decoration or global section may change, transform
+ // and serialize the function definitions first.
+ mVisit = 0;
+ mShouldRecord = false;
+ mStream = mStreamFunctions.get();
+ m->accept(this);
+
+ // Record in the annotation section any new annotations added
+ m->consolidateAnnotations();
+
+ // After the functions are transformed, serialize the other sections to
+ // capture any changes made during the function transformation, and append
+ // the new words from function serialization.
+
+ mVisit = 1;
+ mShouldRecord = true;
+ mStream = mStreamFinal.get();
+
+ // TODO fix Module::accept() to have the header serialization code there
+ m->SerializeHeader(*mStream);
+ m->accept(this);
+
+ auto output = mStream->getWords();
+ auto functions = mStreamFunctions->getWords();
+ output.insert(output.end(), functions.begin(), functions.end());
+
+ if (error) {
+ *error = 0;
+ }
+
+ return output;
+}
+
+void Transformer::insert(Instruction *inst) {
+ // TODO: warn on nullptr inst
+ inst->Serialize(*mStream);
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/transformer.h b/rsov/compiler/spirit/transformer.h
new file mode 100644
index 0000000..e2293f7
--- /dev/null
+++ b/rsov/compiler/spirit/transformer.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef TRANSFORMER_H
+#define TRANSFORMER_H
+
+#include <vector>
+
+#include "instructions.h"
+#include "pass.h"
+#include "visitor.h"
+#include "word_stream.h"
+
+namespace android {
+namespace spirit {
+
+// Transformer is the base class for a transformation that transforms a Module.
+// An instance of a derived class can be added to a PassQueue and applied to a
+// Module.
+class Transformer : public Pass, public DoNothingVisitor {
+public:
+ Transformer()
+ : mStreamFunctions(WordStream::Create()),
+ mStreamFinal(WordStream::Create()) {}
+
+ virtual ~Transformer() {}
+
+ Module *run(Module *m, int *error = nullptr) override;
+
+ std::vector<uint32_t> runAndSerialize(Module *module,
+ int *error = nullptr) override;
+
+ // Returns the module being transformed
+ Module *getModule() const { return mModule; }
+
+ // Inserts a new instruction before the current instruction.
+ // Call this from a transform() method in a derived class.
+ void insert(Instruction *);
+
+ void visit(FunctionDefinition *fdef) override {
+ mShouldRecord = (mVisit == 0);
+ DoNothingVisitor::visit(fdef);
+ }
+
+ // Transforms the current instruction into a new instruction as specified by
+ // the return value. If returns nullptr, deletes the current instruction.
+ // Override this in a derived class for desired behavior.
+#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) \
+ virtual Instruction *transform(INST_CLASS *inst) { \
+ return static_cast<Instruction *>(inst); \
+ } \
+ virtual void visit(INST_CLASS *inst) { \
+ if (!mShouldRecord) { \
+ return; \
+ } \
+ if (Instruction *transformed = transform(inst)) { \
+ transformed->Serialize(*mStream); \
+ } \
+ }
+#include "instruction_dispatches_generated.h"
+#undef HANDLE_INSTRUCTION
+
+private:
+ Module *mModule;
+ int mVisit;
+ bool mShouldRecord;
+ std::unique_ptr<WordStream> mStreamFunctions;
+ std::unique_ptr<WordStream> mStreamFinal;
+ WordStream *mStream;
+};
+
+} // namespace spirit
+} // namespace android
+
+#endif // TRANSFORMER_H
diff --git a/rsov/compiler/spirit/transformer_test.cpp b/rsov/compiler/spirit/transformer_test.cpp
new file mode 100644
index 0000000..a78969f
--- /dev/null
+++ b/rsov/compiler/spirit/transformer_test.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "transformer.h"
+
+#include "file_utils.h"
+#include "spirit.h"
+#include "test_utils.h"
+#include "gtest/gtest.h"
+
+#include <stdint.h>
+
+namespace android {
+namespace spirit {
+
+namespace {
+
+class MulToAddTransformer : public Transformer {
+public:
+ Instruction *transform(IMulInst *mul) override {
+ auto ret = new IAddInst(mul->mResultType, mul->mOperand1, mul->mOperand2);
+ ret->setId(mul->getId());
+ return ret;
+ }
+};
+
+class Deleter : public Transformer {
+public:
+ Instruction *transform(IMulInst *) override { return nullptr; }
+};
+
+class NewDataTypeTransformer : public Transformer {
+public:
+ Instruction *transform(IMulInst *mul) override {
+ insert(mul);
+ auto *DoubleTy = getModule()->getFloatType(64);
+ ConstantInst *ConstDouble2 = getModule()->getConstant(DoubleTy, 2.0);
+ auto ret = new IAddInst(DoubleTy, mul, ConstDouble2);
+
+ IdResult id = ret->getId();
+ ret->setId(mul->getId());
+ mul->setId(id);
+
+ return ret;
+ }
+};
+
+} // annonymous namespace
+
+class TransformerTest : public ::testing::Test {
+protected:
+ virtual void SetUp() { mWordsGreyscale = readWords("greyscale.spv"); }
+
+ std::vector<uint32_t> mWordsGreyscale;
+
+private:
+ std::vector<uint32_t> readWords(const char *testFile) {
+ static const std::string testDataPath(
+ "frameworks/rs/rsov/compiler/spirit/test_data/");
+ const std::string &fullPath = getAbsolutePath(testDataPath + testFile);
+ return readFile<uint32_t>(fullPath);
+ }
+};
+
+TEST_F(TransformerTest, testMulToAdd) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m);
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m.get()));
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+
+ MulToAddTransformer trans;
+ std::unique_ptr<Module> m1(trans.run(m.get()));
+
+ ASSERT_NE(nullptr, m1);
+
+ ASSERT_TRUE(m1->resolveIds());
+
+ EXPECT_EQ(2, countEntity<IAddInst>(m1.get()));
+ EXPECT_EQ(0, countEntity<IMulInst>(m1.get()));
+}
+
+TEST_F(TransformerTest, testDeletion) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m.get());
+
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+
+ Deleter trans;
+ std::unique_ptr<Module> m1(trans.run(m.get()));
+
+ ASSERT_NE(nullptr, m1.get());
+
+ EXPECT_EQ(1, countEntity<IAddInst>(m1.get()));
+ EXPECT_EQ(0, countEntity<IMulInst>(m1.get()));
+}
+
+TEST_F(TransformerTest, testAddInstructionUsingNewDataType) {
+ std::unique_ptr<Module> m(Deserialize<Module>(mWordsGreyscale));
+
+ ASSERT_NE(nullptr, m.get());
+
+ EXPECT_EQ(5, countEntity<ConstantInst>(m.get()));
+ EXPECT_EQ(1, countEntity<TypeFloatInst>(m.get()));
+ EXPECT_EQ(1, countEntity<IMulInst>(m.get()));
+
+ NewDataTypeTransformer trans;
+ std::unique_ptr<Module> m1(trans.run(m.get()));
+
+ ASSERT_NE(nullptr, m1.get());
+
+ EXPECT_EQ(6, countEntity<ConstantInst>(m.get()));
+ EXPECT_EQ(2, countEntity<TypeFloatInst>(m1.get()));
+ EXPECT_EQ(2, countEntity<IAddInst>(m1.get()));
+ EXPECT_EQ(1, countEntity<IMulInst>(m1.get()));
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/visitor.cpp b/rsov/compiler/spirit/visitor.cpp
new file mode 100644
index 0000000..dcc6322
--- /dev/null
+++ b/rsov/compiler/spirit/visitor.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "visitor.h"
+
+#include "instructions.h"
+#include "module.h"
+
+namespace android {
+namespace spirit {
+
+void DoNothingVisitor::visit(Entity *e) { e->accept(this); }
+
+void DoNothingVisitor::visit(Module *m) { m->accept(this); }
+
+void DoNothingVisitor::visit(EntryPointDefinition *entry) {
+ entry->accept(this);
+}
+
+void DoNothingVisitor::visit(DebugInfoSection *dinfo) { dinfo->accept(this); }
+
+void DoNothingVisitor::visit(AnnotationSection *a) { a->accept(this); }
+
+void DoNothingVisitor::visit(GlobalSection *g) { g->accept(this); }
+void DoNothingVisitor::visit(FunctionDeclaration *fdecl) {
+ fdecl->accept(this);
+}
+void DoNothingVisitor::visit(Block *b) { b->accept(this); }
+void DoNothingVisitor::visit(FunctionDefinition *fdef) { fdef->accept(this); }
+void DoNothingVisitor::visit(Instruction *inst) { inst->accept(this); }
+#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) \
+ void DoNothingVisitor::visit(INST_CLASS *) {}
+#include "instruction_dispatches_generated.h"
+#undef HANDLE_INSTRUCTION
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/visitor.h b/rsov/compiler/spirit/visitor.h
new file mode 100644
index 0000000..0e41537
--- /dev/null
+++ b/rsov/compiler/spirit/visitor.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef VISITOR_H
+#define VISITOR_H
+
+#include <functional>
+
+namespace android {
+namespace spirit {
+
+class Entity;
+class Module;
+class EntryPointDefinition;
+class DebugInfoSection;
+class AnnotationSection;
+class GlobalSection;
+class FunctionDeclaration;
+class Block;
+class FunctionDefinition;
+class Instruction;
+#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) class INST_CLASS;
+#include "instruction_dispatches_generated.h"
+#undef HANDLE_INSTRUCTION
+
+class IVisitor {
+public:
+ virtual ~IVisitor() {}
+
+ virtual void visit(Entity *) = 0;
+ virtual void visit(Module *) = 0;
+ virtual void visit(EntryPointDefinition *) = 0;
+ virtual void visit(DebugInfoSection *) = 0;
+ virtual void visit(AnnotationSection *) = 0;
+ virtual void visit(GlobalSection *) = 0;
+ virtual void visit(FunctionDeclaration *) = 0;
+ virtual void visit(Block *) = 0;
+ virtual void visit(FunctionDefinition *) = 0;
+ virtual void visit(Instruction *) = 0;
+#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) \
+ virtual void visit(INST_CLASS *) = 0;
+#include "instruction_dispatches_generated.h"
+#undef HANDLE_INSTRUCTION
+};
+
+class DoNothingVisitor : public IVisitor {
+public:
+ virtual ~DoNothingVisitor() {}
+
+ virtual void visit(Entity *e);
+ virtual void visit(Module *m);
+ virtual void visit(EntryPointDefinition *);
+ virtual void visit(DebugInfoSection *dinfo);
+ virtual void visit(AnnotationSection *a);
+ virtual void visit(GlobalSection *g);
+ virtual void visit(FunctionDeclaration *fdecl);
+ virtual void visit(Block *b);
+ virtual void visit(FunctionDefinition *fdef);
+ // This visit(Instruction *) necessary?
+ virtual void visit(Instruction *inst);
+#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) virtual void visit(INST_CLASS *);
+#include "instruction_dispatches_generated.h"
+#undef HANDLE_INSTRUCTION
+};
+
+template <typename T> class InstructionVisitor : public DoNothingVisitor {
+public:
+ InstructionVisitor(T action) : mAction(action) {}
+
+ virtual ~InstructionVisitor() {}
+
+#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) \
+ void visit(INST_CLASS *inst) override { mAction((Instruction *)inst); }
+#include "instruction_dispatches_generated.h"
+#undef HANDLE_INSTRUCTION
+
+private:
+ T mAction;
+};
+
+template <typename T> static IVisitor *CreateInstructionVisitor(T action) {
+ return new InstructionVisitor<decltype(action)>(action);
+}
+
+} // namespace spirit
+} // namespace android
+
+#endif // VISITOR_H
diff --git a/rsov/compiler/spirit/word_stream.cpp b/rsov/compiler/spirit/word_stream.cpp
new file mode 100644
index 0000000..7061577
--- /dev/null
+++ b/rsov/compiler/spirit/word_stream.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "word_stream.h"
+
+#include "file_utils.h"
+#include "word_stream_impl.h"
+
+namespace android {
+namespace spirit {
+
+InputWordStream *InputWordStream::Create() { return new WordStreamImpl(); }
+
+InputWordStream *InputWordStream::Create(std::vector<uint32_t> &&words) {
+ return new WordStreamImpl(words);
+}
+
+InputWordStream *InputWordStream::Create(const std::vector<uint32_t> &words) {
+ return new WordStreamImpl(words);
+}
+
+InputWordStream *InputWordStream::Create(const std::vector<uint8_t> &bytes) {
+ std::vector<uint32_t> words((uint32_t *)bytes.data(),
+ (uint32_t *)(bytes.data() + bytes.size()));
+ return InputWordStream::Create(words);
+}
+
+InputWordStream *InputWordStream::Create(const char *filePath) {
+ return InputWordStream::Create(readFile<uint32_t>(filePath));
+}
+
+OutputWordStream *OutputWordStream::Create() { return new WordStreamImpl(); }
+
+WordStream *WordStream::Create() { return new WordStreamImpl(); }
+
+WordStream *WordStream::Create(const std::vector<uint32_t> &words) {
+ return new WordStreamImpl(words);
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/word_stream.h b/rsov/compiler/spirit/word_stream.h
new file mode 100644
index 0000000..94333bb
--- /dev/null
+++ b/rsov/compiler/spirit/word_stream.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef WORD_STREAM_H
+#define WORD_STREAM_H
+
+#include "core_defs.h"
+#include "types_generated.h"
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+namespace android {
+namespace spirit {
+
+struct IdRef;
+class Instruction;
+
+class InputWordStream {
+public:
+ static InputWordStream *Create();
+ static InputWordStream *Create(std::vector<uint32_t> &&words);
+ static InputWordStream *Create(const std::vector<uint32_t> &words);
+ static InputWordStream *Create(const std::vector<uint8_t> &bytes);
+ static InputWordStream *Create(const char *fileName);
+
+ virtual ~InputWordStream() {}
+
+ virtual bool empty() const = 0;
+ virtual uint32_t operator*() = 0;
+
+ virtual InputWordStream &operator>>(uint32_t *RHS) = 0;
+ virtual InputWordStream &operator>>(LiteralContextDependentNumber *num) = 0;
+ virtual InputWordStream &operator>>(std::string *str) = 0;
+
+ InputWordStream &operator>>(int32_t *RHS) { return *this >> (uint32_t *)RHS; }
+
+ InputWordStream &operator>>(OpCodeAndWordCount *codeCount) {
+ uint32_t word;
+ *this >> &word;
+ *codeCount = word;
+ return *this;
+ }
+
+ InputWordStream &operator>>(IdRef *RHS) {
+ // The referred instruction will be resolved later towards the end of the
+ // deserialization of the module after all instructions have been
+ // deserialized.
+ // It cannot be resolved here because it may be a forward reference.
+ RHS->mInstruction = nullptr;
+ return *this >> &RHS->mId;
+ ;
+ }
+
+ InputWordStream &operator>>(PairLiteralIntegerIdRef *RHS) {
+ return *this >> &RHS->mField0 >> &RHS->mField1;
+ }
+
+ InputWordStream &operator>>(PairIdRefLiteralInteger *RHS) {
+ return *this >> &RHS->mField0 >> &RHS->mField1;
+ }
+
+ InputWordStream &operator>>(PairIdRefIdRef *RHS) {
+ return *this >> &RHS->mField0 >> &RHS->mField1;
+ }
+
+#define HANDLE_ENUM(Enum) \
+ InputWordStream &operator>>(Enum *RHS) { return *this >> (uint32_t *)RHS; }
+#include "enum_dispatches_generated.h"
+#undef HANDLE_ENUM
+};
+
+class OutputWordStream {
+public:
+ static OutputWordStream *Create();
+
+ virtual ~OutputWordStream() {}
+
+ virtual std::vector<uint32_t> getWords() = 0;
+
+ virtual OutputWordStream &operator<<(const uint32_t RHS) = 0;
+ virtual OutputWordStream &
+ operator<<(const LiteralContextDependentNumber &RHS) = 0;
+ virtual OutputWordStream &operator<<(const std::string &str) = 0;
+
+ OutputWordStream &operator<<(const int32_t RHS) {
+ return *this << (uint32_t)RHS;
+ }
+
+ OutputWordStream &operator<<(const OpCodeAndWordCount codeCount) {
+ return *this << (uint32_t)codeCount;
+ }
+
+ OutputWordStream &operator<<(const IdRef &RHS) {
+ return *this << RHS.mId;
+ }
+
+ OutputWordStream &operator<<(const PairLiteralIntegerIdRef &RHS) {
+ return *this << RHS.mField0 << RHS.mField1;
+ }
+
+ OutputWordStream &operator<<(const PairIdRefLiteralInteger &RHS) {
+ return *this << RHS.mField0 << RHS.mField1;
+ }
+
+ OutputWordStream &operator<<(const PairIdRefIdRef &RHS) {
+ return *this << RHS.mField0 << RHS.mField1;
+ }
+
+#define HANDLE_ENUM(Enum) \
+ OutputWordStream &operator<<(const Enum RHS) { \
+ return *this << static_cast<uint32_t>(RHS); \
+ }
+#include "enum_dispatches_generated.h"
+#undef HANDLE_ENUM
+};
+
+class WordStream : public InputWordStream, public OutputWordStream {
+public:
+ static WordStream *Create();
+ static WordStream *Create(const std::vector<uint32_t> &words);
+
+ virtual ~WordStream() {}
+};
+
+} // namespace spirit
+} // namespace android
+
+#endif // WORD_STREAM_H
diff --git a/rsov/compiler/spirit/word_stream_impl.cpp b/rsov/compiler/spirit/word_stream_impl.cpp
new file mode 100644
index 0000000..33749e7
--- /dev/null
+++ b/rsov/compiler/spirit/word_stream_impl.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "word_stream_impl.h"
+
+namespace android {
+namespace spirit {
+
+WordStreamImpl::WordStreamImpl() {}
+
+WordStreamImpl::WordStreamImpl(const std::vector<uint32_t> &words)
+ : mWords(words), mIter(mWords.begin()) {}
+
+WordStreamImpl::WordStreamImpl(std::vector<uint32_t> &&words)
+ : mWords(words), mIter(mWords.begin()) {}
+
+WordStreamImpl &WordStreamImpl::operator<<(const std::string &str) {
+ const size_t len = str.length();
+ const uint32_t *begin = (uint32_t *)str.c_str();
+ const uint32_t *end = begin + (len / 4);
+ mWords.insert(mWords.end(), begin, end);
+
+ uint32_t lastWord = *end;
+ uint32_t mask = 0xFF;
+ bool clear = false;
+ for (int i = 0; i < 4; i++, mask <<= 8) {
+ if (clear) {
+ lastWord &= ~mask;
+ } else {
+ clear = ((lastWord & mask) == 0);
+ }
+ }
+ mWords.push_back(lastWord);
+ return *this;
+}
+
+WordStreamImpl &WordStreamImpl::operator>>(std::string *str) {
+ const char *s = (const char *)&*mIter;
+ str->assign(s);
+ while (*mIter++ & 0xFF000000) {
+ }
+ return *this;
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/spirit/word_stream_impl.h b/rsov/compiler/spirit/word_stream_impl.h
new file mode 100644
index 0000000..365e3d5
--- /dev/null
+++ b/rsov/compiler/spirit/word_stream_impl.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef WORD_STREAM_IMPL_H
+#define WORD_STREAM_IMPL_H
+
+#include "word_stream.h"
+
+#include <string>
+
+namespace android {
+namespace spirit {
+
+class WordStreamImpl : public WordStream {
+public:
+ WordStreamImpl();
+ WordStreamImpl(const std::vector<uint32_t> &words);
+ WordStreamImpl(std::vector<uint32_t> &&words);
+
+ bool empty() const override {
+ return mWords.empty() || mIter == mWords.end();
+ }
+
+ uint32_t operator*() { return *mIter; }
+
+ WordStreamImpl &operator>>(uint32_t *RHS) override {
+ *RHS = *mIter++;
+ return *this;
+ }
+
+ WordStreamImpl &operator>>(LiteralContextDependentNumber *RHS) override {
+ // TODO: check context in the instruction class to decide the actual size.
+ return *this >> (uint32_t *)(&RHS->intValue);
+ }
+
+ WordStreamImpl &operator>>(std::string *str) override;
+
+ std::vector<uint32_t> getWords() override { return mWords; }
+
+ WordStreamImpl &operator<<(const uint32_t RHS) override {
+ mWords.push_back(RHS);
+ return *this;
+ }
+
+ WordStreamImpl &
+ operator<<(const LiteralContextDependentNumber &RHS) override {
+ // TODO: check context in the instruction class to decide the actual size.
+ // TODO: maybe a word stream class should never take a context dependent
+ // type as argument. Always take concrete types such as int32, int64, float,
+ // double, etc.
+ return *this << (uint32_t)(RHS.intValue);
+ }
+ WordStreamImpl &operator<<(const std::string &str) override;
+
+private:
+ std::vector<uint32_t> mWords;
+ std::vector<uint32_t>::const_iterator mIter;
+};
+
+} // namespace spirit
+} // namespace android
+
+#endif // WORD_STREAM_IMPL_H
diff --git a/rsov/compiler/spirit/word_stream_test.cpp b/rsov/compiler/spirit/word_stream_test.cpp
new file mode 100644
index 0000000..2735e15
--- /dev/null
+++ b/rsov/compiler/spirit/word_stream_test.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include "word_stream.h"
+
+#include "gtest/gtest.h"
+
+#include <vector>
+
+namespace android {
+namespace spirit {
+
+TEST(WordStreamTest, testStringOutput1) {
+ std::unique_ptr<OutputWordStream> OS(OutputWordStream::Create());
+ *OS << "ABCDEFG";
+ auto words = OS->getWords();
+ const std::vector<uint8_t> bytes((uint8_t *)words.data(),
+ (uint8_t *)(words.data() + words.size()));
+ const std::vector<uint8_t> bytesExpected = {0x41, 0x42, 0x43, 0x44,
+ 0x45, 0x46, 0x47, 0x00};
+ EXPECT_EQ(bytesExpected, bytes);
+}
+
+TEST(WordStreamTest, testStringOutput2) {
+ std::unique_ptr<OutputWordStream> OS(OutputWordStream::Create());
+ *OS << "GLSL.std.450";
+ auto words = OS->getWords();
+ const std::vector<uint8_t> bytes((uint8_t *)words.data(),
+ (uint8_t *)(words.data() + words.size()));
+ const std::vector<uint8_t> bytesExpected = {
+ 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64,
+ 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00};
+ EXPECT_EQ(bytesExpected, bytes);
+}
+
+TEST(WordStreamTest, testStringInput1) {
+ uint8_t bytes[] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x00};
+ std::vector<uint32_t> words((uint32_t *)bytes,
+ (uint32_t *)(bytes + sizeof(bytes)));
+ std::unique_ptr<InputWordStream> IS(InputWordStream::Create(words));
+ std::string s;
+ *IS >> &s;
+ EXPECT_STREQ("ABCDEFG", s.c_str());
+}
+
+TEST(WordStreamTest, testStringInput2) {
+ uint8_t bytes[] = {0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64,
+ 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00};
+ std::vector<uint32_t> words((uint32_t *)bytes,
+ (uint32_t *)(bytes + sizeof(bytes)));
+ std::unique_ptr<InputWordStream> IS(InputWordStream::Create(words));
+ std::string s;
+ *IS >> &s;
+ EXPECT_STREQ("GLSL.std.450", s.c_str());
+}
+
+} // namespace spirit
+} // namespace android
diff --git a/rsov/compiler/tests/arguments/foreach_multi_simple.ll b/rsov/compiler/tests/arguments/foreach_multi_simple.ll
new file mode 100644
index 0000000..ee6284e
--- /dev/null
+++ b/rsov/compiler/tests/arguments/foreach_multi_simple.ll
@@ -0,0 +1,46 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+; Decorations
+; CHECK: OpDecorate %[[BUF_0S:.*]] BufferBlock
+; CHECK: OpDecorate %[[BUF_VAR0:.*]] Binding 3
+; CHECK: OpDecorate %[[BUF_1S:.*]] BufferBlock
+; CHECK: OpDecorate %[[BUF_VAR1:.*]] Binding 4
+
+; CHECK:%[[BUF_PTR_TY0:.*]] = OpTypePointer Uniform %[[BUF_0S]]
+; CHECK:%[[BUF_VAR0]] = OpVariable %[[BUF_PTR_TY0]] Uniform
+; CHECK:%[[BUF_PTR_TY1:.*]] = OpTypePointer Uniform %[[BUF_1S]]
+; CHECK:%[[BUF_VAR1]] = OpVariable %[[BUF_PTR_TY1]] Uniform
+
+; Wrapper
+; CHECK: %[[ADDR0:.*]] = OpAccessChain %{{.*}} %[[BUF_VAR0]]
+; CHECK:OpLoad {{.*}} %[[ADDR0]]
+; CHECK: %[[ADDR1:.*]] = OpAccessChain %{{.*}} %[[BUF_VAR1]]
+; CHECK:OpLoad {{.*}} %[[ADDR1]]
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; Function Attrs: norecurse nounwind readnone
+define float @sum2(float %in0, float %in1, i32 %x) local_unnamed_addr #0 {
+entry:
+ %add = fadd float %in0, %in1
+ ret float %add
+}
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4}
+!\23rs_export_foreach_name = !{!5, !6}
+!\23rs_export_foreach = !{!7, !8}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.275480 (based on LLVM 3.8.275480)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"com.android.rs.rsov.test"}
+!5 = !{!"root"}
+!6 = !{!"sum2"}
+!7 = !{!"0"}
+!8 = !{!"43"}
diff --git a/rsov/compiler/tests/arguments/signedness.ll b/rsov/compiler/tests/arguments/signedness.ll
new file mode 100644
index 0000000..c173114
--- /dev/null
+++ b/rsov/compiler/tests/arguments/signedness.ll
@@ -0,0 +1,130 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+; CHECK: OpDecorate [[InVar1:%.*]] Binding 3
+; CHECK: OpDecorate [[OutVar1:%.*]] Binding 2
+
+; CHECK: OpDecorate [[InVar2:%.*]] Binding 3
+; CHECK: OpDecorate [[OutVar2:%.*]] Binding 2
+
+; CHECK: OpDecorate [[InVar3:%.*]] Binding 3
+; CHECK: OpDecorate [[OutVar3:%.*]] Binding 2
+
+; CHECK: OpDecorate [[InVar4:%.*]] Binding 3
+; CHECK: OpDecorate [[OutVar4:%.*]] Binding 2
+
+; CHECK: [[MemberTy1:%.*]] = OpTypeRuntimeArray %v4uint
+; CHECK: [[Struct1:%.*]] = OpTypeStruct [[MemberTy1]]
+; CHECK: [[PtrTy1:%.*]] = OpTypePointer Uniform [[Struct1]]
+; CHECK: [[InVar1]] = OpVariable [[PtrTy1]]
+
+; CHECK: [[OutMemberTy1:%.*]] = OpTypeRuntimeArray %v4uint
+; CHECK: [[OutStruct1:%.*]] = OpTypeStruct [[OutMemberTy1]]
+; CHECK: [[OutPtrTy1:%.*]] = OpTypePointer Uniform [[OutStruct1]]
+; CHECK: [[OutVar1]] = OpVariable [[OutPtrTy1]]
+
+; CHECK: [[MemberTy2:%.*]] = OpTypeRuntimeArray %v4uint
+; CHECK: [[Struct2:%.*]] = OpTypeStruct [[MemberTy2]]
+; CHECK: [[PtrTy2:%.*]] = OpTypePointer Uniform [[Struct2]]
+; CHECK: [[InVar2]] = OpVariable [[PtrTy2]]
+
+; CHECK: [[OutMemberTy2:%.*]] = OpTypeRuntimeArray %v4uint
+; CHECK: [[OutStruct2:%.*]] = OpTypeStruct [[OutMemberTy2]]
+; CHECK: [[OutPtrTy2:%.*]] = OpTypePointer Uniform [[OutStruct2]]
+; CHECK: [[OutVar2]] = OpVariable [[OutPtrTy2]]
+
+; CHECK: [[MemberTy3:%.*]] = OpTypeRuntimeArray %uint
+; CHECK: [[Struct3:%.*]] = OpTypeStruct [[MemberTy3]]
+; CHECK: [[PtrTy3:%.*]] = OpTypePointer Uniform [[Struct3]]
+; CHECK: [[InVar3]] = OpVariable [[PtrTy3]]
+
+; CHECK: [[OutMemberTy3:%.*]] = OpTypeRuntimeArray %uint
+; CHECK: [[OutStruct3:%.*]] = OpTypeStruct [[OutMemberTy3]]
+; CHECK: [[OutPtrTy3:%.*]] = OpTypePointer Uniform [[OutStruct3]]
+; CHECK: [[OutVar3]] = OpVariable [[OutPtrTy3]]
+
+; CHECK: [[MemberTy4:%.*]] = OpTypeRuntimeArray %uint
+; CHECK: [[Struct4:%.*]] = OpTypeStruct [[MemberTy4]]
+; CHECK: [[PtrTy4:%.*]] = OpTypePointer Uniform [[Struct4]]
+; CHECK: [[InVar4]] = OpVariable [[PtrTy4]]
+
+; CHECK: [[OutMemberTy4:%.*]] = OpTypeRuntimeArray %uint
+; CHECK: [[OutStruct4:%.*]] = OpTypeStruct [[OutMemberTy4]]
+; CHECK: [[OutPtrTy4:%.*]] = OpTypePointer Uniform [[OutStruct4]]
+; CHECK: [[OutVar4]] = OpVariable [[OutPtrTy4]]
+
+; // the RS the .rs from which this .ll is generated
+; #pragma version(1)
+; #pragma rs java_package_name(com.android.rs.test)
+
+; int4 RS_KERNEL increment4(int4 in)
+; {
+; return in + 1;
+; }
+
+; uint4 RS_KERNEL uincrement4(uint4 in)
+; {
+; return in + 1;
+; }
+
+; int RS_KERNEL increment(int in)
+; {
+; return in + 1;
+; }
+
+; unsigned RS_KERNEL uincrement(unsigned in)
+; {
+; return in + 1;
+; }
+
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; Function Attrs: norecurse nounwind readnone
+define <4 x i32> @increment4(<4 x i32> %in) local_unnamed_addr #0 {
+entry:
+ %add = add <4 x i32> %in, <i32 1, i32 1, i32 1, i32 1>
+ ret <4 x i32> %add
+}
+
+; Function Attrs: norecurse nounwind readnone
+define <4 x i32> @uincrement4(<4 x i32> %in) local_unnamed_addr #0 {
+entry:
+ %add = add <4 x i32> %in, <i32 1, i32 1, i32 1, i32 1>
+ ret <4 x i32> %add
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @increment(i32 %in) local_unnamed_addr #0 {
+entry:
+ %add = add nsw i32 %in, 1
+ ret i32 %add
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @uincrement(i32 %in) local_unnamed_addr #0 {
+entry:
+ %add = add i32 %in, 1
+ ret i32 %add
+}
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4}
+!\23rs_export_foreach_name = !{!5, !6, !7, !8, !9}
+!\23rs_export_foreach = !{!10, !11, !11, !11, !11}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.275480 (based on LLVM 3.8.275480)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"com.android.rs.test"}
+!5 = !{!"root"}
+!6 = !{!"increment4"}
+!7 = !{!"uincrement4"}
+!8 = !{!"increment"}
+!9 = !{!"uincrement"}
+!10 = !{!"0"}
+!11 = !{!"35"}
diff --git a/rsov/compiler/tests/errors/unsupported_type.rs b/rsov/compiler/tests/errors/unsupported_type.rs
new file mode 100644
index 0000000..a5af55d
--- /dev/null
+++ b/rsov/compiler/tests/errors/unsupported_type.rs
@@ -0,0 +1,6 @@
+#pragma version(1)
+#pragma rs java_package_name(identity)
+
+#define TYPE short
+
+TYPE RS_KERNEL tSet(TYPE v) { return v; }
diff --git a/rsov/compiler/tests/globals/mul.ll b/rsov/compiler/tests/globals/mul.ll
new file mode 100644
index 0000000..e0710fb
--- /dev/null
+++ b/rsov/compiler/tests/globals/mul.ll
@@ -0,0 +1,52 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: OpString ".rsov.ExportedVars:0;"
+
+; CHECK-DAG: OpDecorate [[GPUBlockVar:%[a-zA-Z_0-9]+]] Binding 0
+; CHECK-DAG: OpDecorate [[STRUCT:%struct__.*]] BufferBlock
+; CHECK-DAG: OpMemberDecorate [[STRUCT]] 0 Offset 0
+
+; CHECK: [[STRUCT]] = OpTypeStruct %float
+; CHECK: [[STRUCT_PTR_TY:%[a-zA-Z_0-9]+]] = OpTypePointer Uniform [[STRUCT]]
+
+; CHECK: [[GPUBlockVar]] = OpVariable [[STRUCT_PTR_TY]] Uniform
+
+@c1 = common global float 0.000000e+00, align 4
+
+; Function Attrs: norecurse nounwind readonly
+define <4 x float> @k1(<4 x float> %in) #0 {
+entry:
+ %0 = load float, float* @c1, align 4, !tbaa !11
+ %splat.splatinsert = insertelement <4 x float> undef, float %0, i32 0
+ %splat.splat = shufflevector <4 x float> %splat.splatinsert, <4 x float> undef, <4 x i32> zeroinitializer
+ %mul = fmul <4 x float> %splat.splat, %in
+ ret <4 x float> %mul
+}
+
+attributes #0 = { norecurse nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_var = !{!6}
+!\23rs_object_slots = !{}
+!\23rs_export_foreach_name = !{!7, !8}
+!\23rs_export_foreach = !{!9, !10}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"c1", !"1"}
+!7 = !{!"root"}
+!8 = !{!"k1"}
+!9 = !{!"0"}
+!10 = !{!"35"}
+!11 = !{!12, !12, i64 0}
+!12 = !{!"float", !13, i64 0}
+!13 = !{!"omnipotent char", !14, i64 0}
+!14 = !{!"Simple C/C++ TBAA"}
diff --git a/rsov/compiler/tests/globals/mul.rs b/rsov/compiler/tests/globals/mul.rs
new file mode 100644
index 0000000..77c5c52
--- /dev/null
+++ b/rsov/compiler/tests/globals/mul.rs
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 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.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+float c1;
+
+float4 __attribute__((kernel)) k1(float4 in) {
+ return c1 * in;
+}
diff --git a/rsov/compiler/tests/globals/mul2.ll b/rsov/compiler/tests/globals/mul2.ll
new file mode 100644
index 0000000..ee47542
--- /dev/null
+++ b/rsov/compiler/tests/globals/mul2.ll
@@ -0,0 +1,64 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: OpString ".rsov.ExportedVars:0;24;8;28;"
+
+; CHECK-DAG: OpDecorate [[GPUBlockVar:%[a-zA-Z_0-9]+]] Binding 0
+; CHECK-DAG: OpDecorate [[STRUCT:%struct__.*]] BufferBlock
+; CHECK-DAG: OpMemberDecorate [[STRUCT]] 0 Offset 0
+; CHECK-DAG: OpMemberDecorate [[STRUCT]] 1 Offset 8
+; CHECK-DAG: OpMemberDecorate [[STRUCT]] 2 Offset 24
+; CHECK-DAG: OpMemberDecorate [[STRUCT]] 3 Offset 28
+
+; CHECK: [[STRUCT]] = OpTypeStruct %float %v4float %uchar %uint{{.*}}
+; CHECK: [[STRUCT_PTR_TY:%[a-zA-Z_0-9]+]] = OpTypePointer Uniform [[STRUCT]]
+
+; CHECK: [[GPUBlockVar]] = OpVariable [[STRUCT_PTR_TY]] Uniform
+
+@c1 = common global float 0.000000e+00, align 4
+@c2 = common global <4 x float> zeroinitializer, align 16
+@d = common global i8 0, align 1
+@i = common global i32 0, align 4
+
+; Function Attrs: norecurse nounwind readonly
+define <4 x float> @k1(<4 x float> %in) #0 {
+entry:
+ %0 = load float, float* @c1, align 4, !tbaa !14
+ %splat.splatinsert = insertelement <4 x float> undef, float %0, i32 0
+ %splat.splat = shufflevector <4 x float> %splat.splatinsert, <4 x float> undef, <4 x i32> zeroinitializer
+ %mul = fmul <4 x float> %splat.splat, %in
+ %1 = load <4 x float>, <4 x float>* @c2, align 16, !tbaa !18
+ %mul1 = fmul <4 x float> %1, %mul
+ ret <4 x float> %mul1
+}
+
+attributes #0 = { norecurse nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_var = !{!6, !7, !8, !9}
+!\23rs_object_slots = !{}
+!\23rs_export_foreach_name = !{!10, !11}
+!\23rs_export_foreach = !{!12, !13}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"c1", !"1"}
+!7 = !{!"d", !"7"}
+!8 = !{!"c2", !"float4"}
+!9 = !{!"i", !"5"}
+!10 = !{!"root"}
+!11 = !{!"k1"}
+!12 = !{!"0"}
+!13 = !{!"35"}
+!14 = !{!15, !15, i64 0}
+!15 = !{!"float", !16, i64 0}
+!16 = !{!"omnipotent char", !17, i64 0}
+!17 = !{!"Simple C/C++ TBAA"}
+!18 = !{!16, !16, i64 0}
diff --git a/rsov/compiler/tests/globals/mul2.rs b/rsov/compiler/tests/globals/mul2.rs
new file mode 100644
index 0000000..78e67ac
--- /dev/null
+++ b/rsov/compiler/tests/globals/mul2.rs
@@ -0,0 +1,26 @@
+// Copyright (C) 2016 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.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+float c1;
+uchar d;
+float4 c2;
+int i;
+
+float4 __attribute__((kernel)) k1(float4 in) {
+ return c1 * in * c2;
+}
diff --git a/rsov/compiler/tests/image/blend.ll b/rsov/compiler/tests/image/blend.ll
new file mode 100644
index 0000000..1788845
--- /dev/null
+++ b/rsov/compiler/tests/image/blend.ll
@@ -0,0 +1,62 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: OpEntryPoint GLCompute [[WrapperId:%[a-zA-Z_0-9]*]] "entry_setImageAlpha"
+
+; CHECK-NOT: OpFunctionCall %v4uchar %__Z14convert_uchar4Dv4_j
+; CHECK-NOT: OpFunctionCall %v4uint %__Z13convert_uint4Dv4_h
+
+; CHECK: OpUConvert %v4uint
+; CHECK: OpUConvert %v4uchar
+
+@alpha = global i8 0, align 1
+
+; Function Attrs: nounwind readonly
+define <4 x i8> @setImageAlpha(<4 x i8> %in, i32 %x, i32 %y) #0 {
+entry:
+ %call = tail call <4 x i32> @_Z13convert_uint4Dv4_h(<4 x i8> %in) #2
+ %0 = load i8, i8* @alpha, align 1, !tbaa !11
+ %conv = zext i8 %0 to i32
+ %splat.splatinsert = insertelement <4 x i32> undef, i32 %conv, i32 0
+ %splat.splat = shufflevector <4 x i32> %splat.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer
+ %mul = mul <4 x i32> %splat.splat, %call
+ %shr = lshr <4 x i32> %mul, <i32 8, i32 8, i32 8, i32 8>
+ %call1 = tail call <4 x i8> @_Z14convert_uchar4Dv4_j(<4 x i32> %shr) #2
+ %1 = insertelement <4 x i8> %call1, i8 %0, i32 3
+ ret <4 x i8> %1
+}
+
+; Function Attrs: nounwind readnone
+declare <4 x i8> @_Z14convert_uchar4Dv4_j(<4 x i32>) #1
+
+; Function Attrs: nounwind readnone
+declare <4 x i32> @_Z13convert_uint4Dv4_h(<4 x i8>) #1
+
+attributes #0 = { nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind readnone }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_var = !{!6}
+!\23rs_object_slots = !{}
+!\23rs_export_foreach_name = !{!7, !8}
+!\23rs_export_foreach = !{!9, !10}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"alpha", !"7"}
+!7 = !{!"root"}
+!8 = !{!"setImageAlpha"}
+!9 = !{!"0"}
+!10 = !{!"59"}
+!11 = !{!12, !12, i64 0}
+!12 = !{!"omnipotent char", !13, i64 0}
+!13 = !{!"Simple C/C++ TBAA"}
diff --git a/rsov/compiler/tests/image/blend.rs b/rsov/compiler/tests/image/blend.rs
new file mode 100644
index 0000000..ea1d323
--- /dev/null
+++ b/rsov/compiler/tests/image/blend.rs
@@ -0,0 +1,26 @@
+// Copyright (C) 2011 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.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+uchar alpha = 0x0;
+
+uchar4 __attribute__((kernel)) setImageAlpha(uchar4 in, uint32_t x, uint32_t y) {
+ uchar4 out;
+ out.rgba = convert_uchar4((convert_uint4(in.rgba) * alpha) >> (uint4)8);
+ out.a = alpha;
+ return out;
+}
diff --git a/rsov/compiler/tests/image/contrast.ll b/rsov/compiler/tests/image/contrast.ll
new file mode 100644
index 0000000..77cee16
--- /dev/null
+++ b/rsov/compiler/tests/image/contrast.ll
@@ -0,0 +1,101 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: [[GLSL_EXT_INS:%.*]] = OpExtInstImport "GLSL.std.450"
+; CHECK: OpEntryPoint GLCompute [[WrapperId:%[a-zA-Z_0-9]*]] "entry_contrast"
+
+; CHECK-NOT: OpFunctionCall %v3float %_Z14convert_float3Dv3_h
+; CHECK-NOT: OpFunctionCall %v3float %_Z5clampDv3_fff
+; CHECK-NOT: OpFunctionCall %v3uchar %_Z14convert_uchar3Dv3_f
+
+; CHECK: OpConvertUToF %v3float
+; CHECK: OpExtInst %v3float [[GLSL_EXT_INS]] FClamp
+; CHECK: OpConvertFToU %v3uchar
+
+
+@brightM = internal unnamed_addr global float 0.000000e+00, align 4
+@brightC = internal unnamed_addr global float 0.000000e+00, align 4
+
+; Function Attrs: nounwind
+define void @setBright(float %v) #0 {
+entry:
+ %div = fdiv float %v, 1.000000e+02
+ %call = tail call float @_Z3powff(float 2.000000e+00, float %div) #4
+ store float %call, float* @brightM, align 4, !tbaa !11
+ %mul = fmul float %call, 1.270000e+02
+ %sub = fsub float 1.270000e+02, %mul
+ store float %sub, float* @brightC, align 4, !tbaa !11
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare float @_Z3powff(float, float) #1
+
+; Function Attrs: nounwind readonly
+define <4 x i8> @contrast(<4 x i8> %in) #2 {
+entry:
+ %0 = shufflevector <4 x i8> %in, <4 x i8> undef, <3 x i32> <i32 0, i32 1, i32 2>
+ %call = tail call <3 x float> @_Z14convert_float3Dv3_h(<3 x i8> %0) #4
+ %1 = load float, float* @brightM, align 4, !tbaa !11
+ %splat.splatinsert = insertelement <3 x float> undef, float %1, i32 0
+ %splat.splat = shufflevector <3 x float> %splat.splatinsert, <3 x float> undef, <3 x i32> zeroinitializer
+ %mul = fmul <3 x float> %call, %splat.splat
+ %2 = load float, float* @brightC, align 4, !tbaa !11
+ %splat.splatinsert1 = insertelement <3 x float> undef, float %2, i32 0
+ %splat.splat2 = shufflevector <3 x float> %splat.splatinsert1, <3 x float> undef, <3 x i32> zeroinitializer
+ %add = fadd <3 x float> %mul, %splat.splat2
+ %call4 = tail call <3 x float> @_Z5clampDv3_fff(<3 x float> %add, float 0.000000e+00, float 2.550000e+02) #4
+ %call5 = tail call <3 x i8> @_Z14convert_uchar3Dv3_f(<3 x float> %call4) #4
+ %3 = shufflevector <3 x i8> %call5, <3 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
+ %4 = insertelement <4 x i8> %3, i8 -1, i32 3
+ ret <4 x i8> %4
+}
+
+; Function Attrs: nounwind readnone
+declare <3 x float> @_Z14convert_float3Dv3_h(<3 x i8>) #1
+
+; Function Attrs: nounwind readnone
+declare <3 x i8> @_Z14convert_uchar3Dv3_f(<3 x float>) #1
+
+; Function Attrs: nounwind readnone
+declare <3 x float> @_Z5clampDv3_fff(<3 x float>, float, float) #1
+
+; Function Attrs: noinline nounwind
+define void @.helper_setBright({ float }* nocapture) #3 {
+entry:
+ %1 = getelementptr inbounds { float }, { float }* %0, i32 0, i32 0
+ %2 = load float, float* %1, align 4
+ tail call void @setBright(float %2)
+ ret void
+}
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #3 = { noinline nounwind }
+attributes #4 = { nounwind readnone }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_func = !{!6}
+!\23rs_export_foreach_name = !{!7, !8}
+!\23rs_export_foreach = !{!9, !10}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!".helper_setBright"}
+!7 = !{!"root"}
+!8 = !{!"contrast"}
+!9 = !{!"0"}
+!10 = !{!"35"}
+!11 = !{!12, !12, i64 0}
+!12 = !{!"float", !13, i64 0}
+!13 = !{!"omnipotent char", !14, i64 0}
+!14 = !{!"Simple C/C++ TBAA"}
diff --git a/rsov/compiler/tests/image/contrast.rs b/rsov/compiler/tests/image/contrast.rs
new file mode 100644
index 0000000..dd95ad3
--- /dev/null
+++ b/rsov/compiler/tests/image/contrast.rs
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+static float brightM = 0.f;
+static float brightC = 0.f;
+
+void setBright(float v) {
+ brightM = pow(2.f, v / 100.f);
+ brightC = 127.f - brightM * 127.f;
+}
+
+uchar4 __attribute__((kernel)) contrast(uchar4 in) {
+ float3 v = convert_float3(in.rgb) * brightM + brightC;
+ uchar4 o;
+ o.rgb = convert_uchar3(clamp(v, 0.f, 255.f));
+ o.a = 0xff;
+ return o;
+}
\ No newline at end of file
diff --git a/rsov/compiler/tests/image/copy.ll b/rsov/compiler/tests/image/copy.ll
new file mode 100644
index 0000000..62617c9
--- /dev/null
+++ b/rsov/compiler/tests/image/copy.ll
@@ -0,0 +1,37 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: OpEntryPoint GLCompute [[WrapperId:%[a-zA-Z_0-9]*]] "entry_copy"
+; CHECK: [[KernelId:%[a-zA-Z_0-9]+]] = OpFunction {{.*}}
+
+; Function Attrs: norecurse nounwind readnone
+define <4 x i8> @copy(<4 x i8> %v_in) #0 {
+entry:
+ ret <4 x i8> %v_in
+}
+
+; CHECK: [[WrapperId]] = OpFunction {{.*}}
+; CHECK-NEXT: OpLabel
+; CHECK: %{{[0-9]+}} = OpFunctionCall %{{.*}} [[KernelId]]
+; CHECK: OpReturn
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_foreach_name = !{!6, !7}
+!\23rs_export_foreach = !{!8, !9}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"root"}
+!7 = !{!"copy"}
+!8 = !{!"0"}
+!9 = !{!"35"}
diff --git a/rsov/compiler/tests/image/copy.rs b/rsov/compiler/tests/image/copy.rs
new file mode 100644
index 0000000..1f3ae2e
--- /dev/null
+++ b/rsov/compiler/tests/image/copy.rs
@@ -0,0 +1,7 @@
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+uchar4 __attribute__((kernel)) copy(uchar4 v_in) {
+ return v_in;
+}
diff --git a/rsov/compiler/tests/lit.cfg b/rsov/compiler/tests/lit.cfg
new file mode 100644
index 0000000..66ef028
--- /dev/null
+++ b/rsov/compiler/tests/lit.cfg
@@ -0,0 +1,29 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+import re
+
+# name: The name of this test suite.
+config.name = 'rs2spirv'
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.ll']
+
+# testFormat: The test format to use to interpret tests.
+import lit.formats
+config.test_format = lit.formats.ShTest()
+
+ANDROID_HOST_OUT = os.getenv("ANDROID_HOST_OUT")
+
+if not ANDROID_HOST_OUT:
+ import sys
+ sys.exit(1)
+
+# test_source_root: The path where tests are located (default is the test suite
+# root).
+config.test_source_root = None
+# test_exec_root: The root path where tests should be run.
+config.test_exec_root = os.path.join(ANDROID_HOST_OUT, 'tests', 'rs2spirv')
+
+tools_dir = os.pathsep.join([os.path.join(ANDROID_HOST_OUT, 'bin'),])
diff --git a/rsov/compiler/tests/llvm-lit b/rsov/compiler/tests/llvm-lit
new file mode 100755
index 0000000..cc6f58e
--- /dev/null
+++ b/rsov/compiler/tests/llvm-lit
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+
+import os
+import sys
+
+# In the Android tree, use the environment variables set by envsetup.sh
+# to determine correct path for the root of the source tree.
+# TODO: To run clang tests, @LLVM_BINARY_DIR@ must be substituted also.
+android_source_root = os.getenv('ANDROID_BUILD_TOP', ".")
+llvm_source_root = os.path.join(android_source_root, 'external', 'llvm')
+
+# Make sure we can find the lit package.
+sys.path.append(os.path.join(llvm_source_root, 'utils', 'lit'))
+
+# Set up some builtin parameters, so that by default the LLVM test suite
+# configuration file knows how to find the object tree.
+builtin_parameters = {
+ 'llvm_site_config' : os.path.join('./', 'lit.site.cfg')
+}
+
+if __name__=='__main__':
+ import lit
+ lit.main(builtin_parameters)
diff --git a/rsov/compiler/tests/multi_function/blend_mf.ll b/rsov/compiler/tests/multi_function/blend_mf.ll
new file mode 100644
index 0000000..650d661
--- /dev/null
+++ b/rsov/compiler/tests/multi_function/blend_mf.ll
@@ -0,0 +1,68 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: OpEntryPoint GLCompute %[[WrapperId:[a-zA-Z_0-9]*]] "entry_setImageAlpha"
+
+; Function Attrs: norecurse nounwind readnone
+define void @NOP() #0 {
+entry:
+ ret void
+}
+
+; CHECK: [[KernelId:%[a-zA-Z_0-9]+]] = OpFunction {{.*}}
+
+; Function calls to _Z14convert_uchar4Dv4_j should be translated into OpUConvert instructions
+; CHECK-NOT: OpFunctionCall %v4uchar %_Z14convert_uchar4Dv4_j
+; CHECK-NOT: OpFunctionCall %v4uint %_Z13convert_uint4Dv4_h
+; CHECK: OpUConvert %v4uint
+; CHECK: OpUConvert %v4uchar
+
+; Function Attrs: nounwind readnone
+define <4 x i8> @setImageAlpha(<4 x i8> %in) #1 {
+entry:
+ %call = tail call <4 x i32> @_Z13convert_uint4Dv4_h(<4 x i8> %in) #2
+ %mul = mul <4 x i32> %call, <i32 37, i32 37, i32 37, i32 37>
+ %shr = lshr <4 x i32> %mul, <i32 8, i32 8, i32 8, i32 8>
+ %call1 = tail call <4 x i8> @_Z14convert_uchar4Dv4_j(<4 x i32> %shr) #2
+ %call2 = tail call fastcc <4 x i8> @twice(<4 x i8> %call1)
+ %0 = insertelement <4 x i8> %call2, i8 37, i32 3
+ ret <4 x i8> %0
+}
+
+; Function Attrs: norecurse nounwind readnone
+define internal fastcc <4 x i8> @twice(<4 x i8> %in) #0 {
+entry:
+ %mul = shl <4 x i8> %in, <i8 1, i8 1, i8 1, i8 1>
+ ret <4 x i8> %mul
+}
+
+; Function Attrs: nounwind readnone
+declare <4 x i8> @_Z14convert_uchar4Dv4_j(<4 x i32>) #1
+
+; Function Attrs: nounwind readnone
+declare <4 x i32> @_Z13convert_uint4Dv4_h(<4 x i8>) #1
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind readnone }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_func = !{!6}
+!\23rs_export_foreach_name = !{!7, !8}
+!\23rs_export_foreach = !{!9, !10}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"NOP"}
+!7 = !{!"root"}
+!8 = !{!"setImageAlpha"}
+!9 = !{!"0"}
+!10 = !{!"35"}
diff --git a/rsov/compiler/tests/multi_function/blend_mf.rs b/rsov/compiler/tests/multi_function/blend_mf.rs
new file mode 100644
index 0000000..1769208
--- /dev/null
+++ b/rsov/compiler/tests/multi_function/blend_mf.rs
@@ -0,0 +1,38 @@
+// Copyright (C) 2011 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.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+static uchar4 twice(uchar4 in) {
+ return in * 2;
+}
+
+static uchar getConstant() {
+ return 37;
+}
+
+void NOP() {
+ uchar3 x = {1, 2, 3};
+ (void) convert_float3(x);
+}
+
+uchar4 __attribute__((kernel)) setImageAlpha(uchar4 in) {
+ uchar4 out;
+ out.rgba = twice(convert_uchar4((convert_uint4(in.rgba) * 37) >> (uint4)8));
+ out.a = getConstant();
+ NOP();
+ return out;
+}
diff --git a/rsov/compiler/tests/multi_kernel/invert.ll b/rsov/compiler/tests/multi_kernel/invert.ll
new file mode 100644
index 0000000..4f0bae7
--- /dev/null
+++ b/rsov/compiler/tests/multi_kernel/invert.ll
@@ -0,0 +1,52 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: OpEntryPoint GLCompute [[FuncId1:%[0-9]+]] "entry_invert" %gl_GlobalInvocationID
+; CHECK-NEXT: OpEntryPoint GLCompute [[FuncId2:%[0-9]+]] "entry_scalebytwo" %gl_GlobalInvocationID
+
+; Multi-kernel testcase
+;float4 RS_KERNEL invert(float4 a) {
+; return 1.0f - a;
+;}
+
+; CHECK: [[FuncId1]] = OpFunction %void None
+; Function Attrs: norecurse nounwind readnone
+define <4 x float> @invert(<4 x float> %a) local_unnamed_addr #0 {
+entry:
+ %sub = fsub <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, %a
+ ret <4 x float> %sub
+}
+
+
+; CHECK: [[FuncId2]] = OpFunction %void None
+;float RS_KERNEL scalebytwo(float a) {
+; return a*2;
+;}
+
+; Function Attrs: norecurse nounwind readnone
+define float @scalebytwo(float %a) local_unnamed_addr #0 {
+entry:
+ %mul = fmul float %a, 2.000000e+00
+ ret float %mul
+}
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4}
+!\23rs_export_foreach_name = !{!5, !6, !7}
+!\23rs_export_foreach = !{!8, !9, !9}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.275480 (based on LLVM 3.8.275480)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"com.android.rs.rsov.test"}
+!5 = !{!"root"}
+!6 = !{!"invert"}
+!7 = !{!"scalebytwo"}
+!8 = !{!"0"}
+!9 = !{!"35"}
diff --git a/rsov/compiler/tests/rs2spirv_lit_driver.sh b/rsov/compiler/tests/rs2spirv_lit_driver.sh
new file mode 100755
index 0000000..afd6ff3
--- /dev/null
+++ b/rsov/compiler/tests/rs2spirv_lit_driver.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# Copyright 2016, 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.
+
+# TODO: Consider rewriting as a native binary instead of shell script.
+
+if [ $# -lt 1 ]; then
+ echo 1>&2 "$0: not enough arguments"
+ echo 1>&2 $#
+ exit 2
+fi
+
+script_path="$1"
+script_name=$(basename $script_path)
+script=${script_name%.*} # Remove extension.
+
+output_folder="driver_out"
+mkdir -p $output_folder
+
+eval llvm-as "$script_path" -o "$output_folder/$script.bc" &&
+eval rs2spirv "$output_folder/$script.bc" -o "$output_folder/$script.spv" &&
+eval spirv-val "$output_folder/$script.spv"
+
+if [ $? -ne 0 ]; then
+ echo 1>&2 "Generated SPIR-V failed validation"
+ exit -1
+fi
+
+eval spirv-dis --no-color "$output_folder/$script.spv"
+
+RET=$?
+
+#eval rm "$output_folder/$script.*"
+
+exit $RET
diff --git a/rsov/compiler/tests/rs_allocation/access_same.ll b/rsov/compiler/tests/rs_allocation/access_same.ll
new file mode 100644
index 0000000..34dd334
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/access_same.ll
@@ -0,0 +1,84 @@
+; XFAIL: *
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: %struct___GPUBuffer = OpTypeStruct %uchar
+; CHECK: [[PTR_TYPE:%[a-zA-Z_0-9]+]] = OpTypePointer Uniform %struct___GPUBuffer
+
+; CHECK: %__GPUBlock = OpVariable [[PTR_TYPE]] Uniform
+
+%struct.rs_allocation = type { i32* }
+
+@a1 = common global %struct.rs_allocation zeroinitializer, align 4
+@c1 = common global i8 0, align 1
+
+; Function Attrs: nounwind
+define <4 x i8> @k1(<4 x i8> %in) #0 {
+entry:
+ %0 = extractelement <4 x i8> %in, i32 0
+ %conv = zext i8 %0 to i32
+ %1 = extractelement <4 x i8> %in, i32 1
+ %conv1 = zext i8 %1 to i32
+ %.unpack = load i32, i32* bitcast (%struct.rs_allocation* @a1 to i32*), align 4
+ %2 = insertvalue [1 x i32] undef, i32 %.unpack, 0
+ %call = tail call <4 x i8> @_Z21rsGetElementAt_uchar413rs_allocationjj([1 x i32] %2, i32 %conv, i32 %conv1) #2
+ %3 = extractelement <4 x i8> %in, i32 2
+ %conv2 = zext i8 %3 to i32
+ %4 = extractelement <4 x i8> %in, i32 3
+ %conv3 = zext i8 %4 to i32
+ %.unpack14 = load i32, i32* bitcast (%struct.rs_allocation* @a1 to i32*), align 4
+ %5 = insertvalue [1 x i32] undef, i32 %.unpack14, 0
+ tail call void @_Z21rsSetElementAt_uchar413rs_allocationDv4_hjj([1 x i32] %5, <4 x i8> %call, i32 %conv2, i32 %conv3) #2
+ %6 = load i8, i8* @c1, align 1, !tbaa !13
+ %conv4 = zext i8 %6 to i32
+ %7 = extractelement <4 x i8> %call, i32 2
+ %conv5 = zext i8 %7 to i32
+ %add = add nuw nsw i32 %conv4, %conv5
+ %conv6 = trunc i32 %add to i8
+ %8 = insertelement <4 x i8> %call, i8 %conv6, i32 2
+ ret <4 x i8> %8
+}
+
+declare <4 x i8> @_Z21rsGetElementAt_uchar413rs_allocationjj([1 x i32], i32, i32) #1
+
+declare void @_Z21rsSetElementAt_uchar413rs_allocationDv4_hjj([1 x i32], <4 x i8>, i32, i32) #1
+
+; Function Attrs: nounwind
+define void @.rs.dtor() #0 {
+entry:
+ tail call void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation* nonnull @a1) #2
+ ret void
+}
+
+declare void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation*) #1
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_var = !{!6, !7}
+!\23rs_object_slots = !{!8}
+!\23rs_export_foreach_name = !{!9, !10}
+!\23rs_export_foreach = !{!11, !12}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"c1", !"7"}
+!7 = !{!"a1", !"20"}
+!8 = !{!"1"}
+!9 = !{!"root"}
+!10 = !{!"k1"}
+!11 = !{!"0"}
+!12 = !{!"35"}
+!13 = !{!14, !14, i64 0}
+!14 = !{!"omnipotent char", !15, i64 0}
+!15 = !{!"Simple C/C++ TBAA"}
diff --git a/rsov/compiler/tests/rs_allocation/access_same.rs b/rsov/compiler/tests/rs_allocation/access_same.rs
new file mode 100644
index 0000000..7fce3bb
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/access_same.rs
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 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.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+uchar c1;
+rs_allocation a1;
+
+uchar4 __attribute__((kernel)) k1(uchar4 in) {
+ uchar4 res = rsGetElementAt_uchar4(a1, in.r, in.g);
+ rsSetElementAt_uchar4(a1, res, in.b, in.a);
+ res.b += c1;
+ return res;
+}
+
diff --git a/rsov/compiler/tests/rs_allocation/copy_coords.ll b/rsov/compiler/tests/rs_allocation/copy_coords.ll
new file mode 100644
index 0000000..b29e288
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/copy_coords.ll
@@ -0,0 +1,37 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: [[InvocationID:%.*]] = OpLoad %v3uint %gl_GlobalInvocationID
+; CHECK: {{%.*}} = OpCompositeExtract %uint [[InvocationID]] 0
+; CHECK: {{%.*}} = OpCompositeExtract %uint [[InvocationID]] 1
+
+; Function Attrs: norecurse nounwind readnone
+define <4 x i8> @copy_coords(<4 x i8> %in, i32 %x, i32 %y) #0 {
+entry:
+ %conv = trunc i32 %x to i8
+ %0 = insertelement <4 x i8> %in, i8 %conv, i32 0
+ %conv1 = trunc i32 %y to i8
+ %1 = insertelement <4 x i8> %0, i8 %conv1, i32 1
+ ret <4 x i8> %1
+}
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_foreach_name = !{!6, !7}
+!\23rs_export_foreach = !{!8, !9}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"root"}
+!7 = !{!"copy_coords"}
+!8 = !{!"0"}
+!9 = !{!"59"}
diff --git a/rsov/compiler/tests/rs_allocation/copy_coords.rs b/rsov/compiler/tests/rs_allocation/copy_coords.rs
new file mode 100644
index 0000000..2b36ee7
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/copy_coords.rs
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 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.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+uchar4 __attribute__((kernel)) copy_coords(uchar4 in, uint32_t x, uint32_t y) {
+ uchar4 res = in;
+ res.r = (uchar) x;
+ res.g = (uchar) y;
+ return res;
+}
diff --git a/rsov/compiler/tests/rs_allocation/getdimx.ll b/rsov/compiler/tests/rs_allocation/getdimx.ll
new file mode 100644
index 0000000..6fdeca8
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/getdimx.ll
@@ -0,0 +1,76 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+; rs_allocation g;
+; extern uint32_t __rsov_rsAllocationGetDimX(uint32_t ga);
+; int32_t RS_KERNEL getDim(int32_t dummy) {
+; // lowered accessor by an earlier LLVM pass
+; return __rsov_rsAllocationGetDimX(0);
+;}
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+%struct.rs_allocation = type { i32* }
+; CHECK-NOT OpCapability Kernel
+; CHECK-NOT OpDecorate %{{[a-zA-Z_0-9]*}} Alignment {{[0-9]*}}
+; CHECK: OpMemberDecorate [[MetadataS:%[a-zA-Z_0-9]*]] 0 Offset 4
+; CHECK: OpMemberDecorate [[MetadataS]] 1 Offset 8
+; CHECK: OpMemberDecorate [[MetadataS]] 2 Offset 12
+; CHECK: OpMemberDecorate [[MetadataS]] 3 Offset 16
+; CHECK: OpDecorate [[RuntimeArrS:%[a-zA-Z_0-9]*]] ArrayStride {{[0-9]*}}
+; CHECK: OpDecorate [[MetadataSSBO:%[a-zA-Z_0-9]*]] BufferBlock
+; CHECK: OpDecorate [[Metadata:%[a-zA-Z_0-9]*]] DescriptorSet 0
+; CHECK: OpDecorate [[Metadata]] Binding 1
+
+
+; CHECK: [[MetadataSSBO]] = OpTypeStruct [[RuntimeArrS]]
+; CHECK: [[MetadataPtr:%[a-zA-Z_0-9]*]] = OpTypePointer Uniform [[MetadataSSBO]]
+; CHECK: [[Metadata]] = OpVariable [[MetadataPtr]]
+
+@g = common global %struct.rs_allocation zeroinitializer, align 4
+
+
+; CHECK-NOT OpFunctionCall %uint %__rsov_rsAllocationGetDimX %{{[a-zA-Z_0-9]*}}
+; CHECK: [[DimX:%[a-zA-Z_0-9]*]] = OpAccessChain %_ptr_Uniform_uint [[Metadata]]
+; CHECK: [[Res:%[a-zA-Z_0-9]*]] = OpLoad %uint [[DimX]]
+; CHECK: OpReturnValue [[Res]]
+
+; Function Attrs: nounwind
+define i32 @getDim(i32 %dummy) local_unnamed_addr #0 {
+entry:
+ %call = tail call i32 @__rsov_rsAllocationGetDimX(i32 0) #2
+ ret i32 %call
+}
+
+declare i32 @__rsov_rsAllocationGetDimX(i32) local_unnamed_addr #1
+
+; Function Attrs: nounwind
+define void @.rs.dtor() local_unnamed_addr #0 {
+entry:
+ tail call void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation* nonnull @g) #2
+ ret void
+}
+
+declare void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation*) local_unnamed_addr #1
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4}
+!\23rs_export_var = !{!5}
+!\23rs_object_slots = !{!6}
+!\23rs_export_foreach_name = !{!7, !8}
+!\23rs_export_foreach = !{!6, !9}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.275480 (based on LLVM 3.8.275480)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"com.android.rs.rsov.test"}
+!5 = !{!"g", !"20"}
+!6 = !{!"0"}
+!7 = !{!"root"}
+!8 = !{!"getDim"}
+!9 = !{!"35"}
diff --git a/rsov/compiler/tests/rs_allocation/getdimx_64.ll b/rsov/compiler/tests/rs_allocation/getdimx_64.ll
new file mode 100644
index 0000000..c7792cb
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/getdimx_64.ll
@@ -0,0 +1,76 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+; Source:
+; rs_allocation g;
+; int32_t RS_KERNEL getDim(int32_t dummy) {
+; return rsAllocationGetDimX(g);
+; }
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-gnueabi"
+
+; CHECK: OpString "{\"__RSoV_GA\": {\"g\":0}}"
+; CHECK: OpMemberDecorate [[MetadataS:%[a-zA-Z_0-9]*]] 0 Offset 4
+; CHECK: OpMemberDecorate [[MetadataS]] 1 Offset 8
+; CHECK: OpMemberDecorate [[MetadataS]] 2 Offset 12
+; CHECK: OpMemberDecorate [[MetadataS]] 3 Offset 16
+; CHECK: OpDecorate [[RuntimeArrS:%[a-zA-Z_0-9]*]] ArrayStride {{[0-9]*}}
+; CHECK: OpDecorate [[MetadataSSBO:%[a-zA-Z_0-9]*]] BufferBlock
+; CHECK: OpDecorate [[Metadata:%[a-zA-Z_0-9]*]] DescriptorSet 0
+; CHECK: OpDecorate [[Metadata]] Binding 1
+
+%struct.rs_allocation.1 = type { i64*, i64*, i64*, i64* }
+
+@g = common global %struct.rs_allocation.1 zeroinitializer, align 8
+; CHECK-NOT: %g = OpVariable %{{.*}} Uniform
+; CHECK-NOT: OpCopyMemorySized
+; CHECK-NOT: OpFunctionCall %uint %__rsov_rsAllocationGetDimX
+; CHECK: [[DimX:%[a-zA-Z_0-9]*]] = OpAccessChain %_ptr_Uniform_uint [[Metadata]]
+; CHECK: [[Res:%[a-zA-Z_0-9]*]] = OpLoad %uint [[DimX]]
+; CHECK: OpReturnValue [[Res]]
+
+; Function Attrs: nounwind
+define i32 @getDim(i32 %dummy) unnamed_addr #0 {
+entry:
+ %tmp = alloca %struct.rs_allocation.1, align 8
+ %0 = bitcast %struct.rs_allocation.1* %tmp to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.rs_allocation.1* @g to i8*), i64 32, i32 8, i1 false), !tbaa.struct !8
+ %call = call i32 @_Z19rsAllocationGetDimX13rs_allocation(%struct.rs_allocation.1* %tmp) #0
+ ret i32 %call
+}
+
+declare i32 @_Z19rsAllocationGetDimX13rs_allocation(%struct.rs_allocation.1*) unnamed_addr
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #1
+
+; Function Attrs: nounwind
+define void @.rs.dtor() unnamed_addr #0 {
+entry:
+ tail call void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation.1* @g) #0
+ ret void
+}
+
+declare void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation.1*) unnamed_addr
+
+attributes #0 = { nounwind }
+attributes #1 = { argmemonly nounwind }
+
+!llvm.ident = !{!0}
+!\23pragma = !{!1, !2}
+!\23rs_export_var = !{!3}
+!\23rs_object_slots = !{!4}
+!\23rs_export_foreach_name = !{!5, !6}
+!\23rs_export_foreach = !{!4, !7}
+
+!0 = !{!"Android clang version 3.8.275480 (based on LLVM 3.8.275480)"}
+!1 = !{!"version", !"1"}
+!2 = !{!"java_package_name", !"com.android.rs.rsov.test"}
+!3 = !{!"g", !"20"}
+!4 = !{!"0"}
+!5 = !{!"root"}
+!6 = !{!"getDim"}
+!7 = !{!"35"}
+!8 = !{i64 0, i64 8, !9, i64 8, i64 8, !9, i64 16, i64 8, !9, i64 24, i64 8, !9}
+!9 = !{!10, !10, i64 0}
+!10 = !{!"any pointer", !11, i64 0}
+!11 = !{!"omnipotent char", !12, i64 0}
+!12 = !{!"Simple C/C++ TBAA"}
diff --git a/rsov/compiler/tests/rs_allocation/multi_read.ll b/rsov/compiler/tests/rs_allocation/multi_read.ll
new file mode 100644
index 0000000..3e960f5
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/multi_read.ll
@@ -0,0 +1,87 @@
+; XFAIL: *
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: %struct___GPUBuffer = OpTypeStruct %uchar
+; CHECK: [[PTR_TYPE:%[a-zA-Z_0-9]+]] = OpTypePointer Uniform %struct___GPUBuffer
+
+; CHECK: %__GPUBlock = OpVariable [[PTR_TYPE]] Uniform
+
+%struct.rs_allocation = type { i32* }
+
+@a1 = common global %struct.rs_allocation zeroinitializer, align 4
+@a2 = common global %struct.rs_allocation zeroinitializer, align 4
+@c1 = common global i8 0, align 1
+
+; Function Attrs: nounwind
+define <4 x i8> @k1(<4 x i8> %in) #0 {
+entry:
+ %0 = extractelement <4 x i8> %in, i32 0
+ %conv = zext i8 %0 to i32
+ %1 = extractelement <4 x i8> %in, i32 1
+ %conv1 = zext i8 %1 to i32
+ %.unpack = load i32, i32* bitcast (%struct.rs_allocation* @a1 to i32*), align 4
+ %2 = insertvalue [1 x i32] undef, i32 %.unpack, 0
+ %call = tail call <4 x i8> @_Z21rsGetElementAt_uchar413rs_allocationjj([1 x i32] %2, i32 %conv, i32 %conv1) #2
+ %3 = extractelement <4 x i8> %in, i32 2
+ %conv2 = zext i8 %3 to i32
+ %4 = extractelement <4 x i8> %in, i32 3
+ %conv3 = zext i8 %4 to i32
+ %.unpack16 = load i32, i32* bitcast (%struct.rs_allocation* @a2 to i32*), align 4
+ %5 = insertvalue [1 x i32] undef, i32 %.unpack16, 0
+ %call4 = tail call <4 x i8> @_Z21rsGetElementAt_uchar413rs_allocationjj([1 x i32] %5, i32 %conv2, i32 %conv3) #2
+ %add = add <4 x i8> %call4, %call
+ %6 = load i8, i8* @c1, align 1, !tbaa !15
+ %conv5 = zext i8 %6 to i32
+ %7 = extractelement <4 x i8> %add, i32 2
+ %conv6 = zext i8 %7 to i32
+ %add7 = add nuw nsw i32 %conv6, %conv5
+ %conv8 = trunc i32 %add7 to i8
+ %8 = insertelement <4 x i8> %add, i8 %conv8, i32 2
+ ret <4 x i8> %8
+}
+
+declare <4 x i8> @_Z21rsGetElementAt_uchar413rs_allocationjj([1 x i32], i32, i32) #1
+
+; Function Attrs: nounwind
+define void @.rs.dtor() #0 {
+entry:
+ tail call void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation* nonnull @a1) #2
+ tail call void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation* nonnull @a2) #2
+ ret void
+}
+
+declare void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation*) #1
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_var = !{!6, !7, !8}
+!\23rs_object_slots = !{!9, !10}
+!\23rs_export_foreach_name = !{!11, !12}
+!\23rs_export_foreach = !{!13, !14}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"c1", !"7"}
+!7 = !{!"a1", !"20"}
+!8 = !{!"a2", !"20"}
+!9 = !{!"1"}
+!10 = !{!"2"}
+!11 = !{!"root"}
+!12 = !{!"k1"}
+!13 = !{!"0"}
+!14 = !{!"35"}
+!15 = !{!16, !16, i64 0}
+!16 = !{!"omnipotent char", !17, i64 0}
+!17 = !{!"Simple C/C++ TBAA"}
diff --git a/rsov/compiler/tests/rs_allocation/multi_read.rs b/rsov/compiler/tests/rs_allocation/multi_read.rs
new file mode 100644
index 0000000..bebb0f9
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/multi_read.rs
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 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.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+uchar c1;
+rs_allocation a1;
+rs_allocation a2;
+
+uchar4 __attribute__((kernel)) k1(uchar4 in) {
+ uchar4 res = rsGetElementAt_uchar4(a1, in.r, in.g);
+ res += rsGetElementAt_uchar4(a2, in.b, in.a);
+ res.b += c1;
+ return res;
+}
+
diff --git a/rsov/compiler/tests/rs_allocation/read.ll b/rsov/compiler/tests/rs_allocation/read.ll
new file mode 100644
index 0000000..178fdf7
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/read.ll
@@ -0,0 +1,75 @@
+; XFAIL: *
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: %struct___GPUBuffer = OpTypeStruct %uchar
+; CHECK: [[PTR_TYPE:%[a-zA-Z_0-9]+]] = OpTypePointer Uniform %struct___GPUBuffer
+
+; CHECK: %__GPUBlock = OpVariable [[PTR_TYPE]] Uniform
+
+%struct.rs_allocation = type { i32* }
+
+@alloc = common global %struct.rs_allocation zeroinitializer, align 4
+@c1 = common global i8 0, align 1
+
+; Function Attrs: nounwind
+define <4 x i8> @k1(<4 x i8> %in) #0 {
+entry:
+ %0 = extractelement <4 x i8> %in, i32 0
+ %conv = zext i8 %0 to i32
+ %1 = extractelement <4 x i8> %in, i32 1
+ %conv1 = zext i8 %1 to i32
+ %.unpack = load i32, i32* bitcast (%struct.rs_allocation* @alloc to i32*), align 4
+ %2 = insertvalue [1 x i32] undef, i32 %.unpack, 0
+ %call = tail call <4 x i8> @_Z21rsGetElementAt_uchar413rs_allocationjj([1 x i32] %2, i32 %conv, i32 %conv1) #2
+ %3 = load i8, i8* @c1, align 1, !tbaa !13
+ %conv2 = zext i8 %3 to i32
+ %4 = extractelement <4 x i8> %call, i32 2
+ %conv3 = zext i8 %4 to i32
+ %add = add nuw nsw i32 %conv3, %conv2
+ %conv4 = trunc i32 %add to i8
+ %5 = insertelement <4 x i8> %call, i8 %conv4, i32 2
+ ret <4 x i8> %5
+}
+
+declare <4 x i8> @_Z21rsGetElementAt_uchar413rs_allocationjj([1 x i32], i32, i32) #1
+
+; Function Attrs: nounwind
+define void @.rs.dtor() #0 {
+entry:
+ tail call void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation* nonnull @alloc) #2
+ ret void
+}
+
+declare void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation*) #1
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_var = !{!6, !7}
+!\23rs_object_slots = !{!8}
+!\23rs_export_foreach_name = !{!9, !10}
+!\23rs_export_foreach = !{!11, !12}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"c1", !"7"}
+!7 = !{!"alloc", !"20"}
+!8 = !{!"1"}
+!9 = !{!"root"}
+!10 = !{!"k1"}
+!11 = !{!"0"}
+!12 = !{!"35"}
+!13 = !{!14, !14, i64 0}
+!14 = !{!"omnipotent char", !15, i64 0}
+!15 = !{!"Simple C/C++ TBAA"}
diff --git a/rsov/compiler/tests/rs_allocation/read.rs b/rsov/compiler/tests/rs_allocation/read.rs
new file mode 100644
index 0000000..0cde99f
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/read.rs
@@ -0,0 +1,26 @@
+// Copyright (C) 2016 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.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+uchar c1;
+rs_allocation alloc;
+
+uchar4 __attribute__((kernel)) k1(uchar4 in) {
+ uchar4 res = rsGetElementAt_uchar4(alloc, in.r, in.g);
+ res.b += c1;
+ return res;
+}
diff --git a/rsov/compiler/tests/rs_allocation/read_write.ll b/rsov/compiler/tests/rs_allocation/read_write.ll
new file mode 100644
index 0000000..3f0e47f
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/read_write.ll
@@ -0,0 +1,78 @@
+; XFAIL: *
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: %struct___GPUBuffer = OpTypeStruct %uchar
+; CHECK: [[PTR_TYPE:%[a-zA-Z_0-9]+]] = OpTypePointer Uniform %struct___GPUBuffer
+
+; CHECK: %__GPUBlock = OpVariable [[PTR_TYPE]] Uniform
+
+%struct.rs_allocation = type { i32* }
+
+@r = common global %struct.rs_allocation zeroinitializer, align 4
+@w = common global %struct.rs_allocation zeroinitializer, align 4
+@c1 = common global i8 0, align 1
+
+; Function Attrs: nounwind
+define <4 x i8> @k1(<4 x i8> %in, i32 %x, i32 %y) #0 {
+entry:
+ %.unpack = load i32, i32* bitcast (%struct.rs_allocation* @r to i32*), align 4
+ %0 = insertvalue [1 x i32] undef, i32 %.unpack, 0
+ %call = tail call <4 x i8> @_Z21rsGetElementAt_uchar413rs_allocationjj([1 x i32] %0, i32 %x, i32 %y) #2
+ %1 = load i8, i8* @c1, align 1, !tbaa !15
+ %splat.splatinsert = insertelement <4 x i8> undef, i8 %1, i32 0
+ %splat.splat = shufflevector <4 x i8> %splat.splatinsert, <4 x i8> undef, <4 x i32> zeroinitializer
+ %add = add <4 x i8> %call, %in
+ %add1 = add <4 x i8> %add, %splat.splat
+ %.unpack6 = load i32, i32* bitcast (%struct.rs_allocation* @w to i32*), align 4
+ %2 = insertvalue [1 x i32] undef, i32 %.unpack6, 0
+ tail call void @_Z21rsSetElementAt_uchar413rs_allocationDv4_hjj([1 x i32] %2, <4 x i8> %add1, i32 %x, i32 %y) #2
+ ret <4 x i8> %in
+}
+
+declare <4 x i8> @_Z21rsGetElementAt_uchar413rs_allocationjj([1 x i32], i32, i32) #1
+
+declare void @_Z21rsSetElementAt_uchar413rs_allocationDv4_hjj([1 x i32], <4 x i8>, i32, i32) #1
+
+; Function Attrs: nounwind
+define void @.rs.dtor() #0 {
+entry:
+ tail call void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation* nonnull @r) #2
+ tail call void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation* nonnull @w) #2
+ ret void
+}
+
+declare void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation*) #1
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_var = !{!6, !7, !8}
+!\23rs_object_slots = !{!9, !10}
+!\23rs_export_foreach_name = !{!11, !12}
+!\23rs_export_foreach = !{!13, !14}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"c1", !"7"}
+!7 = !{!"r", !"20"}
+!8 = !{!"w", !"20"}
+!9 = !{!"1"}
+!10 = !{!"2"}
+!11 = !{!"root"}
+!12 = !{!"k1"}
+!13 = !{!"0"}
+!14 = !{!"59"}
+!15 = !{!16, !16, i64 0}
+!16 = !{!"omnipotent char", !17, i64 0}
+!17 = !{!"Simple C/C++ TBAA"}
diff --git a/rsov/compiler/tests/rs_allocation/read_write.rs b/rsov/compiler/tests/rs_allocation/read_write.rs
new file mode 100644
index 0000000..8852c82
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/read_write.rs
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 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.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+uchar c1;
+rs_allocation r;
+rs_allocation w;
+
+uchar4 __attribute__((kernel)) k1(uchar4 in, uint32_t x, uint32_t y) {
+ uchar4 read = rsGetElementAt_uchar4(r, x, y);
+ rsSetElementAt_uchar4(w, in + c1 + read, x, y);
+ return in;
+}
diff --git a/rsov/compiler/tests/rs_allocation/rewrite_getdim.ll b/rsov/compiler/tests/rs_allocation/rewrite_getdim.ll
new file mode 100644
index 0000000..c2a9534
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/rewrite_getdim.ll
@@ -0,0 +1,71 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+; Source:
+; rs_allocation g;
+; int32_t RS_KERNEL getDim(int32_t dummy) {
+; return rsAllocationGetDimX(g);
+; }
+source_filename = "global_query4_out/bc32/global_query4.ll"
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: OpMemberDecorate [[MetadataS:%[a-zA-Z_0-9]*]] 0 Offset 4
+; CHECK: OpMemberDecorate [[MetadataS]] 1 Offset 8
+; CHECK: OpMemberDecorate [[MetadataS]] 2 Offset 12
+; CHECK: OpMemberDecorate [[MetadataS]] 3 Offset 16
+; CHECK: OpDecorate [[RuntimeArrS:%[a-zA-Z_0-9]*]] ArrayStride {{[0-9]*}}
+; CHECK: OpDecorate [[MetadataSSBO:%[a-zA-Z_0-9]*]] BufferBlock
+; CHECK: OpDecorate [[Metadata:%[a-zA-Z_0-9]*]] DescriptorSet 0
+; CHECK: OpDecorate [[Metadata]] Binding 1
+
+%struct.rs_allocation = type { i32* }
+
+@g = common global %struct.rs_allocation zeroinitializer, align 4
+
+; CHECK-NOT: %g = OpVariable %{{.*}} Uniform
+; CHECK-NOT: OpFunctionCall %uint %__rsov_rsAllocationGetDimX
+; CHECK: [[DimX:%[a-zA-Z_0-9]*]] = OpAccessChain %_ptr_Uniform_uint [[Metadata]]
+; CHECK: [[Res:%[a-zA-Z_0-9]*]] = OpLoad %uint [[DimX]]
+; CHECK: OpReturnValue [[Res]]
+
+; Function Attrs: nounwind
+define i32 @getDim(i32 %dummy) local_unnamed_addr #0 {
+entry:
+ %.unpack = load i32, i32* bitcast (%struct.rs_allocation* @g to i32*), align 4
+ %0 = insertvalue [1 x i32] undef, i32 %.unpack, 0
+ %call = tail call i32 @_Z19rsAllocationGetDimX13rs_allocation([1 x i32] %0) #2
+ ret i32 %call
+}
+
+declare i32 @_Z19rsAllocationGetDimX13rs_allocation([1 x i32]) local_unnamed_addr #1
+
+; Function Attrs: nounwind
+define void @.rs.dtor() local_unnamed_addr #0 {
+entry:
+ tail call void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation* nonnull @g) #2
+ ret void
+}
+
+declare void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation*) local_unnamed_addr #1
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4}
+!\23rs_export_var = !{!5}
+!\23rs_object_slots = !{!6}
+!\23rs_export_foreach_name = !{!7, !8}
+!\23rs_export_foreach = !{!6, !9}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.275480 (based on LLVM 3.8.275480)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"com.android.rs.rsov.test"}
+!5 = !{!"g", !"20"}
+!6 = !{!"0"}
+!7 = !{!"root"}
+!8 = !{!"getDim"}
+!9 = !{!"35"}
diff --git a/rsov/compiler/tests/rs_allocation/write.ll b/rsov/compiler/tests/rs_allocation/write.ll
new file mode 100644
index 0000000..8865fb6
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/write.ll
@@ -0,0 +1,68 @@
+; XFAIL: *
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+; CHECK: %struct___GPUBuffer = OpTypeStruct {{.*}}
+; CHECK: [[PTR_TYPE:%[a-zA-Z_0-9]+]] = OpTypePointer Uniform %struct___GPUBuffer
+
+; CHECK: %__GPUBlock = OpVariable [[PTR_TYPE]] Uniform
+
+%struct.rs_allocation = type { i32* }
+
+@alloc = common global %struct.rs_allocation zeroinitializer, align 4
+@c1 = common global i8 0, align 1
+
+; Function Attrs: nounwind
+define <4 x i8> @k1(<4 x i8> %in, i32 %x, i32 %y) #0 {
+entry:
+ %0 = load i8, i8* @c1, align 1, !tbaa !13
+ %splat.splatinsert = insertelement <4 x i8> undef, i8 %0, i32 0
+ %splat.splat = shufflevector <4 x i8> %splat.splatinsert, <4 x i8> undef, <4 x i32> zeroinitializer
+ %add = add <4 x i8> %splat.splat, %in
+ %.unpack = load i32, i32* bitcast (%struct.rs_allocation* @alloc to i32*), align 4
+ %1 = insertvalue [1 x i32] undef, i32 %.unpack, 0
+ tail call void @_Z21rsSetElementAt_uchar413rs_allocationDv4_hjj([1 x i32] %1, <4 x i8> %add, i32 %x, i32 %y) #2
+ ret <4 x i8> %in
+}
+
+declare void @_Z21rsSetElementAt_uchar413rs_allocationDv4_hjj([1 x i32], <4 x i8>, i32, i32) #1
+
+; Function Attrs: nounwind
+define void @.rs.dtor() #0 {
+entry:
+ tail call void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation* nonnull @alloc) #2
+ ret void
+}
+
+declare void @_Z13rsClearObjectP13rs_allocation(%struct.rs_allocation*) #1
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "target-features"="+long64" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4, !5}
+!\23rs_export_var = !{!6, !7}
+!\23rs_object_slots = !{!8}
+!\23rs_export_foreach_name = !{!9, !10}
+!\23rs_export_foreach = !{!11, !12}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!"rs_fp_relaxed", !""}
+!6 = !{!"c1", !"7"}
+!7 = !{!"alloc", !"20"}
+!8 = !{!"1"}
+!9 = !{!"root"}
+!10 = !{!"k1"}
+!11 = !{!"0"}
+!12 = !{!"59"}
+!13 = !{!14, !14, i64 0}
+!14 = !{!"omnipotent char", !15, i64 0}
+!15 = !{!"Simple C/C++ TBAA"}
diff --git a/rsov/compiler/tests/rs_allocation/write.rs b/rsov/compiler/tests/rs_allocation/write.rs
new file mode 100644
index 0000000..ef87c7a
--- /dev/null
+++ b/rsov/compiler/tests/rs_allocation/write.rs
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 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.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+uchar c1;
+rs_allocation alloc;
+
+uchar4 __attribute__((kernel)) k1(uchar4 in, uint32_t x, uint32_t y) {
+ rsSetElementAt_uchar4(alloc, in + c1, x, y);
+ return in;
+}
diff --git a/rsov/compiler/tests/run-lit-tests.sh b/rsov/compiler/tests/run-lit-tests.sh
new file mode 100755
index 0000000..54bb559
--- /dev/null
+++ b/rsov/compiler/tests/run-lit-tests.sh
@@ -0,0 +1,17 @@
+#!/bin/bash -e
+
+current_dir=$(pwd)
+export PATH=$current_dir:$PATH
+LIT_PATH=$current_dir/llvm-lit
+LIBSPIRV_TESTS=$current_dir
+
+for arg in $@ ; do
+ if [[ -a "$arg" ]] ; then
+ # Looks like the user specified one or more files,
+ # so don't implicitly specify the current directory.
+ LIBSPIRV_TESTS=
+ break
+ fi
+done
+
+$LIT_PATH $LIBSPIRV_TESTS $@
diff --git a/rsov/compiler/tests/single_kernel/duff.ll b/rsov/compiler/tests/single_kernel/duff.ll
new file mode 100644
index 0000000..535888b
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/duff.ll
@@ -0,0 +1,104 @@
+; Expecting validation failure
+; RUN: not rs2spirv_lit_driver.sh %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-gnueabi"
+
+; CHECK: OpEntryPoint GLCompute %[[WrapperId:[a-zA-Z_0-9]*]] "entry_duff"
+; CHECK: [[KernelId:%[a-zA-Z_0-9]+]] = OpFunction {{.*}}
+; Function Attrs: norecurse nounwind readnone
+define i32 @duff(i32 %count) #0 {
+entry:
+ %add = add nsw i32 %count, 7
+ %div = sdiv i32 %add, 8
+ %rem = srem i32 %count, 8
+ switch i32 %rem, label %sw.epilog [
+ i32 0, label %do.body
+ i32 7, label %sw.bb1
+ i32 6, label %sw.bb2
+ i32 5, label %sw.bb3
+ i32 4, label %sw.bb6
+ i32 3, label %sw.bb8
+ i32 2, label %sw.bb12
+ i32 1, label %sw.bb14
+ ]
+
+do.body: ; preds = %entry, %sw.bb14
+ %n.0 = phi i32 [ %dec15, %sw.bb14 ], [ %div, %entry ]
+ %x.0 = phi i32 [ %shl, %sw.bb14 ], [ 321, %entry ]
+ %mul = mul nsw i32 %x.0, 5
+ br label %sw.bb1
+
+sw.bb1: ; preds = %entry, %do.body
+ %n.1 = phi i32 [ %n.0, %do.body ], [ %div, %entry ]
+ %x.1 = phi i32 [ %mul, %do.body ], [ 321, %entry ]
+ %dec = add nsw i32 %x.1, -1
+ br label %sw.bb2
+
+sw.bb2: ; preds = %entry, %sw.bb1
+ %n.2 = phi i32 [ %n.1, %sw.bb1 ], [ %div, %entry ]
+ %x.2 = phi i32 [ %dec, %sw.bb1 ], [ 321, %entry ]
+ %xor = xor i32 %x.2, 27
+ br label %sw.bb3
+
+sw.bb3: ; preds = %entry, %sw.bb2
+ %n.3 = phi i32 [ %n.2, %sw.bb2 ], [ %div, %entry ]
+ %x.3 = phi i32 [ %xor, %sw.bb2 ], [ 321, %entry ]
+ %mul4 = mul nsw i32 %x.3, %x.3
+ %sub.neg = add i32 %x.3, 12
+ %sub5 = sub i32 %sub.neg, %mul4
+ br label %sw.bb6
+
+sw.bb6: ; preds = %entry, %sw.bb3
+ %n.4 = phi i32 [ %n.3, %sw.bb3 ], [ %div, %entry ]
+ %x.4 = phi i32 [ %sub5, %sw.bb3 ], [ 321, %entry ]
+ %add7 = add nsw i32 %x.4, 2
+ br label %sw.bb8
+
+sw.bb8: ; preds = %entry, %sw.bb6
+ %n.5 = phi i32 [ %n.4, %sw.bb6 ], [ %div, %entry ]
+ %x.5 = phi i32 [ %add7, %sw.bb6 ], [ 321, %entry ]
+ %rem9 = srem i32 %x.5, 32
+ %mul10 = mul nsw i32 %x.5, %x.5
+ %add11 = add nsw i32 %rem9, %mul10
+ br label %sw.bb12
+
+sw.bb12: ; preds = %entry, %sw.bb8
+ %n.6 = phi i32 [ %n.5, %sw.bb8 ], [ %div, %entry ]
+ %x.6 = phi i32 [ %add11, %sw.bb8 ], [ 321, %entry ]
+ %sub13 = add nsw i32 %x.6, -2
+ br label %sw.bb14
+
+sw.bb14: ; preds = %entry, %sw.bb12
+ %n.7 = phi i32 [ %div, %entry ], [ %n.6, %sw.bb12 ]
+ %x.7 = phi i32 [ 321, %entry ], [ %sub13, %sw.bb12 ]
+ %shl = shl i32 %x.7, 3
+ %dec15 = add nsw i32 %n.7, -1
+ %cmp = icmp sgt i32 %n.7, 1
+ br i1 %cmp, label %do.body, label %sw.epilog
+
+sw.epilog: ; preds = %sw.bb14, %entry
+ %x.8 = phi i32 [ 321, %entry ], [ %shl, %sw.bb14 ]
+ ret i32 %x.8
+}
+
+; CHECK: %[[WrapperId]] = OpFunction {{.*}}
+; CHECK-NEXT: OpLabel
+; CHECK: %{{[0-9]+}} = OpFunctionCall %{{.*}} [[KernelId]]
+; CHECK: OpReturn
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+!\23pragma = !{!1, !2, !3}
+!\23rs_export_foreach_name = !{!4, !5}
+!\23rs_export_foreach = !{!6, !7}
+
+!0 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!1 = !{!"version", !"1"}
+!2 = !{!"java_package_name", !"rs2spirv"}
+!3 = !{!"rs_fp_relaxed", !""}
+!4 = !{!"root"}
+!5 = !{!"duff"}
+!6 = !{!"0"}
+!7 = !{!"35"}
diff --git a/rsov/compiler/tests/single_kernel/fib.ll b/rsov/compiler/tests/single_kernel/fib.ll
new file mode 100644
index 0000000..fe62505
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/fib.ll
@@ -0,0 +1,45 @@
+; Expecting validation failure
+; RUN: not rs2spirv_lit_driver.sh %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-gnueabi"
+
+; Function Attrs: nounwind readnone
+; CHECK: OpEntryPoint GLCompute %{{[a-zA-Z_0-9]*}} "entry_fib" %gl_GlobalInvocationID
+define i32 @fib(i32 %n) #0 {
+entry:
+ %n.off8 = add i32 %n, -1
+ %0 = icmp ult i32 %n.off8, 2
+ br i1 %0, label %return, label %if.end
+
+if.end: ; preds = %entry, %if.end
+ %n.tr10 = phi i32 [ %sub2, %if.end ], [ %n, %entry ]
+ %accumulator.tr9 = phi i32 [ %add, %if.end ], [ 1, %entry ]
+ %sub = add nsw i32 %n.tr10, -1
+ %call = tail call i32 @fib(i32 %sub)
+ %sub2 = add nsw i32 %n.tr10, -2
+ %add = add nsw i32 %call, %accumulator.tr9
+ %n.off = add i32 %n.tr10, -3
+ %1 = icmp ult i32 %n.off, 2
+ br i1 %1, label %return, label %if.end
+
+return: ; preds = %if.end, %entry
+ %accumulator.tr.lcssa = phi i32 [ 1, %entry ], [ %add, %if.end ]
+ ret i32 %accumulator.tr.lcssa
+}
+
+attributes #0 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+!\23pragma = !{!1, !2, !3}
+!\23rs_export_foreach_name = !{!4, !5}
+!\23rs_export_foreach = !{!6, !7}
+
+!0 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!1 = !{!"version", !"1"}
+!2 = !{!"java_package_name", !"rs2spirv"}
+!3 = !{!"rs_fp_relaxed", !""}
+!4 = !{!"root"}
+!5 = !{!"fib"}
+!6 = !{!"0"}
+!7 = !{!"35"}
diff --git a/rsov/compiler/tests/single_kernel/identity.ll b/rsov/compiler/tests/single_kernel/identity.ll
new file mode 100644
index 0000000..4195442
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/identity.ll
@@ -0,0 +1,27 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-gnueabi"
+
+; Function Attrs: norecurse nounwind readnone
+; CHECK: OpEntryPoint GLCompute %{{[a-zA-Z_0-9]*}} "entry_foo" %gl_GlobalInvocationID{{.*}}
+define i32 @foo(i32 %in) #0 {
+; CHECK: OpReturnValue {{.*}}
+ ret i32 %in
+}
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+!\23pragma = !{!1, !2, !3}
+!\23rs_export_foreach_name = !{!4, !5}
+!\23rs_export_foreach = !{!6, !7}
+
+!0 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!1 = !{!"version", !"1"}
+!2 = !{!"java_package_name", !"rs2spirv"}
+!3 = !{!"rs_fp_relaxed", !""}
+!4 = !{!"root"}
+!5 = !{!"foo"}
+!6 = !{!"0"}
+!7 = !{!"35"}
diff --git a/rsov/compiler/tests/single_kernel/identity.rs b/rsov/compiler/tests/single_kernel/identity.rs
new file mode 100644
index 0000000..a3bdb6e
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/identity.rs
@@ -0,0 +1,9 @@
+// TODO: Complete the test.
+
+#pragma version(1)
+#pragma rs java_package_name(rs2srpiv)
+#pragma rs_fp_relaxed
+
+int __attribute__((kernel)) foo(int in) {
+ return in;
+}
diff --git a/rsov/compiler/tests/single_kernel/invert.ll b/rsov/compiler/tests/single_kernel/invert.ll
new file mode 100644
index 0000000..8a9efdb
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/invert.ll
@@ -0,0 +1,46 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-gnueabi"
+
+; Function Attrs: norecurse nounwind readnone
+; CHECK:OpDecorate %[[BUF_S:.*]] BufferBlock
+; CHECK:OpDecorate %[[BUF_VAR:.*]] DescriptorSet {{[0-9]}}
+; CHECK:OpDecorate %[[BUF_VAR]] Binding {{[0-9]}}
+; CHECK:%[[BUF_PTR_TY:.*]] = OpTypePointer Uniform %[[BUF_S]]
+; CHECK:%[[BUF_VAR]] = OpVariable %[[BUF_PTR_TY]] Uniform
+; CHECK:%[[ADDR:.*]] = OpAccessChain {{.*}} %[[BUF_VAR]]
+; CHECK:OpLoad {{.*}} %[[ADDR]]
+
+define <4 x float> @invert(<4 x float> %in) #0 {
+entry:
+ %0 = extractelement <4 x float> %in, i64 0
+ %sub = fsub float 1.000000e+00, %0
+ %1 = insertelement <4 x float> undef, float %sub, i64 0
+ %2 = extractelement <4 x float> %in, i64 1
+ %sub1 = fsub float 1.000000e+00, %2
+ %3 = insertelement <4 x float> %1, float %sub1, i64 1
+ %4 = extractelement <4 x float> %in, i64 2
+ %sub2 = fsub float 1.000000e+00, %4
+ %5 = insertelement <4 x float> %3, float %sub2, i64 2
+ %6 = extractelement <4 x float> %in, i64 3
+ %sub3 = fsub float 1.000000e+00, %6
+ %7 = insertelement <4 x float> %5, float %sub3, i64 3
+ ret <4 x float> %7
+}
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+!\23pragma = !{!1, !2, !3}
+!\23rs_export_foreach_name = !{!4, !5}
+!\23rs_export_foreach = !{!6, !7}
+
+!0 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!1 = !{!"version", !"1"}
+!2 = !{!"java_package_name", !"rs2spirv"}
+!3 = !{!"rs_fp_relaxed", !""}
+!4 = !{!"root"}
+!5 = !{!"invert"}
+!6 = !{!"0"}
+!7 = !{!"35"}
diff --git a/rsov/compiler/tests/single_kernel/kernel.ll b/rsov/compiler/tests/single_kernel/kernel.ll
new file mode 100644
index 0000000..03bea0e
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/kernel.ll
@@ -0,0 +1,32 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-gnueabi"
+
+; CHECK: OpEntryPoint GLCompute [[WrapperId:%[a-zA-Z_0-9]*]] "entry_foo"
+; CHECK: [[KernelId:%[a-zA-Z_0-9]+]] = OpFunction {{.*}}
+
+; Function Attrs: norecurse nounwind readnone
+define void @foo() #0 {
+ ret void
+}
+; CHECK: [[WrapperId]] = OpFunction {{.*}}
+; CHECK-NEXT: OpLabel
+; CHECK-NEXT: %{{[0-9]+}} = OpFunctionCall %{{.*}} [[KernelId]]
+; CHECK-NEXT: OpReturn
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+!\23pragma = !{!1, !2, !3}
+!\23rs_export_foreach_name = !{!4, !5}
+!\23rs_export_foreach = !{!6, !7}
+
+!0 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!1 = !{!"version", !"1"}
+!2 = !{!"java_package_name", !"rs2srpiv"}
+!3 = !{!"rs_fp_relaxed", !""}
+!4 = !{!"root"}
+!5 = !{!"foo"}
+!6 = !{!"0"}
+!7 = !{!"32"}
diff --git a/rsov/compiler/tests/single_kernel/kernel.rs b/rsov/compiler/tests/single_kernel/kernel.rs
new file mode 100644
index 0000000..2e38a13
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/kernel.rs
@@ -0,0 +1,6 @@
+#pragma version(1)
+#pragma rs java_package_name(rs2spirv)
+#pragma rs_fp_relaxed
+
+void __attribute__((kernel)) foo() {
+}
diff --git a/rsov/compiler/tests/single_kernel/mixed.ll b/rsov/compiler/tests/single_kernel/mixed.ll
new file mode 100644
index 0000000..c968ccc
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/mixed.ll
@@ -0,0 +1,66 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+; CHECK: OpEntryPoint GLCompute %{{[a-zA-Z_0-9]*}} "entry_inc" %gl_GlobalInvocationID
+; CHECK-NOT: an_invokable
+
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+@.str = private unnamed_addr constant [24 x i8] c"test_root_output FAILED\00", align 1
+
+; Function Attrs: nounwind
+define void @an_invokable(float %i) local_unnamed_addr #0 {
+entry:
+ %call = tail call fastcc float @sum(float %i, float 2.000000e+00)
+ %conv = fptosi float %call to i32
+ tail call void @_Z7rsDebugPKci(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str, i32 0, i32 0), i32 %conv) #4
+ ret void
+}
+
+declare void @_Z7rsDebugPKci(i8*, i32) local_unnamed_addr #1
+
+; Function Attrs: norecurse nounwind readnone
+define internal fastcc float @sum(float %i, float %j) unnamed_addr #2 {
+entry:
+ %add = fadd float %i, %j
+ ret float %add
+}
+
+; Function Attrs: norecurse nounwind readnone
+define float @inc(float %i) local_unnamed_addr #2 {
+entry:
+ %call = tail call fastcc float @sum(float %i, float 1.000000e+00)
+ ret float %call
+}
+
+; Function Attrs: noinline nounwind
+define void @.helper_an_invokable({ float }* nocapture) local_unnamed_addr #3 {
+entry:
+ %1 = getelementptr inbounds { float }, { float }* %0, i32 0, i32 0
+ %2 = load float, float* %1, align 4
+ tail call void @an_invokable(float %2)
+ ret void
+}
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #3 = { noinline nounwind }
+attributes #4 = { nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4}
+!\23rs_export_func = !{!5}
+!\23rs_export_foreach_name = !{!6, !7}
+!\23rs_export_foreach = !{!8, !9}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"Android clang version 3.8.275480 (based on LLVM 3.8.275480)"}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"rs2spirv"}
+!5 = !{!".helper_an_invokable"}
+!6 = !{!"root"}
+!7 = !{!"inc"}
+!8 = !{!"0"}
+!9 = !{!"35"}
diff --git a/rsov/compiler/tests/single_kernel/newroot.ll b/rsov/compiler/tests/single_kernel/newroot.ll
new file mode 100644
index 0000000..c1055b3
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/newroot.ll
@@ -0,0 +1,30 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-gnueabi"
+
+; CHECK: OpEntryPoint GLCompute [[WrapperId:%[a-zA-Z_0-9]*]] "entry_root"
+; CHECK: [[KernelId:%[a-zA-Z_0-9]+]] = OpFunction {{.*}}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @root(i32 %a) #0 {
+ ret i32 %a
+}
+; CHECK: [[WrapperId]] = OpFunction {{.*}}
+; CHECK-NEXT: OpLabel
+; CHECK: %{{[0-9]+}} = OpFunctionCall %{{.*}} [[KernelId]]
+; CHECK: OpReturn
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+!\23pragma = !{!1, !2, !3}
+!\23rs_export_foreach_name = !{!4}
+!\23rs_export_foreach = !{!5}
+
+!0 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!1 = !{!"version", !"1"}
+!2 = !{!"java_package_name", !"rs2srpiv"}
+!3 = !{!"rs_fp_relaxed", !""}
+!4 = !{!"root"}
+!5 = !{!"35"}
diff --git a/rsov/compiler/tests/single_kernel/oldroot.ll b/rsov/compiler/tests/single_kernel/oldroot.ll
new file mode 100644
index 0000000..1f3da89
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/oldroot.ll
@@ -0,0 +1,23 @@
+; RUN: not rs2spirv_lit_driver.sh %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-gnueabi"
+
+; Function Attrs: norecurse nounwind readnone
+define void @root(i8 *%in, i8 *%out, i32 %x, i32 %y) #0 {
+ ret void
+}
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+!\23pragma = !{!1, !2, !3}
+!\23rs_export_foreach_name = !{!4}
+!\23rs_export_foreach = !{!5}
+
+!0 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!1 = !{!"version", !"1"}
+!2 = !{!"java_package_name", !"rs2srpiv"}
+!3 = !{!"rs_fp_relaxed", !""}
+!4 = !{!"root"}
+!5 = !{!"27"}
diff --git a/rsov/compiler/tests/single_kernel/times.ll b/rsov/compiler/tests/single_kernel/times.ll
new file mode 100644
index 0000000..e63bfee
--- /dev/null
+++ b/rsov/compiler/tests/single_kernel/times.ll
@@ -0,0 +1,35 @@
+; RUN: rs2spirv_lit_driver.sh %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-gnueabi"
+
+; CHECK: OpEntryPoint GLCompute %[[WrapperId:[a-zA-Z_0-9]*]] "entry_times"
+; CHECK: [[KernelId:%[a-zA-Z_0-9]+]] = OpFunction {{.*}}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @times(i32 %x) #0 {
+entry:
+ %mul = shl i32 %x, 1
+ ret i32 %mul
+}
+
+; CHECK: %[[WrapperId]] = OpFunction {{.*}}
+; CHECK-NEXT: OpLabel
+; CHECK: %{{[0-9]+}} = OpFunctionCall %{{.*}} [[KernelId]]
+; CHECK: OpReturn
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="0" "stackrealign" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+!\23pragma = !{!1, !2, !3}
+!\23rs_export_foreach_name = !{!4, !5}
+!\23rs_export_foreach = !{!6, !7}
+
+!0 = !{!"Android clang version 3.8.256229 (based on LLVM 3.8.256229)"}
+!1 = !{!"version", !"1"}
+!2 = !{!"java_package_name", !"rs2spirv"}
+!3 = !{!"rs_fp_relaxed", !""}
+!4 = !{!"root"}
+!5 = !{!"times"}
+!6 = !{!"0"}
+!7 = !{!"42"}
diff --git a/rsov/compiler/unit_tests/TestRunner.h b/rsov/compiler/unit_tests/TestRunner.h
new file mode 100644
index 0000000..4e8f57a
--- /dev/null
+++ b/rsov/compiler/unit_tests/TestRunner.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2016, 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.
+ */
+
+#ifndef RS2SPIRV_TEST_RUNNER
+#define RS2SPIRV_TEST_RUNNER
+
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <cassert>
+#include <vector>
+
+namespace rs2spirv {
+
+struct TestCase {
+ void (*testPtr)(void);
+ const char *const description;
+};
+
+class TestRunnerContext {
+public:
+ static TestRunnerContext &getInstance() {
+ static TestRunnerContext ctx;
+ return ctx;
+ }
+
+ static void addTest(TestCase TC) { getInstance().tests.push_back(TC); }
+ static size_t &getCheckSuccessNum() { return getInstance().checkSuccessNum; }
+ static size_t &getTotalCheckNum() { return getInstance().totalCheckNum; }
+
+ static int runTests() {
+ bool Failed = false;
+ for (auto &TC : getInstance().tests) {
+ getCheckSuccessNum() = getTotalCheckNum() = 0;
+ llvm::outs() << "Test(" << TC.description << ") {\n";
+ TC.testPtr();
+ llvm::outs() << "\n} (" << TC.description << ") [" << getCheckSuccessNum()
+ << "/" << getTotalCheckNum() << "]\n\n";
+ Failed |= getCheckSuccessNum() != getTotalCheckNum();
+ }
+
+ return static_cast<int>(Failed);
+ }
+
+private:
+ TestRunnerContext() = default;
+ std::vector<TestCase> tests;
+ size_t checkSuccessNum;
+ size_t totalCheckNum;
+};
+
+struct TestAdder {
+ TestAdder(TestCase TC) { TestRunnerContext::addTest(TC); }
+};
+
+#define RS2SPIRV_CONCAT_IMPL(S1, S2) S1##S2
+#define RS2SPIRV_CONCAT(S1, S2) RS2SPIRV_CONCAT_IMPL(S1, S2)
+#define RS2SPIRV_ANONYMOUS(X) RS2SPIRV_CONCAT(X, __COUNTER__)
+
+#if RS2SPIRV_DEBUG
+#define RS2SPIRV_TEST_CASE_ADD_IMPL(FNAME, VNAME, DESCRIPTION) \
+ static void FNAME(); \
+ static rs2spirv::TestAdder VNAME({FNAME, DESCRIPTION}); \
+ inline void FNAME()
+#elif defined(__GNUC__) || defined(__clang__)
+#define RS2SPIRV_TEST_CASE_ADD_IMPL(FNAME, VNAME, DESCRIPTION) \
+ static inline void __attribute__((unused)) FNAME()
+#else
+#define RS2SPIRV_TEST_CASE_ADD_IMPL(FNAME, VNAME, DESCRIPTION) \
+ static inline void FNAME()
+#endif
+
+#define RS2SPIRV_TEST_CASE_ADD(NAME, DESCRIPTION) \
+ RS2SPIRV_TEST_CASE_ADD_IMPL(RS2SPIRV_ANONYMOUS(NAME), \
+ RS2SPIRV_ANONYMOUS(NAME), DESCRIPTION)
+
+#define TEST_CASE(DESCRIPTION) RS2SPIRV_TEST_CASE_ADD(TC, DESCRIPTION)
+
+#define CHECK(CONDITION) \
+ ++rs2spirv::TestRunnerContext::getTotalCheckNum(); \
+ if (!(CONDITION)) \
+ llvm::errs() << "\nCHECK <( " #CONDITION " )> failed!\n"; \
+ else \
+ ++rs2spirv::TestRunnerContext::getCheckSuccessNum(); \
+ (void)0
+
+} // namespace rs2spirv
+
+#endif
diff --git a/rsov/driver/.clang-format b/rsov/driver/.clang-format
new file mode 100644
index 0000000..e8b6a2d
--- /dev/null
+++ b/rsov/driver/.clang-format
@@ -0,0 +1,95 @@
+---
+Language: Cpp
+# BasedOnStyle: Google
+AccessModifierOffset: -1
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: true
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: true
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: false
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: true
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeCategories:
+ - Regex: '^<.*\.h>'
+ Priority: 1
+ - Regex: '^<.*'
+ Priority: 2
+ - Regex: '.*'
+ Priority: 3
+IncludeIsMainRegex: '([-_](test|unittest))?$'
+IndentCaseLabels: true
+IndentWidth: 2
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: false
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Auto
+TabWidth: 8
+UseTab: Never
+...
+
diff --git a/rsov/driver/Android.mk b/rsov/driver/Android.mk
new file mode 100644
index 0000000..8154c9e
--- /dev/null
+++ b/rsov/driver/Android.mk
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2016 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.
+#
+
+LOCAL_PATH :=$(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libRSDriver_RSoV
+
+LOCAL_SRC_FILES := \
+ rsovAllocation.cpp \
+ rsovContext.cpp \
+ rsovCore.cpp \
+ rsovElement.cpp \
+ rsovRuntimeStubs.cpp \
+ rsovSampler.cpp \
+ rsovScript.cpp \
+ rsovScriptGroup.cpp \
+ rsovType.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libRS_internal \
+ libRSCpuRef \
+ libbcinfo \
+ libc++ \
+ liblog \
+ libspirit \
+ libvulkan \
+ libgui
+
+LOCAL_C_INCLUDES := \
+ frameworks/compile/libbcc/include \
+ frameworks/native/vulkan/include \
+ frameworks/rs \
+ frameworks/rs/cpu_ref \
+ frameworks/rs/rsov/compiler \
+
+LOCAL_C_INCLUDES += \
+
+LOCAL_CFLAGS := -Werror -Wall -Wextra
+# TODO: remove warnings on unused variables and parameters
+LOCAL_CFLAGS += -Wno-unused-variable -Wno-unused-parameter
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/rsov/driver/rsovAllocation.cpp b/rsov/driver/rsovAllocation.cpp
new file mode 100644
index 0000000..b9d3c98
--- /dev/null
+++ b/rsov/driver/rsovAllocation.cpp
@@ -0,0 +1,698 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "rsovAllocation.h"
+
+#include "rsAllocation.h"
+#include "rsContext.h"
+#include "rsCppUtils.h"
+#include "rsElement.h"
+#include "rsType.h"
+#include "rsovContext.h"
+#include "rsovCore.h"
+
+namespace android {
+namespace renderscript {
+namespace rsov {
+
+namespace {
+
+size_t DeriveYUVLayout(int yuv, Allocation::Hal::DrvState *state) {
+ // For the flexible YCbCr format, layout is initialized during call to
+ // Allocation::ioReceive. Return early and avoid clobberring any
+ // pre-existing layout.
+ if (yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ return 0;
+ }
+
+ // YUV only supports basic 2d
+ // so we can stash the plane pointers in the mipmap levels.
+ size_t uvSize = 0;
+ state->lod[1].dimX = state->lod[0].dimX / 2;
+ state->lod[1].dimY = state->lod[0].dimY / 2;
+ state->lod[2].dimX = state->lod[0].dimX / 2;
+ state->lod[2].dimY = state->lod[0].dimY / 2;
+ state->yuv.shift = 1;
+ state->yuv.step = 1;
+ state->lodCount = 3;
+
+ switch (yuv) {
+ case HAL_PIXEL_FORMAT_YV12:
+ state->lod[2].stride = rsRound(state->lod[0].stride >> 1, 16);
+ state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
+ (state->lod[0].stride * state->lod[0].dimY);
+ uvSize += state->lod[2].stride * state->lod[2].dimY;
+
+ state->lod[1].stride = state->lod[2].stride;
+ state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) +
+ (state->lod[2].stride * state->lod[2].dimY);
+ uvSize += state->lod[1].stride * state->lod[2].dimY;
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
+ // state->lod[1].dimX = state->lod[0].dimX;
+ state->lod[1].stride = state->lod[0].stride;
+ state->lod[2].stride = state->lod[0].stride;
+ state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
+ (state->lod[0].stride * state->lod[0].dimY);
+ state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) + 1;
+ uvSize += state->lod[1].stride * state->lod[1].dimY;
+ state->yuv.step = 2;
+ break;
+ default:
+ rsAssert(0);
+ }
+
+ return uvSize;
+}
+
+// TODO: Dedup this with the same code under frameworks/rs/driver
+size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
+ const Type *type, uint8_t *ptr,
+ size_t requiredAlignment) {
+ alloc->mHal.drvState.lod[0].dimX = type->getDimX();
+ alloc->mHal.drvState.lod[0].dimY = type->getDimY();
+ alloc->mHal.drvState.lod[0].dimZ = type->getDimZ();
+ alloc->mHal.drvState.lod[0].mallocPtr = 0;
+ // Stride needs to be aligned to a boundary defined by requiredAlignment!
+ size_t stride =
+ alloc->mHal.drvState.lod[0].dimX * type->getElementSizeBytes();
+ alloc->mHal.drvState.lod[0].stride = rsRound(stride, requiredAlignment);
+ alloc->mHal.drvState.lodCount = type->getLODCount();
+ alloc->mHal.drvState.faceCount = type->getDimFaces();
+
+ size_t offsets[Allocation::MAX_LOD];
+ memset(offsets, 0, sizeof(offsets));
+
+ size_t o = alloc->mHal.drvState.lod[0].stride *
+ rsMax(alloc->mHal.drvState.lod[0].dimY, 1u) *
+ rsMax(alloc->mHal.drvState.lod[0].dimZ, 1u);
+ if (alloc->mHal.state.yuv) {
+ o += DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);
+
+ for (uint32_t ct = 1; ct < alloc->mHal.drvState.lodCount; ct++) {
+ offsets[ct] = (size_t)alloc->mHal.drvState.lod[ct].mallocPtr;
+ }
+ } else if (alloc->mHal.drvState.lodCount > 1) {
+ uint32_t tx = alloc->mHal.drvState.lod[0].dimX;
+ uint32_t ty = alloc->mHal.drvState.lod[0].dimY;
+ uint32_t tz = alloc->mHal.drvState.lod[0].dimZ;
+ for (uint32_t lod = 1; lod < alloc->mHal.drvState.lodCount; lod++) {
+ alloc->mHal.drvState.lod[lod].dimX = tx;
+ alloc->mHal.drvState.lod[lod].dimY = ty;
+ alloc->mHal.drvState.lod[lod].dimZ = tz;
+ alloc->mHal.drvState.lod[lod].stride =
+ rsRound(tx * type->getElementSizeBytes(), requiredAlignment);
+ offsets[lod] = o;
+ o += alloc->mHal.drvState.lod[lod].stride * rsMax(ty, 1u) * rsMax(tz, 1u);
+ if (tx > 1) tx >>= 1;
+ if (ty > 1) ty >>= 1;
+ if (tz > 1) tz >>= 1;
+ }
+ }
+
+ alloc->mHal.drvState.faceOffset = o;
+
+ alloc->mHal.drvState.lod[0].mallocPtr = ptr;
+ for (uint32_t lod = 1; lod < alloc->mHal.drvState.lodCount; lod++) {
+ alloc->mHal.drvState.lod[lod].mallocPtr = ptr + offsets[lod];
+ }
+
+ size_t allocSize = alloc->mHal.drvState.faceOffset;
+ if (alloc->mHal.drvState.faceCount) {
+ allocSize *= 6;
+ }
+
+ return allocSize;
+}
+
+size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
+ const Type *type, uint8_t *ptr) {
+ return AllocationBuildPointerTable(rsc, alloc, type, ptr,
+ Allocation::kMinimumRSAlignment);
+}
+
+uint8_t *GetOffsetPtr(const Allocation *alloc, uint32_t xoff, uint32_t yoff,
+ uint32_t zoff, uint32_t lod,
+ RsAllocationCubemapFace face) {
+ uint8_t *ptr = (uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
+ ptr += face * alloc->mHal.drvState.faceOffset;
+ ptr += zoff * alloc->mHal.drvState.lod[lod].dimY *
+ alloc->mHal.drvState.lod[lod].stride;
+ ptr += yoff * alloc->mHal.drvState.lod[lod].stride;
+ ptr += xoff * alloc->mHal.state.elementSizeBytes;
+ return ptr;
+}
+
+void mip565(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
+ uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
+ uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
+
+ for (uint32_t y = 0; y < h; y++) {
+ uint16_t *oPtr = (uint16_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
+ const uint16_t *i1 =
+ (uint16_t *)GetOffsetPtr(alloc, 0, 0, y * 2, lod, face);
+ const uint16_t *i2 =
+ (uint16_t *)GetOffsetPtr(alloc, 0, 0, y * 2 + 1, lod, face);
+
+ for (uint32_t x = 0; x < w; x++) {
+ *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
+ oPtr++;
+ i1 += 2;
+ i2 += 2;
+ }
+ }
+}
+
+void mip8888(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
+ uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
+ uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
+
+ for (uint32_t y = 0; y < h; y++) {
+ uint32_t *oPtr = (uint32_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
+ const uint32_t *i1 =
+ (uint32_t *)GetOffsetPtr(alloc, 0, y * 2, 0, lod, face);
+ const uint32_t *i2 =
+ (uint32_t *)GetOffsetPtr(alloc, 0, y * 2 + 1, 0, lod, face);
+
+ for (uint32_t x = 0; x < w; x++) {
+ *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
+ oPtr++;
+ i1 += 2;
+ i2 += 2;
+ }
+ }
+}
+
+void mip8(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
+ uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
+ uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
+
+ for (uint32_t y = 0; y < h; y++) {
+ uint8_t *oPtr = GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
+ const uint8_t *i1 = GetOffsetPtr(alloc, 0, y * 2, 0, lod, face);
+ const uint8_t *i2 = GetOffsetPtr(alloc, 0, y * 2 + 1, 0, lod, face);
+
+ for (uint32_t x = 0; x < w; x++) {
+ *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
+ oPtr++;
+ i1 += 2;
+ i2 += 2;
+ }
+ }
+}
+
+} // anonymous namespace
+
+RSoVAllocation::RSoVAllocation(RSoVContext *context, const Type *type,
+ size_t bufferSize)
+ : mBuffer(new RSoVBuffer(context, bufferSize)),
+ mType(type),
+ mWidth(type->getDimX()),
+ mHeight(type->getDimY()),
+ mDepth(type->getDimZ()) {}
+
+RSoVBuffer::RSoVBuffer(RSoVContext *context, size_t size)
+ : mRSoV(context), mDevice(context->getDevice()) {
+ InitBuffer(size);
+}
+
+RSoVBuffer::~RSoVBuffer() {
+ vkUnmapMemory(mDevice, mMem);
+ vkDestroyBuffer(mDevice, mBuf, nullptr);
+ vkFreeMemory(mDevice, mMem, nullptr);
+}
+
+void RSoVBuffer::InitBuffer(size_t bufferSize) {
+ VkResult res;
+
+ VkBufferCreateInfo buf_info = {
+ .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
+ .pNext = nullptr,
+ .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+ .size = bufferSize,
+ .queueFamilyIndexCount = 0,
+ .pQueueFamilyIndices = nullptr,
+ .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
+ .flags = 0,
+ };
+ res = vkCreateBuffer(mDevice, &buf_info, nullptr, &mBuf);
+ rsAssert(res == VK_SUCCESS);
+
+ VkMemoryRequirements mem_reqs;
+ vkGetBufferMemoryRequirements(mDevice, mBuf, &mem_reqs);
+
+ VkMemoryAllocateInfo allocateInfo = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+ .pNext = nullptr,
+ .memoryTypeIndex = 0,
+ .allocationSize = mem_reqs.size,
+ };
+
+ bool pass;
+ pass =
+ mRSoV->MemoryTypeFromProperties(mem_reqs.memoryTypeBits,
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
+ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+ &allocateInfo.memoryTypeIndex);
+ rsAssert(pass);
+
+ // TODO: Make this aligned
+ res = vkAllocateMemory(mDevice, &allocateInfo, nullptr, &mMem);
+ rsAssert(res == VK_SUCCESS);
+
+ res = vkBindBufferMemory(mDevice, mBuf, mMem, 0);
+ rsAssert(res == VK_SUCCESS);
+
+ mBufferInfo.buffer = mBuf;
+ mBufferInfo.offset = 0;
+ mBufferInfo.range = bufferSize;
+
+ res = vkMapMemory(mDevice, mMem, 0, mem_reqs.size, 0, (void **)&mPtr);
+ rsAssert(res == VK_SUCCESS);
+}
+
+} // namespace rsov
+} // namespace renderscript
+} // namespace android
+
+using android::renderscript::Allocation;
+using android::renderscript::Context;
+using android::renderscript::Element;
+using android::renderscript::Type;
+using android::renderscript::rs_allocation;
+using android::renderscript::rsMax;
+using namespace android::renderscript::rsov;
+
+bool rsovAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
+ RSoVHal *hal = static_cast<RSoVHal *>(rsc->mHal.drv);
+ RSoVContext *rsov = hal->mRSoV;
+ const Type *type = alloc->getType();
+
+ // Calculate the object size.
+ size_t allocSize = AllocationBuildPointerTable(rsc, alloc, type, nullptr);
+ RSoVAllocation *rsovAlloc = new RSoVAllocation(rsov, type, allocSize);
+ alloc->mHal.drv = rsovAlloc;
+ AllocationBuildPointerTable(rsc, alloc, type,
+ (uint8_t *)rsovAlloc->getHostPtr());
+ return true;
+}
+
+void rsovAllocationDestroy(const Context *rsc, Allocation *alloc) {
+ RSoVAllocation *rsovAlloc = static_cast<RSoVAllocation *>(alloc->mHal.drv);
+ delete rsovAlloc;
+ alloc->mHal.drv = nullptr;
+}
+
+void rsovAllocationData1D(const Context *rsc, const Allocation *alloc,
+ uint32_t xoff, uint32_t lod, size_t count,
+ const void *data, size_t sizeBytes) {
+ const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
+ uint8_t *ptr =
+ GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
+ size_t size = count * eSize;
+ if (ptr != data) {
+ // Skip the copy if we are the same allocation. This can arise from
+ // our Bitmap optimization, where we share the same storage.
+ if (alloc->mHal.state.hasReferences) {
+ alloc->incRefs(data, count);
+ alloc->decRefs(ptr, count);
+ }
+ memcpy(ptr, data, size);
+ }
+}
+
+void rsovAllocationData2D(const Context *rsc, const Allocation *alloc,
+ uint32_t xoff, uint32_t yoff, uint32_t lod,
+ RsAllocationCubemapFace face, uint32_t w, uint32_t h,
+ const void *data, size_t sizeBytes, size_t stride) {
+ size_t eSize = alloc->mHal.state.elementSizeBytes;
+ size_t lineSize = eSize * w;
+ if (!stride) {
+ stride = lineSize;
+ }
+
+ if (alloc->mHal.drvState.lod[0].mallocPtr) {
+ const uint8_t *src = static_cast<const uint8_t *>(data);
+ uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
+
+ for (uint32_t line = yoff; line < (yoff + h); line++) {
+ if (alloc->mHal.state.hasReferences) {
+ alloc->incRefs(src, w);
+ alloc->decRefs(dst, w);
+ }
+ memcpy(dst, src, lineSize);
+ src += stride;
+ dst += alloc->mHal.drvState.lod[lod].stride;
+ }
+ // TODO: handle YUV Allocations
+ if (alloc->mHal.state.yuv) {
+ size_t clineSize = lineSize;
+ int lod = 1;
+ int maxLod = 2;
+ if (alloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YV12) {
+ maxLod = 3;
+ clineSize >>= 1;
+ } else if (alloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
+ lod = 2;
+ maxLod = 3;
+ }
+
+ while (lod < maxLod) {
+ uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
+
+ for (uint32_t line = (yoff >> 1); line < ((yoff + h) >> 1); line++) {
+ memcpy(dst, src, clineSize);
+ // When copying from an array to an Allocation, the src pointer
+ // to the array should just move by the number of bytes copied.
+ src += clineSize;
+ dst += alloc->mHal.drvState.lod[lod].stride;
+ }
+ lod++;
+ }
+ }
+ }
+}
+
+void rsovAllocationData3D(const Context *rsc, const Allocation *alloc,
+ uint32_t xoff, uint32_t yoff, uint32_t zoff,
+ uint32_t lod, uint32_t w, uint32_t h, uint32_t d,
+ const void *data, size_t sizeBytes, size_t stride) {
+ uint32_t eSize = alloc->mHal.state.elementSizeBytes;
+ uint32_t lineSize = eSize * w;
+ if (!stride) {
+ stride = lineSize;
+ }
+
+ if (alloc->mHal.drvState.lod[0].mallocPtr) {
+ const uint8_t *src = static_cast<const uint8_t *>(data);
+ for (uint32_t z = zoff; z < (d + zoff); z++) {
+ uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, z, lod,
+ RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
+ for (uint32_t line = yoff; line < (yoff + h); line++) {
+ if (alloc->mHal.state.hasReferences) {
+ alloc->incRefs(src, w);
+ alloc->decRefs(dst, w);
+ }
+ memcpy(dst, src, lineSize);
+ src += stride;
+ dst += alloc->mHal.drvState.lod[lod].stride;
+ }
+ }
+ }
+}
+
+void rsovAllocationRead1D(const Context *rsc, const Allocation *alloc,
+ uint32_t xoff, uint32_t lod, size_t count, void *data,
+ size_t sizeBytes) {
+ const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
+ const uint8_t *ptr =
+ GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
+ if (data != ptr) {
+ // Skip the copy if we are the same allocation. This can arise from
+ // our Bitmap optimization, where we share the same storage.
+ memcpy(data, ptr, count * eSize);
+ }
+}
+
+void rsovAllocationRead2D(const Context *rsc, const Allocation *alloc,
+ uint32_t xoff, uint32_t yoff, uint32_t lod,
+ RsAllocationCubemapFace face, uint32_t w, uint32_t h,
+ void *data, size_t sizeBytes, size_t stride) {
+ size_t eSize = alloc->mHal.state.elementSizeBytes;
+ size_t lineSize = eSize * w;
+ if (!stride) {
+ stride = lineSize;
+ }
+
+ if (alloc->mHal.drvState.lod[0].mallocPtr) {
+ uint8_t *dst = static_cast<uint8_t *>(data);
+ const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
+ if (dst == src) {
+ // Skip the copy if we are the same allocation. This can arise from
+ // our Bitmap optimization, where we share the same storage.
+ return;
+ }
+
+ for (uint32_t line = yoff; line < (yoff + h); line++) {
+ memcpy(dst, src, lineSize);
+ dst += stride;
+ src += alloc->mHal.drvState.lod[lod].stride;
+ }
+ } else {
+ ALOGE("Add code to readback from non-script memory");
+ }
+}
+
+void rsovAllocationRead3D(const Context *rsc, const Allocation *alloc,
+ uint32_t xoff, uint32_t yoff, uint32_t zoff,
+ uint32_t lod, uint32_t w, uint32_t h, uint32_t d,
+ void *data, size_t sizeBytes, size_t stride) {
+ uint32_t eSize = alloc->mHal.state.elementSizeBytes;
+ uint32_t lineSize = eSize * w;
+ if (!stride) {
+ stride = lineSize;
+ }
+
+ if (alloc->mHal.drvState.lod[0].mallocPtr) {
+ uint8_t *dst = static_cast<uint8_t *>(data);
+ for (uint32_t z = zoff; z < (d + zoff); z++) {
+ const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, z, lod,
+ RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
+ if (dst == src) {
+ // Skip the copy if we are the same allocation. This can arise from
+ // our Bitmap optimization, where we share the same storage.
+ return;
+ }
+
+ for (uint32_t line = yoff; line < (yoff + h); line++) {
+ memcpy(dst, src, lineSize);
+ dst += stride;
+ src += alloc->mHal.drvState.lod[lod].stride;
+ }
+ }
+ }
+}
+
+void *rsovAllocationLock1D(const Context *rsc, const Allocation *alloc) {
+ return alloc->mHal.drvState.lod[0].mallocPtr;
+}
+
+void rsovAllocationUnlock1D(const Context *rsc, const Allocation *alloc) {}
+
+void rsovAllocationData1D_alloc(const Context *rsc, const Allocation *dstAlloc,
+ uint32_t dstXoff, uint32_t dstLod, size_t count,
+ const Allocation *srcAlloc, uint32_t srcXoff,
+ uint32_t srcLod) {}
+
+void rsovAllocationData2D_alloc_script(
+ const Context *rsc, const Allocation *dstAlloc, uint32_t dstXoff,
+ uint32_t dstYoff, uint32_t dstLod, RsAllocationCubemapFace dstFace,
+ uint32_t w, uint32_t h, const Allocation *srcAlloc, uint32_t srcXoff,
+ uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) {
+ size_t elementSize = dstAlloc->getType()->getElementSizeBytes();
+ for (uint32_t i = 0; i < h; i++) {
+ uint8_t *dstPtr =
+ GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, 0, dstLod, dstFace);
+ uint8_t *srcPtr =
+ GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, 0, srcLod, srcFace);
+ memcpy(dstPtr, srcPtr, w * elementSize);
+ }
+}
+
+void rsovAllocationData3D_alloc_script(
+ const Context *rsc, const Allocation *dstAlloc, uint32_t dstXoff,
+ uint32_t dstYoff, uint32_t dstZoff, uint32_t dstLod, uint32_t w, uint32_t h,
+ uint32_t d, const Allocation *srcAlloc, uint32_t srcXoff, uint32_t srcYoff,
+ uint32_t srcZoff, uint32_t srcLod) {
+ uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
+ for (uint32_t j = 0; j < d; j++) {
+ for (uint32_t i = 0; i < h; i++) {
+ uint8_t *dstPtr =
+ GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstZoff + j, dstLod,
+ RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
+ uint8_t *srcPtr =
+ GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcZoff + j, srcLod,
+ RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
+ memcpy(dstPtr, srcPtr, w * elementSize);
+ }
+ }
+}
+
+void rsovAllocationData2D_alloc(
+ const Context *rsc, const Allocation *dstAlloc, uint32_t dstXoff,
+ uint32_t dstYoff, uint32_t dstLod, RsAllocationCubemapFace dstFace,
+ uint32_t w, uint32_t h, const Allocation *srcAlloc, uint32_t srcXoff,
+ uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) {
+ if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
+ rsc->setError(RS_ERROR_FATAL_DRIVER,
+ "Non-script allocation copies not "
+ "yet implemented.");
+ return;
+ }
+ rsovAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstLod,
+ dstFace, w, h, srcAlloc, srcXoff, srcYoff,
+ srcLod, srcFace);
+}
+
+void rsovAllocationData3D_alloc(const Context *rsc, const Allocation *dstAlloc,
+ uint32_t dstXoff, uint32_t dstYoff,
+ uint32_t dstZoff, uint32_t dstLod, uint32_t w,
+ uint32_t h, uint32_t d,
+ const Allocation *srcAlloc, uint32_t srcXoff,
+ uint32_t srcYoff, uint32_t srcZoff,
+ uint32_t srcLod) {
+ if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
+ rsc->setError(RS_ERROR_FATAL_DRIVER,
+ "Non-script allocation copies not "
+ "yet implemented.");
+ return;
+ }
+ rsovAllocationData3D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstZoff,
+ dstLod, w, h, d, srcAlloc, srcXoff, srcYoff,
+ srcZoff, srcLod);
+}
+
+void rsovAllocationAdapterOffset(const Context *rsc, const Allocation *alloc) {
+ // Get a base pointer to the new LOD
+ const Allocation *base = alloc->mHal.state.baseAlloc;
+ const Type *type = alloc->mHal.state.type;
+ if (base == nullptr) {
+ return;
+ }
+
+ const int lodBias = alloc->mHal.state.originLOD;
+ uint32_t lodCount = rsMax(alloc->mHal.drvState.lodCount, (uint32_t)1);
+ for (uint32_t lod = 0; lod < lodCount; lod++) {
+ alloc->mHal.drvState.lod[lod] = base->mHal.drvState.lod[lod + lodBias];
+ alloc->mHal.drvState.lod[lod].mallocPtr = GetOffsetPtr(
+ alloc, alloc->mHal.state.originX, alloc->mHal.state.originY,
+ alloc->mHal.state.originZ, lodBias,
+ (RsAllocationCubemapFace)alloc->mHal.state.originFace);
+ }
+}
+
+bool rsovAllocationAdapterInit(const Context *rsc, Allocation *alloc) {
+// TODO: may need a RSoV Allocation here
+#if 0
+ DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
+ if (!drv) {
+ return false;
+ }
+ alloc->mHal.drv = drv;
+#endif
+ // We need to build an allocation that looks like a subset of the parent
+ // allocation
+ rsovAllocationAdapterOffset(rsc, alloc);
+
+ return true;
+}
+
+void rsovAllocationSyncAll(const Context *rsc, const Allocation *alloc,
+ RsAllocationUsageType src) {
+ // TODO: anything to do here?
+}
+
+void rsovAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
+ // TODO: anything to do here?
+}
+
+void rsovAllocationResize(const Context *rsc, const Allocation *alloc,
+ const Type *newType, bool zeroNew) {
+ // TODO: implement this
+ // can this be done without copying, if the new size is greater than the
+ // original?
+}
+
+void rsovAllocationGenerateMipmaps(const Context *rsc,
+ const Allocation *alloc) {
+ if (!alloc->mHal.drvState.lod[0].mallocPtr) {
+ return;
+ }
+ uint32_t numFaces = alloc->getType()->getDimFaces() ? 6 : 1;
+ for (uint32_t face = 0; face < numFaces; face++) {
+ for (uint32_t lod = 0; lod < (alloc->getType()->getLODCount() - 1); lod++) {
+ switch (alloc->getType()->getElement()->getSizeBits()) {
+ case 32:
+ mip8888(alloc, lod, (RsAllocationCubemapFace)face);
+ break;
+ case 16:
+ mip565(alloc, lod, (RsAllocationCubemapFace)face);
+ break;
+ case 8:
+ mip8(alloc, lod, (RsAllocationCubemapFace)face);
+ break;
+ }
+ }
+ }
+}
+
+uint32_t rsovAllocationGrallocBits(const Context *rsc, Allocation *alloc) {
+ return 0;
+}
+
+void rsovAllocationUpdateCachedObject(const Context *rsc,
+ const Allocation *alloc,
+ rs_allocation *obj) {
+ obj->p = alloc;
+#ifdef __LP64__
+ obj->unused1 = nullptr;
+ obj->unused2 = nullptr;
+ obj->unused3 = nullptr;
+#endif
+}
+
+void rsovAllocationSetSurface(const Context *rsc, Allocation *alloc,
+ ANativeWindow *nw) {
+ // TODO: implement this
+}
+
+void rsovAllocationIoSend(const Context *rsc, Allocation *alloc) {
+ // TODO: implement this
+}
+
+void rsovAllocationIoReceive(const Context *rsc, Allocation *alloc) {
+ // TODO: implement this
+}
+
+void rsovAllocationElementData(const Context *rsc, const Allocation *alloc,
+ uint32_t x, uint32_t y, uint32_t z,
+ const void *data, uint32_t cIdx,
+ size_t sizeBytes) {
+ uint8_t *ptr =
+ GetOffsetPtr(alloc, x, y, z, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
+
+ const Element *e = alloc->mHal.state.type->getElement()->getField(cIdx);
+ ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
+
+ if (alloc->mHal.state.hasReferences) {
+ e->incRefs(data);
+ e->decRefs(ptr);
+ }
+
+ memcpy(ptr, data, sizeBytes);
+}
+
+void rsovAllocationElementRead(const Context *rsc, const Allocation *alloc,
+ uint32_t x, uint32_t y, uint32_t z, void *data,
+ uint32_t cIdx, size_t sizeBytes) {
+ uint8_t *ptr =
+ GetOffsetPtr(alloc, x, y, z, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
+
+ const Element *e = alloc->mHal.state.type->getElement()->getField(cIdx);
+ ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
+
+ memcpy(data, ptr, sizeBytes);
+}
diff --git a/rsov/driver/rsovAllocation.h b/rsov/driver/rsovAllocation.h
new file mode 100644
index 0000000..edbf7ff
--- /dev/null
+++ b/rsov/driver/rsovAllocation.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef RSOV_ALLOCATION_H
+#define RSOV_ALLOCATION_H
+
+#include <vulkan/vulkan.h>
+
+#include "rsDefines.h"
+#include "rs_hal.h"
+#include "system/window.h"
+
+namespace android {
+namespace renderscript {
+
+class Allocation;
+class Context;
+class Type;
+
+namespace rsov {
+
+class RSoVContext;
+// Abstraction for a Vulkan Buffer
+class RSoVBuffer {
+ public:
+ RSoVBuffer(RSoVContext *context, size_t bufferSize);
+ ~RSoVBuffer();
+
+ const VkDescriptorBufferInfo *getBufferInfo() const { return &mBufferInfo; }
+ char *getHostPtr() const { return mPtr; }
+
+ private:
+ void InitBuffer(size_t);
+
+ char *mPtr; // Host pointer to mmapped device memory for the Buffer
+ RSoVContext *mRSoV;
+ VkDevice mDevice;
+
+ VkDeviceMemory mMem;
+ VkBuffer mBuf;
+ VkDescriptorBufferInfo mBufferInfo;
+};
+
+class RSoVAllocation {
+ public:
+ RSoVAllocation(RSoVContext *context, const Type *type, size_t bufferSize);
+ ~RSoVAllocation() { delete mBuffer; }
+
+ const Type *getType() const { return mType; }
+ uint32_t getWidth() const { return mWidth; }
+ uint32_t getHeight() const { return mHeight; }
+ uint32_t getDepth() const { return mDepth; }
+ RSoVBuffer *getBuffer() const { return mBuffer; }
+ char *getHostPtr() const { return mBuffer->getHostPtr(); }
+
+ private:
+ RSoVBuffer *mBuffer;
+ const Type *mType;
+ const uint32_t mWidth;
+ const uint32_t mHeight;
+ const uint32_t mDepth;
+};
+
+} // namespace rsov
+} // namespace renderscript
+} // namespace android
+
+extern bool rsovAllocationInit(const android::renderscript::Context *rsc,
+ android::renderscript::Allocation *alloc,
+ bool forceZero);
+
+extern void rsovAllocationDestroy(const android::renderscript::Context *rsc,
+ android::renderscript::Allocation *alloc);
+
+extern void rsovAllocationData1D(const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc,
+ uint32_t xoff, uint32_t lod, size_t count,
+ const void *data, size_t sizeBytes);
+
+extern void rsovAllocationData2D(const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc,
+ uint32_t xoff, uint32_t yoff, uint32_t lod,
+ RsAllocationCubemapFace face, uint32_t w,
+ uint32_t h, const void *data, size_t sizeBytes,
+ size_t stride);
+
+extern void rsovAllocationData3D(const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc,
+ uint32_t xoff, uint32_t yoff, uint32_t zoff,
+ uint32_t lod, uint32_t w, uint32_t h,
+ uint32_t d, const void *data, size_t sizeBytes,
+ size_t stride);
+
+extern void rsovAllocationRead1D(const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc,
+ uint32_t xoff, uint32_t lod, size_t count,
+ void *data, size_t sizeBytes);
+
+extern void rsovAllocationRead2D(const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc,
+ uint32_t xoff, uint32_t yoff, uint32_t lod,
+ RsAllocationCubemapFace face, uint32_t w,
+ uint32_t h, void *data, size_t sizeBytes,
+ size_t stride);
+
+extern void rsovAllocationRead3D(const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc,
+ uint32_t xoff, uint32_t yoff, uint32_t zoff,
+ uint32_t lod, uint32_t w, uint32_t h,
+ uint32_t d, void *data, size_t sizeBytes,
+ size_t stride);
+
+extern void *rsovAllocationLock1D(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc);
+
+extern void rsovAllocationUnlock1D(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc);
+
+extern void rsovAllocationData1D_alloc(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff,
+ uint32_t dstLod, size_t count,
+ const android::renderscript::Allocation *srcAlloc, uint32_t srcXoff,
+ uint32_t srcLod);
+
+extern void rsovAllocationData2D_alloc_script(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff,
+ uint32_t dstYoff, uint32_t dstLod, RsAllocationCubemapFace dstFace,
+ uint32_t w, uint32_t h, const android::renderscript::Allocation *srcAlloc,
+ uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
+ RsAllocationCubemapFace srcFace);
+
+extern void rsovAllocationData2D_alloc(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff,
+ uint32_t dstYoff, uint32_t dstLod, RsAllocationCubemapFace dstFace,
+ uint32_t w, uint32_t h, const android::renderscript::Allocation *srcAlloc,
+ uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
+ RsAllocationCubemapFace srcFace);
+
+extern void rsovAllocationData3D_alloc_script(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff,
+ uint32_t dstYoff, uint32_t dstZoff, uint32_t dstLod, uint32_t w, uint32_t h,
+ uint32_t d, const android::renderscript::Allocation *srcAlloc,
+ uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, uint32_t srcLod);
+
+extern void rsovAllocationData3D_alloc(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff,
+ uint32_t dstYoff, uint32_t dstZoff, uint32_t dstLod, uint32_t w, uint32_t h,
+ uint32_t d, const android::renderscript::Allocation *srcAlloc,
+ uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, uint32_t srcLod);
+
+extern void rsovAllocationAdapterOffset(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc);
+
+extern bool rsovAllocationAdapterInit(const android::renderscript::Context *rsc,
+ android::renderscript::Allocation *alloc);
+
+extern void rsovAllocationSyncAll(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc, RsAllocationUsageType src);
+
+extern void rsovAllocationMarkDirty(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc);
+
+extern void rsovAllocationResize(const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc,
+ const android::renderscript::Type *newType,
+ bool zeroNew);
+
+extern void rsovAllocationGenerateMipmaps(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc);
+
+extern uint32_t rsovAllocationGrallocBits(
+ const android::renderscript::Context *rsc,
+ android::renderscript::Allocation *alloc);
+
+extern void rsovAllocationUpdateCachedObject(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc,
+ android::renderscript::rs_allocation *obj);
+
+extern void rsovAllocationSetSurface(const android::renderscript::Context *rsc,
+ android::renderscript::Allocation *alloc,
+ ANativeWindow *nw);
+
+extern void rsovAllocationIoSend(const android::renderscript::Context *rsc,
+ android::renderscript::Allocation *alloc);
+
+extern void rsovAllocationIoReceive(const android::renderscript::Context *rsc,
+ android::renderscript::Allocation *alloc);
+
+extern void rsovAllocationElementData(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc, uint32_t x, uint32_t y,
+ uint32_t z, const void *data, uint32_t cIdx, size_t sizeBytes);
+
+extern void rsovAllocationElementRead(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc, uint32_t x, uint32_t y,
+ uint32_t z, void *data, uint32_t cIdx, size_t sizeBytes);
+
+#endif // RSOV_ALLOCATION_H
diff --git a/rsov/driver/rsovContext.cpp b/rsov/driver/rsovContext.cpp
new file mode 100644
index 0000000..4aba017
--- /dev/null
+++ b/rsov/driver/rsovContext.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "rsovContext.h"
+
+#include <vector>
+
+#include "rsUtils.h"
+
+namespace android {
+namespace renderscript {
+namespace rsov {
+
+RSoVContext* RSoVContext::mContext = nullptr;
+std::once_flag RSoVContext::mInitFlag;
+
+bool RSoVContext::Initialize(char const* const name) {
+ // Initialize instance
+ VkApplicationInfo appInfo = {
+ .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
+ .pNext = nullptr,
+ .pApplicationName = name, // TODO: set to app name
+ .applicationVersion = 1,
+ .pEngineName = name,
+ .engineVersion = 1,
+ .apiVersion = VK_API_VERSION_1_0};
+
+ VkInstanceCreateInfo instInfo = {
+ .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .pApplicationInfo = &appInfo,
+ };
+
+ VkResult res;
+ res = vkCreateInstance(&instInfo, nullptr, &mInstance);
+ if (res != VK_SUCCESS) {
+ return false;
+ }
+
+ // Enumerate devices
+ uint32_t gpu_count;
+
+ res = vkEnumeratePhysicalDevices(mInstance, &gpu_count, nullptr);
+ if (gpu_count == 0) {
+ return false;
+ }
+
+ std::vector<VkPhysicalDevice> GPUs(gpu_count);
+
+ res = vkEnumeratePhysicalDevices(mInstance, &gpu_count, GPUs.data());
+ if (!(res == VK_SUCCESS && gpu_count > 0)) {
+ return false;
+ }
+
+ mGPU = GPUs[0];
+
+ // Get device memory properties
+ vkGetPhysicalDeviceMemoryProperties(mGPU, &mMemoryProperties);
+
+ // Initialize device
+
+ float queuePriorities[] = {0.0};
+
+ VkDeviceQueueCreateInfo queueInfo = {
+ .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+ .pNext = nullptr,
+ .queueCount = 1,
+ .pQueuePriorities = queuePriorities,
+ };
+
+ VkDeviceCreateInfo deviceInfo = {
+ .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+ .pNext = nullptr,
+ .queueCreateInfoCount = 1,
+ .pQueueCreateInfos = &queueInfo,
+ .pEnabledFeatures = nullptr,
+ };
+
+ res = vkCreateDevice(mGPU, &deviceInfo, nullptr, &mDevice);
+ if (res != VK_SUCCESS) {
+ return false;
+ }
+
+ // Initialize queue family index
+ uint32_t queueCount;
+
+ vkGetPhysicalDeviceQueueFamilyProperties(mGPU, &queueCount, nullptr);
+ if (queueCount == 0) {
+ return false;
+ }
+
+ std::vector<VkQueueFamilyProperties> queueProps(queueCount);
+
+ vkGetPhysicalDeviceQueueFamilyProperties(mGPU, &queueCount,
+ queueProps.data());
+ if (queueCount == 0) {
+ return false;
+ }
+
+ uint32_t queueFamilyIndex = UINT_MAX;
+ bool found = false;
+ for (unsigned int i = 0; i < queueCount; i++) {
+ if (queueProps[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
+ queueFamilyIndex = i;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ return false;
+ }
+
+ // Create a device queue
+
+ vkGetDeviceQueue(mDevice, queueFamilyIndex, 0, &mQueue);
+
+ // Create command pool
+
+ VkCommandPoolCreateInfo cmd_pool_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+ .pNext = nullptr,
+ .queueFamilyIndex = queueFamilyIndex,
+ .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
+ };
+
+ res = vkCreateCommandPool(mDevice, &cmd_pool_info, nullptr, &mCmdPool);
+ if (res != VK_SUCCESS) {
+ return false;
+ }
+
+ return true;
+}
+
+bool RSoVContext::MemoryTypeFromProperties(uint32_t typeBits,
+ VkFlags requirements_mask,
+ uint32_t* typeIndex) {
+ for (uint32_t i = 0; i < 32; i++) {
+ if ((typeBits & 1) == 1) {
+ const uint32_t prop = mMemoryProperties.memoryTypes[i].propertyFlags;
+ if ((prop & requirements_mask) == requirements_mask) {
+ *typeIndex = i;
+ return true;
+ }
+ }
+ typeBits >>= 1;
+ }
+
+ return false;
+}
+
+RSoVContext::RSoVContext() {}
+
+RSoVContext::~RSoVContext() {}
+
+RSoVContext* RSoVContext::create() {
+ std::call_once(mInitFlag, []() {
+ std::unique_ptr<RSoVContext> context(new RSoVContext());
+ char engineName[] = "RSoV";
+
+ if (context && context->Initialize(engineName)) {
+ mContext = context.release();
+ }
+ });
+ return mContext;
+}
+
+} // namespace rsov
+} // namespace renderscript
+} // namespace android
diff --git a/rsov/driver/rsovContext.h b/rsov/driver/rsovContext.h
new file mode 100644
index 0000000..8c933cf
--- /dev/null
+++ b/rsov/driver/rsovContext.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef RSOV_CONTEXT_H
+#define RSOV_CONTEXT_H
+
+#include <vulkan/vulkan.h>
+#include <mutex>
+
+namespace android {
+namespace renderscript {
+
+namespace rsov {
+
+class RSoVContext {
+ public:
+ static RSoVContext* create();
+ ~RSoVContext();
+
+ VkDevice getDevice() const { return mDevice; }
+ VkQueue getQueue() const { return mQueue; }
+ VkCommandPool getCmdPool() const { return mCmdPool; }
+
+ bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask,
+ uint32_t* typeIndex);
+
+ private:
+ RSoVContext();
+
+ bool Initialize(char const* const name);
+
+ static RSoVContext* mContext;
+ static std::once_flag mInitFlag;
+
+ VkInstance mInstance;
+ VkPhysicalDevice mGPU;
+ VkDevice mDevice;
+ VkPhysicalDeviceMemoryProperties mMemoryProperties;
+ VkQueue mQueue;
+ VkCommandPool mCmdPool;
+};
+
+} // namespace rsov
+} // namespace renderscript
+} // namespace android
+
+#endif // RSOV_CONTEXT_H
diff --git a/rsov/driver/rsovCore.cpp b/rsov/driver/rsovCore.cpp
new file mode 100644
index 0000000..123930e
--- /dev/null
+++ b/rsov/driver/rsovCore.cpp
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "rsovCore.h"
+
+#include <malloc.h>
+#include <sched.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+
+#include "cpu_ref/rsd_cpu.h"
+#include "rsContext.h"
+#include "rsovAllocation.h"
+#include "rsovContext.h"
+#include "rsovElement.h"
+#include "rsovSampler.h"
+#include "rsovScript.h"
+#include "rsovScriptGroup.h"
+#include "rsovType.h"
+
+namespace android {
+namespace renderscript {
+
+namespace {
+
+void SetPriority(const Context *rsc, int32_t priority) {
+ RSoVHal *dc = (RSoVHal *)rsc->mHal.drv;
+
+ dc->mCpuRef->setPriority(priority);
+}
+
+void Shutdown(Context *rsc) {
+ RSoVHal *dc = (RSoVHal *)rsc->mHal.drv;
+ delete dc->mCpuRef;
+ free(dc);
+ rsc->mHal.drv = nullptr;
+}
+
+void *AllocRuntimeMem(size_t size, uint32_t flags) {
+ void* buffer = calloc(size, sizeof(char));
+ return buffer;
+}
+
+void FreeRuntimeMem(void* ptr) {
+ free(ptr);
+}
+
+const RsdCpuReference::CpuSymbol *lookupRuntimeStubs(
+ Context *pContext, char const *name) {
+ return nullptr;
+}
+
+} // anonymous namespace
+
+namespace rsov {
+
+namespace {
+
+RsdCpuReference::CpuScript *lookupCpuScript(Context *rsc, const Script *s) {
+ if (RSoVScript::isScriptCpuBacked(s)) {
+ return reinterpret_cast<RsdCpuReference::CpuScript *>(s->mHal.drv);
+ }
+
+ RSoVScript *rsovScript = reinterpret_cast<RSoVScript *>(s->mHal.drv);
+ return rsovScript->getCpuScript();
+}
+
+} // anonymous namespace
+
+} // namespace rsov
+
+
+extern "C" bool rsdHalQueryHal(RsHalInitEnums entry, void **fnPtr) {
+ switch (entry) {
+ case RS_HAL_ALLOCATION_INIT:
+ fnPtr[0] = (void *)rsovAllocationInit;
+ break;
+ case RS_HAL_ALLOCATION_INIT_OEM:
+ fnPtr[0] = (void *)nullptr;
+ break;
+ case RS_HAL_ALLOCATION_INIT_ADAPTER:
+ fnPtr[0] = (void *)rsovAllocationAdapterInit;
+ break;
+ case RS_HAL_ALLOCATION_DESTROY:
+ fnPtr[0] = (void *)rsovAllocationDestroy;
+ break;
+ case RS_HAL_ALLOCATION_GET_GRALLOC_BITS:
+ fnPtr[0] = (void *)rsovAllocationGrallocBits;
+ break;
+ case RS_HAL_ALLOCATION_DATA_1D:
+ fnPtr[0] = (void *)rsovAllocationData1D;
+ break;
+ case RS_HAL_ALLOCATION_DATA_2D:
+ fnPtr[0] = (void *)rsovAllocationData2D;
+ break;
+ case RS_HAL_ALLOCATION_DATA_3D:
+ fnPtr[0] = (void *)rsovAllocationData3D;
+ break;
+ case RS_HAL_ALLOCATION_READ_1D:
+ fnPtr[0] = (void *)rsovAllocationRead1D;
+ break;
+ case RS_HAL_ALLOCATION_READ_2D:
+ fnPtr[0] = (void *)rsovAllocationRead2D;
+ break;
+ case RS_HAL_ALLOCATION_READ_3D:
+ fnPtr[0] = (void *)rsovAllocationRead3D;
+ break;
+ case RS_HAL_ALLOCATION_LOCK_1D:
+ fnPtr[0] = (void *)rsovAllocationLock1D;
+ break;
+ case RS_HAL_ALLOCATION_UNLOCK_1D:
+ fnPtr[0] = (void *)rsovAllocationUnlock1D;
+ break;
+ case RS_HAL_ALLOCATION_COPY_1D:
+ fnPtr[0] = (void *)rsovAllocationData1D_alloc;
+ break;
+ case RS_HAL_ALLOCATION_COPY_2D:
+ fnPtr[0] = (void *)rsovAllocationData2D_alloc;
+ break;
+ case RS_HAL_ALLOCATION_COPY_3D:
+ fnPtr[0] = (void *)rsovAllocationData3D_alloc;
+ break;
+ case RS_HAL_ALLOCATION_ADAPTER_OFFSET:
+ fnPtr[0] = (void *)rsovAllocationAdapterOffset;
+ break;
+ case RS_HAL_ALLOCATION_RESIZE:
+ fnPtr[0] = (void *)rsovAllocationResize;
+ break;
+ case RS_HAL_ALLOCATION_SYNC_ALL:
+ fnPtr[0] = (void *)rsovAllocationSyncAll;
+ break;
+ case RS_HAL_ALLOCATION_MARK_DIRTY:
+ fnPtr[0] = (void *)rsovAllocationMarkDirty;
+ break;
+ case RS_HAL_ALLOCATION_GENERATE_MIPMAPS:
+ fnPtr[0] = (void *)rsovAllocationGenerateMipmaps;
+ break;
+ case RS_HAL_ALLOCATION_UPDATE_CACHED_OBJECT:
+ fnPtr[0] = (void *)rsovAllocationUpdateCachedObject;
+ break;
+ case RS_HAL_ALLOCATION_GET_POINTER:
+ fnPtr[0] = (void *)nullptr;
+ break;
+ case RS_HAL_ALLOCATION_SET_SURFACE:
+ fnPtr[0] = (void *)rsovAllocationSetSurface;
+ break;
+ case RS_HAL_ALLOCATION_IO_SEND:
+ fnPtr[0] = (void *)rsovAllocationIoSend;
+ break;
+ case RS_HAL_ALLOCATION_IO_RECEIVE:
+ fnPtr[0] = (void *)rsovAllocationIoReceive;
+ break;
+ case RS_HAL_ALLOCATION_ELEMENT_DATA:
+ fnPtr[0] = (void *)rsovAllocationElementData;
+ break;
+ case RS_HAL_ALLOCATION_ELEMENT_READ:
+ fnPtr[0] = (void *)rsovAllocationElementRead;
+ break;
+
+ case RS_HAL_CORE_SHUTDOWN:
+ fnPtr[0] = (void *)Shutdown;
+ break;
+ case RS_HAL_CORE_SET_PRIORITY:
+ fnPtr[0] = (void *)SetPriority;
+ break;
+ case RS_HAL_CORE_ALLOC_RUNTIME_MEM:
+ fnPtr[0] = (void *)AllocRuntimeMem;
+ break;
+ case RS_HAL_CORE_FREE_RUNTIME_MEM:
+ fnPtr[0] = (void *)FreeRuntimeMem;
+ break;
+ case RS_HAL_CORE_FINISH:
+ fnPtr[0] = (void *)nullptr;
+ break;
+
+ case RS_HAL_SCRIPT_INIT:
+ fnPtr[0] = (void *)rsovScriptInit;
+ break;
+ case RS_HAL_SCRIPT_INIT_INTRINSIC:
+ fnPtr[0] = (void *)rsovInitIntrinsic;
+ break;
+ case RS_HAL_SCRIPT_INVOKE_FUNCTION:
+ fnPtr[0] = (void *)rsovScriptInvokeFunction;
+ break;
+ case RS_HAL_SCRIPT_INVOKE_ROOT:
+ fnPtr[0] = (void *)rsovScriptInvokeRoot;
+ break;
+ case RS_HAL_SCRIPT_INVOKE_FOR_EACH:
+ fnPtr[0] = (void *)rsovScriptInvokeForEach;
+ break;
+ case RS_HAL_SCRIPT_INVOKE_INIT:
+ fnPtr[0] = (void *)rsovScriptInvokeInit;
+ break;
+ case RS_HAL_SCRIPT_INVOKE_FREE_CHILDREN:
+ fnPtr[0] = (void *)rsovScriptInvokeFreeChildren;
+ break;
+ case RS_HAL_SCRIPT_DESTROY:
+ fnPtr[0] = (void *)rsovScriptDestroy;
+ break;
+ case RS_HAL_SCRIPT_SET_GLOBAL_VAR:
+ fnPtr[0] = (void *)rsovScriptSetGlobalVar;
+ break;
+ case RS_HAL_SCRIPT_GET_GLOBAL_VAR:
+ fnPtr[0] = (void *)rsovScriptGetGlobalVar;
+ break;
+ case RS_HAL_SCRIPT_SET_GLOBAL_VAR_WITH_ELEMENT_DIM:
+ fnPtr[0] = (void *)rsovScriptSetGlobalVarWithElemDims;
+ break;
+ case RS_HAL_SCRIPT_SET_GLOBAL_BIND:
+ fnPtr[0] = (void *)rsovScriptSetGlobalBind;
+ break;
+ case RS_HAL_SCRIPT_SET_GLOBAL_OBJECT:
+ fnPtr[0] = (void *)rsovScriptSetGlobalObj;
+ break;
+ case RS_HAL_SCRIPT_INVOKE_FOR_EACH_MULTI:
+ fnPtr[0] = (void *)rsovScriptInvokeForEachMulti;
+ break;
+ case RS_HAL_SCRIPT_UPDATE_CACHED_OBJECT:
+ fnPtr[0] = (void *)rsovScriptUpdateCachedObject;
+ break;
+ case RS_HAL_SCRIPT_INVOKE_REDUCE:
+ fnPtr[0] = (void *)rsovScriptInvokeReduce;
+ break;
+
+ case RS_HAL_SAMPLER_INIT:
+ fnPtr[0] = (void *)rsovSamplerInit;
+ break;
+ case RS_HAL_SAMPLER_DESTROY:
+ fnPtr[0] = (void *)rsovSamplerDestroy;
+ break;
+ case RS_HAL_SAMPLER_UPDATE_CACHED_OBJECT:
+ fnPtr[0] = (void *)rsovSamplerUpdateCachedObject;
+ break;
+
+ case RS_HAL_TYPE_INIT:
+ fnPtr[0] = (void *)rsovTypeInit;
+ break;
+ case RS_HAL_TYPE_DESTROY:
+ fnPtr[0] = (void *)rsovTypeDestroy;
+ break;
+ case RS_HAL_TYPE_UPDATE_CACHED_OBJECT:
+ fnPtr[0] = (void *)rsovTypeUpdateCachedObject;
+ break;
+
+ case RS_HAL_ELEMENT_INIT:
+ fnPtr[0] = (void *)rsovElementInit;
+ break;
+ case RS_HAL_ELEMENT_DESTROY:
+ fnPtr[0] = (void *)rsovElementDestroy;
+ break;
+ case RS_HAL_ELEMENT_UPDATE_CACHED_OBJECT:
+ fnPtr[0] = (void *)rsovElementUpdateCachedObject;
+ break;
+
+ case RS_HAL_SCRIPT_GROUP_INIT:
+ fnPtr[0] = (void *)rsovScriptGroupInit;
+ break;
+ case RS_HAL_SCRIPT_GROUP_DESTROY:
+ fnPtr[0] = (void *)rsovScriptGroupDestroy;
+ break;
+ case RS_HAL_SCRIPT_GROUP_UPDATE_CACHED_OBJECT:
+ fnPtr[0] = (void *)nullptr;
+ break;
+ case RS_HAL_SCRIPT_GROUP_SET_INPUT:
+ fnPtr[0] = (void *)rsovScriptGroupSetInput;
+ break;
+ case RS_HAL_SCRIPT_GROUP_SET_OUTPUT:
+ fnPtr[0] = (void *)rsovScriptGroupSetOutput;
+ break;
+ case RS_HAL_SCRIPT_GROUP_EXECUTE:
+ fnPtr[0] = (void *)rsovScriptGroupExecute;
+ break;
+
+ // Ignore entries for the legacy graphics api,
+
+ default:
+ ALOGE("ERROR: unknown RenderScript HAL API query, %i", entry);
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" void rsdHalAbort(RsContext) {}
+
+extern "C" bool rsdHalQueryVersion(uint32_t *major, uint32_t *minor) {
+ *major = RS_HAL_VERSION;
+ *minor = 0;
+ return true;
+}
+
+extern "C" bool rsdHalInit(RsContext c, uint32_t version_major,
+ uint32_t version_minor) {
+ Context *rsc = (Context *)c;
+
+ std::unique_ptr<RSoVHal> hal(new RSoVHal());
+ if (!hal) {
+ ALOGE("Failed creating RSoV driver hal.");
+ return false;
+ }
+
+ std::unique_ptr<rsov::RSoVContext> rsov(rsov::RSoVContext::create());
+ if (!rsov) {
+ ALOGE("RSoVContext::create for driver hal failed.");
+ return false;
+ }
+
+ std::unique_ptr<RsdCpuReference> cpuref(RsdCpuReference::create(rsc, version_major, version_minor,
+ &lookupRuntimeStubs,
+ &rsov::lookupCpuScript));
+ if (!cpuref) {
+ ALOGE("RsdCpuReference::create for driver hal failed.");
+ return false;
+ }
+
+ hal->mRSoV = rsov.release();
+ hal->mCpuRef = cpuref.release();
+ rsc->mHal.drv = hal.release();
+
+ return true;
+}
+
+} // namespace renderscript
+} // namespace android
diff --git a/rsov/driver/rsovCore.h b/rsov/driver/rsovCore.h
new file mode 100644
index 0000000..d0c160d
--- /dev/null
+++ b/rsov/driver/rsovCore.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef RSOV_CORE_H
+#define RSOV_CORE_H
+
+namespace android {
+namespace renderscript {
+
+class RsdCpuReference;
+
+namespace rsov {
+
+class RSoVContext;
+
+} // namespace rsov
+} // namespace renderscript
+} // namespace android
+
+struct RSoVHal {
+ android::renderscript::rsov::RSoVContext* mRSoV;
+ android::renderscript::RsdCpuReference *mCpuRef;
+};
+
+#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
+
+#endif
diff --git a/rsov/driver/rsovElement.cpp b/rsov/driver/rsovElement.cpp
new file mode 100644
index 0000000..114e4e3
--- /dev/null
+++ b/rsov/driver/rsovElement.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "rsContext.h"
+#include "rsElement.h"
+
+using android::renderscript::Context;
+using android::renderscript::Element;
+using android::renderscript::rs_element;
+
+bool rsovElementInit(const Context *rsc, const Element *e) { return true; }
+
+void rsovElementDestroy(const Context *rsc, const Element *e) {}
+
+void rsovElementUpdateCachedObject(const Context *rsc, const Element *element,
+ rs_element *obj) {
+ obj->p = element;
+#ifdef __LP64__
+ obj->unused1 = nullptr;
+ obj->unused2 = nullptr;
+ obj->unused3 = nullptr;
+#endif
+}
diff --git a/rsov/driver/rsovElement.h b/rsov/driver/rsovElement.h
new file mode 100644
index 0000000..e3d46bc
--- /dev/null
+++ b/rsov/driver/rsovElement.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef RSOV_ELEMENT_H
+#define RSOV_ELEMENT_H
+
+#include "rs_hal.h"
+
+extern bool rsovElementInit(const android::renderscript::Context *rsc,
+ const android::renderscript::Element *);
+
+extern void rsovElementDestroy(const android::renderscript::Context *rsc,
+ const android::renderscript::Element *);
+
+extern void rsovElementUpdateCachedObject(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Element *,
+ android::renderscript::rs_element *obj);
+
+#endif // RSOV_ELEMENT_H
diff --git a/rsov/driver/rsovRuntimeStubs.cpp b/rsov/driver/rsovRuntimeStubs.cpp
new file mode 100644
index 0000000..2aa7798
--- /dev/null
+++ b/rsov/driver/rsovRuntimeStubs.cpp
@@ -0,0 +1,1148 @@
+/*
+ * 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.
+ */
+
+#include <time.h>
+
+#include "rsContext.h"
+#include "rsElement.h"
+#include "rsMatrix2x2.h"
+#include "rsMatrix3x3.h"
+#include "rsMatrix4x4.h"
+#include "rsRuntime.h"
+#include "rsScriptC.h"
+#include "rsType.h"
+#include "rsovAllocation.h"
+#include "rsovCore.h"
+#include "rsovScript.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+typedef __fp16 half;
+typedef half half2 __attribute__((ext_vector_type(2)));
+typedef half half3 __attribute__((ext_vector_type(3)));
+typedef half half4 __attribute__((ext_vector_type(4)));
+
+typedef float float2 __attribute__((ext_vector_type(2)));
+typedef float float3 __attribute__((ext_vector_type(3)));
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef double double2 __attribute__((ext_vector_type(2)));
+typedef double double3 __attribute__((ext_vector_type(3)));
+typedef double double4 __attribute__((ext_vector_type(4)));
+typedef char char2 __attribute__((ext_vector_type(2)));
+typedef char char3 __attribute__((ext_vector_type(3)));
+typedef char char4 __attribute__((ext_vector_type(4)));
+typedef unsigned char uchar2 __attribute__((ext_vector_type(2)));
+typedef unsigned char uchar3 __attribute__((ext_vector_type(3)));
+typedef unsigned char uchar4 __attribute__((ext_vector_type(4)));
+typedef int16_t short2 __attribute__((ext_vector_type(2)));
+typedef int16_t short3 __attribute__((ext_vector_type(3)));
+typedef int16_t short4 __attribute__((ext_vector_type(4)));
+typedef uint16_t ushort2 __attribute__((ext_vector_type(2)));
+typedef uint16_t ushort3 __attribute__((ext_vector_type(3)));
+typedef uint16_t ushort4 __attribute__((ext_vector_type(4)));
+typedef int32_t int2 __attribute__((ext_vector_type(2)));
+typedef int32_t int3 __attribute__((ext_vector_type(3)));
+typedef int32_t int4 __attribute__((ext_vector_type(4)));
+typedef uint32_t uint2 __attribute__((ext_vector_type(2)));
+typedef uint32_t uint3 __attribute__((ext_vector_type(3)));
+typedef uint32_t uint4 __attribute__((ext_vector_type(4)));
+typedef int64_t long2 __attribute__((ext_vector_type(2)));
+typedef int64_t long3 __attribute__((ext_vector_type(3)));
+typedef int64_t long4 __attribute__((ext_vector_type(4)));
+typedef uint64_t ulong2 __attribute__((ext_vector_type(2)));
+typedef uint64_t ulong3 __attribute__((ext_vector_type(3)));
+typedef uint64_t ulong4 __attribute__((ext_vector_type(4)));
+
+typedef uint8_t uchar;
+typedef uint16_t ushort;
+typedef uint32_t uint;
+typedef uint64_t ulong;
+
+// Add NOLINT to suppress wrong warnings from clang-tidy.
+#ifndef __LP64__
+#define OPAQUETYPE(t) \
+ typedef struct { \
+ const int *const p; \
+ } __attribute__((packed, aligned(4))) t; /*NOLINT*/
+#else
+#define OPAQUETYPE(t) \
+ typedef struct { \
+ const void *p; \
+ const void *unused1; \
+ const void *unused2; \
+ const void *unused3; \
+ } t; /*NOLINT*/
+#endif
+
+OPAQUETYPE(rs_element)
+OPAQUETYPE(rs_type)
+OPAQUETYPE(rs_allocation)
+OPAQUETYPE(rs_sampler)
+OPAQUETYPE(rs_script)
+OPAQUETYPE(rs_script_call)
+
+OPAQUETYPE(rs_program_fragment);
+OPAQUETYPE(rs_program_store);
+OPAQUETYPE(rs_program_vertex);
+OPAQUETYPE(rs_program_raster);
+OPAQUETYPE(rs_mesh);
+OPAQUETYPE(rs_font);
+
+#undef OPAQUETYPE
+
+typedef enum {
+ // Empty to avoid conflicting definitions with RsAllocationCubemapFace
+} rs_allocation_cubemap_face;
+
+typedef enum {
+ // Empty to avoid conflicting definitions with RsYuvFormat
+} rs_yuv_format;
+
+typedef enum {
+ // Empty to avoid conflicting definitions with RsAllocationMipmapControl
+} rs_allocation_mipmap_control;
+
+typedef struct { unsigned int val; } rs_allocation_usage_type;
+
+typedef struct {
+ int tm_sec; ///< seconds
+ int tm_min; ///< minutes
+ int tm_hour; ///< hours
+ int tm_mday; ///< day of the month
+ int tm_mon; ///< month
+ int tm_year; ///< year
+ int tm_wday; ///< day of the week
+ int tm_yday; ///< day of the year
+ int tm_isdst; ///< daylight savings time
+} rs_tm;
+
+// Some RS functions are not threadsafe but can be called from an invoke
+// function. Instead of summarily marking scripts that call these functions as
+// not-threadable we detect calls to them in the driver and sends a fatal error
+// message.
+static bool failIfInKernel(Context *rsc, const char *funcName) {
+ RSoVHal *dc = (RSoVHal *)rsc->mHal.drv;
+ RsdCpuReference *impl = (RsdCpuReference *)dc->mCpuRef;
+
+ if (impl->getInKernel()) {
+ char buf[256];
+ snprintf(buf, sizeof(buf),
+ "Error: Call to unsupported function %s "
+ "in kernel",
+ funcName);
+ rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
+ return true;
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Allocation routines
+//////////////////////////////////////////////////////////////////////////////
+#if defined(__i386__) || (defined(__mips__) && __mips == 32)
+// i386 and MIPS32 have different struct return passing to ARM; emulate with a
+// pointer
+const Allocation *rsGetAllocation(const void *ptr) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ const Script *sc = RsdCpuReference::getTlsScript();
+ Allocation *alloc = rsovScriptGetAllocationForPointer(rsc, sc, ptr);
+ android::renderscript::rs_allocation obj = {0};
+ alloc->callUpdateCacheObject(rsc, &obj);
+ return (Allocation *)obj.p;
+}
+#else
+const android::renderscript::rs_allocation rsGetAllocation(const void *ptr) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ const Script *sc = RsdCpuReference::getTlsScript();
+ Allocation *alloc = rsovScriptGetAllocationForPointer(rsc, sc, ptr);
+
+#ifndef __LP64__ // ARMv7
+ android::renderscript::rs_allocation obj = {0};
+#else // AArch64/x86_64/MIPS64
+ android::renderscript::rs_allocation obj = {0, 0, 0, 0};
+#endif
+ alloc->callUpdateCacheObject(rsc, &obj);
+ return obj;
+}
+#endif
+
+void __attribute__((overloadable)) rsAllocationIoSend(::rs_allocation a) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ if (failIfInKernel(rsc, "rsAllocationIoSend")) return;
+ rsrAllocationIoSend(rsc, (Allocation *)a.p);
+}
+
+void __attribute__((overloadable)) rsAllocationIoReceive(::rs_allocation a) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ if (failIfInKernel(rsc, "rsAllocationIoReceive")) return;
+ rsrAllocationIoReceive(rsc, (Allocation *)a.p);
+}
+
+void __attribute__((overloadable))
+rsAllocationCopy1DRange(::rs_allocation dstAlloc, uint32_t dstOff,
+ uint32_t dstMip, uint32_t count,
+ ::rs_allocation srcAlloc, uint32_t srcOff,
+ uint32_t srcMip) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ if (failIfInKernel(rsc, "rsAllocationCopy1DRange")) return;
+ rsrAllocationCopy1DRange(rsc, (Allocation *)dstAlloc.p, dstOff, dstMip, count,
+ (Allocation *)srcAlloc.p, srcOff, srcMip);
+}
+
+void __attribute__((overloadable))
+rsAllocationCopy2DRange(::rs_allocation dstAlloc, uint32_t dstXoff,
+ uint32_t dstYoff, uint32_t dstMip,
+ rs_allocation_cubemap_face dstFace, uint32_t width,
+ uint32_t height, ::rs_allocation srcAlloc,
+ uint32_t srcXoff, uint32_t srcYoff, uint32_t srcMip,
+ rs_allocation_cubemap_face srcFace) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ if (failIfInKernel(rsc, "rsAllocationCopy2DRange")) return;
+ rsrAllocationCopy2DRange(
+ rsc, (Allocation *)dstAlloc.p, dstXoff, dstYoff, dstMip, dstFace, width,
+ height, (Allocation *)srcAlloc.p, srcXoff, srcYoff, srcMip, srcFace);
+}
+
+static android::renderscript::rs_element CreateElement(RsDataType dt,
+ RsDataKind dk,
+ bool isNormalized,
+ uint32_t vecSize) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+
+ // No need for validation here. The rsCreateElement overload below is not
+ // exposed to the Script. The Element-creation APIs call this function in a
+ // consistent manner and rsComponent.cpp asserts on any inconsistency.
+ Element *element =
+ (Element *)rsrElementCreate(rsc, dt, dk, isNormalized, vecSize);
+ android::renderscript::rs_element obj = {};
+ if (element == nullptr) return obj;
+ element->callUpdateCacheObject(rsc, &obj);
+
+ // Any new rsObject created from inside a script should have the usrRefCount
+ // initialized to 0 and the sysRefCount initialized to 1.
+ element->incSysRef();
+ element->decUserRef();
+
+ return obj;
+}
+
+static android::renderscript::rs_type CreateType(RsElement element,
+ uint32_t dimX, uint32_t dimY,
+ uint32_t dimZ, bool mipmaps,
+ bool faces,
+ uint32_t yuv_format) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ android::renderscript::rs_type obj = {};
+
+ if (element == nullptr) {
+ ALOGE("rs_type creation error: Invalid element");
+ return obj;
+ }
+
+ // validate yuv_format
+ RsYuvFormat yuv = (RsYuvFormat)yuv_format;
+ if (yuv != RS_YUV_NONE && yuv != RS_YUV_YV12 && yuv != RS_YUV_NV21 &&
+ yuv != RS_YUV_420_888) {
+ ALOGE("rs_type creation error: Invalid yuv_format %d\n", yuv_format);
+ return obj;
+ }
+
+ // validate consistency of shape parameters
+ if (dimZ > 0) {
+ if (dimX < 1 || dimY < 1) {
+ ALOGE(
+ "rs_type creation error: Both X and Y dimension required "
+ "when Z is present.");
+ return obj;
+ }
+ if (mipmaps) {
+ ALOGE("rs_type creation error: mipmap control requires 2D types");
+ return obj;
+ }
+ if (faces) {
+ ALOGE("rs_type creation error: Cube maps require 2D types");
+ return obj;
+ }
+ }
+ if (dimY > 0 && dimX < 1) {
+ ALOGE(
+ "rs_type creation error: X dimension required when Y is "
+ "present.");
+ return obj;
+ }
+ if (mipmaps && dimY < 1) {
+ ALOGE("rs_type creation error: mipmap control require 2D Types.");
+ return obj;
+ }
+ if (faces && dimY < 1) {
+ ALOGE("rs_type creation error: Cube maps require 2D Types.");
+ return obj;
+ }
+ if (yuv_format != RS_YUV_NONE) {
+ if (dimZ != 0 || dimY == 0 || faces || mipmaps) {
+ ALOGE("rs_type creation error: YUV only supports basic 2D.");
+ return obj;
+ }
+ }
+
+ Type *type = (Type *)rsrTypeCreate(rsc, element, dimX, dimY, dimZ, mipmaps,
+ faces, yuv_format);
+ if (type == nullptr) return obj;
+ type->callUpdateCacheObject(rsc, &obj);
+
+ // Any new rsObject created from inside a script should have the usrRefCount
+ // initialized to 0 and the sysRefCount initialized to 1.
+ type->incSysRef();
+ type->decUserRef();
+
+ return obj;
+}
+
+static android::renderscript::rs_allocation CreateAllocation(
+ RsType type, RsAllocationMipmapControl mipmaps, uint32_t usages,
+ void *ptr) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ android::renderscript::rs_allocation obj = {};
+
+ if (type == nullptr) {
+ ALOGE("rs_allocation creation error: Invalid type");
+ return obj;
+ }
+
+ uint32_t validUsages =
+ RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
+ if (usages & ~validUsages) {
+ ALOGE("rs_allocation creation error: Invalid usage flag");
+ return obj;
+ }
+
+ Allocation *alloc = (Allocation *)rsrAllocationCreateTyped(
+ rsc, type, mipmaps, usages, (uintptr_t)ptr);
+ if (alloc == nullptr) return obj;
+ alloc->callUpdateCacheObject(rsc, &obj);
+
+ // Any new rsObject created from inside a script should have the usrRefCount
+ // initialized to 0 and the sysRefCount initialized to 1.
+ alloc->incSysRef();
+ alloc->decUserRef();
+
+ return obj;
+}
+
+// Define rsCreateElement, rsCreateType and rsCreateAllocation entry points
+// differently for 32-bit x86 and Mips. The definitions for ARM32 and all
+// 64-bit architectures is further below.
+#if defined(__i386__) || (defined(__mips__) && __mips == 32)
+
+// The calling convention for the driver on 32-bit x86 and Mips returns
+// rs_element etc. as a stack-return parameter. The Script uses ARM32 calling
+// conventions that return the structs in a register. To match this convention,
+// emulate the return value using a pointer.
+Element *rsCreateElement(int32_t dt, int32_t dk, bool isNormalized,
+ uint32_t vecSize) {
+ android::renderscript::rs_element obj =
+ CreateElement((RsDataType)dt, (RsDataKind)dk, isNormalized, vecSize);
+ return (Element *)obj.p;
+}
+
+Type *rsCreateType(::rs_element element, uint32_t dimX, uint32_t dimY,
+ uint32_t dimZ, bool mipmaps, bool faces,
+ rs_yuv_format yuv_format) {
+ android::renderscript::rs_type obj =
+ CreateType((RsElement)element.p, dimX, dimY, dimZ, mipmaps, faces,
+ (RsYuvFormat)yuv_format);
+ return (Type *)obj.p;
+}
+
+Allocation *rsCreateAllocation(::rs_type type,
+ rs_allocation_mipmap_control mipmaps,
+ uint32_t usages, void *ptr) {
+ android::renderscript::rs_allocation obj;
+ obj = CreateAllocation((RsType)type.p, (RsAllocationMipmapControl)mipmaps,
+ usages, ptr);
+ return (Allocation *)obj.p;
+}
+
+#else
+android::renderscript::rs_element rsCreateElement(int32_t dt, int32_t dk,
+ bool isNormalized,
+ uint32_t vecSize) {
+ return CreateElement((RsDataType)dt, (RsDataKind)dk, isNormalized, vecSize);
+}
+
+android::renderscript::rs_type rsCreateType(::rs_element element, uint32_t dimX,
+ uint32_t dimY, uint32_t dimZ,
+ bool mipmaps, bool faces,
+ rs_yuv_format yuv_format) {
+ return CreateType((RsElement)element.p, dimX, dimY, dimZ, mipmaps, faces,
+ yuv_format);
+}
+
+android::renderscript::rs_allocation rsCreateAllocation(
+ ::rs_type type, rs_allocation_mipmap_control mipmaps, uint32_t usages,
+ void *ptr) {
+ return CreateAllocation((RsType)type.p, (RsAllocationMipmapControl)mipmaps,
+ usages, ptr);
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// Object routines
+//////////////////////////////////////////////////////////////////////////////
+// Add NOLINT to suppress wrong warnings from clang-tidy.
+#define IS_CLEAR_SET_OBJ(t) \
+ bool rsIsObject(t src) { return src.p != nullptr; } \
+ void __attribute__((overloadable)) rsClearObject(t *dst) { /*NOLINT*/ \
+ rsrClearObject(reinterpret_cast<rs_object_base *>(dst)); \
+ } \
+ void __attribute__((overloadable)) rsSetObject(t *dst, t src) { /*NOLINT*/ \
+ Context *rsc = RsdCpuReference::getTlsContext(); \
+ rsrSetObject(rsc, reinterpret_cast<rs_object_base *>(dst), \
+ (ObjectBase *)src.p); \
+ }
+
+IS_CLEAR_SET_OBJ(::rs_element)
+IS_CLEAR_SET_OBJ(::rs_type)
+IS_CLEAR_SET_OBJ(::rs_allocation)
+IS_CLEAR_SET_OBJ(::rs_sampler)
+IS_CLEAR_SET_OBJ(::rs_script)
+
+IS_CLEAR_SET_OBJ(::rs_mesh)
+IS_CLEAR_SET_OBJ(::rs_program_fragment)
+IS_CLEAR_SET_OBJ(::rs_program_vertex)
+IS_CLEAR_SET_OBJ(::rs_program_raster)
+IS_CLEAR_SET_OBJ(::rs_program_store)
+IS_CLEAR_SET_OBJ(::rs_font)
+
+#undef IS_CLEAR_SET_OBJ
+
+//////////////////////////////////////////////////////////////////////////////
+// Element routines
+//////////////////////////////////////////////////////////////////////////////
+static void *ElementAt(Allocation *a, RsDataType dt, uint32_t vecSize,
+ uint32_t x, uint32_t y, uint32_t z) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ const Type *t = a->getType();
+ const Element *e = t->getElement();
+
+ char buf[256];
+ if (x && (x >= t->getLODDimX(0))) {
+ snprintf(buf, sizeof(buf), "Out range ElementAt X %i of %i", x,
+ t->getLODDimX(0));
+ rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
+ return nullptr;
+ }
+
+ if (y && (y >= t->getLODDimY(0))) {
+ snprintf(buf, sizeof(buf), "Out range ElementAt Y %i of %i", y,
+ t->getLODDimY(0));
+ rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
+ return nullptr;
+ }
+
+ if (z && (z >= t->getLODDimZ(0))) {
+ snprintf(buf, sizeof(buf), "Out range ElementAt Z %i of %i", z,
+ t->getLODDimZ(0));
+ rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
+ return nullptr;
+ }
+
+ if (vecSize > 0) {
+ if (vecSize != e->getVectorSize()) {
+ snprintf(buf, sizeof(buf), "Vector size mismatch for ElementAt %i of %i",
+ vecSize, e->getVectorSize());
+ rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
+ return nullptr;
+ }
+
+ if (dt != e->getType()) {
+ snprintf(buf, sizeof(buf), "Data type mismatch for ElementAt %i of %i",
+ dt, e->getType());
+ rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
+ return nullptr;
+ }
+ }
+
+ uint8_t *p = (uint8_t *)a->mHal.drvState.lod[0].mallocPtr;
+ const uint32_t eSize = e->getSizeBytes();
+ const uint32_t stride = a->mHal.drvState.lod[0].stride;
+ const uint32_t dimY = a->mHal.drvState.lod[0].dimY;
+ return &p[(x * eSize) + (y * stride) + (z * stride * dimY)];
+}
+
+void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x, uint32_t y,
+ uint32_t z) {
+ const Type *t = const_cast<Allocation *>((Allocation *)a.p)->getType();
+ const Element *e = t->getElement();
+ void *tmp = ElementAt((Allocation *)a.p, RS_TYPE_UNSIGNED_8, 0, x, y, z);
+ if (tmp != nullptr) memcpy(tmp, ptr, e->getSizeBytes());
+}
+
+void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x,
+ uint32_t y) {
+ rsSetElementAt(a, ptr, x, y, 0);
+}
+
+void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x) {
+ rsSetElementAt(a, ptr, x, 0, 0);
+}
+
+const void *rsGetElementAt(::rs_allocation a, uint32_t x, uint32_t y,
+ uint32_t z) {
+ return ElementAt((Allocation *)a.p, RS_TYPE_UNSIGNED_8, 0, x, y, z);
+}
+
+const void *rsGetElementAt(::rs_allocation a, uint32_t x, uint32_t y) {
+ return rsGetElementAt(a, x, y, 0);
+}
+
+const void *rsGetElementAt(::rs_allocation a, uint32_t x) {
+ return rsGetElementAt(a, x, 0, 0);
+}
+
+// Add NOLINT to suppress wrong warnings from clang-tidy.
+#define ELEMENT_AT(T, DT, VS) \
+ void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x, \
+ uint32_t y, uint32_t z) { \
+ void *r = ElementAt((Allocation *)a.p, DT, VS, x, y, z); \
+ if (r != nullptr) \
+ ((T *)r)[0] = *val; \
+ else \
+ ALOGE("Error from %s", __PRETTY_FUNCTION__); \
+ } \
+ void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x, \
+ uint32_t y) { \
+ rsSetElementAt_##T(a, val, x, y, 0); \
+ } \
+ void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x) { \
+ rsSetElementAt_##T(a, val, x, 0, 0); \
+ } \
+ void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x, uint32_t y, \
+ uint32_t z) { /*NOLINT*/ \
+ void *r = ElementAt((Allocation *)a.p, DT, VS, x, y, z); \
+ if (r != nullptr) \
+ *val = ((T *)r)[0]; \
+ else \
+ ALOGE("Error from %s", __PRETTY_FUNCTION__); \
+ } \
+ void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x, \
+ uint32_t y) { /*NOLINT*/ \
+ rsGetElementAt_##T(a, val, x, y, 0); \
+ } \
+ void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x) { /*NOLINT*/ \
+ rsGetElementAt_##T(a, val, x, 0, 0); \
+ }
+
+ELEMENT_AT(char, RS_TYPE_SIGNED_8, 1)
+ELEMENT_AT(char2, RS_TYPE_SIGNED_8, 2)
+ELEMENT_AT(char3, RS_TYPE_SIGNED_8, 3)
+ELEMENT_AT(char4, RS_TYPE_SIGNED_8, 4)
+ELEMENT_AT(uchar, RS_TYPE_UNSIGNED_8, 1)
+ELEMENT_AT(uchar2, RS_TYPE_UNSIGNED_8, 2)
+ELEMENT_AT(uchar3, RS_TYPE_UNSIGNED_8, 3)
+ELEMENT_AT(uchar4, RS_TYPE_UNSIGNED_8, 4)
+ELEMENT_AT(short, RS_TYPE_SIGNED_16, 1)
+ELEMENT_AT(short2, RS_TYPE_SIGNED_16, 2)
+ELEMENT_AT(short3, RS_TYPE_SIGNED_16, 3)
+ELEMENT_AT(short4, RS_TYPE_SIGNED_16, 4)
+ELEMENT_AT(ushort, RS_TYPE_UNSIGNED_16, 1)
+ELEMENT_AT(ushort2, RS_TYPE_UNSIGNED_16, 2)
+ELEMENT_AT(ushort3, RS_TYPE_UNSIGNED_16, 3)
+ELEMENT_AT(ushort4, RS_TYPE_UNSIGNED_16, 4)
+ELEMENT_AT(int, RS_TYPE_SIGNED_32, 1)
+ELEMENT_AT(int2, RS_TYPE_SIGNED_32, 2)
+ELEMENT_AT(int3, RS_TYPE_SIGNED_32, 3)
+ELEMENT_AT(int4, RS_TYPE_SIGNED_32, 4)
+ELEMENT_AT(uint, RS_TYPE_UNSIGNED_32, 1)
+ELEMENT_AT(uint2, RS_TYPE_UNSIGNED_32, 2)
+ELEMENT_AT(uint3, RS_TYPE_UNSIGNED_32, 3)
+ELEMENT_AT(uint4, RS_TYPE_UNSIGNED_32, 4)
+ELEMENT_AT(long, RS_TYPE_SIGNED_64, 1)
+ELEMENT_AT(long2, RS_TYPE_SIGNED_64, 2)
+ELEMENT_AT(long3, RS_TYPE_SIGNED_64, 3)
+ELEMENT_AT(long4, RS_TYPE_SIGNED_64, 4)
+ELEMENT_AT(ulong, RS_TYPE_UNSIGNED_64, 1)
+ELEMENT_AT(ulong2, RS_TYPE_UNSIGNED_64, 2)
+ELEMENT_AT(ulong3, RS_TYPE_UNSIGNED_64, 3)
+ELEMENT_AT(ulong4, RS_TYPE_UNSIGNED_64, 4)
+ELEMENT_AT(half, RS_TYPE_FLOAT_16, 1)
+ELEMENT_AT(half2, RS_TYPE_FLOAT_16, 2)
+ELEMENT_AT(half3, RS_TYPE_FLOAT_16, 3)
+ELEMENT_AT(half4, RS_TYPE_FLOAT_16, 4)
+ELEMENT_AT(float, RS_TYPE_FLOAT_32, 1)
+ELEMENT_AT(float2, RS_TYPE_FLOAT_32, 2)
+ELEMENT_AT(float3, RS_TYPE_FLOAT_32, 3)
+ELEMENT_AT(float4, RS_TYPE_FLOAT_32, 4)
+ELEMENT_AT(double, RS_TYPE_FLOAT_64, 1)
+ELEMENT_AT(double2, RS_TYPE_FLOAT_64, 2)
+ELEMENT_AT(double3, RS_TYPE_FLOAT_64, 3)
+ELEMENT_AT(double4, RS_TYPE_FLOAT_64, 4)
+
+#undef ELEMENT_AT
+
+#ifndef __LP64__
+/*
+ * We miss some symbols for rs{Get,Set}Element_long,ulong variants because 64
+ * bit integer values are 'long' in RS-land but might be 'long long' in the
+ * driver. Define native_long* and native_ulong* types to be vectors of
+ * 'long' as seen by the driver and define overloaded versions of
+ * rsSetElementAt_* and rsGetElementAt_*. This should get us the correct
+ * mangled names in the driver.
+ */
+
+typedef long native_long2 __attribute__((ext_vector_type(2)));
+typedef long native_long3 __attribute__((ext_vector_type(3)));
+typedef long native_long4 __attribute__((ext_vector_type(4)));
+typedef unsigned long native_ulong2 __attribute__((ext_vector_type(2)));
+typedef unsigned long native_ulong3 __attribute__((ext_vector_type(3)));
+typedef unsigned long native_ulong4 __attribute__((ext_vector_type(4)));
+
+// Add NOLINT to suppress wrong warnings from clang-tidy.
+#define ELEMENT_AT_OVERLOADS(T, U) \
+ void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x, \
+ uint32_t y, uint32_t z) { \
+ rsSetElementAt_##T(a, (T *)val, x, y, z); \
+ } \
+ void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x, \
+ uint32_t y) { \
+ rsSetElementAt_##T(a, (T *)val, x, y, 0); \
+ } \
+ void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x) { \
+ rsSetElementAt_##T(a, (T *)val, x, 0, 0); \
+ } \
+ void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x, uint32_t y, \
+ uint32_t z) { /*NOLINT*/ \
+ rsGetElementAt_##T(a, (T *)val, x, y, z); \
+ } \
+ void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x, \
+ uint32_t y) { /*NOLINT*/ \
+ rsGetElementAt_##T(a, (T *)val, x, y, 0); \
+ } \
+ void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x) { /*NOLINT*/ \
+ rsGetElementAt_##T(a, (T *)val, x, 0, 0); \
+ }
+
+ELEMENT_AT_OVERLOADS(long2, native_long2)
+ELEMENT_AT_OVERLOADS(long3, native_long3)
+ELEMENT_AT_OVERLOADS(long4, native_long4)
+ELEMENT_AT_OVERLOADS(ulong, unsigned long)
+ELEMENT_AT_OVERLOADS(ulong2, native_ulong2)
+ELEMENT_AT_OVERLOADS(ulong3, native_ulong3)
+ELEMENT_AT_OVERLOADS(ulong4, native_ulong4)
+
+// We also need variants of rs{Get,Set}ElementAt_long that take 'long long *' as
+// we might have this overloaded variant in old APKs.
+ELEMENT_AT_OVERLOADS(long, long long)
+
+#undef ELEMENT_AT_OVERLOADS
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// ForEach routines
+//////////////////////////////////////////////////////////////////////////////
+void rsForEachInternal(int slot, rs_script_call *options, int hasOutput,
+ int numInputs, ::rs_allocation *allocs) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ Script *s = const_cast<Script *>(RsdCpuReference::getTlsScript());
+ if (numInputs > RS_KERNEL_MAX_ARGUMENTS) {
+ rsc->setError(RS_ERROR_BAD_SCRIPT,
+ "rsForEachInternal: too many inputs to a kernel.");
+ return;
+ }
+ Allocation *inputs[RS_KERNEL_MAX_ARGUMENTS];
+ for (int i = 0; i < numInputs; i++) {
+ inputs[i] = (Allocation *)allocs[i].p;
+ }
+ Allocation *out = hasOutput ? (Allocation *)allocs[numInputs].p : nullptr;
+ rsrForEach(rsc, s, slot, numInputs, numInputs > 0 ? inputs : nullptr, out,
+ nullptr, 0, (RsScriptCall *)options);
+}
+
+void __attribute__((overloadable))
+rsForEach(::rs_script script, ::rs_allocation in, ::rs_allocation out,
+ const void *usr, const rs_script_call *call) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
+ (Allocation *)out.p, usr, 0, (RsScriptCall *)call);
+}
+
+void __attribute__((overloadable))
+rsForEach(::rs_script script, ::rs_allocation in, ::rs_allocation out,
+ const void *usr) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
+ (Allocation *)out.p, usr, 0, nullptr);
+}
+
+void __attribute__((overloadable))
+rsForEach(::rs_script script, ::rs_allocation in, ::rs_allocation out) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
+ (Allocation *)out.p, nullptr, 0, nullptr);
+}
+
+// These functions are only supported in 32-bit.
+#ifndef __LP64__
+void __attribute__((overloadable))
+rsForEach(::rs_script script, ::rs_allocation in, ::rs_allocation out,
+ const void *usr, uint32_t usrLen) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
+ (Allocation *)out.p, usr, usrLen, nullptr);
+}
+
+void __attribute__((overloadable))
+rsForEach(::rs_script script, ::rs_allocation in, ::rs_allocation out,
+ const void *usr, uint32_t usrLen, const rs_script_call *call) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
+ (Allocation *)out.p, usr, usrLen, (RsScriptCall *)call);
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// Message routines
+//////////////////////////////////////////////////////////////////////////////
+uint32_t rsSendToClient(int cmdID) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ return rsrToClient(rsc, cmdID, (const void *)nullptr, 0);
+}
+
+uint32_t rsSendToClient(int cmdID, const void *data, uint32_t len) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ return rsrToClient(rsc, cmdID, data, len);
+}
+
+uint32_t rsSendToClientBlocking(int cmdID) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ return rsrToClientBlocking(rsc, cmdID, (const void *)nullptr, 0);
+}
+
+uint32_t rsSendToClientBlocking(int cmdID, const void *data, uint32_t len) {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ return rsrToClientBlocking(rsc, cmdID, data, len);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Time routines
+//////////////////////////////////////////////////////////////////////////////
+
+// time_t is int in 32-bit RenderScript. time_t is long in bionic. rsTime and
+// rsLocaltime are set to explicitly take 'const int *' so we generate the
+// correct mangled names.
+#ifndef __LP64__
+int rsTime(int *timer) {
+#else
+time_t rsTime(time_t *timer) {
+#endif
+ Context *rsc = RsdCpuReference::getTlsContext();
+ return rsrTime(rsc, (time_t *)timer);
+}
+
+#ifndef __LP64__
+rs_tm *rsLocaltime(rs_tm *local, const int *timer) {
+#else
+rs_tm *rsLocaltime(rs_tm *local, const time_t *timer) {
+#endif
+ Context *rsc = RsdCpuReference::getTlsContext();
+ return (rs_tm *)rsrLocalTime(rsc, (tm *)local, (time_t *)timer);
+}
+
+int64_t rsUptimeMillis() {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ return rsrUptimeMillis(rsc);
+}
+
+int64_t rsUptimeNanos() {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ return rsrUptimeNanos(rsc);
+}
+
+float rsGetDt() {
+ Context *rsc = RsdCpuReference::getTlsContext();
+ const Script *sc = RsdCpuReference::getTlsScript();
+ return rsrGetDt(rsc, sc);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Debug routines
+//////////////////////////////////////////////////////////////////////////////
+void rsDebug(const char *s, float f) {
+ ALOGD("%s %f, 0x%08x", s, f, *((int *)(&f)));
+}
+
+void rsDebug(const char *s, float f1, float f2) {
+ ALOGD("%s {%f, %f}", s, f1, f2);
+}
+
+void rsDebug(const char *s, float f1, float f2, float f3) {
+ ALOGD("%s {%f, %f, %f}", s, f1, f2, f3);
+}
+
+void rsDebug(const char *s, float f1, float f2, float f3, float f4) {
+ ALOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
+}
+
+void rsDebug(const char *s, const float2 *f2) {
+ float2 f = *f2;
+ ALOGD("%s {%f, %f}", s, f.x, f.y);
+}
+
+void rsDebug(const char *s, const float3 *f3) {
+ float3 f = *f3;
+ ALOGD("%s {%f, %f, %f}", s, f.x, f.y, f.z);
+}
+
+void rsDebug(const char *s, const float4 *f4) {
+ float4 f = *f4;
+ ALOGD("%s {%f, %f, %f, %f}", s, f.x, f.y, f.z, f.w);
+}
+
+// Accept a half value converted to float. This eliminates the need in the
+// driver to properly support the half datatype (either by adding compiler flags
+// for half or link against compiler_rt).
+void rsDebug(const char *s, float f, ushort us) {
+ ALOGD("%s {%f} {0x%hx}", s, f, us);
+}
+
+void rsDebug(const char *s, const float2 *f2, const ushort2 *us2) {
+ float2 f = *f2;
+ ushort2 us = *us2;
+ ALOGD("%s {%f %f} {0x%hx 0x%hx}", s, f.x, f.y, us.x, us.y);
+}
+
+void rsDebug(const char *s, const float3 *f3, const ushort3 *us3) {
+ float3 f = *f3;
+ ushort3 us = *us3;
+ ALOGD("%s {%f %f %f} {0x%hx 0x%hx 0x%hx}", s, f.x, f.y, f.z, us.x, us.y,
+ us.z);
+}
+
+void rsDebug(const char *s, const float4 *f4, const ushort4 *us4) {
+ float4 f = *f4;
+ ushort4 us = *us4;
+ ALOGD("%s {%f %f %f %f} {0x%hx 0x%hx 0x%hx 0x%hx}", s, f.x, f.y, f.z, f.w,
+ us.x, us.y, us.z, us.w);
+}
+
+void rsDebug(const char *s, double d) {
+ ALOGD("%s %f, 0x%08llx", s, d, *((long long *)(&d)));
+}
+
+void rsDebug(const char *s, const double2 *d2) {
+ double2 d = *d2;
+ ALOGD("%s {%f, %f}", s, d.x, d.y);
+}
+
+void rsDebug(const char *s, const double3 *d3) {
+ double3 d = *d3;
+ ALOGD("%s {%f, %f, %f}", s, d.x, d.y, d.z);
+}
+
+void rsDebug(const char *s, const double4 *d4) {
+ double4 d = *d4;
+ ALOGD("%s {%f, %f, %f, %f}", s, d.x, d.y, d.z, d.w);
+}
+
+void rsDebug(const char *s, const rs_matrix4x4 *m) {
+ float *f = (float *)m;
+ ALOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
+ ALOGD("%s %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
+ ALOGD("%s %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
+ ALOGD("%s %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
+}
+
+void rsDebug(const char *s, const rs_matrix3x3 *m) {
+ float *f = (float *)m;
+ ALOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
+ ALOGD("%s %f, %f, %f", s, f[1], f[4], f[7]);
+ ALOGD("%s %f, %f, %f}", s, f[2], f[5], f[8]);
+}
+
+void rsDebug(const char *s, const rs_matrix2x2 *m) {
+ float *f = (float *)m;
+ ALOGD("%s {%f, %f", s, f[0], f[2]);
+ ALOGD("%s %f, %f}", s, f[1], f[3]);
+}
+
+void rsDebug(const char *s, char c) {
+ ALOGD("%s %hhd 0x%hhx", s, c, (unsigned char)c);
+}
+
+void rsDebug(const char *s, const char2 *c2) {
+ char2 c = *c2;
+ ALOGD("%s {%hhd, %hhd} 0x%hhx 0x%hhx", s, c.x, c.y, (unsigned char)c.x,
+ (unsigned char)c.y);
+}
+
+void rsDebug(const char *s, const char3 *c3) {
+ char3 c = *c3;
+ ALOGD("%s {%hhd, %hhd, %hhd} 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z,
+ (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z);
+}
+
+void rsDebug(const char *s, const char4 *c4) {
+ char4 c = *c4;
+ ALOGD("%s {%hhd, %hhd, %hhd, %hhd} 0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y,
+ c.z, c.w, (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z,
+ (unsigned char)c.w);
+}
+
+void rsDebug(const char *s, unsigned char c) {
+ ALOGD("%s %hhu 0x%hhx", s, c, c);
+}
+
+void rsDebug(const char *s, const uchar2 *c2) {
+ uchar2 c = *c2;
+ ALOGD("%s {%hhu, %hhu} 0x%hhx 0x%hhx", s, c.x, c.y, c.x, c.y);
+}
+
+void rsDebug(const char *s, const uchar3 *c3) {
+ uchar3 c = *c3;
+ ALOGD("%s {%hhu, %hhu, %hhu} 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.x,
+ c.y, c.z);
+}
+
+void rsDebug(const char *s, const uchar4 *c4) {
+ uchar4 c = *c4;
+ ALOGD("%s {%hhu, %hhu, %hhu, %hhu} 0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y,
+ c.z, c.w, c.x, c.y, c.z, c.w);
+}
+
+void rsDebug(const char *s, short c) { ALOGD("%s %hd 0x%hx", s, c, c); }
+
+void rsDebug(const char *s, const short2 *c2) {
+ short2 c = *c2;
+ ALOGD("%s {%hd, %hd} 0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
+}
+
+void rsDebug(const char *s, const short3 *c3) {
+ short3 c = *c3;
+ ALOGD("%s {%hd, %hd, %hd} 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y,
+ c.z);
+}
+
+void rsDebug(const char *s, const short4 *c4) {
+ short4 c = *c4;
+ ALOGD("%s {%hd, %hd, %hd, %hd} 0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z,
+ c.w, c.x, c.y, c.z, c.w);
+}
+
+void rsDebug(const char *s, unsigned short c) {
+ ALOGD("%s %hu 0x%hx", s, c, c);
+}
+
+void rsDebug(const char *s, const ushort2 *c2) {
+ ushort2 c = *c2;
+ ALOGD("%s {%hu, %hu} 0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
+}
+
+void rsDebug(const char *s, const ushort3 *c3) {
+ ushort3 c = *c3;
+ ALOGD("%s {%hu, %hu, %hu} 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y,
+ c.z);
+}
+
+void rsDebug(const char *s, const ushort4 *c4) {
+ ushort4 c = *c4;
+ ALOGD("%s {%hu, %hu, %hu, %hu} 0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z,
+ c.w, c.x, c.y, c.z, c.w);
+}
+
+void rsDebug(const char *s, int i) { ALOGD("%s %d 0x%x", s, i, i); }
+
+void rsDebug(const char *s, const int2 *i2) {
+ int2 i = *i2;
+ ALOGD("%s {%d, %d} 0x%x 0x%x", s, i.x, i.y, i.x, i.y);
+}
+
+void rsDebug(const char *s, const int3 *i3) {
+ int3 i = *i3;
+ ALOGD("%s {%d, %d, %d} 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
+}
+
+void rsDebug(const char *s, const int4 *i4) {
+ int4 i = *i4;
+ ALOGD("%s {%d, %d, %d, %d} 0x%x 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.w, i.x,
+ i.y, i.z, i.w);
+}
+
+void rsDebug(const char *s, unsigned int i) { ALOGD("%s %u 0x%x", s, i, i); }
+
+void rsDebug(const char *s, const uint2 *i2) {
+ uint2 i = *i2;
+ ALOGD("%s {%u, %u} 0x%x 0x%x", s, i.x, i.y, i.x, i.y);
+}
+
+void rsDebug(const char *s, const uint3 *i3) {
+ uint3 i = *i3;
+ ALOGD("%s {%u, %u, %u} 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
+}
+
+void rsDebug(const char *s, const uint4 *i4) {
+ uint4 i = *i4;
+ ALOGD("%s {%u, %u, %u, %u} 0x%x 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.w, i.x,
+ i.y, i.z, i.w);
+}
+
+template <typename T>
+static inline long long LL(const T &x) {
+ return static_cast<long long>(x);
+}
+
+template <typename T>
+static inline unsigned long long LLu(const T &x) {
+ return static_cast<unsigned long long>(x);
+}
+
+void rsDebug(const char *s, long l) {
+ ALOGD("%s %lld 0x%llx", s, LL(l), LL(l));
+}
+
+void rsDebug(const char *s, long long ll) {
+ ALOGD("%s %lld 0x%llx", s, LL(ll), LL(ll));
+}
+
+void rsDebug(const char *s, const long2 *c) {
+ long2 ll = *c;
+ ALOGD("%s {%lld, %lld} 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x),
+ LL(ll.y));
+}
+
+void rsDebug(const char *s, const long3 *c) {
+ long3 ll = *c;
+ ALOGD("%s {%lld, %lld, %lld} 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y),
+ LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z));
+}
+
+void rsDebug(const char *s, const long4 *c) {
+ long4 ll = *c;
+ ALOGD("%s {%lld, %lld, %lld, %lld} 0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x),
+ LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w));
+}
+
+void rsDebug(const char *s, unsigned long l) {
+ unsigned long long ll = l;
+ ALOGD("%s %llu 0x%llx", s, ll, ll);
+}
+
+void rsDebug(const char *s, unsigned long long ll) {
+ ALOGD("%s %llu 0x%llx", s, ll, ll);
+}
+
+void rsDebug(const char *s, const ulong2 *c) {
+ ulong2 ll = *c;
+ ALOGD("%s {%llu, %llu} 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x),
+ LLu(ll.y));
+}
+
+void rsDebug(const char *s, const ulong3 *c) {
+ ulong3 ll = *c;
+ ALOGD("%s {%llu, %llu, %llu} 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y),
+ LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z));
+}
+
+void rsDebug(const char *s, const ulong4 *c) {
+ ulong4 ll = *c;
+ ALOGD("%s {%llu, %llu, %llu, %llu} 0x%llx 0x%llx 0x%llx 0x%llx", s,
+ LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y),
+ LLu(ll.z), LLu(ll.w));
+}
+
+// FIXME: We need to export these function signatures for the compatibility
+// library. The C++ name mangling that LLVM uses for ext_vector_type requires
+// different versions for "long" vs. "long long". Note that the called
+// functions are still using the appropriate 64-bit sizes.
+
+#ifndef __LP64__
+typedef long l2 __attribute__((ext_vector_type(2)));
+typedef long l3 __attribute__((ext_vector_type(3)));
+typedef long l4 __attribute__((ext_vector_type(4)));
+typedef unsigned long ul2 __attribute__((ext_vector_type(2)));
+typedef unsigned long ul3 __attribute__((ext_vector_type(3)));
+typedef unsigned long ul4 __attribute__((ext_vector_type(4)));
+
+void rsDebug(const char *s, const l2 *c) {
+ long2 ll = *(const long2 *)c;
+ ALOGD("%s {%lld, %lld} 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x),
+ LL(ll.y));
+}
+
+void rsDebug(const char *s, const l3 *c) {
+ long3 ll = *(const long3 *)c;
+ ALOGD("%s {%lld, %lld, %lld} 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y),
+ LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z));
+}
+
+void rsDebug(const char *s, const l4 *c) {
+ long4 ll = *(const long4 *)c;
+ ALOGD("%s {%lld, %lld, %lld, %lld} 0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x),
+ LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w));
+}
+
+void rsDebug(const char *s, const ul2 *c) {
+ ulong2 ll = *(const ulong2 *)c;
+ ALOGD("%s {%llu, %llu} 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x),
+ LLu(ll.y));
+}
+
+void rsDebug(const char *s, const ul3 *c) {
+ ulong3 ll = *(const ulong3 *)c;
+ ALOGD("%s {%llu, %llu, %llu} 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y),
+ LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z));
+}
+
+void rsDebug(const char *s, const ul4 *c) {
+ ulong4 ll = *(const ulong4 *)c;
+ ALOGD("%s {%llu, %llu, %llu, %llu} 0x%llx 0x%llx 0x%llx 0x%llx", s,
+ LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y),
+ LLu(ll.z), LLu(ll.w));
+}
+#endif
+
+void rsDebug(const char *s, const long2 ll) {
+ ALOGD("%s {%lld, %lld} 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x),
+ LL(ll.y));
+}
+
+void rsDebug(const char *s, const long3 ll) {
+ ALOGD("%s {%lld, %lld, %lld} 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y),
+ LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z));
+}
+
+void rsDebug(const char *s, const long4 ll) {
+ ALOGD("%s {%lld, %lld, %lld, %lld} 0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x),
+ LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w));
+}
+
+void rsDebug(const char *s, const ulong2 ll) {
+ ALOGD("%s {%llu, %llu} 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x),
+ LLu(ll.y));
+}
+
+void rsDebug(const char *s, const ulong3 ll) {
+ ALOGD("%s {%llu, %llu, %llu} 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y),
+ LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z));
+}
+
+void rsDebug(const char *s, const ulong4 ll) {
+ ALOGD("%s {%llu, %llu, %llu, %llu} 0x%llx 0x%llx 0x%llx 0x%llx", s,
+ LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y),
+ LLu(ll.z), LLu(ll.w));
+}
+
+void rsDebug(const char *s, const void *p) { ALOGD("%s %p", s, p); }
diff --git a/rsov/driver/rsovSampler.cpp b/rsov/driver/rsovSampler.cpp
new file mode 100644
index 0000000..f8d946c
--- /dev/null
+++ b/rsov/driver/rsovSampler.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "rsovSampler.h"
+
+#include "rsContext.h"
+
+using android::renderscript::Context;
+using android::renderscript::Sampler;
+using android::renderscript::rs_sampler;
+
+bool rsovSamplerInit(const Context *rsc, const Sampler *s) { return true; }
+
+void rsovSamplerDestroy(const Context *rsc, const Sampler *s) {}
+
+void rsovSamplerUpdateCachedObject(const Context *rsc, const Sampler *alloc,
+ rs_sampler *obj) {
+ obj->p = alloc;
+#ifdef __LP64__
+ obj->unused1 = nullptr;
+ obj->unused2 = nullptr;
+ obj->unused3 = nullptr;
+#endif
+}
diff --git a/rsov/driver/rsovSampler.h b/rsov/driver/rsovSampler.h
new file mode 100644
index 0000000..9b8112c
--- /dev/null
+++ b/rsov/driver/rsovSampler.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef RSOV_SAMPLER_H
+#define RSOV_SAMPLER_H
+
+#include "rs_hal.h"
+
+extern bool rsovSamplerInit(const android::renderscript::Context *rsc,
+ const android::renderscript::Sampler *);
+
+extern void rsovSamplerDestroy(const android::renderscript::Context *rsc,
+ const android::renderscript::Sampler *);
+
+extern void rsovSamplerUpdateCachedObject(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Sampler *,
+ android::renderscript::rs_sampler *obj);
+
+#endif // RSD_SAMPLER_H
diff --git a/rsov/driver/rsovScript.cpp b/rsov/driver/rsovScript.cpp
new file mode 100644
index 0000000..d1a6298
--- /dev/null
+++ b/rsov/driver/rsovScript.cpp
@@ -0,0 +1,934 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "rsovScript.h"
+
+#include "bcinfo/MetadataExtractor.h"
+#include "module.h"
+#include "rsContext.h"
+#include "rsDefines.h"
+#include "rsType.h"
+#include "rsUtils.h"
+#include "rsovAllocation.h"
+#include "rsovContext.h"
+#include "rsovCore.h"
+#include "spirit/file_utils.h"
+#include "spirit/instructions.h"
+#include "spirit/module.h"
+
+#include <fstream>
+#include <functional>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+extern "C" {
+char* __GPUBlock = nullptr;
+}
+
+namespace android {
+namespace renderscript {
+namespace rsov {
+
+namespace {
+// Layout of this struct has to be the same as the struct in generated SPIR-V
+// TODO: generate this file from some spec that is shared with the compiler
+struct rsovTypeInfo {
+ uint32_t element_size; // TODO: not implemented
+ uint32_t x_size;
+ uint32_t y_size;
+ uint32_t z_size;
+};
+
+const char *COMPILER_EXE_PATH = "/system/bin/rs2spirv";
+
+std::vector<const char *> setCompilerArgs(const char *bcFileName,
+ const char *cacheDir) {
+ rsAssert(bcFileName && cacheDir);
+
+ std::vector<const char *> args;
+
+ args.push_back(COMPILER_EXE_PATH);
+ args.push_back(bcFileName);
+
+ args.push_back(nullptr);
+ return args;
+}
+
+void writeBytes(const char *filename, const char *bytes, size_t size) {
+ std::ofstream ofs(filename, std::ios::binary);
+ ofs.write(bytes, size);
+ ofs.close();
+}
+
+std::vector<uint32_t> readWords(const char *filename) {
+ std::ifstream ifs(filename, std::ios::binary);
+
+ ifs.seekg(0, ifs.end);
+ int length = ifs.tellg();
+ ifs.seekg(0, ifs.beg);
+
+ rsAssert(((length & 3) == 0) && "File size expected to be multiples of 4");
+
+ std::vector<uint32_t> spvWords(length / sizeof(uint32_t));
+
+ ifs.read((char *)(spvWords.data()), length);
+
+ ifs.close();
+
+ return spvWords;
+}
+
+std::vector<uint32_t> compileBitcode(const char *resName, const char *cacheDir,
+ const char *bitcode, size_t bitcodeSize,
+ std::vector<uint8_t> &modifiedBitcode) {
+ rsAssert(bitcode && bitcodeSize);
+
+ // TODO: Cache the generated code
+
+ std::string bcFileName(cacheDir);
+ bcFileName.append("/");
+ bcFileName.append(resName);
+ bcFileName.append(".bc");
+
+ writeBytes(bcFileName.c_str(), bitcode, bitcodeSize);
+
+ auto args = setCompilerArgs(bcFileName.c_str(), cacheDir);
+
+ if (!rsuExecuteCommand(COMPILER_EXE_PATH, args.size() - 1, args.data())) {
+ ALOGE("compiler command line failed");
+ return std::vector<uint32_t>();
+ }
+
+ ALOGV("compiler command line succeeded");
+
+ std::string spvFileName(cacheDir);
+ spvFileName.append("/");
+ spvFileName.append(resName);
+ spvFileName.append(".spv");
+
+ std::string modifiedBCFileName(cacheDir);
+ modifiedBCFileName.append("/").append(resName).append("_modified.bc");
+
+ args.pop_back();
+ args.push_back("-bc");
+ args.push_back(modifiedBCFileName.c_str());
+ args.push_back(nullptr);
+
+ if (!rsuExecuteCommand(COMPILER_EXE_PATH, args.size() - 1, args.data())) {
+ ALOGE("compiler command line to create modified bitcode failed");
+ return std::vector<uint32_t>();
+ }
+
+ modifiedBitcode = android::spirit::readFile<uint8_t>(modifiedBCFileName);
+
+ return readWords(spvFileName.c_str());
+}
+
+void splitOffsets(const std::string &str, char delimiter,
+ std::vector<uint32_t> *offsets) {
+ std::stringstream ss(str);
+ std::string tok;
+
+ while (std::getline(ss, tok, delimiter)) {
+ const uint32_t offset = static_cast<uint32_t>(std::stoi(tok));
+ offsets->push_back(offset);
+ }
+}
+
+} // anonymous namespace
+
+bool RSoVScript::isScriptCpuBacked(const Script *s) {
+ return s->mHal.info.mVersionMinor == CPU_SCRIPT_MAGIC_NUMBER;
+}
+
+void RSoVScript::initScriptOnCpu(Script *s, RsdCpuReference::CpuScript *cs) {
+ s->mHal.drv = cs;
+ s->mHal.info.mVersionMajor = 0; // Unused. Don't care.
+ s->mHal.info.mVersionMinor = CPU_SCRIPT_MAGIC_NUMBER;
+}
+
+void RSoVScript::initScriptOnRSoV(Script *s, RSoVScript *rsovScript) {
+ s->mHal.drv = rsovScript;
+ s->mHal.info.mVersionMajor = 0; // Unused. Don't care.
+ s->mHal.info.mVersionMinor = 0;
+}
+
+using android::spirit::Module;
+using android::spirit::Deserialize;
+
+RSoVScript::RSoVScript(RSoVContext *context, std::vector<uint32_t> &&spvWords,
+ bcinfo::MetadataExtractor *ME,
+ std::map<std::string, int> *GA2ID)
+ : mRSoV(context),
+ mDevice(context->getDevice()),
+ mSPIRVWords(std::move(spvWords)),
+ mME(ME),
+ mGlobalAllocationMetadata(nullptr),
+ mGAMapping(GA2ID) {
+ std::unique_ptr<Module> module(Deserialize<Module>(mSPIRVWords));
+
+ const std::string &strGlobalSize =
+ module->findStringOfPrefix(".rsov.GlobalSize:");
+ if (strGlobalSize.empty()) {
+ mGlobals.reset(new RSoVBuffer(context, 4));
+ return;
+ }
+ const size_t colonPosSize = strGlobalSize.find(':');
+ const std::string &strVal = strGlobalSize.substr(colonPosSize + 1);
+ const uint64_t globalSize = static_cast<uint64_t>(std::stol(strVal));
+ if (globalSize > 0) {
+ mGlobals.reset(new RSoVBuffer(context, globalSize));
+ __GPUBlock = mGlobals->getHostPtr();
+ const std::string &offsetStr =
+ module->findStringOfPrefix(".rsov.ExportedVars:");
+ const size_t colonPos = offsetStr.find(':');
+ splitOffsets(offsetStr.substr(colonPos + 1), ';', &mExportedVarOffsets);
+ }
+}
+
+RSoVScript::~RSoVScript() {
+ delete mCpuScript;
+ delete mME;
+}
+
+void RSoVScript::populateScript(Script *) {
+}
+
+void RSoVScript::invokeFunction(uint32_t slot, const void *params,
+ size_t paramLength) {
+ getCpuScript()->invokeFunction(slot, params, paramLength);
+}
+
+int RSoVScript::invokeRoot() { return getCpuScript()->invokeRoot(); }
+
+void RSoVScript::invokeForEach(uint32_t slot, const Allocation **ains,
+ uint32_t inLen, Allocation *aout,
+ const void *usr, uint32_t usrLen,
+ const RsScriptCall *sc) {
+ // TODO: Handle kernel without input Allocation
+ rsAssert(ains);
+ std::vector<RSoVAllocation *> inputAllocations(inLen);
+ for (uint32_t i = 0; i < inLen; ++i) {
+ inputAllocations[i] = static_cast<RSoVAllocation *>(ains[i]->mHal.drv);
+ }
+ RSoVAllocation *outputAllocation =
+ static_cast<RSoVAllocation *>(aout->mHal.drv);
+ runForEach(slot, inLen, inputAllocations, outputAllocation);
+}
+
+void RSoVScript::invokeReduce(uint32_t slot, const Allocation **ains,
+ uint32_t inLen, Allocation *aout,
+ const RsScriptCall *sc) {
+ getCpuScript()->invokeReduce(slot, ains, inLen, aout, sc);
+}
+
+void RSoVScript::invokeInit() {
+ getCpuScript()->invokeInit();
+}
+
+void RSoVScript::invokeFreeChildren() {
+ // TODO: implement this
+}
+
+void RSoVScript::setGlobalVar(uint32_t slot, const void *data,
+ size_t dataLength) {
+ char *basePtr = mGlobals->getHostPtr();
+ rsAssert(basePtr != nullptr);
+ const uint32_t offset = GetExportedVarOffset(slot);
+ memcpy(basePtr + offset, data, dataLength);
+}
+
+void RSoVScript::getGlobalVar(uint32_t slot, void *data, size_t dataLength) {
+ const char *basePtr = mGlobals->getHostPtr();
+ rsAssert(basePtr != nullptr);
+ const uint32_t offset = GetExportedVarOffset(slot);
+ memcpy(data, basePtr + offset, dataLength);
+}
+
+void RSoVScript::setGlobalVarWithElemDims(uint32_t slot, const void *data,
+ size_t dataLength, const Element *elem,
+ const uint32_t *dims,
+ size_t dimLength) {
+ char *basePtr = mGlobals->getHostPtr();
+ rsAssert(basePtr != nullptr);
+ const uint32_t offset = GetExportedVarOffset(slot);
+ char *destPtr = basePtr + offset;
+
+ // We want to look at dimension in terms of integer components,
+ // but dimLength is given in terms of bytes.
+ dimLength /= sizeof(int);
+
+ // Only a single dimension is currently supported.
+ rsAssert(dimLength == 1);
+ if (dimLength != 1) {
+ return;
+ }
+
+ // First do the increment loop.
+ size_t stride = elem->getSizeBytes();
+ const char *cVal = reinterpret_cast<const char *>(data);
+ for (uint32_t i = 0; i < dims[0]; i++) {
+ elem->incRefs(cVal);
+ cVal += stride;
+ }
+
+ // Decrement loop comes after (to prevent race conditions).
+ char *oldVal = destPtr;
+ for (uint32_t i = 0; i < dims[0]; i++) {
+ elem->decRefs(oldVal);
+ oldVal += stride;
+ }
+
+ memcpy(destPtr, data, dataLength);
+}
+
+void RSoVScript::setGlobalBind(uint32_t slot, Allocation *data) {
+ ALOGV("%s succeeded.", __FUNCTION__);
+ // TODO: implement this
+}
+
+void RSoVScript::setGlobalObj(uint32_t slot, ObjectBase *obj) {
+ mCpuScript->setGlobalObj(slot, obj);
+ ALOGV("%s succeeded.", __FUNCTION__);
+}
+
+Allocation *RSoVScript::getAllocationForPointer(const void *ptr) const {
+ // TODO: implement this
+ return nullptr;
+}
+
+int RSoVScript::getGlobalEntries() const {
+ // TODO: implement this
+ return 0;
+}
+
+const char *RSoVScript::getGlobalName(int i) const {
+ // TODO: implement this
+ return nullptr;
+}
+
+const void *RSoVScript::getGlobalAddress(int i) const {
+ // TODO: implement this
+ return nullptr;
+}
+
+size_t RSoVScript::getGlobalSize(int i) const {
+ // TODO: implement this
+ return 0;
+}
+
+uint32_t RSoVScript::getGlobalProperties(int i) const {
+ // TODO: implement this
+ return 0;
+}
+
+void RSoVScript::InitDescriptorAndPipelineLayouts(uint32_t inLen) {
+ // TODO: kernels with zero output allocations
+ std::vector<VkDescriptorSetLayoutBinding> bindings(
+ inLen + 3, {
+ .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
+ });
+ for (uint32_t i = 0; i < inLen + 3; i++) {
+ bindings[i].binding = i;
+ }
+
+ VkDescriptorSetLayoutCreateInfo descriptor_layout = {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .bindingCount = inLen + 3,
+ .pBindings = bindings.data(),
+ };
+
+ VkResult res;
+
+ mDescLayout.resize(NUM_DESCRIPTOR_SETS);
+ res = vkCreateDescriptorSetLayout(mDevice, &descriptor_layout, NULL,
+ mDescLayout.data());
+ rsAssert(res == VK_SUCCESS);
+
+ /* Now use the descriptor layout to create a pipeline layout */
+ VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+ .pNext = nullptr,
+ .pushConstantRangeCount = 0,
+ .pPushConstantRanges = nullptr,
+ .setLayoutCount = NUM_DESCRIPTOR_SETS,
+ .pSetLayouts = mDescLayout.data(),
+ };
+
+ res = vkCreatePipelineLayout(mDevice, &pPipelineLayoutCreateInfo, NULL,
+ &mPipelineLayout);
+ rsAssert(res == VK_SUCCESS);
+}
+
+void RSoVScript::InitShader(uint32_t slot) {
+ VkResult res;
+
+ mShaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+ mShaderStage.pNext = nullptr;
+ mShaderStage.pSpecializationInfo = nullptr;
+ mShaderStage.flags = 0;
+ mShaderStage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
+
+ const char **RSKernelNames = mME->getExportForEachNameList();
+ size_t RSKernelNum = mME->getExportForEachSignatureCount();
+ rsAssert(slot < RSKernelNum);
+ rsAssert(RSKernelNames);
+ rsAssert(RSKernelNames[slot]);
+ // ALOGV("slot = %d kernel name = %s", slot, RSKernelNames[slot]);
+ std::string entryName("entry_");
+ entryName.append(RSKernelNames[slot]);
+
+ mShaderStage.pName = strndup(entryName.c_str(), entryName.size());
+
+ VkShaderModuleCreateInfo moduleCreateInfo = {
+ .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .codeSize = mSPIRVWords.size() * sizeof(unsigned int),
+ .pCode = mSPIRVWords.data(),
+ };
+ res = vkCreateShaderModule(mDevice, &moduleCreateInfo, NULL,
+ &mShaderStage.module);
+ rsAssert(res == VK_SUCCESS);
+}
+
+void RSoVScript::InitDescriptorPool(uint32_t inLen) {
+ VkResult res;
+ // 1 global buffer, 1 global allocation metadata buffer, 1 output allocation,
+ // and inLen input allocations
+ VkDescriptorPoolSize type_count[] = {{
+ .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = inLen + 3,
+ }};
+
+ VkDescriptorPoolCreateInfo descriptor_pool = {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
+ .pNext = nullptr,
+ .maxSets = 1,
+ .poolSizeCount = NELEM(type_count),
+ .pPoolSizes = type_count,
+ };
+
+ res = vkCreateDescriptorPool(mDevice, &descriptor_pool, NULL, &mDescPool);
+ rsAssert(res == VK_SUCCESS);
+}
+
+// Iterate through a list of global allocations that are used inside the module
+// and marshal their type information to a dedicated Vulkan Buffer
+void RSoVScript::MarshalTypeInfo(void) {
+ // Marshal global allocation metadata to the device
+ auto *cs = getCpuScript();
+ int nr_globals = mGAMapping->size();
+ if (mGlobalAllocationMetadata == nullptr) {
+ mGlobalAllocationMetadata.reset(
+ new RSoVBuffer(mRSoV, sizeof(struct rsovTypeInfo) * nr_globals));
+ }
+ struct rsovTypeInfo *mappedMetadata =
+ (struct rsovTypeInfo *)mGlobalAllocationMetadata->getHostPtr();
+ for (int i = 0; i < nr_globals; ++i) {
+ if (getGlobalRsType(cs->getGlobalProperties(i)) ==
+ RsDataType::RS_TYPE_ALLOCATION) {
+ ALOGV("global variable %d is an allocation!", i);
+ const void *host_buf;
+ cs->getGlobalVar(i, (void *)&host_buf, sizeof(host_buf));
+ if (!host_buf) continue;
+ const android::renderscript::Allocation *GA =
+ static_cast<const android::renderscript::Allocation *>(host_buf);
+ const android::renderscript::Type *T = GA->getType();
+ rsAssert(T);
+
+ auto global_it = mGAMapping->find(cs->getGlobalName(i));
+ rsAssert(global_it != (*mGAMapping).end());
+ int id = global_it->second;
+ ALOGV("global allocation %s is mapped to ID %d", cs->getGlobalName(i),
+ id);
+ // TODO: marshal other properties
+ mappedMetadata[id].x_size = T->getDimX();
+ mappedMetadata[id].y_size = T->getDimY();
+ mappedMetadata[id].z_size = T->getDimZ();
+ }
+ }
+}
+
+void RSoVScript::InitDescriptorSet(
+ const std::vector<RSoVAllocation *> &inputAllocations,
+ RSoVAllocation *outputAllocation) {
+ VkResult res;
+
+ VkDescriptorSetAllocateInfo alloc_info = {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+ .pNext = NULL,
+ .descriptorPool = mDescPool,
+ .descriptorSetCount = NUM_DESCRIPTOR_SETS,
+ .pSetLayouts = mDescLayout.data(),
+ };
+
+ mDescSet.resize(NUM_DESCRIPTOR_SETS);
+ res = vkAllocateDescriptorSets(mDevice, &alloc_info, mDescSet.data());
+ rsAssert(res == VK_SUCCESS);
+
+ std::vector<VkWriteDescriptorSet> writes{
+ // Global variables
+ {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstSet = mDescSet[0],
+ .dstBinding = 0,
+ .dstArrayElement = 0,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+ .pBufferInfo = mGlobals->getBufferInfo(),
+ },
+ // Metadata for global Allocations
+ {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstSet = mDescSet[0],
+ .dstBinding = 1,
+ .dstArrayElement = 0,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+ .pBufferInfo = mGlobalAllocationMetadata->getBufferInfo(),
+ },
+ // Output Allocation
+ {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstSet = mDescSet[0],
+ .dstBinding = 2,
+ .dstArrayElement = 0,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+ .pBufferInfo = outputAllocation->getBuffer()->getBufferInfo(),
+ },
+ };
+
+ // Input Allocations
+ for (uint32_t i = 0; i < inputAllocations.size(); ++i) {
+ writes.push_back({
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstSet = mDescSet[0],
+ .dstBinding = 3 + i, // input allocations start from binding #3
+ .dstArrayElement = 0,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+ .pBufferInfo = inputAllocations[i]->getBuffer()->getBufferInfo(),
+ });
+ }
+
+ vkUpdateDescriptorSets(mDevice, writes.size(), writes.data(), 0, NULL);
+}
+
+void RSoVScript::InitPipeline() {
+ // DEPENDS on mShaderStage, i.e., InitShader()
+
+ VkResult res;
+
+ VkComputePipelineCreateInfo pipeline_info = {
+ .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+ .pNext = nullptr,
+ .layout = mPipelineLayout,
+ .basePipelineHandle = VK_NULL_HANDLE,
+ .basePipelineIndex = 0,
+ .flags = 0,
+ .stage = mShaderStage,
+ };
+ res = vkCreateComputePipelines(mDevice, VK_NULL_HANDLE, 1, &pipeline_info,
+ NULL, &mComputePipeline);
+ rsAssert(res == VK_SUCCESS);
+}
+
+void RSoVScript::runForEach(
+ uint32_t slot, uint32_t inLen,
+ const std::vector<RSoVAllocation *> &inputAllocations,
+ RSoVAllocation *outputAllocation) {
+ VkResult res;
+
+ InitShader(slot);
+ InitDescriptorPool(inLen);
+ InitDescriptorAndPipelineLayouts(inLen);
+ MarshalTypeInfo();
+ InitDescriptorSet(inputAllocations, outputAllocation);
+ // InitPipelineCache();
+ InitPipeline();
+
+ VkCommandBuffer cmd;
+
+ VkCommandBufferAllocateInfo cmd_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+ .pNext = nullptr,
+ .commandPool = mRSoV->getCmdPool(),
+ .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+ .commandBufferCount = 1,
+ };
+
+ res = vkAllocateCommandBuffers(mDevice, &cmd_info, &cmd);
+ rsAssert(res == VK_SUCCESS);
+
+ VkCommandBufferBeginInfo cmd_buf_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .pInheritanceInfo = nullptr,
+ };
+
+ res = vkBeginCommandBuffer(cmd, &cmd_buf_info);
+ rsAssert(res == VK_SUCCESS);
+
+ vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, mComputePipeline);
+
+ vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, mPipelineLayout,
+ 0, mDescSet.size(), mDescSet.data(), 0, nullptr);
+ // Assuming all input allocations are of the same dimensionality
+ const uint32_t width = inputAllocations[0]->getWidth();
+ const uint32_t height = rsMax(inputAllocations[0]->getHeight(), 1U);
+ const uint32_t depth = rsMax(inputAllocations[0]->getDepth(), 1U);
+ vkCmdDispatch(cmd, width, height, depth);
+
+ res = vkEndCommandBuffer(cmd);
+ assert(res == VK_SUCCESS);
+
+ VkSubmitInfo submit_info = {
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+ .commandBufferCount = 1,
+ .pCommandBuffers = &cmd,
+ };
+
+ VkFence fence;
+
+ VkFenceCreateInfo fenceInfo = {
+ .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ };
+
+ vkCreateFence(mDevice, &fenceInfo, NULL, &fence);
+
+ vkQueueSubmit(mRSoV->getQueue(), 1, &submit_info, fence);
+
+ // Make sure command buffer is finished
+ do {
+ res = vkWaitForFences(mDevice, 1, &fence, VK_TRUE, 100000);
+ } while (res == VK_TIMEOUT);
+
+ rsAssert(res == VK_SUCCESS);
+
+ vkDestroyFence(mDevice, fence, NULL);
+
+ // TODO: shall we reuse command buffers?
+ VkCommandBuffer cmd_bufs[] = {cmd};
+ vkFreeCommandBuffers(mDevice, mRSoV->getCmdPool(), 1, cmd_bufs);
+
+ vkDestroyPipeline(mDevice, mComputePipeline, nullptr);
+ for (int i = 0; i < NUM_DESCRIPTOR_SETS; i++)
+ vkDestroyDescriptorSetLayout(mDevice, mDescLayout[i], nullptr);
+ vkDestroyPipelineLayout(mDevice, mPipelineLayout, nullptr);
+ vkFreeDescriptorSets(mDevice, mDescPool, NUM_DESCRIPTOR_SETS,
+ mDescSet.data());
+ vkDestroyDescriptorPool(mDevice, mDescPool, nullptr);
+ free((void *)mShaderStage.pName);
+ vkDestroyShaderModule(mDevice, mShaderStage.module, nullptr);
+}
+
+} // namespace rsov
+} // namespace renderscript
+} // namespace android
+
+using android::renderscript::Allocation;
+using android::renderscript::Context;
+using android::renderscript::Element;
+using android::renderscript::ObjectBase;
+using android::renderscript::RsdCpuReference;
+using android::renderscript::Script;
+using android::renderscript::ScriptC;
+using android::renderscript::rs_script;
+using android::renderscript::rsov::RSoVContext;
+using android::renderscript::rsov::RSoVScript;
+using android::renderscript::rsov::compileBitcode;
+
+namespace {
+// A class to parse global allocation metadata; essentially a subset of JSON
+// it would look like {"__RSoV_GA": {"g":42}}
+// The result is stored in a refence to a map<string, int>
+class ParseMD {
+ public:
+ ParseMD(std::string s, std::map<std::string, int> &map)
+ : mString(s), mMapping(map) {}
+
+ bool parse(void) {
+ // remove outermose two pairs of braces
+ mString = removeBraces(mString);
+ if (mString.empty()) {
+ return false;
+ }
+
+ mString = removeBraces(mString);
+ if (mString.empty()) {
+ return false;
+ }
+
+ // Now we are supposed to have a comma-separated list that looks like:
+ // "foo":42, "bar":56
+ split<','>(mString, [&](auto s) {
+ split<':'>(s, nullptr, [&](auto pair) {
+ rsAssert(pair.size() == 2);
+ std::string ga_name = removeQuotes(pair[0]);
+ int id = atoi(pair[1].c_str());
+ ALOGV("ParseMD: global allocation %s has ID %d", ga_name.c_str(), id);
+ mMapping[ga_name] = id;
+ });
+ });
+ return true;
+ }
+
+ private:
+ template <char L, char R>
+ static std::string removeMatching(const std::string &s) {
+ auto leftCBrace = s.find(L);
+ if (leftCBrace == std::string::npos) {
+ return "";
+ }
+ leftCBrace++;
+ return s.substr(leftCBrace, s.rfind(R) - leftCBrace);
+ }
+
+ static std::string removeBraces(const std::string &s) {
+ return removeMatching<'{', '}'>(s);
+ }
+
+ static std::string removeQuotes(const std::string &s) {
+ return removeMatching<'"', '"'>(s);
+ }
+
+ // Splitting a string, and call "each" and/or "all" with individal elements
+ // and a vector of all tokenized elements
+ template <char D>
+ static void split(const std::string &s,
+ std::function<void(const std::string &)> each,
+ std::function<void(const std::vector<const std::string> &)>
+ all = nullptr) {
+ std::vector<const std::string> result;
+ for (std::string::size_type pos = 0; pos < s.size(); pos++) {
+ std::string::size_type begin = pos;
+
+ while (pos <= s.size() && s[pos] != D) pos++;
+ std::string found = s.substr(begin, pos - begin);
+ if (each) each(found);
+ if (all) result.push_back(found);
+ }
+ if (all) all(result);
+ }
+
+ std::string mString;
+ std::map<std::string, int> &mMapping;
+};
+
+} // namespace
+
+class ExtractRSoVMD : public android::spirit::DoNothingVisitor {
+ public:
+ ExtractRSoVMD() : mGAMapping(new std::map<std::string, int>) {}
+
+ void visit(android::spirit::StringInst *s) {
+ ALOGV("ExtractRSoVMD: string = %s", s->mOperand1.c_str());
+ std::map<std::string, int> mapping;
+ ParseMD p(s->mOperand1, mapping);
+ if (p.parse()) {
+ *mGAMapping = std::move(mapping);
+ }
+ }
+
+ std::map<std::string, int> *takeMapping(void) { return mGAMapping.release(); }
+
+ private:
+ std::unique_ptr<std::map<std::string, int> > mGAMapping;
+};
+
+bool rsovScriptInit(const Context *rsc, ScriptC *script, char const *resName,
+ char const *cacheDir, uint8_t const *bitcode,
+ size_t bitcodeSize, uint32_t flags) {
+ RSoVHal *hal = static_cast<RSoVHal *>(rsc->mHal.drv);
+
+ std::unique_ptr<bcinfo::MetadataExtractor> bitcodeMetadata(
+ new bcinfo::MetadataExtractor((const char *)bitcode, bitcodeSize));
+ if (!bitcodeMetadata || !bitcodeMetadata->extract()) {
+ ALOGE("Could not extract metadata from bitcode from %s", resName);
+ return false;
+ }
+
+ std::vector<uint8_t> modifiedBitcode;
+ auto spvWords =
+ compileBitcode(resName, cacheDir, (const char *)bitcode, bitcodeSize, modifiedBitcode);
+ if (!spvWords.empty() && !modifiedBitcode.empty()) {
+ // Extract compiler metadata on allocation->binding mapping
+ android::spirit::Module *module =
+ android::spirit::Deserialize<android::spirit::Module>(spvWords);
+ rsAssert(module);
+ ExtractRSoVMD ga_md;
+ module->accept(&ga_md);
+
+ RSoVScript *rsovScript =
+ new RSoVScript(hal->mRSoV, std::move(spvWords),
+ bitcodeMetadata.release(), ga_md.takeMapping());
+ if (rsovScript) {
+ std::string modifiedResName(resName);
+ modifiedResName.append("_modified");
+ RsdCpuReference::CpuScript *cs = hal->mCpuRef->createScript(
+ script, modifiedResName.c_str(), cacheDir, modifiedBitcode.data(),
+ modifiedBitcode.size(), flags);
+ if (cs != nullptr) {
+ cs->populateScript(script);
+ rsovScript->setCpuScript(cs);
+ RSoVScript::initScriptOnRSoV(script, rsovScript);
+ return true;
+ }
+ }
+ }
+
+ ALOGD("Failed creating an RSoV script for %s", resName);
+ // Fall back to CPU driver instead
+
+ std::unique_ptr<RsdCpuReference::CpuScript> cs(hal->mCpuRef->createScript(
+ script, resName, cacheDir, bitcode, bitcodeSize, flags));
+ if (cs == nullptr) {
+ ALOGE("Failed creating a CPU script %p for %s (%p)", cs.get(), resName,
+ script);
+ return false;
+ }
+ cs->populateScript(script);
+
+ RSoVScript::initScriptOnCpu(script, cs.release());
+
+ return true;
+}
+
+bool rsovInitIntrinsic(const Context *rsc, Script *s, RsScriptIntrinsicID iid,
+ Element *e) {
+ RSoVHal *dc = (RSoVHal *)rsc->mHal.drv;
+ RsdCpuReference::CpuScript *cs = dc->mCpuRef->createIntrinsic(s, iid, e);
+ if (cs == nullptr) {
+ return false;
+ }
+ s->mHal.drv = cs;
+ cs->populateScript(s);
+ return true;
+}
+
+void rsovScriptInvokeForEach(const Context *rsc, Script *s, uint32_t slot,
+ const Allocation *ain, Allocation *aout,
+ const void *usr, size_t usrLen,
+ const RsScriptCall *sc) {
+ if (ain == nullptr) {
+ rsovScriptInvokeForEachMulti(rsc, s, slot, nullptr, 0, aout, usr, usrLen,
+ sc);
+ } else {
+ const Allocation *ains[1] = {ain};
+
+ rsovScriptInvokeForEachMulti(rsc, s, slot, ains, 1, aout, usr, usrLen, sc);
+ }
+}
+
+void rsovScriptInvokeForEachMulti(const Context *rsc, Script *s, uint32_t slot,
+ const Allocation **ains, size_t inLen,
+ Allocation *aout, const void *usr,
+ size_t usrLen, const RsScriptCall *sc) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ cs->invokeForEach(slot, ains, inLen, aout, usr, usrLen, sc);
+}
+
+int rsovScriptInvokeRoot(const Context *dc, Script *s) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ return cs->invokeRoot();
+}
+
+void rsovScriptInvokeInit(const Context *dc, Script *s) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ cs->invokeInit();
+}
+
+void rsovScriptInvokeFreeChildren(const Context *dc, Script *s) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ cs->invokeFreeChildren();
+}
+
+void rsovScriptInvokeFunction(const Context *dc, Script *s, uint32_t slot,
+ const void *params, size_t paramLength) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ cs->invokeFunction(slot, params, paramLength);
+}
+
+void rsovScriptInvokeReduce(const Context *dc, Script *s, uint32_t slot,
+ const Allocation **ains, size_t inLen,
+ Allocation *aout, const RsScriptCall *sc) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ cs->invokeReduce(slot, ains, inLen, aout, sc);
+}
+
+void rsovScriptSetGlobalVar(const Context *dc, const Script *s, uint32_t slot,
+ void *data, size_t dataLength) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ cs->setGlobalVar(slot, data, dataLength);
+}
+
+void rsovScriptGetGlobalVar(const Context *dc, const Script *s, uint32_t slot,
+ void *data, size_t dataLength) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ cs->getGlobalVar(slot, data, dataLength);
+}
+
+void rsovScriptSetGlobalVarWithElemDims(
+ const Context *dc, const Script *s, uint32_t slot, void *data,
+ size_t dataLength, const android::renderscript::Element *elem,
+ const uint32_t *dims, size_t dimLength) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ cs->setGlobalVarWithElemDims(slot, data, dataLength, elem, dims, dimLength);
+}
+
+void rsovScriptSetGlobalBind(const Context *dc, const Script *s, uint32_t slot,
+ Allocation *data) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ cs->setGlobalBind(slot, data);
+}
+
+void rsovScriptSetGlobalObj(const Context *dc, const Script *s, uint32_t slot,
+ ObjectBase *data) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ cs->setGlobalObj(slot, data);
+}
+
+void rsovScriptDestroy(const Context *dc, Script *s) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
+ delete cs;
+ s->mHal.drv = nullptr;
+}
+
+Allocation *rsovScriptGetAllocationForPointer(
+ const android::renderscript::Context *dc,
+ const android::renderscript::Script *sc, const void *ptr) {
+ RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)sc->mHal.drv;
+ return cs->getAllocationForPointer(ptr);
+}
+
+void rsovScriptUpdateCachedObject(const Context *rsc, const Script *script,
+ rs_script *obj) {
+ obj->p = script;
+#ifdef __LP64__
+ obj->unused1 = nullptr;
+ obj->unused2 = nullptr;
+ obj->unused3 = nullptr;
+#endif
+}
diff --git a/rsov/driver/rsovScript.h b/rsov/driver/rsovScript.h
new file mode 100644
index 0000000..1300621
--- /dev/null
+++ b/rsov/driver/rsovScript.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef RSOV_SCRIPT_H
+#define RSOV_SCRIPT_H
+
+#include <vulkan/vulkan.h>
+
+#include <map>
+#include <vector>
+
+#include "bcinfo/MetadataExtractor.h"
+#include "rsDefines.h"
+#include "rs_hal.h"
+#include "rsd_cpu.h"
+
+namespace android {
+namespace renderscript {
+
+class Allocation;
+class Context;
+class Element;
+class Script;
+class ScriptC;
+
+namespace rsov {
+
+class RSoVAllocation;
+class RSoVBuffer;
+class RSoVContext;
+
+// TODO: CpuScript is a bad name for the base class. Fix with a refactoring.
+class RSoVScript : RsdCpuReference::CpuScript {
+ public:
+ RSoVScript(RSoVContext *context, std::vector<uint32_t> &&spvWords,
+ bcinfo::MetadataExtractor *ME,
+ std::map<std::string, int> *GAMapping);
+ RSoVScript(RSoVContext *context, const std::vector<uint32_t> &spvWords,
+ bcinfo::MetadataExtractor *ME,
+ std::map<std::string, int> *GAMapping) = delete;
+
+ virtual ~RSoVScript();
+
+ static bool isScriptCpuBacked(const Script *s);
+ static void initScriptOnCpu(Script *s, RsdCpuReference::CpuScript *cs);
+ static void initScriptOnRSoV(Script *s, RSoVScript *rsovScript);
+
+ void populateScript(Script *) override;
+ void invokeFunction(uint32_t slot, const void *params,
+ size_t paramLength) override;
+ int invokeRoot() override;
+
+ void invokeForEach(uint32_t slot, const Allocation **ains, uint32_t inLen,
+ Allocation *aout, const void *usr, uint32_t usrLen,
+ const RsScriptCall *sc) override;
+
+ void invokeReduce(uint32_t slot, const Allocation **ains, uint32_t inLen,
+ Allocation *aout, const RsScriptCall *sc) override;
+
+ void invokeInit() override;
+ void invokeFreeChildren() override;
+
+ void setGlobalVar(uint32_t slot, const void *data,
+ size_t dataLength) override;
+ void getGlobalVar(uint32_t slot, void *data, size_t dataLength) override;
+ void setGlobalVarWithElemDims(uint32_t slot, const void *data,
+ size_t dataLength, const Element *e,
+ const uint32_t *dims,
+ size_t dimLength) override;
+
+ void setGlobalBind(uint32_t slot, Allocation *data) override;
+ void setGlobalObj(uint32_t slot, ObjectBase *obj) override;
+
+ Allocation *getAllocationForPointer(const void *ptr) const override;
+
+ // Returns number of global variables in this Script (may be 0 if
+ // compiler is not configured to emit this information).
+ int getGlobalEntries() const override;
+ // Returns the name of the global variable at index i.
+ const char *getGlobalName(int i) const override;
+ // Returns the CPU address of the global variable at index i.
+ const void *getGlobalAddress(int i) const override;
+ // Returns the size (in bytes) of the global variable at index i.
+ size_t getGlobalSize(int i) const override;
+ // Returns the properties of the global variable at index i.
+ uint32_t getGlobalProperties(int i) const override;
+
+ void setCpuScript(RsdCpuReference::CpuScript *cs) { mCpuScript = cs; }
+
+ RsdCpuReference::CpuScript *getCpuScript() const { return mCpuScript; }
+
+ private:
+ void InitDescriptorAndPipelineLayouts(uint32_t inLen);
+ void InitShader(uint32_t slot);
+ void InitDescriptorPool(uint32_t inLen);
+ void InitDescriptorSet(const std::vector<RSoVAllocation *> &inputAllocations,
+ RSoVAllocation *outputAllocation);
+ void InitPipelineCache();
+ void InitPipeline();
+ void MarshalTypeInfo();
+ void runForEach(uint32_t slot, uint32_t inLen,
+ const std::vector<RSoVAllocation *> &input,
+ RSoVAllocation *output);
+
+ // Gets the offset for the global variable with the given slot number in
+ // the global buffer
+ uint32_t GetExportedVarOffset(uint32_t slot) const {
+ // High-level Java or C++ API has verified that slot is in range
+ return mExportedVarOffsets[slot];
+ }
+
+ static constexpr int CPU_SCRIPT_MAGIC_NUMBER = 0x60000;
+
+ RSoVContext *mRSoV;
+ VkDevice mDevice;
+ std::vector<uint32_t> mSPIRVWords;
+ RsdCpuReference::CpuScript *mCpuScript;
+
+ static constexpr int NUM_DESCRIPTOR_SETS = 1;
+ std::vector<VkDescriptorSetLayout> mDescLayout;
+ VkPipelineLayout mPipelineLayout;
+ VkPipeline mComputePipeline;
+ // TODO: Multiple stages for multiple kernels
+ VkPipelineShaderStageCreateInfo mShaderStage;
+ VkDescriptorPool mDescPool;
+ std::vector<VkDescriptorSet> mDescSet;
+ // For kernel names
+ const bcinfo::MetadataExtractor *mME;
+ std::unique_ptr<RSoVBuffer> mGlobals;
+ std::vector<uint32_t> mExportedVarOffsets;
+ // Metadata of global allocations
+ std::unique_ptr<RSoVBuffer> mGlobalAllocationMetadata;
+ // Mapping of global allocation to rsov-assigned ID
+ std::unique_ptr<std::map<std::string, int> > mGAMapping;
+};
+
+} // namespace rsov
+} // namespace renderscript
+} // namespace android
+
+extern bool rsovScriptInit(const android::renderscript::Context *rsc,
+ android::renderscript::ScriptC *script,
+ char const *resName, char const *cacheDir,
+ uint8_t const *bitcode, size_t bitcodeSize,
+ uint32_t flags);
+
+extern bool rsovInitIntrinsic(const android::renderscript::Context *rsc,
+ android::renderscript::Script *s,
+ RsScriptIntrinsicID iid,
+ android::renderscript::Element *e);
+
+extern void rsovScriptInvokeFunction(const android::renderscript::Context *dc,
+ android::renderscript::Script *script,
+ uint32_t slot, const void *params,
+ size_t paramLength);
+
+extern void rsovScriptInvokeForEach(
+ const android::renderscript::Context *rsc, android::renderscript::Script *s,
+ uint32_t slot, const android::renderscript::Allocation *ain,
+ android::renderscript::Allocation *aout, const void *usr, size_t usrLen,
+ const RsScriptCall *sc);
+
+extern void rsovScriptInvokeReduce(
+ const android::renderscript::Context *rsc, android::renderscript::Script *s,
+ uint32_t slot, const android::renderscript::Allocation **ains, size_t inLen,
+ android::renderscript::Allocation *aout, const RsScriptCall *sc);
+
+extern void rsovScriptInvokeForEachMulti(
+ const android::renderscript::Context *rsc, android::renderscript::Script *s,
+ uint32_t slot, const android::renderscript::Allocation **ains, size_t inLen,
+ android::renderscript::Allocation *aout, const void *usr, size_t usrLen,
+ const RsScriptCall *sc);
+
+extern int rsovScriptInvokeRoot(const android::renderscript::Context *dc,
+ android::renderscript::Script *script);
+
+extern void rsovScriptInvokeInit(const android::renderscript::Context *dc,
+ android::renderscript::Script *script);
+
+extern void rsovScriptInvokeFreeChildren(
+ const android::renderscript::Context *dc,
+ android::renderscript::Script *script);
+
+extern void rsovScriptSetGlobalVar(const android::renderscript::Context *,
+ const android::renderscript::Script *,
+ uint32_t slot, void *data, size_t dataLen);
+
+extern void rsovScriptGetGlobalVar(const android::renderscript::Context *,
+ const android::renderscript::Script *,
+ uint32_t slot, void *data, size_t dataLen);
+
+extern void rsovScriptSetGlobalVarWithElemDims(
+ const android::renderscript::Context *,
+ const android::renderscript::Script *, uint32_t slot, void *data,
+ size_t dataLength, const android::renderscript::Element *,
+ const uint32_t *dims, size_t dimLength);
+extern void rsovScriptSetGlobalBind(const android::renderscript::Context *,
+ const android::renderscript::Script *,
+ uint32_t slot,
+ android::renderscript::Allocation *data);
+
+extern void rsovScriptSetGlobalObj(const android::renderscript::Context *,
+ const android::renderscript::Script *,
+ uint32_t slot,
+ android::renderscript::ObjectBase *data);
+
+extern void rsovScriptSetGlobal(const android::renderscript::Context *dc,
+ const android::renderscript::Script *script,
+ uint32_t slot, void *data, size_t dataLength);
+extern void rsovScriptGetGlobal(const android::renderscript::Context *dc,
+ const android::renderscript::Script *script,
+ uint32_t slot, void *data, size_t dataLength);
+extern void rsovScriptDestroy(const android::renderscript::Context *dc,
+ android::renderscript::Script *script);
+
+extern android::renderscript::Allocation *rsovScriptGetAllocationForPointer(
+ const android::renderscript::Context *dc,
+ const android::renderscript::Script *script, const void *);
+
+extern void rsovScriptUpdateCachedObject(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Script *script,
+ android::renderscript::rs_script *obj);
+
+#endif // RSOV_SCRIPT_H
diff --git a/rsov/driver/rsovScriptGroup.cpp b/rsov/driver/rsovScriptGroup.cpp
new file mode 100644
index 0000000..3603c04
--- /dev/null
+++ b/rsov/driver/rsovScriptGroup.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "rsovCore.h"
+
+#include "rsAllocation.h"
+#include "rsContext.h"
+#include "rsScript.h"
+#include "rsScriptGroup.h"
+#include "rsd_cpu.h"
+
+using android::renderscript::Allocation;
+using android::renderscript::Context;
+using android::renderscript::RsdCpuReference;
+using android::renderscript::ScriptGroup;
+using android::renderscript::ScriptGroupBase;
+using android::renderscript::ScriptKernelID;
+using android::renderscript::rs_script_group;
+
+bool rsovScriptGroupInit(const Context *rsc, ScriptGroupBase *sg) {
+ // Always falls back to CPU implmentation of ScriptGroup
+ RSoVHal *dc = (RSoVHal *)rsc->mHal.drv;
+
+ sg->mHal.drv = dc->mCpuRef->createScriptGroup(sg);
+ return sg->mHal.drv != nullptr;
+}
+
+void rsovScriptGroupSetInput(const Context *rsc, const ScriptGroup *sg,
+ const ScriptKernelID *kid, Allocation *) {}
+
+void rsovScriptGroupSetOutput(const Context *rsc, const ScriptGroup *sg,
+ const ScriptKernelID *kid, Allocation *) {}
+
+void rsovScriptGroupExecute(const Context *rsc, const ScriptGroupBase *sg) {
+ RsdCpuReference::CpuScriptGroupBase *sgi =
+ (RsdCpuReference::CpuScriptGroupBase *)sg->mHal.drv;
+ sgi->execute();
+}
+
+void rsovScriptGroupDestroy(const Context *rsc, const ScriptGroupBase *sg) {
+ RsdCpuReference::CpuScriptGroupBase *sgi =
+ (RsdCpuReference::CpuScriptGroupBase *)sg->mHal.drv;
+ delete sgi;
+}
diff --git a/rsov/driver/rsovScriptGroup.h b/rsov/driver/rsovScriptGroup.h
new file mode 100644
index 0000000..1a16136
--- /dev/null
+++ b/rsov/driver/rsovScriptGroup.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef RSOV_SCRIPT_GROUP_H
+#define RSOV_SCRIPT_GROUP_H
+
+#include "rs_hal.h"
+
+bool rsovScriptGroupInit(const android::renderscript::Context *rsc,
+ android::renderscript::ScriptGroupBase *sg);
+void rsovScriptGroupSetInput(const android::renderscript::Context *rsc,
+ const android::renderscript::ScriptGroup *sg,
+ const android::renderscript::ScriptKernelID *kid,
+ android::renderscript::Allocation *);
+void rsovScriptGroupSetOutput(const android::renderscript::Context *rsc,
+ const android::renderscript::ScriptGroup *sg,
+ const android::renderscript::ScriptKernelID *kid,
+ android::renderscript::Allocation *);
+void rsovScriptGroupExecute(const android::renderscript::Context *rsc,
+ const android::renderscript::ScriptGroupBase *sg);
+void rsovScriptGroupDestroy(const android::renderscript::Context *rsc,
+ const android::renderscript::ScriptGroupBase *sg);
+
+#endif // RSOV_SCRIPT_GROUP_H
diff --git a/rsov/driver/rsovType.cpp b/rsov/driver/rsovType.cpp
new file mode 100644
index 0000000..9930bb8
--- /dev/null
+++ b/rsov/driver/rsovType.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "rsContext.h"
+#include "rsType.h"
+
+using android::renderscript::Context;
+using android::renderscript::Type;
+using android::renderscript::rs_type;
+
+bool rsovTypeInit(const Context *, const Type *t) { return true; }
+
+void rsovTypeDestroy(const Context *rsc, const Type *t) {}
+
+void rsovTypeUpdateCachedObject(const Context *rsc, const Type *t,
+ rs_type *obj) {
+ obj->p = t;
+#ifdef __LP64__
+ obj->unused1 = nullptr;
+ obj->unused2 = nullptr;
+ obj->unused3 = nullptr;
+#endif
+}
diff --git a/rsov/driver/rsovType.h b/rsov/driver/rsovType.h
new file mode 100644
index 0000000..39f31dc
--- /dev/null
+++ b/rsov/driver/rsovType.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef RSOV_TYPE_H
+#define RSOV_TYPE_H
+
+#include "rs_hal.h"
+
+extern bool rsovTypeInit(const android::renderscript::Context *rsc,
+ const android::renderscript::Type *);
+
+extern void rsovTypeDestroy(const android::renderscript::Context *rsc,
+ const android::renderscript::Type *);
+
+extern void rsovTypeUpdateCachedObject(
+ const android::renderscript::Context *rsc,
+ const android::renderscript::Type *, android::renderscript::rs_type *obj);
+
+#endif // RSD_TYPE_H
diff --git a/rsov/tests/Android.mk b/rsov/tests/Android.mk
new file mode 100644
index 0000000..06657c2
--- /dev/null
+++ b/rsov/tests/Android.mk
@@ -0,0 +1,12 @@
+#=====================================================================
+# Include Subdirectories
+#=====================================================================
+
+# Not building RSoV tests in PDK builds.
+ifneq ($(TARGET_BUILD_PDK), true)
+
+LOCAL_PATH:=$(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
+endif # TARGET_BUILD_PDK
diff --git a/rsov/tests/RSoVTest/Android.mk b/rsov/tests/RSoVTest/Android.mk
new file mode 100644
index 0000000..c89902f
--- /dev/null
+++ b/rsov/tests/RSoVTest/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2016 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_RENDERSCRIPT_FLAGS := -target-api 0
+
+LOCAL_PACKAGE_NAME := RSoVTest
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/rsov/tests/RSoVTest/AndroidManifest.xml b/rsov/tests/RSoVTest/AndroidManifest.xml
new file mode 100644
index 0000000..936dd9f
--- /dev/null
+++ b/rsov/tests/RSoVTest/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.rs.rsov.test">
+ <application
+ android:largeHeap="true"
+ android:label="_RSoV_Test"
+ android:icon="@drawable/test_pattern">
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="RSoVTest"
+ android:screenOrientation="portrait">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.rs.rsov.test"/>
+</manifest>
diff --git a/rsov/tests/RSoVTest/res/drawable-nodpi/test_pattern.png b/rsov/tests/RSoVTest/res/drawable-nodpi/test_pattern.png
new file mode 100644
index 0000000..7b34438
--- /dev/null
+++ b/rsov/tests/RSoVTest/res/drawable-nodpi/test_pattern.png
Binary files differ
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/RSoVTest.java b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/RSoVTest.java
new file mode 100644
index 0000000..f9035d2
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/RSoVTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 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.rsov.test;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.renderscript.RenderScript;
+import android.util.Log;
+
+public class RSoVTest extends ListActivity {
+
+ private static final String LOG_TAG = "RSTest";
+ private static final boolean DEBUG = false;
+ private static final boolean LOG_ENABLED = false;
+
+ private RenderScript mRS;
+ private RSoVTestCore RSTC;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mRS = RenderScript.create(this);
+
+ RSTC = new RSoVTestCore(this);
+ RSTC.init(mRS);
+ }
+
+ static void log(String message) {
+ if (LOG_ENABLED) {
+ Log.v(LOG_TAG, message);
+ }
+ }
+
+
+}
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/RSoVTestCore.java b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/RSoVTestCore.java
new file mode 100644
index 0000000..634c1ad
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/RSoVTestCore.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2016 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.rsov.test;
+
+import android.app.ListActivity;
+import android.renderscript.Allocation;
+import android.renderscript.RenderScript;
+import android.widget.ArrayAdapter;
+
+import java.util.ArrayList;
+import java.util.ListIterator;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class RSoVTestCore {
+ ListActivity mCtx;
+
+ public RSoVTestCore(ListActivity ctx) {
+ mCtx = ctx;
+ }
+
+ private RenderScript mRS;
+
+ private ArrayList<UnitTest> unitTests;
+ private ListIterator<UnitTest> test_iter;
+ private UnitTest activeTest;
+ private boolean stopTesting;
+
+ private ScriptField_ListAllocs_s mListAllocs;
+
+ private ArrayAdapter<UnitTest> testAdapter;
+
+ /* Periodic timer for ensuring future tests get scheduled */
+ private Timer mTimer;
+ public static final int RS_TIMER_PERIOD = 100;
+
+ public void init(RenderScript rs) {
+ mRS = rs;
+ stopTesting = false;
+
+ unitTests = new ArrayList<UnitTest>();
+
+ unitTests.add(new UT_invert(this, mCtx));
+ unitTests.add(new UT_modulo(this, mCtx));
+ unitTests.add(new UT_multi_kernel(this, mCtx));
+ unitTests.add(new UT_multi_input(this, mCtx));
+ unitTests.add(new UT_global_query(this, mCtx));
+ unitTests.add(new UT_global(this, mCtx));
+
+ UnitTest[] uta = new UnitTest[unitTests.size()];
+ uta = unitTests.toArray(uta);
+
+ /*
+ mListAllocs = new ScriptField_ListAllocs_s(mRS, uta.length);
+ for (int i = 0; i < uta.length; i++) {
+ ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item();
+ listElem.text = Allocation.createFromString(mRS, uta[i].name, Allocation.USAGE_SCRIPT);
+ listElem.result = uta[i].getResult();
+ mListAllocs.set(listElem, i, false);
+ uta[i].setItem(listElem);
+ }
+
+ mListAllocs.copyAll();
+ */
+ testAdapter = new ArrayAdapter<UnitTest>(mCtx, android.R.layout.simple_list_item_1, unitTests);
+ mCtx.setListAdapter(testAdapter);
+
+ test_iter = unitTests.listIterator();
+ refreshTestResults(); /* Kick off the first test */
+
+ TimerTask pTask = new TimerTask() {
+ public void run() {
+ refreshTestResults();
+ }
+ };
+
+ mTimer = new Timer();
+ mTimer.schedule(pTask, RS_TIMER_PERIOD, RS_TIMER_PERIOD);
+ }
+
+ public void checkAndRunNextTest() {
+ mCtx.runOnUiThread(new Runnable() {
+ public void run() {
+ if (testAdapter != null)
+ testAdapter.notifyDataSetChanged();
+ }
+ });
+
+ if (activeTest != null) {
+ if (!activeTest.isAlive()) {
+ /* Properly clean up on our last test */
+ try {
+ activeTest.join();
+ } catch (InterruptedException e) {
+ }
+ activeTest = null;
+ }
+ }
+
+ if (!stopTesting && activeTest == null) {
+ if (test_iter.hasNext()) {
+ activeTest = test_iter.next();
+ activeTest.start();
+ /* This routine will only get called once when a new test
+ * should start running. The message handler in UnitTest.java
+ * ensures this. */
+ } else {
+ if (mTimer != null) {
+ mTimer.cancel();
+ mTimer.purge();
+ mTimer = null;
+ }
+ }
+ }
+ }
+
+ public void refreshTestResults() {
+ checkAndRunNextTest();
+ }
+
+ public void cleanup() {
+ stopTesting = true;
+ UnitTest t = activeTest;
+
+ /* Stop periodic refresh of testing */
+ if (mTimer != null) {
+ mTimer.cancel();
+ mTimer.purge();
+ mTimer = null;
+ }
+
+ /* Wait to exit until we finish the current test */
+ if (t != null) {
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ }
+ t = null;
+ }
+
+ }
+
+}
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_global.java b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_global.java
new file mode 100644
index 0000000..fe8dacd
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_global.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 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.rsov.test;
+
+import android.content.Context;
+import android.renderscript.*;
+import android.util.Log;
+
+public class UT_global extends UnitTest {
+ private static final String TAG = "global";
+
+ protected UT_global(RSoVTestCore rstc, Context ctx) {
+ super(rstc, "global", ctx);
+ }
+
+ private RenderScript RS;
+ private Allocation A;
+
+ private void test(Element elem, java.lang.Runnable action) {
+ A = Allocation.createSized(RS, elem, 128);
+ action.run();
+ waitForMessage();
+ A.destroy();
+ }
+
+ private void testIntTypes() {
+ ScriptC_global_int s = new ScriptC_global_int(RS);
+
+ test(Element.I32(RS), () -> {
+ int expected = 65536;
+ s.invoke_int_test_init(A);
+ s.set_g_int(expected);
+ s.invoke_int_test(A, expected);
+ });
+
+ test(Element.I32_2(RS), () -> {
+ Int2 expected = new Int2(65536, 65537);;
+ s.invoke_int2_test_init(A);
+ s.set_g_int2(expected);
+ s.invoke_int2_test(A, expected);
+ });
+
+ test(Element.I32_4(RS), () -> {
+ Int4 expected = new Int4(65536, 65537, 65538, 65539);
+ s.invoke_int4_test_init(A);
+ s.set_g_int4(expected);
+ s.invoke_int4_test(A, expected);
+ });
+
+ s.destroy();
+ }
+
+ private void testFloatTypes() {
+ ScriptC_global_float s = new ScriptC_global_float(RS);
+
+ test(Element.F32(RS), () -> {
+ float expected = 3.141593f;
+ s.invoke_float_test_init(A);
+ s.set_g_float(expected);
+ s.invoke_float_test(A, expected);
+ });
+
+ test(Element.F32_2(RS), () -> {
+ Float2 expected = new Float2(3.141593f, 3.141593f / 2);
+ s.invoke_float2_test_init(A);
+ s.set_g_float2(expected);
+ s.invoke_float2_test(A, expected);
+ });
+
+ test(Element.F32_4(RS), () -> {
+ Float4 expected = new Float4(3.141593f, 3.141593f / 2,
+ 3.141593f / 3, 3.141593f / 4);
+ s.invoke_float4_test_init(A);
+ s.set_g_float4(expected);
+ s.invoke_float4_test(A, expected);
+ });
+
+ s.destroy();
+ }
+
+ public void run() {
+ RS = RenderScript.create(mCtx);
+ RS.setMessageHandler(mRsMessage);
+ RS.finish();
+
+ testIntTypes();
+ testFloatTypes();
+
+ RS.destroy();
+ }
+}
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_global_query.java b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_global_query.java
new file mode 100644
index 0000000..821f9d2
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_global_query.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2017 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.rsov.test;
+
+import android.content.Context;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class UT_global_query extends UnitTest {
+ protected UT_global_query(RSoVTestCore rstc, Context ctx) {
+ super(rstc, "global_query", ctx);
+ }
+
+ private boolean Test(int width, int height, int depth) {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_global_query s = new ScriptC_global_query(pRS);
+
+ Type.Builder typeBuilder = new Type.Builder(pRS, Element.I32(pRS));
+ typeBuilder.setX(width);
+ if (height > 0) {
+ typeBuilder.setY(height);
+ if (depth > 0) {
+ typeBuilder.setZ(depth);
+ }
+ }
+
+ if (depth < 1) {
+ depth = 1;
+ }
+
+ if (height < 1) {
+ height = 1;
+ }
+
+ Allocation G = Allocation.createTyped(pRS, typeBuilder.create());
+ Allocation dummy = Allocation.createTyped(pRS, typeBuilder.create());
+ Allocation R = Allocation.createTyped(pRS, typeBuilder.create());
+
+ int g[] = new int[width * height * depth];
+ int d[] = new int[width * height * depth];
+ int r[] = new int[width * height * depth];
+
+ java.util.Random rand = new java.util.Random();
+
+ for (int i = 0; i < width * height * depth; i++) {
+ g[i] = rand.nextInt(123456);
+ d[i] = rand.nextInt(123456);
+ }
+
+ G.copyFrom(g);
+ dummy.copyFrom(d);
+
+ s.set_g(G);
+
+ s.forEach_getDim(dummy, R);
+
+ R.copyTo(r);
+
+ R.destroy();
+ dummy.destroy();
+ G.destroy();
+
+ pRS.finish();
+ pRS.destroy();
+
+ boolean failed = false;
+ for (int i = 0; i < width * height * depth; i++) {
+ if (r[i] != width) {
+ Log.e(name, "expects " + width + " for element " + i +
+ ". got " + r[i]);
+ failed = true;
+ break;
+ }
+ }
+
+ return !failed;
+ }
+
+ public void run() {
+ final int X = 96;
+
+ if (Test(X, 0, 0)) {
+ passTest();
+ return;
+ }
+
+ failTest();
+ }
+}
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_invert.java b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_invert.java
new file mode 100644
index 0000000..017aa06
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_invert.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 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.rsov.test;
+
+import android.content.Context;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class UT_invert extends UnitTest {
+ protected UT_invert(RSoVTestCore rstc, Context ctx) {
+ super(rstc, "invert", ctx);
+ }
+
+ private boolean Test(int width, int height, int depth) {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_invert s = new ScriptC_invert(pRS);
+
+ Type.Builder typeBuilder = new Type.Builder(pRS, Element.F32_4(pRS));
+ typeBuilder.setX(width);
+ if (height > 0) {
+ typeBuilder.setY(height);
+ if (depth > 0) {
+ typeBuilder.setZ(depth);
+ }
+ }
+
+ if (depth < 1) {
+ depth = 1;
+ }
+
+ if (height < 1) {
+ height = 1;
+ }
+
+ Allocation A = Allocation.createTyped(pRS, typeBuilder.create());
+ Allocation B = Allocation.createTyped(pRS, typeBuilder.create());
+
+ float a[] = new float[width * height * depth * 4];
+ float b[] = new float[width * height * depth * 4];
+
+ java.util.Random rand = new java.util.Random();
+
+ for (int i = 0; i < width * height * depth * 4; i++) {
+ a[i] = rand.nextFloat();
+ }
+
+ A.copyFrom(a);
+
+ s.forEach_invert(A, B);
+
+ B.copyTo(b);
+
+ B.destroy();
+ A.destroy();
+
+ pRS.finish();
+ pRS.destroy();
+
+ boolean failed = false;
+ for (int i = 0; i < width * height * depth * 4; i++) {
+ if (b[i] != 1.0f - a[i]) {
+ Log.e(name, "expects " + (1.0f - a[i]) + " for element " + i +
+ ". got " + b[i]);
+ failed = true;
+ break;
+ }
+ }
+
+ return !failed;
+ }
+
+ public void run() {
+ final int X = 96;
+ final int Y = 64;
+ final int Z = 32;
+
+ if (Test(X, 0, 0) && Test(X, Y, 0)) {
+ passTest();
+ return;
+ }
+
+ failTest();
+ }
+}
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_modulo.java b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_modulo.java
new file mode 100644
index 0000000..bb55612
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_modulo.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 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.rsov.test;
+
+import android.content.Context;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class UT_modulo extends UnitTest {
+ private Allocation A;
+ private Allocation B;
+ private final int X = 96;
+ private final int Y = 64;
+
+ protected UT_modulo(RSoVTestCore rstc, Context ctx) {
+ super(rstc, "modulo", ctx);
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_modulo s) {
+ Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ typeBuilder.setX(X);
+ typeBuilder.setY(Y);
+
+ A = Allocation.createTyped(RS, typeBuilder.create());
+ B = Allocation.createTyped(RS, typeBuilder.create());
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_modulo s = new ScriptC_modulo(pRS);
+
+ initializeGlobals(pRS, s);
+
+ int a[] = new int[X*Y];
+ int b[] = new int[X*Y];
+
+ java.util.Random rand = new java.util.Random();
+
+ for (int i = 0; i < X * Y; i++) {
+ a[i] = rand.nextInt(65536);
+ }
+
+ A.copyFrom(a);
+
+ s.forEach_modulo(A, B);
+
+ B.copyTo(b);
+
+ pRS.finish();
+ pRS.destroy();
+
+ boolean failed = false;
+ for (int i = 0; i < X * Y; i++) {
+ int expected = a[i] % 256;
+ if (b[i] != expected) {
+ Log.e(name, "expects " + expected + " got " + b[i]);
+ failed = true;
+ break;
+ }
+ }
+
+ if (failed) {
+ failTest();
+ } else {
+ passTest();
+ }
+ }
+}
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_multi_input.java b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_multi_input.java
new file mode 100644
index 0000000..ebb3853
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_multi_input.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2017 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.rsov.test;
+
+import android.content.Context;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class UT_multi_input extends UnitTest {
+ private Allocation Ain0;
+ private Allocation Ain1;
+
+ private Allocation Out0;
+
+ private final int Xdim = 100;
+ private final float tolerance = 1e-6f;
+
+ protected UT_multi_input(RSoVTestCore rstc, Context ctx) {
+ super(rstc, "Foreach Multi-input", ctx);
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_multi_input s) {
+ Type.Builder floatBuilder = new Type.Builder(RS, Element.F32(RS));
+
+ floatBuilder.setX(Xdim);
+
+ Ain0 = Allocation.createTyped(RS, floatBuilder.create());
+ Ain1 = Allocation.createTyped(RS, floatBuilder.create());
+ Out0 = Allocation.createTyped(RS, floatBuilder.create());
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_multi_input s = new ScriptC_multi_input(pRS);
+
+ initializeGlobals(pRS, s);
+
+ float a[] = new float[Xdim];
+ float b[] = new float[Xdim];
+
+
+ java.util.Random rand = new java.util.Random();
+
+ for (int i = 0; i < Xdim; i++) {
+ a[i] = rand.nextFloat();
+ b[i] = rand.nextFloat();
+ }
+
+ Ain0.copyFrom(a);
+ Ain1.copyFrom(b);
+
+ s.forEach_sum2(Ain0, Ain1, Out0);
+
+ float out0[] = new float[Xdim];
+ float ain0[] = new float[Xdim];
+ float ain1[] = new float[Xdim];
+ Ain0.copyTo(ain0);
+ Ain1.copyTo(ain1);
+ Out0.copyTo(out0);
+
+ pRS.finish();
+ pRS.destroy();
+
+ boolean failed = false;
+ for (int i = 0; i < Xdim; i++) {
+ if (ain0[i] != a[i]) {
+ Log.e(name, "Ain0 was " + a[i] + " but changed to " + ain0[i]);
+ failed = true;
+ break;
+ }
+ if (ain1[i] != b[i]) {
+ Log.e(name, "Ain1 was " + b[i] + " but changed to " + ain1[i]);
+ failed = true;
+ break;
+ }
+ if ((a[i] + b[i] - out0[i]) > tolerance) {
+ float expected = a[i]+b[i];
+ Log.e(name, "expects " + expected + " got " + out0[i]);
+ failed = true;
+ break;
+ }
+ }
+
+ if (failed) {
+ failTest();
+ } else {
+ passTest();
+ }
+ }
+}
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_multi_kernel.java b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_multi_kernel.java
new file mode 100644
index 0000000..980e6e5
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UT_multi_kernel.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 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.rsov.test;
+
+import android.content.Context;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class UT_multi_kernel extends UnitTest {
+ protected UT_multi_kernel(RSoVTestCore rstc, Context ctx) {
+ super(rstc, "multi_kernel", ctx);
+ }
+
+ private boolean Test(int width, int height, int depth) {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_multi_kernel s = new ScriptC_multi_kernel(pRS);
+
+ Type.Builder typeBuilder = new Type.Builder(pRS, Element.F32_4(pRS));
+ typeBuilder.setX(width);
+ if (height > 0) {
+ typeBuilder.setY(height);
+ if (depth > 0) {
+ typeBuilder.setZ(depth);
+ }
+ }
+
+ if (depth < 1) {
+ depth = 1;
+ }
+
+ if (height < 1) {
+ height = 1;
+ }
+
+ Allocation A = Allocation.createTyped(pRS, typeBuilder.create());
+ Allocation B = Allocation.createTyped(pRS, typeBuilder.create());
+
+ float a[] = new float[width * height * depth * 4];
+ float b[] = new float[width * height * depth * 4];
+
+ java.util.Random rand = new java.util.Random(0xcafebabe);
+
+ for (int i = 0; i < width * height * depth * 4; i++) {
+ a[i] = rand.nextFloat();
+ }
+
+ A.copyFrom(a);
+
+ s.forEach_invert(A, B);
+ s.forEach_scalebytwo(B, A);
+ s.forEach_scalebythree(A, B);
+
+ B.copyTo(b);
+
+ B.destroy();
+ A.destroy();
+
+ pRS.finish();
+ pRS.destroy();
+
+ boolean failed = false;
+ for (int i = 0; i < width * height * depth * 4; i++) {
+ if (b[i] != 3.0f * 2.0f * (1.0f - a[i])) {
+ Log.e(name, "expects " + 3.0f * 2.0f * (1.0f - a[i]) + " for element "
+ + i + ". got " + b[i]);
+ failed = true;
+ break;
+ }
+ }
+
+ return !failed;
+ }
+
+ public void run() {
+ final int X = 96;
+ final int Y = 64;
+ final int Z = 32;
+
+ if (Test(X, 0, 0) && Test(X, Y, 0)) {
+ passTest();
+ return;
+ }
+
+ failTest();
+ }
+}
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UnitTest.java b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UnitTest.java
new file mode 100644
index 0000000..f69a96a
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/UnitTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2016 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.rsov.test;
+
+import android.content.Context;
+import android.renderscript.RenderScript.RSMessageHandler;
+import android.util.Log;
+
+public class UnitTest extends Thread {
+ public String name;
+ private int result;
+ private ScriptField_ListAllocs_s.Item mItem;
+ private RSoVTestCore mRSTC;
+ private boolean msgHandled;
+ protected Context mCtx;
+
+ /* These constants must match those in shared.rsh */
+ public static final int RS_MSG_TEST_PASSED = 100;
+ public static final int RS_MSG_TEST_FAILED = 101;
+ public static final int TEST_PASSED = 1;
+ public static final int TEST_FAILED = -1;
+
+ private static int numTests = 0;
+ public int testID;
+
+ protected UnitTest(RSoVTestCore rstc, String n, int initResult, Context ctx) {
+ super();
+ mRSTC = rstc;
+ name = n;
+ msgHandled = false;
+ mCtx = ctx;
+ result = initResult;
+ testID = numTests++;
+ }
+
+ protected UnitTest(RSoVTestCore rstc, String n, Context ctx) {
+ this(rstc, n, 0, ctx);
+ }
+
+ protected UnitTest(RSoVTestCore rstc, Context ctx) {
+ this(rstc, "<Unknown>", ctx);
+ }
+
+ protected UnitTest(Context ctx) {
+ this(null, ctx);
+ }
+
+ protected void _RS_ASSERT(String message, boolean b) {
+ if (b == false) {
+ Log.e(name, message + " FAILED");
+ failTest();
+ }
+ }
+
+ private void updateUI() {
+ msgHandled = true;
+ if (mItem != null) {
+ mItem.result = result;
+ if (mRSTC != null) {
+ // Add null check for mRSTC, for instrumentation tests.
+ try {
+ mRSTC.refreshTestResults();
+ } catch (IllegalStateException e) {
+ /* Ignore the case where our message receiver has been
+ disconnected. This happens when we leave the application
+ before it finishes running all of the unit tests. */
+ }
+ }
+ }
+ }
+
+ protected RSMessageHandler mRsMessage = new RSMessageHandler() {
+ public void run() {
+ if (result == 0) {
+ switch (mID) {
+ case RS_MSG_TEST_PASSED:
+ result = TEST_PASSED;
+ break;
+ case RS_MSG_TEST_FAILED:
+ result = TEST_FAILED;
+ break;
+ default:
+ RSoVTest.log("Unit test got unexpected message");
+ return;
+ }
+ }
+
+ updateUI();
+ }
+ };
+
+ public void waitForMessage() {
+ while (!msgHandled) {
+ yield();
+ }
+ }
+
+ public int getResult() {
+ return result;
+ }
+
+ public void failTest() {
+ result = TEST_FAILED;
+ updateUI();
+ }
+
+ public void passTest() {
+ if (result != TEST_FAILED) {
+ result = TEST_PASSED;
+ }
+ updateUI();
+ }
+
+ public String toString() {
+ String out = name;
+ if (result == TEST_PASSED) {
+ out += " - PASSED";
+ } else if (result == TEST_FAILED) {
+ out += " - FAILED";
+ }
+ return out;
+ }
+
+ public void setItem(ScriptField_ListAllocs_s.Item item) {
+ mItem = item;
+ }
+
+ public void run() {
+ /* This method needs to be implemented for each subclass */
+ if (mRSTC != null) {
+ mRSTC.refreshTestResults();
+ }
+ }
+}
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global.rsh b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global.rsh
new file mode 100644
index 0000000..6e799b5
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global.rsh
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "utils.rsh"
+
+#define DEFINE_TEST(T) \
+ T g_##T=7, notUsed_##T; \
+ /* Test Allocations in between other global variables */ \
+ rs_allocation allocNotUsed_##T; \
+ /* Test statics in between other global variables */ \
+ static T static_##T; \
+ /* Test taking addresses of globals */ \
+ static T *ptr1_##T; \
+ static T *ptr2_##T; \
+ T __attribute__((kernel)) T##_kernel1(T in) { \
+ return g_##T; \
+ } \
+ T __attribute__((kernel)) T##_kernel2(T in) { \
+ return *ptr1_##T + *ptr2_##T; \
+ } \
+ void T##_test_init(rs_allocation a) { \
+ /* Test static local variable */ \
+ rsForEach(T##_kernel1, a, a); \
+ T actual = get_##T(a, 19); \
+ if (!checkEq((T)(7), actual)) { \
+ rsDebug("failed "#T, actual); \
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED); \
+ return; \
+ } \
+ rsDebug("succeeded "#T, actual); \
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED); \
+ } \
+ void T##_test(rs_allocation a, T expected) { \
+ /* Test static local variable */ \
+ static T localStatic; \
+ localStatic = g_##T; \
+ static_##T = localStatic; \
+ ptr1_##T = &g_##T; \
+ ptr2_##T = &static_##T; \
+ rsForEach(T##_kernel2, a, a); \
+ T actual = get_##T(a, 19); \
+ if (!checkEq(expected * 2, actual)) { \
+ rsDebug("failed "#T, actual); \
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED); \
+ return; \
+ } \
+ rsDebug("succeeded "#T, actual); \
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED); \
+ }
+
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global_float.rs
similarity index 83%
copy from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
copy to rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global_float.rs
index b828ae0..3da31dc 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global_float.rs
@@ -14,5 +14,10 @@
* limitations under the License.
*/
-#include "clamp.rscript"
-#pragma rs_fp_relaxed
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.rsov.test)
+
+#include "global.rsh"
+
+HANDLE_TYPE(float)
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global_int.rs
similarity index 83%
copy from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
copy to rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global_int.rs
index b828ae0..ce1ef3e 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global_int.rs
@@ -14,5 +14,10 @@
* limitations under the License.
*/
-#include "clamp.rscript"
-#pragma rs_fp_relaxed
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.rsov.test)
+
+#include "global.rsh"
+
+HANDLE_TYPE(int)
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global_query.rs
similarity index 77%
copy from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
copy to rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global_query.rs
index b828ae0..c15a0b9 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/global_query.rs
@@ -14,5 +14,12 @@
* limitations under the License.
*/
-#include "clamp.rscript"
-#pragma rs_fp_relaxed
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.rsov.test)
+
+rs_allocation g;
+
+int32_t RS_KERNEL getDim(int32_t dummy) {
+ return rsAllocationGetDimX(g);
+}
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/invert.rs
similarity index 74%
copy from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
copy to rsov/tests/RSoVTest/src/com/android/rs/rsov/test/invert.rs
index b828ae0..eb89da2 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/invert.rs
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2016 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.
@@ -14,5 +14,10 @@
* limitations under the License.
*/
-#include "clamp.rscript"
-#pragma rs_fp_relaxed
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.rsov.test)
+
+float4 RS_KERNEL invert(float4 a) {
+ return 1.0f - a;
+}
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/modulo.rs
similarity index 74%
copy from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
copy to rsov/tests/RSoVTest/src/com/android/rs/rsov/test/modulo.rs
index b828ae0..410dccf 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/modulo.rs
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2016 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.
@@ -14,5 +14,10 @@
* limitations under the License.
*/
-#include "clamp.rscript"
-#pragma rs_fp_relaxed
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.rsov.test)
+
+int RS_KERNEL modulo(int a) {
+ return a % 256;
+}
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/multi_input.rs
similarity index 78%
copy from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
copy to rsov/tests/RSoVTest/src/com/android/rs/rsov/test/multi_input.rs
index b828ae0..a05fa5b 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/multi_input.rs
@@ -14,5 +14,11 @@
* limitations under the License.
*/
-#include "clamp.rscript"
-#pragma rs_fp_relaxed
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.rsov.test)
+
+float RS_KERNEL sum2(float in0, float in1, uint32_t x) {
+ return in0 + in1;
+}
+
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/multi_kernel.rs
similarity index 63%
copy from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
copy to rsov/tests/RSoVTest/src/com/android/rs/rsov/test/multi_kernel.rs
index b828ae0..93af5a6 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/multi_kernel.rs
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2016 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.
@@ -14,5 +14,18 @@
* limitations under the License.
*/
-#include "clamp.rscript"
-#pragma rs_fp_relaxed
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.rsov.test)
+
+float4 RS_KERNEL invert(float4 a) {
+ return 1.0f - a;
+}
+
+float4 RS_KERNEL scalebytwo(float4 a) {
+ return 2.0f * a;
+}
+
+float4 RS_KERNEL scalebythree(float4 a) {
+ return 3.0f * a;
+}
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/rslist.rs b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/rslist.rs
new file mode 100644
index 0000000..2d5fa59
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/rslist.rs
@@ -0,0 +1,25 @@
+// Copyright (C) 2009 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.rsov.test)
+
+typedef struct ListAllocs_s {
+ rs_allocation text;
+ int result;
+} ListAllocs;
+
+ListAllocs *gList;
+
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/shared.rsh b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/shared.rsh
new file mode 100644
index 0000000..481e874
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/shared.rsh
@@ -0,0 +1,116 @@
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.rsov.test)
+
+typedef struct TestResult_s {
+ rs_allocation name;
+ bool pass;
+ float score;
+ int64_t time;
+} TestResult;
+//TestResult *g_results;
+
+static int64_t g_time;
+
+static inline void start(void) {
+ g_time = rsUptimeMillis();
+}
+
+static inline float end(uint32_t idx) {
+ int64_t t = rsUptimeMillis() - g_time;
+ //g_results[idx].time = t;
+ //rsDebug("test time", (int)t);
+ return ((float)t) / 1000.f;
+}
+
+#define _RS_ASSERT(b) \
+do { \
+ if (!(b)) { \
+ failed = true; \
+ rsDebug(#b " FAILED", 0); \
+ } \
+\
+} while (0)
+
+#define _RS_ASSERT_EQU(e1, e2) \
+ (((e1) != (e2)) ? (failed = true, rsDebug(#e1 " != " #e2, (e1), (e2)), false) : true)
+
+static const int iposinf = 0x7f800000;
+static const int ineginf = 0xff800000;
+
+static inline const float posinf() {
+ float f = *((float*)&iposinf);
+ return f;
+}
+
+static inline const float neginf() {
+ float f = *((float*)&ineginf);
+ return f;
+}
+
+static inline bool isposinf(float f) {
+ int i = *((int*)(void*)&f);
+ return (i == iposinf);
+}
+
+static inline bool isneginf(float f) {
+ int i = *((int*)(void*)&f);
+ return (i == ineginf);
+}
+
+static inline bool isnan(float f) {
+ int i = *((int*)(void*)&f);
+ return (((i & 0x7f800000) == 0x7f800000) && (i & 0x007fffff));
+}
+
+static inline bool isposzero(float f) {
+ int i = *((int*)(void*)&f);
+ return (i == 0x00000000);
+}
+
+static inline bool isnegzero(float f) {
+ int i = *((int*)(void*)&f);
+ return (i == 0x80000000);
+}
+
+static inline bool iszero(float f) {
+ return isposzero(f) || isnegzero(f);
+}
+
+/* Absolute epsilon used for floats. Value is similar to float.h. */
+#ifndef FLT_EPSILON
+#define FLT_EPSILON 1.19e7f
+#endif
+/* Max ULPs while still being considered "equal". Only used when this number
+ of ULPs is of a greater size than FLT_EPSILON. */
+#define FLT_MAX_ULP 1
+
+/* Calculate the difference in ULPs between the two values. (Return zero on
+ perfect equality.) */
+static inline int float_dist(float f1, float f2) {
+ return *((int *)(&f1)) - *((int *)(&f2));
+}
+
+/* Check if two floats are essentially equal. Will fail with some values
+ due to design. (Validate using FLT_EPSILON or similar if necessary.) */
+static inline bool float_almost_equal(float f1, float f2) {
+ int *i1 = (int*)(&f1);
+ int *i2 = (int*)(&f2);
+
+ // Check for sign equality
+ if ( ((*i1 >> 31) == 0) != ((*i2 >> 31) == 0) ) {
+ // Handle signed zeroes
+ if (f1 == f2)
+ return true;
+ return false;
+ }
+
+ // Check with ULP distance
+ if (float_dist(f1, f2) > FLT_MAX_ULP)
+ return false;
+ return true;
+}
+
+/* These constants must match those in UnitTest.java */
+static const int RS_MSG_TEST_PASSED = 100;
+static const int RS_MSG_TEST_FAILED = 101;
diff --git a/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/utils.rsh b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/utils.rsh
new file mode 100644
index 0000000..08be49c
--- /dev/null
+++ b/rsov/tests/RSoVTest/src/com/android/rs/rsov/test/utils.rsh
@@ -0,0 +1,45 @@
+#ifndef UTILS_RSH
+#define UTILS_RSH
+
+#define RS_MSG_TEST_PASSED 100
+#define RS_MSG_TEST_FAILED 101
+
+#define DEFINE_CHECK(T) \
+ static int __attribute__((overloadable)) \
+ checkEq(T expected, T actual) { \
+ return (expected == actual); \
+ }
+
+#define DEFINE_CHECK2(T) \
+ static int __attribute__((overloadable)) \
+ checkEq(T##2 expected, T##2 actual) { \
+ return (expected.x == actual.x && expected.y == actual.y); \
+ }
+
+#define DEFINE_CHECK4(T) \
+ static int __attribute__((overloadable)) \
+ checkEq(T##4 expected, T##4 actual) { \
+ return (expected.x == actual.x && \
+ expected.y == actual.y && \
+ expected.z == actual.z && \
+ expected.w == actual.w); \
+ }
+
+#define DEFINE_GET(T) \
+ static T __attribute__((overloadable)) \
+ get_##T(rs_allocation a, int x) { \
+ return rsGetElementAt_##T(a, x); \
+ }
+
+#define HANDLE_TYPE(T) \
+ DEFINE_GET(T) \
+ DEFINE_CHECK(T) \
+ DEFINE_TEST(T) \
+ DEFINE_GET(T##2) \
+ DEFINE_CHECK2(T) \
+ DEFINE_TEST(T##2) \
+ DEFINE_GET(T##4) \
+ DEFINE_CHECK4(T) \
+ DEFINE_TEST(T##4) \
+
+#endif // UTILS_RSH
diff --git a/script_api/generate.sh b/script_api/generate.sh
index 1a7fe34..9adc751 100755
--- a/script_api/generate.sh
+++ b/script_api/generate.sh
@@ -59,7 +59,7 @@
for ((i=11; i<=RS_API_LEVEL; i++))
do
- mv slangtest/all$i.rscript ../../compile/slang/tests/P_all_api_$i
+ mv slangtest/all$i.rs ../../compile/slang/tests/P_all_api_$i
done
rm -rf slangtest
diff --git a/tests/cpp_api/cpp-globalguard/Android.mk b/tests/cpp_api/cpp-globalguard/Android.mk
index 0f98f77..b5929d8 100644
--- a/tests/cpp_api/cpp-globalguard/Android.mk
+++ b/tests/cpp_api/cpp-globalguard/Android.mk
@@ -7,7 +7,7 @@
LOCAL_NDK_STL_VARIANT := c++_static
LOCAL_SRC_FILES:= \
- multiply.rscript \
+ multiply.rs \
compute.cpp
LOCAL_STATIC_LIBRARIES := \
diff --git a/tests/cpp_api/cpp-globalguard/multiply.rscript b/tests/cpp_api/cpp-globalguard/multiply.rs
similarity index 100%
rename from tests/cpp_api/cpp-globalguard/multiply.rscript
rename to tests/cpp_api/cpp-globalguard/multiply.rs
diff --git a/tests/cpp_api/cppallocation/Android.mk b/tests/cpp_api/cppallocation/Android.mk
index 3b7a7d7..d578679 100644
--- a/tests/cpp_api/cppallocation/Android.mk
+++ b/tests/cpp_api/cppallocation/Android.mk
@@ -7,7 +7,7 @@
LOCAL_NDK_STL_VARIANT := c++_static
LOCAL_SRC_FILES:= \
- multiply.rscript \
+ multiply.rs \
compute.cpp
LOCAL_STATIC_LIBRARIES := \
diff --git a/tests/cpp_api/cppallocation/multiply.rscript b/tests/cpp_api/cppallocation/multiply.rs
similarity index 100%
rename from tests/cpp_api/cppallocation/multiply.rscript
rename to tests/cpp_api/cppallocation/multiply.rs
diff --git a/tests/cpp_api/cppbasic-getpointer/Android.mk b/tests/cpp_api/cppbasic-getpointer/Android.mk
index c50db0d..7ed2047 100644
--- a/tests/cpp_api/cppbasic-getpointer/Android.mk
+++ b/tests/cpp_api/cppbasic-getpointer/Android.mk
@@ -6,7 +6,7 @@
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_SRC_FILES:= \
- mono.rscript \
+ mono.rs \
compute.cpp
LOCAL_SHARED_LIBRARIES := \
diff --git a/tests/cpp_api/cppbasic-getpointer/mono.rscript b/tests/cpp_api/cppbasic-getpointer/mono.rs
similarity index 100%
rename from tests/cpp_api/cppbasic-getpointer/mono.rscript
rename to tests/cpp_api/cppbasic-getpointer/mono.rs
diff --git a/tests/cpp_api/cppbasic-shared/Android.mk b/tests/cpp_api/cppbasic-shared/Android.mk
index 3ec3035..3d19bfd 100644
--- a/tests/cpp_api/cppbasic-shared/Android.mk
+++ b/tests/cpp_api/cppbasic-shared/Android.mk
@@ -6,7 +6,7 @@
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_SRC_FILES:= \
- mono.rscript \
+ mono.rs \
compute.cpp
LOCAL_SHARED_LIBRARIES := \
diff --git a/tests/cpp_api/cppbasic-shared/mono.rscript b/tests/cpp_api/cppbasic-shared/mono.rs
similarity index 100%
rename from tests/cpp_api/cppbasic-shared/mono.rscript
rename to tests/cpp_api/cppbasic-shared/mono.rs
diff --git a/tests/cpp_api/cppbasic/Android.mk b/tests/cpp_api/cppbasic/Android.mk
index 979d364..0074e36 100644
--- a/tests/cpp_api/cppbasic/Android.mk
+++ b/tests/cpp_api/cppbasic/Android.mk
@@ -7,7 +7,7 @@
LOCAL_NDK_STL_VARIANT := c++_static
LOCAL_SRC_FILES:= \
- mono.rscript \
+ mono.rs \
compute.cpp
LOCAL_STATIC_LIBRARIES := \
diff --git a/tests/cpp_api/cppbasic/mono.rscript b/tests/cpp_api/cppbasic/mono.rs
similarity index 100%
rename from tests/cpp_api/cppbasic/mono.rscript
rename to tests/cpp_api/cppbasic/mono.rs
diff --git a/tests/cpp_api/cppstrided/Android.mk b/tests/cpp_api/cppstrided/Android.mk
index e88f6cf..f9805ef 100644
--- a/tests/cpp_api/cppstrided/Android.mk
+++ b/tests/cpp_api/cppstrided/Android.mk
@@ -7,7 +7,7 @@
LOCAL_NDK_STL_VARIANT := c++_static
LOCAL_SRC_FILES:= \
- multiply.rscript \
+ multiply.rs \
compute.cpp
LOCAL_STATIC_LIBRARIES := \
diff --git a/tests/cpp_api/cppstrided/multiply.rscript b/tests/cpp_api/cppstrided/multiply.rs
similarity index 100%
rename from tests/cpp_api/cppstrided/multiply.rscript
rename to tests/cpp_api/cppstrided/multiply.rs
diff --git a/tests/cpp_api/latency/Android.mk b/tests/cpp_api/latency/Android.mk
index 59d49f5..963363b 100644
--- a/tests/cpp_api/latency/Android.mk
+++ b/tests/cpp_api/latency/Android.mk
@@ -7,7 +7,7 @@
LOCAL_NDK_STL_VARIANT := c++_static
LOCAL_SRC_FILES:= \
- latency.rscript \
+ latency.rs \
latency.cpp
LOCAL_STATIC_LIBRARIES := \
diff --git a/tests/cpp_api/latency/latency.rscript b/tests/cpp_api/latency/latency.rs
similarity index 100%
rename from tests/cpp_api/latency/latency.rscript
rename to tests/cpp_api/latency/latency.rs
diff --git a/tests/cpp_api/typecheck/Android.mk b/tests/cpp_api/typecheck/Android.mk
index 66ad645..1895ed0 100644
--- a/tests/cpp_api/typecheck/Android.mk
+++ b/tests/cpp_api/typecheck/Android.mk
@@ -7,7 +7,7 @@
LOCAL_NDK_STL_VARIANT := c++_static
LOCAL_SRC_FILES:= \
- kernels.rscript \
+ kernels.rs \
typecheck.cpp
LOCAL_STATIC_LIBRARIES := \
diff --git a/tests/cpp_api/typecheck/kernels.rscript b/tests/cpp_api/typecheck/kernels.rs
similarity index 100%
rename from tests/cpp_api/typecheck/kernels.rscript
rename to tests/cpp_api/typecheck/kernels.rs
diff --git a/tests/java_api/Balls/src/com/example/android/rs/balls/ball_physics.rscript b/tests/java_api/Balls/src/com/example/android/rs/balls/ball_physics.rs
similarity index 100%
rename from tests/java_api/Balls/src/com/example/android/rs/balls/ball_physics.rscript
rename to tests/java_api/Balls/src/com/example/android/rs/balls/ball_physics.rs
diff --git a/tests/java_api/Balls/src/com/example/android/rs/balls/balls.rscript b/tests/java_api/Balls/src/com/example/android/rs/balls/balls.rs
similarity index 100%
rename from tests/java_api/Balls/src/com/example/android/rs/balls/balls.rscript
rename to tests/java_api/Balls/src/com/example/android/rs/balls/balls.rs
diff --git a/tests/java_api/CannyLive/src/com/android/example/cannylive/canny.rscript b/tests/java_api/CannyLive/src/com/android/example/cannylive/canny.rs
similarity index 100%
rename from tests/java_api/CannyLive/src/com/android/example/cannylive/canny.rscript
rename to tests/java_api/CannyLive/src/com/android/example/cannylive/canny.rs
diff --git a/tests/java_api/ComputeBenchmark/src/com/example/android/rs/computebench/compute_benchmark.rscript b/tests/java_api/ComputeBenchmark/src/com/example/android/rs/computebench/compute_benchmark.rs
similarity index 100%
rename from tests/java_api/ComputeBenchmark/src/com/example/android/rs/computebench/compute_benchmark.rscript
rename to tests/java_api/ComputeBenchmark/src/com/example/android/rs/computebench/compute_benchmark.rs
diff --git a/tests/java_api/ComputePerf/src/com/example/android/rs/computeperf/launchtest.rscript b/tests/java_api/ComputePerf/src/com/example/android/rs/computeperf/launchtest.rs
similarity index 100%
rename from tests/java_api/ComputePerf/src/com/example/android/rs/computeperf/launchtest.rscript
rename to tests/java_api/ComputePerf/src/com/example/android/rs/computeperf/launchtest.rs
diff --git a/tests/java_api/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rscript b/tests/java_api/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs
similarity index 100%
rename from tests/java_api/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rscript
rename to tests/java_api/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs
diff --git a/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/find_region.rscript b/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/find_region.rs
similarity index 100%
rename from tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/find_region.rscript
rename to tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/find_region.rs
diff --git a/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/healing.rscript b/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/healing.rs
similarity index 100%
rename from tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/healing.rscript
rename to tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/healing.rs
diff --git a/tests/java_api/HelloComputeNDK/libhellocomputendk/Android.mk b/tests/java_api/HelloComputeNDK/libhellocomputendk/Android.mk
index b9fab0b..9f72588 100644
--- a/tests/java_api/HelloComputeNDK/libhellocomputendk/Android.mk
+++ b/tests/java_api/HelloComputeNDK/libhellocomputendk/Android.mk
@@ -21,7 +21,7 @@
LOCAL_MODULE := libhellocomputendk
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := helloComputeNDK.cpp mono.rscript
+LOCAL_SRC_FILES := helloComputeNDK.cpp mono.rs
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
diff --git a/tests/java_api/HelloComputeNDK/libhellocomputendk/mono.rscript b/tests/java_api/HelloComputeNDK/libhellocomputendk/mono.rs
similarity index 100%
rename from tests/java_api/HelloComputeNDK/libhellocomputendk/mono.rscript
rename to tests/java_api/HelloComputeNDK/libhellocomputendk/mono.rs
diff --git a/tests/java_api/HelloComputeNDK/res/drawable-nodpi/data.jpg b/tests/java_api/HelloComputeNDK/res/drawable-nodpi/data.jpg
index b7a0cbd..81a87b1 100644
--- a/tests/java_api/HelloComputeNDK/res/drawable-nodpi/data.jpg
+++ b/tests/java_api/HelloComputeNDK/res/drawable-nodpi/data.jpg
Binary files differ
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/artistic1.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/artistic1.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/artistic1.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/artistic1.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/blend.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/blend.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/blend.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/blend.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/bwfilter.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/bwfilter.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/bwfilter.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/bwfilter.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/colorcube.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/colorcube.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/colorcube.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/colorcube.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/colormatrix.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/colormatrix.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/colormatrix.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/colormatrix.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/contrast.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/contrast.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/contrast.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/contrast.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/convolve3x3.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/convolve3x3.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/convolve3x3.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/convolve3x3.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/convolve5x5.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/convolve5x5.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/convolve5x5.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/convolve5x5.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/copy.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/copy.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/copy.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/copy.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/exposure.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/exposure.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/exposure.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/exposure.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_approx_full.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_approx_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_approx_full.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_approx_full.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_full.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_full.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_full.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/grain.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/grain.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/grain.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/grain.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/greyscale.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/greyscale.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/greyscale.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/greyscale.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/histogram.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/histogram.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/histogram.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/histogram.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/levels_full.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/levels_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/levels_full.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/levels_full.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/levels_relaxed.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/levels_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/levels_relaxed.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/levels_relaxed.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/mandelbrot.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/mandelbrot.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/mandelbrot.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/mandelbrot.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/mirror.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/mirror.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/mirror.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/mirror.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/resize.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/resize.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/resize.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/resize.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/shadows.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/shadows.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/shadows.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/shadows.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/threshold.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/threshold.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/threshold.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/threshold.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/vibrance.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/vibrance.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/vibrance.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/vibrance.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_approx_full.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_approx_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_approx_full.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_approx_full.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_full.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_full.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_full.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_relaxed.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_relaxed.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/vignette_relaxed.rs
diff --git a/tests/java_api/ImageProcessing/src/com/android/rs/image/wbalance.rscript b/tests/java_api/ImageProcessing/src/com/android/rs/image/wbalance.rs
similarity index 100%
rename from tests/java_api/ImageProcessing/src/com/android/rs/image/wbalance.rscript
rename to tests/java_api/ImageProcessing/src/com/android/rs/image/wbalance.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/artistic1.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/artistic1.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/artistic1.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/artistic1.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/blend.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/blend.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/blend.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/blend.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/bwfilter.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/bwfilter.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/bwfilter.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/bwfilter.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/colorcube.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/colorcube.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/colorcube.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/colorcube.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/colormatrix.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/colormatrix.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/colormatrix.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/colormatrix.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/contrast.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/contrast.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/contrast.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/contrast.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/convolve3x3.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/convolve3x3.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/convolve3x3.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/convolve3x3.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/convolve5x5.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/convolve5x5.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/convolve5x5.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/convolve5x5.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/copy.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/copy.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/copy.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/copy.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/exposure.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/exposure.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/exposure.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/exposure.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_approx_full.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_approx_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_approx_full.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_approx_full.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_approx_relaxed.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_approx_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_approx_relaxed.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_approx_relaxed.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_full.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_full.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_full.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_relaxed.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_relaxed.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/fisheye_relaxed.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/grain.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/grain.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/grain.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/grain.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/greyscale.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/greyscale.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/greyscale.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/greyscale.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/levels_full.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/levels_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/levels_full.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/levels_full.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/levels_relaxed.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/levels_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/levels_relaxed.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/levels_relaxed.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/mandelbrot.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/mandelbrot.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/mandelbrot.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/mandelbrot.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/posterize.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/posterize.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/posterize.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/posterize.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/resize.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/resize.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/resize.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/resize.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/shadows.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/shadows.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/shadows.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/shadows.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/threshold.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/threshold.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/threshold.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/threshold.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/util.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/util.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/util.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/util.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/vibrance.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/vibrance.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/vibrance.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/vibrance.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_approx_full.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_approx_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_approx_full.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_approx_full.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_approx_relaxed.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_approx_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_approx_relaxed.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_approx_relaxed.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_full.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_full.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_full.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_relaxed.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_relaxed.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/vignette_relaxed.rs
diff --git a/tests/java_api/ImageProcessing2/src/com/android/rs/image/wbalance.rscript b/tests/java_api/ImageProcessing2/src/com/android/rs/image/wbalance.rs
similarity index 100%
rename from tests/java_api/ImageProcessing2/src/com/android/rs/image/wbalance.rscript
rename to tests/java_api/ImageProcessing2/src/com/android/rs/image/wbalance.rs
diff --git a/tests/java_api/ImageProcessing_jb/res/drawable-nodpi/img3840x2160a.jpg b/tests/java_api/ImageProcessing_jb/res/drawable-nodpi/img3840x2160a.jpg
index 055972a..871b22c 100644
--- a/tests/java_api/ImageProcessing_jb/res/drawable-nodpi/img3840x2160a.jpg
+++ b/tests/java_api/ImageProcessing_jb/res/drawable-nodpi/img3840x2160a.jpg
Binary files differ
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/artistic1.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/artistic1.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/artistic1.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/artistic1.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/blend.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/blend.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/blend.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/blend.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/bwfilter.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/bwfilter.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/bwfilter.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/bwfilter.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/colorcube.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/colorcube.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/colorcube.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/colorcube.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/colormatrix.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/colormatrix.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/colormatrix.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/colormatrix.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/contrast.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/contrast.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/contrast.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/contrast.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/convolve3x3.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/convolve3x3.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/convolve3x3.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/convolve3x3.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/convolve5x5.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/convolve5x5.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/convolve5x5.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/convolve5x5.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/copy.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/copy.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/copy.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/copy.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/exposure.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/exposure.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/exposure.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/exposure.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_full.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_full.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_full.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_relaxed.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_relaxed.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_relaxed.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_full.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_full.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_full.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_relaxed.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_relaxed.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/fisheye_relaxed.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/grain.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/grain.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/grain.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/grain.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/greyscale.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/greyscale.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/greyscale.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/greyscale.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/histogram.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/histogram.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/histogram.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/histogram.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/levels_full.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/levels_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/levels_full.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/levels_full.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/levels_relaxed.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/levels_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/levels_relaxed.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/levels_relaxed.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/mandelbrot.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/mandelbrot.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/mandelbrot.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/mandelbrot.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/posterize.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/posterize.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/posterize.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/posterize.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/resize.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/resize.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/resize.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/resize.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/shadows.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/shadows.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/shadows.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/shadows.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/threshold.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/threshold.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/threshold.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/threshold.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/threshold_half.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/threshold_half.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/threshold_half.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/threshold_half.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vibrance.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vibrance.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vibrance.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vibrance.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_full.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_full.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_full.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_relaxed.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_relaxed.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_relaxed.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_full.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_full.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_full.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_full.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_relaxed.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_relaxed.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_relaxed.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/vignette_relaxed.rs
diff --git a/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/wbalance.rscript b/tests/java_api/ImageProcessing_jb/src/com/android/rs/image/wbalance.rs
similarity index 100%
rename from tests/java_api/ImageProcessing_jb/src/com/android/rs/image/wbalance.rscript
rename to tests/java_api/ImageProcessing_jb/src/com/android/rs/image/wbalance.rs
diff --git a/tests/java_api/LatencyBenchmark/src/com/example/android/rs/computebench/compute_benchmark.rscript b/tests/java_api/LatencyBenchmark/src/com/example/android/rs/computebench/compute_benchmark.rs
similarity index 100%
rename from tests/java_api/LatencyBenchmark/src/com/example/android/rs/computebench/compute_benchmark.rscript
rename to tests/java_api/LatencyBenchmark/src/com/example/android/rs/computebench/compute_benchmark.rs
diff --git a/tests/java_api/LivePreview/src/com/android/rs/livepreview/yuv.rscript b/tests/java_api/LivePreview/src/com/android/rs/livepreview/yuv.rs
similarity index 100%
rename from tests/java_api/LivePreview/src/com/android/rs/livepreview/yuv.rscript
rename to tests/java_api/LivePreview/src/com/android/rs/livepreview/yuv.rs
diff --git a/tests/java_api/MathErr/src/com/example/android/rs/matherr/math_err.rscript b/tests/java_api/MathErr/src/com/example/android/rs/matherr/math_err.rs
similarity index 100%
rename from tests/java_api/MathErr/src/com/example/android/rs/matherr/math_err.rscript
rename to tests/java_api/MathErr/src/com/example/android/rs/matherr/math_err.rs
diff --git a/tests/java_api/RSTestBackward19/Android.mk b/tests/java_api/RSTestBackward19/Android.mk
index 15da2d5..a226b45 100644
--- a/tests/java_api/RSTestBackward19/Android.mk
+++ b/tests/java_api/RSTestBackward19/Android.mk
@@ -32,75 +32,75 @@
$(call all-java-files-under,src)\
$(my_rs_unit_tests_path)/UnitTest.java\
$(my_rs_unit_tests_path)/UT_alloc.java\
- $(my_rs_unit_tests_path)/alloc.rscript\
+ $(my_rs_unit_tests_path)/alloc.rs\
$(my_rs_unit_tests_path)/UT_array_alloc.java\
- $(my_rs_unit_tests_path)/array_alloc.rscript\
+ $(my_rs_unit_tests_path)/array_alloc.rs\
$(my_rs_unit_tests_path)/UT_array_init.java\
- $(my_rs_unit_tests_path)/array_init.rscript\
+ $(my_rs_unit_tests_path)/array_init.rs\
$(my_rs_unit_tests_path)/UT_atomic.java\
- $(my_rs_unit_tests_path)/atomic.rscript\
+ $(my_rs_unit_tests_path)/atomic.rs\
$(my_rs_unit_tests_path)/UT_bitfield.java\
- $(my_rs_unit_tests_path)/bitfield.rscript\
+ $(my_rs_unit_tests_path)/bitfield.rs\
$(my_rs_unit_tests_path)/UT_bug_char.java\
- $(my_rs_unit_tests_path)/bug_char.rscript\
+ $(my_rs_unit_tests_path)/bug_char.rs\
$(my_rs_unit_tests_path)/UT_check_dims.java\
- $(my_rs_unit_tests_path)/check_dims.rscript\
+ $(my_rs_unit_tests_path)/check_dims.rs\
$(my_rs_unit_tests_path)/UT_clamp.java\
- $(my_rs_unit_tests_path)/clamp.rscript\
+ $(my_rs_unit_tests_path)/clamp.rs\
$(my_rs_unit_tests_path)/UT_clamp_relaxed.java\
- $(my_rs_unit_tests_path)/clamp_relaxed.rscript\
+ $(my_rs_unit_tests_path)/clamp_relaxed.rs\
$(my_rs_unit_tests_path)/UT_constant.java\
- $(my_rs_unit_tests_path)/constant.rscript\
+ $(my_rs_unit_tests_path)/constant.rs\
$(my_rs_unit_tests_path)/UT_convert.java\
- $(my_rs_unit_tests_path)/convert.rscript\
+ $(my_rs_unit_tests_path)/convert.rs\
$(my_rs_unit_tests_path)/UT_convert_relaxed.java\
- $(my_rs_unit_tests_path)/convert_relaxed.rscript\
+ $(my_rs_unit_tests_path)/convert_relaxed.rs\
$(my_rs_unit_tests_path)/UT_copy_test.java\
- $(my_rs_unit_tests_path)/copy_test.rscript\
+ $(my_rs_unit_tests_path)/copy_test.rs\
$(my_rs_unit_tests_path)/UT_element.java\
- $(my_rs_unit_tests_path)/element.rscript\
+ $(my_rs_unit_tests_path)/element.rs\
$(my_rs_unit_tests_path)/UT_foreach.java\
- $(my_rs_unit_tests_path)/foreach.rscript\
+ $(my_rs_unit_tests_path)/foreach.rs\
$(my_rs_unit_tests_path)/UT_foreach_bounds.java\
- $(my_rs_unit_tests_path)/foreach_bounds.rscript\
+ $(my_rs_unit_tests_path)/foreach_bounds.rs\
$(my_rs_unit_tests_path)/UT_fp_mad.java\
- $(my_rs_unit_tests_path)/fp_mad.rscript\
+ $(my_rs_unit_tests_path)/fp_mad.rs\
$(my_rs_unit_tests_path)/UT_instance.java\
- $(my_rs_unit_tests_path)/instance.rscript\
+ $(my_rs_unit_tests_path)/instance.rs\
$(my_rs_unit_tests_path)/UT_int4.java\
- $(my_rs_unit_tests_path)/int4.rscript\
+ $(my_rs_unit_tests_path)/int4.rs\
$(my_rs_unit_tests_path)/UT_kernel.java\
- $(my_rs_unit_tests_path)/kernel.rscript\
+ $(my_rs_unit_tests_path)/kernel.rs\
$(my_rs_unit_tests_path)/UT_kernel_struct.java\
- $(my_rs_unit_tests_path)/kernel_struct.rscript\
+ $(my_rs_unit_tests_path)/kernel_struct.rs\
$(my_rs_unit_tests_path)/UT_math.java\
- $(my_rs_unit_tests_path)/math.rscript\
+ $(my_rs_unit_tests_path)/math.rs\
$(my_rs_unit_tests_path)/UT_min.java\
- $(my_rs_unit_tests_path)/min.rscript\
+ $(my_rs_unit_tests_path)/min.rs\
$(my_rs_unit_tests_path)/UT_noroot.java\
- $(my_rs_unit_tests_path)/noroot.rscript\
+ $(my_rs_unit_tests_path)/noroot.rs\
$(my_rs_unit_tests_path)/UT_primitives.java\
- $(my_rs_unit_tests_path)/primitives.rscript\
+ $(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
- $(my_rs_unit_tests_path)/refcount.rscript\
+ $(my_rs_unit_tests_path)/refcount.rs\
$(my_rs_unit_tests_path)/UT_reflection3264.java\
- $(my_rs_unit_tests_path)/reflection3264.rscript\
+ $(my_rs_unit_tests_path)/reflection3264.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
- $(my_rs_unit_tests_path)/rsdebug.rscript\
+ $(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rstime.java\
- $(my_rs_unit_tests_path)/rstime.rscript\
+ $(my_rs_unit_tests_path)/rstime.rs\
$(my_rs_unit_tests_path)/UT_rstypes.java\
- $(my_rs_unit_tests_path)/rstypes.rscript\
+ $(my_rs_unit_tests_path)/rstypes.rs\
$(my_rs_unit_tests_path)/UT_sampler.java\
- $(my_rs_unit_tests_path)/sampler.rscript\
+ $(my_rs_unit_tests_path)/sampler.rs\
$(my_rs_unit_tests_path)/UT_static_globals.java\
- $(my_rs_unit_tests_path)/static_globals.rscript\
+ $(my_rs_unit_tests_path)/static_globals.rs\
$(my_rs_unit_tests_path)/UT_struct.java\
- $(my_rs_unit_tests_path)/struct.rscript\
+ $(my_rs_unit_tests_path)/struct.rs\
$(my_rs_unit_tests_path)/UT_unsigned.java\
- $(my_rs_unit_tests_path)/unsigned.rscript\
+ $(my_rs_unit_tests_path)/unsigned.rs\
$(my_rs_unit_tests_path)/UT_vector.java\
- $(my_rs_unit_tests_path)/vector.rscript\
+ $(my_rs_unit_tests_path)/vector.rs\
include $(BUILD_PACKAGE)
diff --git a/tests/java_api/RSTestForward/21.1.2/Android.mk b/tests/java_api/RSTestForward/21.1.2/Android.mk
index f67fbbd..99bce0c 100644
--- a/tests/java_api/RSTestForward/21.1.2/Android.mk
+++ b/tests/java_api/RSTestForward/21.1.2/Android.mk
@@ -41,79 +41,79 @@
$(call all-java-files-under,src)\
$(my_rs_unit_tests_path)/UnitTest.java\
$(my_rs_unit_tests_path)/UT_alloc.java\
- $(my_rs_unit_tests_path)/alloc.rscript\
+ $(my_rs_unit_tests_path)/alloc.rs\
$(my_rs_unit_tests_path)/UT_array_alloc.java\
- $(my_rs_unit_tests_path)/array_alloc.rscript\
+ $(my_rs_unit_tests_path)/array_alloc.rs\
$(my_rs_unit_tests_path)/UT_array_init.java\
- $(my_rs_unit_tests_path)/array_init.rscript\
+ $(my_rs_unit_tests_path)/array_init.rs\
$(my_rs_unit_tests_path)/UT_atomic.java\
- $(my_rs_unit_tests_path)/atomic.rscript\
+ $(my_rs_unit_tests_path)/atomic.rs\
$(my_rs_unit_tests_path)/UT_bitfield.java\
- $(my_rs_unit_tests_path)/bitfield.rscript\
+ $(my_rs_unit_tests_path)/bitfield.rs\
$(my_rs_unit_tests_path)/UT_bug_char.java\
- $(my_rs_unit_tests_path)/bug_char.rscript\
+ $(my_rs_unit_tests_path)/bug_char.rs\
$(my_rs_unit_tests_path)/UT_check_dims.java\
- $(my_rs_unit_tests_path)/check_dims.rscript\
+ $(my_rs_unit_tests_path)/check_dims.rs\
$(my_rs_unit_tests_path)/UT_clamp.java\
- $(my_rs_unit_tests_path)/clamp.rscript\
+ $(my_rs_unit_tests_path)/clamp.rs\
$(my_rs_unit_tests_path)/UT_clamp_relaxed.java\
- $(my_rs_unit_tests_path)/clamp_relaxed.rscript\
+ $(my_rs_unit_tests_path)/clamp_relaxed.rs\
$(my_rs_unit_tests_path)/UT_constant.java\
- $(my_rs_unit_tests_path)/constant.rscript\
+ $(my_rs_unit_tests_path)/constant.rs\
$(my_rs_unit_tests_path)/UT_convert.java\
- $(my_rs_unit_tests_path)/convert.rscript\
+ $(my_rs_unit_tests_path)/convert.rs\
$(my_rs_unit_tests_path)/UT_convert_relaxed.java\
- $(my_rs_unit_tests_path)/convert_relaxed.rscript\
+ $(my_rs_unit_tests_path)/convert_relaxed.rs\
$(my_rs_unit_tests_path)/UT_copy_test.java\
- $(my_rs_unit_tests_path)/copy_test.rscript\
+ $(my_rs_unit_tests_path)/copy_test.rs\
$(my_rs_unit_tests_path)/UT_element.java\
- $(my_rs_unit_tests_path)/element.rscript\
+ $(my_rs_unit_tests_path)/element.rs\
$(my_rs_unit_tests_path)/UT_foreach.java\
- $(my_rs_unit_tests_path)/foreach.rscript\
+ $(my_rs_unit_tests_path)/foreach.rs\
$(my_rs_unit_tests_path)/UT_foreach_bounds.java\
- $(my_rs_unit_tests_path)/foreach_bounds.rscript\
+ $(my_rs_unit_tests_path)/foreach_bounds.rs\
$(my_rs_unit_tests_path)/UT_foreach_multi.java\
- $(my_rs_unit_tests_path)/foreach_multi.rscript\
+ $(my_rs_unit_tests_path)/foreach_multi.rs\
$(my_rs_unit_tests_path)/UT_fp_mad.java\
- $(my_rs_unit_tests_path)/fp_mad.rscript\
+ $(my_rs_unit_tests_path)/fp_mad.rs\
$(my_rs_unit_tests_path)/UT_instance.java\
- $(my_rs_unit_tests_path)/instance.rscript\
+ $(my_rs_unit_tests_path)/instance.rs\
$(my_rs_unit_tests_path)/UT_int4.java\
- $(my_rs_unit_tests_path)/int4.rscript\
+ $(my_rs_unit_tests_path)/int4.rs\
$(my_rs_unit_tests_path)/UT_kernel.java\
- $(my_rs_unit_tests_path)/kernel.rscript\
+ $(my_rs_unit_tests_path)/kernel.rs\
$(my_rs_unit_tests_path)/UT_kernel_struct.java\
- $(my_rs_unit_tests_path)/kernel_struct.rscript\
+ $(my_rs_unit_tests_path)/kernel_struct.rs\
$(my_rs_unit_tests_path)/UT_math.java\
- $(my_rs_unit_tests_path)/math.rscript\
+ $(my_rs_unit_tests_path)/math.rs\
$(my_rs_unit_tests_path)/UT_math_agree.java\
- $(my_rs_unit_tests_path)/math_agree.rscript\
+ $(my_rs_unit_tests_path)/math_agree.rs\
$(my_rs_unit_tests_path)/UT_math_conformance.java\
- $(my_rs_unit_tests_path)/math_conformance.rscript\
+ $(my_rs_unit_tests_path)/math_conformance.rs\
$(my_rs_unit_tests_path)/UT_min.java\
- $(my_rs_unit_tests_path)/min.rscript\
+ $(my_rs_unit_tests_path)/min.rs\
$(my_rs_unit_tests_path)/UT_noroot.java\
- $(my_rs_unit_tests_path)/noroot.rscript\
+ $(my_rs_unit_tests_path)/noroot.rs\
$(my_rs_unit_tests_path)/UT_primitives.java\
- $(my_rs_unit_tests_path)/primitives.rscript\
+ $(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
- $(my_rs_unit_tests_path)/refcount.rscript\
+ $(my_rs_unit_tests_path)/refcount.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
- $(my_rs_unit_tests_path)/rsdebug.rscript\
+ $(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rstime.java\
- $(my_rs_unit_tests_path)/rstime.rscript\
+ $(my_rs_unit_tests_path)/rstime.rs\
$(my_rs_unit_tests_path)/UT_rstypes.java\
- $(my_rs_unit_tests_path)/rstypes.rscript\
+ $(my_rs_unit_tests_path)/rstypes.rs\
$(my_rs_unit_tests_path)/UT_sampler.java\
- $(my_rs_unit_tests_path)/sampler.rscript\
+ $(my_rs_unit_tests_path)/sampler.rs\
$(my_rs_unit_tests_path)/UT_static_globals.java\
- $(my_rs_unit_tests_path)/static_globals.rscript\
+ $(my_rs_unit_tests_path)/static_globals.rs\
$(my_rs_unit_tests_path)/UT_struct.java\
- $(my_rs_unit_tests_path)/struct.rscript\
+ $(my_rs_unit_tests_path)/struct.rs\
$(my_rs_unit_tests_path)/UT_unsigned.java\
- $(my_rs_unit_tests_path)/unsigned.rscript\
+ $(my_rs_unit_tests_path)/unsigned.rs\
$(my_rs_unit_tests_path)/UT_vector.java\
- $(my_rs_unit_tests_path)/vector.rscript\
+ $(my_rs_unit_tests_path)/vector.rs\
include $(BUILD_PACKAGE)
diff --git a/tests/java_api/RSTestForward/22.0.1/Android.mk b/tests/java_api/RSTestForward/22.0.1/Android.mk
index 34ccb5f..cd49c74 100644
--- a/tests/java_api/RSTestForward/22.0.1/Android.mk
+++ b/tests/java_api/RSTestForward/22.0.1/Android.mk
@@ -41,79 +41,79 @@
$(call all-java-files-under,src)\
$(my_rs_unit_tests_path)/UnitTest.java\
$(my_rs_unit_tests_path)/UT_alloc.java\
- $(my_rs_unit_tests_path)/alloc.rscript\
+ $(my_rs_unit_tests_path)/alloc.rs\
$(my_rs_unit_tests_path)/UT_array_alloc.java\
- $(my_rs_unit_tests_path)/array_alloc.rscript\
+ $(my_rs_unit_tests_path)/array_alloc.rs\
$(my_rs_unit_tests_path)/UT_array_init.java\
- $(my_rs_unit_tests_path)/array_init.rscript\
+ $(my_rs_unit_tests_path)/array_init.rs\
$(my_rs_unit_tests_path)/UT_atomic.java\
- $(my_rs_unit_tests_path)/atomic.rscript\
+ $(my_rs_unit_tests_path)/atomic.rs\
$(my_rs_unit_tests_path)/UT_bitfield.java\
- $(my_rs_unit_tests_path)/bitfield.rscript\
+ $(my_rs_unit_tests_path)/bitfield.rs\
$(my_rs_unit_tests_path)/UT_bug_char.java\
- $(my_rs_unit_tests_path)/bug_char.rscript\
+ $(my_rs_unit_tests_path)/bug_char.rs\
$(my_rs_unit_tests_path)/UT_check_dims.java\
- $(my_rs_unit_tests_path)/check_dims.rscript\
+ $(my_rs_unit_tests_path)/check_dims.rs\
$(my_rs_unit_tests_path)/UT_clamp.java\
- $(my_rs_unit_tests_path)/clamp.rscript\
+ $(my_rs_unit_tests_path)/clamp.rs\
$(my_rs_unit_tests_path)/UT_clamp_relaxed.java\
- $(my_rs_unit_tests_path)/clamp_relaxed.rscript\
+ $(my_rs_unit_tests_path)/clamp_relaxed.rs\
$(my_rs_unit_tests_path)/UT_constant.java\
- $(my_rs_unit_tests_path)/constant.rscript\
+ $(my_rs_unit_tests_path)/constant.rs\
$(my_rs_unit_tests_path)/UT_convert.java\
- $(my_rs_unit_tests_path)/convert.rscript\
+ $(my_rs_unit_tests_path)/convert.rs\
$(my_rs_unit_tests_path)/UT_convert_relaxed.java\
- $(my_rs_unit_tests_path)/convert_relaxed.rscript\
+ $(my_rs_unit_tests_path)/convert_relaxed.rs\
$(my_rs_unit_tests_path)/UT_copy_test.java\
- $(my_rs_unit_tests_path)/copy_test.rscript\
+ $(my_rs_unit_tests_path)/copy_test.rs\
$(my_rs_unit_tests_path)/UT_element.java\
- $(my_rs_unit_tests_path)/element.rscript\
+ $(my_rs_unit_tests_path)/element.rs\
$(my_rs_unit_tests_path)/UT_foreach.java\
- $(my_rs_unit_tests_path)/foreach.rscript\
+ $(my_rs_unit_tests_path)/foreach.rs\
$(my_rs_unit_tests_path)/UT_foreach_bounds.java\
- $(my_rs_unit_tests_path)/foreach_bounds.rscript\
+ $(my_rs_unit_tests_path)/foreach_bounds.rs\
$(my_rs_unit_tests_path)/UT_foreach_multi.java\
- $(my_rs_unit_tests_path)/foreach_multi.rscript\
+ $(my_rs_unit_tests_path)/foreach_multi.rs\
$(my_rs_unit_tests_path)/UT_fp_mad.java\
- $(my_rs_unit_tests_path)/fp_mad.rscript\
+ $(my_rs_unit_tests_path)/fp_mad.rs\
$(my_rs_unit_tests_path)/UT_instance.java\
- $(my_rs_unit_tests_path)/instance.rscript\
+ $(my_rs_unit_tests_path)/instance.rs\
$(my_rs_unit_tests_path)/UT_int4.java\
- $(my_rs_unit_tests_path)/int4.rscript\
+ $(my_rs_unit_tests_path)/int4.rs\
$(my_rs_unit_tests_path)/UT_kernel.java\
- $(my_rs_unit_tests_path)/kernel.rscript\
+ $(my_rs_unit_tests_path)/kernel.rs\
$(my_rs_unit_tests_path)/UT_kernel_struct.java\
- $(my_rs_unit_tests_path)/kernel_struct.rscript\
+ $(my_rs_unit_tests_path)/kernel_struct.rs\
$(my_rs_unit_tests_path)/UT_math.java\
- $(my_rs_unit_tests_path)/math.rscript\
+ $(my_rs_unit_tests_path)/math.rs\
$(my_rs_unit_tests_path)/UT_math_agree.java\
- $(my_rs_unit_tests_path)/math_agree.rscript\
+ $(my_rs_unit_tests_path)/math_agree.rs\
$(my_rs_unit_tests_path)/UT_math_conformance.java\
- $(my_rs_unit_tests_path)/math_conformance.rscript\
+ $(my_rs_unit_tests_path)/math_conformance.rs\
$(my_rs_unit_tests_path)/UT_min.java\
- $(my_rs_unit_tests_path)/min.rscript\
+ $(my_rs_unit_tests_path)/min.rs\
$(my_rs_unit_tests_path)/UT_noroot.java\
- $(my_rs_unit_tests_path)/noroot.rscript\
+ $(my_rs_unit_tests_path)/noroot.rs\
$(my_rs_unit_tests_path)/UT_primitives.java\
- $(my_rs_unit_tests_path)/primitives.rscript\
+ $(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
- $(my_rs_unit_tests_path)/refcount.rscript\
+ $(my_rs_unit_tests_path)/refcount.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
- $(my_rs_unit_tests_path)/rsdebug.rscript\
+ $(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rstime.java\
- $(my_rs_unit_tests_path)/rstime.rscript\
+ $(my_rs_unit_tests_path)/rstime.rs\
$(my_rs_unit_tests_path)/UT_rstypes.java\
- $(my_rs_unit_tests_path)/rstypes.rscript\
+ $(my_rs_unit_tests_path)/rstypes.rs\
$(my_rs_unit_tests_path)/UT_sampler.java\
- $(my_rs_unit_tests_path)/sampler.rscript\
+ $(my_rs_unit_tests_path)/sampler.rs\
$(my_rs_unit_tests_path)/UT_static_globals.java\
- $(my_rs_unit_tests_path)/static_globals.rscript\
+ $(my_rs_unit_tests_path)/static_globals.rs\
$(my_rs_unit_tests_path)/UT_struct.java\
- $(my_rs_unit_tests_path)/struct.rscript\
+ $(my_rs_unit_tests_path)/struct.rs\
$(my_rs_unit_tests_path)/UT_unsigned.java\
- $(my_rs_unit_tests_path)/unsigned.rscript\
+ $(my_rs_unit_tests_path)/unsigned.rs\
$(my_rs_unit_tests_path)/UT_vector.java\
- $(my_rs_unit_tests_path)/vector.rscript\
+ $(my_rs_unit_tests_path)/vector.rs\
include $(BUILD_PACKAGE)
diff --git a/tests/java_api/RSTestForward/23.0.3/Android.mk b/tests/java_api/RSTestForward/23.0.3/Android.mk
index 861541b..6180f33 100644
--- a/tests/java_api/RSTestForward/23.0.3/Android.mk
+++ b/tests/java_api/RSTestForward/23.0.3/Android.mk
@@ -41,100 +41,100 @@
$(call all-java-files-under,src)\
$(my_rs_unit_tests_path)/UnitTest.java\
$(my_rs_unit_tests_path)/UT_alloc.java\
- $(my_rs_unit_tests_path)/alloc.rscript\
+ $(my_rs_unit_tests_path)/alloc.rs\
$(my_rs_unit_tests_path)/UT_alloc_copy.java\
$(my_rs_unit_tests_path)/UT_alloc_copyPadded.java\
$(my_rs_unit_tests_path)/UT_array_alloc.java\
- $(my_rs_unit_tests_path)/array_alloc.rscript\
+ $(my_rs_unit_tests_path)/array_alloc.rs\
$(my_rs_unit_tests_path)/UT_array_init.java\
- $(my_rs_unit_tests_path)/array_init.rscript\
+ $(my_rs_unit_tests_path)/array_init.rs\
$(my_rs_unit_tests_path)/UT_atomic.java\
- $(my_rs_unit_tests_path)/atomic.rscript\
+ $(my_rs_unit_tests_path)/atomic.rs\
$(my_rs_unit_tests_path)/UT_bitfield.java\
- $(my_rs_unit_tests_path)/bitfield.rscript\
+ $(my_rs_unit_tests_path)/bitfield.rs\
$(my_rs_unit_tests_path)/UT_bug_char.java\
- $(my_rs_unit_tests_path)/bug_char.rscript\
+ $(my_rs_unit_tests_path)/bug_char.rs\
$(my_rs_unit_tests_path)/UT_check_dims.java\
- $(my_rs_unit_tests_path)/check_dims.rscript\
+ $(my_rs_unit_tests_path)/check_dims.rs\
$(my_rs_unit_tests_path)/UT_clamp.java\
- $(my_rs_unit_tests_path)/clamp.rscript\
+ $(my_rs_unit_tests_path)/clamp.rs\
$(my_rs_unit_tests_path)/UT_clamp_relaxed.java\
- $(my_rs_unit_tests_path)/clamp_relaxed.rscript\
+ $(my_rs_unit_tests_path)/clamp_relaxed.rs\
$(my_rs_unit_tests_path)/UT_constant.java\
- $(my_rs_unit_tests_path)/constant.rscript\
+ $(my_rs_unit_tests_path)/constant.rs\
$(my_rs_unit_tests_path)/UT_convert.java\
- $(my_rs_unit_tests_path)/convert.rscript\
+ $(my_rs_unit_tests_path)/convert.rs\
$(my_rs_unit_tests_path)/UT_convert_relaxed.java\
- $(my_rs_unit_tests_path)/convert_relaxed.rscript\
+ $(my_rs_unit_tests_path)/convert_relaxed.rs\
$(my_rs_unit_tests_path)/UT_copy_test.java\
- $(my_rs_unit_tests_path)/copy_test.rscript\
+ $(my_rs_unit_tests_path)/copy_test.rs\
$(my_rs_unit_tests_path)/UT_ctxt_default.java\
- $(my_rs_unit_tests_path)/ctxt_default.rscript\
+ $(my_rs_unit_tests_path)/ctxt_default.rs\
$(my_rs_unit_tests_path)/UT_element.java\
- $(my_rs_unit_tests_path)/element.rscript\
+ $(my_rs_unit_tests_path)/element.rs\
$(my_rs_unit_tests_path)/UT_foreach.java\
- $(my_rs_unit_tests_path)/foreach.rscript\
+ $(my_rs_unit_tests_path)/foreach.rs\
$(my_rs_unit_tests_path)/UT_foreach_bounds.java\
- $(my_rs_unit_tests_path)/foreach_bounds.rscript\
+ $(my_rs_unit_tests_path)/foreach_bounds.rs\
$(my_rs_unit_tests_path)/UT_foreach_multi.java\
- $(my_rs_unit_tests_path)/foreach_multi.rscript\
+ $(my_rs_unit_tests_path)/foreach_multi.rs\
$(my_rs_unit_tests_path)/UT_fp_mad.java\
- $(my_rs_unit_tests_path)/fp_mad.rscript\
+ $(my_rs_unit_tests_path)/fp_mad.rs\
$(my_rs_unit_tests_path)/UT_instance.java\
- $(my_rs_unit_tests_path)/instance.rscript\
+ $(my_rs_unit_tests_path)/instance.rs\
$(my_rs_unit_tests_path)/UT_int4.java\
- $(my_rs_unit_tests_path)/int4.rscript\
+ $(my_rs_unit_tests_path)/int4.rs\
$(my_rs_unit_tests_path)/UT_kernel.java\
- $(my_rs_unit_tests_path)/kernel.rscript\
+ $(my_rs_unit_tests_path)/kernel.rs\
$(my_rs_unit_tests_path)/UT_kernel2d.java\
- $(my_rs_unit_tests_path)/kernel2d.rscript\
+ $(my_rs_unit_tests_path)/kernel2d.rs\
$(my_rs_unit_tests_path)/UT_kernel2d_oldstyle.java\
- $(my_rs_unit_tests_path)/kernel2d_oldstyle.rscript\
+ $(my_rs_unit_tests_path)/kernel2d_oldstyle.rs\
$(my_rs_unit_tests_path)/UT_kernel3d.java\
- $(my_rs_unit_tests_path)/kernel3d.rscript\
+ $(my_rs_unit_tests_path)/kernel3d.rs\
$(my_rs_unit_tests_path)/UT_kernel_struct.java\
- $(my_rs_unit_tests_path)/kernel_struct.rscript\
+ $(my_rs_unit_tests_path)/kernel_struct.rs\
$(my_rs_unit_tests_path)/UT_math.java\
- $(my_rs_unit_tests_path)/math.rscript\
+ $(my_rs_unit_tests_path)/math.rs\
$(my_rs_unit_tests_path)/UT_math_agree.java\
- $(my_rs_unit_tests_path)/math_agree.rscript\
+ $(my_rs_unit_tests_path)/math_agree.rs\
$(my_rs_unit_tests_path)/UT_math_conformance.java\
- $(my_rs_unit_tests_path)/math_conformance.rscript\
+ $(my_rs_unit_tests_path)/math_conformance.rs\
$(my_rs_unit_tests_path)/UT_min.java\
- $(my_rs_unit_tests_path)/min.rscript\
+ $(my_rs_unit_tests_path)/min.rs\
$(my_rs_unit_tests_path)/UT_noroot.java\
- $(my_rs_unit_tests_path)/noroot.rscript\
+ $(my_rs_unit_tests_path)/noroot.rs\
$(my_rs_unit_tests_path)/UT_primitives.java\
- $(my_rs_unit_tests_path)/primitives.rscript\
+ $(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
- $(my_rs_unit_tests_path)/refcount.rscript\
+ $(my_rs_unit_tests_path)/refcount.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
- $(my_rs_unit_tests_path)/rsdebug.rscript\
+ $(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rsdebug_23.java\
- $(my_rs_unit_tests_path)/rsdebug_23.rscript\
+ $(my_rs_unit_tests_path)/rsdebug_23.rs\
$(my_rs_unit_tests_path)/UT_rstime.java\
- $(my_rs_unit_tests_path)/rstime.rscript\
+ $(my_rs_unit_tests_path)/rstime.rs\
$(my_rs_unit_tests_path)/UT_rstypes.java\
- $(my_rs_unit_tests_path)/rstypes.rscript\
+ $(my_rs_unit_tests_path)/rstypes.rs\
$(my_rs_unit_tests_path)/UT_sampler.java\
- $(my_rs_unit_tests_path)/sampler.rscript\
+ $(my_rs_unit_tests_path)/sampler.rs\
$(my_rs_unit_tests_path)/UT_script_group2_gatherscatter.java\
- $(my_rs_unit_tests_path)/addup.rscript\
+ $(my_rs_unit_tests_path)/addup.rs\
$(my_rs_unit_tests_path)/UT_script_group2_nochain.java\
- $(my_rs_unit_tests_path)/increment.rscript\
- $(my_rs_unit_tests_path)/increment2.rscript\
- $(my_rs_unit_tests_path)/double.rscript\
+ $(my_rs_unit_tests_path)/increment.rs\
+ $(my_rs_unit_tests_path)/increment2.rs\
+ $(my_rs_unit_tests_path)/double.rs\
$(my_rs_unit_tests_path)/UT_script_group2_pointwise.java\
- $(my_rs_unit_tests_path)/increment.rscript\
- $(my_rs_unit_tests_path)/double.rscript\
+ $(my_rs_unit_tests_path)/increment.rs\
+ $(my_rs_unit_tests_path)/double.rs\
$(my_rs_unit_tests_path)/UT_static_globals.java\
- $(my_rs_unit_tests_path)/static_globals.rscript\
+ $(my_rs_unit_tests_path)/static_globals.rs\
$(my_rs_unit_tests_path)/UT_struct.java\
- $(my_rs_unit_tests_path)/struct.rscript\
+ $(my_rs_unit_tests_path)/struct.rs\
$(my_rs_unit_tests_path)/UT_unsigned.java\
- $(my_rs_unit_tests_path)/unsigned.rscript\
+ $(my_rs_unit_tests_path)/unsigned.rs\
$(my_rs_unit_tests_path)/UT_vector.java\
- $(my_rs_unit_tests_path)/vector.rscript\
+ $(my_rs_unit_tests_path)/vector.rs\
include $(BUILD_PACKAGE)
diff --git a/tests/java_api/RSTestForward/24.0.3/Android.mk b/tests/java_api/RSTestForward/24.0.3/Android.mk
index 3e81caa..c6ebe09 100644
--- a/tests/java_api/RSTestForward/24.0.3/Android.mk
+++ b/tests/java_api/RSTestForward/24.0.3/Android.mk
@@ -41,124 +41,124 @@
$(call all-java-files-under,src)\
$(my_rs_unit_tests_path)/UnitTest.java\
$(my_rs_unit_tests_path)/UT_alloc.java\
- $(my_rs_unit_tests_path)/alloc.rscript\
+ $(my_rs_unit_tests_path)/alloc.rs\
$(my_rs_unit_tests_path)/UT_alloc_copy.java\
$(my_rs_unit_tests_path)/UT_alloc_copyPadded.java\
$(my_rs_unit_tests_path)/UT_array_alloc.java\
- $(my_rs_unit_tests_path)/array_alloc.rscript\
+ $(my_rs_unit_tests_path)/array_alloc.rs\
$(my_rs_unit_tests_path)/UT_array_init.java\
- $(my_rs_unit_tests_path)/array_init.rscript\
+ $(my_rs_unit_tests_path)/array_init.rs\
$(my_rs_unit_tests_path)/UT_atomic.java\
- $(my_rs_unit_tests_path)/atomic.rscript\
+ $(my_rs_unit_tests_path)/atomic.rs\
$(my_rs_unit_tests_path)/UT_bitfield.java\
- $(my_rs_unit_tests_path)/bitfield.rscript\
+ $(my_rs_unit_tests_path)/bitfield.rs\
$(my_rs_unit_tests_path)/UT_bug_char.java\
- $(my_rs_unit_tests_path)/bug_char.rscript\
+ $(my_rs_unit_tests_path)/bug_char.rs\
$(my_rs_unit_tests_path)/UT_check_dims.java\
- $(my_rs_unit_tests_path)/check_dims.rscript\
+ $(my_rs_unit_tests_path)/check_dims.rs\
$(my_rs_unit_tests_path)/UT_clamp.java\
- $(my_rs_unit_tests_path)/clamp.rscript\
+ $(my_rs_unit_tests_path)/clamp.rs\
$(my_rs_unit_tests_path)/UT_clamp_relaxed.java\
- $(my_rs_unit_tests_path)/clamp_relaxed.rscript\
+ $(my_rs_unit_tests_path)/clamp_relaxed.rs\
$(my_rs_unit_tests_path)/UT_constant.java\
- $(my_rs_unit_tests_path)/constant.rscript\
+ $(my_rs_unit_tests_path)/constant.rs\
$(my_rs_unit_tests_path)/UT_convert.java\
- $(my_rs_unit_tests_path)/convert.rscript\
+ $(my_rs_unit_tests_path)/convert.rs\
$(my_rs_unit_tests_path)/UT_convert_relaxed.java\
- $(my_rs_unit_tests_path)/convert_relaxed.rscript\
+ $(my_rs_unit_tests_path)/convert_relaxed.rs\
$(my_rs_unit_tests_path)/UT_copy_test.java\
- $(my_rs_unit_tests_path)/copy_test.rscript\
+ $(my_rs_unit_tests_path)/copy_test.rs\
$(my_rs_unit_tests_path)/UT_ctxt_default.java\
- $(my_rs_unit_tests_path)/ctxt_default.rscript\
+ $(my_rs_unit_tests_path)/ctxt_default.rs\
$(my_rs_unit_tests_path)/UT_element.java\
- $(my_rs_unit_tests_path)/element.rscript\
+ $(my_rs_unit_tests_path)/element.rs\
$(my_rs_unit_tests_path)/UT_foreach.java\
- $(my_rs_unit_tests_path)/foreach.rscript\
+ $(my_rs_unit_tests_path)/foreach.rs\
$(my_rs_unit_tests_path)/UT_foreach_bounds.java\
- $(my_rs_unit_tests_path)/foreach_bounds.rscript\
+ $(my_rs_unit_tests_path)/foreach_bounds.rs\
$(my_rs_unit_tests_path)/UT_foreach_multi.java\
- $(my_rs_unit_tests_path)/foreach_multi.rscript\
+ $(my_rs_unit_tests_path)/foreach_multi.rs\
$(my_rs_unit_tests_path)/UT_fp16.java\
- $(my_rs_unit_tests_path)/fp16.rscript\
+ $(my_rs_unit_tests_path)/fp16.rs\
$(my_rs_unit_tests_path)/UT_fp16_globals.java\
- $(my_rs_unit_tests_path)/fp16_globals.rscript\
+ $(my_rs_unit_tests_path)/fp16_globals.rs\
$(my_rs_unit_tests_path)/UT_fp_mad.java\
- $(my_rs_unit_tests_path)/fp_mad.rscript\
+ $(my_rs_unit_tests_path)/fp_mad.rs\
$(my_rs_unit_tests_path)/UT_instance.java\
- $(my_rs_unit_tests_path)/instance.rscript\
+ $(my_rs_unit_tests_path)/instance.rs\
$(my_rs_unit_tests_path)/UT_int4.java\
- $(my_rs_unit_tests_path)/int4.rscript\
+ $(my_rs_unit_tests_path)/int4.rs\
$(my_rs_unit_tests_path)/UT_kernel.java\
- $(my_rs_unit_tests_path)/kernel.rscript\
+ $(my_rs_unit_tests_path)/kernel.rs\
$(my_rs_unit_tests_path)/UT_kernel2d.java\
- $(my_rs_unit_tests_path)/kernel2d.rscript\
+ $(my_rs_unit_tests_path)/kernel2d.rs\
$(my_rs_unit_tests_path)/UT_kernel2d_oldstyle.java\
- $(my_rs_unit_tests_path)/kernel2d_oldstyle.rscript\
+ $(my_rs_unit_tests_path)/kernel2d_oldstyle.rs\
$(my_rs_unit_tests_path)/UT_kernel3d.java\
- $(my_rs_unit_tests_path)/kernel3d.rscript\
+ $(my_rs_unit_tests_path)/kernel3d.rs\
$(my_rs_unit_tests_path)/UT_kernel_struct.java\
- $(my_rs_unit_tests_path)/kernel_struct.rscript\
+ $(my_rs_unit_tests_path)/kernel_struct.rs\
$(my_rs_unit_tests_path)/UT_math.java\
- $(my_rs_unit_tests_path)/math.rscript\
+ $(my_rs_unit_tests_path)/math.rs\
$(my_rs_unit_tests_path)/UT_math_24.java\
- $(my_rs_unit_tests_path)/math_24.rscript\
+ $(my_rs_unit_tests_path)/math_24.rs\
$(my_rs_unit_tests_path)/UT_math_agree.java\
- $(my_rs_unit_tests_path)/math_agree.rscript\
+ $(my_rs_unit_tests_path)/math_agree.rs\
$(my_rs_unit_tests_path)/UT_math_conformance.java\
- $(my_rs_unit_tests_path)/math_conformance.rscript\
+ $(my_rs_unit_tests_path)/math_conformance.rs\
$(my_rs_unit_tests_path)/UT_math_fp16.java\
- $(my_rs_unit_tests_path)/math_fp16.rscript\
+ $(my_rs_unit_tests_path)/math_fp16.rs\
$(my_rs_unit_tests_path)/UT_min.java\
- $(my_rs_unit_tests_path)/min.rscript\
+ $(my_rs_unit_tests_path)/min.rs\
$(my_rs_unit_tests_path)/UT_noroot.java\
- $(my_rs_unit_tests_path)/noroot.rscript\
+ $(my_rs_unit_tests_path)/noroot.rs\
$(my_rs_unit_tests_path)/UT_primitives.java\
- $(my_rs_unit_tests_path)/primitives.rscript\
+ $(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_reduce.java\
- $(my_rs_unit_tests_path)/reduce.rscript\
+ $(my_rs_unit_tests_path)/reduce.rs\
$(my_rs_unit_tests_path)/UT_reduce_backward.java\
- $(my_rs_unit_tests_path)/reduce_backward.rscript\
+ $(my_rs_unit_tests_path)/reduce_backward.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
- $(my_rs_unit_tests_path)/refcount.rscript\
+ $(my_rs_unit_tests_path)/refcount.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
- $(my_rs_unit_tests_path)/rsdebug.rscript\
+ $(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rsdebug_23.java\
- $(my_rs_unit_tests_path)/rsdebug_23.rscript\
+ $(my_rs_unit_tests_path)/rsdebug_23.rs\
$(my_rs_unit_tests_path)/UT_rsdebug_24.java\
- $(my_rs_unit_tests_path)/rsdebug_24.rscript\
+ $(my_rs_unit_tests_path)/rsdebug_24.rs\
$(my_rs_unit_tests_path)/UT_rstime.java\
- $(my_rs_unit_tests_path)/rstime.rscript\
+ $(my_rs_unit_tests_path)/rstime.rs\
$(my_rs_unit_tests_path)/UT_rstypes.java\
- $(my_rs_unit_tests_path)/rstypes.rscript\
+ $(my_rs_unit_tests_path)/rstypes.rs\
$(my_rs_unit_tests_path)/UT_sampler.java\
- $(my_rs_unit_tests_path)/sampler.rscript\
+ $(my_rs_unit_tests_path)/sampler.rs\
$(my_rs_unit_tests_path)/UT_script_group2_float.java\
- $(my_rs_unit_tests_path)/float_test.rscript\
+ $(my_rs_unit_tests_path)/float_test.rs\
$(my_rs_unit_tests_path)/UT_script_group2_gatherscatter.java\
- $(my_rs_unit_tests_path)/addup.rscript\
+ $(my_rs_unit_tests_path)/addup.rs\
$(my_rs_unit_tests_path)/UT_script_group2_nochain.java\
- $(my_rs_unit_tests_path)/increment.rscript\
- $(my_rs_unit_tests_path)/increment2.rscript\
- $(my_rs_unit_tests_path)/double.rscript\
+ $(my_rs_unit_tests_path)/increment.rs\
+ $(my_rs_unit_tests_path)/increment2.rs\
+ $(my_rs_unit_tests_path)/double.rs\
$(my_rs_unit_tests_path)/UT_script_group2_pointwise.java\
- $(my_rs_unit_tests_path)/increment.rscript\
- $(my_rs_unit_tests_path)/double.rscript\
+ $(my_rs_unit_tests_path)/increment.rs\
+ $(my_rs_unit_tests_path)/double.rs\
$(my_rs_unit_tests_path)/UT_single_source_alloc.java\
- $(my_rs_unit_tests_path)/single_source_alloc.rscript\
+ $(my_rs_unit_tests_path)/single_source_alloc.rs\
$(my_rs_unit_tests_path)/UT_single_source_ref_count.java\
- $(my_rs_unit_tests_path)/single_source_ref_count.rscript\
+ $(my_rs_unit_tests_path)/single_source_ref_count.rs\
$(my_rs_unit_tests_path)/UT_single_source_script.java\
- $(my_rs_unit_tests_path)/single_source_script.rscript\
+ $(my_rs_unit_tests_path)/single_source_script.rs\
$(my_rs_unit_tests_path)/UT_small_struct_2.java\
- $(my_rs_unit_tests_path)/small_struct_2.rscript\
+ $(my_rs_unit_tests_path)/small_struct_2.rs\
$(my_rs_unit_tests_path)/UT_static_globals.java\
- $(my_rs_unit_tests_path)/static_globals.rscript\
+ $(my_rs_unit_tests_path)/static_globals.rs\
$(my_rs_unit_tests_path)/UT_struct.java\
- $(my_rs_unit_tests_path)/struct.rscript\
+ $(my_rs_unit_tests_path)/struct.rs\
$(my_rs_unit_tests_path)/UT_unsigned.java\
- $(my_rs_unit_tests_path)/unsigned.rscript\
+ $(my_rs_unit_tests_path)/unsigned.rs\
$(my_rs_unit_tests_path)/UT_vector.java\
- $(my_rs_unit_tests_path)/vector.rscript\
+ $(my_rs_unit_tests_path)/vector.rs\
include $(BUILD_PACKAGE)
diff --git a/tests/java_api/RSTestForward/25.0.2/Android.mk b/tests/java_api/RSTestForward/25.0.2/Android.mk
index 127f29d..a80624e 100644
--- a/tests/java_api/RSTestForward/25.0.2/Android.mk
+++ b/tests/java_api/RSTestForward/25.0.2/Android.mk
@@ -41,124 +41,124 @@
$(call all-java-files-under,src)\
$(my_rs_unit_tests_path)/UnitTest.java\
$(my_rs_unit_tests_path)/UT_alloc.java\
- $(my_rs_unit_tests_path)/alloc.rscript\
+ $(my_rs_unit_tests_path)/alloc.rs\
$(my_rs_unit_tests_path)/UT_alloc_copy.java\
$(my_rs_unit_tests_path)/UT_alloc_copyPadded.java\
$(my_rs_unit_tests_path)/UT_array_alloc.java\
- $(my_rs_unit_tests_path)/array_alloc.rscript\
+ $(my_rs_unit_tests_path)/array_alloc.rs\
$(my_rs_unit_tests_path)/UT_array_init.java\
- $(my_rs_unit_tests_path)/array_init.rscript\
+ $(my_rs_unit_tests_path)/array_init.rs\
$(my_rs_unit_tests_path)/UT_atomic.java\
- $(my_rs_unit_tests_path)/atomic.rscript\
+ $(my_rs_unit_tests_path)/atomic.rs\
$(my_rs_unit_tests_path)/UT_bitfield.java\
- $(my_rs_unit_tests_path)/bitfield.rscript\
+ $(my_rs_unit_tests_path)/bitfield.rs\
$(my_rs_unit_tests_path)/UT_bug_char.java\
- $(my_rs_unit_tests_path)/bug_char.rscript\
+ $(my_rs_unit_tests_path)/bug_char.rs\
$(my_rs_unit_tests_path)/UT_check_dims.java\
- $(my_rs_unit_tests_path)/check_dims.rscript\
+ $(my_rs_unit_tests_path)/check_dims.rs\
$(my_rs_unit_tests_path)/UT_clamp.java\
- $(my_rs_unit_tests_path)/clamp.rscript\
+ $(my_rs_unit_tests_path)/clamp.rs\
$(my_rs_unit_tests_path)/UT_clamp_relaxed.java\
- $(my_rs_unit_tests_path)/clamp_relaxed.rscript\
+ $(my_rs_unit_tests_path)/clamp_relaxed.rs\
$(my_rs_unit_tests_path)/UT_constant.java\
- $(my_rs_unit_tests_path)/constant.rscript\
+ $(my_rs_unit_tests_path)/constant.rs\
$(my_rs_unit_tests_path)/UT_convert.java\
- $(my_rs_unit_tests_path)/convert.rscript\
+ $(my_rs_unit_tests_path)/convert.rs\
$(my_rs_unit_tests_path)/UT_convert_relaxed.java\
- $(my_rs_unit_tests_path)/convert_relaxed.rscript\
+ $(my_rs_unit_tests_path)/convert_relaxed.rs\
$(my_rs_unit_tests_path)/UT_copy_test.java\
- $(my_rs_unit_tests_path)/copy_test.rscript\
+ $(my_rs_unit_tests_path)/copy_test.rs\
$(my_rs_unit_tests_path)/UT_ctxt_default.java\
- $(my_rs_unit_tests_path)/ctxt_default.rscript\
+ $(my_rs_unit_tests_path)/ctxt_default.rs\
$(my_rs_unit_tests_path)/UT_element.java\
- $(my_rs_unit_tests_path)/element.rscript\
+ $(my_rs_unit_tests_path)/element.rs\
$(my_rs_unit_tests_path)/UT_foreach.java\
- $(my_rs_unit_tests_path)/foreach.rscript\
+ $(my_rs_unit_tests_path)/foreach.rs\
$(my_rs_unit_tests_path)/UT_foreach_bounds.java\
- $(my_rs_unit_tests_path)/foreach_bounds.rscript\
+ $(my_rs_unit_tests_path)/foreach_bounds.rs\
$(my_rs_unit_tests_path)/UT_foreach_multi.java\
- $(my_rs_unit_tests_path)/foreach_multi.rscript\
+ $(my_rs_unit_tests_path)/foreach_multi.rs\
$(my_rs_unit_tests_path)/UT_fp16.java\
- $(my_rs_unit_tests_path)/fp16.rscript\
+ $(my_rs_unit_tests_path)/fp16.rs\
$(my_rs_unit_tests_path)/UT_fp16_globals.java\
- $(my_rs_unit_tests_path)/fp16_globals.rscript\
+ $(my_rs_unit_tests_path)/fp16_globals.rs\
$(my_rs_unit_tests_path)/UT_fp_mad.java\
- $(my_rs_unit_tests_path)/fp_mad.rscript\
+ $(my_rs_unit_tests_path)/fp_mad.rs\
$(my_rs_unit_tests_path)/UT_instance.java\
- $(my_rs_unit_tests_path)/instance.rscript\
+ $(my_rs_unit_tests_path)/instance.rs\
$(my_rs_unit_tests_path)/UT_int4.java\
- $(my_rs_unit_tests_path)/int4.rscript\
+ $(my_rs_unit_tests_path)/int4.rs\
$(my_rs_unit_tests_path)/UT_kernel.java\
- $(my_rs_unit_tests_path)/kernel.rscript\
+ $(my_rs_unit_tests_path)/kernel.rs\
$(my_rs_unit_tests_path)/UT_kernel2d.java\
- $(my_rs_unit_tests_path)/kernel2d.rscript\
+ $(my_rs_unit_tests_path)/kernel2d.rs\
$(my_rs_unit_tests_path)/UT_kernel2d_oldstyle.java\
- $(my_rs_unit_tests_path)/kernel2d_oldstyle.rscript\
+ $(my_rs_unit_tests_path)/kernel2d_oldstyle.rs\
$(my_rs_unit_tests_path)/UT_kernel3d.java\
- $(my_rs_unit_tests_path)/kernel3d.rscript\
+ $(my_rs_unit_tests_path)/kernel3d.rs\
$(my_rs_unit_tests_path)/UT_kernel_struct.java\
- $(my_rs_unit_tests_path)/kernel_struct.rscript\
+ $(my_rs_unit_tests_path)/kernel_struct.rs\
$(my_rs_unit_tests_path)/UT_math.java\
- $(my_rs_unit_tests_path)/math.rscript\
+ $(my_rs_unit_tests_path)/math.rs\
$(my_rs_unit_tests_path)/UT_math_24.java\
- $(my_rs_unit_tests_path)/math_24.rscript\
+ $(my_rs_unit_tests_path)/math_24.rs\
$(my_rs_unit_tests_path)/UT_math_agree.java\
- $(my_rs_unit_tests_path)/math_agree.rscript\
+ $(my_rs_unit_tests_path)/math_agree.rs\
$(my_rs_unit_tests_path)/UT_math_conformance.java\
- $(my_rs_unit_tests_path)/math_conformance.rscript\
+ $(my_rs_unit_tests_path)/math_conformance.rs\
$(my_rs_unit_tests_path)/UT_math_fp16.java\
- $(my_rs_unit_tests_path)/math_fp16.rscript\
+ $(my_rs_unit_tests_path)/math_fp16.rs\
$(my_rs_unit_tests_path)/UT_min.java\
- $(my_rs_unit_tests_path)/min.rscript\
+ $(my_rs_unit_tests_path)/min.rs\
$(my_rs_unit_tests_path)/UT_noroot.java\
- $(my_rs_unit_tests_path)/noroot.rscript\
+ $(my_rs_unit_tests_path)/noroot.rs\
$(my_rs_unit_tests_path)/UT_primitives.java\
- $(my_rs_unit_tests_path)/primitives.rscript\
+ $(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_reduce.java\
- $(my_rs_unit_tests_path)/reduce.rscript\
+ $(my_rs_unit_tests_path)/reduce.rs\
$(my_rs_unit_tests_path)/UT_reduce_backward.java\
- $(my_rs_unit_tests_path)/reduce_backward.rscript\
+ $(my_rs_unit_tests_path)/reduce_backward.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
- $(my_rs_unit_tests_path)/refcount.rscript\
+ $(my_rs_unit_tests_path)/refcount.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
- $(my_rs_unit_tests_path)/rsdebug.rscript\
+ $(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rsdebug_23.java\
- $(my_rs_unit_tests_path)/rsdebug_23.rscript\
+ $(my_rs_unit_tests_path)/rsdebug_23.rs\
$(my_rs_unit_tests_path)/UT_rsdebug_24.java\
- $(my_rs_unit_tests_path)/rsdebug_24.rscript\
+ $(my_rs_unit_tests_path)/rsdebug_24.rs\
$(my_rs_unit_tests_path)/UT_rstime.java\
- $(my_rs_unit_tests_path)/rstime.rscript\
+ $(my_rs_unit_tests_path)/rstime.rs\
$(my_rs_unit_tests_path)/UT_rstypes.java\
- $(my_rs_unit_tests_path)/rstypes.rscript\
+ $(my_rs_unit_tests_path)/rstypes.rs\
$(my_rs_unit_tests_path)/UT_sampler.java\
- $(my_rs_unit_tests_path)/sampler.rscript\
+ $(my_rs_unit_tests_path)/sampler.rs\
$(my_rs_unit_tests_path)/UT_script_group2_float.java\
- $(my_rs_unit_tests_path)/float_test.rscript\
+ $(my_rs_unit_tests_path)/float_test.rs\
$(my_rs_unit_tests_path)/UT_script_group2_gatherscatter.java\
- $(my_rs_unit_tests_path)/addup.rscript\
+ $(my_rs_unit_tests_path)/addup.rs\
$(my_rs_unit_tests_path)/UT_script_group2_nochain.java\
- $(my_rs_unit_tests_path)/increment.rscript\
- $(my_rs_unit_tests_path)/increment2.rscript\
- $(my_rs_unit_tests_path)/double.rscript\
+ $(my_rs_unit_tests_path)/increment.rs\
+ $(my_rs_unit_tests_path)/increment2.rs\
+ $(my_rs_unit_tests_path)/double.rs\
$(my_rs_unit_tests_path)/UT_script_group2_pointwise.java\
- $(my_rs_unit_tests_path)/increment.rscript\
- $(my_rs_unit_tests_path)/double.rscript\
+ $(my_rs_unit_tests_path)/increment.rs\
+ $(my_rs_unit_tests_path)/double.rs\
$(my_rs_unit_tests_path)/UT_single_source_alloc.java\
- $(my_rs_unit_tests_path)/single_source_alloc.rscript\
+ $(my_rs_unit_tests_path)/single_source_alloc.rs\
$(my_rs_unit_tests_path)/UT_single_source_ref_count.java\
- $(my_rs_unit_tests_path)/single_source_ref_count.rscript\
+ $(my_rs_unit_tests_path)/single_source_ref_count.rs\
$(my_rs_unit_tests_path)/UT_single_source_script.java\
- $(my_rs_unit_tests_path)/single_source_script.rscript\
+ $(my_rs_unit_tests_path)/single_source_script.rs\
$(my_rs_unit_tests_path)/UT_small_struct_2.java\
- $(my_rs_unit_tests_path)/small_struct_2.rscript\
+ $(my_rs_unit_tests_path)/small_struct_2.rs\
$(my_rs_unit_tests_path)/UT_static_globals.java\
- $(my_rs_unit_tests_path)/static_globals.rscript\
+ $(my_rs_unit_tests_path)/static_globals.rs\
$(my_rs_unit_tests_path)/UT_struct.java\
- $(my_rs_unit_tests_path)/struct.rscript\
+ $(my_rs_unit_tests_path)/struct.rs\
$(my_rs_unit_tests_path)/UT_unsigned.java\
- $(my_rs_unit_tests_path)/unsigned.rscript\
+ $(my_rs_unit_tests_path)/unsigned.rs\
$(my_rs_unit_tests_path)/UT_vector.java\
- $(my_rs_unit_tests_path)/vector.rscript\
+ $(my_rs_unit_tests_path)/vector.rs\
include $(BUILD_PACKAGE)
diff --git a/tests/java_api/RSTest_CompatLib19/Android.mk b/tests/java_api/RSTest_CompatLib19/Android.mk
index 80596d0..84e71f1 100644
--- a/tests/java_api/RSTest_CompatLib19/Android.mk
+++ b/tests/java_api/RSTest_CompatLib19/Android.mk
@@ -38,75 +38,75 @@
$(call all-java-files-under,src)\
$(my_rs_unit_tests_path)/UnitTest.java\
$(my_rs_unit_tests_path)/UT_alloc.java\
- $(my_rs_unit_tests_path)/alloc.rscript\
+ $(my_rs_unit_tests_path)/alloc.rs\
$(my_rs_unit_tests_path)/UT_array_alloc.java\
- $(my_rs_unit_tests_path)/array_alloc.rscript\
+ $(my_rs_unit_tests_path)/array_alloc.rs\
$(my_rs_unit_tests_path)/UT_array_init.java\
- $(my_rs_unit_tests_path)/array_init.rscript\
+ $(my_rs_unit_tests_path)/array_init.rs\
$(my_rs_unit_tests_path)/UT_atomic.java\
- $(my_rs_unit_tests_path)/atomic.rscript\
+ $(my_rs_unit_tests_path)/atomic.rs\
$(my_rs_unit_tests_path)/UT_bitfield.java\
- $(my_rs_unit_tests_path)/bitfield.rscript\
+ $(my_rs_unit_tests_path)/bitfield.rs\
$(my_rs_unit_tests_path)/UT_bug_char.java\
- $(my_rs_unit_tests_path)/bug_char.rscript\
+ $(my_rs_unit_tests_path)/bug_char.rs\
$(my_rs_unit_tests_path)/UT_check_dims.java\
- $(my_rs_unit_tests_path)/check_dims.rscript\
+ $(my_rs_unit_tests_path)/check_dims.rs\
$(my_rs_unit_tests_path)/UT_clamp.java\
- $(my_rs_unit_tests_path)/clamp.rscript\
+ $(my_rs_unit_tests_path)/clamp.rs\
$(my_rs_unit_tests_path)/UT_clamp_relaxed.java\
- $(my_rs_unit_tests_path)/clamp_relaxed.rscript\
+ $(my_rs_unit_tests_path)/clamp_relaxed.rs\
$(my_rs_unit_tests_path)/UT_constant.java\
- $(my_rs_unit_tests_path)/constant.rscript\
+ $(my_rs_unit_tests_path)/constant.rs\
$(my_rs_unit_tests_path)/UT_convert.java\
- $(my_rs_unit_tests_path)/convert.rscript\
+ $(my_rs_unit_tests_path)/convert.rs\
$(my_rs_unit_tests_path)/UT_convert_relaxed.java\
- $(my_rs_unit_tests_path)/convert_relaxed.rscript\
+ $(my_rs_unit_tests_path)/convert_relaxed.rs\
$(my_rs_unit_tests_path)/UT_copy_test.java\
- $(my_rs_unit_tests_path)/copy_test.rscript\
+ $(my_rs_unit_tests_path)/copy_test.rs\
$(my_rs_unit_tests_path)/UT_element.java\
- $(my_rs_unit_tests_path)/element.rscript\
+ $(my_rs_unit_tests_path)/element.rs\
$(my_rs_unit_tests_path)/UT_foreach.java\
- $(my_rs_unit_tests_path)/foreach.rscript\
+ $(my_rs_unit_tests_path)/foreach.rs\
$(my_rs_unit_tests_path)/UT_foreach_bounds.java\
- $(my_rs_unit_tests_path)/foreach_bounds.rscript\
+ $(my_rs_unit_tests_path)/foreach_bounds.rs\
$(my_rs_unit_tests_path)/UT_fp_mad.java\
- $(my_rs_unit_tests_path)/fp_mad.rscript\
+ $(my_rs_unit_tests_path)/fp_mad.rs\
$(my_rs_unit_tests_path)/UT_instance.java\
- $(my_rs_unit_tests_path)/instance.rscript\
+ $(my_rs_unit_tests_path)/instance.rs\
$(my_rs_unit_tests_path)/UT_int4.java\
- $(my_rs_unit_tests_path)/int4.rscript\
+ $(my_rs_unit_tests_path)/int4.rs\
$(my_rs_unit_tests_path)/UT_kernel.java\
- $(my_rs_unit_tests_path)/kernel.rscript\
+ $(my_rs_unit_tests_path)/kernel.rs\
$(my_rs_unit_tests_path)/UT_kernel_struct.java\
- $(my_rs_unit_tests_path)/kernel_struct.rscript\
+ $(my_rs_unit_tests_path)/kernel_struct.rs\
$(my_rs_unit_tests_path)/UT_math.java\
- $(my_rs_unit_tests_path)/math.rscript\
+ $(my_rs_unit_tests_path)/math.rs\
$(my_rs_unit_tests_path)/UT_min.java\
- $(my_rs_unit_tests_path)/min.rscript\
+ $(my_rs_unit_tests_path)/min.rs\
$(my_rs_unit_tests_path)/UT_noroot.java\
- $(my_rs_unit_tests_path)/noroot.rscript\
+ $(my_rs_unit_tests_path)/noroot.rs\
$(my_rs_unit_tests_path)/UT_primitives.java\
- $(my_rs_unit_tests_path)/primitives.rscript\
+ $(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
- $(my_rs_unit_tests_path)/refcount.rscript\
+ $(my_rs_unit_tests_path)/refcount.rs\
$(my_rs_unit_tests_path)/UT_reflection3264.java\
- $(my_rs_unit_tests_path)/reflection3264.rscript\
+ $(my_rs_unit_tests_path)/reflection3264.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
- $(my_rs_unit_tests_path)/rsdebug.rscript\
+ $(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rstime.java\
- $(my_rs_unit_tests_path)/rstime.rscript\
+ $(my_rs_unit_tests_path)/rstime.rs\
$(my_rs_unit_tests_path)/UT_rstypes.java\
- $(my_rs_unit_tests_path)/rstypes.rscript\
+ $(my_rs_unit_tests_path)/rstypes.rs\
$(my_rs_unit_tests_path)/UT_sampler.java\
- $(my_rs_unit_tests_path)/sampler.rscript\
+ $(my_rs_unit_tests_path)/sampler.rs\
$(my_rs_unit_tests_path)/UT_static_globals.java\
- $(my_rs_unit_tests_path)/static_globals.rscript\
+ $(my_rs_unit_tests_path)/static_globals.rs\
$(my_rs_unit_tests_path)/UT_struct.java\
- $(my_rs_unit_tests_path)/struct.rscript\
+ $(my_rs_unit_tests_path)/struct.rs\
$(my_rs_unit_tests_path)/UT_unsigned.java\
- $(my_rs_unit_tests_path)/unsigned.rscript\
+ $(my_rs_unit_tests_path)/unsigned.rs\
$(my_rs_unit_tests_path)/UT_vector.java\
- $(my_rs_unit_tests_path)/vector.rscript\
+ $(my_rs_unit_tests_path)/vector.rs\
include $(BUILD_PACKAGE)
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/alloc.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/alloc.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/alloc.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/alloc.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/apitest.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/apitest.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/apitest.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/apitest.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/array_alloc.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/array_alloc.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/array_alloc.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/array_alloc.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/array_init.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/array_init.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/array_init.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/array_init.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/atomic.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/atomic.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/atomic.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/atomic.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/bug_char.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/bug_char.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/bug_char.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/bug_char.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/clamp.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/clamp.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/clamp.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/clamp.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/clamp_relaxed.rs b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/clamp_relaxed.rs
new file mode 100644
index 0000000..71c65ae
--- /dev/null
+++ b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/clamp_relaxed.rs
@@ -0,0 +1,2 @@
+#include "clamp.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/clamp_relaxed.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/clamp_relaxed.rscript
deleted file mode 100644
index a9514c3..0000000
--- a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/clamp_relaxed.rscript
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "clamp.rscript"
-#pragma rs_fp_relaxed
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/constant.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/constant.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/constant.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/constant.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/convert.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/convert.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/convert.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/convert.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/convert_relaxed.rs b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/convert_relaxed.rs
new file mode 100644
index 0000000..81abb9b
--- /dev/null
+++ b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/convert_relaxed.rs
@@ -0,0 +1,2 @@
+#include "convert.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/convert_relaxed.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/convert_relaxed.rscript
deleted file mode 100644
index ad41780..0000000
--- a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/convert_relaxed.rscript
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "convert.rscript"
-#pragma rs_fp_relaxed
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/copy_test.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/copy_test.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/copy_test.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/copy_test.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/element.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/element.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/element.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/element.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/foreach.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/foreach.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/foreach.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/foreach.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/foreach_bounds.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/foreach_bounds.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/foreach_bounds.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/foreach_bounds.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/fp_mad.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/fp_mad.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/fp_mad.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/fp_mad.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/instance.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/instance.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/instance.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/instance.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/int4.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/int4.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/int4.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/int4.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/kernel.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/kernel.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/kernel.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/kernel.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/kernel_struct.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/kernel_struct.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/kernel_struct.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/kernel_struct.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math_agree.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math_agree.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math_agree.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math_agree.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math_conformance.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math_conformance.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math_conformance.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/math_conformance.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/min.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/min.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/min.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/min.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/noroot.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/noroot.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/noroot.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/noroot.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/primitives.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/primitives.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/primitives.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/primitives.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/refcount.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/refcount.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/refcount.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/refcount.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rsdebug.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rsdebug.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rsdebug.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rsdebug.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rslist.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rslist.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rslist.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rslist.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rstime.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rstime.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rstime.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rstime.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rstypes.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rstypes.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rstypes.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/rstypes.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/sampler.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/sampler.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/sampler.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/sampler.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/struct.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/struct.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/struct.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/struct.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/unsigned.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/unsigned.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/unsigned.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/unsigned.rs
diff --git a/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/vector.rscript b/tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/vector.rs
similarity index 100%
rename from tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/vector.rscript
rename to tests/java_api/RSTest_CompatLibLegacy/src/com/android/rs/test/vector.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/UT_script_group2_gatherscatter.java b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/UT_script_group2_gatherscatter.java
index 69e9e02..567afbe 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/UT_script_group2_gatherscatter.java
+++ b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/UT_script_group2_gatherscatter.java
@@ -48,7 +48,7 @@
// on global allocations that are passed across kernels in a script group.
// The test sums up all elements in the input int4 array of size ARRAY_SIZE.
// To do so, it adds up the second half of the array to its first half using
- // kernel function add() in addsup.rscript, and then repeatedly applies the same
+ // kernel function add() in addsup.rs, and then repeatedly applies the same
// kernel function to the shrinking result arrays until the result is a
// single int4 value.
// These steps are created as a script group by repeatedly adding the
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/addup.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/addup.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/addup.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/addup.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/alloc.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/alloc.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/alloc.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/alloc.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/array_alloc.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/array_alloc.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/array_alloc.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/array_alloc.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/array_init.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/array_init.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/array_init.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/array_init.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/atomic.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/atomic.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/atomic.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/atomic.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/bitfield.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/bitfield.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/bitfield.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/bitfield.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/bug_char.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/bug_char.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/bug_char.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/bug_char.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/check_dims.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/check_dims.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/check_dims.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/check_dims.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rs
similarity index 95%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rs
index b828ae0..9cc597f 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
+++ b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rs
@@ -14,5 +14,5 @@
* limitations under the License.
*/
-#include "clamp.rscript"
+#include "clamp.rs"
#pragma rs_fp_relaxed
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/constant.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/constant.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/constant.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/constant.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/convert.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/convert.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/convert.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/convert.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/convert_relaxed.rs
similarity index 95%
copy from tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
copy to tests/java_api/RSUnitTests/src/com/android/rs/unittest/convert_relaxed.rs
index b828ae0..93fd7cb 100644
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/clamp_relaxed.rscript
+++ b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/convert_relaxed.rs
@@ -14,5 +14,5 @@
* limitations under the License.
*/
-#include "clamp.rscript"
+#include "convert.rs"
#pragma rs_fp_relaxed
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/convert_relaxed.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/convert_relaxed.rscript
deleted file mode 100644
index 915143a..0000000
--- a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/convert_relaxed.rscript
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "convert.rscript"
-#pragma rs_fp_relaxed
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/copy_test.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/copy_test.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/copy_test.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/copy_test.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/ctxt_default.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/ctxt_default.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/ctxt_default.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/ctxt_default.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/double.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/double.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/double.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/double.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/element.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/element.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/element.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/element.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/float_test.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/float_test.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/float_test.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/float_test.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach_bounds.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach_bounds.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach_bounds.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach_bounds.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach_multi.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach_multi.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach_multi.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/foreach_multi.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp16.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp16.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp16.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp16.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp16_globals.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp16_globals.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp16_globals.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp16_globals.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp_mad.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp_mad.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp_mad.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/fp_mad.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/increment.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/increment.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/increment.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/increment.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/increment2.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/increment2.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/increment2.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/increment2.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/instance.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/instance.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/instance.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/instance.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/int4.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/int4.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/int4.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/int4.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel2d.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel2d.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel2d.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel2d.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel2d_oldstyle.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel2d_oldstyle.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel2d_oldstyle.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel2d_oldstyle.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel3d.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel3d.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel3d.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel3d.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel_struct.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel_struct.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel_struct.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/kernel_struct.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/math.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/math.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/math.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/math.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_24.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_24.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_24.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_24.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_agree.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_agree.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_agree.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_agree.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_conformance.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_conformance.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_conformance.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_conformance.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_fp16.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_fp16.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_fp16.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/math_fp16.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/min.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/min.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/min.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/min.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/noroot.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/noroot.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/noroot.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/noroot.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/primitives.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/primitives.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/primitives.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/primitives.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/reduce.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/reduce.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/reduce.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/reduce.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/reduce_backward.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/reduce_backward.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/reduce_backward.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/reduce_backward.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/refcount.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/refcount.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/refcount.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/refcount.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/reflection3264.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/reflection3264.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/reflection3264.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/reflection3264.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug_23.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug_23.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug_23.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug_23.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug_24.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug_24.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug_24.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/rsdebug_24.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/rstime.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/rstime.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/rstime.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/rstime.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/rstypes.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/rstypes.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/rstypes.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/rstypes.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/sampler.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/sampler.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/sampler.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/sampler.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_alloc.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_alloc.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_alloc.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_alloc.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_ref_count.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_ref_count.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_ref_count.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_ref_count.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_script.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_script.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_script.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/single_source_script.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/small_struct.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/small_struct.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/small_struct.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/small_struct.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/small_struct_2.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/small_struct_2.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/small_struct_2.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/small_struct_2.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/static_globals.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/static_globals.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/static_globals.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/static_globals.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct_field.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct_field.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct_field.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct_field.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct_field_simple.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct_field_simple.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct_field_simple.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/struct_field_simple.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/unsigned.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/unsigned.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/unsigned.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/unsigned.rs
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/vector.rscript b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/vector.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/src/com/android/rs/unittest/vector.rscript
rename to tests/java_api/RSUnitTests/src/com/android/rs/unittest/vector.rs
diff --git a/tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/alloc_supportlib.rscript b/tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/alloc_supportlib.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/alloc_supportlib.rscript
rename to tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/alloc_supportlib.rs
diff --git a/tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/apitest.rscript b/tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/apitest.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/apitest.rscript
rename to tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/apitest.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/UT_script_group2_gatherscatter.java b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/UT_script_group2_gatherscatter.java
index 8d8605d..9146872 100644
--- a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/UT_script_group2_gatherscatter.java
+++ b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/UT_script_group2_gatherscatter.java
@@ -50,7 +50,7 @@
// on global allocations that are passed across kernels in a script group.
// The test sums up all elements in the input int4 array of size ARRAY_SIZE.
// To do so, it adds up the second half of the array to its first half using
- // kernel function add() in addsup.rscript, and then repeatedly applies the same
+ // kernel function add() in addsup.rs, and then repeatedly applies the same
// kernel function to the shrinking result arrays until the result is a
// single int4 value.
// These steps are created as a script group by repeatedly adding the
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/addup.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/addup.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/addup.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/addup.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/alloc.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/alloc.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/alloc.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/alloc.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/alloc_supportlib.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/alloc_supportlib.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/alloc_supportlib.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/alloc_supportlib.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/apitest.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/apitest.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/apitest.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/apitest.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/array_alloc.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/array_alloc.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/array_alloc.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/array_alloc.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/array_init.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/array_init.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/array_init.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/array_init.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/atomic.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/atomic.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/atomic.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/atomic.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/bitfield.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/bitfield.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/bitfield.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/bitfield.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/bug_char.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/bug_char.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/bug_char.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/bug_char.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/check_dims.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/check_dims.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/check_dims.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/check_dims.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/clamp.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/clamp.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/clamp.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/clamp.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert_relaxed.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/clamp_relaxed.rs
similarity index 96%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert_relaxed.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/clamp_relaxed.rs
index 48b61c4..f391d62 100644
--- a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert_relaxed.rscript
+++ b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/clamp_relaxed.rs
@@ -16,5 +16,5 @@
* limitations under the License.
*/
-#include "convert.rscript"
+#include "clamp.rs"
#pragma rs_fp_relaxed
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/clamp_relaxed.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/clamp_relaxed.rscript
deleted file mode 100644
index 72ae631..0000000
--- a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/clamp_relaxed.rscript
+++ /dev/null
@@ -1,20 +0,0 @@
-// This file is automatically generated from
-// frameworks/rs/tests/java_api/RSUnitTests/RSUnitTests.py
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "clamp.rscript"
-#pragma rs_fp_relaxed
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/constant.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/constant.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/constant.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/constant.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert_relaxed.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert_relaxed.rs
similarity index 96%
copy from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert_relaxed.rscript
copy to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert_relaxed.rs
index 48b61c4..05de3c3 100644
--- a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert_relaxed.rscript
+++ b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/convert_relaxed.rs
@@ -16,5 +16,5 @@
* limitations under the License.
*/
-#include "convert.rscript"
+#include "convert.rs"
#pragma rs_fp_relaxed
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/copy_test.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/copy_test.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/copy_test.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/copy_test.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/ctxt_default.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/ctxt_default.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/ctxt_default.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/ctxt_default.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/double.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/double.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/double.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/double.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/element.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/element.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/element.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/element.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/float_test.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/float_test.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/float_test.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/float_test.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach_bounds.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach_bounds.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach_bounds.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach_bounds.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach_multi.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach_multi.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach_multi.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/foreach_multi.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/fp_mad.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/fp_mad.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/fp_mad.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/fp_mad.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/increment.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/increment.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/increment.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/increment.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/increment2.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/increment2.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/increment2.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/increment2.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/instance.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/instance.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/instance.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/instance.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/int4.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/int4.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/int4.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/int4.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel2d.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel2d.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel2d.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel2d.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel2d_oldstyle.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel2d_oldstyle.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel2d_oldstyle.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel2d_oldstyle.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel3d.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel3d.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel3d.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel3d.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel_struct.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel_struct.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel_struct.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/kernel_struct.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_24.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_24.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_24.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_24.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_agree.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_agree.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_agree.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_agree.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_conformance.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_conformance.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_conformance.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/math_conformance.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/min.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/min.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/min.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/min.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/noroot.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/noroot.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/noroot.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/noroot.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/primitives.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/primitives.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/primitives.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/primitives.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reduce.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reduce.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reduce.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reduce.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reduce_backward.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reduce_backward.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reduce_backward.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reduce_backward.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/refcount.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/refcount.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/refcount.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/refcount.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reflection3264.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reflection3264.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reflection3264.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reflection3264.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug_23.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug_23.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug_23.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug_23.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug_24.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug_24.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug_24.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rsdebug_24.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rstime.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rstime.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rstime.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rstime.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rstypes.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rstypes.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rstypes.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/rstypes.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/sampler.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/sampler.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/sampler.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/sampler.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_alloc.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_alloc.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_alloc.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_alloc.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_ref_count.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_ref_count.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_ref_count.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_ref_count.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_script.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_script.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_script.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/single_source_script.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/small_struct.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/small_struct.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/small_struct.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/small_struct.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/small_struct_2.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/small_struct_2.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/small_struct_2.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/small_struct_2.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/static_globals.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/static_globals.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/static_globals.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/static_globals.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct_field.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct_field.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct_field.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct_field.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct_field_simple.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct_field_simple.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct_field_simple.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/struct_field_simple.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/unsigned.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/unsigned.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/unsigned.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/unsigned.rs
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/vector.rscript b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/vector.rs
similarity index 100%
rename from tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/vector.rscript
rename to tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/vector.rs
diff --git a/tests/java_api/Refocus/src/com/android/rs/test/layered_filter_fast_d1new.rscript b/tests/java_api/Refocus/src/com/android/rs/test/layered_filter_fast_d1new.rs
similarity index 100%
rename from tests/java_api/Refocus/src/com/android/rs/test/layered_filter_fast_d1new.rscript
rename to tests/java_api/Refocus/src/com/android/rs/test/layered_filter_fast_d1new.rs
diff --git a/tests/java_api/Refocus/src/com/android/rs/test/layered_filter_fast_f32.rscript b/tests/java_api/Refocus/src/com/android/rs/test/layered_filter_fast_f32.rs
similarity index 100%
rename from tests/java_api/Refocus/src/com/android/rs/test/layered_filter_fast_f32.rscript
rename to tests/java_api/Refocus/src/com/android/rs/test/layered_filter_fast_f32.rs
diff --git a/tests/java_api/RsCameraDemo/src/com/android/example/rscamera/focus_peak.rscript b/tests/java_api/RsCameraDemo/src/com/android/example/rscamera/focus_peak.rs
similarity index 100%
rename from tests/java_api/RsCameraDemo/src/com/android/example/rscamera/focus_peak.rscript
rename to tests/java_api/RsCameraDemo/src/com/android/example/rscamera/focus_peak.rs
diff --git a/tests/java_api/RsNbody/src/com/example/android/rs/nbody_gl/nbody.rscript b/tests/java_api/RsNbody/src/com/example/android/rs/nbody_gl/nbody.rs
similarity index 100%
rename from tests/java_api/RsNbody/src/com/example/android/rs/nbody_gl/nbody.rscript
rename to tests/java_api/RsNbody/src/com/example/android/rs/nbody_gl/nbody.rs
diff --git a/tests/java_api/RsTest_11/src/com/android/rs/test/fp_mad.rscript b/tests/java_api/RsTest_11/src/com/android/rs/test/fp_mad.rs
similarity index 100%
rename from tests/java_api/RsTest_11/src/com/android/rs/test/fp_mad.rscript
rename to tests/java_api/RsTest_11/src/com/android/rs/test/fp_mad.rs
diff --git a/tests/java_api/RsTest_11/src/com/android/rs/test/math.rscript b/tests/java_api/RsTest_11/src/com/android/rs/test/math.rs
similarity index 100%
rename from tests/java_api/RsTest_11/src/com/android/rs/test/math.rscript
rename to tests/java_api/RsTest_11/src/com/android/rs/test/math.rs
diff --git a/tests/java_api/RsTest_11/src/com/android/rs/test/primitives.rscript b/tests/java_api/RsTest_11/src/com/android/rs/test/primitives.rs
similarity index 100%
rename from tests/java_api/RsTest_11/src/com/android/rs/test/primitives.rscript
rename to tests/java_api/RsTest_11/src/com/android/rs/test/primitives.rs
diff --git a/tests/java_api/RsTest_11/src/com/android/rs/test/rsdebug.rscript b/tests/java_api/RsTest_11/src/com/android/rs/test/rsdebug.rs
similarity index 100%
rename from tests/java_api/RsTest_11/src/com/android/rs/test/rsdebug.rscript
rename to tests/java_api/RsTest_11/src/com/android/rs/test/rsdebug.rs
diff --git a/tests/java_api/RsTest_11/src/com/android/rs/test/rslist.rscript b/tests/java_api/RsTest_11/src/com/android/rs/test/rslist.rs
similarity index 100%
rename from tests/java_api/RsTest_11/src/com/android/rs/test/rslist.rscript
rename to tests/java_api/RsTest_11/src/com/android/rs/test/rslist.rs
diff --git a/tests/java_api/RsTest_11/src/com/android/rs/test/rstime.rscript b/tests/java_api/RsTest_11/src/com/android/rs/test/rstime.rs
similarity index 100%
rename from tests/java_api/RsTest_11/src/com/android/rs/test/rstime.rscript
rename to tests/java_api/RsTest_11/src/com/android/rs/test/rstime.rs
diff --git a/tests/java_api/RsTest_11/src/com/android/rs/test/rstypes.rscript b/tests/java_api/RsTest_11/src/com/android/rs/test/rstypes.rs
similarity index 100%
rename from tests/java_api/RsTest_11/src/com/android/rs/test/rstypes.rscript
rename to tests/java_api/RsTest_11/src/com/android/rs/test/rstypes.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/alloc.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/alloc.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/alloc.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/alloc.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/foreach.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/foreach.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/foreach.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/foreach.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/fp_mad.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/fp_mad.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/fp_mad.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/fp_mad.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/math.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/math.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/math.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/math.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/primitives.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/primitives.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/primitives.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/primitives.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/refcount.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/refcount.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/refcount.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/refcount.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/rsdebug.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/rsdebug.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/rsdebug.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/rsdebug.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/rslist.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/rslist.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/rslist.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/rslist.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/rstime.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/rstime.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/rstime.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/rstime.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/rstypes.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/rstypes.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/rstypes.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/rstypes.rs
diff --git a/tests/java_api/RsTest_14/src/com/android/rs/test/vector.rscript b/tests/java_api/RsTest_14/src/com/android/rs/test/vector.rs
similarity index 100%
rename from tests/java_api/RsTest_14/src/com/android/rs/test/vector.rscript
rename to tests/java_api/RsTest_14/src/com/android/rs/test/vector.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/alloc.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/alloc.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/alloc.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/alloc.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/foreach.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/foreach.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/foreach.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/foreach.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/fp_mad.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/fp_mad.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/fp_mad.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/fp_mad.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/math.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/math.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/math.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/math.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/primitives.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/primitives.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/primitives.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/primitives.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/refcount.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/refcount.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/refcount.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/refcount.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/rsdebug.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/rsdebug.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/rsdebug.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/rsdebug.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/rslist.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/rslist.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/rslist.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/rslist.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/rstime.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/rstime.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/rstime.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/rstime.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/rstypes.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/rstypes.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/rstypes.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/rstypes.rs
diff --git a/tests/java_api/RsTest_16/src/com/android/rs/test/vector.rscript b/tests/java_api/RsTest_16/src/com/android/rs/test/vector.rs
similarity index 100%
rename from tests/java_api/RsTest_16/src/com/android/rs/test/vector.rscript
rename to tests/java_api/RsTest_16/src/com/android/rs/test/vector.rs
diff --git a/tests/java_api/SSHealingBrush/src/rs/example/android/com/healingbrush/find_region.rscript b/tests/java_api/SSHealingBrush/src/rs/example/android/com/healingbrush/find_region.rs
similarity index 100%
rename from tests/java_api/SSHealingBrush/src/rs/example/android/com/healingbrush/find_region.rscript
rename to tests/java_api/SSHealingBrush/src/rs/example/android/com/healingbrush/find_region.rs
diff --git a/tests/java_api/SSHealingBrush/src/rs/example/android/com/healingbrush/healing.rscript b/tests/java_api/SSHealingBrush/src/rs/example/android/com/healingbrush/healing.rs
similarity index 100%
rename from tests/java_api/SSHealingBrush/src/rs/example/android/com/healingbrush/healing.rscript
rename to tests/java_api/SSHealingBrush/src/rs/example/android/com/healingbrush/healing.rs
diff --git a/tests/java_api/SampleTest/src/com/android/rs/sample/sample.rscript b/tests/java_api/SampleTest/src/com/android/rs/sample/sample.rs
similarity index 100%
rename from tests/java_api/SampleTest/src/com/android/rs/sample/sample.rscript
rename to tests/java_api/SampleTest/src/com/android/rs/sample/sample.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/colormatrix_f.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/colormatrix_f.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/colormatrix_f.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/colormatrix_f.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/contrast_f.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/contrast_f.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/contrast_f.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/contrast_f.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/exposure_f.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/exposure_f.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/exposure_f.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/exposure_f.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/f4touc4.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/f4touc4.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/f4touc4.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/f4touc4.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_relaxed_f.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_relaxed_f.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_relaxed_f.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_relaxed_f.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/greyscale_f.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/greyscale_f.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/greyscale_f.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/greyscale_f.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/levels_relaxed_f.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/levels_relaxed_f.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/levels_relaxed_f.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/levels_relaxed_f.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/shadows_f.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/shadows_f.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/shadows_f.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/shadows_f.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/uc4tof4.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/uc4tof4.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/uc4tof4.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/uc4tof4.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/vibrance_f.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/vibrance_f.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/vibrance_f.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/vibrance_f.rs
diff --git a/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_relaxed_f.rscript b/tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_relaxed_f.rs
similarity index 100%
rename from tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_relaxed_f.rscript
rename to tests/java_api/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_relaxed_f.rs
diff --git a/tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/bricked.rscript b/tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/bricked.rs
similarity index 100%
rename from tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/bricked.rscript
rename to tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/bricked.rs
diff --git a/tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/bugdroid.rscript b/tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/bugdroid.rs
similarity index 100%
rename from tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/bugdroid.rscript
rename to tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/bugdroid.rs
diff --git a/tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/mandelbulb.rscript b/tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/mandelbulb.rs
similarity index 100%
rename from tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/mandelbulb.rscript
rename to tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/mandelbulb.rs
diff --git a/tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/rasterize.rscript b/tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/rasterize.rs
similarity index 100%
rename from tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/rasterize.rscript
rename to tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/rasterize.rs
diff --git a/tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/vr.rscript b/tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/vr.rs
similarity index 100%
rename from tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/vr.rscript
rename to tests/java_api/VrDemo/src/com/example/android/rs/vr/engine/vr.rs
diff --git a/tests/lldb/cpp/Allocations/Android.mk b/tests/lldb/cpp/Allocations/Android.mk
index 11b484f..16ed1b2 100644
--- a/tests/lldb/cpp/Allocations/Android.mk
+++ b/tests/lldb/cpp/Allocations/Android.mk
@@ -5,7 +5,7 @@
LOCAL_SRC_FILES := \
Allocations.cpp \
- allocs.rscript
+ allocs.rs
LOCAL_STATIC_LIBRARIES := libcompiler_rt
diff --git a/tests/lldb/cpp/Allocations/allocs.rscript b/tests/lldb/cpp/Allocations/allocs.rs
similarity index 100%
rename from tests/lldb/cpp/Allocations/allocs.rscript
rename to tests/lldb/cpp/Allocations/allocs.rs
diff --git a/tests/lldb/cpp/BranchingFunCalls/Android.mk b/tests/lldb/cpp/BranchingFunCalls/Android.mk
index 12a3e32..56bd152 100644
--- a/tests/lldb/cpp/BranchingFunCalls/Android.mk
+++ b/tests/lldb/cpp/BranchingFunCalls/Android.mk
@@ -5,7 +5,7 @@
LOCAL_SRC_FILES := \
BranchingFunCalls.cpp \
- scalars.rscript
+ scalars.rs
include frameworks/rs/tests/lldb/cpp/common.mk
include $(BUILD_EXECUTABLE)
diff --git a/tests/lldb/cpp/BranchingFunCalls/scalars.rscript b/tests/lldb/cpp/BranchingFunCalls/scalars.rs
similarity index 100%
rename from tests/lldb/cpp/BranchingFunCalls/scalars.rscript
rename to tests/lldb/cpp/BranchingFunCalls/scalars.rs
diff --git a/tests/lldb/cpp/InfiniteLoop/Android.mk b/tests/lldb/cpp/InfiniteLoop/Android.mk
index f0895ec..bfcb13a 100644
--- a/tests/lldb/cpp/InfiniteLoop/Android.mk
+++ b/tests/lldb/cpp/InfiniteLoop/Android.mk
@@ -5,7 +5,7 @@
LOCAL_SRC_FILES := \
InfiniteLoop.cpp \
- infiniteloop.rscript
+ infiniteloop.rs
include frameworks/rs/tests/lldb/cpp/common.mk
include $(BUILD_EXECUTABLE)
diff --git a/tests/lldb/cpp/InfiniteLoop/infiniteloop.rscript b/tests/lldb/cpp/InfiniteLoop/infiniteloop.rs
similarity index 100%
rename from tests/lldb/cpp/InfiniteLoop/infiniteloop.rscript
rename to tests/lldb/cpp/InfiniteLoop/infiniteloop.rs
diff --git a/tests/lldb/cpp/KernelVariables/Android.mk b/tests/lldb/cpp/KernelVariables/Android.mk
index b9f9102..2d40475 100644
--- a/tests/lldb/cpp/KernelVariables/Android.mk
+++ b/tests/lldb/cpp/KernelVariables/Android.mk
@@ -5,7 +5,7 @@
LOCAL_SRC_FILES := \
KernelVariables.cpp \
- simple.rscript
+ simple.rs
include frameworks/rs/tests/lldb/cpp/common.mk
include $(BUILD_EXECUTABLE)
diff --git a/tests/lldb/cpp/KernelVariables/simple.rscript b/tests/lldb/cpp/KernelVariables/simple.rs
similarity index 100%
rename from tests/lldb/cpp/KernelVariables/simple.rscript
rename to tests/lldb/cpp/KernelVariables/simple.rs
diff --git a/tests/lldb/cpp/MultipleRSFiles/Android.mk b/tests/lldb/cpp/MultipleRSFiles/Android.mk
index 4c224b8..334f030 100644
--- a/tests/lldb/cpp/MultipleRSFiles/Android.mk
+++ b/tests/lldb/cpp/MultipleRSFiles/Android.mk
@@ -5,8 +5,8 @@
LOCAL_SRC_FILES := \
MultipleRSFiles.cpp \
- first.rscript \
- second.rscript
+ first.rs \
+ second.rs
include frameworks/rs/tests/lldb/cpp/common.mk
include $(BUILD_EXECUTABLE)
diff --git a/tests/lldb/cpp/MultipleRSFiles/first.rscript b/tests/lldb/cpp/MultipleRSFiles/first.rs
similarity index 100%
rename from tests/lldb/cpp/MultipleRSFiles/first.rscript
rename to tests/lldb/cpp/MultipleRSFiles/first.rs
diff --git a/tests/lldb/cpp/MultipleRSFiles/second.rscript b/tests/lldb/cpp/MultipleRSFiles/second.rs
similarity index 100%
rename from tests/lldb/cpp/MultipleRSFiles/second.rscript
rename to tests/lldb/cpp/MultipleRSFiles/second.rs
diff --git a/tests/lldb/cpp/WaitAttach/Android.mk b/tests/lldb/cpp/WaitAttach/Android.mk
index 2c4f18c..0214305 100644
--- a/tests/lldb/cpp/WaitAttach/Android.mk
+++ b/tests/lldb/cpp/WaitAttach/Android.mk
@@ -5,7 +5,7 @@
LOCAL_SRC_FILES := \
WaitAttach.cpp \
- simple.rscript
+ simple.rs
include frameworks/rs/tests/lldb/cpp/common.mk
include $(BUILD_EXECUTABLE)
@@ -16,7 +16,7 @@
LOCAL_SRC_FILES := \
WaitAttach.cpp \
- simple.rscript
+ simple.rs
include frameworks/rs/tests/lldb/cpp/common.mk
LOCAL_RENDERSCRIPT_FLAGS := $(filter-out -g,$(LOCAL_RENDERSCRIPT_FLAGS))
diff --git a/tests/lldb/cpp/WaitAttach/simple.rscript b/tests/lldb/cpp/WaitAttach/simple.rs
similarity index 100%
rename from tests/lldb/cpp/WaitAttach/simple.rscript
rename to tests/lldb/cpp/WaitAttach/simple.rs
diff --git a/tests/lldb/java/Allocations/src/rs/allocs.rscript b/tests/lldb/java/Allocations/src/rs/allocs.rs
similarity index 100%
rename from tests/lldb/java/Allocations/src/rs/allocs.rscript
rename to tests/lldb/java/Allocations/src/rs/allocs.rs
diff --git a/tests/lldb/java/BranchingFunCalls/src/rs/scalars.rscript b/tests/lldb/java/BranchingFunCalls/src/rs/scalars.rs
similarity index 100%
rename from tests/lldb/java/BranchingFunCalls/src/rs/scalars.rscript
rename to tests/lldb/java/BranchingFunCalls/src/rs/scalars.rs
diff --git a/tests/lldb/java/DebugWaitAttach/src/rs/simple.rscript b/tests/lldb/java/DebugWaitAttach/src/rs/simple.rs
similarity index 100%
rename from tests/lldb/java/DebugWaitAttach/src/rs/simple.rscript
rename to tests/lldb/java/DebugWaitAttach/src/rs/simple.rs
diff --git a/tests/lldb/java/InfiniteLoop/src/com/android/rs/infiniteloop/infiniteloop.rscript b/tests/lldb/java/InfiniteLoop/src/com/android/rs/infiniteloop/infiniteloop.rs
similarity index 100%
rename from tests/lldb/java/InfiniteLoop/src/com/android/rs/infiniteloop/infiniteloop.rscript
rename to tests/lldb/java/InfiniteLoop/src/com/android/rs/infiniteloop/infiniteloop.rs
diff --git a/tests/lldb/java/KernelVariables/src/rs/simple.rscript b/tests/lldb/java/KernelVariables/src/rs/simple.rs
similarity index 100%
rename from tests/lldb/java/KernelVariables/src/rs/simple.rscript
rename to tests/lldb/java/KernelVariables/src/rs/simple.rs
diff --git a/tests/lldb/java/MultipleRSFiles/src/rs/first.rscript b/tests/lldb/java/MultipleRSFiles/src/rs/first.rs
similarity index 100%
rename from tests/lldb/java/MultipleRSFiles/src/rs/first.rscript
rename to tests/lldb/java/MultipleRSFiles/src/rs/first.rs
diff --git a/tests/lldb/java/MultipleRSFiles/src/rs/second.rscript b/tests/lldb/java/MultipleRSFiles/src/rs/second.rs
similarity index 100%
rename from tests/lldb/java/MultipleRSFiles/src/rs/second.rscript
rename to tests/lldb/java/MultipleRSFiles/src/rs/second.rs
diff --git a/tests/lldb/java/NoDebugWaitAttach/src/rs/simple.rscript b/tests/lldb/java/NoDebugWaitAttach/src/rs/simple.rs
similarity index 100%
rename from tests/lldb/java/NoDebugWaitAttach/src/rs/simple.rscript
rename to tests/lldb/java/NoDebugWaitAttach/src/rs/simple.rs
diff --git a/tests/lldb/java/Reduction/src/com/android/rs/lldbreductiontest/reduce.rscript b/tests/lldb/java/Reduction/src/com/android/rs/lldbreductiontest/reduce.rs
similarity index 100%
rename from tests/lldb/java/Reduction/src/com/android/rs/lldbreductiontest/reduce.rscript
rename to tests/lldb/java/Reduction/src/com/android/rs/lldbreductiontest/reduce.rs
diff --git a/tests/lldb/java/Reduction/src/com/android/rs/lldbreductiontest/reduce_auto_comb.rscript b/tests/lldb/java/Reduction/src/com/android/rs/lldbreductiontest/reduce_auto_comb.rs
similarity index 100%
rename from tests/lldb/java/Reduction/src/com/android/rs/lldbreductiontest/reduce_auto_comb.rscript
rename to tests/lldb/java/Reduction/src/com/android/rs/lldbreductiontest/reduce_auto_comb.rs
diff --git a/tests/lldb/java/ScriptGroup/src/rs/scriptgroup.rscript b/tests/lldb/java/ScriptGroup/src/rs/scriptgroup.rs
similarity index 100%
rename from tests/lldb/java/ScriptGroup/src/rs/scriptgroup.rscript
rename to tests/lldb/java/ScriptGroup/src/rs/scriptgroup.rs
diff --git a/tests/lldb/java/SingleSource/src/rs/rs_single_source.rscript b/tests/lldb/java/SingleSource/src/rs/rs_single_source.rs
similarity index 100%
rename from tests/lldb/java/SingleSource/src/rs/rs_single_source.rscript
rename to tests/lldb/java/SingleSource/src/rs/rs_single_source.rs
diff --git a/tests/lldb/jni/Allocations/jniallocations/Android.mk b/tests/lldb/jni/Allocations/jniallocations/Android.mk
index e5c2863..2493be1 100644
--- a/tests/lldb/jni/Allocations/jniallocations/Android.mk
+++ b/tests/lldb/jni/Allocations/jniallocations/Android.mk
@@ -3,7 +3,7 @@
LOCAL_MODULE := libjniallocations
-LOCAL_SRC_FILES := jniallocations.cpp allocs.rscript
+LOCAL_SRC_FILES := jniallocations.cpp allocs.rs
LOCAL_RENDERSCRIPT_FLAGS := -g
diff --git a/tests/lldb/jni/Allocations/jniallocations/allocs.rscript b/tests/lldb/jni/Allocations/jniallocations/allocs.rs
similarity index 100%
rename from tests/lldb/jni/Allocations/jniallocations/allocs.rscript
rename to tests/lldb/jni/Allocations/jniallocations/allocs.rs
diff --git a/tests/lldb/jni/BranchingFunCalls/jnibranchingfuncalls/Android.mk b/tests/lldb/jni/BranchingFunCalls/jnibranchingfuncalls/Android.mk
index 34dd1ad..c04cc19 100644
--- a/tests/lldb/jni/BranchingFunCalls/jnibranchingfuncalls/Android.mk
+++ b/tests/lldb/jni/BranchingFunCalls/jnibranchingfuncalls/Android.mk
@@ -3,7 +3,7 @@
LOCAL_MODULE := libjnibranchingfuncalls
-LOCAL_SRC_FILES := jnibranchingfuncalls.cpp scalars.rscript
+LOCAL_SRC_FILES := jnibranchingfuncalls.cpp scalars.rs
LOCAL_RENDERSCRIPT_FLAGS := -g
diff --git a/tests/lldb/jni/BranchingFunCalls/jnibranchingfuncalls/scalars.rscript b/tests/lldb/jni/BranchingFunCalls/jnibranchingfuncalls/scalars.rs
similarity index 100%
rename from tests/lldb/jni/BranchingFunCalls/jnibranchingfuncalls/scalars.rscript
rename to tests/lldb/jni/BranchingFunCalls/jnibranchingfuncalls/scalars.rs
diff --git a/tests/lldb/jni/DebugWaitAttach/jnidebugwaitattach/Android.mk b/tests/lldb/jni/DebugWaitAttach/jnidebugwaitattach/Android.mk
index edb348f..c1df28c 100644
--- a/tests/lldb/jni/DebugWaitAttach/jnidebugwaitattach/Android.mk
+++ b/tests/lldb/jni/DebugWaitAttach/jnidebugwaitattach/Android.mk
@@ -3,7 +3,7 @@
LOCAL_MODULE := libjnidebugwaitattach
-LOCAL_SRC_FILES := jnidebugwaitattach.cpp simple.rscript
+LOCAL_SRC_FILES := jnidebugwaitattach.cpp simple.rs
LOCAL_RENDERSCRIPT_FLAGS := -g
diff --git a/tests/lldb/jni/DebugWaitAttach/jnidebugwaitattach/simple.rscript b/tests/lldb/jni/DebugWaitAttach/jnidebugwaitattach/simple.rs
similarity index 100%
rename from tests/lldb/jni/DebugWaitAttach/jnidebugwaitattach/simple.rscript
rename to tests/lldb/jni/DebugWaitAttach/jnidebugwaitattach/simple.rs
diff --git a/tests/lldb/jni/InfiniteLoop/jniinfiniteloop/Android.mk b/tests/lldb/jni/InfiniteLoop/jniinfiniteloop/Android.mk
index 31001d0..dfc1207 100644
--- a/tests/lldb/jni/InfiniteLoop/jniinfiniteloop/Android.mk
+++ b/tests/lldb/jni/InfiniteLoop/jniinfiniteloop/Android.mk
@@ -3,7 +3,7 @@
LOCAL_MODULE := libjniinfiniteloop
-LOCAL_SRC_FILES := jniinfiniteloop.cpp infiniteloop.rscript
+LOCAL_SRC_FILES := jniinfiniteloop.cpp infiniteloop.rs
LOCAL_RENDERSCRIPT_FLAGS := -g
diff --git a/tests/lldb/jni/InfiniteLoop/jniinfiniteloop/infiniteloop.rscript b/tests/lldb/jni/InfiniteLoop/jniinfiniteloop/infiniteloop.rs
similarity index 100%
rename from tests/lldb/jni/InfiniteLoop/jniinfiniteloop/infiniteloop.rscript
rename to tests/lldb/jni/InfiniteLoop/jniinfiniteloop/infiniteloop.rs
diff --git a/tests/lldb/jni/KernelVariables/jnikernelvariables/Android.mk b/tests/lldb/jni/KernelVariables/jnikernelvariables/Android.mk
index fe372a7..9088f7e 100644
--- a/tests/lldb/jni/KernelVariables/jnikernelvariables/Android.mk
+++ b/tests/lldb/jni/KernelVariables/jnikernelvariables/Android.mk
@@ -3,7 +3,7 @@
LOCAL_MODULE := libjnikernelvariables
-LOCAL_SRC_FILES := jnikernelvariables.cpp simple.rscript
+LOCAL_SRC_FILES := jnikernelvariables.cpp simple.rs
LOCAL_RENDERSCRIPT_FLAGS := -g
diff --git a/tests/lldb/jni/KernelVariables/jnikernelvariables/simple.rscript b/tests/lldb/jni/KernelVariables/jnikernelvariables/simple.rs
similarity index 100%
rename from tests/lldb/jni/KernelVariables/jnikernelvariables/simple.rscript
rename to tests/lldb/jni/KernelVariables/jnikernelvariables/simple.rs
diff --git a/tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/Android.mk b/tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/Android.mk
index 6fd4b10..8d6125e 100644
--- a/tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/Android.mk
+++ b/tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/Android.mk
@@ -3,7 +3,7 @@
LOCAL_MODULE := libjnimultiplersfiles
-LOCAL_SRC_FILES := jnimultiplersfiles.cpp first.rscript second.rscript
+LOCAL_SRC_FILES := jnimultiplersfiles.cpp first.rs second.rs
LOCAL_RENDERSCRIPT_FLAGS := -g
diff --git a/tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/first.rscript b/tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/first.rs
similarity index 100%
rename from tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/first.rscript
rename to tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/first.rs
diff --git a/tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/second.rscript b/tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/second.rs
similarity index 100%
rename from tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/second.rscript
rename to tests/lldb/jni/MultipleRSFiles/jnimultiplersfiles/second.rs
diff --git a/tests/lldb/jni/NoDebugWaitAttach/jninodebugwaitattach/Android.mk b/tests/lldb/jni/NoDebugWaitAttach/jninodebugwaitattach/Android.mk
index fda6fcf..91313d5 100644
--- a/tests/lldb/jni/NoDebugWaitAttach/jninodebugwaitattach/Android.mk
+++ b/tests/lldb/jni/NoDebugWaitAttach/jninodebugwaitattach/Android.mk
@@ -3,7 +3,7 @@
LOCAL_MODULE := libjninodebugwaitattach
-LOCAL_SRC_FILES := jninodebugwaitattach.cpp simple.rscript
+LOCAL_SRC_FILES := jninodebugwaitattach.cpp simple.rs
include frameworks/rs/tests/lldb/jni/common.mk
include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/lldb/jni/NoDebugWaitAttach/jninodebugwaitattach/simple.rscript b/tests/lldb/jni/NoDebugWaitAttach/jninodebugwaitattach/simple.rs
similarity index 100%
rename from tests/lldb/jni/NoDebugWaitAttach/jninodebugwaitattach/simple.rscript
rename to tests/lldb/jni/NoDebugWaitAttach/jninodebugwaitattach/simple.rs