1# Vulkan-Loader
2
3本仓库包含开源软件Vulkan-Loader,为OpenHarmony提供对Vulkan的支持能力。
4
5Vulkan是一个跨平台的2D和3D绘图应用程序接口(API)。它的API分为核心API、窗口系统集成(WSI)扩展API以及其他扩展API。
6
7核心API由GPU驱动实现,窗口系统集成(WSI)扩展API由[swapchain_layer](#swapchain_layer)实现,swapchain_layer是OpenHarmony平台是实现的一个Vulkan Layer,安装在`/system/lib[64]/libvulkan_swapchain.so`中。Vulkan Layer属于增强Vulkan开发环境的扩展功能,被实现为动态链接库(.so文件)。
8
9Vulkan-Loader会加载这些API的实现并对外提供这些接口给应用开发者使用。Vulkan-Loader安装在`/system/lib[64]/libvulkan.so`中。
10
11Vulkan-Loader主要功能概括如下:
12
131、加载GPU驱动。
14
152、加载Vulkan Layer。
16
173、提供Vulkan NDK接口。
18
19![vulkan-loader_location_in_OH](openharmony/imgs/vulkan-loader_location_in_OH.png)
20
21
22## 加载GPU驱动
23
24在OpenHarmony上,Vulkan-Loader会扫描指定路径下的GPU驱动的**json清单文件**并读取该文件加载GPU驱动。
25
26### 指定的扫描路径
27
28```
29/vendor/etc/vulkan/icd.d/
30/system/etc/vulkan/icd.d/
31/data/vulkan/icd.d/
32```
33建议:GPU驱动的json清单文件应放在`/vendor/etc/vulkan/icd.d/`目录中。
34
35Vulkan-Loader会根据GPU驱动的**json清单文件**中配置的`library_path`找到GPU驱动的动态链接库文件(.so文件)并加载。
36
37### GPU驱动的json清单文件示例
38
39```json
40{
41   "file_format_version": "1.0.1",
42   "ICD": {
43      "library_path": "path to driver library",
44      "api_version": "1.3.275",
45      "library_arch" : "64",
46      "is_portability_driver": false
47   }
48}
49```
50
51详细介绍请见:[Driver Manifest File Format](docs/LoaderDriverInterface.md#driver-manifest-file-format)
52
53### GPU驱动的实现
54
55GPU驱动需要实现的Vulkan接口请参考文档:[LoaderDriverInterface](docs/LoaderDriverInterface.md),开发者需要按照文档里的要求实现对应的接口才能够被Vulkan-Loader正确加载。
56
57
58## 加载Vulkan Layer
59
60Vulkan Layer属于增强Vulkan开发环境的扩展功能,可以由开发人员启用或关闭。启用和关闭Vulkan Layer的方式有很多,可以通过环境变量、配置文件、或者代码来开启和关闭指定的Layer。
61
62在OpenHarmony上,Vulkan-Loader通过读取指定路径下的Layer的**json清单文件**加载Vulkan Layer。
63
64### user mode下加载自定义layer使用指南
651. layer对应json文件和so文件放置
66    1. json文件放置位置:      entry\src\main\resources\rawfile\layerName.json
67    2. so文件放置位置:        entry\libs\arm64-v8a\libLayerName.so
68
692. json文件指定so文件位置
70    引入包管理后,json文件中的library_path支持使用相对路径,即将library_path修改为   libLayerName.so
71    同时,兼容现有的library_path写绝对路径的方式,即library_path为    /data/storage/el1/bundle/lib/arm64/libLayerName.so
72
733. 拷贝json文件至沙箱路径
74    由于当前loader无法直接从hap包中获取rawfile路径下文件,因此需要hap工程手动复制json文件到沙箱中
75    在entry\src\main\ets\pages\Index.ets文件中引入@ohos.file.fs, 并在aboutToAppear() 中写入复制方法,如下:
76
77    ``` Java
78    // 在Index.ets文件中
79    import fs from '@ohos.file.fs';
80    // ......
81    aboutToAppear(): void { // Copy layerName.json to hap sandbox
82        let path = getContext(this).filesDir;
83        if (!fs.accessSync(path)) {
84            fs.mkdirSync(path);
85        }
86
87        buffer = getContext(this).resourceManager.getRawFileContentSync('layerName.json');
88        file = fs.openSync(path + '/layerName.json', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
89        fs.writeSync(file.fd, buffer.buffer);
90    }
91    ```
924. 设置环境变量
93    开启时设置环境变量
94    hdc shell param set debug.graphic.debug_layer layerName     (应与json的名字保持一致:xxxxx.json)
95    hdc shell param set debug.graphic.debug_hap hapName         (应于hap包名保持一致)
96
97    关闭时清空两个环境变量
98    hdc shell param set debug.graphic.debug_layer '' (设置成空字符)
99    hdc shell param set debug.graphic.debug_hap '' (设置成空字符)
1005. 异常排查方法
101    1. 检查json文件位置是否正常
102        hap工程路径:    \entry\src\main\resources\rawfile\layerName.json
103        hdc shell路径:   /data/app/el2/100/base/{your_pakage_name}/file/layerName.json
104        应用视角下json文件的路径:    /data/storage/el2/base/haps/entry/files/layerName.json
105
106    2. 检查so文件位置是否正常
107        hap工程路径:        \entry\libs\arm64-v8a\libLayerName.so
108        hdc shell路径:    /data/app/el1/bundle/public/{your_pakage_name}/libs/arm64/libLayerName.so
109        应用视角下json文件的路径:    /data/storage/el1/bundle/libs/arm64/libLayerName.so
110    3. 抓取异常日志
111        ```
112        hdc shell
113        hilog -b X
114        hilog -b D -D D001405
115        hilog |grep -i VulkanLoader
116        ```
1176. 进入应用视角
118    在调试过程中,如果权限不对或文件不存在,开发者需要从调试进程视角切换为应用视角,以便直观分析权限及文件目录问题。视角切换命令如下:
119    ```
120    hdc shell                         // 进入shell
121    ps -ef|grep [hapName]             // 通过ps命令找到对应应用的pid
122    nsenter -t [hapPid] -m /bin/sh    // 通过上一步找到的应用pid进入对应应用的沙箱环境中
123    hdc shell                         // 进入shell
124    ps -ef|grep [hapName]             // 通过ps命令找到对应应用的pid
125    nsenter -t [hapPid] -m /bin/sh    // 通过上一步找到的应用pid进入对应应用的沙箱环境中
126    ```
127    执行完成后,即切换到了应用视角,该视角下的目录路径为应用沙箱路径,可以去排查沙箱路径相关问题。
128
129### 指定的扫描路径
130
131```
132/system/etc/vulkan/implicit_layer.d/
133/system/etc/vulkan/explicit_layer.d/
134/data/vulkan/implicit_layer.d/
135/data/vulkan/explicit_layer.d/
136```
137
138默认加载的layer的json文件应放在`xxx/implicit_layer.d/`下。
139需要显式加载的layer的json文件应放在`xxx/explicit_layer.d/`下,不会被Vulkan-Loader默认加载。
140
141### Vulkan Layer的json清单文件示例
142
143下面给出[swapchain_layer](#swapchain_layer)的json清单文件示例:
144
145```json
146{
147    "file_format_version" : "1.0.0",
148    "layer" : {
149        "name": "VK_LAYER_OHOS_surface",
150        "type": "GLOBAL",
151        "library_path": "libvulkan_swapchain.so",
152        "api_version": "1.3.231",
153        "implementation_version": "1",
154        "description": "Vulkan Swapchain",
155        "disable_environment": {
156            "DISABLE_OHOS_SWAPCHAIN_LAYER": "1"
157        },
158        "instance_extensions": [
159            { "name": "VK_KHR_surface", "spec_version": "25" },
160            { "name": "VK_OHOS_surface", "spec_version": "1" }
161        ],
162        "device_extensions": [
163            { "name": "VK_KHR_swapchain", "spec_version": "70" }
164        ]
165    }
166}
167```
168
169详细介绍请见:[Layer Manifest File Format](docs/LoaderLayerInterface.md#layer-manifest-file-format)
170
171### Vulkan Layer的实现
172
173Vulkan Layer需要实现的Vulkan接口请参考文档:[LoaderLayerInterface](docs/LoaderLayerInterface.md),开发者需要按照文档里的要求实现对应的接口才能够被Vulkan-Loader正确加载。
174
175### swapchain_layer
176
177swapchain_layer是实现Vulkan-Loader与OpenHarmony平台本地窗口(OHNativeWindow)对接的模块,作为一个隐式加载的Vulkan Layer使用。
178
179代码地址:[swapchain_layer](https://gitee.com/openharmony/graphic_graphic_2d/tree/master/frameworks/vulkan_layers/swapchain_layer)
180
181
182## Vulkan NDK
183
184在OpenHarmony上,Vulkan-Loader会提供Vulkan NDK接口,应用层软件(如:图形引擎、XComponent NAPI等)和系统层图形绘制模块(如:Skia)可以调用这些NDK接口。
185
186
187## 构建指导
188
189适配OpenHarmony平台的编译脚本请见:[openharmony/BUILD.gn](openharmony/BUILD.gn)
190
191由于graphic_2d模块的编译脚本中包含了Vulkan-Loader(详见:[bundle.json](https://gitee.com/openharmony/graphic_graphic_2d/blob/master/bundle.json)),所以编译graphic_2d模块可以将Vulkan-Loader同时编译出来,以rk3568平台为例,编译命令:
192
193```shell
194./build.sh --product-name rk3568 --ccache --build-target graphic_2d
195```
196
197也可以单独编译Vulkan-Loader:
198
199```shell
200./build.sh --product-name rk3568 --ccache --build-target vulkan_loader
201```
202
203编译完成后会在`out/rk3568/graphic/graphic_2d`目录下生成`libvulkan.so`
204
205
206## License
207
208Apache License 2.0
209
210见 [LICENSE](LICENSE.txt).