BOOL DRI3CheckExtension(Display *dpy, int major, int minor) { xcb_connection_t *xcb_connection = XGetXCBConnection(dpy); xcb_dri3_query_version_cookie_t dri3_cookie; xcb_dri3_query_version_reply_t *dri3_reply; xcb_generic_error_t *error; const xcb_query_extension_reply_t *extension; int fd; xcb_prefetch_extension_data(xcb_connection, &xcb_dri3_id); extension = xcb_get_extension_data(xcb_connection, &xcb_dri3_id); if (!(extension && extension->present)) { ERR("DRI3 extension is not present\n"); return FALSE; } dri3_cookie = xcb_dri3_query_version(xcb_connection, major, minor); dri3_reply = xcb_dri3_query_version_reply(xcb_connection, dri3_cookie, &error); if (!dri3_reply) { free(error); ERR("Issue getting requested version of DRI3: %d,%d\n", major, minor); return FALSE; } if (!DRI3Open(dpy, DefaultScreen(dpy), &fd)) { ERR("DRI3 advertised, but not working\n"); return FALSE; } close(fd); TRACE("DRI3 version %d,%d found. %d %d requested\n", major, minor, (int)dri3_reply->major_version, (int)dri3_reply->minor_version); free(dri3_reply); return TRUE; }
HRESULT d3dadapter9_new( BOOL ex, Display *dpy, IDirect3D9Ex **ppOut ) { static void * WINAPI (*pD3DAdapter9GetProc)(const char *) = NULL; static BOOL StaticInitDone = FALSE; // load dynamic library and retrieve "D3DAdapter9GetProc" symbol. if (!StaticInitDone) { StaticInitDone = TRUE; if (!PRESENTCheckExtension(dpy, 1, 0)) { ERR("Unable to query PRESENT.\n"); return D3DERR_NOTAVAILABLE; } if (!DRI3CheckExtension(dpy, 1, 0)) { #if !D3DADAPTER9_WITHDRI2 ERR("Unable to query DRI3.\n"); return D3DERR_NOTAVAILABLE; #else ERR("Unable to query DRI3. Trying DRI2 fallback (slower performance).\n"); is_dri2_fallback = 1; if (!DRI2FallbackCheckSupport(dpy)) { ERR("DRI2 fallback unsupported\n"); return D3DERR_NOTAVAILABLE; } #endif } void * handle = dlopen(D3DADAPTERPATH, RTLD_LOCAL | RTLD_NOW); if (!handle) { ERR("Failed to load d3d9 lib: %s\n", dlerror()); return D3DERR_NOTAVAILABLE; } pD3DAdapter9GetProc = dlsym(handle, "D3DAdapter9GetProc"); if (!pD3DAdapter9GetProc) { ERR("Failed to load d3d9 lib symbols\n"); return D3DERR_NOTAVAILABLE; } } int fd; #if D3DADAPTER9_WITHDRI2 if (!is_dri2_fallback && !DRI3Open(dpy, DefaultScreen(dpy), &fd)) { #else if (!DRI3Open(dpy, DefaultScreen(dpy), &fd)) { #endif ERR("DRI3Open failed (fd=%d)\n", fd); return D3DERR_NOTAVAILABLE; } #if D3DADAPTER9_WITHDRI2 if (is_dri2_fallback && !DRI2FallbackOpen(dpy, DefaultScreen(dpy), &fd)) { ERR("DRI2Open failed (fd=%d)\n", fd); return D3DERR_NOTAVAILABLE; } #endif const struct D3DAdapter9DRM *d3d9_drm = pD3DAdapter9GetProc(D3DADAPTER9DRM_NAME); if (!d3d9_drm || d3d9_drm->major_version != D3DADAPTER9DRM_MAJOR) { ERR("Your display driver doesn't support native D3D9 adapters.\n"); return D3DERR_NOTAVAILABLE; } ID3DAdapter9* adapter = NULL; HRESULT hr = d3d9_drm->create_adapter(fd, &adapter); if (FAILED(hr)) { ERR("Unable to create ID3DAdapter9 (fd=%d)\n", fd); return hr; } struct d3dadapter9 *This = calloc(1, sizeof(struct d3dadapter9)); if (!This) { ERR("Out of memory.\n"); return E_OUTOFMEMORY; } This->vtable = &d3dadapter9_vtable; This->refs = 1; This->ex = ex; This->adapter = adapter; *ppOut = (IDirect3D9Ex *)This; FIXME("\033[1;32m\nNative Direct3D 9 is active." "\nFor more information visit https://wiki.ixit.cz/d3d9\033[0m\n"); return D3D_OK; } // -------------------------------------------------------------------- static IDirect3D9Ex* SDL_Direct3DCreate9Ex_common(BOOL ex, SDL_Window *win ) { SDL_SysWMinfo info; SDL_VERSION(&info.version); SDL_bool Ok = SDL_GetWindowWMInfo(win, &info); if (!Ok) { ERR("SDL_GetWindowWMInfo failed."); return NULL; } IDirect3D9Ex *pD3D9Ex = NULL; HRESULT hr = d3dadapter9_new( ex, info.info.x11.display, &pD3D9Ex ); if (FAILED(hr)) { return NULL; } return pD3D9Ex; }