C-WebGL: GLES2エミュレーションのデバッグ
とりあえず黒画になるまでは実装したので、トレースを取ってデバッグしていく。
正常にblitしない問題
いろいろ壊れているが、まずblitが壊れているのを直さないと絵が出ないので最優先で直す。
トレースを見てみると、頂点が正常に渡せていない。これは正常時はfull screen quad(1280x1024の四角形)でないといけない。
gl4esのBlitは glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
で実現されており、この頂点が正常に渡せていない。というわけでhost-side arrayでattributeを渡すところがバグっている。
... というか stride == 0
の扱いを間違えてるな。。gl4esでは、この頂点列を stride == 0
のarrayとして渡してくる。
これだと、頂点をいくら進めても同じアドレスのデータを送るものに見えるが、OpenGLの仕様では:
If
stride
is 0, the generic vertex attributes are understood to be tightly packed in the array.
とあるので、本来のstrideを計算して求めてやる必要がある。これVulkanと仕様違うんだな。。
とりあえず、ゼロのstrideが渡された場合はtightly packedケースで処理するように変えた。
Texcoord
は治ったみたいだけど座標がまだおかしい。。これはVisual Studioで見た結果と一致しているので、これで良いって事なのかな。。
残りのパイプラインを確認すると、ラスタライザに設定されているViewPortが異常っぽい。
これは単に再初期化時にViewportの再設定をしてないからだな。
テクスチャのアルファがおかしい
テクスチャアップロードの実装がおかしい。。?
観察してみると、Blendの状態がおかしい(無効化されている)ことがわかった。
正しくは、
C-WebGL側に手を入れて glDisable(GL_BLEND)
をできないようにしてみるとこの部分は正常に描画されるようになった(ただし背景はまだ描画されない)ので、ステートが正常にリセットできていないのが原因のようだ。
とりあえずステートのリセットを実装
真面目にANGLE側をリセットするようにしてみた。ScissorとかViewportの再設定は不要になったけど現象は改善せず。
readPixels
を適当に実装
wined3dのデバッグ出力をC-WebGLを使わなかったケースとdiffして眺めてみると、readback系のテストが軒並失敗していることがわかった。
@@ -807,19 +790,20 @@ ID[_gl4es_Fog.scale] = 6
uniform #6 : "_gl4es_Fog.scale" (builtin) type=GL_FLOAT size=1
:trace:d3d:wined3d_check_gl_call glGetTexImage call ok ../wine-src-copy/dlls/wined3d/adapter_gl.c / 794.
:trace:d3d:wined3d_check_gl_call ARBfp fog test teardown call ok ../wine-src-copy/dlls/wined3d/adapter_gl.c / 809.
-:trace:d3d:match_broken_arb_fog Fog test data: 00ff0000 00ff0000 00ff0000 00ff0000
+:trace:d3d:match_broken_arb_fog Fog test data: 00c94df0 00c94df0 0000004a 00ed2ac0
:trace:d3d:fixup_extensions Applying driver quirk "ARBfp fogstart == fogend workaround".
... 普通に実装忘れだった。ただこれを修正してもまだblend系のテストに失敗が残る。
depth != stencil チェックに失敗している
ねっとりとステップ実行したところ、
の挙動がC-WebGLと直接ANGLEを使った場合で違うことがわかった。client versionはどちらも 3.1 が指定されているものの、たしかに C-WebGL ではDepth != Stencilになっている。
確かに、 GL_OES_packed_depth_stencil
をアドバタイズしたら正常にblendを設定してくるようになった。つまりextensionをいくつかサポートしないといけないのか。。
Extensionを追加する
ログの差分を見る感じ、NPOTとかdepth textureはサポートしとかないと不味いな。。
@@ -656,14 +645,20 @@ GL4ES GetProcAddress(glVertexAttribPointer) = 7BCB255E
:trace:d3d:parse_extension_string - "GL_ARB_texture_rectangle".
:trace:d3d:parse_extension_string FOUND: GL_ARB_texture_rectangle support.
:trace:d3d:parse_extension_string - "GL_APPLE_texture_2D_limited_npot".
+:trace:d3d:parse_extension_string - "GL_ARB_texture_non_power_of_two".
+:trace:d3d:parse_extension_string FOUND: GL_ARB_texture_non_power_of_two support.
:trace:d3d:parse_extension_string - "GL_EXT_blend_color".
:trace:d3d:parse_extension_string FOUND: GL_EXT_blend_color support.
+:trace:d3d:parse_extension_string - "GL_EXT_blend_minmax".
+:trace:d3d:parse_extension_string FOUND: GL_EXT_blend_minmax support.
:trace:d3d:parse_extension_string - "GL_EXT_blend_equation_separate".
:trace:d3d:parse_extension_string FOUND: GL_EXT_blend_equation_separate support.
:trace:d3d:parse_extension_string - "GL_EXT_blend_func_separate".
:trace:d3d:parse_extension_string FOUND: GL_EXT_blend_func_separate support.
:trace:d3d:parse_extension_string - "GL_EXT_blend_subtract".
:trace:d3d:parse_extension_string FOUND: GL_EXT_blend_subtract support.
+:trace:d3d:parse_extension_string - "GL_EXT_texture_filter_anisotropic".
+:trace:d3d:parse_extension_string FOUND: GL_EXT_texture_filter_anisotropic support.
:trace:d3d:parse_extension_string - "GL_ARB_texture_mirrored_repeat".
:trace:d3d:parse_extension_string FOUND: GL_ARB_texture_mirrored_repeat support.
:trace:d3d:parse_extension_string - "GL_ARB_framebuffer_object".
@@ -683,6 +678,18 @@ GL4ES GetProcAddress(glVertexAttribPointer) = 7BCB255E
:trace:d3d:parse_extension_string - "GL_ARB_texture_cube_map".
:trace:d3d:parse_extension_string FOUND: GL_ARB_texture_cube_map support.
:trace:d3d:parse_extension_string - "GL_EXT_texture_cube_map".
+:trace:d3d:parse_extension_string - "GL_EXT_texture_rg".
+:trace:d3d:parse_extension_string - "GL_ARB_texture_rg".
+:trace:d3d:parse_extension_string FOUND: GL_ARB_texture_rg support.
+:trace:d3d:parse_extension_string - "GL_EXT_texture_float".
+:trace:d3d:parse_extension_string - "GL_ARB_texture_float".
+:trace:d3d:parse_extension_string FOUND: GL_ARB_texture_float support.
+:trace:d3d:parse_extension_string - "GL_EXT_texture_half_float".
+:trace:d3d:parse_extension_string - "GL_EXT_color_buffer_float".
+:trace:d3d:parse_extension_string - "GL_EXT_color_buffer_half_float".
+:trace:d3d:parse_extension_string - "GL_EXT_depth_texture".
+:trace:d3d:parse_extension_string - "GL_ARB_depth_texture".
+:trace:d3d:parse_extension_string FOUND: GL_ARB_depth_texture support.
:trace:d3d:parse_extension_string - "GL_EXT_fog_coord".
:trace:d3d:parse_extension_string FOUND: GL_EXT_fog_coord support.
:trace:d3d:parse_extension_string - "GL_EXT_separate_specular_color".
@@ -712,32 +719,29 @@ GL4ES GetProcAddress(glVertexAttribPointer) = 7BCB255E
:trace:d3d:parse_extension_string - "GL_ARB_fragment_program".
:trace:d3d:parse_extension_string FOUND: GL_ARB_fragment_program support.
:trace:d3d:parse_extension_string - "GL_EXT_program_parameters".
+:trace:d3d:parse_extension_string - "GL_ARB_get_program_binary".
:warn:d3d:wined3d_adapter_init_gl_caps WGL extensions not supported.
:trace:d3d:wined3d_adapter_init_gl_caps GL CORE: GL_EXT_texture3D support.
-:trace:d3d:wined3d_adapter_init_gl_caps GL CORE: GL_ARB_depth_texture support.
:trace:d3d:wined3d_adapter_init_gl_caps GL CORE: GL_ARB_shadow support.
-:trace:d3d:wined3d_adapter_init_gl_caps GL CORE: GL_EXT_blend_minmax support.
:trace:d3d:wined3d_adapter_init_gl_caps GL CORE: GL_NV_point_sprite support.
:trace:d3d:wined3d_adapter_init_gl_caps GL CORE: GL_ARB_occlusion_query support.
-:trace:d3d:wined3d_adapter_init_gl_caps GL CORE: GL_ARB_texture_non_power_of_two support.
:trace:d3d:wined3d_adapter_init_gl_caps GL CORE: GL_ARB_pixel_buffer_object support.
:trace:d3d:wined3d_adapter_init_gl_caps GL CORE: GL_EXT_texture_sRGB support.
:trace:d3d:wined3d_adapter_init_gl_caps IMPLIED: NVIDIA (NV) Texture Gen Reflection support.
:trace:d3d:wined3d_adapter_init_gl_caps Occlusion query counter has 1598834466 bits.
-proc: glGetIntegerv = 7BC91145
:trace:d3d:wined3d_adapter_init_limits Clip plane support - max planes 6.
:trace:d3d:wined3d_adapter_init_limits Light support - max lights 8.
:trace:d3d:wined3d_adapter_init_limits Maximum texture size support - max texture size 16384.
:warn:d3d_perf:wined3d_adapter_init_limits Driver doesn't guarantee a minimum buffer map alignment.
-:trace:d3d:wined3d_adapter_init_limits Max draw buffers: 1.
+:trace:d3d:wined3d_adapter_init_limits Max draw buffers: 8.
:trace:d3d:wined3d_adapter_init_limits Max textures: 8.
:trace:d3d:wined3d_adapter_init_limits Max texture coords: 8.
:trace:d3d:wined3d_adapter_init_limits Max fragment samplers: 16.
:trace:d3d:wined3d_adapter_init_limits Max vertex samplers: 32.
:trace:d3d:wined3d_adapter_init_limits Max combined samplers: 64.
-:trace:d3d:wined3d_adapter_init_limits Max vertex attributes: 32.
-Unknown enum type 8073
+:trace:d3d:wined3d_adapter_init_limits Max vertex attributes: 16.
:trace:d3d:wined3d_adapter_init_limits Max texture3D size: 2048.
+:trace:d3d:wined3d_adapter_init_limits Max anisotropy: 16.
:trace:d3d:wined3d_adapter_init_limits Max ARB_FRAGMENT_PROGRAM float constants: 24.
:trace:d3d:wined3d_adapter_init_limits Max ARB_FRAGMENT_PROGRAM native float constants: 64.
:trace:d3d:wined3d_adapter_init_limits Max ARB_FRAGMENT_PROGRAM native temporaries: 64.
とりあえず GL_OES_texture_npot
を追加したら絵は出るようになった。
それなりに動いた
次は リモート化 → リプレイ実装 かな。。なかなか遠い。。
(左の空のwindowが本来のゲーム出力で、それをYuniframeで乗っ取っている。ミニマップは直接描画時は正常に出ていなかったので、wine側のswapchainエミュレーションがちょっと怪しいな。。)