VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp@ 63105

Last change on this file since 63105 was 63018, checked in by vboxsync, 8 years ago

GA/NT/Graphics: warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 48.9 KB
Line 
1/* $Id: VBoxDispD3DIf.cpp 63018 2016-08-04 23:14:14Z vboxsync $ */
2/** @file
3 * VBoxVideo Display D3D User mode dll
4 */
5
6/*
7 * Copyright (C) 2011-2016 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
18#include "VBoxDispD3DIf.h"
19#include "VBoxDispD3DCmn.h"
20
21#include <iprt/assert.h>
22
23/** Convert a given FourCC code to a D3DDDIFORMAT enum. */
24#define VBOXWDDM_D3DDDIFORMAT_FROM_FOURCC(_a, _b, _c, _d) \
25 ((D3DDDIFORMAT)MAKEFOURCC(_a, _b, _c, _d))
26
27void VBoxDispD3DClose(VBOXDISPD3D *pD3D)
28{
29 FreeLibrary(pD3D->hD3DLib);
30 pD3D->hD3DLib = NULL;
31}
32
33/**
34 * Loads a system DLL.
35 *
36 * @returns Module handle or NULL
37 * @param pszName The DLL name.
38 */
39static HMODULE loadSystemDll(const char *pszName)
40{
41 char szPath[MAX_PATH];
42 UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath));
43 size_t cbName = strlen(pszName) + 1;
44 if (cchPath + 1 + cbName > sizeof(szPath))
45 {
46 SetLastError(ERROR_FILENAME_EXCED_RANGE);
47 return NULL;
48 }
49 szPath[cchPath] = '\\';
50 memcpy(&szPath[cchPath + 1], pszName, cbName);
51 return LoadLibraryA(szPath);
52}
53
54HRESULT VBoxDispD3DOpen(VBOXDISPD3D *pD3D)
55{
56#ifdef VBOX_WDDM_WOW64
57 pD3D->hD3DLib = loadSystemDll("VBoxD3D9wddm-x86.dll");
58#else
59 pD3D->hD3DLib = loadSystemDll("VBoxD3D9wddm.dll");
60#endif
61 if (!pD3D->hD3DLib)
62 {
63 DWORD winErr = GetLastError(); NOREF(winErr);
64 WARN((__FUNCTION__": LoadLibrary failed, winErr = (%d)", winErr));
65 return E_FAIL;
66 }
67
68 do
69 {
70 pD3D->pfnDirect3DCreate9Ex = (PFNVBOXDISPD3DCREATE9EX)GetProcAddress(pD3D->hD3DLib, "Direct3DCreate9Ex");
71 if (!pD3D->pfnDirect3DCreate9Ex)
72 {
73 WARN(("no Direct3DCreate9Ex"));
74 break;
75 }
76
77 pD3D->pfnVBoxWineExD3DDev9CreateTexture = (PFNVBOXWINEEXD3DDEV9_CREATETEXTURE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9CreateTexture");
78 if (!pD3D->pfnVBoxWineExD3DDev9CreateTexture)
79 {
80 WARN(("no VBoxWineExD3DDev9CreateTexture"));
81 break;
82 }
83
84 pD3D->pfnVBoxWineExD3DDev9CreateCubeTexture = (PFNVBOXWINEEXD3DDEV9_CREATECUBETEXTURE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9CreateCubeTexture");
85 if (!pD3D->pfnVBoxWineExD3DDev9CreateCubeTexture)
86 {
87 WARN(("no VBoxWineExD3DDev9CreateCubeTexture"));
88 break;
89 }
90
91 pD3D->pfnVBoxWineExD3DDev9CreateVolumeTexture = (PFNVBOXWINEEXD3DDEV9_CREATEVOLUMETEXTURE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9CreateVolumeTexture");
92 if (!pD3D->pfnVBoxWineExD3DDev9CreateVolumeTexture)
93 {
94 WARN(("no VBoxWineExD3DDev9CreateVolumeTexture"));
95 break;
96 }
97
98 pD3D->pfnVBoxWineExD3DDev9Flush = (PFNVBOXWINEEXD3DDEV9_FLUSH)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Flush");
99 if (!pD3D->pfnVBoxWineExD3DDev9Flush)
100 {
101 WARN(("no VBoxWineExD3DDev9Flush"));
102 break;
103 }
104
105 pD3D->pfnVBoxWineExD3DDev9FlushToHost = (PFNVBOXWINEEXD3DDEV9_FLUSHTOHOST)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9FlushToHost");
106 if (!pD3D->pfnVBoxWineExD3DDev9FlushToHost)
107 {
108 WARN(("no VBoxWineExD3DDev9FlushToHost"));
109 break;
110 }
111
112 pD3D->pfnVBoxWineExD3DDev9Finish = (PFNVBOXWINEEXD3DDEV9_FINISH)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Finish");
113 if (!pD3D->pfnVBoxWineExD3DDev9Finish)
114 {
115 WARN(("no VBoxWineExD3DDev9Finish"));
116 break;
117 }
118
119 pD3D->pfnVBoxWineExD3DDev9VolBlt = (PFNVBOXWINEEXD3DDEV9_VOLBLT)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9VolBlt");
120 if (!pD3D->pfnVBoxWineExD3DDev9VolBlt)
121 {
122 WARN(("no VBoxWineExD3DDev9VolBlt"));
123 break;
124 }
125
126 pD3D->pfnVBoxWineExD3DDev9VolTexBlt = (PFNVBOXWINEEXD3DDEV9_VOLTEXBLT)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9VolTexBlt");
127 if (!pD3D->pfnVBoxWineExD3DDev9VolTexBlt)
128 {
129 WARN(("no VBoxWineExD3DDev9VolTexBlt"));
130 break;
131 }
132
133 pD3D->pfnVBoxWineExD3DDev9Term = (PFNVBOXWINEEXD3DDEV9_TERM)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Term");
134 if (!pD3D->pfnVBoxWineExD3DDev9Term)
135 {
136 WARN(("no VBoxWineExD3DDev9Term"));
137 break;
138 }
139
140 pD3D->pfnVBoxWineExD3DSwapchain9Present = (PFNVBOXWINEEXD3DSWAPCHAIN9_PRESENT)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSwapchain9Present");
141 if (!pD3D->pfnVBoxWineExD3DSwapchain9Present)
142 {
143 WARN(("no VBoxWineExD3DSwapchain9Present"));
144 break;
145 }
146
147 pD3D->pfnVBoxWineExD3DSurf9GetHostId = (PFNVBOXWINEEXD3DSURF9_GETHOSTID)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSurf9GetHostId");
148 if (!pD3D->pfnVBoxWineExD3DSurf9GetHostId)
149 {
150 WARN(("no VBoxWineExD3DSurf9GetHostId"));
151 break;
152 }
153
154 pD3D->pfnVBoxWineExD3DSurf9SyncToHost = (PFNVBOXWINEEXD3DSURF9_SYNCTOHOST)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSurf9SyncToHost");
155 if (!pD3D->pfnVBoxWineExD3DSurf9SyncToHost)
156 {
157 WARN(("no VBoxWineExD3DSurf9SyncToHost"));
158 break;
159 }
160
161 pD3D->pfnVBoxWineExD3DSwapchain9GetHostWinID = (PFNVBOXWINEEXD3DSWAPCHAIN9_GETHOSTWINID)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSwapchain9GetHostWinID");
162 if (!pD3D->pfnVBoxWineExD3DSwapchain9GetHostWinID)
163 {
164 WARN(("no VBoxWineExD3DSwapchain9GetHostWinID"));
165 break;
166 }
167
168 pD3D->pfnVBoxWineExD3DDev9GetHostId = (PFNVBOXWINEEXD3DDEV9_GETHOSTID)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9GetHostId");
169 if (!pD3D->pfnVBoxWineExD3DDev9GetHostId)
170 {
171 WARN(("no VBoxWineExD3DDev9GetHostId"));
172 break;
173 }
174
175 return S_OK;
176
177 } while (0);
178
179 VBoxDispD3DClose(pD3D);
180
181 return E_FAIL;
182}
183
184
185
186static FORMATOP gVBoxFormatOps3D[] = {
187 {D3DDDIFMT_A8R8G8B8,
188 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
189 FORMATOP_SAME_FORMAT_RENDERTARGET|
190 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
191 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
192 FORMATOP_MEMBEROFGROUP_ARGB|
193 FORMATOP_SRGBWRITE|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
194
195 {D3DDDIFMT_X8R8G8B8,
196 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
197 FORMATOP_SAME_FORMAT_RENDERTARGET|
198 FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|
199 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
200 FORMATOP_MEMBEROFGROUP_ARGB|
201 FORMATOP_SRGBWRITE|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
202
203 {D3DDDIFMT_A2R10G10B10,
204 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
205 FORMATOP_SAME_FORMAT_RENDERTARGET|
206 0|
207 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
208 FORMATOP_MEMBEROFGROUP_ARGB|
209 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
210
211 {D3DDDIFMT_X1R5G5B5,
212 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
213 FORMATOP_SAME_FORMAT_RENDERTARGET|
214 0|
215 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
216 FORMATOP_MEMBEROFGROUP_ARGB|
217 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
218
219 {D3DDDIFMT_A1R5G5B5,
220 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
221 FORMATOP_SAME_FORMAT_RENDERTARGET|
222 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
223 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
224 FORMATOP_MEMBEROFGROUP_ARGB|
225 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
226
227 {D3DDDIFMT_A4R4G4B4,
228 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
229 FORMATOP_SAME_FORMAT_RENDERTARGET|
230 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
231 FORMATOP_OFFSCREENPLAIN|
232 0|
233 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
234
235 {D3DDDIFMT_R5G6B5,
236 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
237 FORMATOP_SAME_FORMAT_RENDERTARGET|
238 FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|
239 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
240 FORMATOP_MEMBEROFGROUP_ARGB|
241 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
242
243 {D3DDDIFMT_L16,
244 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
245 0|
246 0|
247 FORMATOP_OFFSCREENPLAIN|
248 0|
249 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
250
251 {D3DDDIFMT_A8L8,
252 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
253 0|
254 0|
255 FORMATOP_OFFSCREENPLAIN|
256 0|
257 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
258
259 {D3DDDIFMT_A8,
260 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
261 0|
262 0|
263 FORMATOP_OFFSCREENPLAIN|
264 0|
265 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
266
267 {D3DDDIFMT_L8,
268 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
269 0|
270 0|
271 FORMATOP_OFFSCREENPLAIN|
272 0|
273 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
274
275 {D3DDDIFMT_D16, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
276 {D3DDDIFMT_D24S8, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
277 {D3DDDIFMT_D24X8, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
278 {D3DDDIFMT_D16_LOCKABLE, FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
279 {D3DDDIFMT_X8D24, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
280 {D3DDDIFMT_D32F_LOCKABLE, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
281 {D3DDDIFMT_S8D24, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
282
283 {D3DDDIFMT_DXT1,
284 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
285 0|
286 0|
287 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
288 0|
289 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
290
291 {D3DDDIFMT_DXT2,
292 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
293 0|
294 0|
295 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
296 0|
297 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
298
299 {D3DDDIFMT_DXT3,
300 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
301 0|
302 0|
303 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
304 0|
305 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
306
307 {D3DDDIFMT_DXT4,
308 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
309 0|
310 0|
311 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
312 0|
313 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
314
315 {D3DDDIFMT_DXT5,
316 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
317 0|
318 0|
319 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
320 0|
321 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
322
323 {D3DDDIFMT_X8L8V8U8,
324 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
325 0|
326 0|
327 0|
328 FORMATOP_BUMPMAP|
329 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
330
331 {D3DDDIFMT_A2W10V10U10,
332 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
333 0|
334 0|
335 0|
336 FORMATOP_BUMPMAP|
337 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
338
339 {D3DDDIFMT_V8U8,
340 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
341 0|
342 0|
343 0|
344 FORMATOP_BUMPMAP|
345 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
346
347 {D3DDDIFMT_Q8W8V8U8,
348 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
349 0|
350 0|
351 FORMATOP_OFFSCREENPLAIN|
352 FORMATOP_BUMPMAP|
353 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
354
355 {D3DDDIFMT_CxV8U8, FORMATOP_NOFILTER|FORMATOP_NOALPHABLEND|FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
356
357 {D3DDDIFMT_R16F,
358 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
359 FORMATOP_SAME_FORMAT_RENDERTARGET|
360 0|
361 FORMATOP_OFFSCREENPLAIN|
362 0|
363 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
364
365 {D3DDDIFMT_R32F,
366 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
367 FORMATOP_SAME_FORMAT_RENDERTARGET|
368 0|
369 FORMATOP_OFFSCREENPLAIN|
370 0|
371 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
372
373 {D3DDDIFMT_G16R16F,
374 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
375 FORMATOP_SAME_FORMAT_RENDERTARGET|
376 0|
377 FORMATOP_OFFSCREENPLAIN|
378 0|
379 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
380
381 {D3DDDIFMT_G32R32F,
382 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
383 FORMATOP_SAME_FORMAT_RENDERTARGET|
384 0|
385 FORMATOP_OFFSCREENPLAIN|
386 0|
387 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
388
389// Floating-point formats are not implemented in Chromium.
390 {D3DDDIFMT_A16B16G16R16F,
391 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
392 FORMATOP_SAME_FORMAT_RENDERTARGET|
393 0|
394 FORMATOP_OFFSCREENPLAIN|
395 0|
396 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
397
398 {D3DDDIFMT_A32B32G32R32F,
399 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
400 FORMATOP_SAME_FORMAT_RENDERTARGET|
401 0|
402 FORMATOP_OFFSCREENPLAIN|
403 0|
404 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
405
406 {D3DDDIFMT_G16R16,
407 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
408 FORMATOP_SAME_FORMAT_RENDERTARGET|
409 0|
410 FORMATOP_OFFSCREENPLAIN|
411 0|
412 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
413
414 {D3DDDIFMT_A16B16G16R16,
415 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
416 FORMATOP_SAME_FORMAT_RENDERTARGET|
417 0|
418 FORMATOP_OFFSCREENPLAIN|
419 0|
420 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
421
422 {D3DDDIFMT_V16U16,
423 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
424 0|
425 0|
426 0|
427 FORMATOP_BUMPMAP|
428 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
429
430 {D3DDDIFMT_P8, FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|FORMATOP_OFFSCREENPLAIN, 0, 0, 0},
431
432 {D3DDDIFMT_UYVY,
433 0|
434 0|
435 0|
436 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
437 FORMATOP_NOFILTER|
438 FORMATOP_NOALPHABLEND|
439 FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
440
441 {D3DDDIFMT_YUY2,
442 0|
443 0|
444 0|
445 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
446 FORMATOP_NOFILTER|
447 FORMATOP_NOALPHABLEND|
448 FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
449
450 {VBOXWDDM_D3DDDIFORMAT_FROM_FOURCC('Y', 'V', '1', '2'),
451 0|
452 0|
453 0|
454 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
455 FORMATOP_NOFILTER|
456 FORMATOP_NOALPHABLEND|
457 FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
458
459 {D3DDDIFMT_Q16W16V16U16,
460 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
461 FORMATOP_SAME_FORMAT_RENDERTARGET|
462 0|
463 FORMATOP_OFFSCREENPLAIN|
464 FORMATOP_BUMPMAP|FORMATOP_DMAP|
465 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
466
467 {D3DDDIFMT_X8B8G8R8,
468 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
469 FORMATOP_SAME_FORMAT_RENDERTARGET|
470 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
471 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
472 FORMATOP_DMAP|FORMATOP_MEMBEROFGROUP_ARGB|
473 FORMATOP_SRGBWRITE|FORMATOP_AUTOGENMIPMAP|FORMATOP_VERTEXTEXTURE|
474 FORMATOP_OVERLAY, 0, 0, 0},
475
476 {D3DDDIFMT_BINARYBUFFER, FORMATOP_OFFSCREENPLAIN, 0, 0, 0},
477
478 {D3DDDIFMT_A4L4,
479 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
480 0|
481 0|
482 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
483 FORMATOP_DMAP|
484 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
485
486 {D3DDDIFMT_A2B10G10R10,
487 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
488 FORMATOP_SAME_FORMAT_RENDERTARGET|
489 0|
490 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
491 FORMATOP_DMAP|FORMATOP_MEMBEROFGROUP_ARGB|
492 FORMATOP_AUTOGENMIPMAP|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
493};
494
495static FORMATOP gVBoxFormatOpsBase[] = {
496 {D3DDDIFMT_X8R8G8B8, FORMATOP_DISPLAYMODE, 0, 0, 0},
497
498 {D3DDDIFMT_R8G8B8, FORMATOP_DISPLAYMODE, 0, 0, 0},
499
500 {D3DDDIFMT_R5G6B5, FORMATOP_DISPLAYMODE, 0, 0, 0},
501
502 {D3DDDIFMT_P8, FORMATOP_DISPLAYMODE, 0, 0, 0},
503};
504
505static DDSURFACEDESC gVBoxSurfDescsBase[] = {
506 {
507 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
508 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
509 0, /* DWORD dwHeight; */
510 0, /* DWORD dwWidth; */
511 {
512 0, /* Union */
513 /* LONG lPitch; */
514 /* DWORD dwLinearSize; */
515 },
516 0, /* DWORD dwBackBufferCount; */
517 {
518 0, /* Union */
519 /* DWORD dwMipMapCount; */
520 /* DWORD dwZBufferBitDepth; */
521 /* DWORD dwRefreshRate; */
522 },
523 0, /* DWORD dwAlphaBitDepth; */
524 0, /* DWORD dwReserved; */
525 NULL, /* LPVOID lpSurface; */
526 {
527 0, /* DWORD dwColorSpaceLowValue; */
528 0, /* DWORD dwColorSpaceHighValue; */
529 }, /* DDCOLORKEY ddckCKDestOverlay; */
530 {
531 0, /* DWORD dwColorSpaceLowValue; */
532 0, /* DWORD dwColorSpaceHighValue; */
533 }, /* DDCOLORKEY ddckCKDestBlt; */
534 {
535 0, /* DWORD dwColorSpaceLowValue; */
536 0, /* DWORD dwColorSpaceHighValue; */
537 }, /* DDCOLORKEY ddckCKSrcOverlay; */
538 {
539 0, /* DWORD dwColorSpaceLowValue; */
540 0, /* DWORD dwColorSpaceHighValue; */
541 }, /* DDCOLORKEY ddckCKSrcBlt; */
542 {
543 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
544 DDPF_RGB, /* DWORD dwFlags; */
545 0, /* DWORD dwFourCC; */
546 {
547 32, /* union */
548 /* DWORD dwRGBBitCount; */
549 /* DWORD dwYUVBitCount; */
550 /* DWORD dwZBufferBitDepth; */
551 /* DWORD dwAlphaBitDepth; */
552 /* DWORD dwLuminanceBitCount; */
553 /* DWORD dwBumpBitCount; */
554 },
555 {
556 0xff0000, /* union */
557 /* DWORD dwRBitMask; */
558 /* DWORD dwYBitMask; */
559 /* DWORD dwStencilBitDepth; */
560 /* DWORD dwLuminanceBitMask; */
561 /* DWORD dwBumpDuBitMask; */
562 },
563 {
564 0xff00,
565 /* DWORD dwGBitMask; */
566 /* DWORD dwUBitMask; */
567 /* DWORD dwZBitMask; */
568 /* DWORD dwBumpDvBitMask; */
569 },
570 {
571 0xff,
572 /* DWORD dwBBitMask; */
573 /* DWORD dwVBitMask; */
574 /* DWORD dwStencilBitMask; */
575 /* DWORD dwBumpLuminanceBitMask; */
576 },
577 {
578 0,
579 /* DWORD dwRGBAlphaBitMask; */
580 /* DWORD dwYUVAlphaBitMask; */
581 /* DWORD dwLuminanceAlphaBitMask; */
582 /* DWORD dwRGBZBitMask; */
583 /* DWORD dwYUVZBitMask; */
584 },
585 }, /* DDPIXELFORMAT ddpfPixelFormat; */
586 {
587 DDSCAPS_BACKBUFFER
588 | DDSCAPS_COMPLEX
589 | DDSCAPS_FLIP
590 | DDSCAPS_FRONTBUFFER
591 | DDSCAPS_LOCALVIDMEM
592 | DDSCAPS_PRIMARYSURFACE
593 | DDSCAPS_VIDEOMEMORY
594 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
595 } /* DDSCAPS ddsCaps; */
596 },
597 {
598 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
599 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
600 0, /* DWORD dwHeight; */
601 0, /* DWORD dwWidth; */
602 {
603 0, /* Union */
604 /* LONG lPitch; */
605 /* DWORD dwLinearSize; */
606 },
607 0, /* DWORD dwBackBufferCount; */
608 {
609 0, /* Union */
610 /* DWORD dwMipMapCount; */
611 /* DWORD dwZBufferBitDepth; */
612 /* DWORD dwRefreshRate; */
613 },
614 0, /* DWORD dwAlphaBitDepth; */
615 0, /* DWORD dwReserved; */
616 NULL, /* LPVOID lpSurface; */
617 {
618 0, /* DWORD dwColorSpaceLowValue; */
619 0, /* DWORD dwColorSpaceHighValue; */
620 }, /* DDCOLORKEY ddckCKDestOverlay; */
621 {
622 0, /* DWORD dwColorSpaceLowValue; */
623 0, /* DWORD dwColorSpaceHighValue; */
624 }, /* DDCOLORKEY ddckCKDestBlt; */
625 {
626 0, /* DWORD dwColorSpaceLowValue; */
627 0, /* DWORD dwColorSpaceHighValue; */
628 }, /* DDCOLORKEY ddckCKSrcOverlay; */
629 {
630 0, /* DWORD dwColorSpaceLowValue; */
631 0, /* DWORD dwColorSpaceHighValue; */
632 }, /* DDCOLORKEY ddckCKSrcBlt; */
633 {
634 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
635 DDPF_RGB, /* DWORD dwFlags; */
636 0, /* DWORD dwFourCC; */
637 {
638 24, /* union */
639 /* DWORD dwRGBBitCount; */
640 /* DWORD dwYUVBitCount; */
641 /* DWORD dwZBufferBitDepth; */
642 /* DWORD dwAlphaBitDepth; */
643 /* DWORD dwLuminanceBitCount; */
644 /* DWORD dwBumpBitCount; */
645 },
646 {
647 0xff0000, /* union */
648 /* DWORD dwRBitMask; */
649 /* DWORD dwYBitMask; */
650 /* DWORD dwStencilBitDepth; */
651 /* DWORD dwLuminanceBitMask; */
652 /* DWORD dwBumpDuBitMask; */
653 },
654 {
655 0xff00,
656 /* DWORD dwGBitMask; */
657 /* DWORD dwUBitMask; */
658 /* DWORD dwZBitMask; */
659 /* DWORD dwBumpDvBitMask; */
660 },
661 {
662 0xff,
663 /* DWORD dwBBitMask; */
664 /* DWORD dwVBitMask; */
665 /* DWORD dwStencilBitMask; */
666 /* DWORD dwBumpLuminanceBitMask; */
667 },
668 {
669 0,
670 /* DWORD dwRGBAlphaBitMask; */
671 /* DWORD dwYUVAlphaBitMask; */
672 /* DWORD dwLuminanceAlphaBitMask; */
673 /* DWORD dwRGBZBitMask; */
674 /* DWORD dwYUVZBitMask; */
675 },
676 }, /* DDPIXELFORMAT ddpfPixelFormat; */
677 {
678 DDSCAPS_BACKBUFFER
679 | DDSCAPS_COMPLEX
680 | DDSCAPS_FLIP
681 | DDSCAPS_FRONTBUFFER
682 | DDSCAPS_LOCALVIDMEM
683 | DDSCAPS_PRIMARYSURFACE
684 | DDSCAPS_VIDEOMEMORY
685 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
686 } /* DDSCAPS ddsCaps; */
687 },
688 {
689 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
690 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
691 0, /* DWORD dwHeight; */
692 0, /* DWORD dwWidth; */
693 {
694 0, /* Union */
695 /* LONG lPitch; */
696 /* DWORD dwLinearSize; */
697 },
698 0, /* DWORD dwBackBufferCount; */
699 {
700 0, /* Union */
701 /* DWORD dwMipMapCount; */
702 /* DWORD dwZBufferBitDepth; */
703 /* DWORD dwRefreshRate; */
704 },
705 0, /* DWORD dwAlphaBitDepth; */
706 0, /* DWORD dwReserved; */
707 NULL, /* LPVOID lpSurface; */
708 {
709 0, /* DWORD dwColorSpaceLowValue; */
710 0, /* DWORD dwColorSpaceHighValue; */
711 }, /* DDCOLORKEY ddckCKDestOverlay; */
712 {
713 0, /* DWORD dwColorSpaceLowValue; */
714 0, /* DWORD dwColorSpaceHighValue; */
715 }, /* DDCOLORKEY ddckCKDestBlt; */
716 {
717 0, /* DWORD dwColorSpaceLowValue; */
718 0, /* DWORD dwColorSpaceHighValue; */
719 }, /* DDCOLORKEY ddckCKSrcOverlay; */
720 {
721 0, /* DWORD dwColorSpaceLowValue; */
722 0, /* DWORD dwColorSpaceHighValue; */
723 }, /* DDCOLORKEY ddckCKSrcBlt; */
724 {
725 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
726 DDPF_RGB, /* DWORD dwFlags; */
727 0, /* DWORD dwFourCC; */
728 {
729 16, /* union */
730 /* DWORD dwRGBBitCount; */
731 /* DWORD dwYUVBitCount; */
732 /* DWORD dwZBufferBitDepth; */
733 /* DWORD dwAlphaBitDepth; */
734 /* DWORD dwLuminanceBitCount; */
735 /* DWORD dwBumpBitCount; */
736 },
737 {
738 0xf800, /* union */
739 /* DWORD dwRBitMask; */
740 /* DWORD dwYBitMask; */
741 /* DWORD dwStencilBitDepth; */
742 /* DWORD dwLuminanceBitMask; */
743 /* DWORD dwBumpDuBitMask; */
744 },
745 {
746 0x7e0,
747 /* DWORD dwGBitMask; */
748 /* DWORD dwUBitMask; */
749 /* DWORD dwZBitMask; */
750 /* DWORD dwBumpDvBitMask; */
751 },
752 {
753 0x1f,
754 /* DWORD dwBBitMask; */
755 /* DWORD dwVBitMask; */
756 /* DWORD dwStencilBitMask; */
757 /* DWORD dwBumpLuminanceBitMask; */
758 },
759 {
760 0,
761 /* DWORD dwRGBAlphaBitMask; */
762 /* DWORD dwYUVAlphaBitMask; */
763 /* DWORD dwLuminanceAlphaBitMask; */
764 /* DWORD dwRGBZBitMask; */
765 /* DWORD dwYUVZBitMask; */
766 },
767 }, /* DDPIXELFORMAT ddpfPixelFormat; */
768 {
769 DDSCAPS_BACKBUFFER
770 | DDSCAPS_COMPLEX
771 | DDSCAPS_FLIP
772 | DDSCAPS_FRONTBUFFER
773 | DDSCAPS_LOCALVIDMEM
774 | DDSCAPS_PRIMARYSURFACE
775 | DDSCAPS_VIDEOMEMORY
776 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
777 } /* DDSCAPS ddsCaps; */
778 },
779};
780
781#ifdef VBOX_WITH_VIDEOHWACCEL
782
783static void vboxVhwaPopulateOverlayFourccSurfDesc(DDSURFACEDESC *pDesc, uint32_t fourcc)
784{
785 memset(pDesc, 0, sizeof (DDSURFACEDESC));
786
787 pDesc->dwSize = sizeof (DDSURFACEDESC);
788 pDesc->dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT;
789 pDesc->ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT);
790 pDesc->ddpfPixelFormat.dwFlags = DDPF_FOURCC;
791 pDesc->ddpfPixelFormat.dwFourCC = fourcc;
792 pDesc->ddsCaps.dwCaps = DDSCAPS_BACKBUFFER
793 | DDSCAPS_COMPLEX
794 | DDSCAPS_FLIP
795 | DDSCAPS_FRONTBUFFER
796 | DDSCAPS_LOCALVIDMEM
797 | DDSCAPS_OVERLAY
798 | DDSCAPS_VIDEOMEMORY
799 | DDSCAPS_VISIBLE;
800}
801
802static bool vboxPixFormatMatch(DDPIXELFORMAT *pFormat1, DDPIXELFORMAT *pFormat2)
803{
804 return !memcmp(pFormat1, pFormat2, sizeof (DDPIXELFORMAT));
805}
806
807HRESULT vboxSurfDescMerge(DDSURFACEDESC *paDescs, uint32_t *pcDescs, uint32_t cMaxDescs, DDSURFACEDESC *pDesc)
808{
809 uint32_t cDescs = *pcDescs;
810
811 Assert(cMaxDescs >= cDescs);
812 Assert(pDesc->dwFlags == (DDSD_CAPS | DDSD_PIXELFORMAT));
813 if (pDesc->dwFlags != (DDSD_CAPS | DDSD_PIXELFORMAT))
814 return E_INVALIDARG;
815
816 for (uint32_t i = 0; i < cDescs; ++i)
817 {
818 DDSURFACEDESC *pCur = &paDescs[i];
819 if (vboxPixFormatMatch(&pCur->ddpfPixelFormat, &pDesc->ddpfPixelFormat))
820 {
821 if (pDesc->dwFlags & DDSD_CAPS)
822 {
823 pCur->dwFlags |= DDSD_CAPS;
824 pCur->ddsCaps.dwCaps |= pDesc->ddsCaps.dwCaps;
825 }
826 return S_OK;
827 }
828 }
829
830 if (cMaxDescs > cDescs)
831 {
832 paDescs[cDescs] = *pDesc;
833 ++cDescs;
834 *pcDescs = cDescs;
835 return VINF_SUCCESS;
836 }
837 return E_FAIL;
838}
839
840HRESULT vboxFormatOpsMerge(FORMATOP *paOps, uint32_t *pcOps, uint32_t cMaxOps, FORMATOP *pOp)
841{
842 uint32_t cOps = *pcOps;
843
844 Assert(cMaxOps >= cOps);
845
846 for (uint32_t i = 0; i < cOps; ++i)
847 {
848 FORMATOP *pCur = &paOps[i];
849 if (pCur->Format == pOp->Format)
850 {
851 pCur->Operations |= pOp->Operations;
852 Assert(pCur->FlipMsTypes == pOp->FlipMsTypes);
853 Assert(pCur->BltMsTypes == pOp->BltMsTypes);
854 Assert(pCur->PrivateFormatBitCount == pOp->PrivateFormatBitCount);
855 return S_OK;
856 }
857 }
858
859 if (cMaxOps > cOps)
860 {
861 paOps[cOps] = *pOp;
862 ++cOps;
863 *pcOps = cOps;
864 return VINF_SUCCESS;
865 }
866 return E_FAIL;
867}
868
869HRESULT VBoxDispD3DGlobal2DFormatsInit(PVBOXWDDMDISP_ADAPTER pAdapter)
870{
871 HRESULT hr = S_OK;
872 memset(&pAdapter->D3D, 0, sizeof (pAdapter->D3D));
873 memset(&pAdapter->Formats, 0, sizeof (pAdapter->Formats));
874
875 /* just calc the max number of formats */
876 uint32_t cFormats = RT_ELEMENTS(gVBoxFormatOpsBase);
877 uint32_t cSurfDescs = RT_ELEMENTS(gVBoxSurfDescsBase);
878 uint32_t cOverlayFormats = 0;
879 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
880 {
881 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
882 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
883 {
884 cOverlayFormats += pVhwa->Settings.cFormats;
885 }
886 }
887
888 cFormats += cOverlayFormats;
889 cSurfDescs += cOverlayFormats;
890
891 uint32_t cbFormatOps = cFormats * sizeof (FORMATOP);
892 cbFormatOps = (cbFormatOps + 7) & ~3;
893 /* ensure the surf descs are 8 byte aligned */
894 uint32_t offSurfDescs = (cbFormatOps + 7) & ~3;
895 uint32_t cbSurfDescs = cSurfDescs * sizeof (DDSURFACEDESC);
896 uint32_t cbBuf = offSurfDescs + cbSurfDescs;
897 uint8_t* pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
898 if (pvBuf)
899 {
900 pAdapter->Formats.paFormstOps = (FORMATOP*)pvBuf;
901 memcpy ((void*)pAdapter->Formats.paFormstOps , gVBoxFormatOpsBase, sizeof (gVBoxFormatOpsBase));
902 pAdapter->Formats.cFormstOps = RT_ELEMENTS(gVBoxFormatOpsBase);
903
904 FORMATOP fo = {D3DDDIFMT_UNKNOWN, 0, 0, 0, 0};
905 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
906 {
907 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
908 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
909 {
910 for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j)
911 {
912 fo.Format = pVhwa->Settings.aFormats[j];
913 fo.Operations = FORMATOP_OVERLAY;
914 hr = vboxFormatOpsMerge((FORMATOP *)pAdapter->Formats.paFormstOps, &pAdapter->Formats.cFormstOps, cFormats, &fo);
915 if (FAILED(hr))
916 {
917 WARN(("vboxFormatOpsMerge failed, hr 0x%x", hr));
918 }
919 }
920 }
921 }
922
923 pAdapter->Formats.paSurfDescs = (DDSURFACEDESC*)(pvBuf + offSurfDescs);
924 memcpy ((void*)pAdapter->Formats.paSurfDescs , gVBoxSurfDescsBase, sizeof (gVBoxSurfDescsBase));
925 pAdapter->Formats.cSurfDescs = RT_ELEMENTS(gVBoxSurfDescsBase);
926
927 DDSURFACEDESC sd;
928 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
929 {
930 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
931 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
932 {
933 for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j)
934 {
935 uint32_t fourcc = vboxWddmFormatToFourcc(pVhwa->Settings.aFormats[j]);
936 if (fourcc)
937 {
938 vboxVhwaPopulateOverlayFourccSurfDesc(&sd, fourcc);
939 hr = vboxSurfDescMerge((DDSURFACEDESC *)pAdapter->Formats.paSurfDescs, &pAdapter->Formats.cSurfDescs, cSurfDescs, &sd);
940 if (FAILED(hr))
941 {
942 WARN(("vboxFormatOpsMerge failed, hr 0x%x", hr));
943 }
944 }
945 }
946 }
947 }
948 }
949 else
950 {
951 WARN(("RTMemAllocZ failed"));
952 return E_FAIL;
953 }
954 return S_OK;
955}
956
957void VBoxDispD3DGlobal2DFormatsTerm(PVBOXWDDMDISP_ADAPTER pAdapter)
958{
959 if (pAdapter->Formats.paFormstOps)
960 RTMemFree((void *)pAdapter->Formats.paFormstOps);
961}
962
963#endif
964
965static CRITICAL_SECTION g_VBoxDispD3DGlobalCritSect;
966static VBOXWDDMDISP_D3D g_VBoxDispD3DGlobalD3D;
967static VBOXWDDMDISP_FORMATS g_VBoxDispD3DGlobalD3DFormats;
968static uint32_t g_cVBoxDispD3DGlobalOpens;
969
970void vboxDispD3DGlobalLock()
971{
972 EnterCriticalSection(&g_VBoxDispD3DGlobalCritSect);
973}
974
975void vboxDispD3DGlobalUnlock()
976{
977 LeaveCriticalSection(&g_VBoxDispD3DGlobalCritSect);
978}
979
980void VBoxDispD3DGlobalInit()
981{
982 g_cVBoxDispD3DGlobalOpens = 0;
983 InitializeCriticalSection(&g_VBoxDispD3DGlobalCritSect);
984}
985
986void VBoxDispD3DGlobalTerm()
987{
988 DeleteCriticalSection(&g_VBoxDispD3DGlobalCritSect);
989}
990
991static void vboxDispD3DGlobalD3DFormatsInit(PVBOXWDDMDISP_FORMATS pFormats)
992{
993 memset(pFormats, 0, sizeof (*pFormats));
994 pFormats->paFormstOps = gVBoxFormatOps3D;
995 pFormats->cFormstOps = RT_ELEMENTS(gVBoxFormatOps3D);
996}
997
998#ifndef D3DCAPS2_CANRENDERWINDOWED
999#define D3DCAPS2_CANRENDERWINDOWED UINT32_C(0x00080000)
1000#endif
1001
1002#ifdef DEBUG
1003/*
1004 * Check capabilities reported by wine and log any which are not good enough for a D3D feature level.
1005 */
1006
1007#define VBOX_D3D_CHECK_FLAGS(level, field, flags) do { \
1008 if (((field) & (flags)) != (flags)) \
1009 { \
1010 LogRel(("D3D level %s %s flags: 0x%08X -> 0x%08X\n", #level, #field, (field), (flags))); \
1011 } \
1012 } while (0)
1013
1014#define VBOX_D3D_CHECK_VALUE(level, field, value) do { \
1015 if ((int64_t)(value) >= 0? (field) < (value): (field) > (value)) \
1016 { \
1017 LogRel(("D3D level %s %s value: %lld -> %lld\n", #level, #field, (int64_t)(field), (int64_t)(value))); \
1018 } \
1019 } while (0)
1020
1021#define VBOX_D3D_CHECK_VALUE_HEX(level, field, value) do { \
1022 if ((field) < (value)) \
1023 { \
1024 LogRel(("D3D level %s %s value: 0x%08X -> 0x%08X\n", #level, #field, (field), (value))); \
1025 } \
1026 } while (0)
1027
1028static void vboxDispCheckCapsLevel(const D3DCAPS9 *pCaps)
1029{
1030 /* Misc. */
1031 VBOX_D3D_CHECK_FLAGS(misc, pCaps->Caps, D3DCAPS_READ_SCANLINE);
1032 VBOX_D3D_CHECK_FLAGS(misc, pCaps->Caps2, D3DCAPS2_CANRENDERWINDOWED | D3DCAPS2_CANSHARERESOURCE);
1033 VBOX_D3D_CHECK_FLAGS(misc, pCaps->DevCaps, D3DDEVCAPS_FLOATTLVERTEX
1034 /*| D3DDEVCAPS_HWVERTEXBUFFER | D3DDEVCAPS_HWINDEXBUFFER | D3DDEVCAPS_SUBVOLUMELOCK */);
1035 VBOX_D3D_CHECK_FLAGS(misc, pCaps->PrimitiveMiscCaps, D3DPMISCCAPS_INDEPENDENTWRITEMASKS /** @todo needs GL_EXT_draw_buffers2 */
1036 | D3DPMISCCAPS_FOGINFVF
1037 | D3DPMISCCAPS_SEPARATEALPHABLEND
1038 | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS);
1039 VBOX_D3D_CHECK_FLAGS(misc, pCaps->RasterCaps, D3DPRASTERCAPS_SUBPIXEL
1040 | D3DPRASTERCAPS_STIPPLE
1041 | D3DPRASTERCAPS_ZBIAS
1042 | D3DPRASTERCAPS_COLORPERSPECTIVE);
1043 VBOX_D3D_CHECK_FLAGS(misc, pCaps->TextureCaps, D3DPTEXTURECAPS_TRANSPARENCY
1044 | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE);
1045 VBOX_D3D_CHECK_FLAGS(misc, pCaps->TextureAddressCaps, D3DPTADDRESSCAPS_MIRRORONCE); /** @todo needs GL_ARB_texture_mirror_clamp_to_edge */
1046 VBOX_D3D_CHECK_FLAGS(misc, pCaps->VolumeTextureAddressCaps, D3DPTADDRESSCAPS_MIRRORONCE); /** @todo needs GL_ARB_texture_mirror_clamp_to_edge */
1047 VBOX_D3D_CHECK_FLAGS(misc, pCaps->StencilCaps, D3DSTENCILCAPS_TWOSIDED);
1048 VBOX_D3D_CHECK_FLAGS(misc, pCaps->DeclTypes, D3DDTCAPS_FLOAT16_2 | D3DDTCAPS_FLOAT16_4); /** @todo both need GL_ARB_half_float_vertex */
1049 VBOX_D3D_CHECK_FLAGS(misc, pCaps->VertexTextureFilterCaps, D3DPTFILTERCAPS_MINFPOINT
1050 | D3DPTFILTERCAPS_MAGFPOINT);
1051 VBOX_D3D_CHECK_VALUE(misc, pCaps->GuardBandLeft, -8192.);
1052 VBOX_D3D_CHECK_VALUE(misc, pCaps->GuardBandTop, -8192.);
1053 VBOX_D3D_CHECK_VALUE(misc, pCaps->GuardBandRight, 8192.);
1054 VBOX_D3D_CHECK_VALUE(misc, pCaps->GuardBandBottom, 8192.);
1055 VBOX_D3D_CHECK_VALUE(misc, pCaps->VS20Caps.DynamicFlowControlDepth, 24);
1056 VBOX_D3D_CHECK_VALUE(misc, pCaps->VS20Caps.NumTemps, D3DVS20_MAX_NUMTEMPS);
1057 VBOX_D3D_CHECK_VALUE(misc, pCaps->PS20Caps.DynamicFlowControlDepth, 24);
1058 VBOX_D3D_CHECK_VALUE(misc, pCaps->PS20Caps.NumTemps, D3DVS20_MAX_NUMTEMPS);
1059
1060 /* 9_1 */
1061 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->Caps2, D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_FULLSCREENGAMMA);
1062 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->PresentationIntervals, D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_INTERVAL_ONE);
1063 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->PrimitiveMiscCaps, D3DPMISCCAPS_COLORWRITEENABLE);
1064 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->ShadeCaps, D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORGOURAUDRGB
1065 | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARGOURAUDRGB);
1066 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->TextureFilterCaps, D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFPOINT
1067 | D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MAGFPOINT);
1068 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->TextureCaps, D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_CUBEMAP
1069 | D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_PERSPECTIVE);
1070 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_INDEPENDENTUV
1071 | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_WRAP);
1072 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->TextureOpCaps, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_MODULATE
1073 | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2);
1074 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->SrcBlendCaps, D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_INVDESTCOLOR
1075 | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_ONE
1076 | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_ZERO);
1077 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->DestBlendCaps, D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_INVSRCALPHA
1078 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_ZERO);
1079 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->StretchRectFilterCaps, D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MAGFPOINT
1080 | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFPOINT);
1081 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->ZCmpCaps, D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_LESSEQUAL);
1082 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->RasterCaps, D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS);
1083 VBOX_D3D_CHECK_FLAGS(9.1, pCaps->StencilCaps, D3DSTENCILCAPS_TWOSIDED);
1084
1085 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxTextureWidth, 2048);
1086 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxTextureHeight, 2048);
1087 VBOX_D3D_CHECK_VALUE(9.1, pCaps->NumSimultaneousRTs, 1);
1088 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxSimultaneousTextures, 8);
1089 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxTextureBlendStages, 8);
1090 VBOX_D3D_CHECK_VALUE_HEX(9.1, pCaps->PixelShaderVersion, D3DPS_VERSION(2,0));
1091 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxPrimitiveCount, 65535);
1092 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxVertexIndex, 65534);
1093 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxVolumeExtent, 256);
1094 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxTextureRepeat, 128); /* Must be zero, or 128, or greater. */
1095 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxAnisotropy, 2);
1096 VBOX_D3D_CHECK_VALUE(9.1, pCaps->MaxVertexW, 0.f);
1097
1098 /* 9_2 */
1099 VBOX_D3D_CHECK_FLAGS(9.2, pCaps->PrimitiveMiscCaps, D3DPMISCCAPS_SEPARATEALPHABLEND);
1100 VBOX_D3D_CHECK_FLAGS(9.2, pCaps->DevCaps2, D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET);
1101 VBOX_D3D_CHECK_FLAGS(9.2, pCaps->TextureAddressCaps, D3DPTADDRESSCAPS_MIRRORONCE);
1102 VBOX_D3D_CHECK_FLAGS(9.2, pCaps->VolumeTextureAddressCaps, D3DPTADDRESSCAPS_MIRRORONCE);
1103 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxTextureWidth, 2048);
1104 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxTextureHeight, 2048);
1105 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxTextureRepeat, 2048); /* Must be zero, or 2048, or greater. */
1106 VBOX_D3D_CHECK_VALUE_HEX(9.2, pCaps->VertexShaderVersion, D3DVS_VERSION(2,0));
1107 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxAnisotropy, 16);
1108 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxPrimitiveCount, 1048575);
1109 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxVertexIndex, 1048575);
1110 VBOX_D3D_CHECK_VALUE(9.2, pCaps->MaxVertexW, 10000000000.f);
1111
1112 /* 9_3 */
1113 VBOX_D3D_CHECK_FLAGS(9.3, pCaps->PS20Caps.Caps, D3DPS20CAPS_GRADIENTINSTRUCTIONS);
1114 VBOX_D3D_CHECK_FLAGS(9.3, pCaps->VS20Caps.Caps, D3DVS20CAPS_PREDICATION);
1115 VBOX_D3D_CHECK_FLAGS(9.3, pCaps->PrimitiveMiscCaps, D3DPMISCCAPS_INDEPENDENTWRITEMASKS | D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING);
1116 VBOX_D3D_CHECK_FLAGS(9.3, pCaps->TextureAddressCaps, D3DPTADDRESSCAPS_BORDER);
1117 VBOX_D3D_CHECK_VALUE(9.3, pCaps->MaxTextureWidth, 4096);
1118 VBOX_D3D_CHECK_VALUE(9.3, pCaps->MaxTextureHeight, 4096);
1119 VBOX_D3D_CHECK_VALUE(9.3, pCaps->MaxTextureRepeat, 8192); /* Must be zero, or 8192, or greater. */
1120 VBOX_D3D_CHECK_VALUE(9.3, pCaps->NumSimultaneousRTs, 4);
1121 VBOX_D3D_CHECK_VALUE(9.3, pCaps->PS20Caps.NumInstructionSlots, 512); /* (Pixel Shader Version 2b) */
1122 VBOX_D3D_CHECK_VALUE(9.3, pCaps->PS20Caps.NumTemps, 32); /* (Pixel Shader Version 2b) */
1123 VBOX_D3D_CHECK_VALUE(9.3, pCaps->VS20Caps.NumTemps, 32); /* (Vertex Shader Version 2a) */
1124 VBOX_D3D_CHECK_VALUE(9.3, pCaps->VS20Caps.StaticFlowControlDepth, 4);
1125 VBOX_D3D_CHECK_VALUE(9.3, pCaps->MaxVertexShaderConst, 256); /* (Vertex Shader Version 2a); */
1126 VBOX_D3D_CHECK_VALUE(9.3, pCaps->MaxVertexShader30InstructionSlots, 512);
1127 VBOX_D3D_CHECK_VALUE_HEX(9.3, pCaps->VertexShaderVersion, D3DVS_VERSION(3,0));
1128
1129 LogRel(("Capabilities check completed\n"));
1130}
1131
1132#undef VBOX_D3D_CHECK_FLAGS
1133#undef VBOX_D3D_CHECK_VALUE
1134#undef VBOX_D3D_CHECK_VALUE_HEX
1135
1136#endif /* DEBUG */
1137
1138static HRESULT vboxWddmGetD3D9Caps(PVBOXWDDMDISP_D3D pD3D, D3DCAPS9 *pCaps)
1139{
1140 HRESULT hr = pD3D->pD3D9If->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pCaps);
1141 if (FAILED(hr))
1142 {
1143 WARN(("GetDeviceCaps failed hr(0x%x)",hr));
1144 return hr;
1145 }
1146
1147#ifdef DEBUG
1148 vboxDispCheckCapsLevel(pCaps);
1149#endif
1150
1151 /* needed for Windows Media Player to work properly */
1152 pCaps->Caps |= D3DCAPS_READ_SCANLINE;
1153 pCaps->Caps2 |= 0x00080000 /*D3DCAPS2_CANRENDERWINDOWED*/;
1154 pCaps->Caps2 |= D3DCAPS2_CANSHARERESOURCE;
1155 pCaps->DevCaps |= D3DDEVCAPS_FLOATTLVERTEX /* <- must be set according to the docs */
1156 /*| D3DDEVCAPS_HWVERTEXBUFFER | D3DDEVCAPS_HWINDEXBUFFER | D3DDEVCAPS_SUBVOLUMELOCK */;
1157 pCaps->PrimitiveMiscCaps |= D3DPMISCCAPS_INDEPENDENTWRITEMASKS
1158 | D3DPMISCCAPS_FOGINFVF
1159 | D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS;
1160 pCaps->RasterCaps |= D3DPRASTERCAPS_SUBPIXEL | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_COLORPERSPECTIVE /* keep */;
1161 pCaps->TextureCaps |= D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE;
1162 pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
1163 pCaps->VolumeTextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
1164 pCaps->StencilCaps |= D3DSTENCILCAPS_TWOSIDED;
1165 pCaps->DeclTypes |= D3DDTCAPS_FLOAT16_2 | D3DDTCAPS_FLOAT16_4;
1166 pCaps->VertexTextureFilterCaps |= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MAGFPOINT;
1167 pCaps->GuardBandLeft = -8192.;
1168 pCaps->GuardBandTop = -8192.;
1169 pCaps->GuardBandRight = 8192.;
1170 pCaps->GuardBandBottom = 8192.;
1171 pCaps->VS20Caps.DynamicFlowControlDepth = 24;
1172 pCaps->VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
1173 pCaps->PS20Caps.DynamicFlowControlDepth = 24;
1174 pCaps->PS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
1175
1176 /* workaround for wine not returning InstructionSlots correctly for shaders v3.0 */
1177 if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
1178 {
1179 pCaps->MaxVertexShader30InstructionSlots = RT_MIN(32768, pCaps->MaxVertexShader30InstructionSlots);
1180 pCaps->MaxPixelShader30InstructionSlots = RT_MIN(32768, pCaps->MaxPixelShader30InstructionSlots);
1181 }
1182#if defined(DEBUG)
1183 if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
1184 {
1185 Assert(pCaps->MaxVertexShader30InstructionSlots >= 512);
1186 Assert(pCaps->MaxVertexShader30InstructionSlots <= 32768);
1187 Assert(pCaps->MaxPixelShader30InstructionSlots >= 512);
1188 Assert(pCaps->MaxPixelShader30InstructionSlots <= 32768);
1189 }
1190 else if ((pCaps->VertexShaderVersion & 0xff00) == 0x0200)
1191 {
1192 Assert(pCaps->MaxVertexShader30InstructionSlots == 0);
1193 Assert(pCaps->MaxPixelShader30InstructionSlots == 0);
1194 }
1195 else
1196 {
1197 WARN(("incorect shader caps!"));
1198 }
1199#endif
1200
1201 pCaps->MaxVertexW = 10000000000.f; /* Required by D3D feature level 9.3. */
1202
1203#ifdef DEBUG
1204 vboxDispCheckCapsLevel(pCaps);
1205#endif
1206
1207 vboxDispDumpD3DCAPS9(pCaps);
1208
1209 return S_OK;
1210}
1211
1212static void vboxDispD3DGlobalDoClose(PVBOXWDDMDISP_D3D pD3D)
1213{
1214 pD3D->pD3D9If->Release();
1215 VBoxDispD3DClose(&pD3D->D3D);
1216}
1217
1218static HRESULT vboxDispD3DGlobalDoOpen(PVBOXWDDMDISP_D3D pD3D)
1219{
1220 memset(pD3D, 0, sizeof (*pD3D));
1221 HRESULT hr = VBoxDispD3DOpen(&pD3D->D3D);
1222 if (SUCCEEDED(hr))
1223 {
1224 hr = pD3D->D3D.pfnDirect3DCreate9Ex(D3D_SDK_VERSION, &pD3D->pD3D9If);
1225 if (SUCCEEDED(hr))
1226 {
1227 hr = vboxWddmGetD3D9Caps(pD3D, &pD3D->Caps);
1228 if (SUCCEEDED(hr))
1229 {
1230 pD3D->cMaxSimRTs = pD3D->Caps.NumSimultaneousRTs;
1231 Assert(pD3D->cMaxSimRTs);
1232 Assert(pD3D->cMaxSimRTs < UINT32_MAX/2);
1233 LOG(("SUCCESS 3D Enabled, pD3D (0x%p)", pD3D));
1234 return S_OK;
1235 }
1236 else
1237 {
1238 WARN(("vboxWddmGetD3D9Caps failed hr = 0x%x", hr));
1239 }
1240 pD3D->pD3D9If->Release();
1241 }
1242 else
1243 {
1244 WARN(("pfnDirect3DCreate9Ex failed hr = 0x%x", hr));
1245 }
1246 VBoxDispD3DClose(&pD3D->D3D);
1247 }
1248 else
1249 {
1250 WARN(("VBoxDispD3DOpen failed hr = 0x%x", hr));
1251 }
1252 return hr;
1253}
1254
1255HRESULT VBoxDispD3DGlobalOpen(PVBOXWDDMDISP_D3D pD3D, PVBOXWDDMDISP_FORMATS pFormats)
1256{
1257 vboxDispD3DGlobalLock();
1258 if (!g_cVBoxDispD3DGlobalOpens)
1259 {
1260 HRESULT hr = vboxDispD3DGlobalDoOpen(&g_VBoxDispD3DGlobalD3D);
1261 if (!SUCCEEDED(hr))
1262 {
1263 vboxDispD3DGlobalUnlock();
1264 WARN(("vboxDispD3DGlobalDoOpen failed hr = 0x%x", hr));
1265 return hr;
1266 }
1267
1268 vboxDispD3DGlobalD3DFormatsInit(&g_VBoxDispD3DGlobalD3DFormats);
1269 }
1270 ++g_cVBoxDispD3DGlobalOpens;
1271 vboxDispD3DGlobalUnlock();
1272
1273 *pD3D = g_VBoxDispD3DGlobalD3D;
1274 *pFormats = g_VBoxDispD3DGlobalD3DFormats;
1275 return S_OK;
1276}
1277
1278void VBoxDispD3DGlobalClose(PVBOXWDDMDISP_D3D pD3D, PVBOXWDDMDISP_FORMATS pFormats)
1279{
1280 RT_NOREF(pD3D, pFormats);
1281 vboxDispD3DGlobalLock();
1282 --g_cVBoxDispD3DGlobalOpens;
1283 if (!g_cVBoxDispD3DGlobalOpens)
1284 vboxDispD3DGlobalDoClose(&g_VBoxDispD3DGlobalD3D);
1285 vboxDispD3DGlobalUnlock();
1286}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette