VirtualBox

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

Last change on this file since 95234 was 95234, checked in by vboxsync, 2 years ago

WDDM: allow gallium based d3d9 and opengl drivers to work with VGPU10. bugref:9845

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 44.0 KB
Line 
1/* $Id: GaWddm.cpp 95234 2022-06-08 16:31:28Z vboxsync $ */
2/** @file
3 * WDDM helpers implemented for the Gallium based driver.
4 */
5
6/*
7 * Copyright (C) 2012-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17#include "../VBoxDispD3DCmn.h"
18
19
20HRESULT GaD3DResourceLockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc,
21 D3DLOCKED_RECT *pLockedRect,
22 const RECT *pRect,
23 DWORD dwLockFlags)
24{
25 HRESULT hr;
26 Assert(pRc->cAllocations > iAlloc);
27
28 VBOXWDDMDISP_ALLOCATION *pAllocation = &pRc->aAllocations[iAlloc];
29 Assert(pAllocation->pD3DIf);
30
31 const VBOXDISP_D3DIFTYPE enmD3DIfType = pAllocation->enmD3DIfType;
32 switch (enmD3DIfType)
33 {
34 case VBOXDISP_D3DIFTYPE_SURFACE:
35 {
36 Assert(!pAllocation->LockInfo.cLocks);
37 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9 *)pAllocation->pD3DIf;
38 hr = pD3DIfSurf->LockRect(pLockedRect, pRect, dwLockFlags);
39 Assert(hr == S_OK);
40 break;
41 }
42 case VBOXDISP_D3DIFTYPE_TEXTURE:
43 {
44 Assert(!pAllocation->LockInfo.cLocks);
45 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9 *)pAllocation->pD3DIf;
46 hr = pD3DIfTex->LockRect(iAlloc, pLockedRect, pRect, dwLockFlags);
47 Assert(hr == S_OK);
48 break;
49 }
50 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
51 {
52 Assert(!pAllocation->LockInfo.cLocks);
53 IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9 *)pAllocation->pD3DIf;
54 hr = pD3DIfCubeTex->LockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, iAlloc),
55 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, iAlloc),
56 pLockedRect, pRect, dwLockFlags);
57 Assert(hr == S_OK);
58 break;
59 }
60 case VBOXDISP_D3DIFTYPE_VERTEXBUFFER:
61 {
62 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9 *)pAllocation->pD3DIf;
63 const UINT OffsetToLock = pRect ? pRect->left : 0;
64 const UINT SizeToLock = pRect ? pRect->right - pRect->left : 0; /* 0 means all */
65 hr = pD3D9VBuf->Lock(OffsetToLock, SizeToLock, &pLockedRect->pBits, dwLockFlags);
66 AssertBreak(hr == S_OK);
67 pLockedRect->Pitch = pAllocation->SurfDesc.pitch;
68 break;
69 }
70 case VBOXDISP_D3DIFTYPE_INDEXBUFFER:
71 {
72 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9 *)pAllocation->pD3DIf;
73 const UINT OffsetToLock = pRect ? pRect->left : 0;
74 const UINT SizeToLock = pRect ? pRect->right - pRect->left : 0; /* 0 means all */
75 hr = pD3D9IBuf->Lock(OffsetToLock, SizeToLock, &pLockedRect->pBits, dwLockFlags);
76 AssertBreak(hr == S_OK);
77 pLockedRect->Pitch = pAllocation->SurfDesc.pitch;
78 break;
79 }
80 default:
81 WARN(("Unknown if type %d", enmD3DIfType));
82 hr = E_FAIL;
83 break;
84 }
85 return hr;
86}
87
88HRESULT GaD3DResourceUnlockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc)
89{
90 HRESULT hr;
91 Assert(pRc->cAllocations > iAlloc);
92
93 VBOXWDDMDISP_ALLOCATION *pAllocation = &pRc->aAllocations[iAlloc];
94 Assert(pAllocation->pD3DIf);
95
96 const VBOXDISP_D3DIFTYPE enmD3DIfType = pAllocation->enmD3DIfType;
97 switch (enmD3DIfType)
98 {
99 case VBOXDISP_D3DIFTYPE_SURFACE:
100 {
101 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9 *)pAllocation->pD3DIf;
102 hr = pD3DIfSurf->UnlockRect();
103 Assert(hr == S_OK);
104 break;
105 }
106 case VBOXDISP_D3DIFTYPE_TEXTURE:
107 {
108 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9 *)pAllocation->pD3DIf;
109 hr = pD3DIfTex->UnlockRect(iAlloc);
110 Assert(hr == S_OK);
111 break;
112 }
113 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
114 {
115 IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9 *)pAllocation->pD3DIf;
116 hr = pD3DIfCubeTex->UnlockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, iAlloc),
117 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, iAlloc));
118 Assert(hr == S_OK);
119 break;
120 }
121 case VBOXDISP_D3DIFTYPE_VERTEXBUFFER:
122 {
123 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9 *)pAllocation->pD3DIf;
124 hr = pD3D9VBuf->Unlock();
125 Assert(hr == S_OK);
126 break;
127 }
128 case VBOXDISP_D3DIFTYPE_INDEXBUFFER:
129 {
130 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9 *)pAllocation->pD3DIf;
131 hr = pD3D9IBuf->Unlock();
132 Assert(hr == S_OK);
133 break;
134 }
135 default:
136 WARN(("unknown if type %d", enmD3DIfType));
137 hr = E_FAIL;
138 break;
139 }
140 return hr;
141}
142
143HRESULT GaD3DResourceSynchMem(PVBOXWDDMDISP_RESOURCE pRc, bool fToBackend)
144{
145 if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM)
146 {
147 return S_OK;
148 }
149
150 const DWORD dwLockFlags = fToBackend ? D3DLOCK_DISCARD : D3DLOCK_READONLY;
151
152 if ( pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
153 || pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE)
154 {
155 /* Exclude plain textures and cube textures because they actually
156 * use (share) the supplied memory buffer (pRc->aAllocations[].pvMem).
157 */
158 /* do nothing */
159 }
160 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE)
161 {
162 HRESULT hr;
163 IDirect3DVolumeTexture9 *pVolTex = (IDirect3DVolumeTexture9 *)pRc->aAllocations[0].pD3DIf;
164
165 UINT Level;
166 for (Level = 0; Level < pRc->cAllocations; ++Level)
167 {
168 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[Level];
169 Assert(pAlloc->pvMem);
170
171 /* Entire level. */
172 D3DBOX box;
173 box.Left = 0;
174 box.Top = 0;
175 box.Right = pAlloc->SurfDesc.width;
176 box.Bottom = pAlloc->SurfDesc.height;
177 box.Front = 0;
178 box.Back = pAlloc->SurfDesc.depth;
179
180 D3DLOCKED_BOX lockedVolume;
181 hr = pVolTex->LockBox(Level, &lockedVolume, &box, dwLockFlags);
182 Assert(hr == S_OK);
183 if (SUCCEEDED(hr))
184 {
185 Assert(lockedVolume.RowPitch > 0);
186 const uint32_t cRows = vboxWddmCalcNumRows(0, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format);
187 const UINT cbLine = RT_MIN(pAlloc->SurfDesc.pitch, (UINT)lockedVolume.RowPitch);
188
189 const uint8_t *pu8Src;
190 int srcRowPitch;
191 int srcSlicePitch;
192 uint8_t *pu8Dst;
193 int dstRowPitch;
194 int dstSlicePitch;
195 if (fToBackend)
196 {
197 pu8Src = (uint8_t *)pAlloc->pvMem;
198 srcRowPitch = pAlloc->SurfDesc.pitch;
199 srcSlicePitch = srcRowPitch * cRows;
200 pu8Dst = (uint8_t *)lockedVolume.pBits;
201 dstRowPitch = lockedVolume.RowPitch;
202 dstSlicePitch = lockedVolume.SlicePitch;
203 }
204 else
205 {
206 pu8Src = (uint8_t *)lockedVolume.pBits;
207 srcRowPitch = lockedVolume.RowPitch;
208 srcSlicePitch = lockedVolume.SlicePitch;
209 pu8Dst = (uint8_t *)pAlloc->pvMem;
210 dstRowPitch = pAlloc->SurfDesc.pitch;
211 dstSlicePitch = srcRowPitch * cRows;
212 }
213
214 for (UINT d = 0; d < pAlloc->SurfDesc.depth; ++d)
215 {
216 uint8_t *pu8RowDst = pu8Dst;
217 const uint8_t *pu8RowSrc = pu8Src;
218 for (UINT h = 0; h < cRows; ++h)
219 {
220 memcpy(pu8RowDst, pu8RowSrc, cbLine);
221 pu8RowDst += dstRowPitch;
222 pu8RowSrc += srcRowPitch;
223 }
224 pu8Dst += dstSlicePitch;
225 pu8Src += srcSlicePitch;
226 }
227
228 hr = pVolTex->UnlockBox(Level);
229 Assert(hr == S_OK);
230 }
231 }
232 }
233 else
234 {
235 for (UINT i = 0; i < pRc->cAllocations; ++i)
236 {
237 D3DLOCKED_RECT Rect;
238 HRESULT hr = GaD3DResourceLockRect(pRc, i, &Rect, NULL, dwLockFlags);
239 if (FAILED(hr))
240 {
241 WARN(("GaD3DResourceLockRect failed, hr(0x%x)", hr));
242 return hr;
243 }
244
245 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
246 Assert(pAlloc->pvMem);
247 Assert(pAlloc->pvMem != Rect.pBits);
248
249 VBoxD3DIfLockUnlockMemSynch(pAlloc, &Rect, NULL, fToBackend);
250
251 hr = GaD3DResourceUnlockRect(pRc, i);
252 Assert(SUCCEEDED(hr));
253 }
254 }
255 return S_OK;
256}
257
258DWORD GaDDI2D3DUsage(D3DDDI_RESOURCEFLAGS fFlags)
259{
260 DWORD fUsage = 0;
261 if (fFlags.Dynamic)
262 fUsage |= D3DUSAGE_DYNAMIC;
263 if (fFlags.AutogenMipmap)
264 fUsage |= D3DUSAGE_AUTOGENMIPMAP;
265 if (fFlags.DMap)
266 fUsage |= D3DUSAGE_DMAP;
267 if (fFlags.WriteOnly)
268 fUsage |= D3DUSAGE_WRITEONLY;
269 if (fFlags.NPatches)
270 fUsage |= D3DUSAGE_NPATCHES;
271 if (fFlags.Points)
272 fUsage |= D3DUSAGE_POINTS;
273 if (fFlags.RenderTarget)
274 fUsage |= D3DUSAGE_RENDERTARGET;
275 if (fFlags.RtPatches)
276 fUsage |= D3DUSAGE_RTPATCHES;
277 if (fFlags.TextApi)
278 fUsage |= D3DUSAGE_TEXTAPI;
279 if (fFlags.WriteOnly)
280 fUsage |= D3DUSAGE_WRITEONLY;
281 if (fFlags.ZBuffer)
282 fUsage |= D3DUSAGE_DEPTHSTENCIL;
283 return fUsage;
284}
285
286#if 0
287void VBoxD3DIfLockUnlockMemSynch(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DLOCKED_RECT *pLockInfo, RECT *pRect, bool bToLockInfo)
288{
289 Assert(pAlloc->SurfDesc.pitch);
290 Assert(pAlloc->pvMem);
291
292 if (!pRect)
293 {
294 if (pAlloc->SurfDesc.pitch == (UINT)pLockInfo->Pitch)
295 {
296 Assert(pAlloc->SurfDesc.cbSize);
297 if (bToLockInfo)
298 memcpy(pLockInfo->pBits, pAlloc->pvMem, pAlloc->SurfDesc.cbSize);
299 else
300 memcpy(pAlloc->pvMem, pLockInfo->pBits, pAlloc->SurfDesc.cbSize);
301 }
302 else
303 {
304 uint8_t *pvSrc, *pvDst;
305 uint32_t srcPitch, dstPitch;
306 if (bToLockInfo)
307 {
308 pvSrc = (uint8_t *)pAlloc->pvMem;
309 pvDst = (uint8_t *)pLockInfo->pBits;
310 srcPitch = pAlloc->SurfDesc.pitch;
311 dstPitch = pLockInfo->Pitch;
312 }
313 else
314 {
315 pvDst = (uint8_t *)pAlloc->pvMem;
316 pvSrc = (uint8_t *)pLockInfo->pBits;
317 dstPitch = pAlloc->SurfDesc.pitch;
318 srcPitch = (uint32_t)pLockInfo->Pitch;
319 }
320
321 uint32_t cRows = vboxWddmCalcNumRows(0, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format);
322 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
323 Assert(pitch);
324 for (UINT j = 0; j < cRows; ++j)
325 {
326 memcpy(pvDst, pvSrc, pitch);
327 pvSrc += srcPitch;
328 pvDst += dstPitch;
329 }
330 }
331 }
332 else
333 {
334 uint8_t *pvSrc, *pvDst;
335 uint32_t srcPitch, dstPitch;
336 uint8_t * pvAllocMemStart = (uint8_t *)pAlloc->pvMem;
337 uint32_t offAllocMemStart = vboxWddmCalcOffXYrd(pRect->left, pRect->top, pAlloc->SurfDesc.pitch, pAlloc->SurfDesc.format);
338 pvAllocMemStart += offAllocMemStart;
339
340 if (bToLockInfo)
341 {
342 pvSrc = (uint8_t *)pvAllocMemStart;
343 pvDst = (uint8_t *)pLockInfo->pBits;
344 srcPitch = pAlloc->SurfDesc.pitch;
345 dstPitch = pLockInfo->Pitch;
346 }
347 else
348 {
349 pvDst = (uint8_t *)pvAllocMemStart;
350 pvSrc = (uint8_t *)pLockInfo->pBits;
351 dstPitch = pAlloc->SurfDesc.pitch;
352 srcPitch = (uint32_t)pLockInfo->Pitch;
353 }
354
355 if (pRect->right - pRect->left == (LONG)pAlloc->SurfDesc.width && srcPitch == dstPitch)
356 {
357 uint32_t cbSize = vboxWddmCalcSize(pAlloc->SurfDesc.pitch, pRect->bottom - pRect->top, pAlloc->SurfDesc.format);
358 memcpy(pvDst, pvSrc, cbSize);
359 }
360 else
361 {
362 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
363 uint32_t cbCopyLine = vboxWddmCalcRowSize(pRect->left, pRect->right, pAlloc->SurfDesc.format);
364 Assert(pitch); NOREF(pitch);
365 uint32_t cRows = vboxWddmCalcNumRows(pRect->top, pRect->bottom, pAlloc->SurfDesc.format);
366 for (UINT j = 0; j < cRows; ++j)
367 {
368 memcpy(pvDst, pvSrc, cbCopyLine);
369 pvSrc += srcPitch;
370 pvDst += dstPitch;
371 }
372 }
373 }
374}
375#endif
376
377HRESULT GaD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc)
378{
379 AssertReturn(pRc->cAllocations > 0, E_INVALIDARG);
380
381 /* Initialize D3D interface pointers in order to be able to clean up on failure later. */
382 for (UINT i = 0; i < pRc->cAllocations; ++i)
383 {
384 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
385 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_UNDEFINED;
386 pAllocation->pD3DIf = NULL;
387 }
388
389 PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice;
390 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
391 AssertReturn(pDevice9If, E_FAIL);
392
393 HRESULT hr = E_FAIL;
394
395 const DWORD d3dUsage = GaDDI2D3DUsage(pRc->RcDesc.fFlags);
396 const D3DFORMAT d3dFormat = vboxDDI2D3DFormat(pRc->RcDesc.enmFormat);
397 const D3DPOOL d3dPool = vboxDDI2D3DPool(pRc->RcDesc.enmPool);
398 const D3DMULTISAMPLE_TYPE d3dMultiSample = vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType);
399 const DWORD d3dMultisampleQuality = pRc->RcDesc.MultisampleQuality;
400 const BOOL d3dLockable = !pRc->RcDesc.fFlags.NotLockable;
401
402 if ( VBOXWDDMDISP_IS_TEXTURE(pRc->RcDesc.fFlags)
403 || pRc->RcDesc.fFlags.VideoProcessRenderTarget
404 || pRc->RcDesc.fFlags.DecodeRenderTarget)
405 {
406 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
407 IDirect3DBaseTexture9 *pD3DIfTex = NULL;
408 VBOXDISP_D3DIFTYPE enmD3DIfType = VBOXDISP_D3DIFTYPE_UNDEFINED;
409
410 if (pRc->RcDesc.fFlags.CubeMap)
411 {
412 if ( pAllocation->SurfDesc.width != pAllocation->SurfDesc.height
413 || pRc->cAllocations % 6 != 0)
414 {
415 WARN(("unexpected cubemap texture config: %dx%d, allocs: %d",
416 pAllocation->SurfDesc.width, pAllocation->SurfDesc.height, pRc->cAllocations));
417 hr = E_INVALIDARG;
418 }
419 else
420 {
421 HANDLE *pSharedHandle = NULL;
422 if (d3dPool == D3DPOOL_SYSTEMMEM)
423 {
424 /* It is expected that allocations are in continous memory blocks. */
425 pSharedHandle = &pRc->aAllocations[0].pvMem;
426 vboxVDbgPrintF((__FUNCTION__" using pvMem %p\n", pRc->aAllocations[0].pvMem));
427 }
428
429 hr = pDevice9If->CreateCubeTexture(pAllocation->SurfDesc.d3dWidth,
430 VBOXDISP_CUBEMAP_LEVELS_COUNT(pRc),
431 d3dUsage, d3dFormat, d3dPool,
432 (IDirect3DCubeTexture9**)&pD3DIfTex,
433 pSharedHandle);
434 Assert(hr == S_OK && pD3DIfTex);
435 enmD3DIfType = VBOXDISP_D3DIFTYPE_CUBE_TEXTURE;
436 }
437 }
438 else if (pRc->RcDesc.fFlags.Volume)
439 {
440 /* D3DUSAGE_DYNAMIC because we have to lock it in GaDdiVolBlt. */
441 hr = pDevice9If->CreateVolumeTexture(pAllocation->SurfDesc.d3dWidth,
442 pAllocation->SurfDesc.height,
443 pAllocation->SurfDesc.depth,
444 pRc->cAllocations,
445 d3dUsage | D3DUSAGE_DYNAMIC, d3dFormat, d3dPool,
446 (IDirect3DVolumeTexture9**)&pD3DIfTex,
447 NULL);
448 Assert(hr == S_OK && pD3DIfTex);
449 enmD3DIfType = VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE;
450 }
451 else
452 {
453 HANDLE *pSharedHandle = NULL;
454 if (d3dPool == D3DPOOL_SYSTEMMEM)
455 {
456 /* It is expected that allocations are in continous memory blocks.
457 *
458 * Also Gallium Nine state tracker has a comment which implies this:
459 * "Some apps expect the memory to be allocated in
460 * continous blocks"
461 */
462 pSharedHandle = &pRc->aAllocations[0].pvMem;
463 vboxVDbgPrintF((__FUNCTION__" using pvMem %p\n", pRc->aAllocations[0].pvMem));
464 }
465
466 hr = pDevice9If->CreateTexture(pAllocation->SurfDesc.d3dWidth,
467 pAllocation->SurfDesc.height,
468 pRc->cAllocations,
469 d3dUsage, d3dFormat, d3dPool,
470 (IDirect3DTexture9**)&pD3DIfTex,
471 pSharedHandle);
472 Assert(hr == S_OK && pD3DIfTex);
473 enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
474 }
475
476 if (SUCCEEDED(hr))
477 {
478 Assert(pD3DIfTex);
479 Assert(enmD3DIfType != VBOXDISP_D3DIFTYPE_UNDEFINED);
480
481 for (UINT i = 0; i < pRc->cAllocations; ++i)
482 {
483 PVBOXWDDMDISP_ALLOCATION p = &pRc->aAllocations[i];
484 p->enmD3DIfType = enmD3DIfType;
485 p->pD3DIf = pD3DIfTex;
486 if (i > 0)
487 pD3DIfTex->AddRef();
488 }
489 }
490 }
491 else if (pRc->RcDesc.fFlags.RenderTarget || pRc->RcDesc.fFlags.Primary)
492 {
493 Assert(pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
494 for (UINT i = 0; i < pRc->cAllocations; ++i)
495 {
496 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
497 IDirect3DSurface9 *pD3D9Surf = NULL;
498
499 if ( pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC
500 || pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
501 {
502 hr = pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
503 pAllocation->SurfDesc.height,
504 d3dFormat,
505 d3dMultiSample,
506 d3dMultisampleQuality,
507 d3dLockable,
508 &pD3D9Surf,
509 NULL);
510 AssertBreak(SUCCEEDED(hr) && pD3D9Surf);
511
512 }
513#ifdef VBOX_WITH_VMSVGA3D_DX9
514 else if (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_D3D)
515 {
516 hr = pDevice9If->CreateRenderTarget(pAllocation->AllocDesc.surfaceInfo.size.width,
517 pAllocation->AllocDesc.surfaceInfo.size.height,
518 d3dFormat,
519 d3dMultiSample,
520 d3dMultisampleQuality,
521 d3dLockable,
522 &pD3D9Surf,
523 NULL);
524 AssertBreak(SUCCEEDED(hr) && pD3D9Surf);
525 }
526#endif
527 else
528 {
529 WARN(("unexpected alloc type %d", pAllocation->enmType));
530 hr = E_FAIL;
531 }
532
533 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
534 pAllocation->pD3DIf = pD3D9Surf;
535 }
536 }
537 else if (pRc->RcDesc.fFlags.ZBuffer)
538 {
539 for (UINT i = 0; i < pRc->cAllocations; ++i)
540 {
541 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
542 const BOOL Discard = TRUE;
543 IDirect3DSurface9 *pD3D9Surf = NULL;
544
545 hr = pDevice9If->CreateDepthStencilSurface(pAllocation->SurfDesc.width,
546 pAllocation->SurfDesc.height,
547 d3dFormat,
548 d3dMultiSample,
549 d3dMultisampleQuality,
550 Discard,
551 &pD3D9Surf,
552 NULL);
553 AssertBreak(SUCCEEDED(hr) && pD3D9Surf);
554
555 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
556 pAllocation->pD3DIf = pD3D9Surf;
557 }
558 }
559 else if (pRc->RcDesc.fFlags.VertexBuffer)
560 {
561 for (UINT i = 0; i < pRc->cAllocations; ++i)
562 {
563 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
564 IDirect3DVertexBuffer9 *pD3D9VBuf = NULL;
565 const DWORD d3dFVF = pRc->RcDesc.Fvf;
566
567 /** @todo need for Gallium? avoid using dynamic to ensure wine does not switch do user buffer */
568 hr = pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width,
569 d3dUsage & (~D3DUSAGE_DYNAMIC),
570 d3dFVF,
571 d3dPool,
572 &pD3D9VBuf,
573 NULL);
574 AssertBreak(SUCCEEDED(hr) && pD3D9VBuf);
575
576 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_VERTEXBUFFER;
577 pAllocation->pD3DIf = pD3D9VBuf;
578 }
579 }
580 else if (pRc->RcDesc.fFlags.IndexBuffer)
581 {
582 for (UINT i = 0; i < pRc->cAllocations; ++i)
583 {
584 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
585 IDirect3DIndexBuffer9 *pD3D9IBuf = NULL;
586
587 hr = pDevice9If->CreateIndexBuffer(pAllocation->SurfDesc.width,
588 d3dUsage,
589 d3dFormat,
590 d3dPool,
591 &pD3D9IBuf,
592 NULL);
593 AssertBreak(SUCCEEDED(hr) && pD3D9IBuf);
594
595 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_INDEXBUFFER;
596 pAllocation->pD3DIf = pD3D9IBuf;
597 }
598 }
599 else
600 {
601 WARN(("unsupported resource flags 0x%x", pRc->RcDesc.fFlags.Value));
602 hr = E_FAIL;
603 }
604
605 if (SUCCEEDED(hr))
606 {
607 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
608 {
609 /* Copy the content of the supplied memory buffer to the Gallium backend. */
610 GaD3DResourceSynchMem(pRc, /*fToBackend=*/ true);
611 }
612 }
613 else
614 {
615 /* Release every created D3D interface. */
616 for (UINT i = 0; i < pRc->cAllocations; ++i)
617 {
618 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
619 if (pAllocation->pD3DIf != NULL)
620 {
621 pAllocation->pD3DIf->Release();
622 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_UNDEFINED;
623 pAllocation->pD3DIf = NULL;
624 }
625 }
626 }
627
628 return hr;
629}
630
631HRESULT GaD3DIfDeviceCreate(struct VBOXWDDMDISP_DEVICE *pDevice)
632{
633 Assert(!pDevice->pDevice9If);
634
635 HRESULT hr;
636 IGalliumStack *pGalliumStack = pDevice->pAdapter->D3D.pGalliumStack;
637 if (pGalliumStack)
638 {
639 /* Gallium backend does not use the implicit swapchain,
640 * therefore the presentation parameters here are sane arbitrary values.
641 */
642 D3DPRESENT_PARAMETERS pp;
643 RT_ZERO(pp);
644 pp.BackBufferWidth = 4;
645 pp.BackBufferHeight = 4;
646 pp.BackBufferFormat = D3DFMT_A8R8G8B8;
647 pp.BackBufferCount = 0;
648 pp.MultiSampleType = D3DMULTISAMPLE_NONE;
649 pp.MultiSampleQuality = 0;
650 pp.SwapEffect = D3DSWAPEFFECT_COPY; /* 'nine' creates 1 back buffer for _COPY instead of 2 for _DISCARD. */
651 pp.Windowed = TRUE;
652
653 const DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING
654 | D3DCREATE_FPU_PRESERVE; /* Do not allow to mess with FPU control word. */
655
656 hr = pGalliumStack->GaCreateDeviceEx(D3DDEVTYPE_HAL, 0, fFlags, &pp, 0,
657 pDevice->pAdapter->hAdapter,
658 pDevice->hDevice,
659 &pDevice->RtCallbacks,
660 &pDevice->pAdapter->AdapterInfo.u.vmsvga.HWInfo,
661 (IDirect3DDevice9Ex **)&pDevice->pDevice9If);
662 if (FAILED(hr))
663 {
664 WARN(("CreateDevice hr 0x%x", hr));
665 }
666 }
667 else
668 {
669 WARN(("pGalliumStack is 0"));
670 hr = E_FAIL;
671 }
672
673 return hr;
674}
675
676static int gaD3DIfSetHostId(IGaDirect3DDevice9Ex *pGaD3DDevice9Ex, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t hostID, uint32_t *pHostID)
677{
678 VBOXDISPIFESCAPE_SETALLOCHOSTID SetHostID;
679 RT_ZERO(SetHostID);
680 SetHostID.EscapeHdr.escapeCode = VBOXESC_SETALLOCHOSTID;
681 SetHostID.hostID = hostID;
682 SetHostID.hAlloc = pAlloc->hAllocation;
683
684 HRESULT hr = pGaD3DDevice9Ex->EscapeCb(&SetHostID, sizeof(SetHostID), /* fHardwareAccess= */ true);
685 if (SUCCEEDED(hr))
686 {
687 if (pHostID)
688 *pHostID = SetHostID.EscapeHdr.u32CmdSpecific;
689
690 return SetHostID.rc;
691 }
692 else
693 WARN(("pfnEscapeCb VBOXESC_SETALLOCHOSTID failed hr 0x%x", hr));
694
695 return VERR_GENERAL_FAILURE;
696}
697
698IUnknown *GaD3DIfCreateSharedPrimary(struct VBOXWDDMDISP_ALLOCATION *pAlloc)
699{
700 /* This allocation has been created in miniport driver DxgkDdiGetStandardAllocationDriverData.
701 * Create the corresponding Gallium D3D interface.
702 *
703 * @todo Consider createing SVGA surface for D3DKMDT_STANDARDALLOCATION_SHAREDPRIMARYSURFACE
704 * in miniport and use it as shared sid.
705 */
706 PVBOXWDDMDISP_RESOURCE pRc = pAlloc->pRc;
707
708 AssertReturn(pAlloc->enmType = VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE, NULL);
709 AssertReturn(pRc->RcDesc.fFlags.SharedResource, NULL);
710 AssertReturn(pRc->fFlags.Opened && pRc->fFlags.KmResource && !pRc->fFlags.Generic, NULL);
711
712 PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice;
713 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
714 IGaDirect3DDevice9Ex *pGaD3DDevice9Ex = NULL;
715 HRESULT hr = pDevice9If->QueryInterface(IID_IGaDirect3DDevice9Ex, (void**)&pGaD3DDevice9Ex);
716 if (FAILED(hr))
717 {
718 WARN(("QueryInterface(IID_IGaDirect3DDevice9Ex), hr 0x%x", hr));
719 return NULL;
720 }
721
722 /* Create Gallium surface for this process. */
723 hr = GaD3DIfCreateForRc(pRc);
724 if (FAILED(hr))
725 {
726 WARN(("GaD3DIfCreateForRc, hr 0x%x", hr));
727 return NULL;
728 }
729
730 Assert(pAlloc->pD3DIf);
731 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
732
733 IDirect3DSurface9 *pSurfIf = NULL;
734 hr = VBoxD3DIfSurfGet(pRc, pAlloc->iAlloc, &pSurfIf);
735 if (FAILED(hr))
736 {
737 WARN(("VBoxD3DIfSurfGet hr %#x", hr));
738 return NULL;
739 }
740
741 /* Must assign the sid to the allocation.
742 * Note: sid == hostID, the latter name is used for historical reasons.
743 */
744 uint32_t hostID = 0;
745 hr = pGaD3DDevice9Ex->GaSurfaceId(pSurfIf, &hostID);
746 if (SUCCEEDED(hr))
747 {
748 Assert(hostID);
749
750 /* Remember the allocation sid. */
751 pAlloc->hostID = hostID;
752
753 /* Inform miniport that this allocation is associated with the given sid.
754 * If the allocation is already associated, the miniport will return the already used sid.
755 */
756 uint32_t usedHostId = 0;
757 int rc = gaD3DIfSetHostId(pGaD3DDevice9Ex, pAlloc, hostID, &usedHostId);
758 if (RT_SUCCESS(rc))
759 {
760 Assert(hostID == usedHostId);
761
762 /* Remember that this sid is used for all operations on this allocation. */
763 pAlloc->hSharedHandle = (HANDLE)(uintptr_t)hostID;
764 }
765 else
766 {
767 if (rc == VERR_NOT_EQUAL)
768 {
769 /* The allocation already has an associated sid.
770 * The resource has been already opened by someone else or there is a bug.
771 * In both cases we need a warning, because this is something unusual.
772 */
773
774#ifndef VBOX_WITH_VMSVGA3D_DX9
775 WARN(("another hostId %d is in use, using it instead", usedHostId));
776#else
777 /* This is most likely a _D3D surface, which is used as actual destination of the shared primary. */
778#endif
779
780 Assert(hostID != usedHostId);
781 Assert(usedHostId);
782
783 /* Remember which sid is actually used for this allocation. */
784 pAlloc->hSharedHandle = (HANDLE)(uintptr_t)usedHostId;
785
786 /* Inform the miniport. */
787 VBOXDISPIFESCAPE_GASHAREDSID data;
788 RT_ZERO(data);
789 data.EscapeHdr.escapeCode = VBOXESC_GASHAREDSID;
790 data.u32Sid = hostID;
791 data.u32SharedSid = usedHostId;
792 hr = pGaD3DDevice9Ex->EscapeCb(&data, sizeof(data), /* fHardwareAccess= */ false);
793 }
794 else
795 {
796 WARN(("gaD3DIfSetHostId %#x", hr));
797 hr = E_FAIL;
798 }
799 }
800 }
801 else
802 {
803 WARN(("GaSurfaceId, hr 0x%x", hr));
804 }
805
806 pGaD3DDevice9Ex->Release();
807
808 pSurfIf->Release();
809
810 if (FAILED(hr))
811 {
812 AssertFailed();
813 pAlloc->pD3DIf->Release();
814 pAlloc->pD3DIf = NULL;
815 }
816
817 return pAlloc->pD3DIf;
818}
819
820#ifndef D3DCAPS2_CANRENDERWINDOWED
821#define D3DCAPS2_CANRENDERWINDOWED UINT32_C(0x00080000)
822#endif
823
824static HRESULT gaWddmGetD3D9Caps(VBOXWDDM_QAI const *pAdapterInfo, IDirect3D9Ex *pD3D9If, D3DCAPS9 *pCaps)
825{
826 HRESULT hr = pD3D9If->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pCaps);
827 if (FAILED(hr))
828 {
829 WARN(("GetDeviceCaps failed hr(0x%x)", hr));
830 return hr;
831 }
832
833#ifdef DEBUG
834 vboxDispCheckCapsLevel(pCaps);
835#endif
836
837 /*
838 * Tweak capabilities which are required for Feature Level 9.3, but
839 * not returned by the backend.
840 */
841
842 /* (Apparently) needed for Windows Media Player to work properly. */
843 pCaps->Caps |= D3DCAPS_READ_SCANLINE;
844 pCaps->Caps2 |= D3DCAPS2_CANRENDERWINDOWED |
845 D3DCAPS2_CANSHARERESOURCE;
846 /* "This flag is obsolete but must be set by the driver." */
847 pCaps->DevCaps |= D3DDEVCAPS_FLOATTLVERTEX;
848 pCaps->PrimitiveMiscCaps |= D3DPMISCCAPS_FOGINFVF |
849 D3DPMISCCAPS_INDEPENDENTWRITEMASKS;
850 pCaps->RasterCaps |= D3DPRASTERCAPS_SUBPIXEL |
851 D3DPRASTERCAPS_STIPPLE |
852 D3DPRASTERCAPS_ZBIAS;
853 pCaps->TextureCaps |= D3DPTEXTURECAPS_TRANSPARENCY |
854 D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE;
855 pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
856 pCaps->VolumeTextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
857 pCaps->VertexTextureFilterCaps |= D3DPTFILTERCAPS_MINFPOINT |
858 D3DPTFILTERCAPS_MAGFPOINT;
859
860
861 /* Required for Shader Model 3.0 but not set by Gallium backend. */
862 pCaps->PS20Caps.Caps |= D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
863
864 if (RT_BOOL(pAdapterInfo->u32AdapterCaps & VBOXWDDM_QAI_CAP_DXVAHD))
865 pCaps->Caps3 |= D3DCAPS3_DXVAHD;
866
867#ifdef DEBUG
868 vboxDispCheckCapsLevel(pCaps);
869#endif
870
871 vboxDispDumpD3DCAPS9(pCaps);
872
873 return S_OK;
874}
875
876static FORMATOP gGaFormatOps3D[] = {
877 {D3DDDIFMT_A8R8G8B8,
878 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
879 FORMATOP_SAME_FORMAT_RENDERTARGET|
880 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
881 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
882 FORMATOP_MEMBEROFGROUP_ARGB|
883 FORMATOP_SRGBWRITE|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
884
885 {D3DDDIFMT_X8R8G8B8,
886 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
887 FORMATOP_SAME_FORMAT_RENDERTARGET|
888 FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|
889 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
890 FORMATOP_MEMBEROFGROUP_ARGB|
891 FORMATOP_SRGBWRITE|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
892
893 {D3DDDIFMT_A2R10G10B10,
894 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
895 FORMATOP_SAME_FORMAT_RENDERTARGET|
896 0|
897 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
898 FORMATOP_MEMBEROFGROUP_ARGB|
899 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
900
901 {D3DDDIFMT_X1R5G5B5,
902 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
903 FORMATOP_SAME_FORMAT_RENDERTARGET|
904 0|
905 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
906 FORMATOP_MEMBEROFGROUP_ARGB|
907 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
908
909 {D3DDDIFMT_A1R5G5B5,
910 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
911 FORMATOP_SAME_FORMAT_RENDERTARGET|
912 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
913 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
914 FORMATOP_MEMBEROFGROUP_ARGB|
915 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
916
917 {D3DDDIFMT_A4R4G4B4,
918 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
919 FORMATOP_SAME_FORMAT_RENDERTARGET|
920 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
921 FORMATOP_OFFSCREENPLAIN|
922 0|
923 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
924
925 {D3DDDIFMT_R5G6B5,
926 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
927 FORMATOP_SAME_FORMAT_RENDERTARGET|
928 FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|
929 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
930 FORMATOP_MEMBEROFGROUP_ARGB|
931 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
932
933 {D3DDDIFMT_L16,
934 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
935 0|
936 0|
937 FORMATOP_OFFSCREENPLAIN|
938 0|
939 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
940
941 {D3DDDIFMT_A8L8,
942 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
943 0|
944 0|
945 FORMATOP_OFFSCREENPLAIN|
946 0|
947 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
948
949 {D3DDDIFMT_A8,
950 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
951 0|
952 0|
953 FORMATOP_OFFSCREENPLAIN|
954 0|
955 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
956
957 {D3DDDIFMT_L8,
958 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
959 0|
960 0|
961 FORMATOP_OFFSCREENPLAIN|
962 0|
963 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
964
965 {D3DDDIFMT_D16, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
966 {D3DDDIFMT_D24S8, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
967 {D3DDDIFMT_D24X8, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
968 {D3DDDIFMT_D16_LOCKABLE, FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
969 {D3DDDIFMT_X8D24, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
970 {D3DDDIFMT_D32F_LOCKABLE, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
971 {D3DDDIFMT_S8D24, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
972
973 {D3DDDIFMT_DXT1,
974 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
975 0|
976 0|
977 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
978 0|
979 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
980
981 {D3DDDIFMT_DXT2,
982 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
983 0|
984 0|
985 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
986 0|
987 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
988
989 {D3DDDIFMT_DXT3,
990 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
991 0|
992 0|
993 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
994 0|
995 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
996
997 {D3DDDIFMT_DXT4,
998 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
999 0|
1000 0|
1001 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
1002 0|
1003 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1004
1005 {D3DDDIFMT_DXT5,
1006 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
1007 0|
1008 0|
1009 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
1010 0|
1011 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1012
1013 {D3DDDIFMT_X8L8V8U8,
1014 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
1015 0|
1016 0|
1017 0|
1018 FORMATOP_BUMPMAP|
1019 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1020
1021 {D3DDDIFMT_A2W10V10U10,
1022 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
1023 0|
1024 0|
1025 0|
1026 FORMATOP_BUMPMAP|
1027 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1028
1029 {D3DDDIFMT_V8U8,
1030 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
1031 0|
1032 0|
1033 0|
1034 FORMATOP_BUMPMAP|
1035 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1036
1037 {D3DDDIFMT_Q8W8V8U8,
1038 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1039 0|
1040 0|
1041 FORMATOP_OFFSCREENPLAIN|
1042 FORMATOP_BUMPMAP|
1043 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1044
1045 {D3DDDIFMT_CxV8U8, FORMATOP_NOFILTER|FORMATOP_NOALPHABLEND|FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
1046
1047 {D3DDDIFMT_R16F,
1048 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1049 FORMATOP_SAME_FORMAT_RENDERTARGET|
1050 0|
1051 FORMATOP_OFFSCREENPLAIN|
1052 0|
1053 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1054
1055 {D3DDDIFMT_R32F,
1056 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1057 FORMATOP_SAME_FORMAT_RENDERTARGET|
1058 0|
1059 FORMATOP_OFFSCREENPLAIN|
1060 0|
1061 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1062
1063 {D3DDDIFMT_G16R16F,
1064 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1065 FORMATOP_SAME_FORMAT_RENDERTARGET|
1066 0|
1067 FORMATOP_OFFSCREENPLAIN|
1068 0|
1069 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1070
1071 {D3DDDIFMT_G32R32F,
1072 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1073 FORMATOP_SAME_FORMAT_RENDERTARGET|
1074 0|
1075 FORMATOP_OFFSCREENPLAIN|
1076 0|
1077 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1078
1079 {D3DDDIFMT_A16B16G16R16F,
1080 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1081 FORMATOP_SAME_FORMAT_RENDERTARGET|
1082 0|
1083 FORMATOP_OFFSCREENPLAIN|
1084 0|
1085 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1086
1087 {D3DDDIFMT_A32B32G32R32F,
1088 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1089 FORMATOP_SAME_FORMAT_RENDERTARGET|
1090 0|
1091 FORMATOP_OFFSCREENPLAIN|
1092 0|
1093 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1094
1095 {D3DDDIFMT_G16R16,
1096 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1097 FORMATOP_SAME_FORMAT_RENDERTARGET|
1098 0|
1099 FORMATOP_OFFSCREENPLAIN|
1100 0|
1101 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1102
1103 {D3DDDIFMT_A16B16G16R16,
1104 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1105 FORMATOP_SAME_FORMAT_RENDERTARGET|
1106 0|
1107 FORMATOP_OFFSCREENPLAIN|
1108 0|
1109 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1110
1111 {D3DDDIFMT_V16U16,
1112 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
1113 0|
1114 0|
1115 0|
1116 FORMATOP_BUMPMAP|
1117 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1118
1119 {D3DDDIFMT_P8, FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|FORMATOP_OFFSCREENPLAIN, 0, 0, 0},
1120
1121 {D3DDDIFMT_UYVY,
1122 0|
1123 0|
1124 0|
1125 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
1126 FORMATOP_NOFILTER|
1127 FORMATOP_NOALPHABLEND|
1128 FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
1129
1130 {D3DDDIFMT_YUY2,
1131 0|
1132 0|
1133 0|
1134 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
1135 FORMATOP_NOFILTER|
1136 FORMATOP_NOALPHABLEND|
1137 FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
1138
1139 {D3DDDIFMT_Q16W16V16U16,
1140 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1141 FORMATOP_SAME_FORMAT_RENDERTARGET|
1142 0|
1143 FORMATOP_OFFSCREENPLAIN|
1144 FORMATOP_BUMPMAP|FORMATOP_DMAP|
1145 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1146
1147 {D3DDDIFMT_X8B8G8R8,
1148 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1149 FORMATOP_SAME_FORMAT_RENDERTARGET|
1150 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
1151 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
1152 FORMATOP_DMAP|FORMATOP_MEMBEROFGROUP_ARGB|
1153 FORMATOP_SRGBWRITE|FORMATOP_AUTOGENMIPMAP|FORMATOP_VERTEXTEXTURE|
1154 FORMATOP_OVERLAY, 0, 0, 0},
1155
1156 {D3DDDIFMT_BINARYBUFFER, FORMATOP_OFFSCREENPLAIN, 0, 0, 0},
1157
1158 {D3DDDIFMT_A4L4,
1159 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
1160 0|
1161 0|
1162 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
1163 FORMATOP_DMAP|
1164 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1165
1166 {D3DDDIFMT_A2B10G10R10,
1167 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
1168 FORMATOP_SAME_FORMAT_RENDERTARGET|
1169 0|
1170 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
1171 FORMATOP_DMAP|FORMATOP_MEMBEROFGROUP_ARGB|
1172 FORMATOP_AUTOGENMIPMAP|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
1173};
1174
1175static void gaWddmD3DBackendClose(PVBOXWDDMDISP_D3D pD3D)
1176{
1177 pD3D->pGalliumStack->Release();
1178 pD3D->pGalliumStack = 0;
1179}
1180
1181HRESULT GaWddmD3DBackendOpen(PVBOXWDDMDISP_D3D pD3D, VBOXWDDM_QAI const *pAdapterInfo, PVBOXWDDMDISP_FORMATS pFormats)
1182{
1183 HRESULT hr = GalliumStackCreate(&pD3D->pGalliumStack);
1184 if (SUCCEEDED(hr))
1185 {
1186 IDirect3D9Ex *pD3D9 = NULL;
1187 hr = pD3D->pGalliumStack->CreateDirect3DEx(0 /* hAdapter */,
1188 0 /* hDevice */,
1189 0 /* pDeviceCallbacks */,
1190 &pAdapterInfo->u.vmsvga.HWInfo,
1191 &pD3D9);
1192 if (SUCCEEDED(hr))
1193 {
1194 hr = gaWddmGetD3D9Caps(pAdapterInfo, pD3D9, &pD3D->Caps);
1195 pD3D9->Release();
1196
1197 if (SUCCEEDED(hr))
1198 {
1199 memset(pFormats, 0, sizeof (*pFormats));
1200 pFormats->paFormatOps = gGaFormatOps3D;
1201 pFormats->cFormatOps = RT_ELEMENTS(gGaFormatOps3D);
1202
1203 pD3D->pfnD3DBackendClose = gaWddmD3DBackendClose;
1204
1205 return S_OK;
1206 }
1207
1208 WARN(("vboxWddmGetD3D9Caps failed hr = 0x%x", hr));
1209 }
1210 else
1211 {
1212 WARN(("Direct3DCreate9Ex failed hr = 0x%x", hr));
1213 }
1214
1215 pD3D->pGalliumStack->Release();
1216 pD3D->pGalliumStack = 0;
1217 }
1218 else
1219 {
1220 WARN(("VBoxDispD3DOpen failed hr = 0x%x", hr));
1221 }
1222 return hr;
1223}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use