175f0d3110b04346b901771f96ce15cdbe907278fYang Ni/*
275f0d3110b04346b901771f96ce15cdbe907278fYang Ni * Copyright (C) 2016 The Android Open Source Project
375f0d3110b04346b901771f96ce15cdbe907278fYang Ni *
475f0d3110b04346b901771f96ce15cdbe907278fYang Ni * Licensed under the Apache License, Version 2.0 (the "License");
575f0d3110b04346b901771f96ce15cdbe907278fYang Ni * you may not use this file except in compliance with the License.
675f0d3110b04346b901771f96ce15cdbe907278fYang Ni * You may obtain a copy of the License at
775f0d3110b04346b901771f96ce15cdbe907278fYang Ni *
875f0d3110b04346b901771f96ce15cdbe907278fYang Ni *      http://www.apache.org/licenses/LICENSE-2.0
975f0d3110b04346b901771f96ce15cdbe907278fYang Ni *
1075f0d3110b04346b901771f96ce15cdbe907278fYang Ni * Unless required by applicable law or agreed to in writing, software
1175f0d3110b04346b901771f96ce15cdbe907278fYang Ni * distributed under the License is distributed on an "AS IS" BASIS,
1275f0d3110b04346b901771f96ce15cdbe907278fYang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1375f0d3110b04346b901771f96ce15cdbe907278fYang Ni * See the License for the specific language governing permissions and
1475f0d3110b04346b901771f96ce15cdbe907278fYang Ni * limitations under the License.
1575f0d3110b04346b901771f96ce15cdbe907278fYang Ni */
1675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
1775f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsovScript.h"
1875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
19ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung#include "bcinfo/MetadataExtractor.h"
2075f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsContext.h"
21c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung#include "rsDefines.h"
2275f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsType.h"
2375f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsUtils.h"
2475f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsovAllocation.h"
2575f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsovContext.h"
2675f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsovCore.h"
27c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung#include "spirit/instructions.h"
28c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung#include "spirit/module.h"
2975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
30ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung#include <fstream>
31c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung#include <functional>
32ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung
3375f0d3110b04346b901771f96ce15cdbe907278fYang Ninamespace android {
3475f0d3110b04346b901771f96ce15cdbe907278fYang Ninamespace renderscript {
3575f0d3110b04346b901771f96ce15cdbe907278fYang Ninamespace rsov {
3675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
3775f0d3110b04346b901771f96ce15cdbe907278fYang Ninamespace {
38c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// Layout of this struct has to be the same as the struct in generated SPIR-V
39c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// TODO: generate this file from some spec that is shared with the compiler
40c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sungstruct rsovTypeInfo {
41c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  uint32_t element_size;  // TODO: not implemented
42c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  uint32_t x_size;
43c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  uint32_t y_size;
44c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  uint32_t z_size;
45c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung};
4675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
4775f0d3110b04346b901771f96ce15cdbe907278fYang Niconst char *COMPILER_EXE_PATH = "/system/bin/bcc_rsov";
4875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
4975f0d3110b04346b901771f96ce15cdbe907278fYang Nistd::vector<const char *> setCompilerArgs(const char *bcFileName,
5075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                          const char *cacheDir) {
5175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(bcFileName && cacheDir);
5275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
5375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  std::vector<const char *> args;
5475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
5575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  args.push_back(COMPILER_EXE_PATH);
5675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  args.push_back(bcFileName);
5775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
5875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  args.push_back(nullptr);
5975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return args;
6075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
6175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
6275f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid writeBytes(const char *filename, const char *bytes, size_t size) {
6375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  std::ofstream ofs(filename, std::ios::binary);
6475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ofs.write(bytes, size);
6575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ofs.close();
6675f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
6775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
6875f0d3110b04346b901771f96ce15cdbe907278fYang Nistd::vector<uint32_t> readWords(const char *filename) {
6975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  std::ifstream ifs(filename, std::ios::binary);
7075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
7175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ifs.seekg(0, ifs.end);
7275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  int length = ifs.tellg();
7375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ifs.seekg(0, ifs.beg);
7475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
7575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(((length & 3) == 0) && "File size expected to be multiples of 4");
7675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
7775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  std::vector<uint32_t> spvWords(length / sizeof(uint32_t));
7875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
7975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ifs.read((char *)(spvWords.data()), length);
8075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
8175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ifs.close();
8275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
8375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return spvWords;
8475f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
8575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
8675f0d3110b04346b901771f96ce15cdbe907278fYang Nistd::vector<uint32_t> compileBitcode(const char *resName, const char *cacheDir,
8775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                     const char *bitcode, size_t bitcodeSize) {
8875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(bitcode && bitcodeSize);
8975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
9075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: Cache the generated code
9175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
9275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  std::string bcFileName(cacheDir);
9375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  bcFileName.append("/");
9475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  bcFileName.append(resName);
9575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  bcFileName.append(".bc");
9675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
9775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  writeBytes(bcFileName.c_str(), bitcode, bitcodeSize);
9875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
9975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  auto args = setCompilerArgs(bcFileName.c_str(), cacheDir);
10075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
10175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (!rsuExecuteCommand(COMPILER_EXE_PATH, args.size() - 1, args.data())) {
10275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ALOGE("compiler command line failed");
10375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    return std::vector<uint32_t>();
10475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
10575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
10675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ALOGV("compiler command line succeeded");
10775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
10875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  std::string spvFileName(cacheDir);
10975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  spvFileName.append("/");
11075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  spvFileName.append(resName);
11175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  spvFileName.append(".spv");
11275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
11375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return readWords(spvFileName.c_str());
11475f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
11575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
11675f0d3110b04346b901771f96ce15cdbe907278fYang Ni}  // anonymous namespace
11775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
11830dfb1368d0a3440cfedc882c27cc236d799f77cYang Nibool RSoVScript::isScriptCpuBacked(const Script *s) {
11930dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  return s->mHal.info.mVersionMinor == CPU_SCRIPT_MAGIC_NUMBER;
12030dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni}
12130dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni
12230dfb1368d0a3440cfedc882c27cc236d799f77cYang Nivoid RSoVScript::initScriptOnCpu(Script *s, RsdCpuReference::CpuScript *cs) {
12330dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  s->mHal.drv = cs;
12430dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  s->mHal.info.mVersionMajor = 0;  // Unused. Don't care.
12530dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  s->mHal.info.mVersionMinor = CPU_SCRIPT_MAGIC_NUMBER;
12630dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni}
12730dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni
12830dfb1368d0a3440cfedc882c27cc236d799f77cYang Nivoid RSoVScript::initScriptOnRSoV(Script *s, RSoVScript *rsovScript) {
12930dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  s->mHal.drv = rsovScript;
13030dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  s->mHal.info.mVersionMajor = 0;  // Unused. Don't care.
13130dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  s->mHal.info.mVersionMinor = 0;
13230dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni}
13330dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni
134ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) SungRSoVScript::RSoVScript(RSoVContext *context, std::vector<uint32_t> &&spvWords,
135c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung                       bcinfo::MetadataExtractor *ME,
136c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung                       std::map<std::string, int> *GA2ID)
13775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    : mRSoV(context),
13875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      mDevice(context->getDevice()),
139ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung      mSPIRVWords(std::move(spvWords)),
140c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      mME(ME),
141c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      mGlobalAllocationMetadata(nullptr),
142c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      mGAMapping(GA2ID) {}
14375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
14475f0d3110b04346b901771f96ce15cdbe907278fYang NiRSoVScript::~RSoVScript() {
14575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  delete mCpuScript;
146ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung  delete mME;
14775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
14875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
14975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::populateScript(Script *) {
15075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
15175f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
15275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
15375f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::invokeFunction(uint32_t slot, const void *params,
15475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                size_t paramLength) {
15530dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  getCpuScript()->invokeFunction(slot, params, paramLength);
15675f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
15775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
15830dfb1368d0a3440cfedc882c27cc236d799f77cYang Niint RSoVScript::invokeRoot() { return getCpuScript()->invokeRoot(); }
15975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
16075f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::invokeForEach(uint32_t slot, const Allocation **ains,
16175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                               uint32_t inLen, Allocation *aout,
16275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                               const void *usr, uint32_t usrLen,
16375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                               const RsScriptCall *sc) {
16475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: Handle kernel without input Allocation
165a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  rsAssert(ains);
166a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  std::vector<RSoVAllocation *> inputAllocations(inLen);
167a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  for (uint32_t i = 0; i < inLen; ++i) {
168a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung    inputAllocations[i] = static_cast<RSoVAllocation *>(ains[i]->mHal.drv);
169a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  }
17075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RSoVAllocation *outputAllocation =
17175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      static_cast<RSoVAllocation *>(aout->mHal.drv);
172a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  runForEach(slot, inLen, inputAllocations, outputAllocation);
17375f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
17475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
17575f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::invokeReduce(uint32_t slot, const Allocation **ains,
17675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                              uint32_t inLen, Allocation *aout,
17775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                              const RsScriptCall *sc) {
17830dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  getCpuScript()->invokeReduce(slot, ains, inLen, aout, sc);
17975f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
18075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
18175f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::invokeInit() {
18275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
18375f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
18475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
18575f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::invokeFreeChildren() {
18675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
18775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
18875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
18975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::setGlobalVar(uint32_t slot, const void *data,
19075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                              size_t dataLength) {
19175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
192c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  ALOGV("%s missing.", __FUNCTION__);
19375f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
19475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
19575f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::getGlobalVar(uint32_t slot, void *data, size_t dataLength) {
19675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
197c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  ALOGV("%s missing.", __FUNCTION__);
19875f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
19975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
20075f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::setGlobalVarWithElemDims(uint32_t slot, const void *data,
20175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                          size_t dataLength, const Element *e,
20275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                          const uint32_t *dims,
20375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                          size_t dimLength) {
20475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
20575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
20675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
20775f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::setGlobalBind(uint32_t slot, Allocation *data) {
208c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  ALOGV("%s succeeded.", __FUNCTION__);
20975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
21075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
21175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
21275f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::setGlobalObj(uint32_t slot, ObjectBase *obj) {
213c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  mCpuScript->setGlobalObj(slot, obj);
214c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  ALOGV("%s succeeded.", __FUNCTION__);
21575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
21675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
21775f0d3110b04346b901771f96ce15cdbe907278fYang NiAllocation *RSoVScript::getAllocationForPointer(const void *ptr) const {
21875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
21975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return nullptr;
22075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
22175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
22275f0d3110b04346b901771f96ce15cdbe907278fYang Niint RSoVScript::getGlobalEntries() const {
22375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
22475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return 0;
22575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
22675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
22775f0d3110b04346b901771f96ce15cdbe907278fYang Niconst char *RSoVScript::getGlobalName(int i) const {
22875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
22975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return nullptr;
23075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
23175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
23275f0d3110b04346b901771f96ce15cdbe907278fYang Niconst void *RSoVScript::getGlobalAddress(int i) const {
23375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
23475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return nullptr;
23575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
23675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
23775f0d3110b04346b901771f96ce15cdbe907278fYang Nisize_t RSoVScript::getGlobalSize(int i) const {
23875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
23975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return 0;
24075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
24175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
24275f0d3110b04346b901771f96ce15cdbe907278fYang Niuint32_t RSoVScript::getGlobalProperties(int i) const {
24375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
24475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return 0;
24575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
24675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
247a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sungvoid RSoVScript::InitDescriptorAndPipelineLayouts(uint32_t inLen) {
248a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  // TODO: global variables
249a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  // TODO: kernels with zero output allocations
250a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  std::vector<VkDescriptorSetLayoutBinding> layout_bindings{
25175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      {
252c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          // for the global allocation metadata
253c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .binding = 0,
254c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
255c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .descriptorCount = 1,
256c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
257c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .pImmutableSamplers = nullptr,
258c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      },
259c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      {
260a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung          // for the output allocation
26175f0d3110b04346b901771f96ce15cdbe907278fYang Ni          .binding = 1,
262f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
26375f0d3110b04346b901771f96ce15cdbe907278fYang Ni          .descriptorCount = 1,
26475f0d3110b04346b901771f96ce15cdbe907278fYang Ni          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
26575f0d3110b04346b901771f96ce15cdbe907278fYang Ni          .pImmutableSamplers = nullptr,
26675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      },
26775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
26875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
269a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  // initialize descriptors for input allocations
270a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  for (uint32_t i = 0; i < inLen; ++i) {
271a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung    layout_bindings.push_back({
272a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .binding = i + 2,  // input allocations start from bining #2
273a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
274a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .descriptorCount = 1,
275a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
276a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .pImmutableSamplers = nullptr,
277a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung    });
278a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  }
279a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung
28075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkDescriptorSetLayoutCreateInfo descriptor_layout = {
28175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
28275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pNext = nullptr,
28375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .flags = 0,
284c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      .bindingCount = inLen + 2,
285a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung      .pBindings = layout_bindings.data(),
28675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
28775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
28875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkResult res;
28975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
29075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  mDescLayout.resize(NUM_DESCRIPTOR_SETS);
29175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  res = vkCreateDescriptorSetLayout(mDevice, &descriptor_layout, NULL,
29275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                    mDescLayout.data());
29375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (res != VK_SUCCESS) {
29475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    __android_log_print(ANDROID_LOG_ERROR, "ComputeTest",
29575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        "vkCreateDescriptorSetLayout() returns %d", res);
29675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
29775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(res == VK_SUCCESS);
298a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung
29975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  /* Now use the descriptor layout to create a pipeline layout */
30075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {
30175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
30275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pNext = nullptr,
30375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pushConstantRangeCount = 0,
30475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pPushConstantRanges = nullptr,
30575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .setLayoutCount = NUM_DESCRIPTOR_SETS,
30675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pSetLayouts = mDescLayout.data(),
30775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
30875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
30975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  res = vkCreatePipelineLayout(mDevice, &pPipelineLayoutCreateInfo, NULL,
31075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                               &mPipelineLayout);
31175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(res == VK_SUCCESS);
31275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
31375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ALOGV("%s succeeded.", __FUNCTION__);
31475f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
31575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
316ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sungvoid RSoVScript::InitShader(uint32_t slot) {
31775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkResult res;
31875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
31975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  mShaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
32075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  mShaderStage.pNext = nullptr;
32175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  mShaderStage.pSpecializationInfo = nullptr;
32275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  mShaderStage.flags = 0;
32375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  mShaderStage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
324ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung  const char **RSKernelNames = mME->getExportForEachNameList();
325ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung  size_t RSKernelNum = mME->getExportForEachSignatureCount();
326ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung  rsAssert(slot < RSKernelNum);
327ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung  rsAssert(RSKernelNames);
328ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung  rsAssert(RSKernelNames[slot]);
329ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung  ALOGV("slot = %d kernel name = %s", slot, RSKernelNames[slot]);
330bf22a8ab4f46a98ee37f95fc0402744132cc3ed2Yang Ni  std::string entryName("entry_");
331bf22a8ab4f46a98ee37f95fc0402744132cc3ed2Yang Ni  entryName.append(RSKernelNames[slot]);
332bf22a8ab4f46a98ee37f95fc0402744132cc3ed2Yang Ni  mShaderStage.pName = strndup(entryName.c_str(), entryName.size());
33375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
33475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkShaderModuleCreateInfo moduleCreateInfo = {
33575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
33675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pNext = nullptr,
33775f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .flags = 0,
33875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .codeSize = mSPIRVWords.size() * sizeof(unsigned int),
33975f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pCode = mSPIRVWords.data(),
34075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
34175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  res = vkCreateShaderModule(mDevice, &moduleCreateInfo, NULL,
34275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                             &mShaderStage.module);
34375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(res == VK_SUCCESS);
34475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
34575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ALOGV("%s succeeded.", __FUNCTION__);
34675f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
34775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
348bf22a8ab4f46a98ee37f95fc0402744132cc3ed2Yang Nivoid RSoVScript::InitDescriptorPool(uint32_t inLen) {
34975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  /* DEPENDS on InitDescriptorAndPipelineLayouts() */
35075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
35175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkResult res;
35275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkDescriptorPoolSize type_count[] = {
35375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      {
354c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
355c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .descriptorCount = 2 + inLen,
35675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      },
35775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
35875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
35975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkDescriptorPoolCreateInfo descriptor_pool = {
36075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
36175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pNext = nullptr,
36275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .maxSets = 1,
36375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .poolSizeCount = NELEM(type_count),
36475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pPoolSizes = type_count,
36575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
36675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
36775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  res = vkCreateDescriptorPool(mDevice, &descriptor_pool, NULL, &mDescPool);
36875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(res == VK_SUCCESS);
36975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
37075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ALOGV("%s succeeded.", __FUNCTION__);
37175f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
37275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
373c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// Iterate through a list of global allocations that are used inside the module
374c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// and marshal their type information to a dedicated Vulkan Buffer
375c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sungvoid RSoVScript::MarshalTypeInfo(void) {
376c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  // Marshal global allocation metadata to the device
377c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  auto *cs = getCpuScript();
378c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  int nr_globals = mGAMapping->size();
379c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  if (mGlobalAllocationMetadata == nullptr) {
380c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    mGlobalAllocationMetadata.reset(
381c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung        new RSoVBuffer(mRSoV, sizeof(struct rsovTypeInfo) * nr_globals));
382c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  }
383c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  struct rsovTypeInfo *mappedMetadata =
384c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      (struct rsovTypeInfo *)mGlobalAllocationMetadata->getHostPtr();
385c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  for (int i = 0; i < nr_globals; ++i) {
386c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    if (getGlobalRsType(cs->getGlobalProperties(i)) ==
387c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung        RsDataType::RS_TYPE_ALLOCATION) {
388c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      ALOGV("global variable %d is an allocation!", i);
389c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      const void *host_buf;
390c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      cs->getGlobalVar(i, (void *)&host_buf, sizeof(host_buf));
391c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      if (!host_buf) continue;
392c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      const android::renderscript::Allocation *GA =
393c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          static_cast<const android::renderscript::Allocation *>(host_buf);
394c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      const android::renderscript::Type *T = GA->getType();
395c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      rsAssert(T);
396c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
397c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      auto global_it = mGAMapping->find(cs->getGlobalName(i));
398c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      rsAssert(global_it != (*mGAMapping).end());
399c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      int id = global_it->second;
400c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      ALOGV("global allocation %s is mapped to ID %d", cs->getGlobalName(i),
401c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung            id);
402c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      // TODO: marshal other properties
403c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      mappedMetadata[id].x_size = T->getDimX();
404c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      mappedMetadata[id].y_size = T->getDimY();
405c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      mappedMetadata[id].z_size = T->getDimZ();
406c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    }
407c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  }
408c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung}
409c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
410a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sungvoid RSoVScript::InitDescriptorSet(
411a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung    const std::vector<RSoVAllocation *> &inputAllocations,
412a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung    RSoVAllocation *outputAllocation) {
41375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkResult res;
41475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
41575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkDescriptorSetAllocateInfo alloc_info = {
41675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
41775f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pNext = NULL,
41875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .descriptorPool = mDescPool,
41975f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .descriptorSetCount = NUM_DESCRIPTOR_SETS,
42075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pSetLayouts = mDescLayout.data(),
42175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
42275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
42375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  mDescSet.resize(NUM_DESCRIPTOR_SETS);
42475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  res = vkAllocateDescriptorSets(mDevice, &alloc_info, mDescSet.data());
425bf22a8ab4f46a98ee37f95fc0402744132cc3ed2Yang Ni  ALOGD("vkAllocateDescriptorSets() result = %d", res);
42675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(res == VK_SUCCESS);
42775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
428a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  // TODO: support for set up the binding(s) of global variables
429a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  uint32_t nBindings = inputAllocations.size() + 1;  // input + output.
430a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  std::vector<VkWriteDescriptorSet> writes{
431c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      // Metadata for global allocations
432c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      {
433c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
434c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .dstSet = mDescSet[0],
435c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .dstBinding = 0,
436c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .dstArrayElement = 0,
437c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .descriptorCount = 1,
438c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
439c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          .pBufferInfo = mGlobalAllocationMetadata->getBufferInfo(),
440c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      },
441c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
44275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      {
44375f0d3110b04346b901771f96ce15cdbe907278fYang Ni          .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
44475f0d3110b04346b901771f96ce15cdbe907278fYang Ni          .dstSet = mDescSet[0],
44575f0d3110b04346b901771f96ce15cdbe907278fYang Ni          .dstBinding = 1,
44675f0d3110b04346b901771f96ce15cdbe907278fYang Ni          .dstArrayElement = 0,
44775f0d3110b04346b901771f96ce15cdbe907278fYang Ni          .descriptorCount = 1,
448f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
449a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung          .pBufferInfo = outputAllocation->getBuffer()->getBufferInfo(),
45075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      },
45175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
452a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  for (uint32_t i = 0; i < inputAllocations.size(); ++i) {
453a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung    writes.push_back({
454a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
455a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .dstSet = mDescSet[0],
456a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .dstBinding = 2 + i,  // input allocations start from binding #2
457a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .dstArrayElement = 0,
458a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .descriptorCount = 1,
459a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
460a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung        .pBufferInfo = inputAllocations[i]->getBuffer()->getBufferInfo(),
461a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung    });
462a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  }
46375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
464a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  vkUpdateDescriptorSets(mDevice, writes.size(), writes.data(), 0, NULL);
46575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
46675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ALOGV("%s succeeded.", __FUNCTION__);
46775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
46875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
46975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid RSoVScript::InitPipeline() {
47075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // DEPENDS on mShaderStage, i.e., InitShader()
47175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
47275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkResult res;
47375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
47475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkComputePipelineCreateInfo pipeline_info = {
47575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
47675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pNext = nullptr,
47775f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .layout = mPipelineLayout,
47875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .basePipelineHandle = VK_NULL_HANDLE,
47975f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .basePipelineIndex = 0,
48075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .flags = 0,
48175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .stage = mShaderStage,
48275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
48375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  res = vkCreateComputePipelines(mDevice, VK_NULL_HANDLE, 1, &pipeline_info,
48475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                 NULL, &mComputePipeline);
48575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(res == VK_SUCCESS);
48675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
48775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ALOGV("%s succeeded.", __FUNCTION__);
48875f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
48975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
490a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sungvoid RSoVScript::runForEach(
491a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung    uint32_t slot, uint32_t inLen,
492a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung    const std::vector<RSoVAllocation *> &inputAllocations,
493a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung    RSoVAllocation *outputAllocation) {
49475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkResult res;
49575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
496a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  InitDescriptorAndPipelineLayouts(inLen);
497ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung  InitShader(slot);
498bf22a8ab4f46a98ee37f95fc0402744132cc3ed2Yang Ni  InitDescriptorPool(inLen);
499c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  MarshalTypeInfo();
500a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  InitDescriptorSet(inputAllocations, outputAllocation);
50175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // InitPipelineCache();
50275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  InitPipeline();
50375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
50475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkCommandBuffer cmd;
50575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
50675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkCommandBufferAllocateInfo cmd_info = {
50775f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
50875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pNext = nullptr,
50975f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .commandPool = mRSoV->getCmdPool(),
51075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
51175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .commandBufferCount = 1,
51275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
51375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
51475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  res = vkAllocateCommandBuffers(mDevice, &cmd_info, &cmd);
51575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(res == VK_SUCCESS);
51675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
51775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkCommandBufferBeginInfo cmd_buf_info = {
51875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
51975f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pNext = nullptr,
52075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .flags = 0,
52175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pInheritanceInfo = nullptr,
52275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
52375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
52475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  res = vkBeginCommandBuffer(cmd, &cmd_buf_info);
52575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(res == VK_SUCCESS);
52675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
52775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, mComputePipeline);
52875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
52975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, mPipelineLayout,
53075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          0, mDescSet.size(), mDescSet.data(), 0, nullptr);
531a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  // Assuming all input allocations are of the same dimensionality
532a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  const uint32_t width = inputAllocations[0]->getWidth();
533a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  const uint32_t height = rsMax(inputAllocations[0]->getHeight(), 1U);
534a075ad49dd56f25efebb5402bcc263766421b0c8I-Jui (Ray) Sung  const uint32_t depth = rsMax(inputAllocations[0]->getDepth(), 1U);
53575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkCmdDispatch(cmd, width, height, depth);
53675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
53775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  res = vkEndCommandBuffer(cmd);
53875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  assert(res == VK_SUCCESS);
53975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
54075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkSubmitInfo submit_info = {
54175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
54275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .commandBufferCount = 1,
54375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pCommandBuffers = &cmd,
54475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
54575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
54675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkFence fence;
54775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
54875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkFenceCreateInfo fenceInfo = {
54975f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
55075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .pNext = nullptr,
55175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      .flags = 0,
55275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  };
55375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
55475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkCreateFence(mDevice, &fenceInfo, NULL, &fence);
55575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
55675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkQueueSubmit(mRSoV->getQueue(), 1, &submit_info, fence);
55775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
55875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // Make sure command buffer is finished
55975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  do {
56075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    res = vkWaitForFences(mDevice, 1, &fence, VK_TRUE, 100000);
56175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  } while (res == VK_TIMEOUT);
56275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
56375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsAssert(res == VK_SUCCESS);
56475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
56575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkDestroyFence(mDevice, fence, NULL);
56675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
56775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: shall we reuse command buffers?
56875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  VkCommandBuffer cmd_bufs[] = {cmd};
56975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkFreeCommandBuffers(mDevice, mRSoV->getCmdPool(), 1, cmd_bufs);
57075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
57175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkDestroyPipeline(mDevice, mComputePipeline, nullptr);
57275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  for (int i = 0; i < NUM_DESCRIPTOR_SETS; i++)
57375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    vkDestroyDescriptorSetLayout(mDevice, mDescLayout[i], nullptr);
57475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkDestroyPipelineLayout(mDevice, mPipelineLayout, nullptr);
575c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  vkFreeDescriptorSets(mDevice, mDescPool, NUM_DESCRIPTOR_SETS,
576c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung                       mDescSet.data());
57775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkDestroyDescriptorPool(mDevice, mDescPool, nullptr);
578c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  free((void *)mShaderStage.pName);
57975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkDestroyShaderModule(mDevice, mShaderStage.module, nullptr);
58075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
58175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ALOGV("%s succeeded.", __FUNCTION__);
58275f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
58375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
58475f0d3110b04346b901771f96ce15cdbe907278fYang Ni}  // namespace rsov
58575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}  // namespace renderscript
58675f0d3110b04346b901771f96ce15cdbe907278fYang Ni}  // namespace android
58775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
58875f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::Allocation;
58975f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::Context;
59075f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::Element;
59175f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::ObjectBase;
59275f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::RsdCpuReference;
59375f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::Script;
59475f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::ScriptC;
59575f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::rs_script;
59675f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::rsov::RSoVContext;
59775f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::rsov::RSoVScript;
59875f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::rsov::compileBitcode;
59975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
600c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sungnamespace {
601c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// A class to parse global allocation metadata; essentially a subset of JSON
602c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// it would look like {"__RSoV_GA": {"g":42}}
603c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// The result is stored in a refence to a map<string, int>
604c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sungclass ParseMD {
605c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung public:
606c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  ParseMD(std::string s, std::map<std::string, int> &map)
607c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      : mString(s), mMapping(map) {}
608c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
609c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  bool parse(void) {
610c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    // remove outermose two pairs of braces
611c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    mString = removeBraces(mString);
612c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    mString = removeBraces(mString);
613c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    // Now we are supposed to have a comma-separated list that looks like:
614c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    // "foo":42, "bar":56
615c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    split<','>(mString, [&](auto s) {
616c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      split<':'>(s, nullptr, [&](auto pair) {
617c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung        rsAssert(pair.size() == 2);
618c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung        std::string ga_name = removeQuotes(pair[0]);
619c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung        int id = atoi(pair[1].c_str());
620c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung        ALOGV("ParseMD: global allocation %s has ID %d", ga_name.c_str(), id);
621c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung        mMapping[ga_name] = id;
622c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      });
623c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    });
624c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    return true;
625c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  }
626c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
627c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung private:
628c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  template <char L, char R>
629c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  static std::string removeMatching(const std::string &s) {
630c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    auto leftCBrace = s.find(L);
631c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    rsAssert(leftCBrace != std::string::npos);
632c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    leftCBrace++;
633c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    return s.substr(leftCBrace, s.rfind(R) - leftCBrace);
634c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  }
635c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
636c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  static std::string removeBraces(const std::string &s) {
637c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    return removeMatching<'{', '}'>(s);
638c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  }
639c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
640c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  static std::string removeQuotes(const std::string &s) {
641c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    return removeMatching<'"', '"'>(s);
642c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  }
643c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
644c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  // Splitting a string, and call "each" and/or "all" with individal elements
645c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  // and a vector of all tokenized elements
646c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  template <char D>
647c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  static void split(const std::string &s,
648c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung                    std::function<void(const std::string &)> each,
649c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung                    std::function<void(const std::vector<const std::string> &)>
650c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung                        all = nullptr) {
651c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    std::vector<const std::string> result;
652c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    for (std::string::size_type pos = 0; pos < s.size(); pos++) {
653c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      std::string::size_type begin = pos;
654c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
655c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      while (s[pos] != D && pos <= s.size()) pos++;
656c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      std::string found = s.substr(begin, pos - begin);
657c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      if (each) each(found);
658c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung      if (all) result.push_back(found);
659c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    }
660c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    if (all) all(result);
661c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  }
662c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
663c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  std::string mString;
664c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  std::map<std::string, int> &mMapping;
665c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung};
666c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
667c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung}  // namespace
668c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
669c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sungclass ExtractRSoVMD : public android::spirit::DoNothingVisitor {
670c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung public:
671c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  ExtractRSoVMD() : mGAMapping(new std::map<std::string, int>) {}
672c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
673c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  void visit(android::spirit::StringInst *s) {
674c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    ALOGV("ExtractRSoVMD: string = %s", s->mOperand1.c_str());
675c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    ParseMD p(s->mOperand1, *mGAMapping);
676c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    p.parse();
677c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  }
678c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
679c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  std::map<std::string, int> *takeMapping(void) { return mGAMapping.release(); }
680c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
681c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung private:
682c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  std::unique_ptr<std::map<std::string, int> > mGAMapping;
683c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung};
684c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung
68575f0d3110b04346b901771f96ce15cdbe907278fYang Nibool rsovScriptInit(const Context *rsc, ScriptC *script, char const *resName,
68675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    char const *cacheDir, uint8_t const *bitcode,
68775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    size_t bitcodeSize, uint32_t flags) {
68875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RSoVHal *hal = static_cast<RSoVHal *>(rsc->mHal.drv);
68975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
69075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  std::unique_ptr<RsdCpuReference::CpuScript> cs(hal->mCpuRef->createScript(
69175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      script, resName, cacheDir, bitcode, bitcodeSize, flags));
69275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (cs == nullptr) {
69330dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni    ALOGE("Failed creating a CPU script %p for %s (%p)", cs.get(), resName,
69430dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni          script);
69575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    return false;
69675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
69775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->populateScript(script);
69875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
69930dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  std::unique_ptr<bcinfo::MetadataExtractor> bitcodeMetadata(
70030dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      new bcinfo::MetadataExtractor((const char *)bitcode, bitcodeSize));
70130dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  if (!bitcodeMetadata || !bitcodeMetadata->extract()) {
70230dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni    ALOGE("Could not extract metadata from bitcode from %s", resName);
703ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung    return false;
704ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung  }
705ffa85366645c163dd529644ba5b8950c4c588d20I-Jui (Ray) Sung
70630dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  auto spvWords =
70730dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      compileBitcode(resName, cacheDir, (const char *)bitcode, bitcodeSize);
70830dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  if (!spvWords.empty()) {
709c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    // Extract compiler metadata on allocation->binding mapping
710c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    android::spirit::Module *module =
711c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung        android::spirit::Deserialize<android::spirit::Module>(spvWords);
712c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    rsAssert(module);
713c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    ExtractRSoVMD ga_md;
714c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    module->accept(&ga_md);
715c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    RSoVScript *rsovScript =
716c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung        new RSoVScript(hal->mRSoV, std::move(spvWords),
717c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung                       bitcodeMetadata.release(), ga_md.takeMapping());
71830dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni    if (rsovScript) {
71930dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      rsovScript->setCpuScript(cs.release());
72030dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      RSoVScript::initScriptOnRSoV(script, rsovScript);
72130dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      return true;
72230dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni    }
72375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
72475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
72530dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  ALOGD("Failed creating an RSoV script for %s", resName);
72630dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  // Fall back to CPU driver instead
72730dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  RSoVScript::initScriptOnCpu(script, cs.release());
72875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
72975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return true;
73075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
73175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
73275f0d3110b04346b901771f96ce15cdbe907278fYang Nibool rsovInitIntrinsic(const Context *rsc, Script *s, RsScriptIntrinsicID iid,
73375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                       Element *e) {
73475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RSoVHal *dc = (RSoVHal *)rsc->mHal.drv;
73575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = dc->mCpuRef->createIntrinsic(s, iid, e);
73675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (cs == nullptr) {
73775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    return false;
73875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
73975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  s->mHal.drv = cs;
74075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->populateScript(s);
74175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return true;
74275f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
74375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
74475f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptInvokeForEach(const Context *rsc, Script *s, uint32_t slot,
74575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                             const Allocation *ain, Allocation *aout,
74675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                             const void *usr, size_t usrLen,
74775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                             const RsScriptCall *sc) {
74875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (ain == nullptr) {
74975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    rsovScriptInvokeForEachMulti(rsc, s, slot, nullptr, 0, aout, usr, usrLen,
75075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                 sc);
75175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  } else {
75275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const Allocation *ains[1] = {ain};
75375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
75475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    rsovScriptInvokeForEachMulti(rsc, s, slot, ains, 1, aout, usr, usrLen, sc);
75575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
75675f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
75775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
75875f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptInvokeForEachMulti(const Context *rsc, Script *s, uint32_t slot,
75975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                  const Allocation **ains, size_t inLen,
76075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                  Allocation *aout, const void *usr,
76175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                  size_t usrLen, const RsScriptCall *sc) {
76275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
76375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->invokeForEach(slot, ains, inLen, aout, usr, usrLen, sc);
76475f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
76575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
76675f0d3110b04346b901771f96ce15cdbe907278fYang Niint rsovScriptInvokeRoot(const Context *dc, Script *s) {
76775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
76875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return cs->invokeRoot();
76975f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
77075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
77175f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptInvokeInit(const Context *dc, Script *s) {
77275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
77375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->invokeInit();
77475f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
77575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
77675f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptInvokeFreeChildren(const Context *dc, Script *s) {
77775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
77875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->invokeFreeChildren();
77975f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
78075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
78175f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptInvokeFunction(const Context *dc, Script *s, uint32_t slot,
78275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                              const void *params, size_t paramLength) {
78375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
78475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->invokeFunction(slot, params, paramLength);
78575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
78675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
78775f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptInvokeReduce(const Context *dc, Script *s, uint32_t slot,
78875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            const Allocation **ains, size_t inLen,
78975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            Allocation *aout, const RsScriptCall *sc) {
79075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
79175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->invokeReduce(slot, ains, inLen, aout, sc);
79275f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
79375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
79475f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptSetGlobalVar(const Context *dc, const Script *s, uint32_t slot,
79575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            void *data, size_t dataLength) {
79675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
79775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->setGlobalVar(slot, data, dataLength);
79875f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
79975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
80075f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptGetGlobalVar(const Context *dc, const Script *s, uint32_t slot,
80175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            void *data, size_t dataLength) {
80275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
80375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->getGlobalVar(slot, data, dataLength);
80475f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
80575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
80675f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptSetGlobalVarWithElemDims(
80775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const Context *dc, const Script *s, uint32_t slot, void *data,
80875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    size_t dataLength, const android::renderscript::Element *elem,
80975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const uint32_t *dims, size_t dimLength) {
81075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
81175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->setGlobalVarWithElemDims(slot, data, dataLength, elem, dims, dimLength);
81275f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
81375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
81475f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptSetGlobalBind(const Context *dc, const Script *s, uint32_t slot,
81575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                             Allocation *data) {
81675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
81775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->setGlobalBind(slot, data);
81875f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
81975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
82075f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptSetGlobalObj(const Context *dc, const Script *s, uint32_t slot,
82175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            ObjectBase *data) {
82275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
82375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  cs->setGlobalObj(slot, data);
82475f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
82575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
82675f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptDestroy(const Context *dc, Script *s) {
82775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)s->mHal.drv;
82875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  delete cs;
82975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  s->mHal.drv = nullptr;
83075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
83175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
83275f0d3110b04346b901771f96ce15cdbe907278fYang NiAllocation *rsovScriptGetAllocationForPointer(
83375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const android::renderscript::Context *dc,
83475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const android::renderscript::Script *sc, const void *ptr) {
83575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)sc->mHal.drv;
83675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return cs->getAllocationForPointer(ptr);
83775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
83875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
83975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovScriptUpdateCachedObject(const Context *rsc, const Script *script,
84075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                  rs_script *obj) {
84175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  obj->p = script;
84275f0d3110b04346b901771f96ce15cdbe907278fYang Ni#ifdef __LP64__
843700e68883c4324c15b380ff6724249f39d4f498cI-Jui (Ray) Sung  obj->unused1 = nullptr;
844700e68883c4324c15b380ff6724249f39d4f498cI-Jui (Ray) Sung  obj->unused2 = nullptr;
845700e68883c4324c15b380ff6724249f39d4f498cI-Jui (Ray) Sung  obj->unused3 = nullptr;
84675f0d3110b04346b901771f96ce15cdbe907278fYang Ni#endif
84775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
848