VirtualBox

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

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

wddm/3d: fix assertions

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