VirtualBox

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

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

wddm/3d: multiple swapchain handling (needed for win7 & multi-screen)

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