VirtualBox

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

Last change on this file since 31828 was 31797, checked in by vboxsync, 15 years ago

wddm/3d: multimonitor for fullscreen apps (Aero), shared rc support needed

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 242.7 KB
Line 
1/** @file
2 *
3 * VBoxVideo Display D3D User mode dll
4 *
5 * Copyright (C) 2010 Oracle Corporation
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.virtualbox.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License (GPL) as published by the Free Software
11 * Foundation, in version 2 as it comes in the "COPYING" file of the
12 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14 */
15#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 PVBOXWDDMDISP_RESOURCE vboxResourceAlloc(UINT cAllocs)
859{
860 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_RESOURCE, aAllocations[cAllocs]));
861 Assert(pRc);
862 if (pRc)
863 {
864 pRc->cAllocations = cAllocs;
865 return pRc;
866 }
867 return NULL;
868}
869
870static void vboxWddmLockUnlockMemSynch(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DLOCKED_RECT *pLockInfo, RECT *pRect, bool bToLockInfo)
871{
872 Assert(pAlloc->SurfDesc.pitch);
873 Assert(pAlloc->pvMem);
874
875 if (!pRect)
876 {
877 if (pAlloc->SurfDesc.pitch == pLockInfo->Pitch)
878 {
879 if (bToLockInfo)
880 memcpy(pLockInfo->pBits, pAlloc->pvMem, pAlloc->SurfDesc.pitch * pAlloc->SurfDesc.height);
881 else
882 memcpy(pAlloc->pvMem, pLockInfo->pBits, pAlloc->SurfDesc.pitch * pAlloc->SurfDesc.height);
883 }
884 else
885 {
886 uint8_t *pvSrc, *pvDst;
887 uint32_t srcPitch, dstPitch;
888 if (bToLockInfo)
889 {
890 pvSrc = (uint8_t *)pAlloc->pvMem;
891 pvDst = (uint8_t *)pLockInfo->pBits;
892 srcPitch = pAlloc->SurfDesc.pitch;
893 dstPitch = pLockInfo->Pitch;
894 }
895 else
896 {
897 pvDst = (uint8_t *)pAlloc->pvMem;
898 pvSrc = (uint8_t *)pLockInfo->pBits;
899 dstPitch = pAlloc->SurfDesc.pitch;
900 srcPitch = (uint32_t)pLockInfo->Pitch;
901 }
902
903 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
904 Assert(pitch);
905 for (UINT j = 0; j < pAlloc->SurfDesc.height; ++j)
906 {
907 memcpy(pvDst, pvSrc, pitch);
908 pvSrc += srcPitch;
909 pvDst += dstPitch;
910 }
911 }
912 }
913 else
914 {
915 uint8_t *pvSrc, *pvDst;
916 uint32_t srcPitch, dstPitch;
917 /* @todo: this is not entirely correct */
918 uint8_t * pvAllocMemStart = (uint8_t *)pAlloc->pvMem;
919 uint32_t cbPP = pAlloc->SurfDesc.pitch/pAlloc->SurfDesc.width;
920 pvAllocMemStart += pAlloc->SurfDesc.pitch * pRect->top + pRect->left * cbPP;
921
922 if (bToLockInfo)
923 {
924 pvSrc = (uint8_t *)pvAllocMemStart;
925 pvDst = (uint8_t *)pLockInfo->pBits;
926 srcPitch = pAlloc->SurfDesc.pitch;
927 dstPitch = pLockInfo->Pitch;
928 }
929 else
930 {
931 pvDst = (uint8_t *)pvAllocMemStart;
932 pvSrc = (uint8_t *)pLockInfo->pBits;
933 dstPitch = pAlloc->SurfDesc.pitch;
934 srcPitch = (uint32_t)pLockInfo->Pitch;
935 }
936
937 uint32_t cPixCopyLine = pRect->right - pRect->left;
938
939 if (cPixCopyLine == pAlloc->SurfDesc.width && srcPitch == dstPitch)
940 {
941 memcpy(pvDst, pvSrc, pAlloc->SurfDesc.pitch * (pRect->bottom - pRect->top));
942 }
943 else
944 {
945 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
946 uint32_t cbCopyLine = cPixCopyLine * cbPP;
947 Assert(pitch);
948 for (int j = pRect->top; j < pRect->bottom; ++j)
949 {
950 memcpy(pvDst, pvSrc, cbCopyLine);
951 pvSrc += srcPitch;
952 pvDst += dstPitch;
953 }
954 }
955 }
956}
957
958#if 0
959static HRESULT vboxWddmRectBltPerform(uint8_t *pvDstSurf, const uint8_t *pvSrcSurf,
960 RECT *pDstRect, RECT *pSrcRect,
961 uint32_t DstPitch, uint32_t SrcPitch, uint32_t bpp,
962 RECT *pDstCopyRect, RECT *pSrcCopyRect)
963{
964 uint32_t DstCopyWidth = pDstCopyRect->left - pDstCopyRect->right;
965 uint32_t DstCopyHeight = pDstCopyRect->bottom - pDstCopyRect->top;
966 uint32_t SrcCopyWidth = pSrcCopyRect->left - pSrcCopyRect->right;
967 uint32_t SrcCopyHeight = pSrcCopyRect->bottom - pSrcCopyRect->top;
968 uint32_t srcBpp = bpp;
969 uint32_t dstBpp = bpp;
970 /* we do not support stretching */
971 Assert(DstCopyWidth == SrcCopyWidth);
972 Assert(DstCopyHeight == SrcCopyWidth);
973 if (DstCopyWidth != SrcCopyWidth)
974 return E_FAIL;
975 if (DstCopyHeight != SrcCopyWidth)
976 return E_FAIL;
977
978 uint32_t DstWidth = pDstRect->left - pDstRect->right;
979 uint32_t DstHeight = pDstRect->bottom - pDstRect->top;
980 uint32_t SrcWidth = pSrcRect->left - pSrcRect->right;
981 uint32_t SrcHeight = pSrcRect->bottom - pSrcRect->top;
982
983 if (DstWidth == DstCopyWidth
984 && SrcWidth == SrcCopyWidth
985 && SrcWidth == DstWidth)
986 {
987 Assert(!pDstCopyRect->left);
988 Assert(!pSrcCopyRect->left);
989 uint32_t cbOff = DstPitch * pDstCopyRect->top;
990 uint32_t cbSize = DstPitch * DstCopyHeight;
991 memcpy(pvDstSurf + cbOff, pvSrcSurf + cbOff, cbSize);
992 }
993 else
994 {
995 uint32_t offDstLineStart = pDstCopyRect->left * dstBpp >> 3;
996 uint32_t offDstLineEnd = ((pDstCopyRect->left * dstBpp + 7) >> 3) + ((dstBpp * DstCopyWidth + 7) >> 3);
997 uint32_t cbDstLine = offDstLineEnd - offDstLineStart;
998 uint32_t offDstStart = DstPitch * pDstCopyRect->top + offDstLineStart;
999 Assert(cbDstLine <= DstPitch);
1000 uint32_t cbDstSkip = DstPitch;
1001 uint8_t * pvDstStart = pvDstSurf + offDstStart;
1002
1003 uint32_t offSrcLineStart = pSrcCopyRect->left * srcBpp >> 3;
1004 uint32_t offSrcLineEnd = ((pSrcCopyRect->left * srcBpp + 7) >> 3) + ((srcBpp * SrcCopyWidth + 7) >> 3);
1005 uint32_t cbSrcLine = offSrcLineEnd - offSrcLineStart;
1006 uint32_t offSrcStart = SrcPitch * pSrcCopyRect->top + offSrcLineStart;
1007 Assert(cbSrcLine <= SrcPitch);
1008 uint32_t cbSrcSkip = SrcPitch;
1009 const uint8_t * pvSrcStart = pvSrcSurf + offSrcStart;
1010
1011 Assert(cbDstLine == cbSrcLine);
1012
1013 for (uint32_t i = 0; ; ++i)
1014 {
1015 memcpy (pvDstStart, pvSrcStart, cbDstLine);
1016 if (i == DstCopyHeight)
1017 break;
1018 pvDstStart += cbDstSkip;
1019 pvSrcStart += cbSrcSkip;
1020 }
1021 }
1022 return S_OK;
1023}
1024#endif
1025
1026static HRESULT vboxWddmRectBltPerform(uint8_t *pvDstSurf, const uint8_t *pvSrcSurf,
1027 const RECT *pDstRect, const RECT *pSrcRect,
1028 uint32_t DstPitch, uint32_t SrcPitch, uint32_t bpp)
1029{
1030 uint32_t DstWidth = pDstRect->left - pDstRect->right;
1031 uint32_t DstHeight = pDstRect->bottom - pDstRect->top;
1032 uint32_t SrcWidth = pSrcRect->left - pSrcRect->right;
1033 uint32_t SrcHeight = pSrcRect->bottom - pSrcRect->top;
1034 uint32_t srcBpp = bpp;
1035 uint32_t dstBpp = bpp;
1036 /* we do not support stretching */
1037 Assert(DstWidth == SrcWidth);
1038 Assert(DstHeight == SrcWidth);
1039 if (DstWidth != SrcWidth)
1040 return E_FAIL;
1041 if (DstHeight != SrcWidth)
1042 return E_FAIL;
1043
1044 if (DstPitch == SrcPitch
1045 && ((DstWidth * bpp)/8) == DstPitch)
1046 {
1047 Assert(!pDstRect->left);
1048 Assert(!pSrcRect->left);
1049 uint32_t cbOff = DstPitch * pDstRect->top;
1050 uint32_t cbSize = DstPitch * DstHeight;
1051 memcpy(pvDstSurf + cbOff, pvSrcSurf + cbOff, cbSize);
1052 }
1053 else
1054 {
1055
1056 uint32_t cbDstLine = (((DstWidth * dstBpp) + 7) >> 3);
1057 for (uint32_t i = 0; ; ++i)
1058 {
1059 memcpy (pvDstSurf, pvSrcSurf, cbDstLine);
1060 if (i == DstHeight)
1061 break;
1062 pvDstSurf += DstPitch;
1063 pvSrcSurf += SrcPitch;
1064 }
1065 }
1066 return S_OK;
1067}
1068
1069static HRESULT vboxWddmRenderTargetUpdateSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf)
1070{
1071 if (pAlloc->SurfDesc.VidPnSourceId != pDevice->iPrimaryScreen)
1072 return S_OK;
1073
1074 IDirect3DSurface9 *pD3D9Surf;
1075 IDirect3DDevice9 *pDevice9If = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
1076 HRESULT hr = pDevice9If->GetBackBuffer(0 /*UINT iSwapChain*/,
1077 iBBuf, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
1078 Assert(hr == S_OK);
1079 if (hr == S_OK)
1080 {
1081 Assert(pD3D9Surf);
1082 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
1083 if (pAlloc->pD3DIf)
1084 pAlloc->pD3DIf->Release();
1085 pAlloc->pD3DIf = pD3D9Surf;
1086 }
1087 return hr;
1088}
1089static HRESULT vboxWddmRenderTargetUpdate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB)
1090{
1091 if (pRc->RcDesc.VidPnSourceId != pDevice->iPrimaryScreen)
1092 return S_OK;
1093
1094 PVBOXWDDMDISP_ALLOCATION pAlloc;
1095 UINT iBBuf = 0;
1096 Assert(iNewRTFB < pRc->cAllocations);
1097
1098 for (UINT i = 1; i < pRc->cAllocations; ++i, ++iBBuf)
1099 {
1100 UINT iAlloc = (iNewRTFB + i) % pRc->cAllocations;
1101 Assert(iAlloc != iNewRTFB);
1102 pAlloc = &pRc->aAllocations[iAlloc];
1103 HRESULT tmpHr = vboxWddmRenderTargetUpdateSurface(pDevice, pAlloc, iBBuf);
1104 Assert(tmpHr == S_OK);
1105 }
1106
1107 pAlloc = &pRc->aAllocations[iNewRTFB];
1108#ifdef VBOXWDDM_WITH_VISIBLE_FB
1109 HRESULT tmpHr = vboxWddmRenderTargetUpdateSurface(pDevice, pAlloc, ~0UL /* <- for the frontbuffer */);
1110 Assert(tmpHr == S_OK);
1111#else
1112 if (pAlloc->pD3DIf)
1113 {
1114 pAlloc->pD3DIf->Release();
1115 pAlloc->pD3DIf = NULL;
1116 }
1117#endif
1118
1119#ifdef DEBUG
1120 for (UINT i = 0; i < pRc->cAllocations; ++i)
1121 {
1122 pAlloc = &pRc->aAllocations[i];
1123 if (iNewRTFB == i)
1124 {
1125 Assert(!pAlloc->pD3DIf);
1126 }
1127
1128 for (UINT j = i+1; j < pRc->cAllocations; ++j)
1129 {
1130 PVBOXWDDMDISP_ALLOCATION pAllocJ = &pRc->aAllocations[j];
1131 Assert(pAlloc->pD3DIf != pAllocJ->pD3DIf);
1132 }
1133 }
1134#endif
1135 return S_OK;
1136}
1137
1138#ifdef DEBUG
1139static void vboxWddmDbgRenderTargetUpdateCheckSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf)
1140{
1141 IDirect3DSurface9 *pD3D9Surf;
1142 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
1143 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
1144 Assert(pScreen->hWnd);
1145 Assert(pScreen->pDevice9If);
1146 HRESULT hr = pScreen->pDevice9If->GetBackBuffer(0 /*UINT iSwapChain*/,
1147 iBBuf, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
1148 Assert(hr == S_OK);
1149 if (hr == S_OK)
1150 {
1151 Assert(pD3D9Surf);
1152 Assert(pD3D9Surf == pAlloc->pD3DIf);
1153 pD3D9Surf->Release();
1154 }
1155}
1156
1157static void vboxWddmDbgRenderTargetCheck(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB)
1158{
1159 PVBOXWDDMDISP_ALLOCATION pAlloc;
1160 UINT iBBuf = 0;
1161 Assert(iNewRTFB < pRc->cAllocations);
1162
1163 for (UINT i = 1; i < pRc->cAllocations; ++i, ++iBBuf)
1164 {
1165 UINT iAlloc = (iNewRTFB + i) % pRc->cAllocations;
1166 Assert(iAlloc != iNewRTFB);
1167 pAlloc = &pRc->aAllocations[iAlloc];
1168 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, iBBuf);
1169 }
1170
1171 pAlloc = &pRc->aAllocations[iNewRTFB];
1172#ifdef VBOXWDDM_WITH_VISIBLE_FB
1173 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, ~0UL /* <- for the frontbuffer */);
1174#else
1175 Assert(pAlloc->pD3DIf == NULL);
1176#endif
1177
1178 for (UINT i = 0; i < pRc->cAllocations; ++i)
1179 {
1180 pAlloc = &pRc->aAllocations[i];
1181 if (iNewRTFB == i)
1182 {
1183 Assert(!pAlloc->pD3DIf);
1184 }
1185
1186 for (UINT j = i+1; j < pRc->cAllocations; ++j)
1187 {
1188 PVBOXWDDMDISP_ALLOCATION pAllocJ = &pRc->aAllocations[j];
1189 Assert(pAlloc->pD3DIf != pAllocJ->pD3DIf);
1190 }
1191 }
1192}
1193
1194# define VBOXVDBG_RTGT_STATECHECK(_pDev) (vboxWddmDbgRenderTargetCheck((_pDev), (_pDev)->aScreens[(_pDev)->iPrimaryScreen].pRenderTargetRc, (_pDev)->aScreens[(_pDev)->iPrimaryScreen].iRenderTargetFrontBuf))
1195#else
1196# define VBOXVDBG_RTGT_STATECHECK(_pDev) do{}while(0)
1197#endif
1198
1199static D3DFORMAT vboxDDI2D3DFormat(D3DDDIFORMAT format)
1200{
1201 /* @todo: check they are all equal */
1202 return (D3DFORMAT)format;
1203}
1204
1205D3DMULTISAMPLE_TYPE vboxDDI2D3DMultiSampleType(D3DDDIMULTISAMPLE_TYPE enmType)
1206{
1207 /* @todo: check they are all equal */
1208 return (D3DMULTISAMPLE_TYPE)enmType;
1209}
1210
1211D3DPOOL vboxDDI2D3DPool(D3DDDI_POOL enmPool)
1212{
1213 /* @todo: check they are all equal */
1214 switch (enmPool)
1215 {
1216 case D3DDDIPOOL_SYSTEMMEM:
1217 return D3DPOOL_SYSTEMMEM;
1218 case D3DDDIPOOL_VIDEOMEMORY:
1219 case D3DDDIPOOL_LOCALVIDMEM:
1220 case D3DDDIPOOL_NONLOCALVIDMEM:
1221 /* @todo: what would be propper here? */
1222 return D3DPOOL_DEFAULT;
1223 default:
1224 Assert(0);
1225 }
1226 return D3DPOOL_DEFAULT;
1227}
1228
1229D3DRENDERSTATETYPE vboxDDI2D3DRenderStateType(D3DDDIRENDERSTATETYPE enmType)
1230{
1231 /* @todo: @fixme: not entirely correct, need to check */
1232 return (D3DRENDERSTATETYPE)enmType;
1233}
1234
1235VBOXWDDMDISP_TSS_LOOKUP vboxDDI2D3DTestureStageStateType(D3DDDITEXTURESTAGESTATETYPE enmType)
1236{
1237 static const VBOXWDDMDISP_TSS_LOOKUP lookup[] =
1238 {
1239 {FALSE, D3DTSS_FORCE_DWORD}, /* 0, D3DDDITSS_TEXTUREMAP */
1240 {FALSE, D3DTSS_COLOROP}, /* 1, D3DDDITSS_COLOROP */
1241 {FALSE, D3DTSS_COLORARG1}, /* 2, D3DDDITSS_COLORARG1 */
1242 {FALSE, D3DTSS_COLORARG2}, /* 3, D3DDDITSS_COLORARG2 */
1243 {FALSE, D3DTSS_ALPHAOP}, /* 4, D3DDDITSS_ALPHAOP */
1244 {FALSE, D3DTSS_ALPHAARG1}, /* 5, D3DDDITSS_ALPHAARG1 */
1245 {FALSE, D3DTSS_ALPHAARG2}, /* 6, D3DDDITSS_ALPHAARG2 */
1246 {FALSE, D3DTSS_BUMPENVMAT00}, /* 7, D3DDDITSS_BUMPENVMAT00 */
1247 {FALSE, D3DTSS_BUMPENVMAT01}, /* 8, D3DDDITSS_BUMPENVMAT01 */
1248 {FALSE, D3DTSS_BUMPENVMAT10}, /* 9, D3DDDITSS_BUMPENVMAT10 */
1249 {FALSE, D3DTSS_BUMPENVMAT11}, /* 10, D3DDDITSS_BUMPENVMAT11 */
1250 {FALSE, D3DTSS_TEXCOORDINDEX}, /* 11, D3DDDITSS_TEXCOORDINDEX */
1251 {FALSE, D3DTSS_FORCE_DWORD}, /* 12, unused */
1252 {TRUE, D3DSAMP_ADDRESSU}, /* 13, D3DDDITSS_ADDRESSU */
1253 {TRUE, D3DSAMP_ADDRESSV}, /* 14, D3DDDITSS_ADDRESSV */
1254 {TRUE, D3DSAMP_BORDERCOLOR}, /* 15, D3DDDITSS_BORDERCOLOR */
1255 {TRUE, D3DSAMP_MAGFILTER}, /* 16, D3DDDITSS_MAGFILTER */
1256 {TRUE, D3DSAMP_MINFILTER}, /* 17, D3DDDITSS_MINFILTER */
1257 {TRUE, D3DSAMP_MIPFILTER}, /* 18, D3DDDITSS_MIPFILTER */
1258 {TRUE, D3DSAMP_MIPMAPLODBIAS}, /* 19, D3DDDITSS_MIPMAPLODBIAS */
1259 {TRUE, D3DSAMP_MAXMIPLEVEL}, /* 20, D3DDDITSS_MAXMIPLEVEL */
1260 {TRUE, D3DSAMP_MAXANISOTROPY}, /* 21, D3DDDITSS_MAXANISOTROPY */
1261 {FALSE, D3DTSS_BUMPENVLSCALE}, /* 22, D3DDDITSS_BUMPENVLSCALE */
1262 {FALSE, D3DTSS_BUMPENVLOFFSET}, /* 23, D3DDDITSS_BUMPENVLOFFSET */
1263 {FALSE, D3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DDDITSS_TEXTURETRANSFORMFLAGS */
1264 {TRUE, D3DSAMP_ADDRESSW}, /* 25, D3DDDITSS_ADDRESSW */
1265 {FALSE, D3DTSS_COLORARG0}, /* 26, D3DDDITSS_COLORARG0 */
1266 {FALSE, D3DTSS_ALPHAARG0}, /* 27, D3DDDITSS_ALPHAARG0 */
1267 {FALSE, D3DTSS_RESULTARG}, /* 28, D3DDDITSS_RESULTARG */
1268 {TRUE, D3DSAMP_SRGBTEXTURE}, /* 29, D3DDDITSS_SRGBTEXTURE */
1269 {TRUE, D3DSAMP_ELEMENTINDEX}, /* 30, D3DDDITSS_ELEMENTINDEX */
1270 {TRUE, D3DSAMP_DMAPOFFSET}, /* 31, D3DDDITSS_DMAPOFFSET */
1271 {FALSE, D3DTSS_CONSTANT}, /* 32, D3DDDITSS_CONSTANT */
1272 {FALSE, D3DTSS_FORCE_DWORD}, /* 33, D3DDDITSS_DISABLETEXTURECOLORKEY */
1273 {FALSE, D3DTSS_FORCE_DWORD}, /* 34, D3DDDITSS_TEXTURECOLORKEYVAL */
1274 };
1275
1276 Assert(enmType > 0);
1277 Assert(enmType < RT_ELEMENTS(lookup));
1278 Assert(lookup[enmType].dType != D3DTSS_FORCE_DWORD);
1279
1280 return lookup[enmType];
1281}
1282
1283DWORD vboxDDI2D3DUsage(D3DDDI_RESOURCEFLAGS fFlags)
1284{
1285 DWORD fUsage = 0;
1286 if (fFlags.Dynamic)
1287 fUsage |= D3DUSAGE_DYNAMIC;
1288 if (fFlags.AutogenMipmap)
1289 fUsage |= D3DUSAGE_AUTOGENMIPMAP;
1290 if (fFlags.DMap)
1291 fUsage |= D3DUSAGE_DMAP;
1292 if (fFlags.WriteOnly)
1293 fUsage |= D3DUSAGE_WRITEONLY;
1294 if (fFlags.NPatches)
1295 fUsage |= D3DUSAGE_NPATCHES;
1296 if (fFlags.Points)
1297 fUsage |= D3DUSAGE_POINTS;
1298 if (fFlags.RenderTarget)
1299 fUsage |= D3DUSAGE_RENDERTARGET;
1300 if (fFlags.RtPatches)
1301 fUsage |= D3DUSAGE_RTPATCHES;
1302 if (fFlags.TextApi)
1303 fUsage |= D3DUSAGE_TEXTAPI;
1304 if (fFlags.WriteOnly)
1305 fUsage |= D3DUSAGE_WRITEONLY;
1306 //below are wddm 1.1-specific
1307// if (fFlags.RestrictedContent)
1308// fUsage |= D3DUSAGE_RESTRICTED_CONTENT;
1309// if (fFlags.RestrictSharedAccess)
1310// fUsage |= D3DUSAGE_RESTRICT_SHARED_RESOURCE;
1311 return fUsage;
1312}
1313
1314DWORD vboxDDI2D3DLockFlags(D3DDDI_LOCKFLAGS fLockFlags)
1315{
1316 DWORD fFlags = 0;
1317 if (fLockFlags.Discard)
1318 fFlags |= D3DLOCK_DISCARD;
1319 if (fLockFlags.NoOverwrite)
1320 fFlags |= D3DLOCK_NOOVERWRITE;
1321 if (fLockFlags.ReadOnly)
1322 fFlags |= D3DLOCK_READONLY;
1323 if (fLockFlags.DoNotWait)
1324 fFlags |= D3DLOCK_DONOTWAIT;
1325 return fFlags;
1326}
1327
1328D3DTEXTUREFILTERTYPE vboxDDI2D3DBltFlags(D3DDDI_BLTFLAGS fFlags)
1329{
1330 if (fFlags.Point)
1331 {
1332 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
1333 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 1);
1334 return D3DTEXF_POINT;
1335 }
1336 if (fFlags.Linear)
1337 {
1338 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
1339 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 2);
1340 return D3DTEXF_LINEAR;
1341 }
1342 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
1343 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 0);
1344 return D3DTEXF_NONE;
1345}
1346
1347static void vboxResourceFree(PVBOXWDDMDISP_RESOURCE pRc)
1348{
1349 RTMemFree(pRc);
1350}
1351
1352/**
1353 * DLL entry point.
1354 */
1355BOOL WINAPI DllMain(HINSTANCE hInstance,
1356 DWORD dwReason,
1357 LPVOID lpReserved)
1358{
1359 switch (dwReason)
1360 {
1361 case DLL_PROCESS_ATTACH:
1362 {
1363 vboxVDbgPrint(("VBoxDispD3D: DLL loaded.\n"));
1364#ifdef VBOXWDDMDISP_DEBUG
1365 vboxVDbgVEHandlerRegister();
1366#endif
1367 RTR3Init();
1368
1369 HRESULT hr = vboxDispCmInit();
1370 Assert(hr == S_OK);
1371 if (hr == S_OK)
1372 {
1373#ifdef VBOXDISPMP_TEST
1374 hr = vboxDispMpTstStart();
1375 Assert(hr == S_OK);
1376 if (hr == S_OK)
1377#endif
1378 {
1379 hr = VBoxScreenMRunnerStart(&g_VBoxScreenMonRunner);
1380 Assert(hr == S_OK);
1381 /* succeed in any way */
1382 hr = S_OK;
1383 if (hr == S_OK)
1384 {
1385 vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n"));
1386 return TRUE;
1387 }
1388#ifdef VBOXDISPMP_TEST
1389 vboxDispMpTstStop();
1390#endif
1391 }
1392 vboxDispCmTerm();
1393 }
1394// VbglR3Init();
1395 break;
1396 }
1397
1398 case DLL_PROCESS_DETACH:
1399 {
1400#ifdef VBOXWDDMDISP_DEBUG
1401 vboxVDbgVEHandlerUnregister();
1402#endif
1403 HRESULT hr = VBoxScreenMRunnerStop(&g_VBoxScreenMonRunner);
1404 Assert(hr == S_OK);
1405 if (hr == S_OK)
1406 {
1407#ifdef VBOXDISPMP_TEST
1408 hr = vboxDispMpTstStop();
1409 Assert(hr == S_OK);
1410 if (hr == S_OK)
1411#endif
1412 {
1413 hr = vboxDispCmTerm();
1414 Assert(hr == S_OK);
1415 if (hr == S_OK)
1416 {
1417 vboxVDbgPrint(("VBoxDispD3D: DLL unloaded.\n"));
1418 return TRUE;
1419 }
1420 }
1421 }
1422// VbglR3Term();
1423 /// @todo RTR3Term();
1424 break;
1425 }
1426
1427 default:
1428 return TRUE;
1429 }
1430 return FALSE;
1431}
1432
1433static HRESULT vboxWddmGetD3D9Caps(PVBOXWDDMDISP_ADAPTER pAdapter, D3DCAPS9 *pCaps)
1434{
1435 HRESULT hr = pAdapter->pD3D9If->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pCaps);
1436 Assert(hr == S_OK);
1437 if (hr == S_OK)
1438 {
1439 pCaps->Caps2 |= D3DCAPS2_CANSHARERESOURCE | 0x00080000 /*D3DCAPS2_CANRENDERWINDOWED*/;
1440 pCaps->DevCaps |= D3DDEVCAPS_FLOATTLVERTEX /* <- must be set according to the docs */
1441 /*| D3DDEVCAPS_HWVERTEXBUFFER | D3DDEVCAPS_HWINDEXBUFFER | D3DDEVCAPS_SUBVOLUMELOCK */;
1442 pCaps->PrimitiveMiscCaps |= D3DPMISCCAPS_INDEPENDENTWRITEMASKS
1443 | D3DPMISCCAPS_FOGINFVF
1444 | D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS;
1445 pCaps->RasterCaps |= D3DPRASTERCAPS_SUBPIXEL | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_COLORPERSPECTIVE /* keep */;
1446 pCaps->TextureCaps |= D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE;
1447 pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
1448 pCaps->VolumeTextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
1449 pCaps->GuardBandLeft = -8192.;
1450 pCaps->GuardBandTop = -8192.;
1451 pCaps->GuardBandRight = 8192.;
1452 pCaps->GuardBandBottom = 8192.;
1453 pCaps->StencilCaps |= D3DSTENCILCAPS_TWOSIDED;
1454 pCaps->DeclTypes |= D3DDTCAPS_FLOAT16_2 | D3DDTCAPS_FLOAT16_4;
1455 pCaps->VS20Caps.DynamicFlowControlDepth = 24;
1456 pCaps->VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
1457 pCaps->PS20Caps.DynamicFlowControlDepth = 24;
1458 pCaps->PS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
1459 pCaps->VertexTextureFilterCaps |= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MAGFPOINT;
1460#if 1 /* workaround for wine not returning InstructionSlots correctly for shaders v3.0 */
1461 if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
1462 {
1463 pCaps->MaxVertexShader30InstructionSlots = RT_MIN(32768, pCaps->MaxVertexShader30InstructionSlots);
1464 pCaps->MaxPixelShader30InstructionSlots = RT_MIN(32768, pCaps->MaxPixelShader30InstructionSlots);
1465 }
1466#endif
1467#ifdef DEBUG
1468 if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
1469 {
1470 Assert(pCaps->MaxVertexShader30InstructionSlots >= 512);
1471 Assert(pCaps->MaxVertexShader30InstructionSlots <= 32768);
1472 Assert(pCaps->MaxPixelShader30InstructionSlots >= 512);
1473 Assert(pCaps->MaxPixelShader30InstructionSlots <= 32768);
1474 }
1475 else if ((pCaps->VertexShaderVersion & 0xff00) == 0x0200)
1476 {
1477 Assert(pCaps->MaxVertexShader30InstructionSlots == 0);
1478 Assert(pCaps->MaxPixelShader30InstructionSlots == 0);
1479 }
1480 else
1481 {
1482 Assert(0);
1483 }
1484#endif
1485 }
1486
1487 return hr;
1488}
1489
1490static HRESULT APIENTRY vboxWddmDispGetCaps (HANDLE hAdapter, CONST D3DDDIARG_GETCAPS* pData)
1491{
1492 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
1493
1494 HRESULT hr = S_OK;
1495 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
1496
1497 switch (pData->Type)
1498 {
1499 case D3DDDICAPS_DDRAW:
1500 {
1501 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
1502 Assert(pData->DataSize == sizeof (DDRAW_CAPS));
1503 if (pData->DataSize >= sizeof (DDRAW_CAPS))
1504 {
1505 memset(pData->pData, 0, sizeof (DDRAW_CAPS));
1506#ifdef VBOX_WITH_VIDEOHWACCEL
1507 if (vboxVhwaHasCKeying(pAdapter))
1508 {
1509 DDRAW_CAPS *pCaps = (DDRAW_CAPS*)pData->pData;
1510 pCaps->Caps |= DDRAW_CAPS_COLORKEY;
1511// pCaps->Caps2 |= DDRAW_CAPS2_FLIPNOVSYNC;
1512 }
1513#endif
1514 }
1515 else
1516 hr = E_INVALIDARG;
1517 break;
1518 }
1519 case D3DDDICAPS_DDRAW_MODE_SPECIFIC:
1520 {
1521 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
1522 Assert(pData->DataSize == sizeof (DDRAW_MODE_SPECIFIC_CAPS));
1523 if (pData->DataSize >= sizeof (DDRAW_MODE_SPECIFIC_CAPS))
1524 {
1525 DDRAW_MODE_SPECIFIC_CAPS * pCaps = (DDRAW_MODE_SPECIFIC_CAPS*)pData->pData;
1526 memset(&pCaps->Caps /* do not cleanup the first "Head" field,
1527 zero starting with the one following "Head", i.e. Caps */,
1528 0, sizeof (DDRAW_MODE_SPECIFIC_CAPS) - RT_OFFSETOF(DDRAW_MODE_SPECIFIC_CAPS, Caps));
1529#ifdef VBOX_WITH_VIDEOHWACCEL
1530 VBOXVHWA_INFO *pSettings = &pAdapter->aHeads[pCaps->Head].Vhwa.Settings;
1531 if (pSettings->fFlags & VBOXVHWA_F_ENABLED)
1532 {
1533 pCaps->Caps |= MODE_CAPS_OVERLAY | MODE_CAPS_OVERLAYSTRETCH;
1534
1535 if (pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
1536 {
1537 pCaps->CKeyCaps |= MODE_CKEYCAPS_DESTOVERLAY
1538 | MODE_CKEYCAPS_DESTOVERLAYYUV /* ?? */
1539 ;
1540 }
1541
1542 if (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC)
1543 {
1544 pCaps->CKeyCaps |= MODE_CKEYCAPS_SRCOVERLAY
1545 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACE /* ?? */
1546 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACEYUV /* ?? */
1547 | MODE_CKEYCAPS_SRCOVERLAYYUV /* ?? */
1548 ;
1549 }
1550
1551 pCaps->FxCaps = MODE_FXCAPS_OVERLAYSHRINKX
1552 | MODE_FXCAPS_OVERLAYSHRINKY
1553 | MODE_FXCAPS_OVERLAYSTRETCHX
1554 | MODE_FXCAPS_OVERLAYSTRETCHY;
1555
1556
1557 pCaps->MaxVisibleOverlays = pSettings->cOverlaysSupported;
1558 pCaps->MinOverlayStretch = 1;
1559 pCaps->MaxOverlayStretch = 32000;
1560 }
1561#endif
1562 }
1563 else
1564 hr = E_INVALIDARG;
1565 break;
1566 }
1567 case D3DDDICAPS_GETFORMATCOUNT:
1568 *((uint32_t*)pData->pData) = pAdapter->cFormstOps;
1569 break;
1570 case D3DDDICAPS_GETFORMATDATA:
1571 Assert(pData->DataSize == pAdapter->cFormstOps * sizeof (FORMATOP));
1572 memcpy(pData->pData, pAdapter->paFormstOps, pAdapter->cFormstOps * sizeof (FORMATOP));
1573 break;
1574 case D3DDDICAPS_GETD3DQUERYCOUNT:
1575#if 0
1576 *((uint32_t*)pData->pData) = VBOX_QUERYTYPE_COUNT();
1577#else
1578 *((uint32_t*)pData->pData) = 0;
1579#endif
1580 break;
1581 case D3DDDICAPS_GETD3DQUERYDATA:
1582#if 0
1583 Assert(pData->DataSize == VBOX_QUERYTYPE_COUNT() * sizeof (D3DDDIQUERYTYPE));
1584 memcpy(pData->pData, gVBoxQueryTypes, VBOX_QUERYTYPE_COUNT() * sizeof (D3DDDIQUERYTYPE));
1585#else
1586 Assert(0);
1587 memset(pData->pData, 0, pData->DataSize);
1588#endif
1589 break;
1590 case D3DDDICAPS_GETD3D3CAPS:
1591 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
1592 Assert(pData->DataSize == sizeof (D3DHAL_GLOBALDRIVERDATA));
1593 if (pData->DataSize >= sizeof (D3DHAL_GLOBALDRIVERDATA))
1594 {
1595 D3DHAL_GLOBALDRIVERDATA *pCaps = (D3DHAL_GLOBALDRIVERDATA *)pData->pData;
1596 memset (pCaps, 0, sizeof (D3DHAL_GLOBALDRIVERDATA));
1597 pCaps->dwSize = sizeof (D3DHAL_GLOBALDRIVERDATA);
1598 pCaps->hwCaps.dwSize = sizeof (D3DDEVICEDESC_V1);
1599 pCaps->hwCaps.dwFlags = D3DDD_COLORMODEL
1600 | D3DDD_DEVCAPS
1601 | D3DDD_DEVICERENDERBITDEPTH;
1602
1603 pCaps->hwCaps.dcmColorModel = D3DCOLOR_RGB;
1604 pCaps->hwCaps.dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP
1605// | D3DDEVCAPS_DRAWPRIMTLVERTEX
1606 | D3DDEVCAPS_EXECUTESYSTEMMEMORY
1607 | D3DDEVCAPS_EXECUTEVIDEOMEMORY
1608// | D3DDEVCAPS_FLOATTLVERTEX
1609 | D3DDEVCAPS_HWRASTERIZATION
1610// | D3DDEVCAPS_HWTRANSFORMANDLIGHT
1611// | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY
1612// | D3DDEVCAPS_TEXTUREVIDEOMEMORY
1613 ;
1614 pCaps->hwCaps.dtcTransformCaps.dwSize = sizeof (D3DTRANSFORMCAPS);
1615 pCaps->hwCaps.dtcTransformCaps.dwCaps = 0;
1616 pCaps->hwCaps.bClipping = FALSE;
1617 pCaps->hwCaps.dlcLightingCaps.dwSize = sizeof (D3DLIGHTINGCAPS);
1618 pCaps->hwCaps.dlcLightingCaps.dwCaps = 0;
1619 pCaps->hwCaps.dlcLightingCaps.dwLightingModel = 0;
1620 pCaps->hwCaps.dlcLightingCaps.dwNumLights = 0;
1621 pCaps->hwCaps.dpcLineCaps.dwSize = sizeof (D3DPRIMCAPS);
1622 pCaps->hwCaps.dpcLineCaps.dwMiscCaps = 0;
1623 pCaps->hwCaps.dpcLineCaps.dwRasterCaps = 0;
1624 pCaps->hwCaps.dpcLineCaps.dwZCmpCaps = 0;
1625 pCaps->hwCaps.dpcLineCaps.dwSrcBlendCaps = 0;
1626 pCaps->hwCaps.dpcLineCaps.dwDestBlendCaps = 0;
1627 pCaps->hwCaps.dpcLineCaps.dwAlphaCmpCaps = 0;
1628 pCaps->hwCaps.dpcLineCaps.dwShadeCaps = 0;
1629 pCaps->hwCaps.dpcLineCaps.dwTextureCaps = 0;
1630 pCaps->hwCaps.dpcLineCaps.dwTextureFilterCaps = 0;
1631 pCaps->hwCaps.dpcLineCaps.dwTextureBlendCaps = 0;
1632 pCaps->hwCaps.dpcLineCaps.dwTextureAddressCaps = 0;
1633 pCaps->hwCaps.dpcLineCaps.dwStippleWidth = 0;
1634 pCaps->hwCaps.dpcLineCaps.dwStippleHeight = 0;
1635
1636 pCaps->hwCaps.dpcTriCaps.dwSize = sizeof (D3DPRIMCAPS);
1637 pCaps->hwCaps.dpcTriCaps.dwMiscCaps = 0;
1638 pCaps->hwCaps.dpcTriCaps.dwRasterCaps = 0;
1639 pCaps->hwCaps.dpcTriCaps.dwZCmpCaps = 0;
1640 pCaps->hwCaps.dpcTriCaps.dwSrcBlendCaps = 0;
1641 pCaps->hwCaps.dpcTriCaps.dwDestBlendCaps = 0;
1642 pCaps->hwCaps.dpcTriCaps.dwAlphaCmpCaps = 0;
1643 pCaps->hwCaps.dpcTriCaps.dwShadeCaps = 0;
1644 pCaps->hwCaps.dpcTriCaps.dwTextureCaps = 0;
1645 pCaps->hwCaps.dpcTriCaps.dwTextureFilterCaps = 0;
1646 pCaps->hwCaps.dpcTriCaps.dwTextureBlendCaps = 0;
1647 pCaps->hwCaps.dpcTriCaps.dwTextureAddressCaps = 0;
1648 pCaps->hwCaps.dpcTriCaps.dwStippleWidth = 0;
1649 pCaps->hwCaps.dpcTriCaps.dwStippleHeight = 0;
1650 pCaps->hwCaps.dwDeviceRenderBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32;
1651 pCaps->hwCaps.dwDeviceZBufferBitDepth = 0;
1652 pCaps->hwCaps.dwMaxBufferSize = 0;
1653 pCaps->hwCaps.dwMaxVertexCount = 0;
1654
1655
1656 pCaps->dwNumVertices = 0;
1657 pCaps->dwNumClipVertices = 0;
1658 pCaps->dwNumTextureFormats = 0;//pAdapter->cSurfDescs;
1659 pCaps->lpTextureFormats = NULL;//pAdapter->paSurfDescs;
1660 }
1661 else
1662 hr = E_INVALIDARG;
1663 break;
1664 case D3DDDICAPS_GETD3D7CAPS:
1665 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
1666 Assert(pData->DataSize == sizeof (D3DHAL_D3DEXTENDEDCAPS));
1667 if (pData->DataSize >= sizeof (D3DHAL_D3DEXTENDEDCAPS))
1668 {
1669 memset(pData->pData, 0, sizeof (D3DHAL_D3DEXTENDEDCAPS));
1670 D3DHAL_D3DEXTENDEDCAPS *pCaps = (D3DHAL_D3DEXTENDEDCAPS*)pData->pData;
1671 pCaps->dwSize = sizeof (D3DHAL_D3DEXTENDEDCAPS);
1672 }
1673 else
1674 hr = E_INVALIDARG;
1675 break;
1676 case D3DDDICAPS_GETD3D9CAPS:
1677 {
1678 Assert(pData->DataSize == sizeof (D3DCAPS9));
1679// Assert(0);
1680 if (pData->DataSize >= sizeof (D3DCAPS9))
1681 {
1682 Assert(VBOXDISPMODE_IS_3D(pAdapter));
1683 if (VBOXDISPMODE_IS_3D(pAdapter))
1684 {
1685 D3DCAPS9* pCaps = (D3DCAPS9*)pData->pData;
1686 hr = vboxWddmGetD3D9Caps(pAdapter, pCaps);
1687 Assert(hr == S_OK);
1688 if (hr == S_OK)
1689 break;
1690
1691 vboxVDbgPrintR((__FUNCTION__": GetDeviceCaps Failed hr(%d)\n", hr));
1692 /* let's fall back to the 3D disabled case */
1693 hr = S_OK;
1694 }
1695
1696 memset(pData->pData, 0, sizeof (D3DCAPS9));
1697 }
1698 else
1699 hr = E_INVALIDARG;
1700 break;
1701 }
1702 case D3DDDICAPS_GETD3D8CAPS:
1703 {
1704 Assert(pData->DataSize == RT_OFFSETOF(D3DCAPS9, DevCaps2));
1705 if (pData->DataSize == RT_OFFSETOF(D3DCAPS9, DevCaps2))
1706 {
1707 Assert(VBOXDISPMODE_IS_3D(pAdapter));
1708 if (VBOXDISPMODE_IS_3D(pAdapter))
1709 {
1710 D3DCAPS9 Caps9;
1711 hr = vboxWddmGetD3D9Caps(pAdapter, &Caps9);
1712 Assert(hr == S_OK);
1713 if (hr == S_OK)
1714 {
1715 memcpy(pData->pData, &Caps9, RT_OFFSETOF(D3DCAPS9, DevCaps2));
1716 break;
1717 }
1718
1719 vboxVDbgPrintR((__FUNCTION__": GetDeviceCaps Failed hr(%d)\n", hr));
1720 /* let's fall back to the 3D disabled case */
1721 hr = S_OK;
1722 }
1723
1724 }
1725 else
1726 hr = E_INVALIDARG;
1727 break;
1728 }
1729 case D3DDDICAPS_GETGAMMARAMPCAPS:
1730 *((uint32_t*)pData->pData) = 0;
1731 break;
1732 case D3DDDICAPS_GETVIDEOPROCESSORCAPS:
1733 case D3DDDICAPS_GETEXTENSIONGUIDCOUNT:
1734 case D3DDDICAPS_GETDECODEGUIDCOUNT:
1735 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDCOUNT:
1736 if (pData->pData && pData->DataSize)
1737 memset(pData->pData, 0, pData->DataSize);
1738 break;
1739 case D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS:
1740 case D3DDDICAPS_GETD3D5CAPS:
1741 case D3DDDICAPS_GETD3D6CAPS:
1742 case D3DDDICAPS_GETDECODEGUIDS:
1743 case D3DDDICAPS_GETDECODERTFORMATCOUNT:
1744 case D3DDDICAPS_GETDECODERTFORMATS:
1745 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFOCOUNT:
1746 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFO:
1747 case D3DDDICAPS_GETDECODECONFIGURATIONCOUNT:
1748 case D3DDDICAPS_GETDECODECONFIGURATIONS:
1749 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDS:
1750 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATCOUNT:
1751 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATS:
1752 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT:
1753 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS:
1754 case D3DDDICAPS_GETPROCAMPRANGE:
1755 case D3DDDICAPS_FILTERPROPERTYRANGE:
1756 case D3DDDICAPS_GETEXTENSIONGUIDS:
1757 case D3DDDICAPS_GETEXTENSIONCAPS:
1758 vboxVDbgPrint((__FUNCTION__": unimplemented caps type(%d)\n", pData->Type));
1759 Assert(0);
1760 if (pData->pData && pData->DataSize)
1761 memset(pData->pData, 0, pData->DataSize);
1762 break;
1763 default:
1764 vboxVDbgPrint((__FUNCTION__": unknown caps type(%d)\n", pData->Type));
1765 Assert(0);
1766 }
1767
1768 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
1769
1770 return S_OK;
1771}
1772
1773static HRESULT APIENTRY vboxWddmDDevSetRenderState(HANDLE hDevice, CONST D3DDDIARG_RENDERSTATE* pData)
1774{
1775 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1776 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1777 Assert(pDevice);
1778 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
1779 Assert(pScreen->hWnd);
1780 Assert(pScreen->pDevice9If);
1781 HRESULT hr = pScreen->pDevice9If->SetRenderState(vboxDDI2D3DRenderStateType(pData->State), pData->Value);
1782 Assert(hr == S_OK);
1783 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1784 return hr;
1785}
1786
1787static HRESULT APIENTRY vboxWddmDDevUpdateWInfo(HANDLE hDevice, CONST D3DDDIARG_WINFO* pData)
1788{
1789 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1790 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1791 return S_OK;
1792}
1793
1794static HRESULT APIENTRY vboxWddmDDevValidateDevice(HANDLE hDevice, D3DDDIARG_VALIDATETEXTURESTAGESTATE* pData)
1795{
1796 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1797 Assert(0);
1798 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1799 return E_FAIL;
1800}
1801
1802static HRESULT APIENTRY vboxWddmDDevSetTextureStageState(HANDLE hDevice, CONST D3DDDIARG_TEXTURESTAGESTATE* pData)
1803{
1804 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1805 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1806 Assert(pDevice);
1807 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
1808 Assert(pScreen->hWnd);
1809 Assert(pScreen->pDevice9If);
1810
1811 VBOXWDDMDISP_TSS_LOOKUP lookup = vboxDDI2D3DTestureStageStateType(pData->State);
1812 HRESULT hr;
1813
1814 if (!lookup.bSamplerState)
1815 {
1816 hr = pScreen->pDevice9If->SetTextureStageState(pData->Stage, D3DTEXTURESTAGESTATETYPE(lookup.dType), pData->Value);
1817 }
1818 else
1819 {
1820 hr = pScreen->pDevice9If->SetSamplerState(pData->Stage, D3DSAMPLERSTATETYPE(lookup.dType), pData->Value);
1821 }
1822
1823 Assert(hr == S_OK);
1824 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1825 return hr;
1826}
1827
1828static HRESULT APIENTRY vboxWddmDDevSetTexture(HANDLE hDevice, UINT Stage, HANDLE hTexture)
1829{
1830 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1831 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1832 Assert(pDevice);
1833 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
1834 Assert(pScreen->hWnd);
1835 Assert(pScreen->pDevice9If);
1836 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hTexture;
1837// Assert(pRc);
1838 IDirect3DTexture9 *pD3DIfTex;
1839 if (pRc)
1840 {
1841 Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE);
1842 pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
1843 }
1844 else
1845 pD3DIfTex = NULL;
1846
1847// Assert(pD3DIfTex);
1848 HRESULT hr = pScreen->pDevice9If->SetTexture(Stage, pD3DIfTex);
1849 Assert(hr == S_OK);
1850 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1851 return hr;
1852}
1853
1854static HRESULT APIENTRY vboxWddmDDevSetPixelShader(HANDLE hDevice, HANDLE hShaderHandle)
1855{
1856 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1857 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1858 Assert(pDevice);
1859 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
1860 Assert(pScreen->hWnd);
1861 Assert(pScreen->pDevice9If);
1862 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
1863 Assert(pShader);
1864 HRESULT hr = pScreen->pDevice9If->SetPixelShader(pShader);
1865 Assert(hr == S_OK);
1866 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1867 return hr;
1868}
1869
1870static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONST* pData, CONST FLOAT* pRegisters)
1871{
1872 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1873 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1874 Assert(pDevice);
1875 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
1876 Assert(pScreen->hWnd);
1877 Assert(pScreen->pDevice9If);
1878 HRESULT hr = pScreen->pDevice9If->SetPixelShaderConstantF(pData->Register, pRegisters, pData->Count);
1879 Assert(hr == S_OK);
1880 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1881 return hr;
1882}
1883
1884static HRESULT APIENTRY vboxWddmDDevSetStreamSourceUm(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEUM* pData, CONST VOID* pUMBuffer )
1885{
1886 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1887 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1888 Assert(pDevice);
1889 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
1890 Assert(pScreen->hWnd);
1891 Assert(pScreen->pDevice9If);
1892 HRESULT hr = S_OK;
1893// IDirect3DVertexBuffer9 *pStreamData;
1894// UINT cbOffset;
1895// UINT cbStride;
1896// hr = pDevice->pDevice9If->GetStreamSource(pData->Stream, &pStreamData, &cbOffset, &cbStride);
1897// Assert(hr == S_OK);
1898// if (hr == S_OK)
1899// {
1900// if (pStreamData)
1901// {
1902// Assert(0);
1903// /* @todo: impl! */
1904// }
1905// else
1906// {
1907 Assert(pData->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm));
1908 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrcUm = &pDevice->aStreamSourceUm[pData->Stream];
1909 pStrSrcUm->pvBuffer = pUMBuffer;
1910 pStrSrcUm->cbStride = pData->Stride;
1911// }
1912// }
1913 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1914 return hr;
1915}
1916
1917static HRESULT APIENTRY vboxWddmDDevSetIndices(HANDLE hDevice, CONST D3DDDIARG_SETINDICES* pData)
1918{
1919 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1920 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1921 Assert(pDevice);
1922 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
1923 Assert(pScreen->hWnd);
1924 Assert(pScreen->pDevice9If);
1925 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hIndexBuffer;
1926 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
1927 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
1928 if (pRc)
1929 {
1930 Assert(pRc->cAllocations == 1);
1931 pAlloc = &pRc->aAllocations[0];
1932 Assert(pAlloc->pD3DIf);
1933 pIndexBuffer = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
1934 }
1935 HRESULT hr = pScreen->pDevice9If->SetIndices(pIndexBuffer);
1936 Assert(hr == S_OK);
1937 if (hr == S_OK)
1938 {
1939 pDevice->pIndicesAlloc = pAlloc;
1940 pDevice->IndiciesInfo.uiStride = pData->Stride;
1941 }
1942 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1943 return hr;
1944}
1945
1946static HRESULT APIENTRY vboxWddmDDevSetIndicesUm(HANDLE hDevice, UINT IndexSize, CONST VOID* pUMBuffer)
1947{
1948 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1949 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1950 Assert(pDevice);
1951 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
1952 Assert(pScreen->hWnd);
1953 Assert(pScreen->pDevice9If);
1954 HRESULT hr = S_OK;
1955 pDevice->IndiciesUm.pvBuffer = pUMBuffer;
1956 pDevice->IndiciesUm.cbSize = IndexSize;
1957 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1958 return hr;
1959}
1960
1961static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE* pData, CONST UINT* pFlagBuffer)
1962{
1963 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
1964 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1965 Assert(pDevice);
1966 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
1967 Assert(pScreen->hWnd);
1968 Assert(pScreen->pDevice9If);
1969 Assert(!pFlagBuffer);
1970 HRESULT hr = S_OK;
1971
1972//#ifdef DEBUG_misha
1973// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
1974// vboxVDbgDumpSurfData((pDevice, ">>>DrawPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
1975// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
1976//#endif
1977
1978 if (!pDevice->cStreamSources)
1979 {
1980 if (pDevice->aStreamSourceUm[0].pvBuffer)
1981 {
1982#ifdef DEBUG
1983 for (UINT i = 1; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
1984 {
1985 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
1986 }
1987#endif
1988 hr = pScreen->pDevice9If->DrawPrimitiveUP(pData->PrimitiveType,
1989 pData->PrimitiveCount,
1990 ((uint8_t*)pDevice->aStreamSourceUm[0].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[0].cbStride,
1991 pDevice->aStreamSourceUm[0].cbStride);
1992 Assert(hr == S_OK);
1993
1994// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
1995 }
1996 else
1997 {
1998 /* todo: impl */
1999 Assert(0);
2000 }
2001 }
2002 else
2003 {
2004
2005#ifdef DEBUG
2006 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2007 {
2008 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
2009 }
2010
2011 uint32_t cStreams = 0;
2012 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
2013 {
2014 if (pDevice->aStreamSource[i])
2015 {
2016 ++cStreams;
2017 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
2018 }
2019 }
2020
2021 Assert(cStreams);
2022 Assert(cStreams == pDevice->cStreamSources);
2023#endif
2024 hr = pScreen->pDevice9If->DrawPrimitive(pData->PrimitiveType,
2025 pData->VStart,
2026 pData->PrimitiveCount);
2027 Assert(hr == S_OK);
2028
2029// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitive\n"));
2030#if 0
2031 IDirect3DVertexDeclaration9* pDecl;
2032 hr = pScreen->pDevice9If->GetVertexDeclaration(&pDecl);
2033 Assert(hr == S_OK);
2034 if (hr == S_OK)
2035 {
2036 Assert(pDecl);
2037 D3DVERTEXELEMENT9 aDecls9[MAXD3DDECLLENGTH];
2038 UINT cDecls9 = 0;
2039 hr = pDecl->GetDeclaration(aDecls9, &cDecls9);
2040 Assert(hr == S_OK);
2041 if (hr == S_OK)
2042 {
2043 Assert(cDecls9);
2044 for (UINT i = 0; i < cDecls9 - 1 /* the last one is D3DDECL_END */; ++i)
2045 {
2046 D3DVERTEXELEMENT9 *pDecl9 = &aDecls9[i];
2047 Assert(pDecl9->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm) || pDecl9->Stream == 0xff);
2048 if (pDecl9->Stream != 0xff)
2049 {
2050 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrc = &pDevice->aStreamSourceUm[pDecl9->Stream];
2051 if (pStrSrc->pvBuffer)
2052 {
2053 WORD iStream = pDecl9->Stream;
2054 D3DVERTEXELEMENT9 *pLastCDecl9 = pDecl9;
2055 for (UINT j = i+1; j < cDecls9 - 1 /* the last one is D3DDECL_END */; ++j)
2056 {
2057 pDecl9 = &aDecls9[j];
2058 if (iStream == pDecl9->Stream)
2059 {
2060 pDecl9->Stream = 0xff; /* mark as done */
2061 Assert(pDecl9->Offset != pLastCDecl9->Offset);
2062 if (pDecl9->Offset > pLastCDecl9->Offset)
2063 pLastCDecl9 = pDecl9;
2064 }
2065 }
2066 /* vertex size is MAX(all Offset's) + sizeof (data_type with MAX offset) + stride*/
2067 UINT cbVertex = pLastCDecl9->Offset + pStrSrc->cbStride;
2068 UINT cbType;
2069 switch (pLastCDecl9->Type)
2070 {
2071 case D3DDECLTYPE_FLOAT1:
2072 cbType = sizeof (float);
2073 break;
2074 case D3DDECLTYPE_FLOAT2:
2075 cbType = sizeof (float) * 2;
2076 break;
2077 case D3DDECLTYPE_FLOAT3:
2078 cbType = sizeof (float) * 3;
2079 break;
2080 case D3DDECLTYPE_FLOAT4:
2081 cbType = sizeof (float) * 4;
2082 break;
2083 case D3DDECLTYPE_D3DCOLOR:
2084 cbType = 4;
2085 break;
2086 case D3DDECLTYPE_UBYTE4:
2087 cbType = 4;
2088 break;
2089 case D3DDECLTYPE_SHORT2:
2090 cbType = sizeof (short) * 2;
2091 break;
2092 case D3DDECLTYPE_SHORT4:
2093 cbType = sizeof (short) * 4;
2094 break;
2095 case D3DDECLTYPE_UBYTE4N:
2096 cbType = 4;
2097 break;
2098 case D3DDECLTYPE_SHORT2N:
2099 cbType = sizeof (short) * 2;
2100 break;
2101 case D3DDECLTYPE_SHORT4N:
2102 cbType = sizeof (short) * 4;
2103 break;
2104 case D3DDECLTYPE_USHORT2N:
2105 cbType = sizeof (short) * 2;
2106 break;
2107 case D3DDECLTYPE_USHORT4N:
2108 cbType = sizeof (short) * 4;
2109 break;
2110 case D3DDECLTYPE_UDEC3:
2111 cbType = sizeof (signed) * 3;
2112 break;
2113 case D3DDECLTYPE_DEC3N:
2114 cbType = sizeof (unsigned) * 3;
2115 break;
2116 case D3DDECLTYPE_FLOAT16_2:
2117 cbType = 2 * 2;
2118 break;
2119 case D3DDECLTYPE_FLOAT16_4:
2120 cbType = 2 * 4;
2121 break;
2122 default:
2123 Assert(0);
2124 cbType = 1;
2125 }
2126 cbVertex += cbType;
2127
2128 UINT cVertexes;
2129 switch (pData->PrimitiveType)
2130 {
2131 case D3DPT_POINTLIST:
2132 cVertexes = pData->PrimitiveCount;
2133 break;
2134 case D3DPT_LINELIST:
2135 cVertexes = pData->PrimitiveCount * 2;
2136 break;
2137 case D3DPT_LINESTRIP:
2138 cVertexes = pData->PrimitiveCount + 1;
2139 break;
2140 case D3DPT_TRIANGLELIST:
2141 cVertexes = pData->PrimitiveCount * 3;
2142 break;
2143 case D3DPT_TRIANGLESTRIP:
2144 cVertexes = pData->PrimitiveCount + 2;
2145 break;
2146 case D3DPT_TRIANGLEFAN:
2147 cVertexes = pData->PrimitiveCount + 2;
2148 break;
2149 default:
2150 Assert(0);
2151 cVertexes = pData->PrimitiveCount;
2152 }
2153 UINT cbVertexes = cVertexes * cbVertex;
2154 IDirect3DVertexBuffer9 *pCurVb = NULL, *pVb = NULL;
2155 UINT cbOffset;
2156 UINT cbStride;
2157 hr = pScreen->pDevice9If->GetStreamSource(iStream, &pCurVb, &cbOffset, &cbStride);
2158 Assert(hr == S_OK);
2159 if (hr == S_OK)
2160 {
2161 if (pCurVb)
2162 {
2163 if (cbStride == pStrSrc->cbStride)
2164 {
2165 /* ensure our data feets in the buffer */
2166 D3DVERTEXBUFFER_DESC Desc;
2167 hr = pCurVb->GetDesc(&Desc);
2168 Assert(hr == S_OK);
2169 if (hr == S_OK)
2170 {
2171 if (Desc.Size >= cbVertexes)
2172 pVb = pCurVb;
2173 }
2174 }
2175 }
2176 }
2177 else
2178 {
2179 pCurVb = NULL;
2180 }
2181
2182 if (!pVb)
2183 {
2184 hr = pScreen->pDevice9If->CreateVertexBuffer(cbVertexes,
2185 0, /* DWORD Usage */
2186 0, /* DWORD FVF */
2187 D3DPOOL_DEFAULT, /* D3DPOOL Pool */
2188 &pVb,
2189 NULL /*HANDLE* pSharedHandle*/);
2190 Assert(hr == S_OK);
2191 if (hr == S_OK)
2192 {
2193 hr = pScreen->pDevice9If->SetStreamSource(iStream, pVb, 0, pStrSrc->cbStride);
2194 Assert(hr == S_OK);
2195 if (hr == S_OK)
2196 {
2197 if (pCurVb)
2198 pCurVb->Release();
2199 }
2200 else
2201 {
2202 pVb->Release();
2203 pVb = NULL;
2204 }
2205 }
2206 }
2207
2208 if (pVb)
2209 {
2210 Assert(hr == S_OK);
2211 VOID *pvData;
2212 hr = pVb->Lock(0, /* UINT OffsetToLock */
2213 cbVertexes,
2214 &pvData,
2215 D3DLOCK_DISCARD);
2216 Assert(hr == S_OK);
2217 if (hr == S_OK)
2218 {
2219 memcpy (pvData, ((uint8_t*)pStrSrc->pvBuffer) + pData->VStart * cbVertex, cbVertexes);
2220 HRESULT tmpHr = pVb->Unlock();
2221 Assert(tmpHr == S_OK);
2222 }
2223 }
2224 }
2225 }
2226 }
2227 }
2228 if (hr == S_OK)
2229 {
2230 hr = pScreen->pDevice9If->DrawPrimitive(pData->PrimitiveType,
2231 0 /* <- since we use our owne StreamSource buffer which has data at the very beginning*/,
2232 pData->PrimitiveCount);
2233 Assert(hr == S_OK);
2234 }
2235 }
2236#endif
2237 }
2238
2239//#ifdef DEBUG_misha
2240// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
2241// vboxVDbgDumpSurfData((pDevice, "<<<DrawPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
2242// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
2243//#endif
2244
2245 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2246 return hr;
2247}
2248
2249static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE* pData)
2250{
2251 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2252 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2253 Assert(pDevice);
2254 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
2255 Assert(pScreen->hWnd);
2256 Assert(pScreen->pDevice9If);
2257//#ifdef DEBUG_misha
2258// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
2259// vboxVDbgDumpSurfData((pDevice, ">>>DrawIndexedPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
2260// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
2261//#endif
2262
2263#ifdef DEBUG
2264 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2265 {
2266 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
2267 }
2268
2269 Assert(pDevice->pIndicesAlloc);
2270 Assert(!pDevice->pIndicesAlloc->LockInfo.cLocks);
2271
2272 uint32_t cStreams = 0;
2273 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
2274 {
2275 if (pDevice->aStreamSource[i])
2276 {
2277 ++cStreams;
2278 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
2279 }
2280 }
2281
2282 Assert(cStreams);
2283 Assert(cStreams == pDevice->cStreamSources);
2284#endif
2285
2286 HRESULT hr = pScreen->pDevice9If->DrawIndexedPrimitive(
2287 pData->PrimitiveType,
2288 pData->BaseVertexIndex,
2289 pData->MinIndex,
2290 pData->NumVertices,
2291 pData->StartIndex,
2292 pData->PrimitiveCount);
2293 Assert(hr == S_OK);
2294
2295//#ifdef DEBUG_misha
2296// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
2297// vboxVDbgDumpSurfData((pDevice, "<<<DrawIndexedPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
2298// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
2299//#endif
2300
2301
2302 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2303 return hr;
2304}
2305
2306static HRESULT APIENTRY vboxWddmDDevDrawRectPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWRECTPATCH* pData, CONST D3DDDIRECTPATCH_INFO* pInfo, CONST FLOAT* pPatch)
2307{
2308 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2309 Assert(0);
2310 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2311 return E_FAIL;
2312}
2313
2314static HRESULT APIENTRY vboxWddmDDevDrawTriPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWTRIPATCH* pData, CONST D3DDDITRIPATCH_INFO* pInfo, CONST FLOAT* pPatch)
2315{
2316 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2317 Assert(0);
2318 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2319 return E_FAIL;
2320}
2321
2322static HRESULT APIENTRY vboxWddmDDevDrawPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE2* pData)
2323{
2324 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2325 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2326 Assert(pDevice);
2327 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
2328 Assert(pScreen->hWnd);
2329 Assert(pScreen->pDevice9If);
2330 HRESULT hr;
2331
2332#if 0
2333 int stream;
2334 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
2335 {
2336 if (pDevice->aStreamSource[stream] && pDevice->aStreamSource[stream]->LockInfo.cLocks)
2337 {
2338 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
2339 if (pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite))
2340 {
2341 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf;
2342 Assert(pLock->fFlags.RangeValid);
2343 pD3D9VBuf->Lock(pLock->Range.Offset, pLock->Range.Size,
2344 &pLock->LockedRect.pBits,
2345 vboxDDI2D3DLockFlags(pLock->fFlags));
2346 RECT r;
2347 r.top = 0;
2348 r.left = pLock->Range.Offset;
2349 r.bottom = 1;
2350 r.right = pLock->Range.Offset + pLock->Range.Size;
2351
2352 vboxWddmLockUnlockMemSynch(pDevice->aStreamSource[stream], &pLock->LockedRect, &r, true /*bool bToLockInfo*/);
2353
2354 pD3D9VBuf->Unlock();
2355 }
2356 }
2357 }
2358
2359 hr = pScreen->pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset, pData->PrimitiveCount);
2360#else
2361//#ifdef DEBUG_misha
2362// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
2363// vboxVDbgDumpSurfData((pDevice, ">>>DrawPrimitive2:\n", pDevice->pRenderTargetRc, iBackBuf,
2364// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
2365//#endif
2366
2367#ifdef DEBUG
2368 uint32_t cStreams = 0;
2369#endif
2370
2371 int stream;
2372 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
2373 {
2374 if (pDevice->aStreamSource[stream])
2375 {
2376#ifdef DEBUG
2377 ++cStreams;
2378#endif
2379 Assert(stream==0); /*only stream 0 should be accessed here*/
2380 Assert(pDevice->StreamSourceInfo[stream].uiStride!=0);
2381 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
2382
2383 if (pDevice->aStreamSource[stream]->LockInfo.cLocks)
2384 {
2385// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
2386
2387 Assert(pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite));
2388 hr = pScreen->pDevice9If->DrawPrimitiveUP(pData->PrimitiveType, pData->PrimitiveCount,
2389 (void*)((uintptr_t)pDevice->aStreamSource[stream]->pvMem+pDevice->StreamSourceInfo[stream].uiOffset+pData->FirstVertexOffset),
2390 pDevice->StreamSourceInfo[stream].uiStride);
2391 Assert(hr == S_OK);
2392 hr = pScreen->pDevice9If->SetStreamSource(stream, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf, pDevice->StreamSourceInfo[stream].uiOffset, pDevice->StreamSourceInfo[stream].uiStride);
2393 Assert(hr == S_OK);
2394 }
2395 else
2396 {
2397// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitive\n"));
2398
2399 hr = pScreen->pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset/pDevice->StreamSourceInfo[stream].uiStride, pData->PrimitiveCount);
2400 Assert(hr == S_OK);
2401 }
2402 }
2403 }
2404
2405#ifdef DEBUG
2406 Assert(cStreams);
2407 Assert(cStreams == pDevice->cStreamSources);
2408#endif
2409#endif
2410
2411//#ifdef DEBUG_misha
2412// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
2413// vboxVDbgDumpSurfData((pDevice, "<<<DrawPrimitive2:\n", pDevice->pRenderTargetRc, iBackBuf,
2414// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
2415//#endif
2416
2417 Assert(hr == S_OK);
2418 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2419 return hr;
2420}
2421
2422static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE2* pData, UINT dwIndicesSize, CONST VOID* pIndexBuffer, CONST UINT* pFlagBuffer)
2423{
2424 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2425 Assert(0);
2426 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2427 return E_FAIL;
2428}
2429
2430static HRESULT APIENTRY vboxWddmDDevVolBlt(HANDLE hDevice, CONST D3DDDIARG_VOLUMEBLT* pData)
2431{
2432 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2433 Assert(0);
2434 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2435 return E_FAIL;
2436}
2437
2438static HRESULT APIENTRY vboxWddmDDevBufBlt(HANDLE hDevice, CONST D3DDDIARG_BUFFERBLT* pData)
2439{
2440 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2441 Assert(0);
2442 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2443 return E_FAIL;
2444}
2445
2446static HRESULT APIENTRY vboxWddmDDevTexBlt(HANDLE hDevice, CONST D3DDDIARG_TEXBLT* pData)
2447{
2448 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2449 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2450 Assert(pDevice);
2451 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
2452 Assert(pScreen->hWnd);
2453 Assert(pScreen->pDevice9If);
2454 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
2455 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
2456 /* requirements for D3DDevice9::UpdateTexture */
2457 Assert(pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
2458 Assert(pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
2459 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcRc->aAllocations[0].pD3DIf;
2460 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstRc->aAllocations[0].pD3DIf;
2461 Assert(pD3DIfSrcTex);
2462 Assert(pD3DIfDstTex);
2463 HRESULT hr = S_OK;
2464
2465 if (pSrcRc->aAllocations[0].SurfDesc.width == pDstRc->aAllocations[0].SurfDesc.width
2466 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
2467 && pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat)
2468 {
2469 /* first check if we can do IDirect3DDevice9::UpdateTexture */
2470 if (pData->DstPoint.x == 0 && pData->DstPoint.y == 0
2471 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
2472 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
2473 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height)
2474 {
2475 hr = pScreen->pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
2476 Assert(hr == S_OK);
2477 }
2478 else
2479 {
2480 Assert(0);
2481 /* @todo: impl */
2482 }
2483 }
2484 else
2485 {
2486 Assert(0);
2487 /* @todo: impl */
2488 }
2489
2490 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2491 return hr;
2492}
2493
2494static HRESULT APIENTRY vboxWddmDDevStateSet(HANDLE hDevice, D3DDDIARG_STATESET* pData)
2495{
2496 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2497 Assert(0);
2498 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2499 return E_FAIL;
2500}
2501static HRESULT APIENTRY vboxWddmDDevSetPriority(HANDLE hDevice, CONST D3DDDIARG_SETPRIORITY* pData)
2502{
2503 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2504 Assert(0);
2505 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2506 return E_FAIL;
2507}
2508AssertCompile(sizeof (RECT) == sizeof (D3DRECT));
2509AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DRECT, x1));
2510AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DRECT, x2));
2511AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DRECT, y1));
2512AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DRECT, y2));
2513AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DRECT, x1));
2514AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DRECT, x2));
2515AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DRECT, y1));
2516AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DRECT, y2));
2517
2518static HRESULT APIENTRY vboxWddmDDevClear(HANDLE hDevice, CONST D3DDDIARG_CLEAR* pData, UINT NumRect, CONST RECT* pRect)
2519{
2520 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2521 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2522 Assert(pDevice);
2523 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
2524 Assert(pScreen->hWnd);
2525 Assert(pScreen->pDevice9If);
2526 HRESULT hr = pScreen->pDevice9If->Clear(NumRect, (D3DRECT*)pRect /* see AssertCompile above */,
2527 pData->Flags,
2528 pData->FillColor,
2529 pData->FillDepth,
2530 pData->FillStencil);
2531 Assert(hr == S_OK);
2532 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2533 return hr;
2534}
2535static HRESULT APIENTRY vboxWddmDDevUpdatePalette(HANDLE hDevice, CONST D3DDDIARG_UPDATEPALETTE* pData, CONST PALETTEENTRY* pPaletteData)
2536{
2537 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2538 Assert(0);
2539 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2540 return E_FAIL;
2541}
2542
2543static HRESULT APIENTRY vboxWddmDDevSetPalette(HANDLE hDevice, CONST D3DDDIARG_SETPALETTE* pData)
2544{
2545 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2546 Assert(0);
2547 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2548 return E_FAIL;
2549}
2550
2551static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONST* pData , CONST VOID* pRegisters)
2552{
2553 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2554 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2555 Assert(pDevice);
2556 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
2557 Assert(pScreen->hWnd);
2558 Assert(pScreen->pDevice9If);
2559 HRESULT hr = pScreen->pDevice9If->SetVertexShaderConstantF(
2560 pData->Register,
2561 (CONST float*)pRegisters,
2562 pData->Count);
2563 Assert(hr == S_OK);
2564 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2565 return hr;
2566}
2567static HRESULT APIENTRY vboxWddmDDevMultiplyTransform(HANDLE hDevice, CONST D3DDDIARG_MULTIPLYTRANSFORM* pData)
2568{
2569 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2570 Assert(0);
2571 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2572 return E_FAIL;
2573}
2574static HRESULT APIENTRY vboxWddmDDevSetTransform(HANDLE hDevice, CONST D3DDDIARG_SETTRANSFORM* pData)
2575{
2576 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2577 Assert(0);
2578 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2579 return E_FAIL;
2580}
2581static HRESULT APIENTRY vboxWddmDDevSetViewport(HANDLE hDevice, CONST D3DDDIARG_VIEWPORTINFO* pData)
2582{
2583 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2584 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2585 Assert(pDevice);
2586 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
2587 Assert(pScreen->hWnd);
2588 Assert(pScreen->pDevice9If);
2589 pDevice->ViewPort.X = pData->X;
2590 pDevice->ViewPort.Y = pData->Y;
2591 pDevice->ViewPort.Width = pData->Width;
2592 pDevice->ViewPort.Height = pData->Height;
2593 HRESULT hr = pScreen->pDevice9If->SetViewport(&pDevice->ViewPort);
2594 Assert(hr == S_OK);
2595 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2596 return hr;
2597}
2598static HRESULT APIENTRY vboxWddmDDevSetZRange(HANDLE hDevice, CONST D3DDDIARG_ZRANGE* pData)
2599{
2600 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2601 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2602 Assert(pDevice);
2603 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
2604 Assert(pScreen->hWnd);
2605 Assert(pScreen->pDevice9If);
2606 pDevice->ViewPort.MinZ = pData->MinZ;
2607 pDevice->ViewPort.MaxZ = pData->MaxZ;
2608 HRESULT hr = pScreen->pDevice9If->SetViewport(&pDevice->ViewPort);
2609 Assert(hr == S_OK);
2610 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2611 return hr;
2612}
2613static HRESULT APIENTRY vboxWddmDDevSetMaterial(HANDLE hDevice, CONST D3DDDIARG_SETMATERIAL* pData)
2614{
2615 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2616 Assert(0);
2617 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2618 return E_FAIL;
2619}
2620static HRESULT APIENTRY vboxWddmDDevSetLight(HANDLE hDevice, CONST D3DDDIARG_SETLIGHT* pData, CONST D3DDDI_LIGHT* pLightProperties)
2621{
2622 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2623 Assert(0);
2624 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2625 return E_FAIL;
2626}
2627static HRESULT APIENTRY vboxWddmDDevCreateLight(HANDLE hDevice, CONST D3DDDIARG_CREATELIGHT* pData)
2628{
2629 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2630 Assert(0);
2631 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2632 return E_FAIL;
2633}
2634static HRESULT APIENTRY vboxWddmDDevDestroyLight(HANDLE hDevice, CONST D3DDDIARG_DESTROYLIGHT* pData)
2635{
2636 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2637 Assert(0);
2638 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2639 return E_FAIL;
2640}
2641static HRESULT APIENTRY vboxWddmDDevSetClipPlane(HANDLE hDevice, CONST D3DDDIARG_SETCLIPPLANE* pData)
2642{
2643 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2644 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2645 Assert(pDevice);
2646 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
2647 Assert(pScreen->hWnd);
2648 Assert(pScreen->pDevice9If);
2649 HRESULT hr = pScreen->pDevice9If->SetClipPlane(pData->Index, pData->Plane);
2650 Assert(hr == S_OK);
2651 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2652 return hr;
2653}
2654
2655static HRESULT APIENTRY vboxWddmDDevGetInfo(HANDLE hDevice, UINT DevInfoID, VOID* pDevInfoStruct, UINT DevInfoSize)
2656{
2657 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2658 HRESULT hr = S_OK;
2659 switch (DevInfoID)
2660 {
2661 case D3DDDIDEVINFOID_VCACHE:
2662 {
2663 Assert(DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE));
2664 if (DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE))
2665 {
2666 D3DDDIDEVINFO_VCACHE *pVCache = (D3DDDIDEVINFO_VCACHE*)pDevInfoStruct;
2667 pVCache->Pattern = MAKEFOURCC('C', 'A', 'C', 'H');
2668 pVCache->OptMethod = 0 /* D3DXMESHOPT_STRIPREORDER */;
2669 pVCache->CacheSize = 0;
2670 pVCache->MagicNumber = 0;
2671 }
2672 else
2673 hr = E_INVALIDARG;
2674 break;
2675 }
2676 default:
2677 Assert(0);
2678 hr = E_NOTIMPL;
2679 }
2680 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2681 return hr;
2682}
2683
2684static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
2685{
2686 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2687 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2688 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
2689 Assert(pData->SubResourceIndex < pRc->cAllocations);
2690 if (pData->SubResourceIndex >= pRc->cAllocations)
2691 return E_INVALIDARG;
2692
2693 HRESULT hr = S_OK;
2694
2695 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
2696 {
2697 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
2698
2699 Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex);
2700
2701 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
2702 {
2703 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
2704 Assert(pData->SubResourceIndex < pRc->cAllocations);
2705 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
2706 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
2707 Assert(pD3DIfTex);
2708 RECT *pRect = NULL;
2709 bool bNeedResynch = false;
2710 Assert(!pData->Flags.RangeValid);
2711 Assert(!pData->Flags.BoxValid);
2712 if (pData->Flags.AreaValid)
2713 {
2714 pRect = &pData->Area;
2715 }
2716
2717 /* else - we lock the entire texture, pRect == NULL */
2718
2719// Assert(!pLockAlloc->LockInfo.cLocks);
2720 if (!pLockAlloc->LockInfo.cLocks)
2721 {
2722 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
2723 &pLockAlloc->LockInfo.LockedRect,
2724 pRect,
2725 vboxDDI2D3DLockFlags(pData->Flags));
2726 Assert(hr == S_OK);
2727 if (hr == S_OK)
2728 {
2729
2730// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
2731 pLockAlloc->LockInfo.fFlags = pData->Flags;
2732 if (pRect)
2733 {
2734 pLockAlloc->LockInfo.Area = *pRect;
2735 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 1);
2736// pLockAlloc->LockInfo.fFlags.AreaValid = 1;
2737 }
2738 else
2739 {
2740 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 0);
2741// pLockAlloc->LockInfo.fFlags.AreaValid = 0;
2742 }
2743
2744 bNeedResynch = !pData->Flags.Discard;
2745 }
2746 }
2747 else
2748 {
2749// Assert(pLockAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
2750// if (pLockAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
2751// {
2752// }
2753 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid);
2754 if (pLockAlloc->LockInfo.fFlags.AreaValid && pData->Flags.AreaValid)
2755 {
2756 Assert(pLockAlloc->LockInfo.Area.left == pData->Area.left);
2757 Assert(pLockAlloc->LockInfo.Area.top == pData->Area.top);
2758 Assert(pLockAlloc->LockInfo.Area.right == pData->Area.right);
2759 Assert(pLockAlloc->LockInfo.Area.bottom == pData->Area.bottom);
2760 }
2761 Assert(pLockAlloc->LockInfo.LockedRect.pBits);
2762
2763 bNeedResynch = pLockAlloc->LockInfo.fFlags.Discard && !pData->Flags.Discard;
2764
2765 Assert(!bNeedResynch);
2766
2767 if (/*(pLockAlloc->LockInfo.fFlags.Discard && !pData->Flags.Discard)
2768 || */
2769 (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly))
2770 {
2771 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
2772 Assert(hr == S_OK);
2773 if (hr == S_OK)
2774 {
2775 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
2776 &pLockAlloc->LockInfo.LockedRect,
2777 pRect,
2778 vboxDDI2D3DLockFlags(pData->Flags));
2779 Assert(hr == S_OK);
2780 pLockAlloc->LockInfo.fFlags.ReadOnly = 0;
2781 }
2782 }
2783 }
2784
2785 if (hr == S_OK)
2786 {
2787 ++pLockAlloc->LockInfo.cLocks;
2788
2789 if (!pData->Flags.NotifyOnly)
2790 {
2791 pData->pSurfData = pLockAlloc->LockInfo.LockedRect.pBits;
2792 pData->Pitch = pLockAlloc->LockInfo.LockedRect.Pitch;
2793 pData->SlicePitch = 0;
2794 Assert(pLockAlloc->SurfDesc.slicePitch == 0);
2795 Assert(!pLockAlloc->pvMem);
2796 }
2797 else
2798 {
2799 Assert(pLockAlloc->pvMem);
2800 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
2801#if 0
2802 if (bNeedResynch)
2803 vboxWddmLockUnlockMemSynch(pLockAlloc, &pLockAlloc->LockInfo.LockedRect, pRect, false /*bool bToLockInfo*/);
2804#endif
2805 }
2806 }
2807 }
2808 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
2809 {
2810 Assert(pData->SubResourceIndex < pRc->cAllocations);
2811 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
2812 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
2813 BOOL bLocked = false;
2814 Assert(pD3D9VBuf);
2815 Assert(!pData->Flags.AreaValid);
2816 Assert(!pData->Flags.BoxValid);
2817 D3DDDIRANGE *pRange = NULL;
2818 if (pData->Flags.RangeValid)
2819 {
2820 pRange = &pData->Range;
2821 }
2822
2823 /* else - we lock the entire vertex buffer, pRect == NULL */
2824
2825 Assert(!pAlloc->LockInfo.cLocks);
2826 if (!pAlloc->LockInfo.cLocks)
2827 {
2828 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
2829 {
2830 hr = pD3D9VBuf->Lock(pRange ? pRange->Offset : 0,
2831 pRange ? pRange->Size : 0,
2832 &pAlloc->LockInfo.LockedRect.pBits,
2833 vboxDDI2D3DLockFlags(pData->Flags));
2834 bLocked = true;
2835 }
2836
2837 Assert(hr == S_OK);
2838 if (hr == S_OK)
2839 {
2840 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.width;
2841// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
2842 pAlloc->LockInfo.fFlags = pData->Flags;
2843 if (pRange)
2844 {
2845 pAlloc->LockInfo.Range = *pRange;
2846 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
2847// pAlloc->LockInfo.fFlags.RangeValid = 1;
2848 }
2849 else
2850 {
2851 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
2852// pAlloc->LockInfo.fFlags.RangeValid = 0;
2853 }
2854 }
2855 }
2856 else
2857 {
2858// Assert(pAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
2859// if (pAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
2860// {
2861// }
2862 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
2863 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
2864 {
2865 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
2866 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
2867 }
2868 Assert(pAlloc->LockInfo.LockedRect.pBits);
2869 }
2870
2871 if (hr == S_OK)
2872 {
2873 ++pAlloc->LockInfo.cLocks;
2874
2875 if (!pData->Flags.NotifyOnly)
2876 {
2877 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
2878 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
2879 pData->SlicePitch = 0;
2880 Assert(pAlloc->SurfDesc.slicePitch == 0);
2881 Assert(!pAlloc->pvMem);
2882 }
2883 else
2884 {
2885 Assert(pAlloc->pvMem);
2886 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
2887 if (bLocked && !pData->Flags.Discard)
2888 {
2889 RECT r, *pr;
2890 if (pRange)
2891 {
2892 r.top = 0;
2893 r.left = pRange->Offset;
2894 r.bottom = 1;
2895 r.right = pRange->Offset + pRange->Size;
2896 pr = &r;
2897 }
2898 else
2899 pr = NULL;
2900 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
2901 }
2902 }
2903 }
2904 }
2905 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
2906 {
2907 Assert(pData->SubResourceIndex < pRc->cAllocations);
2908 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
2909 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
2910 BOOL bLocked = false;
2911 Assert(pD3D9IBuf);
2912 Assert(!pData->Flags.AreaValid);
2913 Assert(!pData->Flags.BoxValid);
2914 D3DDDIRANGE *pRange = NULL;
2915 if (pData->Flags.RangeValid)
2916 {
2917 pRange = &pData->Range;
2918 }
2919
2920 /* else - we lock the entire vertex buffer, pRect == NULL */
2921
2922 Assert(!pAlloc->LockInfo.cLocks);
2923 if (!pAlloc->LockInfo.cLocks)
2924 {
2925 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
2926 {
2927 hr = pD3D9IBuf->Lock(pRange ? pRange->Offset : 0,
2928 pRange ? pRange->Size : 0,
2929 &pAlloc->LockInfo.LockedRect.pBits,
2930 vboxDDI2D3DLockFlags(pData->Flags));
2931 bLocked = true;
2932 }
2933
2934 Assert(hr == S_OK);
2935 if (hr == S_OK)
2936 {
2937 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.width;
2938// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
2939 pAlloc->LockInfo.fFlags = pData->Flags;
2940 if (pRange)
2941 {
2942 pAlloc->LockInfo.Range = *pRange;
2943 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
2944// pAlloc->LockInfo.fFlags.RangeValid = 1;
2945 }
2946 else
2947 {
2948 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
2949// pAlloc->LockInfo.fFlags.RangeValid = 0;
2950 }
2951 }
2952 }
2953 else
2954 {
2955// Assert(pAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
2956// if (pAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
2957// {
2958// }
2959 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
2960 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
2961 {
2962 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
2963 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
2964 }
2965 Assert(pAlloc->LockInfo.LockedRect.pBits);
2966 }
2967
2968 if (hr == S_OK)
2969 {
2970 ++pAlloc->LockInfo.cLocks;
2971
2972 if (!pData->Flags.NotifyOnly)
2973 {
2974 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
2975 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
2976 pData->SlicePitch = 0;
2977 Assert(pAlloc->SurfDesc.slicePitch == 0);
2978 Assert(!pAlloc->pvMem);
2979 }
2980 else
2981 {
2982 Assert(pAlloc->pvMem);
2983 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
2984 if (bLocked && !pData->Flags.Discard)
2985 {
2986 RECT r, *pr;
2987 if (pRange)
2988 {
2989 r.top = 0;
2990 r.left = pRange->Offset;
2991 r.bottom = 1;
2992 r.right = pRange->Offset + pRange->Size;
2993 pr = &r;
2994 }
2995 else
2996 pr = NULL;
2997 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
2998 }
2999 }
3000 }
3001 }
3002 else
3003 {
3004 Assert(0);
3005 }
3006 }
3007 else
3008 {
3009 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3010 D3DDDICB_LOCK LockData;
3011 LockData.hAllocation = pAlloc->hAllocation;
3012 LockData.PrivateDriverData = 0;
3013 LockData.NumPages = 0;
3014 LockData.pPages = NULL;
3015 LockData.pData = NULL; /* out */
3016 LockData.Flags.Value = 0;
3017 LockData.Flags.Discard = pData->Flags.Discard;
3018 LockData.Flags.DonotWait = pData->Flags.DoNotWait;
3019
3020
3021 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
3022 Assert(hr == S_OK || (hr == D3DERR_WASSTILLDRAWING && pData->Flags.DoNotWait));
3023 if (hr == S_OK)
3024 {
3025 Assert(!pAlloc->LockInfo.cLocks);
3026
3027 uintptr_t offset;
3028 if (pData->Flags.AreaValid)
3029 {
3030 offset = pAlloc->SurfDesc.pitch * pData->Area.top +
3031 ((pAlloc->SurfDesc.bpp * pData->Area.left) >> 3);
3032 }
3033 else if (pData->Flags.RangeValid)
3034 {
3035 offset = pData->Range.Offset;
3036 }
3037 else if (pData->Flags.BoxValid)
3038 {
3039 vboxVDbgPrintF((__FUNCTION__": Implement Box area"));
3040 Assert(0);
3041 }
3042 else
3043 {
3044 offset = 0;
3045 }
3046
3047 if (!pData->Flags.ReadOnly)
3048 {
3049 if (pData->Flags.AreaValid)
3050 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, &pData->Area);
3051 else
3052 {
3053 Assert(!pData->Flags.RangeValid);
3054 Assert(!pData->Flags.BoxValid);
3055 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, NULL); /* <- NULL means the entire surface */
3056 }
3057 }
3058
3059 if (pData->Flags.Discard)
3060 {
3061 /* check if the surface was renamed */
3062 if (LockData.hAllocation)
3063 pAlloc->hAllocation = LockData.hAllocation;
3064 }
3065
3066 pData->pSurfData = ((uint8_t*)LockData.pData) + offset;
3067 pData->Pitch = pAlloc->SurfDesc.pitch;
3068 pData->SlicePitch = pAlloc->SurfDesc.slicePitch;
3069
3070 Assert(hr == S_OK);
3071 ++pAlloc->LockInfo.cLocks;
3072 }
3073 }
3074
3075 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(%d)\n", hDevice, hr));
3076 return hr;
3077}
3078static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOCK* pData)
3079{
3080 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3081 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3082 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
3083 HRESULT hr = S_OK;
3084
3085 Assert(pData->SubResourceIndex < pRc->cAllocations);
3086 if (pData->SubResourceIndex >= pRc->cAllocations)
3087 return E_INVALIDARG;
3088
3089 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
3090 {
3091 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
3092 {
3093 Assert(pData->SubResourceIndex < pRc->cAllocations);
3094 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3095
3096 --pLockAlloc->LockInfo.cLocks;
3097 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
3098// pLockAlloc->LockInfo.cLocks = 0;
3099 if (!pLockAlloc->LockInfo.cLocks)
3100 {
3101 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
3102// Assert(!pLockAlloc->LockInfo.cLocks);
3103 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
3104 Assert(pD3DIfTex);
3105 /* this is a sysmem texture, update */
3106#if 0
3107 if (pLockAlloc->pvMem && !pLockAlloc->LockInfo.fFlags.ReadOnly)
3108 {
3109 vboxWddmLockUnlockMemSynch(pLockAlloc, &pLockAlloc->LockInfo.LockedRect,
3110 pLockAlloc->LockInfo.fFlags.AreaValid ? &pLockAlloc->LockInfo.Area : NULL,
3111 true /*bool bToLockInfo*/);
3112 }
3113#endif
3114 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
3115 Assert(hr == S_OK);
3116 }
3117 else
3118 {
3119 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
3120 }
3121 }
3122 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
3123 {
3124 Assert(pData->SubResourceIndex < pRc->cAllocations);
3125 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3126
3127 --pAlloc->LockInfo.cLocks;
3128 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
3129 if (!pAlloc->LockInfo.cLocks
3130 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
3131 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
3132 {
3133// Assert(!pAlloc->LockInfo.cLocks);
3134 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
3135 Assert(pD3D9VBuf);
3136 /* this is a sysmem texture, update */
3137 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
3138 {
3139 RECT r, *pr;
3140 if (pAlloc->LockInfo.fFlags.RangeValid)
3141 {
3142 r.top = 0;
3143 r.left = pAlloc->LockInfo.Range.Offset;
3144 r.bottom = 1;
3145 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
3146 pr = &r;
3147 }
3148 else
3149 pr = NULL;
3150 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
3151 pr,
3152 true /*bool bToLockInfo*/);
3153 }
3154 hr = pD3D9VBuf->Unlock();
3155 Assert(hr == S_OK);
3156 }
3157 else
3158 {
3159 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
3160 }
3161 }
3162 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
3163 {
3164 Assert(pData->SubResourceIndex < pRc->cAllocations);
3165 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3166
3167 --pAlloc->LockInfo.cLocks;
3168 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
3169 if (!pAlloc->LockInfo.cLocks
3170 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
3171 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
3172 {
3173// Assert(!pAlloc->LockInfo.cLocks);
3174 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
3175 Assert(pD3D9IBuf);
3176 /* this is a sysmem texture, update */
3177 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
3178 {
3179 RECT r, *pr;
3180 if (pAlloc->LockInfo.fFlags.RangeValid)
3181 {
3182 r.top = 0;
3183 r.left = pAlloc->LockInfo.Range.Offset;
3184 r.bottom = 1;
3185 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
3186 pr = &r;
3187 }
3188 else
3189 pr = NULL;
3190 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
3191 pr,
3192 true /*bool bToLockInfo*/);
3193 }
3194 hr = pD3D9IBuf->Unlock();
3195 Assert(hr == S_OK);
3196 }
3197 else
3198 {
3199 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
3200 }
3201 }
3202 else
3203 {
3204 Assert(0);
3205 }
3206 }
3207 else
3208 {
3209 struct
3210 {
3211 D3DDDICB_UNLOCK Unlock;
3212 D3DKMT_HANDLE hAllocation;
3213 } UnlockData;
3214
3215 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3216
3217 UnlockData.Unlock.NumAllocations = 1;
3218 UnlockData.Unlock.phAllocations = &UnlockData.hAllocation;
3219 UnlockData.hAllocation = pAlloc->hAllocation;
3220
3221 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &UnlockData.Unlock);
3222 Assert(hr == S_OK);
3223 if (hr == S_OK)
3224 {
3225 Assert(pAlloc->LockInfo.cLocks);
3226 --pAlloc->LockInfo.cLocks;
3227 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
3228 }
3229 }
3230
3231 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3232 return hr;
3233}
3234static HRESULT APIENTRY vboxWddmDDevLockAsync(HANDLE hDevice, D3DDDIARG_LOCKASYNC* pData)
3235{
3236 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3237 Assert(0);
3238 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3239 return E_FAIL;
3240}
3241static HRESULT APIENTRY vboxWddmDDevUnlockAsync(HANDLE hDevice, CONST D3DDDIARG_UNLOCKASYNC* pData)
3242{
3243 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3244 Assert(0);
3245 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3246 return E_FAIL;
3247}
3248static HRESULT APIENTRY vboxWddmDDevRename(HANDLE hDevice, CONST D3DDDIARG_RENAME* pData)
3249{
3250 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3251 Assert(0);
3252 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3253 return E_FAIL;
3254}
3255
3256static void vboxWddmRequestAllocFree(D3DDDICB_ALLOCATE* pAlloc)
3257{
3258 RTMemFree(pAlloc);
3259}
3260
3261static D3DDDICB_ALLOCATE* vboxWddmRequestAllocAlloc(D3DDDIARG_CREATERESOURCE* pResource)
3262{
3263 /* allocate buffer for D3DDDICB_ALLOCATE + D3DDDI_ALLOCATIONINFO * numAllocs + PVBOXWDDM_RCINFO with aAllocInfos[numAllocs] */
3264 uint32_t cbBuf = sizeof (D3DDDICB_ALLOCATE);
3265 uint32_t offDdiAllocInfos = (cbBuf + 7) & ~3;
3266 uint32_t cbDdiAllocInfos = sizeof (D3DDDI_ALLOCATIONINFO) * pResource->SurfCount;
3267 cbBuf = offDdiAllocInfos + cbDdiAllocInfos;
3268 uint32_t offRcInfo = (cbBuf + 7) & ~3;
3269 uint32_t cbRcInfo = sizeof (VBOXWDDM_RCINFO);
3270 cbBuf = offRcInfo + cbRcInfo;
3271 uint32_t offAllocInfos = (cbBuf + 7) & ~3;
3272 uint32_t cbAllocInfos = sizeof (VBOXWDDM_ALLOCINFO) * pResource->SurfCount;
3273 cbBuf = offAllocInfos + cbAllocInfos;
3274 uint8_t *pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
3275 Assert(pvBuf);
3276 if (pvBuf)
3277 {
3278 D3DDDICB_ALLOCATE* pAlloc = (D3DDDICB_ALLOCATE*)pvBuf;
3279 pAlloc->NumAllocations = pResource->SurfCount;
3280 pAlloc->pAllocationInfo = (D3DDDI_ALLOCATIONINFO*)(pvBuf + offDdiAllocInfos);
3281 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)(pvBuf + offRcInfo);
3282 pAlloc->PrivateDriverDataSize = cbRcInfo;
3283 pAlloc->pPrivateDriverData = pRcInfo;
3284 pAlloc->hResource = pResource->hResource;
3285 PVBOXWDDM_ALLOCINFO pAllocInfos = (PVBOXWDDM_ALLOCINFO)(pvBuf + offAllocInfos);
3286 for (UINT i = 0; i < pResource->SurfCount; ++i)
3287 {
3288 D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pAlloc->pAllocationInfo[i];
3289 PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
3290 pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
3291 pDdiAllocInfo->PrivateDriverDataSize = sizeof (VBOXWDDM_ALLOCINFO);
3292 }
3293 return pAlloc;
3294 }
3295 return NULL;
3296}
3297
3298static HRESULT vboxWddmSurfSynchMem(PVBOXWDDMDISP_RESOURCE pRc, PVBOXWDDMDISP_ALLOCATION pAllocation)
3299{
3300 HRESULT hr = S_OK;
3301 Assert(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
3302 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
3303 {
3304 Assert(pAllocation->pvMem);
3305 D3DLOCKED_RECT lockInfo;
3306 IDirect3DSurface9 *pD3D9Surf = (IDirect3DSurface9*)pAllocation->pD3DIf;
3307 hr = pD3D9Surf->LockRect(&lockInfo, NULL, D3DLOCK_DISCARD);
3308 Assert(hr == S_OK);
3309 if (hr == S_OK)
3310 {
3311 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
3312 HRESULT tmpHr = pD3D9Surf->UnlockRect();
3313 Assert(tmpHr == S_OK);
3314 }
3315 }
3316 else
3317 {
3318 Assert(!pAllocation->pvMem);
3319 }
3320 return hr;
3321}
3322
3323static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE* pResource)
3324{
3325 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3326 HRESULT hr = S_OK;
3327 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3328 Assert(pDevice);
3329 Assert(pResource);
3330 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
3331
3332 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pResource->SurfCount);
3333 Assert(pRc);
3334 if (pRc)
3335 {
3336 bool bIssueCreateResource = false;
3337
3338 pRc->hResource = pResource->hResource;
3339 pRc->hKMResource = NULL;
3340 pRc->pDevice = pDevice;
3341 pRc->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
3342 pRc->RcDesc.fFlags = pResource->Flags;
3343 pRc->RcDesc.enmFormat = pResource->Format;
3344 pRc->RcDesc.enmPool = pResource->Pool;
3345 pRc->RcDesc.enmMultisampleType = pResource->MultisampleType;
3346 pRc->RcDesc.MultisampleQuality = pResource->MultisampleQuality;
3347 pRc->RcDesc.MipLevels = pResource->MipLevels;
3348 pRc->RcDesc.Fvf = pResource->Fvf;
3349 pRc->RcDesc.VidPnSourceId = pResource->VidPnSourceId;
3350 pRc->RcDesc.RefreshRate = pResource->RefreshRate;
3351 pRc->RcDesc.enmRotation = pResource->Rotation;
3352 pRc->cAllocations = pResource->SurfCount;
3353 for (UINT i = 0; i < pResource->SurfCount; ++i)
3354 {
3355 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3356 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
3357 pAllocation->hAllocation = NULL;
3358 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
3359 pAllocation->pvMem = (void*)pSurf->pSysMem;
3360 pAllocation->SurfDesc.pitch = pSurf->SysMemPitch;
3361 pAllocation->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
3362 pAllocation->SurfDesc.depth = pSurf->Depth;
3363 pAllocation->SurfDesc.width = pSurf->Width;
3364 pAllocation->SurfDesc.height = pSurf->Height;
3365 pAllocation->SurfDesc.format = pResource->Format;
3366 }
3367
3368 if (VBOXDISPMODE_IS_3D(pAdapter))
3369 {
3370 if (pResource->Flags.SharedResource)
3371 {
3372 Assert(0); /* <-- need to test that */
3373 bIssueCreateResource = true;
3374 }
3375
3376 if (pResource->Flags.ZBuffer)
3377 {
3378 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
3379 Assert(pScreen->hWnd);
3380 Assert(pScreen->pDevice9If);
3381 for (UINT i = 0; i < pResource->SurfCount; ++i)
3382 {
3383 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3384 IDirect3DSurface9 *pD3D9Surf;
3385 hr = pScreen->pDevice9If->CreateDepthStencilSurface(pAllocation->SurfDesc.width,
3386 pAllocation->SurfDesc.height,
3387 vboxDDI2D3DFormat(pResource->Format),
3388 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
3389 pResource->MultisampleQuality,
3390 TRUE /* @todo: BOOL Discard */,
3391 &pD3D9Surf,
3392 NULL /*HANDLE* pSharedHandle*/);
3393 Assert(hr == S_OK);
3394 if (hr == S_OK)
3395 {
3396 Assert(pD3D9Surf);
3397 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
3398 pAllocation->pD3DIf = pD3D9Surf;
3399 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
3400 Assert(hr == S_OK);
3401 }
3402 else
3403 {
3404 for (UINT j = 0; j < i; ++j)
3405 {
3406 pRc->aAllocations[j].pD3DIf->Release();
3407 }
3408 break;
3409 }
3410 }
3411 }
3412 else if (pResource->Flags.VertexBuffer)
3413 {
3414 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
3415 Assert(pScreen->hWnd);
3416 Assert(pScreen->pDevice9If);
3417 for (UINT i = 0; i < pResource->SurfCount; ++i)
3418 {
3419 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3420 IDirect3DVertexBuffer9 *pD3D9VBuf;
3421 hr = pScreen->pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width,
3422 vboxDDI2D3DUsage(pResource->Flags),
3423 pResource->Fvf,
3424 vboxDDI2D3DPool(pResource->Pool),
3425 &pD3D9VBuf,
3426 NULL /*HANDLE* pSharedHandle*/);
3427 Assert(hr == S_OK);
3428 if (hr == S_OK)
3429 {
3430 Assert(pD3D9VBuf);
3431 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_VERTEXBUFFER;
3432 pAllocation->pD3DIf = pD3D9VBuf;
3433 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
3434 {
3435 Assert(pAllocation->pvMem);
3436 D3DLOCKED_RECT lockInfo;
3437 hr = pD3D9VBuf->Lock(0, pAllocation->SurfDesc.width, &lockInfo.pBits, D3DLOCK_DISCARD);
3438 Assert(hr == S_OK);
3439 if (hr == S_OK)
3440 {
3441 lockInfo.Pitch = pAllocation->SurfDesc.pitch;
3442 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
3443 HRESULT tmpHr = pD3D9VBuf->Unlock();
3444 Assert(tmpHr == S_OK);
3445 }
3446 }
3447 else
3448 {
3449 Assert(!pAllocation->pvMem);
3450 }
3451 }
3452 else
3453 {
3454 for (UINT j = 0; j < i; ++j)
3455 {
3456 pRc->aAllocations[j].pD3DIf->Release();
3457 }
3458 break;
3459 }
3460 }
3461 }
3462 else if (pResource->Flags.IndexBuffer)
3463 {
3464 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
3465 Assert(pScreen->hWnd);
3466 Assert(pScreen->pDevice9If);
3467 for (UINT i = 0; i < pResource->SurfCount; ++i)
3468 {
3469 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3470 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
3471 IDirect3DIndexBuffer9 *pD3D9IBuf;
3472 hr = pScreen->pDevice9If->CreateIndexBuffer(pSurf->Width,
3473 vboxDDI2D3DUsage(pResource->Flags),
3474 vboxDDI2D3DFormat(pResource->Format),
3475 vboxDDI2D3DPool(pResource->Pool),
3476 &pD3D9IBuf,
3477 NULL /*HANDLE* pSharedHandle*/
3478 );
3479 Assert(hr == S_OK);
3480 if (hr == S_OK)
3481 {
3482 Assert(pD3D9IBuf);
3483 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_INDEXBUFFER;
3484 pAllocation->pD3DIf = pD3D9IBuf;
3485 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
3486 {
3487 Assert(pAllocation->pvMem);
3488 D3DLOCKED_RECT lockInfo;
3489 hr = pD3D9IBuf->Lock(0, pAllocation->SurfDesc.width, &lockInfo.pBits, D3DLOCK_DISCARD);
3490 Assert(hr == S_OK);
3491 if (hr == S_OK)
3492 {
3493 lockInfo.Pitch = pAllocation->SurfDesc.pitch;
3494 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
3495 HRESULT tmpHr = pD3D9IBuf->Unlock();
3496 Assert(tmpHr == S_OK);
3497 }
3498 }
3499 else
3500 {
3501 Assert(!pAllocation->pvMem);
3502 }
3503 }
3504 else
3505 {
3506 for (UINT j = 0; j < i; ++j)
3507 {
3508 pRc->aAllocations[j].pD3DIf->Release();
3509 }
3510 break;
3511 }
3512 }
3513 }
3514 else if (pResource->Flags.Texture || pResource->Flags.Value == 0)
3515 {
3516 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
3517 Assert(pScreen->hWnd);
3518 Assert(pScreen->pDevice9If);
3519#ifdef DEBUG
3520 {
3521 uint32_t tstW = pResource->pSurfList[0].Width;
3522 uint32_t tstH = pResource->pSurfList[0].Height;
3523 for (UINT i = 1; i < pResource->SurfCount; ++i)
3524 {
3525 tstW /= 2;
3526 tstH /= 2;
3527 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
3528 Assert((pSurf->Width == tstW) || (!tstW && (pSurf->Width==1)));
3529 Assert((pSurf->Height == tstH) || (!tstH && (pSurf->Height==1)));
3530 }
3531 }
3532#endif
3533
3534 if (pResource->Flags.RenderTarget)
3535 bIssueCreateResource = true;
3536
3537 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
3538 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[0];
3539 IDirect3DTexture9 *pD3DIfTex;
3540 HANDLE hSharedHandle = NULL;
3541#if 0
3542 hr = pScreen->pDevice9If->CreateTexture(pSurf->Width,
3543 pSurf->Height,
3544 pResource->SurfCount,
3545 vboxDDI2D3DUsage(pResource->Flags),
3546 vboxDDI2D3DFormat(pResource->Format),
3547 vboxDDI2D3DPool(pResource->Pool),
3548 &pD3DIfTex,
3549 NULL /* HANDLE* pSharedHandle */
3550 );
3551#else
3552 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pScreen->pDevice9If,
3553 pSurf->Width,
3554 pSurf->Height,
3555 pResource->SurfCount,
3556 vboxDDI2D3DUsage(pResource->Flags),
3557 vboxDDI2D3DFormat(pResource->Format),
3558 vboxDDI2D3DPool(pResource->Pool),
3559 &pD3DIfTex,
3560 pResource->Flags.SharedResource ? &hSharedHandle : NULL,
3561 pResource->Pool == D3DDDIPOOL_SYSTEMMEM ? pRc->aAllocations[0].pvMem : NULL);
3562#endif
3563 Assert(hr == S_OK);
3564 if (hr == S_OK)
3565 {
3566 Assert(pD3DIfTex);
3567 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
3568 pAllocation->pD3DIf = pD3DIfTex;
3569 Assert(!!(pResource->Flags.SharedResource) == !!(hSharedHandle));
3570 pAllocation->hSharedHandle = hSharedHandle;
3571#if 0
3572 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
3573 {
3574 for (UINT i = 0; i < pResource->SurfCount; ++i)
3575 {
3576 D3DLOCKED_RECT lockInfo;
3577 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3578 Assert(pAllocation->pvMem);
3579 hr = pD3DIfTex->LockRect(i, &lockInfo, NULL, D3DLOCK_DISCARD);
3580 Assert(hr == S_OK);
3581 if (hr == S_OK)
3582 {
3583 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
3584 HRESULT tmpHr = pD3DIfTex->UnlockRect(i);
3585 Assert(tmpHr == S_OK);
3586 }
3587 else
3588 {
3589 pD3DIfTex->Release();
3590 break;
3591 }
3592 }
3593 }
3594#endif
3595 }
3596#ifdef DEBUG
3597 else
3598 {
3599 for (UINT i = 0; i < pResource->SurfCount; ++i)
3600 {
3601 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3602 Assert(!pAllocation->pvMem);
3603 }
3604 }
3605#endif
3606 }
3607 else if (pResource->Flags.RenderTarget)
3608 {
3609 HWND hWnd = NULL;
3610 bIssueCreateResource = true;
3611 Assert(pResource->SurfCount);
3612 IDirect3DDevice9 *pPrimaryDevice = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
3613 if (!pPrimaryDevice || pResource->Flags.Primary)
3614 {
3615 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pResource->VidPnSourceId];
3616 Assert(!pScreen->pDevice9If);
3617 Assert(!pScreen->hWnd);
3618 hr = VBoxDispWndCreate(pAdapter, pResource->pSurfList[0].Width, pResource->pSurfList[0].Height, &hWnd);
3619 Assert(hr == S_OK);
3620 if (hr == S_OK)
3621 {
3622 pScreen->hWnd = hWnd;
3623
3624 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
3625 if (pDevice->fFlags.AllowMultithreading)
3626 fFlags |= D3DCREATE_MULTITHREADED;
3627
3628 IDirect3DDevice9 *pDevice9If = NULL;
3629 D3DPRESENT_PARAMETERS params;
3630 memset(&params, 0, sizeof (params));
3631 params.BackBufferWidth = pResource->pSurfList[0].Width;
3632 params.BackBufferHeight = pResource->pSurfList[0].Height;
3633 params.BackBufferFormat = vboxDDI2D3DFormat(pResource->Format);
3634 Assert(pResource->SurfCount);
3635 params.BackBufferCount = !pPrimaryDevice ? pResource->SurfCount - 1 : 0;
3636 params.MultiSampleType = vboxDDI2D3DMultiSampleType(pResource->MultisampleType);
3637 if (pResource->Flags.DiscardRenderTarget)
3638 params.SwapEffect = D3DSWAPEFFECT_DISCARD;
3639 params.hDeviceWindow = hWnd;
3640 /* @todo: it seems there should be a way to detect this correctly since
3641 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
3642 params.Windowed = TRUE;
3643 // params.EnableAutoDepthStencil = FALSE;
3644 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
3645 // params.Flags;
3646 // params.FullScreen_RefreshRateInHz;
3647 // params.FullScreen_PresentationInterval;
3648 hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, fFlags, &params, &pDevice9If);
3649 Assert(hr == S_OK);
3650 if (hr == S_OK)
3651 {
3652 pScreen->pDevice9If = pDevice9If;
3653 pScreen->pRenderTargetRc = pRc;
3654 ++pDevice->cScreens;
3655
3656 for (UINT i = 0; i < pResource->SurfCount; ++i)
3657 {
3658 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3659 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
3660 }
3661
3662 if (pPrimaryDevice)
3663 {
3664 for (UINT i = 0; i < pResource->SurfCount; ++i)
3665 {
3666 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3667 IDirect3DSurface9 *pRt;
3668 IDirect3DSurface9 *pSecondaryOpenedRt;
3669 HANDLE hSharedHandle = NULL;
3670 hr = pPrimaryDevice->CreateRenderTarget(
3671 pResource->pSurfList[i].Width,
3672 pResource->pSurfList[i].Height,
3673 vboxDDI2D3DFormat(pResource->Format),
3674 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
3675 0, /*DWORD MultisampleQuality*/
3676 TRUE, /*BOOL Lockable*/
3677 &pRt,
3678 &hSharedHandle);
3679 Assert(hr == S_OK);
3680 if (hr == S_OK)
3681 {
3682 Assert(hSharedHandle != NULL);
3683 /* open render target for primary device */
3684 hr = pDevice9If->CreateRenderTarget(
3685 pResource->pSurfList[i].Width,
3686 pResource->pSurfList[i].Height,
3687 vboxDDI2D3DFormat(pResource->Format),
3688 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
3689 0, /*DWORD MultisampleQuality*/
3690 TRUE, /*BOOL Lockable*/
3691 &pSecondaryOpenedRt,
3692 &hSharedHandle);
3693 Assert(hr == S_OK);
3694 if (hr == S_OK)
3695 {
3696 pAllocation->pD3DIf = pRt;
3697 pAllocation->pSecondaryOpenedD3DIf = pSecondaryOpenedRt;
3698 pAllocation->hSharedHandle = hSharedHandle;
3699 continue;
3700 }
3701 pRt->Release();
3702 }
3703
3704 for (UINT j = 0; j < i; ++j)
3705 {
3706 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[j];
3707 pAlloc->pD3DIf->Release();
3708 pAlloc->pSecondaryOpenedD3DIf->Release();
3709 }
3710
3711 break;
3712 }
3713 }
3714 else
3715 {
3716 pDevice->iPrimaryScreen = pResource->VidPnSourceId;
3717 }
3718
3719 if (hr == S_OK)
3720 {
3721 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0);
3722 Assert(hr == S_OK);
3723 if (hr == S_OK)
3724 {
3725 for (UINT i = 0; i < pResource->SurfCount; ++i)
3726 {
3727 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3728 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
3729 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
3730 Assert(hr == S_OK);
3731 if (hr != S_OK)
3732 {
3733 break;
3734 }
3735 }
3736
3737#ifndef VBOXWDDM_WITH_VISIBLE_FB
3738 if (!pPrimaryDevice)
3739 {
3740 if (hr == S_OK)
3741 {
3742 IDirect3DSurface9* pD3D9Surf;
3743 hr = pDevice9If->CreateRenderTarget(pRc->aAllocations[0].SurfDesc.width,
3744 pRc->aAllocations[0].SurfDesc.height,
3745 vboxDDI2D3DFormat(pResource->Format),
3746 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
3747 pResource->MultisampleQuality,
3748 !pResource->Flags.NotLockable /* BOOL Lockable */,
3749 &pD3D9Surf,
3750 NULL /* HANDLE* pSharedHandle */
3751 );
3752 Assert(hr == S_OK);
3753 if (hr == S_OK)
3754 {
3755 pDevice->pRenderTargetFbCopy = pD3D9Surf;
3756 }
3757 }
3758 }
3759#endif
3760
3761 if (hr != S_OK)
3762 {
3763 for (UINT i = 0; i < pResource->SurfCount; ++i)
3764 {
3765 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3766 pAllocation->pD3DIf->Release();
3767 }
3768 }
3769 }
3770 }
3771
3772 if (hr != S_OK)
3773 {
3774 pDevice9If->Release();
3775 --pDevice->cScreens;
3776 Assert(pDevice->cScreens < UINT32_MAX/2);
3777 }
3778 }
3779
3780 if (hr != S_OK)
3781 {
3782 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pScreen->hWnd);
3783 Assert(tmpHr == S_OK);
3784 }
3785 }
3786
3787
3788 }
3789 else
3790 {
3791 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
3792 Assert(pScreen->hWnd);
3793 Assert(pScreen->pDevice9If);
3794 for (UINT i = 0; i < pResource->SurfCount; ++i)
3795 {
3796 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3797
3798 IDirect3DSurface9* pD3D9Surf;
3799 hr = pScreen->pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
3800 pAllocation->SurfDesc.height,
3801 vboxDDI2D3DFormat(pResource->Format),
3802 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
3803 pResource->MultisampleQuality,
3804 !pResource->Flags.NotLockable /* BOOL Lockable */,
3805 &pD3D9Surf,
3806 NULL /* HANDLE* pSharedHandle */
3807 );
3808 Assert(hr == S_OK);
3809 if (hr == S_OK)
3810 {
3811 Assert(pD3D9Surf);
3812 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
3813 pAllocation->pD3DIf = pD3D9Surf;
3814 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
3815 Assert(hr == S_OK);
3816 if (hr == S_OK)
3817 continue;
3818
3819 /* fail branch */
3820 pD3D9Surf->Release();
3821 }
3822
3823 for (UINT j = 0; j < i; ++j)
3824 {
3825 pRc->aAllocations[j].pD3DIf->Release();
3826 }
3827 break;
3828 }
3829 }
3830 }
3831 else
3832 {
3833 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
3834 Assert(pScreen->hWnd);
3835 Assert(pScreen->pDevice9If);
3836 Assert(0);
3837 }
3838 }
3839 else
3840 {
3841 bIssueCreateResource = true;
3842 }
3843
3844
3845 if (hr == S_OK && bIssueCreateResource)
3846 {
3847 D3DDDICB_ALLOCATE *pDdiAllocate = vboxWddmRequestAllocAlloc(pResource);
3848 Assert(pDdiAllocate);
3849 if (pDdiAllocate)
3850 {
3851 Assert(pDdiAllocate->pPrivateDriverData);
3852 Assert(pDdiAllocate->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
3853 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)pDdiAllocate->pPrivateDriverData;
3854 pRcInfo->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
3855 pRcInfo->RcDesc = pRc->RcDesc;
3856 pRcInfo->cAllocInfos = pResource->SurfCount;
3857
3858 for (UINT i = 0; i < pResource->SurfCount; ++i)
3859 {
3860 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
3861 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3862 Assert(pDdiAllocI->pPrivateDriverData);
3863 Assert(pDdiAllocI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
3864 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
3865 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
3866 pDdiAllocI->hAllocation = NULL;
3867 pDdiAllocI->pSystemMem = pSurf->pSysMem;
3868 Assert((!!(pSurf->pSysMem)) == (pResource->Pool == D3DDDIPOOL_SYSTEMMEM));
3869 pDdiAllocI->VidPnSourceId = pResource->VidPnSourceId;
3870 pDdiAllocI->Flags.Value = 0;
3871 if (pResource->Flags.Primary)
3872 {
3873 Assert(pResource->Flags.RenderTarget);
3874 pDdiAllocI->Flags.Primary = 1;
3875 }
3876
3877 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
3878 pAllocInfo->fFlags = pResource->Flags;
3879 pAllocInfo->hSharedHandle = pAllocation->hSharedHandle;
3880 pAllocInfo->SurfDesc.width = pSurf->Width;
3881 pAllocInfo->SurfDesc.height = pSurf->Height;
3882 pAllocInfo->SurfDesc.format = pResource->Format;
3883 if (!vboxWddmFormatToFourcc(pResource->Format))
3884 pAllocInfo->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
3885 else
3886 pAllocInfo->SurfDesc.bpp = 0;
3887
3888 if (pSurf->SysMemPitch)
3889 {
3890 pAllocInfo->SurfDesc.pitch = pSurf->SysMemPitch;
3891#ifdef DEBUG
3892 UINT tst = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
3893 Assert(tst == pSurf->SysMemPitch);
3894#endif
3895 }
3896 else
3897 pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
3898
3899 pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
3900 pAllocInfo->SurfDesc.depth = pSurf->Depth;
3901 pAllocInfo->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
3902 pAllocInfo->SurfDesc.VidPnSourceId = pResource->VidPnSourceId;
3903 pAllocInfo->SurfDesc.RefreshRate = pResource->RefreshRate;
3904 }
3905
3906 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
3907 Assert(hr == S_OK);
3908 Assert(pDdiAllocate->hKMResource);
3909 if (hr == S_OK)
3910 {
3911 pRc->hKMResource = pDdiAllocate->hKMResource;
3912
3913 for (UINT i = 0; i < pResource->SurfCount; ++i)
3914 {
3915 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
3916 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
3917 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
3918 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
3919 pAllocation->hAllocation = pDdiAllocI->hAllocation;
3920 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
3921 pAllocation->pvMem = (void*)pSurf->pSysMem;
3922 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
3923 }
3924 }
3925
3926 vboxWddmRequestAllocFree(pDdiAllocate);
3927 }
3928 else
3929 {
3930 hr = E_OUTOFMEMORY;
3931 }
3932 }
3933
3934 if (hr == S_OK)
3935 pResource->hResource = pRc;
3936 else
3937 vboxResourceFree(pRc);
3938 }
3939 else
3940 {
3941 hr = E_OUTOFMEMORY;
3942 }
3943
3944
3945 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3946 return hr;
3947}
3948
3949static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource)
3950{
3951 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3952 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3953 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
3954 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hResource;
3955
3956 HRESULT hr = S_OK;
3957
3958 Assert(pDevice);
3959 Assert(hResource);
3960
3961 if (VBOXDISPMODE_IS_3D(pAdapter))
3962 {
3963// if (pRc->RcDesc.fFlags.RenderTarget)
3964// {
3965// Assert(pDevice->hWnd);
3966// Assert(pDevice->pDevice9If);
3967// }
3968
3969 for (UINT i = 0; i < pRc->cAllocations; ++i)
3970 {
3971 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
3972 if (pAlloc->pD3DIf)
3973 pAlloc->pD3DIf->Release();
3974 if (pAlloc->pSecondaryOpenedD3DIf)
3975 pAlloc->pSecondaryOpenedD3DIf->Release();
3976 }
3977 }
3978
3979 Assert(pRc->hResource);
3980 Assert(pRc->hKMResource || VBOXDISPMODE_IS_3D(pAdapter));
3981 if (pRc->hKMResource)
3982 {
3983 if (!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED))
3984 {
3985 D3DDDICB_DEALLOCATE Dealloc;
3986 Dealloc.hResource = pRc->hResource;
3987 /* according to the docs the below two are ignored in case we set the hResource */
3988 Dealloc.NumAllocations = 0;
3989 Dealloc.HandleList = NULL;
3990 hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
3991 Assert(hr == S_OK);
3992// for (UINT j = 0; j < pRc->cAllocations; ++j)
3993// {
3994// D3DDDICB_DEALLOCATE Dealloc;
3995// Dealloc.hResource = NULL;
3996// Dealloc.NumAllocations = 1;
3997// Dealloc.HandleList = &pRc->aAllocations[j].hAllocation;
3998// HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
3999// Assert(tmpHr = S_OK);
4000// }
4001 }
4002 }
4003
4004 vboxResourceFree(pRc);
4005 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4006 return hr;
4007}
4008static HRESULT APIENTRY vboxWddmDDevSetDisplayMode(HANDLE hDevice, CONST D3DDDIARG_SETDISPLAYMODE* pData)
4009{
4010 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4011 HRESULT hr = S_OK;
4012 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4013 Assert(pDevice);
4014 Assert(VBOXDISPMODE_IS_3D(pDevice->pAdapter));
4015 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4016 Assert(pRc);
4017 Assert(pRc->cAllocations > pData->SubResourceIndex);
4018 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4019 Assert(pRc->RcDesc.fFlags.RenderTarget);
4020 Assert(pRc->RcDesc.fFlags.Primary);
4021 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
4022 Assert(pAlloc->hAllocation);
4023 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
4024 Assert(pScreen->hWnd);
4025 Assert(pScreen->pDevice9If);
4026 D3DDDICB_SETDISPLAYMODE DdiDm = {0};
4027 DdiDm.hPrimaryAllocation = pAlloc->hAllocation;
4028// DdiDm.PrivateDriverFormatAttribute = 0;
4029 Assert(pScreen->pRenderTargetRc == pRc);
4030 Assert(pScreen->iRenderTargetFrontBuf == pData->SubResourceIndex);
4031
4032#if 0
4033 IDirect3DSurface9 *pSoD3DIfSurf = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
4034 hr = pScreen->pDevice9If->SetRenderTarget(0, pSoD3DIfSurf);
4035 Assert(hr == S_OK);
4036 if (hr == S_OK)
4037#endif
4038 {
4039 hr = pDevice->RtCallbacks.pfnSetDisplayModeCb(pDevice->hDevice, &DdiDm);
4040 Assert(hr == S_OK);
4041 }
4042
4043 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4044 return hr;
4045}
4046static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRESENT* pData)
4047{
4048 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4049 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4050 Assert(pDevice);
4051 HRESULT hr = S_OK;
4052 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4053 {
4054 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
4055 Assert(pRc);
4056 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
4057 Assert(pScreen->hWnd);
4058 Assert(pScreen->pDevice9If);
4059 Assert(pRc == pScreen->pRenderTargetRc);
4060#if 1
4061 VBOXVDBG_RTGT_STATECHECK(pDevice);
4062
4063 if (pRc->RcDesc.VidPnSourceId != pDevice->iPrimaryScreen)
4064 {
4065 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
4066 IDirect3DSurface9 *pSecondaryRt;
4067 IDirect3DSurface9 *pDataRt = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
4068 Assert(pDataRt);
4069 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
4070 hr = pScreen->pDevice9If->GetRenderTarget(0, &pSecondaryRt);
4071 Assert(hr == S_OK);
4072 if (hr == S_OK)
4073 {
4074 hr = pScreen->pDevice9If->StretchRect(pDataRt,
4075 NULL,
4076 pSecondaryRt,
4077 NULL,
4078 D3DTEXF_NONE);
4079 pSecondaryRt->Release();
4080 }
4081 }
4082
4083 hr = pScreen->pDevice9If->Present(NULL, /* CONST RECT * pSourceRect */
4084 NULL, /* CONST RECT * pDestRect */
4085 NULL, /* HWND hDestWindowOverride */
4086 NULL /*CONST RGNDATA * pDirtyRegion */
4087 );
4088 Assert(hr == S_OK);
4089#endif
4090 }
4091#if 0
4092 else
4093#endif
4094 {
4095 if (pData->Flags.Flip)
4096 {
4097 Assert(pData->hSrcResource);
4098 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
4099 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
4100 Assert(pScreen->hWnd);
4101 Assert(pScreen->pDevice9If);
4102 Assert(pScreen->pRenderTargetRc == pRc);
4103 Assert(pRc->cAllocations >= 2);
4104 Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
4105 Assert(pRc->RcDesc.fFlags.RenderTarget);
4106 uint32_t iNewRTFB = (pScreen->iRenderTargetFrontBuf + 1) % pRc->cAllocations;
4107
4108 Assert(pScreen->iRenderTargetFrontBuf != iNewRTFB);
4109 Assert(pData->SrcSubResourceIndex == iNewRTFB);
4110
4111 vboxWddmRenderTargetUpdate(pDevice, pRc, iNewRTFB);
4112
4113 /* assign a new frontbuffer index */
4114 pScreen->iRenderTargetFrontBuf = iNewRTFB;
4115
4116 VBOXVDBG_RTGT_STATECHECK(pDevice);
4117 }
4118 D3DDDICB_PRESENT DdiPresent = {0};
4119 if (pData->hSrcResource)
4120 {
4121 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
4122 Assert(pRc->hKMResource);
4123 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
4124 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
4125 Assert(pAlloc->hAllocation);
4126 DdiPresent.hSrcAllocation = pAlloc->hAllocation;
4127 }
4128 if (pData->hDstResource)
4129 {
4130 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
4131 Assert(pRc->hKMResource);
4132 Assert(pRc->cAllocations > pData->DstSubResourceIndex);
4133 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->DstSubResourceIndex];
4134 Assert(pAlloc->hAllocation);
4135 DdiPresent.hDstAllocation = pAlloc->hAllocation;
4136 }
4137 DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext;
4138// DdiPresent.BroadcastContextCount;
4139// DdiPresent.BroadcastContext[D3DDDI_MAX_BROADCAST_CONTEXT];
4140
4141 hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent);
4142 Assert(hr == S_OK);
4143 }
4144 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4145 return hr;
4146}
4147static HRESULT APIENTRY vboxWddmDDevFlush(HANDLE hDevice)
4148{
4149 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4150 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4151 Assert(pDevice);
4152 HRESULT hr = S_OK;
4153 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4154 {
4155 Assert(pDevice->cScreens);
4156 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aScreens); ++i)
4157 {
4158 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i];
4159 if (pScreen->pDevice9If)
4160 {
4161 /* @todo: make a flush */
4162 }
4163 }
4164 }
4165 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4166 return hr;
4167}
4168
4169AssertCompile(sizeof (D3DDDIVERTEXELEMENT) == sizeof (D3DVERTEXELEMENT9));
4170AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Stream) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Stream));
4171AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Offset) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Offset));
4172AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Type) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Type));
4173AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Method) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Method));
4174AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Usage) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Usage));
4175AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, UsageIndex) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, UsageIndex));
4176
4177AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Stream) == RT_OFFSETOF(D3DVERTEXELEMENT9, Stream));
4178AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Offset) == RT_OFFSETOF(D3DVERTEXELEMENT9, Offset));
4179AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Type) == RT_OFFSETOF(D3DVERTEXELEMENT9, Type));
4180AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Method) == RT_OFFSETOF(D3DVERTEXELEMENT9, Method));
4181AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Usage) == RT_OFFSETOF(D3DVERTEXELEMENT9, Usage));
4182AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, UsageIndex) == RT_OFFSETOF(D3DVERTEXELEMENT9, UsageIndex));
4183
4184static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderDecl(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERDECL* pData, CONST D3DDDIVERTEXELEMENT* pVertexElements)
4185{
4186 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4187 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4188 Assert(pDevice);
4189 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4190 Assert(pScreen->hWnd);
4191 Assert(pScreen->pDevice9If);
4192 IDirect3DVertexDeclaration9 *pDecl;
4193 static D3DVERTEXELEMENT9 DeclEnd = D3DDECL_END();
4194 D3DVERTEXELEMENT9* pVe;
4195 HRESULT hr = S_OK;
4196 bool bFreeVe = false;
4197 if(memcmp(&DeclEnd, &pVertexElements[pData->NumVertexElements], sizeof (DeclEnd)))
4198 {
4199 pVe = (D3DVERTEXELEMENT9*)RTMemAlloc(sizeof (D3DVERTEXELEMENT9) * (pData->NumVertexElements + 1));
4200 if (pVe)
4201 {
4202 memcpy(pVe, pVertexElements, sizeof (D3DVERTEXELEMENT9) * pData->NumVertexElements);
4203 pVe[pData->NumVertexElements] = DeclEnd;
4204 bFreeVe = true;
4205 }
4206 else
4207 hr = E_OUTOFMEMORY;
4208 }
4209 else
4210 pVe = (D3DVERTEXELEMENT9*)pVertexElements;
4211
4212 if (hr == S_OK)
4213 {
4214 hr = pScreen->pDevice9If->CreateVertexDeclaration(
4215 pVe,
4216 &pDecl
4217 );
4218 Assert(hr == S_OK);
4219 if (hr == S_OK)
4220 {
4221 Assert(pDecl);
4222 pData->ShaderHandle = pDecl;
4223 }
4224 }
4225
4226 if (bFreeVe)
4227 RTMemFree((void*)pVe);
4228
4229 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4230 return hr;
4231}
4232static HRESULT APIENTRY vboxWddmDDevSetVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
4233{
4234 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4235 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4236 Assert(pDevice);
4237 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4238 Assert(pScreen->hWnd);
4239 Assert(pScreen->pDevice9If);
4240 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
4241 Assert(pDecl);
4242 HRESULT hr = pScreen->pDevice9If->SetVertexDeclaration(pDecl);
4243 Assert(hr == S_OK);
4244 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4245 return hr;
4246}
4247static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
4248{
4249 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4250 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4251 Assert(pDevice);
4252 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4253 Assert(pScreen->hWnd);
4254 Assert(pScreen->pDevice9If);
4255 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
4256 HRESULT hr = S_OK;
4257 pDecl->Release();
4258 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4259 return hr;
4260}
4261static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderFunc(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERFUNC* pData, CONST UINT* pCode)
4262{
4263 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4264 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4265 Assert(pDevice);
4266 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4267 Assert(pScreen->hWnd);
4268 Assert(pScreen->pDevice9If);
4269 IDirect3DVertexShader9 *pShader;
4270 Assert(*((UINT*)((uint8_t*)pCode + pData->Size-4)) == 0x0000FFFF /* end token */);
4271 HRESULT hr = pScreen->pDevice9If->CreateVertexShader((const DWORD *)pCode, &pShader);
4272 Assert(hr == S_OK);
4273 if (hr == S_OK)
4274 {
4275 Assert(pShader);
4276 pData->ShaderHandle = pShader;
4277 }
4278 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4279 return hr;
4280}
4281static HRESULT APIENTRY vboxWddmDDevSetVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
4282{
4283 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4284 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4285 Assert(pDevice);
4286 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4287 Assert(pScreen->hWnd);
4288 Assert(pScreen->pDevice9If);
4289 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
4290 Assert(pShader);
4291 HRESULT hr = pScreen->pDevice9If->SetVertexShader(pShader);
4292 Assert(hr == S_OK);
4293 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4294 return hr;
4295}
4296static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
4297{
4298 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4299 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4300 Assert(pDevice);
4301 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4302 Assert(pScreen->hWnd);
4303 Assert(pScreen->pDevice9If);
4304 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
4305 HRESULT hr = S_OK;
4306 pShader->Release();
4307 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4308 return hr;
4309}
4310static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTI* pData, CONST INT* pRegisters)
4311{
4312 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4313 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4314 Assert(pDevice);
4315 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4316 Assert(pScreen->hWnd);
4317 Assert(pScreen->pDevice9If);
4318 HRESULT hr = pScreen->pDevice9If->SetVertexShaderConstantI(pData->Register, pRegisters, pData->Count);
4319 Assert(hr == S_OK);
4320 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4321 return hr;
4322}
4323static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTB* pData, CONST BOOL* pRegisters)
4324{
4325 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4326 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4327 Assert(pDevice);
4328 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4329 Assert(pScreen->hWnd);
4330 Assert(pScreen->pDevice9If);
4331 HRESULT hr = pScreen->pDevice9If->SetVertexShaderConstantB(pData->Register, pRegisters, pData->Count);
4332 Assert(hr == S_OK);
4333 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4334 return hr;
4335}
4336static HRESULT APIENTRY vboxWddmDDevSetScissorRect(HANDLE hDevice, CONST RECT* pRect)
4337{
4338 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4339 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4340 Assert(pDevice);
4341 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4342 Assert(pScreen->hWnd);
4343 Assert(pScreen->pDevice9If);
4344 HRESULT hr = pScreen->pDevice9If->SetScissorRect(pRect);
4345 Assert(hr == S_OK);
4346 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4347 return hr;
4348}
4349static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCE* pData)
4350{
4351 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4352 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4353 Assert(pDevice);
4354 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4355 Assert(pScreen->hWnd);
4356 Assert(pScreen->pDevice9If);
4357 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hVertexBuffer;
4358 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
4359 IDirect3DVertexBuffer9 *pStreamData = NULL;
4360 if (pRc)
4361 {
4362 Assert(pRc->cAllocations == 1);
4363 pAlloc = &pRc->aAllocations[0];
4364 Assert(pAlloc->pD3DIf);
4365 pStreamData = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4366 }
4367 HRESULT hr = pScreen->pDevice9If->SetStreamSource(pData->Stream, pStreamData, pData->Offset, pData->Stride);
4368 Assert(hr == S_OK);
4369 Assert(pData->Stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS);
4370 if (hr == S_OK)
4371 {
4372 if (pDevice->aStreamSource[pData->Stream] && !pAlloc)
4373 {
4374 --pDevice->cStreamSources;
4375 Assert(pDevice->cStreamSources < UINT32_MAX/2);
4376 }
4377 else if (!pDevice->aStreamSource[pData->Stream] && pAlloc)
4378 {
4379 ++pDevice->cStreamSources;
4380 Assert(pDevice->cStreamSources <= RT_ELEMENTS(pDevice->aStreamSource));
4381 }
4382 pDevice->aStreamSource[pData->Stream] = pAlloc;
4383 pDevice->StreamSourceInfo[pData->Stream].uiOffset = pData->Offset;
4384 pDevice->StreamSourceInfo[pData->Stream].uiStride = pData->Stride;
4385 }
4386 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4387 return hr;
4388}
4389static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData)
4390{
4391 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4392 Assert(0);
4393 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4394 return E_FAIL;
4395}
4396static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData)
4397{
4398 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4399 Assert(0);
4400 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4401 return E_FAIL;
4402}
4403static HRESULT APIENTRY vboxWddmDDevComposeRects(HANDLE hDevice, CONST D3DDDIARG_COMPOSERECTS* pData)
4404{
4405 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4406 Assert(0);
4407 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4408 return E_FAIL;
4409}
4410static HRESULT vboxWddmLockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc,
4411 D3DLOCKED_RECT * pLockedRect,
4412 CONST RECT *pRect,
4413 DWORD fLockFlags)
4414{
4415 HRESULT hr = E_FAIL;
4416 Assert(!pRc->aAllocations[iAlloc].LockInfo.cLocks);
4417 Assert(pRc->cAllocations > iAlloc);
4418 switch (pRc->aAllocations[0].enmD3DIfType)
4419 {
4420 case VBOXDISP_D3DIFTYPE_SURFACE:
4421 {
4422 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
4423 Assert(pD3DIfSurf);
4424 hr = pD3DIfSurf->LockRect(pLockedRect, pRect, fLockFlags);
4425 Assert(hr == S_OK);
4426 break;
4427 }
4428 case VBOXDISP_D3DIFTYPE_TEXTURE:
4429 {
4430 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
4431 Assert(pD3DIfTex);
4432 hr = pD3DIfTex->LockRect(iAlloc, pLockedRect, pRect, fLockFlags);
4433 Assert(hr == S_OK);
4434 break;
4435 }
4436 default:
4437 Assert(0);
4438 break;
4439 }
4440 return hr;
4441}
4442static HRESULT vboxWddmUnlockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc)
4443{
4444 HRESULT hr = S_OK;
4445 Assert(pRc->cAllocations > iAlloc);
4446 switch (pRc->aAllocations[0].enmD3DIfType)
4447 {
4448 case VBOXDISP_D3DIFTYPE_SURFACE:
4449 {
4450 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
4451 Assert(pD3DIfSurf);
4452 hr = pD3DIfSurf->UnlockRect();
4453 Assert(hr == S_OK);
4454 break;
4455 }
4456 case VBOXDISP_D3DIFTYPE_TEXTURE:
4457 {
4458 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
4459 Assert(pD3DIfTex);
4460 hr = pD3DIfTex->UnlockRect(iAlloc);
4461 Assert(hr == S_OK);
4462 break;
4463 }
4464 default:
4465 Assert(0);
4466 hr = E_FAIL;
4467 break;
4468 }
4469 return hr;
4470}
4471
4472/* on success increments the surface ref counter,
4473 * i.e. one must call pSurf->Release() once the surface is not needed*/
4474static HRESULT vboxWddmSurfGet(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc, IDirect3DSurface9 **ppSurf)
4475{
4476 HRESULT hr = S_OK;
4477 Assert(pRc->cAllocations > iAlloc);
4478 switch (pRc->aAllocations[0].enmD3DIfType)
4479 {
4480 case VBOXDISP_D3DIFTYPE_SURFACE:
4481 {
4482 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
4483 Assert(pD3DIfSurf);
4484 pD3DIfSurf->AddRef();
4485 *ppSurf = pD3DIfSurf;
4486 break;
4487 }
4488 case VBOXDISP_D3DIFTYPE_TEXTURE:
4489 {
4490 Assert(pRc->cAllocations == 1); /* <- vboxWddmSurfGet is typically used in Blt & ColorFill functions
4491 * in this case, if texture is used as a destination,
4492 * we should update sub-layers as well which is not done currently
4493 * so for now check vboxWddmSurfGet is used for one-level textures */
4494 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
4495 IDirect3DSurface9 *pSurfaceLevel;
4496 Assert(pD3DIfTex);
4497 hr = pD3DIfTex->GetSurfaceLevel(iAlloc, &pSurfaceLevel);
4498 Assert(hr == S_OK);
4499 if (hr == S_OK)
4500 {
4501 *ppSurf = pSurfaceLevel;
4502 }
4503 break;
4504 }
4505 default:
4506 Assert(0);
4507 hr = E_FAIL;
4508 break;
4509 }
4510 return hr;
4511}
4512
4513static HRESULT APIENTRY vboxWddmDDevBlt(HANDLE hDevice, CONST D3DDDIARG_BLT* pData)
4514{
4515 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4516 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4517 Assert(pDevice);
4518 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4519 Assert(pScreen->hWnd);
4520 Assert(pScreen->pDevice9If);
4521 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
4522 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
4523 Assert(pDstRc->cAllocations > pData->DstSubResourceIndex);
4524 Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex);
4525 Assert(pDstRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->DstSubResourceIndex);
4526 HRESULT hr = S_OK;
4527 /* try StretchRect */
4528 IDirect3DSurface9 *pSrcSurfIf = NULL;
4529 IDirect3DSurface9 *pDstSurfIf = NULL;
4530 hr = vboxWddmSurfGet(pDstRc, pData->DstSubResourceIndex, &pDstSurfIf);
4531 Assert(hr == S_OK);
4532 if (hr == S_OK)
4533 {
4534 Assert(pDstSurfIf);
4535 do
4536 {
4537#ifndef VBOXWDDM_WITH_VISIBLE_FB
4538 if (pSrcRc == pScreen->pRenderTargetRc && pScreen->iRenderTargetFrontBuf == pData->SrcSubResourceIndex)
4539 {
4540 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
4541 PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
4542// Assert(pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width);
4543// Assert(pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height);
4544// Assert(pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format);
4545// Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
4546// Assert(pSrcAlloc->SurfDesc.pitch == pDstAlloc->SurfDesc.pitch);
4547// Assert(pSrcAlloc->SurfDesc.depth == pDstAlloc->SurfDesc.depth);
4548// Assert(pSrcAlloc->SurfDesc.slicePitch == pDstAlloc->SurfDesc.slicePitch);
4549// Assert(pSrcAlloc->SurfDesc.cbSize == pDstAlloc->SurfDesc.cbSize);
4550// Assert(pData->DstRect.left == 0);
4551// Assert(pData->DstRect.top == 0);
4552// Assert(pData->DstRect.right == pDstAlloc->SurfDesc.width);
4553// Assert(pData->DstRect.bottom == pDstAlloc->SurfDesc.height);
4554// Assert(pData->SrcRect.left == 0);
4555// Assert(pData->SrcRect.top == 0);
4556// Assert(pData->SrcRect.right == pSrcAlloc->SurfDesc.width);
4557// Assert(pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height);
4558#if 0
4559 if (pData->DstRect.left == 0 && pData->DstRect.top == 0
4560 && pData->DstRect.right == pDstAlloc->SurfDesc.width
4561 && pData->DstRect.bottom == pDstAlloc->SurfDesc.height
4562 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
4563 && pData->SrcRect.right == pSrcAlloc->SurfDesc.width
4564 && pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height
4565 && pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width
4566 && pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height
4567 && pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format)
4568 {
4569 hr = pScreen->pDevice9If->GetFrontBufferData(0, pDstSurfIf);
4570 Assert(hr == S_OK);
4571 break;
4572 }
4573 else
4574#endif
4575 {
4576 pSrcSurfIf = pDevice->pRenderTargetFbCopy;
4577 Assert(pSrcSurfIf);
4578 hr = pScreen->pDevice9If->GetFrontBufferData(0, pDevice->pRenderTargetFbCopy);
4579 Assert(hr == S_OK);
4580 if (hr == S_OK)
4581 {
4582 /* do pSrcSurfIf->AddRef since we do a Release in the following if (hr == S_OK) branch */
4583 pSrcSurfIf->AddRef();
4584 }
4585 }
4586 }
4587 else
4588#endif
4589 {
4590 hr = vboxWddmSurfGet(pSrcRc, pData->SrcSubResourceIndex, &pSrcSurfIf);
4591 Assert(hr == S_OK);
4592 }
4593
4594 if (hr == S_OK)
4595 {
4596 Assert(pSrcSurfIf);
4597#ifdef DEBUG_misha
4598 bool bDo = false;
4599
4600 if (g_VDbgTstDumpEnable)
4601 {
4602 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
4603 {
4604 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
4605 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
4606 {
4607 D3DSURFACE_DESC SrcDesc;
4608 HRESULT hr = pSrcSurfIf->GetDesc(&SrcDesc);
4609 Assert(hr == S_OK);
4610 if (hr == S_OK)
4611 {
4612 D3DSURFACE_DESC DstDesc;
4613 hr = pDstSurfIf->GetDesc(&DstDesc);
4614 Assert(hr == S_OK);
4615 if (hr == S_OK)
4616 {
4617 if (SrcDesc.Width == DstDesc.Width
4618 && SrcDesc.Height == DstDesc.Height)
4619 {
4620 bDo = true;
4621 }
4622 }
4623 }
4624 }
4625 }
4626 }
4627
4628 if (bDo)
4629 {
4630 vboxVDbgDumpSurfData((pDevice, "Blt-pre Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
4631 vboxVDbgDumpSurfData((pDevice, "Blt-pre Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
4632 }
4633#endif
4634 /* we support only Point & Linear, we ignore [Begin|Continue|End]PresentToDwm */
4635 Assert((pData->Flags.Value & (~(0x00000100 | 0x00000200 | 0x00000400 | 0x00000001 | 0x00000002))) == 0);
4636 hr = pScreen->pDevice9If->StretchRect(pSrcSurfIf,
4637 &pData->SrcRect,
4638 pDstSurfIf,
4639 &pData->DstRect,
4640 vboxDDI2D3DBltFlags(pData->Flags));
4641 Assert(hr == S_OK);
4642
4643#ifdef DEBUG_misha
4644 if (bDo)
4645 {
4646 vboxVDbgDumpSurfData((pDevice, "Blt-post Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
4647 vboxVDbgDumpSurfData((pDevice, "Blt-post Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
4648 }
4649#endif
4650 pSrcSurfIf->Release();
4651 }
4652 } while (0);
4653
4654 pDstSurfIf->Release();
4655 }
4656
4657 if (hr != S_OK)
4658 {
4659 /* todo: fallback to memcpy or whatever ? */
4660 Assert(0);
4661 }
4662
4663
4664#if 0
4665 if ((use pAlloc->enmD3DIfType instead!!! pDstRc->RcDesc.fFlags.Texture || pDstRc->RcDesc.fFlags.Value == 0)
4666 && (pSrcRc->RcDesc.fFlags.Texture || pSrcRc->RcDesc.fFlags.Value == 0))
4667 {
4668 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcAlloc->pD3DIf;
4669 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstAlloc->pD3DIf;
4670 Assert(pD3DIfSrcTex);
4671 Assert(pD3DIfDstTex);
4672
4673 if (pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat)
4674 {
4675 if (pSrcRc->aAllocations[0].SurfDesc.width == pDstRc->aAllocations[0].SurfDesc.width
4676 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
4677 && pData->DstRect.left == 0 && pData->DstRect.top == 0
4678 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
4679 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
4680 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height
4681 && pData->DstRect.right - pData->DstRect.left == pDstRc->aAllocations[0].SurfDesc.width
4682 && pData->DstRect.bottom - pData->DstRect.top == pDstRc->aAllocations[0].SurfDesc.height
4683 )
4684 {
4685 hr = pScreen->pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
4686 Assert(hr == S_OK);
4687 }
4688 else if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
4689 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
4690 {
4691 Assert(pDstAlloc->SurfDesc.bpp);
4692 Assert(pSrcAlloc->SurfDesc.bpp);
4693 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
4694 D3DLOCKED_RECT DstRect, SrcRect;
4695 Assert(!pSrcAlloc->LockInfo.cLocks);
4696 Assert(!pDstAlloc->LockInfo.cLocks);
4697 hr = pD3DIfDstTex->LockRect(pData->DstSubResourceIndex, &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
4698 Assert(hr == S_OK);
4699 if (hr == S_OK)
4700 {
4701 hr = pD3DIfSrcTex->LockRect(pData->SrcSubResourceIndex, &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
4702 Assert(hr == S_OK);
4703 if (hr == S_OK)
4704 {
4705 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
4706 &pData->DstRect, &pData->SrcRect,
4707 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
4708 Assert(hr == S_OK);
4709
4710 pD3DIfSrcTex->UnlockRect(pData->SrcSubResourceIndex);
4711 }
4712 pD3DIfDstTex->UnlockRect(pData->DstSubResourceIndex);
4713 }
4714 }
4715 else
4716 {
4717
4718 Assert(0);
4719 /* @todo: impl */
4720 }
4721 }
4722 else
4723 {
4724 Assert(0);
4725 /* @todo: impl */
4726 }
4727 }
4728 else
4729 {
4730 if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
4731 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
4732 {
4733 Assert(pDstAlloc->SurfDesc.bpp);
4734 Assert(pSrcAlloc->SurfDesc.bpp);
4735 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
4736
4737 D3DLOCKED_RECT DstRect, SrcRect;
4738 hr = vboxWddmLockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags,
4739 &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
4740 Assert(hr == S_OK);
4741 if (hr == S_OK)
4742 {
4743 hr = vboxWddmLockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags,
4744 &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
4745 Assert(hr == S_OK);
4746 if (hr == S_OK)
4747 {
4748 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
4749 &pData->DstRect, &pData->SrcRect,
4750 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
4751 Assert(hr == S_OK);
4752
4753 HRESULT tmpHr = vboxWddmUnlockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags);
4754 Assert(tmpHr == S_OK);
4755 }
4756 HRESULT tmpHr = vboxWddmUnlockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags);
4757 Assert(tmpHr == S_OK);
4758 }
4759 }
4760 else
4761 {
4762 Assert(0);
4763 /* @todo: impl */
4764 }
4765 }
4766#endif
4767
4768 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4769 return hr;
4770}
4771static HRESULT APIENTRY vboxWddmDDevColorFill(HANDLE hDevice, CONST D3DDDIARG_COLORFILL* pData)
4772{
4773 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4774 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4775 Assert(pDevice);
4776 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4777 Assert(pScreen->hWnd);
4778 Assert(pScreen->pDevice9If);
4779 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4780 Assert(pRc);
4781 IDirect3DSurface9 *pSurfIf = NULL;
4782 HRESULT hr = vboxWddmSurfGet(pRc, pData->SubResourceIndex, &pSurfIf);
4783 Assert(hr == S_OK);
4784 if (hr == S_OK)
4785 {
4786 Assert(pSurfIf);
4787 hr = pScreen->pDevice9If->ColorFill(pSurfIf, &pData->DstRect, pData->Color);
4788 Assert(hr == S_OK);
4789 /* @todo: check what need to do when PresentToDwm flag is set */
4790 Assert(pData->Flags.Value == 0);
4791
4792 pSurfIf->Release();
4793 }
4794 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4795 return hr;
4796}
4797static HRESULT APIENTRY vboxWddmDDevDepthFill(HANDLE hDevice, CONST D3DDDIARG_DEPTHFILL* pData)
4798{
4799 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4800 Assert(0);
4801 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4802 return E_FAIL;
4803}
4804static HRESULT APIENTRY vboxWddmDDevCreateQuery(HANDLE hDevice, D3DDDIARG_CREATEQUERY* pData)
4805{
4806 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4807 Assert(0);
4808 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4809 return E_FAIL;
4810}
4811static HRESULT APIENTRY vboxWddmDDevDestroyQuery(HANDLE hDevice, HANDLE hQuery)
4812{
4813 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4814 Assert(0);
4815 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4816 return E_FAIL;
4817}
4818static HRESULT APIENTRY vboxWddmDDevIssueQuery(HANDLE hDevice, CONST D3DDDIARG_ISSUEQUERY* pData)
4819{
4820 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4821 Assert(0);
4822 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4823 return E_FAIL;
4824}
4825static HRESULT APIENTRY vboxWddmDDevGetQueryData(HANDLE hDevice, CONST D3DDDIARG_GETQUERYDATA* pData)
4826{
4827 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4828 Assert(0);
4829 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4830 return E_FAIL;
4831}
4832static HRESULT APIENTRY vboxWddmDDevSetRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETRENDERTARGET* pData)
4833{
4834 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4835 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4836 Assert(pDevice);
4837 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4838 Assert(pScreen->hWnd);
4839 Assert(pScreen->pDevice9If);
4840 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget;
4841 Assert(pRc);
4842 Assert(pData->SubResourceIndex < pRc->cAllocations);
4843 PVBOXWDDMDISP_SCREEN pVisibleScreen = pRc->RcDesc.fFlags.Primary ? &pDevice->aScreens[pRc->RcDesc.VidPnSourceId] : pScreen;
4844 if (pRc == pVisibleScreen->pRenderTargetRc)
4845 {
4846 /* backbuffer */
4847 Assert(pData->SubResourceIndex == ((pVisibleScreen->iRenderTargetFrontBuf + 1) % pVisibleScreen->pRenderTargetRc->cAllocations));
4848 }
4849
4850 HRESULT hr = S_OK;
4851 IDirect3DSurface9 *pD3D9Surf;
4852 if (pRc == pScreen->pRenderTargetRc && pRc->cAllocations == 1 && pData->RenderTargetIndex == 0)
4853 {
4854 /* work-around wine double-buffering for the case we have no backbuffers */
4855 hr = pScreen->pDevice9If->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
4856 Assert(hr == S_OK);
4857 Assert(pD3D9Surf);
4858 }
4859 else
4860 {
4861 hr = vboxWddmSurfGet(pRc, pData->SubResourceIndex, &pD3D9Surf);
4862 Assert(hr == S_OK);
4863 Assert(pD3D9Surf);
4864 }
4865 if (hr == S_OK)
4866 {
4867 Assert(pD3D9Surf);
4868 hr = pScreen->pDevice9If->SetRenderTarget(pData->RenderTargetIndex, pD3D9Surf);
4869 Assert(hr == S_OK);
4870 pD3D9Surf->Release();
4871 }
4872 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4873 return hr;
4874}
4875static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDIARG_SETDEPTHSTENCIL* pData)
4876{
4877 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4878 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4879 Assert(pDevice);
4880 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4881 Assert(pScreen->hWnd);
4882 Assert(pScreen->pDevice9If);
4883 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hZBuffer;
4884 IDirect3DSurface9 *pD3D9Surf = NULL;
4885 if (pRc)
4886 {
4887 Assert(pRc->cAllocations == 1);
4888 pD3D9Surf = (IDirect3DSurface9*)pRc->aAllocations[0].pD3DIf;
4889 Assert(pD3D9Surf);
4890 }
4891 HRESULT hr = pScreen->pDevice9If->SetDepthStencilSurface(pD3D9Surf);
4892 Assert(hr == S_OK);
4893 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4894 return hr;
4895}
4896static HRESULT APIENTRY vboxWddmDDevGenerateMipSubLevels(HANDLE hDevice, CONST D3DDDIARG_GENERATEMIPSUBLEVELS* pData)
4897{
4898 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4899 Assert(0);
4900 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4901 return E_FAIL;
4902}
4903static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTI* pData, CONST INT* pRegisters)
4904{
4905 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4906 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4907 Assert(pDevice);
4908 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4909 Assert(pScreen->hWnd);
4910 Assert(pScreen->pDevice9If);
4911 HRESULT hr = pScreen->pDevice9If->SetPixelShaderConstantI(pData->Register, pRegisters, pData->Count);
4912 Assert(hr == S_OK);
4913 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4914 return hr;
4915}
4916static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTB* pData, CONST BOOL* pRegisters)
4917{
4918 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4919 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4920 Assert(pDevice);
4921 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4922 Assert(pScreen->hWnd);
4923 Assert(pScreen->pDevice9If);
4924 HRESULT hr = pScreen->pDevice9If->SetPixelShaderConstantB(pData->Register, pRegisters, pData->Count);
4925 Assert(hr == S_OK);
4926 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4927 return hr;
4928}
4929static HRESULT APIENTRY vboxWddmDDevCreatePixelShader(HANDLE hDevice, D3DDDIARG_CREATEPIXELSHADER* pData, CONST UINT* pCode)
4930{
4931 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4932 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4933 Assert(pDevice);
4934 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4935 Assert(pScreen->hWnd);
4936 Assert(pScreen->pDevice9If);
4937 IDirect3DPixelShader9 *pShader;
4938 Assert(*((UINT*)((uint8_t*)pCode + pData->CodeSize-4)) == 0x0000FFFF /* end token */);
4939 HRESULT hr = pScreen->pDevice9If->CreatePixelShader((const DWORD *)pCode, &pShader);
4940 Assert(hr == S_OK);
4941 if (hr == S_OK)
4942 {
4943 Assert(pShader);
4944 pData->ShaderHandle = pShader;
4945 }
4946 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4947 return hr;
4948}
4949static HRESULT APIENTRY vboxWddmDDevDeletePixelShader(HANDLE hDevice, HANDLE hShaderHandle)
4950{
4951 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4952 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4953 Assert(pDevice);
4954 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4955 Assert(pScreen->hWnd);
4956 Assert(pScreen->pDevice9If);
4957 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
4958 HRESULT hr = S_OK;
4959 pShader->Release();
4960 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4961 return hr;
4962}
4963static HRESULT APIENTRY vboxWddmDDevCreateDecodeDevice(HANDLE hDevice, D3DDDIARG_CREATEDECODEDEVICE* pData)
4964{
4965 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4966 Assert(0);
4967 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4968 return E_FAIL;
4969}
4970static HRESULT APIENTRY vboxWddmDDevDestroyDecodeDevice(HANDLE hDevice, HANDLE hDecodeDevice)
4971{
4972 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4973 Assert(0);
4974 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4975 return E_FAIL;
4976}
4977static HRESULT APIENTRY vboxWddmDDevSetDecodeRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETDECODERENDERTARGET* pData)
4978{
4979 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4980 Assert(0);
4981 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4982 return E_FAIL;
4983}
4984static HRESULT APIENTRY vboxWddmDDevDecodeBeginFrame(HANDLE hDevice, D3DDDIARG_DECODEBEGINFRAME* pData)
4985{
4986 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4987 Assert(0);
4988 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4989 return E_FAIL;
4990}
4991static HRESULT APIENTRY vboxWddmDDevDecodeEndFrame(HANDLE hDevice, D3DDDIARG_DECODEENDFRAME* pData)
4992{
4993 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4994 Assert(0);
4995 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4996 return E_FAIL;
4997}
4998static HRESULT APIENTRY vboxWddmDDevDecodeExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXECUTE* pData)
4999{
5000 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5001 Assert(0);
5002 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5003 return E_FAIL;
5004}
5005static HRESULT APIENTRY vboxWddmDDevDecodeExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXTENSIONEXECUTE* pData)
5006{
5007 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5008 Assert(0);
5009 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5010 return E_FAIL;
5011}
5012static HRESULT APIENTRY vboxWddmDDevCreateVideoProcessDevice(HANDLE hDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE* pData)
5013{
5014 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5015 Assert(0);
5016 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5017 return E_FAIL;
5018}
5019static HRESULT APIENTRY vboxWddmDDevDestroyVideoProcessDevice(HANDLE hDevice, HANDLE hVideoProcessor)
5020{
5021 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5022 Assert(0);
5023 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5024 return E_FAIL;
5025}
5026static HRESULT APIENTRY vboxWddmDDevVideoProcessBeginFrame(HANDLE hDevice, HANDLE hVideoProcess)
5027{
5028 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5029 Assert(0);
5030 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5031 return E_FAIL;
5032}
5033static HRESULT APIENTRY vboxWddmDDevVideoProcessEndFrame(HANDLE hDevice, D3DDDIARG_VIDEOPROCESSENDFRAME* pData)
5034{
5035 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5036 Assert(0);
5037 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5038 return E_FAIL;
5039}
5040static HRESULT APIENTRY vboxWddmDDevSetVideoProcessRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETVIDEOPROCESSRENDERTARGET* pData)
5041{
5042 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5043 Assert(0);
5044 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5045 return E_FAIL;
5046}
5047static HRESULT APIENTRY vboxWddmDDevVideoProcessBlt(HANDLE hDevice, CONST D3DDDIARG_VIDEOPROCESSBLT* pData)
5048{
5049 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5050 Assert(0);
5051 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5052 return E_FAIL;
5053}
5054static HRESULT APIENTRY vboxWddmDDevCreateExtensionDevice(HANDLE hDevice, D3DDDIARG_CREATEEXTENSIONDEVICE* pData)
5055{
5056 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5057 Assert(0);
5058 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5059 return E_FAIL;
5060}
5061static HRESULT APIENTRY vboxWddmDDevDestroyExtensionDevice(HANDLE hDevice, HANDLE hExtension)
5062{
5063 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5064 Assert(0);
5065 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5066 return E_FAIL;
5067}
5068static HRESULT APIENTRY vboxWddmDDevExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_EXTENSIONEXECUTE* pData)
5069{
5070 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5071 Assert(0);
5072 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5073 return E_FAIL;
5074}
5075static HRESULT APIENTRY vboxWddmDDevDestroyDevice(IN HANDLE hDevice)
5076{
5077 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5078
5079 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5080 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
5081// Assert(!pDevice->cScreens);
5082#ifndef VBOXWDDM_WITH_VISIBLE_FB
5083 if(pDevice->pRenderTargetFbCopy)
5084 pDevice->pRenderTargetFbCopy->Release();
5085#endif
5086 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aScreens); ++i)
5087 {
5088 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i];
5089 if (pScreen->pDevice9If)
5090 {
5091 pScreen->pDevice9If->Release();
5092 Assert(pScreen->hWnd);
5093 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pScreen->hWnd);
5094 Assert(tmpHr == S_OK);
5095 }
5096 }
5097
5098 HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
5099 Assert(hr == S_OK);
5100 if (hr == S_OK)
5101 RTMemFree(pDevice);
5102 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5103 return hr;
5104}
5105
5106AssertCompile(sizeof (RECT) == sizeof (D3DDDIRECT));
5107AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DDDIRECT, left));
5108AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DDDIRECT, right));
5109AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DDDIRECT, top));
5110AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DDDIRECT, bottom));
5111AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DDDIRECT, left));
5112AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DDDIRECT, right));
5113AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DDDIRECT, top));
5114AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DDDIRECT, bottom));
5115
5116static HRESULT APIENTRY vboxWddmDDevCreateOverlay(HANDLE hDevice, D3DDDIARG_CREATEOVERLAY* pData)
5117{
5118 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5119 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5120 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
5121 Assert(pRc);
5122 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
5123 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
5124 HRESULT hr = S_OK;
5125 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)RTMemAllocZ(sizeof (VBOXWDDMDISP_OVERLAY));
5126 Assert(pOverlay);
5127 if (pOverlay)
5128 {
5129 VBOXWDDM_OVERLAY_INFO OurInfo;
5130 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
5131 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
5132 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
5133 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
5134 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
5135 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
5136 Assert(!pAlloc->LockInfo.cLocks);
5137 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
5138 D3DDDICB_CREATEOVERLAY OverInfo;
5139 OverInfo.VidPnSourceId = pData->VidPnSourceId;
5140 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
5141 Assert(pAlloc->hAllocation);
5142 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
5143 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
5144 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
5145 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
5146 OverInfo.hKernelOverlay = NULL; /* <-- out */
5147#ifndef VBOXWDDMOVERLAY_TEST
5148 hr = pDevice->RtCallbacks.pfnCreateOverlayCb(pDevice->hDevice, &OverInfo);
5149 Assert(hr == S_OK);
5150 if (hr == S_OK)
5151 {
5152 Assert(OverInfo.hKernelOverlay);
5153 pOverlay->hOverlay = OverInfo.hKernelOverlay;
5154 pOverlay->VidPnSourceId = pData->VidPnSourceId;
5155
5156 Assert(!pAlloc->LockInfo.cLocks);
5157 if (!pAlloc->LockInfo.cLocks)
5158 {
5159 /* we have reported the dirty rect, may clear it if no locks are pending currently */
5160 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
5161 }
5162
5163 pData->hOverlay = pOverlay;
5164 }
5165 else
5166 {
5167 RTMemFree(pOverlay);
5168 }
5169#else
5170 pData->hOverlay = pOverlay;
5171#endif
5172 }
5173 else
5174 hr = E_OUTOFMEMORY;
5175
5176 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5177 return hr;
5178}
5179static HRESULT APIENTRY vboxWddmDDevUpdateOverlay(HANDLE hDevice, CONST D3DDDIARG_UPDATEOVERLAY* pData)
5180{
5181 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5182 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5183 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
5184 Assert(pRc);
5185 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
5186 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
5187 HRESULT hr = S_OK;
5188 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
5189 VBOXWDDM_OVERLAY_INFO OurInfo;
5190 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
5191 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
5192 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
5193 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
5194 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
5195 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
5196 Assert(!pAlloc->LockInfo.cLocks);
5197 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
5198 D3DDDICB_UPDATEOVERLAY OverInfo;
5199 OverInfo.hKernelOverlay = pOverlay->hOverlay;
5200 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
5201 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
5202 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
5203 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
5204 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
5205#ifndef VBOXWDDMOVERLAY_TEST
5206 hr = pDevice->RtCallbacks.pfnUpdateOverlayCb(pDevice->hDevice, &OverInfo);
5207 Assert(hr == S_OK);
5208 if (hr == S_OK)
5209#endif
5210 {
5211 Assert(!pAlloc->LockInfo.cLocks);
5212 if (!pAlloc->LockInfo.cLocks)
5213 {
5214 /* we have reported the dirty rect, may clear it if no locks are pending currently */
5215 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
5216 }
5217 }
5218
5219 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5220 return hr;
5221}
5222static HRESULT APIENTRY vboxWddmDDevFlipOverlay(HANDLE hDevice, CONST D3DDDIARG_FLIPOVERLAY* pData)
5223{
5224 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5225 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5226 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSource;
5227 Assert(pRc);
5228 Assert(pRc->cAllocations > pData->SourceIndex);
5229 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SourceIndex];
5230 HRESULT hr = S_OK;
5231 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
5232 VBOXWDDM_OVERLAYFLIP_INFO OurInfo;
5233 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
5234 Assert(!pAlloc->LockInfo.cLocks);
5235 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
5236 D3DDDICB_FLIPOVERLAY OverInfo;
5237 OverInfo.hKernelOverlay = pOverlay->hOverlay;
5238 OverInfo.hSource = pAlloc->hAllocation;
5239 OverInfo.pPrivateDriverData = &OurInfo;
5240 OverInfo.PrivateDriverDataSize = sizeof (OurInfo);
5241#ifndef VBOXWDDMOVERLAY_TEST
5242 hr = pDevice->RtCallbacks.pfnFlipOverlayCb(pDevice->hDevice, &OverInfo);
5243 Assert(hr == S_OK);
5244 if (hr == S_OK)
5245#endif
5246 {
5247 Assert(!pAlloc->LockInfo.cLocks);
5248 if (!pAlloc->LockInfo.cLocks)
5249 {
5250 /* we have reported the dirty rect, may clear it if no locks are pending currently */
5251 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
5252 }
5253 }
5254
5255 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5256 return hr;
5257}
5258static HRESULT APIENTRY vboxWddmDDevGetOverlayColorControls(HANDLE hDevice, D3DDDIARG_GETOVERLAYCOLORCONTROLS* pData)
5259{
5260 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5261 Assert(0);
5262 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5263 return E_FAIL;
5264}
5265static HRESULT APIENTRY vboxWddmDDevSetOverlayColorControls(HANDLE hDevice, CONST D3DDDIARG_SETOVERLAYCOLORCONTROLS* pData)
5266{
5267 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5268 Assert(0);
5269 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5270 return E_FAIL;
5271}
5272static HRESULT APIENTRY vboxWddmDDevDestroyOverlay(HANDLE hDevice, CONST D3DDDIARG_DESTROYOVERLAY* pData)
5273{
5274 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5275 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5276 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
5277 D3DDDICB_DESTROYOVERLAY OverInfo;
5278 OverInfo.hKernelOverlay = pOverlay->hOverlay;
5279#ifndef VBOXWDDMOVERLAY_TEST
5280 HRESULT hr = pDevice->RtCallbacks.pfnDestroyOverlayCb(pDevice->hDevice, &OverInfo);
5281 Assert(hr == S_OK);
5282 if (hr == S_OK)
5283#else
5284 HRESULT hr = S_OK;
5285#endif
5286 {
5287 RTMemFree(pOverlay);
5288 }
5289
5290 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5291 return hr;
5292}
5293static HRESULT APIENTRY vboxWddmDDevQueryResourceResidency(HANDLE hDevice, CONST D3DDDIARG_QUERYRESOURCERESIDENCY* pData)
5294{
5295 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5296 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5297 Assert(0);
5298 HRESULT hr = S_OK;
5299#if 0
5300 for (UINT i = 0; i < pData->NumResources; ++i)
5301 {
5302 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->pHandleList[i];
5303 Assert(pRc->pDevice == pDevice);
5304 if (pRc->hKMResource)
5305 {
5306
5307 }
5308 }
5309#endif
5310 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5311 return hr;
5312}
5313
5314static HRESULT vboxAllocationInit(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DDDI_OPENALLOCATIONINFO *pInfo)
5315{
5316 HRESULT hr = S_OK;
5317 pAlloc->hAllocation = pInfo->hAllocation;
5318 Assert(pInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
5319 Assert(pInfo->pPrivateDriverData);
5320 if (pInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
5321 {
5322 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pInfo->pPrivateDriverData;
5323 pAlloc->enmType = pAllocInfo->enmType;
5324 Assert(pAllocInfo->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
5325 || VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE
5326 || VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE);
5327 pAlloc->pvMem = NULL;
5328 pAlloc->SurfDesc = pAllocInfo->SurfDesc;
5329 }
5330 else
5331 {
5332 vboxVDbgPrintR((__FUNCTION__": ERROR: PrivateDriverDataSize(%d) < (%d)\n", pInfo->PrivateDriverDataSize, sizeof (VBOXWDDM_ALLOCINFO)));
5333 hr = E_INVALIDARG;
5334 }
5335 return hr;
5336}
5337
5338static HRESULT APIENTRY vboxWddmDDevOpenResource(HANDLE hDevice, D3DDDIARG_OPENRESOURCE* pData)
5339{
5340 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5341 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5342 HRESULT hr = S_OK;
5343
5344 Assert(pDevice);
5345 Assert(pData->NumAllocations);
5346 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pData->NumAllocations);
5347 Assert(pRc);
5348 if (pRc)
5349 {
5350 pRc->hResource = pData->hResource;
5351 pRc->hKMResource = pData->hKMResource;
5352 pRc->pDevice = pDevice;
5353 pRc->RcDesc.enmRotation = pData->Rotation;
5354 pRc->fFlags = VBOXWDDM_RESOURCE_F_OPENNED;
5355 if (!pData->pPrivateDriverData || !pData->PrivateDriverDataSize)
5356 {
5357 /* this is a "standard" allocation resource */
5358
5359 /* both should be actually zero */
5360 Assert(!pData->pPrivateDriverData && !pData->PrivateDriverDataSize);
5361 pRc->RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
5362 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
5363 pRc->RcDesc.MultisampleQuality = 0;
5364 pRc->RcDesc.MipLevels = 0;
5365 pRc->RcDesc.Fvf;
5366 pRc->RcDesc.fFlags.Value = 0;
5367
5368 Assert(pData->NumAllocations);
5369 D3DDDI_OPENALLOCATIONINFO* pDdiAllocInfo = &pData->pOpenAllocationInfo[0];
5370 Assert(pDdiAllocInfo->pPrivateDriverData);
5371 Assert(pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO));
5372 if (pDdiAllocInfo->pPrivateDriverData && pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
5373 {
5374 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocInfo->pPrivateDriverData;
5375 switch(pAllocInfo->enmType)
5376 {
5377 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
5378 pRc->RcDesc.fFlags.Primary = 1;
5379 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
5380 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
5381 pRc->RcDesc.enmFormat = pAllocInfo->SurfDesc.format;
5382 pRc->RcDesc.VidPnSourceId = pAllocInfo->SurfDesc.VidPnSourceId;
5383 pRc->RcDesc.RefreshRate = pAllocInfo->SurfDesc.RefreshRate;
5384 break;
5385 default:
5386 Assert(0);
5387 hr = E_INVALIDARG;
5388 }
5389 }
5390 else
5391 hr = E_INVALIDARG;
5392 }
5393 else
5394 {
5395 /* this is a "generic" resource whose creation is initiaded by the UMD */
5396 Assert(pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
5397 if (pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO))
5398 {
5399 VBOXWDDM_RCINFO *pRcInfo = (VBOXWDDM_RCINFO*)pData->pPrivateDriverData;
5400 Assert(pRcInfo->fFlags == VBOXWDDM_RESOURCE_F_TYPE_GENERIC);
5401 Assert(pRcInfo->cAllocInfos == pData->NumAllocations);
5402 pRc->fFlags = pRcInfo->fFlags | VBOXWDDM_RESOURCE_F_OPENNED;
5403 pRc->RcDesc = pRcInfo->RcDesc;
5404 pRc->cAllocations = pData->NumAllocations;
5405
5406 for (UINT i = 0; i < pData->NumAllocations; ++i)
5407 {
5408 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5409 D3DDDI_OPENALLOCATIONINFO* pOAI = pData->pOpenAllocationInfo;
5410 Assert(pOAI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
5411 if (pOAI->PrivateDriverDataSize != sizeof (VBOXWDDM_ALLOCINFO))
5412 {
5413 hr = E_INVALIDARG;
5414 break;
5415 }
5416 Assert(pOAI->pPrivateDriverData);
5417 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pOAI->pPrivateDriverData;
5418 pAllocation->hAllocation = pOAI->hAllocation;
5419 pAllocation->enmType = pAllocInfo->enmType;
5420 pAllocation->hSharedHandle = pAllocInfo->hSharedHandle;
5421 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
5422 Assert(pAllocation->hSharedHandle);
5423 }
5424
5425 Assert(pRc->RcDesc.fFlags.SharedResource);
5426 if (pRc->RcDesc.fFlags.Texture)
5427 {
5428 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5429 Assert(pScreen->hWnd);
5430 Assert(pScreen->pDevice9If);
5431 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
5432 IDirect3DTexture9 *pD3DIfTex;
5433 HANDLE hSharedHandle = pAllocation->hSharedHandle;
5434 Assert(pAllocation->hSharedHandle);
5435
5436 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pScreen->pDevice9If,
5437 pAllocation->SurfDesc.width,
5438 pAllocation->SurfDesc.height,
5439 pRc->cAllocations,
5440 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
5441 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
5442 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
5443 &pD3DIfTex,
5444 &hSharedHandle,
5445 NULL);
5446 Assert(hr == S_OK);
5447 if (hr == S_OK)
5448 {
5449 Assert(pD3DIfTex);
5450 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
5451 pAllocation->pD3DIf = pD3DIfTex;
5452 Assert(pAllocation->hSharedHandle == hSharedHandle);
5453 Assert(pAllocation->hSharedHandle);
5454 }
5455 }
5456 else
5457 {
5458 /* impl */
5459 Assert(0);
5460 }
5461 }
5462 else
5463 hr = E_INVALIDARG;
5464 }
5465
5466 if (hr == S_OK)
5467 {
5468 for (UINT i = 0; i < pData->NumAllocations; ++i)
5469 {
5470 hr = vboxAllocationInit(&pRc->aAllocations[i], &pData->pOpenAllocationInfo[i]);
5471 Assert(hr == S_OK);
5472 if (hr != S_OK)
5473 break;
5474 }
5475 }
5476
5477 if (hr == S_OK)
5478 pData->hResource = pRc;
5479 else
5480 vboxResourceFree(pRc);
5481 }
5482 else
5483 {
5484 vboxVDbgPrintR((__FUNCTION__": vboxResourceAlloc failed for hDevice(0x%p), NumAllocations(%d)\n", hDevice, pData->NumAllocations));
5485 hr = E_OUTOFMEMORY;
5486 }
5487
5488 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5489 return hr;
5490}
5491static HRESULT APIENTRY vboxWddmDDevGetCaptureAllocationHandle(HANDLE hDevice, D3DDDIARG_GETCAPTUREALLOCATIONHANDLE* pData)
5492{
5493 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5494 Assert(0);
5495 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5496 return E_FAIL;
5497}
5498
5499static HRESULT APIENTRY vboxWddmDDevCaptureToSysMem(HANDLE hDevice, CONST D3DDDIARG_CAPTURETOSYSMEM* pData)
5500{
5501 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5502 Assert(0);
5503 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5504 return E_FAIL;
5505}
5506
5507static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIARG_CREATEDEVICE* pCreateData)
5508{
5509 HRESULT hr = S_OK;
5510 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), Interface(%d), Version(%d)\n", hAdapter, pCreateData->Interface, pCreateData->Version));
5511
5512// Assert(0);
5513
5514 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(sizeof (VBOXWDDMDISP_DEVICE));
5515 if (pDevice)
5516 {
5517 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
5518
5519 pDevice->hDevice = pCreateData->hDevice;
5520 pDevice->pAdapter = pAdapter;
5521 pDevice->u32IfVersion = pCreateData->Interface;
5522 pDevice->uRtVersion = pCreateData->Version;
5523 pDevice->RtCallbacks = *pCreateData->pCallbacks;
5524 pDevice->pvCmdBuffer = pCreateData->pCommandBuffer;
5525 pDevice->cbCmdBuffer = pCreateData->CommandBufferSize;
5526 pDevice->fFlags = pCreateData->Flags;
5527 /* Set Viewport to some default values */
5528 pDevice->ViewPort.X = 0;
5529 pDevice->ViewPort.Y = 0;
5530 pDevice->ViewPort.Width = 1;
5531 pDevice->ViewPort.Height = 1;
5532 pDevice->ViewPort.MinZ = 0.;
5533 pDevice->ViewPort.MaxZ = 1.;
5534
5535 Assert(!pCreateData->AllocationListSize);
5536 Assert(!pCreateData->PatchLocationListSize);
5537
5538 pCreateData->hDevice = pDevice;
5539
5540 pCreateData->pDeviceFuncs->pfnSetRenderState = vboxWddmDDevSetRenderState;
5541 pCreateData->pDeviceFuncs->pfnUpdateWInfo = vboxWddmDDevUpdateWInfo;
5542 pCreateData->pDeviceFuncs->pfnValidateDevice = vboxWddmDDevValidateDevice;
5543 pCreateData->pDeviceFuncs->pfnSetTextureStageState = vboxWddmDDevSetTextureStageState;
5544 pCreateData->pDeviceFuncs->pfnSetTexture = vboxWddmDDevSetTexture;
5545 pCreateData->pDeviceFuncs->pfnSetPixelShader = vboxWddmDDevSetPixelShader;
5546 pCreateData->pDeviceFuncs->pfnSetPixelShaderConst = vboxWddmDDevSetPixelShaderConst;
5547 pCreateData->pDeviceFuncs->pfnSetStreamSourceUm = vboxWddmDDevSetStreamSourceUm;
5548 pCreateData->pDeviceFuncs->pfnSetIndices = vboxWddmDDevSetIndices;
5549 pCreateData->pDeviceFuncs->pfnSetIndicesUm = vboxWddmDDevSetIndicesUm;
5550 pCreateData->pDeviceFuncs->pfnDrawPrimitive = vboxWddmDDevDrawPrimitive;
5551 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive = vboxWddmDDevDrawIndexedPrimitive;
5552 pCreateData->pDeviceFuncs->pfnDrawRectPatch = vboxWddmDDevDrawRectPatch;
5553 pCreateData->pDeviceFuncs->pfnDrawTriPatch = vboxWddmDDevDrawTriPatch;
5554 pCreateData->pDeviceFuncs->pfnDrawPrimitive2 = vboxWddmDDevDrawPrimitive2;
5555 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive2 = vboxWddmDDevDrawIndexedPrimitive2;
5556 pCreateData->pDeviceFuncs->pfnVolBlt = vboxWddmDDevVolBlt;
5557 pCreateData->pDeviceFuncs->pfnBufBlt = vboxWddmDDevBufBlt;
5558 pCreateData->pDeviceFuncs->pfnTexBlt = vboxWddmDDevTexBlt;
5559 pCreateData->pDeviceFuncs->pfnStateSet = vboxWddmDDevStateSet;
5560 pCreateData->pDeviceFuncs->pfnSetPriority = vboxWddmDDevSetPriority;
5561 pCreateData->pDeviceFuncs->pfnClear = vboxWddmDDevClear;
5562 pCreateData->pDeviceFuncs->pfnUpdatePalette = vboxWddmDDevUpdatePalette;
5563 pCreateData->pDeviceFuncs->pfnSetPalette = vboxWddmDDevSetPalette;
5564 pCreateData->pDeviceFuncs->pfnSetVertexShaderConst = vboxWddmDDevSetVertexShaderConst;
5565 pCreateData->pDeviceFuncs->pfnMultiplyTransform = vboxWddmDDevMultiplyTransform;
5566 pCreateData->pDeviceFuncs->pfnSetTransform = vboxWddmDDevSetTransform;
5567 pCreateData->pDeviceFuncs->pfnSetViewport = vboxWddmDDevSetViewport;
5568 pCreateData->pDeviceFuncs->pfnSetZRange = vboxWddmDDevSetZRange;
5569 pCreateData->pDeviceFuncs->pfnSetMaterial = vboxWddmDDevSetMaterial;
5570 pCreateData->pDeviceFuncs->pfnSetLight = vboxWddmDDevSetLight;
5571 pCreateData->pDeviceFuncs->pfnCreateLight = vboxWddmDDevCreateLight;
5572 pCreateData->pDeviceFuncs->pfnDestroyLight = vboxWddmDDevDestroyLight;
5573 pCreateData->pDeviceFuncs->pfnSetClipPlane = vboxWddmDDevSetClipPlane;
5574 pCreateData->pDeviceFuncs->pfnGetInfo = vboxWddmDDevGetInfo;
5575 pCreateData->pDeviceFuncs->pfnLock = vboxWddmDDevLock;
5576 pCreateData->pDeviceFuncs->pfnUnlock = vboxWddmDDevUnlock;
5577 pCreateData->pDeviceFuncs->pfnCreateResource = vboxWddmDDevCreateResource;
5578 pCreateData->pDeviceFuncs->pfnDestroyResource = vboxWddmDDevDestroyResource;
5579 pCreateData->pDeviceFuncs->pfnSetDisplayMode = vboxWddmDDevSetDisplayMode;
5580 pCreateData->pDeviceFuncs->pfnPresent = vboxWddmDDevPresent;
5581 pCreateData->pDeviceFuncs->pfnFlush = vboxWddmDDevFlush;
5582 pCreateData->pDeviceFuncs->pfnCreateVertexShaderFunc = vboxWddmDDevCreateVertexShaderFunc;
5583 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderFunc = vboxWddmDDevDeleteVertexShaderFunc;
5584 pCreateData->pDeviceFuncs->pfnSetVertexShaderFunc = vboxWddmDDevSetVertexShaderFunc;
5585 pCreateData->pDeviceFuncs->pfnCreateVertexShaderDecl = vboxWddmDDevCreateVertexShaderDecl;
5586 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderDecl = vboxWddmDDevDeleteVertexShaderDecl;
5587 pCreateData->pDeviceFuncs->pfnSetVertexShaderDecl = vboxWddmDDevSetVertexShaderDecl;
5588 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstI = vboxWddmDDevSetVertexShaderConstI;
5589 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstB = vboxWddmDDevSetVertexShaderConstB;
5590 pCreateData->pDeviceFuncs->pfnSetScissorRect = vboxWddmDDevSetScissorRect;
5591 pCreateData->pDeviceFuncs->pfnSetStreamSource = vboxWddmDDevSetStreamSource;
5592 pCreateData->pDeviceFuncs->pfnSetStreamSourceFreq = vboxWddmDDevSetStreamSourceFreq;
5593 pCreateData->pDeviceFuncs->pfnSetConvolutionKernelMono = vboxWddmDDevSetConvolutionKernelMono;
5594 pCreateData->pDeviceFuncs->pfnComposeRects = vboxWddmDDevComposeRects;
5595 pCreateData->pDeviceFuncs->pfnBlt = vboxWddmDDevBlt;
5596 pCreateData->pDeviceFuncs->pfnColorFill = vboxWddmDDevColorFill;
5597 pCreateData->pDeviceFuncs->pfnDepthFill = vboxWddmDDevDepthFill;
5598 pCreateData->pDeviceFuncs->pfnCreateQuery = vboxWddmDDevCreateQuery;
5599 pCreateData->pDeviceFuncs->pfnDestroyQuery = vboxWddmDDevDestroyQuery;
5600 pCreateData->pDeviceFuncs->pfnIssueQuery = vboxWddmDDevIssueQuery;
5601 pCreateData->pDeviceFuncs->pfnGetQueryData = vboxWddmDDevGetQueryData;
5602 pCreateData->pDeviceFuncs->pfnSetRenderTarget = vboxWddmDDevSetRenderTarget;
5603 pCreateData->pDeviceFuncs->pfnSetDepthStencil = vboxWddmDDevSetDepthStencil;
5604 pCreateData->pDeviceFuncs->pfnGenerateMipSubLevels = vboxWddmDDevGenerateMipSubLevels;
5605 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstI = vboxWddmDDevSetPixelShaderConstI;
5606 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstB = vboxWddmDDevSetPixelShaderConstB;
5607 pCreateData->pDeviceFuncs->pfnCreatePixelShader = vboxWddmDDevCreatePixelShader;
5608 pCreateData->pDeviceFuncs->pfnDeletePixelShader = vboxWddmDDevDeletePixelShader;
5609 pCreateData->pDeviceFuncs->pfnCreateDecodeDevice = vboxWddmDDevCreateDecodeDevice;
5610 pCreateData->pDeviceFuncs->pfnDestroyDecodeDevice = vboxWddmDDevDestroyDecodeDevice;
5611 pCreateData->pDeviceFuncs->pfnSetDecodeRenderTarget = vboxWddmDDevSetDecodeRenderTarget;
5612 pCreateData->pDeviceFuncs->pfnDecodeBeginFrame = vboxWddmDDevDecodeBeginFrame;
5613 pCreateData->pDeviceFuncs->pfnDecodeEndFrame = vboxWddmDDevDecodeEndFrame;
5614 pCreateData->pDeviceFuncs->pfnDecodeExecute = vboxWddmDDevDecodeExecute;
5615 pCreateData->pDeviceFuncs->pfnDecodeExtensionExecute = vboxWddmDDevDecodeExtensionExecute;
5616 pCreateData->pDeviceFuncs->pfnCreateVideoProcessDevice = vboxWddmDDevCreateVideoProcessDevice;
5617 pCreateData->pDeviceFuncs->pfnDestroyVideoProcessDevice = vboxWddmDDevDestroyVideoProcessDevice;
5618 pCreateData->pDeviceFuncs->pfnVideoProcessBeginFrame = vboxWddmDDevVideoProcessBeginFrame;
5619 pCreateData->pDeviceFuncs->pfnVideoProcessEndFrame = vboxWddmDDevVideoProcessEndFrame;
5620 pCreateData->pDeviceFuncs->pfnSetVideoProcessRenderTarget = vboxWddmDDevSetVideoProcessRenderTarget;
5621 pCreateData->pDeviceFuncs->pfnVideoProcessBlt = vboxWddmDDevVideoProcessBlt;
5622 pCreateData->pDeviceFuncs->pfnCreateExtensionDevice = vboxWddmDDevCreateExtensionDevice;
5623 pCreateData->pDeviceFuncs->pfnDestroyExtensionDevice = vboxWddmDDevDestroyExtensionDevice;
5624 pCreateData->pDeviceFuncs->pfnExtensionExecute = vboxWddmDDevExtensionExecute;
5625 pCreateData->pDeviceFuncs->pfnCreateOverlay = vboxWddmDDevCreateOverlay;
5626 pCreateData->pDeviceFuncs->pfnUpdateOverlay = vboxWddmDDevUpdateOverlay;
5627 pCreateData->pDeviceFuncs->pfnFlipOverlay = vboxWddmDDevFlipOverlay;
5628 pCreateData->pDeviceFuncs->pfnGetOverlayColorControls = vboxWddmDDevGetOverlayColorControls;
5629 pCreateData->pDeviceFuncs->pfnSetOverlayColorControls = vboxWddmDDevSetOverlayColorControls;
5630 pCreateData->pDeviceFuncs->pfnDestroyOverlay = vboxWddmDDevDestroyOverlay;
5631 pCreateData->pDeviceFuncs->pfnDestroyDevice = vboxWddmDDevDestroyDevice;
5632 pCreateData->pDeviceFuncs->pfnQueryResourceResidency = vboxWddmDDevQueryResourceResidency;
5633 pCreateData->pDeviceFuncs->pfnOpenResource = vboxWddmDDevOpenResource;
5634 pCreateData->pDeviceFuncs->pfnGetCaptureAllocationHandle = vboxWddmDDevGetCaptureAllocationHandle;
5635 pCreateData->pDeviceFuncs->pfnCaptureToSysMem = vboxWddmDDevCaptureToSysMem;
5636 pCreateData->pDeviceFuncs->pfnLockAsync = NULL; //vboxWddmDDevLockAsync;
5637 pCreateData->pDeviceFuncs->pfnUnlockAsync = NULL; //vboxWddmDDevUnlockAsync;
5638 pCreateData->pDeviceFuncs->pfnRename = NULL; //vboxWddmDDevRename;
5639
5640
5641 do
5642 {
5643 Assert(!pCreateData->AllocationListSize
5644 && !pCreateData->PatchLocationListSize);
5645 if (!pCreateData->AllocationListSize
5646 && !pCreateData->PatchLocationListSize)
5647 {
5648 hr = vboxDispCmCtxCreate(pDevice, &pDevice->DefaultContext);
5649 Assert(hr == S_OK);
5650 if (hr == S_OK)
5651 break;
5652 }
5653 else
5654 {
5655 vboxVDbgPrintR((__FUNCTION__": Not implemented: PatchLocationListSize(%d), AllocationListSize(%d)\n",
5656 pCreateData->PatchLocationListSize, pCreateData->AllocationListSize));
5657 //pCreateData->pAllocationList = ??
5658 hr = E_FAIL;
5659 }
5660
5661 RTMemFree(pDevice);
5662 } while (0);
5663 }
5664 else
5665 {
5666 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
5667 hr = E_OUTOFMEMORY;
5668 }
5669
5670 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
5671
5672 return hr;
5673}
5674
5675static HRESULT APIENTRY vboxWddmDispCloseAdapter (IN HANDLE hAdapter)
5676{
5677 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
5678
5679// Assert(0);
5680
5681 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
5682 if (VBOXDISPMODE_IS_3D(pAdapter))
5683 {
5684 HRESULT hr = VBoxDispWorkerDestroy(&pAdapter->WndWorker);
5685 Assert(hr == S_OK);
5686 pAdapter->pD3D9If->Release();
5687 VBoxDispD3DClose(&pAdapter->D3D);
5688 }
5689
5690 vboxCapsFree(pAdapter);
5691
5692 RTMemFree(pAdapter);
5693
5694 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
5695
5696 return S_OK;
5697}
5698
5699HRESULT APIENTRY OpenAdapter (__inout D3DDDIARG_OPENADAPTER* pOpenData)
5700{
5701 vboxVDbgPrint(("==> "__FUNCTION__"\n"));
5702
5703 VBOXWDDM_QI Query;
5704 D3DDDICB_QUERYADAPTERINFO DdiQuery;
5705 DdiQuery.PrivateDriverDataSize = sizeof(Query);
5706 DdiQuery.pPrivateDriverData = &Query;
5707 HRESULT hr = pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb(pOpenData->hAdapter, &DdiQuery);
5708 Assert(hr == S_OK);
5709 if (hr != S_OK)
5710 {
5711 vboxVDbgPrintR((__FUNCTION__": pfnQueryAdapterInfoCb failed, hr (%d)\n", hr));
5712 return E_FAIL;
5713 }
5714
5715 /* check the miniport version match display version */
5716 if (Query.u32Version != VBOXVIDEOIF_VERSION)
5717 {
5718 vboxVDbgPrintR((__FUNCTION__": miniport version mismatch, expected (%d), but was (%d)\n",
5719 VBOXVIDEOIF_VERSION,
5720 Query.u32Version));
5721 return E_FAIL;
5722 }
5723
5724#ifdef VBOX_WITH_VIDEOHWACCEL
5725 Assert(Query.cInfos >= 1);
5726 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_ADAPTER, aHeads[Query.cInfos]));
5727#else
5728 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(sizeof (VBOXWDDMDISP_ADAPTER));
5729#endif
5730 Assert(pAdapter);
5731 if (pAdapter)
5732 {
5733 pAdapter->hAdapter = pOpenData->hAdapter;
5734 pAdapter->uIfVersion = pOpenData->Interface;
5735 pAdapter->uRtVersion= pOpenData->Version;
5736 pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
5737
5738 pAdapter->cHeads = Query.cInfos;
5739
5740
5741 pOpenData->hAdapter = pAdapter;
5742 pOpenData->pAdapterFuncs->pfnGetCaps = vboxWddmDispGetCaps;
5743 pOpenData->pAdapterFuncs->pfnCreateDevice = vboxWddmDispCreateDevice;
5744 pOpenData->pAdapterFuncs->pfnCloseAdapter = vboxWddmDispCloseAdapter;
5745 pOpenData->DriverVersion = D3D_UMD_INTERFACE_VERSION;
5746 /*
5747 * here we detect whether we are called by the d3d or ddraw.
5748 * in the d3d case we init our d3d environment
5749 * in the ddraw case we init 2D acceleration
5750 * if interface version is > 7, this is D3D, treat it as so
5751 * otherwise treat it as ddraw
5752 * @todo: need a more clean way of doing this */
5753
5754 if (pAdapter->uIfVersion > 7)
5755 {
5756 do
5757 {
5758 /* try enable the 3D */
5759 hr = VBoxDispD3DOpen(&pAdapter->D3D);
5760 Assert(hr == S_OK);
5761 if (hr == S_OK)
5762 {
5763 hr = pAdapter->D3D.pfnDirect3DCreate9Ex(D3D_SDK_VERSION, &pAdapter->pD3D9If);
5764 Assert(hr == S_OK);
5765 if (hr == S_OK)
5766 {
5767 hr = VBoxDispWorkerCreate(&pAdapter->WndWorker);
5768 Assert(hr == S_OK);
5769 if (hr == S_OK)
5770 {
5771 vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
5772 break;
5773 }
5774 pAdapter->pD3D9If->Release();
5775 }
5776 else
5777 vboxVDbgPrintR((__FUNCTION__": pfnDirect3DCreate9Ex failed, hr (%d)\n", hr));
5778 VBoxDispD3DClose(&pAdapter->D3D);
5779 }
5780 else
5781 vboxVDbgPrintR((__FUNCTION__": VBoxDispD3DOpen failed, hr (%d)\n", hr));
5782 } while (0);
5783 }
5784#ifdef VBOX_WITH_VIDEOHWACCEL
5785 else
5786 {
5787 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
5788 {
5789 pAdapter->aHeads[i].Vhwa.Settings = Query.aInfos[i];
5790 }
5791 }
5792#endif
5793
5794 vboxCapsInit(pAdapter);
5795 hr = S_OK;
5796// RTMemFree(pAdapter);
5797 }
5798 else
5799 {
5800 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
5801 hr = E_OUTOFMEMORY;
5802 }
5803
5804 vboxVDbgPrint(("<== "__FUNCTION__", hr (%d)\n", hr));
5805
5806 return hr;
5807}
5808
5809#ifdef VBOXWDDMDISP_DEBUG
5810
5811bool g_VDbgTstDumpEnable = false;
5812bool g_VDbgTstDumpOnSys2VidSameSizeEnable = false;
5813
5814VOID vboxVDbgDoDumpSurfData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const RECT *pRect, IDirect3DSurface9 *pSurf, const char* pSuffix)
5815{
5816 if (pPrefix)
5817 {
5818 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
5819 }
5820
5821 Assert(pRc->cAllocations > iAlloc);
5822 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
5823
5824 vboxVDbgMpPrintAlloc((pDevice, "allocation info:\n", pRc, iAlloc, "\n"));
5825
5826 D3DLOCKED_RECT Lr;
5827 if (pRect)
5828 {
5829 Assert(pRect->right > pRect->left);
5830 Assert(pRect->bottom > pRect->top);
5831 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
5832 }
5833 HRESULT srcHr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
5834 Assert(srcHr == S_OK);
5835 if (srcHr == S_OK)
5836 {
5837 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
5838// Assert(bpp == pAlloc->SurfDesc.bpp);
5839// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
5840 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
5841 Lr.pBits, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, bpp, Lr.Pitch));
5842 if (pRect)
5843 {
5844 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
5845 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
5846 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
5847 }
5848 Assert(0);
5849
5850 srcHr = pSurf->UnlockRect();
5851 Assert(srcHr == S_OK);
5852 }
5853 if (pSuffix)
5854 {
5855 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
5856 }
5857}
5858
5859VOID vboxVDbgDoDumpSurfDataBySurf(const PVBOXWDDMDISP_DEVICE pDevice, IDirect3DSurface9 *pSurf)
5860{
5861 D3DSURFACE_DESC Desc;
5862 HRESULT hr = pSurf->GetDesc(&Desc);
5863 Assert(hr == S_OK);
5864 if (hr == S_OK)
5865 {
5866 D3DLOCKED_RECT Lr;
5867 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
5868 Assert(hr == S_OK);
5869 if (hr == S_OK)
5870 {
5871 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
5872 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
5873 Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch));
5874
5875 Assert(0);
5876
5877 hr = pSurf->UnlockRect();
5878 Assert(hr == S_OK);
5879 }
5880 }
5881}
5882
5883void vboxVDbgDoMpPrintAlloc(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
5884{
5885 Assert(pRc->cAllocations > iAlloc);
5886 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
5887 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
5888 BOOL bFrontBuf = FALSE;
5889 if (bPrimary)
5890 {
5891 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5892 Assert(pRc == pScreen->pRenderTargetRc);
5893 bFrontBuf = (iAlloc == pScreen->iRenderTargetFrontBuf);
5894 }
5895 vboxVDbgDoMpPrintF(pDevice, "%s width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
5896 pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
5897 bPrimary ?
5898 (bFrontBuf ? "Front Buffer" : "Back Buffer")
5899 : "?Everage? Alloc",
5900 pSuffix);
5901}
5902
5903void vboxVDbgDoMpPrintRect(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const RECT *pRect, const char * pSuffix)
5904{
5905 vboxVDbgDoMpPrintF(pDevice, "%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix);
5906}
5907
5908VOID vboxVDbgDoMpPrint(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString)
5909{
5910 uint32_t cbString = strlen(szString) + 1;
5911 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
5912 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
5913 Assert(pCmd);
5914 if (pCmd)
5915 {
5916 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
5917 memcpy(pCmd->aStringBuf, szString, cbString);
5918
5919 D3DDDICB_ESCAPE DdiEscape = {0};
5920 DdiEscape.hContext = NULL;
5921 DdiEscape.hDevice = NULL;
5922 DdiEscape.Flags.Value = 0;
5923 DdiEscape.pPrivateDriverData = pCmd;
5924 DdiEscape.PrivateDriverDataSize = cbCmd;
5925
5926 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
5927 Assert(hr == S_OK);
5928
5929 RTMemFree(pCmd);
5930 }
5931}
5932VOID vboxVDbgDoMpPrintF(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString, ...)
5933{
5934 char szBuffer[4096] = {0};
5935 va_list pArgList;
5936 va_start(pArgList, szString);
5937 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
5938 va_end(pArgList);
5939
5940 if (pDevice)
5941 {
5942 vboxVDbgDoMpPrint(pDevice, szBuffer);
5943 }
5944 else
5945 {
5946 OutputDebugStringA(szBuffer);
5947 }
5948}
5949VOID vboxVDbgDoPrint(LPCSTR szString, ...)
5950{
5951 char szBuffer[1024] = {0};
5952 va_list pArgList;
5953 va_start(pArgList, szString);
5954 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
5955 va_end(pArgList);
5956
5957 OutputDebugStringA(szBuffer);
5958}
5959
5960static PVOID g_VBoxWDbgVEHandler = NULL;
5961LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
5962{
5963 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
5964 PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
5965 switch (pExceptionRecord->ExceptionCode)
5966 {
5967 case 0x40010006: /* <- OutputDebugString exception, ignore */
5968 break;
5969 default:
5970 Assert(0);
5971 break;
5972 }
5973 return EXCEPTION_CONTINUE_SEARCH;
5974}
5975
5976void vboxVDbgVEHandlerRegister()
5977{
5978 Assert(!g_VBoxWDbgVEHandler);
5979 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
5980 Assert(g_VBoxWDbgVEHandler);
5981}
5982
5983void vboxVDbgVEHandlerUnregister()
5984{
5985 Assert(g_VBoxWDbgVEHandler);
5986 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
5987 Assert(uResult);
5988 g_VBoxWDbgVEHandler = NULL;
5989}
5990
5991#endif
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette