Open3

C-WebGL: ANGLEがVulkan上でどうやって定数の頂点Attributeを実現しているのか調査

okuokuokuoku

stride = 0 っぽい

... これ許可されてるの。。!?

問題

WebGL1というかOpenGL ESでは、頂点アトリビュートとしては配列と定数の両方を指定することができた。しかし、VulkanのAPI上は頂点属性に設定できるのはバッファのみで定数を供給する機能が存在しないため、どうやって定数を指定するのかが謎だった。

Vulkan上のOpenGL ESの先輩としてGoogleのANGLE( https://github.com/google/angle )があるので、これを使って確認してみることにした。

okuokuokuoku

実験

適当にImGuiのシェーダに余計なAttributeを追加し、C-WebGL + ANGLE + Vulkanで実行、RenderDocでトレースしてみた。

https://github.com/okuoku/yuniframe/commit/4aade04df20b6774bde2c16e25baaeb2d0f4aec5

ANGLEが出力したシェーダ

#version 450

struct _48
{
    float _m0;
    float _m1;
    float _m2;
    float _m3;
};

layout(set = 1, binding = 0, std140) uniform _30_32
{
    mat4 _m0; // ★ ProjMtx
} _32;

layout(set = 0, binding = 0, std140) uniform _49_51
{
    vec4 _m0; // ★ こちらは未使用
    uint _m1;
    uint _m2;
    int _m3;
    int _m4;
    ivec4 _m5;
    uvec4 _m6;
    _48 _m7;
} _51;

layout(location = 1) out mediump vec2 _53;
layout(location = 1) in vec2 _11;
layout(location = 0) out mediump vec4 _54;
layout(location = 2) in vec4 _17;
layout(location = 3) in vec4 _27; // ★ 追加したダミー属性(bogus)
layout(location = 0) in vec2 _36; // ★ Position
vec2 _9;
vec4 _15;
vec4 _52;

void main()
{
    _9 = _11;
    _15 = _17;
    // ★ ↓ gl_Position = bogus + ProjMtx * vec4(Position.xy,0,1);
    gl_Position = _27 + (_32._m0 * vec4(_36, 0.0, 1.0));
    _53 = _9;
    _54 = _15;
    // ★ ↓ これはZ値補正で元のシェーダコードにない
    gl_Position = vec4(gl_Position.xy, (gl_Position.z + gl_Position.w) * 0.5, gl_Position.w);
}
okuokuokuoku

観察

ダミー属性は location = 3 に追加されていた。

layout(location = 3) in vec4 _27; // ★ 追加したダミー属性(bogus)

このため、RenderDocのpipline state → VertexInput(スクリーンショットでは略記されてVTX)で location = 3 のアトリビュートを見れば良い事になる。

stride = 0 のバッファを指定している。 ... 確かにstride = 0のバッファを用意してそこに書けば、全ての頂点で同じ頂点属性を使わせることができるが、これができるという発想が無かった。。