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
30namespace android {
31namespace renderscript {
32
33class Allocation;
34class Context;
35class Element;
36class Script;
37class ScriptC;
38
39namespace rsov {
40
41class RSoVAllocation;
42class RSoVBuffer;
43class RSoVContext;
44
45// TODO: CpuScript is a bad name for the base class. Fix with a refactoring.
46class 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
101  void setCpuScript(RsdCpuReference::CpuScript *cs) { mCpuScript = cs; }
102
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
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
154extern 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
160extern bool rsovInitIntrinsic(const android::renderscript::Context *rsc,
161                              android::renderscript::Script *s,
162                              RsScriptIntrinsicID iid,
163                              android::renderscript::Element *e);
164
165extern void rsovScriptInvokeFunction(const android::renderscript::Context *dc,
166                                     android::renderscript::Script *script,
167                                     uint32_t slot, const void *params,
168                                     size_t paramLength);
169
170extern 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
176extern 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
181extern 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
187extern int rsovScriptInvokeRoot(const android::renderscript::Context *dc,
188                                android::renderscript::Script *script);
189
190extern void rsovScriptInvokeInit(const android::renderscript::Context *dc,
191                                 android::renderscript::Script *script);
192
193extern void rsovScriptInvokeFreeChildren(
194    const android::renderscript::Context *dc,
195    android::renderscript::Script *script);
196
197extern void rsovScriptSetGlobalVar(const android::renderscript::Context *,
198                                   const android::renderscript::Script *,
199                                   uint32_t slot, void *data, size_t dataLen);
200
201extern void rsovScriptGetGlobalVar(const android::renderscript::Context *,
202                                   const android::renderscript::Script *,
203                                   uint32_t slot, void *data, size_t dataLen);
204
205extern 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);
210extern void rsovScriptSetGlobalBind(const android::renderscript::Context *,
211                                    const android::renderscript::Script *,
212                                    uint32_t slot,
213                                    android::renderscript::Allocation *data);
214
215extern void rsovScriptSetGlobalObj(const android::renderscript::Context *,
216                                   const android::renderscript::Script *,
217                                   uint32_t slot,
218                                   android::renderscript::ObjectBase *data);
219
220extern void rsovScriptSetGlobal(const android::renderscript::Context *dc,
221                                const android::renderscript::Script *script,
222                                uint32_t slot, void *data, size_t dataLength);
223extern void rsovScriptGetGlobal(const android::renderscript::Context *dc,
224                                const android::renderscript::Script *script,
225                                uint32_t slot, void *data, size_t dataLength);
226extern void rsovScriptDestroy(const android::renderscript::Context *dc,
227                              android::renderscript::Script *script);
228
229extern android::renderscript::Allocation *rsovScriptGetAllocationForPointer(
230    const android::renderscript::Context *dc,
231    const android::renderscript::Script *script, const void *);
232
233extern 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