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