Open8

C-WebGL: GLES2エミュレーションのデバッグ

okuokuokuoku

とりあえず黒画になるまでは実装したので、トレースを取ってデバッグしていく。

okuokuokuoku

正常にblitしない問題

いろいろ壊れているが、まずblitが壊れているのを直さないと絵が出ないので最優先で直す。

トレースを見てみると、頂点が正常に渡せていない。これは正常時はfull screen quad(1280x1024の四角形)でないといけない。

gl4esのBlitは glDrawArrays(GL_TRIANGLE_FAN, 0, 4); で実現されており、この頂点が正常に渡せていない。というわけでhost-side arrayでattributeを渡すところがバグっている。

... というか stride == 0 の扱いを間違えてるな。。gl4esでは、この頂点列を stride == 0 のarrayとして渡してくる。

https://github.com/ptitSeb/gl4es/blob/8b4f462ac0ee0aadb9c426fad78c73f97b53c103/src/gl/fpe.c#L1576-L1588

これだと、頂点をいくら進めても同じアドレスのデータを送るものに見えるが、OpenGLの仕様では:

If stride is 0, the generic vertex attributes are understood to be tightly packed in the array.

とあるので、本来のstrideを計算して求めてやる必要がある。これVulkanと仕様違うんだな。。

https://github.com/okuoku/cwgl-glue/commit/ed0ff93c83378e3ff77941054d9acfa182bf612b

とりあえず、ゼロのstrideが渡された場合はtightly packedケースで処理するように変えた。

Texcoord は治ったみたいだけど座標がまだおかしい。。これはVisual Studioで見た結果と一致しているので、これで良いって事なのかな。。

残りのパイプラインを確認すると、ラスタライザに設定されているViewPortが異常っぽい。

これは単に再初期化時にViewportの再設定をしてないからだな。

https://github.com/okuoku/cwgl-glue/commit/5830551c6b7c5ada1fd567f003b4797e2d5b4538

okuokuokuoku

テクスチャのアルファがおかしい

テクスチャアップロードの実装がおかしい。。?

観察してみると、Blendの状態がおかしい(無効化されている)ことがわかった。

正しくは、

C-WebGL側に手を入れて glDisable(GL_BLEND) をできないようにしてみるとこの部分は正常に描画されるようになった(ただし背景はまだ描画されない)ので、ステートが正常にリセットできていないのが原因のようだ。

okuokuokuoku

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系のテストに失敗が残る。

https://github.com/okuoku/cwgl-glue/commit/abce68a8e4d3ad4a338e3cfa74731f25a60fc907

okuokuokuoku

depth != stencil チェックに失敗している

ねっとりとステップ実行したところ、

https://github.com/google/angle/blob/e5671e16b83ff26b25c2a831ff9cdc3930f8c06d/src/libANGLE/Framebuffer.cpp#L1524-L1531

の挙動がC-WebGLと直接ANGLEを使った場合で違うことがわかった。client versionはどちらも 3.1 が指定されているものの、たしかに C-WebGL ではDepth != Stencilになっている。

確かに、 GL_OES_packed_depth_stencil をアドバタイズしたら正常にblendを設定してくるようになった。つまりextensionをいくつかサポートしないといけないのか。。

okuokuokuoku

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 を追加したら絵は出るようになった。

okuokuokuoku

それなりに動いた

次は リモート化 → リプレイ実装 かな。。なかなか遠い。。

(左の空のwindowが本来のゲーム出力で、それをYuniframeで乗っ取っている。ミニマップは直接描画時は正常に出ていなかったので、wine側のswapchainエミュレーションがちょっと怪しいな。。)