六一的部落格


关关难过关关过,前路漫漫亦灿灿。




MoltenVK

MoltenVK

通过MoltenVK, 可以在macOS和iOS上运行Vulkan

MoltenVK是运行时库 Runtime Library , 将Vulkan映射为Apple的Metal图形架构

通过MoltenVK, 不用重写使用Vulkan实现的应用程序, 就可获得基于iOS和macOS使用的Metal架构的性能优势, 调试和性能优化能力

而Metal底层又调用Vulkan接口

GitHub - MoltenVK

Vulkan


环境配置

-
macOS Ventura 13.6.4
Xcode 14.2
Vulkan 1.3.275
CMake 3.28.1
Python 3.9.6
1xcodebuild -version
2cmake -version
3python3 -V

安装Python和CMake

GitHub - MoltenVK

1brew install cmake --cask
2
3brew install python

安装Vulkan SDK

  1. 入口

  2. 下载SDK Installer

    1.3.275

  3. 安装SDK

    -
    SDK路径 /Users/<用户名>/VulkanSDK/1.3.275.0

    选择组件


安装成功后如下



验证Vulkan SDK安装成功

  1. 命令行

    1vkvia


  2. 运行vkcube程序



安装glfw

Graphics Library Framework

窗口相关: 创建窗口等

-
包路径 /usr/local/Cellar/glfw/3.3.9
1brew install glfw

其他

  1. MoltenVK

    Vulkan SDK中已包含MoltenVK. 也可以通过Homebrew安装

    1brew search moltenvk
    2brew install molten-vk
  2. glm

    OpenGL Mathematics

    OpenGL数学库, 封装了矩阵和变换等运算接口

    安装Vulkan SDK时已勾选glm, 也可以通过Homebrew安装

    1brew install glm

便签

-
glfw, glm

配置Xcode项目

Xcode


创建命令行项目, 语言C++




添加头文件搜索路径

Header Search Paths

-
/usr/local/include 使用Homebrew安装的包的头文件路径: glfw
/Users/<用户名>/VulkanSDK/1.3.275.0/macOS/include Vulkan SDK头文件路径



添加库搜索路径

Library Search Paths

-
/usr/local/lib 使用Homebrew安装的包的库路径: glfw
/Users/<用户名>/VulkanSDK/1.3.275.0/macOS/lib Vulkan SDK库路径



添加编译时要链接的动态库

Link Binary With Libraries

Copy Files

  1. libvulkan.1.dylib 指向 libvulkan.1.3.275.dylib

  2. 将文件从Finder拖动到指定行

    路径
    glfw /usr/local/Cellar/glfw/3.3.9/lib
    vulkan /Users/<用户名>/VulkanSDK/1.3.275.0/macOS/lib

    使用open命令

    1open /usr/local/Cellar/glfw/3.3.9/lib
  3. 选择创建引用

    Copy Files




设置项目用环境变量

  1. 入口


  2. 设置环境变量

    -
    VK_LAYER_PATH /Users/<用户名>/VulkanSDK/1.3.275.0/macOS/share/vulkan/explicit_layer.d
    VK_ICD_FILENAMES /Users/<用户名>/VulkanSDK/1.3.275.0/macOS/share/vulkan/icd.d/MoltenVK_icd.json



便签

-
Mac搭建Vulkan开发环境
Mac搭建Vulkan开发环境, 附测试代码

使用CMake编译项目

  1. CMakeLists.txt

    必须使用C++ 17

     1cmake_minimum_required( VERSION 3.28 )
     2
     3project(HelloTriangle)
     4
     5set(CMAKE_CXX_STANDARD 17)
     6
     7add_executable(HelloTriangle main.cpp)
     8
     9# 添加 GLFW3 预编译库
    10add_library(glfw SHARED IMPORTED)
    11SET_TARGET_PROPERTIES(glfw PROPERTIES IMPORTED_LOCATION "/usr/local/Cellar/glfw/3.3.9/lib/libglfw.3.3.dylib")
    12
    13# Vulkan
    14find_package(Vulkan REQUIRED)
    15target_link_libraries(${PROJECT_NAME} glfw Vulkan::Vulkan)
    16
    17# copy the shader files to the cmake-build-debug folder
    18file(COPY shaders DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
  2. 项目编译

    • 项目内创建build文件夹, 编译时进入

      1mkdir build
      2cd build
    • 编译

      1cmake ..
      2make

便签

-
Mac搭建Vulkan开发环境, 使用CMake编译项目
cmake

使用Vulkan绘制三角形


3个源码文件

Vulkan Tutorial - 绘制三角形

点击即下载
C++ code
Vertex shader
Fragment shader

代码纠正


创建实例时

  1. 使能 VK_KHR_portability_enumeration
  2. VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR 置1


  • 使能插件

    在函数 getRequiredExtensions 设置要使用插件

    1if (enableValidationLayers) {
    2    extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
    3    extensions.emplace_back("VK_KHR_portability_enumeration");
    4}
  • 置1

    1// createInstance
    2createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;

创建设备时

使能 VK_KHR_portability_subset


1const std::vector<const char*> deviceExtensions = {
2    VK_KHR_SWAPCHAIN_EXTENSION_NAME,
3    "VK_KHR_portability_subset"
4};

创建实例时

使能 VK_KHR_get_physical_device_properties2


在函数 getRequiredExtensions 设置要使用插件

1if (enableValidationLayers) {
2    extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
3    extensions.emplace_back("VK_KHR_portability_enumeration");
4    extensions.emplace_back("VK_KHR_get_physical_device_properties2");
5}

生成(.spv)格式文件

  1. 安装glslang

    1brew search glslang
    2brew install glslang
  2. 从(.frag)和(.vert)文件生成(.spv)文件

    1glslangvalidator -V test.frag -o frag.spv
    2glslangvalidator -V test.vert -o vert.spv 
  3. 在项目内创建文件夹shaders, 将frag.spv和vert.spv移动到 shaders/ 目录下

  4. 确认文件路径

    1// createGraphicsPipeline
    2
    3auto vertShaderCode = readFile("shaders/vert.spv");
    4auto fragShaderCode = readFile("shaders/frag.spv");

运行



便签

-
知乎 - Vulkan三角形
知乎 -Vulkan - Triangle Setup
VK_KHR_get_physical_device_properties2的错误设置

附: 选择Vulkan的理由

之前学习《交互式计算机图形学(第六版)》时已接触过OpenGL, 大学CG课的机械臂和光照也是用OpenGL实现的, 但能进一步, 就尽量提高付出的转化率

支持Mac的游戏不多, 我在Steam下过CSGo, 跑了OpenGL例程, 觉得超级牛, 但清晰度确实不太行…

我本来想说OpenGL和Vulkan支持跨平台, 而DirectX特供Windows, Metal特供macOS, 但Mac上可以通过MoltenVK使用Vulkan SDK, 也可以学Vulkan

-
OpenGL和Vulkan比较
OpenGL和Vulkan性能评测

OpenGL的跨平台不允许开发者直接控制硬件细节, 而Vulkan和DirectX作为底层API, 都支持硬件优化, 最终呈现的效果, 则依赖于开发者的功力


附: 总结

之前也在Mac上配置过OpenGL和D3D12环境, 都没这回折腾, 但弄出来之后, 也没这回开心

同样是渲染一个基本图形, D3D12最简单, 也有少量的纠正, 可和OpenGL一样, 代码量很少

而Vulkan, 从一开始就涉及到设备参数读取和判断, 仅仅是渲染一个三角形, 近1k行代码, 而且顶点和片元数据还需要先用glslang生成(.spv)字节码

使用CMake编译项目时, 源码里使用了C++ 17的特性, 而之前学OpenGL时, 感觉自己在写C


附: 项目源码

CMake

GitHub - LearningVulkan - HelloTriangle: 使用Vulkan绘制三角形

标题目录

macOS安装Vulkan SDK



MoltenVK

MoltenVK

通过MoltenVK, 可以在macOS和iOS上运行Vulkan

MoltenVK是运行时库 Runtime Library , 将Vulkan映射为Apple的Metal图形架构

通过MoltenVK, 不用重写使用Vulkan实现的应用程序, 就可获得基于iOS和macOS使用的Metal架构的性能优势, 调试和性能优化能力

而Metal底层又调用Vulkan接口

GitHub - MoltenVK

Vulkan


环境配置

-
macOS Ventura 13.6.4
Xcode 14.2
Vulkan 1.3.275
CMake 3.28.1
Python 3.9.6
1xcodebuild -version
2cmake -version
3python3 -V

安装Python和CMake

GitHub - MoltenVK

1brew install cmake --cask
2
3brew install python

安装Vulkan SDK

  1. 入口

  2. 下载SDK Installer

    1.3.275

  3. 安装SDK

    -
    SDK路径 /Users/<用户名>/VulkanSDK/1.3.275.0

    选择组件


安装成功后如下



验证Vulkan SDK安装成功

  1. 命令行

    1vkvia


  2. 运行vkcube程序



安装glfw

Graphics Library Framework

窗口相关: 创建窗口等

-
包路径 /usr/local/Cellar/glfw/3.3.9
1brew install glfw

其他

  1. MoltenVK

    Vulkan SDK中已包含MoltenVK. 也可以通过Homebrew安装

    1brew search moltenvk
    2brew install molten-vk
  2. glm

    OpenGL Mathematics

    OpenGL数学库, 封装了矩阵和变换等运算接口

    安装Vulkan SDK时已勾选glm, 也可以通过Homebrew安装

    1brew install glm

便签

-
glfw, glm

配置Xcode项目

Xcode


创建命令行项目, 语言C++




添加头文件搜索路径

Header Search Paths

-
/usr/local/include 使用Homebrew安装的包的头文件路径: glfw
/Users/<用户名>/VulkanSDK/1.3.275.0/macOS/include Vulkan SDK头文件路径



添加库搜索路径

Library Search Paths

-
/usr/local/lib 使用Homebrew安装的包的库路径: glfw
/Users/<用户名>/VulkanSDK/1.3.275.0/macOS/lib Vulkan SDK库路径



添加编译时要链接的动态库

Link Binary With Libraries

Copy Files

  1. libvulkan.1.dylib 指向 libvulkan.1.3.275.dylib

  2. 将文件从Finder拖动到指定行

    路径
    glfw /usr/local/Cellar/glfw/3.3.9/lib
    vulkan /Users/<用户名>/VulkanSDK/1.3.275.0/macOS/lib

    使用open命令

    1open /usr/local/Cellar/glfw/3.3.9/lib
  3. 选择创建引用

    Copy Files




设置项目用环境变量

  1. 入口


  2. 设置环境变量

    -
    VK_LAYER_PATH /Users/<用户名>/VulkanSDK/1.3.275.0/macOS/share/vulkan/explicit_layer.d
    VK_ICD_FILENAMES /Users/<用户名>/VulkanSDK/1.3.275.0/macOS/share/vulkan/icd.d/MoltenVK_icd.json



便签

-
Mac搭建Vulkan开发环境
Mac搭建Vulkan开发环境, 附测试代码

使用CMake编译项目

  1. CMakeLists.txt

    必须使用C++ 17

     1cmake_minimum_required( VERSION 3.28 )
     2
     3project(HelloTriangle)
     4
     5set(CMAKE_CXX_STANDARD 17)
     6
     7add_executable(HelloTriangle main.cpp)
     8
     9# 添加 GLFW3 预编译库
    10add_library(glfw SHARED IMPORTED)
    11SET_TARGET_PROPERTIES(glfw PROPERTIES IMPORTED_LOCATION "/usr/local/Cellar/glfw/3.3.9/lib/libglfw.3.3.dylib")
    12
    13# Vulkan
    14find_package(Vulkan REQUIRED)
    15target_link_libraries(${PROJECT_NAME} glfw Vulkan::Vulkan)
    16
    17# copy the shader files to the cmake-build-debug folder
    18file(COPY shaders DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
  2. 项目编译

    • 项目内创建build文件夹, 编译时进入

      1mkdir build
      2cd build
    • 编译

      1cmake ..
      2make

便签

-
Mac搭建Vulkan开发环境, 使用CMake编译项目
cmake

使用Vulkan绘制三角形


3个源码文件

Vulkan Tutorial - 绘制三角形

点击即下载
C++ code
Vertex shader
Fragment shader

代码纠正


创建实例时

  1. 使能 VK_KHR_portability_enumeration
  2. VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR 置1


  • 使能插件

    在函数 getRequiredExtensions 设置要使用插件

    1if (enableValidationLayers) {
    2    extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
    3    extensions.emplace_back("VK_KHR_portability_enumeration");
    4}
  • 置1

    1// createInstance
    2createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;

创建设备时

使能 VK_KHR_portability_subset


1const std::vector<const char*> deviceExtensions = {
2    VK_KHR_SWAPCHAIN_EXTENSION_NAME,
3    "VK_KHR_portability_subset"
4};

创建实例时

使能 VK_KHR_get_physical_device_properties2


在函数 getRequiredExtensions 设置要使用插件

1if (enableValidationLayers) {
2    extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
3    extensions.emplace_back("VK_KHR_portability_enumeration");
4    extensions.emplace_back("VK_KHR_get_physical_device_properties2");
5}

生成(.spv)格式文件

  1. 安装glslang

    1brew search glslang
    2brew install glslang
  2. 从(.frag)和(.vert)文件生成(.spv)文件

    1glslangvalidator -V test.frag -o frag.spv
    2glslangvalidator -V test.vert -o vert.spv 
  3. 在项目内创建文件夹shaders, 将frag.spv和vert.spv移动到 shaders/ 目录下

  4. 确认文件路径

    1// createGraphicsPipeline
    2
    3auto vertShaderCode = readFile("shaders/vert.spv");
    4auto fragShaderCode = readFile("shaders/frag.spv");

运行



便签

-
知乎 - Vulkan三角形
知乎 -Vulkan - Triangle Setup
VK_KHR_get_physical_device_properties2的错误设置

附: 选择Vulkan的理由

之前学习《交互式计算机图形学(第六版)》时已接触过OpenGL, 大学CG课的机械臂和光照也是用OpenGL实现的, 但能进一步, 就尽量提高付出的转化率

支持Mac的游戏不多, 我在Steam下过CSGo, 跑了OpenGL例程, 觉得超级牛, 但清晰度确实不太行…

我本来想说OpenGL和Vulkan支持跨平台, 而DirectX特供Windows, Metal特供macOS, 但Mac上可以通过MoltenVK使用Vulkan SDK, 也可以学Vulkan

-
OpenGL和Vulkan比较
OpenGL和Vulkan性能评测

OpenGL的跨平台不允许开发者直接控制硬件细节, 而Vulkan和DirectX作为底层API, 都支持硬件优化, 最终呈现的效果, 则依赖于开发者的功力


附: 总结

之前也在Mac上配置过OpenGL和D3D12环境, 都没这回折腾, 但弄出来之后, 也没这回开心

同样是渲染一个基本图形, D3D12最简单, 也有少量的纠正, 可和OpenGL一样, 代码量很少

而Vulkan, 从一开始就涉及到设备参数读取和判断, 仅仅是渲染一个三角形, 近1k行代码, 而且顶点和片元数据还需要先用glslang生成(.spv)字节码

使用CMake编译项目时, 源码里使用了C++ 17的特性, 而之前学OpenGL时, 感觉自己在写C


附: 项目源码

CMake

GitHub - LearningVulkan - HelloTriangle: 使用Vulkan绘制三角形