Posted at

HLSL を SPIR-V 経由で GLSL に変換してみた

More than 1 year has passed since last update.

HLSL を入力としたシェーダのトランスコンパイラをやってみたくなったので調べてみました。


準備

DirectXShaderCompiler は Windows SDK に含まれていますが、SPIR-V のコードジェネレータは含まれていないようでした。

なのでコンパイラを自分でビルドします。

前提条件や公式の手順は こちら です。

git clone https://github.com/Microsoft/DirectXShaderCompiler.git

cd DirectXShaderCompiler
git submodule update --init

.\utils\hct\hctstart.cmd <dxc-src-dir> <dxc-bin-dir>
.\utils\hct\hctbuild.cmd -spirv

<dxc-src-dir> はクローンフォルダ、<dxc-bin-dir> はビルドのための一時フォルダです。

私の環境では Windows Driver Kit はすでにインストールされていたので、hctgettaef.py の実行はスキップしました。

ビルドが成功すると <dxc-bin-dir>/Debug/bin/dxc.exe に実行ファイルが出力されます。


変換してみる

HLSLのシェーダを用意します。


test.hlsl

Texture2D txDiffuse : register(t0);

SamplerState samLinear : register(s0);

cbuffer ConstBuff : register(b0)
{
matrix mtxProj;
matrix mtxView;
matrix mtxWorld;
float4 Diffuse;
};

struct PS_INPUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
};

float4 main(PS_INPUT input) : SV_Target
{
return txDiffuse.Sample(samLinear, input.Tex)*Diffuse;
}


dxc を使って SPIR-V に変換します。

> dxc -spirv -T ps_6_0 -E main test.hlsl -Fo test.spv

spirv-cross を使って GLSL に変換します。(spirv-cross は VulkanSDK に含まれています)

> spirv-cross --version 310 --es test.spv > test.frag

以下のようなコードが出力されました。


test.frag

#version 310 es

precision mediump float;
precision highp int;

layout(binding = 0, std140) uniform type_ConstBuff
{
layout(row_major) highp mat4 mtxProj;
layout(row_major) highp mat4 mtxView;
layout(row_major) highp mat4 mtxWorld;
highp vec4 Diffuse;
} ConstBuff;

uniform highp sampler2D SPIRV_Cross_CombinedtxDiffusesamLinear;

layout(location = 0) in highp vec2 in_var_TEXCOORD;
layout(location = 0) out highp vec4 out_var_SV_Target;

void main()
{
out_var_SV_Target = texture(SPIRV_Cross_CombinedtxDiffusesamLinear, in_var_TEXCOORD) * ConstBuff.Diffuse;
}