LoginSignup
4
4

More than 5 years have passed since last update.

D言語でVulkanする件について。
https://github.com/ousttrue/VulkanOnD

d_triangle.png

もともとはDでDirectXするつもりであったのだけど、
Vulkanの機が熟したのでやってみた。

ひとつ前に書いた
Vulkanことはじめ
のC++をベタにD言語に移植したものです。

D-Vulkan
を使った。

環境は Windows10上のDMD + dub + VisualD。
64bitビルドはリンクがいろいろ嵌るので、32bitビルドに妥協。

D-Vulkanのコード生成

バインディングを手作りしたのかと思ったら、何やらpythonでコード生成している。
辿っていくとkhronosの公式APIがxmlで管理されていて、そこからpythonでCのヘッダやドキュメントを出力するシステムがあった。

D-VulkanはこれをベースにしたD言語バインディングの出力スクリプトを作っていた。

dvulkan> python.exe vkdgen.py ../Vulkan-Docs/src/spec source/dvulkan 

とするとtypes.dとfunction.dが更新される。
dvulkanに手を入れるときはvkdgen.pyに手を入れるとよい。

D-Vulkanちょっと改造

Cのコールバックにextern(C)を付けるのと、最新のxmlを使うとエクステンションが増えるのでそれを防ぐ処置など。
https://github.com/ousttrue/dvulkan

Win32Surfaceのバインディング

alias PFN_vkCreateWin32SurfaceKHR
        = extern(C) VkResult function(VkInstance instance,
                const(VkWin32SurfaceCreateInfoKHR)* pCreateInfo
                    , const(VkAllocationCallbacks)* pAllocator
                        ,VkSurfaceKHR* pSurface);
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;

auto p=vkGetInstanceProcAddr(inst.get(), "vkCreateWin32SurfaceKHR");
vkCreateWin32SurfaceKHR = cast(PFN_vkCreateWin32SurfaceKHR) p;

struct VkWin32SurfaceCreateInfoKHR
{
    VkStructureType sType = VkStructureType.VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
    const(void)* pNext;
    VkFlags flags;
    HINSTANCE hinstance;
    HWND hwnd;
};

vkdgen.pyの除外エクステンションからWin32Surfaceを外す手もあったのだけど、モジュールがプラットフォーム固有の型で汚染されるので見送り。アプリ側で手動定義した。

D-Vulkan使用上の注意

VkInstance inst;
VkResult res = vkCreateInstance(&inst_info, null, &inst);
if (res != VK_SUCCESS) {
    return null;
}
loadInstanceFunctions(inst); // <- これ

vkCreateInstanceしたらloadInstanceFunctionsを呼ばないとほとんどの関数が呼べる状態にならない。
呼ばないとnullの関数ポインタをコールしてAccessViolationが出て頭をひねることになるので注意。
他は、Cバージョンとだいたい同じなのでD固有の注意点はない。

おわり

久しぶりにDを再開したのだが、C++のコードをDに移植するのが楽すぎてびっくりした。
まるで、std::shared_ptrとstd::vectorとstd::stringが内包されたC++のような使い勝手になっている。
自分のC++のスタイルにすごくフィットしている感じで実に快適。
CのAPIに対してポインタを渡す時に、&struct, array.ptr, string.ptrとするだけでできてしまうのでわかりやすい。
C#のDllImportと比べてかなり楽に使える。
localのclass変数にscopeを付けると、structにしなくても寿命がgc管理ではなくscopeアウトまでにできるのもよい。

scope auto uniform_buffer=new BufferResource(device);

開発環境にはVisualDを使った。
VisualDのソリューションはdubで生成できる。

> dub generate visuald

ブレイクポイントを置いてステップ実行することができるので十分使える。
括弧の中で改行したときなどインデントがちょっとキモイ場合があるとか、実行時にエラーが発生すると死亡するときがあるなどまだ開発版な感じがするが使っていく。

CG方面でD言語は有望だと思うので試してみようと思っている。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4