SwiftShader を試してみた

今年 SwiftShader が Vulkan 1.1 の conformance test を通過したと聞いたので、気になって手元でも試してみることにしました。

SwiftShader とは

Google 製の CPU による Vulkan 実装というところです。次の場所で公開されています。

google/swiftshader
SwiftShader is a high-performance CPU-based implementation of the Vulkan, OpenGL ES, and Direct3D 9 graphics APIs. Its goal is to provide hardware independence ...

CPUでラスタライズ処理をするため、 GPU の機能を使用しません。そのためGPUが Vulkan 非対応の環境でも使用することができるようです。なお、 SwiftShaderは Vulkan 以外にも OpenGL ES や DirectX9 の実装も現時点では持っているようです。

ただし、そのうち Vulkan のみの対応となっていくようです。(Siggraph 2019の資料より)

vulkaninfo を実行

Windows で SwiftShader を使うようにしてみたのでその紹介です。まずは vulkaninfo の結果です。

Instance Extensions:
 Instance Extensions     count = 7
         VK_KHR_device_group_creation        : extension revision  1
         VK_KHR_external_fence_capabilities  : extension revision  1
         VK_KHR_external_memory_capabilities : extension revision  1
         VK_KHR_external_semaphore_capabilities: extension revision  1
         VK_KHR_get_physical_device_properties2: extension revision  2
         VK_KHR_surface                      : extension revision 25
         VK_KHR_win32_surface                : extension revision  6
 Layers: count = 0
 Presentable Surfaces:
 GPU id       : 0 (SwiftShader Device)
 Surface type : VK_KHR_win32_surface
 Formats:                count = 2
         B8G8R8A8_UNORM
         B8G8R8A8_SRGB
 Present Modes:          count = 1
         FIFO_KHR
 VkSurfaceCapabilitiesKHR:
 (省略)
 Groups :
========
        Device Group Properties (Group 0) :
                physicalDeviceCount = 1
                        SwiftShader Device (ID: 0)

                subsetAllocation = 0
Device Properties and Extensions :
==================================
GPU0
VkPhysicalDeviceProperties:
===========================
        apiVersion     = 0x401000  (1.1.0)
        driverVersion  = 20971520 (0x1400000)
        vendorID       = 0x1ae0
        deviceID       = 0xc0de
        deviceType     = CPU
        deviceName     = SwiftShader Device
        VkPhysicalDeviceLimits:
        -----------------------
                maxImageDimension1D                     = 8192
                maxImageDimension2D                     = 8192
                maxImageDimension3D                     = 1024
                maxImageDimensionCube                   = 8192
                maxImageArrayLayers                     = 2048
                maxTexelBufferElements                  = 0x10000
                maxUniformBufferRange                   = 0x4000

(省略)
                maxVertexInputAttributes                = 16
                maxVertexInputBindings                  = 16
                maxVertexInputAttributeOffset           = 0x7ff
                maxVertexInputBindingStride             = 0x800
                maxVertexOutputComponents               = 128
                maxTessellationGenerationLevel          = 0
                maxTessellationPatchSize                        = 0
                maxTessellationControlPerVertexInputComponents  = 0
                maxTessellationControlPerVertexOutputComponents = 0
                maxTessellationControlPerPatchOutputComponents  = 0
                maxTessellationControlTotalOutputComponents     = 0
                maxTessellationEvaluationInputComponents        = 0
                maxTessellationEvaluationOutputComponents       = 0
                maxGeometryShaderInvocations            = 0
                maxGeometryInputComponents              = 0
                maxGeometryOutputComponents             = 0
                maxGeometryOutputVertices               = 0
                maxGeometryTotalOutputComponents        = 0
                maxFragmentInputComponents              = 128
                maxFragmentOutputAttachments            = 4
(以下省略)

このような感じにあっており、 SwiftShader でのデバイスが使えそうなことがわかります。ただし、ジオメトリシェーダーやテッセレーション関連は機能がないこともこの結果より分かりました。

cube の実行

以前に Vulkan SDK に付属していたテクスチャ付き Cube 描画のサンプルを動かしてみました。垂直同期の部分がうまく機能できていませんが、動作可能でした。

この動作中は、予想通り CPU の使用率が 100 % に張り付きました。

ゲーム制作者になるための3Dグラフィックス技術 改訂3版
インプレス
¥4,400(2019/12/20 23:13時点)

他のプログラムを実行

Vulkan Programming Vol.1 で使った VRM モデルを描画するものについて、 SwiftShader 経由で動作できるかを試してみました。

結果は残念ながらそのままでは動作しませんでした。
エラー内容は、「vkCreateSwapchainKHR がダイナミックリンクライブラリから見つかりませんでした」というものです。

Vulkan SDK に付属のものと比較

何がちがっているのかを見てみました。以下のものがその比較です。
(エラー内容から当たり前のものだったりしますが…)

Vulkan SDK 付属のもの

SwiftShader で作ったもの

一部の関数が含まれていないようでした。
cube.exe がどうして動作したのかをみてみたら、直接 vkCreateSwapchainKHR を呼び出していないようでした。

GitHubでのコードを確認してみたら、vkGetProcAddr を用いて各種関数を取り出すことを期待しているようでした。( https://github.com/google/swiftshader/blob/master/src/Vulkan/VkGetProcAddress.cpp )
動的に取り出すようにしたら動くようになるものと思われます。

感想

予想よりはうまく動作できて驚きました。逆にスワップチェインに関係する部分が動的に取り出さないといけない点が予想外でした。いくつかの Vulkanのサンプルでは確かにそうしているので、マルチプラットフォームを考慮したときには、このように動的取り出しのほうが主な方法なのかもしれません。

Linux には Mesa 3D の LLVMPipe というソフトウェアレンダラーがあります。こちらはOpenGLについてのCPU実装となっています。SIMD命令も活用して割と実用的な速度で動作し、機能も揃っているので大変便利です。 Vulkan においての SwiftShader がそのようなレベルにまで進んで行ってくれることに期待しています。

Vulkan
すらりんをフォローする
すらりん日記

コメント

タイトルとURLをコピーしました