VirtualBox

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

Last change on this file since 31634 was 30986, checked in by vboxsync, 15 years ago

wddm/d3d: basic d3d8 support

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

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