Android Studio 3.2.1
上 vuh
库使用的例子,首先使用 基于Vulkan的GPGPU计算框架Vuh 编译出 Android
版本的动态库,然后依照如下步骤建立工程。
分类: Vulkan
Vulkan是一个跨平台的2D和3D绘图应用程序接口(API),最早由科纳斯组织在2015年游戏开发者大会(GDC)上发表。
科纳斯最先把VulkanAPI称为“次世代OpenGL行动”(nextgenerationOpenGLinitiative)或“glNext”,但在正式宣布Vulkan之后这些名字就没有再使用了。就像OpenGL,Vulkan针对实时3D程序(如电子游戏)设计,Vulkan并计划提供高性能和低CPU管理负担(overhead),这也是Direct3D12和AMD的Mantle的目标。Vulkan兼容Mantle的一个分支,并使用了Mantle的一些组件
macOS Mojave(10.14.2)系统上编译LunarG/VulkanTools工程的Android版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
$ cd ~ $ git clone https://github.com/LunarG/VulkanTools.git $ cd VulkanTools $ cd build-android $ export ANDROID_SDK_HOME=~/Library/Android/sdk $ export ANDROID_NDK_HOME=~/Library/Android/sdk/ndk-bundle # 当前的版本需要Android SDK 23.0.0,但是需要Java 11以下版本的Java才能执行SDK里面的sdkmanager # 显示可以安装的Java版本号信息,需要检出这个内容 $ brew tap caskroom/versions $ brew search "java*" ==> Formulae app-engine-java javarepl libreadline-java google-java-format jslint4java ==> Casks charles-applejava java-beta netbeans-java-se eclipse-java java6 oracle-jdk-javadoc eclipse-javascript java8 yourkit-java-profiler java netbeans-java-ee ==> Did you mean to perform a regular expression search? Surround your query wit # 可以看到上面存在Java8可以安装,我们安装Java8 $ brew cask install java8 # 指定默认的Java版本 $ export JAVA_HOME=`/usr/libexec/java_home -v 1.8` $ $ANDROID_SDK_HOME/tools/bin/sdkmanager --update # 目前的代码需要android-23的SDK $ $ANDROID_SDK_HOME/tools/bin/sdkmanager "platforms;android-23" $ $ANDROID_SDK_HOME/tools/bin/sdkmanager "platforms;android-24" $ $ANDROID_SDK_HOME/tools/bin/sdkmanager "build-tools;24.0.3" # 可选安装 # $ANDROID_SDK_HOME/tools/bin/sdkmanager "platform-tools" "platforms;24.0.3" # 需要Android 7.0以上才支持Vulkan,因此,我们需要更高版本的编译工具 $ export PATH=$ANDROID_NDK_HOME:$ANDROID_SDK_HOME/build-tools/24.0.3/:$PATH # 启用 ccache 减少二次编译的时间 $ brew install ccache $ export NDK_CCACHE=ccache $ export USE_CCACHE=1 $ export VULKAN_HEADERS_INSTALL_DIR=./third_party/Vulkan-Headers $ bash build_all.sh # 编译完成后,执行 bash test_APK.sh 测试功能,不过话说,这个工具是做什么的,有点看不懂了 # 难不成是厂家测试驱动用的? $ bash test_APK.sh |
参考链接
- Failed to install android-sdk: “java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema”
- 使用新版android sdk tool 的 sdkmanager 安装 android sdk 组件
- Failed to run sdkmanager --list (Android SDK) with Java 9
- How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException in Java 9
- Android SDK is not installed or is not configured properly, environment looks ok #3139
- Installing specific major Java JDK versions on OS X via Homebrew
- Vulkan 设置
OpenCL代码编译成Vulkan代码的工具clspv
最近接到个任务,就是把OpenCL
的.cl
代码编译成Vulkan
程序。
使用Google
开源的工具clspv
实现这个功能即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ git clone https://github.com/google/clspv.git $ cd clspv $ python utils/fetch_sources.py $ mkdir build $ cd build $ cmake .. $ make -j8 |
编译完成后,在 bin
目录下生成 clspv
这个可执行程序。
使用的时候参考项目的文档 OpenCL C 1.2 Language on Vulkan 。
只是需要注意的是,如果使用了 image 类型,比如image2d_t
则需要提供 -samplermap
这个参数,这个参数指向一个文件,文件内容可能如下:
1 2 |
CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR |
具体的定义跟在 OpenCL
中调用 read_image/write_image 函数时候指定的 sampler
参数一致即可。
参考链接
OpenCL代码编译成Vulkan代码(SPIR-V)的工具
最近接到个任务,就是把OpenCL
的.cl
代码编译成Vulkan
程序。
请使用 OpenCL代码编译成Vulkan代码的工具clspv 实现这部分功能,官方提供的转换库,目前看来暂时没办法使用。
根据官方文档,Vulkan 1.0
支持OpenCL 1.0/2.1
的代码直接编译成Vulkan
程序。
官方提供了一个名为 KhronosGroup/SPIR 的开源项目,支持OpenCL
编译成SPIR-V
代码的功能(Vulkan
使用SPIR-V
)。
这个工具在 macOS Mojave(10.14.2)
系统上使用 Xcode Version 10.1 (10B61)
编译流程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ cd ~ $ git clone -b khronos/spirv-3.6.1 https://github.com/KhronosGroup/SPIRV-LLVM.git llvm $ cd llvm/tools # 默认分支要求检出 spir_12 分支,但是貌似执行完成 clone 之后,就已经在这个分支上了 # git checkout --track -b spir_12 remotes/origin/spir_12 # 默认是 SPIR 的编译,Vulkan 需要 SPIR-V 两者是不同的 # Vulkan 需要编译 SPIR-V 我们需要手工切换到 spirv-1.0 分支上 $ git clone -b spirv-1.0 https://github.com/KhronosGroup/SPIR clang $ cd .. $ mkdir build $ cd build $ cmake .. # 多线程同时编译,提高编译速度 $ make -j8 |
编译完成后的使用方式如下:
1 2 3 4 |
$ ~/llvm/build/bin/clang -cc1 -emit-spirv -triple <triple> -cl-std=<CLversion> -include opencl.h -x cl -o <output> <input> # 反汇编查看编译结果 $ spirv-dis <output> |
<triple>
: for 32 bit SPIR-V use spir-unknown-unknown, for 64 bit SPIR-V use spir64-unknown-unknown.- -D: to enable support for extension. e.g. -Dcl_khr_fp16 compile option will enable half support.
- -O: -O0 (default) is the only tested option value at the moment. It's assumed by design that all optimizations are executed by SPIR-V consumer.
比如:
1 2 3 4 5 |
# 编译kernel.cl 到 kernel.spir $ ~/llvm/build/bin/clang -cc1 -emit-spirv -triple=spir-unknown-unknown -cl-std=CL2.0 -include opencl.h kernel.cl -o kernel.spir # 反汇编查看编译结果 $ spirv-dis kernel.spir |
继续阅读OpenCL代码编译成Vulkan代码(SPIR-V)的工具
基于Vulkan的GPGPU计算框架Vuh
发现一个写的比较好的基于Vulkan
的GPGPU
计算框架Vuh
,github
上的代码地址为:
1 |
https://github.com/Glavnokoman/vuh.git |
在macOS Mojave(10.14.2)
中编译方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
$ git clone https://github.com/Glavnokoman/vuh.git $ cd vuh/config $ pip install --user cget $ export PATH=/Users/`whoami`/Library/Python/2.7/bin:$PATH $ export CGET_PREFIX=. # 安装Vulkan相关依赖库 $ bash install_dependencies.sh # 指定Vulkan相关环境变量,后续的CMake文件中的FindVulkan.cmake会使用这个 $ export VULKAN_SDK=`pwd` # 我们刚刚安装的Catch2的路径,CMake需要 $ export Catch2_DIR=`pwd`/lib/cmake/Catch2 $ export ARGS=-DCatch2_DIR=$Catch2_DIR # 安装其他依赖 $ brew install spdlog $ brew install doxygen $ cd .. $ mkdir build $ cd build $ cmake .. $ARGS $ make |
如果编译的时候报错
1 2 3 4 5 6 7 8 9 10 |
Scanning dependencies of target vuh_example_spdlog [ 60%] Building CXX object doc/examples/spdlog/CMakeFiles/vuh_example_spdlog.dir/main.cpp.o /Users/xxx/Source/vuh/doc/examples/spdlog/main.cpp:14:27: error: no member named 'basic_logger_mt' in namespace 'spdlog' static auto logger = spd::basic_logger_mt("logger", "vuh.log"); ~~~~~^ 1 error generated. make[2]: *** [doc/examples/spdlog/CMakeFiles/vuh_example_spdlog.dir/main.cpp.o] Error 1 make[1]: *** [doc/examples/spdlog/CMakeFiles/vuh_example_spdlog.dir/all] Error 2 make: *** [all] Error 2 |
这个原因是由于新版本的spdlog-1.2.1
变更了basic_logger_mt
这个类的头文件。
在源代码的vuh/doc/examples/spdlog/main.cpp
中,包含如下头文件即可:
1 |
#include <spdlog/sinks/basic_file_sink.h> |
如果需要编译 Android
版本,那么如下方式进行编译:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
$ git clone https://github.com/Glavnokoman/vuh.git $ cd vuh/config $ pip install --user cget $ export PATH=/Users/`whoami`/Library/Python/2.7/bin:$PATH $ export CGET_PREFIX=. # 安装Vulkan相关依赖库 $ bash install_dependencies.sh $ export ANDROID_NDK_HOME=~/Library/Android/sdk/ndk-bundle $ cd .. $ mkdir build $ cd build $ cmake .. \ -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_ABI="armeabi-v7a" \ -DCMAKE_BUILD_TYPE=Release \ -DANDROID_STL=c++_static \ -DANDROID_NATIVE_API_LEVEL=android-24 \ -DANDROID_TOOLCHAIN=clang \ -DVUH_BUILD_TESTS=OFF \ -DVUH_BUILD_DOCS=OFF \ -DVUH_BUILD_EXAMPLES=OFF \ -DCMAKE_CXX_FLAGS="-DVK_USE_PLATFORM_ANDROID_KHR=1 -DVULKAN_HPP_TYPESAFE_CONVERSION=1 -I$ANDROID_NDK_HOME/sources/third_party/vulkan/src/include/" # 最后生成 libvuh.so ,然后自己写代码调用这个库即可,简单的直接修改代码中的例子即可 $ make |
注意最后几个参数,文档,测试用例,例子都不参与编译,原因在于这几个工程不适合 Android
上运行,最后需要定义几个 C++
的编译宏,否则编译不通过。
如果上面编译的时候,提示如下错误信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[ 20%] Building CXX object src/CMakeFiles/vuh.dir/instance.cpp.o vuh/src/instance.cpp:127:33: error: incompatible operand types ('vuh::debug_reporter_t' (aka 'unsigned int (*)(unsigned int, VkDebugReportObjectTypeEXT, unsigned long long, unsigned int, int, const char *, const char *, void *) __attribute__((pcs("aapcs-vfp")))') and 'auto (*)(VkDebugReportFlagsEXT, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char *, const char *, void *) -> VkBool32' (aka 'auto (*)(unsigned int, VkDebugReportObjectTypeEXT, unsigned long long, unsigned int, int, const char *, const char *, void *) -> unsigned int')) , _reporter(report_callback ? report_callback : debugReporter) ^ ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~ vuh/src/instance.cpp:128:49: warning: field '_reporter' is uninitialized when used here [-Wuninitialized] , _reporter_cbk(registerReporter(_instance, _reporter)) ^ 1 warning and 1 error generated. make[2]: *** [src/CMakeFiles/vuh.dir/instance.cpp.o] Error 1 make[1]: *** [src/CMakeFiles/vuh.dir/all] Error 2 make: *** [all] Error 2 |
这个错误的原因是 vuh/src/instance.cpp
中定义
1 2 3 4 5 6 7 8 9 10 11 |
/// Default debug reporter used when user did not care to provide his own. static auto debugReporter( VkDebugReportFlagsEXT , VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t , const char* pLayerPrefix , const char* pMessage , void* /*pUserData*/ )-> VkBool32 { std::cerr << "[Vulkan]:" << pLayerPrefix << ": " << pMessage << "\n"; return VK_FALSE; } |
的时候,缺少 VKAPI_ATTR
这个宏。貌似只有在 Android
平台上这个宏被赋值,其他平台都是空。因此其他平台编译的时候,没有这个参数也是没问题的。
修改后的结果为:
1 2 3 4 5 6 7 8 9 10 11 |
/// Default debug reporter used when user did not care to provide his own. static auto VKAPI_ATTR debugReporter( VkDebugReportFlagsEXT , VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t , const char* pLayerPrefix , const char* pMessage , void* /*pUserData*/ )-> VkBool32 { std::cerr << "[Vulkan]:" << pLayerPrefix << ": " << pMessage << "\n"; return VK_FALSE; } |
VKAPI_ATTR
这个宏在 vk_platform.h
这个文件中被定义,定义的具体内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
/* *************************************************************************************************** * Platform-specific directives and type declarations *************************************************************************************************** */ /* Platform-specific calling convention macros. * * Platforms should define these so that Vulkan clients call Vulkan commands * with the same calling conventions that the Vulkan implementation expects. * * VKAPI_ATTR - Placed before the return type in function declarations. * Useful for C++11 and GCC/Clang-style function attribute syntax. * VKAPI_CALL - Placed after the return type in function declarations. * Useful for MSVC-style calling convention syntax. * VKAPI_PTR - Placed between the '(' and '*' in function pointer types. * * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void); * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void); */ #if defined(_WIN32) // On Windows, Vulkan commands use the stdcall convention #define VKAPI_ATTR #define VKAPI_CALL __stdcall #define VKAPI_PTR VKAPI_CALL #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 #error "Vulkan isn't supported for the 'armeabi' NDK ABI" #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" // calling convention, i.e. float parameters are passed in registers. This // is true even if the rest of the application passes floats on the stack, // as it does by default when compiling for the armeabi-v7a NDK ABI. #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp"))) #define VKAPI_CALL #define VKAPI_PTR VKAPI_ATTR #else // On other platforms, use the default calling convention #define VKAPI_ATTR #define VKAPI_CALL #define VKAPI_PTR #endif |
Vulkan官方API文档Vulkan® 1.0.95 - A Specification
Vulkan官方API文档 Vulkan® 1.0.95 - A Specification 对于开发者来说,非常有用。
由于官方网站访问非常缓慢,建议下载PDF版本到本地来查看。
官方文档地址: Vulkan® 1.0.95 - A Specification - Khronos Group
官方PDF版本地址: Vulkan® 1.0.95 - A Specification - Khronos Group
本站的一份PDF版拷贝
继续阅读Vulkan官方API文档Vulkan® 1.0.95 - A Specification
Vulkan中的"#version 430 core"的理解
最近在学习Vulkan
,结果在查看示例代码的时候:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#version 430 core layout (local_size_x = 64) in; layout(std430, binding=4 ) buffer INFO { vec2 info[]; }; void main() { uint gid = gl_GlobalInvocationID.x; info[gid].x += 1.0; info[gid].y += 1.0; memoryBarrier(); } |
对于如下语句出现了疑问
1 |
#version 430 core |
这句话的意思是OpenGL
必须是4.3
以及以上的版本。
那么是不是意味着,如果设备上的OpenGL
低于这个版本,那么我们编写的Vulkan
代码就不能执行呢?
答案是否定的,目前我们开发Vulkan
默认是使用GLSL
(OpenGL Shading Language
)语言,然后编译完成后的操作符被直接映射成Vulkan
的定义操作符。
换句话说,我们只要执行如下命令,
1 |
$ glslangValidator xx.comp --target-env vulkan1.0 |
能编译通过,就可以随意指定#version
的版本。
这个版本号仅仅是GLSL
语言在进行语法检查的时候需要的,而Vulkan
是没有这个版本号需要的。
如果不使用GLSL
语言编写,上述的#version
应该都不会在语法中出现。
Vulkan中的gl_GlobalInvocationID, local_size_x的理解
最近在学习Vulkan
,结果在查看示例代码的时候,对于如下两句出现了疑问:
1 |
layout(local_size_x = X, local_size_y = Y, local_size_z = Z) in; |
1 |
ivec3 pos = ivec3(gl_GlobalInvocationID); |
首先是Invocation
这个单词的理解,计算机语言中他的意思是 "the act of making a particular function start
" ,中文意思是 "调用,启用
"。
其中
1 |
layout(local_size_x = X, local_size_y = Y, local_size_z = Z) in; |
意思是初始化,X * Y * Z
个计算单元供我们的代码调用,可以简单理解成线程数。如果不设置这几个值,默认值是 1
,也就是只提供一个计算单元(线程)。
而使用如下的代码
1 |
ivec3 pos = ivec3(gl_GlobalInvocationID); |
意思是获取当前代码运行的计算单元的编号,也可以理解成获取当前线程的索引。
下面的代码都使用如下的命令编译成Vulkan
使用的SPIR-V
格式的代码
1 |
$ glslangValidator xx.comp --target-env vulkan1.0 |
比如下面的代码,就是一个简单的利用gl_GlobalInvocationID
,进行并行计算的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#version 430 core layout (local_size_x = 64) in; layout(std430, binding=4 ) buffer INFO { vec2 info[]; }; void main() { uint gid = gl_GlobalInvocationID.x; info[gid].x += 1.0; info[gid].y += 1.0; memoryBarrier(); } |
但是,如果传入的数组的大小超过我们设置的计算单元的数量的情况,上述的代码是处理不了的。
可以如下方式处理上述情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/*atomicAdd 从4.30版本的opengl开始提供,之前的版本没有这个函数*/ #version 430 core layout (local_size_x = 64) in; layout(std430, binding=4 ) buffer INFO { vec2 info[]; }; layout(std430, binding=5 ) buffer LEN { uint len; }; uint counter = 0; void main() { uint gid = atomicAdd(counter,1); if (gid <= len ) { info[gid].x += 1.0; info[gid].y += 1.0; memoryBarrier(); } } void main() { uint gid = atomicAdd(counter,1); if (gid <= len ) { info[gid].x += 1.0; info[gid].y += 1.0; memoryBarrier(); } } |
如果想动态调整计算单元的数量,增加处理灵活性,可以参考下面的代码:
1 2 3 4 5 6 |
#version 450 layout(local_size_x_id = 0) in; layout(local_size_y_id = 1) in; layout(local_size_z_id = 2) in; //rest of the shader |
外部通过
1 2 3 4 5 6 7 |
VkResult vkCreateComputePipelines( VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); |
函数调用的时候,指定
1 2 3 4 5 6 7 8 9 |
typedef struct VkComputePipelineCreateInfo { VkStructureType sType; const void* pNext; VkPipelineCreateFlags flags; VkPipelineShaderStageCreateInfo stage; VkPipelineLayout layout; VkPipeline basePipelineHandle; int32_t basePipelineIndex; } VkComputePipelineCreateInfo; |
参数中的
1 2 3 4 5 6 7 8 9 |
typedef struct VkPipelineShaderStageCreateInfo { VkStructureType sType; const void* pNext; VkPipelineShaderStageCreateFlags flags; VkShaderStageFlagBits stage; VkShaderModule module; const char* pName; const VkSpecializationInfo* pSpecializationInfo; } VkPipelineShaderStageCreateInfo; |
参数中的
1 2 3 4 5 6 |
typedef struct VkSpecializationInfo { uint32_t mapEntryCount; const VkSpecializationMapEntry* pMapEntries; size_t dataSize; const void* pData; } VkSpecializationInfo; |
参数中的
1 2 3 4 5 |
typedef struct VkSpecializationMapEntry { uint32_t constantID; uint32_t offset; size_t size; } VkSpecializationMapEntry; |
指定的数值来动态调整所需要的计算单元的数量。
整个参数的设置流程特别长,非常难掌握。具体的使用例子参考 Glavnokoman/vuh以及 Vulkan® 1.0.95 - A Specification - Khronos Group文档中的上述参数的使用例子。
如果内部不指定,也可以通过外部调用
1 2 3 4 5 |
void vkCmdDispatch( VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); |
的时候设置,但是这样的设置存在一定的灵活性问题,可能需要多个独立的ComputePipeline
来配合。
Android Studio 3.2.1编译Vulkan示例项目
最近在学习Vulkan
,根据Google
官方给出的文档,是存在一些问题的,总结一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 官方文档说要检出 git clone https://github.com/googlesamples/vulkan-basic-samples.git # 实际上 vulkan-basic-samples.git 是 VulkanSamples.git 的一个fork,google简化了部分编译流程 # vulkan-basic-samples.git检出后,直接用 Android Studio打开即可 # https://github.com/SaschaWillems/Vulkan.git也存在一个例子工程 # 但是貌似根正苗红的是VulkanSamples这个例子 $ git clone https://github.com/LunarG/VulkanSamples.git $ cd VulkanSamples $ cd API-Samples # 最后在当前目录下生成一个 android 的目录,用Android Studio导入这个目录下的工程 # 也就是 "VulkanSamples/API-Samples/android" 这个目录是我们的工程目录 $ cmake -DANDROID=ON -DABI_NAME=armeabi-v7a |
如果代码下载不成功,可以本站下载一份拷贝。 点击这里下载 VulkanSamples vulkan-basic-samples
继续阅读Android Studio 3.2.1编译Vulkan示例项目
macOS Mojave(10.14.1)安装Vulkan依赖的工具链SPIR-V Toolchain
目前在研究学习Vulkan
,Vulkan
使用SPIR-V
工具链进行编译,在macOS Mojave(10.14.1)
中使用如下命令安装工具链:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
$ brew info glslang glslang: stable 7.10.2984 (bottled), HEAD OpenGL and OpenGL ES reference compiler for shading languages https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/ Not installed From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/glslang.rb ==> Dependencies Build: cmake ✘ ==> Options --HEAD Install HEAD version ==> Analytics install: 1,147 (30 days), 1,770 (90 days), 2,664 (365 days) install_on_request: 383 (30 days), 696 (90 days), 1,537 (365 days) build_error: 0 (30 days) $ brew install glslang ==> Downloading https://homebrew.bintray.com/bottles/glslang-7.10.2984.mojave.bo ######################################################################## 100.0% ==> Pouring glslang-7.10.2984.mojave.bottle.tar.gz ? /usr/local/Cellar/glslang/7.10.2984: 58 files, 6.7MB $ glslangValidator -v Glslang Version: 7.10.2984 ESSL Version: OpenGL ES GLSL 3.20 glslang Khronos. 10.2984 GLSL Version: 4.60 glslang Khronos. 10.2984 SPIR-V Version 0x00010300, Revision 1 GLSL.std.450 Version 100, Revision 1 Khronos Tool ID 8 SPIR-V Generator Version 7 GL_KHR_vulkan_glsl version 100 ARB_GL_gl_spirv version 100 |
但是,需要注意的是,使用HomeBrew
安装的版本,缺少部分功能,如果使用"-Os
"(代码大小优化)参数的时候,会报告错误,如下:
1 2 |
$ glslangValidator -V -Os glslangValidator: Error -Os not available; optimizer not linked (use -h for usage) |
这是由于代码大小优化部分需要spirv-tools
执行,然而HomeBrew
编译的版本没有关联spirv-tools
导致安装的程序没办法使用这个功能。
如果需要这部分功能,我们只能手动编译安装:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# 移除brew安装的版本 $ brew remove glslang # 编译安装 glslang $ git clone https://github.com/KhronosGroup/glslang.git $ cd glslang # 目前(2018.12.17)的正式版,最稳定的版本,试过最新的版本,编译部分代码存在问题 $ git checkout 7.10.2984 # 下载 spirv-tools 部分的功能代码 $ python update_glslang_sources.py $ mkdir build $ cd build $ cmake .. $ make $ sudo make install |
继续阅读macOS Mojave(10.14.1)安装Vulkan依赖的工具链SPIR-V Toolchain