VirtualBox

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

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

wddm/3d: change present call

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