VirtualBox

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

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

wddm/3d: display resize when aero is on (autoresize not working with aero yet)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 283.7 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 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[iRt];
1827 HRESULT hr = pSwapchain->pSwapChainIf->GetBackBuffer(iBb, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
1828 Assert(hr == S_OK);
1829 if (hr == S_OK)
1830 {
1831 PVBOXWDDMDISP_ALLOCATION pAlloc = pRt->pAlloc;
1832 Assert(pD3D9Surf);
1833 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
1834 if (pAlloc->pD3DIf)
1835 {
1836 if (pSwapchain->fFlags.bChanged)
1837 {
1838 IDirect3DSurface9 *pD3D9OldSurf = (IDirect3DSurface9*)pAlloc->pD3DIf;
1839 if (pD3D9OldSurf && pD3D9OldSurf != pD3D9Surf)
1840 {
1841 Assert(0);
1842 hr = pDevice->pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9Surf, NULL, D3DTEXF_NONE);
1843 Assert(hr == S_OK);
1844 }
1845 }
1846 pAlloc->pD3DIf->Release();
1847 }
1848 pAlloc->pD3DIf = pD3D9Surf;
1849 pRt->fFlags.Value = 0;
1850
1851 if (pSwapchain->fFlags.bChanged)
1852 {
1853 for (UINT i = 0; i < pDevice->cRTs; ++i)
1854 {
1855 if (pDevice->apRTs[i] == pAlloc)
1856 {
1857 hr = vboxWddmRenderTargetSet(pDevice, i, pAlloc, TRUE);
1858 Assert(hr == S_OK);
1859 }
1860 }
1861 }
1862 }
1863 return hr;
1864}
1865
1866static HRESULT vboxWddmSwapchainSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1867{
1868 HRESULT hr = S_OK;
1869 if (pSwapchain->cRTs > 1)
1870 {
1871 for (int iBb = -1; iBb < int(pSwapchain->cRTs - 1); ++iBb)
1872 {
1873 hr = vboxWddmSwapchainRtSynch(pDevice, pSwapchain, (UINT)iBb);
1874 Assert(hr == S_OK);
1875 }
1876 }
1877 else
1878 {
1879 /* work-around wine backbuffer */
1880 hr = vboxWddmSwapchainRtSynch(pDevice, pSwapchain, 0);
1881 Assert(hr == S_OK);
1882 }
1883
1884 if (pSwapchain->fFlags.bChanged)
1885 {
1886 hr = vboxWddmSwapchainKmSynch(pDevice, pSwapchain);
1887 if (hr == S_OK)
1888 {
1889 pSwapchain->fFlags.bChanged = 0;
1890 }
1891 }
1892 return hr;
1893}
1894
1895static VOID vboxWddmSwapchainFillParams(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, D3DPRESENT_PARAMETERS *pParams)
1896{
1897 memset(pParams, 0, sizeof (D3DPRESENT_PARAMETERS));
1898 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pSwapchain);
1899 PVBOXWDDMDISP_RESOURCE pRc = pRt->pAlloc->pRc;
1900 pParams->BackBufferWidth = pRt->pAlloc->SurfDesc.width;
1901 pParams->BackBufferHeight = pRt->pAlloc->SurfDesc.height;
1902 pParams->BackBufferFormat = vboxDDI2D3DFormat(pRt->pAlloc->SurfDesc.format);
1903 pParams->BackBufferCount = pSwapchain->cRTs - 1;
1904 pParams->MultiSampleType = vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType);
1905 pParams->MultiSampleQuality = pRc->RcDesc.MultisampleQuality;
1906 if (pRc->RcDesc.fFlags.DiscardRenderTarget)
1907 pParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
1908}
1909
1910static HRESULT vboxWddmSwapchainChkCreateIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1911{
1912 if (!pSwapchain->fFlags.bChanged && pSwapchain->pSwapChainIf)
1913 return S_OK;
1914 /* preserve the old one */
1915 IDirect3DSwapChain9 * pOldIf = pSwapchain->pSwapChainIf;
1916 HRESULT hr = S_OK;
1917 BOOL bReuseSwapchain = FALSE;
1918 D3DPRESENT_PARAMETERS Params;
1919 vboxWddmSwapchainFillParams(pSwapchain, &Params);
1920 /* check if we need to re-create the swapchain */
1921 if (pOldIf)
1922 {
1923 D3DPRESENT_PARAMETERS OldParams;
1924 hr = pOldIf->GetPresentParameters(&OldParams);
1925 Assert(hr == S_OK);
1926 if (hr == S_OK)
1927 {
1928 if (OldParams.BackBufferCount == Params.BackBufferCount)
1929 {
1930 bReuseSwapchain = TRUE;
1931 }
1932 }
1933 }
1934
1935 /* first create the new one */
1936 IDirect3DSwapChain9 * pNewIf;
1937 ///
1938 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
1939 UINT cSurfs = pSwapchain->cRTs;
1940 IDirect3DDevice9 *pDevice9If = NULL;
1941 HWND hOldWnd = pSwapchain->hWnd;
1942 if (!bReuseSwapchain)
1943 {
1944//#define VBOXDISP_NEWWND_ON_SWAPCHAINUPDATE
1945#ifndef VBOXDISP_NEWWND_ON_SWAPCHAINUPDATE
1946 if (!hOldWnd)
1947#endif
1948 {
1949 hr = VBoxDispWndCreate(pAdapter, Params.BackBufferWidth, Params.BackBufferHeight, &pSwapchain->hWnd);
1950 Assert(hr == S_OK);
1951 }
1952 if (hr == S_OK)
1953 {
1954 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
1955 if (pDevice->fFlags.AllowMultithreading)
1956 fFlags |= D3DCREATE_MULTITHREADED;
1957
1958 Params.hDeviceWindow = pSwapchain->hWnd;
1959 /* @todo: it seems there should be a way to detect this correctly since
1960 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
1961 Params.Windowed = TRUE;
1962 // params.EnableAutoDepthStencil = FALSE;
1963 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
1964 // params.Flags;
1965 // params.FullScreen_RefreshRateInHz;
1966 // params.FullScreen_PresentationInterval;
1967 if (!pDevice->pDevice9If)
1968 {
1969 hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pSwapchain->hWnd, fFlags, &Params, &pDevice9If);
1970 Assert(hr == S_OK);
1971 if (hr == S_OK)
1972 {
1973 pDevice->pDevice9If = pDevice9If;
1974 hr = pDevice9If->GetSwapChain(0, &pNewIf);
1975 Assert(hr == S_OK);
1976 if (hr == S_OK)
1977 {
1978 Assert(pNewIf);
1979 }
1980 else
1981 {
1982 pDevice9If->Release();
1983 }
1984 }
1985 }
1986 else
1987 {
1988 pDevice9If = pDevice->pDevice9If;
1989 hr = pDevice->pDevice9If->CreateAdditionalSwapChain(&Params, &pNewIf);
1990 Assert(hr == S_OK);
1991 if (hr == S_OK)
1992 {
1993 Assert(pNewIf);
1994 }
1995 }
1996 }
1997 }
1998 else
1999 {
2000 Assert(pOldIf);
2001 Assert(hOldWnd);
2002 pNewIf = pOldIf;
2003 /* to ensure the swapchain is not deleted once we release the pOldIf */
2004 pNewIf->AddRef();
2005 }
2006
2007 if (hr == S_OK)
2008 {
2009 Assert(pNewIf);
2010 pSwapchain->pSwapChainIf = pNewIf;
2011#ifndef VBOXWDDM_WITH_VISIBLE_FB
2012 if (!pSwapchain->pRenderTargetFbCopy)
2013 {
2014 IDirect3DSurface9* pD3D9Surf;
2015 hr = pDevice9If->CreateRenderTarget(
2016 Params.BackBufferWidth, Params.BackBufferHeight,
2017 Params.BackBufferFormat,
2018 Params.MultiSampleType,
2019 Params.MultiSampleQuality,
2020 TRUE, /*bLockable*/
2021 &pD3D9Surf,
2022 NULL /* HANDLE* pSharedHandle */
2023 );
2024 Assert(hr == S_OK);
2025 if (hr == S_OK)
2026 {
2027 Assert(pD3D9Surf);
2028 pSwapchain->pRenderTargetFbCopy = pD3D9Surf;
2029 }
2030 }
2031#endif
2032
2033 if (hr == S_OK)
2034 {
2035 for (UINT i = 0; i < cSurfs; ++i)
2036 {
2037 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[i];
2038 pRt->pAlloc->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2039 }
2040
2041 hr = vboxWddmSwapchainSynch(pDevice, pSwapchain);
2042 Assert(hr == S_OK);
2043 if (hr == S_OK)
2044 {
2045 for (UINT i = 0; i < cSurfs; ++i)
2046 {
2047 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[i];
2048 hr = vboxWddmSurfSynchMem(pRt->pAlloc->pRc, pRt->pAlloc);
2049 Assert(hr == S_OK);
2050 if (hr != S_OK)
2051 {
2052 break;
2053 }
2054 }
2055
2056 Assert(hr == S_OK);
2057 if (hr == S_OK)
2058 {
2059 Assert(pSwapchain->fFlags.Value == 0);
2060 if (pOldIf)
2061 {
2062 Assert(hOldWnd);
2063 pOldIf->Release();
2064 if (hOldWnd != pSwapchain->hWnd)
2065 {
2066 VBoxDispWndDestroy(pAdapter, hOldWnd);
2067 }
2068 }
2069 else
2070 {
2071 Assert(!hOldWnd);
2072 }
2073 return S_OK;
2074 }
2075 }
2076 pNewIf->Release();
2077 pSwapchain->pSwapChainIf = pOldIf;
2078 }
2079
2080 Assert(hr != S_OK);
2081 if (hOldWnd != pSwapchain->hWnd)
2082 {
2083 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pSwapchain->hWnd);
2084 Assert(tmpHr == S_OK);
2085 pSwapchain->hWnd = hOldWnd;
2086 }
2087 }
2088
2089 return hr;
2090}
2091
2092static HRESULT vboxWddmSwapchainCreateIfForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, PVBOXWDDMDISP_SWAPCHAIN *ppSwapchain)
2093{
2094 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainCreateForRc(pDevice, pRc);
2095 Assert(pSwapchain);
2096 *ppSwapchain = NULL;
2097 if (pSwapchain)
2098 {
2099 HRESULT hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
2100 Assert(hr == S_OK);
2101 if (hr == S_OK)
2102 {
2103 *ppSwapchain = pSwapchain;
2104 }
2105 return hr;
2106 }
2107 return E_OUTOFMEMORY;
2108}
2109
2110static HRESULT vboxWddmSwapchainPresentPerform(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
2111{
2112 HRESULT hr = pSwapchain->pSwapChainIf->Present(NULL, NULL, NULL, NULL, 0);
2113 Assert(hr == S_OK);
2114 if (hr == S_OK)
2115 {
2116 vboxWddmSwapchainFlip(pSwapchain);
2117 Assert(pSwapchain->fFlags.Value == 0);
2118 hr = vboxWddmSwapchainSynch(pDevice, pSwapchain);
2119 Assert(hr == S_OK);
2120 }
2121 return hr;
2122}
2123
2124static HRESULT vboxWddmSwapchainPresent(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc)
2125{
2126 BOOL bChanged = FALSE;
2127 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainFindCreate(pDevice, pBbAlloc);
2128 Assert(pSwapchain);
2129 if (pSwapchain)
2130 {
2131 HRESULT hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
2132 Assert(hr == S_OK);
2133 if (hr == S_OK)
2134 {
2135 hr = vboxWddmSwapchainPresentPerform(pDevice, pSwapchain);
2136 Assert(hr == S_OK);
2137 }
2138 return hr;
2139 }
2140 return E_OUTOFMEMORY;
2141}
2142
2143#if 0 //def DEBUG
2144static void vboxWddmDbgRenderTargetUpdateCheckSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf)
2145{
2146 IDirect3DSurface9 *pD3D9Surf;
2147 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
2148 IDirect3DDevice9 * pDevice9If = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
2149 HRESULT hr = pDevice9If->GetBackBuffer(0 /*UINT iSwapChain*/,
2150 iBBuf, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
2151 Assert(hr == S_OK);
2152 if (hr == S_OK)
2153 {
2154 Assert(pD3D9Surf);
2155 Assert(pD3D9Surf == pAlloc->pD3DIf);
2156 pD3D9Surf->Release();
2157 }
2158}
2159
2160static void vboxWddmDbgRenderTargetCheck(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB)
2161{
2162 PVBOXWDDMDISP_ALLOCATION pAlloc;
2163 UINT iBBuf = 0;
2164 Assert(iNewRTFB < pRc->cAllocations);
2165
2166 for (UINT i = 1; i < pRc->cAllocations; ++i, ++iBBuf)
2167 {
2168 UINT iAlloc = (iNewRTFB + i) % pRc->cAllocations;
2169 Assert(iAlloc != iNewRTFB);
2170 pAlloc = &pRc->aAllocations[iAlloc];
2171 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, iBBuf);
2172 }
2173
2174 pAlloc = &pRc->aAllocations[iNewRTFB];
2175#ifdef VBOXWDDM_WITH_VISIBLE_FB
2176 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, ~0UL /* <- for the frontbuffer */);
2177#else
2178 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));
2179#endif
2180
2181 for (UINT i = 0; i < pRc->cAllocations; ++i)
2182 {
2183 pAlloc = &pRc->aAllocations[i];
2184 if (iNewRTFB == i)
2185 {
2186 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));
2187 }
2188
2189 for (UINT j = i+1; j < pRc->cAllocations; ++j)
2190 {
2191 PVBOXWDDMDISP_ALLOCATION pAllocJ = &pRc->aAllocations[j];
2192 Assert(pAlloc->pD3DIf != pAllocJ->pD3DIf);
2193 }
2194 }
2195}
2196
2197# define VBOXVDBG_RTGT_STATECHECK(_pDev) (vboxWddmDbgRenderTargetCheck((_pDev), (_pDev)->aScreens[(_pDev)->iPrimaryScreen].pRenderTargetRc, (_pDev)->aScreens[(_pDev)->iPrimaryScreen].iRenderTargetFrontBuf))
2198#else
2199# define VBOXVDBG_RTGT_STATECHECK(_pDev) do{}while(0)
2200#endif
2201
2202#if 0
2203static HRESULT vboxWddmD3DDeviceCreate(PVBOXWDDMDISP_DEVICE pDevice, UINT iScreen, PVBOXWDDMDISP_RESOURCE pRc, D3DPRESENT_PARAMETERS * pParams, BOOL bLockable)
2204{
2205 UINT cSurfs = pParams->BackBufferCount + 1;
2206 Assert(pRc->cAllocations = cSurfs);
2207 IDirect3DDevice9 *pPrimaryDevice = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
2208 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[iScreen];
2209 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
2210 HRESULT hr;
2211 HWND hWnd = NULL;
2212 Assert(!pScreen->pDevice9If);
2213 Assert(!pScreen->hWnd);
2214 hr = VBoxDispWndCreate(pAdapter, pParams->BackBufferWidth, pParams->BackBufferHeight, &hWnd);
2215 Assert(hr == S_OK);
2216 if (hr == S_OK)
2217 {
2218 pScreen->hWnd = hWnd;
2219
2220 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
2221 if (pDevice->fFlags.AllowMultithreading)
2222 fFlags |= D3DCREATE_MULTITHREADED;
2223
2224 IDirect3DDevice9 *pDevice9If = NULL;
2225 pParams->hDeviceWindow = hWnd;
2226 /* @todo: it seems there should be a way to detect this correctly since
2227 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
2228 pParams->Windowed = TRUE;
2229 // params.EnableAutoDepthStencil = FALSE;
2230 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
2231 // params.Flags;
2232 // params.FullScreen_RefreshRateInHz;
2233 // params.FullScreen_PresentationInterval;
2234 hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, fFlags, pParams, &pDevice9If);
2235 Assert(hr == S_OK);
2236 if (hr == S_OK)
2237 {
2238 pScreen->pDevice9If = pDevice9If;
2239 pScreen->pRenderTargetRc = pRc;
2240 ++pDevice->cScreens;
2241
2242 for (UINT i = 0; i < cSurfs; ++i)
2243 {
2244 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2245 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2246 }
2247
2248 if (pPrimaryDevice)
2249 {
2250 for (UINT i = 0; i < cSurfs; ++i)
2251 {
2252 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2253 IDirect3DSurface9 *pRt;
2254 IDirect3DSurface9 *pSecondaryOpenedRt;
2255 HANDLE hSharedHandle = NULL;
2256 hr = pPrimaryDevice->CreateRenderTarget(
2257 pParams->BackBufferWidth, pParams->BackBufferHeight,
2258 pParams->BackBufferFormat,
2259 pParams->MultiSampleType,
2260 pParams->MultiSampleQuality,
2261 TRUE, /*BOOL Lockable*/
2262 &pRt,
2263 &hSharedHandle);
2264 Assert(hr == S_OK);
2265 if (hr == S_OK)
2266 {
2267 Assert(hSharedHandle != NULL);
2268 /* open render target for primary device */
2269 hr = pDevice9If->CreateRenderTarget(
2270 pParams->BackBufferWidth, pParams->BackBufferHeight,
2271 pParams->BackBufferFormat,
2272 pParams->MultiSampleType,
2273 pParams->MultiSampleQuality,
2274 TRUE, /*BOOL Lockable*/
2275 &pSecondaryOpenedRt,
2276 &hSharedHandle);
2277 Assert(hr == S_OK);
2278 if (hr == S_OK)
2279 {
2280 pAllocation->pD3DIf = pRt;
2281 pAllocation->pSecondaryOpenedD3DIf = pSecondaryOpenedRt;
2282 pAllocation->hSharedHandle = hSharedHandle;
2283 continue;
2284 }
2285 pRt->Release();
2286 }
2287
2288 for (UINT j = 0; j < i; ++j)
2289 {
2290 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[j];
2291 pAlloc->pD3DIf->Release();
2292 pAlloc->pSecondaryOpenedD3DIf->Release();
2293 }
2294
2295 break;
2296 }
2297 }
2298 else
2299 {
2300 pDevice->iPrimaryScreen = iScreen;
2301 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0);
2302 Assert(hr == S_OK);
2303 }
2304
2305 if (hr == S_OK)
2306 {
2307 for (UINT i = 0; i < cSurfs; ++i)
2308 {
2309 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2310 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2311 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
2312 Assert(hr == S_OK);
2313 if (hr != S_OK)
2314 {
2315 break;
2316 }
2317 }
2318
2319#ifndef VBOXWDDM_WITH_VISIBLE_FB
2320 if (!pPrimaryDevice)
2321 {
2322 if (hr == S_OK)
2323 {
2324 IDirect3DSurface9* pD3D9Surf;
2325 hr = pDevice9If->CreateRenderTarget(
2326 pParams->BackBufferWidth, pParams->BackBufferHeight,
2327 pParams->BackBufferFormat,
2328 pParams->MultiSampleType,
2329 pParams->MultiSampleQuality,
2330 bLockable,
2331 &pD3D9Surf,
2332 NULL /* HANDLE* pSharedHandle */
2333 );
2334 Assert(hr == S_OK);
2335 if (hr == S_OK)
2336 {
2337 pDevice->pRenderTargetFbCopy = pD3D9Surf;
2338 }
2339 }
2340 }
2341#endif
2342
2343 if (hr != S_OK)
2344 {
2345 for (UINT i = 0; i < cSurfs; ++i)
2346 {
2347 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2348 pAllocation->pD3DIf->Release();
2349 }
2350 }
2351 }
2352
2353 if (hr != S_OK)
2354 {
2355 pDevice9If->Release();
2356 --pDevice->cScreens;
2357 Assert(pDevice->cScreens < UINT32_MAX/2);
2358 }
2359 }
2360
2361 if (hr != S_OK)
2362 {
2363 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pScreen->hWnd);
2364 Assert(tmpHr == S_OK);
2365 }
2366 }
2367
2368 return hr;
2369}
2370#endif
2371static HRESULT vboxWddmD3DDeviceCreateDummy(PVBOXWDDMDISP_DEVICE pDevice)
2372{
2373 HRESULT hr;
2374 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);
2375 Assert(pRc);
2376 if (pRc)
2377 {
2378 pRc->RcDesc.enmFormat = D3DDDIFMT_A8R8G8B8;
2379 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
2380 pRc->RcDesc.MultisampleQuality = 0;
2381 for (UINT i = 0 ; i < pRc->cAllocations; ++i)
2382 {
2383 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
2384 pAlloc->SurfDesc.width = 0x4;
2385 pAlloc->SurfDesc.height = 0x4;
2386 pAlloc->SurfDesc.format = D3DDDIFMT_A8R8G8B8;
2387 }
2388
2389 PVBOXWDDMDISP_SWAPCHAIN pSwapchain;
2390 hr = vboxWddmSwapchainCreateIfForRc(pDevice, pRc, &pSwapchain);
2391 Assert(hr == S_OK);
2392 if (hr != S_OK)
2393 vboxResourceFree(pRc);
2394 }
2395 else
2396 {
2397 hr = E_OUTOFMEMORY;
2398 }
2399
2400 return hr;
2401}
2402
2403DECLINLINE(IDirect3DDevice9*) vboxWddmD3DDeviceGet(PVBOXWDDMDISP_DEVICE pDevice)
2404{
2405 if (pDevice->pDevice9If)
2406 return pDevice->pDevice9If;
2407 HRESULT hr = vboxWddmD3DDeviceCreateDummy(pDevice);
2408 Assert(hr == S_OK);
2409 Assert(pDevice->pDevice9If);
2410 return pDevice->pDevice9If;
2411}
2412
2413#if 0
2414static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource);
2415
2416static HRESULT vboxWddmD3DDeviceUpdate(PVBOXWDDMDISP_DEVICE pDevice, UINT iScreen, PVBOXWDDMDISP_RESOURCE pRc, D3DPRESENT_PARAMETERS * pParams, BOOL bLockable)
2417{
2418 UINT cSurfs = pParams->BackBufferCount + 1;
2419 Assert(pRc->cAllocations = cSurfs);
2420 Assert(iScreen == pDevice->iPrimaryScreen);
2421 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[iScreen];
2422 PVBOXWDDMDISP_RESOURCE pCurRc = pScreen->pRenderTargetRc;
2423 IDirect3DDevice9Ex *pNewDevice;
2424 HRESULT hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Update((IDirect3DDevice9Ex*)pScreen->pDevice9If, pParams, &pNewDevice);
2425 Assert(hr == S_OK);
2426 if (hr == S_OK)
2427 {
2428 pScreen->pDevice9If->Release();
2429 pScreen->pDevice9If = pNewDevice;
2430 pScreen->pRenderTargetRc = pRc;
2431
2432 for (UINT i = 0; i < cSurfs; ++i)
2433 {
2434 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2435 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2436 }
2437
2438#ifndef VBOXWDDM_WITH_VISIBLE_FB
2439 if (pDevice->pRenderTargetFbCopy)
2440 {
2441 pDevice->pRenderTargetFbCopy->Release();
2442 }
2443 IDirect3DSurface9* pD3D9Surf;
2444 hr = pNewDevice->CreateRenderTarget(
2445 pParams->BackBufferWidth, pParams->BackBufferHeight,
2446 pParams->BackBufferFormat,
2447 pParams->MultiSampleType,
2448 pParams->MultiSampleQuality,
2449 bLockable,
2450 &pD3D9Surf,
2451 NULL /* HANDLE* pSharedHandle */
2452 );
2453 Assert(hr == S_OK);
2454 if (hr == S_OK)
2455 {
2456 pDevice->pRenderTargetFbCopy = pD3D9Surf;
2457 }
2458#endif
2459 if (hr == S_OK)
2460 {
2461 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0);
2462 Assert(hr == S_OK);
2463 if (hr == S_OK)
2464 {
2465 for (UINT i = 0; i < cSurfs; ++i)
2466 {
2467 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2468 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2469 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
2470 Assert(hr == S_OK);
2471 if (hr != S_OK)
2472 {
2473 break;
2474 }
2475 }
2476 }
2477 }
2478 }
2479
2480
2481 if (!pCurRc->hResource)
2482 {
2483 HRESULT tmpHr = vboxWddmDDevDestroyResource(pDevice, pCurRc);
2484 Assert(tmpHr == S_OK);
2485 }
2486
2487 return hr;
2488}
2489#endif
2490/******/
2491
2492static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch)
2493{
2494 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2495 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
2496 if (pSwapchain)
2497 {
2498 /* backbuffer */
2499 Assert(vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc);
2500 }
2501
2502 HRESULT hr = S_OK;
2503 IDirect3DSurface9 *pD3D9Surf;
2504 if (pSwapchain && vboxWddmSwapchainNumRTs(pSwapchain) == 1 && iRt == 0)
2505 {
2506 /* work-around wine double-buffering for the case we have no backbuffers */
2507 Assert((!pSwapchain->fFlags.bChanged || bOnSwapchainSynch) && pSwapchain->pSwapChainIf);
2508 if (!bOnSwapchainSynch)
2509 {
2510 vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
2511 }
2512 hr = pSwapchain->pSwapChainIf->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
2513 Assert(hr == S_OK);
2514 Assert(pD3D9Surf);
2515 }
2516 else
2517 {
2518 hr = vboxWddmSurfGet(pAlloc->pRc, pAlloc->iAlloc, &pD3D9Surf);
2519 Assert(hr == S_OK);
2520 Assert(pD3D9Surf);
2521 }
2522
2523 if (hr == S_OK)
2524 {
2525 Assert(pD3D9Surf);
2526 hr = pDevice9If->SetRenderTarget(iRt, pD3D9Surf);
2527 Assert(hr == S_OK);
2528 if (hr == S_OK)
2529 {
2530 Assert(iRt < pDevice->cRTs);
2531 pDevice->apRTs[iRt] = pAlloc;
2532 }
2533 pD3D9Surf->Release();
2534 }
2535
2536 return hr;
2537}
2538
2539
2540static CRITICAL_SECTION g_VBoxCritSect;
2541
2542void vboxDispLock()
2543{
2544 EnterCriticalSection(&g_VBoxCritSect);
2545}
2546
2547void vboxDispUnlock()
2548{
2549 LeaveCriticalSection(&g_VBoxCritSect);
2550}
2551
2552void vboxDispLockInit()
2553{
2554 InitializeCriticalSection(&g_VBoxCritSect);
2555}
2556
2557/**
2558 * DLL entry point.
2559 */
2560BOOL WINAPI DllMain(HINSTANCE hInstance,
2561 DWORD dwReason,
2562 LPVOID lpReserved)
2563{
2564 switch (dwReason)
2565 {
2566 case DLL_PROCESS_ATTACH:
2567 {
2568 vboxDispLockInit();
2569
2570 vboxVDbgPrint(("VBoxDispD3D: DLL loaded.\n"));
2571#ifdef VBOXWDDMDISP_DEBUG
2572 vboxVDbgVEHandlerRegister();
2573#endif
2574 RTR3Init();
2575
2576 HRESULT hr = vboxDispCmInit();
2577 Assert(hr == S_OK);
2578 if (hr == S_OK)
2579 {
2580#ifdef VBOXDISPMP_TEST
2581 hr = vboxDispMpTstStart();
2582 Assert(hr == S_OK);
2583 if (hr == S_OK)
2584#endif
2585 {
2586// hr = VBoxScreenMRunnerStart(&g_VBoxScreenMonRunner);
2587// Assert(hr == S_OK);
2588 /* succeed in any way */
2589 hr = S_OK;
2590 if (hr == S_OK)
2591 {
2592 vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n"));
2593 return TRUE;
2594 }
2595#ifdef VBOXDISPMP_TEST
2596 vboxDispMpTstStop();
2597#endif
2598 }
2599 vboxDispCmTerm();
2600 }
2601// VbglR3Init();
2602 break;
2603 }
2604
2605 case DLL_PROCESS_DETACH:
2606 {
2607#ifdef VBOXWDDMDISP_DEBUG
2608 vboxVDbgVEHandlerUnregister();
2609#endif
2610 HRESULT hr = S_OK;
2611// hr = VBoxScreenMRunnerStop(&g_VBoxScreenMonRunner);
2612// Assert(hr == S_OK);
2613// if (hr == S_OK)
2614 {
2615#ifdef VBOXDISPMP_TEST
2616 hr = vboxDispMpTstStop();
2617 Assert(hr == S_OK);
2618 if (hr == S_OK)
2619#endif
2620 {
2621 hr = vboxDispCmTerm();
2622 Assert(hr == S_OK);
2623 if (hr == S_OK)
2624 {
2625 vboxVDbgPrint(("VBoxDispD3D: DLL unloaded.\n"));
2626 return TRUE;
2627 }
2628 }
2629 }
2630// VbglR3Term();
2631 /// @todo RTR3Term();
2632 break;
2633 }
2634
2635 default:
2636 return TRUE;
2637 }
2638 return FALSE;
2639}
2640
2641static HRESULT vboxWddmGetD3D9Caps(PVBOXWDDMDISP_ADAPTER pAdapter, D3DCAPS9 *pCaps)
2642{
2643 HRESULT hr = pAdapter->pD3D9If->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pCaps);
2644 Assert(hr == S_OK);
2645 if (hr == S_OK)
2646 {
2647 pCaps->Caps2 |= D3DCAPS2_CANSHARERESOURCE | 0x00080000 /*D3DCAPS2_CANRENDERWINDOWED*/;
2648 pCaps->DevCaps |= D3DDEVCAPS_FLOATTLVERTEX /* <- must be set according to the docs */
2649 /*| D3DDEVCAPS_HWVERTEXBUFFER | D3DDEVCAPS_HWINDEXBUFFER | D3DDEVCAPS_SUBVOLUMELOCK */;
2650 pCaps->PrimitiveMiscCaps |= D3DPMISCCAPS_INDEPENDENTWRITEMASKS
2651 | D3DPMISCCAPS_FOGINFVF
2652 | D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS;
2653 pCaps->RasterCaps |= D3DPRASTERCAPS_SUBPIXEL | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_COLORPERSPECTIVE /* keep */;
2654 pCaps->TextureCaps |= D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE;
2655 pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
2656 pCaps->VolumeTextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
2657 pCaps->GuardBandLeft = -8192.;
2658 pCaps->GuardBandTop = -8192.;
2659 pCaps->GuardBandRight = 8192.;
2660 pCaps->GuardBandBottom = 8192.;
2661 pCaps->StencilCaps |= D3DSTENCILCAPS_TWOSIDED;
2662 pCaps->DeclTypes |= D3DDTCAPS_FLOAT16_2 | D3DDTCAPS_FLOAT16_4;
2663 pCaps->VS20Caps.DynamicFlowControlDepth = 24;
2664 pCaps->VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
2665 pCaps->PS20Caps.DynamicFlowControlDepth = 24;
2666 pCaps->PS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
2667 pCaps->VertexTextureFilterCaps |= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MAGFPOINT;
2668#if 1 /* workaround for wine not returning InstructionSlots correctly for shaders v3.0 */
2669 if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
2670 {
2671 pCaps->MaxVertexShader30InstructionSlots = RT_MIN(32768, pCaps->MaxVertexShader30InstructionSlots);
2672 pCaps->MaxPixelShader30InstructionSlots = RT_MIN(32768, pCaps->MaxPixelShader30InstructionSlots);
2673 }
2674#endif
2675#ifdef DEBUG
2676 if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
2677 {
2678 Assert(pCaps->MaxVertexShader30InstructionSlots >= 512);
2679 Assert(pCaps->MaxVertexShader30InstructionSlots <= 32768);
2680 Assert(pCaps->MaxPixelShader30InstructionSlots >= 512);
2681 Assert(pCaps->MaxPixelShader30InstructionSlots <= 32768);
2682 }
2683 else if ((pCaps->VertexShaderVersion & 0xff00) == 0x0200)
2684 {
2685 Assert(pCaps->MaxVertexShader30InstructionSlots == 0);
2686 Assert(pCaps->MaxPixelShader30InstructionSlots == 0);
2687 }
2688 else
2689 {
2690 Assert(0);
2691 }
2692#endif
2693 }
2694
2695 return hr;
2696}
2697
2698static HRESULT APIENTRY vboxWddmDispGetCaps (HANDLE hAdapter, CONST D3DDDIARG_GETCAPS* pData)
2699{
2700 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
2701
2702 HRESULT hr = S_OK;
2703 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
2704
2705 switch (pData->Type)
2706 {
2707 case D3DDDICAPS_DDRAW:
2708 {
2709 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
2710 Assert(pData->DataSize == sizeof (DDRAW_CAPS));
2711 if (pData->DataSize >= sizeof (DDRAW_CAPS))
2712 {
2713 memset(pData->pData, 0, sizeof (DDRAW_CAPS));
2714#ifdef VBOX_WITH_VIDEOHWACCEL
2715 if (vboxVhwaHasCKeying(pAdapter))
2716 {
2717 DDRAW_CAPS *pCaps = (DDRAW_CAPS*)pData->pData;
2718 pCaps->Caps |= DDRAW_CAPS_COLORKEY;
2719// pCaps->Caps2 |= DDRAW_CAPS2_FLIPNOVSYNC;
2720 }
2721#endif
2722 }
2723 else
2724 hr = E_INVALIDARG;
2725 break;
2726 }
2727 case D3DDDICAPS_DDRAW_MODE_SPECIFIC:
2728 {
2729 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
2730 Assert(pData->DataSize == sizeof (DDRAW_MODE_SPECIFIC_CAPS));
2731 if (pData->DataSize >= sizeof (DDRAW_MODE_SPECIFIC_CAPS))
2732 {
2733 DDRAW_MODE_SPECIFIC_CAPS * pCaps = (DDRAW_MODE_SPECIFIC_CAPS*)pData->pData;
2734 memset(&pCaps->Caps /* do not cleanup the first "Head" field,
2735 zero starting with the one following "Head", i.e. Caps */,
2736 0, sizeof (DDRAW_MODE_SPECIFIC_CAPS) - RT_OFFSETOF(DDRAW_MODE_SPECIFIC_CAPS, Caps));
2737#ifdef VBOX_WITH_VIDEOHWACCEL
2738 VBOXVHWA_INFO *pSettings = &pAdapter->aHeads[pCaps->Head].Vhwa.Settings;
2739 if (pSettings->fFlags & VBOXVHWA_F_ENABLED)
2740 {
2741 pCaps->Caps |= MODE_CAPS_OVERLAY | MODE_CAPS_OVERLAYSTRETCH;
2742
2743 if (pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
2744 {
2745 pCaps->CKeyCaps |= MODE_CKEYCAPS_DESTOVERLAY
2746 | MODE_CKEYCAPS_DESTOVERLAYYUV /* ?? */
2747 ;
2748 }
2749
2750 if (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC)
2751 {
2752 pCaps->CKeyCaps |= MODE_CKEYCAPS_SRCOVERLAY
2753 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACE /* ?? */
2754 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACEYUV /* ?? */
2755 | MODE_CKEYCAPS_SRCOVERLAYYUV /* ?? */
2756 ;
2757 }
2758
2759 pCaps->FxCaps = MODE_FXCAPS_OVERLAYSHRINKX
2760 | MODE_FXCAPS_OVERLAYSHRINKY
2761 | MODE_FXCAPS_OVERLAYSTRETCHX
2762 | MODE_FXCAPS_OVERLAYSTRETCHY;
2763
2764
2765 pCaps->MaxVisibleOverlays = pSettings->cOverlaysSupported;
2766 pCaps->MinOverlayStretch = 1;
2767 pCaps->MaxOverlayStretch = 32000;
2768 }
2769#endif
2770 }
2771 else
2772 hr = E_INVALIDARG;
2773 break;
2774 }
2775 case D3DDDICAPS_GETFORMATCOUNT:
2776 *((uint32_t*)pData->pData) = pAdapter->cFormstOps;
2777 break;
2778 case D3DDDICAPS_GETFORMATDATA:
2779 Assert(pData->DataSize == pAdapter->cFormstOps * sizeof (FORMATOP));
2780 memcpy(pData->pData, pAdapter->paFormstOps, pAdapter->cFormstOps * sizeof (FORMATOP));
2781 break;
2782 case D3DDDICAPS_GETD3DQUERYCOUNT:
2783#if 1
2784 *((uint32_t*)pData->pData) = VBOX_QUERYTYPE_COUNT();
2785#else
2786 *((uint32_t*)pData->pData) = 0;
2787#endif
2788 break;
2789 case D3DDDICAPS_GETD3DQUERYDATA:
2790#if 1
2791 Assert(pData->DataSize == VBOX_QUERYTYPE_COUNT() * sizeof (D3DDDIQUERYTYPE));
2792 memcpy(pData->pData, gVBoxQueryTypes, VBOX_QUERYTYPE_COUNT() * sizeof (D3DDDIQUERYTYPE));
2793#else
2794 Assert(0);
2795 memset(pData->pData, 0, pData->DataSize);
2796#endif
2797 break;
2798 case D3DDDICAPS_GETD3D3CAPS:
2799 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
2800 Assert(pData->DataSize == sizeof (D3DHAL_GLOBALDRIVERDATA));
2801 if (pData->DataSize >= sizeof (D3DHAL_GLOBALDRIVERDATA))
2802 {
2803 D3DHAL_GLOBALDRIVERDATA *pCaps = (D3DHAL_GLOBALDRIVERDATA *)pData->pData;
2804 memset (pCaps, 0, sizeof (D3DHAL_GLOBALDRIVERDATA));
2805 pCaps->dwSize = sizeof (D3DHAL_GLOBALDRIVERDATA);
2806 pCaps->hwCaps.dwSize = sizeof (D3DDEVICEDESC_V1);
2807 pCaps->hwCaps.dwFlags = D3DDD_COLORMODEL
2808 | D3DDD_DEVCAPS
2809 | D3DDD_DEVICERENDERBITDEPTH;
2810
2811 pCaps->hwCaps.dcmColorModel = D3DCOLOR_RGB;
2812 pCaps->hwCaps.dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP
2813// | D3DDEVCAPS_DRAWPRIMTLVERTEX
2814 | D3DDEVCAPS_EXECUTESYSTEMMEMORY
2815 | D3DDEVCAPS_EXECUTEVIDEOMEMORY
2816// | D3DDEVCAPS_FLOATTLVERTEX
2817 | D3DDEVCAPS_HWRASTERIZATION
2818// | D3DDEVCAPS_HWTRANSFORMANDLIGHT
2819// | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY
2820// | D3DDEVCAPS_TEXTUREVIDEOMEMORY
2821 ;
2822 pCaps->hwCaps.dtcTransformCaps.dwSize = sizeof (D3DTRANSFORMCAPS);
2823 pCaps->hwCaps.dtcTransformCaps.dwCaps = 0;
2824 pCaps->hwCaps.bClipping = FALSE;
2825 pCaps->hwCaps.dlcLightingCaps.dwSize = sizeof (D3DLIGHTINGCAPS);
2826 pCaps->hwCaps.dlcLightingCaps.dwCaps = 0;
2827 pCaps->hwCaps.dlcLightingCaps.dwLightingModel = 0;
2828 pCaps->hwCaps.dlcLightingCaps.dwNumLights = 0;
2829 pCaps->hwCaps.dpcLineCaps.dwSize = sizeof (D3DPRIMCAPS);
2830 pCaps->hwCaps.dpcLineCaps.dwMiscCaps = 0;
2831 pCaps->hwCaps.dpcLineCaps.dwRasterCaps = 0;
2832 pCaps->hwCaps.dpcLineCaps.dwZCmpCaps = 0;
2833 pCaps->hwCaps.dpcLineCaps.dwSrcBlendCaps = 0;
2834 pCaps->hwCaps.dpcLineCaps.dwDestBlendCaps = 0;
2835 pCaps->hwCaps.dpcLineCaps.dwAlphaCmpCaps = 0;
2836 pCaps->hwCaps.dpcLineCaps.dwShadeCaps = 0;
2837 pCaps->hwCaps.dpcLineCaps.dwTextureCaps = 0;
2838 pCaps->hwCaps.dpcLineCaps.dwTextureFilterCaps = 0;
2839 pCaps->hwCaps.dpcLineCaps.dwTextureBlendCaps = 0;
2840 pCaps->hwCaps.dpcLineCaps.dwTextureAddressCaps = 0;
2841 pCaps->hwCaps.dpcLineCaps.dwStippleWidth = 0;
2842 pCaps->hwCaps.dpcLineCaps.dwStippleHeight = 0;
2843
2844 pCaps->hwCaps.dpcTriCaps.dwSize = sizeof (D3DPRIMCAPS);
2845 pCaps->hwCaps.dpcTriCaps.dwMiscCaps = 0;
2846 pCaps->hwCaps.dpcTriCaps.dwRasterCaps = 0;
2847 pCaps->hwCaps.dpcTriCaps.dwZCmpCaps = 0;
2848 pCaps->hwCaps.dpcTriCaps.dwSrcBlendCaps = 0;
2849 pCaps->hwCaps.dpcTriCaps.dwDestBlendCaps = 0;
2850 pCaps->hwCaps.dpcTriCaps.dwAlphaCmpCaps = 0;
2851 pCaps->hwCaps.dpcTriCaps.dwShadeCaps = 0;
2852 pCaps->hwCaps.dpcTriCaps.dwTextureCaps = 0;
2853 pCaps->hwCaps.dpcTriCaps.dwTextureFilterCaps = 0;
2854 pCaps->hwCaps.dpcTriCaps.dwTextureBlendCaps = 0;
2855 pCaps->hwCaps.dpcTriCaps.dwTextureAddressCaps = 0;
2856 pCaps->hwCaps.dpcTriCaps.dwStippleWidth = 0;
2857 pCaps->hwCaps.dpcTriCaps.dwStippleHeight = 0;
2858 pCaps->hwCaps.dwDeviceRenderBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32;
2859 pCaps->hwCaps.dwDeviceZBufferBitDepth = 0;
2860 pCaps->hwCaps.dwMaxBufferSize = 0;
2861 pCaps->hwCaps.dwMaxVertexCount = 0;
2862
2863
2864 pCaps->dwNumVertices = 0;
2865 pCaps->dwNumClipVertices = 0;
2866 pCaps->dwNumTextureFormats = 0;//pAdapter->cSurfDescs;
2867 pCaps->lpTextureFormats = NULL;//pAdapter->paSurfDescs;
2868 }
2869 else
2870 hr = E_INVALIDARG;
2871 break;
2872 case D3DDDICAPS_GETD3D7CAPS:
2873 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
2874 Assert(pData->DataSize == sizeof (D3DHAL_D3DEXTENDEDCAPS));
2875 if (pData->DataSize >= sizeof (D3DHAL_D3DEXTENDEDCAPS))
2876 {
2877 memset(pData->pData, 0, sizeof (D3DHAL_D3DEXTENDEDCAPS));
2878 D3DHAL_D3DEXTENDEDCAPS *pCaps = (D3DHAL_D3DEXTENDEDCAPS*)pData->pData;
2879 pCaps->dwSize = sizeof (D3DHAL_D3DEXTENDEDCAPS);
2880 }
2881 else
2882 hr = E_INVALIDARG;
2883 break;
2884 case D3DDDICAPS_GETD3D9CAPS:
2885 {
2886 Assert(pData->DataSize == sizeof (D3DCAPS9));
2887// Assert(0);
2888 if (pData->DataSize >= sizeof (D3DCAPS9))
2889 {
2890 Assert(VBOXDISPMODE_IS_3D(pAdapter));
2891 if (VBOXDISPMODE_IS_3D(pAdapter))
2892 {
2893 D3DCAPS9* pCaps = (D3DCAPS9*)pData->pData;
2894 hr = vboxWddmGetD3D9Caps(pAdapter, pCaps);
2895 Assert(hr == S_OK);
2896 if (hr == S_OK)
2897 break;
2898
2899 vboxVDbgPrintR((__FUNCTION__": GetDeviceCaps Failed hr(%d)\n", hr));
2900 /* let's fall back to the 3D disabled case */
2901 hr = S_OK;
2902 }
2903
2904 memset(pData->pData, 0, sizeof (D3DCAPS9));
2905 }
2906 else
2907 hr = E_INVALIDARG;
2908 break;
2909 }
2910 case D3DDDICAPS_GETD3D8CAPS:
2911 {
2912 Assert(pData->DataSize == RT_OFFSETOF(D3DCAPS9, DevCaps2));
2913 if (pData->DataSize == RT_OFFSETOF(D3DCAPS9, DevCaps2))
2914 {
2915 Assert(VBOXDISPMODE_IS_3D(pAdapter));
2916 if (VBOXDISPMODE_IS_3D(pAdapter))
2917 {
2918 D3DCAPS9 Caps9;
2919 hr = vboxWddmGetD3D9Caps(pAdapter, &Caps9);
2920 Assert(hr == S_OK);
2921 if (hr == S_OK)
2922 {
2923 memcpy(pData->pData, &Caps9, RT_OFFSETOF(D3DCAPS9, DevCaps2));
2924 break;
2925 }
2926
2927 vboxVDbgPrintR((__FUNCTION__": GetDeviceCaps Failed hr(%d)\n", hr));
2928 /* let's fall back to the 3D disabled case */
2929 hr = S_OK;
2930 }
2931
2932 }
2933 else
2934 hr = E_INVALIDARG;
2935 break;
2936 }
2937 case D3DDDICAPS_GETGAMMARAMPCAPS:
2938 *((uint32_t*)pData->pData) = 0;
2939 break;
2940 case D3DDDICAPS_GETVIDEOPROCESSORCAPS:
2941 case D3DDDICAPS_GETEXTENSIONGUIDCOUNT:
2942 case D3DDDICAPS_GETDECODEGUIDCOUNT:
2943 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDCOUNT:
2944 if (pData->pData && pData->DataSize)
2945 memset(pData->pData, 0, pData->DataSize);
2946 break;
2947 case D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS:
2948 case D3DDDICAPS_GETD3D5CAPS:
2949 case D3DDDICAPS_GETD3D6CAPS:
2950 case D3DDDICAPS_GETDECODEGUIDS:
2951 case D3DDDICAPS_GETDECODERTFORMATCOUNT:
2952 case D3DDDICAPS_GETDECODERTFORMATS:
2953 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFOCOUNT:
2954 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFO:
2955 case D3DDDICAPS_GETDECODECONFIGURATIONCOUNT:
2956 case D3DDDICAPS_GETDECODECONFIGURATIONS:
2957 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDS:
2958 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATCOUNT:
2959 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATS:
2960 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT:
2961 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS:
2962 case D3DDDICAPS_GETPROCAMPRANGE:
2963 case D3DDDICAPS_FILTERPROPERTYRANGE:
2964 case D3DDDICAPS_GETEXTENSIONGUIDS:
2965 case D3DDDICAPS_GETEXTENSIONCAPS:
2966 vboxVDbgPrint((__FUNCTION__": unimplemented caps type(%d)\n", pData->Type));
2967 Assert(0);
2968 if (pData->pData && pData->DataSize)
2969 memset(pData->pData, 0, pData->DataSize);
2970 break;
2971 default:
2972 vboxVDbgPrint((__FUNCTION__": unknown caps type(%d)\n", pData->Type));
2973 Assert(0);
2974 }
2975
2976 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
2977
2978 return S_OK;
2979}
2980
2981static HRESULT APIENTRY vboxWddmDDevSetRenderState(HANDLE hDevice, CONST D3DDDIARG_RENDERSTATE* pData)
2982{
2983 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2984 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2985 Assert(pDevice);
2986 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2987 HRESULT hr = pDevice9If->SetRenderState(vboxDDI2D3DRenderStateType(pData->State), pData->Value);
2988 Assert(hr == S_OK);
2989 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2990 return hr;
2991}
2992
2993static HRESULT APIENTRY vboxWddmDDevUpdateWInfo(HANDLE hDevice, CONST D3DDDIARG_WINFO* pData)
2994{
2995 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2996 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2997 return S_OK;
2998}
2999
3000static HRESULT APIENTRY vboxWddmDDevValidateDevice(HANDLE hDevice, D3DDDIARG_VALIDATETEXTURESTAGESTATE* pData)
3001{
3002 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3003 Assert(0);
3004 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3005 return E_FAIL;
3006}
3007
3008static HRESULT APIENTRY vboxWddmDDevSetTextureStageState(HANDLE hDevice, CONST D3DDDIARG_TEXTURESTAGESTATE* pData)
3009{
3010 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3011 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3012 Assert(pDevice);
3013 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3014
3015 VBOXWDDMDISP_TSS_LOOKUP lookup = vboxDDI2D3DTestureStageStateType(pData->State);
3016 HRESULT hr;
3017
3018 if (!lookup.bSamplerState)
3019 {
3020 hr = pDevice9If->SetTextureStageState(pData->Stage, D3DTEXTURESTAGESTATETYPE(lookup.dType), pData->Value);
3021 }
3022 else
3023 {
3024 hr = pDevice9If->SetSamplerState(pData->Stage, D3DSAMPLERSTATETYPE(lookup.dType), pData->Value);
3025 }
3026
3027 Assert(hr == S_OK);
3028 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3029 return hr;
3030}
3031
3032static HRESULT APIENTRY vboxWddmDDevSetTexture(HANDLE hDevice, UINT Stage, HANDLE hTexture)
3033{
3034 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3035 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3036 Assert(pDevice);
3037 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3038 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hTexture;
3039// Assert(pRc);
3040 IDirect3DTexture9 *pD3DIfTex;
3041 if (pRc)
3042 {
3043 Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE);
3044 pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
3045#ifdef DEBUG_misha
3046 bool bDo = false;
3047
3048 if (bDo)
3049 {
3050 vboxVDbgDumpSurfData((pDevice, "SetTexture:\n", pRc, 0 /* alloc index*/, NULL, NULL, "\n"));
3051 }
3052#endif
3053 }
3054 else
3055 pD3DIfTex = NULL;
3056
3057// Assert(pD3DIfTex);
3058 HRESULT hr = pDevice9If->SetTexture(Stage, pD3DIfTex);
3059 Assert(hr == S_OK);
3060 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3061 return hr;
3062}
3063
3064static HRESULT APIENTRY vboxWddmDDevSetPixelShader(HANDLE hDevice, HANDLE hShaderHandle)
3065{
3066 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3067 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3068 Assert(pDevice);
3069 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3070 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
3071 Assert(pShader);
3072 HRESULT hr = pDevice9If->SetPixelShader(pShader);
3073 Assert(hr == S_OK);
3074 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3075 return hr;
3076}
3077
3078static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONST* pData, CONST FLOAT* pRegisters)
3079{
3080 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3081 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3082 Assert(pDevice);
3083 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3084 HRESULT hr = pDevice9If->SetPixelShaderConstantF(pData->Register, pRegisters, pData->Count);
3085 Assert(hr == S_OK);
3086 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3087 return hr;
3088}
3089
3090static HRESULT APIENTRY vboxWddmDDevSetStreamSourceUm(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEUM* pData, CONST VOID* pUMBuffer )
3091{
3092 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3093 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3094 Assert(pDevice);
3095 HRESULT hr = S_OK;
3096// IDirect3DVertexBuffer9 *pStreamData;
3097// UINT cbOffset;
3098// UINT cbStride;
3099// hr = pDevice->pDevice9If->GetStreamSource(pData->Stream, &pStreamData, &cbOffset, &cbStride);
3100// Assert(hr == S_OK);
3101// if (hr == S_OK)
3102// {
3103// if (pStreamData)
3104// {
3105// Assert(0);
3106// /* @todo: impl! */
3107// }
3108// else
3109// {
3110 Assert(pData->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm));
3111 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrcUm = &pDevice->aStreamSourceUm[pData->Stream];
3112 pStrSrcUm->pvBuffer = pUMBuffer;
3113 pStrSrcUm->cbStride = pData->Stride;
3114// }
3115// }
3116 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3117 return hr;
3118}
3119
3120static HRESULT APIENTRY vboxWddmDDevSetIndices(HANDLE hDevice, CONST D3DDDIARG_SETINDICES* pData)
3121{
3122 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3123 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3124 Assert(pDevice);
3125 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3126 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hIndexBuffer;
3127 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
3128 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
3129 if (pRc)
3130 {
3131 Assert(pRc->cAllocations == 1);
3132 pAlloc = &pRc->aAllocations[0];
3133 Assert(pAlloc->pD3DIf);
3134 pIndexBuffer = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
3135 }
3136 HRESULT hr = pDevice9If->SetIndices(pIndexBuffer);
3137 Assert(hr == S_OK);
3138 if (hr == S_OK)
3139 {
3140 pDevice->pIndicesAlloc = pAlloc;
3141 pDevice->IndiciesInfo.uiStride = pData->Stride;
3142 }
3143 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3144 return hr;
3145}
3146
3147static HRESULT APIENTRY vboxWddmDDevSetIndicesUm(HANDLE hDevice, UINT IndexSize, CONST VOID* pUMBuffer)
3148{
3149 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3150 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3151 Assert(pDevice);
3152 HRESULT hr = S_OK;
3153 pDevice->IndiciesUm.pvBuffer = pUMBuffer;
3154 pDevice->IndiciesUm.cbSize = IndexSize;
3155 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3156 return hr;
3157}
3158
3159static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE* pData, CONST UINT* pFlagBuffer)
3160{
3161 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3162 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3163 Assert(pDevice);
3164 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3165 Assert(!pFlagBuffer);
3166 HRESULT hr = S_OK;
3167
3168//#ifdef DEBUG_misha
3169// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3170// vboxVDbgDumpSurfData((pDevice, ">>>DrawPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3171// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3172//#endif
3173
3174 if (!pDevice->cStreamSources)
3175 {
3176 if (pDevice->aStreamSourceUm[0].pvBuffer)
3177 {
3178#ifdef DEBUG
3179 for (UINT i = 1; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3180 {
3181 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3182 }
3183#endif
3184 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType,
3185 pData->PrimitiveCount,
3186 ((uint8_t*)pDevice->aStreamSourceUm[0].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[0].cbStride,
3187 pDevice->aStreamSourceUm[0].cbStride);
3188 Assert(hr == S_OK);
3189
3190// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
3191 }
3192 else
3193 {
3194 /* todo: impl */
3195 Assert(0);
3196 }
3197 }
3198 else
3199 {
3200
3201#ifdef DEBUG
3202 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3203 {
3204 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3205 }
3206
3207 uint32_t cStreams = 0;
3208 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
3209 {
3210 if (pDevice->aStreamSource[i])
3211 {
3212 ++cStreams;
3213 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
3214 }
3215 }
3216
3217 Assert(cStreams);
3218 Assert(cStreams == pDevice->cStreamSources);
3219#endif
3220 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
3221 pData->VStart,
3222 pData->PrimitiveCount);
3223 Assert(hr == S_OK);
3224
3225// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitive\n"));
3226#if 0
3227 IDirect3DVertexDeclaration9* pDecl;
3228 hr = pDevice9If->GetVertexDeclaration(&pDecl);
3229 Assert(hr == S_OK);
3230 if (hr == S_OK)
3231 {
3232 Assert(pDecl);
3233 D3DVERTEXELEMENT9 aDecls9[MAXD3DDECLLENGTH];
3234 UINT cDecls9 = 0;
3235 hr = pDecl->GetDeclaration(aDecls9, &cDecls9);
3236 Assert(hr == S_OK);
3237 if (hr == S_OK)
3238 {
3239 Assert(cDecls9);
3240 for (UINT i = 0; i < cDecls9 - 1 /* the last one is D3DDECL_END */; ++i)
3241 {
3242 D3DVERTEXELEMENT9 *pDecl9 = &aDecls9[i];
3243 Assert(pDecl9->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm) || pDecl9->Stream == 0xff);
3244 if (pDecl9->Stream != 0xff)
3245 {
3246 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrc = &pDevice->aStreamSourceUm[pDecl9->Stream];
3247 if (pStrSrc->pvBuffer)
3248 {
3249 WORD iStream = pDecl9->Stream;
3250 D3DVERTEXELEMENT9 *pLastCDecl9 = pDecl9;
3251 for (UINT j = i+1; j < cDecls9 - 1 /* the last one is D3DDECL_END */; ++j)
3252 {
3253 pDecl9 = &aDecls9[j];
3254 if (iStream == pDecl9->Stream)
3255 {
3256 pDecl9->Stream = 0xff; /* mark as done */
3257 Assert(pDecl9->Offset != pLastCDecl9->Offset);
3258 if (pDecl9->Offset > pLastCDecl9->Offset)
3259 pLastCDecl9 = pDecl9;
3260 }
3261 }
3262 /* vertex size is MAX(all Offset's) + sizeof (data_type with MAX offset) + stride*/
3263 UINT cbVertex = pLastCDecl9->Offset + pStrSrc->cbStride;
3264 UINT cbType;
3265 switch (pLastCDecl9->Type)
3266 {
3267 case D3DDECLTYPE_FLOAT1:
3268 cbType = sizeof (float);
3269 break;
3270 case D3DDECLTYPE_FLOAT2:
3271 cbType = sizeof (float) * 2;
3272 break;
3273 case D3DDECLTYPE_FLOAT3:
3274 cbType = sizeof (float) * 3;
3275 break;
3276 case D3DDECLTYPE_FLOAT4:
3277 cbType = sizeof (float) * 4;
3278 break;
3279 case D3DDECLTYPE_D3DCOLOR:
3280 cbType = 4;
3281 break;
3282 case D3DDECLTYPE_UBYTE4:
3283 cbType = 4;
3284 break;
3285 case D3DDECLTYPE_SHORT2:
3286 cbType = sizeof (short) * 2;
3287 break;
3288 case D3DDECLTYPE_SHORT4:
3289 cbType = sizeof (short) * 4;
3290 break;
3291 case D3DDECLTYPE_UBYTE4N:
3292 cbType = 4;
3293 break;
3294 case D3DDECLTYPE_SHORT2N:
3295 cbType = sizeof (short) * 2;
3296 break;
3297 case D3DDECLTYPE_SHORT4N:
3298 cbType = sizeof (short) * 4;
3299 break;
3300 case D3DDECLTYPE_USHORT2N:
3301 cbType = sizeof (short) * 2;
3302 break;
3303 case D3DDECLTYPE_USHORT4N:
3304 cbType = sizeof (short) * 4;
3305 break;
3306 case D3DDECLTYPE_UDEC3:
3307 cbType = sizeof (signed) * 3;
3308 break;
3309 case D3DDECLTYPE_DEC3N:
3310 cbType = sizeof (unsigned) * 3;
3311 break;
3312 case D3DDECLTYPE_FLOAT16_2:
3313 cbType = 2 * 2;
3314 break;
3315 case D3DDECLTYPE_FLOAT16_4:
3316 cbType = 2 * 4;
3317 break;
3318 default:
3319 Assert(0);
3320 cbType = 1;
3321 }
3322 cbVertex += cbType;
3323
3324 UINT cVertexes;
3325 switch (pData->PrimitiveType)
3326 {
3327 case D3DPT_POINTLIST:
3328 cVertexes = pData->PrimitiveCount;
3329 break;
3330 case D3DPT_LINELIST:
3331 cVertexes = pData->PrimitiveCount * 2;
3332 break;
3333 case D3DPT_LINESTRIP:
3334 cVertexes = pData->PrimitiveCount + 1;
3335 break;
3336 case D3DPT_TRIANGLELIST:
3337 cVertexes = pData->PrimitiveCount * 3;
3338 break;
3339 case D3DPT_TRIANGLESTRIP:
3340 cVertexes = pData->PrimitiveCount + 2;
3341 break;
3342 case D3DPT_TRIANGLEFAN:
3343 cVertexes = pData->PrimitiveCount + 2;
3344 break;
3345 default:
3346 Assert(0);
3347 cVertexes = pData->PrimitiveCount;
3348 }
3349 UINT cbVertexes = cVertexes * cbVertex;
3350 IDirect3DVertexBuffer9 *pCurVb = NULL, *pVb = NULL;
3351 UINT cbOffset;
3352 UINT cbStride;
3353 hr = pDevice9If->GetStreamSource(iStream, &pCurVb, &cbOffset, &cbStride);
3354 Assert(hr == S_OK);
3355 if (hr == S_OK)
3356 {
3357 if (pCurVb)
3358 {
3359 if (cbStride == pStrSrc->cbStride)
3360 {
3361 /* ensure our data feets in the buffer */
3362 D3DVERTEXBUFFER_DESC Desc;
3363 hr = pCurVb->GetDesc(&Desc);
3364 Assert(hr == S_OK);
3365 if (hr == S_OK)
3366 {
3367 if (Desc.Size >= cbVertexes)
3368 pVb = pCurVb;
3369 }
3370 }
3371 }
3372 }
3373 else
3374 {
3375 pCurVb = NULL;
3376 }
3377
3378 if (!pVb)
3379 {
3380 hr = pDevice9If->CreateVertexBuffer(cbVertexes,
3381 0, /* DWORD Usage */
3382 0, /* DWORD FVF */
3383 D3DPOOL_DEFAULT, /* D3DPOOL Pool */
3384 &pVb,
3385 NULL /*HANDLE* pSharedHandle*/);
3386 Assert(hr == S_OK);
3387 if (hr == S_OK)
3388 {
3389 hr = pDevice9If->SetStreamSource(iStream, pVb, 0, pStrSrc->cbStride);
3390 Assert(hr == S_OK);
3391 if (hr == S_OK)
3392 {
3393 if (pCurVb)
3394 pCurVb->Release();
3395 }
3396 else
3397 {
3398 pVb->Release();
3399 pVb = NULL;
3400 }
3401 }
3402 }
3403
3404 if (pVb)
3405 {
3406 Assert(hr == S_OK);
3407 VOID *pvData;
3408 hr = pVb->Lock(0, /* UINT OffsetToLock */
3409 cbVertexes,
3410 &pvData,
3411 D3DLOCK_DISCARD);
3412 Assert(hr == S_OK);
3413 if (hr == S_OK)
3414 {
3415 memcpy (pvData, ((uint8_t*)pStrSrc->pvBuffer) + pData->VStart * cbVertex, cbVertexes);
3416 HRESULT tmpHr = pVb->Unlock();
3417 Assert(tmpHr == S_OK);
3418 }
3419 }
3420 }
3421 }
3422 }
3423 }
3424 if (hr == S_OK)
3425 {
3426 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
3427 0 /* <- since we use our owne StreamSource buffer which has data at the very beginning*/,
3428 pData->PrimitiveCount);
3429 Assert(hr == S_OK);
3430 }
3431 }
3432#endif
3433 }
3434
3435//#ifdef DEBUG_misha
3436// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3437// vboxVDbgDumpSurfData((pDevice, "<<<DrawPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3438// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3439//#endif
3440
3441 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3442 return hr;
3443}
3444
3445static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE* pData)
3446{
3447 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3448 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3449 Assert(pDevice);
3450 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3451//#ifdef DEBUG_misha
3452// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3453// vboxVDbgDumpSurfData((pDevice, ">>>DrawIndexedPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3454// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3455//#endif
3456
3457#ifdef DEBUG
3458 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3459 {
3460 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3461 }
3462
3463 Assert(pDevice->pIndicesAlloc);
3464 Assert(!pDevice->pIndicesAlloc->LockInfo.cLocks);
3465
3466 uint32_t cStreams = 0;
3467 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
3468 {
3469 if (pDevice->aStreamSource[i])
3470 {
3471 ++cStreams;
3472 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
3473 }
3474 }
3475
3476 Assert(cStreams);
3477 Assert(cStreams == pDevice->cStreamSources);
3478#endif
3479
3480 HRESULT hr = pDevice9If->DrawIndexedPrimitive(
3481 pData->PrimitiveType,
3482 pData->BaseVertexIndex,
3483 pData->MinIndex,
3484 pData->NumVertices,
3485 pData->StartIndex,
3486 pData->PrimitiveCount);
3487 Assert(hr == S_OK);
3488
3489//#ifdef DEBUG_misha
3490// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3491// vboxVDbgDumpSurfData((pDevice, "<<<DrawIndexedPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3492// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3493//#endif
3494
3495
3496 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3497 return hr;
3498}
3499
3500static HRESULT APIENTRY vboxWddmDDevDrawRectPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWRECTPATCH* pData, CONST D3DDDIRECTPATCH_INFO* pInfo, CONST FLOAT* pPatch)
3501{
3502 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3503 Assert(0);
3504 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3505 return E_FAIL;
3506}
3507
3508static HRESULT APIENTRY vboxWddmDDevDrawTriPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWTRIPATCH* pData, CONST D3DDDITRIPATCH_INFO* pInfo, CONST FLOAT* pPatch)
3509{
3510 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3511 Assert(0);
3512 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3513 return E_FAIL;
3514}
3515
3516static HRESULT APIENTRY vboxWddmDDevDrawPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE2* pData)
3517{
3518 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3519 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3520 Assert(pDevice);
3521 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3522 HRESULT hr;
3523
3524#if 0
3525 int stream;
3526 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
3527 {
3528 if (pDevice->aStreamSource[stream] && pDevice->aStreamSource[stream]->LockInfo.cLocks)
3529 {
3530 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
3531 if (pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite))
3532 {
3533 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf;
3534 Assert(pLock->fFlags.RangeValid);
3535 pD3D9VBuf->Lock(pLock->Range.Offset, pLock->Range.Size,
3536 &pLock->LockedRect.pBits,
3537 vboxDDI2D3DLockFlags(pLock->fFlags));
3538 RECT r;
3539 r.top = 0;
3540 r.left = pLock->Range.Offset;
3541 r.bottom = 1;
3542 r.right = pLock->Range.Offset + pLock->Range.Size;
3543
3544 vboxWddmLockUnlockMemSynch(pDevice->aStreamSource[stream], &pLock->LockedRect, &r, true /*bool bToLockInfo*/);
3545
3546 pD3D9VBuf->Unlock();
3547 }
3548 }
3549 }
3550
3551 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset, pData->PrimitiveCount);
3552#else
3553//#ifdef DEBUG_misha
3554// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3555// vboxVDbgDumpSurfData((pDevice, ">>>DrawPrimitive2:\n", pDevice->pRenderTargetRc, iBackBuf,
3556// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3557//#endif
3558
3559#ifdef DEBUG
3560 uint32_t cStreams = 0;
3561#endif
3562
3563 int stream;
3564 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
3565 {
3566 if (pDevice->aStreamSource[stream])
3567 {
3568#ifdef DEBUG
3569 ++cStreams;
3570#endif
3571 Assert(stream==0); /*only stream 0 should be accessed here*/
3572 Assert(pDevice->StreamSourceInfo[stream].uiStride!=0);
3573 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
3574
3575 if (pDevice->aStreamSource[stream]->LockInfo.cLocks)
3576 {
3577// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
3578
3579 Assert(pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite));
3580 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType, pData->PrimitiveCount,
3581 (void*)((uintptr_t)pDevice->aStreamSource[stream]->pvMem+pDevice->StreamSourceInfo[stream].uiOffset+pData->FirstVertexOffset),
3582 pDevice->StreamSourceInfo[stream].uiStride);
3583 Assert(hr == S_OK);
3584 hr = pDevice9If->SetStreamSource(stream, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf, pDevice->StreamSourceInfo[stream].uiOffset, pDevice->StreamSourceInfo[stream].uiStride);
3585 Assert(hr == S_OK);
3586 }
3587 else
3588 {
3589// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitive\n"));
3590
3591 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset/pDevice->StreamSourceInfo[stream].uiStride, pData->PrimitiveCount);
3592 Assert(hr == S_OK);
3593 }
3594 }
3595 }
3596
3597#ifdef DEBUG
3598 Assert(cStreams);
3599 Assert(cStreams == pDevice->cStreamSources);
3600#endif
3601#endif
3602
3603//#ifdef DEBUG_misha
3604// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3605// vboxVDbgDumpSurfData((pDevice, "<<<DrawPrimitive2:\n", pDevice->pRenderTargetRc, iBackBuf,
3606// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3607//#endif
3608
3609 Assert(hr == S_OK);
3610 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3611 return hr;
3612}
3613
3614static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE2* pData, UINT dwIndicesSize, CONST VOID* pIndexBuffer, CONST UINT* pFlagBuffer)
3615{
3616 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3617 Assert(0);
3618 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3619 return E_FAIL;
3620}
3621
3622static HRESULT APIENTRY vboxWddmDDevVolBlt(HANDLE hDevice, CONST D3DDDIARG_VOLUMEBLT* pData)
3623{
3624 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3625 Assert(0);
3626 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3627 return E_FAIL;
3628}
3629
3630static HRESULT APIENTRY vboxWddmDDevBufBlt(HANDLE hDevice, CONST D3DDDIARG_BUFFERBLT* pData)
3631{
3632 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3633 Assert(0);
3634 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3635 return E_FAIL;
3636}
3637
3638static HRESULT APIENTRY vboxWddmDDevTexBlt(HANDLE hDevice, CONST D3DDDIARG_TEXBLT* pData)
3639{
3640 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3641 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3642 Assert(pDevice);
3643 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3644 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
3645 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
3646 /* requirements for D3DDevice9::UpdateTexture */
3647 Assert(pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
3648 Assert(pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
3649 HRESULT hr = S_OK;
3650
3651#ifdef DEBUG_misha
3652 bool bDo = false;
3653 IDirect3DSurface9 *pTstSrcSurfIf = NULL;
3654 IDirect3DSurface9 *pTstDstSurfIf = NULL;
3655
3656 if (g_VDbgTstDumpEnable)
3657 {
3658 hr = vboxWddmSurfGet(pSrcRc, 0, &pTstSrcSurfIf);
3659 Assert(hr == S_OK);
3660 hr = vboxWddmSurfGet(pDstRc, 0, &pTstDstSurfIf);
3661 Assert(hr == S_OK);
3662
3663 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
3664 {
3665 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
3666 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
3667 {
3668 D3DSURFACE_DESC SrcDesc;
3669 HRESULT hr = pTstSrcSurfIf->GetDesc(&SrcDesc);
3670 Assert(hr == S_OK);
3671 if (hr == S_OK)
3672 {
3673 D3DSURFACE_DESC DstDesc;
3674 hr = pTstDstSurfIf->GetDesc(&DstDesc);
3675 Assert(hr == S_OK);
3676 if (hr == S_OK)
3677 {
3678 if (SrcDesc.Width == DstDesc.Width
3679 && SrcDesc.Height == DstDesc.Height)
3680 {
3681 bDo = true;
3682 }
3683 }
3684 }
3685 }
3686 }
3687 }
3688
3689 if (bDo)
3690 {
3691 RECT DstRect;
3692 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
3693 vboxVDbgDumpSurfData((pDevice, "TexBlt-pre Src:\n", pSrcRc, 0, &pData->SrcRect, pTstSrcSurfIf, "\n"));
3694 vboxVDbgDumpSurfData((pDevice, "TexBlt-pre Dst:\n", pDstRc, 0, &DstRect, pTstDstSurfIf, "\n"));
3695 }
3696#endif
3697
3698 if (pSrcRc->aAllocations[0].D3DWidth == pDstRc->aAllocations[0].D3DWidth
3699 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
3700 && pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat
3701 &&pData->DstPoint.x == 0 && pData->DstPoint.y == 0
3702 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
3703 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
3704 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height)
3705 {
3706 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcRc->aAllocations[0].pD3DIf;
3707 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstRc->aAllocations[0].pD3DIf;
3708 Assert(pD3DIfSrcTex);
3709 Assert(pD3DIfDstTex);
3710 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
3711 Assert(hr == S_OK);
3712 }
3713 else
3714 {
3715 IDirect3DSurface9 *pSrcSurfIf = NULL;
3716 IDirect3DSurface9 *pDstSurfIf = NULL;
3717 hr = vboxWddmSurfGet(pDstRc, 0, &pDstSurfIf);
3718 Assert(hr == S_OK);
3719 if (hr == S_OK)
3720 {
3721 hr = vboxWddmSurfGet(pSrcRc, 0, &pSrcSurfIf);
3722 Assert(hr == S_OK);
3723 if (hr == S_OK)
3724 {
3725 RECT DstRect;
3726 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
3727#ifdef DEBUG
3728 RECT tstRect = {0,0, pDstRc->aAllocations[0].SurfDesc.width, pDstRc->aAllocations[0].SurfDesc.height};
3729 Assert(vboxWddmRectIsCoveres(&tstRect, &DstRect));
3730#endif
3731 hr = pDevice9If->StretchRect(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &DstRect, D3DTEXF_NONE);
3732 Assert(hr == S_OK);
3733 pSrcSurfIf->Release();
3734 }
3735 pDstSurfIf->Release();
3736 }
3737 }
3738
3739#ifdef DEBUG_misha
3740 if (bDo)
3741 {
3742 RECT DstRect;
3743 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
3744 vboxVDbgDumpSurfData((pDevice, "TexBlt-post Src:\n", pSrcRc, 0, &pData->SrcRect, pTstSrcSurfIf, "\n"));
3745 vboxVDbgDumpSurfData((pDevice, "TexBlt-post Dst:\n", pDstRc, 0, &DstRect, pTstDstSurfIf, "\n"));
3746 }
3747
3748 if (pTstDstSurfIf)
3749 pTstDstSurfIf->Release();
3750 if (pTstSrcSurfIf)
3751 pTstSrcSurfIf->Release();
3752#endif
3753 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3754 return hr;
3755}
3756
3757static HRESULT APIENTRY vboxWddmDDevStateSet(HANDLE hDevice, D3DDDIARG_STATESET* pData)
3758{
3759 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3760 Assert(0);
3761 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3762 return E_FAIL;
3763}
3764static HRESULT APIENTRY vboxWddmDDevSetPriority(HANDLE hDevice, CONST D3DDDIARG_SETPRIORITY* pData)
3765{
3766 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3767 Assert(0);
3768 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3769 return E_FAIL;
3770}
3771AssertCompile(sizeof (RECT) == sizeof (D3DRECT));
3772AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DRECT, x1));
3773AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DRECT, x2));
3774AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DRECT, y1));
3775AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DRECT, y2));
3776AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DRECT, x1));
3777AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DRECT, x2));
3778AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DRECT, y1));
3779AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DRECT, y2));
3780
3781static HRESULT APIENTRY vboxWddmDDevClear(HANDLE hDevice, CONST D3DDDIARG_CLEAR* pData, UINT NumRect, CONST RECT* pRect)
3782{
3783 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3784 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3785 Assert(pDevice);
3786 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3787 HRESULT hr = pDevice9If->Clear(NumRect, (D3DRECT*)pRect /* see AssertCompile above */,
3788 pData->Flags,
3789 pData->FillColor,
3790 pData->FillDepth,
3791 pData->FillStencil);
3792 Assert(hr == S_OK);
3793 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3794 return hr;
3795}
3796static HRESULT APIENTRY vboxWddmDDevUpdatePalette(HANDLE hDevice, CONST D3DDDIARG_UPDATEPALETTE* pData, CONST PALETTEENTRY* pPaletteData)
3797{
3798 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3799 Assert(0);
3800 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3801 return E_FAIL;
3802}
3803
3804static HRESULT APIENTRY vboxWddmDDevSetPalette(HANDLE hDevice, CONST D3DDDIARG_SETPALETTE* pData)
3805{
3806 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3807 Assert(0);
3808 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3809 return E_FAIL;
3810}
3811
3812static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONST* pData , CONST VOID* pRegisters)
3813{
3814 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3815 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3816 Assert(pDevice);
3817 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3818 HRESULT hr = pDevice9If->SetVertexShaderConstantF(
3819 pData->Register,
3820 (CONST float*)pRegisters,
3821 pData->Count);
3822 Assert(hr == S_OK);
3823 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3824 return hr;
3825}
3826static HRESULT APIENTRY vboxWddmDDevMultiplyTransform(HANDLE hDevice, CONST D3DDDIARG_MULTIPLYTRANSFORM* pData)
3827{
3828 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3829 Assert(0);
3830 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3831 return E_FAIL;
3832}
3833static HRESULT APIENTRY vboxWddmDDevSetTransform(HANDLE hDevice, CONST D3DDDIARG_SETTRANSFORM* pData)
3834{
3835 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3836 Assert(0);
3837 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3838 return E_FAIL;
3839}
3840static HRESULT APIENTRY vboxWddmDDevSetViewport(HANDLE hDevice, CONST D3DDDIARG_VIEWPORTINFO* pData)
3841{
3842 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3843 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3844 Assert(pDevice);
3845 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3846 pDevice->ViewPort.X = pData->X;
3847 pDevice->ViewPort.Y = pData->Y;
3848 pDevice->ViewPort.Width = pData->Width;
3849 pDevice->ViewPort.Height = pData->Height;
3850 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
3851 Assert(hr == S_OK);
3852 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3853 return hr;
3854}
3855static HRESULT APIENTRY vboxWddmDDevSetZRange(HANDLE hDevice, CONST D3DDDIARG_ZRANGE* pData)
3856{
3857 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3858 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3859 Assert(pDevice);
3860 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3861 pDevice->ViewPort.MinZ = pData->MinZ;
3862 pDevice->ViewPort.MaxZ = pData->MaxZ;
3863 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
3864 Assert(hr == S_OK);
3865 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3866 return hr;
3867}
3868static HRESULT APIENTRY vboxWddmDDevSetMaterial(HANDLE hDevice, CONST D3DDDIARG_SETMATERIAL* pData)
3869{
3870 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3871 Assert(0);
3872 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3873 return E_FAIL;
3874}
3875static HRESULT APIENTRY vboxWddmDDevSetLight(HANDLE hDevice, CONST D3DDDIARG_SETLIGHT* pData, CONST D3DDDI_LIGHT* pLightProperties)
3876{
3877 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3878 Assert(0);
3879 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3880 return E_FAIL;
3881}
3882static HRESULT APIENTRY vboxWddmDDevCreateLight(HANDLE hDevice, CONST D3DDDIARG_CREATELIGHT* 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 vboxWddmDDevDestroyLight(HANDLE hDevice, CONST D3DDDIARG_DESTROYLIGHT* pData)
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 vboxWddmDDevSetClipPlane(HANDLE hDevice, CONST D3DDDIARG_SETCLIPPLANE* pData)
3897{
3898 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3899 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3900 Assert(pDevice);
3901 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3902 HRESULT hr = pDevice9If->SetClipPlane(pData->Index, pData->Plane);
3903 Assert(hr == S_OK);
3904 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3905 return hr;
3906}
3907
3908static HRESULT APIENTRY vboxWddmDDevGetInfo(HANDLE hDevice, UINT DevInfoID, VOID* pDevInfoStruct, UINT DevInfoSize)
3909{
3910 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3911 HRESULT hr = S_OK;
3912 switch (DevInfoID)
3913 {
3914 case D3DDDIDEVINFOID_VCACHE:
3915 {
3916 Assert(DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE));
3917 if (DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE))
3918 {
3919 D3DDDIDEVINFO_VCACHE *pVCache = (D3DDDIDEVINFO_VCACHE*)pDevInfoStruct;
3920 pVCache->Pattern = MAKEFOURCC('C', 'A', 'C', 'H');
3921 pVCache->OptMethod = 0 /* D3DXMESHOPT_STRIPREORDER */;
3922 pVCache->CacheSize = 0;
3923 pVCache->MagicNumber = 0;
3924 }
3925 else
3926 hr = E_INVALIDARG;
3927 break;
3928 }
3929 default:
3930 Assert(0);
3931 hr = E_NOTIMPL;
3932 }
3933 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3934 return hr;
3935}
3936
3937static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
3938{
3939 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3940 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3941 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
3942 Assert(pData->SubResourceIndex < pRc->cAllocations);
3943 if (pData->SubResourceIndex >= pRc->cAllocations)
3944 return E_INVALIDARG;
3945
3946 HRESULT hr = S_OK;
3947
3948 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
3949 {
3950// Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex);
3951
3952 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
3953 {
3954 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
3955 Assert(pData->SubResourceIndex < pRc->cAllocations);
3956 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3957 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
3958 Assert(pD3DIfTex);
3959 RECT *pRect = NULL;
3960 bool bNeedResynch = false;
3961 Assert(!pData->Flags.RangeValid);
3962 Assert(!pData->Flags.BoxValid);
3963 if (pData->Flags.AreaValid)
3964 {
3965 pRect = &pData->Area;
3966 }
3967
3968 /* else - we lock the entire texture, pRect == NULL */
3969
3970// Assert(!pLockAlloc->LockInfo.cLocks);
3971 if (!pLockAlloc->LockInfo.cLocks)
3972 {
3973 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
3974 &pLockAlloc->LockInfo.LockedRect,
3975 pRect,
3976 vboxDDI2D3DLockFlags(pData->Flags));
3977 Assert(hr == S_OK);
3978 if (hr == S_OK)
3979 {
3980
3981// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
3982 pLockAlloc->LockInfo.fFlags = pData->Flags;
3983 if (pRect)
3984 {
3985 pLockAlloc->LockInfo.Area = *pRect;
3986 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 1);
3987// pLockAlloc->LockInfo.fFlags.AreaValid = 1;
3988 }
3989 else
3990 {
3991 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 0);
3992// pLockAlloc->LockInfo.fFlags.AreaValid = 0;
3993 }
3994
3995 bNeedResynch = !pData->Flags.Discard;
3996 }
3997 }
3998 else
3999 {
4000// Assert(pLockAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4001// if (pLockAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4002// {
4003// }
4004 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid);
4005 if (pLockAlloc->LockInfo.fFlags.AreaValid && pData->Flags.AreaValid)
4006 {
4007 Assert(pLockAlloc->LockInfo.Area.left == pData->Area.left);
4008 Assert(pLockAlloc->LockInfo.Area.top == pData->Area.top);
4009 Assert(pLockAlloc->LockInfo.Area.right == pData->Area.right);
4010 Assert(pLockAlloc->LockInfo.Area.bottom == pData->Area.bottom);
4011 }
4012 Assert(pLockAlloc->LockInfo.LockedRect.pBits);
4013
4014 bNeedResynch = pLockAlloc->LockInfo.fFlags.Discard && !pData->Flags.Discard;
4015
4016 Assert(!bNeedResynch);
4017
4018 if (/*(pLockAlloc->LockInfo.fFlags.Discard && !pData->Flags.Discard)
4019 || */
4020 (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly))
4021 {
4022 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
4023 Assert(hr == S_OK);
4024 if (hr == S_OK)
4025 {
4026 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
4027 &pLockAlloc->LockInfo.LockedRect,
4028 pRect,
4029 vboxDDI2D3DLockFlags(pData->Flags));
4030 Assert(hr == S_OK);
4031 pLockAlloc->LockInfo.fFlags.ReadOnly = 0;
4032 }
4033 }
4034 }
4035
4036 if (hr == S_OK)
4037 {
4038 ++pLockAlloc->LockInfo.cLocks;
4039
4040 if (!pData->Flags.NotifyOnly)
4041 {
4042 pData->pSurfData = pLockAlloc->LockInfo.LockedRect.pBits;
4043 pData->Pitch = pLockAlloc->LockInfo.LockedRect.Pitch;
4044 pData->SlicePitch = 0;
4045 Assert(pLockAlloc->SurfDesc.slicePitch == 0);
4046 Assert(!pLockAlloc->pvMem);
4047 }
4048 else
4049 {
4050 Assert(pLockAlloc->pvMem);
4051 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4052#if 0
4053 if (bNeedResynch)
4054 vboxWddmLockUnlockMemSynch(pLockAlloc, &pLockAlloc->LockInfo.LockedRect, pRect, false /*bool bToLockInfo*/);
4055#endif
4056 }
4057 }
4058 }
4059 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
4060 {
4061 Assert(pData->SubResourceIndex < pRc->cAllocations);
4062 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4063 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4064 BOOL bLocked = false;
4065 Assert(pD3D9VBuf);
4066 Assert(!pData->Flags.AreaValid);
4067 Assert(!pData->Flags.BoxValid);
4068 D3DDDIRANGE *pRange = NULL;
4069 if (pData->Flags.RangeValid)
4070 {
4071 pRange = &pData->Range;
4072 }
4073
4074 /* else - we lock the entire vertex buffer, pRect == NULL */
4075
4076 Assert(!pAlloc->LockInfo.cLocks);
4077 if (!pAlloc->LockInfo.cLocks)
4078 {
4079 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
4080 {
4081 hr = pD3D9VBuf->Lock(pRange ? pRange->Offset : 0,
4082 pRange ? pRange->Size : 0,
4083 &pAlloc->LockInfo.LockedRect.pBits,
4084 vboxDDI2D3DLockFlags(pData->Flags));
4085 bLocked = true;
4086 }
4087
4088 Assert(hr == S_OK);
4089 if (hr == S_OK)
4090 {
4091 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.width;
4092// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4093 pAlloc->LockInfo.fFlags = pData->Flags;
4094 if (pRange)
4095 {
4096 pAlloc->LockInfo.Range = *pRange;
4097 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
4098// pAlloc->LockInfo.fFlags.RangeValid = 1;
4099 }
4100 else
4101 {
4102 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
4103// pAlloc->LockInfo.fFlags.RangeValid = 0;
4104 }
4105 }
4106 }
4107 else
4108 {
4109// Assert(pAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4110// if (pAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4111// {
4112// }
4113 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
4114 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
4115 {
4116 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
4117 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
4118 }
4119 Assert(pAlloc->LockInfo.LockedRect.pBits);
4120 }
4121
4122 if (hr == S_OK)
4123 {
4124 ++pAlloc->LockInfo.cLocks;
4125
4126 if (!pData->Flags.NotifyOnly)
4127 {
4128 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
4129 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
4130 pData->SlicePitch = 0;
4131 Assert(pAlloc->SurfDesc.slicePitch == 0);
4132 Assert(!pAlloc->pvMem);
4133 }
4134 else
4135 {
4136 Assert(pAlloc->pvMem);
4137 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4138 if (bLocked && !pData->Flags.Discard)
4139 {
4140 RECT r, *pr;
4141 if (pRange)
4142 {
4143 r.top = 0;
4144 r.left = pRange->Offset;
4145 r.bottom = 1;
4146 r.right = pRange->Offset + pRange->Size;
4147 pr = &r;
4148 }
4149 else
4150 pr = NULL;
4151 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
4152 }
4153 }
4154 }
4155 }
4156 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
4157 {
4158 Assert(pData->SubResourceIndex < pRc->cAllocations);
4159 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4160 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
4161 BOOL bLocked = false;
4162 Assert(pD3D9IBuf);
4163 Assert(!pData->Flags.AreaValid);
4164 Assert(!pData->Flags.BoxValid);
4165 D3DDDIRANGE *pRange = NULL;
4166 if (pData->Flags.RangeValid)
4167 {
4168 pRange = &pData->Range;
4169 }
4170
4171 /* else - we lock the entire vertex buffer, pRect == NULL */
4172
4173 Assert(!pAlloc->LockInfo.cLocks);
4174 if (!pAlloc->LockInfo.cLocks)
4175 {
4176 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
4177 {
4178 hr = pD3D9IBuf->Lock(pRange ? pRange->Offset : 0,
4179 pRange ? pRange->Size : 0,
4180 &pAlloc->LockInfo.LockedRect.pBits,
4181 vboxDDI2D3DLockFlags(pData->Flags));
4182 bLocked = true;
4183 }
4184
4185 Assert(hr == S_OK);
4186 if (hr == S_OK)
4187 {
4188 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.width;
4189// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4190 pAlloc->LockInfo.fFlags = pData->Flags;
4191 if (pRange)
4192 {
4193 pAlloc->LockInfo.Range = *pRange;
4194 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
4195// pAlloc->LockInfo.fFlags.RangeValid = 1;
4196 }
4197 else
4198 {
4199 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
4200// pAlloc->LockInfo.fFlags.RangeValid = 0;
4201 }
4202 }
4203 }
4204 else
4205 {
4206// Assert(pAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4207// if (pAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4208// {
4209// }
4210 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
4211 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
4212 {
4213 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
4214 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
4215 }
4216 Assert(pAlloc->LockInfo.LockedRect.pBits);
4217 }
4218
4219 if (hr == S_OK)
4220 {
4221 ++pAlloc->LockInfo.cLocks;
4222
4223 if (!pData->Flags.NotifyOnly)
4224 {
4225 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
4226 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
4227 pData->SlicePitch = 0;
4228 Assert(pAlloc->SurfDesc.slicePitch == 0);
4229 Assert(!pAlloc->pvMem);
4230 }
4231 else
4232 {
4233 Assert(pAlloc->pvMem);
4234 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4235 if (bLocked && !pData->Flags.Discard)
4236 {
4237 RECT r, *pr;
4238 if (pRange)
4239 {
4240 r.top = 0;
4241 r.left = pRange->Offset;
4242 r.bottom = 1;
4243 r.right = pRange->Offset + pRange->Size;
4244 pr = &r;
4245 }
4246 else
4247 pr = NULL;
4248 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
4249 }
4250 }
4251 }
4252 }
4253 else
4254 {
4255 Assert(0);
4256 }
4257 }
4258 else
4259 {
4260 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4261 D3DDDICB_LOCK LockData;
4262 LockData.hAllocation = pAlloc->hAllocation;
4263 LockData.PrivateDriverData = 0;
4264 LockData.NumPages = 0;
4265 LockData.pPages = NULL;
4266 LockData.pData = NULL; /* out */
4267 LockData.Flags.Value = 0;
4268 LockData.Flags.Discard = pData->Flags.Discard;
4269 LockData.Flags.DonotWait = pData->Flags.DoNotWait;
4270
4271
4272 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
4273 Assert(hr == S_OK || (hr == D3DERR_WASSTILLDRAWING && pData->Flags.DoNotWait));
4274 if (hr == S_OK)
4275 {
4276 Assert(!pAlloc->LockInfo.cLocks);
4277
4278 uintptr_t offset;
4279 if (pData->Flags.AreaValid)
4280 {
4281 offset = pAlloc->SurfDesc.pitch * pData->Area.top +
4282 ((pAlloc->SurfDesc.bpp * pData->Area.left) >> 3);
4283 }
4284 else if (pData->Flags.RangeValid)
4285 {
4286 offset = pData->Range.Offset;
4287 }
4288 else if (pData->Flags.BoxValid)
4289 {
4290 vboxVDbgPrintF((__FUNCTION__": Implement Box area"));
4291 Assert(0);
4292 }
4293 else
4294 {
4295 offset = 0;
4296 }
4297
4298 if (!pData->Flags.ReadOnly)
4299 {
4300 if (pData->Flags.AreaValid)
4301 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, &pData->Area);
4302 else
4303 {
4304 Assert(!pData->Flags.RangeValid);
4305 Assert(!pData->Flags.BoxValid);
4306 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, NULL); /* <- NULL means the entire surface */
4307 }
4308 }
4309
4310 if (pData->Flags.Discard)
4311 {
4312 /* check if the surface was renamed */
4313 if (LockData.hAllocation)
4314 pAlloc->hAllocation = LockData.hAllocation;
4315 }
4316
4317 pData->pSurfData = ((uint8_t*)LockData.pData) + offset;
4318 pData->Pitch = pAlloc->SurfDesc.pitch;
4319 pData->SlicePitch = pAlloc->SurfDesc.slicePitch;
4320
4321 Assert(hr == S_OK);
4322 ++pAlloc->LockInfo.cLocks;
4323 }
4324 }
4325
4326 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(%d)\n", hDevice, hr));
4327 return hr;
4328}
4329static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOCK* pData)
4330{
4331 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4332 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4333 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4334 HRESULT hr = S_OK;
4335
4336 Assert(pData->SubResourceIndex < pRc->cAllocations);
4337 if (pData->SubResourceIndex >= pRc->cAllocations)
4338 return E_INVALIDARG;
4339
4340 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4341 {
4342 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
4343 {
4344 Assert(pData->SubResourceIndex < pRc->cAllocations);
4345 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4346
4347 --pLockAlloc->LockInfo.cLocks;
4348 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
4349// pLockAlloc->LockInfo.cLocks = 0;
4350 if (!pLockAlloc->LockInfo.cLocks)
4351 {
4352 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
4353// Assert(!pLockAlloc->LockInfo.cLocks);
4354 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
4355 Assert(pD3DIfTex);
4356 /* this is a sysmem texture, update */
4357#if 0
4358 if (pLockAlloc->pvMem && !pLockAlloc->LockInfo.fFlags.ReadOnly)
4359 {
4360 vboxWddmLockUnlockMemSynch(pLockAlloc, &pLockAlloc->LockInfo.LockedRect,
4361 pLockAlloc->LockInfo.fFlags.AreaValid ? &pLockAlloc->LockInfo.Area : NULL,
4362 true /*bool bToLockInfo*/);
4363 }
4364#endif
4365 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
4366 Assert(hr == S_OK);
4367 }
4368 else
4369 {
4370 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
4371 }
4372 }
4373 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
4374 {
4375 Assert(pData->SubResourceIndex < pRc->cAllocations);
4376 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4377
4378 --pAlloc->LockInfo.cLocks;
4379 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4380 if (!pAlloc->LockInfo.cLocks
4381 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
4382 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
4383 {
4384// Assert(!pAlloc->LockInfo.cLocks);
4385 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4386 Assert(pD3D9VBuf);
4387 /* this is a sysmem texture, update */
4388 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
4389 {
4390 RECT r, *pr;
4391 if (pAlloc->LockInfo.fFlags.RangeValid)
4392 {
4393 r.top = 0;
4394 r.left = pAlloc->LockInfo.Range.Offset;
4395 r.bottom = 1;
4396 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
4397 pr = &r;
4398 }
4399 else
4400 pr = NULL;
4401 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
4402 pr,
4403 true /*bool bToLockInfo*/);
4404 }
4405 hr = pD3D9VBuf->Unlock();
4406 Assert(hr == S_OK);
4407 }
4408 else
4409 {
4410 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4411 }
4412 }
4413 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
4414 {
4415 Assert(pData->SubResourceIndex < pRc->cAllocations);
4416 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4417
4418 --pAlloc->LockInfo.cLocks;
4419 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4420 if (!pAlloc->LockInfo.cLocks
4421 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
4422 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
4423 {
4424// Assert(!pAlloc->LockInfo.cLocks);
4425 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
4426 Assert(pD3D9IBuf);
4427 /* this is a sysmem texture, update */
4428 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
4429 {
4430 RECT r, *pr;
4431 if (pAlloc->LockInfo.fFlags.RangeValid)
4432 {
4433 r.top = 0;
4434 r.left = pAlloc->LockInfo.Range.Offset;
4435 r.bottom = 1;
4436 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
4437 pr = &r;
4438 }
4439 else
4440 pr = NULL;
4441 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
4442 pr,
4443 true /*bool bToLockInfo*/);
4444 }
4445 hr = pD3D9IBuf->Unlock();
4446 Assert(hr == S_OK);
4447 }
4448 else
4449 {
4450 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4451 }
4452 }
4453 else
4454 {
4455 Assert(0);
4456 }
4457 }
4458 else
4459 {
4460 struct
4461 {
4462 D3DDDICB_UNLOCK Unlock;
4463 D3DKMT_HANDLE hAllocation;
4464 } UnlockData;
4465
4466 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4467
4468 UnlockData.Unlock.NumAllocations = 1;
4469 UnlockData.Unlock.phAllocations = &UnlockData.hAllocation;
4470 UnlockData.hAllocation = pAlloc->hAllocation;
4471
4472 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &UnlockData.Unlock);
4473 Assert(hr == S_OK);
4474 if (hr == S_OK)
4475 {
4476 Assert(pAlloc->LockInfo.cLocks);
4477 --pAlloc->LockInfo.cLocks;
4478 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4479 }
4480 }
4481
4482 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4483 return hr;
4484}
4485static HRESULT APIENTRY vboxWddmDDevLockAsync(HANDLE hDevice, D3DDDIARG_LOCKASYNC* pData)
4486{
4487 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4488 Assert(0);
4489 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4490 return E_FAIL;
4491}
4492static HRESULT APIENTRY vboxWddmDDevUnlockAsync(HANDLE hDevice, CONST D3DDDIARG_UNLOCKASYNC* pData)
4493{
4494 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4495 Assert(0);
4496 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4497 return E_FAIL;
4498}
4499static HRESULT APIENTRY vboxWddmDDevRename(HANDLE hDevice, CONST D3DDDIARG_RENAME* 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}
4506
4507static void vboxWddmRequestAllocFree(D3DDDICB_ALLOCATE* pAlloc)
4508{
4509 RTMemFree(pAlloc);
4510}
4511
4512static D3DDDICB_ALLOCATE* vboxWddmRequestAllocAlloc(D3DDDIARG_CREATERESOURCE* pResource)
4513{
4514 /* allocate buffer for D3DDDICB_ALLOCATE + D3DDDI_ALLOCATIONINFO * numAllocs + PVBOXWDDM_RCINFO with aAllocInfos[numAllocs] */
4515 uint32_t cbBuf = sizeof (D3DDDICB_ALLOCATE);
4516 uint32_t offDdiAllocInfos = (cbBuf + 7) & ~3;
4517 uint32_t cbDdiAllocInfos = sizeof (D3DDDI_ALLOCATIONINFO) * pResource->SurfCount;
4518 cbBuf = offDdiAllocInfos + cbDdiAllocInfos;
4519 uint32_t offRcInfo = (cbBuf + 7) & ~3;
4520 uint32_t cbRcInfo = sizeof (VBOXWDDM_RCINFO);
4521 cbBuf = offRcInfo + cbRcInfo;
4522 uint32_t offAllocInfos = (cbBuf + 7) & ~3;
4523 uint32_t cbAllocInfos = sizeof (VBOXWDDM_ALLOCINFO) * pResource->SurfCount;
4524 cbBuf = offAllocInfos + cbAllocInfos;
4525 uint8_t *pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
4526 Assert(pvBuf);
4527 if (pvBuf)
4528 {
4529 D3DDDICB_ALLOCATE* pAlloc = (D3DDDICB_ALLOCATE*)pvBuf;
4530 pAlloc->NumAllocations = pResource->SurfCount;
4531 pAlloc->pAllocationInfo = (D3DDDI_ALLOCATIONINFO*)(pvBuf + offDdiAllocInfos);
4532 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)(pvBuf + offRcInfo);
4533 pAlloc->PrivateDriverDataSize = cbRcInfo;
4534 pAlloc->pPrivateDriverData = pRcInfo;
4535 pAlloc->hResource = pResource->hResource;
4536 PVBOXWDDM_ALLOCINFO pAllocInfos = (PVBOXWDDM_ALLOCINFO)(pvBuf + offAllocInfos);
4537 for (UINT i = 0; i < pResource->SurfCount; ++i)
4538 {
4539 D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pAlloc->pAllocationInfo[i];
4540 PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
4541 pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
4542 pDdiAllocInfo->PrivateDriverDataSize = sizeof (VBOXWDDM_ALLOCINFO);
4543 }
4544 return pAlloc;
4545 }
4546 return NULL;
4547}
4548
4549static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE* pResource)
4550{
4551 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4552 HRESULT hr = S_OK;
4553 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4554 Assert(pDevice);
4555 Assert(pResource);
4556 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
4557
4558 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pResource->SurfCount);
4559 Assert(pRc);
4560 if (pRc)
4561 {
4562 bool bIssueCreateResource = false;
4563 bool bCreateSwapchain = false;
4564 bool bCreateKMResource = false;
4565
4566 pRc->hResource = pResource->hResource;
4567 pRc->hKMResource = NULL;
4568 pRc->pDevice = pDevice;
4569 pRc->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
4570 pRc->RcDesc.fFlags = pResource->Flags;
4571 pRc->RcDesc.enmFormat = pResource->Format;
4572 pRc->RcDesc.enmPool = pResource->Pool;
4573 pRc->RcDesc.enmMultisampleType = pResource->MultisampleType;
4574 pRc->RcDesc.MultisampleQuality = pResource->MultisampleQuality;
4575 pRc->RcDesc.MipLevels = pResource->MipLevels;
4576 pRc->RcDesc.Fvf = pResource->Fvf;
4577 pRc->RcDesc.VidPnSourceId = pResource->VidPnSourceId;
4578 pRc->RcDesc.RefreshRate = pResource->RefreshRate;
4579 pRc->RcDesc.enmRotation = pResource->Rotation;
4580 pRc->cAllocations = pResource->SurfCount;
4581 for (UINT i = 0; i < pResource->SurfCount; ++i)
4582 {
4583 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4584 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
4585 pAllocation->hAllocation = NULL;
4586 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
4587 pAllocation->iAlloc = i;
4588 pAllocation->pRc = pRc;
4589 pAllocation->D3DWidth = pSurf->Width;
4590 pAllocation->pvMem = (void*)pSurf->pSysMem;
4591 pAllocation->SurfDesc.pitch = pSurf->SysMemPitch;
4592 pAllocation->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
4593 pAllocation->SurfDesc.depth = pSurf->Depth;
4594 pAllocation->SurfDesc.width = pSurf->Width;
4595 pAllocation->SurfDesc.height = pSurf->Height;
4596 pAllocation->SurfDesc.format = pResource->Format;
4597 }
4598
4599 if (VBOXDISPMODE_IS_3D(pAdapter))
4600 {
4601 if (pResource->Flags.SharedResource)
4602 {
4603 Assert(0); /* <-- need to test that */
4604 bIssueCreateResource = true;
4605 bCreateKMResource = true;
4606 }
4607
4608 if (pResource->Flags.ZBuffer)
4609 {
4610 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4611 for (UINT i = 0; i < pResource->SurfCount; ++i)
4612 {
4613 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4614 IDirect3DSurface9 *pD3D9Surf;
4615 hr = pDevice9If->CreateDepthStencilSurface(pAllocation->SurfDesc.width,
4616 pAllocation->SurfDesc.height,
4617 vboxDDI2D3DFormat(pResource->Format),
4618 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
4619 pResource->MultisampleQuality,
4620 TRUE /* @todo: BOOL Discard */,
4621 &pD3D9Surf,
4622 NULL /*HANDLE* pSharedHandle*/);
4623 Assert(hr == S_OK);
4624 if (hr == S_OK)
4625 {
4626 Assert(pD3D9Surf);
4627 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
4628 pAllocation->pD3DIf = pD3D9Surf;
4629 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
4630 Assert(hr == S_OK);
4631 }
4632 else
4633 {
4634 for (UINT j = 0; j < i; ++j)
4635 {
4636 pRc->aAllocations[j].pD3DIf->Release();
4637 }
4638 break;
4639 }
4640 }
4641 }
4642 else if (pResource->Flags.VertexBuffer)
4643 {
4644 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4645
4646 for (UINT i = 0; i < pResource->SurfCount; ++i)
4647 {
4648 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4649 IDirect3DVertexBuffer9 *pD3D9VBuf;
4650 hr = pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width,
4651 vboxDDI2D3DUsage(pResource->Flags),
4652 pResource->Fvf,
4653 vboxDDI2D3DPool(pResource->Pool),
4654 &pD3D9VBuf,
4655 NULL /*HANDLE* pSharedHandle*/);
4656 Assert(hr == S_OK);
4657 if (hr == S_OK)
4658 {
4659 Assert(pD3D9VBuf);
4660 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_VERTEXBUFFER;
4661 pAllocation->pD3DIf = pD3D9VBuf;
4662 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
4663 {
4664 Assert(pAllocation->pvMem);
4665 D3DLOCKED_RECT lockInfo;
4666 hr = pD3D9VBuf->Lock(0, pAllocation->SurfDesc.width, &lockInfo.pBits, D3DLOCK_DISCARD);
4667 Assert(hr == S_OK);
4668 if (hr == S_OK)
4669 {
4670 lockInfo.Pitch = pAllocation->SurfDesc.pitch;
4671 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
4672 HRESULT tmpHr = pD3D9VBuf->Unlock();
4673 Assert(tmpHr == S_OK);
4674 }
4675 }
4676 else
4677 {
4678 Assert(!pAllocation->pvMem);
4679 }
4680 }
4681 else
4682 {
4683 for (UINT j = 0; j < i; ++j)
4684 {
4685 pRc->aAllocations[j].pD3DIf->Release();
4686 }
4687 break;
4688 }
4689 }
4690 }
4691 else if (pResource->Flags.IndexBuffer)
4692 {
4693 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4694
4695 for (UINT i = 0; i < pResource->SurfCount; ++i)
4696 {
4697 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4698 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
4699 IDirect3DIndexBuffer9 *pD3D9IBuf;
4700 hr = pDevice9If->CreateIndexBuffer(pSurf->Width,
4701 vboxDDI2D3DUsage(pResource->Flags),
4702 vboxDDI2D3DFormat(pResource->Format),
4703 vboxDDI2D3DPool(pResource->Pool),
4704 &pD3D9IBuf,
4705 NULL /*HANDLE* pSharedHandle*/
4706 );
4707 Assert(hr == S_OK);
4708 if (hr == S_OK)
4709 {
4710 Assert(pD3D9IBuf);
4711 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_INDEXBUFFER;
4712 pAllocation->pD3DIf = pD3D9IBuf;
4713 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
4714 {
4715 Assert(pAllocation->pvMem);
4716 D3DLOCKED_RECT lockInfo;
4717 hr = pD3D9IBuf->Lock(0, pAllocation->SurfDesc.width, &lockInfo.pBits, D3DLOCK_DISCARD);
4718 Assert(hr == S_OK);
4719 if (hr == S_OK)
4720 {
4721 lockInfo.Pitch = pAllocation->SurfDesc.pitch;
4722 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
4723 HRESULT tmpHr = pD3D9IBuf->Unlock();
4724 Assert(tmpHr == S_OK);
4725 }
4726 }
4727 else
4728 {
4729 Assert(!pAllocation->pvMem);
4730 }
4731 }
4732 else
4733 {
4734 for (UINT j = 0; j < i; ++j)
4735 {
4736 pRc->aAllocations[j].pD3DIf->Release();
4737 }
4738 break;
4739 }
4740 }
4741 }
4742 else if (pResource->Flags.Texture || pResource->Flags.Value == 0)
4743 {
4744 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4745
4746#ifdef DEBUG
4747 {
4748 uint32_t tstW = pResource->pSurfList[0].Width;
4749 uint32_t tstH = pResource->pSurfList[0].Height;
4750 for (UINT i = 1; i < pResource->SurfCount; ++i)
4751 {
4752 tstW /= 2;
4753 tstH /= 2;
4754 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
4755 Assert((pSurf->Width == tstW) || (!tstW && (pSurf->Width==1)));
4756 Assert((pSurf->Height == tstH) || (!tstH && (pSurf->Height==1)));
4757 }
4758 }
4759#endif
4760
4761// if (pResource->Flags.RenderTarget)
4762// bIssueCreateResource = true;
4763
4764 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
4765 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[0];
4766 IDirect3DTexture9 *pD3DIfTex;
4767 HANDLE hSharedHandle = NULL;
4768 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
4769 {
4770 Assert(pSurf->pSysMem);
4771 Assert(pSurf->SysMemPitch);
4772 UINT bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
4773 Assert(bpp);
4774 if (bpp)
4775 {
4776 pAllocation->D3DWidth = ((pSurf->SysMemPitch << 3) / bpp);
4777 if ((pSurf->SysMemPitch << 3) % bpp)
4778 {
4779 Assert(0);
4780 ++pAllocation->D3DWidth;
4781 }
4782 Assert(pAllocation->D3DWidth >= pSurf->Width);
4783#ifdef DEBUG_misha
4784 /* break to test */
4785 Assert(pAllocation->D3DWidth == pSurf->Width);
4786#endif
4787 }
4788 }
4789#if 0
4790 hr = pDevice9If->CreateTexture(pSurf->Width,
4791 pAllocation->D3DWidth,
4792 pResource->SurfCount,
4793 vboxDDI2D3DUsage(pResource->Flags),
4794 vboxDDI2D3DFormat(pResource->Format),
4795 vboxDDI2D3DPool(pResource->Pool),
4796 &pD3DIfTex,
4797 NULL /* HANDLE* pSharedHandle */
4798 );
4799#else
4800 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
4801 pAllocation->D3DWidth,
4802 pSurf->Height,
4803 pResource->SurfCount,
4804 vboxDDI2D3DUsage(pResource->Flags),
4805 vboxDDI2D3DFormat(pResource->Format),
4806 vboxDDI2D3DPool(pResource->Pool),
4807 &pD3DIfTex,
4808 pResource->Flags.SharedResource ? &hSharedHandle : NULL,
4809 pResource->Pool == D3DDDIPOOL_SYSTEMMEM ? pRc->aAllocations[0].pvMem : NULL);
4810#endif
4811 Assert(hr == S_OK);
4812 if (hr == S_OK)
4813 {
4814 Assert(pD3DIfTex);
4815 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
4816 pAllocation->pD3DIf = pD3DIfTex;
4817 Assert(!!(pResource->Flags.SharedResource) == !!(hSharedHandle));
4818 pAllocation->hSharedHandle = hSharedHandle;
4819#if 0
4820 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
4821 {
4822 for (UINT i = 0; i < pResource->SurfCount; ++i)
4823 {
4824 D3DLOCKED_RECT lockInfo;
4825 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4826 Assert(pAllocation->pvMem);
4827 hr = pD3DIfTex->LockRect(i, &lockInfo, NULL, D3DLOCK_DISCARD);
4828 Assert(hr == S_OK);
4829 if (hr == S_OK)
4830 {
4831 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
4832 HRESULT tmpHr = pD3DIfTex->UnlockRect(i);
4833 Assert(tmpHr == S_OK);
4834 }
4835 else
4836 {
4837 pD3DIfTex->Release();
4838 break;
4839 }
4840 }
4841 }
4842#endif
4843 }
4844#ifdef DEBUG
4845 else
4846 {
4847 for (UINT i = 0; i < pResource->SurfCount; ++i)
4848 {
4849 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4850 Assert(!pAllocation->pvMem);
4851 }
4852 }
4853#endif
4854 }
4855 else if (pResource->Flags.RenderTarget)
4856 {
4857 HWND hWnd = NULL;
4858 bIssueCreateResource = true;
4859 Assert(pResource->SurfCount);
4860 if (RTListIsEmpty(&pDevice->SwapchainList))
4861 {
4862 bCreateSwapchain = true;
4863 Assert(bIssueCreateResource);
4864 }
4865 else
4866 {
4867 for (UINT i = 0; i < pResource->SurfCount; ++i)
4868 {
4869 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4870
4871 IDirect3DSurface9* pD3D9Surf;
4872 hr = pDevice->pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
4873 pAllocation->SurfDesc.height,
4874 vboxDDI2D3DFormat(pResource->Format),
4875 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
4876 pResource->MultisampleQuality,
4877 !pResource->Flags.NotLockable /* BOOL Lockable */,
4878 &pD3D9Surf,
4879 NULL /* HANDLE* pSharedHandle */
4880 );
4881 Assert(hr == S_OK);
4882 if (hr == S_OK)
4883 {
4884 Assert(pD3D9Surf);
4885 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
4886 pAllocation->pD3DIf = pD3D9Surf;
4887 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
4888 Assert(hr == S_OK);
4889 if (hr == S_OK)
4890 {
4891#if 0
4892 if(pResource->Flags.Primary)
4893 {
4894 for (UINT i = 0; i < pResource->SurfCount; ++i)
4895 {
4896 vboxWddmSwapchainFindCreate(pDevice, &pRc->aAllocations[i]);
4897 }
4898 Assert(bIssueCreateResource);
4899 }
4900#endif
4901 continue;
4902 }
4903
4904 /* fail branch */
4905 pD3D9Surf->Release();
4906 }
4907
4908 for (UINT j = 0; j < i; ++j)
4909 {
4910 pRc->aAllocations[j].pD3DIf->Release();
4911 }
4912 break;
4913 }
4914 }
4915 }
4916 else
4917 {
4918// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4919// Assert(pScreen->hWnd);
4920// Assert(pScreen->pDevice9If);
4921 Assert(0);
4922 }
4923 }
4924 else
4925 {
4926 bIssueCreateResource = true;
4927 bCreateKMResource = true;
4928 }
4929
4930
4931 if (hr == S_OK && bIssueCreateResource)
4932 {
4933 D3DDDICB_ALLOCATE *pDdiAllocate = vboxWddmRequestAllocAlloc(pResource);
4934 Assert(pDdiAllocate);
4935 if (pDdiAllocate)
4936 {
4937 Assert(pDdiAllocate->pPrivateDriverData);
4938 Assert(pDdiAllocate->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
4939 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)pDdiAllocate->pPrivateDriverData;
4940 pRcInfo->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
4941 pRcInfo->RcDesc = pRc->RcDesc;
4942 pRcInfo->cAllocInfos = pResource->SurfCount;
4943
4944 for (UINT i = 0; i < pResource->SurfCount; ++i)
4945 {
4946 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
4947 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4948 Assert(pDdiAllocI->pPrivateDriverData);
4949 Assert(pDdiAllocI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
4950 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
4951 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
4952 pDdiAllocI->hAllocation = NULL;
4953 pDdiAllocI->pSystemMem = pSurf->pSysMem;
4954 Assert((!!(pSurf->pSysMem)) == (pResource->Pool == D3DDDIPOOL_SYSTEMMEM));
4955 pDdiAllocI->VidPnSourceId = pResource->VidPnSourceId;
4956 pDdiAllocI->Flags.Value = 0;
4957 if (pResource->Flags.Primary)
4958 {
4959 Assert(pResource->Flags.RenderTarget);
4960 pDdiAllocI->Flags.Primary = 1;
4961 }
4962
4963 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
4964 pAllocInfo->fFlags = pResource->Flags;
4965 pAllocInfo->hSharedHandle = pAllocation->hSharedHandle;
4966 pAllocInfo->SurfDesc.width = pSurf->Width;
4967 pAllocInfo->SurfDesc.height = pSurf->Height;
4968 pAllocInfo->SurfDesc.format = pResource->Format;
4969 if (!vboxWddmFormatToFourcc(pResource->Format))
4970 pAllocInfo->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
4971 else
4972 pAllocInfo->SurfDesc.bpp = 0;
4973
4974 if (pSurf->SysMemPitch)
4975 {
4976 pAllocInfo->SurfDesc.pitch = pSurf->SysMemPitch;
4977#ifdef DEBUG
4978 UINT tst = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
4979 Assert(tst == pSurf->SysMemPitch);
4980#endif
4981 }
4982 else
4983 pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
4984
4985 pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
4986 pAllocInfo->SurfDesc.depth = pSurf->Depth;
4987 pAllocInfo->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
4988 pAllocInfo->SurfDesc.VidPnSourceId = pResource->VidPnSourceId;
4989 pAllocInfo->SurfDesc.RefreshRate = pResource->RefreshRate;
4990 }
4991
4992 if (bCreateKMResource)
4993 {
4994 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
4995 Assert(hr == S_OK);
4996 Assert(pDdiAllocate->hKMResource);
4997 }
4998 else
4999 {
5000 pDdiAllocate->hResource = NULL;
5001 pDdiAllocate->NumAllocations = 1;
5002 pDdiAllocate->PrivateDriverDataSize = 0;
5003 pDdiAllocate->pPrivateDriverData = NULL;
5004 D3DDDI_ALLOCATIONINFO *pDdiAllocIBase = pDdiAllocate->pAllocationInfo;
5005
5006 for (UINT i = 0; i < pResource->SurfCount; ++i)
5007 {
5008 pDdiAllocate->pAllocationInfo = &pDdiAllocIBase[i];
5009 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
5010 Assert(hr == S_OK);
5011 Assert(!pDdiAllocate->hKMResource);
5012 if (hr == S_OK)
5013 {
5014 Assert(pDdiAllocate->pAllocationInfo->hAllocation);
5015 }
5016 else
5017 {
5018 for (UINT j = 0; i < j; ++j)
5019 {
5020 D3DDDI_ALLOCATIONINFO * pCur = &pDdiAllocIBase[i];
5021 D3DDDICB_DEALLOCATE Dealloc;
5022 Dealloc.hResource = 0;
5023 Dealloc.NumAllocations = 1;
5024 Dealloc.HandleList = &pCur->hAllocation;
5025 HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5026 Assert(tmpHr == S_OK);
5027 }
5028 break;
5029 }
5030 }
5031
5032 pDdiAllocate->pAllocationInfo = pDdiAllocIBase;
5033 }
5034
5035 if (hr == S_OK)
5036 {
5037 pRc->hKMResource = pDdiAllocate->hKMResource;
5038
5039 for (UINT i = 0; i < pResource->SurfCount; ++i)
5040 {
5041 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5042 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
5043 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
5044 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5045 pAllocation->hAllocation = pDdiAllocI->hAllocation;
5046 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
5047 pAllocation->pvMem = (void*)pSurf->pSysMem;
5048 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
5049 }
5050
5051 if(bCreateSwapchain)
5052 {
5053 PVBOXWDDMDISP_SWAPCHAIN pSwapchain;
5054 hr = vboxWddmSwapchainCreateIfForRc(pDevice, pRc, &pSwapchain);
5055 Assert(hr == S_OK);
5056 }
5057 }
5058
5059 vboxWddmRequestAllocFree(pDdiAllocate);
5060 }
5061 else
5062 {
5063 hr = E_OUTOFMEMORY;
5064 }
5065 }
5066
5067 if (hr == S_OK)
5068 pResource->hResource = pRc;
5069 else
5070 vboxResourceFree(pRc);
5071 }
5072 else
5073 {
5074 hr = E_OUTOFMEMORY;
5075 }
5076
5077
5078 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5079 return hr;
5080}
5081
5082static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource)
5083{
5084 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5085 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5086 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
5087 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hResource;
5088
5089 HRESULT hr = S_OK;
5090
5091 Assert(pDevice);
5092 Assert(hResource);
5093
5094 if (VBOXDISPMODE_IS_3D(pAdapter))
5095 {
5096// if (pRc->RcDesc.fFlags.RenderTarget)
5097// {
5098// Assert(pDevice->hWnd);
5099// Assert(pDevice->pDevice9If);
5100// }
5101
5102 for (UINT i = 0; i < pRc->cAllocations; ++i)
5103 {
5104 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
5105 if (pAlloc->pD3DIf)
5106 pAlloc->pD3DIf->Release();
5107 if (pAlloc->pSecondaryOpenedD3DIf)
5108 pAlloc->pSecondaryOpenedD3DIf->Release();
5109
5110 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
5111 if (pSwapchain)
5112 {
5113 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainRtForAlloc(pSwapchain, pAlloc);
5114 vboxWddmSwapchainRtRemove(pSwapchain, pRt);
5115 Assert(!vboxWddmSwapchainForAlloc(pAlloc));
5116 if (!vboxWddmSwapchainNumRTs(pSwapchain))
5117 vboxWddmSwapchainDestroy(pDevice, pSwapchain);
5118 }
5119
5120 EnterCriticalSection(&pDevice->DirtyAllocListLock);
5121 if (pAlloc->DirtyAllocListEntry.pNext)
5122 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
5123 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5124 }
5125 }
5126
5127 Assert(pRc->hResource);
5128 Assert(pRc->hKMResource || VBOXDISPMODE_IS_3D(pAdapter));
5129 if (pRc->hKMResource)
5130 {
5131 if (!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED))
5132 {
5133 D3DDDICB_DEALLOCATE Dealloc;
5134 Dealloc.hResource = pRc->hResource;
5135 /* according to the docs the below two are ignored in case we set the hResource */
5136 Dealloc.NumAllocations = 0;
5137 Dealloc.HandleList = NULL;
5138 hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5139 Assert(hr == S_OK);
5140 }
5141 }
5142 else
5143 {
5144 Assert(!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED));
5145 for (UINT j = 0; j < pRc->cAllocations; ++j)
5146 {
5147 if (pRc->aAllocations[j].hAllocation)
5148 {
5149 D3DDDICB_DEALLOCATE Dealloc;
5150 Dealloc.hResource = NULL;
5151 Dealloc.NumAllocations = 1;
5152 Dealloc.HandleList = &pRc->aAllocations[j].hAllocation;
5153 HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5154 Assert(tmpHr == S_OK);
5155 }
5156 }
5157 }
5158
5159 vboxResourceFree(pRc);
5160 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5161 return hr;
5162}
5163static HRESULT APIENTRY vboxWddmDDevSetDisplayMode(HANDLE hDevice, CONST D3DDDIARG_SETDISPLAYMODE* pData)
5164{
5165 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5166 HRESULT hr = S_OK;
5167 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5168 Assert(pDevice);
5169 Assert(VBOXDISPMODE_IS_3D(pDevice->pAdapter));
5170 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
5171 Assert(pRc);
5172 Assert(pRc->cAllocations > pData->SubResourceIndex);
5173 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
5174 Assert(pRc->RcDesc.fFlags.RenderTarget);
5175 Assert(pRc->RcDesc.fFlags.Primary);
5176 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5177 Assert(pAlloc->hAllocation);
5178// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5179// Assert(pScreen->hWnd);
5180// Assert(pScreen->pDevice9If);
5181 D3DDDICB_SETDISPLAYMODE DdiDm = {0};
5182 DdiDm.hPrimaryAllocation = pAlloc->hAllocation;
5183// DdiDm.PrivateDriverFormatAttribute = 0;
5184// Assert(pScreen->pRenderTargetRc == pRc);
5185// Assert(pScreen->iRenderTargetFrontBuf == pData->SubResourceIndex);
5186
5187#if 0
5188 IDirect3DSurface9 *pSoD3DIfSurf = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
5189 hr = pScreen->pDevice9If->SetRenderTarget(0, pSoD3DIfSurf);
5190 Assert(hr == S_OK);
5191 if (hr == S_OK)
5192#endif
5193 {
5194 hr = pDevice->RtCallbacks.pfnSetDisplayModeCb(pDevice->hDevice, &DdiDm);
5195 Assert(hr == S_OK);
5196 }
5197
5198 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5199 return hr;
5200}
5201static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRESENT* pData)
5202{
5203 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5204 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5205 Assert(pDevice);
5206 HRESULT hr = S_OK;
5207 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
5208 {
5209#if 1
5210 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5211 Assert(pRc);
5212 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
5213 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5214 hr = vboxWddmSwapchainPresent(pDevice, pAlloc);
5215 Assert(hr == S_OK);
5216#else
5217 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5218 Assert(pRc);
5219 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5220 Assert(pScreen->hWnd);
5221 Assert(pScreen->pDevice9If);
5222 Assert(pRc == pScreen->pRenderTargetRc);
5223#if 1
5224 VBOXVDBG_RTGT_STATECHECK(pDevice);
5225
5226 if (pRc->RcDesc.VidPnSourceId != pDevice->iPrimaryScreen)
5227 {
5228 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5229 PVBOXWDDMDISP_SCREEN pPrimaryScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5230 Assert(pPrimaryScreen->pDevice9If);
5231 IDirect3DSurface9 *pSecondaryRt;
5232 IDirect3DSurface9 *pDataRt = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
5233 Assert(pDataRt);
5234 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5235 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pPrimaryScreen->pDevice9If);
5236 Assert(hr == S_OK);
5237 if (hr == S_OK)
5238 {
5239 hr = pScreen->pDevice9If->GetRenderTarget(0, &pSecondaryRt);
5240 Assert(hr == S_OK);
5241 if (hr == S_OK)
5242 {
5243 hr = pScreen->pDevice9If->StretchRect(pDataRt,
5244 NULL,
5245 pSecondaryRt,
5246 NULL,
5247 D3DTEXF_NONE);
5248 pSecondaryRt->Release();
5249 }
5250 }
5251 }
5252
5253 hr = pScreen->pDevice9If->Present(NULL, /* CONST RECT * pSourceRect */
5254 NULL, /* CONST RECT * pDestRect */
5255 NULL, /* HWND hDestWindowOverride */
5256 NULL /*CONST RGNDATA * pDirtyRegion */
5257 );
5258 Assert(hr == S_OK);
5259#endif
5260#endif
5261 }
5262#if 0
5263 else
5264#endif
5265 {
5266// if (pData->Flags.Flip)
5267// {
5268// Assert(pData->hSrcResource);
5269// PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5270// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5271// Assert(pScreen->hWnd);
5272// Assert(pScreen->pDevice9If);
5273// Assert(pScreen->pRenderTargetRc == pRc);
5274// Assert(pRc->cAllocations >= 2);
5275// Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5276// Assert(pRc->RcDesc.fFlags.RenderTarget);
5277// uint32_t iNewRTFB = (pScreen->iRenderTargetFrontBuf + 1) % pRc->cAllocations;
5278//
5279// Assert(pScreen->iRenderTargetFrontBuf != iNewRTFB);
5280// Assert(pData->SrcSubResourceIndex == iNewRTFB);
5281//
5282// vboxWddmRenderTargetUpdate(pDevice, pRc, iNewRTFB);
5283//
5284// /* assign a new frontbuffer index */
5285// pScreen->iRenderTargetFrontBuf = iNewRTFB;
5286//
5287// VBOXVDBG_RTGT_STATECHECK(pDevice);
5288// }
5289 D3DDDICB_PRESENT DdiPresent = {0};
5290 if (pData->hSrcResource)
5291 {
5292 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5293 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
5294 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5295 Assert(pAlloc->hAllocation);
5296 DdiPresent.hSrcAllocation = pAlloc->hAllocation;
5297 }
5298 if (pData->hDstResource)
5299 {
5300 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
5301 Assert(pRc->cAllocations > pData->DstSubResourceIndex);
5302 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->DstSubResourceIndex];
5303 Assert(pAlloc->hAllocation);
5304 DdiPresent.hDstAllocation = pAlloc->hAllocation;
5305 }
5306 DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext;
5307// DdiPresent.BroadcastContextCount;
5308// DdiPresent.BroadcastContext[D3DDDI_MAX_BROADCAST_CONTEXT];
5309
5310 hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent);
5311 Assert(hr == S_OK);
5312 }
5313 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5314 return hr;
5315}
5316
5317typedef struct VBOXWDDMDISP_NSCADD
5318{
5319 VOID* pvCommandBuffer;
5320 UINT cbCommandBuffer;
5321 D3DDDI_ALLOCATIONLIST* pAllocationList;
5322 UINT cAllocationList;
5323 D3DDDI_PATCHLOCATIONLIST* pPatchLocationList;
5324 UINT cPatchLocationList;
5325 UINT cAllocations;
5326}VBOXWDDMDISP_NSCADD, *PVBOXWDDMDISP_NSCADD;
5327
5328static HRESULT vboxWddmNSCAddAlloc(PVBOXWDDMDISP_NSCADD pData, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bWrite)
5329{
5330 HRESULT hr = S_OK;
5331 if (pData->cAllocationList && pData->cPatchLocationList && pData->cbCommandBuffer > 4)
5332 {
5333 memset(pData->pAllocationList, 0, sizeof (D3DDDI_ALLOCATIONLIST));
5334 pData->pAllocationList[0].hAllocation = pAlloc->hAllocation;
5335 if (bWrite)
5336 pData->pAllocationList[0].WriteOperation = 1;
5337
5338 memset(pData->pPatchLocationList, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
5339 pData->pPatchLocationList[0].PatchOffset = pData->cAllocations*4;
5340 pData->pPatchLocationList[0].AllocationIndex = pData->cAllocations;
5341
5342 pData->cbCommandBuffer -= 4;
5343 --pData->cAllocationList;
5344 --pData->cPatchLocationList;
5345 ++pData->cAllocations;
5346 }
5347 else
5348 hr = S_FALSE;
5349
5350 ++pData->pAllocationList;
5351 ++pData->pPatchLocationList;
5352 pData->pvCommandBuffer = (VOID*)(((uint8_t*)pData->pvCommandBuffer) + 4);
5353
5354 return hr;
5355}
5356
5357static HRESULT vboxWddmNotifySharedChange(PVBOXWDDMDISP_DEVICE pDevice)
5358{
5359 VBOXWDDMDISP_NSCADD NscAdd;
5360 BOOL bReinitRenderData = TRUE;
5361
5362 do
5363 {
5364 if (bReinitRenderData)
5365 {
5366 NscAdd.pvCommandBuffer = pDevice->DefaultContext.ContextInfo.pCommandBuffer;
5367 NscAdd.cbCommandBuffer = pDevice->DefaultContext.ContextInfo.CommandBufferSize;
5368 NscAdd.pAllocationList = pDevice->DefaultContext.ContextInfo.pAllocationList;
5369 NscAdd.cAllocationList = pDevice->DefaultContext.ContextInfo.AllocationListSize;
5370 NscAdd.pPatchLocationList = pDevice->DefaultContext.ContextInfo.pPatchLocationList;
5371 NscAdd.cPatchLocationList = pDevice->DefaultContext.ContextInfo.PatchLocationListSize;
5372 NscAdd.cAllocations = 0;
5373 bReinitRenderData = FALSE;
5374 }
5375
5376 EnterCriticalSection(&pDevice->DirtyAllocListLock);
5377
5378 PVBOXWDDMDISP_ALLOCATION pAlloc = RTListNodeGetFirst(&pDevice->DirtyAllocList, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry);
5379 if (pAlloc)
5380 {
5381 HRESULT tmpHr = vboxWddmNSCAddAlloc(&NscAdd, pAlloc, TRUE);
5382 Assert(tmpHr == S_OK || tmpHr == S_FALSE);
5383 if (tmpHr == S_OK)
5384 {
5385 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
5386 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5387 continue;
5388 }
5389
5390 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5391
5392 }
5393 else
5394 {
5395 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5396 if (!NscAdd.cAllocations)
5397 break;
5398 }
5399
5400 D3DDDICB_RENDER RenderData = {0};
5401 RenderData.CommandLength = pDevice->DefaultContext.ContextInfo.CommandBufferSize - NscAdd.cbCommandBuffer;
5402 Assert(RenderData.CommandLength);
5403 Assert(RenderData.CommandLength < UINT32_MAX/2);
5404 RenderData.CommandOffset = 0;
5405 RenderData.NumAllocations = pDevice->DefaultContext.ContextInfo.AllocationListSize - NscAdd.cAllocationList;
5406 Assert(RenderData.NumAllocations == NscAdd.cAllocations);
5407 RenderData.NumPatchLocations = pDevice->DefaultContext.ContextInfo.PatchLocationListSize - NscAdd.cPatchLocationList;
5408 Assert(RenderData.NumPatchLocations == NscAdd.cAllocations);
5409 RenderData.NewCommandBufferSize = sizeof (VBOXVDMACMD) + 4 * (100);
5410 RenderData.NewAllocationListSize = 100;
5411 RenderData.NewPatchLocationListSize = 100;
5412 RenderData.hContext = pDevice->DefaultContext.ContextInfo.hContext;
5413
5414 HRESULT hr = pDevice->RtCallbacks.pfnRenderCb(pDevice->hDevice, &RenderData);
5415 Assert(hr == S_OK);
5416 if (hr == S_OK)
5417 {
5418 pDevice->DefaultContext.ContextInfo.CommandBufferSize = RenderData.NewCommandBufferSize;
5419 pDevice->DefaultContext.ContextInfo.pCommandBuffer = RenderData.pNewCommandBuffer;
5420 pDevice->DefaultContext.ContextInfo.AllocationListSize = RenderData.NewAllocationListSize;
5421 pDevice->DefaultContext.ContextInfo.pAllocationList = RenderData.pNewAllocationList;
5422 pDevice->DefaultContext.ContextInfo.PatchLocationListSize = RenderData.NewPatchLocationListSize;
5423 pDevice->DefaultContext.ContextInfo.pPatchLocationList = RenderData.pNewPatchLocationList;
5424 bReinitRenderData = TRUE;
5425 }
5426 else
5427 break;
5428 } while (1);
5429
5430 return S_OK;
5431}
5432
5433static HRESULT APIENTRY vboxWddmDDevFlush(HANDLE hDevice)
5434{
5435 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5436 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5437 Assert(pDevice);
5438 HRESULT hr = S_OK;
5439 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
5440 {
5441// Assert(pDevice->cScreens);
5442// UINT cProcessed = 0;
5443// for (UINT i = 0; cProcessed < pDevice->cScreens && i < RT_ELEMENTS(pDevice->aScreens); ++i)
5444// {
5445// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i];
5446// if (pScreen->pDevice9If)
5447// {
5448// ++cProcessed;
5449//// if (pScreen->pRenderTargetRc->cAllocations == 1)
5450//// {
5451//// hr = pScreen->pDevice9If->Present(NULL, NULL, NULL, NULL);
5452//// Assert(hr == S_OK);
5453//// }
5454//// else
5455 {
5456 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pDevice->pDevice9If);
5457 Assert(hr == S_OK);
5458 }
5459// }
5460// }
5461
5462 vboxWddmNotifySharedChange(pDevice);
5463 }
5464 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5465 return hr;
5466}
5467
5468AssertCompile(sizeof (D3DDDIVERTEXELEMENT) == sizeof (D3DVERTEXELEMENT9));
5469AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Stream) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Stream));
5470AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Offset) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Offset));
5471AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Type) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Type));
5472AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Method) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Method));
5473AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Usage) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Usage));
5474AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, UsageIndex) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, UsageIndex));
5475
5476AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Stream) == RT_OFFSETOF(D3DVERTEXELEMENT9, Stream));
5477AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Offset) == RT_OFFSETOF(D3DVERTEXELEMENT9, Offset));
5478AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Type) == RT_OFFSETOF(D3DVERTEXELEMENT9, Type));
5479AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Method) == RT_OFFSETOF(D3DVERTEXELEMENT9, Method));
5480AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Usage) == RT_OFFSETOF(D3DVERTEXELEMENT9, Usage));
5481AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, UsageIndex) == RT_OFFSETOF(D3DVERTEXELEMENT9, UsageIndex));
5482
5483static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderDecl(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERDECL* pData, CONST D3DDDIVERTEXELEMENT* pVertexElements)
5484{
5485 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5486 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5487 Assert(pDevice);
5488 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5489 IDirect3DVertexDeclaration9 *pDecl;
5490 static D3DVERTEXELEMENT9 DeclEnd = D3DDECL_END();
5491 D3DVERTEXELEMENT9* pVe;
5492 HRESULT hr = S_OK;
5493 bool bFreeVe = false;
5494 if(memcmp(&DeclEnd, &pVertexElements[pData->NumVertexElements], sizeof (DeclEnd)))
5495 {
5496 pVe = (D3DVERTEXELEMENT9*)RTMemAlloc(sizeof (D3DVERTEXELEMENT9) * (pData->NumVertexElements + 1));
5497 if (pVe)
5498 {
5499 memcpy(pVe, pVertexElements, sizeof (D3DVERTEXELEMENT9) * pData->NumVertexElements);
5500 pVe[pData->NumVertexElements] = DeclEnd;
5501 bFreeVe = true;
5502 }
5503 else
5504 hr = E_OUTOFMEMORY;
5505 }
5506 else
5507 pVe = (D3DVERTEXELEMENT9*)pVertexElements;
5508
5509 if (hr == S_OK)
5510 {
5511 hr = pDevice9If->CreateVertexDeclaration(
5512 pVe,
5513 &pDecl
5514 );
5515 Assert(hr == S_OK);
5516 if (hr == S_OK)
5517 {
5518 Assert(pDecl);
5519 pData->ShaderHandle = pDecl;
5520 }
5521 }
5522
5523 if (bFreeVe)
5524 RTMemFree((void*)pVe);
5525
5526 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5527 return hr;
5528}
5529static HRESULT APIENTRY vboxWddmDDevSetVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
5530{
5531 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5532 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5533 Assert(pDevice);
5534 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5535 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
5536 Assert(pDecl);
5537 HRESULT hr = pDevice9If->SetVertexDeclaration(pDecl);
5538 Assert(hr == S_OK);
5539 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5540 return hr;
5541}
5542static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
5543{
5544 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5545 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5546 Assert(pDevice);
5547 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
5548 HRESULT hr = S_OK;
5549 pDecl->Release();
5550 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5551 return hr;
5552}
5553static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderFunc(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERFUNC* pData, CONST UINT* pCode)
5554{
5555 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5556 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5557 Assert(pDevice);
5558 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5559 IDirect3DVertexShader9 *pShader;
5560 Assert(*((UINT*)((uint8_t*)pCode + pData->Size-4)) == 0x0000FFFF /* end token */);
5561 HRESULT hr = pDevice9If->CreateVertexShader((const DWORD *)pCode, &pShader);
5562 Assert(hr == S_OK);
5563 if (hr == S_OK)
5564 {
5565 Assert(pShader);
5566 pData->ShaderHandle = pShader;
5567 }
5568 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5569 return hr;
5570}
5571static HRESULT APIENTRY vboxWddmDDevSetVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
5572{
5573 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5574 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5575 Assert(pDevice);
5576 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5577 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
5578 Assert(pShader);
5579 HRESULT hr = pDevice9If->SetVertexShader(pShader);
5580 Assert(hr == S_OK);
5581 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5582 return hr;
5583}
5584static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
5585{
5586 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5587 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5588 Assert(pDevice);
5589 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
5590 HRESULT hr = S_OK;
5591 pShader->Release();
5592 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5593 return hr;
5594}
5595static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTI* pData, CONST INT* pRegisters)
5596{
5597 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5598 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5599 Assert(pDevice);
5600 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5601 HRESULT hr = pDevice9If->SetVertexShaderConstantI(pData->Register, pRegisters, pData->Count);
5602 Assert(hr == S_OK);
5603 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5604 return hr;
5605}
5606static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTB* pData, CONST BOOL* pRegisters)
5607{
5608 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5609 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5610 Assert(pDevice);
5611 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5612 HRESULT hr = pDevice9If->SetVertexShaderConstantB(pData->Register, pRegisters, pData->Count);
5613 Assert(hr == S_OK);
5614 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5615 return hr;
5616}
5617static HRESULT APIENTRY vboxWddmDDevSetScissorRect(HANDLE hDevice, CONST RECT* pRect)
5618{
5619 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5620 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5621 Assert(pDevice);
5622 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5623 HRESULT hr = pDevice9If->SetScissorRect(pRect);
5624 Assert(hr == S_OK);
5625 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5626 return hr;
5627}
5628static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCE* pData)
5629{
5630 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5631 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5632 Assert(pDevice);
5633 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5634 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hVertexBuffer;
5635 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
5636 IDirect3DVertexBuffer9 *pStreamData = NULL;
5637 if (pRc)
5638 {
5639 Assert(pRc->cAllocations == 1);
5640 pAlloc = &pRc->aAllocations[0];
5641 Assert(pAlloc->pD3DIf);
5642 pStreamData = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
5643 }
5644 HRESULT hr = pDevice9If->SetStreamSource(pData->Stream, pStreamData, pData->Offset, pData->Stride);
5645 Assert(hr == S_OK);
5646 Assert(pData->Stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS);
5647 if (hr == S_OK)
5648 {
5649 if (pDevice->aStreamSource[pData->Stream] && !pAlloc)
5650 {
5651 --pDevice->cStreamSources;
5652 Assert(pDevice->cStreamSources < UINT32_MAX/2);
5653 }
5654 else if (!pDevice->aStreamSource[pData->Stream] && pAlloc)
5655 {
5656 ++pDevice->cStreamSources;
5657 Assert(pDevice->cStreamSources <= RT_ELEMENTS(pDevice->aStreamSource));
5658 }
5659 pDevice->aStreamSource[pData->Stream] = pAlloc;
5660 pDevice->StreamSourceInfo[pData->Stream].uiOffset = pData->Offset;
5661 pDevice->StreamSourceInfo[pData->Stream].uiStride = pData->Stride;
5662 }
5663 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5664 return hr;
5665}
5666static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData)
5667{
5668 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5669 Assert(0);
5670 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5671 return E_FAIL;
5672}
5673static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData)
5674{
5675 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5676 Assert(0);
5677 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5678 return E_FAIL;
5679}
5680static HRESULT APIENTRY vboxWddmDDevComposeRects(HANDLE hDevice, CONST D3DDDIARG_COMPOSERECTS* pData)
5681{
5682 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5683 Assert(0);
5684 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5685 return E_FAIL;
5686}
5687static HRESULT vboxWddmLockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc,
5688 D3DLOCKED_RECT * pLockedRect,
5689 CONST RECT *pRect,
5690 DWORD fLockFlags)
5691{
5692 HRESULT hr = E_FAIL;
5693 Assert(!pRc->aAllocations[iAlloc].LockInfo.cLocks);
5694 Assert(pRc->cAllocations > iAlloc);
5695 switch (pRc->aAllocations[0].enmD3DIfType)
5696 {
5697 case VBOXDISP_D3DIFTYPE_SURFACE:
5698 {
5699 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
5700 Assert(pD3DIfSurf);
5701 hr = pD3DIfSurf->LockRect(pLockedRect, pRect, fLockFlags);
5702 Assert(hr == S_OK);
5703 break;
5704 }
5705 case VBOXDISP_D3DIFTYPE_TEXTURE:
5706 {
5707 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
5708 Assert(pD3DIfTex);
5709 hr = pD3DIfTex->LockRect(iAlloc, pLockedRect, pRect, fLockFlags);
5710 Assert(hr == S_OK);
5711 break;
5712 }
5713 default:
5714 Assert(0);
5715 break;
5716 }
5717 return hr;
5718}
5719static HRESULT vboxWddmUnlockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc)
5720{
5721 HRESULT hr = S_OK;
5722 Assert(pRc->cAllocations > iAlloc);
5723 switch (pRc->aAllocations[0].enmD3DIfType)
5724 {
5725 case VBOXDISP_D3DIFTYPE_SURFACE:
5726 {
5727 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
5728 Assert(pD3DIfSurf);
5729 hr = pD3DIfSurf->UnlockRect();
5730 Assert(hr == S_OK);
5731 break;
5732 }
5733 case VBOXDISP_D3DIFTYPE_TEXTURE:
5734 {
5735 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
5736 Assert(pD3DIfTex);
5737 hr = pD3DIfTex->UnlockRect(iAlloc);
5738 Assert(hr == S_OK);
5739 break;
5740 }
5741 default:
5742 Assert(0);
5743 hr = E_FAIL;
5744 break;
5745 }
5746 return hr;
5747}
5748
5749static HRESULT APIENTRY vboxWddmDDevBlt(HANDLE hDevice, CONST D3DDDIARG_BLT* pData)
5750{
5751 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5752 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5753 Assert(pDevice);
5754// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5755 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5756 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
5757 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5758 Assert(pDstRc->cAllocations > pData->DstSubResourceIndex);
5759 Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex);
5760 HRESULT hr = S_OK;
5761 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
5762 PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
5763 PVBOXWDDMDISP_SWAPCHAIN pSrcSwapchain = vboxWddmSwapchainForAlloc(pSrcAlloc);
5764 PVBOXWDDMDISP_SWAPCHAIN pDstSwapchain = vboxWddmSwapchainForAlloc(pDstAlloc);
5765 Assert(!pDstSwapchain || vboxWddmSwapchainGetFb(pDstSwapchain)->pAlloc != pDstAlloc);
5766 /* try StretchRect */
5767 IDirect3DSurface9 *pSrcSurfIf = NULL;
5768 IDirect3DSurface9 *pDstSurfIf = NULL;
5769 hr = vboxWddmSurfGet(pDstRc, pData->DstSubResourceIndex, &pDstSurfIf);
5770 Assert(hr == S_OK);
5771 if (hr == S_OK)
5772 {
5773 Assert(pDstSurfIf);
5774 do
5775 {
5776#ifndef VBOXWDDM_WITH_VISIBLE_FB
5777 if (pSrcSwapchain
5778 && pSrcSwapchain->pRenderTargetFbCopy
5779 && vboxWddmSwapchainGetFb(pSrcSwapchain)->pAlloc == pSrcAlloc
5780 && vboxWddmSwapchainNumRTs(pSrcSwapchain) > 1) /* work-around wine backbuffer */
5781 {
5782// Assert(pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width);
5783// Assert(pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height);
5784// Assert(pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format);
5785// Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
5786// Assert(pSrcAlloc->SurfDesc.pitch == pDstAlloc->SurfDesc.pitch);
5787// Assert(pSrcAlloc->SurfDesc.depth == pDstAlloc->SurfDesc.depth);
5788// Assert(pSrcAlloc->SurfDesc.slicePitch == pDstAlloc->SurfDesc.slicePitch);
5789// Assert(pSrcAlloc->SurfDesc.cbSize == pDstAlloc->SurfDesc.cbSize);
5790// Assert(pData->DstRect.left == 0);
5791// Assert(pData->DstRect.top == 0);
5792// Assert(pData->DstRect.right == pDstAlloc->SurfDesc.width);
5793// Assert(pData->DstRect.bottom == pDstAlloc->SurfDesc.height);
5794// Assert(pData->SrcRect.left == 0);
5795// Assert(pData->SrcRect.top == 0);
5796// Assert(pData->SrcRect.right == pSrcAlloc->SurfDesc.width);
5797// Assert(pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height);
5798#if 0
5799 if (pData->DstRect.left == 0 && pData->DstRect.top == 0
5800 && pData->DstRect.right == pDstAlloc->SurfDesc.width
5801 && pData->DstRect.bottom == pDstAlloc->SurfDesc.height
5802 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
5803 && pData->SrcRect.right == pSrcAlloc->SurfDesc.width
5804 && pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height
5805 && pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width
5806 && pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height
5807 && pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format)
5808 {
5809 hr = pDevice9If->GetFrontBufferData(0, pDstSurfIf);
5810 Assert(hr == S_OK);
5811 break;
5812 }
5813 else
5814#endif
5815 {
5816 pSrcSurfIf = pSrcSwapchain->pRenderTargetFbCopy;
5817 Assert(pSrcSurfIf);
5818 hr = pSrcSwapchain->pSwapChainIf->GetFrontBufferData(pSrcSurfIf);
5819 Assert(hr == S_OK);
5820 if (hr == S_OK)
5821 {
5822 /* do pSrcSurfIf->AddRef since we do a Release in the following if (hr == S_OK) branch */
5823 pSrcSurfIf->AddRef();
5824 }
5825 }
5826 }
5827 else
5828#endif
5829 {
5830 hr = vboxWddmSurfGet(pSrcRc, pData->SrcSubResourceIndex, &pSrcSurfIf);
5831 Assert(hr == S_OK);
5832 }
5833
5834 if (hr == S_OK)
5835 {
5836 Assert(pSrcSurfIf);
5837#ifdef DEBUG_misha
5838 bool bDo = false;
5839
5840 if (g_VDbgTstDumpEnable)
5841 {
5842 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
5843 {
5844 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
5845 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
5846 {
5847 D3DSURFACE_DESC SrcDesc;
5848 HRESULT hr = pSrcSurfIf->GetDesc(&SrcDesc);
5849 Assert(hr == S_OK);
5850 if (hr == S_OK)
5851 {
5852 D3DSURFACE_DESC DstDesc;
5853 hr = pDstSurfIf->GetDesc(&DstDesc);
5854 Assert(hr == S_OK);
5855 if (hr == S_OK)
5856 {
5857 if (SrcDesc.Width == DstDesc.Width
5858 && SrcDesc.Height == DstDesc.Height)
5859 {
5860 bDo = true;
5861 }
5862 }
5863 }
5864 }
5865 }
5866 }
5867
5868 if (bDo)
5869 {
5870 vboxVDbgDumpSurfData((pDevice, "Blt-pre Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
5871 vboxVDbgDumpSurfData((pDevice, "Blt-pre Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
5872 }
5873#endif
5874 /* we support only Point & Linear, we ignore [Begin|Continue|End]PresentToDwm */
5875 Assert((pData->Flags.Value & (~(0x00000100 | 0x00000200 | 0x00000400 | 0x00000001 | 0x00000002))) == 0);
5876 hr = pDevice9If->StretchRect(pSrcSurfIf,
5877 &pData->SrcRect,
5878 pDstSurfIf,
5879 &pData->DstRect,
5880 vboxDDI2D3DBltFlags(pData->Flags));
5881 Assert(hr == S_OK);
5882
5883#ifdef DEBUG_misha
5884 if (bDo)
5885 {
5886 vboxVDbgDumpSurfData((pDevice, "Blt-post Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
5887 vboxVDbgDumpSurfData((pDevice, "Blt-post Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
5888 }
5889#endif
5890 pSrcSurfIf->Release();
5891 }
5892 } while (0);
5893
5894 pDstSurfIf->Release();
5895 }
5896
5897 if (hr != S_OK)
5898 {
5899 /* todo: fallback to memcpy or whatever ? */
5900 Assert(0);
5901 }
5902
5903
5904#if 0
5905 if ((use pAlloc->enmD3DIfType instead!!! pDstRc->RcDesc.fFlags.Texture || pDstRc->RcDesc.fFlags.Value == 0)
5906 && (pSrcRc->RcDesc.fFlags.Texture || pSrcRc->RcDesc.fFlags.Value == 0))
5907 {
5908 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcAlloc->pD3DIf;
5909 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstAlloc->pD3DIf;
5910 Assert(pD3DIfSrcTex);
5911 Assert(pD3DIfDstTex);
5912
5913 if (pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat)
5914 {
5915 if (pSrcRc->aAllocations[0].SurfDesc.width == pDstRc->aAllocations[0].SurfDesc.width
5916 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
5917 && pData->DstRect.left == 0 && pData->DstRect.top == 0
5918 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
5919 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
5920 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height
5921 && pData->DstRect.right - pData->DstRect.left == pDstRc->aAllocations[0].SurfDesc.width
5922 && pData->DstRect.bottom - pData->DstRect.top == pDstRc->aAllocations[0].SurfDesc.height
5923 )
5924 {
5925 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
5926 Assert(hr == S_OK);
5927 }
5928 else if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
5929 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
5930 {
5931 Assert(pDstAlloc->SurfDesc.bpp);
5932 Assert(pSrcAlloc->SurfDesc.bpp);
5933 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
5934 D3DLOCKED_RECT DstRect, SrcRect;
5935 Assert(!pSrcAlloc->LockInfo.cLocks);
5936 Assert(!pDstAlloc->LockInfo.cLocks);
5937 hr = pD3DIfDstTex->LockRect(pData->DstSubResourceIndex, &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
5938 Assert(hr == S_OK);
5939 if (hr == S_OK)
5940 {
5941 hr = pD3DIfSrcTex->LockRect(pData->SrcSubResourceIndex, &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
5942 Assert(hr == S_OK);
5943 if (hr == S_OK)
5944 {
5945 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
5946 &pData->DstRect, &pData->SrcRect,
5947 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
5948 Assert(hr == S_OK);
5949
5950 pD3DIfSrcTex->UnlockRect(pData->SrcSubResourceIndex);
5951 }
5952 pD3DIfDstTex->UnlockRect(pData->DstSubResourceIndex);
5953 }
5954 }
5955 else
5956 {
5957
5958 Assert(0);
5959 /* @todo: impl */
5960 }
5961 }
5962 else
5963 {
5964 Assert(0);
5965 /* @todo: impl */
5966 }
5967 }
5968 else
5969 {
5970 if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
5971 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
5972 {
5973 Assert(pDstAlloc->SurfDesc.bpp);
5974 Assert(pSrcAlloc->SurfDesc.bpp);
5975 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
5976
5977 D3DLOCKED_RECT DstRect, SrcRect;
5978 hr = vboxWddmLockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags,
5979 &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
5980 Assert(hr == S_OK);
5981 if (hr == S_OK)
5982 {
5983 hr = vboxWddmLockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags,
5984 &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
5985 Assert(hr == S_OK);
5986 if (hr == S_OK)
5987 {
5988 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
5989 &pData->DstRect, &pData->SrcRect,
5990 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
5991 Assert(hr == S_OK);
5992
5993 HRESULT tmpHr = vboxWddmUnlockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags);
5994 Assert(tmpHr == S_OK);
5995 }
5996 HRESULT tmpHr = vboxWddmUnlockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags);
5997 Assert(tmpHr == S_OK);
5998 }
5999 }
6000 else
6001 {
6002 Assert(0);
6003 /* @todo: impl */
6004 }
6005 }
6006#endif
6007
6008 if (pDstRc->RcDesc.fFlags.SharedResource)
6009 {
6010 PVBOXWDDMDISP_ALLOCATION pAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
6011 EnterCriticalSection(&pDevice->DirtyAllocListLock);
6012 if (!pAlloc->DirtyAllocListEntry.pNext)
6013 RTListAppend(&pDevice->DirtyAllocList, &pAlloc->DirtyAllocListEntry);
6014 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
6015 }
6016
6017 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6018 return hr;
6019}
6020static HRESULT APIENTRY vboxWddmDDevColorFill(HANDLE hDevice, CONST D3DDDIARG_COLORFILL* pData)
6021{
6022 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6023 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6024 Assert(pDevice);
6025 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6026 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
6027 Assert(pRc);
6028 IDirect3DSurface9 *pSurfIf = NULL;
6029 HRESULT hr = vboxWddmSurfGet(pRc, pData->SubResourceIndex, &pSurfIf);
6030 Assert(hr == S_OK);
6031 if (hr == S_OK)
6032 {
6033 Assert(pSurfIf);
6034 hr = pDevice9If->ColorFill(pSurfIf, &pData->DstRect, pData->Color);
6035 Assert(hr == S_OK);
6036 /* @todo: check what need to do when PresentToDwm flag is set */
6037 Assert(pData->Flags.Value == 0);
6038
6039 pSurfIf->Release();
6040 }
6041 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6042 return hr;
6043}
6044static HRESULT APIENTRY vboxWddmDDevDepthFill(HANDLE hDevice, CONST D3DDDIARG_DEPTHFILL* pData)
6045{
6046 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6047 Assert(0);
6048 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6049 return E_FAIL;
6050}
6051static HRESULT APIENTRY vboxWddmDDevCreateQuery(HANDLE hDevice, D3DDDIARG_CREATEQUERY* pData)
6052{
6053 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6054 Assert(0);
6055 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6056 return E_FAIL;
6057}
6058static HRESULT APIENTRY vboxWddmDDevDestroyQuery(HANDLE hDevice, HANDLE hQuery)
6059{
6060 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6061 Assert(0);
6062 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6063 return E_FAIL;
6064}
6065static HRESULT APIENTRY vboxWddmDDevIssueQuery(HANDLE hDevice, CONST D3DDDIARG_ISSUEQUERY* pData)
6066{
6067 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6068 Assert(0);
6069 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6070 return E_FAIL;
6071}
6072static HRESULT APIENTRY vboxWddmDDevGetQueryData(HANDLE hDevice, CONST D3DDDIARG_GETQUERYDATA* pData)
6073{
6074 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6075 Assert(0);
6076 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6077 return E_FAIL;
6078}
6079static HRESULT APIENTRY vboxWddmDDevSetRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETRENDERTARGET* pData)
6080{
6081 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6082 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6083 Assert(pDevice);
6084 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6085 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget;
6086 Assert(pRc);
6087 Assert(pData->SubResourceIndex < pRc->cAllocations);
6088 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
6089 HRESULT hr = vboxWddmRenderTargetSet(pDevice, pData->RenderTargetIndex, pAlloc, FALSE);
6090 Assert(hr == S_OK);
6091 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6092 return hr;
6093}
6094static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDIARG_SETDEPTHSTENCIL* pData)
6095{
6096 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6097 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6098 Assert(pDevice);
6099 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6100 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hZBuffer;
6101 IDirect3DSurface9 *pD3D9Surf = NULL;
6102 if (pRc)
6103 {
6104 Assert(pRc->cAllocations == 1);
6105 pD3D9Surf = (IDirect3DSurface9*)pRc->aAllocations[0].pD3DIf;
6106 Assert(pD3D9Surf);
6107 }
6108 HRESULT hr = pDevice9If->SetDepthStencilSurface(pD3D9Surf);
6109 Assert(hr == S_OK);
6110 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6111 return hr;
6112}
6113static HRESULT APIENTRY vboxWddmDDevGenerateMipSubLevels(HANDLE hDevice, CONST D3DDDIARG_GENERATEMIPSUBLEVELS* pData)
6114{
6115 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6116 Assert(0);
6117 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6118 return E_FAIL;
6119}
6120static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTI* pData, CONST INT* pRegisters)
6121{
6122 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6123 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6124 Assert(pDevice);
6125 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6126 HRESULT hr = pDevice9If->SetPixelShaderConstantI(pData->Register, pRegisters, pData->Count);
6127 Assert(hr == S_OK);
6128 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6129 return hr;
6130}
6131static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTB* pData, CONST BOOL* pRegisters)
6132{
6133 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6134 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6135 Assert(pDevice);
6136 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6137 HRESULT hr = pDevice9If->SetPixelShaderConstantB(pData->Register, pRegisters, pData->Count);
6138 Assert(hr == S_OK);
6139 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6140 return hr;
6141}
6142static HRESULT APIENTRY vboxWddmDDevCreatePixelShader(HANDLE hDevice, D3DDDIARG_CREATEPIXELSHADER* pData, CONST UINT* pCode)
6143{
6144 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6145 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6146 Assert(pDevice);
6147 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6148 IDirect3DPixelShader9 *pShader;
6149 Assert(*((UINT*)((uint8_t*)pCode + pData->CodeSize-4)) == 0x0000FFFF /* end token */);
6150 HRESULT hr = pDevice9If->CreatePixelShader((const DWORD *)pCode, &pShader);
6151 Assert(hr == S_OK);
6152 if (hr == S_OK)
6153 {
6154 Assert(pShader);
6155 pData->ShaderHandle = pShader;
6156 }
6157 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6158 return hr;
6159}
6160static HRESULT APIENTRY vboxWddmDDevDeletePixelShader(HANDLE hDevice, HANDLE hShaderHandle)
6161{
6162 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6163 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6164 Assert(pDevice);
6165 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
6166 HRESULT hr = S_OK;
6167 pShader->Release();
6168 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6169 return hr;
6170}
6171static HRESULT APIENTRY vboxWddmDDevCreateDecodeDevice(HANDLE hDevice, D3DDDIARG_CREATEDECODEDEVICE* pData)
6172{
6173 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6174 Assert(0);
6175 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6176 return E_FAIL;
6177}
6178static HRESULT APIENTRY vboxWddmDDevDestroyDecodeDevice(HANDLE hDevice, HANDLE hDecodeDevice)
6179{
6180 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6181 Assert(0);
6182 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6183 return E_FAIL;
6184}
6185static HRESULT APIENTRY vboxWddmDDevSetDecodeRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETDECODERENDERTARGET* pData)
6186{
6187 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6188 Assert(0);
6189 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6190 return E_FAIL;
6191}
6192static HRESULT APIENTRY vboxWddmDDevDecodeBeginFrame(HANDLE hDevice, D3DDDIARG_DECODEBEGINFRAME* pData)
6193{
6194 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6195 Assert(0);
6196 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6197 return E_FAIL;
6198}
6199static HRESULT APIENTRY vboxWddmDDevDecodeEndFrame(HANDLE hDevice, D3DDDIARG_DECODEENDFRAME* pData)
6200{
6201 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6202 Assert(0);
6203 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6204 return E_FAIL;
6205}
6206static HRESULT APIENTRY vboxWddmDDevDecodeExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXECUTE* pData)
6207{
6208 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6209 Assert(0);
6210 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6211 return E_FAIL;
6212}
6213static HRESULT APIENTRY vboxWddmDDevDecodeExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXTENSIONEXECUTE* pData)
6214{
6215 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6216 Assert(0);
6217 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6218 return E_FAIL;
6219}
6220static HRESULT APIENTRY vboxWddmDDevCreateVideoProcessDevice(HANDLE hDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE* pData)
6221{
6222 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6223 Assert(0);
6224 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6225 return E_FAIL;
6226}
6227static HRESULT APIENTRY vboxWddmDDevDestroyVideoProcessDevice(HANDLE hDevice, HANDLE hVideoProcessor)
6228{
6229 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6230 Assert(0);
6231 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6232 return E_FAIL;
6233}
6234static HRESULT APIENTRY vboxWddmDDevVideoProcessBeginFrame(HANDLE hDevice, HANDLE hVideoProcess)
6235{
6236 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6237 Assert(0);
6238 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6239 return E_FAIL;
6240}
6241static HRESULT APIENTRY vboxWddmDDevVideoProcessEndFrame(HANDLE hDevice, D3DDDIARG_VIDEOPROCESSENDFRAME* pData)
6242{
6243 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6244 Assert(0);
6245 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6246 return E_FAIL;
6247}
6248static HRESULT APIENTRY vboxWddmDDevSetVideoProcessRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETVIDEOPROCESSRENDERTARGET* pData)
6249{
6250 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6251 Assert(0);
6252 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6253 return E_FAIL;
6254}
6255static HRESULT APIENTRY vboxWddmDDevVideoProcessBlt(HANDLE hDevice, CONST D3DDDIARG_VIDEOPROCESSBLT* pData)
6256{
6257 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6258 Assert(0);
6259 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6260 return E_FAIL;
6261}
6262static HRESULT APIENTRY vboxWddmDDevCreateExtensionDevice(HANDLE hDevice, D3DDDIARG_CREATEEXTENSIONDEVICE* pData)
6263{
6264 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6265 Assert(0);
6266 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6267 return E_FAIL;
6268}
6269static HRESULT APIENTRY vboxWddmDDevDestroyExtensionDevice(HANDLE hDevice, HANDLE hExtension)
6270{
6271 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6272 Assert(0);
6273 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6274 return E_FAIL;
6275}
6276static HRESULT APIENTRY vboxWddmDDevExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_EXTENSIONEXECUTE* pData)
6277{
6278 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6279 Assert(0);
6280 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6281 return E_FAIL;
6282}
6283static HRESULT APIENTRY vboxWddmDDevDestroyDevice(IN HANDLE hDevice)
6284{
6285 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6286
6287 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6288 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
6289// Assert(!pDevice->cScreens);
6290 vboxWddmSwapchainDestroyAll(pDevice);
6291 pDevice->pDevice9If->Release();
6292
6293 HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
6294 Assert(hr == S_OK);
6295 if (hr == S_OK)
6296 RTMemFree(pDevice);
6297 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6298 return hr;
6299}
6300
6301AssertCompile(sizeof (RECT) == sizeof (D3DDDIRECT));
6302AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DDDIRECT, left));
6303AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DDDIRECT, right));
6304AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DDDIRECT, top));
6305AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DDDIRECT, bottom));
6306AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DDDIRECT, left));
6307AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DDDIRECT, right));
6308AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DDDIRECT, top));
6309AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DDDIRECT, bottom));
6310
6311static HRESULT APIENTRY vboxWddmDDevCreateOverlay(HANDLE hDevice, D3DDDIARG_CREATEOVERLAY* pData)
6312{
6313 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6314 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6315 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
6316 Assert(pRc);
6317 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
6318 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
6319 HRESULT hr = S_OK;
6320 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)RTMemAllocZ(sizeof (VBOXWDDMDISP_OVERLAY));
6321 Assert(pOverlay);
6322 if (pOverlay)
6323 {
6324 VBOXWDDM_OVERLAY_INFO OurInfo;
6325 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
6326 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
6327 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
6328 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
6329 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
6330 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
6331 Assert(!pAlloc->LockInfo.cLocks);
6332 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
6333 D3DDDICB_CREATEOVERLAY OverInfo;
6334 OverInfo.VidPnSourceId = pData->VidPnSourceId;
6335 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
6336 Assert(pAlloc->hAllocation);
6337 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
6338 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
6339 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
6340 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
6341 OverInfo.hKernelOverlay = NULL; /* <-- out */
6342#ifndef VBOXWDDMOVERLAY_TEST
6343 hr = pDevice->RtCallbacks.pfnCreateOverlayCb(pDevice->hDevice, &OverInfo);
6344 Assert(hr == S_OK);
6345 if (hr == S_OK)
6346 {
6347 Assert(OverInfo.hKernelOverlay);
6348 pOverlay->hOverlay = OverInfo.hKernelOverlay;
6349 pOverlay->VidPnSourceId = pData->VidPnSourceId;
6350
6351 Assert(!pAlloc->LockInfo.cLocks);
6352 if (!pAlloc->LockInfo.cLocks)
6353 {
6354 /* we have reported the dirty rect, may clear it if no locks are pending currently */
6355 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
6356 }
6357
6358 pData->hOverlay = pOverlay;
6359 }
6360 else
6361 {
6362 RTMemFree(pOverlay);
6363 }
6364#else
6365 pData->hOverlay = pOverlay;
6366#endif
6367 }
6368 else
6369 hr = E_OUTOFMEMORY;
6370
6371 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6372 return hr;
6373}
6374static HRESULT APIENTRY vboxWddmDDevUpdateOverlay(HANDLE hDevice, CONST D3DDDIARG_UPDATEOVERLAY* pData)
6375{
6376 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6377 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6378 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
6379 Assert(pRc);
6380 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
6381 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
6382 HRESULT hr = S_OK;
6383 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
6384 VBOXWDDM_OVERLAY_INFO OurInfo;
6385 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
6386 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
6387 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
6388 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
6389 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
6390 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
6391 Assert(!pAlloc->LockInfo.cLocks);
6392 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
6393 D3DDDICB_UPDATEOVERLAY OverInfo;
6394 OverInfo.hKernelOverlay = pOverlay->hOverlay;
6395 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
6396 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
6397 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
6398 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
6399 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
6400#ifndef VBOXWDDMOVERLAY_TEST
6401 hr = pDevice->RtCallbacks.pfnUpdateOverlayCb(pDevice->hDevice, &OverInfo);
6402 Assert(hr == S_OK);
6403 if (hr == S_OK)
6404#endif
6405 {
6406 Assert(!pAlloc->LockInfo.cLocks);
6407 if (!pAlloc->LockInfo.cLocks)
6408 {
6409 /* we have reported the dirty rect, may clear it if no locks are pending currently */
6410 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
6411 }
6412 }
6413
6414 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6415 return hr;
6416}
6417static HRESULT APIENTRY vboxWddmDDevFlipOverlay(HANDLE hDevice, CONST D3DDDIARG_FLIPOVERLAY* pData)
6418{
6419 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6420 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6421 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSource;
6422 Assert(pRc);
6423 Assert(pRc->cAllocations > pData->SourceIndex);
6424 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SourceIndex];
6425 HRESULT hr = S_OK;
6426 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
6427 VBOXWDDM_OVERLAYFLIP_INFO OurInfo;
6428 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
6429 Assert(!pAlloc->LockInfo.cLocks);
6430 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
6431 D3DDDICB_FLIPOVERLAY OverInfo;
6432 OverInfo.hKernelOverlay = pOverlay->hOverlay;
6433 OverInfo.hSource = pAlloc->hAllocation;
6434 OverInfo.pPrivateDriverData = &OurInfo;
6435 OverInfo.PrivateDriverDataSize = sizeof (OurInfo);
6436#ifndef VBOXWDDMOVERLAY_TEST
6437 hr = pDevice->RtCallbacks.pfnFlipOverlayCb(pDevice->hDevice, &OverInfo);
6438 Assert(hr == S_OK);
6439 if (hr == S_OK)
6440#endif
6441 {
6442 Assert(!pAlloc->LockInfo.cLocks);
6443 if (!pAlloc->LockInfo.cLocks)
6444 {
6445 /* we have reported the dirty rect, may clear it if no locks are pending currently */
6446 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
6447 }
6448 }
6449
6450 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6451 return hr;
6452}
6453static HRESULT APIENTRY vboxWddmDDevGetOverlayColorControls(HANDLE hDevice, D3DDDIARG_GETOVERLAYCOLORCONTROLS* pData)
6454{
6455 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6456 Assert(0);
6457 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6458 return E_FAIL;
6459}
6460static HRESULT APIENTRY vboxWddmDDevSetOverlayColorControls(HANDLE hDevice, CONST D3DDDIARG_SETOVERLAYCOLORCONTROLS* pData)
6461{
6462 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6463 Assert(0);
6464 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6465 return E_FAIL;
6466}
6467static HRESULT APIENTRY vboxWddmDDevDestroyOverlay(HANDLE hDevice, CONST D3DDDIARG_DESTROYOVERLAY* pData)
6468{
6469 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6470 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6471 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
6472 D3DDDICB_DESTROYOVERLAY OverInfo;
6473 OverInfo.hKernelOverlay = pOverlay->hOverlay;
6474#ifndef VBOXWDDMOVERLAY_TEST
6475 HRESULT hr = pDevice->RtCallbacks.pfnDestroyOverlayCb(pDevice->hDevice, &OverInfo);
6476 Assert(hr == S_OK);
6477 if (hr == S_OK)
6478#else
6479 HRESULT hr = S_OK;
6480#endif
6481 {
6482 RTMemFree(pOverlay);
6483 }
6484
6485 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6486 return hr;
6487}
6488static HRESULT APIENTRY vboxWddmDDevQueryResourceResidency(HANDLE hDevice, CONST D3DDDIARG_QUERYRESOURCERESIDENCY* pData)
6489{
6490 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6491 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6492 Assert(0);
6493 HRESULT hr = S_OK;
6494#if 0
6495 for (UINT i = 0; i < pData->NumResources; ++i)
6496 {
6497 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->pHandleList[i];
6498 Assert(pRc->pDevice == pDevice);
6499 if (pRc->hKMResource)
6500 {
6501
6502 }
6503 }
6504#endif
6505 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6506 return hr;
6507}
6508
6509static HRESULT vboxAllocationInit(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DDDI_OPENALLOCATIONINFO *pInfo)
6510{
6511 HRESULT hr = S_OK;
6512 pAlloc->hAllocation = pInfo->hAllocation;
6513 Assert(pInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
6514 Assert(pInfo->pPrivateDriverData);
6515 if (pInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
6516 {
6517 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pInfo->pPrivateDriverData;
6518 pAlloc->enmType = pAllocInfo->enmType;
6519 Assert(pAllocInfo->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
6520 || VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE
6521 || VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE);
6522 pAlloc->pvMem = NULL;
6523 pAlloc->SurfDesc = pAllocInfo->SurfDesc;
6524 }
6525 else
6526 {
6527 vboxVDbgPrintR((__FUNCTION__": ERROR: PrivateDriverDataSize(%d) < (%d)\n", pInfo->PrivateDriverDataSize, sizeof (VBOXWDDM_ALLOCINFO)));
6528 hr = E_INVALIDARG;
6529 }
6530 return hr;
6531}
6532
6533static HRESULT APIENTRY vboxWddmDDevOpenResource(HANDLE hDevice, D3DDDIARG_OPENRESOURCE* pData)
6534{
6535 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6536 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6537 HRESULT hr = S_OK;
6538
6539 Assert(pDevice);
6540 Assert(pData->NumAllocations);
6541 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pData->NumAllocations);
6542 Assert(pRc);
6543 if (pRc)
6544 {
6545 pRc->hResource = pData->hResource;
6546 pRc->hKMResource = pData->hKMResource;
6547 pRc->pDevice = pDevice;
6548 pRc->RcDesc.enmRotation = pData->Rotation;
6549 pRc->fFlags = VBOXWDDM_RESOURCE_F_OPENNED;
6550 if (!pData->pPrivateDriverData || !pData->PrivateDriverDataSize)
6551 {
6552 /* this is a "standard" allocation resource */
6553
6554 /* both should be actually zero */
6555 Assert(!pData->pPrivateDriverData && !pData->PrivateDriverDataSize);
6556 pRc->RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
6557 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
6558 pRc->RcDesc.MultisampleQuality = 0;
6559 pRc->RcDesc.MipLevels = 0;
6560 pRc->RcDesc.Fvf;
6561 pRc->RcDesc.fFlags.Value = 0;
6562
6563 Assert(pData->NumAllocations);
6564 D3DDDI_OPENALLOCATIONINFO* pDdiAllocInfo = &pData->pOpenAllocationInfo[0];
6565 Assert(pDdiAllocInfo->pPrivateDriverData);
6566 Assert(pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO));
6567 if (pDdiAllocInfo->pPrivateDriverData && pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
6568 {
6569 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocInfo->pPrivateDriverData;
6570 switch(pAllocInfo->enmType)
6571 {
6572 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
6573 pRc->RcDesc.fFlags.Primary = 1;
6574 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
6575 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
6576 pRc->RcDesc.enmFormat = pAllocInfo->SurfDesc.format;
6577 pRc->RcDesc.VidPnSourceId = pAllocInfo->SurfDesc.VidPnSourceId;
6578 pRc->RcDesc.RefreshRate = pAllocInfo->SurfDesc.RefreshRate;
6579 break;
6580 default:
6581 Assert(0);
6582 hr = E_INVALIDARG;
6583 }
6584 }
6585 else
6586 hr = E_INVALIDARG;
6587 }
6588 else
6589 {
6590 /* this is a "generic" resource whose creation is initiaded by the UMD */
6591 Assert(pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
6592 if (pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO))
6593 {
6594 VBOXWDDM_RCINFO *pRcInfo = (VBOXWDDM_RCINFO*)pData->pPrivateDriverData;
6595 Assert(pRcInfo->fFlags == VBOXWDDM_RESOURCE_F_TYPE_GENERIC);
6596 Assert(pRcInfo->cAllocInfos == pData->NumAllocations);
6597 pRc->fFlags = pRcInfo->fFlags | VBOXWDDM_RESOURCE_F_OPENNED;
6598 pRc->RcDesc = pRcInfo->RcDesc;
6599 pRc->cAllocations = pData->NumAllocations;
6600
6601 for (UINT i = 0; i < pData->NumAllocations; ++i)
6602 {
6603 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
6604 D3DDDI_OPENALLOCATIONINFO* pOAI = pData->pOpenAllocationInfo;
6605 Assert(pOAI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
6606 if (pOAI->PrivateDriverDataSize != sizeof (VBOXWDDM_ALLOCINFO))
6607 {
6608 hr = E_INVALIDARG;
6609 break;
6610 }
6611 Assert(pOAI->pPrivateDriverData);
6612 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pOAI->pPrivateDriverData;
6613 pAllocation->hAllocation = pOAI->hAllocation;
6614 pAllocation->enmType = pAllocInfo->enmType;
6615 pAllocation->hSharedHandle = pAllocInfo->hSharedHandle;
6616 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
6617 Assert(pAllocation->hSharedHandle);
6618 }
6619
6620 Assert(pRc->RcDesc.fFlags.SharedResource);
6621 if (pRc->RcDesc.fFlags.Texture)
6622 {
6623 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6624 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
6625 IDirect3DTexture9 *pD3DIfTex;
6626 HANDLE hSharedHandle = pAllocation->hSharedHandle;
6627 Assert(pAllocation->hSharedHandle);
6628
6629 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
6630 pAllocation->SurfDesc.width,
6631 pAllocation->SurfDesc.height,
6632 pRc->cAllocations,
6633 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
6634 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
6635 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
6636 &pD3DIfTex,
6637 &hSharedHandle,
6638 NULL);
6639 Assert(hr == S_OK);
6640 if (hr == S_OK)
6641 {
6642 Assert(pD3DIfTex);
6643 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
6644 pAllocation->pD3DIf = pD3DIfTex;
6645 Assert(pAllocation->hSharedHandle == hSharedHandle);
6646 Assert(pAllocation->hSharedHandle);
6647 }
6648 }
6649 else
6650 {
6651 /* impl */
6652 Assert(0);
6653 }
6654 }
6655 else
6656 hr = E_INVALIDARG;
6657 }
6658
6659 if (hr == S_OK)
6660 {
6661 for (UINT i = 0; i < pData->NumAllocations; ++i)
6662 {
6663 hr = vboxAllocationInit(&pRc->aAllocations[i], &pData->pOpenAllocationInfo[i]);
6664 Assert(hr == S_OK);
6665 if (hr != S_OK)
6666 break;
6667 }
6668 }
6669
6670 if (hr == S_OK)
6671 pData->hResource = pRc;
6672 else
6673 vboxResourceFree(pRc);
6674 }
6675 else
6676 {
6677 vboxVDbgPrintR((__FUNCTION__": vboxResourceAlloc failed for hDevice(0x%p), NumAllocations(%d)\n", hDevice, pData->NumAllocations));
6678 hr = E_OUTOFMEMORY;
6679 }
6680
6681 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6682 return hr;
6683}
6684static HRESULT APIENTRY vboxWddmDDevGetCaptureAllocationHandle(HANDLE hDevice, D3DDDIARG_GETCAPTUREALLOCATIONHANDLE* pData)
6685{
6686 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6687 Assert(0);
6688 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6689 return E_FAIL;
6690}
6691
6692static HRESULT APIENTRY vboxWddmDDevCaptureToSysMem(HANDLE hDevice, CONST D3DDDIARG_CAPTURETOSYSMEM* pData)
6693{
6694 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6695 Assert(0);
6696 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6697 return E_FAIL;
6698}
6699
6700static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIARG_CREATEDEVICE* pCreateData)
6701{
6702 HRESULT hr = S_OK;
6703 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), Interface(%d), Version(%d)\n", hAdapter, pCreateData->Interface, pCreateData->Version));
6704
6705// Assert(0);
6706 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
6707
6708 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_DEVICE, apRTs[pAdapter->cMaxSimRTs]));
6709 if (pDevice)
6710 {
6711 pDevice->cRTs = pAdapter->cMaxSimRTs;
6712 pDevice->hDevice = pCreateData->hDevice;
6713 pDevice->pAdapter = pAdapter;
6714 pDevice->u32IfVersion = pCreateData->Interface;
6715 pDevice->uRtVersion = pCreateData->Version;
6716 pDevice->RtCallbacks = *pCreateData->pCallbacks;
6717 pDevice->pvCmdBuffer = pCreateData->pCommandBuffer;
6718 pDevice->cbCmdBuffer = pCreateData->CommandBufferSize;
6719 pDevice->fFlags = pCreateData->Flags;
6720 /* Set Viewport to some default values */
6721 pDevice->ViewPort.X = 0;
6722 pDevice->ViewPort.Y = 0;
6723 pDevice->ViewPort.Width = 1;
6724 pDevice->ViewPort.Height = 1;
6725 pDevice->ViewPort.MinZ = 0.;
6726 pDevice->ViewPort.MaxZ = 1.;
6727
6728 InitializeCriticalSection(&pDevice->DirtyAllocListLock);
6729 RTListInit(&pDevice->DirtyAllocList);
6730
6731 Assert(!pCreateData->AllocationListSize);
6732 Assert(!pCreateData->PatchLocationListSize);
6733
6734 pCreateData->hDevice = pDevice;
6735
6736 pCreateData->pDeviceFuncs->pfnSetRenderState = vboxWddmDDevSetRenderState;
6737 pCreateData->pDeviceFuncs->pfnUpdateWInfo = vboxWddmDDevUpdateWInfo;
6738 pCreateData->pDeviceFuncs->pfnValidateDevice = vboxWddmDDevValidateDevice;
6739 pCreateData->pDeviceFuncs->pfnSetTextureStageState = vboxWddmDDevSetTextureStageState;
6740 pCreateData->pDeviceFuncs->pfnSetTexture = vboxWddmDDevSetTexture;
6741 pCreateData->pDeviceFuncs->pfnSetPixelShader = vboxWddmDDevSetPixelShader;
6742 pCreateData->pDeviceFuncs->pfnSetPixelShaderConst = vboxWddmDDevSetPixelShaderConst;
6743 pCreateData->pDeviceFuncs->pfnSetStreamSourceUm = vboxWddmDDevSetStreamSourceUm;
6744 pCreateData->pDeviceFuncs->pfnSetIndices = vboxWddmDDevSetIndices;
6745 pCreateData->pDeviceFuncs->pfnSetIndicesUm = vboxWddmDDevSetIndicesUm;
6746 pCreateData->pDeviceFuncs->pfnDrawPrimitive = vboxWddmDDevDrawPrimitive;
6747 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive = vboxWddmDDevDrawIndexedPrimitive;
6748 pCreateData->pDeviceFuncs->pfnDrawRectPatch = vboxWddmDDevDrawRectPatch;
6749 pCreateData->pDeviceFuncs->pfnDrawTriPatch = vboxWddmDDevDrawTriPatch;
6750 pCreateData->pDeviceFuncs->pfnDrawPrimitive2 = vboxWddmDDevDrawPrimitive2;
6751 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive2 = vboxWddmDDevDrawIndexedPrimitive2;
6752 pCreateData->pDeviceFuncs->pfnVolBlt = vboxWddmDDevVolBlt;
6753 pCreateData->pDeviceFuncs->pfnBufBlt = vboxWddmDDevBufBlt;
6754 pCreateData->pDeviceFuncs->pfnTexBlt = vboxWddmDDevTexBlt;
6755 pCreateData->pDeviceFuncs->pfnStateSet = vboxWddmDDevStateSet;
6756 pCreateData->pDeviceFuncs->pfnSetPriority = vboxWddmDDevSetPriority;
6757 pCreateData->pDeviceFuncs->pfnClear = vboxWddmDDevClear;
6758 pCreateData->pDeviceFuncs->pfnUpdatePalette = vboxWddmDDevUpdatePalette;
6759 pCreateData->pDeviceFuncs->pfnSetPalette = vboxWddmDDevSetPalette;
6760 pCreateData->pDeviceFuncs->pfnSetVertexShaderConst = vboxWddmDDevSetVertexShaderConst;
6761 pCreateData->pDeviceFuncs->pfnMultiplyTransform = vboxWddmDDevMultiplyTransform;
6762 pCreateData->pDeviceFuncs->pfnSetTransform = vboxWddmDDevSetTransform;
6763 pCreateData->pDeviceFuncs->pfnSetViewport = vboxWddmDDevSetViewport;
6764 pCreateData->pDeviceFuncs->pfnSetZRange = vboxWddmDDevSetZRange;
6765 pCreateData->pDeviceFuncs->pfnSetMaterial = vboxWddmDDevSetMaterial;
6766 pCreateData->pDeviceFuncs->pfnSetLight = vboxWddmDDevSetLight;
6767 pCreateData->pDeviceFuncs->pfnCreateLight = vboxWddmDDevCreateLight;
6768 pCreateData->pDeviceFuncs->pfnDestroyLight = vboxWddmDDevDestroyLight;
6769 pCreateData->pDeviceFuncs->pfnSetClipPlane = vboxWddmDDevSetClipPlane;
6770 pCreateData->pDeviceFuncs->pfnGetInfo = vboxWddmDDevGetInfo;
6771 pCreateData->pDeviceFuncs->pfnLock = vboxWddmDDevLock;
6772 pCreateData->pDeviceFuncs->pfnUnlock = vboxWddmDDevUnlock;
6773 pCreateData->pDeviceFuncs->pfnCreateResource = vboxWddmDDevCreateResource;
6774 pCreateData->pDeviceFuncs->pfnDestroyResource = vboxWddmDDevDestroyResource;
6775 pCreateData->pDeviceFuncs->pfnSetDisplayMode = vboxWddmDDevSetDisplayMode;
6776 pCreateData->pDeviceFuncs->pfnPresent = vboxWddmDDevPresent;
6777 pCreateData->pDeviceFuncs->pfnFlush = vboxWddmDDevFlush;
6778 pCreateData->pDeviceFuncs->pfnCreateVertexShaderFunc = vboxWddmDDevCreateVertexShaderFunc;
6779 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderFunc = vboxWddmDDevDeleteVertexShaderFunc;
6780 pCreateData->pDeviceFuncs->pfnSetVertexShaderFunc = vboxWddmDDevSetVertexShaderFunc;
6781 pCreateData->pDeviceFuncs->pfnCreateVertexShaderDecl = vboxWddmDDevCreateVertexShaderDecl;
6782 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderDecl = vboxWddmDDevDeleteVertexShaderDecl;
6783 pCreateData->pDeviceFuncs->pfnSetVertexShaderDecl = vboxWddmDDevSetVertexShaderDecl;
6784 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstI = vboxWddmDDevSetVertexShaderConstI;
6785 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstB = vboxWddmDDevSetVertexShaderConstB;
6786 pCreateData->pDeviceFuncs->pfnSetScissorRect = vboxWddmDDevSetScissorRect;
6787 pCreateData->pDeviceFuncs->pfnSetStreamSource = vboxWddmDDevSetStreamSource;
6788 pCreateData->pDeviceFuncs->pfnSetStreamSourceFreq = vboxWddmDDevSetStreamSourceFreq;
6789 pCreateData->pDeviceFuncs->pfnSetConvolutionKernelMono = vboxWddmDDevSetConvolutionKernelMono;
6790 pCreateData->pDeviceFuncs->pfnComposeRects = vboxWddmDDevComposeRects;
6791 pCreateData->pDeviceFuncs->pfnBlt = vboxWddmDDevBlt;
6792 pCreateData->pDeviceFuncs->pfnColorFill = vboxWddmDDevColorFill;
6793 pCreateData->pDeviceFuncs->pfnDepthFill = vboxWddmDDevDepthFill;
6794 pCreateData->pDeviceFuncs->pfnCreateQuery = vboxWddmDDevCreateQuery;
6795 pCreateData->pDeviceFuncs->pfnDestroyQuery = vboxWddmDDevDestroyQuery;
6796 pCreateData->pDeviceFuncs->pfnIssueQuery = vboxWddmDDevIssueQuery;
6797 pCreateData->pDeviceFuncs->pfnGetQueryData = vboxWddmDDevGetQueryData;
6798 pCreateData->pDeviceFuncs->pfnSetRenderTarget = vboxWddmDDevSetRenderTarget;
6799 pCreateData->pDeviceFuncs->pfnSetDepthStencil = vboxWddmDDevSetDepthStencil;
6800 pCreateData->pDeviceFuncs->pfnGenerateMipSubLevels = vboxWddmDDevGenerateMipSubLevels;
6801 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstI = vboxWddmDDevSetPixelShaderConstI;
6802 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstB = vboxWddmDDevSetPixelShaderConstB;
6803 pCreateData->pDeviceFuncs->pfnCreatePixelShader = vboxWddmDDevCreatePixelShader;
6804 pCreateData->pDeviceFuncs->pfnDeletePixelShader = vboxWddmDDevDeletePixelShader;
6805 pCreateData->pDeviceFuncs->pfnCreateDecodeDevice = vboxWddmDDevCreateDecodeDevice;
6806 pCreateData->pDeviceFuncs->pfnDestroyDecodeDevice = vboxWddmDDevDestroyDecodeDevice;
6807 pCreateData->pDeviceFuncs->pfnSetDecodeRenderTarget = vboxWddmDDevSetDecodeRenderTarget;
6808 pCreateData->pDeviceFuncs->pfnDecodeBeginFrame = vboxWddmDDevDecodeBeginFrame;
6809 pCreateData->pDeviceFuncs->pfnDecodeEndFrame = vboxWddmDDevDecodeEndFrame;
6810 pCreateData->pDeviceFuncs->pfnDecodeExecute = vboxWddmDDevDecodeExecute;
6811 pCreateData->pDeviceFuncs->pfnDecodeExtensionExecute = vboxWddmDDevDecodeExtensionExecute;
6812 pCreateData->pDeviceFuncs->pfnCreateVideoProcessDevice = vboxWddmDDevCreateVideoProcessDevice;
6813 pCreateData->pDeviceFuncs->pfnDestroyVideoProcessDevice = vboxWddmDDevDestroyVideoProcessDevice;
6814 pCreateData->pDeviceFuncs->pfnVideoProcessBeginFrame = vboxWddmDDevVideoProcessBeginFrame;
6815 pCreateData->pDeviceFuncs->pfnVideoProcessEndFrame = vboxWddmDDevVideoProcessEndFrame;
6816 pCreateData->pDeviceFuncs->pfnSetVideoProcessRenderTarget = vboxWddmDDevSetVideoProcessRenderTarget;
6817 pCreateData->pDeviceFuncs->pfnVideoProcessBlt = vboxWddmDDevVideoProcessBlt;
6818 pCreateData->pDeviceFuncs->pfnCreateExtensionDevice = vboxWddmDDevCreateExtensionDevice;
6819 pCreateData->pDeviceFuncs->pfnDestroyExtensionDevice = vboxWddmDDevDestroyExtensionDevice;
6820 pCreateData->pDeviceFuncs->pfnExtensionExecute = vboxWddmDDevExtensionExecute;
6821 pCreateData->pDeviceFuncs->pfnCreateOverlay = vboxWddmDDevCreateOverlay;
6822 pCreateData->pDeviceFuncs->pfnUpdateOverlay = vboxWddmDDevUpdateOverlay;
6823 pCreateData->pDeviceFuncs->pfnFlipOverlay = vboxWddmDDevFlipOverlay;
6824 pCreateData->pDeviceFuncs->pfnGetOverlayColorControls = vboxWddmDDevGetOverlayColorControls;
6825 pCreateData->pDeviceFuncs->pfnSetOverlayColorControls = vboxWddmDDevSetOverlayColorControls;
6826 pCreateData->pDeviceFuncs->pfnDestroyOverlay = vboxWddmDDevDestroyOverlay;
6827 pCreateData->pDeviceFuncs->pfnDestroyDevice = vboxWddmDDevDestroyDevice;
6828 pCreateData->pDeviceFuncs->pfnQueryResourceResidency = vboxWddmDDevQueryResourceResidency;
6829 pCreateData->pDeviceFuncs->pfnOpenResource = vboxWddmDDevOpenResource;
6830 pCreateData->pDeviceFuncs->pfnGetCaptureAllocationHandle = vboxWddmDDevGetCaptureAllocationHandle;
6831 pCreateData->pDeviceFuncs->pfnCaptureToSysMem = vboxWddmDDevCaptureToSysMem;
6832 pCreateData->pDeviceFuncs->pfnLockAsync = NULL; //vboxWddmDDevLockAsync;
6833 pCreateData->pDeviceFuncs->pfnUnlockAsync = NULL; //vboxWddmDDevUnlockAsync;
6834 pCreateData->pDeviceFuncs->pfnRename = NULL; //vboxWddmDDevRename;
6835
6836
6837 do
6838 {
6839 RTListInit(&pDevice->SwapchainList);
6840 Assert(!pCreateData->AllocationListSize
6841 && !pCreateData->PatchLocationListSize);
6842 if (!pCreateData->AllocationListSize
6843 && !pCreateData->PatchLocationListSize)
6844 {
6845 hr = vboxDispCmCtxCreate(pDevice, &pDevice->DefaultContext);
6846 Assert(hr == S_OK);
6847 if (hr == S_OK)
6848 {
6849#ifdef VBOXDISP_EARLYCREATEDEVICE
6850 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);
6851 Assert(pRc);
6852 if (pRc)
6853 {
6854 D3DPRESENT_PARAMETERS params;
6855 memset(&params, 0, sizeof (params));
6856// params.BackBufferWidth = 640;
6857// params.BackBufferHeight = 480;
6858 params.BackBufferWidth = 0x400;
6859 params.BackBufferHeight = 0x300;
6860 params.BackBufferFormat = D3DFMT_A8R8G8B8;
6861// params.BackBufferCount = 0;
6862 params.BackBufferCount = 1;
6863 params.MultiSampleType = D3DMULTISAMPLE_NONE;
6864 params.SwapEffect = D3DSWAPEFFECT_DISCARD;
6865 // params.hDeviceWindow = hWnd;
6866 /* @todo: it seems there should be a way to detect this correctly since
6867 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
6868 params.Windowed = TRUE;
6869 // params.EnableAutoDepthStencil = FALSE;
6870 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
6871 // params.Flags;
6872 // params.FullScreen_RefreshRateInHz;
6873 // params.FullScreen_PresentationInterval;
6874
6875 hr = vboxWddmD3DDeviceCreate(pDevice, 0, pRc, &params, TRUE /*BOOL bLockable*/);
6876 Assert(hr == S_OK);
6877 if (hr == S_OK)
6878 break;
6879 vboxResourceFree(pRc);
6880 }
6881 else
6882 {
6883 hr = E_OUTOFMEMORY;
6884 }
6885#else
6886//# define VBOXDISP_TEST_SWAPCHAIN
6887# ifdef VBOXDISP_TEST_SWAPCHAIN
6888 VBOXDISP_D3DEV(pDevice);
6889# endif
6890 break;
6891#endif
6892
6893 HRESULT tmpHr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
6894 Assert(tmpHr == S_OK);
6895 }
6896 }
6897 else
6898 {
6899 vboxVDbgPrintR((__FUNCTION__": Not implemented: PatchLocationListSize(%d), AllocationListSize(%d)\n",
6900 pCreateData->PatchLocationListSize, pCreateData->AllocationListSize));
6901 //pCreateData->pAllocationList = ??
6902 hr = E_FAIL;
6903 }
6904
6905 RTMemFree(pDevice);
6906 } while (0);
6907 }
6908 else
6909 {
6910 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
6911 hr = E_OUTOFMEMORY;
6912 }
6913
6914 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
6915
6916 return hr;
6917}
6918
6919static HRESULT APIENTRY vboxWddmDispCloseAdapter (IN HANDLE hAdapter)
6920{
6921 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
6922
6923// Assert(0);
6924
6925 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
6926 if (VBOXDISPMODE_IS_3D(pAdapter))
6927 {
6928 HRESULT hr = VBoxDispWorkerDestroy(&pAdapter->WndWorker);
6929 Assert(hr == S_OK);
6930 pAdapter->pD3D9If->Release();
6931 VBoxDispD3DClose(&pAdapter->D3D);
6932 }
6933
6934 vboxCapsFree(pAdapter);
6935
6936 RTMemFree(pAdapter);
6937
6938 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
6939
6940 return S_OK;
6941}
6942
6943HRESULT APIENTRY OpenAdapter (__inout D3DDDIARG_OPENADAPTER* pOpenData)
6944{
6945 vboxVDbgPrint(("==> "__FUNCTION__"\n"));
6946
6947// vboxDispLock();
6948
6949 HRESULT hr = E_FAIL;
6950
6951 do
6952 {
6953
6954 VBOXWDDM_QI Query;
6955 D3DDDICB_QUERYADAPTERINFO DdiQuery;
6956 DdiQuery.PrivateDriverDataSize = sizeof(Query);
6957 DdiQuery.pPrivateDriverData = &Query;
6958 hr = pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb(pOpenData->hAdapter, &DdiQuery);
6959 Assert(hr == S_OK);
6960 if (hr != S_OK)
6961 {
6962 vboxVDbgPrintR((__FUNCTION__": pfnQueryAdapterInfoCb failed, hr (%d)\n", hr));
6963 hr = E_FAIL;
6964 break;
6965 }
6966
6967 /* check the miniport version match display version */
6968 if (Query.u32Version != VBOXVIDEOIF_VERSION)
6969 {
6970 vboxVDbgPrintR((__FUNCTION__": miniport version mismatch, expected (%d), but was (%d)\n",
6971 VBOXVIDEOIF_VERSION,
6972 Query.u32Version));
6973 hr = E_FAIL;
6974 break;
6975 }
6976
6977#ifdef VBOX_WITH_VIDEOHWACCEL
6978 Assert(Query.cInfos >= 1);
6979 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_ADAPTER, aHeads[Query.cInfos]));
6980#else
6981 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(sizeof (VBOXWDDMDISP_ADAPTER));
6982#endif
6983 Assert(pAdapter);
6984 if (pAdapter)
6985 {
6986 pAdapter->hAdapter = pOpenData->hAdapter;
6987 pAdapter->uIfVersion = pOpenData->Interface;
6988 pAdapter->uRtVersion= pOpenData->Version;
6989 pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
6990
6991 pAdapter->cHeads = Query.cInfos;
6992
6993
6994 pOpenData->hAdapter = pAdapter;
6995 pOpenData->pAdapterFuncs->pfnGetCaps = vboxWddmDispGetCaps;
6996 pOpenData->pAdapterFuncs->pfnCreateDevice = vboxWddmDispCreateDevice;
6997 pOpenData->pAdapterFuncs->pfnCloseAdapter = vboxWddmDispCloseAdapter;
6998 pOpenData->DriverVersion = D3D_UMD_INTERFACE_VERSION;
6999 /*
7000 * here we detect whether we are called by the d3d or ddraw.
7001 * in the d3d case we init our d3d environment
7002 * in the ddraw case we init 2D acceleration
7003 * if interface version is > 7, this is D3D, treat it as so
7004 * otherwise treat it as ddraw
7005 * @todo: need a more clean way of doing this */
7006
7007 if (pAdapter->uIfVersion > 7)
7008 {
7009 do
7010 {
7011 /* try enable the 3D */
7012 hr = VBoxDispD3DOpen(&pAdapter->D3D);
7013 Assert(hr == S_OK);
7014 if (hr == S_OK)
7015 {
7016// Assert(0);
7017 hr = pAdapter->D3D.pfnDirect3DCreate9Ex(D3D_SDK_VERSION, &pAdapter->pD3D9If);
7018 Assert(hr == S_OK);
7019 if (hr == S_OK)
7020 {
7021 D3DCAPS9 Caps;
7022 memset(&Caps, 0, sizeof (Caps));
7023 hr = vboxWddmGetD3D9Caps(pAdapter, &Caps);
7024 Assert(hr == S_OK);
7025 if (hr == S_OK)
7026 {
7027 pAdapter->cMaxSimRTs = Caps.NumSimultaneousRTs;
7028 Assert(pAdapter->cMaxSimRTs);
7029 Assert(pAdapter->cMaxSimRTs < UINT32_MAX/2);
7030 hr = VBoxDispWorkerCreate(&pAdapter->WndWorker);
7031 Assert(hr == S_OK);
7032 if (hr == S_OK)
7033 {
7034 vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
7035 break;
7036 }
7037 }
7038 pAdapter->pD3D9If->Release();
7039 }
7040 else
7041 vboxVDbgPrintR((__FUNCTION__": pfnDirect3DCreate9Ex failed, hr (%d)\n", hr));
7042 VBoxDispD3DClose(&pAdapter->D3D);
7043 }
7044 else
7045 vboxVDbgPrintR((__FUNCTION__": VBoxDispD3DOpen failed, hr (%d)\n", hr));
7046 } while (0);
7047 }
7048#ifdef VBOX_WITH_VIDEOHWACCEL
7049 else
7050 {
7051 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
7052 {
7053 pAdapter->aHeads[i].Vhwa.Settings = Query.aInfos[i];
7054 }
7055 }
7056#endif
7057
7058 vboxCapsInit(pAdapter);
7059 hr = S_OK;
7060// RTMemFree(pAdapter);
7061 }
7062 else
7063 {
7064 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
7065 hr = E_OUTOFMEMORY;
7066 }
7067
7068 } while (0);
7069
7070// vboxDispUnlock();
7071
7072 vboxVDbgPrint(("<== "__FUNCTION__", hr (%d)\n", hr));
7073
7074 return hr;
7075}
7076
7077#ifdef VBOXWDDMDISP_DEBUG
7078
7079bool g_VDbgTstDumpEnable = false;
7080bool g_VDbgTstDumpOnSys2VidSameSizeEnable = false;
7081
7082VOID vboxVDbgDoDumpSurfData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const RECT *pRect, IDirect3DSurface9 *pSurf, const char* pSuffix)
7083{
7084 if (pPrefix)
7085 {
7086 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
7087 }
7088
7089 Assert(pRc->cAllocations > iAlloc);
7090 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
7091
7092 vboxVDbgMpPrintAlloc((pDevice, "allocation info:\n", pRc, iAlloc, "\n"));
7093
7094 D3DLOCKED_RECT Lr;
7095 if (pRect)
7096 {
7097 Assert(pRect->right > pRect->left);
7098 Assert(pRect->bottom > pRect->top);
7099 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
7100 }
7101
7102 BOOL bReleaseSurf = false;
7103 if (!pSurf)
7104 {
7105 HRESULT tmpHr = vboxWddmSurfGet(pRc, iAlloc, &pSurf);
7106 Assert(tmpHr == S_OK);
7107 bReleaseSurf = TRUE;
7108 }
7109 HRESULT srcHr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
7110 Assert(srcHr == S_OK);
7111 if (srcHr == S_OK)
7112 {
7113 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
7114// Assert(bpp == pAlloc->SurfDesc.bpp);
7115// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
7116 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
7117 Lr.pBits, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, Lr.Pitch));
7118 if (pRect)
7119 {
7120 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
7121 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
7122 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
7123 }
7124 Assert(0);
7125
7126 srcHr = pSurf->UnlockRect();
7127 Assert(srcHr == S_OK);
7128 }
7129 if (pSuffix)
7130 {
7131 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
7132 }
7133
7134 if (bReleaseSurf)
7135 pSurf->Release();
7136}
7137
7138VOID vboxVDbgDoDumpSurfDataBySurf(const PVBOXWDDMDISP_DEVICE pDevice, IDirect3DSurface9 *pSurf)
7139{
7140 D3DSURFACE_DESC Desc;
7141 HRESULT hr = pSurf->GetDesc(&Desc);
7142 Assert(hr == S_OK);
7143 if (hr == S_OK)
7144 {
7145 D3DLOCKED_RECT Lr;
7146 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
7147 Assert(hr == S_OK);
7148 if (hr == S_OK)
7149 {
7150 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
7151 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
7152 Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch));
7153
7154 Assert(0);
7155
7156 hr = pSurf->UnlockRect();
7157 Assert(hr == S_OK);
7158 }
7159 }
7160}
7161
7162void vboxVDbgDoMpPrintAlloc(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
7163{
7164 Assert(pRc->cAllocations > iAlloc);
7165 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
7166 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
7167 BOOL bFrontBuf = FALSE;
7168 if (bPrimary)
7169 {
7170 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
7171 Assert(pSwapchain);
7172 bFrontBuf = (vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc);
7173 }
7174 vboxVDbgDoMpPrintF(pDevice, "%s D3DWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
7175 pAlloc->D3DWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
7176 bPrimary ?
7177 (bFrontBuf ? "Front Buffer" : "Back Buffer")
7178 : "?Everage? Alloc",
7179 pSuffix);
7180}
7181
7182void vboxVDbgDoMpPrintRect(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const RECT *pRect, const char * pSuffix)
7183{
7184 vboxVDbgDoMpPrintF(pDevice, "%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix);
7185}
7186
7187VOID vboxVDbgDoMpPrint(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString)
7188{
7189 uint32_t cbString = strlen(szString) + 1;
7190 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
7191 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
7192 Assert(pCmd);
7193 if (pCmd)
7194 {
7195 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
7196 memcpy(pCmd->aStringBuf, szString, cbString);
7197
7198 D3DDDICB_ESCAPE DdiEscape = {0};
7199 DdiEscape.hContext = NULL;
7200 DdiEscape.hDevice = NULL;
7201 DdiEscape.Flags.Value = 0;
7202 DdiEscape.pPrivateDriverData = pCmd;
7203 DdiEscape.PrivateDriverDataSize = cbCmd;
7204
7205 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
7206 Assert(hr == S_OK);
7207
7208 RTMemFree(pCmd);
7209 }
7210}
7211VOID vboxVDbgDoMpPrintF(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString, ...)
7212{
7213 char szBuffer[4096] = {0};
7214 va_list pArgList;
7215 va_start(pArgList, szString);
7216 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
7217 va_end(pArgList);
7218
7219 if (pDevice)
7220 {
7221 vboxVDbgDoMpPrint(pDevice, szBuffer);
7222 }
7223 else
7224 {
7225 OutputDebugStringA(szBuffer);
7226 }
7227}
7228VOID vboxVDbgDoPrint(LPCSTR szString, ...)
7229{
7230 char szBuffer[1024] = {0};
7231 va_list pArgList;
7232 va_start(pArgList, szString);
7233 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
7234 va_end(pArgList);
7235
7236 OutputDebugStringA(szBuffer);
7237}
7238
7239static PVOID g_VBoxWDbgVEHandler = NULL;
7240LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
7241{
7242 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
7243 PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
7244 switch (pExceptionRecord->ExceptionCode)
7245 {
7246 case 0x40010006: /* <- OutputDebugString exception, ignore */
7247 case 0xe06d7363: /* <- ms compiler - generated exception related to C++ exception */
7248 break;
7249 default:
7250 Assert(0);
7251 break;
7252 }
7253 return EXCEPTION_CONTINUE_SEARCH;
7254}
7255
7256void vboxVDbgVEHandlerRegister()
7257{
7258 Assert(!g_VBoxWDbgVEHandler);
7259 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
7260 Assert(g_VBoxWDbgVEHandler);
7261}
7262
7263void vboxVDbgVEHandlerUnregister()
7264{
7265 Assert(g_VBoxWDbgVEHandler);
7266 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
7267 Assert(uResult);
7268 g_VBoxWDbgVEHandler = NULL;
7269}
7270
7271#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