VirtualBox

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

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

wddm/3d: [partial] fix to the first black frame with Aero on Win7

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