VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.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: 30.1 KB
Line 
1/* $Id: VBoxDispD3DIf.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBoxVideo Display D3D User mode dll
4 */
5
6/*
7 * Copyright (C) 2011-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 "VBoxDispD3DIf.h"
29#include "VBoxDispD3DCmn.h"
30
31#include <iprt/assert.h>
32
33/** Convert a given FourCC code to a D3DDDIFORMAT enum. */
34#define VBOXWDDM_D3DDDIFORMAT_FROM_FOURCC(_a, _b, _c, _d) \
35 ((D3DDDIFORMAT)MAKEFOURCC(_a, _b, _c, _d))
36
37static FORMATOP gVBoxFormatOpsBase[] = {
38 {D3DDDIFMT_X8R8G8B8, FORMATOP_DISPLAYMODE, 0, 0, 0},
39
40 {D3DDDIFMT_R8G8B8, FORMATOP_DISPLAYMODE, 0, 0, 0},
41
42 {D3DDDIFMT_R5G6B5, FORMATOP_DISPLAYMODE, 0, 0, 0},
43
44 {D3DDDIFMT_P8, FORMATOP_DISPLAYMODE, 0, 0, 0},
45};
46
47static DDSURFACEDESC gVBoxSurfDescsBase[] = {
48 {
49 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
50 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
51 0, /* DWORD dwHeight; */
52 0, /* DWORD dwWidth; */
53 {
54 0, /* Union */
55 /* LONG lPitch; */
56 /* DWORD dwLinearSize; */
57 },
58 0, /* DWORD dwBackBufferCount; */
59 {
60 0, /* Union */
61 /* DWORD dwMipMapCount; */
62 /* DWORD dwZBufferBitDepth; */
63 /* DWORD dwRefreshRate; */
64 },
65 0, /* DWORD dwAlphaBitDepth; */
66 0, /* DWORD dwReserved; */
67 NULL, /* LPVOID lpSurface; */
68 {
69 0, /* DWORD dwColorSpaceLowValue; */
70 0, /* DWORD dwColorSpaceHighValue; */
71 }, /* DDCOLORKEY ddckCKDestOverlay; */
72 {
73 0, /* DWORD dwColorSpaceLowValue; */
74 0, /* DWORD dwColorSpaceHighValue; */
75 }, /* DDCOLORKEY ddckCKDestBlt; */
76 {
77 0, /* DWORD dwColorSpaceLowValue; */
78 0, /* DWORD dwColorSpaceHighValue; */
79 }, /* DDCOLORKEY ddckCKSrcOverlay; */
80 {
81 0, /* DWORD dwColorSpaceLowValue; */
82 0, /* DWORD dwColorSpaceHighValue; */
83 }, /* DDCOLORKEY ddckCKSrcBlt; */
84 {
85 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
86 DDPF_RGB, /* DWORD dwFlags; */
87 0, /* DWORD dwFourCC; */
88 {
89 32, /* union */
90 /* DWORD dwRGBBitCount; */
91 /* DWORD dwYUVBitCount; */
92 /* DWORD dwZBufferBitDepth; */
93 /* DWORD dwAlphaBitDepth; */
94 /* DWORD dwLuminanceBitCount; */
95 /* DWORD dwBumpBitCount; */
96 },
97 {
98 0xff0000, /* union */
99 /* DWORD dwRBitMask; */
100 /* DWORD dwYBitMask; */
101 /* DWORD dwStencilBitDepth; */
102 /* DWORD dwLuminanceBitMask; */
103 /* DWORD dwBumpDuBitMask; */
104 },
105 {
106 0xff00,
107 /* DWORD dwGBitMask; */
108 /* DWORD dwUBitMask; */
109 /* DWORD dwZBitMask; */
110 /* DWORD dwBumpDvBitMask; */
111 },
112 {
113 0xff,
114 /* DWORD dwBBitMask; */
115 /* DWORD dwVBitMask; */
116 /* DWORD dwStencilBitMask; */
117 /* DWORD dwBumpLuminanceBitMask; */
118 },
119 {
120 0,
121 /* DWORD dwRGBAlphaBitMask; */
122 /* DWORD dwYUVAlphaBitMask; */
123 /* DWORD dwLuminanceAlphaBitMask; */
124 /* DWORD dwRGBZBitMask; */
125 /* DWORD dwYUVZBitMask; */
126 },
127 }, /* DDPIXELFORMAT ddpfPixelFormat; */
128 {
129 DDSCAPS_BACKBUFFER
130 | DDSCAPS_COMPLEX
131 | DDSCAPS_FLIP
132 | DDSCAPS_FRONTBUFFER
133 | DDSCAPS_LOCALVIDMEM
134 | DDSCAPS_PRIMARYSURFACE
135 | DDSCAPS_VIDEOMEMORY
136 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
137 } /* DDSCAPS ddsCaps; */
138 },
139 {
140 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
141 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
142 0, /* DWORD dwHeight; */
143 0, /* DWORD dwWidth; */
144 {
145 0, /* Union */
146 /* LONG lPitch; */
147 /* DWORD dwLinearSize; */
148 },
149 0, /* DWORD dwBackBufferCount; */
150 {
151 0, /* Union */
152 /* DWORD dwMipMapCount; */
153 /* DWORD dwZBufferBitDepth; */
154 /* DWORD dwRefreshRate; */
155 },
156 0, /* DWORD dwAlphaBitDepth; */
157 0, /* DWORD dwReserved; */
158 NULL, /* LPVOID lpSurface; */
159 {
160 0, /* DWORD dwColorSpaceLowValue; */
161 0, /* DWORD dwColorSpaceHighValue; */
162 }, /* DDCOLORKEY ddckCKDestOverlay; */
163 {
164 0, /* DWORD dwColorSpaceLowValue; */
165 0, /* DWORD dwColorSpaceHighValue; */
166 }, /* DDCOLORKEY ddckCKDestBlt; */
167 {
168 0, /* DWORD dwColorSpaceLowValue; */
169 0, /* DWORD dwColorSpaceHighValue; */
170 }, /* DDCOLORKEY ddckCKSrcOverlay; */
171 {
172 0, /* DWORD dwColorSpaceLowValue; */
173 0, /* DWORD dwColorSpaceHighValue; */
174 }, /* DDCOLORKEY ddckCKSrcBlt; */
175 {
176 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
177 DDPF_RGB, /* DWORD dwFlags; */
178 0, /* DWORD dwFourCC; */
179 {
180 24, /* union */
181 /* DWORD dwRGBBitCount; */
182 /* DWORD dwYUVBitCount; */
183 /* DWORD dwZBufferBitDepth; */
184 /* DWORD dwAlphaBitDepth; */
185 /* DWORD dwLuminanceBitCount; */
186 /* DWORD dwBumpBitCount; */
187 },
188 {
189 0xff0000, /* union */
190 /* DWORD dwRBitMask; */
191 /* DWORD dwYBitMask; */
192 /* DWORD dwStencilBitDepth; */
193 /* DWORD dwLuminanceBitMask; */
194 /* DWORD dwBumpDuBitMask; */
195 },
196 {
197 0xff00,
198 /* DWORD dwGBitMask; */
199 /* DWORD dwUBitMask; */
200 /* DWORD dwZBitMask; */
201 /* DWORD dwBumpDvBitMask; */
202 },
203 {
204 0xff,
205 /* DWORD dwBBitMask; */
206 /* DWORD dwVBitMask; */
207 /* DWORD dwStencilBitMask; */
208 /* DWORD dwBumpLuminanceBitMask; */
209 },
210 {
211 0,
212 /* DWORD dwRGBAlphaBitMask; */
213 /* DWORD dwYUVAlphaBitMask; */
214 /* DWORD dwLuminanceAlphaBitMask; */
215 /* DWORD dwRGBZBitMask; */
216 /* DWORD dwYUVZBitMask; */
217 },
218 }, /* DDPIXELFORMAT ddpfPixelFormat; */
219 {
220 DDSCAPS_BACKBUFFER
221 | DDSCAPS_COMPLEX
222 | DDSCAPS_FLIP
223 | DDSCAPS_FRONTBUFFER
224 | DDSCAPS_LOCALVIDMEM
225 | DDSCAPS_PRIMARYSURFACE
226 | DDSCAPS_VIDEOMEMORY
227 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
228 } /* DDSCAPS ddsCaps; */
229 },
230 {
231 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
232 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
233 0, /* DWORD dwHeight; */
234 0, /* DWORD dwWidth; */
235 {
236 0, /* Union */
237 /* LONG lPitch; */
238 /* DWORD dwLinearSize; */
239 },
240 0, /* DWORD dwBackBufferCount; */
241 {
242 0, /* Union */
243 /* DWORD dwMipMapCount; */
244 /* DWORD dwZBufferBitDepth; */
245 /* DWORD dwRefreshRate; */
246 },
247 0, /* DWORD dwAlphaBitDepth; */
248 0, /* DWORD dwReserved; */
249 NULL, /* LPVOID lpSurface; */
250 {
251 0, /* DWORD dwColorSpaceLowValue; */
252 0, /* DWORD dwColorSpaceHighValue; */
253 }, /* DDCOLORKEY ddckCKDestOverlay; */
254 {
255 0, /* DWORD dwColorSpaceLowValue; */
256 0, /* DWORD dwColorSpaceHighValue; */
257 }, /* DDCOLORKEY ddckCKDestBlt; */
258 {
259 0, /* DWORD dwColorSpaceLowValue; */
260 0, /* DWORD dwColorSpaceHighValue; */
261 }, /* DDCOLORKEY ddckCKSrcOverlay; */
262 {
263 0, /* DWORD dwColorSpaceLowValue; */
264 0, /* DWORD dwColorSpaceHighValue; */
265 }, /* DDCOLORKEY ddckCKSrcBlt; */
266 {
267 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
268 DDPF_RGB, /* DWORD dwFlags; */
269 0, /* DWORD dwFourCC; */
270 {
271 16, /* union */
272 /* DWORD dwRGBBitCount; */
273 /* DWORD dwYUVBitCount; */
274 /* DWORD dwZBufferBitDepth; */
275 /* DWORD dwAlphaBitDepth; */
276 /* DWORD dwLuminanceBitCount; */
277 /* DWORD dwBumpBitCount; */
278 },
279 {
280 0xf800, /* union */
281 /* DWORD dwRBitMask; */
282 /* DWORD dwYBitMask; */
283 /* DWORD dwStencilBitDepth; */
284 /* DWORD dwLuminanceBitMask; */
285 /* DWORD dwBumpDuBitMask; */
286 },
287 {
288 0x7e0,
289 /* DWORD dwGBitMask; */
290 /* DWORD dwUBitMask; */
291 /* DWORD dwZBitMask; */
292 /* DWORD dwBumpDvBitMask; */
293 },
294 {
295 0x1f,
296 /* DWORD dwBBitMask; */
297 /* DWORD dwVBitMask; */
298 /* DWORD dwStencilBitMask; */
299 /* DWORD dwBumpLuminanceBitMask; */
300 },
301 {
302 0,
303 /* DWORD dwRGBAlphaBitMask; */
304 /* DWORD dwYUVAlphaBitMask; */
305 /* DWORD dwLuminanceAlphaBitMask; */
306 /* DWORD dwRGBZBitMask; */
307 /* DWORD dwYUVZBitMask; */
308 },
309 }, /* DDPIXELFORMAT ddpfPixelFormat; */
310 {
311 DDSCAPS_BACKBUFFER
312 | DDSCAPS_COMPLEX
313 | DDSCAPS_FLIP
314 | DDSCAPS_FRONTBUFFER
315 | DDSCAPS_LOCALVIDMEM
316 | DDSCAPS_PRIMARYSURFACE
317 | DDSCAPS_VIDEOMEMORY
318 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
319 } /* DDSCAPS ddsCaps; */
320 },
321};
322
323#ifdef VBOX_WITH_VIDEOHWACCEL
324
325static void vboxVhwaPopulateOverlayFourccSurfDesc(DDSURFACEDESC *pDesc, uint32_t fourcc)
326{
327 memset(pDesc, 0, sizeof (DDSURFACEDESC));
328
329 pDesc->dwSize = sizeof (DDSURFACEDESC);
330 pDesc->dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT;
331 pDesc->ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT);
332 pDesc->ddpfPixelFormat.dwFlags = DDPF_FOURCC;
333 pDesc->ddpfPixelFormat.dwFourCC = fourcc;
334 pDesc->ddsCaps.dwCaps = DDSCAPS_BACKBUFFER
335 | DDSCAPS_COMPLEX
336 | DDSCAPS_FLIP
337 | DDSCAPS_FRONTBUFFER
338 | DDSCAPS_LOCALVIDMEM
339 | DDSCAPS_OVERLAY
340 | DDSCAPS_VIDEOMEMORY
341 | DDSCAPS_VISIBLE;
342}
343
344static bool vboxPixFormatMatch(DDPIXELFORMAT *pFormat1, DDPIXELFORMAT *pFormat2)
345{
346 return !memcmp(pFormat1, pFormat2, sizeof (DDPIXELFORMAT));
347}
348
349HRESULT vboxSurfDescMerge(DDSURFACEDESC *paDescs, uint32_t *pcDescs, uint32_t cMaxDescs, DDSURFACEDESC *pDesc)
350{
351 uint32_t cDescs = *pcDescs;
352
353 Assert(cMaxDescs >= cDescs);
354 Assert(pDesc->dwFlags == (DDSD_CAPS | DDSD_PIXELFORMAT));
355 if (pDesc->dwFlags != (DDSD_CAPS | DDSD_PIXELFORMAT))
356 return E_INVALIDARG;
357
358 for (uint32_t i = 0; i < cDescs; ++i)
359 {
360 DDSURFACEDESC *pCur = &paDescs[i];
361 if (vboxPixFormatMatch(&pCur->ddpfPixelFormat, &pDesc->ddpfPixelFormat))
362 {
363 if (pDesc->dwFlags & DDSD_CAPS)
364 {
365 pCur->dwFlags |= DDSD_CAPS;
366 pCur->ddsCaps.dwCaps |= pDesc->ddsCaps.dwCaps;
367 }
368 return S_OK;
369 }
370 }
371
372 if (cMaxDescs > cDescs)
373 {
374 paDescs[cDescs] = *pDesc;
375 ++cDescs;
376 *pcDescs = cDescs;
377 return VINF_SUCCESS;
378 }
379 return E_FAIL;
380}
381
382HRESULT vboxFormatOpsMerge(FORMATOP *paOps, uint32_t *pcOps, uint32_t cMaxOps, FORMATOP *pOp)
383{
384 uint32_t cOps = *pcOps;
385
386 Assert(cMaxOps >= cOps);
387
388 for (uint32_t i = 0; i < cOps; ++i)
389 {
390 FORMATOP *pCur = &paOps[i];
391 if (pCur->Format == pOp->Format)
392 {
393 pCur->Operations |= pOp->Operations;
394 Assert(pCur->FlipMsTypes == pOp->FlipMsTypes);
395 Assert(pCur->BltMsTypes == pOp->BltMsTypes);
396 Assert(pCur->PrivateFormatBitCount == pOp->PrivateFormatBitCount);
397 return S_OK;
398 }
399 }
400
401 if (cMaxOps > cOps)
402 {
403 paOps[cOps] = *pOp;
404 ++cOps;
405 *pcOps = cOps;
406 return VINF_SUCCESS;
407 }
408 return E_FAIL;
409}
410
411HRESULT VBoxDispD3DGlobal2DFormatsInit(PVBOXWDDMDISP_ADAPTER pAdapter)
412{
413 HRESULT hr = S_OK;
414 memset(&pAdapter->D3D, 0, sizeof (pAdapter->D3D));
415 memset(&pAdapter->Formats, 0, sizeof (pAdapter->Formats));
416
417 /* just calc the max number of formats */
418 uint32_t cFormats = RT_ELEMENTS(gVBoxFormatOpsBase);
419 uint32_t cSurfDescs = RT_ELEMENTS(gVBoxSurfDescsBase);
420 uint32_t cOverlayFormats = 0;
421 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
422 {
423 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
424 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
425 {
426 cOverlayFormats += pVhwa->Settings.cFormats;
427 }
428 }
429
430 cFormats += cOverlayFormats;
431 cSurfDescs += cOverlayFormats;
432
433 uint32_t cbFormatOps = cFormats * sizeof (FORMATOP);
434 cbFormatOps = (cbFormatOps + 7) & ~3;
435 /* ensure the surf descs are 8 byte aligned */
436 uint32_t offSurfDescs = (cbFormatOps + 7) & ~3;
437 uint32_t cbSurfDescs = cSurfDescs * sizeof (DDSURFACEDESC);
438 uint32_t cbBuf = offSurfDescs + cbSurfDescs;
439 uint8_t* pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
440 if (pvBuf)
441 {
442 pAdapter->Formats.paFormatOps = (FORMATOP*)pvBuf;
443 memcpy ((void*)pAdapter->Formats.paFormatOps , gVBoxFormatOpsBase, sizeof (gVBoxFormatOpsBase));
444 pAdapter->Formats.cFormatOps = RT_ELEMENTS(gVBoxFormatOpsBase);
445
446 FORMATOP fo = {D3DDDIFMT_UNKNOWN, 0, 0, 0, 0};
447 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
448 {
449 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
450 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
451 {
452 for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j)
453 {
454 fo.Format = pVhwa->Settings.aFormats[j];
455 fo.Operations = FORMATOP_OVERLAY;
456 hr = vboxFormatOpsMerge((FORMATOP *)pAdapter->Formats.paFormatOps, &pAdapter->Formats.cFormatOps, cFormats, &fo);
457 if (FAILED(hr))
458 {
459 WARN(("vboxFormatOpsMerge failed, hr 0x%x", hr));
460 }
461 }
462 }
463 }
464
465 pAdapter->Formats.paSurfDescs = (DDSURFACEDESC*)(pvBuf + offSurfDescs);
466 memcpy ((void*)pAdapter->Formats.paSurfDescs , gVBoxSurfDescsBase, sizeof (gVBoxSurfDescsBase));
467 pAdapter->Formats.cSurfDescs = RT_ELEMENTS(gVBoxSurfDescsBase);
468
469 DDSURFACEDESC sd;
470 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
471 {
472 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
473 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
474 {
475 for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j)
476 {
477 uint32_t fourcc = vboxWddmFormatToFourcc(pVhwa->Settings.aFormats[j]);
478 if (fourcc)
479 {
480 vboxVhwaPopulateOverlayFourccSurfDesc(&sd, fourcc);
481 hr = vboxSurfDescMerge((DDSURFACEDESC *)pAdapter->Formats.paSurfDescs, &pAdapter->Formats.cSurfDescs, cSurfDescs, &sd);
482 if (FAILED(hr))
483 {
484 WARN(("vboxFormatOpsMerge failed, hr 0x%x", hr));
485 }
486 }
487 }
488 }
489 }
490 }
491 else
492 {
493 WARN(("RTMemAllocZ failed"));
494 return E_FAIL;
495 }
496 return S_OK;
497}
498
499void VBoxDispD3DGlobal2DFormatsTerm(PVBOXWDDMDISP_ADAPTER pAdapter)
500{
501 if (pAdapter->Formats.paFormatOps)
502 {
503 RTMemFree((void *)pAdapter->Formats.paFormatOps);
504 pAdapter->Formats.paFormatOps = NULL;
505 }
506}
507
508#endif
509
510static CRITICAL_SECTION g_VBoxDispD3DGlobalCritSect;
511static VBOXWDDMDISP_D3D g_VBoxDispD3DGlobalD3D;
512static VBOXWDDMDISP_FORMATS g_VBoxDispD3DGlobalD3DFormats;
513static uint32_t g_cVBoxDispD3DGlobalOpens;
514
515void vboxDispD3DGlobalLock()
516{
517 EnterCriticalSection(&g_VBoxDispD3DGlobalCritSect);
518}
519
520void vboxDispD3DGlobalUnlock()
521{
522 LeaveCriticalSection(&g_VBoxDispD3DGlobalCritSect);
523}
524
525void VBoxDispD3DGlobalInit()
526{
527 g_cVBoxDispD3DGlobalOpens = 0;
528 InitializeCriticalSection(&g_VBoxDispD3DGlobalCritSect);
529}
530
531void VBoxDispD3DGlobalTerm()
532{
533 DeleteCriticalSection(&g_VBoxDispD3DGlobalCritSect);
534}
535
536#ifndef D3DCAPS2_CANRENDERWINDOWED
537#define D3DCAPS2_CANRENDERWINDOWED UINT32_C(0x00080000)
538#endif
539
540#ifdef DEBUG
541/*
542 * Check capabilities reported by wine and log any which are not good enough for a D3D feature level.
543 */
544
545#define VBOX_D3D_CHECK_FLAGS(level, field, flags) do { \
546 if (((field) & (flags)) != (flags)) \
547 { \
548 LogRel(("D3D level %s %s flags: 0x%08X -> 0x%08X (missing 0x%08X)\n", #level, #field, (field), (flags), ((field) & (flags)) ^ (flags))); \
549 } \
550 } while (0)
551
552#define VBOX_D3D_CHECK_VALUE(level, field, value) do { \
553 if ((int64_t)(value) >= 0? (field) < (value): (field) > (value)) \
554 { \
555 LogRel(("D3D level %s %s value: %lld -> %lld\n", #level, #field, (int64_t)(field), (int64_t)(value))); \
556 } \
557 } while (0)
558
559#define VBOX_D3D_CHECK_VALUE_HEX(level, field, value) do { \
560 if ((field) < (value)) \
561 { \
562 LogRel(("D3D level %s %s value: 0x%08X -> 0x%08X\n", #level, #field, (field), (value))); \
563 } \
564 } while (0)
565
566void vboxDispCheckCapsLevel(const D3DCAPS9 *pCaps)
567{
568 /* Misc. */
569 VBOX_D3D_CHECK_FLAGS(misc, pCaps->Caps, D3DCAPS_READ_SCANLINE);
570 VBOX_D3D_CHECK_FLAGS(misc, pCaps->Caps2, D3DCAPS2_CANRENDERWINDOWED | D3DCAPS2_CANSHARERESOURCE);
571 VBOX_D3D_CHECK_FLAGS(misc, pCaps->DevCaps, D3DDEVCAPS_FLOATTLVERTEX
572 /*| D3DDEVCAPS_HWVERTEXBUFFER | D3DDEVCAPS_HWINDEXBUFFER | D3DDEVCAPS_SUBVOLUMELOCK */);
573 VBOX_D3D_CHECK_FLAGS(misc, pCaps->PrimitiveMiscCaps, D3DPMISCCAPS_INDEPENDENTWRITEMASKS /** @todo needs GL_EXT_draw_buffers2 */
574 | D3DPMISCCAPS_FOGINFVF
575 | D3DPMISCCAPS_SEPARATEALPHABLEND
576 | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS);
577 VBOX_D3D_CHECK_FLAGS(misc, pCaps->RasterCaps, D3DPRASTERCAPS_SUBPIXEL
578 | D3DPRASTERCAPS_STIPPLE
579 | D3DPRASTERCAPS_ZBIAS
580 | D3DPRASTERCAPS_COLORPERSPECTIVE);
581 VBOX_D3D_CHECK_FLAGS(misc, pCaps->TextureCaps, D3DPTEXTURECAPS_TRANSPARENCY
582 | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE);
583 VBOX_D3D_CHECK_FLAGS(misc, pCaps->TextureAddressCaps, D3DPTADDRESSCAPS_MIRRORONCE); /** @todo needs GL_ARB_texture_mirror_clamp_to_edge */
584 VBOX_D3D_CHECK_FLAGS(misc, pCaps->VolumeTextureAddressCaps, D3DPTADDRESSCAPS_MIRRORONCE); /** @todo needs GL_ARB_texture_mirror_clamp_to_edge */
585 VBOX_D3D_CHECK_FLAGS(misc, pCaps->StencilCaps, D3DSTENCILCAPS_TWOSIDED);
586 VBOX_D3D_CHECK_FLAGS(misc, pCaps->DeclTypes, D3DDTCAPS_FLOAT16_2 | D3DDTCAPS_FLOAT16_4); /** @todo both need GL_ARB_half_float_vertex */
587 VBOX_D3D_CHECK_FLAGS(misc, pCaps->VertexTextureFilterCaps, D3DPTFILTERCAPS_MINFPOINT
588 | D3DPTFILTERCAPS_MAGFPOINT);
589 VBOX_D3D_CHECK_VALUE(misc, pCaps->GuardBandLeft, -8192.);
590 VBOX_D3D_CHECK_VALUE(misc, pCaps->GuardBandTop, -8192.);
591 VBOX_D3D_CHECK_VALUE(misc, pCaps->GuardBandRight, 8192.);
592 VBOX_D3D_CHECK_VALUE(misc, pCaps->GuardBandBottom, 8192.);
593 VBOX_D3D_CHECK_VALUE(misc, pCaps->VS20Caps.DynamicFlowControlDepth, 24);
594 VBOX_D3D_CHECK_VALUE(misc, pCaps->VS20Caps.NumTemps, D3DVS20_MAX_NUMTEMPS);
595 VBOX_D3D_CHECK_VALUE(misc, pCaps->PS20Caps.DynamicFlowControlDepth, 24);
596 VBOX_D3D_CHECK_VALUE(misc, pCaps->PS20Caps.NumTemps, D3DVS20_MAX_NUMTEMPS);
597
598 /* 9_1 */
599 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->Caps2, D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_FULLSCREENGAMMA);
600 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->PresentationIntervals, D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_INTERVAL_ONE);
601 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->PrimitiveMiscCaps, D3DPMISCCAPS_COLORWRITEENABLE);
602 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->ShadeCaps, D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORGOURAUDRGB
603 | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARGOURAUDRGB);
604 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->TextureFilterCaps, D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFPOINT
605 | D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MAGFPOINT);
606 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->TextureCaps, D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_CUBEMAP
607 | D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_PERSPECTIVE);
608 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_INDEPENDENTUV
609 | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_WRAP);
610 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->TextureOpCaps, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_MODULATE
611 | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2);
612 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->SrcBlendCaps, D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_INVDESTCOLOR
613 | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_ONE
614 | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_ZERO);
615 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->DestBlendCaps, D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_INVSRCALPHA
616 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_ZERO);
617 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->StretchRectFilterCaps, D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MAGFPOINT
618 | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFPOINT);
619 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->ZCmpCaps, D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_LESSEQUAL);
620 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->RasterCaps, D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS);
621 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->StencilCaps, D3DSTENCILCAPS_TWOSIDED);
622
623 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxTextureWidth, 2048);
624 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxTextureHeight, 2048);
625 VBOX_D3D_CHECK_VALUE(9.1, pCaps->NumSimultaneousRTs, 1);
626 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxSimultaneousTextures, 8);
627 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxTextureBlendStages, 8);
628 VBOX_D3D_CHECK_VALUE_HEX(9.1, pCaps->PixelShaderVersion, D3DPS_VERSION(2,0));
629 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxPrimitiveCount, 65535);
630 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxVertexIndex, 65534);
631 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxVolumeExtent, 256);
632 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxTextureRepeat, 128); /* Must be zero, or 128, or greater. */
633 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxAnisotropy, 2);
634 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxVertexW, 0.f);
635
636 /* 9_2 */
637 VBOX_D3D_CHECK_FLAGS(9.2, pCaps->PrimitiveMiscCaps, D3DPMISCCAPS_SEPARATEALPHABLEND);
638 VBOX_D3D_CHECK_FLAGS(9.2, pCaps->DevCaps2, D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET);
639 VBOX_D3D_CHECK_FLAGS(9.2, pCaps->TextureAddressCaps, D3DPTADDRESSCAPS_MIRRORONCE);
640 VBOX_D3D_CHECK_FLAGS(9.2, pCaps->VolumeTextureAddressCaps, D3DPTADDRESSCAPS_MIRRORONCE);
641 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxTextureWidth, 2048);
642 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxTextureHeight, 2048);
643 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxTextureRepeat, 2048); /* Must be zero, or 2048, or greater. */
644 VBOX_D3D_CHECK_VALUE_HEX(9.2, pCaps->VertexShaderVersion, D3DVS_VERSION(2,0));
645 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxAnisotropy, 16);
646 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxPrimitiveCount, 1048575);
647 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxVertexIndex, 1048575);
648 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxVertexW, 10000000000.f);
649
650 /* 9_3 */
651 VBOX_D3D_CHECK_FLAGS(9.3, pCaps->PS20Caps.Caps, D3DPS20CAPS_GRADIENTINSTRUCTIONS);
652 VBOX_D3D_CHECK_FLAGS(9.3, pCaps->VS20Caps.Caps, D3DVS20CAPS_PREDICATION);
653 VBOX_D3D_CHECK_FLAGS(9.3, pCaps->PrimitiveMiscCaps, D3DPMISCCAPS_INDEPENDENTWRITEMASKS | D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING);
654 VBOX_D3D_CHECK_FLAGS(9.3, pCaps->TextureAddressCaps, D3DPTADDRESSCAPS_BORDER);
655 VBOX_D3D_CHECK_VALUE(9.3, pCaps->MaxTextureWidth, 4096);
656 VBOX_D3D_CHECK_VALUE(9.3, pCaps->MaxTextureHeight, 4096);
657 VBOX_D3D_CHECK_VALUE(9.3, pCaps->MaxTextureRepeat, 8192); /* Must be zero, or 8192, or greater. */
658 VBOX_D3D_CHECK_VALUE(9.3, pCaps->NumSimultaneousRTs, 4);
659 VBOX_D3D_CHECK_VALUE(9.3, pCaps->PS20Caps.NumInstructionSlots, 512); /* (Pixel Shader Version 2b) */
660 VBOX_D3D_CHECK_VALUE(9.3, pCaps->PS20Caps.NumTemps, 32); /* (Pixel Shader Version 2b) */
661 VBOX_D3D_CHECK_VALUE(9.3, pCaps->VS20Caps.NumTemps, 32); /* (Vertex Shader Version 2a) */
662 VBOX_D3D_CHECK_VALUE(9.3, pCaps->VS20Caps.StaticFlowControlDepth, 4);
663 VBOX_D3D_CHECK_VALUE(9.3, pCaps->MaxVertexShaderConst, 256); /* (Vertex Shader Version 2a); */
664 VBOX_D3D_CHECK_VALUE(9.3, pCaps->MaxVertexShader30InstructionSlots, 512);
665 VBOX_D3D_CHECK_VALUE_HEX(9.3, pCaps->VertexShaderVersion, D3DVS_VERSION(3,0));
666
667 LogRel(("Capabilities check completed\n"));
668}
669
670#undef VBOX_D3D_CHECK_FLAGS
671#undef VBOX_D3D_CHECK_VALUE
672#undef VBOX_D3D_CHECK_VALUE_HEX
673
674#endif /* DEBUG */
675
676#ifdef VBOX_WITH_MESA3D
677HRESULT GaWddmD3DBackendOpen(PVBOXWDDMDISP_D3D pD3D, VBOXWDDM_QAI const *pAdapterInfo, PVBOXWDDMDISP_FORMATS pFormats);
678#endif
679
680static HRESULT vboxDispD3DGlobalDoOpen(PVBOXWDDMDISP_D3D pD3D, VBOXWDDM_QAI const *pAdapterInfo, PVBOXWDDMDISP_FORMATS pFormats)
681{
682 memset(pD3D, 0, sizeof (*pD3D));
683
684 HRESULT hr;
685 if (pAdapterInfo->enmHwType == VBOXVIDEO_HWTYPE_VBOX)
686 {
687 hr = E_FAIL;
688 }
689#ifdef VBOX_WITH_MESA3D
690 else if (pAdapterInfo->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA)
691 hr = GaWddmD3DBackendOpen(pD3D, pAdapterInfo, pFormats);
692#endif
693 else
694 {
695 RT_NOREF(pFormats);
696 hr = E_FAIL;
697 }
698
699 if (SUCCEEDED(hr))
700 {
701 pD3D->cMaxSimRTs = pD3D->Caps.NumSimultaneousRTs;
702
703 Assert(pD3D->cMaxSimRTs);
704 Assert(pD3D->cMaxSimRTs < UINT32_MAX/2);
705
706 LOG(("SUCCESS 3D Enabled, pD3D (0x%p)", pD3D));
707 }
708
709 return hr;
710}
711
712HRESULT VBoxDispD3DGlobalOpen(PVBOXWDDMDISP_D3D pD3D, PVBOXWDDMDISP_FORMATS pFormats, VBOXWDDM_QAI const *pAdapterInfo)
713{
714 vboxDispD3DGlobalLock();
715 if (!g_cVBoxDispD3DGlobalOpens)
716 {
717 HRESULT hr = vboxDispD3DGlobalDoOpen(&g_VBoxDispD3DGlobalD3D, pAdapterInfo, &g_VBoxDispD3DGlobalD3DFormats);
718 if (!SUCCEEDED(hr))
719 {
720 vboxDispD3DGlobalUnlock();
721 WARN(("vboxDispD3DGlobalDoOpen failed hr = 0x%x", hr));
722 return hr;
723 }
724 }
725 ++g_cVBoxDispD3DGlobalOpens;
726 vboxDispD3DGlobalUnlock();
727
728 *pD3D = g_VBoxDispD3DGlobalD3D;
729 *pFormats = g_VBoxDispD3DGlobalD3DFormats;
730 return S_OK;
731}
732
733void VBoxDispD3DGlobalClose(PVBOXWDDMDISP_D3D pD3D, PVBOXWDDMDISP_FORMATS pFormats)
734{
735 RT_NOREF(pD3D, pFormats);
736 vboxDispD3DGlobalLock();
737 --g_cVBoxDispD3DGlobalOpens;
738 if (!g_cVBoxDispD3DGlobalOpens)
739 g_VBoxDispD3DGlobalD3D.pfnD3DBackendClose(&g_VBoxDispD3DGlobalD3D);
740 vboxDispD3DGlobalUnlock();
741}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use