VirtualBox

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

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

wddm/3d: bugfixes

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

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