VirtualBox

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

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

wddm/3d: shared resources frontend (driver) part

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