VirtualBox

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

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

wddm/3d: issue render cmd on flush for shared resources to notify d3d runtime about surf contents change (not completed)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 249.8 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 == NULL);
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);
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
4234 do
4235 {
4236 NscAdd.pvCommandBuffer = pDevice->DefaultContext.ContextInfo.pCommandBuffer;
4237 NscAdd.cbCommandBuffer = pDevice->DefaultContext.ContextInfo.CommandBufferSize;
4238 NscAdd.pAllocationList = pDevice->DefaultContext.ContextInfo.pAllocationList;
4239 NscAdd.cAllocationList = pDevice->DefaultContext.ContextInfo.AllocationListSize;
4240 NscAdd.pPatchLocationList = pDevice->DefaultContext.ContextInfo.pPatchLocationList;
4241 NscAdd.cPatchLocationList = pDevice->DefaultContext.ContextInfo.PatchLocationListSize;
4242 NscAdd.cAllocations = 0;
4243
4244 EnterCriticalSection(&pDevice->DirtyAllocListLock);
4245
4246 PVBOXWDDMDISP_ALLOCATION pAlloc = RTListNodeGetFirst(&pDevice->DirtyAllocList, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry);
4247 if (pAlloc)
4248 {
4249 HRESULT tmpHr = vboxWddmNSCAddAlloc(&NscAdd, pAlloc, TRUE);
4250 Assert(tmpHr == S_OK || tmpHr == S_FALSE);
4251 if (tmpHr == S_OK)
4252 {
4253 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
4254 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
4255 continue;
4256 }
4257
4258 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
4259
4260 }
4261 else
4262 {
4263 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
4264 if (!NscAdd.cAllocations)
4265 break;
4266 }
4267
4268 D3DDDICB_RENDER RenderData = {0};
4269 RenderData.CommandLength = pDevice->DefaultContext.ContextInfo.CommandBufferSize - NscAdd.cbCommandBuffer;
4270 Assert(RenderData.CommandLength);
4271 Assert(RenderData.CommandLength < UINT32_MAX/2);
4272 RenderData.CommandOffset = 0;
4273 RenderData.NumAllocations = pDevice->DefaultContext.ContextInfo.AllocationListSize - NscAdd.cAllocationList;
4274 Assert(RenderData.NumAllocations == NscAdd.cAllocations);
4275 RenderData.NumPatchLocations = pDevice->DefaultContext.ContextInfo.PatchLocationListSize - NscAdd.cPatchLocationList;
4276 Assert(RenderData.NumPatchLocations == NscAdd.cAllocations);
4277 RenderData.NewCommandBufferSize = sizeof (VBOXVDMACMD) + 4 * (100);
4278 RenderData.NewAllocationListSize = 100;
4279 RenderData.NewPatchLocationListSize = 100;
4280 RenderData.hContext = pDevice->DefaultContext.ContextInfo.hContext;
4281
4282 HRESULT hr = pDevice->RtCallbacks.pfnRenderCb(pDevice->hDevice, &RenderData);
4283 Assert(hr == S_OK);
4284 if (hr == S_OK)
4285 {
4286 pDevice->DefaultContext.ContextInfo.CommandBufferSize = RenderData.NewCommandBufferSize;
4287 pDevice->DefaultContext.ContextInfo.pCommandBuffer = RenderData.pNewCommandBuffer;
4288 pDevice->DefaultContext.ContextInfo.AllocationListSize = RenderData.NewAllocationListSize;
4289 pDevice->DefaultContext.ContextInfo.pAllocationList = RenderData.pNewAllocationList;
4290 pDevice->DefaultContext.ContextInfo.PatchLocationListSize = RenderData.NewPatchLocationListSize;
4291 pDevice->DefaultContext.ContextInfo.pPatchLocationList = RenderData.pNewPatchLocationList;
4292 }
4293 else
4294 break;
4295 } while (1);
4296
4297 return S_OK;
4298}
4299
4300static HRESULT APIENTRY vboxWddmDDevFlush(HANDLE hDevice)
4301{
4302 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4303 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4304 Assert(pDevice);
4305 HRESULT hr = S_OK;
4306 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4307 {
4308 Assert(pDevice->cScreens);
4309 UINT cProcessed = 0;
4310 for (UINT i = 0; cProcessed < pDevice->cScreens && i < RT_ELEMENTS(pDevice->aScreens); ++i)
4311 {
4312 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i];
4313 if (pScreen->pDevice9If)
4314 {
4315 ++cProcessed;
4316// if (pScreen->pRenderTargetRc->cAllocations == 1)
4317// {
4318// hr = pScreen->pDevice9If->Present(NULL, NULL, NULL, NULL);
4319// Assert(hr == S_OK);
4320// }
4321// else
4322 {
4323 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pScreen->pDevice9If);
4324 Assert(hr == S_OK);
4325 }
4326 }
4327 }
4328
4329 vboxWddmNotifySharedChange(pDevice);
4330 }
4331 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4332 return hr;
4333}
4334
4335AssertCompile(sizeof (D3DDDIVERTEXELEMENT) == sizeof (D3DVERTEXELEMENT9));
4336AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Stream) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Stream));
4337AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Offset) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Offset));
4338AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Type) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Type));
4339AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Method) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Method));
4340AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Usage) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Usage));
4341AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, UsageIndex) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, UsageIndex));
4342
4343AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Stream) == RT_OFFSETOF(D3DVERTEXELEMENT9, Stream));
4344AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Offset) == RT_OFFSETOF(D3DVERTEXELEMENT9, Offset));
4345AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Type) == RT_OFFSETOF(D3DVERTEXELEMENT9, Type));
4346AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Method) == RT_OFFSETOF(D3DVERTEXELEMENT9, Method));
4347AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Usage) == RT_OFFSETOF(D3DVERTEXELEMENT9, Usage));
4348AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, UsageIndex) == RT_OFFSETOF(D3DVERTEXELEMENT9, UsageIndex));
4349
4350static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderDecl(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERDECL* pData, CONST D3DDDIVERTEXELEMENT* pVertexElements)
4351{
4352 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4353 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4354 Assert(pDevice);
4355 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4356 Assert(pScreen->hWnd);
4357 Assert(pScreen->pDevice9If);
4358 IDirect3DVertexDeclaration9 *pDecl;
4359 static D3DVERTEXELEMENT9 DeclEnd = D3DDECL_END();
4360 D3DVERTEXELEMENT9* pVe;
4361 HRESULT hr = S_OK;
4362 bool bFreeVe = false;
4363 if(memcmp(&DeclEnd, &pVertexElements[pData->NumVertexElements], sizeof (DeclEnd)))
4364 {
4365 pVe = (D3DVERTEXELEMENT9*)RTMemAlloc(sizeof (D3DVERTEXELEMENT9) * (pData->NumVertexElements + 1));
4366 if (pVe)
4367 {
4368 memcpy(pVe, pVertexElements, sizeof (D3DVERTEXELEMENT9) * pData->NumVertexElements);
4369 pVe[pData->NumVertexElements] = DeclEnd;
4370 bFreeVe = true;
4371 }
4372 else
4373 hr = E_OUTOFMEMORY;
4374 }
4375 else
4376 pVe = (D3DVERTEXELEMENT9*)pVertexElements;
4377
4378 if (hr == S_OK)
4379 {
4380 hr = pScreen->pDevice9If->CreateVertexDeclaration(
4381 pVe,
4382 &pDecl
4383 );
4384 Assert(hr == S_OK);
4385 if (hr == S_OK)
4386 {
4387 Assert(pDecl);
4388 pData->ShaderHandle = pDecl;
4389 }
4390 }
4391
4392 if (bFreeVe)
4393 RTMemFree((void*)pVe);
4394
4395 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4396 return hr;
4397}
4398static HRESULT APIENTRY vboxWddmDDevSetVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
4399{
4400 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4401 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4402 Assert(pDevice);
4403 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4404 Assert(pScreen->hWnd);
4405 Assert(pScreen->pDevice9If);
4406 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
4407 Assert(pDecl);
4408 HRESULT hr = pScreen->pDevice9If->SetVertexDeclaration(pDecl);
4409 Assert(hr == S_OK);
4410 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4411 return hr;
4412}
4413static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
4414{
4415 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4416 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4417 Assert(pDevice);
4418 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4419 Assert(pScreen->hWnd);
4420 Assert(pScreen->pDevice9If);
4421 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
4422 HRESULT hr = S_OK;
4423 pDecl->Release();
4424 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4425 return hr;
4426}
4427static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderFunc(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERFUNC* pData, CONST UINT* pCode)
4428{
4429 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4430 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4431 Assert(pDevice);
4432 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4433 Assert(pScreen->hWnd);
4434 Assert(pScreen->pDevice9If);
4435 IDirect3DVertexShader9 *pShader;
4436 Assert(*((UINT*)((uint8_t*)pCode + pData->Size-4)) == 0x0000FFFF /* end token */);
4437 HRESULT hr = pScreen->pDevice9If->CreateVertexShader((const DWORD *)pCode, &pShader);
4438 Assert(hr == S_OK);
4439 if (hr == S_OK)
4440 {
4441 Assert(pShader);
4442 pData->ShaderHandle = pShader;
4443 }
4444 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4445 return hr;
4446}
4447static HRESULT APIENTRY vboxWddmDDevSetVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
4448{
4449 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4450 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4451 Assert(pDevice);
4452 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4453 Assert(pScreen->hWnd);
4454 Assert(pScreen->pDevice9If);
4455 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
4456 Assert(pShader);
4457 HRESULT hr = pScreen->pDevice9If->SetVertexShader(pShader);
4458 Assert(hr == S_OK);
4459 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4460 return hr;
4461}
4462static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
4463{
4464 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4465 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4466 Assert(pDevice);
4467 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4468 Assert(pScreen->hWnd);
4469 Assert(pScreen->pDevice9If);
4470 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
4471 HRESULT hr = S_OK;
4472 pShader->Release();
4473 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4474 return hr;
4475}
4476static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTI* pData, CONST INT* pRegisters)
4477{
4478 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4479 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4480 Assert(pDevice);
4481 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4482 Assert(pScreen->hWnd);
4483 Assert(pScreen->pDevice9If);
4484 HRESULT hr = pScreen->pDevice9If->SetVertexShaderConstantI(pData->Register, pRegisters, pData->Count);
4485 Assert(hr == S_OK);
4486 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4487 return hr;
4488}
4489static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTB* pData, CONST BOOL* pRegisters)
4490{
4491 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4492 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4493 Assert(pDevice);
4494 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4495 Assert(pScreen->hWnd);
4496 Assert(pScreen->pDevice9If);
4497 HRESULT hr = pScreen->pDevice9If->SetVertexShaderConstantB(pData->Register, pRegisters, pData->Count);
4498 Assert(hr == S_OK);
4499 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4500 return hr;
4501}
4502static HRESULT APIENTRY vboxWddmDDevSetScissorRect(HANDLE hDevice, CONST RECT* pRect)
4503{
4504 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4505 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4506 Assert(pDevice);
4507 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4508 Assert(pScreen->hWnd);
4509 Assert(pScreen->pDevice9If);
4510 HRESULT hr = pScreen->pDevice9If->SetScissorRect(pRect);
4511 Assert(hr == S_OK);
4512 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4513 return hr;
4514}
4515static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCE* pData)
4516{
4517 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4518 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4519 Assert(pDevice);
4520 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4521 Assert(pScreen->hWnd);
4522 Assert(pScreen->pDevice9If);
4523 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hVertexBuffer;
4524 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
4525 IDirect3DVertexBuffer9 *pStreamData = NULL;
4526 if (pRc)
4527 {
4528 Assert(pRc->cAllocations == 1);
4529 pAlloc = &pRc->aAllocations[0];
4530 Assert(pAlloc->pD3DIf);
4531 pStreamData = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4532 }
4533 HRESULT hr = pScreen->pDevice9If->SetStreamSource(pData->Stream, pStreamData, pData->Offset, pData->Stride);
4534 Assert(hr == S_OK);
4535 Assert(pData->Stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS);
4536 if (hr == S_OK)
4537 {
4538 if (pDevice->aStreamSource[pData->Stream] && !pAlloc)
4539 {
4540 --pDevice->cStreamSources;
4541 Assert(pDevice->cStreamSources < UINT32_MAX/2);
4542 }
4543 else if (!pDevice->aStreamSource[pData->Stream] && pAlloc)
4544 {
4545 ++pDevice->cStreamSources;
4546 Assert(pDevice->cStreamSources <= RT_ELEMENTS(pDevice->aStreamSource));
4547 }
4548 pDevice->aStreamSource[pData->Stream] = pAlloc;
4549 pDevice->StreamSourceInfo[pData->Stream].uiOffset = pData->Offset;
4550 pDevice->StreamSourceInfo[pData->Stream].uiStride = pData->Stride;
4551 }
4552 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4553 return hr;
4554}
4555static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData)
4556{
4557 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4558 Assert(0);
4559 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4560 return E_FAIL;
4561}
4562static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData)
4563{
4564 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4565 Assert(0);
4566 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4567 return E_FAIL;
4568}
4569static HRESULT APIENTRY vboxWddmDDevComposeRects(HANDLE hDevice, CONST D3DDDIARG_COMPOSERECTS* pData)
4570{
4571 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4572 Assert(0);
4573 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4574 return E_FAIL;
4575}
4576static HRESULT vboxWddmLockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc,
4577 D3DLOCKED_RECT * pLockedRect,
4578 CONST RECT *pRect,
4579 DWORD fLockFlags)
4580{
4581 HRESULT hr = E_FAIL;
4582 Assert(!pRc->aAllocations[iAlloc].LockInfo.cLocks);
4583 Assert(pRc->cAllocations > iAlloc);
4584 switch (pRc->aAllocations[0].enmD3DIfType)
4585 {
4586 case VBOXDISP_D3DIFTYPE_SURFACE:
4587 {
4588 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
4589 Assert(pD3DIfSurf);
4590 hr = pD3DIfSurf->LockRect(pLockedRect, pRect, fLockFlags);
4591 Assert(hr == S_OK);
4592 break;
4593 }
4594 case VBOXDISP_D3DIFTYPE_TEXTURE:
4595 {
4596 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
4597 Assert(pD3DIfTex);
4598 hr = pD3DIfTex->LockRect(iAlloc, pLockedRect, pRect, fLockFlags);
4599 Assert(hr == S_OK);
4600 break;
4601 }
4602 default:
4603 Assert(0);
4604 break;
4605 }
4606 return hr;
4607}
4608static HRESULT vboxWddmUnlockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc)
4609{
4610 HRESULT hr = S_OK;
4611 Assert(pRc->cAllocations > iAlloc);
4612 switch (pRc->aAllocations[0].enmD3DIfType)
4613 {
4614 case VBOXDISP_D3DIFTYPE_SURFACE:
4615 {
4616 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
4617 Assert(pD3DIfSurf);
4618 hr = pD3DIfSurf->UnlockRect();
4619 Assert(hr == S_OK);
4620 break;
4621 }
4622 case VBOXDISP_D3DIFTYPE_TEXTURE:
4623 {
4624 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
4625 Assert(pD3DIfTex);
4626 hr = pD3DIfTex->UnlockRect(iAlloc);
4627 Assert(hr == S_OK);
4628 break;
4629 }
4630 default:
4631 Assert(0);
4632 hr = E_FAIL;
4633 break;
4634 }
4635 return hr;
4636}
4637
4638/* on success increments the surface ref counter,
4639 * i.e. one must call pSurf->Release() once the surface is not needed*/
4640static HRESULT vboxWddmSurfGet(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc, IDirect3DSurface9 **ppSurf)
4641{
4642 HRESULT hr = S_OK;
4643 Assert(pRc->cAllocations > iAlloc);
4644 switch (pRc->aAllocations[0].enmD3DIfType)
4645 {
4646 case VBOXDISP_D3DIFTYPE_SURFACE:
4647 {
4648 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
4649 Assert(pD3DIfSurf);
4650 pD3DIfSurf->AddRef();
4651 *ppSurf = pD3DIfSurf;
4652 break;
4653 }
4654 case VBOXDISP_D3DIFTYPE_TEXTURE:
4655 {
4656 Assert(pRc->cAllocations == 1); /* <- vboxWddmSurfGet is typically used in Blt & ColorFill functions
4657 * in this case, if texture is used as a destination,
4658 * we should update sub-layers as well which is not done currently
4659 * so for now check vboxWddmSurfGet is used for one-level textures */
4660 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
4661 IDirect3DSurface9 *pSurfaceLevel;
4662 Assert(pD3DIfTex);
4663 hr = pD3DIfTex->GetSurfaceLevel(iAlloc, &pSurfaceLevel);
4664 Assert(hr == S_OK);
4665 if (hr == S_OK)
4666 {
4667 *ppSurf = pSurfaceLevel;
4668 }
4669 break;
4670 }
4671 default:
4672 Assert(0);
4673 hr = E_FAIL;
4674 break;
4675 }
4676 return hr;
4677}
4678
4679static HRESULT APIENTRY vboxWddmDDevBlt(HANDLE hDevice, CONST D3DDDIARG_BLT* pData)
4680{
4681 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4682 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4683 Assert(pDevice);
4684 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4685 Assert(pScreen->hWnd);
4686 Assert(pScreen->pDevice9If);
4687 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
4688 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
4689 Assert(pDstRc->cAllocations > pData->DstSubResourceIndex);
4690 Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex);
4691 Assert(pDstRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->DstSubResourceIndex);
4692 HRESULT hr = S_OK;
4693 /* try StretchRect */
4694 IDirect3DSurface9 *pSrcSurfIf = NULL;
4695 IDirect3DSurface9 *pDstSurfIf = NULL;
4696 hr = vboxWddmSurfGet(pDstRc, pData->DstSubResourceIndex, &pDstSurfIf);
4697 Assert(hr == S_OK);
4698 if (hr == S_OK)
4699 {
4700 Assert(pDstSurfIf);
4701 do
4702 {
4703#ifndef VBOXWDDM_WITH_VISIBLE_FB
4704 if (pSrcRc == pScreen->pRenderTargetRc && pScreen->iRenderTargetFrontBuf == pData->SrcSubResourceIndex
4705 && pScreen->pRenderTargetRc->cAllocations > 1) /* work-around wine backbuffer */
4706 {
4707 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
4708 PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
4709// Assert(pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width);
4710// Assert(pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height);
4711// Assert(pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format);
4712// Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
4713// Assert(pSrcAlloc->SurfDesc.pitch == pDstAlloc->SurfDesc.pitch);
4714// Assert(pSrcAlloc->SurfDesc.depth == pDstAlloc->SurfDesc.depth);
4715// Assert(pSrcAlloc->SurfDesc.slicePitch == pDstAlloc->SurfDesc.slicePitch);
4716// Assert(pSrcAlloc->SurfDesc.cbSize == pDstAlloc->SurfDesc.cbSize);
4717// Assert(pData->DstRect.left == 0);
4718// Assert(pData->DstRect.top == 0);
4719// Assert(pData->DstRect.right == pDstAlloc->SurfDesc.width);
4720// Assert(pData->DstRect.bottom == pDstAlloc->SurfDesc.height);
4721// Assert(pData->SrcRect.left == 0);
4722// Assert(pData->SrcRect.top == 0);
4723// Assert(pData->SrcRect.right == pSrcAlloc->SurfDesc.width);
4724// Assert(pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height);
4725#if 0
4726 if (pData->DstRect.left == 0 && pData->DstRect.top == 0
4727 && pData->DstRect.right == pDstAlloc->SurfDesc.width
4728 && pData->DstRect.bottom == pDstAlloc->SurfDesc.height
4729 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
4730 && pData->SrcRect.right == pSrcAlloc->SurfDesc.width
4731 && pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height
4732 && pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width
4733 && pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height
4734 && pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format)
4735 {
4736 hr = pScreen->pDevice9If->GetFrontBufferData(0, pDstSurfIf);
4737 Assert(hr == S_OK);
4738 break;
4739 }
4740 else
4741#endif
4742 {
4743 pSrcSurfIf = pDevice->pRenderTargetFbCopy;
4744 Assert(pSrcSurfIf);
4745 hr = pScreen->pDevice9If->GetFrontBufferData(0, pDevice->pRenderTargetFbCopy);
4746 Assert(hr == S_OK);
4747 if (hr == S_OK)
4748 {
4749 /* do pSrcSurfIf->AddRef since we do a Release in the following if (hr == S_OK) branch */
4750 pSrcSurfIf->AddRef();
4751 }
4752 }
4753 }
4754 else
4755#endif
4756 {
4757 hr = vboxWddmSurfGet(pSrcRc, pData->SrcSubResourceIndex, &pSrcSurfIf);
4758 Assert(hr == S_OK);
4759 }
4760
4761 if (hr == S_OK)
4762 {
4763 Assert(pSrcSurfIf);
4764#ifdef DEBUG_misha
4765 bool bDo = false;
4766
4767 if (g_VDbgTstDumpEnable)
4768 {
4769 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
4770 {
4771 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
4772 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
4773 {
4774 D3DSURFACE_DESC SrcDesc;
4775 HRESULT hr = pSrcSurfIf->GetDesc(&SrcDesc);
4776 Assert(hr == S_OK);
4777 if (hr == S_OK)
4778 {
4779 D3DSURFACE_DESC DstDesc;
4780 hr = pDstSurfIf->GetDesc(&DstDesc);
4781 Assert(hr == S_OK);
4782 if (hr == S_OK)
4783 {
4784 if (SrcDesc.Width == DstDesc.Width
4785 && SrcDesc.Height == DstDesc.Height)
4786 {
4787 bDo = true;
4788 }
4789 }
4790 }
4791 }
4792 }
4793 }
4794
4795 if (bDo)
4796 {
4797 vboxVDbgDumpSurfData((pDevice, "Blt-pre Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
4798 vboxVDbgDumpSurfData((pDevice, "Blt-pre Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
4799 }
4800#endif
4801 /* we support only Point & Linear, we ignore [Begin|Continue|End]PresentToDwm */
4802 Assert((pData->Flags.Value & (~(0x00000100 | 0x00000200 | 0x00000400 | 0x00000001 | 0x00000002))) == 0);
4803 hr = pScreen->pDevice9If->StretchRect(pSrcSurfIf,
4804 &pData->SrcRect,
4805 pDstSurfIf,
4806 &pData->DstRect,
4807 vboxDDI2D3DBltFlags(pData->Flags));
4808 Assert(hr == S_OK);
4809
4810#ifdef DEBUG_misha
4811 if (bDo)
4812 {
4813 vboxVDbgDumpSurfData((pDevice, "Blt-post Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
4814 vboxVDbgDumpSurfData((pDevice, "Blt-post Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
4815 }
4816#endif
4817 pSrcSurfIf->Release();
4818 }
4819 } while (0);
4820
4821 pDstSurfIf->Release();
4822 }
4823
4824 if (hr != S_OK)
4825 {
4826 /* todo: fallback to memcpy or whatever ? */
4827 Assert(0);
4828 }
4829
4830
4831#if 0
4832 if ((use pAlloc->enmD3DIfType instead!!! pDstRc->RcDesc.fFlags.Texture || pDstRc->RcDesc.fFlags.Value == 0)
4833 && (pSrcRc->RcDesc.fFlags.Texture || pSrcRc->RcDesc.fFlags.Value == 0))
4834 {
4835 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcAlloc->pD3DIf;
4836 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstAlloc->pD3DIf;
4837 Assert(pD3DIfSrcTex);
4838 Assert(pD3DIfDstTex);
4839
4840 if (pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat)
4841 {
4842 if (pSrcRc->aAllocations[0].SurfDesc.width == pDstRc->aAllocations[0].SurfDesc.width
4843 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
4844 && pData->DstRect.left == 0 && pData->DstRect.top == 0
4845 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
4846 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
4847 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height
4848 && pData->DstRect.right - pData->DstRect.left == pDstRc->aAllocations[0].SurfDesc.width
4849 && pData->DstRect.bottom - pData->DstRect.top == pDstRc->aAllocations[0].SurfDesc.height
4850 )
4851 {
4852 hr = pScreen->pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
4853 Assert(hr == S_OK);
4854 }
4855 else if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
4856 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
4857 {
4858 Assert(pDstAlloc->SurfDesc.bpp);
4859 Assert(pSrcAlloc->SurfDesc.bpp);
4860 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
4861 D3DLOCKED_RECT DstRect, SrcRect;
4862 Assert(!pSrcAlloc->LockInfo.cLocks);
4863 Assert(!pDstAlloc->LockInfo.cLocks);
4864 hr = pD3DIfDstTex->LockRect(pData->DstSubResourceIndex, &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
4865 Assert(hr == S_OK);
4866 if (hr == S_OK)
4867 {
4868 hr = pD3DIfSrcTex->LockRect(pData->SrcSubResourceIndex, &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
4869 Assert(hr == S_OK);
4870 if (hr == S_OK)
4871 {
4872 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
4873 &pData->DstRect, &pData->SrcRect,
4874 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
4875 Assert(hr == S_OK);
4876
4877 pD3DIfSrcTex->UnlockRect(pData->SrcSubResourceIndex);
4878 }
4879 pD3DIfDstTex->UnlockRect(pData->DstSubResourceIndex);
4880 }
4881 }
4882 else
4883 {
4884
4885 Assert(0);
4886 /* @todo: impl */
4887 }
4888 }
4889 else
4890 {
4891 Assert(0);
4892 /* @todo: impl */
4893 }
4894 }
4895 else
4896 {
4897 if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
4898 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
4899 {
4900 Assert(pDstAlloc->SurfDesc.bpp);
4901 Assert(pSrcAlloc->SurfDesc.bpp);
4902 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
4903
4904 D3DLOCKED_RECT DstRect, SrcRect;
4905 hr = vboxWddmLockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags,
4906 &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
4907 Assert(hr == S_OK);
4908 if (hr == S_OK)
4909 {
4910 hr = vboxWddmLockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags,
4911 &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
4912 Assert(hr == S_OK);
4913 if (hr == S_OK)
4914 {
4915 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
4916 &pData->DstRect, &pData->SrcRect,
4917 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
4918 Assert(hr == S_OK);
4919
4920 HRESULT tmpHr = vboxWddmUnlockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags);
4921 Assert(tmpHr == S_OK);
4922 }
4923 HRESULT tmpHr = vboxWddmUnlockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags);
4924 Assert(tmpHr == S_OK);
4925 }
4926 }
4927 else
4928 {
4929 Assert(0);
4930 /* @todo: impl */
4931 }
4932 }
4933#endif
4934
4935 if (pDstRc->RcDesc.fFlags.SharedResource)
4936 {
4937 PVBOXWDDMDISP_ALLOCATION pAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
4938 EnterCriticalSection(&pDevice->DirtyAllocListLock);
4939 if (!pAlloc->DirtyAllocListEntry.pNext)
4940 RTListAppend(&pDevice->DirtyAllocList, &pAlloc->DirtyAllocListEntry);
4941 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
4942 }
4943
4944 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4945 return hr;
4946}
4947static HRESULT APIENTRY vboxWddmDDevColorFill(HANDLE hDevice, CONST D3DDDIARG_COLORFILL* pData)
4948{
4949 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4950 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4951 Assert(pDevice);
4952 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4953 Assert(pScreen->hWnd);
4954 Assert(pScreen->pDevice9If);
4955 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4956 Assert(pRc);
4957 IDirect3DSurface9 *pSurfIf = NULL;
4958 HRESULT hr = vboxWddmSurfGet(pRc, pData->SubResourceIndex, &pSurfIf);
4959 Assert(hr == S_OK);
4960 if (hr == S_OK)
4961 {
4962 Assert(pSurfIf);
4963 hr = pScreen->pDevice9If->ColorFill(pSurfIf, &pData->DstRect, pData->Color);
4964 Assert(hr == S_OK);
4965 /* @todo: check what need to do when PresentToDwm flag is set */
4966 Assert(pData->Flags.Value == 0);
4967
4968 pSurfIf->Release();
4969 }
4970 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4971 return hr;
4972}
4973static HRESULT APIENTRY vboxWddmDDevDepthFill(HANDLE hDevice, CONST D3DDDIARG_DEPTHFILL* pData)
4974{
4975 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4976 Assert(0);
4977 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4978 return E_FAIL;
4979}
4980static HRESULT APIENTRY vboxWddmDDevCreateQuery(HANDLE hDevice, D3DDDIARG_CREATEQUERY* pData)
4981{
4982 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4983 Assert(0);
4984 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4985 return E_FAIL;
4986}
4987static HRESULT APIENTRY vboxWddmDDevDestroyQuery(HANDLE hDevice, HANDLE hQuery)
4988{
4989 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4990 Assert(0);
4991 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4992 return E_FAIL;
4993}
4994static HRESULT APIENTRY vboxWddmDDevIssueQuery(HANDLE hDevice, CONST D3DDDIARG_ISSUEQUERY* pData)
4995{
4996 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4997 Assert(0);
4998 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4999 return E_FAIL;
5000}
5001static HRESULT APIENTRY vboxWddmDDevGetQueryData(HANDLE hDevice, CONST D3DDDIARG_GETQUERYDATA* pData)
5002{
5003 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5004 Assert(0);
5005 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5006 return E_FAIL;
5007}
5008static HRESULT APIENTRY vboxWddmDDevSetRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETRENDERTARGET* pData)
5009{
5010 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5011 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5012 Assert(pDevice);
5013 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5014 Assert(pScreen->hWnd);
5015 Assert(pScreen->pDevice9If);
5016 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget;
5017 Assert(pRc);
5018 Assert(pData->SubResourceIndex < pRc->cAllocations);
5019 PVBOXWDDMDISP_SCREEN pVisibleScreen = pRc->RcDesc.fFlags.Primary ? &pDevice->aScreens[pRc->RcDesc.VidPnSourceId] : pScreen;
5020 if (pRc == pVisibleScreen->pRenderTargetRc)
5021 {
5022 /* backbuffer */
5023 Assert(pData->SubResourceIndex == ((pVisibleScreen->iRenderTargetFrontBuf + 1) % pVisibleScreen->pRenderTargetRc->cAllocations));
5024 }
5025
5026 HRESULT hr = S_OK;
5027 IDirect3DSurface9 *pD3D9Surf;
5028 if (pRc == pScreen->pRenderTargetRc && pRc->cAllocations == 1 && pData->RenderTargetIndex == 0)
5029 {
5030 /* work-around wine double-buffering for the case we have no backbuffers */
5031 hr = pScreen->pDevice9If->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
5032 Assert(hr == S_OK);
5033 Assert(pD3D9Surf);
5034 }
5035 else
5036 {
5037 hr = vboxWddmSurfGet(pRc, pData->SubResourceIndex, &pD3D9Surf);
5038 Assert(hr == S_OK);
5039 Assert(pD3D9Surf);
5040 }
5041 if (hr == S_OK)
5042 {
5043 Assert(pD3D9Surf);
5044 hr = pScreen->pDevice9If->SetRenderTarget(pData->RenderTargetIndex, pD3D9Surf);
5045 Assert(hr == S_OK);
5046 pD3D9Surf->Release();
5047 }
5048 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5049 return hr;
5050}
5051static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDIARG_SETDEPTHSTENCIL* pData)
5052{
5053 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5054 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5055 Assert(pDevice);
5056 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5057 Assert(pScreen->hWnd);
5058 Assert(pScreen->pDevice9If);
5059 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hZBuffer;
5060 IDirect3DSurface9 *pD3D9Surf = NULL;
5061 if (pRc)
5062 {
5063 Assert(pRc->cAllocations == 1);
5064 pD3D9Surf = (IDirect3DSurface9*)pRc->aAllocations[0].pD3DIf;
5065 Assert(pD3D9Surf);
5066 }
5067 HRESULT hr = pScreen->pDevice9If->SetDepthStencilSurface(pD3D9Surf);
5068 Assert(hr == S_OK);
5069 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5070 return hr;
5071}
5072static HRESULT APIENTRY vboxWddmDDevGenerateMipSubLevels(HANDLE hDevice, CONST D3DDDIARG_GENERATEMIPSUBLEVELS* pData)
5073{
5074 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5075 Assert(0);
5076 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5077 return E_FAIL;
5078}
5079static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTI* pData, CONST INT* pRegisters)
5080{
5081 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5082 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5083 Assert(pDevice);
5084 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5085 Assert(pScreen->hWnd);
5086 Assert(pScreen->pDevice9If);
5087 HRESULT hr = pScreen->pDevice9If->SetPixelShaderConstantI(pData->Register, pRegisters, pData->Count);
5088 Assert(hr == S_OK);
5089 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5090 return hr;
5091}
5092static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTB* pData, CONST BOOL* pRegisters)
5093{
5094 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5095 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5096 Assert(pDevice);
5097 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5098 Assert(pScreen->hWnd);
5099 Assert(pScreen->pDevice9If);
5100 HRESULT hr = pScreen->pDevice9If->SetPixelShaderConstantB(pData->Register, pRegisters, pData->Count);
5101 Assert(hr == S_OK);
5102 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5103 return hr;
5104}
5105static HRESULT APIENTRY vboxWddmDDevCreatePixelShader(HANDLE hDevice, D3DDDIARG_CREATEPIXELSHADER* pData, CONST UINT* pCode)
5106{
5107 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5108 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5109 Assert(pDevice);
5110 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5111 Assert(pScreen->hWnd);
5112 Assert(pScreen->pDevice9If);
5113 IDirect3DPixelShader9 *pShader;
5114 Assert(*((UINT*)((uint8_t*)pCode + pData->CodeSize-4)) == 0x0000FFFF /* end token */);
5115 HRESULT hr = pScreen->pDevice9If->CreatePixelShader((const DWORD *)pCode, &pShader);
5116 Assert(hr == S_OK);
5117 if (hr == S_OK)
5118 {
5119 Assert(pShader);
5120 pData->ShaderHandle = pShader;
5121 }
5122 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5123 return hr;
5124}
5125static HRESULT APIENTRY vboxWddmDDevDeletePixelShader(HANDLE hDevice, HANDLE hShaderHandle)
5126{
5127 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5128 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5129 Assert(pDevice);
5130 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5131 Assert(pScreen->hWnd);
5132 Assert(pScreen->pDevice9If);
5133 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
5134 HRESULT hr = S_OK;
5135 pShader->Release();
5136 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5137 return hr;
5138}
5139static HRESULT APIENTRY vboxWddmDDevCreateDecodeDevice(HANDLE hDevice, D3DDDIARG_CREATEDECODEDEVICE* pData)
5140{
5141 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5142 Assert(0);
5143 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5144 return E_FAIL;
5145}
5146static HRESULT APIENTRY vboxWddmDDevDestroyDecodeDevice(HANDLE hDevice, HANDLE hDecodeDevice)
5147{
5148 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5149 Assert(0);
5150 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5151 return E_FAIL;
5152}
5153static HRESULT APIENTRY vboxWddmDDevSetDecodeRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETDECODERENDERTARGET* pData)
5154{
5155 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5156 Assert(0);
5157 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5158 return E_FAIL;
5159}
5160static HRESULT APIENTRY vboxWddmDDevDecodeBeginFrame(HANDLE hDevice, D3DDDIARG_DECODEBEGINFRAME* pData)
5161{
5162 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5163 Assert(0);
5164 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5165 return E_FAIL;
5166}
5167static HRESULT APIENTRY vboxWddmDDevDecodeEndFrame(HANDLE hDevice, D3DDDIARG_DECODEENDFRAME* pData)
5168{
5169 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5170 Assert(0);
5171 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5172 return E_FAIL;
5173}
5174static HRESULT APIENTRY vboxWddmDDevDecodeExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXECUTE* pData)
5175{
5176 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5177 Assert(0);
5178 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5179 return E_FAIL;
5180}
5181static HRESULT APIENTRY vboxWddmDDevDecodeExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXTENSIONEXECUTE* pData)
5182{
5183 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5184 Assert(0);
5185 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5186 return E_FAIL;
5187}
5188static HRESULT APIENTRY vboxWddmDDevCreateVideoProcessDevice(HANDLE hDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE* pData)
5189{
5190 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5191 Assert(0);
5192 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5193 return E_FAIL;
5194}
5195static HRESULT APIENTRY vboxWddmDDevDestroyVideoProcessDevice(HANDLE hDevice, HANDLE hVideoProcessor)
5196{
5197 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5198 Assert(0);
5199 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5200 return E_FAIL;
5201}
5202static HRESULT APIENTRY vboxWddmDDevVideoProcessBeginFrame(HANDLE hDevice, HANDLE hVideoProcess)
5203{
5204 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5205 Assert(0);
5206 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5207 return E_FAIL;
5208}
5209static HRESULT APIENTRY vboxWddmDDevVideoProcessEndFrame(HANDLE hDevice, D3DDDIARG_VIDEOPROCESSENDFRAME* pData)
5210{
5211 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5212 Assert(0);
5213 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5214 return E_FAIL;
5215}
5216static HRESULT APIENTRY vboxWddmDDevSetVideoProcessRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETVIDEOPROCESSRENDERTARGET* pData)
5217{
5218 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5219 Assert(0);
5220 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5221 return E_FAIL;
5222}
5223static HRESULT APIENTRY vboxWddmDDevVideoProcessBlt(HANDLE hDevice, CONST D3DDDIARG_VIDEOPROCESSBLT* pData)
5224{
5225 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5226 Assert(0);
5227 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5228 return E_FAIL;
5229}
5230static HRESULT APIENTRY vboxWddmDDevCreateExtensionDevice(HANDLE hDevice, D3DDDIARG_CREATEEXTENSIONDEVICE* pData)
5231{
5232 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5233 Assert(0);
5234 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5235 return E_FAIL;
5236}
5237static HRESULT APIENTRY vboxWddmDDevDestroyExtensionDevice(HANDLE hDevice, HANDLE hExtension)
5238{
5239 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5240 Assert(0);
5241 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5242 return E_FAIL;
5243}
5244static HRESULT APIENTRY vboxWddmDDevExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_EXTENSIONEXECUTE* pData)
5245{
5246 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5247 Assert(0);
5248 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5249 return E_FAIL;
5250}
5251static HRESULT APIENTRY vboxWddmDDevDestroyDevice(IN HANDLE hDevice)
5252{
5253 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5254
5255 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5256 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
5257// Assert(!pDevice->cScreens);
5258#ifndef VBOXWDDM_WITH_VISIBLE_FB
5259 if(pDevice->pRenderTargetFbCopy)
5260 pDevice->pRenderTargetFbCopy->Release();
5261#endif
5262 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aScreens); ++i)
5263 {
5264 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i];
5265 if (pScreen->pDevice9If)
5266 {
5267 pScreen->pDevice9If->Release();
5268 Assert(pScreen->hWnd);
5269 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pScreen->hWnd);
5270 Assert(tmpHr == S_OK);
5271 }
5272 }
5273
5274 HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
5275 Assert(hr == S_OK);
5276 if (hr == S_OK)
5277 RTMemFree(pDevice);
5278 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5279 return hr;
5280}
5281
5282AssertCompile(sizeof (RECT) == sizeof (D3DDDIRECT));
5283AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DDDIRECT, left));
5284AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DDDIRECT, right));
5285AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DDDIRECT, top));
5286AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DDDIRECT, bottom));
5287AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DDDIRECT, left));
5288AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DDDIRECT, right));
5289AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DDDIRECT, top));
5290AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DDDIRECT, bottom));
5291
5292static HRESULT APIENTRY vboxWddmDDevCreateOverlay(HANDLE hDevice, D3DDDIARG_CREATEOVERLAY* pData)
5293{
5294 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5295 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5296 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
5297 Assert(pRc);
5298 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
5299 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
5300 HRESULT hr = S_OK;
5301 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)RTMemAllocZ(sizeof (VBOXWDDMDISP_OVERLAY));
5302 Assert(pOverlay);
5303 if (pOverlay)
5304 {
5305 VBOXWDDM_OVERLAY_INFO OurInfo;
5306 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
5307 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
5308 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
5309 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
5310 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
5311 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
5312 Assert(!pAlloc->LockInfo.cLocks);
5313 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
5314 D3DDDICB_CREATEOVERLAY OverInfo;
5315 OverInfo.VidPnSourceId = pData->VidPnSourceId;
5316 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
5317 Assert(pAlloc->hAllocation);
5318 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
5319 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
5320 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
5321 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
5322 OverInfo.hKernelOverlay = NULL; /* <-- out */
5323#ifndef VBOXWDDMOVERLAY_TEST
5324 hr = pDevice->RtCallbacks.pfnCreateOverlayCb(pDevice->hDevice, &OverInfo);
5325 Assert(hr == S_OK);
5326 if (hr == S_OK)
5327 {
5328 Assert(OverInfo.hKernelOverlay);
5329 pOverlay->hOverlay = OverInfo.hKernelOverlay;
5330 pOverlay->VidPnSourceId = pData->VidPnSourceId;
5331
5332 Assert(!pAlloc->LockInfo.cLocks);
5333 if (!pAlloc->LockInfo.cLocks)
5334 {
5335 /* we have reported the dirty rect, may clear it if no locks are pending currently */
5336 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
5337 }
5338
5339 pData->hOverlay = pOverlay;
5340 }
5341 else
5342 {
5343 RTMemFree(pOverlay);
5344 }
5345#else
5346 pData->hOverlay = pOverlay;
5347#endif
5348 }
5349 else
5350 hr = E_OUTOFMEMORY;
5351
5352 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5353 return hr;
5354}
5355static HRESULT APIENTRY vboxWddmDDevUpdateOverlay(HANDLE hDevice, CONST D3DDDIARG_UPDATEOVERLAY* pData)
5356{
5357 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5358 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5359 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
5360 Assert(pRc);
5361 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
5362 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
5363 HRESULT hr = S_OK;
5364 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
5365 VBOXWDDM_OVERLAY_INFO OurInfo;
5366 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
5367 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
5368 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
5369 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
5370 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
5371 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
5372 Assert(!pAlloc->LockInfo.cLocks);
5373 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
5374 D3DDDICB_UPDATEOVERLAY OverInfo;
5375 OverInfo.hKernelOverlay = pOverlay->hOverlay;
5376 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
5377 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
5378 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
5379 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
5380 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
5381#ifndef VBOXWDDMOVERLAY_TEST
5382 hr = pDevice->RtCallbacks.pfnUpdateOverlayCb(pDevice->hDevice, &OverInfo);
5383 Assert(hr == S_OK);
5384 if (hr == S_OK)
5385#endif
5386 {
5387 Assert(!pAlloc->LockInfo.cLocks);
5388 if (!pAlloc->LockInfo.cLocks)
5389 {
5390 /* we have reported the dirty rect, may clear it if no locks are pending currently */
5391 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
5392 }
5393 }
5394
5395 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5396 return hr;
5397}
5398static HRESULT APIENTRY vboxWddmDDevFlipOverlay(HANDLE hDevice, CONST D3DDDIARG_FLIPOVERLAY* pData)
5399{
5400 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5401 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5402 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSource;
5403 Assert(pRc);
5404 Assert(pRc->cAllocations > pData->SourceIndex);
5405 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SourceIndex];
5406 HRESULT hr = S_OK;
5407 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
5408 VBOXWDDM_OVERLAYFLIP_INFO OurInfo;
5409 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
5410 Assert(!pAlloc->LockInfo.cLocks);
5411 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
5412 D3DDDICB_FLIPOVERLAY OverInfo;
5413 OverInfo.hKernelOverlay = pOverlay->hOverlay;
5414 OverInfo.hSource = pAlloc->hAllocation;
5415 OverInfo.pPrivateDriverData = &OurInfo;
5416 OverInfo.PrivateDriverDataSize = sizeof (OurInfo);
5417#ifndef VBOXWDDMOVERLAY_TEST
5418 hr = pDevice->RtCallbacks.pfnFlipOverlayCb(pDevice->hDevice, &OverInfo);
5419 Assert(hr == S_OK);
5420 if (hr == S_OK)
5421#endif
5422 {
5423 Assert(!pAlloc->LockInfo.cLocks);
5424 if (!pAlloc->LockInfo.cLocks)
5425 {
5426 /* we have reported the dirty rect, may clear it if no locks are pending currently */
5427 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
5428 }
5429 }
5430
5431 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5432 return hr;
5433}
5434static HRESULT APIENTRY vboxWddmDDevGetOverlayColorControls(HANDLE hDevice, D3DDDIARG_GETOVERLAYCOLORCONTROLS* pData)
5435{
5436 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5437 Assert(0);
5438 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5439 return E_FAIL;
5440}
5441static HRESULT APIENTRY vboxWddmDDevSetOverlayColorControls(HANDLE hDevice, CONST D3DDDIARG_SETOVERLAYCOLORCONTROLS* pData)
5442{
5443 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5444 Assert(0);
5445 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5446 return E_FAIL;
5447}
5448static HRESULT APIENTRY vboxWddmDDevDestroyOverlay(HANDLE hDevice, CONST D3DDDIARG_DESTROYOVERLAY* pData)
5449{
5450 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5451 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5452 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
5453 D3DDDICB_DESTROYOVERLAY OverInfo;
5454 OverInfo.hKernelOverlay = pOverlay->hOverlay;
5455#ifndef VBOXWDDMOVERLAY_TEST
5456 HRESULT hr = pDevice->RtCallbacks.pfnDestroyOverlayCb(pDevice->hDevice, &OverInfo);
5457 Assert(hr == S_OK);
5458 if (hr == S_OK)
5459#else
5460 HRESULT hr = S_OK;
5461#endif
5462 {
5463 RTMemFree(pOverlay);
5464 }
5465
5466 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5467 return hr;
5468}
5469static HRESULT APIENTRY vboxWddmDDevQueryResourceResidency(HANDLE hDevice, CONST D3DDDIARG_QUERYRESOURCERESIDENCY* pData)
5470{
5471 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5472 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5473 Assert(0);
5474 HRESULT hr = S_OK;
5475#if 0
5476 for (UINT i = 0; i < pData->NumResources; ++i)
5477 {
5478 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->pHandleList[i];
5479 Assert(pRc->pDevice == pDevice);
5480 if (pRc->hKMResource)
5481 {
5482
5483 }
5484 }
5485#endif
5486 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5487 return hr;
5488}
5489
5490static HRESULT vboxAllocationInit(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DDDI_OPENALLOCATIONINFO *pInfo)
5491{
5492 HRESULT hr = S_OK;
5493 pAlloc->hAllocation = pInfo->hAllocation;
5494 Assert(pInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
5495 Assert(pInfo->pPrivateDriverData);
5496 if (pInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
5497 {
5498 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pInfo->pPrivateDriverData;
5499 pAlloc->enmType = pAllocInfo->enmType;
5500 Assert(pAllocInfo->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
5501 || VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE
5502 || VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE);
5503 pAlloc->pvMem = NULL;
5504 pAlloc->SurfDesc = pAllocInfo->SurfDesc;
5505 }
5506 else
5507 {
5508 vboxVDbgPrintR((__FUNCTION__": ERROR: PrivateDriverDataSize(%d) < (%d)\n", pInfo->PrivateDriverDataSize, sizeof (VBOXWDDM_ALLOCINFO)));
5509 hr = E_INVALIDARG;
5510 }
5511 return hr;
5512}
5513
5514static HRESULT APIENTRY vboxWddmDDevOpenResource(HANDLE hDevice, D3DDDIARG_OPENRESOURCE* pData)
5515{
5516 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5517 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5518 HRESULT hr = S_OK;
5519
5520 Assert(pDevice);
5521 Assert(pData->NumAllocations);
5522 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pData->NumAllocations);
5523 Assert(pRc);
5524 if (pRc)
5525 {
5526 pRc->hResource = pData->hResource;
5527 pRc->hKMResource = pData->hKMResource;
5528 pRc->pDevice = pDevice;
5529 pRc->RcDesc.enmRotation = pData->Rotation;
5530 pRc->fFlags = VBOXWDDM_RESOURCE_F_OPENNED;
5531 if (!pData->pPrivateDriverData || !pData->PrivateDriverDataSize)
5532 {
5533 /* this is a "standard" allocation resource */
5534
5535 /* both should be actually zero */
5536 Assert(!pData->pPrivateDriverData && !pData->PrivateDriverDataSize);
5537 pRc->RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
5538 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
5539 pRc->RcDesc.MultisampleQuality = 0;
5540 pRc->RcDesc.MipLevels = 0;
5541 pRc->RcDesc.Fvf;
5542 pRc->RcDesc.fFlags.Value = 0;
5543
5544 Assert(pData->NumAllocations);
5545 D3DDDI_OPENALLOCATIONINFO* pDdiAllocInfo = &pData->pOpenAllocationInfo[0];
5546 Assert(pDdiAllocInfo->pPrivateDriverData);
5547 Assert(pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO));
5548 if (pDdiAllocInfo->pPrivateDriverData && pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
5549 {
5550 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocInfo->pPrivateDriverData;
5551 switch(pAllocInfo->enmType)
5552 {
5553 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
5554 pRc->RcDesc.fFlags.Primary = 1;
5555 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
5556 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
5557 pRc->RcDesc.enmFormat = pAllocInfo->SurfDesc.format;
5558 pRc->RcDesc.VidPnSourceId = pAllocInfo->SurfDesc.VidPnSourceId;
5559 pRc->RcDesc.RefreshRate = pAllocInfo->SurfDesc.RefreshRate;
5560 break;
5561 default:
5562 Assert(0);
5563 hr = E_INVALIDARG;
5564 }
5565 }
5566 else
5567 hr = E_INVALIDARG;
5568 }
5569 else
5570 {
5571 /* this is a "generic" resource whose creation is initiaded by the UMD */
5572 Assert(pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
5573 if (pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO))
5574 {
5575 VBOXWDDM_RCINFO *pRcInfo = (VBOXWDDM_RCINFO*)pData->pPrivateDriverData;
5576 Assert(pRcInfo->fFlags == VBOXWDDM_RESOURCE_F_TYPE_GENERIC);
5577 Assert(pRcInfo->cAllocInfos == pData->NumAllocations);
5578 pRc->fFlags = pRcInfo->fFlags | VBOXWDDM_RESOURCE_F_OPENNED;
5579 pRc->RcDesc = pRcInfo->RcDesc;
5580 pRc->cAllocations = pData->NumAllocations;
5581
5582 for (UINT i = 0; i < pData->NumAllocations; ++i)
5583 {
5584 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5585 D3DDDI_OPENALLOCATIONINFO* pOAI = pData->pOpenAllocationInfo;
5586 Assert(pOAI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
5587 if (pOAI->PrivateDriverDataSize != sizeof (VBOXWDDM_ALLOCINFO))
5588 {
5589 hr = E_INVALIDARG;
5590 break;
5591 }
5592 Assert(pOAI->pPrivateDriverData);
5593 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pOAI->pPrivateDriverData;
5594 pAllocation->hAllocation = pOAI->hAllocation;
5595 pAllocation->enmType = pAllocInfo->enmType;
5596 pAllocation->hSharedHandle = pAllocInfo->hSharedHandle;
5597 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
5598 Assert(pAllocation->hSharedHandle);
5599 }
5600
5601 Assert(pRc->RcDesc.fFlags.SharedResource);
5602 if (pRc->RcDesc.fFlags.Texture)
5603 {
5604 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5605 Assert(pScreen->hWnd);
5606 Assert(pScreen->pDevice9If);
5607 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
5608 IDirect3DTexture9 *pD3DIfTex;
5609 HANDLE hSharedHandle = pAllocation->hSharedHandle;
5610 Assert(pAllocation->hSharedHandle);
5611
5612 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pScreen->pDevice9If,
5613 pAllocation->SurfDesc.width,
5614 pAllocation->SurfDesc.height,
5615 pRc->cAllocations,
5616 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
5617 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
5618 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
5619 &pD3DIfTex,
5620 &hSharedHandle,
5621 NULL);
5622 Assert(hr == S_OK);
5623 if (hr == S_OK)
5624 {
5625 Assert(pD3DIfTex);
5626 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
5627 pAllocation->pD3DIf = pD3DIfTex;
5628 Assert(pAllocation->hSharedHandle == hSharedHandle);
5629 Assert(pAllocation->hSharedHandle);
5630 }
5631 }
5632 else
5633 {
5634 /* impl */
5635 Assert(0);
5636 }
5637 }
5638 else
5639 hr = E_INVALIDARG;
5640 }
5641
5642 if (hr == S_OK)
5643 {
5644 for (UINT i = 0; i < pData->NumAllocations; ++i)
5645 {
5646 hr = vboxAllocationInit(&pRc->aAllocations[i], &pData->pOpenAllocationInfo[i]);
5647 Assert(hr == S_OK);
5648 if (hr != S_OK)
5649 break;
5650 }
5651 }
5652
5653 if (hr == S_OK)
5654 pData->hResource = pRc;
5655 else
5656 vboxResourceFree(pRc);
5657 }
5658 else
5659 {
5660 vboxVDbgPrintR((__FUNCTION__": vboxResourceAlloc failed for hDevice(0x%p), NumAllocations(%d)\n", hDevice, pData->NumAllocations));
5661 hr = E_OUTOFMEMORY;
5662 }
5663
5664 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5665 return hr;
5666}
5667static HRESULT APIENTRY vboxWddmDDevGetCaptureAllocationHandle(HANDLE hDevice, D3DDDIARG_GETCAPTUREALLOCATIONHANDLE* pData)
5668{
5669 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5670 Assert(0);
5671 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5672 return E_FAIL;
5673}
5674
5675static HRESULT APIENTRY vboxWddmDDevCaptureToSysMem(HANDLE hDevice, CONST D3DDDIARG_CAPTURETOSYSMEM* pData)
5676{
5677 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5678 Assert(0);
5679 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5680 return E_FAIL;
5681}
5682
5683static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIARG_CREATEDEVICE* pCreateData)
5684{
5685 HRESULT hr = S_OK;
5686 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), Interface(%d), Version(%d)\n", hAdapter, pCreateData->Interface, pCreateData->Version));
5687
5688// Assert(0);
5689
5690 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(sizeof (VBOXWDDMDISP_DEVICE));
5691 if (pDevice)
5692 {
5693 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
5694
5695 pDevice->hDevice = pCreateData->hDevice;
5696 pDevice->pAdapter = pAdapter;
5697 pDevice->u32IfVersion = pCreateData->Interface;
5698 pDevice->uRtVersion = pCreateData->Version;
5699 pDevice->RtCallbacks = *pCreateData->pCallbacks;
5700 pDevice->pvCmdBuffer = pCreateData->pCommandBuffer;
5701 pDevice->cbCmdBuffer = pCreateData->CommandBufferSize;
5702 pDevice->fFlags = pCreateData->Flags;
5703 /* Set Viewport to some default values */
5704 pDevice->ViewPort.X = 0;
5705 pDevice->ViewPort.Y = 0;
5706 pDevice->ViewPort.Width = 1;
5707 pDevice->ViewPort.Height = 1;
5708 pDevice->ViewPort.MinZ = 0.;
5709 pDevice->ViewPort.MaxZ = 1.;
5710
5711 InitializeCriticalSection(&pDevice->DirtyAllocListLock);
5712 RTListInit(&pDevice->DirtyAllocList);
5713
5714 Assert(!pCreateData->AllocationListSize);
5715 Assert(!pCreateData->PatchLocationListSize);
5716
5717 pCreateData->hDevice = pDevice;
5718
5719 pCreateData->pDeviceFuncs->pfnSetRenderState = vboxWddmDDevSetRenderState;
5720 pCreateData->pDeviceFuncs->pfnUpdateWInfo = vboxWddmDDevUpdateWInfo;
5721 pCreateData->pDeviceFuncs->pfnValidateDevice = vboxWddmDDevValidateDevice;
5722 pCreateData->pDeviceFuncs->pfnSetTextureStageState = vboxWddmDDevSetTextureStageState;
5723 pCreateData->pDeviceFuncs->pfnSetTexture = vboxWddmDDevSetTexture;
5724 pCreateData->pDeviceFuncs->pfnSetPixelShader = vboxWddmDDevSetPixelShader;
5725 pCreateData->pDeviceFuncs->pfnSetPixelShaderConst = vboxWddmDDevSetPixelShaderConst;
5726 pCreateData->pDeviceFuncs->pfnSetStreamSourceUm = vboxWddmDDevSetStreamSourceUm;
5727 pCreateData->pDeviceFuncs->pfnSetIndices = vboxWddmDDevSetIndices;
5728 pCreateData->pDeviceFuncs->pfnSetIndicesUm = vboxWddmDDevSetIndicesUm;
5729 pCreateData->pDeviceFuncs->pfnDrawPrimitive = vboxWddmDDevDrawPrimitive;
5730 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive = vboxWddmDDevDrawIndexedPrimitive;
5731 pCreateData->pDeviceFuncs->pfnDrawRectPatch = vboxWddmDDevDrawRectPatch;
5732 pCreateData->pDeviceFuncs->pfnDrawTriPatch = vboxWddmDDevDrawTriPatch;
5733 pCreateData->pDeviceFuncs->pfnDrawPrimitive2 = vboxWddmDDevDrawPrimitive2;
5734 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive2 = vboxWddmDDevDrawIndexedPrimitive2;
5735 pCreateData->pDeviceFuncs->pfnVolBlt = vboxWddmDDevVolBlt;
5736 pCreateData->pDeviceFuncs->pfnBufBlt = vboxWddmDDevBufBlt;
5737 pCreateData->pDeviceFuncs->pfnTexBlt = vboxWddmDDevTexBlt;
5738 pCreateData->pDeviceFuncs->pfnStateSet = vboxWddmDDevStateSet;
5739 pCreateData->pDeviceFuncs->pfnSetPriority = vboxWddmDDevSetPriority;
5740 pCreateData->pDeviceFuncs->pfnClear = vboxWddmDDevClear;
5741 pCreateData->pDeviceFuncs->pfnUpdatePalette = vboxWddmDDevUpdatePalette;
5742 pCreateData->pDeviceFuncs->pfnSetPalette = vboxWddmDDevSetPalette;
5743 pCreateData->pDeviceFuncs->pfnSetVertexShaderConst = vboxWddmDDevSetVertexShaderConst;
5744 pCreateData->pDeviceFuncs->pfnMultiplyTransform = vboxWddmDDevMultiplyTransform;
5745 pCreateData->pDeviceFuncs->pfnSetTransform = vboxWddmDDevSetTransform;
5746 pCreateData->pDeviceFuncs->pfnSetViewport = vboxWddmDDevSetViewport;
5747 pCreateData->pDeviceFuncs->pfnSetZRange = vboxWddmDDevSetZRange;
5748 pCreateData->pDeviceFuncs->pfnSetMaterial = vboxWddmDDevSetMaterial;
5749 pCreateData->pDeviceFuncs->pfnSetLight = vboxWddmDDevSetLight;
5750 pCreateData->pDeviceFuncs->pfnCreateLight = vboxWddmDDevCreateLight;
5751 pCreateData->pDeviceFuncs->pfnDestroyLight = vboxWddmDDevDestroyLight;
5752 pCreateData->pDeviceFuncs->pfnSetClipPlane = vboxWddmDDevSetClipPlane;
5753 pCreateData->pDeviceFuncs->pfnGetInfo = vboxWddmDDevGetInfo;
5754 pCreateData->pDeviceFuncs->pfnLock = vboxWddmDDevLock;
5755 pCreateData->pDeviceFuncs->pfnUnlock = vboxWddmDDevUnlock;
5756 pCreateData->pDeviceFuncs->pfnCreateResource = vboxWddmDDevCreateResource;
5757 pCreateData->pDeviceFuncs->pfnDestroyResource = vboxWddmDDevDestroyResource;
5758 pCreateData->pDeviceFuncs->pfnSetDisplayMode = vboxWddmDDevSetDisplayMode;
5759 pCreateData->pDeviceFuncs->pfnPresent = vboxWddmDDevPresent;
5760 pCreateData->pDeviceFuncs->pfnFlush = vboxWddmDDevFlush;
5761 pCreateData->pDeviceFuncs->pfnCreateVertexShaderFunc = vboxWddmDDevCreateVertexShaderFunc;
5762 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderFunc = vboxWddmDDevDeleteVertexShaderFunc;
5763 pCreateData->pDeviceFuncs->pfnSetVertexShaderFunc = vboxWddmDDevSetVertexShaderFunc;
5764 pCreateData->pDeviceFuncs->pfnCreateVertexShaderDecl = vboxWddmDDevCreateVertexShaderDecl;
5765 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderDecl = vboxWddmDDevDeleteVertexShaderDecl;
5766 pCreateData->pDeviceFuncs->pfnSetVertexShaderDecl = vboxWddmDDevSetVertexShaderDecl;
5767 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstI = vboxWddmDDevSetVertexShaderConstI;
5768 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstB = vboxWddmDDevSetVertexShaderConstB;
5769 pCreateData->pDeviceFuncs->pfnSetScissorRect = vboxWddmDDevSetScissorRect;
5770 pCreateData->pDeviceFuncs->pfnSetStreamSource = vboxWddmDDevSetStreamSource;
5771 pCreateData->pDeviceFuncs->pfnSetStreamSourceFreq = vboxWddmDDevSetStreamSourceFreq;
5772 pCreateData->pDeviceFuncs->pfnSetConvolutionKernelMono = vboxWddmDDevSetConvolutionKernelMono;
5773 pCreateData->pDeviceFuncs->pfnComposeRects = vboxWddmDDevComposeRects;
5774 pCreateData->pDeviceFuncs->pfnBlt = vboxWddmDDevBlt;
5775 pCreateData->pDeviceFuncs->pfnColorFill = vboxWddmDDevColorFill;
5776 pCreateData->pDeviceFuncs->pfnDepthFill = vboxWddmDDevDepthFill;
5777 pCreateData->pDeviceFuncs->pfnCreateQuery = vboxWddmDDevCreateQuery;
5778 pCreateData->pDeviceFuncs->pfnDestroyQuery = vboxWddmDDevDestroyQuery;
5779 pCreateData->pDeviceFuncs->pfnIssueQuery = vboxWddmDDevIssueQuery;
5780 pCreateData->pDeviceFuncs->pfnGetQueryData = vboxWddmDDevGetQueryData;
5781 pCreateData->pDeviceFuncs->pfnSetRenderTarget = vboxWddmDDevSetRenderTarget;
5782 pCreateData->pDeviceFuncs->pfnSetDepthStencil = vboxWddmDDevSetDepthStencil;
5783 pCreateData->pDeviceFuncs->pfnGenerateMipSubLevels = vboxWddmDDevGenerateMipSubLevels;
5784 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstI = vboxWddmDDevSetPixelShaderConstI;
5785 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstB = vboxWddmDDevSetPixelShaderConstB;
5786 pCreateData->pDeviceFuncs->pfnCreatePixelShader = vboxWddmDDevCreatePixelShader;
5787 pCreateData->pDeviceFuncs->pfnDeletePixelShader = vboxWddmDDevDeletePixelShader;
5788 pCreateData->pDeviceFuncs->pfnCreateDecodeDevice = vboxWddmDDevCreateDecodeDevice;
5789 pCreateData->pDeviceFuncs->pfnDestroyDecodeDevice = vboxWddmDDevDestroyDecodeDevice;
5790 pCreateData->pDeviceFuncs->pfnSetDecodeRenderTarget = vboxWddmDDevSetDecodeRenderTarget;
5791 pCreateData->pDeviceFuncs->pfnDecodeBeginFrame = vboxWddmDDevDecodeBeginFrame;
5792 pCreateData->pDeviceFuncs->pfnDecodeEndFrame = vboxWddmDDevDecodeEndFrame;
5793 pCreateData->pDeviceFuncs->pfnDecodeExecute = vboxWddmDDevDecodeExecute;
5794 pCreateData->pDeviceFuncs->pfnDecodeExtensionExecute = vboxWddmDDevDecodeExtensionExecute;
5795 pCreateData->pDeviceFuncs->pfnCreateVideoProcessDevice = vboxWddmDDevCreateVideoProcessDevice;
5796 pCreateData->pDeviceFuncs->pfnDestroyVideoProcessDevice = vboxWddmDDevDestroyVideoProcessDevice;
5797 pCreateData->pDeviceFuncs->pfnVideoProcessBeginFrame = vboxWddmDDevVideoProcessBeginFrame;
5798 pCreateData->pDeviceFuncs->pfnVideoProcessEndFrame = vboxWddmDDevVideoProcessEndFrame;
5799 pCreateData->pDeviceFuncs->pfnSetVideoProcessRenderTarget = vboxWddmDDevSetVideoProcessRenderTarget;
5800 pCreateData->pDeviceFuncs->pfnVideoProcessBlt = vboxWddmDDevVideoProcessBlt;
5801 pCreateData->pDeviceFuncs->pfnCreateExtensionDevice = vboxWddmDDevCreateExtensionDevice;
5802 pCreateData->pDeviceFuncs->pfnDestroyExtensionDevice = vboxWddmDDevDestroyExtensionDevice;
5803 pCreateData->pDeviceFuncs->pfnExtensionExecute = vboxWddmDDevExtensionExecute;
5804 pCreateData->pDeviceFuncs->pfnCreateOverlay = vboxWddmDDevCreateOverlay;
5805 pCreateData->pDeviceFuncs->pfnUpdateOverlay = vboxWddmDDevUpdateOverlay;
5806 pCreateData->pDeviceFuncs->pfnFlipOverlay = vboxWddmDDevFlipOverlay;
5807 pCreateData->pDeviceFuncs->pfnGetOverlayColorControls = vboxWddmDDevGetOverlayColorControls;
5808 pCreateData->pDeviceFuncs->pfnSetOverlayColorControls = vboxWddmDDevSetOverlayColorControls;
5809 pCreateData->pDeviceFuncs->pfnDestroyOverlay = vboxWddmDDevDestroyOverlay;
5810 pCreateData->pDeviceFuncs->pfnDestroyDevice = vboxWddmDDevDestroyDevice;
5811 pCreateData->pDeviceFuncs->pfnQueryResourceResidency = vboxWddmDDevQueryResourceResidency;
5812 pCreateData->pDeviceFuncs->pfnOpenResource = vboxWddmDDevOpenResource;
5813 pCreateData->pDeviceFuncs->pfnGetCaptureAllocationHandle = vboxWddmDDevGetCaptureAllocationHandle;
5814 pCreateData->pDeviceFuncs->pfnCaptureToSysMem = vboxWddmDDevCaptureToSysMem;
5815 pCreateData->pDeviceFuncs->pfnLockAsync = NULL; //vboxWddmDDevLockAsync;
5816 pCreateData->pDeviceFuncs->pfnUnlockAsync = NULL; //vboxWddmDDevUnlockAsync;
5817 pCreateData->pDeviceFuncs->pfnRename = NULL; //vboxWddmDDevRename;
5818
5819
5820 do
5821 {
5822 Assert(!pCreateData->AllocationListSize
5823 && !pCreateData->PatchLocationListSize);
5824 if (!pCreateData->AllocationListSize
5825 && !pCreateData->PatchLocationListSize)
5826 {
5827 hr = vboxDispCmCtxCreate(pDevice, &pDevice->DefaultContext);
5828 Assert(hr == S_OK);
5829 if (hr == S_OK)
5830 break;
5831 }
5832 else
5833 {
5834 vboxVDbgPrintR((__FUNCTION__": Not implemented: PatchLocationListSize(%d), AllocationListSize(%d)\n",
5835 pCreateData->PatchLocationListSize, pCreateData->AllocationListSize));
5836 //pCreateData->pAllocationList = ??
5837 hr = E_FAIL;
5838 }
5839
5840 RTMemFree(pDevice);
5841 } while (0);
5842 }
5843 else
5844 {
5845 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
5846 hr = E_OUTOFMEMORY;
5847 }
5848
5849 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
5850
5851 return hr;
5852}
5853
5854static HRESULT APIENTRY vboxWddmDispCloseAdapter (IN HANDLE hAdapter)
5855{
5856 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
5857
5858// Assert(0);
5859
5860 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
5861 if (VBOXDISPMODE_IS_3D(pAdapter))
5862 {
5863 HRESULT hr = VBoxDispWorkerDestroy(&pAdapter->WndWorker);
5864 Assert(hr == S_OK);
5865 pAdapter->pD3D9If->Release();
5866 VBoxDispD3DClose(&pAdapter->D3D);
5867 }
5868
5869 vboxCapsFree(pAdapter);
5870
5871 RTMemFree(pAdapter);
5872
5873 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
5874
5875 return S_OK;
5876}
5877
5878HRESULT APIENTRY OpenAdapter (__inout D3DDDIARG_OPENADAPTER* pOpenData)
5879{
5880 vboxVDbgPrint(("==> "__FUNCTION__"\n"));
5881
5882// vboxDispLock();
5883
5884 HRESULT hr = E_FAIL;
5885
5886 do
5887 {
5888
5889 VBOXWDDM_QI Query;
5890 D3DDDICB_QUERYADAPTERINFO DdiQuery;
5891 DdiQuery.PrivateDriverDataSize = sizeof(Query);
5892 DdiQuery.pPrivateDriverData = &Query;
5893 hr = pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb(pOpenData->hAdapter, &DdiQuery);
5894 Assert(hr == S_OK);
5895 if (hr != S_OK)
5896 {
5897 vboxVDbgPrintR((__FUNCTION__": pfnQueryAdapterInfoCb failed, hr (%d)\n", hr));
5898 hr = E_FAIL;
5899 break;
5900 }
5901
5902 /* check the miniport version match display version */
5903 if (Query.u32Version != VBOXVIDEOIF_VERSION)
5904 {
5905 vboxVDbgPrintR((__FUNCTION__": miniport version mismatch, expected (%d), but was (%d)\n",
5906 VBOXVIDEOIF_VERSION,
5907 Query.u32Version));
5908 hr = E_FAIL;
5909 break;
5910 }
5911
5912#ifdef VBOX_WITH_VIDEOHWACCEL
5913 Assert(Query.cInfos >= 1);
5914 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_ADAPTER, aHeads[Query.cInfos]));
5915#else
5916 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(sizeof (VBOXWDDMDISP_ADAPTER));
5917#endif
5918 Assert(pAdapter);
5919 if (pAdapter)
5920 {
5921 pAdapter->hAdapter = pOpenData->hAdapter;
5922 pAdapter->uIfVersion = pOpenData->Interface;
5923 pAdapter->uRtVersion= pOpenData->Version;
5924 pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
5925
5926 pAdapter->cHeads = Query.cInfos;
5927
5928
5929 pOpenData->hAdapter = pAdapter;
5930 pOpenData->pAdapterFuncs->pfnGetCaps = vboxWddmDispGetCaps;
5931 pOpenData->pAdapterFuncs->pfnCreateDevice = vboxWddmDispCreateDevice;
5932 pOpenData->pAdapterFuncs->pfnCloseAdapter = vboxWddmDispCloseAdapter;
5933 pOpenData->DriverVersion = D3D_UMD_INTERFACE_VERSION;
5934 /*
5935 * here we detect whether we are called by the d3d or ddraw.
5936 * in the d3d case we init our d3d environment
5937 * in the ddraw case we init 2D acceleration
5938 * if interface version is > 7, this is D3D, treat it as so
5939 * otherwise treat it as ddraw
5940 * @todo: need a more clean way of doing this */
5941
5942 if (pAdapter->uIfVersion > 7)
5943 {
5944 do
5945 {
5946 /* try enable the 3D */
5947 hr = VBoxDispD3DOpen(&pAdapter->D3D);
5948 Assert(hr == S_OK);
5949 if (hr == S_OK)
5950 {
5951// Assert(0);
5952 hr = pAdapter->D3D.pfnDirect3DCreate9Ex(D3D_SDK_VERSION, &pAdapter->pD3D9If);
5953 Assert(hr == S_OK);
5954 if (hr == S_OK)
5955 {
5956 hr = VBoxDispWorkerCreate(&pAdapter->WndWorker);
5957 Assert(hr == S_OK);
5958 if (hr == S_OK)
5959 {
5960 vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
5961 break;
5962 }
5963 pAdapter->pD3D9If->Release();
5964 }
5965 else
5966 vboxVDbgPrintR((__FUNCTION__": pfnDirect3DCreate9Ex failed, hr (%d)\n", hr));
5967 VBoxDispD3DClose(&pAdapter->D3D);
5968 }
5969 else
5970 vboxVDbgPrintR((__FUNCTION__": VBoxDispD3DOpen failed, hr (%d)\n", hr));
5971 } while (0);
5972 }
5973#ifdef VBOX_WITH_VIDEOHWACCEL
5974 else
5975 {
5976 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
5977 {
5978 pAdapter->aHeads[i].Vhwa.Settings = Query.aInfos[i];
5979 }
5980 }
5981#endif
5982
5983 vboxCapsInit(pAdapter);
5984 hr = S_OK;
5985// RTMemFree(pAdapter);
5986 }
5987 else
5988 {
5989 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
5990 hr = E_OUTOFMEMORY;
5991 }
5992
5993 } while (0);
5994
5995// vboxDispUnlock();
5996
5997 vboxVDbgPrint(("<== "__FUNCTION__", hr (%d)\n", hr));
5998
5999 return hr;
6000}
6001
6002#ifdef VBOXWDDMDISP_DEBUG
6003
6004bool g_VDbgTstDumpEnable = false;
6005bool g_VDbgTstDumpOnSys2VidSameSizeEnable = false;
6006
6007VOID vboxVDbgDoDumpSurfData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const RECT *pRect, IDirect3DSurface9 *pSurf, const char* pSuffix)
6008{
6009 if (pPrefix)
6010 {
6011 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
6012 }
6013
6014 Assert(pRc->cAllocations > iAlloc);
6015 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
6016
6017 vboxVDbgMpPrintAlloc((pDevice, "allocation info:\n", pRc, iAlloc, "\n"));
6018
6019 D3DLOCKED_RECT Lr;
6020 if (pRect)
6021 {
6022 Assert(pRect->right > pRect->left);
6023 Assert(pRect->bottom > pRect->top);
6024 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
6025 }
6026
6027 BOOL bReleaseSurf = false;
6028 if (!pSurf)
6029 {
6030 HRESULT tmpHr = vboxWddmSurfGet(pRc, iAlloc, &pSurf);
6031 Assert(tmpHr == S_OK);
6032 bReleaseSurf = TRUE;
6033 }
6034 HRESULT srcHr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
6035 Assert(srcHr == S_OK);
6036 if (srcHr == S_OK)
6037 {
6038 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
6039// Assert(bpp == pAlloc->SurfDesc.bpp);
6040// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
6041 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
6042 Lr.pBits, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, bpp, Lr.Pitch));
6043 if (pRect)
6044 {
6045 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
6046 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
6047 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
6048 }
6049 Assert(0);
6050
6051 srcHr = pSurf->UnlockRect();
6052 Assert(srcHr == S_OK);
6053 }
6054 if (pSuffix)
6055 {
6056 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
6057 }
6058
6059 if (bReleaseSurf)
6060 pSurf->Release();
6061}
6062
6063VOID vboxVDbgDoDumpSurfDataBySurf(const PVBOXWDDMDISP_DEVICE pDevice, IDirect3DSurface9 *pSurf)
6064{
6065 D3DSURFACE_DESC Desc;
6066 HRESULT hr = pSurf->GetDesc(&Desc);
6067 Assert(hr == S_OK);
6068 if (hr == S_OK)
6069 {
6070 D3DLOCKED_RECT Lr;
6071 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
6072 Assert(hr == S_OK);
6073 if (hr == S_OK)
6074 {
6075 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
6076 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
6077 Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch));
6078
6079 Assert(0);
6080
6081 hr = pSurf->UnlockRect();
6082 Assert(hr == S_OK);
6083 }
6084 }
6085}
6086
6087void vboxVDbgDoMpPrintAlloc(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
6088{
6089 Assert(pRc->cAllocations > iAlloc);
6090 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
6091 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
6092 BOOL bFrontBuf = FALSE;
6093 if (bPrimary)
6094 {
6095 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
6096 Assert(pRc == pScreen->pRenderTargetRc);
6097 bFrontBuf = (iAlloc == pScreen->iRenderTargetFrontBuf);
6098 }
6099 vboxVDbgDoMpPrintF(pDevice, "%s width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
6100 pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
6101 bPrimary ?
6102 (bFrontBuf ? "Front Buffer" : "Back Buffer")
6103 : "?Everage? Alloc",
6104 pSuffix);
6105}
6106
6107void vboxVDbgDoMpPrintRect(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const RECT *pRect, const char * pSuffix)
6108{
6109 vboxVDbgDoMpPrintF(pDevice, "%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix);
6110}
6111
6112VOID vboxVDbgDoMpPrint(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString)
6113{
6114 uint32_t cbString = strlen(szString) + 1;
6115 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
6116 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
6117 Assert(pCmd);
6118 if (pCmd)
6119 {
6120 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
6121 memcpy(pCmd->aStringBuf, szString, cbString);
6122
6123 D3DDDICB_ESCAPE DdiEscape = {0};
6124 DdiEscape.hContext = NULL;
6125 DdiEscape.hDevice = NULL;
6126 DdiEscape.Flags.Value = 0;
6127 DdiEscape.pPrivateDriverData = pCmd;
6128 DdiEscape.PrivateDriverDataSize = cbCmd;
6129
6130 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
6131 Assert(hr == S_OK);
6132
6133 RTMemFree(pCmd);
6134 }
6135}
6136VOID vboxVDbgDoMpPrintF(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString, ...)
6137{
6138 char szBuffer[4096] = {0};
6139 va_list pArgList;
6140 va_start(pArgList, szString);
6141 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
6142 va_end(pArgList);
6143
6144 if (pDevice)
6145 {
6146 vboxVDbgDoMpPrint(pDevice, szBuffer);
6147 }
6148 else
6149 {
6150 OutputDebugStringA(szBuffer);
6151 }
6152}
6153VOID vboxVDbgDoPrint(LPCSTR szString, ...)
6154{
6155 char szBuffer[1024] = {0};
6156 va_list pArgList;
6157 va_start(pArgList, szString);
6158 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
6159 va_end(pArgList);
6160
6161 OutputDebugStringA(szBuffer);
6162}
6163
6164static PVOID g_VBoxWDbgVEHandler = NULL;
6165LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
6166{
6167 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
6168 PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
6169 switch (pExceptionRecord->ExceptionCode)
6170 {
6171 case 0x40010006: /* <- OutputDebugString exception, ignore */
6172 break;
6173 default:
6174 Assert(0);
6175 break;
6176 }
6177 return EXCEPTION_CONTINUE_SEARCH;
6178}
6179
6180void vboxVDbgVEHandlerRegister()
6181{
6182 Assert(!g_VBoxWDbgVEHandler);
6183 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
6184 Assert(g_VBoxWDbgVEHandler);
6185}
6186
6187void vboxVDbgVEHandlerUnregister()
6188{
6189 Assert(g_VBoxWDbgVEHandler);
6190 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
6191 Assert(uResult);
6192 g_VBoxWDbgVEHandler = NULL;
6193}
6194
6195#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