qemuのVirglをWindows上でも使いたい
qemuのソースを見ると、一応対応のためのコードは一通り入っているようだ。というわけで何とか有効にしてみる。
ビルド
適当にパッケージを足し、 --enable-sdl --enable-virglrenderer
をconfigureに足したらちゃんとビルドできた。
起動
qemu-system-x86_64.exe -vga virtio -machine q35 -smp 6 -cpu qemu64-v1 \
-accel whpx,kernel-irqchip=off -k ja -m 8192 \
-netdev user,id=net1,hostfwd=tcp:127.0.0.1:5522-:22 -device virtio-net-pci,netdev=net1 \
-drive file=alpine.qcow2,id=blk1,if=none -device virtio-blk-pci,drive=blk1 \
-device virtio-gpu-gl-pci -display sdl,gl=es
virtio-gpu-gl-pci
と display sdl,gl=es
を足す。
動かないので最新のvirglrendererをビルドする
デバッグ情報なしだと厳しいもんがあるので。。最小ビルドは想定していないようで、適当なパッチを当てた。
HEAD = 2fcee2ef2bfc91692508c9dba1ffef1dd54e7f81
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index 32ad9440..5eea7db6 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -39,6 +39,8 @@
#include "tgsi_util.h"
#include "tgsi_dump.h"
+typedef unsigned int uint; // WRONG
+
static bool is_alpha_underscore( const char *cur )
{
return
diff --git a/src/virgl_context.c b/src/virgl_context.c
index 83385ff0..0da4acd5 100644
--- a/src/virgl_context.c
+++ b/src/virgl_context.c
@@ -26,7 +26,8 @@
#include <errno.h>
-#include "util/libsync.h"
+#include <unistd.h> // WRONG
+//#include "util/libsync.h"
#include "util/os_misc.h"
#include "util/u_hash_table.h"
#include "util/u_pointer.h"
diff --git a/src/virgl_fence.c b/src/virgl_fence.c
index a22727fb..dc800e9e 100644
--- a/src/virgl_fence.c
+++ b/src/virgl_fence.c
@@ -16,6 +16,8 @@
#include "virgl_util.h"
+#include <unistd.h> // WRONG
+
#define FENCE_HUNG_CHECK_TIME_SEC 10
struct virgl_fence {
https://gitlab.freedesktop.org/virgl/virglrenderer/-/commit/d396366b30471a6e43227194f7b8c497c976162e の変更で何に失敗したのか出るようになった。
Unable to create OpenGL context >= 3.0
C:\qemugfx\qemu-system-x86_64.exe: virgl could not be initialized: 22
(qemuは、まだGLESフラグを渡していないので OpenGL
と出てしまっているが、)GLES 3.0コンテキストの生成に失敗したようだ。これは結局のところ SDL_GL_CreateContext
の失敗のようなので、SDLをビルドしないといけないな。。
window
が渡っていない
VirGLがコンテキストを作るときに (gdb) c
Continuing.
Thread 1 hit Breakpoint 1, SDL_GL_CreateContext_REAL (window=0x44fc7f60)
at E:/repos/SDL/src/video/SDL_video.c:4063
4063 {
(gdb) c
Continuing.
Thread 1 hit Breakpoint 1, SDL_GL_CreateContext_REAL (window=0x44d930a0)
at E:/repos/SDL/src/video/SDL_video.c:4063
4063 {
(gdb) c
Continuing.
Thread 1 hit Breakpoint 1, SDL_GL_CreateContext_REAL (window=0x478600a0)
at E:/repos/SDL/src/video/SDL_video.c:4063
4063 {
(gdb) c
Continuing.
[New Thread 62872.0x1858c]
warning: onecore\base\appmodel\runtime\winrt\lib\windows.applicationmodel.package.cpp(1008)\Windows.
ApplicationModel.dll!00007FFFD8B838EF: (caller: 00007FFFD8B6CAFC) ReturnHr(1) tid(492c) 80070002 指
定されたファイルが見つかりません。
warning: onecore\base\appmodel\runtime\winrt\lib\windows.applicationmodel.package.cpp(512)\Windows.A
pplicationModel.dll!00007FFFD8B83761: (caller: 00007FFF72EF1B00) ReturnHr(2) tid(492c) 80070002 指定
されたファイルが見つかりません。
[Thread 62872.0x13a0c exited with code 0]
Thread 1 hit Breakpoint 1, SDL_GL_CreateContext_REAL (window=0x0)
at E:/repos/SDL/src/video/SDL_video.c:4063
4063 {
これはココで、
real_window
がセットされていない sdl2_console
について実行されるのがバグなんだろう。。だいぶ根が深い気がしてきた。。
デバッグブレークするとホストのキーボードが効かなくなる
この辺があやしいな。。というか直球のファイルがあった:
SetWindowsHookEx
を一旦コメントアウトしておくか。。 GUI的なWindowができるまで待って、フォーカスを外してイベントループを1周させれば防げるけど。
SDL_GL_SHARE_WITH_CURRENT_CONTEXT
している
何故か EDIT: これは意図的で、SDLのOpenGLコンテキストが全windowで共有できることを前提にしている。
qemuはバックエンドがGLかGLESかに関わらず SDL_GL_SHARE_WITH_CURRENT_CONTEXT
している。これはMesaしかできない気がする。
とりあえずSDL側で無視するようにしたら先に進んだ。
glBindTexture
で死ぬ
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x00007ff60ae7a7a7 in surface_gl_update_texture (gls=0x536cd70, surface=0x33097b0, x=x@entry=0, y=y@entry=16, w=w@entry=8, h=h@entry=16) at ../ui/console-gl.c:108
#2 0x00007ff60ae84174 in sdl2_gl_update (dcl=0x48a9b60, x=0, y=16, w=8, h=16) at ../ui/sdl2-gl.c:75
#3 0x00007ff60ac188be in dpy_gfx_update (con=0x33092e0, x=<optimized out>, x@entry=0, y=<optimized out>, y@entry=16, w=<optimized out>, w@entry=8, h=<optimized out>, h@entry=16) at ../ui/console.c:819
#4 0x00007ff60ac22a81 in vc_chr_write (chr=<optimized out>, buf=<optimized out>, len=<optimized out>) at ../ui/console-vc.c:870
#5 0x00007ff60b0d4bcc in qemu_chr_write_buffer (s=s@entry=0x3309210, buf=buf@entry=0x4dab224 "\r\aツ\023\v ー", len=1, offset=offset@entry=0x466f500, write_all=false) at ../chardev/char.c:122
#6 0x00007ff60b0d5059 in qemu_chr_write (s=0x3309210, buf=buf@entry=0x4dab224 "\r\aツ\023\v ー", len=len@entry=1, write_all=<optimized out>, write_all@entry=false) at ../chardev/char.c:186
#7 0x00007ff60b0cd090 in qemu_chr_fe_write (be=be@entry=0x4dab240, buf=buf@entry=0x4dab224 "\r\aツ\023\v ー", len=len@entry=1) at ../chardev/char-fe.c:41
#8 0x00007ff60ac78dcc in serial_xmit (s=0x4dab180) at ../hw/char/serial.c:259
#9 0x00007ff60af7d236 in memory_region_write_accessor (mr=0x4dab300, addr=0, value=<optimized out>, size=1, shift=0, mask=255, attrs=...) at ../system/memory.c:497
#10 0x00007ff60af7cab1 in access_with_adjusted_size (addr=addr@entry=0, value=value@entry=0x466f7a0, size=size@entry=1, access_size_min=<optimized out>, access_size_max=1, access_fn=access_fn@entry=0x7ff60af7d1a0 <memory_region_write_accessor>,
mr=0x4dab300, attrs=...) at ../system/memory.c:573
#11 0x00007ff60af7ce97 in memory_region_dispatch_write (mr=mr@entry=0x4dab300, addr=addr@entry=0, data=<optimized out>, op=<optimized out>, attrs=attrs@entry=...) at ../system/memory.c:1528
#12 0x00007ff60af85c55 in flatview_write_continue_step (attrs=attrs@entry=..., buf=buf@entry=0x341d608 "\r", mr_addr=0, l=l@entry=0x466f890, mr=0x4dab300, len=1) at ../system/physmem.c:2757
#13 0x00007ff60af85f24 in flatview_write_continue (fv=0x5db5880, addr=1016, attrs=..., ptr=0x1, len=1, mr_addr=<optimized out>, l=<optimized out>, mr=<optimized out>) at ../system/physmem.c:2787
#14 flatview_write (fv=0x5db5880, addr=addr@entry=1016, attrs=attrs@entry=..., buf=buf@entry=0x341d608, len=len@entry=1) at ../system/physmem.c:2818
#15 0x00007ff60af88a93 in address_space_write (as=0x7ff60bf71260 <address_space_io>, addr=1016, attrs=..., buf=0x341d608, len=1) at ../system/physmem.c:2938
#16 address_space_rw (as=0x7ff60bf71260 <address_space_io>, addr=1016, attrs=attrs@entry=..., buf=0x341d608, len=<optimized out>, is_write=<optimized out>) at ../system/physmem.c:2948
#17 0x00007ff60aeb33d3 in whpx_emu_ioport_callback (ctx=<optimized out>, IoAccess=<optimized out>) at ../target/i386/whpx/whpx-all.c:783
#18 0x00007fffa18ba469 in WinHvEmulation!WHvEmulatorTryMmioEmulation () from C:\WINDOWS\SYSTEM32\WinHvEmulation.dll
#19 0x00007fffa18c0ddb in WinHvEmulation!WHvEmulatorTryMmioEmulation () from C:\WINDOWS\SYSTEM32\WinHvEmulation.dll
#20 0x00007fffa18bae15 in WinHvEmulation!WHvEmulatorTryMmioEmulation () from C:\WINDOWS\SYSTEM32\WinHvEmulation.dll
#21 0x00007fffa18b9cf3 in WinHvEmulation!WHvEmulatorTryMmioEmulation () from C:\WINDOWS\SYSTEM32\WinHvEmulation.dll
#22 0x00007fffa18b860f in WinHvEmulation!WHvEmulatorTryIoEmulation () from C:\WINDOWS\SYSTEM32\WinHvEmulation.dll
#23 0x00007ff60aeb5273 in whpx_handle_portio (cpu=0x3408dc0, ctx=0x341d500) at ../target/i386/whpx/whpx-all.c:911
#24 whpx_vcpu_run (cpu=0x3408dc0) at ../target/i386/whpx/whpx-all.c:1759
#25 whpx_vcpu_exec (cpu=cpu@entry=0x3408dc0) at ../target/i386/whpx/whpx-all.c:2264
#26 0x00007ff60aeb7608 in whpx_cpu_thread_fn (arg=arg@entry=0x3408dc0) at ../target/i386/whpx/whpx-accel-ops.c:45
#27 0x00007ff60b182955 in win32_start_routine (arg=0x3414e20) at ../util/qemu-thread-win32.c:411
#28 0x00007fffe1a41bb2 in ucrtbase!_configthreadlocale () from C:\WINDOWS\System32\ucrtbase.dll
#29 0x00007fffe3d57344 in KERNEL32!BaseThreadInitThunk () from C:\WINDOWS\System32\kernel32.dll
#30 0x00007fffe3fdcc91 in ntdll!RtlUserThreadStart () from C:\WINDOWS\SYSTEM32\ntdll.dll
#31 0x0000000000000000 in ?? ()
(gdb) f 1
#1 0x00007ff60ae7a7a7 in surface_gl_update_texture (gls=0x536cd70, surface=0x33097b0, x=x@entry=0, y=y@entry=16, w=w@entry=8, h=h@entry=16) at ../ui/console-gl.c:108
108 glBindTexture(GL_TEXTURE_2D, surface->texture);
(gdb) p surface
$1 = (DisplaySurface *) 0x33097b0
(gdb) p *surface
$2 = {image = 0x3309810, flags = 1 '\001', glformat = 32993, gltype = 5121, texture = 1, handle = 0x40c, handle_offset = 0}
(gdb) p glBindTexture
$3 = {<text variable, no debug info>} 0x7fffc1ff96b0 <glBindTexture>
これは辛いな。。glBindTexture
はOpenGL32.dllにもあるので、OpenGL32.dllのpull inをまず排除する必要がある。SDL側で切るしかないかな。。つまりMSYSのパッケージが使えないということになる。
$ cmake -DSDL_OPENGL=0 .
OpenGL的なエラーが何かある
まず kvm で正常に動かしてからtryしないとダメっぽいな。。
Running without ARB/KHR robustness in place may crash
virtio_gpu_virgl_process_cmd: ctrl 0x103, error 0x1203
virtio_gpu_virgl_process_cmd: ctrl 0x103, error 0x1203
[New Thread 71964.0x6c60]
[Thread 71964.0xdd04 exited with code 0]
[Thread 71964.0xa584 exited with code 0]
[Thread 71964.0xf680 exited with code 0]
[Thread 71964.0x3304 exited with code 0]
[New Thread 71964.0xed0c]
[New Thread 71964.0x1851c]
[New Thread 71964.0x1407c]
[New Thread 71964.0x46e8]
[New Thread 71964.0x134ec]
[New Thread 71964.0x5a40]
[New Thread 71964.0xaf0]
[New Thread 71964.0x1708]
[New Thread 71964.0xa62c]
vrend_check_no_error: context error reported 2 "gnome-shell" Unknown 1282
context 2 failed to dispatch COPY_TRANSFER3D: 22
vrend_decode_ctx_submit_cmd: context error reported 2 "gnome-shell" Illegal command buffer 917549
Wait sync failed: illegal fence object 0000000000000001
[New Thread 71964.0x10e8c]
[New Thread 71964.0x4f78]
[New Thread 71964.0x7d74]
[New Thread 71964.0xbb4c]
[New Thread 71964.0xc874]
vrend_check_no_error: context error reported 4 "Xwayland" Unknown 1282
context 4 failed to dispatch COPY_TRANSFER3D: 22
vrend_decode_ctx_submit_cmd: context error reported 4 "Xwayland" Illegal command buffer 917549
Wait sync failed: illegal fence object 0000000000000001
vrend_check_no_error: context error reported 4 "Xwayland" Unknown 1281
virtio_gpu_virgl_process_cmd: ctrl 0x103, error 0x1203
virtio_gpu_virgl_process_cmd: ctrl 0x103, error 0x1203
virtio_gpu_virgl_process_cmd: ctrl 0x103, error 0x1203
VIRTIO_GPU_CMD_SET_SCANOUT
が VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID
。
この HAVE_VIRGL_D3D_INFO_EXT
側でエラーになっている。ただ ext
は正常に埋まっているように見えるんだよなぁ。。
(gdb) p ext
$8 = {version = 0, base = {handle = 5, virgl_format = 2, width = 1280, height = 800, depth = 1, flags = 0, tex_id = 3, stride = 5120, drm_fourcc = 0, fd = -1}, has_dmabuf_export = false, planes = 0, modifiers = 0, d3d_tex2d = 0x0}
とりあえず、 d3d_tex2d
を埋める必要性は無いので一旦消したらこのエラーは無くなり、qemuのWindow自体は正常にリサイズされるようになった。
diff --git a/src/virglrenderer.c b/src/virglrenderer.c
index f701da00..330ecd8d 100644
--- a/src/virglrenderer.c
+++ b/src/virglrenderer.c
@@ -497,9 +497,11 @@ static int virgl_renderer_resource_get_info_common(int res_handle,
vrend_renderer_resource_get_info(res->pipe_resource,
(struct vrend_renderer_resource_info *)info);
+#if 0
#ifdef WIN32
if (d3d_tex2d)
ret = vrend_renderer_resource_d3d11_texture2d(res->pipe_resource, d3d_tex2d);
+#endif
#endif
return ret;
でもエラーは残っている。
vrend_check_no_error: context error reported 2 "gnome-shell" Unknown 1282
context 2 failed to dispatch COPY_TRANSFER3D: 22
vrend_decode_ctx_submit_cmd: context error reported 2 "gnome-shell" Illegal command buffer 917549
Wait sync failed: illegal fence object 0000000000000001
vrend_check_no_error: context error reported 4 "Xwayland" Unknown 1282
context 4 failed to dispatch COPY_TRANSFER3D: 22
vrend_decode_ctx_submit_cmd: context error reported 4 "Xwayland" Illegal command buffer 917549
Wait sync failed: illegal fence object 0000000000000001
[Thread 97780.0x17a0c exited with code 0]
vrend_check_no_error: context error reported 4 "Xwayland" Unknown 1281
Shared contextに戻したら動いた
けっこう常識的な速度で動作する。というかVirtualBoxの3Dより安定して高速な気がする。ただ、何故かVMの中はGLES2になってしまう(のでWebGL2は使えない)。一応DirectX11なのでGLES3.2まで行けるはずだが。。