vbox6: basic 3D support

Implement GLX and X functionality through Mesa's EGL interface. This
requires multiple OpenGL contexts and in turn GEM context support in
libdrm/iris, as implemented in libdrm and intel_gpu_drv.

Update recipes and machine.vbox6 files accordingly,

issue #4380
This commit is contained in:
Sebastian Sumpf 2021-10-12 17:45:34 +02:00 committed by Norman Feske
parent 27883c976c
commit b98e07ed34
14 changed files with 319 additions and 69 deletions

View File

@ -1,6 +1,6 @@
include $(REP_DIR)/lib/mk/virtualbox6-common.inc
LIBS += stdcxx mesa
LIBS += stdcxx mesa egl virtualbox6-shaderlib
SRC_CC += Devices/Audio/AudioHlp.cpp
SRC_CC += Devices/Audio/AudioMixBuffer.cpp
@ -34,15 +34,6 @@ SRC_CC += Devices/Graphics/DevVGA_VBVA.cpp
SRC_CC += Devices/Graphics/DevVGA_VDMA.cpp
SRC_CC += Devices/Graphics/HGSMI/HGSMIHost.cpp
SRC_CC += Devices/Graphics/HGSMI/SHGSMIHost.cpp
SRC_C += Devices/Graphics/shaderlib/directx.c
SRC_C += Devices/Graphics/shaderlib/glsl_shader.c
SRC_C += Devices/Graphics/shaderlib/libWineStub/debug.c
SRC_C += Devices/Graphics/shaderlib/shader.c
SRC_C += Devices/Graphics/shaderlib/shader_sm1.c
SRC_C += Devices/Graphics/shaderlib/shader_sm4.c
SRC_C += Devices/Graphics/shaderlib/shaderapi.c
SRC_C += Devices/Graphics/shaderlib/stateblock.c
SRC_C += Devices/Graphics/shaderlib/utils.c
SRC_CC += Devices/Input/DevPS2.cpp
SRC_CC += Devices/Input/DevPS2K.cpp
SRC_CC += Devices/Input/DevPS2M.cpp
@ -129,23 +120,6 @@ INC_DIR += $(VIRTUALBOX_DIR)/include/VBox/Graphics
# found in src/VBox/Devices/Makefile.kmk
CC_OPT += -DVBOX_HGCM_HOST_CODE
# SVGA3D/wine specific config
WINE_CC_OPT := -D__WINESRC__ -DWINE_NOWINSOCK -D_USE_MATH_DEFINES \
-DVBOX_USING_WINDDK_W7_OR_LATER \
-DVBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT \
-DVBOX_WINE_WITH_IPRT \
-UVBOX_WITH_WDDM
CC_OPT_Devices/Graphics/shaderlib/directx = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/glsl_shader = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/libWineStub/debug = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/shader = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/shader_sm1 = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/shader_sm4 = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/shaderapi = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/stateblock = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/utils = $(WINE_CC_OPT)
Devices/Graphics/DevVGA.o: vbetables.h
vbetables.h: vbetables-gen

View File

@ -0,0 +1,34 @@
include $(REP_DIR)/lib/mk/virtualbox6-common.inc
SHARED_LIB = yes
LIBS = stdcxx mesa
SRC_C += Devices/Graphics/shaderlib/directx.c
SRC_C += Devices/Graphics/shaderlib/glsl_shader.c
SRC_C += Devices/Graphics/shaderlib/libWineStub/debug.c
SRC_C += Devices/Graphics/shaderlib/shader.c
SRC_C += Devices/Graphics/shaderlib/shader_sm1.c
SRC_C += Devices/Graphics/shaderlib/shader_sm4.c
SRC_C += Devices/Graphics/shaderlib/shaderapi.c
SRC_C += Devices/Graphics/shaderlib/stateblock.c
SRC_C += Devices/Graphics/shaderlib/utils.c
INC_DIR += $(VBOX_DIR)/Devices/Graphics/shaderlib/wine/include
INC_DIR += $(VIRTUALBOX_DIR)/include/VBox/Graphics
# SVGA3D/wine specific config
WINE_CC_OPT := -D__WINESRC__ -DWINE_NOWINSOCK -D_USE_MATH_DEFINES \
-DVBOX_USING_WINDDK_W7_OR_LATER \
-DVBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT \
-DVBOX_WINE_WITH_IPRT \
-UVBOX_WITH_WDDM
CC_OPT_Devices/Graphics/shaderlib/directx = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/glsl_shader = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/libWineStub/debug = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/shader = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/shader_sm1 = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/shader_sm4 = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/shaderapi = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/stateblock = $(WINE_CC_OPT)
CC_OPT_Devices/Graphics/shaderlib/utils = $(WINE_CC_OPT)

View File

@ -1 +1 @@
7991a9853bb0a96cad9a54ebaf3290dfda9ae2d2
ee399455b46b3f366f0423567e06608b0bf1a853

View File

@ -1,13 +1,17 @@
_/raw/vbox6
_/src/expat
_/src/init
_/src/jpeg
_/src/libc
_/src/libdrm
_/src/libiconv
_/src/libyuv
_/src/mesa
_/src/posix
_/src/stdcxx
_/src/vbox6
_/src/vfs
_/src/vfs_gpu
_/src/vfs_oss
_/src/vfs_pipe
_/src/zlib

View File

@ -1,10 +1,11 @@
<runtime ram="4300M" caps="2500" binary="init">
<runtime ram="4300M" caps="8000" binary="init">
<requires>
<file_system label="vm"/>
<file_system label="shared"/>
<vm/>
<timer/>
<gpu/>
<gui/>
<nic/>
<rom label="capslock"/>
@ -12,6 +13,7 @@
<report label="shape"/>
<report label="clipboard"/>
<rom label="clipboard"/>
<rom label="mesa_gpu_drv.lib.so"/>
<rm/>
<rtc/>
<rom label="usb_devices"/>
@ -30,6 +32,7 @@
<service name="LOG"/>
<service name="VM"/>
<service name="Gui"/>
<service name="Gpu"/>
<service name="Timer"/>
<service name="Rtc"/>
<service name="Report"/>
@ -44,14 +47,14 @@
<default caps="100"/>
<start name="vbox" caps="2000">
<start name="vbox" caps="7000">
<binary name="virtualbox6" />
<resource name="RAM" quantum="8G"/>
<exit propagate="yes"/>
<config vbox_file="machine.vbox6" xhci="yes" vm_name="linux" capslock="rom" ld_verbose="yes">
<vfs>
<dir name="dev">
<log/> <rtc/> <null/> <zero/> <oss name="dsp"/>
<log/> <rtc/> <null/> <gpu/> <zero/> <oss name="dsp"/>
</dir>
<dir name="pipe"> <pipe/> </dir>
<dir name="shared"> <fs label="shared" writeable="yes"/> </dir>
@ -82,6 +85,8 @@
<parent label="virtualbox6-sharedclipboard.lib.so"/> </service>
<service name="ROM" label="VBoxSharedFolders.so">
<parent label="virtualbox6-sharedfolders.lib.so"/> </service>
<service name="ROM" label="mesa_gpu_drv.lib.so">
<parent label="mesa_gpu_drv.lib.so"/> </service>
<service name="Nic"> <parent/> </service>
<service name="Report" label="shape"> <parent label="shape"/> </service>
<service name="ROM" label="clipboard"> <parent label="clipboard"/> </service>
@ -93,21 +98,29 @@
</config>
<content>
<rom label="egl.lib.so"/>
<rom label="expat.lib.so"/>
<rom label="glapi.lib.so"/>
<rom label="ld.lib.so"/>
<rom label="init"/>
<rom label="virtualbox6"/>
<rom label="jpeg.lib.so"/>
<rom label="libc.lib.so"/>
<rom label="libdrm.lib.so"/>
<rom label="libiconv.lib.so"/>
<rom label="libm.lib.so"/>
<rom label="libyuv.lib.so"/>
<rom label="mesa.lib.so"/>
<rom label="qemu-usb.lib.so"/>
<rom label="stdcxx.lib.so"/>
<rom label="vfs.lib.so"/>
<rom label="vfs_gpu.lib.so"/>
<rom label="vfs_oss.lib.so"/>
<rom label="vfs_pipe.lib.so"/>
<rom label="virtualbox6-shaderlib.lib.so"/>
<rom label="virtualbox6-sharedclipboard.lib.so"/>
<rom label="virtualbox6-sharedfolders.lib.so"/>
<rom label="zlib.lib.so"/>
</content>
</runtime>

View File

@ -17,7 +17,14 @@
</CPU>
<Memory RAMSize="4096"/>
<HID Pointing="PS2Mouse"/>
<!-- normal operation -->
<Display VRAMSize="20" monitorCount="1" controller="VBoxSVGA"/>
<!-- 3D Linux
<Display controller="VMSVGA" VRAMSize="256" accelerate3D="true"/>
-->
<!-- 3D Windows
<Display VRAMSize="128" monitorCount="1" controller="VBoxSVGA" accelerate3D="true"/>
-->
<RemoteDisplay enabled="false"/>
<Paravirt provider="KVM"/>
<BIOS>

View File

@ -6,6 +6,7 @@ gui_session
input_session
libc
libiconv
mesa
nic_session
nitpicker_gfx
os

View File

@ -1,6 +1,7 @@
/*
* \brief GLX/X11 emulation for SVGA3D
* \author Christian Helmuth
* \author Sebastian Sumpf
* \date 2021-10-01
*/
@ -27,7 +28,7 @@
/* local includes */
#include <stub_macros.h>
static bool const debug = true;
static bool const debug = false;
using namespace Genode;
@ -40,42 +41,187 @@ extern "C" int ExplicitlyLoadVBoxSVGA3D(bool fResolveAllImports, PRTERRINFO pErr
* GLX
*/
//static void impl_glXGetProcAddress(GLubyte const *procname)
//{
//}
void (*glXGetProcAddress(const GLubyte *procname))(void)
{
log(__func__, ": procname='", (char const *)procname, "'");
return (void(*)())nullptr;
}
extern "C" GLXFBConfig * glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems) STOP
extern "C" XVisualInfo * glXChooseVisual(Display *dpy, int screen, int *attribList) STOP
extern "C" GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct) STOP
extern "C" void glXDestroyContext(Display *dpy, GLXContext ctx) STOP
extern "C" int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) STOP
extern "C" XVisualInfo * glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) STOP
extern "C" Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) STOP
extern "C" Bool glXQueryVersion(Display *dpy, int *maj, int *min) STOP
typedef void (*__GLXextFuncPtr)(void);
__GLXextFuncPtr glXGetProcAddress(GLubyte const *procname)
{
return (__GLXextFuncPtr)eglGetProcAddress((char const *)procname);
}
extern "C"
Bool glXQueryVersion(Display *display, int *major, int *minor)
{
EGLBoolean initialized = eglInitialize(display->dpy, major, minor);
if (initialized)
Genode::log("EGL_VERSION = ", eglQueryString(display->dpy, EGL_VERSION));
return initialized;
}
extern "C"
XVisualInfo * glXChooseVisual(Display *display, int screen, int *attribList)
{
EGLConfig config;
EGLint config_attribs[32];
EGLint num_configs, i;
i = 0;
config_attribs[i++] = EGL_RED_SIZE;
config_attribs[i++] = 1;
config_attribs[i++] = EGL_GREEN_SIZE;
config_attribs[i++] = 1;
config_attribs[i++] = EGL_BLUE_SIZE;
config_attribs[i++] = 1;
config_attribs[i++] = EGL_DEPTH_SIZE;
config_attribs[i++] = 1;
config_attribs[i++] = EGL_SURFACE_TYPE;
config_attribs[i++] = EGL_WINDOW_BIT;
config_attribs[i++] = EGL_RENDERABLE_TYPE;
config_attribs[i++] = EGL_OPENGL_BIT;
config_attribs[i] = EGL_NONE;
if (!eglChooseConfig(display->dpy, config_attribs, &config, 1, &num_configs)
|| !num_configs) {
Genode::error("failed to choose a config");
return nullptr;
}
static XVisualInfo info { };
static Visual visual { };
visual.config = config;
info.visual = &visual;
return &info;
}
extern "C"
GLXContext glXCreateContext(Display *display, XVisualInfo *vis,
GLXContext shareList, Bool direct)
{
eglBindAPI(EGL_OPENGL_API);
EGLint context_attribs[1] { EGL_NONE };
GLXContext ctx = new _GLXContext();
ctx->context = eglCreateContext(display->dpy, vis->visual->config,
shareList ? shareList->context : EGL_NO_CONTEXT,
context_attribs);
if (!ctx->context) {
Genode::error("failed to create context");
return nullptr;
}
return ctx;
}
extern "C"
Bool glXMakeCurrent(Display *display, GLXDrawable drawable, GLXContext ctx)
{
if (!eglMakeCurrent(display->dpy,
drawable ? drawable->surface : EGL_NO_SURFACE,
drawable ? drawable->surface : EGL_NO_SURFACE,
ctx ? ctx->context : EGL_NO_CONTEXT)) {
Genode::error("failed to make current drawable");
return False;
}
//Genode::warning("glXMakeCurrent: succeeded");
return True;
}
extern "C"
void glXDestroyContext(Display *display, GLXContext ctx)
{
eglDestroyContext(display->dpy, ctx->context);
}
/*
* Xlib
*/
extern "C" Window XDefaultRootWindow(Display *) TRACE(Window());
extern "C" Colormap XCreateColormap(Display *, Window, Visual *, int) TRACE(Colormap(1));
extern "C" XErrorHandler XSetErrorHandler(XErrorHandler) TRACE(XErrorHandler(nullptr));
extern "C" int XCloseDisplay(Display *) STOP
extern "C" Colormap XCreateColormap(Display *, Window, Visual *, int) STOP
extern "C" Window XCreateWindow( Display *, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual *, unsigned long, XSetWindowAttributes *) STOP
extern "C" Window XDefaultRootWindow(Display *) STOP
extern "C" int XDestroyWindow(Display *, Window) STOP
extern "C" XErrorHandler XSetErrorHandler(XErrorHandler) STOP
extern "C" int XFree(void *) STOP
extern "C" Status XGetWindowAttributes(Display *, Window, XWindowAttributes *) STOP
extern "C" int XMapWindow(Display *, Window) STOP
extern "C" int XNextEvent(Display *, XEvent *) STOP
extern "C" Display * XOpenDisplay(char *name) STOP
extern "C" int XPending(Display *) STOP
extern "C" int XScreenNumberOfScreen(Screen *) STOP
extern "C" int XSync(Display *, Bool) STOP
extern "C" int XFree(void *) STOP
extern "C" Status XGetWindowAttributes(Display *, Window, XWindowAttributes *) STOP
extern "C" int XMapWindow(Display *, Window) STOP
extern "C" int XNextEvent(Display *, XEvent *) STOP
extern "C" int XScreenNumberOfScreen(Screen *) STOP
extern "C" int XSync(Display *, Bool) STOP
extern "C"
Display * XOpenDisplay(char *)
{
Display *display = new Display();
display->dpy = eglGetDisplay(EGLNativeDisplayType());
return display;
}
extern "C"
int XCloseDisplay(Display *display)
{
delete display;
return 0;
}
extern "C"
int XPending(Display *)
{
static bool once = true;
if (once) {
Genode::error(__func__, " called by 'vmsvga3dXEventThread' implement!");
once = false;
}
return 0;
}
extern "C"
Window XCreateWindow(Display *display, Window,
int, int,
unsigned width, unsigned height,
unsigned int, int, unsigned int,
Visual *visual, unsigned long, XSetWindowAttributes *)
{
Genode_egl_window *egl_window = new Genode_egl_window();
egl_window->width = width;
egl_window->height = height;
egl_window->type = Surface_type::WINDOW;
egl_window->addr = (unsigned char*)0xcafebabe;
Window window = new _Window();
window->window = egl_window;
window->surface = eglCreateWindowSurface(display->dpy, visual->config, egl_window, NULL);
if (window->surface == EGL_NO_SURFACE) {
Genode::error("could not create surface");
return nullptr;
}
return window;
}
extern "C" int XDestroyWindow(Display *display, Window window)
{
eglDestroySurface(display->dpy, window->surface);
delete window->window;
delete window;
return 0;
}

View File

@ -4,7 +4,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/gl.h>
#include <EGL/egl.h>
#ifdef __cplusplus
extern "C" {
@ -23,10 +23,13 @@ extern "C" {
#define GLX_WINDOW_BIT 0x00000001
#define GLX_DRAWABLE_TYPE 0x8010
typedef struct _GLXContext { void *dummy; } * GLXContext;
typedef struct _GLXContext
{
EGLContext context;
} * GLXContext;
typedef struct _GLXFBConfig { void *dummy; } * GLXFBConfig;
typedef XID GLXDrawable;
typedef Window GLXDrawable;
extern void (*glXGetProcAddress(const GLubyte *procname))(void);

View File

@ -1,6 +1,8 @@
#ifndef _X11__X_H_
#define _X11__X_H_
#include <EGL/egl.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -8,9 +10,11 @@ extern "C" {
/* originally in X11/Xmd.h */
typedef unsigned int CARD32;
struct _Window;
typedef CARD32 XID;
typedef CARD32 VisualID;
typedef XID Window;
typedef struct _Window* Window;
typedef XID Colormap;
#define None 0L

View File

@ -2,7 +2,7 @@
#define _X11__XLIB_H_
#include <X11/X.h>
#include <EGL/egl.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -12,9 +12,18 @@ extern "C" {
#define True 1
#define False 0
typedef struct { void *dummy; } Display;
typedef struct { EGLDisplay dpy; } Display;
typedef struct { void *dummy; } Screen;
typedef struct { void *dummy; } Visual;
typedef struct
{
EGLConfig config;
} Visual;
struct _Window
{
EGLSurface surface;
EGLNativeWindowType window;
};
typedef struct { unsigned char error_code; } XErrorEvent;

View File

@ -9,3 +9,5 @@ tm_poke.patch
exec_state.patch
rttimer.patch
devsvga.patch
shaderlib.patch
svga.patch

View File

@ -0,0 +1,43 @@
diff --git a/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/shader.c b/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/shader.c
index 19da2bc..1510e67 100644
--- a/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/shader.c
+++ b/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/shader.c
@@ -745,7 +745,8 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct
/* Fake sampler usage, only set reserved bit and type. */
sampler_idx = dst_param.reg.idx;
- AssertReturn(sampler_idx < RT_ELEMENTS(reg_maps->sampler_type), E_INVALIDARG);
+ /* triggers in native VirtualBox6 as well */
+ //AssertReturn(sampler_idx < RT_ELEMENTS(reg_maps->sampler_type), E_INVALIDARG);
TRACE("Setting fake 2D sampler for 1.x pixelshader.\n");
reg_maps->sampler_type[sampler_idx] = WINED3DSTT_2D;
diff --git a/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/wined3d_gl.h b/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/wined3d_gl.h
index 2fa9b12..99bd0d9 100644
--- a/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/wined3d_gl.h
+++ b/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/wined3d_gl.h
@@ -64,6 +64,11 @@
#define WINE_GLAPI
#endif
+#ifdef DECLSPEC_HIDDEN
+#undef DECLSPEC_HIDDEN
+#endif
+#define DECLSPEC_HIDDEN __attribute__((visibility("hidden")))
+
/****************************************************
* OpenGL 1.0/1.1/1.2/1.3
* types, #defines and function pointers
diff --git a/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h b/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h
index 3c7e750..bc23da2 100644
--- a/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h
+++ b/src/virtualbox6/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h
@@ -1323,7 +1323,7 @@ struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3
, struct VBOXUHGSMI *pHgsmi
#endif
) DECLSPEC_HIDDEN;
-struct IWineD3DDeviceImpl *context_get_device(const struct wined3d_context *context); DECLSPEC_HIDDEN;
+struct IWineD3DDeviceImpl *context_get_device(const struct wined3d_context *context) DECLSPEC_HIDDEN;
#ifdef VBOX_WITH_WDDM
struct wined3d_context *context_find_create(IWineD3DDeviceImpl *device, IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target,
const struct wined3d_format_desc *ds_format_desc) DECLSPEC_HIDDEN;

View File

@ -0,0 +1,10 @@
--- virtualbox6-0cabc6a3f8e2884326dabeb1768916704dfdd115/src/virtualbox6/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h 2021-01-07 16:39:17.000000000 +0100
+++ virtualbox6-devel-gpu/src/virtualbox6/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h 2021-10-12 12:06:58.895163551 +0200
@@ -88,6 +88,7 @@
#include "vmsvga/svga3d_shaderdefs.h"
#ifdef VMSVGA3D_OPENGL
+#undef GL_GLEXT_VERSION
# include "vmsvga_glext/glext.h"
# include "shaderlib/shaderlib.h"
#endif