VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use