VirtualBox

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

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

wddm/2d: color fill operation (not yet tested)

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