VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/VBoxGallium.cpp

Last change on this file was 103999, checked in by vboxsync, 6 weeks ago

Addition/3D,Additions/WINNT/Graphics: Updates for mesa-24.0.2 (not enabled yet). bugref:10606

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.1 KB
Line 
1/* $Id: VBoxGallium.cpp 103999 2024-03-22 12:38:39Z vboxsync $ */
2/** @file
3 * VirtualBox Windows Guest Mesa3D - Gallium driver interface. Constructs Gallium stack.
4 */
5
6/*
7 * Copyright (C) 2016-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include "VBoxGallium.h"
29#include <VBoxGaNine.h>
30
31#include "VBoxD3DAdapter9.h"
32#include "VBoxPresent.h"
33#include "VBoxGaD3DDevice9Ex.h"
34#include "GaDrvEnvWddm.h"
35
36#include <VBox/log.h>
37
38#include <iprt/asm.h>
39#include <iprt/string.h>
40
41#if VBOX_MESA_V_MAJOR < 24
42/*
43 * Loading Gallium state tracker and driver:
44 * 1) load the hardware driver VBoxVMSVGA or VBoxVirGL:
45 * a) get an entry point to create the pipe_screen;
46 * b) create the pipe_screen passing handles required to call the WDDM miniport driver.
47 * 2) load VBoxNine:
48 * a) get an entry point to create the ID3DAdapter interface (GaNineD3DAdapter9Create);
49 * b) create ID3DAdapter passing the pipe_screen pointer.
50 * 3) create GaDirect3D9Ex to have IDirect3DEx or GaDirect3DDevice9Ex to have IDirect3DDevice9Ex,
51 * which is returned to WDDM user mode driver to substitute wine's IDirect3DDevice9Ex.
52 */
53
54static const char *gpszNineDll =
55#ifdef VBOX_WDDM_WOW64
56 "VBoxNine-x86.dll"
57#else
58 "VBoxNine.dll"
59#endif
60;
61
62static const char *gpszSvgaDll =
63#ifdef VBOX_WDDM_WOW64
64 "VBoxSVGA-x86.dll"
65#else
66 "VBoxSVGA.dll"
67#endif
68;
69#else /* VBOX_MESA_V_MAJOR >= 24 */
70/*
71 * Loading Gallium D3D9 state tracker and driver:
72 * 1) load the state tracker DLL (VBoxNine) which contains the driver code too
73 * (they have to be in the same dll because both use and compare adresses of global constant
74 * glsl_type glsl_type_builtin_* structures from Mesa code).
75 * a) get an entry point to create the ID3DAdapter interface (GaNineD3DAdapter9Create);
76 * b) create ID3DAdapter, which will create the pipe_screen to access the driver internally.
77 * 3) create GaDirect3D9Ex to have IDirect3DEx or GaDirect3DDevice9Ex to have IDirect3DDevice9Ex,
78 * which is returned to WDDM user mode driver to substitute wine's IDirect3DDevice9Ex.
79 */
80static const char *gpszNineDll =
81#ifdef VBOX_WDDM_WOW64
82 "VBoxNine-x86.dll"
83#else
84 "VBoxNine.dll"
85#endif
86;
87#endif /* VBOX_MESA_V_MAJOR >= 24 */
88
89/**
90 * Loads a system DLL.
91 *
92 * @returns Module handle or NULL
93 * @param pszName The DLL name.
94 */
95static HMODULE loadSystemDll(const char *pszName)
96{
97 char szPath[MAX_PATH];
98 UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath));
99 size_t cbName = strlen(pszName) + 1;
100 if (cchPath + 1 + cbName > sizeof(szPath))
101 {
102 SetLastError(ERROR_FILENAME_EXCED_RANGE);
103 return NULL;
104 }
105 szPath[cchPath] = '\\';
106 memcpy(&szPath[cchPath + 1], pszName, cbName);
107 return LoadLibraryA(szPath);
108}
109
110struct VBOXGAPROC
111{
112 const char *pszName;
113 FARPROC *ppfn;
114};
115
116static HRESULT getProcAddresses(HMODULE hmod, struct VBOXGAPROC *paProcs)
117{
118 struct VBOXGAPROC *pIter = paProcs;
119 while (pIter->pszName)
120 {
121 FARPROC pfn = GetProcAddress(hmod, pIter->pszName);
122 if (pfn == NULL)
123 {
124 Log(("Failed to get the entry point: %s\n", pIter->pszName));
125 return E_FAIL;
126 }
127
128 *pIter->ppfn = pfn;
129 ++pIter;
130 }
131
132 return S_OK;
133}
134
135static HRESULT loadDll(const char *pszName, HMODULE *phmod, struct VBOXGAPROC *paProcs)
136{
137 *phmod = loadSystemDll(pszName);
138 if (!*phmod)
139 {
140 Log(("Failed to load the DLL: %s\n", pszName));
141 return E_FAIL;
142 }
143
144 return getProcAddresses(*phmod, paProcs);
145}
146
147/*
148 * GalliumStack
149 *
150 * Load Gallium dlls and provide helpers to create D3D9 interfaces and call Gallium driver API.
151 */
152class VBoxGalliumStack: public IGalliumStack
153{
154 public:
155 VBoxGalliumStack();
156 virtual ~VBoxGalliumStack();
157
158 HRESULT Load();
159
160 /* IUnknown methods */
161 STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj);
162 STDMETHOD_(ULONG,AddRef)(THIS);
163 STDMETHOD_(ULONG,Release)(THIS);
164
165 /* IGalliumStack */
166 STDMETHOD(CreateDirect3DEx)(HANDLE hAdapter,
167 HANDLE hDevice,
168 const D3DDDI_DEVICECALLBACKS *pDeviceCallbacks,
169 const VBOXGAHWINFO *pHWInfo,
170 IDirect3D9Ex **ppOut);
171 STDMETHOD(GaCreateDeviceEx)(THIS_
172 D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,
173 D3DPRESENT_PARAMETERS* pPresentationParameters,
174 D3DDISPLAYMODEEX* pFullscreenDisplayMode,
175 HANDLE hAdapter,
176 HANDLE hDevice,
177 const D3DDDI_DEVICECALLBACKS *pDeviceCallbacks,
178 const VBOXGAHWINFO *pHWInfo,
179 IDirect3DDevice9Ex** ppReturnedDeviceInterface);
180
181#if VBOX_MESA_V_MAJOR < 24
182 STDMETHOD(GaNineD3DAdapter9Create)(struct pipe_screen *s, ID3DAdapter9 **ppOut);
183 STDMETHOD_(struct pipe_resource *, GaNinePipeResourceFromSurface)(IUnknown *pSurface);
184 STDMETHOD_(struct pipe_context *, GaNinePipeContextFromDevice)(IDirect3DDevice9 *pDevice);
185#else
186 STDMETHOD(GaNineD3DAdapter9Create)(const WDDMGalliumDriverEnv *pEnv, ID3DAdapter9 **ppOut);
187 STDMETHOD_(uint32_t, GaNineGetSurfaceId)(IUnknown *pSurface);
188 STDMETHOD_(uint32_t, GaNineGetContextId)(IDirect3DDevice9 *pDevice);
189 STDMETHOD_(void, GaNineFlush)(IDirect3DDevice9 *pDevice);
190#endif
191
192#if VBOX_MESA_V_MAJOR < 24
193 STDMETHOD_(struct pipe_screen *, GaDrvScreenCreate)(const WDDMGalliumDriverEnv *pEnv);
194 STDMETHOD_(void, GaDrvScreenDestroy)(struct pipe_screen *s);
195 STDMETHOD_(WDDMGalliumDriverEnv const *, GaDrvGetWDDMEnv)(struct pipe_screen *pScreen);
196 STDMETHOD_(uint32_t, GaDrvGetContextId)(struct pipe_context *pPipeContext);
197 STDMETHOD_(uint32_t, GaDrvGetSurfaceId)(struct pipe_screen *pScreen, struct pipe_resource *pResource);
198 STDMETHOD_(void, GaDrvContextFlush)(struct pipe_context *pPipeContext);
199#endif
200
201 private:
202 void unload();
203
204 volatile ULONG mcRefs;
205
206 HMODULE mhmodStateTracker;
207#if VBOX_MESA_V_MAJOR < 24
208 HMODULE mhmodDriver;
209#endif
210
211 struct GaNineFunctions
212 {
213#if VBOX_MESA_V_MAJOR < 24
214 PFNGaNineD3DAdapter9Create pfnGaNineD3DAdapter9Create;
215 PFNGaNinePipeResourceFromSurface pfnGaNinePipeResourceFromSurface;
216 PFNGaNinePipeContextFromDevice pfnGaNinePipeContextFromDevice;
217#else
218 PFNGaNineD3DAdapter9Create pfnGaNineD3DAdapter9Create;
219 PFNGaNineGetSurfaceId pfnGaNineGetSurfaceId;
220 PFNGaNineGetContextId pfnGaNineGetContextId;
221 PFNGaNineFlush pfnGaNineFlush;
222#endif
223 } mNine;
224
225#if VBOX_MESA_V_MAJOR < 24
226 struct GaDrvFunctions
227 {
228 PFNGaDrvScreenCreate pfnGaDrvScreenCreate;
229 PFNGaDrvScreenDestroy pfnGaDrvScreenDestroy;
230 PFNGaDrvGetWDDMEnv pfnGaDrvGetWDDMEnv;
231 PFNGaDrvGetContextId pfnGaDrvGetContextId;
232 PFNGaDrvGetSurfaceId pfnGaDrvGetSurfaceId;
233 PFNGaDrvContextFlush pfnGaDrvContextFlush;
234 } mDrv;
235#endif
236};
237
238
239/*
240 * IDirect3D9Ex implementation corresponds to one WDDM device.
241 */
242class GaDirect3D9Ex: public IGaDirect3D9Ex
243{
244 public:
245 GaDirect3D9Ex(VBoxGalliumStack *pStack);
246 virtual ~GaDirect3D9Ex();
247
248 HRESULT Init(HANDLE hAdapter,
249 HANDLE hDevice,
250 const D3DDDI_DEVICECALLBACKS *pDeviceCallbacks,
251 const VBOXGAHWINFO *pHWInfo);
252
253 /*** IUnknown methods ***/
254 STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj);
255 STDMETHOD_(ULONG,AddRef)(THIS);
256 STDMETHOD_(ULONG,Release)(THIS);
257
258 /*** IDirect3D9 methods ***/
259 STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction);
260 STDMETHOD_(UINT, GetAdapterCount)(THIS);
261 STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier);
262 STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format);
263 STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode);
264 STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode);
265 STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,
266 D3DFORMAT BackBufferFormat,BOOL bWindowed);
267 STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,
268 DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat);
269 STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,
270 BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels);
271 STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,
272 D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat);
273 STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,
274 D3DFORMAT TargetFormat);
275 STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps);
276 STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter);
277 STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,
278 DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,
279 IDirect3DDevice9** ppReturnedDeviceInterface);
280
281 /*** IDirect3D9Ex methods ***/
282 STDMETHOD_(UINT, GetAdapterModeCountEx)(THIS_ UINT Adapter,CONST D3DDISPLAYMODEFILTER* pFilter);
283 STDMETHOD(EnumAdapterModesEx)(THIS_ UINT Adapter,CONST D3DDISPLAYMODEFILTER* pFilter,
284 UINT Mode,D3DDISPLAYMODEEX* pMode);
285 STDMETHOD(GetAdapterDisplayModeEx)(THIS_ UINT Adapter,D3DDISPLAYMODEEX* pMode,D3DDISPLAYROTATION* pRotation);
286 STDMETHOD(CreateDeviceEx)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,
287 D3DPRESENT_PARAMETERS* pPresentationParameters,
288 D3DDISPLAYMODEEX* pFullscreenDisplayMode,
289 IDirect3DDevice9Ex** ppReturnedDeviceInterface);
290 STDMETHOD(GetAdapterLUID)(THIS_ UINT Adapter,LUID * pLUID);
291
292 /* IGaDirect3D9Ex methods */
293 STDMETHOD_(IGalliumStack *, GetGalliumStack)(THIS);
294 STDMETHOD_(ID3DAdapter9 *, GetAdapter9)(THIS);
295#if VBOX_MESA_V_MAJOR < 24
296 STDMETHOD_(struct pipe_screen *, GetScreen)(THIS);
297#else
298 STDMETHOD_(const WDDMGalliumDriverEnv *, GetWDDMEnv)(THIS);
299#endif
300
301 private:
302 void cleanup();
303
304 volatile ULONG mcRefs;
305
306 VBoxGalliumStack *mpStack;
307#if VBOX_MESA_V_MAJOR < 24
308 struct pipe_screen *mpPipeScreen;
309#endif
310 ID3DAdapter9 *mpD3DAdapter9;
311
312 /* The Gallium driver environment helper object. */
313 GaDrvEnvWddm mEnv;
314};
315
316
317/*
318 * VBoxGalliumStack implementation.
319 */
320
321VBoxGalliumStack::VBoxGalliumStack()
322 :
323 mcRefs(0)
324 , mhmodStateTracker(0)
325#if VBOX_MESA_V_MAJOR < 24
326 , mhmodDriver(0)
327#endif
328{
329 RT_ZERO(mNine);
330#if VBOX_MESA_V_MAJOR < 24
331 RT_ZERO(mDrv);
332#endif
333}
334
335VBoxGalliumStack::~VBoxGalliumStack()
336{
337 unload();
338}
339
340STDMETHODIMP_(ULONG) VBoxGalliumStack::AddRef()
341{
342 ULONG refs = InterlockedIncrement(&mcRefs);
343 return refs;
344}
345
346STDMETHODIMP_(ULONG) VBoxGalliumStack::Release()
347{
348 ULONG refs = InterlockedDecrement(&mcRefs);
349 if (refs == 0)
350 {
351 delete this;
352 }
353 return refs;
354}
355
356STDMETHODIMP VBoxGalliumStack::QueryInterface(REFIID riid,
357 void **ppvObject)
358{
359 if (!ppvObject)
360 {
361 return E_POINTER;
362 }
363
364 if (IsEqualGUID(IID_IUnknown, riid))
365 {
366 AddRef();
367 *ppvObject = this;
368 return S_OK;
369 }
370
371 *ppvObject = NULL;
372 return E_NOINTERFACE;
373}
374
375HRESULT VBoxGalliumStack::Load()
376{
377 struct VBOXGAPROC aNineProcs[] =
378 {
379#if VBOX_MESA_V_MAJOR < 24
380 { "GaNineD3DAdapter9Create", (FARPROC *)&mNine.pfnGaNineD3DAdapter9Create },
381 { "GaNinePipeResourceFromSurface", (FARPROC *)&mNine.pfnGaNinePipeResourceFromSurface },
382 { "GaNinePipeContextFromDevice", (FARPROC *)&mNine.pfnGaNinePipeContextFromDevice },
383#else
384 { "GaNineD3DAdapter9Create", (FARPROC *)&mNine.pfnGaNineD3DAdapter9Create },
385 { "GaNineGetSurfaceId", (FARPROC *)&mNine.pfnGaNineGetSurfaceId },
386 { "GaNineGetContextId", (FARPROC *)&mNine.pfnGaNineGetContextId },
387 { "GaNineFlush", (FARPROC *)&mNine.pfnGaNineFlush },
388#endif
389 { NULL, NULL }
390 };
391
392#if VBOX_MESA_V_MAJOR < 24
393 struct VBOXGAPROC aDrvProcs[] =
394 {
395 { "GaDrvScreenCreate", (FARPROC *)&mDrv.pfnGaDrvScreenCreate },
396 { "GaDrvScreenDestroy", (FARPROC *)&mDrv.pfnGaDrvScreenDestroy },
397 { "GaDrvGetWDDMEnv", (FARPROC *)&mDrv.pfnGaDrvGetWDDMEnv },
398 { "GaDrvGetContextId", (FARPROC *)&mDrv.pfnGaDrvGetContextId },
399 { "GaDrvGetSurfaceId", (FARPROC *)&mDrv.pfnGaDrvGetSurfaceId },
400 { "GaDrvContextFlush", (FARPROC *)&mDrv.pfnGaDrvContextFlush },
401 { NULL, NULL }
402 };
403
404 /** @todo Select the driver dll according to the hardware. */
405 const char *pszDriverDll = gpszSvgaDll;
406
407 HRESULT hr = loadDll(pszDriverDll, &mhmodDriver, aDrvProcs);
408 if (SUCCEEDED(hr))
409 {
410 hr = loadDll(gpszNineDll, &mhmodStateTracker, aNineProcs);
411 }
412#else
413 HRESULT hr = loadDll(gpszNineDll, &mhmodStateTracker, aNineProcs);
414#endif
415
416 return hr;
417}
418
419void VBoxGalliumStack::unload()
420{
421 RT_ZERO(mNine);
422#if VBOX_MESA_V_MAJOR < 24
423 RT_ZERO(mDrv);
424#endif
425
426 if (mhmodStateTracker)
427 {
428 FreeLibrary(mhmodStateTracker);
429 mhmodStateTracker = 0;
430 }
431
432#if VBOX_MESA_V_MAJOR < 24
433 if (mhmodDriver)
434 {
435 FreeLibrary(mhmodDriver);
436 mhmodDriver = 0;
437 }
438#endif
439}
440
441#if VBOX_MESA_V_MAJOR < 24
442STDMETHODIMP VBoxGalliumStack::GaNineD3DAdapter9Create(struct pipe_screen *s,
443 ID3DAdapter9 **ppOut)
444{
445 return mNine.pfnGaNineD3DAdapter9Create(s, ppOut);
446}
447
448STDMETHODIMP_(struct pipe_resource *) VBoxGalliumStack::GaNinePipeResourceFromSurface(IUnknown *pSurface)
449{
450 return mNine.pfnGaNinePipeResourceFromSurface(pSurface);
451}
452
453STDMETHODIMP_(struct pipe_context *) VBoxGalliumStack::GaNinePipeContextFromDevice(IDirect3DDevice9 *pDevice)
454{
455 return mNine.pfnGaNinePipeContextFromDevice(pDevice);
456}
457#else
458STDMETHODIMP VBoxGalliumStack::GaNineD3DAdapter9Create(const WDDMGalliumDriverEnv *pEnv,
459 ID3DAdapter9 **ppOut)
460{
461 return mNine.pfnGaNineD3DAdapter9Create(pEnv, ppOut);
462}
463
464STDMETHODIMP_(uint32_t) VBoxGalliumStack::GaNineGetSurfaceId(IUnknown *pSurface)
465{
466 return mNine.pfnGaNineGetSurfaceId(pSurface);
467}
468
469STDMETHODIMP_(uint32_t) VBoxGalliumStack::GaNineGetContextId(IDirect3DDevice9 *pDevice)
470{
471 return mNine.pfnGaNineGetContextId(pDevice);
472}
473
474STDMETHODIMP_(void) VBoxGalliumStack::GaNineFlush(IDirect3DDevice9 *pDevice)
475{
476 return mNine.pfnGaNineFlush(pDevice);
477}
478#endif
479
480#if VBOX_MESA_V_MAJOR < 24
481STDMETHODIMP_(struct pipe_screen *) VBoxGalliumStack::GaDrvScreenCreate(const WDDMGalliumDriverEnv *pEnv)
482{
483 return mDrv.pfnGaDrvScreenCreate(pEnv);
484}
485
486STDMETHODIMP_(void) VBoxGalliumStack::GaDrvScreenDestroy(struct pipe_screen *s)
487{
488 mDrv.pfnGaDrvScreenDestroy(s);
489}
490
491STDMETHODIMP_(WDDMGalliumDriverEnv const *) VBoxGalliumStack::GaDrvGetWDDMEnv(struct pipe_screen *pScreen)
492{
493 return mDrv.pfnGaDrvGetWDDMEnv(pScreen);
494}
495
496STDMETHODIMP_(uint32_t) VBoxGalliumStack::GaDrvGetContextId(struct pipe_context *pPipeContext)
497{
498 return mDrv.pfnGaDrvGetContextId(pPipeContext);
499}
500
501STDMETHODIMP_(uint32_t) VBoxGalliumStack::GaDrvGetSurfaceId(struct pipe_screen *pScreen,
502 struct pipe_resource *pResource)
503{
504 return mDrv.pfnGaDrvGetSurfaceId(pScreen, pResource);
505}
506
507STDMETHODIMP_(void) VBoxGalliumStack::GaDrvContextFlush(struct pipe_context *pPipeContext)
508{
509 mDrv.pfnGaDrvContextFlush(pPipeContext);
510}
511#endif
512
513STDMETHODIMP VBoxGalliumStack::CreateDirect3DEx(HANDLE hAdapter,
514 HANDLE hDevice,
515 const D3DDDI_DEVICECALLBACKS *pDeviceCallbacks,
516 const VBOXGAHWINFO *pHWInfo,
517 IDirect3D9Ex **ppOut)
518{
519 GaDirect3D9Ex *p = new GaDirect3D9Ex(this);
520 if (!p)
521 return E_OUTOFMEMORY;
522
523 HRESULT hr = p->Init(hAdapter, hDevice, pDeviceCallbacks, pHWInfo);
524 if (SUCCEEDED(hr))
525 {
526 p->AddRef();
527 *ppOut = p;
528 }
529 else
530 {
531 delete p;
532 }
533
534 return hr;
535}
536
537STDMETHODIMP VBoxGalliumStack::GaCreateDeviceEx(D3DDEVTYPE DeviceType,
538 HWND hFocusWindow,
539 DWORD BehaviorFlags,
540 D3DPRESENT_PARAMETERS* pPresentationParameters,
541 D3DDISPLAYMODEEX* pFullscreenDisplayMode,
542 HANDLE hAdapter,
543 HANDLE hDevice,
544 const D3DDDI_DEVICECALLBACKS *pDeviceCallbacks,
545 const VBOXGAHWINFO *pHWInfo,
546 IDirect3DDevice9Ex **ppReturnedDeviceInterface)
547{
548 /* Create the per-WDDM-device gallium adapter. */
549 IGaDirect3D9Ex *pD3D9 = NULL;
550 HRESULT hr = CreateDirect3DEx(hAdapter,
551 hDevice,
552 pDeviceCallbacks,
553 pHWInfo,
554 (IDirect3D9Ex **)&pD3D9);
555 if (SUCCEEDED(hr))
556 {
557 /* Create wrapper object for IDirect3DDevice9Ex */
558 GaDirect3DDevice9Ex *p = new GaDirect3DDevice9Ex(pD3D9, hAdapter, hDevice, pDeviceCallbacks);
559 if (p)
560 {
561 hr = p->Init(DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, pFullscreenDisplayMode);
562 if (SUCCEEDED(hr))
563 {
564 p->AddRef();
565 *ppReturnedDeviceInterface = p;
566 }
567 else
568 {
569 delete p;
570 }
571 }
572 else
573 {
574 hr = E_OUTOFMEMORY;
575 }
576
577 pD3D9->Release();
578 }
579
580 return hr;
581}
582
583HRESULT GalliumStackCreate(IGalliumStack **ppOut)
584{
585 VBoxGalliumStack *p = new VBoxGalliumStack();
586 if (!p)
587 return E_OUTOFMEMORY;
588
589 HRESULT hr = p->Load();
590 if (SUCCEEDED(hr))
591 {
592 p->AddRef();
593 *ppOut = p;
594 }
595 else
596 {
597 delete p;
598 }
599
600 return hr;
601}
602
603
604/*
605 * GaDirect3D9Ex
606 *
607 * IDirect3D9Ex implementation based on Gallium D3D9 state tracker "nine".
608 */
609
610GaDirect3D9Ex::GaDirect3D9Ex(VBoxGalliumStack *pStack)
611 :
612 mcRefs(0),
613 mpStack(pStack),
614#if VBOX_MESA_V_MAJOR < 24
615 mpPipeScreen(0),
616#endif
617 mpD3DAdapter9(0)
618{
619 mpStack->AddRef();
620}
621
622GaDirect3D9Ex::~GaDirect3D9Ex()
623{
624 cleanup();
625}
626
627STDMETHODIMP_(ULONG) GaDirect3D9Ex::AddRef()
628{
629 ULONG refs = InterlockedIncrement(&mcRefs);
630 return refs;
631}
632
633STDMETHODIMP_(ULONG) GaDirect3D9Ex::Release()
634{
635 ULONG refs = InterlockedDecrement(&mcRefs);
636 if (refs == 0)
637 {
638 delete this;
639 }
640 return refs;
641}
642
643STDMETHODIMP GaDirect3D9Ex::QueryInterface(REFIID riid,
644 void **ppvObject)
645{
646 if (!ppvObject)
647 {
648 return E_POINTER;
649 }
650
651 if ( IsEqualGUID(IID_IGaDirect3D9Ex, riid)
652 || IsEqualGUID(IID_IDirect3D9Ex, riid)
653 || IsEqualGUID(IID_IDirect3D9, riid)
654 || IsEqualGUID(IID_IUnknown, riid))
655 {
656 AddRef();
657 *ppvObject = this;
658 return S_OK;
659 }
660
661 *ppvObject = NULL;
662 return E_NOINTERFACE;
663}
664
665HRESULT GaDirect3D9Ex::Init(HANDLE hAdapter,
666 HANDLE hDevice,
667 const D3DDDI_DEVICECALLBACKS *pDeviceCallbacks,
668 const VBOXGAHWINFO *pHWInfo)
669{
670 LogFunc(("%p %p %p\n", hAdapter, hDevice, pDeviceCallbacks));
671
672 HRESULT hr;
673
674 mEnv.Init(hAdapter, hDevice, pDeviceCallbacks, pHWInfo);
675 const WDDMGalliumDriverEnv *pEnv = mEnv.Env();
676
677#if VBOX_MESA_V_MAJOR < 24
678 mpPipeScreen = mpStack->GaDrvScreenCreate(pEnv);
679 if (mpPipeScreen)
680 {
681 hr = mpStack->GaNineD3DAdapter9Create(mpPipeScreen, &mpD3DAdapter9);
682 Assert(SUCCEEDED(hr));
683 }
684 else
685 {
686 hr = E_FAIL;
687 AssertFailed();
688 }
689#else
690 hr = mpStack->GaNineD3DAdapter9Create(pEnv, &mpD3DAdapter9);
691 Assert(SUCCEEDED(hr));
692#endif
693
694 return hr;
695}
696
697void GaDirect3D9Ex::cleanup()
698{
699 if (mpD3DAdapter9)
700 {
701 D3DAdapter9_Release(mpD3DAdapter9);
702 mpD3DAdapter9 = NULL;
703 }
704
705#if VBOX_MESA_V_MAJOR < 24
706 if (mpPipeScreen)
707 {
708 mpStack->GaDrvScreenDestroy(mpPipeScreen);
709 mpPipeScreen = NULL;
710 }
711#endif
712
713 if (mpStack)
714 {
715 mpStack->Release();
716 mpStack = 0;
717 }
718}
719
720#define TRAPNOTIMPL do { \
721 ASMBreakpoint(); \
722} while (0)
723
724
725STDMETHODIMP GaDirect3D9Ex::RegisterSoftwareDevice(void *pInitializeFunction)
726{
727 RT_NOREF(pInitializeFunction);
728 TRAPNOTIMPL;
729 return D3DERR_INVALIDCALL;
730}
731
732STDMETHODIMP_(UINT) GaDirect3D9Ex::GetAdapterCount()
733{
734 TRAPNOTIMPL;
735 return 1;
736}
737
738STDMETHODIMP GaDirect3D9Ex::GetAdapterIdentifier(UINT Adapter,
739 DWORD Flags,
740 D3DADAPTER_IDENTIFIER9 *pIdentifier)
741{
742 RT_NOREF3(Adapter, Flags, pIdentifier);
743 TRAPNOTIMPL;
744 return D3DERR_INVALIDCALL;
745}
746
747STDMETHODIMP_(UINT) GaDirect3D9Ex::GetAdapterModeCount(UINT Adapter,
748 D3DFORMAT Format)
749{
750 RT_NOREF2(Adapter, Format);
751 TRAPNOTIMPL;
752 return 1;
753}
754
755STDMETHODIMP GaDirect3D9Ex::EnumAdapterModes(UINT Adapter,
756 D3DFORMAT Format,
757 UINT Mode,
758 D3DDISPLAYMODE *pMode)
759{
760 RT_NOREF4(Adapter, Format, Mode, pMode);
761 TRAPNOTIMPL;
762 return D3DERR_INVALIDCALL;
763}
764
765STDMETHODIMP GaDirect3D9Ex::GetAdapterDisplayMode(UINT Adapter,
766 D3DDISPLAYMODE *pMode)
767{
768 RT_NOREF2(Adapter, pMode);
769 TRAPNOTIMPL;
770 return D3DERR_INVALIDCALL;
771}
772
773STDMETHODIMP GaDirect3D9Ex::CheckDeviceType(UINT iAdapter,
774 D3DDEVTYPE DevType,
775 D3DFORMAT DisplayFormat,
776 D3DFORMAT BackBufferFormat,
777 BOOL bWindowed)
778{
779 RT_NOREF5(iAdapter, DevType, DisplayFormat, BackBufferFormat, bWindowed);
780 TRAPNOTIMPL;
781 return D3DERR_INVALIDCALL;
782}
783
784STDMETHODIMP GaDirect3D9Ex::CheckDeviceFormat(UINT Adapter,
785 D3DDEVTYPE DeviceType,
786 D3DFORMAT AdapterFormat,
787 DWORD Usage,
788 D3DRESOURCETYPE RType,
789 D3DFORMAT CheckFormat)
790{
791 RT_NOREF6(Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat);
792 TRAPNOTIMPL;
793 return D3DERR_INVALIDCALL;
794}
795
796STDMETHODIMP GaDirect3D9Ex::CheckDeviceMultiSampleType(UINT Adapter,
797 D3DDEVTYPE DeviceType,
798 D3DFORMAT SurfaceFormat,
799 BOOL Windowed,
800 D3DMULTISAMPLE_TYPE MultiSampleType,
801 DWORD *pQualityLevels)
802{
803 RT_NOREF6(Adapter, DeviceType, SurfaceFormat, Windowed, MultiSampleType, pQualityLevels);
804 TRAPNOTIMPL;
805 return D3DERR_INVALIDCALL;
806}
807
808STDMETHODIMP GaDirect3D9Ex::CheckDepthStencilMatch(UINT Adapter,
809 D3DDEVTYPE DeviceType,
810 D3DFORMAT AdapterFormat,
811 D3DFORMAT RenderTargetFormat,
812 D3DFORMAT DepthStencilFormat)
813{
814 RT_NOREF5(Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat);
815 TRAPNOTIMPL;
816 return D3DERR_INVALIDCALL;
817}
818
819STDMETHODIMP GaDirect3D9Ex::CheckDeviceFormatConversion(UINT Adapter,
820 D3DDEVTYPE DeviceType,
821 D3DFORMAT SourceFormat,
822 D3DFORMAT TargetFormat)
823{
824 RT_NOREF4(Adapter, DeviceType, SourceFormat, TargetFormat);
825 TRAPNOTIMPL;
826 return D3DERR_INVALIDCALL;
827}
828
829STDMETHODIMP GaDirect3D9Ex::GetDeviceCaps(UINT Adapter,
830 D3DDEVTYPE DeviceType,
831 D3DCAPS9 *pCaps)
832{
833 RT_NOREF(Adapter);
834 HRESULT hr = D3DAdapter9_GetDeviceCaps(mpD3DAdapter9, DeviceType, pCaps);
835 return hr;
836}
837
838STDMETHODIMP_(HMONITOR) GaDirect3D9Ex::GetAdapterMonitor(UINT Adapter)
839{
840 RT_NOREF(Adapter);
841 TRAPNOTIMPL;
842 return NULL;
843}
844
845STDMETHODIMP GaDirect3D9Ex::CreateDevice(UINT Adapter,
846 D3DDEVTYPE DeviceType,
847 HWND hFocusWindow,
848 DWORD BehaviorFlags,
849 D3DPRESENT_PARAMETERS *pPresentationParameters,
850 IDirect3DDevice9 **ppReturnedDeviceInterface)
851{
852 return CreateDeviceEx(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters,
853 NULL, (IDirect3DDevice9Ex **)ppReturnedDeviceInterface);
854}
855
856STDMETHODIMP_(UINT) GaDirect3D9Ex::GetAdapterModeCountEx(UINT Adapter,
857 CONST D3DDISPLAYMODEFILTER *pFilter)
858{
859 RT_NOREF2(Adapter, pFilter);
860 TRAPNOTIMPL;
861 return 1;
862}
863
864STDMETHODIMP GaDirect3D9Ex::EnumAdapterModesEx(UINT Adapter,
865 CONST D3DDISPLAYMODEFILTER *pFilter,
866 UINT Mode,
867 D3DDISPLAYMODEEX *pMode)
868{
869 RT_NOREF4(Adapter, pFilter, Mode, pMode);
870 TRAPNOTIMPL;
871 return D3DERR_INVALIDCALL;
872}
873
874STDMETHODIMP GaDirect3D9Ex::GetAdapterDisplayModeEx(UINT Adapter,
875 D3DDISPLAYMODEEX *pMode,
876 D3DDISPLAYROTATION *pRotation)
877{
878 RT_NOREF3(Adapter, pMode, pRotation);
879 TRAPNOTIMPL;
880 return D3DERR_INVALIDCALL;
881}
882
883STDMETHODIMP GaDirect3D9Ex::CreateDeviceEx(UINT Adapter,
884 D3DDEVTYPE DeviceType,
885 HWND hFocusWindow,
886 DWORD BehaviorFlags,
887 D3DPRESENT_PARAMETERS *pPresentationParameters,
888 D3DDISPLAYMODEEX *pFullscreenDisplayMode,
889 IDirect3DDevice9Ex **ppReturnedDeviceInterface)
890{
891 RT_NOREF7(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters,
892 pFullscreenDisplayMode, ppReturnedDeviceInterface);
893 /* This method should never be called. GaCreateDeviceEx is the right one. */
894 TRAPNOTIMPL;
895 return D3DERR_INVALIDCALL;
896}
897
898STDMETHODIMP GaDirect3D9Ex::GetAdapterLUID(UINT Adapter,
899 LUID *pLUID)
900{
901 RT_NOREF2(Adapter, pLUID);
902 TRAPNOTIMPL;
903 return D3DERR_INVALIDCALL;
904}
905
906STDMETHODIMP_(IGalliumStack *) GaDirect3D9Ex::GetGalliumStack(void)
907{
908 return mpStack;
909}
910
911STDMETHODIMP_(ID3DAdapter9 *) GaDirect3D9Ex::GetAdapter9(void)
912{
913 return mpD3DAdapter9;
914}
915
916#if VBOX_MESA_V_MAJOR < 24
917STDMETHODIMP_(struct pipe_screen *) GaDirect3D9Ex::GetScreen(void)
918{
919 return mpPipeScreen;
920}
921#else
922STDMETHODIMP_(const WDDMGalliumDriverEnv *) GaDirect3D9Ex::GetWDDMEnv(void)
923{
924 return mEnv.Env();
925}
926#endif
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use