VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp@ 32823

Last change on this file since 32823 was 32823, checked in by vboxsync, 14 years ago

wddm/2d: 2D video accel support fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 294.8 KB
Line 
1/** @file
2 *
3 * VBoxVideo Display D3D User mode dll
4 *
5 * Copyright (C) 2010 Oracle Corporation
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.virtualbox.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License (GPL) as published by the Free Software
11 * Foundation, in version 2 as it comes in the "COPYING" file of the
12 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14 */
15#define INITGUID
16
17#include <iprt/initterm.h>
18#include <iprt/log.h>
19#include <iprt/mem.h>
20
21#include <VBox/Log.h>
22
23#include <VBox/VBoxGuestLib.h>
24
25#include "VBoxDispD3DCmn.h"
26#include "VBoxDispD3D.h"
27#include "VBoxScreen.h"
28
29#ifdef VBOX_WDDMDISP_WITH_PROFILE
30#include "VBoxDispProfile.h"
31static VBoxDispProfileSet g_VBoxDispProfileDDI("D3D_DDI");
32//static BOOL g_VBoxDispPrifileDDIDumpAndReset = FALSE;
33#define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE() VBOXDISPPROFILE_FUNCTION_PROLOGUE(g_VBoxDispProfileDDI)
34
35#define VBOXDISPPROFILE_DDI_DUMPRESET(_pDev) do {\
36 AssertRelease(0); \
37 g_VBoxDispProfileDDI.dump(_pDev);\
38 g_VBoxDispProfileDDI.resetEntries();\
39 VBOXDISPPROFILE_FUNCTION_LOGGER_DISABLE_CURRENT();\
40 } while (0)
41
42
43#else
44#define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE() do {} while (0)
45#define VBOXDISPPROFILE_DDI_DUMPRESET(_pDev) do {} while (0)
46#endif
47
48#ifdef VBOXDISPMP_TEST
49HRESULT vboxDispMpTstStart();
50HRESULT vboxDispMpTstStop();
51#endif
52
53#ifdef VBOXWDDMDISP_DEBUG_PRINT
54# include <stdio.h>
55#endif
56
57#define VBOXDISP_WITH_WINE_BB_WORKAROUND
58
59static VBOXSCREENMONRUNNER g_VBoxScreenMonRunner;
60
61//#define VBOXWDDMOVERLAY_TEST
62
63static FORMATOP gVBoxFormatOps3D[] = {
64 {D3DDDIFMT_A8R8G8B8,
65 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
66 FORMATOP_SAME_FORMAT_RENDERTARGET|
67 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
68 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
69 FORMATOP_MEMBEROFGROUP_ARGB|
70 FORMATOP_SRGBWRITE|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
71
72 {D3DDDIFMT_X8R8G8B8,
73 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
74 FORMATOP_SAME_FORMAT_RENDERTARGET|
75 FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|
76 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
77 FORMATOP_MEMBEROFGROUP_ARGB|
78 FORMATOP_SRGBWRITE|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
79
80 {D3DDDIFMT_A2R10G10B10,
81 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
82 FORMATOP_SAME_FORMAT_RENDERTARGET|
83 0|
84 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
85 FORMATOP_MEMBEROFGROUP_ARGB|
86 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
87
88 {D3DDDIFMT_X1R5G5B5,
89 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
90 FORMATOP_SAME_FORMAT_RENDERTARGET|
91 0|
92 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
93 FORMATOP_MEMBEROFGROUP_ARGB|
94 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
95
96 {D3DDDIFMT_A1R5G5B5,
97 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
98 FORMATOP_SAME_FORMAT_RENDERTARGET|
99 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
100 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
101 FORMATOP_MEMBEROFGROUP_ARGB|
102 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
103
104 {D3DDDIFMT_A4R4G4B4,
105 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
106 FORMATOP_SAME_FORMAT_RENDERTARGET|
107 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
108 FORMATOP_OFFSCREENPLAIN|
109 0|
110 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
111
112 {D3DDDIFMT_R5G6B5,
113 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
114 FORMATOP_SAME_FORMAT_RENDERTARGET|
115 FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|
116 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
117 FORMATOP_MEMBEROFGROUP_ARGB|
118 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
119
120 {D3DDDIFMT_L16,
121 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
122 0|
123 0|
124 FORMATOP_OFFSCREENPLAIN|
125 0|
126 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
127
128 {D3DDDIFMT_A8L8,
129 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
130 0|
131 0|
132 FORMATOP_OFFSCREENPLAIN|
133 0|
134 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
135
136 {D3DDDIFMT_A8,
137 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
138 0|
139 0|
140 FORMATOP_OFFSCREENPLAIN|
141 0|
142 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
143
144 {D3DDDIFMT_L8,
145 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
146 0|
147 0|
148 FORMATOP_OFFSCREENPLAIN|
149 0|
150 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
151
152 {D3DDDIFMT_D16, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
153 {D3DDDIFMT_D24S8, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
154 {D3DDDIFMT_D24X8, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
155 {D3DDDIFMT_D16_LOCKABLE, FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
156 {D3DDDIFMT_X8D24, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
157 {D3DDDIFMT_D32F_LOCKABLE, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
158 {D3DDDIFMT_S8D24, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
159
160 {D3DDDIFMT_DXT1,
161 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
162 0|
163 0|
164 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
165 0|
166 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
167
168 {D3DDDIFMT_DXT2,
169 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
170 0|
171 0|
172 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
173 0|
174 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
175
176 {D3DDDIFMT_DXT3,
177 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
178 0|
179 0|
180 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
181 0|
182 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
183
184 {D3DDDIFMT_DXT4,
185 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
186 0|
187 0|
188 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
189 0|
190 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
191
192 {D3DDDIFMT_DXT5,
193 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
194 0|
195 0|
196 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
197 0|
198 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
199
200 {D3DDDIFMT_X8L8V8U8,
201 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
202 0|
203 0|
204 0|
205 FORMATOP_BUMPMAP|
206 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
207
208 {D3DDDIFMT_A2W10V10U10,
209 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
210 0|
211 0|
212 0|
213 FORMATOP_BUMPMAP|
214 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
215
216 {D3DDDIFMT_V8U8,
217 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
218 0|
219 0|
220 0|
221 FORMATOP_BUMPMAP|
222 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
223
224 {D3DDDIFMT_Q8W8V8U8,
225 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
226 0|
227 0|
228 FORMATOP_OFFSCREENPLAIN|
229 FORMATOP_BUMPMAP|
230 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
231
232 {D3DDDIFMT_CxV8U8, FORMATOP_NOFILTER|FORMATOP_NOALPHABLEND|FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
233
234 {D3DDDIFMT_R16F,
235 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
236 FORMATOP_SAME_FORMAT_RENDERTARGET|
237 0|
238 FORMATOP_OFFSCREENPLAIN|
239 0|
240 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
241
242 {D3DDDIFMT_R32F,
243 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
244 FORMATOP_SAME_FORMAT_RENDERTARGET|
245 0|
246 FORMATOP_OFFSCREENPLAIN|
247 0|
248 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
249
250 {D3DDDIFMT_G16R16F,
251 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
252 FORMATOP_SAME_FORMAT_RENDERTARGET|
253 0|
254 FORMATOP_OFFSCREENPLAIN|
255 0|
256 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
257
258 {D3DDDIFMT_G32R32F,
259 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
260 FORMATOP_SAME_FORMAT_RENDERTARGET|
261 0|
262 FORMATOP_OFFSCREENPLAIN|
263 0|
264 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
265
266 {D3DDDIFMT_A16B16G16R16F,
267 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
268 FORMATOP_SAME_FORMAT_RENDERTARGET|
269 0|
270 FORMATOP_OFFSCREENPLAIN|
271 0|
272 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
273
274 {D3DDDIFMT_A32B32G32R32F,
275 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
276 FORMATOP_SAME_FORMAT_RENDERTARGET|
277 0|
278 FORMATOP_OFFSCREENPLAIN|
279 0|
280 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
281
282 {D3DDDIFMT_G16R16,
283 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
284 FORMATOP_SAME_FORMAT_RENDERTARGET|
285 0|
286 FORMATOP_OFFSCREENPLAIN|
287 0|
288 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
289
290 {D3DDDIFMT_A16B16G16R16,
291 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
292 FORMATOP_SAME_FORMAT_RENDERTARGET|
293 0|
294 FORMATOP_OFFSCREENPLAIN|
295 0|
296 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
297
298 {D3DDDIFMT_V16U16,
299 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
300 0|
301 0|
302 0|
303 FORMATOP_BUMPMAP|
304 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
305
306 {D3DDDIFMT_P8, FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|FORMATOP_OFFSCREENPLAIN, 0, 0, 0},
307
308 {D3DDDIFMT_UYVY,
309 0|
310 0|
311 0|
312 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
313 FORMATOP_NOFILTER|
314 FORMATOP_NOALPHABLEND|
315 FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
316
317 {D3DDDIFMT_YUY2,
318 0|
319 0|
320 0|
321 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
322 FORMATOP_NOFILTER|
323 FORMATOP_NOALPHABLEND|
324 FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
325
326 {D3DDDIFMT_Q16W16V16U16,
327 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
328 FORMATOP_SAME_FORMAT_RENDERTARGET|
329 0|
330 FORMATOP_OFFSCREENPLAIN|
331 FORMATOP_BUMPMAP|FORMATOP_DMAP|
332 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
333
334 {D3DDDIFMT_X8B8G8R8,
335 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
336 FORMATOP_SAME_FORMAT_RENDERTARGET|
337 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
338 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
339 FORMATOP_DMAP|FORMATOP_MEMBEROFGROUP_ARGB|
340 FORMATOP_SRGBWRITE|FORMATOP_AUTOGENMIPMAP|FORMATOP_VERTEXTEXTURE|
341 FORMATOP_OVERLAY, 0, 0, 0},
342
343 {D3DDDIFMT_BINARYBUFFER, FORMATOP_OFFSCREENPLAIN, 0, 0, 0},
344
345 {D3DDDIFMT_A4L4,
346 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
347 0|
348 0|
349 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
350 FORMATOP_DMAP|
351 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
352
353 {D3DDDIFMT_A2B10G10R10,
354 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
355 FORMATOP_SAME_FORMAT_RENDERTARGET|
356 0|
357 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
358 FORMATOP_DMAP|FORMATOP_MEMBEROFGROUP_ARGB|
359 FORMATOP_AUTOGENMIPMAP|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
360};
361
362static FORMATOP gVBoxFormatOpsBase[] = {
363 {D3DDDIFMT_X8R8G8B8, FORMATOP_DISPLAYMODE, 0, 0, 0},
364
365 {D3DDDIFMT_R8G8B8, FORMATOP_DISPLAYMODE, 0, 0, 0},
366
367 {D3DDDIFMT_R5G6B5, FORMATOP_DISPLAYMODE, 0, 0, 0},
368
369 {D3DDDIFMT_P8, FORMATOP_DISPLAYMODE, 0, 0, 0},
370};
371
372static DDSURFACEDESC gVBoxSurfDescsBase[] = {
373 {
374 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
375 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
376 0, /* DWORD dwHeight; */
377 0, /* DWORD dwWidth; */
378 {
379 0, /* Union */
380 /* LONG lPitch; */
381 /* DWORD dwLinearSize; */
382 },
383 0, /* DWORD dwBackBufferCount; */
384 {
385 0, /* Union */
386 /* DWORD dwMipMapCount; */
387 /* DWORD dwZBufferBitDepth; */
388 /* DWORD dwRefreshRate; */
389 },
390 0, /* DWORD dwAlphaBitDepth; */
391 0, /* DWORD dwReserved; */
392 NULL, /* LPVOID lpSurface; */
393 {
394 0, /* DWORD dwColorSpaceLowValue; */
395 0, /* DWORD dwColorSpaceHighValue; */
396 }, /* DDCOLORKEY ddckCKDestOverlay; */
397 {
398 0, /* DWORD dwColorSpaceLowValue; */
399 0, /* DWORD dwColorSpaceHighValue; */
400 }, /* DDCOLORKEY ddckCKDestBlt; */
401 {
402 0, /* DWORD dwColorSpaceLowValue; */
403 0, /* DWORD dwColorSpaceHighValue; */
404 }, /* DDCOLORKEY ddckCKSrcOverlay; */
405 {
406 0, /* DWORD dwColorSpaceLowValue; */
407 0, /* DWORD dwColorSpaceHighValue; */
408 }, /* DDCOLORKEY ddckCKSrcBlt; */
409 {
410 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
411 DDPF_RGB, /* DWORD dwFlags; */
412 0, /* DWORD dwFourCC; */
413 {
414 32, /* union */
415 /* DWORD dwRGBBitCount; */
416 /* DWORD dwYUVBitCount; */
417 /* DWORD dwZBufferBitDepth; */
418 /* DWORD dwAlphaBitDepth; */
419 /* DWORD dwLuminanceBitCount; */
420 /* DWORD dwBumpBitCount; */
421 },
422 {
423 0xff0000, /* union */
424 /* DWORD dwRBitMask; */
425 /* DWORD dwYBitMask; */
426 /* DWORD dwStencilBitDepth; */
427 /* DWORD dwLuminanceBitMask; */
428 /* DWORD dwBumpDuBitMask; */
429 },
430 {
431 0xff00,
432 /* DWORD dwGBitMask; */
433 /* DWORD dwUBitMask; */
434 /* DWORD dwZBitMask; */
435 /* DWORD dwBumpDvBitMask; */
436 },
437 {
438 0xff,
439 /* DWORD dwBBitMask; */
440 /* DWORD dwVBitMask; */
441 /* DWORD dwStencilBitMask; */
442 /* DWORD dwBumpLuminanceBitMask; */
443 },
444 {
445 0,
446 /* DWORD dwRGBAlphaBitMask; */
447 /* DWORD dwYUVAlphaBitMask; */
448 /* DWORD dwLuminanceAlphaBitMask; */
449 /* DWORD dwRGBZBitMask; */
450 /* DWORD dwYUVZBitMask; */
451 },
452 }, /* DDPIXELFORMAT ddpfPixelFormat; */
453 {
454 DDSCAPS_BACKBUFFER
455 | DDSCAPS_COMPLEX
456 | DDSCAPS_FLIP
457 | DDSCAPS_FRONTBUFFER
458 | DDSCAPS_LOCALVIDMEM
459 | DDSCAPS_PRIMARYSURFACE
460 | DDSCAPS_VIDEOMEMORY
461 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
462 } /* DDSCAPS ddsCaps; */
463 },
464 {
465 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
466 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
467 0, /* DWORD dwHeight; */
468 0, /* DWORD dwWidth; */
469 {
470 0, /* Union */
471 /* LONG lPitch; */
472 /* DWORD dwLinearSize; */
473 },
474 0, /* DWORD dwBackBufferCount; */
475 {
476 0, /* Union */
477 /* DWORD dwMipMapCount; */
478 /* DWORD dwZBufferBitDepth; */
479 /* DWORD dwRefreshRate; */
480 },
481 0, /* DWORD dwAlphaBitDepth; */
482 0, /* DWORD dwReserved; */
483 NULL, /* LPVOID lpSurface; */
484 {
485 0, /* DWORD dwColorSpaceLowValue; */
486 0, /* DWORD dwColorSpaceHighValue; */
487 }, /* DDCOLORKEY ddckCKDestOverlay; */
488 {
489 0, /* DWORD dwColorSpaceLowValue; */
490 0, /* DWORD dwColorSpaceHighValue; */
491 }, /* DDCOLORKEY ddckCKDestBlt; */
492 {
493 0, /* DWORD dwColorSpaceLowValue; */
494 0, /* DWORD dwColorSpaceHighValue; */
495 }, /* DDCOLORKEY ddckCKSrcOverlay; */
496 {
497 0, /* DWORD dwColorSpaceLowValue; */
498 0, /* DWORD dwColorSpaceHighValue; */
499 }, /* DDCOLORKEY ddckCKSrcBlt; */
500 {
501 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
502 DDPF_RGB, /* DWORD dwFlags; */
503 0, /* DWORD dwFourCC; */
504 {
505 24, /* union */
506 /* DWORD dwRGBBitCount; */
507 /* DWORD dwYUVBitCount; */
508 /* DWORD dwZBufferBitDepth; */
509 /* DWORD dwAlphaBitDepth; */
510 /* DWORD dwLuminanceBitCount; */
511 /* DWORD dwBumpBitCount; */
512 },
513 {
514 0xff0000, /* union */
515 /* DWORD dwRBitMask; */
516 /* DWORD dwYBitMask; */
517 /* DWORD dwStencilBitDepth; */
518 /* DWORD dwLuminanceBitMask; */
519 /* DWORD dwBumpDuBitMask; */
520 },
521 {
522 0xff00,
523 /* DWORD dwGBitMask; */
524 /* DWORD dwUBitMask; */
525 /* DWORD dwZBitMask; */
526 /* DWORD dwBumpDvBitMask; */
527 },
528 {
529 0xff,
530 /* DWORD dwBBitMask; */
531 /* DWORD dwVBitMask; */
532 /* DWORD dwStencilBitMask; */
533 /* DWORD dwBumpLuminanceBitMask; */
534 },
535 {
536 0,
537 /* DWORD dwRGBAlphaBitMask; */
538 /* DWORD dwYUVAlphaBitMask; */
539 /* DWORD dwLuminanceAlphaBitMask; */
540 /* DWORD dwRGBZBitMask; */
541 /* DWORD dwYUVZBitMask; */
542 },
543 }, /* DDPIXELFORMAT ddpfPixelFormat; */
544 {
545 DDSCAPS_BACKBUFFER
546 | DDSCAPS_COMPLEX
547 | DDSCAPS_FLIP
548 | DDSCAPS_FRONTBUFFER
549 | DDSCAPS_LOCALVIDMEM
550 | DDSCAPS_PRIMARYSURFACE
551 | DDSCAPS_VIDEOMEMORY
552 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
553 } /* DDSCAPS ddsCaps; */
554 },
555 {
556 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
557 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
558 0, /* DWORD dwHeight; */
559 0, /* DWORD dwWidth; */
560 {
561 0, /* Union */
562 /* LONG lPitch; */
563 /* DWORD dwLinearSize; */
564 },
565 0, /* DWORD dwBackBufferCount; */
566 {
567 0, /* Union */
568 /* DWORD dwMipMapCount; */
569 /* DWORD dwZBufferBitDepth; */
570 /* DWORD dwRefreshRate; */
571 },
572 0, /* DWORD dwAlphaBitDepth; */
573 0, /* DWORD dwReserved; */
574 NULL, /* LPVOID lpSurface; */
575 {
576 0, /* DWORD dwColorSpaceLowValue; */
577 0, /* DWORD dwColorSpaceHighValue; */
578 }, /* DDCOLORKEY ddckCKDestOverlay; */
579 {
580 0, /* DWORD dwColorSpaceLowValue; */
581 0, /* DWORD dwColorSpaceHighValue; */
582 }, /* DDCOLORKEY ddckCKDestBlt; */
583 {
584 0, /* DWORD dwColorSpaceLowValue; */
585 0, /* DWORD dwColorSpaceHighValue; */
586 }, /* DDCOLORKEY ddckCKSrcOverlay; */
587 {
588 0, /* DWORD dwColorSpaceLowValue; */
589 0, /* DWORD dwColorSpaceHighValue; */
590 }, /* DDCOLORKEY ddckCKSrcBlt; */
591 {
592 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
593 DDPF_RGB, /* DWORD dwFlags; */
594 0, /* DWORD dwFourCC; */
595 {
596 16, /* union */
597 /* DWORD dwRGBBitCount; */
598 /* DWORD dwYUVBitCount; */
599 /* DWORD dwZBufferBitDepth; */
600 /* DWORD dwAlphaBitDepth; */
601 /* DWORD dwLuminanceBitCount; */
602 /* DWORD dwBumpBitCount; */
603 },
604 {
605 0xf800, /* union */
606 /* DWORD dwRBitMask; */
607 /* DWORD dwYBitMask; */
608 /* DWORD dwStencilBitDepth; */
609 /* DWORD dwLuminanceBitMask; */
610 /* DWORD dwBumpDuBitMask; */
611 },
612 {
613 0x7e0,
614 /* DWORD dwGBitMask; */
615 /* DWORD dwUBitMask; */
616 /* DWORD dwZBitMask; */
617 /* DWORD dwBumpDvBitMask; */
618 },
619 {
620 0x1f,
621 /* DWORD dwBBitMask; */
622 /* DWORD dwVBitMask; */
623 /* DWORD dwStencilBitMask; */
624 /* DWORD dwBumpLuminanceBitMask; */
625 },
626 {
627 0,
628 /* DWORD dwRGBAlphaBitMask; */
629 /* DWORD dwYUVAlphaBitMask; */
630 /* DWORD dwLuminanceAlphaBitMask; */
631 /* DWORD dwRGBZBitMask; */
632 /* DWORD dwYUVZBitMask; */
633 },
634 }, /* DDPIXELFORMAT ddpfPixelFormat; */
635 {
636 DDSCAPS_BACKBUFFER
637 | DDSCAPS_COMPLEX
638 | DDSCAPS_FLIP
639 | DDSCAPS_FRONTBUFFER
640 | DDSCAPS_LOCALVIDMEM
641 | DDSCAPS_PRIMARYSURFACE
642 | DDSCAPS_VIDEOMEMORY
643 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
644 } /* DDSCAPS ddsCaps; */
645 },
646};
647
648static D3DDDIQUERYTYPE gVBoxQueryTypes[] = {
649 D3DDDIQUERYTYPE_EVENT,
650// D3DDDIQUERYTYPE_OCCLUSION
651};
652
653#define VBOX_QUERYTYPE_COUNT() RT_ELEMENTS(gVBoxQueryTypes)
654
655#ifdef VBOX_WITH_VIDEOHWACCEL
656
657static bool vboxVhwaIsEnabled(PVBOXWDDMDISP_ADAPTER pAdapter)
658{
659 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
660 {
661 if (pAdapter->aHeads[i].Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED)
662 return true;
663 }
664 return false;
665}
666
667static bool vboxVhwaHasCKeying(PVBOXWDDMDISP_ADAPTER pAdapter)
668{
669 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
670 {
671 VBOXVHWA_INFO* pSettings = &pAdapter->aHeads[i].Vhwa.Settings;
672 if ((pSettings->fFlags & VBOXVHWA_F_ENABLED)
673 && ((pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
674 || (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC))
675 )
676 return true;
677 }
678 return false;
679}
680
681static void vboxVhwaPopulateOverlayFourccSurfDesc(DDSURFACEDESC *pDesc, uint32_t fourcc)
682{
683 memset(pDesc, 0, sizeof (DDSURFACEDESC));
684
685 pDesc->dwSize = sizeof (DDSURFACEDESC);
686 pDesc->dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT;
687 pDesc->ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT);
688 pDesc->ddpfPixelFormat.dwFlags = DDPF_FOURCC;
689 pDesc->ddpfPixelFormat.dwFourCC = fourcc;
690 pDesc->ddsCaps.dwCaps = DDSCAPS_BACKBUFFER
691 | DDSCAPS_COMPLEX
692 | DDSCAPS_FLIP
693 | DDSCAPS_FRONTBUFFER
694 | DDSCAPS_LOCALVIDMEM
695 | DDSCAPS_OVERLAY
696 | DDSCAPS_VIDEOMEMORY
697 | DDSCAPS_VISIBLE;
698}
699
700#endif
701
702static bool vboxPixFormatMatch(DDPIXELFORMAT *pFormat1, DDPIXELFORMAT *pFormat2)
703{
704 return !memcmp(pFormat1, pFormat2, sizeof (DDPIXELFORMAT));
705}
706
707int vboxSurfDescMerge(DDSURFACEDESC *paDescs, uint32_t *pcDescs, uint32_t cMaxDescs, DDSURFACEDESC *pDesc)
708{
709 uint32_t cDescs = *pcDescs;
710
711 Assert(cMaxDescs >= cDescs);
712 Assert(pDesc->dwFlags == (DDSD_CAPS | DDSD_PIXELFORMAT));
713 if (pDesc->dwFlags != (DDSD_CAPS | DDSD_PIXELFORMAT))
714 return VERR_INVALID_PARAMETER;
715
716 for (uint32_t i = 0; i < cDescs; ++i)
717 {
718 DDSURFACEDESC *pCur = &paDescs[i];
719 if (vboxPixFormatMatch(&pCur->ddpfPixelFormat, &pDesc->ddpfPixelFormat))
720 {
721 if (pDesc->dwFlags & DDSD_CAPS)
722 {
723 pCur->dwFlags |= DDSD_CAPS;
724 pCur->ddsCaps.dwCaps |= pDesc->ddsCaps.dwCaps;
725 }
726 return VINF_SUCCESS;
727 }
728 }
729
730 if (cMaxDescs > cDescs)
731 {
732 paDescs[cDescs] = *pDesc;
733 ++cDescs;
734 *pcDescs = cDescs;
735 return VINF_SUCCESS;
736 }
737 return VERR_BUFFER_OVERFLOW;
738}
739
740int vboxFormatOpsMerge(FORMATOP *paOps, uint32_t *pcOps, uint32_t cMaxOps, FORMATOP *pOp)
741{
742 uint32_t cOps = *pcOps;
743
744 Assert(cMaxOps >= cOps);
745
746 for (uint32_t i = 0; i < cOps; ++i)
747 {
748 FORMATOP *pCur = &paOps[i];
749 if (pCur->Format == pOp->Format)
750 {
751 pCur->Operations |= pOp->Operations;
752 Assert(pCur->FlipMsTypes == pOp->FlipMsTypes);
753 Assert(pCur->BltMsTypes == pOp->BltMsTypes);
754 Assert(pCur->PrivateFormatBitCount == pOp->PrivateFormatBitCount);
755 return VINF_SUCCESS;
756 }
757 }
758
759 if (cMaxOps > cOps)
760 {
761 paOps[cOps] = *pOp;
762 ++cOps;
763 *pcOps = cOps;
764 return VINF_SUCCESS;
765 }
766 return VERR_BUFFER_OVERFLOW;
767}
768
769int vboxCapsInit(PVBOXWDDMDISP_ADAPTER pAdapter)
770{
771 pAdapter->cFormstOps = 0;
772 pAdapter->paFormstOps = NULL;
773 pAdapter->cSurfDescs = 0;
774 pAdapter->paSurfDescs = NULL;
775
776 if (pAdapter->uIfVersion > 7)
777 {
778 if (pAdapter->pD3D9If)
779 {
780 pAdapter->paFormstOps = (FORMATOP*)RTMemAllocZ(sizeof (gVBoxFormatOps3D));
781 Assert(pAdapter->paFormstOps);
782 if (pAdapter->paFormstOps)
783 {
784 memcpy (pAdapter->paFormstOps , gVBoxFormatOps3D, sizeof (gVBoxFormatOps3D));
785 pAdapter->cFormstOps = RT_ELEMENTS(gVBoxFormatOps3D);
786 }
787 else
788 return VERR_OUT_OF_RESOURCES;
789
790 /* @todo: do we need surface caps here ? */
791 }
792 }
793#ifdef VBOX_WITH_VIDEOHWACCEL
794 else
795 {
796 /* just calc the max number of formats */
797 uint32_t cFormats = RT_ELEMENTS(gVBoxFormatOpsBase);
798 uint32_t cSurfDescs = RT_ELEMENTS(gVBoxSurfDescsBase);
799 uint32_t cOverlayFormats = 0;
800 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
801 {
802 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
803 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
804 {
805 cOverlayFormats += pVhwa->Settings.cFormats;
806 }
807 }
808
809 cFormats += cOverlayFormats;
810 cSurfDescs += cOverlayFormats;
811
812 uint32_t cbFormatOps = cFormats * sizeof (FORMATOP);
813 cbFormatOps = (cbFormatOps + 7) & ~3;
814 /* ensure the surf descs are 8 byte alligned */
815 uint32_t offSurfDescs = (cbFormatOps + 7) & ~3;
816 uint32_t cbSurfDescs = cSurfDescs * sizeof (DDSURFACEDESC);
817 uint32_t cbBuf = offSurfDescs + cbSurfDescs;
818 uint8_t* pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
819 Assert(pvBuf);
820 if (pvBuf)
821 {
822 pAdapter->paFormstOps = (FORMATOP*)pvBuf;
823 memcpy (pAdapter->paFormstOps , gVBoxFormatOpsBase, sizeof (gVBoxFormatOpsBase));
824 pAdapter->cFormstOps = RT_ELEMENTS(gVBoxFormatOpsBase);
825
826 FORMATOP fo = {D3DDDIFMT_UNKNOWN, 0, 0, 0, 0};
827 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
828 {
829 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
830 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
831 {
832 for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j)
833 {
834 fo.Format = pVhwa->Settings.aFormats[j];
835 fo.Operations = FORMATOP_OVERLAY;
836 int rc = vboxFormatOpsMerge(pAdapter->paFormstOps, &pAdapter->cFormstOps, cFormats, &fo);
837 AssertRC(rc);
838 }
839 }
840 }
841
842 pAdapter->paSurfDescs = (DDSURFACEDESC*)(pvBuf + offSurfDescs);
843 memcpy (pAdapter->paSurfDescs , gVBoxSurfDescsBase, sizeof (gVBoxSurfDescsBase));
844 pAdapter->cSurfDescs = RT_ELEMENTS(gVBoxSurfDescsBase);
845
846 DDSURFACEDESC sd;
847 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
848 {
849 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
850 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
851 {
852 for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j)
853 {
854 uint32_t fourcc = vboxWddmFormatToFourcc(pVhwa->Settings.aFormats[j]);
855 if (fourcc)
856 {
857 vboxVhwaPopulateOverlayFourccSurfDesc(&sd, fourcc);
858 int rc = vboxSurfDescMerge(pAdapter->paSurfDescs, &pAdapter->cSurfDescs, cSurfDescs, &sd);
859 AssertRC(rc);
860 }
861 }
862 }
863 }
864 }
865 else
866 return VERR_OUT_OF_RESOURCES;
867 }
868#endif
869
870 return VINF_SUCCESS;
871}
872
873void vboxCapsFree(PVBOXWDDMDISP_ADAPTER pAdapter)
874{
875 if (pAdapter->paFormstOps)
876 RTMemFree(pAdapter->paFormstOps);
877}
878
879static void vboxResourceFree(PVBOXWDDMDISP_RESOURCE pRc)
880{
881 RTMemFree(pRc);
882}
883
884static PVBOXWDDMDISP_RESOURCE vboxResourceAlloc(UINT cAllocs)
885{
886 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_RESOURCE, aAllocations[cAllocs]));
887 Assert(pRc);
888 if (pRc)
889 {
890 pRc->cAllocations = cAllocs;
891 for (UINT i = 0; i < cAllocs; ++i)
892 {
893 pRc->aAllocations[i].iAlloc = i;
894 pRc->aAllocations[i].pRc = pRc;
895 }
896 return pRc;
897 }
898 return NULL;
899}
900
901static void vboxWddmLockUnlockMemSynch(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DLOCKED_RECT *pLockInfo, RECT *pRect, bool bToLockInfo)
902{
903 Assert(pAlloc->SurfDesc.pitch);
904 Assert(pAlloc->pvMem);
905
906 if (!pRect)
907 {
908 if (pAlloc->SurfDesc.pitch == pLockInfo->Pitch)
909 {
910 if (bToLockInfo)
911 memcpy(pLockInfo->pBits, pAlloc->pvMem, pAlloc->SurfDesc.pitch * pAlloc->SurfDesc.height);
912 else
913 memcpy(pAlloc->pvMem, pLockInfo->pBits, pAlloc->SurfDesc.pitch * pAlloc->SurfDesc.height);
914 }
915 else
916 {
917 uint8_t *pvSrc, *pvDst;
918 uint32_t srcPitch, dstPitch;
919 if (bToLockInfo)
920 {
921 pvSrc = (uint8_t *)pAlloc->pvMem;
922 pvDst = (uint8_t *)pLockInfo->pBits;
923 srcPitch = pAlloc->SurfDesc.pitch;
924 dstPitch = pLockInfo->Pitch;
925 }
926 else
927 {
928 pvDst = (uint8_t *)pAlloc->pvMem;
929 pvSrc = (uint8_t *)pLockInfo->pBits;
930 dstPitch = pAlloc->SurfDesc.pitch;
931 srcPitch = (uint32_t)pLockInfo->Pitch;
932 }
933
934 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
935 Assert(pitch);
936 for (UINT j = 0; j < pAlloc->SurfDesc.height; ++j)
937 {
938 memcpy(pvDst, pvSrc, pitch);
939 pvSrc += srcPitch;
940 pvDst += dstPitch;
941 }
942 }
943 }
944 else
945 {
946 uint8_t *pvSrc, *pvDst;
947 uint32_t srcPitch, dstPitch;
948 /* @todo: this is not entirely correct */
949 uint8_t * pvAllocMemStart = (uint8_t *)pAlloc->pvMem;
950 uint32_t cbPP = pAlloc->SurfDesc.pitch/pAlloc->SurfDesc.width;
951 pvAllocMemStart += pAlloc->SurfDesc.pitch * pRect->top + pRect->left * cbPP;
952
953 if (bToLockInfo)
954 {
955 pvSrc = (uint8_t *)pvAllocMemStart;
956 pvDst = (uint8_t *)pLockInfo->pBits;
957 srcPitch = pAlloc->SurfDesc.pitch;
958 dstPitch = pLockInfo->Pitch;
959 }
960 else
961 {
962 pvDst = (uint8_t *)pvAllocMemStart;
963 pvSrc = (uint8_t *)pLockInfo->pBits;
964 dstPitch = pAlloc->SurfDesc.pitch;
965 srcPitch = (uint32_t)pLockInfo->Pitch;
966 }
967
968 uint32_t cPixCopyLine = pRect->right - pRect->left;
969
970 if (cPixCopyLine == pAlloc->SurfDesc.width && srcPitch == dstPitch)
971 {
972 memcpy(pvDst, pvSrc, pAlloc->SurfDesc.pitch * (pRect->bottom - pRect->top));
973 }
974 else
975 {
976 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
977 uint32_t cbCopyLine = cPixCopyLine * cbPP;
978 Assert(pitch);
979 for (int j = pRect->top; j < pRect->bottom; ++j)
980 {
981 memcpy(pvDst, pvSrc, cbCopyLine);
982 pvSrc += srcPitch;
983 pvDst += dstPitch;
984 }
985 }
986 }
987}
988
989#if 0
990static HRESULT vboxWddmRectBltPerform(uint8_t *pvDstSurf, const uint8_t *pvSrcSurf,
991 RECT *pDstRect, RECT *pSrcRect,
992 uint32_t DstPitch, uint32_t SrcPitch, uint32_t bpp,
993 RECT *pDstCopyRect, RECT *pSrcCopyRect)
994{
995 uint32_t DstCopyWidth = pDstCopyRect->left - pDstCopyRect->right;
996 uint32_t DstCopyHeight = pDstCopyRect->bottom - pDstCopyRect->top;
997 uint32_t SrcCopyWidth = pSrcCopyRect->left - pSrcCopyRect->right;
998 uint32_t SrcCopyHeight = pSrcCopyRect->bottom - pSrcCopyRect->top;
999 uint32_t srcBpp = bpp;
1000 uint32_t dstBpp = bpp;
1001 /* we do not support stretching */
1002 Assert(DstCopyWidth == SrcCopyWidth);
1003 Assert(DstCopyHeight == SrcCopyWidth);
1004 if (DstCopyWidth != SrcCopyWidth)
1005 return E_FAIL;
1006 if (DstCopyHeight != SrcCopyWidth)
1007 return E_FAIL;
1008
1009 uint32_t DstWidth = pDstRect->left - pDstRect->right;
1010 uint32_t DstHeight = pDstRect->bottom - pDstRect->top;
1011 uint32_t SrcWidth = pSrcRect->left - pSrcRect->right;
1012 uint32_t SrcHeight = pSrcRect->bottom - pSrcRect->top;
1013
1014 if (DstWidth == DstCopyWidth
1015 && SrcWidth == SrcCopyWidth
1016 && SrcWidth == DstWidth)
1017 {
1018 Assert(!pDstCopyRect->left);
1019 Assert(!pSrcCopyRect->left);
1020 uint32_t cbOff = DstPitch * pDstCopyRect->top;
1021 uint32_t cbSize = DstPitch * DstCopyHeight;
1022 memcpy(pvDstSurf + cbOff, pvSrcSurf + cbOff, cbSize);
1023 }
1024 else
1025 {
1026 uint32_t offDstLineStart = pDstCopyRect->left * dstBpp >> 3;
1027 uint32_t offDstLineEnd = ((pDstCopyRect->left * dstBpp + 7) >> 3) + ((dstBpp * DstCopyWidth + 7) >> 3);
1028 uint32_t cbDstLine = offDstLineEnd - offDstLineStart;
1029 uint32_t offDstStart = DstPitch * pDstCopyRect->top + offDstLineStart;
1030 Assert(cbDstLine <= DstPitch);
1031 uint32_t cbDstSkip = DstPitch;
1032 uint8_t * pvDstStart = pvDstSurf + offDstStart;
1033
1034 uint32_t offSrcLineStart = pSrcCopyRect->left * srcBpp >> 3;
1035 uint32_t offSrcLineEnd = ((pSrcCopyRect->left * srcBpp + 7) >> 3) + ((srcBpp * SrcCopyWidth + 7) >> 3);
1036 uint32_t cbSrcLine = offSrcLineEnd - offSrcLineStart;
1037 uint32_t offSrcStart = SrcPitch * pSrcCopyRect->top + offSrcLineStart;
1038 Assert(cbSrcLine <= SrcPitch);
1039 uint32_t cbSrcSkip = SrcPitch;
1040 const uint8_t * pvSrcStart = pvSrcSurf + offSrcStart;
1041
1042 Assert(cbDstLine == cbSrcLine);
1043
1044 for (uint32_t i = 0; ; ++i)
1045 {
1046 memcpy (pvDstStart, pvSrcStart, cbDstLine);
1047 if (i == DstCopyHeight)
1048 break;
1049 pvDstStart += cbDstSkip;
1050 pvSrcStart += cbSrcSkip;
1051 }
1052 }
1053 return S_OK;
1054}
1055#endif
1056
1057static HRESULT vboxWddmRectBltPerform(uint8_t *pvDstSurf, const uint8_t *pvSrcSurf,
1058 const RECT *pDstRect, const RECT *pSrcRect,
1059 uint32_t DstPitch, uint32_t SrcPitch, uint32_t bpp)
1060{
1061 uint32_t DstWidth = pDstRect->left - pDstRect->right;
1062 uint32_t DstHeight = pDstRect->bottom - pDstRect->top;
1063 uint32_t SrcWidth = pSrcRect->left - pSrcRect->right;
1064 uint32_t SrcHeight = pSrcRect->bottom - pSrcRect->top;
1065 uint32_t srcBpp = bpp;
1066 uint32_t dstBpp = bpp;
1067 /* we do not support stretching */
1068 Assert(DstWidth == SrcWidth);
1069 Assert(DstHeight == SrcWidth);
1070 if (DstWidth != SrcWidth)
1071 return E_FAIL;
1072 if (DstHeight != SrcWidth)
1073 return E_FAIL;
1074
1075 if (DstPitch == SrcPitch
1076 && ((DstWidth * bpp)/8) == DstPitch)
1077 {
1078 Assert(!pDstRect->left);
1079 Assert(!pSrcRect->left);
1080 uint32_t cbOff = DstPitch * pDstRect->top;
1081 uint32_t cbSize = DstPitch * DstHeight;
1082 memcpy(pvDstSurf + cbOff, pvSrcSurf + cbOff, cbSize);
1083 }
1084 else
1085 {
1086
1087 uint32_t cbDstLine = (((DstWidth * dstBpp) + 7) >> 3);
1088 for (uint32_t i = 0; ; ++i)
1089 {
1090 memcpy (pvDstSurf, pvSrcSurf, cbDstLine);
1091 if (i == DstHeight)
1092 break;
1093 pvDstSurf += DstPitch;
1094 pvSrcSurf += SrcPitch;
1095 }
1096 }
1097 return S_OK;
1098}
1099
1100static HRESULT vboxWddmSurfSynchMem(PVBOXWDDMDISP_RESOURCE pRc, PVBOXWDDMDISP_ALLOCATION pAllocation)
1101{
1102 HRESULT hr = S_OK;
1103 Assert(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
1104 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
1105 {
1106 Assert(pAllocation->pvMem);
1107 D3DLOCKED_RECT lockInfo;
1108 IDirect3DSurface9 *pD3D9Surf = (IDirect3DSurface9*)pAllocation->pD3DIf;
1109 hr = pD3D9Surf->LockRect(&lockInfo, NULL, D3DLOCK_DISCARD);
1110 Assert(hr == S_OK);
1111 if (hr == S_OK)
1112 {
1113 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
1114 HRESULT tmpHr = pD3D9Surf->UnlockRect();
1115 Assert(tmpHr == S_OK);
1116 }
1117 }
1118 else
1119 {
1120 Assert(!pAllocation->pvMem);
1121 }
1122 return hr;
1123}
1124
1125#if 0
1126static HRESULT vboxWddmRenderTargetUpdateSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf)
1127{
1128 if (pAlloc->SurfDesc.VidPnSourceId != pDevice->iPrimaryScreen)
1129 return S_OK;
1130
1131 IDirect3DSurface9 *pD3D9Surf;
1132 IDirect3DDevice9 *pDevice9If = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
1133 HRESULT hr = pDevice9If->GetBackBuffer(0 /*UINT iSwapChain*/,
1134 iBBuf, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
1135 Assert(hr == S_OK);
1136 if (hr == S_OK)
1137 {
1138 Assert(pD3D9Surf);
1139 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
1140 if (pAlloc->pD3DIf)
1141 pAlloc->pD3DIf->Release();
1142 pAlloc->pD3DIf = pD3D9Surf;
1143 }
1144 return hr;
1145}
1146static HRESULT vboxWddmRenderTargetUpdate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB)
1147{
1148 if (pRc->RcDesc.VidPnSourceId != pDevice->iPrimaryScreen)
1149 return S_OK;
1150
1151 PVBOXWDDMDISP_ALLOCATION pAlloc;
1152 UINT iBBuf = 0;
1153 Assert(iNewRTFB < pRc->cAllocations);
1154
1155 for (UINT i = 1; i < pRc->cAllocations; ++i, ++iBBuf)
1156 {
1157 UINT iAlloc = (iNewRTFB + i) % pRc->cAllocations;
1158 Assert(iAlloc != iNewRTFB);
1159 pAlloc = &pRc->aAllocations[iAlloc];
1160 HRESULT tmpHr = vboxWddmRenderTargetUpdateSurface(pDevice, pAlloc, iBBuf);
1161 Assert(tmpHr == S_OK);
1162 }
1163
1164 pAlloc = &pRc->aAllocations[iNewRTFB];
1165 if (pRc->cAllocations > 1)
1166 {
1167#ifdef VBOXWDDM_WITH_VISIBLE_FB
1168 HRESULT tmpHr = vboxWddmRenderTargetUpdateSurface(pDevice, pAlloc, ~0UL /* <- for the frontbuffer */);
1169 Assert(tmpHr == S_OK);
1170#else
1171 if (pAlloc->pD3DIf)
1172 {
1173 pAlloc->pD3DIf->Release();
1174 pAlloc->pD3DIf = NULL;
1175 }
1176#endif
1177 }
1178 else
1179 {
1180#ifndef VBOXDISP_WITH_WINE_BB_WORKAROUND
1181# error "port me!"
1182#endif
1183 /* work-around wine backbuffer for devices w/o backbuffers */
1184 HRESULT tmpHr = vboxWddmRenderTargetUpdateSurface(pDevice, pAlloc, 0);
1185 Assert(tmpHr == S_OK);
1186 }
1187
1188#ifdef DEBUG
1189 for (UINT i = 0; i < pRc->cAllocations; ++i)
1190 {
1191 pAlloc = &pRc->aAllocations[i];
1192 if (iNewRTFB == i)
1193 {
1194 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));
1195 }
1196
1197 for (UINT j = i+1; j < pRc->cAllocations; ++j)
1198 {
1199 PVBOXWDDMDISP_ALLOCATION pAllocJ = &pRc->aAllocations[j];
1200 Assert(pAlloc->pD3DIf != pAllocJ->pD3DIf);
1201 }
1202 }
1203#endif
1204 return S_OK;
1205}
1206#endif
1207
1208static D3DFORMAT vboxDDI2D3DFormat(D3DDDIFORMAT format)
1209{
1210 /* @todo: check they are all equal */
1211 return (D3DFORMAT)format;
1212}
1213
1214D3DMULTISAMPLE_TYPE vboxDDI2D3DMultiSampleType(D3DDDIMULTISAMPLE_TYPE enmType)
1215{
1216 /* @todo: check they are all equal */
1217 return (D3DMULTISAMPLE_TYPE)enmType;
1218}
1219
1220D3DPOOL vboxDDI2D3DPool(D3DDDI_POOL enmPool)
1221{
1222 /* @todo: check they are all equal */
1223 switch (enmPool)
1224 {
1225 case D3DDDIPOOL_SYSTEMMEM:
1226 return D3DPOOL_SYSTEMMEM;
1227 case D3DDDIPOOL_VIDEOMEMORY:
1228 case D3DDDIPOOL_LOCALVIDMEM:
1229 case D3DDDIPOOL_NONLOCALVIDMEM:
1230 /* @todo: what would be propper here? */
1231 return D3DPOOL_DEFAULT;
1232 default:
1233 Assert(0);
1234 }
1235 return D3DPOOL_DEFAULT;
1236}
1237
1238D3DRENDERSTATETYPE vboxDDI2D3DRenderStateType(D3DDDIRENDERSTATETYPE enmType)
1239{
1240 /* @todo: @fixme: not entirely correct, need to check */
1241 return (D3DRENDERSTATETYPE)enmType;
1242}
1243
1244VBOXWDDMDISP_TSS_LOOKUP vboxDDI2D3DTestureStageStateType(D3DDDITEXTURESTAGESTATETYPE enmType)
1245{
1246 static const VBOXWDDMDISP_TSS_LOOKUP lookup[] =
1247 {
1248 {FALSE, D3DTSS_FORCE_DWORD}, /* 0, D3DDDITSS_TEXTUREMAP */
1249 {FALSE, D3DTSS_COLOROP}, /* 1, D3DDDITSS_COLOROP */
1250 {FALSE, D3DTSS_COLORARG1}, /* 2, D3DDDITSS_COLORARG1 */
1251 {FALSE, D3DTSS_COLORARG2}, /* 3, D3DDDITSS_COLORARG2 */
1252 {FALSE, D3DTSS_ALPHAOP}, /* 4, D3DDDITSS_ALPHAOP */
1253 {FALSE, D3DTSS_ALPHAARG1}, /* 5, D3DDDITSS_ALPHAARG1 */
1254 {FALSE, D3DTSS_ALPHAARG2}, /* 6, D3DDDITSS_ALPHAARG2 */
1255 {FALSE, D3DTSS_BUMPENVMAT00}, /* 7, D3DDDITSS_BUMPENVMAT00 */
1256 {FALSE, D3DTSS_BUMPENVMAT01}, /* 8, D3DDDITSS_BUMPENVMAT01 */
1257 {FALSE, D3DTSS_BUMPENVMAT10}, /* 9, D3DDDITSS_BUMPENVMAT10 */
1258 {FALSE, D3DTSS_BUMPENVMAT11}, /* 10, D3DDDITSS_BUMPENVMAT11 */
1259 {FALSE, D3DTSS_TEXCOORDINDEX}, /* 11, D3DDDITSS_TEXCOORDINDEX */
1260 {FALSE, D3DTSS_FORCE_DWORD}, /* 12, unused */
1261 {TRUE, D3DSAMP_ADDRESSU}, /* 13, D3DDDITSS_ADDRESSU */
1262 {TRUE, D3DSAMP_ADDRESSV}, /* 14, D3DDDITSS_ADDRESSV */
1263 {TRUE, D3DSAMP_BORDERCOLOR}, /* 15, D3DDDITSS_BORDERCOLOR */
1264 {TRUE, D3DSAMP_MAGFILTER}, /* 16, D3DDDITSS_MAGFILTER */
1265 {TRUE, D3DSAMP_MINFILTER}, /* 17, D3DDDITSS_MINFILTER */
1266 {TRUE, D3DSAMP_MIPFILTER}, /* 18, D3DDDITSS_MIPFILTER */
1267 {TRUE, D3DSAMP_MIPMAPLODBIAS}, /* 19, D3DDDITSS_MIPMAPLODBIAS */
1268 {TRUE, D3DSAMP_MAXMIPLEVEL}, /* 20, D3DDDITSS_MAXMIPLEVEL */
1269 {TRUE, D3DSAMP_MAXANISOTROPY}, /* 21, D3DDDITSS_MAXANISOTROPY */
1270 {FALSE, D3DTSS_BUMPENVLSCALE}, /* 22, D3DDDITSS_BUMPENVLSCALE */
1271 {FALSE, D3DTSS_BUMPENVLOFFSET}, /* 23, D3DDDITSS_BUMPENVLOFFSET */
1272 {FALSE, D3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DDDITSS_TEXTURETRANSFORMFLAGS */
1273 {TRUE, D3DSAMP_ADDRESSW}, /* 25, D3DDDITSS_ADDRESSW */
1274 {FALSE, D3DTSS_COLORARG0}, /* 26, D3DDDITSS_COLORARG0 */
1275 {FALSE, D3DTSS_ALPHAARG0}, /* 27, D3DDDITSS_ALPHAARG0 */
1276 {FALSE, D3DTSS_RESULTARG}, /* 28, D3DDDITSS_RESULTARG */
1277 {TRUE, D3DSAMP_SRGBTEXTURE}, /* 29, D3DDDITSS_SRGBTEXTURE */
1278 {TRUE, D3DSAMP_ELEMENTINDEX}, /* 30, D3DDDITSS_ELEMENTINDEX */
1279 {TRUE, D3DSAMP_DMAPOFFSET}, /* 31, D3DDDITSS_DMAPOFFSET */
1280 {FALSE, D3DTSS_CONSTANT}, /* 32, D3DDDITSS_CONSTANT */
1281 {FALSE, D3DTSS_FORCE_DWORD}, /* 33, D3DDDITSS_DISABLETEXTURECOLORKEY */
1282 {FALSE, D3DTSS_FORCE_DWORD}, /* 34, D3DDDITSS_TEXTURECOLORKEYVAL */
1283 };
1284
1285 Assert(enmType > 0);
1286 Assert(enmType < RT_ELEMENTS(lookup));
1287 Assert(lookup[enmType].dType != D3DTSS_FORCE_DWORD);
1288
1289 return lookup[enmType];
1290}
1291
1292DWORD vboxDDI2D3DUsage(D3DDDI_RESOURCEFLAGS fFlags)
1293{
1294 DWORD fUsage = 0;
1295 if (fFlags.Dynamic)
1296 fUsage |= D3DUSAGE_DYNAMIC;
1297 if (fFlags.AutogenMipmap)
1298 fUsage |= D3DUSAGE_AUTOGENMIPMAP;
1299 if (fFlags.DMap)
1300 fUsage |= D3DUSAGE_DMAP;
1301 if (fFlags.WriteOnly)
1302 fUsage |= D3DUSAGE_WRITEONLY;
1303 if (fFlags.NPatches)
1304 fUsage |= D3DUSAGE_NPATCHES;
1305 if (fFlags.Points)
1306 fUsage |= D3DUSAGE_POINTS;
1307 if (fFlags.RenderTarget)
1308 fUsage |= D3DUSAGE_RENDERTARGET;
1309 if (fFlags.RtPatches)
1310 fUsage |= D3DUSAGE_RTPATCHES;
1311 if (fFlags.TextApi)
1312 fUsage |= D3DUSAGE_TEXTAPI;
1313 if (fFlags.WriteOnly)
1314 fUsage |= D3DUSAGE_WRITEONLY;
1315 //below are wddm 1.1-specific
1316// if (fFlags.RestrictedContent)
1317// fUsage |= D3DUSAGE_RESTRICTED_CONTENT;
1318// if (fFlags.RestrictSharedAccess)
1319// fUsage |= D3DUSAGE_RESTRICT_SHARED_RESOURCE;
1320 return fUsage;
1321}
1322
1323DWORD vboxDDI2D3DLockFlags(D3DDDI_LOCKFLAGS fLockFlags)
1324{
1325 DWORD fFlags = 0;
1326 if (fLockFlags.Discard)
1327 fFlags |= D3DLOCK_DISCARD;
1328 if (fLockFlags.NoOverwrite)
1329 fFlags |= D3DLOCK_NOOVERWRITE;
1330 if (fLockFlags.ReadOnly)
1331 fFlags |= D3DLOCK_READONLY;
1332 if (fLockFlags.DoNotWait)
1333 fFlags |= D3DLOCK_DONOTWAIT;
1334 return fFlags;
1335}
1336
1337D3DTEXTUREFILTERTYPE vboxDDI2D3DBltFlags(D3DDDI_BLTFLAGS fFlags)
1338{
1339 if (fFlags.Point)
1340 {
1341 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
1342 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 1);
1343 return D3DTEXF_POINT;
1344 }
1345 if (fFlags.Linear)
1346 {
1347 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
1348 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 2);
1349 return D3DTEXF_LINEAR;
1350 }
1351 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
1352 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 0);
1353 return D3DTEXF_NONE;
1354}
1355
1356/* on success increments the surface ref counter,
1357 * i.e. one must call pSurf->Release() once the surface is not needed*/
1358static HRESULT vboxWddmSurfGet(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc, IDirect3DSurface9 **ppSurf)
1359{
1360 HRESULT hr = S_OK;
1361 Assert(pRc->cAllocations > iAlloc);
1362 switch (pRc->aAllocations[0].enmD3DIfType)
1363 {
1364 case VBOXDISP_D3DIFTYPE_SURFACE:
1365 {
1366 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
1367 Assert(pD3DIfSurf);
1368 pD3DIfSurf->AddRef();
1369 *ppSurf = pD3DIfSurf;
1370 break;
1371 }
1372 case VBOXDISP_D3DIFTYPE_TEXTURE:
1373 {
1374 Assert(pRc->cAllocations == 1); /* <- vboxWddmSurfGet is typically used in Blt & ColorFill functions
1375 * in this case, if texture is used as a destination,
1376 * we should update sub-layers as well which is not done currently
1377 * so for now check vboxWddmSurfGet is used for one-level textures */
1378 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
1379 IDirect3DSurface9 *pSurfaceLevel;
1380 Assert(pD3DIfTex);
1381 hr = pD3DIfTex->GetSurfaceLevel(iAlloc, &pSurfaceLevel);
1382 Assert(hr == S_OK);
1383 if (hr == S_OK)
1384 {
1385 *ppSurf = pSurfaceLevel;
1386 }
1387 break;
1388 }
1389 default:
1390 Assert(0);
1391 hr = E_FAIL;
1392 break;
1393 }
1394 return hr;
1395}
1396
1397/******/
1398static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch);
1399
1400DECLINLINE(VOID) vboxWddmSwapchainInit(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1401{
1402 RTLISTNODE ListEntry = pSwapchain->ListEntry;
1403 memset(pSwapchain, 0, sizeof (VBOXWDDMDISP_SWAPCHAIN));
1404 pSwapchain->ListEntry = ListEntry;
1405 pSwapchain->iBB = VBOXWDDMDISP_INDEX_UNDEFINED;
1406}
1407
1408static HRESULT vboxWddmSwapchainKmSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1409{
1410 struct
1411 {
1412 VBOXDISPIFESCAPE_SWAPCHAININFO SwapchainInfo;
1413 D3DKMT_HANDLE ahAllocs[VBOXWDDMDISP_MAX_SWAPCHAIN_SIZE];
1414 } Buf;
1415
1416 memset(&Buf.SwapchainInfo, 0, sizeof (Buf.SwapchainInfo));
1417 Buf.SwapchainInfo.EscapeHdr.escapeCode = VBOXESC_SWAPCHAININFO;
1418 Buf.SwapchainInfo.SwapchainInfo.hSwapchainKm = pSwapchain->hSwapchainKm;
1419 Buf.SwapchainInfo.SwapchainInfo.hSwapchainUm = (VBOXDISP_UMHANDLE)pSwapchain;
1420// Buf.SwapchainInfo.SwapchainInfo.Rect;
1421// Buf.SwapchainInfo.SwapchainInfo.u32Reserved;
1422 Buf.SwapchainInfo.SwapchainInfo.cAllocs = pSwapchain->cRTs;
1423 UINT cAllocsKm = 0;
1424 for (UINT i = 0; i < Buf.SwapchainInfo.SwapchainInfo.cAllocs; ++i)
1425 {
1426// Assert(pSwapchain->aRTs[i].pAlloc->hAllocation);
1427 Buf.SwapchainInfo.SwapchainInfo.ahAllocs[i] = pSwapchain->aRTs[i].pAlloc->hAllocation;
1428 if (Buf.SwapchainInfo.SwapchainInfo.ahAllocs[i])
1429 ++cAllocsKm;
1430 }
1431
1432 Assert(cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs || !cAllocsKm);
1433
1434 if (cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs)
1435 {
1436 D3DDDICB_ESCAPE DdiEscape = {0};
1437 DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext;
1438 DdiEscape.hDevice = pDevice->hDevice;
1439 // DdiEscape.Flags.Value = 0;
1440 DdiEscape.pPrivateDriverData = &Buf.SwapchainInfo;
1441 DdiEscape.PrivateDriverDataSize = RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[Buf.SwapchainInfo.SwapchainInfo.cAllocs]);
1442 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
1443 Assert(hr == S_OK);
1444 if (hr == S_OK)
1445 {
1446 pSwapchain->hSwapchainKm = Buf.SwapchainInfo.SwapchainInfo.hSwapchainKm;
1447 }
1448
1449 return hr;
1450 }
1451 return S_OK;
1452}
1453
1454static HRESULT vboxWddmSwapchainKmDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1455{
1456 HRESULT hr = S_OK;
1457 if (pSwapchain->hSwapchainKm)
1458 {
1459 /* submit empty swapchain to destroy the KM one */
1460 UINT cOldRTc = pSwapchain->cRTs;
1461 pSwapchain->cRTs = 0;
1462 hr = vboxWddmSwapchainKmSynch(pDevice, pSwapchain);
1463 Assert(hr == S_OK);
1464 Assert(!pSwapchain->hSwapchainKm);
1465 pSwapchain->cRTs = cOldRTc;
1466 }
1467 return hr;
1468}
1469static HRESULT vboxWddmSwapchainDestroyIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1470{
1471 if (pSwapchain->pSwapChainIf)
1472 {
1473#ifndef VBOXWDDM_WITH_VISIBLE_FB
1474 pSwapchain->pRenderTargetFbCopy->Release();
1475 pSwapchain->pRenderTargetFbCopy = NULL;
1476#endif
1477 pSwapchain->pSwapChainIf->Release();
1478 Assert(pSwapchain->hWnd);
1479 HRESULT hr = VBoxDispWndDestroy(pDevice->pAdapter, pSwapchain->hWnd);
1480 Assert(hr == S_OK);
1481 pSwapchain->pSwapChainIf = NULL;
1482 pSwapchain->hWnd = NULL;
1483 return hr;
1484 }
1485
1486 Assert(!pSwapchain->hWnd);
1487 return S_OK;
1488}
1489
1490DECLINLINE(VOID) vboxWddmSwapchainClear(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1491{
1492 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
1493 {
1494 pSwapchain->aRTs[i].pAlloc->pSwapchain = NULL;
1495 }
1496 vboxWddmSwapchainDestroyIf(pDevice, pSwapchain);
1497 vboxWddmSwapchainKmDestroy(pDevice, pSwapchain);
1498 vboxWddmSwapchainInit(pSwapchain);
1499}
1500
1501static VOID vboxWddmSwapchainDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1502{
1503 vboxWddmSwapchainClear(pDevice, pSwapchain);
1504 RTListNodeRemove(&pSwapchain->ListEntry);
1505 RTMemFree(pSwapchain);
1506}
1507
1508static VOID vboxWddmSwapchainDestroyAll(PVBOXWDDMDISP_DEVICE pDevice)
1509{
1510 PVBOXWDDMDISP_SWAPCHAIN pCur = RTListNodeGetFirst(&pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
1511 while (pCur)
1512 {
1513 PVBOXWDDMDISP_SWAPCHAIN pNext = NULL;
1514 if (!RTListNodeIsLast(&pDevice->SwapchainList, &pCur->ListEntry))
1515 {
1516 pNext = RTListNodeGetNext(&pCur->ListEntry, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
1517 }
1518
1519 vboxWddmSwapchainDestroy(pDevice, pCur);
1520
1521 pCur = pNext;
1522 }
1523}
1524
1525static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainAlloc(PVBOXWDDMDISP_DEVICE pDevice)
1526{
1527 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)RTMemAllocZ(sizeof (VBOXWDDMDISP_SWAPCHAIN));
1528 Assert(pSwapchain);
1529 if (pSwapchain)
1530 {
1531 RTListAppend(&pDevice->SwapchainList, &pSwapchain->ListEntry);
1532 vboxWddmSwapchainInit(pSwapchain);
1533 return pSwapchain;
1534 }
1535 return NULL;
1536}
1537
1538DECLINLINE(VOID) vboxWddmSwapchainRtInit(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRt, PVBOXWDDMDISP_ALLOCATION pAlloc)
1539{
1540 pSwapchain->fFlags.bChanged = 1;
1541 pRt->pAlloc = pAlloc;
1542 pRt->cNumFlips = 0;
1543 pRt->fFlags.Value = 0;
1544 pRt->fFlags.bAdded = 1;
1545}
1546
1547DECLINLINE(VOID) vboxWddmSwapchainBbAddTail(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bAssignAsBb)
1548{
1549 pAlloc->pSwapchain = pSwapchain;
1550 VBOXWDDMDISP_SWAPCHAIN_FLAGS fOldFlags = pSwapchain->fFlags;
1551 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[pSwapchain->cRTs];
1552 ++pSwapchain->cRTs;
1553 vboxWddmSwapchainRtInit(pSwapchain, pRt, pAlloc);
1554 if (pSwapchain->cRTs == 1)
1555 {
1556 Assert(pSwapchain->iBB == VBOXWDDMDISP_INDEX_UNDEFINED);
1557 pSwapchain->iBB = 0;
1558 }
1559 else if (bAssignAsBb)
1560 {
1561 pSwapchain->iBB = pSwapchain->cRTs - 1;
1562 }
1563 else if (pSwapchain->cRTs == 2) /* the first one is a frontbuffer */
1564 {
1565 pSwapchain->iBB = 1;
1566 }
1567}
1568
1569DECLINLINE(UINT) vboxWddmSwapchainIdxFb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1570{
1571 return (pSwapchain->iBB + pSwapchain->cRTs - 1) % pSwapchain->cRTs;
1572}
1573
1574/* if swapchain contains only one surface returns this surface */
1575DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainGetBb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1576{
1577 if (pSwapchain->cRTs)
1578 {
1579 Assert(pSwapchain->iBB < pSwapchain->cRTs);
1580 return &pSwapchain->aRTs[pSwapchain->iBB];
1581 }
1582 return NULL;
1583}
1584
1585DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainGetFb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1586{
1587 if (pSwapchain->cRTs)
1588 {
1589 UINT iFb = vboxWddmSwapchainIdxFb(pSwapchain);
1590 return &pSwapchain->aRTs[iFb];
1591 }
1592 return NULL;
1593}
1594
1595DECLINLINE(VOID) vboxWddmSwapchainFlip(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1596{
1597 pSwapchain->iBB = (pSwapchain->iBB + 1) % pSwapchain->cRTs;
1598}
1599
1600DECLINLINE(UINT) vboxWddmSwapchainNumRTs(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1601{
1602 return pSwapchain->cRTs;
1603}
1604
1605
1606DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainRtForAlloc(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc)
1607{
1608 if (pAlloc->pSwapchain != pSwapchain)
1609 return NULL;
1610
1611 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
1612 {
1613 Assert(pSwapchain->aRTs[i].pAlloc->pSwapchain = pSwapchain);
1614 if (pSwapchain->aRTs[i].pAlloc == pAlloc)
1615 return &pSwapchain->aRTs[i];
1616 }
1617
1618 /* should never happen */
1619 Assert(0);
1620 return NULL;
1621}
1622
1623DECLINLINE(UINT) vboxWddmSwapchainRtIndex(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
1624{
1625 UINT offFirst = RT_OFFSETOF(VBOXWDDMDISP_SWAPCHAIN, aRTs);
1626 UINT offRT = UINT((uintptr_t)pRT - (uintptr_t)pSwapchain);
1627 Assert(offRT < sizeof (VBOXWDDMDISP_SWAPCHAIN));
1628 Assert(offRT >= offFirst);
1629 Assert(!((offRT - offFirst) % sizeof (VBOXWDDMDISP_RENDERTGT)));
1630 UINT iRt = (offRT - offFirst) / sizeof (VBOXWDDMDISP_RENDERTGT);
1631 Assert(iRt < pSwapchain->cRTs);
1632 return iRt;
1633}
1634
1635DECLINLINE(PVBOXWDDMDISP_SWAPCHAIN) vboxWddmSwapchainForAlloc(PVBOXWDDMDISP_ALLOCATION pAlloc)
1636{
1637 return pAlloc->pSwapchain;
1638}
1639
1640DECLINLINE(VOID) vboxWddmSwapchainRtRemove(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
1641{
1642 UINT iRt = vboxWddmSwapchainRtIndex(pSwapchain, pRT);
1643 Assert(iRt < pSwapchain->cRTs);
1644 pRT->pAlloc->pSwapchain = NULL;
1645 for (UINT i = iRt; i < pSwapchain->cRTs - 1; ++i)
1646 {
1647 pSwapchain->aRTs[i] = pSwapchain->aRTs[i + 1];
1648 }
1649
1650 --pSwapchain->cRTs;
1651 if (pSwapchain->cRTs)
1652 {
1653 if (pSwapchain->iBB > iRt)
1654 {
1655 --pSwapchain->iBB;
1656 }
1657 else if (pSwapchain->iBB == iRt)
1658 {
1659 Assert(0);
1660 pSwapchain->iBB = 0;
1661 }
1662 }
1663 else
1664 {
1665 pSwapchain->iBB = VBOXWDDMDISP_INDEX_UNDEFINED;
1666 }
1667 pSwapchain->fFlags.bChanged = TRUE;
1668}
1669
1670#if 0
1671
1672
1673DECLINLINE(VOID) vboxWddmSwapchainSetBb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
1674{
1675 UINT iRt = vboxWddmSwapchainRtIndex(pSwapchain, pRT);
1676 Assert(iRt < pSwapchain->cRTs);
1677 pSwapchain->iBB = iRt;
1678}
1679
1680/* the paRemoved buffer should at least contain VBOXWDDMDISP_MAX_SWAPCHAIN_SIZE elements,
1681 * the function does not validate its size in any way */
1682static BOOL vboxWddmSwapchainAdjust(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pBbAlloc, PUINT pcRemoved, PVBOXWDDMDISP_ALLOCATION paRemoved)
1683{
1684 UINT cRemoved = 0;
1685 BOOL bChanged = FALSE;
1686 PVBOXWDDMDISP_RENDERTGT pCurBbRt = vboxWddmSwapchainGetBb(pSwapchain);
1687 if (pCurBb)
1688 {
1689 if (pCurBbRt->pAlloc != pBbAlloc)
1690 {
1691 bChanged = TRUE;
1692
1693 /* determine whether we need to add the current BB
1694 * or remove part or all of the current RTs in the swapchain */
1695 PVBOXWDDMDISP_RENDERTGT pCorrectRt = vboxWddmSwapchainSearchRt(pSwapchain, pBbAlloc);
1696 if (pCorrectRt)
1697 {
1698 paRemoved[cRemoved] = pCurBbRt->pAlloc;
1699 ++cRemoved;
1700 vboxWddmSwapchainRemoveRt(pSwapchain, pCurBbRt);
1701 vboxWddmSwapchainSetBb(pSwapchain, pBbAlloc);
1702 }
1703 else
1704 {
1705 /* check if the pCurBbRt stored in the swapchain match those of the pBbAlloc */
1706 if (pBbAlloc->SurfDesc.width == pCurBbRt->pAlloc->SurfDesc.width
1707 && pBbAlloc->SurfDesc.height == pCurBbRt->pAlloc->SurfDesc.height
1708 && pBbAlloc->SurfDesc.format == pCurBbRt->pAlloc->SurfDesc.format)
1709 {
1710 for (UINT i = 0; i < pSwapchain->cRTs;)
1711 {
1712 if (pSwapchain->aRTs[i].cNumFlips > 1)
1713 {
1714 paRemoved[cRemoved] = pSwapchain->aRTs[i].pAlloc;
1715 ++cRemoved;
1716 vboxWddmSwapchainRemoveRt(pSwapchain, &pSwapchain->aRTs[i]);
1717 }
1718 else
1719 {
1720 ++i;
1721 }
1722 }
1723 }
1724 else
1725 {
1726 /* remove all */
1727 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
1728 {
1729 paRemoved[cRemoved] = pSwapchain->aRTs[i].pAlloc;
1730 ++cRemoved;
1731 }
1732
1733 vboxWddmSwapchainClear(pSwapchain);
1734 }
1735
1736 vboxWddmSwapchainAllocAddTail(pSwapchain, pBbAlloc);
1737 vboxWddmSwapchainSetBb(pSwapchain, pBbAlloc);
1738 }
1739 }
1740 }
1741 else
1742 {
1743 vboxWddmSwapchainAllocAddTail(pSwapchain, pBbAlloc);
1744 bChanged = TRUE;
1745 }
1746
1747 if (!bChanged)
1748 {
1749 Assert(cRemoved == 0);
1750 }
1751
1752 *pcRemoved = cRemoved;
1753
1754 return bChanged;
1755}
1756#endif
1757static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainFindCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc)
1758{
1759 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = pBbAlloc->pSwapchain;
1760 if (pSwapchain)
1761 {
1762 /* check if this is what we expect */
1763 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pSwapchain);
1764 if (pRt->pAlloc != pBbAlloc)
1765 {
1766 /* bad, @todo: correct the swapchain by either removing the Rt and adding it to another swapchain
1767 * or by removing the pBbAlloc out of it */
1768 Assert(0);
1769 }
1770 }
1771 if (!pSwapchain)
1772 {
1773#ifdef DEBUG_misha
1774 Assert(0);
1775#endif
1776 /* first search for the swapchain the alloc might be added to */
1777 PVBOXWDDMDISP_SWAPCHAIN pCur = RTListNodeGetFirst(&pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
1778 while (pCur)
1779 {
1780 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pCur);
1781 Assert(pRt);
1782 if (pRt->cNumFlips < 2
1783 && vboxWddmSwapchainRtIndex(pCur, pRt) == 0) /* <- in case we add a rt to the swapchain on present this would mean
1784 * that the last RT in the swapchain array is now a frontbuffer and
1785 * thus the aRTs[0] is a backbuffer */
1786 {
1787 PVBOXWDDMDISP_RESOURCE pBbRc = pBbAlloc->pRc;
1788 PVBOXWDDMDISP_RESOURCE pRtRc = pRt->pAlloc->pRc;
1789 if (pBbAlloc->SurfDesc.width == pRt->pAlloc->SurfDesc.width
1790 && pBbAlloc->SurfDesc.height == pRt->pAlloc->SurfDesc.height
1791 && pBbAlloc->SurfDesc.format == pRt->pAlloc->SurfDesc.format
1792 && pBbAlloc->SurfDesc.VidPnSourceId == pRt->pAlloc->SurfDesc.VidPnSourceId
1793 && (pBbRc == pRtRc
1794 || (pBbRc->fFlags == pRtRc->fFlags
1795 && pBbRc->RcDesc.enmPool == pRtRc->RcDesc.enmPool
1796// && pBbRc->RcDesc.fFlags.Value == pRtRc->RcDesc.fFlags.Value
1797 )
1798 ))
1799 {
1800 vboxWddmSwapchainBbAddTail(pCur, pBbAlloc, TRUE);
1801 pSwapchain = pCur;
1802 break;
1803 }
1804 }
1805 if (RTListNodeIsLast(&pDevice->SwapchainList, &pCur->ListEntry))
1806 break;
1807 pCur = RTListNodeGetNext(&pCur->ListEntry, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
1808 }
1809
1810// if (!pSwapchain) need to create a new one (see below)
1811 }
1812
1813 if (!pSwapchain)
1814 {
1815 pSwapchain = vboxWddmSwapchainAlloc(pDevice);
1816 Assert(pSwapchain);
1817 if (pSwapchain)
1818 {
1819 vboxWddmSwapchainBbAddTail(pSwapchain, pBbAlloc, FALSE);
1820 }
1821 }
1822
1823 return pSwapchain;
1824}
1825
1826static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainCreateForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc)
1827{
1828 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainAlloc(pDevice);
1829 Assert(pSwapchain);
1830 if (pSwapchain)
1831 {
1832 for (UINT i = 0; i < pRc->cAllocations; ++i)
1833 {
1834 vboxWddmSwapchainBbAddTail(pSwapchain, &pRc->aAllocations[i], FALSE);
1835 }
1836 return pSwapchain;
1837 }
1838 return NULL;
1839}
1840
1841DECLINLINE(UINT) vboxWddmSwapchainIdxBb2Rt(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb)
1842{
1843 return iBb != (~0) ? (iBb + pSwapchain->iBB) % pSwapchain->cRTs : vboxWddmSwapchainIdxFb(pSwapchain);
1844}
1845
1846static HRESULT vboxWddmSwapchainRtSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb)
1847{
1848 IDirect3DSurface9 *pD3D9Surf;
1849#ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
1850 if (pSwapchain->cRTs == 1)
1851 {
1852 iBb = 0;
1853 }
1854#endif
1855 UINT iRt = vboxWddmSwapchainIdxBb2Rt(pSwapchain, iBb);
1856 Assert(iRt < pSwapchain->cRTs);
1857 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[iRt];
1858 HRESULT hr = pSwapchain->pSwapChainIf->GetBackBuffer(iBb, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
1859 Assert(hr == S_OK);
1860 if (hr == S_OK)
1861 {
1862 PVBOXWDDMDISP_ALLOCATION pAlloc = pRt->pAlloc;
1863 Assert(pD3D9Surf);
1864 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
1865 if (pAlloc->pD3DIf)
1866 {
1867 if (pSwapchain->fFlags.bChanged)
1868 {
1869 IDirect3DSurface9 *pD3D9OldSurf = (IDirect3DSurface9*)pAlloc->pD3DIf;
1870 if (pD3D9OldSurf && pD3D9OldSurf != pD3D9Surf)
1871 {
1872 VOID *pvSwapchain = NULL;
1873 HRESULT tmpHr = pD3D9OldSurf->GetContainer(IID_IDirect3DSwapChain9, &pvSwapchain);
1874 if (tmpHr == S_OK)
1875 {
1876 Assert(pvSwapchain);
1877 ((IDirect3DSwapChain9 *)pvSwapchain)->Release();
1878 }
1879 else
1880 {
1881 Assert(!pvSwapchain);
1882 }
1883 if (pvSwapchain != pSwapchain->pSwapChainIf)
1884 {
1885 Assert(0);
1886 if (iBb == (~0))
1887 {
1888 pD3D9Surf->Release();
1889 hr = pSwapchain->pSwapChainIf->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
1890 Assert(hr == S_OK);
1891 }
1892 hr = pDevice->pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9Surf, NULL, D3DTEXF_NONE);
1893 Assert(hr == S_OK);
1894 if (iBb == (~0))
1895 {
1896 pD3D9Surf->Release();
1897 hr = pSwapchain->pSwapChainIf->Present(NULL, NULL, NULL, NULL, 0);
1898 Assert(hr == S_OK);
1899 hr = pSwapchain->pSwapChainIf->GetBackBuffer(~0, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
1900 Assert(hr == S_OK);
1901 }
1902 }
1903 }
1904 }
1905 pAlloc->pD3DIf->Release();
1906 }
1907 pAlloc->pD3DIf = pD3D9Surf;
1908 pRt->fFlags.Value = 0;
1909
1910 if (pSwapchain->fFlags.bChanged)
1911 {
1912 for (UINT i = 0; i < pDevice->cRTs; ++i)
1913 {
1914 if (pDevice->apRTs[i] == pAlloc)
1915 {
1916 hr = vboxWddmRenderTargetSet(pDevice, i, pAlloc, TRUE);
1917 Assert(hr == S_OK);
1918 }
1919 }
1920 }
1921 }
1922 return hr;
1923}
1924
1925static HRESULT vboxWddmSwapchainSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1926{
1927 HRESULT hr = S_OK;
1928 for (int iBb = -1; iBb < int(pSwapchain->cRTs - 1); ++iBb)
1929 {
1930 hr = vboxWddmSwapchainRtSynch(pDevice, pSwapchain, (UINT)iBb);
1931 Assert(hr == S_OK);
1932 }
1933 if (pSwapchain->fFlags.bChanged)
1934 {
1935 hr = vboxWddmSwapchainKmSynch(pDevice, pSwapchain);
1936 if (hr == S_OK)
1937 {
1938 pSwapchain->fFlags.bChanged = 0;
1939 }
1940 }
1941 return hr;
1942}
1943
1944static VOID vboxWddmSwapchainFillParams(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, D3DPRESENT_PARAMETERS *pParams)
1945{
1946 Assert(pSwapchain->cRTs);
1947 Assert(pSwapchain->cRTs <= 2);
1948 memset(pParams, 0, sizeof (D3DPRESENT_PARAMETERS));
1949 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pSwapchain);
1950 PVBOXWDDMDISP_RESOURCE pRc = pRt->pAlloc->pRc;
1951 pParams->BackBufferWidth = pRt->pAlloc->SurfDesc.width;
1952 pParams->BackBufferHeight = pRt->pAlloc->SurfDesc.height;
1953 pParams->BackBufferFormat = vboxDDI2D3DFormat(pRt->pAlloc->SurfDesc.format);
1954 pParams->BackBufferCount = pSwapchain->cRTs - 1;
1955 pParams->MultiSampleType = vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType);
1956 pParams->MultiSampleQuality = pRc->RcDesc.MultisampleQuality;
1957#ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
1958 if (pSwapchain->cRTs == 1)
1959 pParams->SwapEffect = D3DSWAPEFFECT_COPY;
1960 else
1961#endif
1962 if (pRc->RcDesc.fFlags.DiscardRenderTarget)
1963 pParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
1964}
1965
1966static HRESULT vboxWddmSwapchainChkCreateIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1967{
1968 if (!pSwapchain->fFlags.bChanged && pSwapchain->pSwapChainIf)
1969 return S_OK;
1970 /* preserve the old one */
1971 IDirect3DSwapChain9 * pOldIf = pSwapchain->pSwapChainIf;
1972 HRESULT hr = S_OK;
1973 BOOL bReuseSwapchain = FALSE;
1974 D3DPRESENT_PARAMETERS Params;
1975 D3DPRESENT_PARAMETERS OldParams;
1976 vboxWddmSwapchainFillParams(pSwapchain, &Params);
1977 /* check if we need to re-create the swapchain */
1978 if (pOldIf)
1979 {
1980 hr = pOldIf->GetPresentParameters(&OldParams);
1981 Assert(hr == S_OK);
1982 if (hr == S_OK)
1983 {
1984 if (OldParams.BackBufferCount == Params.BackBufferCount
1985 && OldParams.SwapEffect == Params.SwapEffect)
1986 {
1987 bReuseSwapchain = TRUE;
1988 }
1989 }
1990 }
1991
1992 /* first create the new one */
1993 IDirect3DSwapChain9 * pNewIf;
1994 ///
1995 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
1996 UINT cSurfs = pSwapchain->cRTs;
1997 IDirect3DDevice9 *pDevice9If = NULL;
1998 HWND hOldWnd = pSwapchain->hWnd;
1999 if (!bReuseSwapchain)
2000 {
2001//#define VBOXDISP_NEWWND_ON_SWAPCHAINUPDATE
2002#ifndef VBOXDISP_NEWWND_ON_SWAPCHAINUPDATE
2003 if (!hOldWnd)
2004#endif
2005 {
2006 hr = VBoxDispWndCreate(pAdapter, Params.BackBufferWidth, Params.BackBufferHeight, &pSwapchain->hWnd);
2007 Assert(hr == S_OK);
2008 }
2009 if (hr == S_OK)
2010 {
2011 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
2012 if (pDevice->fFlags.AllowMultithreading)
2013 fFlags |= D3DCREATE_MULTITHREADED;
2014
2015 Params.hDeviceWindow = pSwapchain->hWnd;
2016 /* @todo: it seems there should be a way to detect this correctly since
2017 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
2018 Params.Windowed = TRUE;
2019 // params.EnableAutoDepthStencil = FALSE;
2020 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
2021 // params.Flags;
2022 // params.FullScreen_RefreshRateInHz;
2023 // params.FullScreen_PresentationInterval;
2024 if (!pDevice->pDevice9If)
2025 {
2026 hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pSwapchain->hWnd, fFlags, &Params, &pDevice9If);
2027 Assert(hr == S_OK);
2028 if (hr == S_OK)
2029 {
2030 pDevice->pDevice9If = pDevice9If;
2031 hr = pDevice9If->GetSwapChain(0, &pNewIf);
2032 Assert(hr == S_OK);
2033 if (hr == S_OK)
2034 {
2035 Assert(pNewIf);
2036 }
2037 else
2038 {
2039 pDevice9If->Release();
2040 }
2041 }
2042 }
2043 else
2044 {
2045 pDevice9If = pDevice->pDevice9If;
2046 if (pOldIf)
2047 {
2048 Assert(0);
2049 /* copy current rt data to offscreen render targets */
2050 IDirect3DSurface9* pD3D9OldFb = NULL;
2051 HRESULT tmpHr = pOldIf->GetBackBuffer(~0, D3DBACKBUFFER_TYPE_MONO, &pD3D9OldFb);
2052 Assert(tmpHr == S_OK);
2053 if (tmpHr == S_OK)
2054 {
2055 /* just need a pointer to match */
2056 pD3D9OldFb->Release();
2057 }
2058 UINT cOldRts = OldParams.SwapEffect == D3DSWAPEFFECT_COPY ? 1 : OldParams.BackBufferCount + 1;
2059 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
2060 {
2061 PVBOXWDDMDISP_RENDERTGT pRT = &pSwapchain->aRTs[i];
2062 if (!pRT->pAlloc->pD3DIf)
2063 continue;
2064 IDirect3DSurface9* pD3D9OldSurf = (IDirect3DSurface9*)pRT->pAlloc->pD3DIf;
2065 VOID *pvSwapchain = NULL;
2066 tmpHr = pD3D9OldSurf->GetContainer(IID_IDirect3DSwapChain9, &pvSwapchain);
2067 if (tmpHr == S_OK)
2068 {
2069 Assert(pvSwapchain);
2070 ((IDirect3DSwapChain9 *)pvSwapchain)->Release();
2071 }
2072 else
2073 {
2074 Assert(!pvSwapchain);
2075 }
2076 if (pvSwapchain != pOldIf)
2077 continue;
2078
2079 IDirect3DSurface9* pD3D9NewSurf;
2080 tmpHr = pDevice9If->CreateRenderTarget(
2081 Params.BackBufferWidth, Params.BackBufferHeight,
2082 Params.BackBufferFormat,
2083 Params.MultiSampleType,
2084 Params.MultiSampleQuality,
2085 TRUE, /*bLockable*/
2086 &pD3D9NewSurf,
2087 NULL /* HANDLE* pSharedHandle */
2088 );
2089 Assert(tmpHr == S_OK);
2090 if (tmpHr != S_OK)
2091 continue;
2092
2093 if (pD3D9OldSurf != pD3D9OldFb && cOldRts != 1)
2094 {
2095 tmpHr = pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9NewSurf, NULL, D3DTEXF_NONE);
2096 Assert(tmpHr == S_OK);
2097 }
2098 else
2099 {
2100 tmpHr = pOldIf->GetFrontBufferData(pD3D9NewSurf);
2101 Assert(tmpHr == S_OK);
2102 }
2103
2104 if (tmpHr != S_OK)
2105 continue;
2106
2107 pRT->pAlloc->pD3DIf = pD3D9NewSurf;
2108 pD3D9OldSurf->Release();
2109 }
2110 }
2111
2112 hr = pDevice->pDevice9If->CreateAdditionalSwapChain(&Params, &pNewIf);
2113 Assert(hr == S_OK);
2114 if (hr == S_OK)
2115 {
2116 Assert(pNewIf);
2117 }
2118 }
2119 }
2120 }
2121 else
2122 {
2123 Assert(pOldIf);
2124 Assert(hOldWnd);
2125 pNewIf = pOldIf;
2126 /* to ensure the swapchain is not deleted once we release the pOldIf */
2127 pNewIf->AddRef();
2128 }
2129
2130 if (hr == S_OK)
2131 {
2132 Assert(pNewIf);
2133 pSwapchain->pSwapChainIf = pNewIf;
2134#ifndef VBOXWDDM_WITH_VISIBLE_FB
2135 if (!pSwapchain->pRenderTargetFbCopy)
2136 {
2137 IDirect3DSurface9* pD3D9Surf;
2138 hr = pDevice9If->CreateRenderTarget(
2139 Params.BackBufferWidth, Params.BackBufferHeight,
2140 Params.BackBufferFormat,
2141 Params.MultiSampleType,
2142 Params.MultiSampleQuality,
2143 TRUE, /*bLockable*/
2144 &pD3D9Surf,
2145 NULL /* HANDLE* pSharedHandle */
2146 );
2147 Assert(hr == S_OK);
2148 if (hr == S_OK)
2149 {
2150 Assert(pD3D9Surf);
2151 pSwapchain->pRenderTargetFbCopy = pD3D9Surf;
2152 }
2153 }
2154#endif
2155
2156 if (hr == S_OK)
2157 {
2158 for (UINT i = 0; i < cSurfs; ++i)
2159 {
2160 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[i];
2161 pRt->pAlloc->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2162 }
2163
2164 hr = vboxWddmSwapchainSynch(pDevice, pSwapchain);
2165 Assert(hr == S_OK);
2166 if (hr == S_OK)
2167 {
2168 for (UINT i = 0; i < cSurfs; ++i)
2169 {
2170 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[i];
2171 hr = vboxWddmSurfSynchMem(pRt->pAlloc->pRc, pRt->pAlloc);
2172 Assert(hr == S_OK);
2173 if (hr != S_OK)
2174 {
2175 break;
2176 }
2177 }
2178
2179 Assert(hr == S_OK);
2180 if (hr == S_OK)
2181 {
2182 Assert(pSwapchain->fFlags.Value == 0);
2183 if (pOldIf)
2184 {
2185 Assert(hOldWnd);
2186 pOldIf->Release();
2187 if (hOldWnd != pSwapchain->hWnd)
2188 {
2189 VBoxDispWndDestroy(pAdapter, hOldWnd);
2190 }
2191 }
2192 else
2193 {
2194 Assert(!hOldWnd);
2195 }
2196 return S_OK;
2197 }
2198 }
2199 pNewIf->Release();
2200 pSwapchain->pSwapChainIf = pOldIf;
2201 }
2202
2203 Assert(hr != S_OK);
2204 if (hOldWnd != pSwapchain->hWnd)
2205 {
2206 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pSwapchain->hWnd);
2207 Assert(tmpHr == S_OK);
2208 pSwapchain->hWnd = hOldWnd;
2209 }
2210 }
2211
2212 return hr;
2213}
2214
2215static HRESULT vboxWddmSwapchainCreateIfForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, PVBOXWDDMDISP_SWAPCHAIN *ppSwapchain)
2216{
2217 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainCreateForRc(pDevice, pRc);
2218 Assert(pSwapchain);
2219 *ppSwapchain = NULL;
2220 if (pSwapchain)
2221 {
2222 HRESULT hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
2223 Assert(hr == S_OK);
2224 if (hr == S_OK)
2225 {
2226 *ppSwapchain = pSwapchain;
2227 }
2228 return hr;
2229 }
2230 return E_OUTOFMEMORY;
2231}
2232
2233static HRESULT vboxWddmSwapchainPresentPerform(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
2234{
2235 HRESULT hr = pSwapchain->pSwapChainIf->Present(NULL, NULL, NULL, NULL, 0);
2236 Assert(hr == S_OK);
2237 if (hr == S_OK)
2238 {
2239 vboxWddmSwapchainFlip(pSwapchain);
2240 Assert(pSwapchain->fFlags.Value == 0);
2241 hr = vboxWddmSwapchainSynch(pDevice, pSwapchain);
2242 Assert(hr == S_OK);
2243 }
2244 return hr;
2245}
2246
2247static HRESULT vboxWddmSwapchainPresent(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc)
2248{
2249 BOOL bChanged = FALSE;
2250 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainFindCreate(pDevice, pBbAlloc);
2251 Assert(pSwapchain);
2252 if (pSwapchain)
2253 {
2254 HRESULT hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
2255 Assert(hr == S_OK);
2256 if (hr == S_OK)
2257 {
2258 hr = vboxWddmSwapchainPresentPerform(pDevice, pSwapchain);
2259 Assert(hr == S_OK);
2260 }
2261 return hr;
2262 }
2263 return E_OUTOFMEMORY;
2264}
2265
2266#if 0 //def DEBUG
2267static void vboxWddmDbgRenderTargetUpdateCheckSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf)
2268{
2269 IDirect3DSurface9 *pD3D9Surf;
2270 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
2271 IDirect3DDevice9 * pDevice9If = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
2272 HRESULT hr = pDevice9If->GetBackBuffer(0 /*UINT iSwapChain*/,
2273 iBBuf, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
2274 Assert(hr == S_OK);
2275 if (hr == S_OK)
2276 {
2277 Assert(pD3D9Surf);
2278 Assert(pD3D9Surf == pAlloc->pD3DIf);
2279 pD3D9Surf->Release();
2280 }
2281}
2282
2283static void vboxWddmDbgRenderTargetCheck(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB)
2284{
2285 PVBOXWDDMDISP_ALLOCATION pAlloc;
2286 UINT iBBuf = 0;
2287 Assert(iNewRTFB < pRc->cAllocations);
2288
2289 for (UINT i = 1; i < pRc->cAllocations; ++i, ++iBBuf)
2290 {
2291 UINT iAlloc = (iNewRTFB + i) % pRc->cAllocations;
2292 Assert(iAlloc != iNewRTFB);
2293 pAlloc = &pRc->aAllocations[iAlloc];
2294 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, iBBuf);
2295 }
2296
2297 pAlloc = &pRc->aAllocations[iNewRTFB];
2298#ifdef VBOXWDDM_WITH_VISIBLE_FB
2299 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, ~0UL /* <- for the frontbuffer */);
2300#else
2301 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));
2302#endif
2303
2304 for (UINT i = 0; i < pRc->cAllocations; ++i)
2305 {
2306 pAlloc = &pRc->aAllocations[i];
2307 if (iNewRTFB == i)
2308 {
2309 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));
2310 }
2311
2312 for (UINT j = i+1; j < pRc->cAllocations; ++j)
2313 {
2314 PVBOXWDDMDISP_ALLOCATION pAllocJ = &pRc->aAllocations[j];
2315 Assert(pAlloc->pD3DIf != pAllocJ->pD3DIf);
2316 }
2317 }
2318}
2319
2320# define VBOXVDBG_RTGT_STATECHECK(_pDev) (vboxWddmDbgRenderTargetCheck((_pDev), (_pDev)->aScreens[(_pDev)->iPrimaryScreen].pRenderTargetRc, (_pDev)->aScreens[(_pDev)->iPrimaryScreen].iRenderTargetFrontBuf))
2321#else
2322# define VBOXVDBG_RTGT_STATECHECK(_pDev) do{}while(0)
2323#endif
2324
2325#if 0
2326static HRESULT vboxWddmD3DDeviceCreate(PVBOXWDDMDISP_DEVICE pDevice, UINT iScreen, PVBOXWDDMDISP_RESOURCE pRc, D3DPRESENT_PARAMETERS * pParams, BOOL bLockable)
2327{
2328 UINT cSurfs = pParams->BackBufferCount + 1;
2329 Assert(pRc->cAllocations = cSurfs);
2330 IDirect3DDevice9 *pPrimaryDevice = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
2331 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[iScreen];
2332 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
2333 HRESULT hr;
2334 HWND hWnd = NULL;
2335 Assert(!pScreen->pDevice9If);
2336 Assert(!pScreen->hWnd);
2337 hr = VBoxDispWndCreate(pAdapter, pParams->BackBufferWidth, pParams->BackBufferHeight, &hWnd);
2338 Assert(hr == S_OK);
2339 if (hr == S_OK)
2340 {
2341 pScreen->hWnd = hWnd;
2342
2343 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
2344 if (pDevice->fFlags.AllowMultithreading)
2345 fFlags |= D3DCREATE_MULTITHREADED;
2346
2347 IDirect3DDevice9 *pDevice9If = NULL;
2348 pParams->hDeviceWindow = hWnd;
2349 /* @todo: it seems there should be a way to detect this correctly since
2350 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
2351 pParams->Windowed = TRUE;
2352 // params.EnableAutoDepthStencil = FALSE;
2353 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
2354 // params.Flags;
2355 // params.FullScreen_RefreshRateInHz;
2356 // params.FullScreen_PresentationInterval;
2357 hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, fFlags, pParams, &pDevice9If);
2358 Assert(hr == S_OK);
2359 if (hr == S_OK)
2360 {
2361 pScreen->pDevice9If = pDevice9If;
2362 pScreen->pRenderTargetRc = pRc;
2363 ++pDevice->cScreens;
2364
2365 for (UINT i = 0; i < cSurfs; ++i)
2366 {
2367 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2368 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2369 }
2370
2371 if (pPrimaryDevice)
2372 {
2373 for (UINT i = 0; i < cSurfs; ++i)
2374 {
2375 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2376 IDirect3DSurface9 *pRt;
2377 IDirect3DSurface9 *pSecondaryOpenedRt;
2378 HANDLE hSharedHandle = NULL;
2379 hr = pPrimaryDevice->CreateRenderTarget(
2380 pParams->BackBufferWidth, pParams->BackBufferHeight,
2381 pParams->BackBufferFormat,
2382 pParams->MultiSampleType,
2383 pParams->MultiSampleQuality,
2384 TRUE, /*BOOL Lockable*/
2385 &pRt,
2386 &hSharedHandle);
2387 Assert(hr == S_OK);
2388 if (hr == S_OK)
2389 {
2390 Assert(hSharedHandle != NULL);
2391 /* open render target for primary device */
2392 hr = pDevice9If->CreateRenderTarget(
2393 pParams->BackBufferWidth, pParams->BackBufferHeight,
2394 pParams->BackBufferFormat,
2395 pParams->MultiSampleType,
2396 pParams->MultiSampleQuality,
2397 TRUE, /*BOOL Lockable*/
2398 &pSecondaryOpenedRt,
2399 &hSharedHandle);
2400 Assert(hr == S_OK);
2401 if (hr == S_OK)
2402 {
2403 pAllocation->pD3DIf = pRt;
2404 pAllocation->pSecondaryOpenedD3DIf = pSecondaryOpenedRt;
2405 pAllocation->hSharedHandle = hSharedHandle;
2406 continue;
2407 }
2408 pRt->Release();
2409 }
2410
2411 for (UINT j = 0; j < i; ++j)
2412 {
2413 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[j];
2414 pAlloc->pD3DIf->Release();
2415 pAlloc->pSecondaryOpenedD3DIf->Release();
2416 }
2417
2418 break;
2419 }
2420 }
2421 else
2422 {
2423 pDevice->iPrimaryScreen = iScreen;
2424 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0);
2425 Assert(hr == S_OK);
2426 }
2427
2428 if (hr == S_OK)
2429 {
2430 for (UINT i = 0; i < cSurfs; ++i)
2431 {
2432 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2433 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2434 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
2435 Assert(hr == S_OK);
2436 if (hr != S_OK)
2437 {
2438 break;
2439 }
2440 }
2441
2442#ifndef VBOXWDDM_WITH_VISIBLE_FB
2443 if (!pPrimaryDevice)
2444 {
2445 if (hr == S_OK)
2446 {
2447 IDirect3DSurface9* pD3D9Surf;
2448 hr = pDevice9If->CreateRenderTarget(
2449 pParams->BackBufferWidth, pParams->BackBufferHeight,
2450 pParams->BackBufferFormat,
2451 pParams->MultiSampleType,
2452 pParams->MultiSampleQuality,
2453 bLockable,
2454 &pD3D9Surf,
2455 NULL /* HANDLE* pSharedHandle */
2456 );
2457 Assert(hr == S_OK);
2458 if (hr == S_OK)
2459 {
2460 pDevice->pRenderTargetFbCopy = pD3D9Surf;
2461 }
2462 }
2463 }
2464#endif
2465
2466 if (hr != S_OK)
2467 {
2468 for (UINT i = 0; i < cSurfs; ++i)
2469 {
2470 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2471 pAllocation->pD3DIf->Release();
2472 }
2473 }
2474 }
2475
2476 if (hr != S_OK)
2477 {
2478 pDevice9If->Release();
2479 --pDevice->cScreens;
2480 Assert(pDevice->cScreens < UINT32_MAX/2);
2481 }
2482 }
2483
2484 if (hr != S_OK)
2485 {
2486 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pScreen->hWnd);
2487 Assert(tmpHr == S_OK);
2488 }
2489 }
2490
2491 return hr;
2492}
2493#endif
2494static HRESULT vboxWddmD3DDeviceCreateDummy(PVBOXWDDMDISP_DEVICE pDevice)
2495{
2496 HRESULT hr;
2497 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);
2498 Assert(pRc);
2499 if (pRc)
2500 {
2501 pRc->RcDesc.enmFormat = D3DDDIFMT_A8R8G8B8;
2502 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
2503 pRc->RcDesc.MultisampleQuality = 0;
2504 for (UINT i = 0 ; i < pRc->cAllocations; ++i)
2505 {
2506 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
2507 pAlloc->SurfDesc.width = 0x4;
2508 pAlloc->SurfDesc.height = 0x4;
2509 pAlloc->SurfDesc.format = D3DDDIFMT_A8R8G8B8;
2510 }
2511
2512 PVBOXWDDMDISP_SWAPCHAIN pSwapchain;
2513 hr = vboxWddmSwapchainCreateIfForRc(pDevice, pRc, &pSwapchain);
2514 Assert(hr == S_OK);
2515 if (hr != S_OK)
2516 vboxResourceFree(pRc);
2517 }
2518 else
2519 {
2520 hr = E_OUTOFMEMORY;
2521 }
2522
2523 return hr;
2524}
2525
2526DECLINLINE(IDirect3DDevice9*) vboxWddmD3DDeviceGet(PVBOXWDDMDISP_DEVICE pDevice)
2527{
2528 if (pDevice->pDevice9If)
2529 return pDevice->pDevice9If;
2530 HRESULT hr = vboxWddmD3DDeviceCreateDummy(pDevice);
2531 Assert(hr == S_OK);
2532 Assert(pDevice->pDevice9If);
2533 return pDevice->pDevice9If;
2534}
2535
2536#if 0
2537static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource);
2538
2539static HRESULT vboxWddmD3DDeviceUpdate(PVBOXWDDMDISP_DEVICE pDevice, UINT iScreen, PVBOXWDDMDISP_RESOURCE pRc, D3DPRESENT_PARAMETERS * pParams, BOOL bLockable)
2540{
2541 UINT cSurfs = pParams->BackBufferCount + 1;
2542 Assert(pRc->cAllocations = cSurfs);
2543 Assert(iScreen == pDevice->iPrimaryScreen);
2544 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[iScreen];
2545 PVBOXWDDMDISP_RESOURCE pCurRc = pScreen->pRenderTargetRc;
2546 IDirect3DDevice9Ex *pNewDevice;
2547 HRESULT hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Update((IDirect3DDevice9Ex*)pScreen->pDevice9If, pParams, &pNewDevice);
2548 Assert(hr == S_OK);
2549 if (hr == S_OK)
2550 {
2551 pScreen->pDevice9If->Release();
2552 pScreen->pDevice9If = pNewDevice;
2553 pScreen->pRenderTargetRc = pRc;
2554
2555 for (UINT i = 0; i < cSurfs; ++i)
2556 {
2557 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2558 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2559 }
2560
2561#ifndef VBOXWDDM_WITH_VISIBLE_FB
2562 if (pDevice->pRenderTargetFbCopy)
2563 {
2564 pDevice->pRenderTargetFbCopy->Release();
2565 }
2566 IDirect3DSurface9* pD3D9Surf;
2567 hr = pNewDevice->CreateRenderTarget(
2568 pParams->BackBufferWidth, pParams->BackBufferHeight,
2569 pParams->BackBufferFormat,
2570 pParams->MultiSampleType,
2571 pParams->MultiSampleQuality,
2572 bLockable,
2573 &pD3D9Surf,
2574 NULL /* HANDLE* pSharedHandle */
2575 );
2576 Assert(hr == S_OK);
2577 if (hr == S_OK)
2578 {
2579 pDevice->pRenderTargetFbCopy = pD3D9Surf;
2580 }
2581#endif
2582 if (hr == S_OK)
2583 {
2584 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0);
2585 Assert(hr == S_OK);
2586 if (hr == S_OK)
2587 {
2588 for (UINT i = 0; i < cSurfs; ++i)
2589 {
2590 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2591 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2592 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
2593 Assert(hr == S_OK);
2594 if (hr != S_OK)
2595 {
2596 break;
2597 }
2598 }
2599 }
2600 }
2601 }
2602
2603
2604 if (!pCurRc->hResource)
2605 {
2606 HRESULT tmpHr = vboxWddmDDevDestroyResource(pDevice, pCurRc);
2607 Assert(tmpHr == S_OK);
2608 }
2609
2610 return hr;
2611}
2612#endif
2613/******/
2614
2615static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch)
2616{
2617 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2618 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
2619 if (pSwapchain)
2620 {
2621 /* backbuffer */
2622 Assert(vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc);
2623 }
2624
2625 HRESULT hr = S_OK;
2626 IDirect3DSurface9 *pD3D9Surf;
2627 if (!bOnSwapchainSynch && pSwapchain)
2628 {
2629 /* work-around wine double-buffering for the case we have no backbuffers */
2630 Assert(!pSwapchain->fFlags.bChanged);
2631 Assert(pSwapchain->pSwapChainIf);
2632 vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
2633 }
2634
2635#ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
2636 if (pSwapchain && vboxWddmSwapchainNumRTs(pSwapchain) == 1 && iRt == 0)
2637 {
2638 hr = pSwapchain->pSwapChainIf->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
2639 Assert(hr == S_OK);
2640 Assert(pD3D9Surf);
2641 }
2642 else
2643#endif
2644 {
2645 hr = vboxWddmSurfGet(pAlloc->pRc, pAlloc->iAlloc, &pD3D9Surf);
2646 Assert(hr == S_OK);
2647 Assert(pD3D9Surf);
2648 }
2649
2650 if (hr == S_OK)
2651 {
2652 Assert(pD3D9Surf);
2653 hr = pDevice9If->SetRenderTarget(iRt, pD3D9Surf);
2654 Assert(hr == S_OK);
2655 if (hr == S_OK)
2656 {
2657 Assert(iRt < pDevice->cRTs);
2658 pDevice->apRTs[iRt] = pAlloc;
2659 }
2660 pD3D9Surf->Release();
2661 }
2662
2663 return hr;
2664}
2665
2666
2667static CRITICAL_SECTION g_VBoxCritSect;
2668
2669void vboxDispLock()
2670{
2671 EnterCriticalSection(&g_VBoxCritSect);
2672}
2673
2674void vboxDispUnlock()
2675{
2676 LeaveCriticalSection(&g_VBoxCritSect);
2677}
2678
2679void vboxDispLockInit()
2680{
2681 InitializeCriticalSection(&g_VBoxCritSect);
2682}
2683
2684/**
2685 * DLL entry point.
2686 */
2687BOOL WINAPI DllMain(HINSTANCE hInstance,
2688 DWORD dwReason,
2689 LPVOID lpReserved)
2690{
2691 switch (dwReason)
2692 {
2693 case DLL_PROCESS_ATTACH:
2694 {
2695 vboxDispLockInit();
2696
2697 vboxVDbgPrint(("VBoxDispD3D: DLL loaded.\n"));
2698#ifdef VBOXWDDMDISP_DEBUG
2699 vboxVDbgVEHandlerRegister();
2700#endif
2701 RTR3Init();
2702
2703 HRESULT hr = vboxDispCmInit();
2704 Assert(hr == S_OK);
2705 if (hr == S_OK)
2706 {
2707#ifdef VBOXDISPMP_TEST
2708 hr = vboxDispMpTstStart();
2709 Assert(hr == S_OK);
2710 if (hr == S_OK)
2711#endif
2712 {
2713// hr = VBoxScreenMRunnerStart(&g_VBoxScreenMonRunner);
2714// Assert(hr == S_OK);
2715 /* succeed in any way */
2716 hr = S_OK;
2717 if (hr == S_OK)
2718 {
2719 vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n"));
2720 return TRUE;
2721 }
2722#ifdef VBOXDISPMP_TEST
2723 vboxDispMpTstStop();
2724#endif
2725 }
2726 vboxDispCmTerm();
2727 }
2728// VbglR3Init();
2729 break;
2730 }
2731
2732 case DLL_PROCESS_DETACH:
2733 {
2734#ifdef VBOXWDDMDISP_DEBUG
2735 vboxVDbgVEHandlerUnregister();
2736#endif
2737 HRESULT hr = S_OK;
2738// hr = VBoxScreenMRunnerStop(&g_VBoxScreenMonRunner);
2739// Assert(hr == S_OK);
2740// if (hr == S_OK)
2741 {
2742#ifdef VBOXDISPMP_TEST
2743 hr = vboxDispMpTstStop();
2744 Assert(hr == S_OK);
2745 if (hr == S_OK)
2746#endif
2747 {
2748 hr = vboxDispCmTerm();
2749 Assert(hr == S_OK);
2750 if (hr == S_OK)
2751 {
2752 vboxVDbgPrint(("VBoxDispD3D: DLL unloaded.\n"));
2753 return TRUE;
2754 }
2755 }
2756 }
2757// VbglR3Term();
2758 /// @todo RTR3Term();
2759 break;
2760 }
2761
2762 default:
2763 return TRUE;
2764 }
2765 return FALSE;
2766}
2767
2768static HRESULT vboxWddmGetD3D9Caps(PVBOXWDDMDISP_ADAPTER pAdapter, D3DCAPS9 *pCaps)
2769{
2770 HRESULT hr = pAdapter->pD3D9If->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pCaps);
2771 Assert(hr == S_OK);
2772 if (hr == S_OK)
2773 {
2774 pCaps->Caps2 |= D3DCAPS2_CANSHARERESOURCE | 0x00080000 /*D3DCAPS2_CANRENDERWINDOWED*/;
2775 pCaps->DevCaps |= D3DDEVCAPS_FLOATTLVERTEX /* <- must be set according to the docs */
2776 /*| D3DDEVCAPS_HWVERTEXBUFFER | D3DDEVCAPS_HWINDEXBUFFER | D3DDEVCAPS_SUBVOLUMELOCK */;
2777 pCaps->PrimitiveMiscCaps |= D3DPMISCCAPS_INDEPENDENTWRITEMASKS
2778 | D3DPMISCCAPS_FOGINFVF
2779 | D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS;
2780 pCaps->RasterCaps |= D3DPRASTERCAPS_SUBPIXEL | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_COLORPERSPECTIVE /* keep */;
2781 pCaps->TextureCaps |= D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE;
2782 pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
2783 pCaps->VolumeTextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
2784 pCaps->GuardBandLeft = -8192.;
2785 pCaps->GuardBandTop = -8192.;
2786 pCaps->GuardBandRight = 8192.;
2787 pCaps->GuardBandBottom = 8192.;
2788 pCaps->StencilCaps |= D3DSTENCILCAPS_TWOSIDED;
2789 pCaps->DeclTypes |= D3DDTCAPS_FLOAT16_2 | D3DDTCAPS_FLOAT16_4;
2790 pCaps->VS20Caps.DynamicFlowControlDepth = 24;
2791 pCaps->VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
2792 pCaps->PS20Caps.DynamicFlowControlDepth = 24;
2793 pCaps->PS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
2794 pCaps->VertexTextureFilterCaps |= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MAGFPOINT;
2795#if 1 /* workaround for wine not returning InstructionSlots correctly for shaders v3.0 */
2796 if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
2797 {
2798 pCaps->MaxVertexShader30InstructionSlots = RT_MIN(32768, pCaps->MaxVertexShader30InstructionSlots);
2799 pCaps->MaxPixelShader30InstructionSlots = RT_MIN(32768, pCaps->MaxPixelShader30InstructionSlots);
2800 }
2801#endif
2802#ifdef DEBUG
2803 if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
2804 {
2805 Assert(pCaps->MaxVertexShader30InstructionSlots >= 512);
2806 Assert(pCaps->MaxVertexShader30InstructionSlots <= 32768);
2807 Assert(pCaps->MaxPixelShader30InstructionSlots >= 512);
2808 Assert(pCaps->MaxPixelShader30InstructionSlots <= 32768);
2809 }
2810 else if ((pCaps->VertexShaderVersion & 0xff00) == 0x0200)
2811 {
2812 Assert(pCaps->MaxVertexShader30InstructionSlots == 0);
2813 Assert(pCaps->MaxPixelShader30InstructionSlots == 0);
2814 }
2815 else
2816 {
2817 Assert(0);
2818 }
2819#endif
2820 }
2821
2822 return hr;
2823}
2824
2825static HRESULT APIENTRY vboxWddmDispGetCaps (HANDLE hAdapter, CONST D3DDDIARG_GETCAPS* pData)
2826{
2827 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
2828
2829 HRESULT hr = S_OK;
2830 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
2831
2832 switch (pData->Type)
2833 {
2834 case D3DDDICAPS_DDRAW:
2835 {
2836 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
2837 Assert(pData->DataSize == sizeof (DDRAW_CAPS));
2838 if (pData->DataSize >= sizeof (DDRAW_CAPS))
2839 {
2840 memset(pData->pData, 0, sizeof (DDRAW_CAPS));
2841#ifdef VBOX_WITH_VIDEOHWACCEL
2842 if (vboxVhwaHasCKeying(pAdapter))
2843 {
2844 DDRAW_CAPS *pCaps = (DDRAW_CAPS*)pData->pData;
2845 pCaps->Caps |= DDRAW_CAPS_COLORKEY;
2846// pCaps->Caps2 |= DDRAW_CAPS2_FLIPNOVSYNC;
2847 }
2848#endif
2849 }
2850 else
2851 hr = E_INVALIDARG;
2852 break;
2853 }
2854 case D3DDDICAPS_DDRAW_MODE_SPECIFIC:
2855 {
2856 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
2857 Assert(pData->DataSize == sizeof (DDRAW_MODE_SPECIFIC_CAPS));
2858 if (pData->DataSize >= sizeof (DDRAW_MODE_SPECIFIC_CAPS))
2859 {
2860 DDRAW_MODE_SPECIFIC_CAPS * pCaps = (DDRAW_MODE_SPECIFIC_CAPS*)pData->pData;
2861 memset(&pCaps->Caps /* do not cleanup the first "Head" field,
2862 zero starting with the one following "Head", i.e. Caps */,
2863 0, sizeof (DDRAW_MODE_SPECIFIC_CAPS) - RT_OFFSETOF(DDRAW_MODE_SPECIFIC_CAPS, Caps));
2864#ifdef VBOX_WITH_VIDEOHWACCEL
2865 VBOXVHWA_INFO *pSettings = &pAdapter->aHeads[pCaps->Head].Vhwa.Settings;
2866 if (pSettings->fFlags & VBOXVHWA_F_ENABLED)
2867 {
2868 pCaps->Caps |= MODE_CAPS_OVERLAY | MODE_CAPS_OVERLAYSTRETCH;
2869
2870 if (pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
2871 {
2872 pCaps->CKeyCaps |= MODE_CKEYCAPS_DESTOVERLAY
2873 | MODE_CKEYCAPS_DESTOVERLAYYUV /* ?? */
2874 ;
2875 }
2876
2877 if (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC)
2878 {
2879 pCaps->CKeyCaps |= MODE_CKEYCAPS_SRCOVERLAY
2880 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACE /* ?? */
2881 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACEYUV /* ?? */
2882 | MODE_CKEYCAPS_SRCOVERLAYYUV /* ?? */
2883 ;
2884 }
2885
2886 pCaps->FxCaps = MODE_FXCAPS_OVERLAYSHRINKX
2887 | MODE_FXCAPS_OVERLAYSHRINKY
2888 | MODE_FXCAPS_OVERLAYSTRETCHX
2889 | MODE_FXCAPS_OVERLAYSTRETCHY;
2890
2891
2892 pCaps->MaxVisibleOverlays = pSettings->cOverlaysSupported;
2893 pCaps->MinOverlayStretch = 1;
2894 pCaps->MaxOverlayStretch = 32000;
2895 }
2896#endif
2897 }
2898 else
2899 hr = E_INVALIDARG;
2900 break;
2901 }
2902 case D3DDDICAPS_GETFORMATCOUNT:
2903 *((uint32_t*)pData->pData) = pAdapter->cFormstOps;
2904 break;
2905 case D3DDDICAPS_GETFORMATDATA:
2906 Assert(pData->DataSize == pAdapter->cFormstOps * sizeof (FORMATOP));
2907 memcpy(pData->pData, pAdapter->paFormstOps, pAdapter->cFormstOps * sizeof (FORMATOP));
2908 break;
2909 case D3DDDICAPS_GETD3DQUERYCOUNT:
2910#if 1
2911 *((uint32_t*)pData->pData) = VBOX_QUERYTYPE_COUNT();
2912#else
2913 *((uint32_t*)pData->pData) = 0;
2914#endif
2915 break;
2916 case D3DDDICAPS_GETD3DQUERYDATA:
2917#if 1
2918 Assert(pData->DataSize == VBOX_QUERYTYPE_COUNT() * sizeof (D3DDDIQUERYTYPE));
2919 memcpy(pData->pData, gVBoxQueryTypes, VBOX_QUERYTYPE_COUNT() * sizeof (D3DDDIQUERYTYPE));
2920#else
2921 Assert(0);
2922 memset(pData->pData, 0, pData->DataSize);
2923#endif
2924 break;
2925 case D3DDDICAPS_GETD3D3CAPS:
2926 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
2927 Assert(pData->DataSize == sizeof (D3DHAL_GLOBALDRIVERDATA));
2928 if (pData->DataSize >= sizeof (D3DHAL_GLOBALDRIVERDATA))
2929 {
2930 D3DHAL_GLOBALDRIVERDATA *pCaps = (D3DHAL_GLOBALDRIVERDATA *)pData->pData;
2931 memset (pCaps, 0, sizeof (D3DHAL_GLOBALDRIVERDATA));
2932 pCaps->dwSize = sizeof (D3DHAL_GLOBALDRIVERDATA);
2933 pCaps->hwCaps.dwSize = sizeof (D3DDEVICEDESC_V1);
2934 pCaps->hwCaps.dwFlags = D3DDD_COLORMODEL
2935 | D3DDD_DEVCAPS
2936 | D3DDD_DEVICERENDERBITDEPTH;
2937
2938 pCaps->hwCaps.dcmColorModel = D3DCOLOR_RGB;
2939 pCaps->hwCaps.dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP
2940// | D3DDEVCAPS_DRAWPRIMTLVERTEX
2941 | D3DDEVCAPS_EXECUTESYSTEMMEMORY
2942 | D3DDEVCAPS_EXECUTEVIDEOMEMORY
2943// | D3DDEVCAPS_FLOATTLVERTEX
2944 | D3DDEVCAPS_HWRASTERIZATION
2945// | D3DDEVCAPS_HWTRANSFORMANDLIGHT
2946// | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY
2947// | D3DDEVCAPS_TEXTUREVIDEOMEMORY
2948 ;
2949 pCaps->hwCaps.dtcTransformCaps.dwSize = sizeof (D3DTRANSFORMCAPS);
2950 pCaps->hwCaps.dtcTransformCaps.dwCaps = 0;
2951 pCaps->hwCaps.bClipping = FALSE;
2952 pCaps->hwCaps.dlcLightingCaps.dwSize = sizeof (D3DLIGHTINGCAPS);
2953 pCaps->hwCaps.dlcLightingCaps.dwCaps = 0;
2954 pCaps->hwCaps.dlcLightingCaps.dwLightingModel = 0;
2955 pCaps->hwCaps.dlcLightingCaps.dwNumLights = 0;
2956 pCaps->hwCaps.dpcLineCaps.dwSize = sizeof (D3DPRIMCAPS);
2957 pCaps->hwCaps.dpcLineCaps.dwMiscCaps = 0;
2958 pCaps->hwCaps.dpcLineCaps.dwRasterCaps = 0;
2959 pCaps->hwCaps.dpcLineCaps.dwZCmpCaps = 0;
2960 pCaps->hwCaps.dpcLineCaps.dwSrcBlendCaps = 0;
2961 pCaps->hwCaps.dpcLineCaps.dwDestBlendCaps = 0;
2962 pCaps->hwCaps.dpcLineCaps.dwAlphaCmpCaps = 0;
2963 pCaps->hwCaps.dpcLineCaps.dwShadeCaps = 0;
2964 pCaps->hwCaps.dpcLineCaps.dwTextureCaps = 0;
2965 pCaps->hwCaps.dpcLineCaps.dwTextureFilterCaps = 0;
2966 pCaps->hwCaps.dpcLineCaps.dwTextureBlendCaps = 0;
2967 pCaps->hwCaps.dpcLineCaps.dwTextureAddressCaps = 0;
2968 pCaps->hwCaps.dpcLineCaps.dwStippleWidth = 0;
2969 pCaps->hwCaps.dpcLineCaps.dwStippleHeight = 0;
2970
2971 pCaps->hwCaps.dpcTriCaps.dwSize = sizeof (D3DPRIMCAPS);
2972 pCaps->hwCaps.dpcTriCaps.dwMiscCaps = 0;
2973 pCaps->hwCaps.dpcTriCaps.dwRasterCaps = 0;
2974 pCaps->hwCaps.dpcTriCaps.dwZCmpCaps = 0;
2975 pCaps->hwCaps.dpcTriCaps.dwSrcBlendCaps = 0;
2976 pCaps->hwCaps.dpcTriCaps.dwDestBlendCaps = 0;
2977 pCaps->hwCaps.dpcTriCaps.dwAlphaCmpCaps = 0;
2978 pCaps->hwCaps.dpcTriCaps.dwShadeCaps = 0;
2979 pCaps->hwCaps.dpcTriCaps.dwTextureCaps = 0;
2980 pCaps->hwCaps.dpcTriCaps.dwTextureFilterCaps = 0;
2981 pCaps->hwCaps.dpcTriCaps.dwTextureBlendCaps = 0;
2982 pCaps->hwCaps.dpcTriCaps.dwTextureAddressCaps = 0;
2983 pCaps->hwCaps.dpcTriCaps.dwStippleWidth = 0;
2984 pCaps->hwCaps.dpcTriCaps.dwStippleHeight = 0;
2985 pCaps->hwCaps.dwDeviceRenderBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32;
2986 pCaps->hwCaps.dwDeviceZBufferBitDepth = 0;
2987 pCaps->hwCaps.dwMaxBufferSize = 0;
2988 pCaps->hwCaps.dwMaxVertexCount = 0;
2989
2990
2991 pCaps->dwNumVertices = 0;
2992 pCaps->dwNumClipVertices = 0;
2993 pCaps->dwNumTextureFormats = 0;//pAdapter->cSurfDescs;
2994 pCaps->lpTextureFormats = NULL;//pAdapter->paSurfDescs;
2995 }
2996 else
2997 hr = E_INVALIDARG;
2998 break;
2999 case D3DDDICAPS_GETD3D7CAPS:
3000 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
3001 Assert(pData->DataSize == sizeof (D3DHAL_D3DEXTENDEDCAPS));
3002 if (pData->DataSize >= sizeof (D3DHAL_D3DEXTENDEDCAPS))
3003 {
3004 memset(pData->pData, 0, sizeof (D3DHAL_D3DEXTENDEDCAPS));
3005 D3DHAL_D3DEXTENDEDCAPS *pCaps = (D3DHAL_D3DEXTENDEDCAPS*)pData->pData;
3006 pCaps->dwSize = sizeof (D3DHAL_D3DEXTENDEDCAPS);
3007 }
3008 else
3009 hr = E_INVALIDARG;
3010 break;
3011 case D3DDDICAPS_GETD3D9CAPS:
3012 {
3013 Assert(pData->DataSize == sizeof (D3DCAPS9));
3014// Assert(0);
3015 if (pData->DataSize >= sizeof (D3DCAPS9))
3016 {
3017 Assert(VBOXDISPMODE_IS_3D(pAdapter));
3018 if (VBOXDISPMODE_IS_3D(pAdapter))
3019 {
3020 D3DCAPS9* pCaps = (D3DCAPS9*)pData->pData;
3021 hr = vboxWddmGetD3D9Caps(pAdapter, pCaps);
3022 Assert(hr == S_OK);
3023 if (hr == S_OK)
3024 break;
3025
3026 vboxVDbgPrintR((__FUNCTION__": GetDeviceCaps Failed hr(%d)\n", hr));
3027 /* let's fall back to the 3D disabled case */
3028 hr = S_OK;
3029 }
3030
3031 memset(pData->pData, 0, sizeof (D3DCAPS9));
3032 }
3033 else
3034 hr = E_INVALIDARG;
3035 break;
3036 }
3037 case D3DDDICAPS_GETD3D8CAPS:
3038 {
3039 Assert(pData->DataSize == RT_OFFSETOF(D3DCAPS9, DevCaps2));
3040 if (pData->DataSize == RT_OFFSETOF(D3DCAPS9, DevCaps2))
3041 {
3042 Assert(VBOXDISPMODE_IS_3D(pAdapter));
3043 if (VBOXDISPMODE_IS_3D(pAdapter))
3044 {
3045 D3DCAPS9 Caps9;
3046 hr = vboxWddmGetD3D9Caps(pAdapter, &Caps9);
3047 Assert(hr == S_OK);
3048 if (hr == S_OK)
3049 {
3050 memcpy(pData->pData, &Caps9, RT_OFFSETOF(D3DCAPS9, DevCaps2));
3051 break;
3052 }
3053
3054 vboxVDbgPrintR((__FUNCTION__": GetDeviceCaps Failed hr(%d)\n", hr));
3055 /* let's fall back to the 3D disabled case */
3056 hr = S_OK;
3057 }
3058
3059 }
3060 else
3061 hr = E_INVALIDARG;
3062 break;
3063 }
3064 case D3DDDICAPS_GETGAMMARAMPCAPS:
3065 *((uint32_t*)pData->pData) = 0;
3066 break;
3067 case D3DDDICAPS_GETVIDEOPROCESSORCAPS:
3068 case D3DDDICAPS_GETEXTENSIONGUIDCOUNT:
3069 case D3DDDICAPS_GETDECODEGUIDCOUNT:
3070 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDCOUNT:
3071 if (pData->pData && pData->DataSize)
3072 memset(pData->pData, 0, pData->DataSize);
3073 break;
3074 case D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS:
3075 case D3DDDICAPS_GETD3D5CAPS:
3076 case D3DDDICAPS_GETD3D6CAPS:
3077 case D3DDDICAPS_GETDECODEGUIDS:
3078 case D3DDDICAPS_GETDECODERTFORMATCOUNT:
3079 case D3DDDICAPS_GETDECODERTFORMATS:
3080 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFOCOUNT:
3081 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFO:
3082 case D3DDDICAPS_GETDECODECONFIGURATIONCOUNT:
3083 case D3DDDICAPS_GETDECODECONFIGURATIONS:
3084 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDS:
3085 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATCOUNT:
3086 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATS:
3087 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT:
3088 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS:
3089 case D3DDDICAPS_GETPROCAMPRANGE:
3090 case D3DDDICAPS_FILTERPROPERTYRANGE:
3091 case D3DDDICAPS_GETEXTENSIONGUIDS:
3092 case D3DDDICAPS_GETEXTENSIONCAPS:
3093 vboxVDbgPrint((__FUNCTION__": unimplemented caps type(%d)\n", pData->Type));
3094 Assert(0);
3095 if (pData->pData && pData->DataSize)
3096 memset(pData->pData, 0, pData->DataSize);
3097 break;
3098 default:
3099 vboxVDbgPrint((__FUNCTION__": unknown caps type(%d)\n", pData->Type));
3100 Assert(0);
3101 }
3102
3103 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
3104
3105 return S_OK;
3106}
3107
3108static HRESULT APIENTRY vboxWddmDDevSetRenderState(HANDLE hDevice, CONST D3DDDIARG_RENDERSTATE* pData)
3109{
3110 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3111 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3112 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3113 Assert(pDevice);
3114 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3115 HRESULT hr = pDevice9If->SetRenderState(vboxDDI2D3DRenderStateType(pData->State), pData->Value);
3116 Assert(hr == S_OK);
3117 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3118 return hr;
3119}
3120
3121static HRESULT APIENTRY vboxWddmDDevUpdateWInfo(HANDLE hDevice, CONST D3DDDIARG_WINFO* pData)
3122{
3123 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3124 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3125 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3126 return S_OK;
3127}
3128
3129static HRESULT APIENTRY vboxWddmDDevValidateDevice(HANDLE hDevice, D3DDDIARG_VALIDATETEXTURESTAGESTATE* pData)
3130{
3131 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3132 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3133 Assert(0);
3134 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3135 return E_FAIL;
3136}
3137
3138static HRESULT APIENTRY vboxWddmDDevSetTextureStageState(HANDLE hDevice, CONST D3DDDIARG_TEXTURESTAGESTATE* pData)
3139{
3140 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3141 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3142 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3143 Assert(pDevice);
3144 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3145
3146 VBOXWDDMDISP_TSS_LOOKUP lookup = vboxDDI2D3DTestureStageStateType(pData->State);
3147 HRESULT hr;
3148
3149 if (!lookup.bSamplerState)
3150 {
3151 hr = pDevice9If->SetTextureStageState(pData->Stage, D3DTEXTURESTAGESTATETYPE(lookup.dType), pData->Value);
3152 }
3153 else
3154 {
3155 hr = pDevice9If->SetSamplerState(pData->Stage, D3DSAMPLERSTATETYPE(lookup.dType), pData->Value);
3156 }
3157
3158 Assert(hr == S_OK);
3159 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3160 return hr;
3161}
3162
3163static HRESULT APIENTRY vboxWddmDDevSetTexture(HANDLE hDevice, UINT Stage, HANDLE hTexture)
3164{
3165 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3166 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3167 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3168 Assert(pDevice);
3169 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3170 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hTexture;
3171// Assert(pRc);
3172 IDirect3DTexture9 *pD3DIfTex;
3173 if (pRc)
3174 {
3175 Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE);
3176 pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
3177#ifdef DEBUG_misha
3178 bool bDo = false;
3179
3180 if (bDo)
3181 {
3182 vboxVDbgDumpSurfData((pDevice, "SetTexture:\n", pRc, 0 /* alloc index*/, NULL, NULL, "\n"));
3183 }
3184#endif
3185 }
3186 else
3187 pD3DIfTex = NULL;
3188
3189// Assert(pD3DIfTex);
3190 HRESULT hr = pDevice9If->SetTexture(Stage, pD3DIfTex);
3191 Assert(hr == S_OK);
3192 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3193 return hr;
3194}
3195
3196static HRESULT APIENTRY vboxWddmDDevSetPixelShader(HANDLE hDevice, HANDLE hShaderHandle)
3197{
3198 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3199 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3200 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3201 Assert(pDevice);
3202 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3203 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
3204 Assert(pShader);
3205 HRESULT hr = pDevice9If->SetPixelShader(pShader);
3206 Assert(hr == S_OK);
3207 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3208 return hr;
3209}
3210
3211static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONST* pData, CONST FLOAT* pRegisters)
3212{
3213 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3214 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3215 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3216 Assert(pDevice);
3217 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3218 HRESULT hr = pDevice9If->SetPixelShaderConstantF(pData->Register, pRegisters, pData->Count);
3219 Assert(hr == S_OK);
3220 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3221 return hr;
3222}
3223
3224static HRESULT APIENTRY vboxWddmDDevSetStreamSourceUm(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEUM* pData, CONST VOID* pUMBuffer )
3225{
3226 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3227 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3228 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3229 Assert(pDevice);
3230 HRESULT hr = S_OK;
3231// IDirect3DVertexBuffer9 *pStreamData;
3232// UINT cbOffset;
3233// UINT cbStride;
3234// hr = pDevice->pDevice9If->GetStreamSource(pData->Stream, &pStreamData, &cbOffset, &cbStride);
3235// Assert(hr == S_OK);
3236// if (hr == S_OK)
3237// {
3238// if (pStreamData)
3239// {
3240// Assert(0);
3241// /* @todo: impl! */
3242// }
3243// else
3244// {
3245 Assert(pData->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm));
3246 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrcUm = &pDevice->aStreamSourceUm[pData->Stream];
3247 pStrSrcUm->pvBuffer = pUMBuffer;
3248 pStrSrcUm->cbStride = pData->Stride;
3249// }
3250// }
3251 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3252 return hr;
3253}
3254
3255static HRESULT APIENTRY vboxWddmDDevSetIndices(HANDLE hDevice, CONST D3DDDIARG_SETINDICES* pData)
3256{
3257 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3258 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3259 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3260 Assert(pDevice);
3261 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3262 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hIndexBuffer;
3263 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
3264 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
3265 if (pRc)
3266 {
3267 Assert(pRc->cAllocations == 1);
3268 pAlloc = &pRc->aAllocations[0];
3269 Assert(pAlloc->pD3DIf);
3270 pIndexBuffer = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
3271 }
3272 HRESULT hr = pDevice9If->SetIndices(pIndexBuffer);
3273 Assert(hr == S_OK);
3274 if (hr == S_OK)
3275 {
3276 pDevice->pIndicesAlloc = pAlloc;
3277 pDevice->IndiciesInfo.uiStride = pData->Stride;
3278 }
3279 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3280 return hr;
3281}
3282
3283static HRESULT APIENTRY vboxWddmDDevSetIndicesUm(HANDLE hDevice, UINT IndexSize, CONST VOID* pUMBuffer)
3284{
3285 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3286 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3287 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3288 Assert(pDevice);
3289 HRESULT hr = S_OK;
3290 pDevice->IndiciesUm.pvBuffer = pUMBuffer;
3291 pDevice->IndiciesUm.cbSize = IndexSize;
3292 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3293 return hr;
3294}
3295
3296static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE* pData, CONST UINT* pFlagBuffer)
3297{
3298 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3299 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3300 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3301 Assert(pDevice);
3302 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3303 Assert(!pFlagBuffer);
3304 HRESULT hr = S_OK;
3305
3306//#ifdef DEBUG_misha
3307// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3308// vboxVDbgDumpSurfData((pDevice, ">>>DrawPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3309// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3310//#endif
3311
3312 if (!pDevice->cStreamSources)
3313 {
3314 if (pDevice->aStreamSourceUm[0].pvBuffer)
3315 {
3316#ifdef DEBUG
3317 for (UINT i = 1; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3318 {
3319 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3320 }
3321#endif
3322 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType,
3323 pData->PrimitiveCount,
3324 ((uint8_t*)pDevice->aStreamSourceUm[0].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[0].cbStride,
3325 pDevice->aStreamSourceUm[0].cbStride);
3326 Assert(hr == S_OK);
3327
3328// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
3329 }
3330 else
3331 {
3332 /* todo: impl */
3333 Assert(0);
3334 }
3335 }
3336 else
3337 {
3338
3339#ifdef DEBUG
3340 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3341 {
3342 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3343 }
3344
3345 uint32_t cStreams = 0;
3346 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
3347 {
3348 if (pDevice->aStreamSource[i])
3349 {
3350 ++cStreams;
3351 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
3352 }
3353 }
3354
3355 Assert(cStreams);
3356 Assert(cStreams == pDevice->cStreamSources);
3357#endif
3358 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
3359 pData->VStart,
3360 pData->PrimitiveCount);
3361 Assert(hr == S_OK);
3362
3363// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitive\n"));
3364#if 0
3365 IDirect3DVertexDeclaration9* pDecl;
3366 hr = pDevice9If->GetVertexDeclaration(&pDecl);
3367 Assert(hr == S_OK);
3368 if (hr == S_OK)
3369 {
3370 Assert(pDecl);
3371 D3DVERTEXELEMENT9 aDecls9[MAXD3DDECLLENGTH];
3372 UINT cDecls9 = 0;
3373 hr = pDecl->GetDeclaration(aDecls9, &cDecls9);
3374 Assert(hr == S_OK);
3375 if (hr == S_OK)
3376 {
3377 Assert(cDecls9);
3378 for (UINT i = 0; i < cDecls9 - 1 /* the last one is D3DDECL_END */; ++i)
3379 {
3380 D3DVERTEXELEMENT9 *pDecl9 = &aDecls9[i];
3381 Assert(pDecl9->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm) || pDecl9->Stream == 0xff);
3382 if (pDecl9->Stream != 0xff)
3383 {
3384 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrc = &pDevice->aStreamSourceUm[pDecl9->Stream];
3385 if (pStrSrc->pvBuffer)
3386 {
3387 WORD iStream = pDecl9->Stream;
3388 D3DVERTEXELEMENT9 *pLastCDecl9 = pDecl9;
3389 for (UINT j = i+1; j < cDecls9 - 1 /* the last one is D3DDECL_END */; ++j)
3390 {
3391 pDecl9 = &aDecls9[j];
3392 if (iStream == pDecl9->Stream)
3393 {
3394 pDecl9->Stream = 0xff; /* mark as done */
3395 Assert(pDecl9->Offset != pLastCDecl9->Offset);
3396 if (pDecl9->Offset > pLastCDecl9->Offset)
3397 pLastCDecl9 = pDecl9;
3398 }
3399 }
3400 /* vertex size is MAX(all Offset's) + sizeof (data_type with MAX offset) + stride*/
3401 UINT cbVertex = pLastCDecl9->Offset + pStrSrc->cbStride;
3402 UINT cbType;
3403 switch (pLastCDecl9->Type)
3404 {
3405 case D3DDECLTYPE_FLOAT1:
3406 cbType = sizeof (float);
3407 break;
3408 case D3DDECLTYPE_FLOAT2:
3409 cbType = sizeof (float) * 2;
3410 break;
3411 case D3DDECLTYPE_FLOAT3:
3412 cbType = sizeof (float) * 3;
3413 break;
3414 case D3DDECLTYPE_FLOAT4:
3415 cbType = sizeof (float) * 4;
3416 break;
3417 case D3DDECLTYPE_D3DCOLOR:
3418 cbType = 4;
3419 break;
3420 case D3DDECLTYPE_UBYTE4:
3421 cbType = 4;
3422 break;
3423 case D3DDECLTYPE_SHORT2:
3424 cbType = sizeof (short) * 2;
3425 break;
3426 case D3DDECLTYPE_SHORT4:
3427 cbType = sizeof (short) * 4;
3428 break;
3429 case D3DDECLTYPE_UBYTE4N:
3430 cbType = 4;
3431 break;
3432 case D3DDECLTYPE_SHORT2N:
3433 cbType = sizeof (short) * 2;
3434 break;
3435 case D3DDECLTYPE_SHORT4N:
3436 cbType = sizeof (short) * 4;
3437 break;
3438 case D3DDECLTYPE_USHORT2N:
3439 cbType = sizeof (short) * 2;
3440 break;
3441 case D3DDECLTYPE_USHORT4N:
3442 cbType = sizeof (short) * 4;
3443 break;
3444 case D3DDECLTYPE_UDEC3:
3445 cbType = sizeof (signed) * 3;
3446 break;
3447 case D3DDECLTYPE_DEC3N:
3448 cbType = sizeof (unsigned) * 3;
3449 break;
3450 case D3DDECLTYPE_FLOAT16_2:
3451 cbType = 2 * 2;
3452 break;
3453 case D3DDECLTYPE_FLOAT16_4:
3454 cbType = 2 * 4;
3455 break;
3456 default:
3457 Assert(0);
3458 cbType = 1;
3459 }
3460 cbVertex += cbType;
3461
3462 UINT cVertexes;
3463 switch (pData->PrimitiveType)
3464 {
3465 case D3DPT_POINTLIST:
3466 cVertexes = pData->PrimitiveCount;
3467 break;
3468 case D3DPT_LINELIST:
3469 cVertexes = pData->PrimitiveCount * 2;
3470 break;
3471 case D3DPT_LINESTRIP:
3472 cVertexes = pData->PrimitiveCount + 1;
3473 break;
3474 case D3DPT_TRIANGLELIST:
3475 cVertexes = pData->PrimitiveCount * 3;
3476 break;
3477 case D3DPT_TRIANGLESTRIP:
3478 cVertexes = pData->PrimitiveCount + 2;
3479 break;
3480 case D3DPT_TRIANGLEFAN:
3481 cVertexes = pData->PrimitiveCount + 2;
3482 break;
3483 default:
3484 Assert(0);
3485 cVertexes = pData->PrimitiveCount;
3486 }
3487 UINT cbVertexes = cVertexes * cbVertex;
3488 IDirect3DVertexBuffer9 *pCurVb = NULL, *pVb = NULL;
3489 UINT cbOffset;
3490 UINT cbStride;
3491 hr = pDevice9If->GetStreamSource(iStream, &pCurVb, &cbOffset, &cbStride);
3492 Assert(hr == S_OK);
3493 if (hr == S_OK)
3494 {
3495 if (pCurVb)
3496 {
3497 if (cbStride == pStrSrc->cbStride)
3498 {
3499 /* ensure our data feets in the buffer */
3500 D3DVERTEXBUFFER_DESC Desc;
3501 hr = pCurVb->GetDesc(&Desc);
3502 Assert(hr == S_OK);
3503 if (hr == S_OK)
3504 {
3505 if (Desc.Size >= cbVertexes)
3506 pVb = pCurVb;
3507 }
3508 }
3509 }
3510 }
3511 else
3512 {
3513 pCurVb = NULL;
3514 }
3515
3516 if (!pVb)
3517 {
3518 hr = pDevice9If->CreateVertexBuffer(cbVertexes,
3519 0, /* DWORD Usage */
3520 0, /* DWORD FVF */
3521 D3DPOOL_DEFAULT, /* D3DPOOL Pool */
3522 &pVb,
3523 NULL /*HANDLE* pSharedHandle*/);
3524 Assert(hr == S_OK);
3525 if (hr == S_OK)
3526 {
3527 hr = pDevice9If->SetStreamSource(iStream, pVb, 0, pStrSrc->cbStride);
3528 Assert(hr == S_OK);
3529 if (hr == S_OK)
3530 {
3531 if (pCurVb)
3532 pCurVb->Release();
3533 }
3534 else
3535 {
3536 pVb->Release();
3537 pVb = NULL;
3538 }
3539 }
3540 }
3541
3542 if (pVb)
3543 {
3544 Assert(hr == S_OK);
3545 VOID *pvData;
3546 hr = pVb->Lock(0, /* UINT OffsetToLock */
3547 cbVertexes,
3548 &pvData,
3549 D3DLOCK_DISCARD);
3550 Assert(hr == S_OK);
3551 if (hr == S_OK)
3552 {
3553 memcpy (pvData, ((uint8_t*)pStrSrc->pvBuffer) + pData->VStart * cbVertex, cbVertexes);
3554 HRESULT tmpHr = pVb->Unlock();
3555 Assert(tmpHr == S_OK);
3556 }
3557 }
3558 }
3559 }
3560 }
3561 }
3562 if (hr == S_OK)
3563 {
3564 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
3565 0 /* <- since we use our owne StreamSource buffer which has data at the very beginning*/,
3566 pData->PrimitiveCount);
3567 Assert(hr == S_OK);
3568 }
3569 }
3570#endif
3571 }
3572
3573//#ifdef DEBUG_misha
3574// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3575// vboxVDbgDumpSurfData((pDevice, "<<<DrawPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3576// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3577//#endif
3578
3579 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3580 return hr;
3581}
3582
3583static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE* pData)
3584{
3585 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3586 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3587 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3588 Assert(pDevice);
3589 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3590//#ifdef DEBUG_misha
3591// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3592// vboxVDbgDumpSurfData((pDevice, ">>>DrawIndexedPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3593// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3594//#endif
3595
3596#ifdef DEBUG
3597 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3598 {
3599 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3600 }
3601
3602 Assert(pDevice->pIndicesAlloc);
3603 Assert(!pDevice->pIndicesAlloc->LockInfo.cLocks);
3604
3605 uint32_t cStreams = 0;
3606 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
3607 {
3608 if (pDevice->aStreamSource[i])
3609 {
3610 ++cStreams;
3611 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
3612 }
3613 }
3614
3615 Assert(cStreams);
3616 Assert(cStreams == pDevice->cStreamSources);
3617#endif
3618
3619 HRESULT hr = pDevice9If->DrawIndexedPrimitive(
3620 pData->PrimitiveType,
3621 pData->BaseVertexIndex,
3622 pData->MinIndex,
3623 pData->NumVertices,
3624 pData->StartIndex,
3625 pData->PrimitiveCount);
3626 Assert(hr == S_OK);
3627
3628//#ifdef DEBUG_misha
3629// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3630// vboxVDbgDumpSurfData((pDevice, "<<<DrawIndexedPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3631// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3632//#endif
3633
3634
3635 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3636 return hr;
3637}
3638
3639static HRESULT APIENTRY vboxWddmDDevDrawRectPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWRECTPATCH* pData, CONST D3DDDIRECTPATCH_INFO* pInfo, CONST FLOAT* pPatch)
3640{
3641 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3642 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3643 Assert(0);
3644 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3645 return E_FAIL;
3646}
3647
3648static HRESULT APIENTRY vboxWddmDDevDrawTriPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWTRIPATCH* pData, CONST D3DDDITRIPATCH_INFO* pInfo, CONST FLOAT* pPatch)
3649{
3650 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3651 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3652 Assert(0);
3653 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3654 return E_FAIL;
3655}
3656
3657static HRESULT APIENTRY vboxWddmDDevDrawPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE2* pData)
3658{
3659 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3660 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3661 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3662 Assert(pDevice);
3663 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3664 HRESULT hr;
3665
3666#if 0
3667 int stream;
3668 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
3669 {
3670 if (pDevice->aStreamSource[stream] && pDevice->aStreamSource[stream]->LockInfo.cLocks)
3671 {
3672 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
3673 if (pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite))
3674 {
3675 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf;
3676 Assert(pLock->fFlags.RangeValid);
3677 pD3D9VBuf->Lock(pLock->Range.Offset, pLock->Range.Size,
3678 &pLock->LockedRect.pBits,
3679 vboxDDI2D3DLockFlags(pLock->fFlags));
3680 RECT r;
3681 r.top = 0;
3682 r.left = pLock->Range.Offset;
3683 r.bottom = 1;
3684 r.right = pLock->Range.Offset + pLock->Range.Size;
3685
3686 vboxWddmLockUnlockMemSynch(pDevice->aStreamSource[stream], &pLock->LockedRect, &r, true /*bool bToLockInfo*/);
3687
3688 pD3D9VBuf->Unlock();
3689 }
3690 }
3691 }
3692
3693 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset, pData->PrimitiveCount);
3694#else
3695//#ifdef DEBUG_misha
3696// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3697// vboxVDbgDumpSurfData((pDevice, ">>>DrawPrimitive2:\n", pDevice->pRenderTargetRc, iBackBuf,
3698// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3699//#endif
3700
3701#ifdef DEBUG
3702 uint32_t cStreams = 0;
3703#endif
3704
3705 int stream;
3706 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
3707 {
3708 if (pDevice->aStreamSource[stream])
3709 {
3710#ifdef DEBUG
3711 ++cStreams;
3712#endif
3713 Assert(stream==0); /*only stream 0 should be accessed here*/
3714 Assert(pDevice->StreamSourceInfo[stream].uiStride!=0);
3715 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
3716
3717 if (pDevice->aStreamSource[stream]->LockInfo.cLocks)
3718 {
3719// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
3720
3721 Assert(pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite));
3722 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType, pData->PrimitiveCount,
3723 (void*)((uintptr_t)pDevice->aStreamSource[stream]->pvMem+pDevice->StreamSourceInfo[stream].uiOffset+pData->FirstVertexOffset),
3724 pDevice->StreamSourceInfo[stream].uiStride);
3725 Assert(hr == S_OK);
3726 hr = pDevice9If->SetStreamSource(stream, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf, pDevice->StreamSourceInfo[stream].uiOffset, pDevice->StreamSourceInfo[stream].uiStride);
3727 Assert(hr == S_OK);
3728 }
3729 else
3730 {
3731// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitive\n"));
3732
3733 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset/pDevice->StreamSourceInfo[stream].uiStride, pData->PrimitiveCount);
3734 Assert(hr == S_OK);
3735 }
3736 }
3737 }
3738
3739#ifdef DEBUG
3740 Assert(cStreams);
3741 Assert(cStreams == pDevice->cStreamSources);
3742#endif
3743#endif
3744
3745//#ifdef DEBUG_misha
3746// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3747// vboxVDbgDumpSurfData((pDevice, "<<<DrawPrimitive2:\n", pDevice->pRenderTargetRc, iBackBuf,
3748// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3749//#endif
3750
3751 Assert(hr == S_OK);
3752 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3753 return hr;
3754}
3755
3756static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE2* pData, UINT dwIndicesSize, CONST VOID* pIndexBuffer, CONST UINT* pFlagBuffer)
3757{
3758 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3759 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3760 Assert(0);
3761 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3762 return E_FAIL;
3763}
3764
3765static HRESULT APIENTRY vboxWddmDDevVolBlt(HANDLE hDevice, CONST D3DDDIARG_VOLUMEBLT* pData)
3766{
3767 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3768 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3769 Assert(0);
3770 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3771 return E_FAIL;
3772}
3773
3774static HRESULT APIENTRY vboxWddmDDevBufBlt(HANDLE hDevice, CONST D3DDDIARG_BUFFERBLT* pData)
3775{
3776 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3777 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3778 Assert(0);
3779 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3780 return E_FAIL;
3781}
3782
3783static HRESULT APIENTRY vboxWddmDDevTexBlt(HANDLE hDevice, CONST D3DDDIARG_TEXBLT* pData)
3784{
3785 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3786 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3787 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3788 Assert(pDevice);
3789 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3790 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
3791 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
3792 /* requirements for D3DDevice9::UpdateTexture */
3793 Assert(pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
3794 Assert(pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
3795 HRESULT hr = S_OK;
3796
3797#ifdef DEBUG_misha
3798 bool bDo = false;
3799 IDirect3DSurface9 *pTstSrcSurfIf = NULL;
3800 IDirect3DSurface9 *pTstDstSurfIf = NULL;
3801
3802 if (g_VDbgTstDumpEnable)
3803 {
3804 hr = vboxWddmSurfGet(pSrcRc, 0, &pTstSrcSurfIf);
3805 Assert(hr == S_OK);
3806 hr = vboxWddmSurfGet(pDstRc, 0, &pTstDstSurfIf);
3807 Assert(hr == S_OK);
3808
3809 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
3810 {
3811 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
3812 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
3813 {
3814 D3DSURFACE_DESC SrcDesc;
3815 HRESULT hr = pTstSrcSurfIf->GetDesc(&SrcDesc);
3816 Assert(hr == S_OK);
3817 if (hr == S_OK)
3818 {
3819 D3DSURFACE_DESC DstDesc;
3820 hr = pTstDstSurfIf->GetDesc(&DstDesc);
3821 Assert(hr == S_OK);
3822 if (hr == S_OK)
3823 {
3824 if (SrcDesc.Width == DstDesc.Width
3825 && SrcDesc.Height == DstDesc.Height)
3826 {
3827 bDo = true;
3828 }
3829 }
3830 }
3831 }
3832 }
3833 }
3834
3835 if (bDo)
3836 {
3837 RECT DstRect;
3838 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
3839 vboxVDbgDumpSurfData((pDevice, "TexBlt-pre Src:\n", pSrcRc, 0, &pData->SrcRect, pTstSrcSurfIf, "\n"));
3840 vboxVDbgDumpSurfData((pDevice, "TexBlt-pre Dst:\n", pDstRc, 0, &DstRect, pTstDstSurfIf, "\n"));
3841 }
3842#endif
3843
3844 if (pSrcRc->aAllocations[0].D3DWidth == pDstRc->aAllocations[0].D3DWidth
3845 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
3846 && pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat
3847 &&pData->DstPoint.x == 0 && pData->DstPoint.y == 0
3848 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
3849 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
3850 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height)
3851 {
3852 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcRc->aAllocations[0].pD3DIf;
3853 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstRc->aAllocations[0].pD3DIf;
3854 Assert(pD3DIfSrcTex);
3855 Assert(pD3DIfDstTex);
3856 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
3857 Assert(hr == S_OK);
3858 }
3859 else
3860 {
3861 IDirect3DSurface9 *pSrcSurfIf = NULL;
3862 IDirect3DSurface9 *pDstSurfIf = NULL;
3863 hr = vboxWddmSurfGet(pDstRc, 0, &pDstSurfIf);
3864 Assert(hr == S_OK);
3865 if (hr == S_OK)
3866 {
3867 hr = vboxWddmSurfGet(pSrcRc, 0, &pSrcSurfIf);
3868 Assert(hr == S_OK);
3869 if (hr == S_OK)
3870 {
3871 RECT DstRect;
3872 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
3873#ifdef DEBUG
3874 RECT tstRect = {0,0, pDstRc->aAllocations[0].SurfDesc.width, pDstRc->aAllocations[0].SurfDesc.height};
3875 Assert(vboxWddmRectIsCoveres(&tstRect, &DstRect));
3876#endif
3877 hr = pDevice9If->StretchRect(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &DstRect, D3DTEXF_NONE);
3878 Assert(hr == S_OK);
3879 pSrcSurfIf->Release();
3880 }
3881 pDstSurfIf->Release();
3882 }
3883 }
3884
3885#ifdef DEBUG_misha
3886 if (bDo)
3887 {
3888 RECT DstRect;
3889 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
3890 vboxVDbgDumpSurfData((pDevice, "TexBlt-post Src:\n", pSrcRc, 0, &pData->SrcRect, pTstSrcSurfIf, "\n"));
3891 vboxVDbgDumpSurfData((pDevice, "TexBlt-post Dst:\n", pDstRc, 0, &DstRect, pTstDstSurfIf, "\n"));
3892 }
3893
3894 if (pTstDstSurfIf)
3895 pTstDstSurfIf->Release();
3896 if (pTstSrcSurfIf)
3897 pTstSrcSurfIf->Release();
3898#endif
3899 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3900 return hr;
3901}
3902
3903static HRESULT APIENTRY vboxWddmDDevStateSet(HANDLE hDevice, D3DDDIARG_STATESET* pData)
3904{
3905 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3906 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3907 Assert(0);
3908 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3909 return E_FAIL;
3910}
3911static HRESULT APIENTRY vboxWddmDDevSetPriority(HANDLE hDevice, CONST D3DDDIARG_SETPRIORITY* pData)
3912{
3913 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3914 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3915 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3916 return S_OK;
3917}
3918AssertCompile(sizeof (RECT) == sizeof (D3DRECT));
3919AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DRECT, x1));
3920AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DRECT, x2));
3921AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DRECT, y1));
3922AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DRECT, y2));
3923AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DRECT, x1));
3924AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DRECT, x2));
3925AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DRECT, y1));
3926AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DRECT, y2));
3927
3928static HRESULT APIENTRY vboxWddmDDevClear(HANDLE hDevice, CONST D3DDDIARG_CLEAR* pData, UINT NumRect, CONST RECT* pRect)
3929{
3930 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3931 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3932 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3933 Assert(pDevice);
3934 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3935 HRESULT hr = pDevice9If->Clear(NumRect, (D3DRECT*)pRect /* see AssertCompile above */,
3936 pData->Flags,
3937 pData->FillColor,
3938 pData->FillDepth,
3939 pData->FillStencil);
3940 Assert(hr == S_OK);
3941 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3942 return hr;
3943}
3944static HRESULT APIENTRY vboxWddmDDevUpdatePalette(HANDLE hDevice, CONST D3DDDIARG_UPDATEPALETTE* pData, CONST PALETTEENTRY* pPaletteData)
3945{
3946 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3947 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3948 Assert(0);
3949 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3950 return E_FAIL;
3951}
3952
3953static HRESULT APIENTRY vboxWddmDDevSetPalette(HANDLE hDevice, CONST D3DDDIARG_SETPALETTE* pData)
3954{
3955 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3956 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3957 Assert(0);
3958 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3959 return E_FAIL;
3960}
3961
3962static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONST* pData , CONST VOID* pRegisters)
3963{
3964 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3965 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3966 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3967 Assert(pDevice);
3968 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3969 HRESULT hr = pDevice9If->SetVertexShaderConstantF(
3970 pData->Register,
3971 (CONST float*)pRegisters,
3972 pData->Count);
3973 Assert(hr == S_OK);
3974 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3975 return hr;
3976}
3977static HRESULT APIENTRY vboxWddmDDevMultiplyTransform(HANDLE hDevice, CONST D3DDDIARG_MULTIPLYTRANSFORM* pData)
3978{
3979 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3980 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3981 Assert(0);
3982 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3983 return E_FAIL;
3984}
3985static HRESULT APIENTRY vboxWddmDDevSetTransform(HANDLE hDevice, CONST D3DDDIARG_SETTRANSFORM* pData)
3986{
3987 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3988 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3989 Assert(0);
3990 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3991 return E_FAIL;
3992}
3993static HRESULT APIENTRY vboxWddmDDevSetViewport(HANDLE hDevice, CONST D3DDDIARG_VIEWPORTINFO* pData)
3994{
3995 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3996 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3997 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3998 Assert(pDevice);
3999 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4000 pDevice->ViewPort.X = pData->X;
4001 pDevice->ViewPort.Y = pData->Y;
4002 pDevice->ViewPort.Width = pData->Width;
4003 pDevice->ViewPort.Height = pData->Height;
4004 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
4005 Assert(hr == S_OK);
4006 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4007 return hr;
4008}
4009static HRESULT APIENTRY vboxWddmDDevSetZRange(HANDLE hDevice, CONST D3DDDIARG_ZRANGE* pData)
4010{
4011 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4012 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4013 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4014 Assert(pDevice);
4015 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4016 pDevice->ViewPort.MinZ = pData->MinZ;
4017 pDevice->ViewPort.MaxZ = pData->MaxZ;
4018 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
4019 Assert(hr == S_OK);
4020 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4021 return hr;
4022}
4023static HRESULT APIENTRY vboxWddmDDevSetMaterial(HANDLE hDevice, CONST D3DDDIARG_SETMATERIAL* pData)
4024{
4025 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4026 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4027 Assert(0);
4028 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4029 return E_FAIL;
4030}
4031static HRESULT APIENTRY vboxWddmDDevSetLight(HANDLE hDevice, CONST D3DDDIARG_SETLIGHT* pData, CONST D3DDDI_LIGHT* pLightProperties)
4032{
4033 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4034 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4035 Assert(0);
4036 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4037 return E_FAIL;
4038}
4039static HRESULT APIENTRY vboxWddmDDevCreateLight(HANDLE hDevice, CONST D3DDDIARG_CREATELIGHT* pData)
4040{
4041 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4042 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4043 Assert(0);
4044 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4045 return E_FAIL;
4046}
4047static HRESULT APIENTRY vboxWddmDDevDestroyLight(HANDLE hDevice, CONST D3DDDIARG_DESTROYLIGHT* pData)
4048{
4049 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4050 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4051 Assert(0);
4052 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4053 return E_FAIL;
4054}
4055static HRESULT APIENTRY vboxWddmDDevSetClipPlane(HANDLE hDevice, CONST D3DDDIARG_SETCLIPPLANE* pData)
4056{
4057 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4058 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4059 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4060 Assert(pDevice);
4061 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4062 HRESULT hr = pDevice9If->SetClipPlane(pData->Index, pData->Plane);
4063 Assert(hr == S_OK);
4064 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4065 return hr;
4066}
4067
4068static HRESULT APIENTRY vboxWddmDDevGetInfo(HANDLE hDevice, UINT DevInfoID, VOID* pDevInfoStruct, UINT DevInfoSize)
4069{
4070 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4071 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4072 HRESULT hr = S_OK;
4073 switch (DevInfoID)
4074 {
4075 case D3DDDIDEVINFOID_VCACHE:
4076 {
4077 Assert(DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE));
4078 if (DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE))
4079 {
4080 D3DDDIDEVINFO_VCACHE *pVCache = (D3DDDIDEVINFO_VCACHE*)pDevInfoStruct;
4081 pVCache->Pattern = MAKEFOURCC('C', 'A', 'C', 'H');
4082 pVCache->OptMethod = 0 /* D3DXMESHOPT_STRIPREORDER */;
4083 pVCache->CacheSize = 0;
4084 pVCache->MagicNumber = 0;
4085 }
4086 else
4087 hr = E_INVALIDARG;
4088 break;
4089 }
4090 default:
4091 Assert(0);
4092 hr = E_NOTIMPL;
4093 }
4094 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4095 return hr;
4096}
4097
4098static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
4099{
4100 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4101 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4102 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4103 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4104 Assert(pData->SubResourceIndex < pRc->cAllocations);
4105 if (pData->SubResourceIndex >= pRc->cAllocations)
4106 return E_INVALIDARG;
4107
4108 HRESULT hr = S_OK;
4109
4110 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4111 {
4112// Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex);
4113
4114 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
4115 {
4116 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
4117 Assert(pData->SubResourceIndex < pRc->cAllocations);
4118 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4119 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
4120 Assert(pD3DIfTex);
4121 RECT *pRect = NULL;
4122 bool bNeedResynch = false;
4123 Assert(!pData->Flags.RangeValid);
4124 Assert(!pData->Flags.BoxValid);
4125 if (pData->Flags.AreaValid)
4126 {
4127 pRect = &pData->Area;
4128 }
4129
4130 /* else - we lock the entire texture, pRect == NULL */
4131
4132// Assert(!pLockAlloc->LockInfo.cLocks);
4133 if (!pLockAlloc->LockInfo.cLocks)
4134 {
4135 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
4136 &pLockAlloc->LockInfo.LockedRect,
4137 pRect,
4138 vboxDDI2D3DLockFlags(pData->Flags));
4139 Assert(hr == S_OK);
4140 if (hr == S_OK)
4141 {
4142
4143// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4144 pLockAlloc->LockInfo.fFlags = pData->Flags;
4145 if (pRect)
4146 {
4147 pLockAlloc->LockInfo.Area = *pRect;
4148 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 1);
4149// pLockAlloc->LockInfo.fFlags.AreaValid = 1;
4150 }
4151 else
4152 {
4153 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 0);
4154// pLockAlloc->LockInfo.fFlags.AreaValid = 0;
4155 }
4156
4157 bNeedResynch = !pData->Flags.Discard;
4158 }
4159 }
4160 else
4161 {
4162// Assert(pLockAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4163// if (pLockAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4164// {
4165// }
4166 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid);
4167 if (pLockAlloc->LockInfo.fFlags.AreaValid && pData->Flags.AreaValid)
4168 {
4169 Assert(pLockAlloc->LockInfo.Area.left == pData->Area.left);
4170 Assert(pLockAlloc->LockInfo.Area.top == pData->Area.top);
4171 Assert(pLockAlloc->LockInfo.Area.right == pData->Area.right);
4172 Assert(pLockAlloc->LockInfo.Area.bottom == pData->Area.bottom);
4173 }
4174 Assert(pLockAlloc->LockInfo.LockedRect.pBits);
4175
4176 bNeedResynch = pLockAlloc->LockInfo.fFlags.Discard && !pData->Flags.Discard;
4177
4178 Assert(!bNeedResynch);
4179
4180 if (/*(pLockAlloc->LockInfo.fFlags.Discard && !pData->Flags.Discard)
4181 || */
4182 (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly))
4183 {
4184 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
4185 Assert(hr == S_OK);
4186 if (hr == S_OK)
4187 {
4188 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
4189 &pLockAlloc->LockInfo.LockedRect,
4190 pRect,
4191 vboxDDI2D3DLockFlags(pData->Flags));
4192 Assert(hr == S_OK);
4193 pLockAlloc->LockInfo.fFlags.ReadOnly = 0;
4194 }
4195 }
4196 }
4197
4198 if (hr == S_OK)
4199 {
4200 ++pLockAlloc->LockInfo.cLocks;
4201
4202 if (!pData->Flags.NotifyOnly)
4203 {
4204 pData->pSurfData = pLockAlloc->LockInfo.LockedRect.pBits;
4205 pData->Pitch = pLockAlloc->LockInfo.LockedRect.Pitch;
4206 pData->SlicePitch = 0;
4207 Assert(pLockAlloc->SurfDesc.slicePitch == 0);
4208 Assert(!pLockAlloc->pvMem);
4209 }
4210 else
4211 {
4212 Assert(pLockAlloc->pvMem);
4213 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4214#if 0
4215 if (bNeedResynch)
4216 vboxWddmLockUnlockMemSynch(pLockAlloc, &pLockAlloc->LockInfo.LockedRect, pRect, false /*bool bToLockInfo*/);
4217#endif
4218 }
4219 }
4220 }
4221 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
4222 {
4223 Assert(pData->SubResourceIndex < pRc->cAllocations);
4224 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4225 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4226 BOOL bLocked = false;
4227 Assert(pD3D9VBuf);
4228 Assert(!pData->Flags.AreaValid);
4229 Assert(!pData->Flags.BoxValid);
4230 D3DDDIRANGE *pRange = NULL;
4231 if (pData->Flags.RangeValid)
4232 {
4233 pRange = &pData->Range;
4234 }
4235
4236 /* else - we lock the entire vertex buffer, pRect == NULL */
4237
4238 Assert(!pAlloc->LockInfo.cLocks);
4239 if (!pAlloc->LockInfo.cLocks)
4240 {
4241 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
4242 {
4243 hr = pD3D9VBuf->Lock(pRange ? pRange->Offset : 0,
4244 pRange ? pRange->Size : 0,
4245 &pAlloc->LockInfo.LockedRect.pBits,
4246 vboxDDI2D3DLockFlags(pData->Flags));
4247 bLocked = true;
4248 }
4249
4250 Assert(hr == S_OK);
4251 if (hr == S_OK)
4252 {
4253 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.width;
4254// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4255 pAlloc->LockInfo.fFlags = pData->Flags;
4256 if (pRange)
4257 {
4258 pAlloc->LockInfo.Range = *pRange;
4259 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
4260// pAlloc->LockInfo.fFlags.RangeValid = 1;
4261 }
4262 else
4263 {
4264 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
4265// pAlloc->LockInfo.fFlags.RangeValid = 0;
4266 }
4267 }
4268 }
4269 else
4270 {
4271// Assert(pAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4272// if (pAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4273// {
4274// }
4275 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
4276 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
4277 {
4278 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
4279 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
4280 }
4281 Assert(pAlloc->LockInfo.LockedRect.pBits);
4282 }
4283
4284 if (hr == S_OK)
4285 {
4286 ++pAlloc->LockInfo.cLocks;
4287
4288 if (!pData->Flags.NotifyOnly)
4289 {
4290 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
4291 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
4292 pData->SlicePitch = 0;
4293 Assert(pAlloc->SurfDesc.slicePitch == 0);
4294 Assert(!pAlloc->pvMem);
4295 }
4296 else
4297 {
4298 Assert(pAlloc->pvMem);
4299 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4300 if (bLocked && !pData->Flags.Discard)
4301 {
4302 RECT r, *pr;
4303 if (pRange)
4304 {
4305 r.top = 0;
4306 r.left = pRange->Offset;
4307 r.bottom = 1;
4308 r.right = pRange->Offset + pRange->Size;
4309 pr = &r;
4310 }
4311 else
4312 pr = NULL;
4313 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
4314 }
4315 }
4316 }
4317 }
4318 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
4319 {
4320 Assert(pData->SubResourceIndex < pRc->cAllocations);
4321 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4322 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
4323 BOOL bLocked = false;
4324 Assert(pD3D9IBuf);
4325 Assert(!pData->Flags.AreaValid);
4326 Assert(!pData->Flags.BoxValid);
4327 D3DDDIRANGE *pRange = NULL;
4328 if (pData->Flags.RangeValid)
4329 {
4330 pRange = &pData->Range;
4331 }
4332
4333 /* else - we lock the entire vertex buffer, pRect == NULL */
4334
4335 Assert(!pAlloc->LockInfo.cLocks);
4336 if (!pAlloc->LockInfo.cLocks)
4337 {
4338 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
4339 {
4340 hr = pD3D9IBuf->Lock(pRange ? pRange->Offset : 0,
4341 pRange ? pRange->Size : 0,
4342 &pAlloc->LockInfo.LockedRect.pBits,
4343 vboxDDI2D3DLockFlags(pData->Flags));
4344 bLocked = true;
4345 }
4346
4347 Assert(hr == S_OK);
4348 if (hr == S_OK)
4349 {
4350 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.width;
4351// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4352 pAlloc->LockInfo.fFlags = pData->Flags;
4353 if (pRange)
4354 {
4355 pAlloc->LockInfo.Range = *pRange;
4356 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
4357// pAlloc->LockInfo.fFlags.RangeValid = 1;
4358 }
4359 else
4360 {
4361 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
4362// pAlloc->LockInfo.fFlags.RangeValid = 0;
4363 }
4364 }
4365 }
4366 else
4367 {
4368// Assert(pAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4369// if (pAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4370// {
4371// }
4372 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
4373 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
4374 {
4375 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
4376 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
4377 }
4378 Assert(pAlloc->LockInfo.LockedRect.pBits);
4379 }
4380
4381 if (hr == S_OK)
4382 {
4383 ++pAlloc->LockInfo.cLocks;
4384
4385 if (!pData->Flags.NotifyOnly)
4386 {
4387 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
4388 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
4389 pData->SlicePitch = 0;
4390 Assert(pAlloc->SurfDesc.slicePitch == 0);
4391 Assert(!pAlloc->pvMem);
4392 }
4393 else
4394 {
4395 Assert(pAlloc->pvMem);
4396 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4397 if (bLocked && !pData->Flags.Discard)
4398 {
4399 RECT r, *pr;
4400 if (pRange)
4401 {
4402 r.top = 0;
4403 r.left = pRange->Offset;
4404 r.bottom = 1;
4405 r.right = pRange->Offset + pRange->Size;
4406 pr = &r;
4407 }
4408 else
4409 pr = NULL;
4410 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
4411 }
4412 }
4413 }
4414 }
4415 else
4416 {
4417 Assert(0);
4418 }
4419 }
4420 else
4421 {
4422 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4423 D3DDDICB_LOCK LockData;
4424 LockData.hAllocation = pAlloc->hAllocation;
4425 LockData.PrivateDriverData = 0;
4426 LockData.NumPages = 0;
4427 LockData.pPages = NULL;
4428 LockData.pData = NULL; /* out */
4429 LockData.Flags.Value = 0;
4430 LockData.Flags.Discard = pData->Flags.Discard;
4431 LockData.Flags.DonotWait = pData->Flags.DoNotWait;
4432
4433
4434 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
4435 Assert(hr == S_OK || (hr == D3DERR_WASSTILLDRAWING && pData->Flags.DoNotWait));
4436 if (hr == S_OK)
4437 {
4438 Assert(!pAlloc->LockInfo.cLocks);
4439
4440 uintptr_t offset;
4441 if (pData->Flags.AreaValid)
4442 {
4443 offset = pAlloc->SurfDesc.pitch * pData->Area.top +
4444 ((pAlloc->SurfDesc.bpp * pData->Area.left) >> 3);
4445 }
4446 else if (pData->Flags.RangeValid)
4447 {
4448 offset = pData->Range.Offset;
4449 }
4450 else if (pData->Flags.BoxValid)
4451 {
4452 vboxVDbgPrintF((__FUNCTION__": Implement Box area"));
4453 Assert(0);
4454 }
4455 else
4456 {
4457 offset = 0;
4458 }
4459
4460 if (!pData->Flags.ReadOnly)
4461 {
4462 if (pData->Flags.AreaValid)
4463 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, &pData->Area);
4464 else
4465 {
4466 Assert(!pData->Flags.RangeValid);
4467 Assert(!pData->Flags.BoxValid);
4468 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, NULL); /* <- NULL means the entire surface */
4469 }
4470 }
4471
4472 if (pData->Flags.Discard)
4473 {
4474 /* check if the surface was renamed */
4475 if (LockData.hAllocation)
4476 pAlloc->hAllocation = LockData.hAllocation;
4477 }
4478
4479 pData->pSurfData = ((uint8_t*)LockData.pData) + offset;
4480 pData->Pitch = pAlloc->SurfDesc.pitch;
4481 pData->SlicePitch = pAlloc->SurfDesc.slicePitch;
4482
4483 Assert(hr == S_OK);
4484 ++pAlloc->LockInfo.cLocks;
4485 }
4486 }
4487
4488 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(%d)\n", hDevice, hr));
4489 return hr;
4490}
4491static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOCK* pData)
4492{
4493 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4494 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4495 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4496 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4497 HRESULT hr = S_OK;
4498
4499 Assert(pData->SubResourceIndex < pRc->cAllocations);
4500 if (pData->SubResourceIndex >= pRc->cAllocations)
4501 return E_INVALIDARG;
4502
4503 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4504 {
4505 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
4506 {
4507 Assert(pData->SubResourceIndex < pRc->cAllocations);
4508 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4509
4510 --pLockAlloc->LockInfo.cLocks;
4511 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
4512// pLockAlloc->LockInfo.cLocks = 0;
4513 if (!pLockAlloc->LockInfo.cLocks)
4514 {
4515 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
4516// Assert(!pLockAlloc->LockInfo.cLocks);
4517 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
4518 Assert(pD3DIfTex);
4519 /* this is a sysmem texture, update */
4520#if 0
4521 if (pLockAlloc->pvMem && !pLockAlloc->LockInfo.fFlags.ReadOnly)
4522 {
4523 vboxWddmLockUnlockMemSynch(pLockAlloc, &pLockAlloc->LockInfo.LockedRect,
4524 pLockAlloc->LockInfo.fFlags.AreaValid ? &pLockAlloc->LockInfo.Area : NULL,
4525 true /*bool bToLockInfo*/);
4526 }
4527#endif
4528 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
4529 Assert(hr == S_OK);
4530 }
4531 else
4532 {
4533 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
4534 }
4535 }
4536 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
4537 {
4538 Assert(pData->SubResourceIndex < pRc->cAllocations);
4539 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4540
4541 --pAlloc->LockInfo.cLocks;
4542 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4543 if (!pAlloc->LockInfo.cLocks
4544 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
4545 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
4546 {
4547// Assert(!pAlloc->LockInfo.cLocks);
4548 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4549 Assert(pD3D9VBuf);
4550 /* this is a sysmem texture, update */
4551 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
4552 {
4553 RECT r, *pr;
4554 if (pAlloc->LockInfo.fFlags.RangeValid)
4555 {
4556 r.top = 0;
4557 r.left = pAlloc->LockInfo.Range.Offset;
4558 r.bottom = 1;
4559 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
4560 pr = &r;
4561 }
4562 else
4563 pr = NULL;
4564 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
4565 pr,
4566 true /*bool bToLockInfo*/);
4567 }
4568 hr = pD3D9VBuf->Unlock();
4569 Assert(hr == S_OK);
4570 }
4571 else
4572 {
4573 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4574 }
4575 }
4576 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
4577 {
4578 Assert(pData->SubResourceIndex < pRc->cAllocations);
4579 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4580
4581 --pAlloc->LockInfo.cLocks;
4582 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4583 if (!pAlloc->LockInfo.cLocks
4584 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
4585 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
4586 {
4587// Assert(!pAlloc->LockInfo.cLocks);
4588 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
4589 Assert(pD3D9IBuf);
4590 /* this is a sysmem texture, update */
4591 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
4592 {
4593 RECT r, *pr;
4594 if (pAlloc->LockInfo.fFlags.RangeValid)
4595 {
4596 r.top = 0;
4597 r.left = pAlloc->LockInfo.Range.Offset;
4598 r.bottom = 1;
4599 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
4600 pr = &r;
4601 }
4602 else
4603 pr = NULL;
4604 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
4605 pr,
4606 true /*bool bToLockInfo*/);
4607 }
4608 hr = pD3D9IBuf->Unlock();
4609 Assert(hr == S_OK);
4610 }
4611 else
4612 {
4613 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4614 }
4615 }
4616 else
4617 {
4618 Assert(0);
4619 }
4620 }
4621 else
4622 {
4623 struct
4624 {
4625 D3DDDICB_UNLOCK Unlock;
4626 D3DKMT_HANDLE hAllocation;
4627 } UnlockData;
4628
4629 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4630
4631 UnlockData.Unlock.NumAllocations = 1;
4632 UnlockData.Unlock.phAllocations = &UnlockData.hAllocation;
4633 UnlockData.hAllocation = pAlloc->hAllocation;
4634
4635 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &UnlockData.Unlock);
4636 Assert(hr == S_OK);
4637 if (hr == S_OK)
4638 {
4639 Assert(pAlloc->LockInfo.cLocks);
4640 --pAlloc->LockInfo.cLocks;
4641 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4642 }
4643 }
4644
4645 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4646 return hr;
4647}
4648static HRESULT APIENTRY vboxWddmDDevLockAsync(HANDLE hDevice, D3DDDIARG_LOCKASYNC* pData)
4649{
4650 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4651 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4652 Assert(0);
4653 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4654 return E_FAIL;
4655}
4656static HRESULT APIENTRY vboxWddmDDevUnlockAsync(HANDLE hDevice, CONST D3DDDIARG_UNLOCKASYNC* pData)
4657{
4658 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4659 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4660 Assert(0);
4661 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4662 return E_FAIL;
4663}
4664static HRESULT APIENTRY vboxWddmDDevRename(HANDLE hDevice, CONST D3DDDIARG_RENAME* pData)
4665{
4666 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4667 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4668 Assert(0);
4669 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4670 return E_FAIL;
4671}
4672
4673static void vboxWddmRequestAllocFree(D3DDDICB_ALLOCATE* pAlloc)
4674{
4675 RTMemFree(pAlloc);
4676}
4677
4678static D3DDDICB_ALLOCATE* vboxWddmRequestAllocAlloc(D3DDDIARG_CREATERESOURCE* pResource)
4679{
4680 /* allocate buffer for D3DDDICB_ALLOCATE + D3DDDI_ALLOCATIONINFO * numAllocs + PVBOXWDDM_RCINFO with aAllocInfos[numAllocs] */
4681 uint32_t cbBuf = sizeof (D3DDDICB_ALLOCATE);
4682 uint32_t offDdiAllocInfos = (cbBuf + 7) & ~3;
4683 uint32_t cbDdiAllocInfos = sizeof (D3DDDI_ALLOCATIONINFO) * pResource->SurfCount;
4684 cbBuf = offDdiAllocInfos + cbDdiAllocInfos;
4685 uint32_t offRcInfo = (cbBuf + 7) & ~3;
4686 uint32_t cbRcInfo = sizeof (VBOXWDDM_RCINFO);
4687 cbBuf = offRcInfo + cbRcInfo;
4688 uint32_t offAllocInfos = (cbBuf + 7) & ~3;
4689 uint32_t cbAllocInfos = sizeof (VBOXWDDM_ALLOCINFO) * pResource->SurfCount;
4690 cbBuf = offAllocInfos + cbAllocInfos;
4691 uint8_t *pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
4692 Assert(pvBuf);
4693 if (pvBuf)
4694 {
4695 D3DDDICB_ALLOCATE* pAlloc = (D3DDDICB_ALLOCATE*)pvBuf;
4696 pAlloc->NumAllocations = pResource->SurfCount;
4697 pAlloc->pAllocationInfo = (D3DDDI_ALLOCATIONINFO*)(pvBuf + offDdiAllocInfos);
4698 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)(pvBuf + offRcInfo);
4699 pAlloc->PrivateDriverDataSize = cbRcInfo;
4700 pAlloc->pPrivateDriverData = pRcInfo;
4701 pAlloc->hResource = pResource->hResource;
4702 PVBOXWDDM_ALLOCINFO pAllocInfos = (PVBOXWDDM_ALLOCINFO)(pvBuf + offAllocInfos);
4703 for (UINT i = 0; i < pResource->SurfCount; ++i)
4704 {
4705 D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pAlloc->pAllocationInfo[i];
4706 PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
4707 pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
4708 pDdiAllocInfo->PrivateDriverDataSize = sizeof (VBOXWDDM_ALLOCINFO);
4709 }
4710 return pAlloc;
4711 }
4712 return NULL;
4713}
4714
4715static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE* pResource)
4716{
4717 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4718 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4719 HRESULT hr = S_OK;
4720 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4721 Assert(pDevice);
4722 Assert(pResource);
4723 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
4724
4725 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pResource->SurfCount);
4726 Assert(pRc);
4727 if (pRc)
4728 {
4729 bool bIssueCreateResource = false;
4730 bool bCreateSwapchain = false;
4731 bool bCreateKMResource = false;
4732
4733 pRc->hResource = pResource->hResource;
4734 pRc->hKMResource = NULL;
4735 pRc->pDevice = pDevice;
4736 pRc->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
4737 pRc->RcDesc.fFlags = pResource->Flags;
4738 pRc->RcDesc.enmFormat = pResource->Format;
4739 pRc->RcDesc.enmPool = pResource->Pool;
4740 pRc->RcDesc.enmMultisampleType = pResource->MultisampleType;
4741 pRc->RcDesc.MultisampleQuality = pResource->MultisampleQuality;
4742 pRc->RcDesc.MipLevels = pResource->MipLevels;
4743 pRc->RcDesc.Fvf = pResource->Fvf;
4744 pRc->RcDesc.VidPnSourceId = pResource->VidPnSourceId;
4745 pRc->RcDesc.RefreshRate = pResource->RefreshRate;
4746 pRc->RcDesc.enmRotation = pResource->Rotation;
4747 pRc->cAllocations = pResource->SurfCount;
4748 for (UINT i = 0; i < pResource->SurfCount; ++i)
4749 {
4750 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4751 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
4752 pAllocation->hAllocation = NULL;
4753 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
4754 pAllocation->iAlloc = i;
4755 pAllocation->pRc = pRc;
4756 pAllocation->D3DWidth = pSurf->Width;
4757 pAllocation->pvMem = (void*)pSurf->pSysMem;
4758 pAllocation->SurfDesc.pitch = pSurf->SysMemPitch;
4759 pAllocation->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
4760 pAllocation->SurfDesc.depth = pSurf->Depth;
4761 pAllocation->SurfDesc.width = pSurf->Width;
4762 pAllocation->SurfDesc.height = pSurf->Height;
4763 pAllocation->SurfDesc.format = pResource->Format;
4764 }
4765
4766 if (VBOXDISPMODE_IS_3D(pAdapter))
4767 {
4768 if (pResource->Flags.SharedResource)
4769 {
4770 Assert(0); /* <-- need to test that */
4771 bIssueCreateResource = true;
4772 bCreateKMResource = true;
4773 }
4774
4775 if (pResource->Flags.ZBuffer)
4776 {
4777 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4778 for (UINT i = 0; i < pResource->SurfCount; ++i)
4779 {
4780 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4781 IDirect3DSurface9 *pD3D9Surf;
4782 hr = pDevice9If->CreateDepthStencilSurface(pAllocation->SurfDesc.width,
4783 pAllocation->SurfDesc.height,
4784 vboxDDI2D3DFormat(pResource->Format),
4785 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
4786 pResource->MultisampleQuality,
4787 TRUE /* @todo: BOOL Discard */,
4788 &pD3D9Surf,
4789 NULL /*HANDLE* pSharedHandle*/);
4790 Assert(hr == S_OK);
4791 if (hr == S_OK)
4792 {
4793 Assert(pD3D9Surf);
4794 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
4795 pAllocation->pD3DIf = pD3D9Surf;
4796 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
4797 Assert(hr == S_OK);
4798 }
4799 else
4800 {
4801 for (UINT j = 0; j < i; ++j)
4802 {
4803 pRc->aAllocations[j].pD3DIf->Release();
4804 }
4805 break;
4806 }
4807 }
4808 }
4809 else if (pResource->Flags.VertexBuffer)
4810 {
4811 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4812
4813 for (UINT i = 0; i < pResource->SurfCount; ++i)
4814 {
4815 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4816 IDirect3DVertexBuffer9 *pD3D9VBuf;
4817 hr = pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width,
4818 vboxDDI2D3DUsage(pResource->Flags),
4819 pResource->Fvf,
4820 vboxDDI2D3DPool(pResource->Pool),
4821 &pD3D9VBuf,
4822 NULL /*HANDLE* pSharedHandle*/);
4823 Assert(hr == S_OK);
4824 if (hr == S_OK)
4825 {
4826 Assert(pD3D9VBuf);
4827 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_VERTEXBUFFER;
4828 pAllocation->pD3DIf = pD3D9VBuf;
4829 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
4830 {
4831 Assert(pAllocation->pvMem);
4832 D3DLOCKED_RECT lockInfo;
4833 hr = pD3D9VBuf->Lock(0, pAllocation->SurfDesc.width, &lockInfo.pBits, D3DLOCK_DISCARD);
4834 Assert(hr == S_OK);
4835 if (hr == S_OK)
4836 {
4837 lockInfo.Pitch = pAllocation->SurfDesc.pitch;
4838 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
4839 HRESULT tmpHr = pD3D9VBuf->Unlock();
4840 Assert(tmpHr == S_OK);
4841 }
4842 }
4843 else
4844 {
4845 Assert(!pAllocation->pvMem);
4846 }
4847 }
4848 else
4849 {
4850 for (UINT j = 0; j < i; ++j)
4851 {
4852 pRc->aAllocations[j].pD3DIf->Release();
4853 }
4854 break;
4855 }
4856 }
4857 }
4858 else if (pResource->Flags.IndexBuffer)
4859 {
4860 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4861
4862 for (UINT i = 0; i < pResource->SurfCount; ++i)
4863 {
4864 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4865 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
4866 IDirect3DIndexBuffer9 *pD3D9IBuf;
4867 hr = pDevice9If->CreateIndexBuffer(pSurf->Width,
4868 vboxDDI2D3DUsage(pResource->Flags),
4869 vboxDDI2D3DFormat(pResource->Format),
4870 vboxDDI2D3DPool(pResource->Pool),
4871 &pD3D9IBuf,
4872 NULL /*HANDLE* pSharedHandle*/
4873 );
4874 Assert(hr == S_OK);
4875 if (hr == S_OK)
4876 {
4877 Assert(pD3D9IBuf);
4878 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_INDEXBUFFER;
4879 pAllocation->pD3DIf = pD3D9IBuf;
4880 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
4881 {
4882 Assert(pAllocation->pvMem);
4883 D3DLOCKED_RECT lockInfo;
4884 hr = pD3D9IBuf->Lock(0, pAllocation->SurfDesc.width, &lockInfo.pBits, D3DLOCK_DISCARD);
4885 Assert(hr == S_OK);
4886 if (hr == S_OK)
4887 {
4888 lockInfo.Pitch = pAllocation->SurfDesc.pitch;
4889 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
4890 HRESULT tmpHr = pD3D9IBuf->Unlock();
4891 Assert(tmpHr == S_OK);
4892 }
4893 }
4894 else
4895 {
4896 Assert(!pAllocation->pvMem);
4897 }
4898 }
4899 else
4900 {
4901 for (UINT j = 0; j < i; ++j)
4902 {
4903 pRc->aAllocations[j].pD3DIf->Release();
4904 }
4905 break;
4906 }
4907 }
4908 }
4909 else if (pResource->Flags.Texture || pResource->Flags.Value == 0)
4910 {
4911 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4912
4913#ifdef DEBUG
4914 {
4915 uint32_t tstW = pResource->pSurfList[0].Width;
4916 uint32_t tstH = pResource->pSurfList[0].Height;
4917 for (UINT i = 1; i < pResource->SurfCount; ++i)
4918 {
4919 tstW /= 2;
4920 tstH /= 2;
4921 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
4922 Assert((pSurf->Width == tstW) || (!tstW && (pSurf->Width==1)));
4923 Assert((pSurf->Height == tstH) || (!tstH && (pSurf->Height==1)));
4924 }
4925 }
4926#endif
4927
4928// if (pResource->Flags.RenderTarget)
4929// bIssueCreateResource = true;
4930
4931 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
4932 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[0];
4933 IDirect3DTexture9 *pD3DIfTex;
4934 HANDLE hSharedHandle = NULL;
4935 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
4936 {
4937 Assert(pSurf->pSysMem);
4938 Assert(pSurf->SysMemPitch);
4939 UINT bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
4940 Assert(bpp);
4941 if (bpp)
4942 {
4943 pAllocation->D3DWidth = ((pSurf->SysMemPitch << 3) / bpp);
4944 if ((pSurf->SysMemPitch << 3) % bpp)
4945 {
4946 Assert(0);
4947 ++pAllocation->D3DWidth;
4948 }
4949 Assert(pAllocation->D3DWidth >= pSurf->Width);
4950 }
4951 }
4952#if 0
4953 hr = pDevice9If->CreateTexture(pSurf->Width,
4954 pAllocation->D3DWidth,
4955 pResource->SurfCount,
4956 vboxDDI2D3DUsage(pResource->Flags),
4957 vboxDDI2D3DFormat(pResource->Format),
4958 vboxDDI2D3DPool(pResource->Pool),
4959 &pD3DIfTex,
4960 NULL /* HANDLE* pSharedHandle */
4961 );
4962#else
4963 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
4964 pAllocation->D3DWidth,
4965 pSurf->Height,
4966 pResource->SurfCount,
4967 vboxDDI2D3DUsage(pResource->Flags),
4968 vboxDDI2D3DFormat(pResource->Format),
4969 vboxDDI2D3DPool(pResource->Pool),
4970 &pD3DIfTex,
4971 pResource->Flags.SharedResource ? &hSharedHandle : NULL,
4972 pResource->Pool == D3DDDIPOOL_SYSTEMMEM ? pRc->aAllocations[0].pvMem : NULL);
4973#endif
4974 Assert(hr == S_OK);
4975 if (hr == S_OK)
4976 {
4977 Assert(pD3DIfTex);
4978 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
4979 pAllocation->pD3DIf = pD3DIfTex;
4980 Assert(!!(pResource->Flags.SharedResource) == !!(hSharedHandle));
4981 pAllocation->hSharedHandle = hSharedHandle;
4982#if 0
4983 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
4984 {
4985 for (UINT i = 0; i < pResource->SurfCount; ++i)
4986 {
4987 D3DLOCKED_RECT lockInfo;
4988 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4989 Assert(pAllocation->pvMem);
4990 hr = pD3DIfTex->LockRect(i, &lockInfo, NULL, D3DLOCK_DISCARD);
4991 Assert(hr == S_OK);
4992 if (hr == S_OK)
4993 {
4994 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
4995 HRESULT tmpHr = pD3DIfTex->UnlockRect(i);
4996 Assert(tmpHr == S_OK);
4997 }
4998 else
4999 {
5000 pD3DIfTex->Release();
5001 break;
5002 }
5003 }
5004 }
5005#endif
5006 }
5007#ifdef DEBUG
5008 else
5009 {
5010 for (UINT i = 0; i < pResource->SurfCount; ++i)
5011 {
5012 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5013 Assert(!pAllocation->pvMem);
5014 }
5015 }
5016#endif
5017 }
5018 else if (pResource->Flags.RenderTarget)
5019 {
5020 HWND hWnd = NULL;
5021 bIssueCreateResource = true;
5022 Assert(pResource->SurfCount);
5023 if (RTListIsEmpty(&pDevice->SwapchainList))
5024 {
5025 bCreateSwapchain = true;
5026 Assert(bIssueCreateResource);
5027 }
5028 else
5029 {
5030 for (UINT i = 0; i < pResource->SurfCount; ++i)
5031 {
5032 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5033
5034 IDirect3DSurface9* pD3D9Surf;
5035 hr = pDevice->pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
5036 pAllocation->SurfDesc.height,
5037 vboxDDI2D3DFormat(pResource->Format),
5038 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
5039 pResource->MultisampleQuality,
5040 !pResource->Flags.NotLockable /* BOOL Lockable */,
5041 &pD3D9Surf,
5042 NULL /* HANDLE* pSharedHandle */
5043 );
5044 Assert(hr == S_OK);
5045 if (hr == S_OK)
5046 {
5047 Assert(pD3D9Surf);
5048 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
5049 pAllocation->pD3DIf = pD3D9Surf;
5050 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
5051 Assert(hr == S_OK);
5052 if (hr == S_OK)
5053 {
5054#if 0
5055 if(pResource->Flags.Primary)
5056 {
5057 for (UINT i = 0; i < pResource->SurfCount; ++i)
5058 {
5059 vboxWddmSwapchainFindCreate(pDevice, &pRc->aAllocations[i]);
5060 }
5061 Assert(bIssueCreateResource);
5062 }
5063#endif
5064 continue;
5065 }
5066
5067 /* fail branch */
5068 pD3D9Surf->Release();
5069 }
5070
5071 for (UINT j = 0; j < i; ++j)
5072 {
5073 pRc->aAllocations[j].pD3DIf->Release();
5074 }
5075 break;
5076 }
5077 }
5078 }
5079 else
5080 {
5081// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5082// Assert(pScreen->hWnd);
5083// Assert(pScreen->pDevice9If);
5084 Assert(0);
5085 }
5086 }
5087 else
5088 {
5089 bIssueCreateResource = true;
5090 bCreateKMResource = true;
5091 }
5092
5093
5094 if (hr == S_OK && bIssueCreateResource)
5095 {
5096 D3DDDICB_ALLOCATE *pDdiAllocate = vboxWddmRequestAllocAlloc(pResource);
5097 Assert(pDdiAllocate);
5098 if (pDdiAllocate)
5099 {
5100 Assert(pDdiAllocate->pPrivateDriverData);
5101 Assert(pDdiAllocate->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
5102 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)pDdiAllocate->pPrivateDriverData;
5103 pRcInfo->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
5104 pRcInfo->RcDesc = pRc->RcDesc;
5105 pRcInfo->cAllocInfos = pResource->SurfCount;
5106
5107 for (UINT i = 0; i < pResource->SurfCount; ++i)
5108 {
5109 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
5110 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5111 Assert(pDdiAllocI->pPrivateDriverData);
5112 Assert(pDdiAllocI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
5113 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
5114 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5115 pDdiAllocI->hAllocation = NULL;
5116 pDdiAllocI->pSystemMem = pSurf->pSysMem;
5117 Assert((!!(pSurf->pSysMem)) == (pResource->Pool == D3DDDIPOOL_SYSTEMMEM));
5118 pDdiAllocI->VidPnSourceId = pResource->VidPnSourceId;
5119 pDdiAllocI->Flags.Value = 0;
5120 if (pResource->Flags.Primary)
5121 {
5122 Assert(pResource->Flags.RenderTarget);
5123 pDdiAllocI->Flags.Primary = 1;
5124 }
5125
5126 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
5127 pAllocInfo->fFlags = pResource->Flags;
5128 pAllocInfo->hSharedHandle = pAllocation->hSharedHandle;
5129 pAllocInfo->SurfDesc.width = pSurf->Width;
5130 pAllocInfo->SurfDesc.height = pSurf->Height;
5131 pAllocInfo->SurfDesc.format = pResource->Format;
5132 if (!vboxWddmFormatToFourcc(pResource->Format))
5133 pAllocInfo->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
5134 else
5135 pAllocInfo->SurfDesc.bpp = 0;
5136
5137 if (pSurf->SysMemPitch)
5138 {
5139 pAllocInfo->SurfDesc.pitch = pSurf->SysMemPitch;
5140#ifdef DEBUG
5141 UINT tst = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
5142 Assert(tst == pSurf->SysMemPitch);
5143#endif
5144 }
5145 else
5146 pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
5147
5148 pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
5149 pAllocInfo->SurfDesc.depth = pSurf->Depth;
5150 pAllocInfo->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
5151 pAllocInfo->SurfDesc.VidPnSourceId = pResource->VidPnSourceId;
5152 pAllocInfo->SurfDesc.RefreshRate = pResource->RefreshRate;
5153 }
5154
5155 if (bCreateKMResource)
5156 {
5157 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
5158 Assert(hr == S_OK);
5159 Assert(pDdiAllocate->hKMResource);
5160 }
5161 else
5162 {
5163 pDdiAllocate->hResource = NULL;
5164 pDdiAllocate->NumAllocations = 1;
5165 pDdiAllocate->PrivateDriverDataSize = 0;
5166 pDdiAllocate->pPrivateDriverData = NULL;
5167 D3DDDI_ALLOCATIONINFO *pDdiAllocIBase = pDdiAllocate->pAllocationInfo;
5168
5169 for (UINT i = 0; i < pResource->SurfCount; ++i)
5170 {
5171 pDdiAllocate->pAllocationInfo = &pDdiAllocIBase[i];
5172 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
5173 Assert(hr == S_OK);
5174 Assert(!pDdiAllocate->hKMResource);
5175 if (hr == S_OK)
5176 {
5177 Assert(pDdiAllocate->pAllocationInfo->hAllocation);
5178 }
5179 else
5180 {
5181 for (UINT j = 0; i < j; ++j)
5182 {
5183 D3DDDI_ALLOCATIONINFO * pCur = &pDdiAllocIBase[i];
5184 D3DDDICB_DEALLOCATE Dealloc;
5185 Dealloc.hResource = 0;
5186 Dealloc.NumAllocations = 1;
5187 Dealloc.HandleList = &pCur->hAllocation;
5188 HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5189 Assert(tmpHr == S_OK);
5190 }
5191 break;
5192 }
5193 }
5194
5195 pDdiAllocate->pAllocationInfo = pDdiAllocIBase;
5196 }
5197
5198 if (hr == S_OK)
5199 {
5200 pRc->hKMResource = pDdiAllocate->hKMResource;
5201
5202 for (UINT i = 0; i < pResource->SurfCount; ++i)
5203 {
5204 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5205 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
5206 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
5207 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5208 pAllocation->hAllocation = pDdiAllocI->hAllocation;
5209 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
5210 pAllocation->pvMem = (void*)pSurf->pSysMem;
5211 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
5212 }
5213
5214 if(bCreateSwapchain)
5215 {
5216 PVBOXWDDMDISP_SWAPCHAIN pSwapchain;
5217 hr = vboxWddmSwapchainCreateIfForRc(pDevice, pRc, &pSwapchain);
5218 Assert(hr == S_OK);
5219 }
5220 }
5221
5222 vboxWddmRequestAllocFree(pDdiAllocate);
5223 }
5224 else
5225 {
5226 hr = E_OUTOFMEMORY;
5227 }
5228 }
5229
5230 if (hr == S_OK)
5231 pResource->hResource = pRc;
5232 else
5233 vboxResourceFree(pRc);
5234 }
5235 else
5236 {
5237 hr = E_OUTOFMEMORY;
5238 }
5239
5240
5241 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5242 return hr;
5243}
5244
5245static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource)
5246{
5247 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5248 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5249 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5250 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
5251 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hResource;
5252
5253 HRESULT hr = S_OK;
5254
5255 Assert(pDevice);
5256 Assert(hResource);
5257
5258 if (VBOXDISPMODE_IS_3D(pAdapter))
5259 {
5260// if (pRc->RcDesc.fFlags.RenderTarget)
5261// {
5262// Assert(pDevice->hWnd);
5263// Assert(pDevice->pDevice9If);
5264// }
5265
5266 for (UINT i = 0; i < pRc->cAllocations; ++i)
5267 {
5268 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
5269 if (pAlloc->pD3DIf)
5270 pAlloc->pD3DIf->Release();
5271 if (pAlloc->pSecondaryOpenedD3DIf)
5272 pAlloc->pSecondaryOpenedD3DIf->Release();
5273
5274 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
5275 if (pSwapchain)
5276 {
5277 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainRtForAlloc(pSwapchain, pAlloc);
5278 vboxWddmSwapchainRtRemove(pSwapchain, pRt);
5279 Assert(!vboxWddmSwapchainForAlloc(pAlloc));
5280 if (!vboxWddmSwapchainNumRTs(pSwapchain))
5281 vboxWddmSwapchainDestroy(pDevice, pSwapchain);
5282 }
5283
5284 EnterCriticalSection(&pDevice->DirtyAllocListLock);
5285 if (pAlloc->DirtyAllocListEntry.pNext)
5286 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
5287 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5288 }
5289 }
5290
5291 Assert(pRc->hResource);
5292 Assert(pRc->hKMResource || VBOXDISPMODE_IS_3D(pAdapter));
5293 if (pRc->hKMResource)
5294 {
5295 if (!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED))
5296 {
5297 D3DDDICB_DEALLOCATE Dealloc;
5298 Dealloc.hResource = pRc->hResource;
5299 /* according to the docs the below two are ignored in case we set the hResource */
5300 Dealloc.NumAllocations = 0;
5301 Dealloc.HandleList = NULL;
5302 hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5303 Assert(hr == S_OK);
5304 }
5305 }
5306 else
5307 {
5308 Assert(!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED));
5309 for (UINT j = 0; j < pRc->cAllocations; ++j)
5310 {
5311 if (pRc->aAllocations[j].hAllocation)
5312 {
5313 D3DDDICB_DEALLOCATE Dealloc;
5314 Dealloc.hResource = NULL;
5315 Dealloc.NumAllocations = 1;
5316 Dealloc.HandleList = &pRc->aAllocations[j].hAllocation;
5317 HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5318 Assert(tmpHr == S_OK);
5319 }
5320 }
5321 }
5322
5323 vboxResourceFree(pRc);
5324 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5325 return hr;
5326}
5327static HRESULT APIENTRY vboxWddmDDevSetDisplayMode(HANDLE hDevice, CONST D3DDDIARG_SETDISPLAYMODE* pData)
5328{
5329 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5330 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5331 HRESULT hr = S_OK;
5332 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5333 Assert(pDevice);
5334 Assert(VBOXDISPMODE_IS_3D(pDevice->pAdapter));
5335 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
5336 Assert(pRc);
5337 Assert(pRc->cAllocations > pData->SubResourceIndex);
5338 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
5339 Assert(pRc->RcDesc.fFlags.RenderTarget);
5340 Assert(pRc->RcDesc.fFlags.Primary);
5341 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5342 Assert(pAlloc->hAllocation);
5343// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5344// Assert(pScreen->hWnd);
5345// Assert(pScreen->pDevice9If);
5346 D3DDDICB_SETDISPLAYMODE DdiDm = {0};
5347 DdiDm.hPrimaryAllocation = pAlloc->hAllocation;
5348// DdiDm.PrivateDriverFormatAttribute = 0;
5349// Assert(pScreen->pRenderTargetRc == pRc);
5350// Assert(pScreen->iRenderTargetFrontBuf == pData->SubResourceIndex);
5351
5352#if 0
5353 IDirect3DSurface9 *pSoD3DIfSurf = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
5354 hr = pScreen->pDevice9If->SetRenderTarget(0, pSoD3DIfSurf);
5355 Assert(hr == S_OK);
5356 if (hr == S_OK)
5357#endif
5358 {
5359 hr = pDevice->RtCallbacks.pfnSetDisplayModeCb(pDevice->hDevice, &DdiDm);
5360 Assert(hr == S_OK);
5361 }
5362
5363 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5364 return hr;
5365}
5366static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRESENT* pData)
5367{
5368 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5369 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5370 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5371// VBOXDISPPROFILE_DDI_CHKDUMPRESET(pDevice);
5372 Assert(pDevice);
5373 HRESULT hr = S_OK;
5374 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
5375 {
5376#if 1
5377 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5378 Assert(pRc);
5379 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
5380 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5381 hr = vboxWddmSwapchainPresent(pDevice, pAlloc);
5382 Assert(hr == S_OK);
5383#else
5384 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5385 Assert(pRc);
5386 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5387 Assert(pScreen->hWnd);
5388 Assert(pScreen->pDevice9If);
5389 Assert(pRc == pScreen->pRenderTargetRc);
5390#if 1
5391 VBOXVDBG_RTGT_STATECHECK(pDevice);
5392
5393 if (pRc->RcDesc.VidPnSourceId != pDevice->iPrimaryScreen)
5394 {
5395 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5396 PVBOXWDDMDISP_SCREEN pPrimaryScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5397 Assert(pPrimaryScreen->pDevice9If);
5398 IDirect3DSurface9 *pSecondaryRt;
5399 IDirect3DSurface9 *pDataRt = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
5400 Assert(pDataRt);
5401 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5402 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pPrimaryScreen->pDevice9If);
5403 Assert(hr == S_OK);
5404 if (hr == S_OK)
5405 {
5406 hr = pScreen->pDevice9If->GetRenderTarget(0, &pSecondaryRt);
5407 Assert(hr == S_OK);
5408 if (hr == S_OK)
5409 {
5410 hr = pScreen->pDevice9If->StretchRect(pDataRt,
5411 NULL,
5412 pSecondaryRt,
5413 NULL,
5414 D3DTEXF_NONE);
5415 pSecondaryRt->Release();
5416 }
5417 }
5418 }
5419
5420 hr = pScreen->pDevice9If->Present(NULL, /* CONST RECT * pSourceRect */
5421 NULL, /* CONST RECT * pDestRect */
5422 NULL, /* HWND hDestWindowOverride */
5423 NULL /*CONST RGNDATA * pDirtyRegion */
5424 );
5425 Assert(hr == S_OK);
5426#endif
5427#endif
5428 }
5429#if 0
5430 else
5431#endif
5432 {
5433// if (pData->Flags.Flip)
5434// {
5435// Assert(pData->hSrcResource);
5436// PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5437// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5438// Assert(pScreen->hWnd);
5439// Assert(pScreen->pDevice9If);
5440// Assert(pScreen->pRenderTargetRc == pRc);
5441// Assert(pRc->cAllocations >= 2);
5442// Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5443// Assert(pRc->RcDesc.fFlags.RenderTarget);
5444// uint32_t iNewRTFB = (pScreen->iRenderTargetFrontBuf + 1) % pRc->cAllocations;
5445//
5446// Assert(pScreen->iRenderTargetFrontBuf != iNewRTFB);
5447// Assert(pData->SrcSubResourceIndex == iNewRTFB);
5448//
5449// vboxWddmRenderTargetUpdate(pDevice, pRc, iNewRTFB);
5450//
5451// /* assign a new frontbuffer index */
5452// pScreen->iRenderTargetFrontBuf = iNewRTFB;
5453//
5454// VBOXVDBG_RTGT_STATECHECK(pDevice);
5455// }
5456 D3DDDICB_PRESENT DdiPresent = {0};
5457 if (pData->hSrcResource)
5458 {
5459 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5460 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
5461 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5462 Assert(pAlloc->hAllocation);
5463 DdiPresent.hSrcAllocation = pAlloc->hAllocation;
5464 }
5465 if (pData->hDstResource)
5466 {
5467 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
5468 Assert(pRc->cAllocations > pData->DstSubResourceIndex);
5469 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->DstSubResourceIndex];
5470 Assert(pAlloc->hAllocation);
5471 DdiPresent.hDstAllocation = pAlloc->hAllocation;
5472 }
5473 DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext;
5474// DdiPresent.BroadcastContextCount;
5475// DdiPresent.BroadcastContext[D3DDDI_MAX_BROADCAST_CONTEXT];
5476
5477 hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent);
5478 Assert(hr == S_OK);
5479 }
5480 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5481 return hr;
5482}
5483
5484typedef struct VBOXWDDMDISP_NSCADD
5485{
5486 VOID* pvCommandBuffer;
5487 UINT cbCommandBuffer;
5488 D3DDDI_ALLOCATIONLIST* pAllocationList;
5489 UINT cAllocationList;
5490 D3DDDI_PATCHLOCATIONLIST* pPatchLocationList;
5491 UINT cPatchLocationList;
5492 UINT cAllocations;
5493}VBOXWDDMDISP_NSCADD, *PVBOXWDDMDISP_NSCADD;
5494
5495static HRESULT vboxWddmNSCAddAlloc(PVBOXWDDMDISP_NSCADD pData, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bWrite)
5496{
5497 HRESULT hr = S_OK;
5498 if (pData->cAllocationList && pData->cPatchLocationList && pData->cbCommandBuffer > 4)
5499 {
5500 memset(pData->pAllocationList, 0, sizeof (D3DDDI_ALLOCATIONLIST));
5501 pData->pAllocationList[0].hAllocation = pAlloc->hAllocation;
5502 if (bWrite)
5503 pData->pAllocationList[0].WriteOperation = 1;
5504
5505 memset(pData->pPatchLocationList, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
5506 pData->pPatchLocationList[0].PatchOffset = pData->cAllocations*4;
5507 pData->pPatchLocationList[0].AllocationIndex = pData->cAllocations;
5508
5509 pData->cbCommandBuffer -= 4;
5510 --pData->cAllocationList;
5511 --pData->cPatchLocationList;
5512 ++pData->cAllocations;
5513 }
5514 else
5515 hr = S_FALSE;
5516
5517 ++pData->pAllocationList;
5518 ++pData->pPatchLocationList;
5519 pData->pvCommandBuffer = (VOID*)(((uint8_t*)pData->pvCommandBuffer) + 4);
5520
5521 return hr;
5522}
5523
5524static HRESULT vboxWddmNotifySharedChange(PVBOXWDDMDISP_DEVICE pDevice)
5525{
5526 VBOXWDDMDISP_NSCADD NscAdd;
5527 BOOL bReinitRenderData = TRUE;
5528
5529 do
5530 {
5531 if (bReinitRenderData)
5532 {
5533 NscAdd.pvCommandBuffer = pDevice->DefaultContext.ContextInfo.pCommandBuffer;
5534 NscAdd.cbCommandBuffer = pDevice->DefaultContext.ContextInfo.CommandBufferSize;
5535 NscAdd.pAllocationList = pDevice->DefaultContext.ContextInfo.pAllocationList;
5536 NscAdd.cAllocationList = pDevice->DefaultContext.ContextInfo.AllocationListSize;
5537 NscAdd.pPatchLocationList = pDevice->DefaultContext.ContextInfo.pPatchLocationList;
5538 NscAdd.cPatchLocationList = pDevice->DefaultContext.ContextInfo.PatchLocationListSize;
5539 NscAdd.cAllocations = 0;
5540 bReinitRenderData = FALSE;
5541 }
5542
5543 EnterCriticalSection(&pDevice->DirtyAllocListLock);
5544
5545 PVBOXWDDMDISP_ALLOCATION pAlloc = RTListNodeGetFirst(&pDevice->DirtyAllocList, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry);
5546 if (pAlloc)
5547 {
5548 HRESULT tmpHr = vboxWddmNSCAddAlloc(&NscAdd, pAlloc, TRUE);
5549 Assert(tmpHr == S_OK || tmpHr == S_FALSE);
5550 if (tmpHr == S_OK)
5551 {
5552 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
5553 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5554 continue;
5555 }
5556
5557 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5558
5559 }
5560 else
5561 {
5562 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5563 if (!NscAdd.cAllocations)
5564 break;
5565 }
5566
5567 D3DDDICB_RENDER RenderData = {0};
5568 RenderData.CommandLength = pDevice->DefaultContext.ContextInfo.CommandBufferSize - NscAdd.cbCommandBuffer;
5569 Assert(RenderData.CommandLength);
5570 Assert(RenderData.CommandLength < UINT32_MAX/2);
5571 RenderData.CommandOffset = 0;
5572 RenderData.NumAllocations = pDevice->DefaultContext.ContextInfo.AllocationListSize - NscAdd.cAllocationList;
5573 Assert(RenderData.NumAllocations == NscAdd.cAllocations);
5574 RenderData.NumPatchLocations = pDevice->DefaultContext.ContextInfo.PatchLocationListSize - NscAdd.cPatchLocationList;
5575 Assert(RenderData.NumPatchLocations == NscAdd.cAllocations);
5576 RenderData.NewCommandBufferSize = sizeof (VBOXVDMACMD) + 4 * (100);
5577 RenderData.NewAllocationListSize = 100;
5578 RenderData.NewPatchLocationListSize = 100;
5579 RenderData.hContext = pDevice->DefaultContext.ContextInfo.hContext;
5580
5581 HRESULT hr = pDevice->RtCallbacks.pfnRenderCb(pDevice->hDevice, &RenderData);
5582 Assert(hr == S_OK);
5583 if (hr == S_OK)
5584 {
5585 pDevice->DefaultContext.ContextInfo.CommandBufferSize = RenderData.NewCommandBufferSize;
5586 pDevice->DefaultContext.ContextInfo.pCommandBuffer = RenderData.pNewCommandBuffer;
5587 pDevice->DefaultContext.ContextInfo.AllocationListSize = RenderData.NewAllocationListSize;
5588 pDevice->DefaultContext.ContextInfo.pAllocationList = RenderData.pNewAllocationList;
5589 pDevice->DefaultContext.ContextInfo.PatchLocationListSize = RenderData.NewPatchLocationListSize;
5590 pDevice->DefaultContext.ContextInfo.pPatchLocationList = RenderData.pNewPatchLocationList;
5591 bReinitRenderData = TRUE;
5592 }
5593 else
5594 break;
5595 } while (1);
5596
5597 return S_OK;
5598}
5599
5600static HRESULT APIENTRY vboxWddmDDevFlush(HANDLE hDevice)
5601{
5602 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5603 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5604 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5605 Assert(pDevice);
5606 HRESULT hr = S_OK;
5607 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
5608 {
5609// Assert(pDevice->cScreens);
5610// UINT cProcessed = 0;
5611// for (UINT i = 0; cProcessed < pDevice->cScreens && i < RT_ELEMENTS(pDevice->aScreens); ++i)
5612// {
5613// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i];
5614// if (pScreen->pDevice9If)
5615// {
5616// ++cProcessed;
5617//// if (pScreen->pRenderTargetRc->cAllocations == 1)
5618//// {
5619//// hr = pScreen->pDevice9If->Present(NULL, NULL, NULL, NULL);
5620//// Assert(hr == S_OK);
5621//// }
5622//// else
5623 {
5624 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pDevice->pDevice9If);
5625 Assert(hr == S_OK);
5626 }
5627// }
5628// }
5629
5630 vboxWddmNotifySharedChange(pDevice);
5631 }
5632 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5633 return hr;
5634}
5635
5636AssertCompile(sizeof (D3DDDIVERTEXELEMENT) == sizeof (D3DVERTEXELEMENT9));
5637AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Stream) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Stream));
5638AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Offset) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Offset));
5639AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Type) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Type));
5640AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Method) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Method));
5641AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Usage) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Usage));
5642AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, UsageIndex) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, UsageIndex));
5643
5644AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Stream) == RT_OFFSETOF(D3DVERTEXELEMENT9, Stream));
5645AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Offset) == RT_OFFSETOF(D3DVERTEXELEMENT9, Offset));
5646AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Type) == RT_OFFSETOF(D3DVERTEXELEMENT9, Type));
5647AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Method) == RT_OFFSETOF(D3DVERTEXELEMENT9, Method));
5648AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Usage) == RT_OFFSETOF(D3DVERTEXELEMENT9, Usage));
5649AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, UsageIndex) == RT_OFFSETOF(D3DVERTEXELEMENT9, UsageIndex));
5650
5651static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderDecl(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERDECL* pData, CONST D3DDDIVERTEXELEMENT* pVertexElements)
5652{
5653 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5654 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5655 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5656 Assert(pDevice);
5657 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5658 IDirect3DVertexDeclaration9 *pDecl;
5659 static D3DVERTEXELEMENT9 DeclEnd = D3DDECL_END();
5660 D3DVERTEXELEMENT9* pVe;
5661 HRESULT hr = S_OK;
5662 bool bFreeVe = false;
5663 if(memcmp(&DeclEnd, &pVertexElements[pData->NumVertexElements], sizeof (DeclEnd)))
5664 {
5665 pVe = (D3DVERTEXELEMENT9*)RTMemAlloc(sizeof (D3DVERTEXELEMENT9) * (pData->NumVertexElements + 1));
5666 if (pVe)
5667 {
5668 memcpy(pVe, pVertexElements, sizeof (D3DVERTEXELEMENT9) * pData->NumVertexElements);
5669 pVe[pData->NumVertexElements] = DeclEnd;
5670 bFreeVe = true;
5671 }
5672 else
5673 hr = E_OUTOFMEMORY;
5674 }
5675 else
5676 pVe = (D3DVERTEXELEMENT9*)pVertexElements;
5677
5678 if (hr == S_OK)
5679 {
5680 hr = pDevice9If->CreateVertexDeclaration(
5681 pVe,
5682 &pDecl
5683 );
5684 Assert(hr == S_OK);
5685 if (hr == S_OK)
5686 {
5687 Assert(pDecl);
5688 pData->ShaderHandle = pDecl;
5689 }
5690 }
5691
5692 if (bFreeVe)
5693 RTMemFree((void*)pVe);
5694
5695 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5696 return hr;
5697}
5698static HRESULT APIENTRY vboxWddmDDevSetVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
5699{
5700 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5701 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5702 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5703 Assert(pDevice);
5704 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5705 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
5706 Assert(pDecl);
5707 HRESULT hr = pDevice9If->SetVertexDeclaration(pDecl);
5708 Assert(hr == S_OK);
5709 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5710 return hr;
5711}
5712static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
5713{
5714 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5715 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5716 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5717 Assert(pDevice);
5718 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
5719 HRESULT hr = S_OK;
5720 pDecl->Release();
5721 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5722 return hr;
5723}
5724static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderFunc(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERFUNC* pData, CONST UINT* pCode)
5725{
5726 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5727 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5728 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5729 Assert(pDevice);
5730 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5731 IDirect3DVertexShader9 *pShader;
5732 Assert(*((UINT*)((uint8_t*)pCode + pData->Size-4)) == 0x0000FFFF /* end token */);
5733 HRESULT hr = pDevice9If->CreateVertexShader((const DWORD *)pCode, &pShader);
5734 Assert(hr == S_OK);
5735 if (hr == S_OK)
5736 {
5737 Assert(pShader);
5738 pData->ShaderHandle = pShader;
5739 }
5740 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5741 return hr;
5742}
5743static HRESULT APIENTRY vboxWddmDDevSetVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
5744{
5745 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5746 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5747 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5748 Assert(pDevice);
5749 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5750 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
5751 Assert(pShader);
5752 HRESULT hr = pDevice9If->SetVertexShader(pShader);
5753 Assert(hr == S_OK);
5754 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5755 return hr;
5756}
5757static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
5758{
5759 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5760 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5761 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5762 Assert(pDevice);
5763 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
5764 HRESULT hr = S_OK;
5765 pShader->Release();
5766 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5767 return hr;
5768}
5769static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTI* pData, CONST INT* pRegisters)
5770{
5771 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5772 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5773 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5774 Assert(pDevice);
5775 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5776 HRESULT hr = pDevice9If->SetVertexShaderConstantI(pData->Register, pRegisters, pData->Count);
5777 Assert(hr == S_OK);
5778 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5779 return hr;
5780}
5781static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTB* pData, CONST BOOL* pRegisters)
5782{
5783 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5784 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5785 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5786 Assert(pDevice);
5787 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5788 HRESULT hr = pDevice9If->SetVertexShaderConstantB(pData->Register, pRegisters, pData->Count);
5789 Assert(hr == S_OK);
5790 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5791 return hr;
5792}
5793static HRESULT APIENTRY vboxWddmDDevSetScissorRect(HANDLE hDevice, CONST RECT* pRect)
5794{
5795 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5796 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5797 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5798 Assert(pDevice);
5799 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5800 HRESULT hr = pDevice9If->SetScissorRect(pRect);
5801 Assert(hr == S_OK);
5802 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5803 return hr;
5804}
5805static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCE* pData)
5806{
5807 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5808 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5809 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5810 Assert(pDevice);
5811 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5812 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hVertexBuffer;
5813 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
5814 IDirect3DVertexBuffer9 *pStreamData = NULL;
5815 if (pRc)
5816 {
5817 Assert(pRc->cAllocations == 1);
5818 pAlloc = &pRc->aAllocations[0];
5819 Assert(pAlloc->pD3DIf);
5820 pStreamData = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
5821 }
5822 HRESULT hr = pDevice9If->SetStreamSource(pData->Stream, pStreamData, pData->Offset, pData->Stride);
5823 Assert(hr == S_OK);
5824 Assert(pData->Stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS);
5825 if (hr == S_OK)
5826 {
5827 if (pDevice->aStreamSource[pData->Stream] && !pAlloc)
5828 {
5829 --pDevice->cStreamSources;
5830 Assert(pDevice->cStreamSources < UINT32_MAX/2);
5831 }
5832 else if (!pDevice->aStreamSource[pData->Stream] && pAlloc)
5833 {
5834 ++pDevice->cStreamSources;
5835 Assert(pDevice->cStreamSources <= RT_ELEMENTS(pDevice->aStreamSource));
5836 }
5837 pDevice->aStreamSource[pData->Stream] = pAlloc;
5838 pDevice->StreamSourceInfo[pData->Stream].uiOffset = pData->Offset;
5839 pDevice->StreamSourceInfo[pData->Stream].uiStride = pData->Stride;
5840 }
5841 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5842 return hr;
5843}
5844static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData)
5845{
5846 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5847 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5848 Assert(0);
5849 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5850 return E_FAIL;
5851}
5852static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData)
5853{
5854 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5855 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5856 Assert(0);
5857 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5858 return E_FAIL;
5859}
5860static HRESULT APIENTRY vboxWddmDDevComposeRects(HANDLE hDevice, CONST D3DDDIARG_COMPOSERECTS* pData)
5861{
5862 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5863 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5864 Assert(0);
5865 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5866 return E_FAIL;
5867}
5868static HRESULT vboxWddmLockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc,
5869 D3DLOCKED_RECT * pLockedRect,
5870 CONST RECT *pRect,
5871 DWORD fLockFlags)
5872{
5873 HRESULT hr = E_FAIL;
5874 Assert(!pRc->aAllocations[iAlloc].LockInfo.cLocks);
5875 Assert(pRc->cAllocations > iAlloc);
5876 switch (pRc->aAllocations[0].enmD3DIfType)
5877 {
5878 case VBOXDISP_D3DIFTYPE_SURFACE:
5879 {
5880 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
5881 Assert(pD3DIfSurf);
5882 hr = pD3DIfSurf->LockRect(pLockedRect, pRect, fLockFlags);
5883 Assert(hr == S_OK);
5884 break;
5885 }
5886 case VBOXDISP_D3DIFTYPE_TEXTURE:
5887 {
5888 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
5889 Assert(pD3DIfTex);
5890 hr = pD3DIfTex->LockRect(iAlloc, pLockedRect, pRect, fLockFlags);
5891 Assert(hr == S_OK);
5892 break;
5893 }
5894 default:
5895 Assert(0);
5896 break;
5897 }
5898 return hr;
5899}
5900static HRESULT vboxWddmUnlockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc)
5901{
5902 HRESULT hr = S_OK;
5903 Assert(pRc->cAllocations > iAlloc);
5904 switch (pRc->aAllocations[0].enmD3DIfType)
5905 {
5906 case VBOXDISP_D3DIFTYPE_SURFACE:
5907 {
5908 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
5909 Assert(pD3DIfSurf);
5910 hr = pD3DIfSurf->UnlockRect();
5911 Assert(hr == S_OK);
5912 break;
5913 }
5914 case VBOXDISP_D3DIFTYPE_TEXTURE:
5915 {
5916 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
5917 Assert(pD3DIfTex);
5918 hr = pD3DIfTex->UnlockRect(iAlloc);
5919 Assert(hr == S_OK);
5920 break;
5921 }
5922 default:
5923 Assert(0);
5924 hr = E_FAIL;
5925 break;
5926 }
5927 return hr;
5928}
5929
5930static HRESULT APIENTRY vboxWddmDDevBlt(HANDLE hDevice, CONST D3DDDIARG_BLT* pData)
5931{
5932 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5933 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5934 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5935 Assert(pDevice);
5936// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5937 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5938 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
5939 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5940 Assert(pDstRc->cAllocations > pData->DstSubResourceIndex);
5941 Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex);
5942 HRESULT hr = S_OK;
5943 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
5944 PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
5945 PVBOXWDDMDISP_SWAPCHAIN pSrcSwapchain = vboxWddmSwapchainForAlloc(pSrcAlloc);
5946 PVBOXWDDMDISP_SWAPCHAIN pDstSwapchain = vboxWddmSwapchainForAlloc(pDstAlloc);
5947 Assert(!pDstSwapchain || vboxWddmSwapchainGetFb(pDstSwapchain)->pAlloc != pDstAlloc);
5948 /* try StretchRect */
5949 IDirect3DSurface9 *pSrcSurfIf = NULL;
5950 IDirect3DSurface9 *pDstSurfIf = NULL;
5951 hr = vboxWddmSurfGet(pDstRc, pData->DstSubResourceIndex, &pDstSurfIf);
5952 Assert(hr == S_OK);
5953 if (hr == S_OK)
5954 {
5955 Assert(pDstSurfIf);
5956 do
5957 {
5958#ifndef VBOXWDDM_WITH_VISIBLE_FB
5959 if (pSrcSwapchain
5960 && pSrcSwapchain->pRenderTargetFbCopy
5961 && vboxWddmSwapchainGetFb(pSrcSwapchain)->pAlloc == pSrcAlloc
5962# ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
5963 && vboxWddmSwapchainNumRTs(pSrcSwapchain) > 1 /* work-around wine backbuffer */
5964# endif
5965 )
5966 {
5967// Assert(pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width);
5968// Assert(pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height);
5969// Assert(pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format);
5970// Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
5971// Assert(pSrcAlloc->SurfDesc.pitch == pDstAlloc->SurfDesc.pitch);
5972// Assert(pSrcAlloc->SurfDesc.depth == pDstAlloc->SurfDesc.depth);
5973// Assert(pSrcAlloc->SurfDesc.slicePitch == pDstAlloc->SurfDesc.slicePitch);
5974// Assert(pSrcAlloc->SurfDesc.cbSize == pDstAlloc->SurfDesc.cbSize);
5975// Assert(pData->DstRect.left == 0);
5976// Assert(pData->DstRect.top == 0);
5977// Assert(pData->DstRect.right == pDstAlloc->SurfDesc.width);
5978// Assert(pData->DstRect.bottom == pDstAlloc->SurfDesc.height);
5979// Assert(pData->SrcRect.left == 0);
5980// Assert(pData->SrcRect.top == 0);
5981// Assert(pData->SrcRect.right == pSrcAlloc->SurfDesc.width);
5982// Assert(pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height);
5983# if 0
5984 if (pData->DstRect.left == 0 && pData->DstRect.top == 0
5985 && pData->DstRect.right == pDstAlloc->SurfDesc.width
5986 && pData->DstRect.bottom == pDstAlloc->SurfDesc.height
5987 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
5988 && pData->SrcRect.right == pSrcAlloc->SurfDesc.width
5989 && pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height
5990 && pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width
5991 && pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height
5992 && pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format)
5993 {
5994 hr = pDevice9If->GetFrontBufferData(0, pDstSurfIf);
5995 Assert(hr == S_OK);
5996 break;
5997 }
5998 else
5999# endif
6000 {
6001 pSrcSurfIf = pSrcSwapchain->pRenderTargetFbCopy;
6002 Assert(pSrcSurfIf);
6003 hr = pSrcSwapchain->pSwapChainIf->GetFrontBufferData(pSrcSurfIf);
6004 Assert(hr == S_OK);
6005 if (hr == S_OK)
6006 {
6007 /* do pSrcSurfIf->AddRef since we do a Release in the following if (hr == S_OK) branch */
6008 pSrcSurfIf->AddRef();
6009 }
6010 }
6011 }
6012 else
6013#endif
6014 {
6015 hr = vboxWddmSurfGet(pSrcRc, pData->SrcSubResourceIndex, &pSrcSurfIf);
6016 Assert(hr == S_OK);
6017 }
6018
6019 if (hr == S_OK)
6020 {
6021 Assert(pSrcSurfIf);
6022#ifdef DEBUG_misha
6023 bool bDo = false;
6024
6025 if (g_VDbgTstDumpEnable)
6026 {
6027 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
6028 {
6029 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
6030 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
6031 {
6032 D3DSURFACE_DESC SrcDesc;
6033 HRESULT hr = pSrcSurfIf->GetDesc(&SrcDesc);
6034 Assert(hr == S_OK);
6035 if (hr == S_OK)
6036 {
6037 D3DSURFACE_DESC DstDesc;
6038 hr = pDstSurfIf->GetDesc(&DstDesc);
6039 Assert(hr == S_OK);
6040 if (hr == S_OK)
6041 {
6042 if (SrcDesc.Width == DstDesc.Width
6043 && SrcDesc.Height == DstDesc.Height)
6044 {
6045 bDo = true;
6046 }
6047 }
6048 }
6049 }
6050 }
6051 }
6052
6053 if (bDo)
6054 {
6055 vboxVDbgDumpSurfData((pDevice, "Blt-pre Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
6056 vboxVDbgDumpSurfData((pDevice, "Blt-pre Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
6057 }
6058#endif
6059 /* we support only Point & Linear, we ignore [Begin|Continue|End]PresentToDwm */
6060 Assert((pData->Flags.Value & (~(0x00000100 | 0x00000200 | 0x00000400 | 0x00000001 | 0x00000002))) == 0);
6061 hr = pDevice9If->StretchRect(pSrcSurfIf,
6062 &pData->SrcRect,
6063 pDstSurfIf,
6064 &pData->DstRect,
6065 vboxDDI2D3DBltFlags(pData->Flags));
6066 Assert(hr == S_OK);
6067
6068#ifdef DEBUG_misha
6069 if (bDo)
6070 {
6071 vboxVDbgDumpSurfData((pDevice, "Blt-post Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
6072 vboxVDbgDumpSurfData((pDevice, "Blt-post Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
6073 }
6074#endif
6075 pSrcSurfIf->Release();
6076 }
6077 } while (0);
6078
6079 pDstSurfIf->Release();
6080 }
6081
6082 if (hr != S_OK)
6083 {
6084 /* todo: fallback to memcpy or whatever ? */
6085 Assert(0);
6086 }
6087
6088
6089#if 0
6090 if ((use pAlloc->enmD3DIfType instead!!! pDstRc->RcDesc.fFlags.Texture || pDstRc->RcDesc.fFlags.Value == 0)
6091 && (pSrcRc->RcDesc.fFlags.Texture || pSrcRc->RcDesc.fFlags.Value == 0))
6092 {
6093 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcAlloc->pD3DIf;
6094 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstAlloc->pD3DIf;
6095 Assert(pD3DIfSrcTex);
6096 Assert(pD3DIfDstTex);
6097
6098 if (pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat)
6099 {
6100 if (pSrcRc->aAllocations[0].SurfDesc.width == pDstRc->aAllocations[0].SurfDesc.width
6101 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
6102 && pData->DstRect.left == 0 && pData->DstRect.top == 0
6103 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
6104 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
6105 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height
6106 && pData->DstRect.right - pData->DstRect.left == pDstRc->aAllocations[0].SurfDesc.width
6107 && pData->DstRect.bottom - pData->DstRect.top == pDstRc->aAllocations[0].SurfDesc.height
6108 )
6109 {
6110 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
6111 Assert(hr == S_OK);
6112 }
6113 else if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
6114 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
6115 {
6116 Assert(pDstAlloc->SurfDesc.bpp);
6117 Assert(pSrcAlloc->SurfDesc.bpp);
6118 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
6119 D3DLOCKED_RECT DstRect, SrcRect;
6120 Assert(!pSrcAlloc->LockInfo.cLocks);
6121 Assert(!pDstAlloc->LockInfo.cLocks);
6122 hr = pD3DIfDstTex->LockRect(pData->DstSubResourceIndex, &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
6123 Assert(hr == S_OK);
6124 if (hr == S_OK)
6125 {
6126 hr = pD3DIfSrcTex->LockRect(pData->SrcSubResourceIndex, &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
6127 Assert(hr == S_OK);
6128 if (hr == S_OK)
6129 {
6130 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
6131 &pData->DstRect, &pData->SrcRect,
6132 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
6133 Assert(hr == S_OK);
6134
6135 pD3DIfSrcTex->UnlockRect(pData->SrcSubResourceIndex);
6136 }
6137 pD3DIfDstTex->UnlockRect(pData->DstSubResourceIndex);
6138 }
6139 }
6140 else
6141 {
6142
6143 Assert(0);
6144 /* @todo: impl */
6145 }
6146 }
6147 else
6148 {
6149 Assert(0);
6150 /* @todo: impl */
6151 }
6152 }
6153 else
6154 {
6155 if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
6156 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
6157 {
6158 Assert(pDstAlloc->SurfDesc.bpp);
6159 Assert(pSrcAlloc->SurfDesc.bpp);
6160 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
6161
6162 D3DLOCKED_RECT DstRect, SrcRect;
6163 hr = vboxWddmLockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags,
6164 &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
6165 Assert(hr == S_OK);
6166 if (hr == S_OK)
6167 {
6168 hr = vboxWddmLockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags,
6169 &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
6170 Assert(hr == S_OK);
6171 if (hr == S_OK)
6172 {
6173 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
6174 &pData->DstRect, &pData->SrcRect,
6175 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
6176 Assert(hr == S_OK);
6177
6178 HRESULT tmpHr = vboxWddmUnlockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags);
6179 Assert(tmpHr == S_OK);
6180 }
6181 HRESULT tmpHr = vboxWddmUnlockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags);
6182 Assert(tmpHr == S_OK);
6183 }
6184 }
6185 else
6186 {
6187 Assert(0);
6188 /* @todo: impl */
6189 }
6190 }
6191#endif
6192
6193 if (pDstRc->RcDesc.fFlags.SharedResource)
6194 {
6195 PVBOXWDDMDISP_ALLOCATION pAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
6196 EnterCriticalSection(&pDevice->DirtyAllocListLock);
6197 if (!pAlloc->DirtyAllocListEntry.pNext)
6198 RTListAppend(&pDevice->DirtyAllocList, &pAlloc->DirtyAllocListEntry);
6199 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
6200 }
6201
6202 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6203 return hr;
6204}
6205static HRESULT APIENTRY vboxWddmDDevColorFill(HANDLE hDevice, CONST D3DDDIARG_COLORFILL* pData)
6206{
6207 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6208 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6209 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6210 Assert(pDevice);
6211 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6212 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
6213 Assert(pRc);
6214 IDirect3DSurface9 *pSurfIf = NULL;
6215 HRESULT hr = vboxWddmSurfGet(pRc, pData->SubResourceIndex, &pSurfIf);
6216 Assert(hr == S_OK);
6217 if (hr == S_OK)
6218 {
6219 Assert(pSurfIf);
6220 hr = pDevice9If->ColorFill(pSurfIf, &pData->DstRect, pData->Color);
6221 Assert(hr == S_OK);
6222 /* @todo: check what need to do when PresentToDwm flag is set */
6223 Assert(pData->Flags.Value == 0);
6224
6225 pSurfIf->Release();
6226 }
6227 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6228 return hr;
6229}
6230static HRESULT APIENTRY vboxWddmDDevDepthFill(HANDLE hDevice, CONST D3DDDIARG_DEPTHFILL* pData)
6231{
6232 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6233 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6234 Assert(0);
6235 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6236 return E_FAIL;
6237}
6238static HRESULT APIENTRY vboxWddmDDevCreateQuery(HANDLE hDevice, D3DDDIARG_CREATEQUERY* pData)
6239{
6240 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6241 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6242 HRESULT hr = S_OK;
6243 if (pData->QueryType == D3DDDIQUERYTYPE_EVENT)
6244 {
6245 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)RTMemAllocZ(sizeof (VBOXWDDMDISP_QUERY));
6246 Assert(pQuery);
6247 if (pQuery)
6248 {
6249 pQuery->enmType = pData->QueryType;
6250 pData->hQuery = pQuery;
6251 }
6252 else
6253 {
6254 hr = E_OUTOFMEMORY;
6255 }
6256 }
6257 else
6258 {
6259 Assert(0);
6260 hr = E_FAIL;
6261 }
6262 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6263 return hr;
6264}
6265static HRESULT APIENTRY vboxWddmDDevDestroyQuery(HANDLE hDevice, HANDLE hQuery)
6266{
6267 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6268 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6269 HRESULT hr = S_OK;
6270 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)hQuery;
6271 Assert(pQuery);
6272 RTMemFree(pQuery);
6273 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6274 return hr;
6275}
6276static HRESULT APIENTRY vboxWddmDDevIssueQuery(HANDLE hDevice, CONST D3DDDIARG_ISSUEQUERY* pData)
6277{
6278 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6279 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6280 HRESULT hr = S_OK;
6281 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
6282 Assert(pQuery);
6283 pQuery->fQueryState.Value |= pData->Flags.Value;
6284 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6285 return hr;
6286}
6287static HRESULT APIENTRY vboxWddmDDevGetQueryData(HANDLE hDevice, CONST D3DDDIARG_GETQUERYDATA* pData)
6288{
6289 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6290 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6291 HRESULT hr = S_OK;
6292 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
6293 Assert(pQuery);
6294 switch (pQuery->enmType)
6295 {
6296 case D3DDDIQUERYTYPE_EVENT:
6297 Assert(0);
6298 pQuery->data.bData = TRUE;
6299 Assert(pData->pData);
6300 *((BOOL*)pData->pData) = TRUE;
6301 break;
6302 default:
6303 Assert(0);
6304 hr = E_FAIL;
6305 break;
6306 }
6307 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6308 return hr;
6309}
6310static HRESULT APIENTRY vboxWddmDDevSetRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETRENDERTARGET* pData)
6311{
6312 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6313 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6314 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6315 Assert(pDevice);
6316 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6317 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget;
6318 Assert(pRc);
6319 Assert(pData->SubResourceIndex < pRc->cAllocations);
6320 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
6321 HRESULT hr = vboxWddmRenderTargetSet(pDevice, pData->RenderTargetIndex, pAlloc, FALSE);
6322 Assert(hr == S_OK);
6323 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6324 return hr;
6325}
6326static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDIARG_SETDEPTHSTENCIL* pData)
6327{
6328 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6329 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6330 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6331 Assert(pDevice);
6332 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6333 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hZBuffer;
6334 IDirect3DSurface9 *pD3D9Surf = NULL;
6335 if (pRc)
6336 {
6337 Assert(pRc->cAllocations == 1);
6338 pD3D9Surf = (IDirect3DSurface9*)pRc->aAllocations[0].pD3DIf;
6339 Assert(pD3D9Surf);
6340 }
6341 HRESULT hr = pDevice9If->SetDepthStencilSurface(pD3D9Surf);
6342 Assert(hr == S_OK);
6343 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6344 return hr;
6345}
6346static HRESULT APIENTRY vboxWddmDDevGenerateMipSubLevels(HANDLE hDevice, CONST D3DDDIARG_GENERATEMIPSUBLEVELS* pData)
6347{
6348 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6349 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6350 Assert(0);
6351 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6352 return E_FAIL;
6353}
6354static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTI* pData, CONST INT* pRegisters)
6355{
6356 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6357 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6358 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6359 Assert(pDevice);
6360 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6361 HRESULT hr = pDevice9If->SetPixelShaderConstantI(pData->Register, pRegisters, pData->Count);
6362 Assert(hr == S_OK);
6363 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6364 return hr;
6365}
6366static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTB* pData, CONST BOOL* pRegisters)
6367{
6368 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6369 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6370 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6371 Assert(pDevice);
6372 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6373 HRESULT hr = pDevice9If->SetPixelShaderConstantB(pData->Register, pRegisters, pData->Count);
6374 Assert(hr == S_OK);
6375 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6376 return hr;
6377}
6378static HRESULT APIENTRY vboxWddmDDevCreatePixelShader(HANDLE hDevice, D3DDDIARG_CREATEPIXELSHADER* pData, CONST UINT* pCode)
6379{
6380 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6381 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6382 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6383 Assert(pDevice);
6384 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6385 IDirect3DPixelShader9 *pShader;
6386 Assert(*((UINT*)((uint8_t*)pCode + pData->CodeSize-4)) == 0x0000FFFF /* end token */);
6387 HRESULT hr = pDevice9If->CreatePixelShader((const DWORD *)pCode, &pShader);
6388 Assert(hr == S_OK);
6389 if (hr == S_OK)
6390 {
6391 Assert(pShader);
6392 pData->ShaderHandle = pShader;
6393 }
6394 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6395 return hr;
6396}
6397static HRESULT APIENTRY vboxWddmDDevDeletePixelShader(HANDLE hDevice, HANDLE hShaderHandle)
6398{
6399 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6400 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6401 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6402 Assert(pDevice);
6403 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
6404 HRESULT hr = S_OK;
6405 pShader->Release();
6406 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6407 return hr;
6408}
6409static HRESULT APIENTRY vboxWddmDDevCreateDecodeDevice(HANDLE hDevice, D3DDDIARG_CREATEDECODEDEVICE* pData)
6410{
6411 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6412 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6413 Assert(0);
6414 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6415 return E_FAIL;
6416}
6417static HRESULT APIENTRY vboxWddmDDevDestroyDecodeDevice(HANDLE hDevice, HANDLE hDecodeDevice)
6418{
6419 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6420 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6421 Assert(0);
6422 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6423 return E_FAIL;
6424}
6425static HRESULT APIENTRY vboxWddmDDevSetDecodeRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETDECODERENDERTARGET* pData)
6426{
6427 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6428 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6429 Assert(0);
6430 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6431 return E_FAIL;
6432}
6433static HRESULT APIENTRY vboxWddmDDevDecodeBeginFrame(HANDLE hDevice, D3DDDIARG_DECODEBEGINFRAME* pData)
6434{
6435 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6436 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6437 Assert(0);
6438 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6439 return E_FAIL;
6440}
6441static HRESULT APIENTRY vboxWddmDDevDecodeEndFrame(HANDLE hDevice, D3DDDIARG_DECODEENDFRAME* pData)
6442{
6443 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6444 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6445 Assert(0);
6446 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6447 return E_FAIL;
6448}
6449static HRESULT APIENTRY vboxWddmDDevDecodeExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXECUTE* pData)
6450{
6451 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6452 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6453 Assert(0);
6454 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6455 return E_FAIL;
6456}
6457static HRESULT APIENTRY vboxWddmDDevDecodeExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXTENSIONEXECUTE* pData)
6458{
6459 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6460 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6461 Assert(0);
6462 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6463 return E_FAIL;
6464}
6465static HRESULT APIENTRY vboxWddmDDevCreateVideoProcessDevice(HANDLE hDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE* pData)
6466{
6467 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6468 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6469 Assert(0);
6470 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6471 return E_FAIL;
6472}
6473static HRESULT APIENTRY vboxWddmDDevDestroyVideoProcessDevice(HANDLE hDevice, HANDLE hVideoProcessor)
6474{
6475 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6476 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6477 Assert(0);
6478 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6479 return E_FAIL;
6480}
6481static HRESULT APIENTRY vboxWddmDDevVideoProcessBeginFrame(HANDLE hDevice, HANDLE hVideoProcess)
6482{
6483 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6484 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6485 Assert(0);
6486 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6487 return E_FAIL;
6488}
6489static HRESULT APIENTRY vboxWddmDDevVideoProcessEndFrame(HANDLE hDevice, D3DDDIARG_VIDEOPROCESSENDFRAME* pData)
6490{
6491 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6492 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6493 Assert(0);
6494 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6495 return E_FAIL;
6496}
6497static HRESULT APIENTRY vboxWddmDDevSetVideoProcessRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETVIDEOPROCESSRENDERTARGET* pData)
6498{
6499 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6500 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6501 Assert(0);
6502 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6503 return E_FAIL;
6504}
6505static HRESULT APIENTRY vboxWddmDDevVideoProcessBlt(HANDLE hDevice, CONST D3DDDIARG_VIDEOPROCESSBLT* pData)
6506{
6507 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6508 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6509 Assert(0);
6510 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6511 return E_FAIL;
6512}
6513static HRESULT APIENTRY vboxWddmDDevCreateExtensionDevice(HANDLE hDevice, D3DDDIARG_CREATEEXTENSIONDEVICE* pData)
6514{
6515 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6516 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6517 Assert(0);
6518 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6519 return E_FAIL;
6520}
6521static HRESULT APIENTRY vboxWddmDDevDestroyExtensionDevice(HANDLE hDevice, HANDLE hExtension)
6522{
6523 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6524 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6525 Assert(0);
6526 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6527 return E_FAIL;
6528}
6529static HRESULT APIENTRY vboxWddmDDevExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_EXTENSIONEXECUTE* pData)
6530{
6531 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6532 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6533 Assert(0);
6534 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6535 return E_FAIL;
6536}
6537static HRESULT APIENTRY vboxWddmDDevDestroyDevice(IN HANDLE hDevice)
6538{
6539 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6540 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6541
6542 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6543 VBOXDISPPROFILE_DDI_DUMPRESET(pDevice);
6544 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
6545 if (VBOXDISPMODE_IS_3D(pAdapter))
6546 {
6547// Assert(!pDevice->cScreens);
6548 vboxWddmSwapchainDestroyAll(pDevice);
6549 pDevice->pDevice9If->Release();
6550 }
6551
6552 HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
6553 Assert(hr == S_OK);
6554 if (hr == S_OK)
6555 RTMemFree(pDevice);
6556 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6557 return hr;
6558}
6559
6560AssertCompile(sizeof (RECT) == sizeof (D3DDDIRECT));
6561AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DDDIRECT, left));
6562AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DDDIRECT, right));
6563AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DDDIRECT, top));
6564AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DDDIRECT, bottom));
6565AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DDDIRECT, left));
6566AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DDDIRECT, right));
6567AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DDDIRECT, top));
6568AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DDDIRECT, bottom));
6569
6570static HRESULT APIENTRY vboxWddmDDevCreateOverlay(HANDLE hDevice, D3DDDIARG_CREATEOVERLAY* pData)
6571{
6572 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6573 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6574 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6575 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
6576 Assert(pRc);
6577 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
6578 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
6579 HRESULT hr = S_OK;
6580 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)RTMemAllocZ(sizeof (VBOXWDDMDISP_OVERLAY));
6581 Assert(pOverlay);
6582 if (pOverlay)
6583 {
6584 VBOXWDDM_OVERLAY_INFO OurInfo;
6585 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
6586 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
6587 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
6588 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
6589 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
6590 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
6591 Assert(!pAlloc->LockInfo.cLocks);
6592 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
6593 D3DDDICB_CREATEOVERLAY OverInfo;
6594 OverInfo.VidPnSourceId = pData->VidPnSourceId;
6595 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
6596 Assert(pAlloc->hAllocation);
6597 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
6598 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
6599 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
6600 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
6601 OverInfo.hKernelOverlay = NULL; /* <-- out */
6602#ifndef VBOXWDDMOVERLAY_TEST
6603 hr = pDevice->RtCallbacks.pfnCreateOverlayCb(pDevice->hDevice, &OverInfo);
6604 Assert(hr == S_OK);
6605 if (hr == S_OK)
6606 {
6607 Assert(OverInfo.hKernelOverlay);
6608 pOverlay->hOverlay = OverInfo.hKernelOverlay;
6609 pOverlay->VidPnSourceId = pData->VidPnSourceId;
6610
6611 Assert(!pAlloc->LockInfo.cLocks);
6612 if (!pAlloc->LockInfo.cLocks)
6613 {
6614 /* we have reported the dirty rect, may clear it if no locks are pending currently */
6615 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
6616 }
6617
6618 pData->hOverlay = pOverlay;
6619 }
6620 else
6621 {
6622 RTMemFree(pOverlay);
6623 }
6624#else
6625 pData->hOverlay = pOverlay;
6626#endif
6627 }
6628 else
6629 hr = E_OUTOFMEMORY;
6630
6631 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6632 return hr;
6633}
6634static HRESULT APIENTRY vboxWddmDDevUpdateOverlay(HANDLE hDevice, CONST D3DDDIARG_UPDATEOVERLAY* pData)
6635{
6636 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6637 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6638 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6639 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
6640 Assert(pRc);
6641 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
6642 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
6643 HRESULT hr = S_OK;
6644 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
6645 VBOXWDDM_OVERLAY_INFO OurInfo;
6646 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
6647 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
6648 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
6649 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
6650 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
6651 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
6652 Assert(!pAlloc->LockInfo.cLocks);
6653 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
6654 D3DDDICB_UPDATEOVERLAY OverInfo;
6655 OverInfo.hKernelOverlay = pOverlay->hOverlay;
6656 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
6657 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
6658 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
6659 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
6660 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
6661#ifndef VBOXWDDMOVERLAY_TEST
6662 hr = pDevice->RtCallbacks.pfnUpdateOverlayCb(pDevice->hDevice, &OverInfo);
6663 Assert(hr == S_OK);
6664 if (hr == S_OK)
6665#endif
6666 {
6667 Assert(!pAlloc->LockInfo.cLocks);
6668 if (!pAlloc->LockInfo.cLocks)
6669 {
6670 /* we have reported the dirty rect, may clear it if no locks are pending currently */
6671 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
6672 }
6673 }
6674
6675 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6676 return hr;
6677}
6678static HRESULT APIENTRY vboxWddmDDevFlipOverlay(HANDLE hDevice, CONST D3DDDIARG_FLIPOVERLAY* pData)
6679{
6680 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6681 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6682 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6683 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSource;
6684 Assert(pRc);
6685 Assert(pRc->cAllocations > pData->SourceIndex);
6686 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SourceIndex];
6687 HRESULT hr = S_OK;
6688 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
6689 VBOXWDDM_OVERLAYFLIP_INFO OurInfo;
6690 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
6691 Assert(!pAlloc->LockInfo.cLocks);
6692 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
6693 D3DDDICB_FLIPOVERLAY OverInfo;
6694 OverInfo.hKernelOverlay = pOverlay->hOverlay;
6695 OverInfo.hSource = pAlloc->hAllocation;
6696 OverInfo.pPrivateDriverData = &OurInfo;
6697 OverInfo.PrivateDriverDataSize = sizeof (OurInfo);
6698#ifndef VBOXWDDMOVERLAY_TEST
6699 hr = pDevice->RtCallbacks.pfnFlipOverlayCb(pDevice->hDevice, &OverInfo);
6700 Assert(hr == S_OK);
6701 if (hr == S_OK)
6702#endif
6703 {
6704 Assert(!pAlloc->LockInfo.cLocks);
6705 if (!pAlloc->LockInfo.cLocks)
6706 {
6707 /* we have reported the dirty rect, may clear it if no locks are pending currently */
6708 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
6709 }
6710 }
6711
6712 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6713 return hr;
6714}
6715static HRESULT APIENTRY vboxWddmDDevGetOverlayColorControls(HANDLE hDevice, D3DDDIARG_GETOVERLAYCOLORCONTROLS* pData)
6716{
6717 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6718 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6719 Assert(0);
6720 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6721 return E_FAIL;
6722}
6723static HRESULT APIENTRY vboxWddmDDevSetOverlayColorControls(HANDLE hDevice, CONST D3DDDIARG_SETOVERLAYCOLORCONTROLS* pData)
6724{
6725 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6726 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6727 Assert(0);
6728 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6729 return E_FAIL;
6730}
6731static HRESULT APIENTRY vboxWddmDDevDestroyOverlay(HANDLE hDevice, CONST D3DDDIARG_DESTROYOVERLAY* pData)
6732{
6733 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6734 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6735 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6736 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
6737 D3DDDICB_DESTROYOVERLAY OverInfo;
6738 OverInfo.hKernelOverlay = pOverlay->hOverlay;
6739#ifndef VBOXWDDMOVERLAY_TEST
6740 HRESULT hr = pDevice->RtCallbacks.pfnDestroyOverlayCb(pDevice->hDevice, &OverInfo);
6741 Assert(hr == S_OK);
6742 if (hr == S_OK)
6743#else
6744 HRESULT hr = S_OK;
6745#endif
6746 {
6747 RTMemFree(pOverlay);
6748 }
6749
6750 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6751 return hr;
6752}
6753static HRESULT APIENTRY vboxWddmDDevQueryResourceResidency(HANDLE hDevice, CONST D3DDDIARG_QUERYRESOURCERESIDENCY* pData)
6754{
6755 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6756 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6757 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6758 Assert(0);
6759 HRESULT hr = S_OK;
6760#if 0
6761 for (UINT i = 0; i < pData->NumResources; ++i)
6762 {
6763 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->pHandleList[i];
6764 Assert(pRc->pDevice == pDevice);
6765 if (pRc->hKMResource)
6766 {
6767
6768 }
6769 }
6770#endif
6771 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6772 return hr;
6773}
6774
6775static HRESULT vboxAllocationInit(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DDDI_OPENALLOCATIONINFO *pInfo)
6776{
6777 HRESULT hr = S_OK;
6778 pAlloc->hAllocation = pInfo->hAllocation;
6779 Assert(pInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
6780 Assert(pInfo->pPrivateDriverData);
6781 if (pInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
6782 {
6783 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pInfo->pPrivateDriverData;
6784 pAlloc->enmType = pAllocInfo->enmType;
6785 Assert(pAllocInfo->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
6786 || VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE
6787 || VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE);
6788 pAlloc->pvMem = NULL;
6789 pAlloc->SurfDesc = pAllocInfo->SurfDesc;
6790 }
6791 else
6792 {
6793 vboxVDbgPrintR((__FUNCTION__": ERROR: PrivateDriverDataSize(%d) < (%d)\n", pInfo->PrivateDriverDataSize, sizeof (VBOXWDDM_ALLOCINFO)));
6794 hr = E_INVALIDARG;
6795 }
6796 return hr;
6797}
6798
6799static HRESULT APIENTRY vboxWddmDDevOpenResource(HANDLE hDevice, D3DDDIARG_OPENRESOURCE* pData)
6800{
6801 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6802 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6803 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6804 HRESULT hr = S_OK;
6805
6806 Assert(pDevice);
6807 Assert(pData->NumAllocations);
6808 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pData->NumAllocations);
6809 Assert(pRc);
6810 if (pRc)
6811 {
6812 pRc->hResource = pData->hResource;
6813 pRc->hKMResource = pData->hKMResource;
6814 pRc->pDevice = pDevice;
6815 pRc->RcDesc.enmRotation = pData->Rotation;
6816 pRc->fFlags = VBOXWDDM_RESOURCE_F_OPENNED;
6817 if (!pData->pPrivateDriverData || !pData->PrivateDriverDataSize)
6818 {
6819 /* this is a "standard" allocation resource */
6820
6821 /* both should be actually zero */
6822 Assert(!pData->pPrivateDriverData && !pData->PrivateDriverDataSize);
6823 pRc->RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
6824 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
6825 pRc->RcDesc.MultisampleQuality = 0;
6826 pRc->RcDesc.MipLevels = 0;
6827 pRc->RcDesc.Fvf;
6828 pRc->RcDesc.fFlags.Value = 0;
6829
6830 Assert(pData->NumAllocations);
6831 D3DDDI_OPENALLOCATIONINFO* pDdiAllocInfo = &pData->pOpenAllocationInfo[0];
6832 Assert(pDdiAllocInfo->pPrivateDriverData);
6833 Assert(pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO));
6834 if (pDdiAllocInfo->pPrivateDriverData && pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
6835 {
6836 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocInfo->pPrivateDriverData;
6837 switch(pAllocInfo->enmType)
6838 {
6839 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
6840 pRc->RcDesc.fFlags.Primary = 1;
6841 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
6842 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
6843 pRc->RcDesc.enmFormat = pAllocInfo->SurfDesc.format;
6844 pRc->RcDesc.VidPnSourceId = pAllocInfo->SurfDesc.VidPnSourceId;
6845 pRc->RcDesc.RefreshRate = pAllocInfo->SurfDesc.RefreshRate;
6846 break;
6847 default:
6848 Assert(0);
6849 hr = E_INVALIDARG;
6850 }
6851 }
6852 else
6853 hr = E_INVALIDARG;
6854 }
6855 else
6856 {
6857 /* this is a "generic" resource whose creation is initiaded by the UMD */
6858 Assert(pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
6859 if (pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO))
6860 {
6861 VBOXWDDM_RCINFO *pRcInfo = (VBOXWDDM_RCINFO*)pData->pPrivateDriverData;
6862 Assert(pRcInfo->fFlags == VBOXWDDM_RESOURCE_F_TYPE_GENERIC);
6863 Assert(pRcInfo->cAllocInfos == pData->NumAllocations);
6864 pRc->fFlags = pRcInfo->fFlags | VBOXWDDM_RESOURCE_F_OPENNED;
6865 pRc->RcDesc = pRcInfo->RcDesc;
6866 pRc->cAllocations = pData->NumAllocations;
6867
6868 for (UINT i = 0; i < pData->NumAllocations; ++i)
6869 {
6870 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
6871 D3DDDI_OPENALLOCATIONINFO* pOAI = pData->pOpenAllocationInfo;
6872 Assert(pOAI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
6873 if (pOAI->PrivateDriverDataSize != sizeof (VBOXWDDM_ALLOCINFO))
6874 {
6875 hr = E_INVALIDARG;
6876 break;
6877 }
6878 Assert(pOAI->pPrivateDriverData);
6879 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pOAI->pPrivateDriverData;
6880 pAllocation->hAllocation = pOAI->hAllocation;
6881 pAllocation->enmType = pAllocInfo->enmType;
6882 pAllocation->hSharedHandle = pAllocInfo->hSharedHandle;
6883 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
6884 Assert(pAllocation->hSharedHandle);
6885 }
6886
6887 Assert(pRc->RcDesc.fFlags.SharedResource);
6888 if (pRc->RcDesc.fFlags.Texture)
6889 {
6890 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6891 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
6892 IDirect3DTexture9 *pD3DIfTex;
6893 HANDLE hSharedHandle = pAllocation->hSharedHandle;
6894 Assert(pAllocation->hSharedHandle);
6895
6896 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
6897 pAllocation->SurfDesc.width,
6898 pAllocation->SurfDesc.height,
6899 pRc->cAllocations,
6900 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
6901 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
6902 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
6903 &pD3DIfTex,
6904 &hSharedHandle,
6905 NULL);
6906 Assert(hr == S_OK);
6907 if (hr == S_OK)
6908 {
6909 Assert(pD3DIfTex);
6910 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
6911 pAllocation->pD3DIf = pD3DIfTex;
6912 Assert(pAllocation->hSharedHandle == hSharedHandle);
6913 Assert(pAllocation->hSharedHandle);
6914 }
6915 }
6916 else
6917 {
6918 /* impl */
6919 Assert(0);
6920 }
6921 }
6922 else
6923 hr = E_INVALIDARG;
6924 }
6925
6926 if (hr == S_OK)
6927 {
6928 for (UINT i = 0; i < pData->NumAllocations; ++i)
6929 {
6930 hr = vboxAllocationInit(&pRc->aAllocations[i], &pData->pOpenAllocationInfo[i]);
6931 Assert(hr == S_OK);
6932 if (hr != S_OK)
6933 break;
6934 }
6935 }
6936
6937 if (hr == S_OK)
6938 pData->hResource = pRc;
6939 else
6940 vboxResourceFree(pRc);
6941 }
6942 else
6943 {
6944 vboxVDbgPrintR((__FUNCTION__": vboxResourceAlloc failed for hDevice(0x%p), NumAllocations(%d)\n", hDevice, pData->NumAllocations));
6945 hr = E_OUTOFMEMORY;
6946 }
6947
6948 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6949 return hr;
6950}
6951static HRESULT APIENTRY vboxWddmDDevGetCaptureAllocationHandle(HANDLE hDevice, D3DDDIARG_GETCAPTUREALLOCATIONHANDLE* pData)
6952{
6953 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6954 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6955 Assert(0);
6956 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6957 return E_FAIL;
6958}
6959
6960static HRESULT APIENTRY vboxWddmDDevCaptureToSysMem(HANDLE hDevice, CONST D3DDDIARG_CAPTURETOSYSMEM* pData)
6961{
6962 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6963 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6964 Assert(0);
6965 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6966 return E_FAIL;
6967}
6968
6969static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIARG_CREATEDEVICE* pCreateData)
6970{
6971 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6972 HRESULT hr = S_OK;
6973 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), Interface(%d), Version(%d)\n", hAdapter, pCreateData->Interface, pCreateData->Version));
6974
6975// Assert(0);
6976 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
6977
6978 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_DEVICE, apRTs[pAdapter->cMaxSimRTs]));
6979 if (pDevice)
6980 {
6981 pDevice->cRTs = pAdapter->cMaxSimRTs;
6982 pDevice->hDevice = pCreateData->hDevice;
6983 pDevice->pAdapter = pAdapter;
6984 pDevice->u32IfVersion = pCreateData->Interface;
6985 pDevice->uRtVersion = pCreateData->Version;
6986 pDevice->RtCallbacks = *pCreateData->pCallbacks;
6987 pDevice->pvCmdBuffer = pCreateData->pCommandBuffer;
6988 pDevice->cbCmdBuffer = pCreateData->CommandBufferSize;
6989 pDevice->fFlags = pCreateData->Flags;
6990 /* Set Viewport to some default values */
6991 pDevice->ViewPort.X = 0;
6992 pDevice->ViewPort.Y = 0;
6993 pDevice->ViewPort.Width = 1;
6994 pDevice->ViewPort.Height = 1;
6995 pDevice->ViewPort.MinZ = 0.;
6996 pDevice->ViewPort.MaxZ = 1.;
6997
6998 InitializeCriticalSection(&pDevice->DirtyAllocListLock);
6999 RTListInit(&pDevice->DirtyAllocList);
7000
7001 Assert(!pCreateData->AllocationListSize);
7002 Assert(!pCreateData->PatchLocationListSize);
7003
7004 pCreateData->hDevice = pDevice;
7005
7006 pCreateData->pDeviceFuncs->pfnSetRenderState = vboxWddmDDevSetRenderState;
7007 pCreateData->pDeviceFuncs->pfnUpdateWInfo = vboxWddmDDevUpdateWInfo;
7008 pCreateData->pDeviceFuncs->pfnValidateDevice = vboxWddmDDevValidateDevice;
7009 pCreateData->pDeviceFuncs->pfnSetTextureStageState = vboxWddmDDevSetTextureStageState;
7010 pCreateData->pDeviceFuncs->pfnSetTexture = vboxWddmDDevSetTexture;
7011 pCreateData->pDeviceFuncs->pfnSetPixelShader = vboxWddmDDevSetPixelShader;
7012 pCreateData->pDeviceFuncs->pfnSetPixelShaderConst = vboxWddmDDevSetPixelShaderConst;
7013 pCreateData->pDeviceFuncs->pfnSetStreamSourceUm = vboxWddmDDevSetStreamSourceUm;
7014 pCreateData->pDeviceFuncs->pfnSetIndices = vboxWddmDDevSetIndices;
7015 pCreateData->pDeviceFuncs->pfnSetIndicesUm = vboxWddmDDevSetIndicesUm;
7016 pCreateData->pDeviceFuncs->pfnDrawPrimitive = vboxWddmDDevDrawPrimitive;
7017 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive = vboxWddmDDevDrawIndexedPrimitive;
7018 pCreateData->pDeviceFuncs->pfnDrawRectPatch = vboxWddmDDevDrawRectPatch;
7019 pCreateData->pDeviceFuncs->pfnDrawTriPatch = vboxWddmDDevDrawTriPatch;
7020 pCreateData->pDeviceFuncs->pfnDrawPrimitive2 = vboxWddmDDevDrawPrimitive2;
7021 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive2 = vboxWddmDDevDrawIndexedPrimitive2;
7022 pCreateData->pDeviceFuncs->pfnVolBlt = vboxWddmDDevVolBlt;
7023 pCreateData->pDeviceFuncs->pfnBufBlt = vboxWddmDDevBufBlt;
7024 pCreateData->pDeviceFuncs->pfnTexBlt = vboxWddmDDevTexBlt;
7025 pCreateData->pDeviceFuncs->pfnStateSet = vboxWddmDDevStateSet;
7026 pCreateData->pDeviceFuncs->pfnSetPriority = vboxWddmDDevSetPriority;
7027 pCreateData->pDeviceFuncs->pfnClear = vboxWddmDDevClear;
7028 pCreateData->pDeviceFuncs->pfnUpdatePalette = vboxWddmDDevUpdatePalette;
7029 pCreateData->pDeviceFuncs->pfnSetPalette = vboxWddmDDevSetPalette;
7030 pCreateData->pDeviceFuncs->pfnSetVertexShaderConst = vboxWddmDDevSetVertexShaderConst;
7031 pCreateData->pDeviceFuncs->pfnMultiplyTransform = vboxWddmDDevMultiplyTransform;
7032 pCreateData->pDeviceFuncs->pfnSetTransform = vboxWddmDDevSetTransform;
7033 pCreateData->pDeviceFuncs->pfnSetViewport = vboxWddmDDevSetViewport;
7034 pCreateData->pDeviceFuncs->pfnSetZRange = vboxWddmDDevSetZRange;
7035 pCreateData->pDeviceFuncs->pfnSetMaterial = vboxWddmDDevSetMaterial;
7036 pCreateData->pDeviceFuncs->pfnSetLight = vboxWddmDDevSetLight;
7037 pCreateData->pDeviceFuncs->pfnCreateLight = vboxWddmDDevCreateLight;
7038 pCreateData->pDeviceFuncs->pfnDestroyLight = vboxWddmDDevDestroyLight;
7039 pCreateData->pDeviceFuncs->pfnSetClipPlane = vboxWddmDDevSetClipPlane;
7040 pCreateData->pDeviceFuncs->pfnGetInfo = vboxWddmDDevGetInfo;
7041 pCreateData->pDeviceFuncs->pfnLock = vboxWddmDDevLock;
7042 pCreateData->pDeviceFuncs->pfnUnlock = vboxWddmDDevUnlock;
7043 pCreateData->pDeviceFuncs->pfnCreateResource = vboxWddmDDevCreateResource;
7044 pCreateData->pDeviceFuncs->pfnDestroyResource = vboxWddmDDevDestroyResource;
7045 pCreateData->pDeviceFuncs->pfnSetDisplayMode = vboxWddmDDevSetDisplayMode;
7046 pCreateData->pDeviceFuncs->pfnPresent = vboxWddmDDevPresent;
7047 pCreateData->pDeviceFuncs->pfnFlush = vboxWddmDDevFlush;
7048 pCreateData->pDeviceFuncs->pfnCreateVertexShaderFunc = vboxWddmDDevCreateVertexShaderFunc;
7049 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderFunc = vboxWddmDDevDeleteVertexShaderFunc;
7050 pCreateData->pDeviceFuncs->pfnSetVertexShaderFunc = vboxWddmDDevSetVertexShaderFunc;
7051 pCreateData->pDeviceFuncs->pfnCreateVertexShaderDecl = vboxWddmDDevCreateVertexShaderDecl;
7052 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderDecl = vboxWddmDDevDeleteVertexShaderDecl;
7053 pCreateData->pDeviceFuncs->pfnSetVertexShaderDecl = vboxWddmDDevSetVertexShaderDecl;
7054 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstI = vboxWddmDDevSetVertexShaderConstI;
7055 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstB = vboxWddmDDevSetVertexShaderConstB;
7056 pCreateData->pDeviceFuncs->pfnSetScissorRect = vboxWddmDDevSetScissorRect;
7057 pCreateData->pDeviceFuncs->pfnSetStreamSource = vboxWddmDDevSetStreamSource;
7058 pCreateData->pDeviceFuncs->pfnSetStreamSourceFreq = vboxWddmDDevSetStreamSourceFreq;
7059 pCreateData->pDeviceFuncs->pfnSetConvolutionKernelMono = vboxWddmDDevSetConvolutionKernelMono;
7060 pCreateData->pDeviceFuncs->pfnComposeRects = vboxWddmDDevComposeRects;
7061 pCreateData->pDeviceFuncs->pfnBlt = vboxWddmDDevBlt;
7062 pCreateData->pDeviceFuncs->pfnColorFill = vboxWddmDDevColorFill;
7063 pCreateData->pDeviceFuncs->pfnDepthFill = vboxWddmDDevDepthFill;
7064 pCreateData->pDeviceFuncs->pfnCreateQuery = vboxWddmDDevCreateQuery;
7065 pCreateData->pDeviceFuncs->pfnDestroyQuery = vboxWddmDDevDestroyQuery;
7066 pCreateData->pDeviceFuncs->pfnIssueQuery = vboxWddmDDevIssueQuery;
7067 pCreateData->pDeviceFuncs->pfnGetQueryData = vboxWddmDDevGetQueryData;
7068 pCreateData->pDeviceFuncs->pfnSetRenderTarget = vboxWddmDDevSetRenderTarget;
7069 pCreateData->pDeviceFuncs->pfnSetDepthStencil = vboxWddmDDevSetDepthStencil;
7070 pCreateData->pDeviceFuncs->pfnGenerateMipSubLevels = vboxWddmDDevGenerateMipSubLevels;
7071 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstI = vboxWddmDDevSetPixelShaderConstI;
7072 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstB = vboxWddmDDevSetPixelShaderConstB;
7073 pCreateData->pDeviceFuncs->pfnCreatePixelShader = vboxWddmDDevCreatePixelShader;
7074 pCreateData->pDeviceFuncs->pfnDeletePixelShader = vboxWddmDDevDeletePixelShader;
7075 pCreateData->pDeviceFuncs->pfnCreateDecodeDevice = vboxWddmDDevCreateDecodeDevice;
7076 pCreateData->pDeviceFuncs->pfnDestroyDecodeDevice = vboxWddmDDevDestroyDecodeDevice;
7077 pCreateData->pDeviceFuncs->pfnSetDecodeRenderTarget = vboxWddmDDevSetDecodeRenderTarget;
7078 pCreateData->pDeviceFuncs->pfnDecodeBeginFrame = vboxWddmDDevDecodeBeginFrame;
7079 pCreateData->pDeviceFuncs->pfnDecodeEndFrame = vboxWddmDDevDecodeEndFrame;
7080 pCreateData->pDeviceFuncs->pfnDecodeExecute = vboxWddmDDevDecodeExecute;
7081 pCreateData->pDeviceFuncs->pfnDecodeExtensionExecute = vboxWddmDDevDecodeExtensionExecute;
7082 pCreateData->pDeviceFuncs->pfnCreateVideoProcessDevice = vboxWddmDDevCreateVideoProcessDevice;
7083 pCreateData->pDeviceFuncs->pfnDestroyVideoProcessDevice = vboxWddmDDevDestroyVideoProcessDevice;
7084 pCreateData->pDeviceFuncs->pfnVideoProcessBeginFrame = vboxWddmDDevVideoProcessBeginFrame;
7085 pCreateData->pDeviceFuncs->pfnVideoProcessEndFrame = vboxWddmDDevVideoProcessEndFrame;
7086 pCreateData->pDeviceFuncs->pfnSetVideoProcessRenderTarget = vboxWddmDDevSetVideoProcessRenderTarget;
7087 pCreateData->pDeviceFuncs->pfnVideoProcessBlt = vboxWddmDDevVideoProcessBlt;
7088 pCreateData->pDeviceFuncs->pfnCreateExtensionDevice = vboxWddmDDevCreateExtensionDevice;
7089 pCreateData->pDeviceFuncs->pfnDestroyExtensionDevice = vboxWddmDDevDestroyExtensionDevice;
7090 pCreateData->pDeviceFuncs->pfnExtensionExecute = vboxWddmDDevExtensionExecute;
7091 pCreateData->pDeviceFuncs->pfnCreateOverlay = vboxWddmDDevCreateOverlay;
7092 pCreateData->pDeviceFuncs->pfnUpdateOverlay = vboxWddmDDevUpdateOverlay;
7093 pCreateData->pDeviceFuncs->pfnFlipOverlay = vboxWddmDDevFlipOverlay;
7094 pCreateData->pDeviceFuncs->pfnGetOverlayColorControls = vboxWddmDDevGetOverlayColorControls;
7095 pCreateData->pDeviceFuncs->pfnSetOverlayColorControls = vboxWddmDDevSetOverlayColorControls;
7096 pCreateData->pDeviceFuncs->pfnDestroyOverlay = vboxWddmDDevDestroyOverlay;
7097 pCreateData->pDeviceFuncs->pfnDestroyDevice = vboxWddmDDevDestroyDevice;
7098 pCreateData->pDeviceFuncs->pfnQueryResourceResidency = vboxWddmDDevQueryResourceResidency;
7099 pCreateData->pDeviceFuncs->pfnOpenResource = vboxWddmDDevOpenResource;
7100 pCreateData->pDeviceFuncs->pfnGetCaptureAllocationHandle = vboxWddmDDevGetCaptureAllocationHandle;
7101 pCreateData->pDeviceFuncs->pfnCaptureToSysMem = vboxWddmDDevCaptureToSysMem;
7102 pCreateData->pDeviceFuncs->pfnLockAsync = NULL; //vboxWddmDDevLockAsync;
7103 pCreateData->pDeviceFuncs->pfnUnlockAsync = NULL; //vboxWddmDDevUnlockAsync;
7104 pCreateData->pDeviceFuncs->pfnRename = NULL; //vboxWddmDDevRename;
7105
7106
7107 do
7108 {
7109 RTListInit(&pDevice->SwapchainList);
7110 Assert(!pCreateData->AllocationListSize
7111 && !pCreateData->PatchLocationListSize);
7112 if (!pCreateData->AllocationListSize
7113 && !pCreateData->PatchLocationListSize)
7114 {
7115 hr = vboxDispCmCtxCreate(pDevice, &pDevice->DefaultContext);
7116 Assert(hr == S_OK);
7117 if (hr == S_OK)
7118 {
7119#ifdef VBOXDISP_EARLYCREATEDEVICE
7120 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);
7121 Assert(pRc);
7122 if (pRc)
7123 {
7124 D3DPRESENT_PARAMETERS params;
7125 memset(&params, 0, sizeof (params));
7126// params.BackBufferWidth = 640;
7127// params.BackBufferHeight = 480;
7128 params.BackBufferWidth = 0x400;
7129 params.BackBufferHeight = 0x300;
7130 params.BackBufferFormat = D3DFMT_A8R8G8B8;
7131// params.BackBufferCount = 0;
7132 params.BackBufferCount = 1;
7133 params.MultiSampleType = D3DMULTISAMPLE_NONE;
7134 params.SwapEffect = D3DSWAPEFFECT_DISCARD;
7135 // params.hDeviceWindow = hWnd;
7136 /* @todo: it seems there should be a way to detect this correctly since
7137 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
7138 params.Windowed = TRUE;
7139 // params.EnableAutoDepthStencil = FALSE;
7140 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
7141 // params.Flags;
7142 // params.FullScreen_RefreshRateInHz;
7143 // params.FullScreen_PresentationInterval;
7144
7145 hr = vboxWddmD3DDeviceCreate(pDevice, 0, pRc, &params, TRUE /*BOOL bLockable*/);
7146 Assert(hr == S_OK);
7147 if (hr == S_OK)
7148 break;
7149 vboxResourceFree(pRc);
7150 }
7151 else
7152 {
7153 hr = E_OUTOFMEMORY;
7154 }
7155#else
7156//# define VBOXDISP_TEST_SWAPCHAIN
7157# ifdef VBOXDISP_TEST_SWAPCHAIN
7158 VBOXDISP_D3DEV(pDevice);
7159# endif
7160 break;
7161#endif
7162
7163 HRESULT tmpHr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
7164 Assert(tmpHr == S_OK);
7165 }
7166 }
7167 else
7168 {
7169 vboxVDbgPrintR((__FUNCTION__": Not implemented: PatchLocationListSize(%d), AllocationListSize(%d)\n",
7170 pCreateData->PatchLocationListSize, pCreateData->AllocationListSize));
7171 //pCreateData->pAllocationList = ??
7172 hr = E_FAIL;
7173 }
7174
7175 RTMemFree(pDevice);
7176 } while (0);
7177 }
7178 else
7179 {
7180 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
7181 hr = E_OUTOFMEMORY;
7182 }
7183
7184 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7185
7186 return hr;
7187}
7188
7189static HRESULT APIENTRY vboxWddmDispCloseAdapter (IN HANDLE hAdapter)
7190{
7191 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7192 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7193
7194// Assert(0);
7195
7196 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
7197 if (VBOXDISPMODE_IS_3D(pAdapter))
7198 {
7199 HRESULT hr = VBoxDispWorkerDestroy(&pAdapter->WndWorker);
7200 Assert(hr == S_OK);
7201 pAdapter->pD3D9If->Release();
7202 VBoxDispD3DClose(&pAdapter->D3D);
7203 }
7204
7205 vboxCapsFree(pAdapter);
7206
7207 RTMemFree(pAdapter);
7208
7209 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7210
7211 return S_OK;
7212}
7213
7214HRESULT APIENTRY OpenAdapter (__inout D3DDDIARG_OPENADAPTER* pOpenData)
7215{
7216 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7217 vboxVDbgPrint(("==> "__FUNCTION__"\n"));
7218
7219// vboxDispLock();
7220
7221 HRESULT hr = E_FAIL;
7222
7223 do
7224 {
7225
7226 VBOXWDDM_QI Query;
7227 D3DDDICB_QUERYADAPTERINFO DdiQuery;
7228 DdiQuery.PrivateDriverDataSize = sizeof(Query);
7229 DdiQuery.pPrivateDriverData = &Query;
7230 hr = pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb(pOpenData->hAdapter, &DdiQuery);
7231 Assert(hr == S_OK);
7232 if (hr != S_OK)
7233 {
7234 vboxVDbgPrintR((__FUNCTION__": pfnQueryAdapterInfoCb failed, hr (%d)\n", hr));
7235 hr = E_FAIL;
7236 break;
7237 }
7238
7239 /* check the miniport version match display version */
7240 if (Query.u32Version != VBOXVIDEOIF_VERSION)
7241 {
7242 vboxVDbgPrintR((__FUNCTION__": miniport version mismatch, expected (%d), but was (%d)\n",
7243 VBOXVIDEOIF_VERSION,
7244 Query.u32Version));
7245 hr = E_FAIL;
7246 break;
7247 }
7248
7249#ifdef VBOX_WITH_VIDEOHWACCEL
7250 Assert(Query.cInfos >= 1);
7251 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_ADAPTER, aHeads[Query.cInfos]));
7252#else
7253 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(sizeof (VBOXWDDMDISP_ADAPTER));
7254#endif
7255 Assert(pAdapter);
7256 if (pAdapter)
7257 {
7258 pAdapter->hAdapter = pOpenData->hAdapter;
7259 pAdapter->uIfVersion = pOpenData->Interface;
7260 pAdapter->uRtVersion= pOpenData->Version;
7261 pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
7262
7263 pAdapter->cHeads = Query.cInfos;
7264
7265
7266 pOpenData->hAdapter = pAdapter;
7267 pOpenData->pAdapterFuncs->pfnGetCaps = vboxWddmDispGetCaps;
7268 pOpenData->pAdapterFuncs->pfnCreateDevice = vboxWddmDispCreateDevice;
7269 pOpenData->pAdapterFuncs->pfnCloseAdapter = vboxWddmDispCloseAdapter;
7270 pOpenData->DriverVersion = D3D_UMD_INTERFACE_VERSION;
7271 /*
7272 * here we detect whether we are called by the d3d or ddraw.
7273 * in the d3d case we init our d3d environment
7274 * in the ddraw case we init 2D acceleration
7275 * if interface version is > 7, this is D3D, treat it as so
7276 * otherwise treat it as ddraw
7277 * @todo: need a more clean way of doing this */
7278
7279 if (pAdapter->uIfVersion > 7)
7280 {
7281 do
7282 {
7283 /* try enable the 3D */
7284 hr = VBoxDispD3DOpen(&pAdapter->D3D);
7285 Assert(hr == S_OK);
7286 if (hr == S_OK)
7287 {
7288// Assert(0);
7289 hr = pAdapter->D3D.pfnDirect3DCreate9Ex(D3D_SDK_VERSION, &pAdapter->pD3D9If);
7290 Assert(hr == S_OK);
7291 if (hr == S_OK)
7292 {
7293 D3DCAPS9 Caps;
7294 memset(&Caps, 0, sizeof (Caps));
7295 hr = vboxWddmGetD3D9Caps(pAdapter, &Caps);
7296 Assert(hr == S_OK);
7297 if (hr == S_OK)
7298 {
7299 pAdapter->cMaxSimRTs = Caps.NumSimultaneousRTs;
7300 Assert(pAdapter->cMaxSimRTs);
7301 Assert(pAdapter->cMaxSimRTs < UINT32_MAX/2);
7302 hr = VBoxDispWorkerCreate(&pAdapter->WndWorker);
7303 Assert(hr == S_OK);
7304 if (hr == S_OK)
7305 {
7306 vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
7307 break;
7308 }
7309 }
7310 pAdapter->pD3D9If->Release();
7311 }
7312 else
7313 vboxVDbgPrintR((__FUNCTION__": pfnDirect3DCreate9Ex failed, hr (%d)\n", hr));
7314 VBoxDispD3DClose(&pAdapter->D3D);
7315 }
7316 else
7317 vboxVDbgPrintR((__FUNCTION__": VBoxDispD3DOpen failed, hr (%d)\n", hr));
7318 } while (0);
7319 }
7320#ifdef VBOX_WITH_VIDEOHWACCEL
7321 else
7322 {
7323 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
7324 {
7325 pAdapter->aHeads[i].Vhwa.Settings = Query.aInfos[i];
7326 }
7327 }
7328#endif
7329
7330 vboxCapsInit(pAdapter);
7331 hr = S_OK;
7332// RTMemFree(pAdapter);
7333 }
7334 else
7335 {
7336 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
7337 hr = E_OUTOFMEMORY;
7338 }
7339
7340 } while (0);
7341
7342// vboxDispUnlock();
7343
7344 vboxVDbgPrint(("<== "__FUNCTION__", hr (%d)\n", hr));
7345
7346 return hr;
7347}
7348
7349#ifdef VBOXWDDMDISP_DEBUG_PRINT
7350VOID vboxVDbgDoMpPrint(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString)
7351{
7352 uint32_t cbString = strlen(szString) + 1;
7353 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
7354 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
7355 Assert(pCmd);
7356 if (pCmd)
7357 {
7358 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
7359 memcpy(pCmd->aStringBuf, szString, cbString);
7360
7361 D3DDDICB_ESCAPE DdiEscape = {0};
7362 DdiEscape.hContext = NULL;
7363 DdiEscape.hDevice = NULL;
7364 DdiEscape.Flags.Value = 0;
7365 DdiEscape.pPrivateDriverData = pCmd;
7366 DdiEscape.PrivateDriverDataSize = cbCmd;
7367
7368 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
7369 Assert(hr == S_OK);
7370
7371 RTMemFree(pCmd);
7372 }
7373}
7374VOID vboxVDbgDoMpPrintF(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString, ...)
7375{
7376 char szBuffer[4096] = {0};
7377 va_list pArgList;
7378 va_start(pArgList, szString);
7379 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
7380 va_end(pArgList);
7381
7382 if (pDevice)
7383 {
7384 vboxVDbgDoMpPrint(pDevice, szBuffer);
7385 }
7386 else
7387 {
7388 OutputDebugStringA(szBuffer);
7389 }
7390}
7391VOID vboxVDbgDoPrint(LPCSTR szString, ...)
7392{
7393 char szBuffer[1024] = {0};
7394 va_list pArgList;
7395 va_start(pArgList, szString);
7396 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
7397 va_end(pArgList);
7398
7399 OutputDebugStringA(szBuffer);
7400}
7401#endif
7402
7403#ifdef VBOXWDDMDISP_DEBUG
7404
7405bool g_VDbgTstDumpEnable = false;
7406bool g_VDbgTstDumpOnSys2VidSameSizeEnable = false;
7407
7408VOID vboxVDbgDoDumpSurfData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const RECT *pRect, IDirect3DSurface9 *pSurf, const char* pSuffix)
7409{
7410 if (pPrefix)
7411 {
7412 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
7413 }
7414
7415 Assert(pRc->cAllocations > iAlloc);
7416 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
7417
7418 vboxVDbgMpPrintAlloc((pDevice, "allocation info:\n", pRc, iAlloc, "\n"));
7419
7420 D3DLOCKED_RECT Lr;
7421 if (pRect)
7422 {
7423 Assert(pRect->right > pRect->left);
7424 Assert(pRect->bottom > pRect->top);
7425 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
7426 }
7427
7428 BOOL bReleaseSurf = false;
7429 if (!pSurf)
7430 {
7431 HRESULT tmpHr = vboxWddmSurfGet(pRc, iAlloc, &pSurf);
7432 Assert(tmpHr == S_OK);
7433 bReleaseSurf = TRUE;
7434 }
7435 HRESULT srcHr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
7436 Assert(srcHr == S_OK);
7437 if (srcHr == S_OK)
7438 {
7439 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
7440// Assert(bpp == pAlloc->SurfDesc.bpp);
7441// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
7442 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
7443 Lr.pBits, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, Lr.Pitch));
7444 if (pRect)
7445 {
7446 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
7447 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
7448 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
7449 }
7450 Assert(0);
7451
7452 srcHr = pSurf->UnlockRect();
7453 Assert(srcHr == S_OK);
7454 }
7455 if (pSuffix)
7456 {
7457 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
7458 }
7459
7460 if (bReleaseSurf)
7461 pSurf->Release();
7462}
7463
7464VOID vboxVDbgDoDumpSurfDataBySurf(const PVBOXWDDMDISP_DEVICE pDevice, IDirect3DSurface9 *pSurf)
7465{
7466 D3DSURFACE_DESC Desc;
7467 HRESULT hr = pSurf->GetDesc(&Desc);
7468 Assert(hr == S_OK);
7469 if (hr == S_OK)
7470 {
7471 D3DLOCKED_RECT Lr;
7472 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
7473 Assert(hr == S_OK);
7474 if (hr == S_OK)
7475 {
7476 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
7477 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
7478 Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch));
7479
7480 Assert(0);
7481
7482 hr = pSurf->UnlockRect();
7483 Assert(hr == S_OK);
7484 }
7485 }
7486}
7487
7488void vboxVDbgDoMpPrintAlloc(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
7489{
7490 Assert(pRc->cAllocations > iAlloc);
7491 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
7492 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
7493 BOOL bFrontBuf = FALSE;
7494 if (bPrimary)
7495 {
7496 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
7497 Assert(pSwapchain);
7498 bFrontBuf = (vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc);
7499 }
7500 vboxVDbgDoMpPrintF(pDevice, "%s D3DWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
7501 pAlloc->D3DWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
7502 bPrimary ?
7503 (bFrontBuf ? "Front Buffer" : "Back Buffer")
7504 : "?Everage? Alloc",
7505 pSuffix);
7506}
7507
7508void vboxVDbgDoMpPrintRect(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const RECT *pRect, const char * pSuffix)
7509{
7510 vboxVDbgDoMpPrintF(pDevice, "%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix);
7511}
7512
7513static PVOID g_VBoxWDbgVEHandler = NULL;
7514LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
7515{
7516 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
7517 PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
7518 switch (pExceptionRecord->ExceptionCode)
7519 {
7520 case 0x40010006: /* <- OutputDebugString exception, ignore */
7521 case 0xe06d7363: /* <- ms compiler - generated exception related to C++ exception */
7522 break;
7523 default:
7524 Assert(0);
7525 break;
7526 }
7527 return EXCEPTION_CONTINUE_SEARCH;
7528}
7529
7530void vboxVDbgVEHandlerRegister()
7531{
7532 Assert(!g_VBoxWDbgVEHandler);
7533 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
7534 Assert(g_VBoxWDbgVEHandler);
7535}
7536
7537void vboxVDbgVEHandlerUnregister()
7538{
7539 Assert(g_VBoxWDbgVEHandler);
7540 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
7541 Assert(uResult);
7542 g_VBoxWDbgVEHandler = NULL;
7543}
7544
7545#endif
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