gl4esでmainの無いシェーダーに対応したい
Framebuffer問題はあとまわしにして、wined3dは(Desktop GLでは可能な)シェーダを複数回に分けてコンパイルする手法を使ってくるようなのでそれに対応したい。
prev
問題のシェーダー
問題のシェーダーは、wined3dの関数 shader_glsl_generate_vs3_rasterizer_input_setup
でGLSLの関数 setup_vs_output
として生成される。
このシェーダーと、この関数を利用するシェーダーそれぞれ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時まで遅延して処理する ...で行けるんではないだろうか。
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.
そこそこレンダリングできるようになってきた
とりあえず不正なテクニックでIntelのVulkanドライバをロードできるようにしてかなり安定して動作するようになった。ドライバなんで死ぬと電源再投入が必要なのが辛いところだが。。
Zバッファ自体が確保されていないのが原因だった。 ... Zバッファ無しでDepthを有効にしてもframe buffer completeにはなるのか。。
テクスチャの抜けについてはピクセルシェーダの変換失敗か、そもそもメモリ確保の失敗だと思う。
現状でもまだメモリには余裕があるので、wined3d内部かな。。そもそも、
WINE_D3D_CONFIG=VideoMemorySize=512
って設定してるのに効いてないんだろうか。。