VirtualBox

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

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

wddm/3d: multi-swapchain fixes

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