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   static constexpr int CPU_SCRIPT_MAGIC_NUMBER = 0x60000;
119 
120   RSoVContext *mRSoV;
121   VkDevice mDevice;
122   std::vector<uint32_t> mSPIRVWords;
123   RsdCpuReference::CpuScript *mCpuScript;
124 
125   static constexpr int NUM_DESCRIPTOR_SETS = 1;
126   std::vector<VkDescriptorSetLayout> mDescLayout;
127   VkPipelineLayout mPipelineLayout;
128   VkPipeline mComputePipeline;
129   // TODO: Multiple stages for multiple kernels
130   VkPipelineShaderStageCreateInfo mShaderStage;
131   VkDescriptorPool mDescPool;
132   std::vector<VkDescriptorSet> mDescSet;
133   // For kernel names
134   const bcinfo::MetadataExtractor *mME;
135   // Metadata of global allocations
136   std::unique_ptr<RSoVBuffer> mGlobalAllocationMetadata;
137   // Mapping of global allocation to rsov-assigned ID
138   std::unique_ptr<std::map<std::string, int> > mGAMapping;
139 };
140 
141 }  // namespace rsov
142 }  // namespace renderscript
143 }  // namespace android
144 
145 extern bool rsovScriptInit(const android::renderscript::Context *rsc,
146                            android::renderscript::ScriptC *script,
147                            char const *resName, char const *cacheDir,
148                            uint8_t const *bitcode, size_t bitcodeSize,
149                            uint32_t flags);
150 
151 extern bool rsovInitIntrinsic(const android::renderscript::Context *rsc,
152                               android::renderscript::Script *s,
153                               RsScriptIntrinsicID iid,
154                               android::renderscript::Element *e);
155 
156 extern void rsovScriptInvokeFunction(const android::renderscript::Context *dc,
157                                      android::renderscript::Script *script,
158                                      uint32_t slot, const void *params,
159                                      size_t paramLength);
160 
161 extern void rsovScriptInvokeForEach(
162     const android::renderscript::Context *rsc, android::renderscript::Script *s,
163     uint32_t slot, const android::renderscript::Allocation *ain,
164     android::renderscript::Allocation *aout, const void *usr, size_t usrLen,
165     const RsScriptCall *sc);
166 
167 extern void rsovScriptInvokeReduce(
168     const android::renderscript::Context *rsc, android::renderscript::Script *s,
169     uint32_t slot, const android::renderscript::Allocation **ains, size_t inLen,
170     android::renderscript::Allocation *aout, const RsScriptCall *sc);
171 
172 extern void rsovScriptInvokeForEachMulti(
173     const android::renderscript::Context *rsc, android::renderscript::Script *s,
174     uint32_t slot, const android::renderscript::Allocation **ains, size_t inLen,
175     android::renderscript::Allocation *aout, const void *usr, size_t usrLen,
176     const RsScriptCall *sc);
177 
178 extern int rsovScriptInvokeRoot(const android::renderscript::Context *dc,
179                                 android::renderscript::Script *script);
180 
181 extern void rsovScriptInvokeInit(const android::renderscript::Context *dc,
182                                  android::renderscript::Script *script);
183 
184 extern void rsovScriptInvokeFreeChildren(
185     const android::renderscript::Context *dc,
186     android::renderscript::Script *script);
187 
188 extern void rsovScriptSetGlobalVar(const android::renderscript::Context *,
189                                    const android::renderscript::Script *,
190                                    uint32_t slot, void *data, size_t dataLen);
191 
192 extern void rsovScriptGetGlobalVar(const android::renderscript::Context *,
193                                    const android::renderscript::Script *,
194                                    uint32_t slot, void *data, size_t dataLen);
195 
196 extern void rsovScriptSetGlobalVarWithElemDims(
197     const android::renderscript::Context *,
198     const android::renderscript::Script *, uint32_t slot, void *data,
199     size_t dataLength, const android::renderscript::Element *,
200     const uint32_t *dims, size_t dimLength);
201 extern void rsovScriptSetGlobalBind(const android::renderscript::Context *,
202                                     const android::renderscript::Script *,
203                                     uint32_t slot,
204                                     android::renderscript::Allocation *data);
205 
206 extern void rsovScriptSetGlobalObj(const android::renderscript::Context *,
207                                    const android::renderscript::Script *,
208                                    uint32_t slot,
209                                    android::renderscript::ObjectBase *data);
210 
211 extern void rsovScriptSetGlobal(const android::renderscript::Context *dc,
212                                 const android::renderscript::Script *script,
213                                 uint32_t slot, void *data, size_t dataLength);
214 extern void rsovScriptGetGlobal(const android::renderscript::Context *dc,
215                                 const android::renderscript::Script *script,
216                                 uint32_t slot, void *data, size_t dataLength);
217 extern void rsovScriptDestroy(const android::renderscript::Context *dc,
218                               android::renderscript::Script *script);
219 
220 extern android::renderscript::Allocation *rsovScriptGetAllocationForPointer(
221     const android::renderscript::Context *dc,
222     const android::renderscript::Script *script, const void *);
223 
224 extern void rsovScriptUpdateCachedObject(
225     const android::renderscript::Context *rsc,
226     const android::renderscript::Script *script,
227     android::renderscript::rs_script *obj);
228 
229 #endif  // RSOV_SCRIPT_H
230