Open4

gl4esでmainの無いシェーダーに対応したい

okuokuokuoku

問題のシェーダー

問題のシェーダーは、wined3dの関数 shader_glsl_generate_vs3_rasterizer_input_setup でGLSLの関数 setup_vs_output として生成される。

https://github.com/wine-mirror/wine/blob/983bcd96397ffb8dc10f6b229f19d78df165672a/dlls/wined3d/glsl_shader.c#L7160

このシェーダーと、この関数を利用するシェーダーそれぞれCompileしてから一緒にAttachしてLinkすることで(通常のC言語のように)シェーダーを使用できる。仕様 https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf では:

The function main is used as the entry point to a shader executable. A shader need not contain a function named main, but one shader in a set of shaders linked together to form a single shader executable must, or a link-time error results.

しかし、OpenGL ESでは、そのようなシェーダーは禁止されている。仕様 https://registry.khronos.org/OpenGL/specs/es/3.2/GLSL_ES_Specification_3.20.pdf によると:

All shaders must define a function named main.

一応コンパイルエラーをLink時に検出するのは合法なので、CompileをLink時まで遅延して処理する ...で行けるんではないだろうか。

okuokuokuoku

SwiftShader内で落ちる

シェーダーを連結することでANGLE内のコンパイルは通るようになったが、実際に描画させてみるとSwiftShader内で落ちることがわかった。

これはキツいな。。JITCしたコードの内部で落ちていて、Visual Studioのデバッガは動的生成されたデバッグ情報を喰えないので、どこで落ちたのか見当もつかない。。SwiftShaderは頂点を128プリミティブ単位でバッチ処理していて、ここでは頂点シェーダを処理していると考えられる。

VBOを使用している描画は基本的にANGLE側が用意したメモリ領域で処理していると考えられるので、いわゆるclient side arrayを使っている描画が怪しい。Vulkan側のvalidation layerとかトレースで捕まるか。。?

 	224fc884()	Unknown	No symbols loaded.
 	[Frames below may be incorrect and/or missing]		Annotated Frame
 	vk_swiftshader.dll!rr::RoutineT<void __cdecl(vk::Device const *,sw::Vertex *,unsigned int *,sw::VertexTask *,sw::DrawData *)>::operator()<vk::Device *,sw::Vertex *,unsigned int *,sw::VertexTask *,sw::DrawData *>(vk::Device * <args_0>=0x0da6b010, sw::Vertex * <args_1>=0x10a10e50, unsigned int * <args_2>=0x0dd9f768, sw::VertexTask * <args_3>=0x10e83e50, sw::DrawData * <args_4>=0x0e7f1f20) Line 60	C++	Symbols loaded.
>	vk_swiftshader.dll!sw::DrawCall::processVertices(vk::Device * device=0x0da6b010, sw::DrawCall * draw=0x0e7edc50, sw::DrawCall::BatchData * batch=0x10a10e50) Line 630	C++	Symbols loaded.
 	vk_swiftshader.dll!sw::DrawCall::run::__l4::<lambda>() Line 581	C++	Symbols loaded.
 	vk_swiftshader.dll!std::invoke<void <lambda>(void) &>(sw::DrawCall::run::__l4::void <lambda>(void) & _Obj=void <lambda>(void){...}) Line 1563	C++	Symbols loaded.
 	vk_swiftshader.dll!std::_Invoker_ret<void>::_Call<void <lambda>(void) &>(sw::DrawCall::run::__l4::void <lambda>(void) & _Func=void <lambda>(void){...}) Line 670	C++	Symbols loaded.
 	vk_swiftshader.dll!std::_Func_impl_no_alloc<void <lambda>(void),void>::_Do_call() Line 833	C++	Symbols loaded.
 	vk_swiftshader.dll!std::_Func_class<void>::operator()() Line 874	C++	Symbols loaded.
 	vk_swiftshader.dll!marl::Task::operator()() Line 98	C++	Symbols loaded.
 	vk_swiftshader.dll!marl::Scheduler::Worker::runUntilIdle() Line 707	C++	Symbols loaded.
 	vk_swiftshader.dll!marl::Scheduler::Worker::runUntilShutdown() Line 589	C++	Symbols loaded.
 	vk_swiftshader.dll!marl::Scheduler::Worker::run() Line 582	C++	Symbols loaded.
 	vk_swiftshader.dll!marl::Scheduler::Worker::start::__l5::<lambda>() Line 386	C++	Symbols loaded.
 	vk_swiftshader.dll!std::invoke<void <lambda>(void) &>(marl::Scheduler::Worker::start::__l5::void <lambda>(void) & _Obj=void <lambda>(void){...}) Line 1563	C++	Symbols loaded.
 	vk_swiftshader.dll!std::_Invoker_ret<void>::_Call<void <lambda>(void) &>(marl::Scheduler::Worker::start::__l5::void <lambda>(void) & _Func=void <lambda>(void){...}) Line 670	C++	Symbols loaded.
 	vk_swiftshader.dll!std::_Func_impl_no_alloc<void <lambda>(void),void>::_Do_call() Line 833	C++	Symbols loaded.
 	vk_swiftshader.dll!std::_Func_class<void>::operator()() Line 874	C++	Symbols loaded.
 	vk_swiftshader.dll!marl::Thread::Impl::run(void * self=0x03736e30) Line 280	C++	Symbols loaded.
 	kernel32.dll!@BaseThreadInitThunk@12()	Unknown	Symbols loaded.
 	ntdll.dll!__RtlUserThreadStart()	Unknown	Symbols loaded.
 	ntdll.dll!__RtlUserThreadStart@8()	Unknown	Symbols loaded.
okuokuokuoku

そこそこレンダリングできるようになってきた

https://github.com/okuoku/fakegl32-proto/commit/0ec60171af5567c265bd71738a35253748b9ae25

とりあえず不正なテクニックでIntelのVulkanドライバをロードできるようにしてかなり安定して動作するようになった。ドライバなんで死ぬと電源再投入が必要なのが辛いところだが。。

https://twitter.com/okuoku/status/1605542386263740416

Zバッファ自体が確保されていないのが原因だった。 ... Zバッファ無しでDepthを有効にしてもframe buffer completeにはなるのか。。

テクスチャの抜けについてはピクセルシェーダの変換失敗か、そもそもメモリ確保の失敗だと思う。

現状でもまだメモリには余裕があるので、wined3d内部かな。。そもそも、

WINE_D3D_CONFIG=VideoMemorySize=512

って設定してるのに効いてないんだろうか。。