VirtualBox

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

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

wddm/3d: more debugging

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

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