VirtualBox

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

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

wddm/3d: chromium over hgsmi transport fixing & perf measurement

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 296.2 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}
5366
5367#ifdef VBOXWDDM_TEST_UHGSMI
5368int vboxUhgsmiTst(PVBOXUHGSMI pUhgsmi, uint32_t cbBuf, uint32_t cNumCals, uint64_t * pTimeMs);
5369#endif
5370
5371static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRESENT* pData)
5372{
5373 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5374 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5375 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5376// VBOXDISPPROFILE_DDI_CHKDUMPRESET(pDevice);
5377 Assert(pDevice);
5378 HRESULT hr = S_OK;
5379 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
5380 {
5381#ifdef VBOXWDDM_TEST_UHGSMI
5382 {
5383 Assert(0);
5384 static uint32_t cCals = 10000;
5385 static uint32_t cbData = 8 * 1024 * 1024;
5386 uint64_t TimeMs;
5387 int rc = vboxUhgsmiTst(&pDevice->Uhgsmi.Base, cbData, cCals, &TimeMs);
5388 uint32_t cCPS = (((uint64_t)cCals) * 1000ULL)/TimeMs;
5389 Assert(0);
5390 vboxVDbgDoMpPrintF(pDevice, "Time : %I64u ms, calls: %d, cps: %d\n", TimeMs, cCals, cCPS);
5391 }
5392#endif
5393#if 1
5394 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5395 Assert(pRc);
5396 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
5397 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5398 hr = vboxWddmSwapchainPresent(pDevice, pAlloc);
5399 Assert(hr == S_OK);
5400#else
5401 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5402 Assert(pRc);
5403 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5404 Assert(pScreen->hWnd);
5405 Assert(pScreen->pDevice9If);
5406 Assert(pRc == pScreen->pRenderTargetRc);
5407#if 1
5408 VBOXVDBG_RTGT_STATECHECK(pDevice);
5409
5410 if (pRc->RcDesc.VidPnSourceId != pDevice->iPrimaryScreen)
5411 {
5412 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5413 PVBOXWDDMDISP_SCREEN pPrimaryScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5414 Assert(pPrimaryScreen->pDevice9If);
5415 IDirect3DSurface9 *pSecondaryRt;
5416 IDirect3DSurface9 *pDataRt = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
5417 Assert(pDataRt);
5418 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5419 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pPrimaryScreen->pDevice9If);
5420 Assert(hr == S_OK);
5421 if (hr == S_OK)
5422 {
5423 hr = pScreen->pDevice9If->GetRenderTarget(0, &pSecondaryRt);
5424 Assert(hr == S_OK);
5425 if (hr == S_OK)
5426 {
5427 hr = pScreen->pDevice9If->StretchRect(pDataRt,
5428 NULL,
5429 pSecondaryRt,
5430 NULL,
5431 D3DTEXF_NONE);
5432 pSecondaryRt->Release();
5433 }
5434 }
5435 }
5436
5437 hr = pScreen->pDevice9If->Present(NULL, /* CONST RECT * pSourceRect */
5438 NULL, /* CONST RECT * pDestRect */
5439 NULL, /* HWND hDestWindowOverride */
5440 NULL /*CONST RGNDATA * pDirtyRegion */
5441 );
5442 Assert(hr == S_OK);
5443#endif
5444#endif
5445 }
5446#if 0
5447 else
5448#endif
5449 {
5450// if (pData->Flags.Flip)
5451// {
5452// Assert(pData->hSrcResource);
5453// PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5454// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5455// Assert(pScreen->hWnd);
5456// Assert(pScreen->pDevice9If);
5457// Assert(pScreen->pRenderTargetRc == pRc);
5458// Assert(pRc->cAllocations >= 2);
5459// Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5460// Assert(pRc->RcDesc.fFlags.RenderTarget);
5461// uint32_t iNewRTFB = (pScreen->iRenderTargetFrontBuf + 1) % pRc->cAllocations;
5462//
5463// Assert(pScreen->iRenderTargetFrontBuf != iNewRTFB);
5464// Assert(pData->SrcSubResourceIndex == iNewRTFB);
5465//
5466// vboxWddmRenderTargetUpdate(pDevice, pRc, iNewRTFB);
5467//
5468// /* assign a new frontbuffer index */
5469// pScreen->iRenderTargetFrontBuf = iNewRTFB;
5470//
5471// VBOXVDBG_RTGT_STATECHECK(pDevice);
5472// }
5473 D3DDDICB_PRESENT DdiPresent = {0};
5474 if (pData->hSrcResource)
5475 {
5476 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5477 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
5478 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5479 Assert(pAlloc->hAllocation);
5480 DdiPresent.hSrcAllocation = pAlloc->hAllocation;
5481 }
5482 if (pData->hDstResource)
5483 {
5484 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
5485 Assert(pRc->cAllocations > pData->DstSubResourceIndex);
5486 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->DstSubResourceIndex];
5487 Assert(pAlloc->hAllocation);
5488 DdiPresent.hDstAllocation = pAlloc->hAllocation;
5489 }
5490 DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext;
5491// DdiPresent.BroadcastContextCount;
5492// DdiPresent.BroadcastContext[D3DDDI_MAX_BROADCAST_CONTEXT];
5493
5494 hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent);
5495 Assert(hr == S_OK);
5496 }
5497 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5498 return hr;
5499}
5500
5501typedef struct VBOXWDDMDISP_NSCADD
5502{
5503 VOID* pvCommandBuffer;
5504 UINT cbCommandBuffer;
5505 D3DDDI_ALLOCATIONLIST* pAllocationList;
5506 UINT cAllocationList;
5507 D3DDDI_PATCHLOCATIONLIST* pPatchLocationList;
5508 UINT cPatchLocationList;
5509 UINT cAllocations;
5510}VBOXWDDMDISP_NSCADD, *PVBOXWDDMDISP_NSCADD;
5511
5512static HRESULT vboxWddmNSCAddAlloc(PVBOXWDDMDISP_NSCADD pData, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bWrite)
5513{
5514 HRESULT hr = S_OK;
5515 if (pData->cAllocationList && pData->cPatchLocationList && pData->cbCommandBuffer > 4)
5516 {
5517 memset(pData->pAllocationList, 0, sizeof (D3DDDI_ALLOCATIONLIST));
5518 pData->pAllocationList[0].hAllocation = pAlloc->hAllocation;
5519 if (bWrite)
5520 pData->pAllocationList[0].WriteOperation = 1;
5521
5522 memset(pData->pPatchLocationList, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
5523 pData->pPatchLocationList[0].PatchOffset = pData->cAllocations*4;
5524 pData->pPatchLocationList[0].AllocationIndex = pData->cAllocations;
5525
5526 pData->cbCommandBuffer -= 4;
5527 --pData->cAllocationList;
5528 --pData->cPatchLocationList;
5529 ++pData->cAllocations;
5530
5531 ++pData->pAllocationList;
5532 ++pData->pPatchLocationList;
5533 pData->pvCommandBuffer = (VOID*)(((uint8_t*)pData->pvCommandBuffer) + 4);
5534
5535 }
5536 else
5537 hr = S_FALSE;
5538
5539 return hr;
5540}
5541
5542static HRESULT vboxWddmNotifySharedChange(PVBOXWDDMDISP_DEVICE pDevice)
5543{
5544 VBOXWDDMDISP_NSCADD NscAdd;
5545 BOOL bReinitRenderData = TRUE;
5546
5547 do
5548 {
5549 if (bReinitRenderData)
5550 {
5551 NscAdd.pvCommandBuffer = pDevice->DefaultContext.ContextInfo.pCommandBuffer;
5552 NscAdd.cbCommandBuffer = pDevice->DefaultContext.ContextInfo.CommandBufferSize;
5553 NscAdd.pAllocationList = pDevice->DefaultContext.ContextInfo.pAllocationList;
5554 NscAdd.cAllocationList = pDevice->DefaultContext.ContextInfo.AllocationListSize;
5555 NscAdd.pPatchLocationList = pDevice->DefaultContext.ContextInfo.pPatchLocationList;
5556 NscAdd.cPatchLocationList = pDevice->DefaultContext.ContextInfo.PatchLocationListSize;
5557 NscAdd.cAllocations = 0;
5558 Assert(NscAdd.cbCommandBuffer >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR));
5559 if (NscAdd.cbCommandBuffer < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
5560 return E_FAIL;
5561
5562 PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pHdr = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)NscAdd.pvCommandBuffer;
5563 pHdr->enmCmd = VBOXVDMACMD_TYPE_DMA_NOP;
5564 NscAdd.pvCommandBuffer = (VOID*)(((uint8_t*)NscAdd.pvCommandBuffer) + sizeof (*pHdr));
5565 NscAdd.cbCommandBuffer -= sizeof (*pHdr);
5566 bReinitRenderData = FALSE;
5567 }
5568
5569 EnterCriticalSection(&pDevice->DirtyAllocListLock);
5570
5571 PVBOXWDDMDISP_ALLOCATION pAlloc = RTListNodeGetFirst(&pDevice->DirtyAllocList, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry);
5572 if (pAlloc)
5573 {
5574 HRESULT tmpHr = vboxWddmNSCAddAlloc(&NscAdd, pAlloc, TRUE);
5575 Assert(tmpHr == S_OK || tmpHr == S_FALSE);
5576 if (tmpHr == S_OK)
5577 {
5578 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
5579 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5580 continue;
5581 }
5582
5583 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5584
5585 }
5586 else
5587 {
5588 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5589 if (!NscAdd.cAllocations)
5590 break;
5591 }
5592
5593 D3DDDICB_RENDER RenderData = {0};
5594 RenderData.CommandLength = pDevice->DefaultContext.ContextInfo.CommandBufferSize - NscAdd.cbCommandBuffer;
5595 Assert(RenderData.CommandLength);
5596 Assert(RenderData.CommandLength < UINT32_MAX/2);
5597 RenderData.CommandOffset = 0;
5598 RenderData.NumAllocations = pDevice->DefaultContext.ContextInfo.AllocationListSize - NscAdd.cAllocationList;
5599 Assert(RenderData.NumAllocations == NscAdd.cAllocations);
5600 RenderData.NumPatchLocations = pDevice->DefaultContext.ContextInfo.PatchLocationListSize - NscAdd.cPatchLocationList;
5601 Assert(RenderData.NumPatchLocations == NscAdd.cAllocations);
5602// RenderData.NewCommandBufferSize = sizeof (VBOXVDMACMD) + 4 * (100);
5603// RenderData.NewAllocationListSize = 100;
5604// RenderData.NewPatchLocationListSize = 100;
5605 RenderData.hContext = pDevice->DefaultContext.ContextInfo.hContext;
5606
5607 HRESULT hr = pDevice->RtCallbacks.pfnRenderCb(pDevice->hDevice, &RenderData);
5608 Assert(hr == S_OK);
5609 if (hr == S_OK)
5610 {
5611 pDevice->DefaultContext.ContextInfo.CommandBufferSize = RenderData.NewCommandBufferSize;
5612 pDevice->DefaultContext.ContextInfo.pCommandBuffer = RenderData.pNewCommandBuffer;
5613 pDevice->DefaultContext.ContextInfo.AllocationListSize = RenderData.NewAllocationListSize;
5614 pDevice->DefaultContext.ContextInfo.pAllocationList = RenderData.pNewAllocationList;
5615 pDevice->DefaultContext.ContextInfo.PatchLocationListSize = RenderData.NewPatchLocationListSize;
5616 pDevice->DefaultContext.ContextInfo.pPatchLocationList = RenderData.pNewPatchLocationList;
5617 bReinitRenderData = TRUE;
5618 }
5619 else
5620 break;
5621 } while (1);
5622
5623 return S_OK;
5624}
5625
5626static HRESULT APIENTRY vboxWddmDDevFlush(HANDLE hDevice)
5627{
5628 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5629 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5630 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5631 Assert(pDevice);
5632 HRESULT hr = S_OK;
5633 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
5634 {
5635// Assert(pDevice->cScreens);
5636// UINT cProcessed = 0;
5637// for (UINT i = 0; cProcessed < pDevice->cScreens && i < RT_ELEMENTS(pDevice->aScreens); ++i)
5638// {
5639// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i];
5640// if (pScreen->pDevice9If)
5641// {
5642// ++cProcessed;
5643//// if (pScreen->pRenderTargetRc->cAllocations == 1)
5644//// {
5645//// hr = pScreen->pDevice9If->Present(NULL, NULL, NULL, NULL);
5646//// Assert(hr == S_OK);
5647//// }
5648//// else
5649 {
5650 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pDevice->pDevice9If);
5651 Assert(hr == S_OK);
5652 }
5653// }
5654// }
5655
5656 vboxWddmNotifySharedChange(pDevice);
5657 }
5658 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5659 return hr;
5660}
5661
5662AssertCompile(sizeof (D3DDDIVERTEXELEMENT) == sizeof (D3DVERTEXELEMENT9));
5663AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Stream) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Stream));
5664AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Offset) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Offset));
5665AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Type) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Type));
5666AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Method) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Method));
5667AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Usage) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Usage));
5668AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, UsageIndex) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, UsageIndex));
5669
5670AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Stream) == RT_OFFSETOF(D3DVERTEXELEMENT9, Stream));
5671AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Offset) == RT_OFFSETOF(D3DVERTEXELEMENT9, Offset));
5672AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Type) == RT_OFFSETOF(D3DVERTEXELEMENT9, Type));
5673AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Method) == RT_OFFSETOF(D3DVERTEXELEMENT9, Method));
5674AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Usage) == RT_OFFSETOF(D3DVERTEXELEMENT9, Usage));
5675AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, UsageIndex) == RT_OFFSETOF(D3DVERTEXELEMENT9, UsageIndex));
5676
5677static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderDecl(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERDECL* pData, CONST D3DDDIVERTEXELEMENT* pVertexElements)
5678{
5679 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5680 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5681 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5682 Assert(pDevice);
5683 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5684 IDirect3DVertexDeclaration9 *pDecl;
5685 static D3DVERTEXELEMENT9 DeclEnd = D3DDECL_END();
5686 D3DVERTEXELEMENT9* pVe;
5687 HRESULT hr = S_OK;
5688 bool bFreeVe = false;
5689 if(memcmp(&DeclEnd, &pVertexElements[pData->NumVertexElements], sizeof (DeclEnd)))
5690 {
5691 pVe = (D3DVERTEXELEMENT9*)RTMemAlloc(sizeof (D3DVERTEXELEMENT9) * (pData->NumVertexElements + 1));
5692 if (pVe)
5693 {
5694 memcpy(pVe, pVertexElements, sizeof (D3DVERTEXELEMENT9) * pData->NumVertexElements);
5695 pVe[pData->NumVertexElements] = DeclEnd;
5696 bFreeVe = true;
5697 }
5698 else
5699 hr = E_OUTOFMEMORY;
5700 }
5701 else
5702 pVe = (D3DVERTEXELEMENT9*)pVertexElements;
5703
5704 if (hr == S_OK)
5705 {
5706 hr = pDevice9If->CreateVertexDeclaration(
5707 pVe,
5708 &pDecl
5709 );
5710 Assert(hr == S_OK);
5711 if (hr == S_OK)
5712 {
5713 Assert(pDecl);
5714 pData->ShaderHandle = pDecl;
5715 }
5716 }
5717
5718 if (bFreeVe)
5719 RTMemFree((void*)pVe);
5720
5721 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5722 return hr;
5723}
5724static HRESULT APIENTRY vboxWddmDDevSetVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
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 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
5732 Assert(pDecl);
5733 HRESULT hr = pDevice9If->SetVertexDeclaration(pDecl);
5734 Assert(hr == S_OK);
5735 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5736 return hr;
5737}
5738static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
5739{
5740 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5741 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5742 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5743 Assert(pDevice);
5744 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
5745 HRESULT hr = S_OK;
5746 pDecl->Release();
5747 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5748 return hr;
5749}
5750static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderFunc(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERFUNC* pData, CONST UINT* pCode)
5751{
5752 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5753 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5754 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5755 Assert(pDevice);
5756 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5757 IDirect3DVertexShader9 *pShader;
5758 Assert(*((UINT*)((uint8_t*)pCode + pData->Size-4)) == 0x0000FFFF /* end token */);
5759 HRESULT hr = pDevice9If->CreateVertexShader((const DWORD *)pCode, &pShader);
5760 Assert(hr == S_OK);
5761 if (hr == S_OK)
5762 {
5763 Assert(pShader);
5764 pData->ShaderHandle = pShader;
5765 }
5766 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5767 return hr;
5768}
5769static HRESULT APIENTRY vboxWddmDDevSetVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
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 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
5777 Assert(pShader);
5778 HRESULT hr = pDevice9If->SetVertexShader(pShader);
5779 Assert(hr == S_OK);
5780 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5781 return hr;
5782}
5783static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
5784{
5785 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5786 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5787 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5788 Assert(pDevice);
5789 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
5790 HRESULT hr = S_OK;
5791 pShader->Release();
5792 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5793 return hr;
5794}
5795static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTI* pData, CONST INT* pRegisters)
5796{
5797 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5798 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5799 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5800 Assert(pDevice);
5801 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5802 HRESULT hr = pDevice9If->SetVertexShaderConstantI(pData->Register, pRegisters, pData->Count);
5803 Assert(hr == S_OK);
5804 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5805 return hr;
5806}
5807static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTB* pData, CONST BOOL* pRegisters)
5808{
5809 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5810 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5811 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5812 Assert(pDevice);
5813 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5814 HRESULT hr = pDevice9If->SetVertexShaderConstantB(pData->Register, pRegisters, pData->Count);
5815 Assert(hr == S_OK);
5816 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5817 return hr;
5818}
5819static HRESULT APIENTRY vboxWddmDDevSetScissorRect(HANDLE hDevice, CONST RECT* pRect)
5820{
5821 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5822 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5823 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5824 Assert(pDevice);
5825 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5826 HRESULT hr = pDevice9If->SetScissorRect(pRect);
5827 Assert(hr == S_OK);
5828 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5829 return hr;
5830}
5831static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCE* pData)
5832{
5833 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5834 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5835 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5836 Assert(pDevice);
5837 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5838 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hVertexBuffer;
5839 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
5840 IDirect3DVertexBuffer9 *pStreamData = NULL;
5841 if (pRc)
5842 {
5843 Assert(pRc->cAllocations == 1);
5844 pAlloc = &pRc->aAllocations[0];
5845 Assert(pAlloc->pD3DIf);
5846 pStreamData = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
5847 }
5848 HRESULT hr = pDevice9If->SetStreamSource(pData->Stream, pStreamData, pData->Offset, pData->Stride);
5849 Assert(hr == S_OK);
5850 Assert(pData->Stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS);
5851 if (hr == S_OK)
5852 {
5853 if (pDevice->aStreamSource[pData->Stream] && !pAlloc)
5854 {
5855 --pDevice->cStreamSources;
5856 Assert(pDevice->cStreamSources < UINT32_MAX/2);
5857 }
5858 else if (!pDevice->aStreamSource[pData->Stream] && pAlloc)
5859 {
5860 ++pDevice->cStreamSources;
5861 Assert(pDevice->cStreamSources <= RT_ELEMENTS(pDevice->aStreamSource));
5862 }
5863 pDevice->aStreamSource[pData->Stream] = pAlloc;
5864 pDevice->StreamSourceInfo[pData->Stream].uiOffset = pData->Offset;
5865 pDevice->StreamSourceInfo[pData->Stream].uiStride = pData->Stride;
5866 }
5867 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5868 return hr;
5869}
5870static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData)
5871{
5872 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5873 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5874 Assert(0);
5875 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5876 return E_FAIL;
5877}
5878static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData)
5879{
5880 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5881 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5882 Assert(0);
5883 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5884 return E_FAIL;
5885}
5886static HRESULT APIENTRY vboxWddmDDevComposeRects(HANDLE hDevice, CONST D3DDDIARG_COMPOSERECTS* pData)
5887{
5888 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5889 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5890 Assert(0);
5891 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5892 return E_FAIL;
5893}
5894static HRESULT vboxWddmLockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc,
5895 D3DLOCKED_RECT * pLockedRect,
5896 CONST RECT *pRect,
5897 DWORD fLockFlags)
5898{
5899 HRESULT hr = E_FAIL;
5900 Assert(!pRc->aAllocations[iAlloc].LockInfo.cLocks);
5901 Assert(pRc->cAllocations > iAlloc);
5902 switch (pRc->aAllocations[0].enmD3DIfType)
5903 {
5904 case VBOXDISP_D3DIFTYPE_SURFACE:
5905 {
5906 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
5907 Assert(pD3DIfSurf);
5908 hr = pD3DIfSurf->LockRect(pLockedRect, pRect, fLockFlags);
5909 Assert(hr == S_OK);
5910 break;
5911 }
5912 case VBOXDISP_D3DIFTYPE_TEXTURE:
5913 {
5914 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
5915 Assert(pD3DIfTex);
5916 hr = pD3DIfTex->LockRect(iAlloc, pLockedRect, pRect, fLockFlags);
5917 Assert(hr == S_OK);
5918 break;
5919 }
5920 default:
5921 Assert(0);
5922 break;
5923 }
5924 return hr;
5925}
5926static HRESULT vboxWddmUnlockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc)
5927{
5928 HRESULT hr = S_OK;
5929 Assert(pRc->cAllocations > iAlloc);
5930 switch (pRc->aAllocations[0].enmD3DIfType)
5931 {
5932 case VBOXDISP_D3DIFTYPE_SURFACE:
5933 {
5934 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
5935 Assert(pD3DIfSurf);
5936 hr = pD3DIfSurf->UnlockRect();
5937 Assert(hr == S_OK);
5938 break;
5939 }
5940 case VBOXDISP_D3DIFTYPE_TEXTURE:
5941 {
5942 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
5943 Assert(pD3DIfTex);
5944 hr = pD3DIfTex->UnlockRect(iAlloc);
5945 Assert(hr == S_OK);
5946 break;
5947 }
5948 default:
5949 Assert(0);
5950 hr = E_FAIL;
5951 break;
5952 }
5953 return hr;
5954}
5955
5956static HRESULT APIENTRY vboxWddmDDevBlt(HANDLE hDevice, CONST D3DDDIARG_BLT* pData)
5957{
5958 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5959 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5960 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5961 Assert(pDevice);
5962// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5963 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5964 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
5965 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5966 Assert(pDstRc->cAllocations > pData->DstSubResourceIndex);
5967 Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex);
5968 HRESULT hr = S_OK;
5969 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
5970 PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
5971 PVBOXWDDMDISP_SWAPCHAIN pSrcSwapchain = vboxWddmSwapchainForAlloc(pSrcAlloc);
5972 PVBOXWDDMDISP_SWAPCHAIN pDstSwapchain = vboxWddmSwapchainForAlloc(pDstAlloc);
5973 Assert(!pDstSwapchain || vboxWddmSwapchainGetFb(pDstSwapchain)->pAlloc != pDstAlloc);
5974 /* try StretchRect */
5975 IDirect3DSurface9 *pSrcSurfIf = NULL;
5976 IDirect3DSurface9 *pDstSurfIf = NULL;
5977 hr = vboxWddmSurfGet(pDstRc, pData->DstSubResourceIndex, &pDstSurfIf);
5978 Assert(hr == S_OK);
5979 if (hr == S_OK)
5980 {
5981 Assert(pDstSurfIf);
5982 do
5983 {
5984#ifndef VBOXWDDM_WITH_VISIBLE_FB
5985 if (pSrcSwapchain
5986 && pSrcSwapchain->pRenderTargetFbCopy
5987 && vboxWddmSwapchainGetFb(pSrcSwapchain)->pAlloc == pSrcAlloc
5988# ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
5989 && vboxWddmSwapchainNumRTs(pSrcSwapchain) > 1 /* work-around wine backbuffer */
5990# endif
5991 )
5992 {
5993// Assert(pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width);
5994// Assert(pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height);
5995// Assert(pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format);
5996// Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
5997// Assert(pSrcAlloc->SurfDesc.pitch == pDstAlloc->SurfDesc.pitch);
5998// Assert(pSrcAlloc->SurfDesc.depth == pDstAlloc->SurfDesc.depth);
5999// Assert(pSrcAlloc->SurfDesc.slicePitch == pDstAlloc->SurfDesc.slicePitch);
6000// Assert(pSrcAlloc->SurfDesc.cbSize == pDstAlloc->SurfDesc.cbSize);
6001// Assert(pData->DstRect.left == 0);
6002// Assert(pData->DstRect.top == 0);
6003// Assert(pData->DstRect.right == pDstAlloc->SurfDesc.width);
6004// Assert(pData->DstRect.bottom == pDstAlloc->SurfDesc.height);
6005// Assert(pData->SrcRect.left == 0);
6006// Assert(pData->SrcRect.top == 0);
6007// Assert(pData->SrcRect.right == pSrcAlloc->SurfDesc.width);
6008// Assert(pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height);
6009# if 0
6010 if (pData->DstRect.left == 0 && pData->DstRect.top == 0
6011 && pData->DstRect.right == pDstAlloc->SurfDesc.width
6012 && pData->DstRect.bottom == pDstAlloc->SurfDesc.height
6013 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
6014 && pData->SrcRect.right == pSrcAlloc->SurfDesc.width
6015 && pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height
6016 && pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width
6017 && pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height
6018 && pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format)
6019 {
6020 hr = pDevice9If->GetFrontBufferData(0, pDstSurfIf);
6021 Assert(hr == S_OK);
6022 break;
6023 }
6024 else
6025# endif
6026 {
6027 pSrcSurfIf = pSrcSwapchain->pRenderTargetFbCopy;
6028 Assert(pSrcSurfIf);
6029 hr = pSrcSwapchain->pSwapChainIf->GetFrontBufferData(pSrcSurfIf);
6030 Assert(hr == S_OK);
6031 if (hr == S_OK)
6032 {
6033 /* do pSrcSurfIf->AddRef since we do a Release in the following if (hr == S_OK) branch */
6034 pSrcSurfIf->AddRef();
6035 }
6036 }
6037 }
6038 else
6039#endif
6040 {
6041 hr = vboxWddmSurfGet(pSrcRc, pData->SrcSubResourceIndex, &pSrcSurfIf);
6042 Assert(hr == S_OK);
6043 }
6044
6045 if (hr == S_OK)
6046 {
6047 Assert(pSrcSurfIf);
6048#ifdef DEBUG_misha
6049 bool bDo = false;
6050
6051 if (g_VDbgTstDumpEnable)
6052 {
6053 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
6054 {
6055 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
6056 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
6057 {
6058 D3DSURFACE_DESC SrcDesc;
6059 HRESULT hr = pSrcSurfIf->GetDesc(&SrcDesc);
6060 Assert(hr == S_OK);
6061 if (hr == S_OK)
6062 {
6063 D3DSURFACE_DESC DstDesc;
6064 hr = pDstSurfIf->GetDesc(&DstDesc);
6065 Assert(hr == S_OK);
6066 if (hr == S_OK)
6067 {
6068 if (SrcDesc.Width == DstDesc.Width
6069 && SrcDesc.Height == DstDesc.Height)
6070 {
6071 bDo = true;
6072 }
6073 }
6074 }
6075 }
6076 }
6077 }
6078
6079 if (bDo)
6080 {
6081 vboxVDbgDumpSurfData((pDevice, "Blt-pre Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
6082 vboxVDbgDumpSurfData((pDevice, "Blt-pre Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
6083 }
6084#endif
6085 /* we support only Point & Linear, we ignore [Begin|Continue|End]PresentToDwm */
6086 Assert((pData->Flags.Value & (~(0x00000100 | 0x00000200 | 0x00000400 | 0x00000001 | 0x00000002))) == 0);
6087 hr = pDevice9If->StretchRect(pSrcSurfIf,
6088 &pData->SrcRect,
6089 pDstSurfIf,
6090 &pData->DstRect,
6091 vboxDDI2D3DBltFlags(pData->Flags));
6092 Assert(hr == S_OK);
6093
6094#ifdef DEBUG_misha
6095 if (bDo)
6096 {
6097 vboxVDbgDumpSurfData((pDevice, "Blt-post Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
6098 vboxVDbgDumpSurfData((pDevice, "Blt-post Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
6099 }
6100#endif
6101 pSrcSurfIf->Release();
6102 }
6103 } while (0);
6104
6105 pDstSurfIf->Release();
6106 }
6107
6108 if (hr != S_OK)
6109 {
6110 /* todo: fallback to memcpy or whatever ? */
6111 Assert(0);
6112 }
6113
6114
6115#if 0
6116 if ((use pAlloc->enmD3DIfType instead!!! pDstRc->RcDesc.fFlags.Texture || pDstRc->RcDesc.fFlags.Value == 0)
6117 && (pSrcRc->RcDesc.fFlags.Texture || pSrcRc->RcDesc.fFlags.Value == 0))
6118 {
6119 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcAlloc->pD3DIf;
6120 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstAlloc->pD3DIf;
6121 Assert(pD3DIfSrcTex);
6122 Assert(pD3DIfDstTex);
6123
6124 if (pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat)
6125 {
6126 if (pSrcRc->aAllocations[0].SurfDesc.width == pDstRc->aAllocations[0].SurfDesc.width
6127 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
6128 && pData->DstRect.left == 0 && pData->DstRect.top == 0
6129 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
6130 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
6131 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height
6132 && pData->DstRect.right - pData->DstRect.left == pDstRc->aAllocations[0].SurfDesc.width
6133 && pData->DstRect.bottom - pData->DstRect.top == pDstRc->aAllocations[0].SurfDesc.height
6134 )
6135 {
6136 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
6137 Assert(hr == S_OK);
6138 }
6139 else if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
6140 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
6141 {
6142 Assert(pDstAlloc->SurfDesc.bpp);
6143 Assert(pSrcAlloc->SurfDesc.bpp);
6144 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
6145 D3DLOCKED_RECT DstRect, SrcRect;
6146 Assert(!pSrcAlloc->LockInfo.cLocks);
6147 Assert(!pDstAlloc->LockInfo.cLocks);
6148 hr = pD3DIfDstTex->LockRect(pData->DstSubResourceIndex, &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
6149 Assert(hr == S_OK);
6150 if (hr == S_OK)
6151 {
6152 hr = pD3DIfSrcTex->LockRect(pData->SrcSubResourceIndex, &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
6153 Assert(hr == S_OK);
6154 if (hr == S_OK)
6155 {
6156 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
6157 &pData->DstRect, &pData->SrcRect,
6158 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
6159 Assert(hr == S_OK);
6160
6161 pD3DIfSrcTex->UnlockRect(pData->SrcSubResourceIndex);
6162 }
6163 pD3DIfDstTex->UnlockRect(pData->DstSubResourceIndex);
6164 }
6165 }
6166 else
6167 {
6168
6169 Assert(0);
6170 /* @todo: impl */
6171 }
6172 }
6173 else
6174 {
6175 Assert(0);
6176 /* @todo: impl */
6177 }
6178 }
6179 else
6180 {
6181 if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
6182 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
6183 {
6184 Assert(pDstAlloc->SurfDesc.bpp);
6185 Assert(pSrcAlloc->SurfDesc.bpp);
6186 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
6187
6188 D3DLOCKED_RECT DstRect, SrcRect;
6189 hr = vboxWddmLockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags,
6190 &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
6191 Assert(hr == S_OK);
6192 if (hr == S_OK)
6193 {
6194 hr = vboxWddmLockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags,
6195 &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
6196 Assert(hr == S_OK);
6197 if (hr == S_OK)
6198 {
6199 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
6200 &pData->DstRect, &pData->SrcRect,
6201 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
6202 Assert(hr == S_OK);
6203
6204 HRESULT tmpHr = vboxWddmUnlockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags);
6205 Assert(tmpHr == S_OK);
6206 }
6207 HRESULT tmpHr = vboxWddmUnlockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags);
6208 Assert(tmpHr == S_OK);
6209 }
6210 }
6211 else
6212 {
6213 Assert(0);
6214 /* @todo: impl */
6215 }
6216 }
6217#endif
6218
6219 if (pDstRc->RcDesc.fFlags.SharedResource)
6220 {
6221 PVBOXWDDMDISP_ALLOCATION pAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
6222 EnterCriticalSection(&pDevice->DirtyAllocListLock);
6223 if (!pAlloc->DirtyAllocListEntry.pNext)
6224 RTListAppend(&pDevice->DirtyAllocList, &pAlloc->DirtyAllocListEntry);
6225 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
6226 }
6227
6228 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6229 return hr;
6230}
6231static HRESULT APIENTRY vboxWddmDDevColorFill(HANDLE hDevice, CONST D3DDDIARG_COLORFILL* pData)
6232{
6233 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6234 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6235 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6236 Assert(pDevice);
6237 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6238 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
6239 Assert(pRc);
6240 IDirect3DSurface9 *pSurfIf = NULL;
6241 HRESULT hr = vboxWddmSurfGet(pRc, pData->SubResourceIndex, &pSurfIf);
6242 Assert(hr == S_OK);
6243 if (hr == S_OK)
6244 {
6245 Assert(pSurfIf);
6246 hr = pDevice9If->ColorFill(pSurfIf, &pData->DstRect, pData->Color);
6247 Assert(hr == S_OK);
6248 /* @todo: check what need to do when PresentToDwm flag is set */
6249 Assert(pData->Flags.Value == 0);
6250
6251 pSurfIf->Release();
6252 }
6253 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6254 return hr;
6255}
6256static HRESULT APIENTRY vboxWddmDDevDepthFill(HANDLE hDevice, CONST D3DDDIARG_DEPTHFILL* pData)
6257{
6258 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6259 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6260 Assert(0);
6261 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6262 return E_FAIL;
6263}
6264static HRESULT APIENTRY vboxWddmDDevCreateQuery(HANDLE hDevice, D3DDDIARG_CREATEQUERY* pData)
6265{
6266 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6267 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6268 HRESULT hr = S_OK;
6269 if (pData->QueryType == D3DDDIQUERYTYPE_EVENT)
6270 {
6271 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)RTMemAllocZ(sizeof (VBOXWDDMDISP_QUERY));
6272 Assert(pQuery);
6273 if (pQuery)
6274 {
6275 pQuery->enmType = pData->QueryType;
6276 pData->hQuery = pQuery;
6277 }
6278 else
6279 {
6280 hr = E_OUTOFMEMORY;
6281 }
6282 }
6283 else
6284 {
6285 Assert(0);
6286 hr = E_FAIL;
6287 }
6288 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6289 return hr;
6290}
6291static HRESULT APIENTRY vboxWddmDDevDestroyQuery(HANDLE hDevice, HANDLE hQuery)
6292{
6293 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6294 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6295 HRESULT hr = S_OK;
6296 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)hQuery;
6297 Assert(pQuery);
6298 RTMemFree(pQuery);
6299 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6300 return hr;
6301}
6302static HRESULT APIENTRY vboxWddmDDevIssueQuery(HANDLE hDevice, CONST D3DDDIARG_ISSUEQUERY* pData)
6303{
6304 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6305 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6306 HRESULT hr = S_OK;
6307 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
6308 Assert(pQuery);
6309 pQuery->fQueryState.Value |= pData->Flags.Value;
6310 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6311 return hr;
6312}
6313static HRESULT APIENTRY vboxWddmDDevGetQueryData(HANDLE hDevice, CONST D3DDDIARG_GETQUERYDATA* pData)
6314{
6315 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6316 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6317 HRESULT hr = S_OK;
6318 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
6319 Assert(pQuery);
6320 switch (pQuery->enmType)
6321 {
6322 case D3DDDIQUERYTYPE_EVENT:
6323 Assert(0);
6324 pQuery->data.bData = TRUE;
6325 Assert(pData->pData);
6326 *((BOOL*)pData->pData) = TRUE;
6327 break;
6328 default:
6329 Assert(0);
6330 hr = E_FAIL;
6331 break;
6332 }
6333 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6334 return hr;
6335}
6336static HRESULT APIENTRY vboxWddmDDevSetRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETRENDERTARGET* pData)
6337{
6338 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6339 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6340 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6341 Assert(pDevice);
6342 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6343 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget;
6344 Assert(pRc);
6345 Assert(pData->SubResourceIndex < pRc->cAllocations);
6346 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
6347 HRESULT hr = vboxWddmRenderTargetSet(pDevice, pData->RenderTargetIndex, pAlloc, FALSE);
6348 Assert(hr == S_OK);
6349 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6350 return hr;
6351}
6352static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDIARG_SETDEPTHSTENCIL* pData)
6353{
6354 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6355 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6356 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6357 Assert(pDevice);
6358 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6359 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hZBuffer;
6360 IDirect3DSurface9 *pD3D9Surf = NULL;
6361 if (pRc)
6362 {
6363 Assert(pRc->cAllocations == 1);
6364 pD3D9Surf = (IDirect3DSurface9*)pRc->aAllocations[0].pD3DIf;
6365 Assert(pD3D9Surf);
6366 }
6367 HRESULT hr = pDevice9If->SetDepthStencilSurface(pD3D9Surf);
6368 Assert(hr == S_OK);
6369 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6370 return hr;
6371}
6372static HRESULT APIENTRY vboxWddmDDevGenerateMipSubLevels(HANDLE hDevice, CONST D3DDDIARG_GENERATEMIPSUBLEVELS* pData)
6373{
6374 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6375 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6376 Assert(0);
6377 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6378 return E_FAIL;
6379}
6380static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTI* pData, CONST INT* pRegisters)
6381{
6382 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6383 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6384 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6385 Assert(pDevice);
6386 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6387 HRESULT hr = pDevice9If->SetPixelShaderConstantI(pData->Register, pRegisters, pData->Count);
6388 Assert(hr == S_OK);
6389 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6390 return hr;
6391}
6392static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTB* pData, CONST BOOL* pRegisters)
6393{
6394 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6395 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6396 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6397 Assert(pDevice);
6398 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6399 HRESULT hr = pDevice9If->SetPixelShaderConstantB(pData->Register, pRegisters, pData->Count);
6400 Assert(hr == S_OK);
6401 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6402 return hr;
6403}
6404static HRESULT APIENTRY vboxWddmDDevCreatePixelShader(HANDLE hDevice, D3DDDIARG_CREATEPIXELSHADER* pData, CONST UINT* pCode)
6405{
6406 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6407 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6408 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6409 Assert(pDevice);
6410 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6411 IDirect3DPixelShader9 *pShader;
6412 Assert(*((UINT*)((uint8_t*)pCode + pData->CodeSize-4)) == 0x0000FFFF /* end token */);
6413 HRESULT hr = pDevice9If->CreatePixelShader((const DWORD *)pCode, &pShader);
6414 Assert(hr == S_OK);
6415 if (hr == S_OK)
6416 {
6417 Assert(pShader);
6418 pData->ShaderHandle = pShader;
6419 }
6420 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6421 return hr;
6422}
6423static HRESULT APIENTRY vboxWddmDDevDeletePixelShader(HANDLE hDevice, HANDLE hShaderHandle)
6424{
6425 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6426 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6427 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6428 Assert(pDevice);
6429 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
6430 HRESULT hr = S_OK;
6431 pShader->Release();
6432 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6433 return hr;
6434}
6435static HRESULT APIENTRY vboxWddmDDevCreateDecodeDevice(HANDLE hDevice, D3DDDIARG_CREATEDECODEDEVICE* pData)
6436{
6437 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6438 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6439 Assert(0);
6440 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6441 return E_FAIL;
6442}
6443static HRESULT APIENTRY vboxWddmDDevDestroyDecodeDevice(HANDLE hDevice, HANDLE hDecodeDevice)
6444{
6445 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6446 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6447 Assert(0);
6448 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6449 return E_FAIL;
6450}
6451static HRESULT APIENTRY vboxWddmDDevSetDecodeRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETDECODERENDERTARGET* pData)
6452{
6453 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6454 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6455 Assert(0);
6456 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6457 return E_FAIL;
6458}
6459static HRESULT APIENTRY vboxWddmDDevDecodeBeginFrame(HANDLE hDevice, D3DDDIARG_DECODEBEGINFRAME* pData)
6460{
6461 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6462 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6463 Assert(0);
6464 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6465 return E_FAIL;
6466}
6467static HRESULT APIENTRY vboxWddmDDevDecodeEndFrame(HANDLE hDevice, D3DDDIARG_DECODEENDFRAME* pData)
6468{
6469 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6470 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6471 Assert(0);
6472 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6473 return E_FAIL;
6474}
6475static HRESULT APIENTRY vboxWddmDDevDecodeExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXECUTE* pData)
6476{
6477 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6478 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6479 Assert(0);
6480 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6481 return E_FAIL;
6482}
6483static HRESULT APIENTRY vboxWddmDDevDecodeExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXTENSIONEXECUTE* pData)
6484{
6485 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6486 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6487 Assert(0);
6488 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6489 return E_FAIL;
6490}
6491static HRESULT APIENTRY vboxWddmDDevCreateVideoProcessDevice(HANDLE hDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE* pData)
6492{
6493 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6494 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6495 Assert(0);
6496 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6497 return E_FAIL;
6498}
6499static HRESULT APIENTRY vboxWddmDDevDestroyVideoProcessDevice(HANDLE hDevice, HANDLE hVideoProcessor)
6500{
6501 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6502 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6503 Assert(0);
6504 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6505 return E_FAIL;
6506}
6507static HRESULT APIENTRY vboxWddmDDevVideoProcessBeginFrame(HANDLE hDevice, HANDLE hVideoProcess)
6508{
6509 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6510 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6511 Assert(0);
6512 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6513 return E_FAIL;
6514}
6515static HRESULT APIENTRY vboxWddmDDevVideoProcessEndFrame(HANDLE hDevice, D3DDDIARG_VIDEOPROCESSENDFRAME* pData)
6516{
6517 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6518 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6519 Assert(0);
6520 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6521 return E_FAIL;
6522}
6523static HRESULT APIENTRY vboxWddmDDevSetVideoProcessRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETVIDEOPROCESSRENDERTARGET* pData)
6524{
6525 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6526 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6527 Assert(0);
6528 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6529 return E_FAIL;
6530}
6531static HRESULT APIENTRY vboxWddmDDevVideoProcessBlt(HANDLE hDevice, CONST D3DDDIARG_VIDEOPROCESSBLT* pData)
6532{
6533 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6534 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6535 Assert(0);
6536 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6537 return E_FAIL;
6538}
6539static HRESULT APIENTRY vboxWddmDDevCreateExtensionDevice(HANDLE hDevice, D3DDDIARG_CREATEEXTENSIONDEVICE* pData)
6540{
6541 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6542 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6543 Assert(0);
6544 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6545 return E_FAIL;
6546}
6547static HRESULT APIENTRY vboxWddmDDevDestroyExtensionDevice(HANDLE hDevice, HANDLE hExtension)
6548{
6549 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6550 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6551 Assert(0);
6552 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6553 return E_FAIL;
6554}
6555static HRESULT APIENTRY vboxWddmDDevExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_EXTENSIONEXECUTE* pData)
6556{
6557 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6558 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6559 Assert(0);
6560 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6561 return E_FAIL;
6562}
6563static HRESULT APIENTRY vboxWddmDDevDestroyDevice(IN HANDLE hDevice)
6564{
6565 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6566 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6567
6568 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6569 VBOXDISPPROFILE_DDI_DUMPRESET(pDevice);
6570 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
6571 if (VBOXDISPMODE_IS_3D(pAdapter))
6572 {
6573// Assert(!pDevice->cScreens);
6574 vboxWddmSwapchainDestroyAll(pDevice);
6575 pDevice->pDevice9If->Release();
6576 }
6577
6578 HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
6579 Assert(hr == S_OK);
6580 if (hr == S_OK)
6581 RTMemFree(pDevice);
6582 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6583 return hr;
6584}
6585
6586AssertCompile(sizeof (RECT) == sizeof (D3DDDIRECT));
6587AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DDDIRECT, left));
6588AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DDDIRECT, right));
6589AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DDDIRECT, top));
6590AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DDDIRECT, bottom));
6591AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DDDIRECT, left));
6592AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DDDIRECT, right));
6593AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DDDIRECT, top));
6594AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DDDIRECT, bottom));
6595
6596static HRESULT APIENTRY vboxWddmDDevCreateOverlay(HANDLE hDevice, D3DDDIARG_CREATEOVERLAY* pData)
6597{
6598 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6599 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6600 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6601 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
6602 Assert(pRc);
6603 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
6604 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
6605 HRESULT hr = S_OK;
6606 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)RTMemAllocZ(sizeof (VBOXWDDMDISP_OVERLAY));
6607 Assert(pOverlay);
6608 if (pOverlay)
6609 {
6610 VBOXWDDM_OVERLAY_INFO OurInfo;
6611 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
6612 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
6613 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
6614 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
6615 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
6616 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
6617 Assert(!pAlloc->LockInfo.cLocks);
6618 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
6619 D3DDDICB_CREATEOVERLAY OverInfo;
6620 OverInfo.VidPnSourceId = pData->VidPnSourceId;
6621 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
6622 Assert(pAlloc->hAllocation);
6623 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
6624 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
6625 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
6626 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
6627 OverInfo.hKernelOverlay = NULL; /* <-- out */
6628#ifndef VBOXWDDMOVERLAY_TEST
6629 hr = pDevice->RtCallbacks.pfnCreateOverlayCb(pDevice->hDevice, &OverInfo);
6630 Assert(hr == S_OK);
6631 if (hr == S_OK)
6632 {
6633 Assert(OverInfo.hKernelOverlay);
6634 pOverlay->hOverlay = OverInfo.hKernelOverlay;
6635 pOverlay->VidPnSourceId = pData->VidPnSourceId;
6636
6637 Assert(!pAlloc->LockInfo.cLocks);
6638 if (!pAlloc->LockInfo.cLocks)
6639 {
6640 /* we have reported the dirty rect, may clear it if no locks are pending currently */
6641 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
6642 }
6643
6644 pData->hOverlay = pOverlay;
6645 }
6646 else
6647 {
6648 RTMemFree(pOverlay);
6649 }
6650#else
6651 pData->hOverlay = pOverlay;
6652#endif
6653 }
6654 else
6655 hr = E_OUTOFMEMORY;
6656
6657 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6658 return hr;
6659}
6660static HRESULT APIENTRY vboxWddmDDevUpdateOverlay(HANDLE hDevice, CONST D3DDDIARG_UPDATEOVERLAY* pData)
6661{
6662 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6663 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6664 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6665 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
6666 Assert(pRc);
6667 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
6668 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
6669 HRESULT hr = S_OK;
6670 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
6671 VBOXWDDM_OVERLAY_INFO OurInfo;
6672 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
6673 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
6674 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
6675 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
6676 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
6677 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
6678 Assert(!pAlloc->LockInfo.cLocks);
6679 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
6680 D3DDDICB_UPDATEOVERLAY OverInfo;
6681 OverInfo.hKernelOverlay = pOverlay->hOverlay;
6682 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
6683 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
6684 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
6685 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
6686 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
6687#ifndef VBOXWDDMOVERLAY_TEST
6688 hr = pDevice->RtCallbacks.pfnUpdateOverlayCb(pDevice->hDevice, &OverInfo);
6689 Assert(hr == S_OK);
6690 if (hr == S_OK)
6691#endif
6692 {
6693 Assert(!pAlloc->LockInfo.cLocks);
6694 if (!pAlloc->LockInfo.cLocks)
6695 {
6696 /* we have reported the dirty rect, may clear it if no locks are pending currently */
6697 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
6698 }
6699 }
6700
6701 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6702 return hr;
6703}
6704static HRESULT APIENTRY vboxWddmDDevFlipOverlay(HANDLE hDevice, CONST D3DDDIARG_FLIPOVERLAY* pData)
6705{
6706 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6707 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6708 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6709 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSource;
6710 Assert(pRc);
6711 Assert(pRc->cAllocations > pData->SourceIndex);
6712 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SourceIndex];
6713 HRESULT hr = S_OK;
6714 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
6715 VBOXWDDM_OVERLAYFLIP_INFO OurInfo;
6716 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
6717 Assert(!pAlloc->LockInfo.cLocks);
6718 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
6719 D3DDDICB_FLIPOVERLAY OverInfo;
6720 OverInfo.hKernelOverlay = pOverlay->hOverlay;
6721 OverInfo.hSource = pAlloc->hAllocation;
6722 OverInfo.pPrivateDriverData = &OurInfo;
6723 OverInfo.PrivateDriverDataSize = sizeof (OurInfo);
6724#ifndef VBOXWDDMOVERLAY_TEST
6725 hr = pDevice->RtCallbacks.pfnFlipOverlayCb(pDevice->hDevice, &OverInfo);
6726 Assert(hr == S_OK);
6727 if (hr == S_OK)
6728#endif
6729 {
6730 Assert(!pAlloc->LockInfo.cLocks);
6731 if (!pAlloc->LockInfo.cLocks)
6732 {
6733 /* we have reported the dirty rect, may clear it if no locks are pending currently */
6734 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
6735 }
6736 }
6737
6738 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6739 return hr;
6740}
6741static HRESULT APIENTRY vboxWddmDDevGetOverlayColorControls(HANDLE hDevice, D3DDDIARG_GETOVERLAYCOLORCONTROLS* pData)
6742{
6743 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6744 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6745 Assert(0);
6746 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6747 return E_FAIL;
6748}
6749static HRESULT APIENTRY vboxWddmDDevSetOverlayColorControls(HANDLE hDevice, CONST D3DDDIARG_SETOVERLAYCOLORCONTROLS* pData)
6750{
6751 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6752 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6753 Assert(0);
6754 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6755 return E_FAIL;
6756}
6757static HRESULT APIENTRY vboxWddmDDevDestroyOverlay(HANDLE hDevice, CONST D3DDDIARG_DESTROYOVERLAY* pData)
6758{
6759 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6760 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6761 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6762 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
6763 D3DDDICB_DESTROYOVERLAY OverInfo;
6764 OverInfo.hKernelOverlay = pOverlay->hOverlay;
6765#ifndef VBOXWDDMOVERLAY_TEST
6766 HRESULT hr = pDevice->RtCallbacks.pfnDestroyOverlayCb(pDevice->hDevice, &OverInfo);
6767 Assert(hr == S_OK);
6768 if (hr == S_OK)
6769#else
6770 HRESULT hr = S_OK;
6771#endif
6772 {
6773 RTMemFree(pOverlay);
6774 }
6775
6776 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6777 return hr;
6778}
6779static HRESULT APIENTRY vboxWddmDDevQueryResourceResidency(HANDLE hDevice, CONST D3DDDIARG_QUERYRESOURCERESIDENCY* pData)
6780{
6781 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6782 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6783 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6784 Assert(0);
6785 HRESULT hr = S_OK;
6786#if 0
6787 for (UINT i = 0; i < pData->NumResources; ++i)
6788 {
6789 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->pHandleList[i];
6790 Assert(pRc->pDevice == pDevice);
6791 if (pRc->hKMResource)
6792 {
6793
6794 }
6795 }
6796#endif
6797 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6798 return hr;
6799}
6800
6801static HRESULT vboxAllocationInit(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DDDI_OPENALLOCATIONINFO *pInfo)
6802{
6803 HRESULT hr = S_OK;
6804 pAlloc->hAllocation = pInfo->hAllocation;
6805 Assert(pInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
6806 Assert(pInfo->pPrivateDriverData);
6807 if (pInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
6808 {
6809 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pInfo->pPrivateDriverData;
6810 pAlloc->enmType = pAllocInfo->enmType;
6811 Assert(pAllocInfo->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
6812 || VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE
6813 || VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE);
6814 pAlloc->pvMem = NULL;
6815 pAlloc->SurfDesc = pAllocInfo->SurfDesc;
6816 }
6817 else
6818 {
6819 vboxVDbgPrintR((__FUNCTION__": ERROR: PrivateDriverDataSize(%d) < (%d)\n", pInfo->PrivateDriverDataSize, sizeof (VBOXWDDM_ALLOCINFO)));
6820 hr = E_INVALIDARG;
6821 }
6822 return hr;
6823}
6824
6825static HRESULT APIENTRY vboxWddmDDevOpenResource(HANDLE hDevice, D3DDDIARG_OPENRESOURCE* pData)
6826{
6827 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6828 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6829 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6830 HRESULT hr = S_OK;
6831
6832 Assert(pDevice);
6833 Assert(pData->NumAllocations);
6834 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pData->NumAllocations);
6835 Assert(pRc);
6836 if (pRc)
6837 {
6838 pRc->hResource = pData->hResource;
6839 pRc->hKMResource = pData->hKMResource;
6840 pRc->pDevice = pDevice;
6841 pRc->RcDesc.enmRotation = pData->Rotation;
6842 pRc->fFlags = VBOXWDDM_RESOURCE_F_OPENNED;
6843 if (!pData->pPrivateDriverData || !pData->PrivateDriverDataSize)
6844 {
6845 /* this is a "standard" allocation resource */
6846
6847 /* both should be actually zero */
6848 Assert(!pData->pPrivateDriverData && !pData->PrivateDriverDataSize);
6849 pRc->RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
6850 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
6851 pRc->RcDesc.MultisampleQuality = 0;
6852 pRc->RcDesc.MipLevels = 0;
6853 pRc->RcDesc.Fvf;
6854 pRc->RcDesc.fFlags.Value = 0;
6855
6856 Assert(pData->NumAllocations);
6857 D3DDDI_OPENALLOCATIONINFO* pDdiAllocInfo = &pData->pOpenAllocationInfo[0];
6858 Assert(pDdiAllocInfo->pPrivateDriverData);
6859 Assert(pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO));
6860 if (pDdiAllocInfo->pPrivateDriverData && pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
6861 {
6862 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocInfo->pPrivateDriverData;
6863 switch(pAllocInfo->enmType)
6864 {
6865 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
6866 pRc->RcDesc.fFlags.Primary = 1;
6867 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
6868 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
6869 pRc->RcDesc.enmFormat = pAllocInfo->SurfDesc.format;
6870 pRc->RcDesc.VidPnSourceId = pAllocInfo->SurfDesc.VidPnSourceId;
6871 pRc->RcDesc.RefreshRate = pAllocInfo->SurfDesc.RefreshRate;
6872 break;
6873 default:
6874 Assert(0);
6875 hr = E_INVALIDARG;
6876 }
6877 }
6878 else
6879 hr = E_INVALIDARG;
6880 }
6881 else
6882 {
6883 /* this is a "generic" resource whose creation is initiaded by the UMD */
6884 Assert(pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
6885 if (pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO))
6886 {
6887 VBOXWDDM_RCINFO *pRcInfo = (VBOXWDDM_RCINFO*)pData->pPrivateDriverData;
6888 Assert(pRcInfo->fFlags == VBOXWDDM_RESOURCE_F_TYPE_GENERIC);
6889 Assert(pRcInfo->cAllocInfos == pData->NumAllocations);
6890 pRc->fFlags = pRcInfo->fFlags | VBOXWDDM_RESOURCE_F_OPENNED;
6891 pRc->RcDesc = pRcInfo->RcDesc;
6892 pRc->cAllocations = pData->NumAllocations;
6893
6894 for (UINT i = 0; i < pData->NumAllocations; ++i)
6895 {
6896 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
6897 D3DDDI_OPENALLOCATIONINFO* pOAI = pData->pOpenAllocationInfo;
6898 Assert(pOAI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
6899 if (pOAI->PrivateDriverDataSize != sizeof (VBOXWDDM_ALLOCINFO))
6900 {
6901 hr = E_INVALIDARG;
6902 break;
6903 }
6904 Assert(pOAI->pPrivateDriverData);
6905 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pOAI->pPrivateDriverData;
6906 pAllocation->hAllocation = pOAI->hAllocation;
6907 pAllocation->enmType = pAllocInfo->enmType;
6908 pAllocation->hSharedHandle = pAllocInfo->hSharedHandle;
6909 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
6910 Assert(pAllocation->hSharedHandle);
6911 }
6912
6913 Assert(pRc->RcDesc.fFlags.SharedResource);
6914 if (pRc->RcDesc.fFlags.Texture)
6915 {
6916 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6917 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
6918 IDirect3DTexture9 *pD3DIfTex;
6919 HANDLE hSharedHandle = pAllocation->hSharedHandle;
6920 Assert(pAllocation->hSharedHandle);
6921
6922 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
6923 pAllocation->SurfDesc.width,
6924 pAllocation->SurfDesc.height,
6925 pRc->cAllocations,
6926 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
6927 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
6928 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
6929 &pD3DIfTex,
6930 &hSharedHandle,
6931 NULL);
6932 Assert(hr == S_OK);
6933 if (hr == S_OK)
6934 {
6935 Assert(pD3DIfTex);
6936 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
6937 pAllocation->pD3DIf = pD3DIfTex;
6938 Assert(pAllocation->hSharedHandle == hSharedHandle);
6939 Assert(pAllocation->hSharedHandle);
6940 }
6941 }
6942 else
6943 {
6944 /* impl */
6945 Assert(0);
6946 }
6947 }
6948 else
6949 hr = E_INVALIDARG;
6950 }
6951
6952 if (hr == S_OK)
6953 {
6954 for (UINT i = 0; i < pData->NumAllocations; ++i)
6955 {
6956 hr = vboxAllocationInit(&pRc->aAllocations[i], &pData->pOpenAllocationInfo[i]);
6957 Assert(hr == S_OK);
6958 if (hr != S_OK)
6959 break;
6960 }
6961 }
6962
6963 if (hr == S_OK)
6964 pData->hResource = pRc;
6965 else
6966 vboxResourceFree(pRc);
6967 }
6968 else
6969 {
6970 vboxVDbgPrintR((__FUNCTION__": vboxResourceAlloc failed for hDevice(0x%p), NumAllocations(%d)\n", hDevice, pData->NumAllocations));
6971 hr = E_OUTOFMEMORY;
6972 }
6973
6974 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6975 return hr;
6976}
6977static HRESULT APIENTRY vboxWddmDDevGetCaptureAllocationHandle(HANDLE hDevice, D3DDDIARG_GETCAPTUREALLOCATIONHANDLE* pData)
6978{
6979 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6980 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6981 Assert(0);
6982 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6983 return E_FAIL;
6984}
6985
6986static HRESULT APIENTRY vboxWddmDDevCaptureToSysMem(HANDLE hDevice, CONST D3DDDIARG_CAPTURETOSYSMEM* pData)
6987{
6988 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6989 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6990 Assert(0);
6991 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6992 return E_FAIL;
6993}
6994
6995static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIARG_CREATEDEVICE* pCreateData)
6996{
6997 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6998 HRESULT hr = S_OK;
6999 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), Interface(%d), Version(%d)\n", hAdapter, pCreateData->Interface, pCreateData->Version));
7000
7001// Assert(0);
7002 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
7003
7004 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_DEVICE, apRTs[pAdapter->cMaxSimRTs]));
7005 if (pDevice)
7006 {
7007 pDevice->cRTs = pAdapter->cMaxSimRTs;
7008 pDevice->hDevice = pCreateData->hDevice;
7009 pDevice->pAdapter = pAdapter;
7010 pDevice->u32IfVersion = pCreateData->Interface;
7011 pDevice->uRtVersion = pCreateData->Version;
7012 pDevice->RtCallbacks = *pCreateData->pCallbacks;
7013 pDevice->pvCmdBuffer = pCreateData->pCommandBuffer;
7014 pDevice->cbCmdBuffer = pCreateData->CommandBufferSize;
7015 pDevice->fFlags = pCreateData->Flags;
7016 /* Set Viewport to some default values */
7017 pDevice->ViewPort.X = 0;
7018 pDevice->ViewPort.Y = 0;
7019 pDevice->ViewPort.Width = 1;
7020 pDevice->ViewPort.Height = 1;
7021 pDevice->ViewPort.MinZ = 0.;
7022 pDevice->ViewPort.MaxZ = 1.;
7023
7024 InitializeCriticalSection(&pDevice->DirtyAllocListLock);
7025 RTListInit(&pDevice->DirtyAllocList);
7026
7027 Assert(!pCreateData->AllocationListSize);
7028 Assert(!pCreateData->PatchLocationListSize);
7029
7030 pCreateData->hDevice = pDevice;
7031
7032 pCreateData->pDeviceFuncs->pfnSetRenderState = vboxWddmDDevSetRenderState;
7033 pCreateData->pDeviceFuncs->pfnUpdateWInfo = vboxWddmDDevUpdateWInfo;
7034 pCreateData->pDeviceFuncs->pfnValidateDevice = vboxWddmDDevValidateDevice;
7035 pCreateData->pDeviceFuncs->pfnSetTextureStageState = vboxWddmDDevSetTextureStageState;
7036 pCreateData->pDeviceFuncs->pfnSetTexture = vboxWddmDDevSetTexture;
7037 pCreateData->pDeviceFuncs->pfnSetPixelShader = vboxWddmDDevSetPixelShader;
7038 pCreateData->pDeviceFuncs->pfnSetPixelShaderConst = vboxWddmDDevSetPixelShaderConst;
7039 pCreateData->pDeviceFuncs->pfnSetStreamSourceUm = vboxWddmDDevSetStreamSourceUm;
7040 pCreateData->pDeviceFuncs->pfnSetIndices = vboxWddmDDevSetIndices;
7041 pCreateData->pDeviceFuncs->pfnSetIndicesUm = vboxWddmDDevSetIndicesUm;
7042 pCreateData->pDeviceFuncs->pfnDrawPrimitive = vboxWddmDDevDrawPrimitive;
7043 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive = vboxWddmDDevDrawIndexedPrimitive;
7044 pCreateData->pDeviceFuncs->pfnDrawRectPatch = vboxWddmDDevDrawRectPatch;
7045 pCreateData->pDeviceFuncs->pfnDrawTriPatch = vboxWddmDDevDrawTriPatch;
7046 pCreateData->pDeviceFuncs->pfnDrawPrimitive2 = vboxWddmDDevDrawPrimitive2;
7047 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive2 = vboxWddmDDevDrawIndexedPrimitive2;
7048 pCreateData->pDeviceFuncs->pfnVolBlt = vboxWddmDDevVolBlt;
7049 pCreateData->pDeviceFuncs->pfnBufBlt = vboxWddmDDevBufBlt;
7050 pCreateData->pDeviceFuncs->pfnTexBlt = vboxWddmDDevTexBlt;
7051 pCreateData->pDeviceFuncs->pfnStateSet = vboxWddmDDevStateSet;
7052 pCreateData->pDeviceFuncs->pfnSetPriority = vboxWddmDDevSetPriority;
7053 pCreateData->pDeviceFuncs->pfnClear = vboxWddmDDevClear;
7054 pCreateData->pDeviceFuncs->pfnUpdatePalette = vboxWddmDDevUpdatePalette;
7055 pCreateData->pDeviceFuncs->pfnSetPalette = vboxWddmDDevSetPalette;
7056 pCreateData->pDeviceFuncs->pfnSetVertexShaderConst = vboxWddmDDevSetVertexShaderConst;
7057 pCreateData->pDeviceFuncs->pfnMultiplyTransform = vboxWddmDDevMultiplyTransform;
7058 pCreateData->pDeviceFuncs->pfnSetTransform = vboxWddmDDevSetTransform;
7059 pCreateData->pDeviceFuncs->pfnSetViewport = vboxWddmDDevSetViewport;
7060 pCreateData->pDeviceFuncs->pfnSetZRange = vboxWddmDDevSetZRange;
7061 pCreateData->pDeviceFuncs->pfnSetMaterial = vboxWddmDDevSetMaterial;
7062 pCreateData->pDeviceFuncs->pfnSetLight = vboxWddmDDevSetLight;
7063 pCreateData->pDeviceFuncs->pfnCreateLight = vboxWddmDDevCreateLight;
7064 pCreateData->pDeviceFuncs->pfnDestroyLight = vboxWddmDDevDestroyLight;
7065 pCreateData->pDeviceFuncs->pfnSetClipPlane = vboxWddmDDevSetClipPlane;
7066 pCreateData->pDeviceFuncs->pfnGetInfo = vboxWddmDDevGetInfo;
7067 pCreateData->pDeviceFuncs->pfnLock = vboxWddmDDevLock;
7068 pCreateData->pDeviceFuncs->pfnUnlock = vboxWddmDDevUnlock;
7069 pCreateData->pDeviceFuncs->pfnCreateResource = vboxWddmDDevCreateResource;
7070 pCreateData->pDeviceFuncs->pfnDestroyResource = vboxWddmDDevDestroyResource;
7071 pCreateData->pDeviceFuncs->pfnSetDisplayMode = vboxWddmDDevSetDisplayMode;
7072 pCreateData->pDeviceFuncs->pfnPresent = vboxWddmDDevPresent;
7073 pCreateData->pDeviceFuncs->pfnFlush = vboxWddmDDevFlush;
7074 pCreateData->pDeviceFuncs->pfnCreateVertexShaderFunc = vboxWddmDDevCreateVertexShaderFunc;
7075 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderFunc = vboxWddmDDevDeleteVertexShaderFunc;
7076 pCreateData->pDeviceFuncs->pfnSetVertexShaderFunc = vboxWddmDDevSetVertexShaderFunc;
7077 pCreateData->pDeviceFuncs->pfnCreateVertexShaderDecl = vboxWddmDDevCreateVertexShaderDecl;
7078 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderDecl = vboxWddmDDevDeleteVertexShaderDecl;
7079 pCreateData->pDeviceFuncs->pfnSetVertexShaderDecl = vboxWddmDDevSetVertexShaderDecl;
7080 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstI = vboxWddmDDevSetVertexShaderConstI;
7081 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstB = vboxWddmDDevSetVertexShaderConstB;
7082 pCreateData->pDeviceFuncs->pfnSetScissorRect = vboxWddmDDevSetScissorRect;
7083 pCreateData->pDeviceFuncs->pfnSetStreamSource = vboxWddmDDevSetStreamSource;
7084 pCreateData->pDeviceFuncs->pfnSetStreamSourceFreq = vboxWddmDDevSetStreamSourceFreq;
7085 pCreateData->pDeviceFuncs->pfnSetConvolutionKernelMono = vboxWddmDDevSetConvolutionKernelMono;
7086 pCreateData->pDeviceFuncs->pfnComposeRects = vboxWddmDDevComposeRects;
7087 pCreateData->pDeviceFuncs->pfnBlt = vboxWddmDDevBlt;
7088 pCreateData->pDeviceFuncs->pfnColorFill = vboxWddmDDevColorFill;
7089 pCreateData->pDeviceFuncs->pfnDepthFill = vboxWddmDDevDepthFill;
7090 pCreateData->pDeviceFuncs->pfnCreateQuery = vboxWddmDDevCreateQuery;
7091 pCreateData->pDeviceFuncs->pfnDestroyQuery = vboxWddmDDevDestroyQuery;
7092 pCreateData->pDeviceFuncs->pfnIssueQuery = vboxWddmDDevIssueQuery;
7093 pCreateData->pDeviceFuncs->pfnGetQueryData = vboxWddmDDevGetQueryData;
7094 pCreateData->pDeviceFuncs->pfnSetRenderTarget = vboxWddmDDevSetRenderTarget;
7095 pCreateData->pDeviceFuncs->pfnSetDepthStencil = vboxWddmDDevSetDepthStencil;
7096 pCreateData->pDeviceFuncs->pfnGenerateMipSubLevels = vboxWddmDDevGenerateMipSubLevels;
7097 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstI = vboxWddmDDevSetPixelShaderConstI;
7098 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstB = vboxWddmDDevSetPixelShaderConstB;
7099 pCreateData->pDeviceFuncs->pfnCreatePixelShader = vboxWddmDDevCreatePixelShader;
7100 pCreateData->pDeviceFuncs->pfnDeletePixelShader = vboxWddmDDevDeletePixelShader;
7101 pCreateData->pDeviceFuncs->pfnCreateDecodeDevice = vboxWddmDDevCreateDecodeDevice;
7102 pCreateData->pDeviceFuncs->pfnDestroyDecodeDevice = vboxWddmDDevDestroyDecodeDevice;
7103 pCreateData->pDeviceFuncs->pfnSetDecodeRenderTarget = vboxWddmDDevSetDecodeRenderTarget;
7104 pCreateData->pDeviceFuncs->pfnDecodeBeginFrame = vboxWddmDDevDecodeBeginFrame;
7105 pCreateData->pDeviceFuncs->pfnDecodeEndFrame = vboxWddmDDevDecodeEndFrame;
7106 pCreateData->pDeviceFuncs->pfnDecodeExecute = vboxWddmDDevDecodeExecute;
7107 pCreateData->pDeviceFuncs->pfnDecodeExtensionExecute = vboxWddmDDevDecodeExtensionExecute;
7108 pCreateData->pDeviceFuncs->pfnCreateVideoProcessDevice = vboxWddmDDevCreateVideoProcessDevice;
7109 pCreateData->pDeviceFuncs->pfnDestroyVideoProcessDevice = vboxWddmDDevDestroyVideoProcessDevice;
7110 pCreateData->pDeviceFuncs->pfnVideoProcessBeginFrame = vboxWddmDDevVideoProcessBeginFrame;
7111 pCreateData->pDeviceFuncs->pfnVideoProcessEndFrame = vboxWddmDDevVideoProcessEndFrame;
7112 pCreateData->pDeviceFuncs->pfnSetVideoProcessRenderTarget = vboxWddmDDevSetVideoProcessRenderTarget;
7113 pCreateData->pDeviceFuncs->pfnVideoProcessBlt = vboxWddmDDevVideoProcessBlt;
7114 pCreateData->pDeviceFuncs->pfnCreateExtensionDevice = vboxWddmDDevCreateExtensionDevice;
7115 pCreateData->pDeviceFuncs->pfnDestroyExtensionDevice = vboxWddmDDevDestroyExtensionDevice;
7116 pCreateData->pDeviceFuncs->pfnExtensionExecute = vboxWddmDDevExtensionExecute;
7117 pCreateData->pDeviceFuncs->pfnCreateOverlay = vboxWddmDDevCreateOverlay;
7118 pCreateData->pDeviceFuncs->pfnUpdateOverlay = vboxWddmDDevUpdateOverlay;
7119 pCreateData->pDeviceFuncs->pfnFlipOverlay = vboxWddmDDevFlipOverlay;
7120 pCreateData->pDeviceFuncs->pfnGetOverlayColorControls = vboxWddmDDevGetOverlayColorControls;
7121 pCreateData->pDeviceFuncs->pfnSetOverlayColorControls = vboxWddmDDevSetOverlayColorControls;
7122 pCreateData->pDeviceFuncs->pfnDestroyOverlay = vboxWddmDDevDestroyOverlay;
7123 pCreateData->pDeviceFuncs->pfnDestroyDevice = vboxWddmDDevDestroyDevice;
7124 pCreateData->pDeviceFuncs->pfnQueryResourceResidency = vboxWddmDDevQueryResourceResidency;
7125 pCreateData->pDeviceFuncs->pfnOpenResource = vboxWddmDDevOpenResource;
7126 pCreateData->pDeviceFuncs->pfnGetCaptureAllocationHandle = vboxWddmDDevGetCaptureAllocationHandle;
7127 pCreateData->pDeviceFuncs->pfnCaptureToSysMem = vboxWddmDDevCaptureToSysMem;
7128 pCreateData->pDeviceFuncs->pfnLockAsync = NULL; //vboxWddmDDevLockAsync;
7129 pCreateData->pDeviceFuncs->pfnUnlockAsync = NULL; //vboxWddmDDevUnlockAsync;
7130 pCreateData->pDeviceFuncs->pfnRename = NULL; //vboxWddmDDevRename;
7131
7132
7133 do
7134 {
7135 RTListInit(&pDevice->SwapchainList);
7136 Assert(!pCreateData->AllocationListSize
7137 && !pCreateData->PatchLocationListSize);
7138 if (!pCreateData->AllocationListSize
7139 && !pCreateData->PatchLocationListSize)
7140 {
7141 hr = vboxUhgsmiD3DInit(&pDevice->Uhgsmi, pDevice);
7142 Assert(hr == S_OK);
7143 if (hr == S_OK)
7144 {
7145 hr = vboxDispCmCtxCreate(pDevice, &pDevice->DefaultContext);
7146 Assert(hr == S_OK);
7147 if (hr == S_OK)
7148 {
7149 #ifdef VBOXDISP_EARLYCREATEDEVICE
7150 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);
7151 Assert(pRc);
7152 if (pRc)
7153 {
7154 D3DPRESENT_PARAMETERS params;
7155 memset(&params, 0, sizeof (params));
7156 // params.BackBufferWidth = 640;
7157 // params.BackBufferHeight = 480;
7158 params.BackBufferWidth = 0x400;
7159 params.BackBufferHeight = 0x300;
7160 params.BackBufferFormat = D3DFMT_A8R8G8B8;
7161 // params.BackBufferCount = 0;
7162 params.BackBufferCount = 1;
7163 params.MultiSampleType = D3DMULTISAMPLE_NONE;
7164 params.SwapEffect = D3DSWAPEFFECT_DISCARD;
7165 // params.hDeviceWindow = hWnd;
7166 /* @todo: it seems there should be a way to detect this correctly since
7167 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
7168 params.Windowed = TRUE;
7169 // params.EnableAutoDepthStencil = FALSE;
7170 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
7171 // params.Flags;
7172 // params.FullScreen_RefreshRateInHz;
7173 // params.FullScreen_PresentationInterval;
7174
7175 hr = vboxWddmD3DDeviceCreate(pDevice, 0, pRc, &params, TRUE /*BOOL bLockable*/);
7176 Assert(hr == S_OK);
7177 if (hr == S_OK)
7178 break;
7179 vboxResourceFree(pRc);
7180 }
7181 else
7182 {
7183 hr = E_OUTOFMEMORY;
7184 }
7185 #else
7186 //# define VBOXDISP_TEST_SWAPCHAIN
7187 # ifdef VBOXDISP_TEST_SWAPCHAIN
7188 VBOXDISP_D3DEV(pDevice);
7189 # endif
7190 break;
7191 #endif
7192
7193 HRESULT tmpHr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
7194 Assert(tmpHr == S_OK);
7195 }
7196 }
7197 }
7198 else
7199 {
7200 vboxVDbgPrintR((__FUNCTION__": Not implemented: PatchLocationListSize(%d), AllocationListSize(%d)\n",
7201 pCreateData->PatchLocationListSize, pCreateData->AllocationListSize));
7202 //pCreateData->pAllocationList = ??
7203 hr = E_FAIL;
7204 }
7205
7206 RTMemFree(pDevice);
7207 } while (0);
7208 }
7209 else
7210 {
7211 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
7212 hr = E_OUTOFMEMORY;
7213 }
7214
7215 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7216
7217 return hr;
7218}
7219
7220static HRESULT APIENTRY vboxWddmDispCloseAdapter (IN HANDLE hAdapter)
7221{
7222 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7223 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7224
7225// Assert(0);
7226
7227 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
7228 if (VBOXDISPMODE_IS_3D(pAdapter))
7229 {
7230 HRESULT hr = VBoxDispWorkerDestroy(&pAdapter->WndWorker);
7231 Assert(hr == S_OK);
7232 pAdapter->pD3D9If->Release();
7233 VBoxDispD3DClose(&pAdapter->D3D);
7234 }
7235
7236 vboxCapsFree(pAdapter);
7237
7238 RTMemFree(pAdapter);
7239
7240 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7241
7242 return S_OK;
7243}
7244
7245HRESULT APIENTRY OpenAdapter (__inout D3DDDIARG_OPENADAPTER* pOpenData)
7246{
7247 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7248 vboxVDbgPrint(("==> "__FUNCTION__"\n"));
7249
7250// vboxDispLock();
7251
7252 HRESULT hr = E_FAIL;
7253
7254 do
7255 {
7256
7257 VBOXWDDM_QI Query;
7258 D3DDDICB_QUERYADAPTERINFO DdiQuery;
7259 DdiQuery.PrivateDriverDataSize = sizeof(Query);
7260 DdiQuery.pPrivateDriverData = &Query;
7261 hr = pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb(pOpenData->hAdapter, &DdiQuery);
7262 Assert(hr == S_OK);
7263 if (hr != S_OK)
7264 {
7265 vboxVDbgPrintR((__FUNCTION__": pfnQueryAdapterInfoCb failed, hr (%d)\n", hr));
7266 hr = E_FAIL;
7267 break;
7268 }
7269
7270 /* check the miniport version match display version */
7271 if (Query.u32Version != VBOXVIDEOIF_VERSION)
7272 {
7273 vboxVDbgPrintR((__FUNCTION__": miniport version mismatch, expected (%d), but was (%d)\n",
7274 VBOXVIDEOIF_VERSION,
7275 Query.u32Version));
7276 hr = E_FAIL;
7277 break;
7278 }
7279
7280#ifdef VBOX_WITH_VIDEOHWACCEL
7281 Assert(Query.cInfos >= 1);
7282 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_ADAPTER, aHeads[Query.cInfos]));
7283#else
7284 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(sizeof (VBOXWDDMDISP_ADAPTER));
7285#endif
7286 Assert(pAdapter);
7287 if (pAdapter)
7288 {
7289 pAdapter->hAdapter = pOpenData->hAdapter;
7290 pAdapter->uIfVersion = pOpenData->Interface;
7291 pAdapter->uRtVersion= pOpenData->Version;
7292 pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
7293
7294 pAdapter->cHeads = Query.cInfos;
7295
7296
7297 pOpenData->hAdapter = pAdapter;
7298 pOpenData->pAdapterFuncs->pfnGetCaps = vboxWddmDispGetCaps;
7299 pOpenData->pAdapterFuncs->pfnCreateDevice = vboxWddmDispCreateDevice;
7300 pOpenData->pAdapterFuncs->pfnCloseAdapter = vboxWddmDispCloseAdapter;
7301 pOpenData->DriverVersion = D3D_UMD_INTERFACE_VERSION;
7302 /*
7303 * here we detect whether we are called by the d3d or ddraw.
7304 * in the d3d case we init our d3d environment
7305 * in the ddraw case we init 2D acceleration
7306 * if interface version is > 7, this is D3D, treat it as so
7307 * otherwise treat it as ddraw
7308 * @todo: need a more clean way of doing this */
7309
7310 if (pAdapter->uIfVersion > 7)
7311 {
7312 do
7313 {
7314 /* try enable the 3D */
7315 hr = VBoxDispD3DOpen(&pAdapter->D3D);
7316 Assert(hr == S_OK);
7317 if (hr == S_OK)
7318 {
7319// Assert(0);
7320 hr = pAdapter->D3D.pfnDirect3DCreate9Ex(D3D_SDK_VERSION, &pAdapter->pD3D9If);
7321 Assert(hr == S_OK);
7322 if (hr == S_OK)
7323 {
7324 D3DCAPS9 Caps;
7325 memset(&Caps, 0, sizeof (Caps));
7326 hr = vboxWddmGetD3D9Caps(pAdapter, &Caps);
7327 Assert(hr == S_OK);
7328 if (hr == S_OK)
7329 {
7330 pAdapter->cMaxSimRTs = Caps.NumSimultaneousRTs;
7331 Assert(pAdapter->cMaxSimRTs);
7332 Assert(pAdapter->cMaxSimRTs < UINT32_MAX/2);
7333 hr = VBoxDispWorkerCreate(&pAdapter->WndWorker);
7334 Assert(hr == S_OK);
7335 if (hr == S_OK)
7336 {
7337 vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
7338 break;
7339 }
7340 }
7341 pAdapter->pD3D9If->Release();
7342 }
7343 else
7344 vboxVDbgPrintR((__FUNCTION__": pfnDirect3DCreate9Ex failed, hr (%d)\n", hr));
7345 VBoxDispD3DClose(&pAdapter->D3D);
7346 }
7347 else
7348 vboxVDbgPrintR((__FUNCTION__": VBoxDispD3DOpen failed, hr (%d)\n", hr));
7349 } while (0);
7350 }
7351#ifdef VBOX_WITH_VIDEOHWACCEL
7352 else
7353 {
7354 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
7355 {
7356 pAdapter->aHeads[i].Vhwa.Settings = Query.aInfos[i];
7357 }
7358 }
7359#endif
7360
7361 vboxCapsInit(pAdapter);
7362 hr = S_OK;
7363// RTMemFree(pAdapter);
7364 }
7365 else
7366 {
7367 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
7368 hr = E_OUTOFMEMORY;
7369 }
7370
7371 } while (0);
7372
7373// vboxDispUnlock();
7374
7375 vboxVDbgPrint(("<== "__FUNCTION__", hr (%d)\n", hr));
7376
7377 return hr;
7378}
7379
7380#ifdef VBOXWDDMDISP_DEBUG_PRINT
7381VOID vboxVDbgDoMpPrint(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString)
7382{
7383 uint32_t cbString = strlen(szString) + 1;
7384 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
7385 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
7386 Assert(pCmd);
7387 if (pCmd)
7388 {
7389 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
7390 memcpy(pCmd->aStringBuf, szString, cbString);
7391
7392 D3DDDICB_ESCAPE DdiEscape = {0};
7393 DdiEscape.hContext = NULL;
7394 DdiEscape.hDevice = NULL;
7395 DdiEscape.Flags.Value = 0;
7396 DdiEscape.pPrivateDriverData = pCmd;
7397 DdiEscape.PrivateDriverDataSize = cbCmd;
7398
7399 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
7400 Assert(hr == S_OK);
7401
7402 RTMemFree(pCmd);
7403 }
7404}
7405VOID vboxVDbgDoMpPrintF(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString, ...)
7406{
7407 char szBuffer[4096] = {0};
7408 va_list pArgList;
7409 va_start(pArgList, szString);
7410 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
7411 va_end(pArgList);
7412
7413 if (pDevice)
7414 {
7415 vboxVDbgDoMpPrint(pDevice, szBuffer);
7416 }
7417 else
7418 {
7419 OutputDebugStringA(szBuffer);
7420 }
7421}
7422VOID vboxVDbgDoPrint(LPCSTR szString, ...)
7423{
7424 char szBuffer[1024] = {0};
7425 va_list pArgList;
7426 va_start(pArgList, szString);
7427 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
7428 va_end(pArgList);
7429
7430 OutputDebugStringA(szBuffer);
7431}
7432#endif
7433
7434#ifdef VBOXWDDMDISP_DEBUG
7435
7436bool g_VDbgTstDumpEnable = false;
7437bool g_VDbgTstDumpOnSys2VidSameSizeEnable = false;
7438
7439VOID vboxVDbgDoDumpSurfData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const RECT *pRect, IDirect3DSurface9 *pSurf, const char* pSuffix)
7440{
7441 if (pPrefix)
7442 {
7443 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
7444 }
7445
7446 Assert(pRc->cAllocations > iAlloc);
7447 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
7448
7449 vboxVDbgMpPrintAlloc((pDevice, "allocation info:\n", pRc, iAlloc, "\n"));
7450
7451 D3DLOCKED_RECT Lr;
7452 if (pRect)
7453 {
7454 Assert(pRect->right > pRect->left);
7455 Assert(pRect->bottom > pRect->top);
7456 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
7457 }
7458
7459 BOOL bReleaseSurf = false;
7460 if (!pSurf)
7461 {
7462 HRESULT tmpHr = vboxWddmSurfGet(pRc, iAlloc, &pSurf);
7463 Assert(tmpHr == S_OK);
7464 bReleaseSurf = TRUE;
7465 }
7466 HRESULT srcHr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
7467 Assert(srcHr == S_OK);
7468 if (srcHr == S_OK)
7469 {
7470 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
7471// Assert(bpp == pAlloc->SurfDesc.bpp);
7472// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
7473 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
7474 Lr.pBits, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, Lr.Pitch));
7475 if (pRect)
7476 {
7477 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
7478 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
7479 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
7480 }
7481 Assert(0);
7482
7483 srcHr = pSurf->UnlockRect();
7484 Assert(srcHr == S_OK);
7485 }
7486 if (pSuffix)
7487 {
7488 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
7489 }
7490
7491 if (bReleaseSurf)
7492 pSurf->Release();
7493}
7494
7495VOID vboxVDbgDoDumpSurfDataBySurf(const PVBOXWDDMDISP_DEVICE pDevice, IDirect3DSurface9 *pSurf)
7496{
7497 D3DSURFACE_DESC Desc;
7498 HRESULT hr = pSurf->GetDesc(&Desc);
7499 Assert(hr == S_OK);
7500 if (hr == S_OK)
7501 {
7502 D3DLOCKED_RECT Lr;
7503 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
7504 Assert(hr == S_OK);
7505 if (hr == S_OK)
7506 {
7507 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
7508 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
7509 Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch));
7510
7511 Assert(0);
7512
7513 hr = pSurf->UnlockRect();
7514 Assert(hr == S_OK);
7515 }
7516 }
7517}
7518
7519void vboxVDbgDoMpPrintAlloc(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
7520{
7521 Assert(pRc->cAllocations > iAlloc);
7522 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
7523 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
7524 BOOL bFrontBuf = FALSE;
7525 if (bPrimary)
7526 {
7527 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
7528 Assert(pSwapchain);
7529 bFrontBuf = (vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc);
7530 }
7531 vboxVDbgDoMpPrintF(pDevice, "%s D3DWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
7532 pAlloc->D3DWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
7533 bPrimary ?
7534 (bFrontBuf ? "Front Buffer" : "Back Buffer")
7535 : "?Everage? Alloc",
7536 pSuffix);
7537}
7538
7539void vboxVDbgDoMpPrintRect(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const RECT *pRect, const char * pSuffix)
7540{
7541 vboxVDbgDoMpPrintF(pDevice, "%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix);
7542}
7543
7544static PVOID g_VBoxWDbgVEHandler = NULL;
7545LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
7546{
7547 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
7548 PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
7549 switch (pExceptionRecord->ExceptionCode)
7550 {
7551 case 0x40010006: /* <- OutputDebugString exception, ignore */
7552 case 0xe06d7363: /* <- ms compiler - generated exception related to C++ exception */
7553 break;
7554 default:
7555 Assert(0);
7556 break;
7557 }
7558 return EXCEPTION_CONTINUE_SEARCH;
7559}
7560
7561void vboxVDbgVEHandlerRegister()
7562{
7563 Assert(!g_VBoxWDbgVEHandler);
7564 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
7565 Assert(g_VBoxWDbgVEHandler);
7566}
7567
7568void vboxVDbgVEHandlerUnregister()
7569{
7570 Assert(g_VBoxWDbgVEHandler);
7571 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
7572 Assert(uResult);
7573 g_VBoxWDbgVEHandler = NULL;
7574}
7575
7576#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