差分

ナビゲーションに移動 検索に移動

SPIR-VからHLSLを生成する

4,121 バイト追加, 2019年11月1日 (金) 07:24
編集の要約なし
[[SPIR-V]]から様々な[[シェーディング言語]]に[[逆コンパイル]]できると色々捗ると思われる。
[[SPIR-V]]は[[HLSL]]と[[GLSL]]から生成できるので相互変換もできることになる。
[[夢が広がりんぐ]]。

==準備==
[[Vulkan]] [[SDK]]に[[SPIR-V]]から[[GLSL]]を生成する[[逆コンパイラ]]が含まれている。
まずは[[ダウンロード]]だ。今回は[[macOS]]版をダウンロードしてきた。

*https://vulkan.lunarg.com/sdk/home

Vulkan SDKを展開すると以下に逆コンパイラがある(mac版の場合)。
./macOS/bin/spirv-cross

[[SPIR-V]]ファイルは「[[DirectX Shader CompilerでSPIR-Vを出力する]]」で生成したものを使った。[[GLSL]]ではなく[[HLSL]]から生成した[[SPIR-V]]ファイルだ。


spirv-crossのHLSL変換は「[[シェーダーモデル]]3.0以降」をサポートしている。


== SM 6.0 ==
実行
<syntaxhighlight lang="bash">
./spirv-cross --hlsl --shader-model 60 light_vs.spv
</syntaxhighlight>

結果。出力用の変数にgl_PositionなどのGLSLのシステム変数名が使われている。なかなか衝撃的な[[ソースコード]]だ。
<syntaxhighlight lang="hlsl">
cbuffer type_Globals : register(b0, space0)
{
column_major float4x4 _Globals_WorldViewProjection : packoffset(c0);
};


static float4 gl_Position;
static float4 in_var_POSITION0;
static float4 in_var_COLOR0;
static float4 out_var_COLOR0;

struct SPIRV_Cross_Input
{
float4 in_var_POSITION0 : TEXCOORD0;
float4 in_var_COLOR0 : TEXCOORD1;
};

struct SPIRV_Cross_Output
{
float4 out_var_COLOR0 : TEXCOORD0;
float4 gl_Position : SV_Position;
};

void vert_main()
{
gl_Position = mul(in_var_POSITION0, _Globals_WorldViewProjection);
out_var_COLOR0 = in_var_COLOR0;
}

SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
in_var_POSITION0 = stage_input.in_var_POSITION0;
in_var_COLOR0 = stage_input.in_var_COLOR0;
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
stage_output.out_var_COLOR0 = out_var_COLOR0;
return stage_output;
}
</syntaxhighlight>

== SM 3.0 ==
実行
<syntaxhighlight lang="bash">
./spirv-cross --hlsl --shader-model 30 light_vs.spv
</syntaxhighlight>

結果。
<syntaxhighlight lang="hlsl">
cbuffer type_Globals : register(b0)
{
column_major float4x4 _Globals_WorldViewProjection : packoffset(c0);
};

uniform float4 gl_HalfPixel;

static float4 gl_Position;
static float4 in_var_POSITION0;
static float4 in_var_COLOR0;
static float4 out_var_COLOR0;

struct SPIRV_Cross_Input
{
float4 in_var_POSITION0 : TEXCOORD0;
float4 in_var_COLOR0 : TEXCOORD1;
};

struct SPIRV_Cross_Output
{
float4 out_var_COLOR0 : TEXCOORD0;
float4 gl_Position : POSITION;
};

void vert_main()
{
gl_Position = mul(in_var_POSITION0, _Globals_WorldViewProjection);
out_var_COLOR0 = in_var_COLOR0;
gl_Position.x = gl_Position.x - gl_HalfPixel.x * gl_Position.w;
gl_Position.y = gl_Position.y + gl_HalfPixel.y * gl_Position.w;
}

SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
in_var_POSITION0 = stage_input.in_var_POSITION0;
in_var_COLOR0 = stage_input.in_var_COLOR0;
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
stage_output.out_var_COLOR0 = out_var_COLOR0;
return stage_output;
}
</syntaxhighlight>

== 備考 ==
[[SPIR-V]]経由で出力したコードを比較した限りでは以下のような結論に達した。
* HLSLで書く
* HLSLはHLSLのまま使う
* HLSLからGLSLを生成する

比較量は少ないでまだ正確なことは言えないが、
GLSLで書いてHLSLへ変換という逆パターンは危険そうな雰囲気がある。

== 関連項目 ==
* [[SPIR-VからHLSLを生成する]]
* [[GLSLのversionディレクティブ一覧]]
* [[DirectX Shader CompilerでSPIR-Vを出力する]]
* [[MacでDirectX Shader Compilerをビルドする]]
* [[MacにMoltenVKを入れてVulkanを使ってみる]]

[[category: SPIR-V]]
[[category: HLSL]]
[[category: Vulkan]]
匿名利用者

案内メニュー