1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef RSOV_SCRIPT_H
18 #define RSOV_SCRIPT_H
19 
20 #include <vulkan/vulkan.h>
21 
22 #include <map>
23 #include <vector>
24 
25 #include "bcinfo/MetadataExtractor.h"
26 #include "rsDefines.h"
27 #include "rs_hal.h"
28 #include "rsd_cpu.h"
29 
30 namespace android {
31 namespace renderscript {
32 
33 class Allocation;
34 class Context;
35 class Element;
36 class Script;
37 class ScriptC;
38 
39 namespace rsov {
40 
41 class RSoVAllocation;
42 class RSoVBuffer;
43 class RSoVContext;
44 
45 // TODO: CpuScript is a bad name for the base class. Fix with a refactoring.
46 class RSoVScript : RsdCpuReference::CpuScript {
47  public:
48   RSoVScript(RSoVContext *context, std::vector<uint32_t> &&spvWords,
49              bcinfo::MetadataExtractor *ME,
50              std::map<std::string, int> *GAMapping);
51   RSoVScript(RSoVContext *context, const std::vector<uint32_t> &spvWords,
52              bcinfo::MetadataExtractor *ME,
53              std::map<std::string, int> *GAMapping) = delete;
54 
55   virtual ~RSoVScript();
56 
57   static bool isScriptCpuBacked(const Script *s);
58   static void initScriptOnCpu(Script *s, RsdCpuReference::CpuScript *cs);
59   static void initScriptOnRSoV(Script *s, RSoVScript *rsovScript);
60 
61   void populateScript(Script *) override;
62   void invokeFunction(uint32_t slot, const void *params,
63                       size_t paramLength) override;
64   int invokeRoot() override;
65 
66   void invokeForEach(uint32_t slot, const Allocation **ains, uint32_t inLen,
67                      Allocation *aout, const void *usr, uint32_t usrLen,
68                      const RsScriptCall *sc) override;
69 
70   void invokeReduce(uint32_t slot, const Allocation **ains, uint32_t inLen,
71                     Allocation *aout, const RsScriptCall *sc) override;
72 
73   void invokeInit() override;
74   void invokeFreeChildren() override;
75 
76   void setGlobalVar(uint32_t slot, const void *data,
77                     size_t dataLength) override;
78   void getGlobalVar(uint32_t slot, void *data, size_t dataLength) override;
79   void setGlobalVarWithElemDims(uint32_t slot, const void *data,
80                                 size_t dataLength, const Element *e,
81                                 const uint32_t *dims,
82                                 size_t dimLength) override;
83 
84   void setGlobalBind(uint32_t slot, Allocation *data) override;
85   void setGlobalObj(uint32_t slot, ObjectBase *obj) override;
86 
87   Allocation *getAllocationForPointer(const void *ptr) const override;
88 
89   // Returns number of global variables in this Script (may be 0 if
90   // compiler is not configured to emit this information).
91   int getGlobalEntries() const override;
92   // Returns the name of the global variable at index i.
93   const char *getGlobalName(int i) const override;
94   // Returns the CPU address of the global variable at index i.
95   const void *getGlobalAddress(int i) const override;
96   // Returns the size (in bytes) of the global variable at index i.
97   size_t getGlobalSize(int i) const override;
98   // Returns the properties of the global variable at index i.
99   uint32_t getGlobalProperties(int i) const override;
100 
setCpuScript(RsdCpuReference::CpuScript * cs)101   void setCpuScript(RsdCpuReference::CpuScript *cs) { mCpuScript = cs; }
102 
getCpuScript()103   RsdCpuReference::CpuScript *getCpuScript() const { return mCpuScript; }
104 
105  private:
106   void InitDescriptorAndPipelineLayouts(uint32_t inLen);
107   void InitShader(uint32_t slot);
108   void InitDescriptorPool(uint32_t inLen);
109   void InitDescriptorSet(const std::vector<RSoVAllocation *> &inputAllocations,
110                          RSoVAllocation *outputAllocation);
111   void InitPipelineCache();
112   void InitPipeline();
113   void MarshalTypeInfo();
114   void runForEach(uint32_t slot, uint32_t inLen,
115                   const std::vector<RSoVAllocation *> &input,
116                   RSoVAllocation *output);
117 
118   // Gets the offset for the global variable with the given slot number in
119   // the global buffer
GetExportedVarOffset(uint32_t slot)120   uint32_t GetExportedVarOffset(uint32_t slot) const {
121     // High-level Java or C++ API has verified that slot is in range
122     return mExportedVarOffsets[slot];
123   }
124 
125   static constexpr int CPU_SCRIPT_MAGIC_NUMBER = 0x60000;
126 
127   RSoVContext *mRSoV;
128   VkDevice mDevice;
129   std::vector<uint32_t> mSPIRVWords;
130   RsdCpuReference::CpuScript *mCpuScript;
131 
132   static constexpr int NUM_DESCRIPTOR_SETS = 1;
133   std::vector<VkDescriptorSetLayout> mDescLayout;
134   VkPipelineLayout mPipelineLayout;
135   VkPipeline mComputePipeline;
136   // TODO: Multiple stages for multiple kernels
137   VkPipelineShaderStageCreateInfo mShaderStage;
138   VkDescriptorPool mDescPool;
139   std::vector<VkDescriptorSet> mDescSet;
140   // For kernel names
141   const bcinfo::MetadataExtractor *mME;
142   std::unique_ptr<RSoVBuffer> mGlobals;
143   std::vector<uint32_t> mExportedVarOffsets;
144   // Metadata of global allocations
145   std::unique_ptr<RSoVBuffer> mGlobalAllocationMetadata;
146   // Mapping of global allocation to rsov-assigned ID
147   std::unique_ptr<std::map<std::string, int> > mGAMapping;
148 };
149 
150 }  // namespace rsov
151 }  // namespace renderscript
152 }  // namespace android
153 
154 extern bool rsovScriptInit(const android::renderscript::Context *rsc,
155                            android::renderscript::ScriptC *script,
156                            char const *resName, char const *cacheDir,
157                            uint8_t const *bitcode, size_t bitcodeSize,
158                            uint32_t flags);
159 
160 extern bool rsovInitIntrinsic(const android::renderscript::Context *rsc,
161                               android::renderscript::Script *s,
162                               RsScriptIntrinsicID iid,
163                               android::renderscript::Element *e);
164 
165 extern void rsovScriptInvokeFunction(const android::renderscript::Context *dc,
166                                      android::renderscript::Script *script,
167                                      uint32_t slot, const void *params,
168                                      size_t paramLength);
169 
170 extern void rsovScriptInvokeForEach(
171     const android::renderscript::Context *rsc, android::renderscript::Script *s,
172     uint32_t slot, const android::renderscript::Allocation *ain,
173     android::renderscript::Allocation *aout, const void *usr, size_t usrLen,
174     const RsScriptCall *sc);
175 
176 extern void rsovScriptInvokeReduce(
177     const android::renderscript::Context *rsc, android::renderscript::Script *s,
178     uint32_t slot, const android::renderscript::Allocation **ains, size_t inLen,
179     android::renderscript::Allocation *aout, const RsScriptCall *sc);
180 
181 extern void rsovScriptInvokeForEachMulti(
182     const android::renderscript::Context *rsc, android::renderscript::Script *s,
183     uint32_t slot, const android::renderscript::Allocation **ains, size_t inLen,
184     android::renderscript::Allocation *aout, const void *usr, size_t usrLen,
185     const RsScriptCall *sc);
186 
187 extern int rsovScriptInvokeRoot(const android::renderscript::Context *dc,
188                                 android::renderscript::Script *script);
189 
190 extern void rsovScriptInvokeInit(const android::renderscript::Context *dc,
191                                  android::renderscript::Script *script);
192 
193 extern void rsovScriptInvokeFreeChildren(
194     const android::renderscript::Context *dc,
195     android::renderscript::Script *script);
196 
197 extern void rsovScriptSetGlobalVar(const android::renderscript::Context *,
198                                    const android::renderscript::Script *,
199                                    uint32_t slot, void *data, size_t dataLen);
200 
201 extern void rsovScriptGetGlobalVar(const android::renderscript::Context *,
202                                    const android::renderscript::Script *,
203                                    uint32_t slot, void *data, size_t dataLen);
204 
205 extern void rsovScriptSetGlobalVarWithElemDims(
206     const android::renderscript::Context *,
207     const android::renderscript::Script *, uint32_t slot, void *data,
208     size_t dataLength, const android::renderscript::Element *,
209     const uint32_t *dims, size_t dimLength);
210 extern void rsovScriptSetGlobalBind(const android::renderscript::Context *,
211                                     const android::renderscript::Script *,
212                                     uint32_t slot,
213                                     android::renderscript::Allocation *data);
214 
215 extern void rsovScriptSetGlobalObj(const android::renderscript::Context *,
216                                    const android::renderscript::Script *,
217                                    uint32_t slot,
218                                    android::renderscript::ObjectBase *data);
219 
220 extern void rsovScriptSetGlobal(const android::renderscript::Context *dc,
221                                 const android::renderscript::Script *script,
222                                 uint32_t slot, void *data, size_t dataLength);
223 extern void rsovScriptGetGlobal(const android::renderscript::Context *dc,
224                                 const android::renderscript::Script *script,
225                                 uint32_t slot, void *data, size_t dataLength);
226 extern void rsovScriptDestroy(const android::renderscript::Context *dc,
227                               android::renderscript::Script *script);
228 
229 extern android::renderscript::Allocation *rsovScriptGetAllocationForPointer(
230     const android::renderscript::Context *dc,
231     const android::renderscript::Script *script, const void *);
232 
233 extern void rsovScriptUpdateCachedObject(
234     const android::renderscript::Context *rsc,
235     const android::renderscript::Script *script,
236     android::renderscript::rs_script *obj);
237 
238 #endif  // RSOV_SCRIPT_H
239