VirtualBox

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

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

*: spelling fixes, thanks Timeless!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 317.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#define INITGUID
16
17#include <iprt/initterm.h>
18#include <iprt/log.h>
19#include <iprt/mem.h>
20
21#include <VBox/Log.h>
22
23#include <VBox/VBoxGuestLib.h>
24
25#include "VBoxDispD3DCmn.h"
26#include "VBoxDispD3D.h"
27#include "VBoxScreen.h"
28#include <VBox/VBoxCrHgsmi.h>
29
30#ifdef VBOX_WDDMDISP_WITH_PROFILE
31#include "VBoxDispProfile.h"
32
33/* uncomment to enable particular logging */
34#define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_ENABLE
35//#define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_ENABLE
36
37#ifdef VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_ENABLE
38static VBoxDispProfileSet g_VBoxDispProfileDDI("D3D_DDI");
39#define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE() VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(g_VBoxDispProfileDDI)
40#define VBOXDDIROFILE_FUNCTION_LOGGER_DUMP() do {\
41 g_VBoxDispProfileDDI.dump(_pDev); \
42 } while (0)
43#define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET() do {\
44 g_VBoxDispProfileDDI.resetEntries();\
45 } while (0)
46#define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DISABLE_CURRENT() do {\
47 VBOXDISPPROFILE_FUNCTION_LOGGER_DISABLE_CURRENT();\
48 } while (0)
49
50
51#else
52#define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE() do {} while(0)
53#define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP() do {} while(0)
54#define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET() do {} while(0)
55#define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DISABLE_CURRENT() do {} while (0)
56#endif
57
58#ifdef VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_ENABLE
59static VBoxDispProfileFpsCounter g_VBoxDispFpsDDI(64);
60#define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE() VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(&g_VBoxDispFpsDDI)
61#define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DISABLE_CURRENT() do {\
62 VBOXDISPPROFILE_STATISTIC_LOGGER_DISABLE_CURRENT();\
63 } while (0)
64#define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pDev) do { \
65 VBOXDISPPROFILE_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT(); \
66 g_VBoxDispFpsDDI.ReportFrame(); \
67 if(!(g_VBoxDispFpsDDI.GetNumFrames() % 31)) \
68 { \
69 double fps = g_VBoxDispFpsDDI.GetFps(); \
70 double cps = g_VBoxDispFpsDDI.GetCps(); \
71 double tup = g_VBoxDispFpsDDI.GetTimeProcPercent(); \
72 VBOXDISPPROFILE_DUMP((_pDev, "fps: %f, cps: %.1f, host %.1f%%\n", fps, cps, tup)); \
73 } \
74 } while (0)
75#else
76#define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE() do {} while(0)
77#define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DISABLE_CURRENT() do {} while (0)
78#define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pDev) do {} while (0)
79#endif
80
81#define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE() \
82 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE(); \
83 VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE();
84
85#define VBOXDISPPROFILE_DDI_DUMPRESET(_pDev) do {\
86 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(); \
87 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET(); \
88 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DISABLE_CURRENT();\
89 } while (0)
90
91#define VBOXDISPPROFILE_DDI_REPORT_FRAME(_pDev) do {\
92 VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pDev); \
93 } while (0)
94
95
96#else
97#define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE() do {} while (0)
98#define VBOXDISPPROFILE_DDI_DUMPRESET(_pDev) do {} while (0)
99#define VBOXDISPPROFILE_DDI_REPORT_FRAME(_pDev) do {} while (0)
100#endif
101
102#ifdef VBOXDISPMP_TEST
103HRESULT vboxDispMpTstStart();
104HRESULT vboxDispMpTstStop();
105#endif
106
107#ifdef VBOXWDDMDISP_DEBUG_PRINT
108# include <stdio.h>
109#endif
110
111#define VBOXDISP_WITH_WINE_BB_WORKAROUND
112
113static VBOXSCREENMONRUNNER g_VBoxScreenMonRunner;
114
115//#define VBOXWDDMOVERLAY_TEST
116
117static FORMATOP gVBoxFormatOps3D[] = {
118 {D3DDDIFMT_A8R8G8B8,
119 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
120 FORMATOP_SAME_FORMAT_RENDERTARGET|
121 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
122 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
123 FORMATOP_MEMBEROFGROUP_ARGB|
124 FORMATOP_SRGBWRITE|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
125
126 {D3DDDIFMT_X8R8G8B8,
127 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
128 FORMATOP_SAME_FORMAT_RENDERTARGET|
129 FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|
130 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
131 FORMATOP_MEMBEROFGROUP_ARGB|
132 FORMATOP_SRGBWRITE|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
133
134 {D3DDDIFMT_A2R10G10B10,
135 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
136 FORMATOP_SAME_FORMAT_RENDERTARGET|
137 0|
138 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
139 FORMATOP_MEMBEROFGROUP_ARGB|
140 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
141
142 {D3DDDIFMT_X1R5G5B5,
143 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
144 FORMATOP_SAME_FORMAT_RENDERTARGET|
145 0|
146 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
147 FORMATOP_MEMBEROFGROUP_ARGB|
148 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
149
150 {D3DDDIFMT_A1R5G5B5,
151 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
152 FORMATOP_SAME_FORMAT_RENDERTARGET|
153 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
154 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
155 FORMATOP_MEMBEROFGROUP_ARGB|
156 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
157
158 {D3DDDIFMT_A4R4G4B4,
159 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
160 FORMATOP_SAME_FORMAT_RENDERTARGET|
161 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
162 FORMATOP_OFFSCREENPLAIN|
163 0|
164 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
165
166 {D3DDDIFMT_R5G6B5,
167 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
168 FORMATOP_SAME_FORMAT_RENDERTARGET|
169 FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|
170 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
171 FORMATOP_MEMBEROFGROUP_ARGB|
172 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
173
174 {D3DDDIFMT_L16,
175 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
176 0|
177 0|
178 FORMATOP_OFFSCREENPLAIN|
179 0|
180 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
181
182 {D3DDDIFMT_A8L8,
183 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
184 0|
185 0|
186 FORMATOP_OFFSCREENPLAIN|
187 0|
188 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
189
190 {D3DDDIFMT_A8,
191 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
192 0|
193 0|
194 FORMATOP_OFFSCREENPLAIN|
195 0|
196 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
197
198 {D3DDDIFMT_L8,
199 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
200 0|
201 0|
202 FORMATOP_OFFSCREENPLAIN|
203 0|
204 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
205
206 {D3DDDIFMT_D16, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
207 {D3DDDIFMT_D24S8, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
208 {D3DDDIFMT_D24X8, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
209 {D3DDDIFMT_D16_LOCKABLE, FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
210 {D3DDDIFMT_X8D24, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
211 {D3DDDIFMT_D32F_LOCKABLE, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
212 {D3DDDIFMT_S8D24, FORMATOP_TEXTURE|FORMATOP_ZSTENCIL|FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH, 0, 0, 0},
213
214 {D3DDDIFMT_DXT1,
215 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
216 0|
217 0|
218 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
219 0|
220 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
221
222 {D3DDDIFMT_DXT2,
223 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
224 0|
225 0|
226 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
227 0|
228 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
229
230 {D3DDDIFMT_DXT3,
231 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
232 0|
233 0|
234 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
235 0|
236 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
237
238 {D3DDDIFMT_DXT4,
239 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
240 0|
241 0|
242 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
243 0|
244 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
245
246 {D3DDDIFMT_DXT5,
247 FORMATOP_TEXTURE|FORMATOP_CUBETEXTURE|
248 0|
249 0|
250 FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
251 0|
252 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
253
254 {D3DDDIFMT_X8L8V8U8,
255 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
256 0|
257 0|
258 0|
259 FORMATOP_BUMPMAP|
260 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
261
262 {D3DDDIFMT_A2W10V10U10,
263 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
264 0|
265 0|
266 0|
267 FORMATOP_BUMPMAP|
268 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
269
270 {D3DDDIFMT_V8U8,
271 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
272 0|
273 0|
274 0|
275 FORMATOP_BUMPMAP|
276 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
277
278 {D3DDDIFMT_Q8W8V8U8,
279 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
280 0|
281 0|
282 FORMATOP_OFFSCREENPLAIN|
283 FORMATOP_BUMPMAP|
284 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
285
286 {D3DDDIFMT_CxV8U8, FORMATOP_NOFILTER|FORMATOP_NOALPHABLEND|FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
287
288 {D3DDDIFMT_R16F,
289 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
290 FORMATOP_SAME_FORMAT_RENDERTARGET|
291 0|
292 FORMATOP_OFFSCREENPLAIN|
293 0|
294 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
295
296 {D3DDDIFMT_R32F,
297 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
298 FORMATOP_SAME_FORMAT_RENDERTARGET|
299 0|
300 FORMATOP_OFFSCREENPLAIN|
301 0|
302 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
303
304 {D3DDDIFMT_G16R16F,
305 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
306 FORMATOP_SAME_FORMAT_RENDERTARGET|
307 0|
308 FORMATOP_OFFSCREENPLAIN|
309 0|
310 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
311
312 {D3DDDIFMT_G32R32F,
313 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
314 FORMATOP_SAME_FORMAT_RENDERTARGET|
315 0|
316 FORMATOP_OFFSCREENPLAIN|
317 0|
318 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
319
320 {D3DDDIFMT_A16B16G16R16F,
321 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
322 FORMATOP_SAME_FORMAT_RENDERTARGET|
323 0|
324 FORMATOP_OFFSCREENPLAIN|
325 0|
326 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
327
328 {D3DDDIFMT_A32B32G32R32F,
329 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
330 FORMATOP_SAME_FORMAT_RENDERTARGET|
331 0|
332 FORMATOP_OFFSCREENPLAIN|
333 0|
334 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
335
336 {D3DDDIFMT_G16R16,
337 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
338 FORMATOP_SAME_FORMAT_RENDERTARGET|
339 0|
340 FORMATOP_OFFSCREENPLAIN|
341 0|
342 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
343
344 {D3DDDIFMT_A16B16G16R16,
345 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
346 FORMATOP_SAME_FORMAT_RENDERTARGET|
347 0|
348 FORMATOP_OFFSCREENPLAIN|
349 0|
350 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
351
352 {D3DDDIFMT_V16U16,
353 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
354 0|
355 0|
356 0|
357 FORMATOP_BUMPMAP|
358 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
359
360 {D3DDDIFMT_P8, FORMATOP_DISPLAYMODE|FORMATOP_3DACCELERATION|FORMATOP_OFFSCREENPLAIN, 0, 0, 0},
361
362 {D3DDDIFMT_UYVY,
363 0|
364 0|
365 0|
366 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
367 FORMATOP_NOFILTER|
368 FORMATOP_NOALPHABLEND|
369 FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
370
371 {D3DDDIFMT_YUY2,
372 0|
373 0|
374 0|
375 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
376 FORMATOP_NOFILTER|
377 FORMATOP_NOALPHABLEND|
378 FORMATOP_NOTEXCOORDWRAPNORMIP, 0, 0, 0},
379
380 {D3DDDIFMT_Q16W16V16U16,
381 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
382 FORMATOP_SAME_FORMAT_RENDERTARGET|
383 0|
384 FORMATOP_OFFSCREENPLAIN|
385 FORMATOP_BUMPMAP|FORMATOP_DMAP|
386 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
387
388 {D3DDDIFMT_X8B8G8R8,
389 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
390 FORMATOP_SAME_FORMAT_RENDERTARGET|
391 FORMATOP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET|
392 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|FORMATOP_SRGBREAD|
393 FORMATOP_DMAP|FORMATOP_MEMBEROFGROUP_ARGB|
394 FORMATOP_SRGBWRITE|FORMATOP_AUTOGENMIPMAP|FORMATOP_VERTEXTEXTURE|
395 FORMATOP_OVERLAY, 0, 0, 0},
396
397 {D3DDDIFMT_BINARYBUFFER, FORMATOP_OFFSCREENPLAIN, 0, 0, 0},
398
399 {D3DDDIFMT_A4L4,
400 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|
401 0|
402 0|
403 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
404 FORMATOP_DMAP|
405 FORMATOP_VERTEXTEXTURE, 0, 0, 0},
406
407 {D3DDDIFMT_A2B10G10R10,
408 FORMATOP_TEXTURE|FORMATOP_VOLUMETEXTURE|FORMATOP_CUBETEXTURE|FORMATOP_OFFSCREEN_RENDERTARGET|
409 FORMATOP_SAME_FORMAT_RENDERTARGET|
410 0|
411 FORMATOP_CONVERT_TO_ARGB|FORMATOP_OFFSCREENPLAIN|
412 FORMATOP_DMAP|FORMATOP_MEMBEROFGROUP_ARGB|
413 FORMATOP_AUTOGENMIPMAP|FORMATOP_VERTEXTEXTURE, 0, 0, 0},
414};
415
416static FORMATOP gVBoxFormatOpsBase[] = {
417 {D3DDDIFMT_X8R8G8B8, FORMATOP_DISPLAYMODE, 0, 0, 0},
418
419 {D3DDDIFMT_R8G8B8, FORMATOP_DISPLAYMODE, 0, 0, 0},
420
421 {D3DDDIFMT_R5G6B5, FORMATOP_DISPLAYMODE, 0, 0, 0},
422
423 {D3DDDIFMT_P8, FORMATOP_DISPLAYMODE, 0, 0, 0},
424};
425
426static DDSURFACEDESC gVBoxSurfDescsBase[] = {
427 {
428 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
429 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
430 0, /* DWORD dwHeight; */
431 0, /* DWORD dwWidth; */
432 {
433 0, /* Union */
434 /* LONG lPitch; */
435 /* DWORD dwLinearSize; */
436 },
437 0, /* DWORD dwBackBufferCount; */
438 {
439 0, /* Union */
440 /* DWORD dwMipMapCount; */
441 /* DWORD dwZBufferBitDepth; */
442 /* DWORD dwRefreshRate; */
443 },
444 0, /* DWORD dwAlphaBitDepth; */
445 0, /* DWORD dwReserved; */
446 NULL, /* LPVOID lpSurface; */
447 {
448 0, /* DWORD dwColorSpaceLowValue; */
449 0, /* DWORD dwColorSpaceHighValue; */
450 }, /* DDCOLORKEY ddckCKDestOverlay; */
451 {
452 0, /* DWORD dwColorSpaceLowValue; */
453 0, /* DWORD dwColorSpaceHighValue; */
454 }, /* DDCOLORKEY ddckCKDestBlt; */
455 {
456 0, /* DWORD dwColorSpaceLowValue; */
457 0, /* DWORD dwColorSpaceHighValue; */
458 }, /* DDCOLORKEY ddckCKSrcOverlay; */
459 {
460 0, /* DWORD dwColorSpaceLowValue; */
461 0, /* DWORD dwColorSpaceHighValue; */
462 }, /* DDCOLORKEY ddckCKSrcBlt; */
463 {
464 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
465 DDPF_RGB, /* DWORD dwFlags; */
466 0, /* DWORD dwFourCC; */
467 {
468 32, /* union */
469 /* DWORD dwRGBBitCount; */
470 /* DWORD dwYUVBitCount; */
471 /* DWORD dwZBufferBitDepth; */
472 /* DWORD dwAlphaBitDepth; */
473 /* DWORD dwLuminanceBitCount; */
474 /* DWORD dwBumpBitCount; */
475 },
476 {
477 0xff0000, /* union */
478 /* DWORD dwRBitMask; */
479 /* DWORD dwYBitMask; */
480 /* DWORD dwStencilBitDepth; */
481 /* DWORD dwLuminanceBitMask; */
482 /* DWORD dwBumpDuBitMask; */
483 },
484 {
485 0xff00,
486 /* DWORD dwGBitMask; */
487 /* DWORD dwUBitMask; */
488 /* DWORD dwZBitMask; */
489 /* DWORD dwBumpDvBitMask; */
490 },
491 {
492 0xff,
493 /* DWORD dwBBitMask; */
494 /* DWORD dwVBitMask; */
495 /* DWORD dwStencilBitMask; */
496 /* DWORD dwBumpLuminanceBitMask; */
497 },
498 {
499 0,
500 /* DWORD dwRGBAlphaBitMask; */
501 /* DWORD dwYUVAlphaBitMask; */
502 /* DWORD dwLuminanceAlphaBitMask; */
503 /* DWORD dwRGBZBitMask; */
504 /* DWORD dwYUVZBitMask; */
505 },
506 }, /* DDPIXELFORMAT ddpfPixelFormat; */
507 {
508 DDSCAPS_BACKBUFFER
509 | DDSCAPS_COMPLEX
510 | DDSCAPS_FLIP
511 | DDSCAPS_FRONTBUFFER
512 | DDSCAPS_LOCALVIDMEM
513 | DDSCAPS_PRIMARYSURFACE
514 | DDSCAPS_VIDEOMEMORY
515 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
516 } /* DDSCAPS ddsCaps; */
517 },
518 {
519 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
520 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
521 0, /* DWORD dwHeight; */
522 0, /* DWORD dwWidth; */
523 {
524 0, /* Union */
525 /* LONG lPitch; */
526 /* DWORD dwLinearSize; */
527 },
528 0, /* DWORD dwBackBufferCount; */
529 {
530 0, /* Union */
531 /* DWORD dwMipMapCount; */
532 /* DWORD dwZBufferBitDepth; */
533 /* DWORD dwRefreshRate; */
534 },
535 0, /* DWORD dwAlphaBitDepth; */
536 0, /* DWORD dwReserved; */
537 NULL, /* LPVOID lpSurface; */
538 {
539 0, /* DWORD dwColorSpaceLowValue; */
540 0, /* DWORD dwColorSpaceHighValue; */
541 }, /* DDCOLORKEY ddckCKDestOverlay; */
542 {
543 0, /* DWORD dwColorSpaceLowValue; */
544 0, /* DWORD dwColorSpaceHighValue; */
545 }, /* DDCOLORKEY ddckCKDestBlt; */
546 {
547 0, /* DWORD dwColorSpaceLowValue; */
548 0, /* DWORD dwColorSpaceHighValue; */
549 }, /* DDCOLORKEY ddckCKSrcOverlay; */
550 {
551 0, /* DWORD dwColorSpaceLowValue; */
552 0, /* DWORD dwColorSpaceHighValue; */
553 }, /* DDCOLORKEY ddckCKSrcBlt; */
554 {
555 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
556 DDPF_RGB, /* DWORD dwFlags; */
557 0, /* DWORD dwFourCC; */
558 {
559 24, /* union */
560 /* DWORD dwRGBBitCount; */
561 /* DWORD dwYUVBitCount; */
562 /* DWORD dwZBufferBitDepth; */
563 /* DWORD dwAlphaBitDepth; */
564 /* DWORD dwLuminanceBitCount; */
565 /* DWORD dwBumpBitCount; */
566 },
567 {
568 0xff0000, /* union */
569 /* DWORD dwRBitMask; */
570 /* DWORD dwYBitMask; */
571 /* DWORD dwStencilBitDepth; */
572 /* DWORD dwLuminanceBitMask; */
573 /* DWORD dwBumpDuBitMask; */
574 },
575 {
576 0xff00,
577 /* DWORD dwGBitMask; */
578 /* DWORD dwUBitMask; */
579 /* DWORD dwZBitMask; */
580 /* DWORD dwBumpDvBitMask; */
581 },
582 {
583 0xff,
584 /* DWORD dwBBitMask; */
585 /* DWORD dwVBitMask; */
586 /* DWORD dwStencilBitMask; */
587 /* DWORD dwBumpLuminanceBitMask; */
588 },
589 {
590 0,
591 /* DWORD dwRGBAlphaBitMask; */
592 /* DWORD dwYUVAlphaBitMask; */
593 /* DWORD dwLuminanceAlphaBitMask; */
594 /* DWORD dwRGBZBitMask; */
595 /* DWORD dwYUVZBitMask; */
596 },
597 }, /* DDPIXELFORMAT ddpfPixelFormat; */
598 {
599 DDSCAPS_BACKBUFFER
600 | DDSCAPS_COMPLEX
601 | DDSCAPS_FLIP
602 | DDSCAPS_FRONTBUFFER
603 | DDSCAPS_LOCALVIDMEM
604 | DDSCAPS_PRIMARYSURFACE
605 | DDSCAPS_VIDEOMEMORY
606 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
607 } /* DDSCAPS ddsCaps; */
608 },
609 {
610 sizeof (DDSURFACEDESC), /* DWORD dwSize; */
611 DDSD_CAPS | DDSD_PIXELFORMAT, /* DWORD dwFlags; */
612 0, /* DWORD dwHeight; */
613 0, /* DWORD dwWidth; */
614 {
615 0, /* Union */
616 /* LONG lPitch; */
617 /* DWORD dwLinearSize; */
618 },
619 0, /* DWORD dwBackBufferCount; */
620 {
621 0, /* Union */
622 /* DWORD dwMipMapCount; */
623 /* DWORD dwZBufferBitDepth; */
624 /* DWORD dwRefreshRate; */
625 },
626 0, /* DWORD dwAlphaBitDepth; */
627 0, /* DWORD dwReserved; */
628 NULL, /* LPVOID lpSurface; */
629 {
630 0, /* DWORD dwColorSpaceLowValue; */
631 0, /* DWORD dwColorSpaceHighValue; */
632 }, /* DDCOLORKEY ddckCKDestOverlay; */
633 {
634 0, /* DWORD dwColorSpaceLowValue; */
635 0, /* DWORD dwColorSpaceHighValue; */
636 }, /* DDCOLORKEY ddckCKDestBlt; */
637 {
638 0, /* DWORD dwColorSpaceLowValue; */
639 0, /* DWORD dwColorSpaceHighValue; */
640 }, /* DDCOLORKEY ddckCKSrcOverlay; */
641 {
642 0, /* DWORD dwColorSpaceLowValue; */
643 0, /* DWORD dwColorSpaceHighValue; */
644 }, /* DDCOLORKEY ddckCKSrcBlt; */
645 {
646 sizeof (DDPIXELFORMAT), /* DWORD dwSize; */
647 DDPF_RGB, /* DWORD dwFlags; */
648 0, /* DWORD dwFourCC; */
649 {
650 16, /* union */
651 /* DWORD dwRGBBitCount; */
652 /* DWORD dwYUVBitCount; */
653 /* DWORD dwZBufferBitDepth; */
654 /* DWORD dwAlphaBitDepth; */
655 /* DWORD dwLuminanceBitCount; */
656 /* DWORD dwBumpBitCount; */
657 },
658 {
659 0xf800, /* union */
660 /* DWORD dwRBitMask; */
661 /* DWORD dwYBitMask; */
662 /* DWORD dwStencilBitDepth; */
663 /* DWORD dwLuminanceBitMask; */
664 /* DWORD dwBumpDuBitMask; */
665 },
666 {
667 0x7e0,
668 /* DWORD dwGBitMask; */
669 /* DWORD dwUBitMask; */
670 /* DWORD dwZBitMask; */
671 /* DWORD dwBumpDvBitMask; */
672 },
673 {
674 0x1f,
675 /* DWORD dwBBitMask; */
676 /* DWORD dwVBitMask; */
677 /* DWORD dwStencilBitMask; */
678 /* DWORD dwBumpLuminanceBitMask; */
679 },
680 {
681 0,
682 /* DWORD dwRGBAlphaBitMask; */
683 /* DWORD dwYUVAlphaBitMask; */
684 /* DWORD dwLuminanceAlphaBitMask; */
685 /* DWORD dwRGBZBitMask; */
686 /* DWORD dwYUVZBitMask; */
687 },
688 }, /* DDPIXELFORMAT ddpfPixelFormat; */
689 {
690 DDSCAPS_BACKBUFFER
691 | DDSCAPS_COMPLEX
692 | DDSCAPS_FLIP
693 | DDSCAPS_FRONTBUFFER
694 | DDSCAPS_LOCALVIDMEM
695 | DDSCAPS_PRIMARYSURFACE
696 | DDSCAPS_VIDEOMEMORY
697 | DDSCAPS_VISIBLE /* DWORD dwCaps; */
698 } /* DDSCAPS ddsCaps; */
699 },
700};
701
702static D3DDDIQUERYTYPE gVBoxQueryTypes[] = {
703 D3DDDIQUERYTYPE_EVENT,
704// D3DDDIQUERYTYPE_OCCLUSION
705};
706
707#define VBOX_QUERYTYPE_COUNT() RT_ELEMENTS(gVBoxQueryTypes)
708
709static CRITICAL_SECTION g_VBoxCritSect;
710
711void vboxDispLock()
712{
713 EnterCriticalSection(&g_VBoxCritSect);
714}
715
716void vboxDispUnlock()
717{
718 LeaveCriticalSection(&g_VBoxCritSect);
719}
720
721void vboxDispLockInit()
722{
723 InitializeCriticalSection(&g_VBoxCritSect);
724}
725
726
727#ifdef VBOX_WITH_CRHGSMI
728/* cr hgsmi */
729static VBOXCRHGSMI_CALLBACKS g_VBoxCrHgsmiCallbacks = {0};
730#define VBOXUHGSMIKMT_PERTHREAD
731#ifdef VBOXUHGSMIKMT_PERTHREAD
732#define VBOXUHGSMIKMT_VAR(_type) __declspec(thread) _type
733#else
734#define VBOXUHGSMIKMT_VAR(_type) _type
735#endif
736static VBOXUHGSMIKMT_VAR(VBOXUHGSMI_PRIVATE_KMT) g_VBoxUhgsmiKmt;
737static VBOXUHGSMIKMT_VAR(uint32_t) g_cVBoxUhgsmiKmtRefs = 0;
738#endif
739
740#ifdef VBOX_WITH_CRHGSMI
741static __declspec(thread) PVBOXUHGSMI_PRIVATE_BASE gt_pHgsmi = NULL;
742#endif
743
744VBOXWDDMDISP_DECL(int) VBoxDispCrHgsmiInit(PVBOXCRHGSMI_CALLBACKS pCallbacks)
745{
746#ifdef VBOX_WITH_CRHGSMI
747 vboxDispLock(); /* the lock is needed here only to ensure callbacks are not initialized & used concurrently
748 * @todo: make a separate call used to init the per-thread info and make the VBoxDispCrHgsmiInit be called only once */
749 g_VBoxCrHgsmiCallbacks = *pCallbacks;
750 PVBOXUHGSMI_PRIVATE_BASE pHgsmi = gt_pHgsmi;
751#ifdef DEBUG_misha
752 Assert(pHgsmi);
753#endif
754 if (pHgsmi)
755 {
756 if (!pHgsmi->hClient)
757 {
758 pHgsmi->hClient = g_VBoxCrHgsmiCallbacks.pfnClientCreate(&pHgsmi->Base);
759 Assert(pHgsmi->hClient);
760 }
761 }
762 vboxDispUnlock();
763#endif
764 return VINF_SUCCESS;
765}
766
767VBOXWDDMDISP_DECL(int) VBoxDispCrHgsmiTerm()
768{
769 return VINF_SUCCESS;
770}
771
772VBOXWDDMDISP_DECL(HVBOXCRHGSMI_CLIENT) VBoxDispCrHgsmiQueryClient()
773{
774#ifdef VBOX_WITH_CRHGSMI
775 PVBOXUHGSMI_PRIVATE_BASE pHgsmi = gt_pHgsmi;
776#ifdef DEBUG_misha
777 Assert(pHgsmi);
778#endif
779 if (pHgsmi)
780 {
781 Assert(pHgsmi->hClient);
782 return pHgsmi->hClient;
783 }
784#endif
785 return NULL;
786}
787
788#ifdef VBOX_WITH_CRHGSMI
789static HRESULT vboxUhgsmiGlobalRetain()
790{
791 HRESULT hr = S_OK;
792 vboxDispLock();
793 if (!g_cVBoxUhgsmiKmtRefs)
794 {
795 hr = vboxUhgsmiKmtCreate(&g_VBoxUhgsmiKmt, TRUE);
796 Assert(hr == S_OK);
797 /* can not do it here because callbacks may not be set yet
798 * @todo: need to call the cr lib from here to get the callbacks
799 * rather than making the cr lib call us */
800// if (hr == S_OK)
801// {
802// g_VBoxUhgsmiKmt.BasePrivate.hClient = g_VBoxCrHgsmiCallbacks.pfnClientCreate(&g_VBoxUhgsmiKmt.BasePrivate.Base);
803// Assert(g_VBoxUhgsmiKmt.BasePrivate.hClient);
804// }
805 }
806
807 if (hr == S_OK)
808 {
809 ++g_cVBoxUhgsmiKmtRefs;
810 }
811 vboxDispUnlock();
812
813 return hr;
814}
815
816static HRESULT vboxUhgsmiGlobalRelease()
817{
818 HRESULT hr = S_OK;
819 vboxDispLock();
820 --g_cVBoxUhgsmiKmtRefs;
821 if (!g_cVBoxUhgsmiKmtRefs)
822 {
823 if (g_VBoxUhgsmiKmt.BasePrivate.hClient)
824 g_VBoxCrHgsmiCallbacks.pfnClientDestroy(g_VBoxUhgsmiKmt.BasePrivate.hClient);
825 hr = vboxUhgsmiKmtDestroy(&g_VBoxUhgsmiKmt);
826 Assert(hr == S_OK);
827 }
828 vboxDispUnlock();
829 return hr;
830}
831
832DECLINLINE(void) vboxDispCrHgsmiClientSet(PVBOXUHGSMI_PRIVATE_BASE pHgsmi)
833{
834 gt_pHgsmi = pHgsmi;
835}
836
837DECLINLINE(void) vboxDispCrHgsmiClientClear()
838{
839 gt_pHgsmi = NULL;
840}
841
842HRESULT vboxUhgsmiGlobalSetCurrent()
843{
844 HRESULT hr = vboxUhgsmiGlobalRetain();
845 Assert(hr == S_OK);
846 if (hr == S_OK)
847 vboxDispCrHgsmiClientSet(&g_VBoxUhgsmiKmt.BasePrivate);
848 return hr;
849}
850
851HRESULT vboxUhgsmiGlobalClearCurrent()
852{
853 vboxUhgsmiGlobalRelease();
854 vboxDispCrHgsmiClientClear();
855 return S_OK;
856}
857
858class VBoxDispCrHgsmiScope
859{
860public:
861 VBoxDispCrHgsmiScope(PVBOXUHGSMI_PRIVATE_BASE pHgsmi)
862 {
863 vboxDispCrHgsmiClientSet(pHgsmi);
864 }
865
866 ~VBoxDispCrHgsmiScope()
867 {
868 vboxDispCrHgsmiClientClear();
869 }
870private:
871};
872
873#define VBOXDISPCRHGSMI_SCOPE_SET_DEV(_pDev) VBoxDispCrHgsmiScope __vboxCrHgsmiScope(&(_pDev)->Uhgsmi.BasePrivate)
874#define VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL() VBoxDispCrHgsmiScope __vboxCrHgsmiScope(&g_VBoxUhgsmiKmt.BasePrivate)
875#else
876#define VBOXDISPCRHGSMI_SCOPE_SET_DEV(_pDev) do {} while(0)
877#define VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL() do {} while(0)
878#endif
879
880#ifdef VBOX_WITH_VIDEOHWACCEL
881
882static bool vboxVhwaIsEnabled(PVBOXWDDMDISP_ADAPTER pAdapter)
883{
884 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
885 {
886 if (pAdapter->aHeads[i].Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED)
887 return true;
888 }
889 return false;
890}
891
892static bool vboxVhwaHasCKeying(PVBOXWDDMDISP_ADAPTER pAdapter)
893{
894 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
895 {
896 VBOXVHWA_INFO* pSettings = &pAdapter->aHeads[i].Vhwa.Settings;
897 if ((pSettings->fFlags & VBOXVHWA_F_ENABLED)
898 && ((pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
899 || (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC))
900 )
901 return true;
902 }
903 return false;
904}
905
906static void vboxVhwaPopulateOverlayFourccSurfDesc(DDSURFACEDESC *pDesc, uint32_t fourcc)
907{
908 memset(pDesc, 0, sizeof (DDSURFACEDESC));
909
910 pDesc->dwSize = sizeof (DDSURFACEDESC);
911 pDesc->dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT;
912 pDesc->ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT);
913 pDesc->ddpfPixelFormat.dwFlags = DDPF_FOURCC;
914 pDesc->ddpfPixelFormat.dwFourCC = fourcc;
915 pDesc->ddsCaps.dwCaps = DDSCAPS_BACKBUFFER
916 | DDSCAPS_COMPLEX
917 | DDSCAPS_FLIP
918 | DDSCAPS_FRONTBUFFER
919 | DDSCAPS_LOCALVIDMEM
920 | DDSCAPS_OVERLAY
921 | DDSCAPS_VIDEOMEMORY
922 | DDSCAPS_VISIBLE;
923}
924
925#endif
926
927static bool vboxPixFormatMatch(DDPIXELFORMAT *pFormat1, DDPIXELFORMAT *pFormat2)
928{
929 return !memcmp(pFormat1, pFormat2, sizeof (DDPIXELFORMAT));
930}
931
932int vboxSurfDescMerge(DDSURFACEDESC *paDescs, uint32_t *pcDescs, uint32_t cMaxDescs, DDSURFACEDESC *pDesc)
933{
934 uint32_t cDescs = *pcDescs;
935
936 Assert(cMaxDescs >= cDescs);
937 Assert(pDesc->dwFlags == (DDSD_CAPS | DDSD_PIXELFORMAT));
938 if (pDesc->dwFlags != (DDSD_CAPS | DDSD_PIXELFORMAT))
939 return VERR_INVALID_PARAMETER;
940
941 for (uint32_t i = 0; i < cDescs; ++i)
942 {
943 DDSURFACEDESC *pCur = &paDescs[i];
944 if (vboxPixFormatMatch(&pCur->ddpfPixelFormat, &pDesc->ddpfPixelFormat))
945 {
946 if (pDesc->dwFlags & DDSD_CAPS)
947 {
948 pCur->dwFlags |= DDSD_CAPS;
949 pCur->ddsCaps.dwCaps |= pDesc->ddsCaps.dwCaps;
950 }
951 return VINF_SUCCESS;
952 }
953 }
954
955 if (cMaxDescs > cDescs)
956 {
957 paDescs[cDescs] = *pDesc;
958 ++cDescs;
959 *pcDescs = cDescs;
960 return VINF_SUCCESS;
961 }
962 return VERR_BUFFER_OVERFLOW;
963}
964
965int vboxFormatOpsMerge(FORMATOP *paOps, uint32_t *pcOps, uint32_t cMaxOps, FORMATOP *pOp)
966{
967 uint32_t cOps = *pcOps;
968
969 Assert(cMaxOps >= cOps);
970
971 for (uint32_t i = 0; i < cOps; ++i)
972 {
973 FORMATOP *pCur = &paOps[i];
974 if (pCur->Format == pOp->Format)
975 {
976 pCur->Operations |= pOp->Operations;
977 Assert(pCur->FlipMsTypes == pOp->FlipMsTypes);
978 Assert(pCur->BltMsTypes == pOp->BltMsTypes);
979 Assert(pCur->PrivateFormatBitCount == pOp->PrivateFormatBitCount);
980 return VINF_SUCCESS;
981 }
982 }
983
984 if (cMaxOps > cOps)
985 {
986 paOps[cOps] = *pOp;
987 ++cOps;
988 *pcOps = cOps;
989 return VINF_SUCCESS;
990 }
991 return VERR_BUFFER_OVERFLOW;
992}
993
994int vboxCapsInit(PVBOXWDDMDISP_ADAPTER pAdapter)
995{
996 pAdapter->cFormstOps = 0;
997 pAdapter->paFormstOps = NULL;
998 pAdapter->cSurfDescs = 0;
999 pAdapter->paSurfDescs = NULL;
1000
1001 if (pAdapter->uIfVersion > 7)
1002 {
1003 if (pAdapter->pD3D9If)
1004 {
1005 pAdapter->paFormstOps = (FORMATOP*)RTMemAllocZ(sizeof (gVBoxFormatOps3D));
1006 Assert(pAdapter->paFormstOps);
1007 if (pAdapter->paFormstOps)
1008 {
1009 memcpy (pAdapter->paFormstOps , gVBoxFormatOps3D, sizeof (gVBoxFormatOps3D));
1010 pAdapter->cFormstOps = RT_ELEMENTS(gVBoxFormatOps3D);
1011 }
1012 else
1013 return VERR_OUT_OF_RESOURCES;
1014
1015 /* @todo: do we need surface caps here ? */
1016 }
1017 }
1018#ifdef VBOX_WITH_VIDEOHWACCEL
1019 else
1020 {
1021 /* just calc the max number of formats */
1022 uint32_t cFormats = RT_ELEMENTS(gVBoxFormatOpsBase);
1023 uint32_t cSurfDescs = RT_ELEMENTS(gVBoxSurfDescsBase);
1024 uint32_t cOverlayFormats = 0;
1025 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
1026 {
1027 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
1028 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
1029 {
1030 cOverlayFormats += pVhwa->Settings.cFormats;
1031 }
1032 }
1033
1034 cFormats += cOverlayFormats;
1035 cSurfDescs += cOverlayFormats;
1036
1037 uint32_t cbFormatOps = cFormats * sizeof (FORMATOP);
1038 cbFormatOps = (cbFormatOps + 7) & ~3;
1039 /* ensure the surf descs are 8 byte aligned */
1040 uint32_t offSurfDescs = (cbFormatOps + 7) & ~3;
1041 uint32_t cbSurfDescs = cSurfDescs * sizeof (DDSURFACEDESC);
1042 uint32_t cbBuf = offSurfDescs + cbSurfDescs;
1043 uint8_t* pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
1044 Assert(pvBuf);
1045 if (pvBuf)
1046 {
1047 pAdapter->paFormstOps = (FORMATOP*)pvBuf;
1048 memcpy (pAdapter->paFormstOps , gVBoxFormatOpsBase, sizeof (gVBoxFormatOpsBase));
1049 pAdapter->cFormstOps = RT_ELEMENTS(gVBoxFormatOpsBase);
1050
1051 FORMATOP fo = {D3DDDIFMT_UNKNOWN, 0, 0, 0, 0};
1052 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
1053 {
1054 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
1055 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
1056 {
1057 for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j)
1058 {
1059 fo.Format = pVhwa->Settings.aFormats[j];
1060 fo.Operations = FORMATOP_OVERLAY;
1061 int rc = vboxFormatOpsMerge(pAdapter->paFormstOps, &pAdapter->cFormstOps, cFormats, &fo);
1062 AssertRC(rc);
1063 }
1064 }
1065 }
1066
1067 pAdapter->paSurfDescs = (DDSURFACEDESC*)(pvBuf + offSurfDescs);
1068 memcpy (pAdapter->paSurfDescs , gVBoxSurfDescsBase, sizeof (gVBoxSurfDescsBase));
1069 pAdapter->cSurfDescs = RT_ELEMENTS(gVBoxSurfDescsBase);
1070
1071 DDSURFACEDESC sd;
1072 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
1073 {
1074 VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa;
1075 if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED)
1076 {
1077 for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j)
1078 {
1079 uint32_t fourcc = vboxWddmFormatToFourcc(pVhwa->Settings.aFormats[j]);
1080 if (fourcc)
1081 {
1082 vboxVhwaPopulateOverlayFourccSurfDesc(&sd, fourcc);
1083 int rc = vboxSurfDescMerge(pAdapter->paSurfDescs, &pAdapter->cSurfDescs, cSurfDescs, &sd);
1084 AssertRC(rc);
1085 }
1086 }
1087 }
1088 }
1089 }
1090 else
1091 return VERR_OUT_OF_RESOURCES;
1092 }
1093#endif
1094
1095 return VINF_SUCCESS;
1096}
1097
1098void vboxCapsFree(PVBOXWDDMDISP_ADAPTER pAdapter)
1099{
1100 if (pAdapter->paFormstOps)
1101 RTMemFree(pAdapter->paFormstOps);
1102}
1103
1104static void vboxResourceFree(PVBOXWDDMDISP_RESOURCE pRc)
1105{
1106 RTMemFree(pRc);
1107}
1108
1109static PVBOXWDDMDISP_RESOURCE vboxResourceAlloc(UINT cAllocs)
1110{
1111 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_RESOURCE, aAllocations[cAllocs]));
1112 Assert(pRc);
1113 if (pRc)
1114 {
1115 pRc->cAllocations = cAllocs;
1116 for (UINT i = 0; i < cAllocs; ++i)
1117 {
1118 pRc->aAllocations[i].iAlloc = i;
1119 pRc->aAllocations[i].pRc = pRc;
1120 }
1121 return pRc;
1122 }
1123 return NULL;
1124}
1125
1126static void vboxWddmLockUnlockMemSynch(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DLOCKED_RECT *pLockInfo, RECT *pRect, bool bToLockInfo)
1127{
1128 Assert(pAlloc->SurfDesc.pitch);
1129 Assert(pAlloc->pvMem);
1130
1131 if (!pRect)
1132 {
1133 if (pAlloc->SurfDesc.pitch == pLockInfo->Pitch)
1134 {
1135 if (bToLockInfo)
1136 memcpy(pLockInfo->pBits, pAlloc->pvMem, pAlloc->SurfDesc.pitch * pAlloc->SurfDesc.height);
1137 else
1138 memcpy(pAlloc->pvMem, pLockInfo->pBits, pAlloc->SurfDesc.pitch * pAlloc->SurfDesc.height);
1139 }
1140 else
1141 {
1142 uint8_t *pvSrc, *pvDst;
1143 uint32_t srcPitch, dstPitch;
1144 if (bToLockInfo)
1145 {
1146 pvSrc = (uint8_t *)pAlloc->pvMem;
1147 pvDst = (uint8_t *)pLockInfo->pBits;
1148 srcPitch = pAlloc->SurfDesc.pitch;
1149 dstPitch = pLockInfo->Pitch;
1150 }
1151 else
1152 {
1153 pvDst = (uint8_t *)pAlloc->pvMem;
1154 pvSrc = (uint8_t *)pLockInfo->pBits;
1155 dstPitch = pAlloc->SurfDesc.pitch;
1156 srcPitch = (uint32_t)pLockInfo->Pitch;
1157 }
1158
1159 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
1160 Assert(pitch);
1161 for (UINT j = 0; j < pAlloc->SurfDesc.height; ++j)
1162 {
1163 memcpy(pvDst, pvSrc, pitch);
1164 pvSrc += srcPitch;
1165 pvDst += dstPitch;
1166 }
1167 }
1168 }
1169 else
1170 {
1171 uint8_t *pvSrc, *pvDst;
1172 uint32_t srcPitch, dstPitch;
1173 /* @todo: this is not entirely correct */
1174 uint8_t * pvAllocMemStart = (uint8_t *)pAlloc->pvMem;
1175 uint32_t cbPP = pAlloc->SurfDesc.pitch/pAlloc->SurfDesc.width;
1176 pvAllocMemStart += pAlloc->SurfDesc.pitch * pRect->top + pRect->left * cbPP;
1177
1178 if (bToLockInfo)
1179 {
1180 pvSrc = (uint8_t *)pvAllocMemStart;
1181 pvDst = (uint8_t *)pLockInfo->pBits;
1182 srcPitch = pAlloc->SurfDesc.pitch;
1183 dstPitch = pLockInfo->Pitch;
1184 }
1185 else
1186 {
1187 pvDst = (uint8_t *)pvAllocMemStart;
1188 pvSrc = (uint8_t *)pLockInfo->pBits;
1189 dstPitch = pAlloc->SurfDesc.pitch;
1190 srcPitch = (uint32_t)pLockInfo->Pitch;
1191 }
1192
1193 uint32_t cPixCopyLine = pRect->right - pRect->left;
1194
1195 if (cPixCopyLine == pAlloc->SurfDesc.width && srcPitch == dstPitch)
1196 {
1197 memcpy(pvDst, pvSrc, pAlloc->SurfDesc.pitch * (pRect->bottom - pRect->top));
1198 }
1199 else
1200 {
1201 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
1202 uint32_t cbCopyLine = cPixCopyLine * cbPP;
1203 Assert(pitch);
1204 for (int j = pRect->top; j < pRect->bottom; ++j)
1205 {
1206 memcpy(pvDst, pvSrc, cbCopyLine);
1207 pvSrc += srcPitch;
1208 pvDst += dstPitch;
1209 }
1210 }
1211 }
1212}
1213
1214#if 0
1215static HRESULT vboxWddmRectBltPerform(uint8_t *pvDstSurf, const uint8_t *pvSrcSurf,
1216 RECT *pDstRect, RECT *pSrcRect,
1217 uint32_t DstPitch, uint32_t SrcPitch, uint32_t bpp,
1218 RECT *pDstCopyRect, RECT *pSrcCopyRect)
1219{
1220 uint32_t DstCopyWidth = pDstCopyRect->left - pDstCopyRect->right;
1221 uint32_t DstCopyHeight = pDstCopyRect->bottom - pDstCopyRect->top;
1222 uint32_t SrcCopyWidth = pSrcCopyRect->left - pSrcCopyRect->right;
1223 uint32_t SrcCopyHeight = pSrcCopyRect->bottom - pSrcCopyRect->top;
1224 uint32_t srcBpp = bpp;
1225 uint32_t dstBpp = bpp;
1226 /* we do not support stretching */
1227 Assert(DstCopyWidth == SrcCopyWidth);
1228 Assert(DstCopyHeight == SrcCopyWidth);
1229 if (DstCopyWidth != SrcCopyWidth)
1230 return E_FAIL;
1231 if (DstCopyHeight != SrcCopyWidth)
1232 return E_FAIL;
1233
1234 uint32_t DstWidth = pDstRect->left - pDstRect->right;
1235 uint32_t DstHeight = pDstRect->bottom - pDstRect->top;
1236 uint32_t SrcWidth = pSrcRect->left - pSrcRect->right;
1237 uint32_t SrcHeight = pSrcRect->bottom - pSrcRect->top;
1238
1239 if (DstWidth == DstCopyWidth
1240 && SrcWidth == SrcCopyWidth
1241 && SrcWidth == DstWidth)
1242 {
1243 Assert(!pDstCopyRect->left);
1244 Assert(!pSrcCopyRect->left);
1245 uint32_t cbOff = DstPitch * pDstCopyRect->top;
1246 uint32_t cbSize = DstPitch * DstCopyHeight;
1247 memcpy(pvDstSurf + cbOff, pvSrcSurf + cbOff, cbSize);
1248 }
1249 else
1250 {
1251 uint32_t offDstLineStart = pDstCopyRect->left * dstBpp >> 3;
1252 uint32_t offDstLineEnd = ((pDstCopyRect->left * dstBpp + 7) >> 3) + ((dstBpp * DstCopyWidth + 7) >> 3);
1253 uint32_t cbDstLine = offDstLineEnd - offDstLineStart;
1254 uint32_t offDstStart = DstPitch * pDstCopyRect->top + offDstLineStart;
1255 Assert(cbDstLine <= DstPitch);
1256 uint32_t cbDstSkip = DstPitch;
1257 uint8_t * pvDstStart = pvDstSurf + offDstStart;
1258
1259 uint32_t offSrcLineStart = pSrcCopyRect->left * srcBpp >> 3;
1260 uint32_t offSrcLineEnd = ((pSrcCopyRect->left * srcBpp + 7) >> 3) + ((srcBpp * SrcCopyWidth + 7) >> 3);
1261 uint32_t cbSrcLine = offSrcLineEnd - offSrcLineStart;
1262 uint32_t offSrcStart = SrcPitch * pSrcCopyRect->top + offSrcLineStart;
1263 Assert(cbSrcLine <= SrcPitch);
1264 uint32_t cbSrcSkip = SrcPitch;
1265 const uint8_t * pvSrcStart = pvSrcSurf + offSrcStart;
1266
1267 Assert(cbDstLine == cbSrcLine);
1268
1269 for (uint32_t i = 0; ; ++i)
1270 {
1271 memcpy (pvDstStart, pvSrcStart, cbDstLine);
1272 if (i == DstCopyHeight)
1273 break;
1274 pvDstStart += cbDstSkip;
1275 pvSrcStart += cbSrcSkip;
1276 }
1277 }
1278 return S_OK;
1279}
1280#endif
1281
1282static HRESULT vboxWddmRectBltPerform(uint8_t *pvDstSurf, const uint8_t *pvSrcSurf,
1283 const RECT *pDstRect, const RECT *pSrcRect,
1284 uint32_t DstPitch, uint32_t SrcPitch, uint32_t bpp)
1285{
1286 uint32_t DstWidth = pDstRect->left - pDstRect->right;
1287 uint32_t DstHeight = pDstRect->bottom - pDstRect->top;
1288 uint32_t SrcWidth = pSrcRect->left - pSrcRect->right;
1289 uint32_t SrcHeight = pSrcRect->bottom - pSrcRect->top;
1290 uint32_t srcBpp = bpp;
1291 uint32_t dstBpp = bpp;
1292 /* we do not support stretching */
1293 Assert(DstWidth == SrcWidth);
1294 Assert(DstHeight == SrcWidth);
1295 if (DstWidth != SrcWidth)
1296 return E_FAIL;
1297 if (DstHeight != SrcWidth)
1298 return E_FAIL;
1299
1300 if (DstPitch == SrcPitch
1301 && ((DstWidth * bpp)/8) == DstPitch)
1302 {
1303 Assert(!pDstRect->left);
1304 Assert(!pSrcRect->left);
1305 uint32_t cbOff = DstPitch * pDstRect->top;
1306 uint32_t cbSize = DstPitch * DstHeight;
1307 memcpy(pvDstSurf + cbOff, pvSrcSurf + cbOff, cbSize);
1308 }
1309 else
1310 {
1311
1312 uint32_t cbDstLine = (((DstWidth * dstBpp) + 7) >> 3);
1313 for (uint32_t i = 0; ; ++i)
1314 {
1315 memcpy (pvDstSurf, pvSrcSurf, cbDstLine);
1316 if (i == DstHeight)
1317 break;
1318 pvDstSurf += DstPitch;
1319 pvSrcSurf += SrcPitch;
1320 }
1321 }
1322 return S_OK;
1323}
1324
1325static HRESULT vboxWddmSurfSynchMem(PVBOXWDDMDISP_RESOURCE pRc, PVBOXWDDMDISP_ALLOCATION pAllocation)
1326{
1327 HRESULT hr = S_OK;
1328 Assert(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
1329 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
1330 {
1331 Assert(pAllocation->pvMem);
1332 D3DLOCKED_RECT lockInfo;
1333 IDirect3DSurface9 *pD3D9Surf = (IDirect3DSurface9*)pAllocation->pD3DIf;
1334 hr = pD3D9Surf->LockRect(&lockInfo, NULL, D3DLOCK_DISCARD);
1335 Assert(hr == S_OK);
1336 if (hr == S_OK)
1337 {
1338 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
1339 HRESULT tmpHr = pD3D9Surf->UnlockRect();
1340 Assert(tmpHr == S_OK);
1341 }
1342 }
1343 else
1344 {
1345 Assert(!pAllocation->pvMem);
1346 }
1347 return hr;
1348}
1349
1350#if 0
1351static HRESULT vboxWddmRenderTargetUpdateSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf)
1352{
1353 if (pAlloc->SurfDesc.VidPnSourceId != pDevice->iPrimaryScreen)
1354 return S_OK;
1355
1356 IDirect3DSurface9 *pD3D9Surf;
1357 IDirect3DDevice9 *pDevice9If = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
1358 HRESULT hr = pDevice9If->GetBackBuffer(0 /*UINT iSwapChain*/,
1359 iBBuf, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
1360 Assert(hr == S_OK);
1361 if (hr == S_OK)
1362 {
1363 Assert(pD3D9Surf);
1364 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
1365 if (pAlloc->pD3DIf)
1366 pAlloc->pD3DIf->Release();
1367 pAlloc->pD3DIf = pD3D9Surf;
1368 }
1369 return hr;
1370}
1371static HRESULT vboxWddmRenderTargetUpdate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB)
1372{
1373 if (pRc->RcDesc.VidPnSourceId != pDevice->iPrimaryScreen)
1374 return S_OK;
1375
1376 PVBOXWDDMDISP_ALLOCATION pAlloc;
1377 UINT iBBuf = 0;
1378 Assert(iNewRTFB < pRc->cAllocations);
1379
1380 for (UINT i = 1; i < pRc->cAllocations; ++i, ++iBBuf)
1381 {
1382 UINT iAlloc = (iNewRTFB + i) % pRc->cAllocations;
1383 Assert(iAlloc != iNewRTFB);
1384 pAlloc = &pRc->aAllocations[iAlloc];
1385 HRESULT tmpHr = vboxWddmRenderTargetUpdateSurface(pDevice, pAlloc, iBBuf);
1386 Assert(tmpHr == S_OK);
1387 }
1388
1389 pAlloc = &pRc->aAllocations[iNewRTFB];
1390 if (pRc->cAllocations > 1)
1391 {
1392#ifdef VBOXWDDM_WITH_VISIBLE_FB
1393 HRESULT tmpHr = vboxWddmRenderTargetUpdateSurface(pDevice, pAlloc, ~0UL /* <- for the frontbuffer */);
1394 Assert(tmpHr == S_OK);
1395#else
1396 if (pAlloc->pD3DIf)
1397 {
1398 pAlloc->pD3DIf->Release();
1399 pAlloc->pD3DIf = NULL;
1400 }
1401#endif
1402 }
1403 else
1404 {
1405#ifndef VBOXDISP_WITH_WINE_BB_WORKAROUND
1406# error "port me!"
1407#endif
1408 /* work-around wine backbuffer for devices w/o backbuffers */
1409 HRESULT tmpHr = vboxWddmRenderTargetUpdateSurface(pDevice, pAlloc, 0);
1410 Assert(tmpHr == S_OK);
1411 }
1412
1413#ifdef DEBUG
1414 for (UINT i = 0; i < pRc->cAllocations; ++i)
1415 {
1416 pAlloc = &pRc->aAllocations[i];
1417 if (iNewRTFB == i)
1418 {
1419 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));
1420 }
1421
1422 for (UINT j = i+1; j < pRc->cAllocations; ++j)
1423 {
1424 PVBOXWDDMDISP_ALLOCATION pAllocJ = &pRc->aAllocations[j];
1425 Assert(pAlloc->pD3DIf != pAllocJ->pD3DIf);
1426 }
1427 }
1428#endif
1429 return S_OK;
1430}
1431#endif
1432
1433static D3DFORMAT vboxDDI2D3DFormat(D3DDDIFORMAT format)
1434{
1435 /* @todo: check they are all equal */
1436 return (D3DFORMAT)format;
1437}
1438
1439D3DMULTISAMPLE_TYPE vboxDDI2D3DMultiSampleType(D3DDDIMULTISAMPLE_TYPE enmType)
1440{
1441 /* @todo: check they are all equal */
1442 return (D3DMULTISAMPLE_TYPE)enmType;
1443}
1444
1445D3DPOOL vboxDDI2D3DPool(D3DDDI_POOL enmPool)
1446{
1447 /* @todo: check they are all equal */
1448 switch (enmPool)
1449 {
1450 case D3DDDIPOOL_SYSTEMMEM:
1451 return D3DPOOL_SYSTEMMEM;
1452 case D3DDDIPOOL_VIDEOMEMORY:
1453 case D3DDDIPOOL_LOCALVIDMEM:
1454 case D3DDDIPOOL_NONLOCALVIDMEM:
1455 /* @todo: what would be proper here? */
1456 return D3DPOOL_DEFAULT;
1457 default:
1458 Assert(0);
1459 }
1460 return D3DPOOL_DEFAULT;
1461}
1462
1463D3DRENDERSTATETYPE vboxDDI2D3DRenderStateType(D3DDDIRENDERSTATETYPE enmType)
1464{
1465 /* @todo: @fixme: not entirely correct, need to check */
1466 return (D3DRENDERSTATETYPE)enmType;
1467}
1468
1469VBOXWDDMDISP_TSS_LOOKUP vboxDDI2D3DTestureStageStateType(D3DDDITEXTURESTAGESTATETYPE enmType)
1470{
1471 static const VBOXWDDMDISP_TSS_LOOKUP lookup[] =
1472 {
1473 {FALSE, D3DTSS_FORCE_DWORD}, /* 0, D3DDDITSS_TEXTUREMAP */
1474 {FALSE, D3DTSS_COLOROP}, /* 1, D3DDDITSS_COLOROP */
1475 {FALSE, D3DTSS_COLORARG1}, /* 2, D3DDDITSS_COLORARG1 */
1476 {FALSE, D3DTSS_COLORARG2}, /* 3, D3DDDITSS_COLORARG2 */
1477 {FALSE, D3DTSS_ALPHAOP}, /* 4, D3DDDITSS_ALPHAOP */
1478 {FALSE, D3DTSS_ALPHAARG1}, /* 5, D3DDDITSS_ALPHAARG1 */
1479 {FALSE, D3DTSS_ALPHAARG2}, /* 6, D3DDDITSS_ALPHAARG2 */
1480 {FALSE, D3DTSS_BUMPENVMAT00}, /* 7, D3DDDITSS_BUMPENVMAT00 */
1481 {FALSE, D3DTSS_BUMPENVMAT01}, /* 8, D3DDDITSS_BUMPENVMAT01 */
1482 {FALSE, D3DTSS_BUMPENVMAT10}, /* 9, D3DDDITSS_BUMPENVMAT10 */
1483 {FALSE, D3DTSS_BUMPENVMAT11}, /* 10, D3DDDITSS_BUMPENVMAT11 */
1484 {FALSE, D3DTSS_TEXCOORDINDEX}, /* 11, D3DDDITSS_TEXCOORDINDEX */
1485 {FALSE, D3DTSS_FORCE_DWORD}, /* 12, unused */
1486 {TRUE, D3DSAMP_ADDRESSU}, /* 13, D3DDDITSS_ADDRESSU */
1487 {TRUE, D3DSAMP_ADDRESSV}, /* 14, D3DDDITSS_ADDRESSV */
1488 {TRUE, D3DSAMP_BORDERCOLOR}, /* 15, D3DDDITSS_BORDERCOLOR */
1489 {TRUE, D3DSAMP_MAGFILTER}, /* 16, D3DDDITSS_MAGFILTER */
1490 {TRUE, D3DSAMP_MINFILTER}, /* 17, D3DDDITSS_MINFILTER */
1491 {TRUE, D3DSAMP_MIPFILTER}, /* 18, D3DDDITSS_MIPFILTER */
1492 {TRUE, D3DSAMP_MIPMAPLODBIAS}, /* 19, D3DDDITSS_MIPMAPLODBIAS */
1493 {TRUE, D3DSAMP_MAXMIPLEVEL}, /* 20, D3DDDITSS_MAXMIPLEVEL */
1494 {TRUE, D3DSAMP_MAXANISOTROPY}, /* 21, D3DDDITSS_MAXANISOTROPY */
1495 {FALSE, D3DTSS_BUMPENVLSCALE}, /* 22, D3DDDITSS_BUMPENVLSCALE */
1496 {FALSE, D3DTSS_BUMPENVLOFFSET}, /* 23, D3DDDITSS_BUMPENVLOFFSET */
1497 {FALSE, D3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DDDITSS_TEXTURETRANSFORMFLAGS */
1498 {TRUE, D3DSAMP_ADDRESSW}, /* 25, D3DDDITSS_ADDRESSW */
1499 {FALSE, D3DTSS_COLORARG0}, /* 26, D3DDDITSS_COLORARG0 */
1500 {FALSE, D3DTSS_ALPHAARG0}, /* 27, D3DDDITSS_ALPHAARG0 */
1501 {FALSE, D3DTSS_RESULTARG}, /* 28, D3DDDITSS_RESULTARG */
1502 {TRUE, D3DSAMP_SRGBTEXTURE}, /* 29, D3DDDITSS_SRGBTEXTURE */
1503 {TRUE, D3DSAMP_ELEMENTINDEX}, /* 30, D3DDDITSS_ELEMENTINDEX */
1504 {TRUE, D3DSAMP_DMAPOFFSET}, /* 31, D3DDDITSS_DMAPOFFSET */
1505 {FALSE, D3DTSS_CONSTANT}, /* 32, D3DDDITSS_CONSTANT */
1506 {FALSE, D3DTSS_FORCE_DWORD}, /* 33, D3DDDITSS_DISABLETEXTURECOLORKEY */
1507 {FALSE, D3DTSS_FORCE_DWORD}, /* 34, D3DDDITSS_TEXTURECOLORKEYVAL */
1508 };
1509
1510 Assert(enmType > 0);
1511 Assert(enmType < RT_ELEMENTS(lookup));
1512 Assert(lookup[enmType].dType != D3DTSS_FORCE_DWORD);
1513
1514 return lookup[enmType];
1515}
1516
1517DWORD vboxDDI2D3DUsage(D3DDDI_RESOURCEFLAGS fFlags)
1518{
1519 DWORD fUsage = 0;
1520 if (fFlags.Dynamic)
1521 fUsage |= D3DUSAGE_DYNAMIC;
1522 if (fFlags.AutogenMipmap)
1523 fUsage |= D3DUSAGE_AUTOGENMIPMAP;
1524 if (fFlags.DMap)
1525 fUsage |= D3DUSAGE_DMAP;
1526 if (fFlags.WriteOnly)
1527 fUsage |= D3DUSAGE_WRITEONLY;
1528 if (fFlags.NPatches)
1529 fUsage |= D3DUSAGE_NPATCHES;
1530 if (fFlags.Points)
1531 fUsage |= D3DUSAGE_POINTS;
1532 if (fFlags.RenderTarget)
1533 fUsage |= D3DUSAGE_RENDERTARGET;
1534 if (fFlags.RtPatches)
1535 fUsage |= D3DUSAGE_RTPATCHES;
1536 if (fFlags.TextApi)
1537 fUsage |= D3DUSAGE_TEXTAPI;
1538 if (fFlags.WriteOnly)
1539 fUsage |= D3DUSAGE_WRITEONLY;
1540 //below are wddm 1.1-specific
1541// if (fFlags.RestrictedContent)
1542// fUsage |= D3DUSAGE_RESTRICTED_CONTENT;
1543// if (fFlags.RestrictSharedAccess)
1544// fUsage |= D3DUSAGE_RESTRICT_SHARED_RESOURCE;
1545 return fUsage;
1546}
1547
1548DWORD vboxDDI2D3DLockFlags(D3DDDI_LOCKFLAGS fLockFlags)
1549{
1550 DWORD fFlags = 0;
1551 if (fLockFlags.Discard)
1552 fFlags |= D3DLOCK_DISCARD;
1553 if (fLockFlags.NoOverwrite)
1554 fFlags |= D3DLOCK_NOOVERWRITE;
1555 if (fLockFlags.ReadOnly)
1556 fFlags |= D3DLOCK_READONLY;
1557 if (fLockFlags.DoNotWait)
1558 fFlags |= D3DLOCK_DONOTWAIT;
1559 return fFlags;
1560}
1561
1562D3DTEXTUREFILTERTYPE vboxDDI2D3DBltFlags(D3DDDI_BLTFLAGS fFlags)
1563{
1564 if (fFlags.Point)
1565 {
1566 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
1567 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 1);
1568 return D3DTEXF_POINT;
1569 }
1570 if (fFlags.Linear)
1571 {
1572 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
1573 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 2);
1574 return D3DTEXF_LINEAR;
1575 }
1576 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
1577 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 0);
1578 return D3DTEXF_NONE;
1579}
1580
1581/* on success increments the surface ref counter,
1582 * i.e. one must call pSurf->Release() once the surface is not needed*/
1583static HRESULT vboxWddmSurfGet(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc, IDirect3DSurface9 **ppSurf)
1584{
1585 HRESULT hr = S_OK;
1586 Assert(pRc->cAllocations > iAlloc);
1587 switch (pRc->aAllocations[0].enmD3DIfType)
1588 {
1589 case VBOXDISP_D3DIFTYPE_SURFACE:
1590 {
1591 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
1592 Assert(pD3DIfSurf);
1593 pD3DIfSurf->AddRef();
1594 *ppSurf = pD3DIfSurf;
1595 break;
1596 }
1597 case VBOXDISP_D3DIFTYPE_TEXTURE:
1598 {
1599 Assert(pRc->cAllocations == 1); /* <- vboxWddmSurfGet is typically used in Blt & ColorFill functions
1600 * in this case, if texture is used as a destination,
1601 * we should update sub-layers as well which is not done currently
1602 * so for now check vboxWddmSurfGet is used for one-level textures */
1603 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
1604 IDirect3DSurface9 *pSurfaceLevel;
1605 Assert(pD3DIfTex);
1606 hr = pD3DIfTex->GetSurfaceLevel(iAlloc, &pSurfaceLevel);
1607 Assert(hr == S_OK);
1608 if (hr == S_OK)
1609 {
1610 *ppSurf = pSurfaceLevel;
1611 }
1612 break;
1613 }
1614 default:
1615 Assert(0);
1616 hr = E_FAIL;
1617 break;
1618 }
1619 return hr;
1620}
1621
1622/******/
1623static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch);
1624
1625DECLINLINE(VOID) vboxWddmSwapchainInit(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1626{
1627 RTLISTNODE ListEntry = pSwapchain->ListEntry;
1628 memset(pSwapchain, 0, sizeof (VBOXWDDMDISP_SWAPCHAIN));
1629 pSwapchain->ListEntry = ListEntry;
1630 pSwapchain->iBB = VBOXWDDMDISP_INDEX_UNDEFINED;
1631}
1632
1633static HRESULT vboxWddmSwapchainKmSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1634{
1635 struct
1636 {
1637 VBOXDISPIFESCAPE_SWAPCHAININFO SwapchainInfo;
1638 D3DKMT_HANDLE ahAllocs[VBOXWDDMDISP_MAX_SWAPCHAIN_SIZE];
1639 } Buf;
1640
1641 memset(&Buf.SwapchainInfo, 0, sizeof (Buf.SwapchainInfo));
1642 Buf.SwapchainInfo.EscapeHdr.escapeCode = VBOXESC_SWAPCHAININFO;
1643 Buf.SwapchainInfo.SwapchainInfo.hSwapchainKm = pSwapchain->hSwapchainKm;
1644 Buf.SwapchainInfo.SwapchainInfo.hSwapchainUm = (VBOXDISP_UMHANDLE)pSwapchain;
1645// Buf.SwapchainInfo.SwapchainInfo.Rect;
1646// Buf.SwapchainInfo.SwapchainInfo.u32Reserved;
1647 Buf.SwapchainInfo.SwapchainInfo.cAllocs = pSwapchain->cRTs;
1648 UINT cAllocsKm = 0;
1649 for (UINT i = 0; i < Buf.SwapchainInfo.SwapchainInfo.cAllocs; ++i)
1650 {
1651// Assert(pSwapchain->aRTs[i].pAlloc->hAllocation);
1652 Buf.SwapchainInfo.SwapchainInfo.ahAllocs[i] = pSwapchain->aRTs[i].pAlloc->hAllocation;
1653 if (Buf.SwapchainInfo.SwapchainInfo.ahAllocs[i])
1654 ++cAllocsKm;
1655 }
1656
1657 Assert(cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs || !cAllocsKm);
1658
1659 if (cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs)
1660 {
1661 D3DDDICB_ESCAPE DdiEscape = {0};
1662 DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext;
1663 DdiEscape.hDevice = pDevice->hDevice;
1664 // DdiEscape.Flags.Value = 0;
1665 DdiEscape.pPrivateDriverData = &Buf.SwapchainInfo;
1666 DdiEscape.PrivateDriverDataSize = RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[Buf.SwapchainInfo.SwapchainInfo.cAllocs]);
1667 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
1668 Assert(hr == S_OK);
1669 if (hr == S_OK)
1670 {
1671 pSwapchain->hSwapchainKm = Buf.SwapchainInfo.SwapchainInfo.hSwapchainKm;
1672 }
1673
1674 return hr;
1675 }
1676 return S_OK;
1677}
1678
1679static HRESULT vboxWddmSwapchainKmDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1680{
1681 HRESULT hr = S_OK;
1682 if (pSwapchain->hSwapchainKm)
1683 {
1684 /* submit empty swapchain to destroy the KM one */
1685 UINT cOldRTc = pSwapchain->cRTs;
1686 pSwapchain->cRTs = 0;
1687 hr = vboxWddmSwapchainKmSynch(pDevice, pSwapchain);
1688 Assert(hr == S_OK);
1689 Assert(!pSwapchain->hSwapchainKm);
1690 pSwapchain->cRTs = cOldRTc;
1691 }
1692 return hr;
1693}
1694static HRESULT vboxWddmSwapchainDestroyIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1695{
1696 if (pSwapchain->pSwapChainIf)
1697 {
1698#ifndef VBOXWDDM_WITH_VISIBLE_FB
1699 pSwapchain->pRenderTargetFbCopy->Release();
1700 pSwapchain->pRenderTargetFbCopy = NULL;
1701 pSwapchain->bRTFbCopyUpToDate = FALSE;
1702#endif
1703 pSwapchain->pSwapChainIf->Release();
1704 Assert(pSwapchain->hWnd);
1705 HRESULT hr = VBoxDispWndDestroy(pDevice->pAdapter, pSwapchain->hWnd);
1706 Assert(hr == S_OK);
1707 pSwapchain->pSwapChainIf = NULL;
1708 pSwapchain->hWnd = NULL;
1709 return hr;
1710 }
1711
1712 Assert(!pSwapchain->hWnd);
1713 return S_OK;
1714}
1715
1716DECLINLINE(VOID) vboxWddmSwapchainClear(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1717{
1718 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
1719 {
1720 pSwapchain->aRTs[i].pAlloc->pSwapchain = NULL;
1721 }
1722 vboxWddmSwapchainDestroyIf(pDevice, pSwapchain);
1723 vboxWddmSwapchainKmDestroy(pDevice, pSwapchain);
1724 vboxWddmSwapchainInit(pSwapchain);
1725}
1726
1727static VOID vboxWddmSwapchainDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1728{
1729 vboxWddmSwapchainClear(pDevice, pSwapchain);
1730 RTListNodeRemove(&pSwapchain->ListEntry);
1731 RTMemFree(pSwapchain);
1732}
1733
1734static VOID vboxWddmSwapchainDestroyAll(PVBOXWDDMDISP_DEVICE pDevice)
1735{
1736 PVBOXWDDMDISP_SWAPCHAIN pCur = RTListNodeGetFirst(&pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
1737 while (pCur)
1738 {
1739 PVBOXWDDMDISP_SWAPCHAIN pNext = NULL;
1740 if (!RTListNodeIsLast(&pDevice->SwapchainList, &pCur->ListEntry))
1741 {
1742 pNext = RTListNodeGetNext(&pCur->ListEntry, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
1743 }
1744
1745 vboxWddmSwapchainDestroy(pDevice, pCur);
1746
1747 pCur = pNext;
1748 }
1749}
1750
1751static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainAlloc(PVBOXWDDMDISP_DEVICE pDevice)
1752{
1753 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)RTMemAllocZ(sizeof (VBOXWDDMDISP_SWAPCHAIN));
1754 Assert(pSwapchain);
1755 if (pSwapchain)
1756 {
1757 RTListAppend(&pDevice->SwapchainList, &pSwapchain->ListEntry);
1758 vboxWddmSwapchainInit(pSwapchain);
1759 return pSwapchain;
1760 }
1761 return NULL;
1762}
1763
1764DECLINLINE(VOID) vboxWddmSwapchainRtInit(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRt, PVBOXWDDMDISP_ALLOCATION pAlloc)
1765{
1766 pSwapchain->fFlags.bChanged = 1;
1767 pRt->pAlloc = pAlloc;
1768 pRt->cNumFlips = 0;
1769 pRt->fFlags.Value = 0;
1770 pRt->fFlags.bAdded = 1;
1771}
1772
1773DECLINLINE(VOID) vboxWddmSwapchainBbAddTail(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bAssignAsBb)
1774{
1775 pAlloc->pSwapchain = pSwapchain;
1776 VBOXWDDMDISP_SWAPCHAIN_FLAGS fOldFlags = pSwapchain->fFlags;
1777 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[pSwapchain->cRTs];
1778 ++pSwapchain->cRTs;
1779 vboxWddmSwapchainRtInit(pSwapchain, pRt, pAlloc);
1780 if (pSwapchain->cRTs == 1)
1781 {
1782 Assert(pSwapchain->iBB == VBOXWDDMDISP_INDEX_UNDEFINED);
1783 pSwapchain->iBB = 0;
1784 }
1785 else if (bAssignAsBb)
1786 {
1787 pSwapchain->iBB = pSwapchain->cRTs - 1;
1788 }
1789 else if (pSwapchain->cRTs == 2) /* the first one is a frontbuffer */
1790 {
1791 pSwapchain->iBB = 1;
1792 }
1793}
1794
1795DECLINLINE(UINT) vboxWddmSwapchainIdxFb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1796{
1797 return (pSwapchain->iBB + pSwapchain->cRTs - 1) % pSwapchain->cRTs;
1798}
1799
1800/* if swapchain contains only one surface returns this surface */
1801DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainGetBb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1802{
1803 if (pSwapchain->cRTs)
1804 {
1805 Assert(pSwapchain->iBB < pSwapchain->cRTs);
1806 return &pSwapchain->aRTs[pSwapchain->iBB];
1807 }
1808 return NULL;
1809}
1810
1811DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainGetFb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1812{
1813 if (pSwapchain->cRTs)
1814 {
1815 UINT iFb = vboxWddmSwapchainIdxFb(pSwapchain);
1816 return &pSwapchain->aRTs[iFb];
1817 }
1818 return NULL;
1819}
1820
1821DECLINLINE(VOID) vboxWddmSwapchainFlip(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1822{
1823 pSwapchain->iBB = (pSwapchain->iBB + 1) % pSwapchain->cRTs;
1824}
1825
1826DECLINLINE(UINT) vboxWddmSwapchainNumRTs(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1827{
1828 return pSwapchain->cRTs;
1829}
1830
1831
1832DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainRtForAlloc(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc)
1833{
1834 if (pAlloc->pSwapchain != pSwapchain)
1835 return NULL;
1836
1837 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
1838 {
1839 Assert(pSwapchain->aRTs[i].pAlloc->pSwapchain = pSwapchain);
1840 if (pSwapchain->aRTs[i].pAlloc == pAlloc)
1841 return &pSwapchain->aRTs[i];
1842 }
1843
1844 /* should never happen */
1845 Assert(0);
1846 return NULL;
1847}
1848
1849DECLINLINE(UINT) vboxWddmSwapchainRtIndex(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
1850{
1851 UINT offFirst = RT_OFFSETOF(VBOXWDDMDISP_SWAPCHAIN, aRTs);
1852 UINT offRT = UINT((uintptr_t)pRT - (uintptr_t)pSwapchain);
1853 Assert(offRT < sizeof (VBOXWDDMDISP_SWAPCHAIN));
1854 Assert(offRT >= offFirst);
1855 Assert(!((offRT - offFirst) % sizeof (VBOXWDDMDISP_RENDERTGT)));
1856 UINT iRt = (offRT - offFirst) / sizeof (VBOXWDDMDISP_RENDERTGT);
1857 Assert(iRt < pSwapchain->cRTs);
1858 return iRt;
1859}
1860
1861DECLINLINE(PVBOXWDDMDISP_SWAPCHAIN) vboxWddmSwapchainForAlloc(PVBOXWDDMDISP_ALLOCATION pAlloc)
1862{
1863 return pAlloc->pSwapchain;
1864}
1865
1866DECLINLINE(VOID) vboxWddmSwapchainRtRemove(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
1867{
1868 UINT iRt = vboxWddmSwapchainRtIndex(pSwapchain, pRT);
1869 Assert(iRt < pSwapchain->cRTs);
1870 pRT->pAlloc->pSwapchain = NULL;
1871 for (UINT i = iRt; i < pSwapchain->cRTs - 1; ++i)
1872 {
1873 pSwapchain->aRTs[i] = pSwapchain->aRTs[i + 1];
1874 }
1875
1876 --pSwapchain->cRTs;
1877 if (pSwapchain->cRTs)
1878 {
1879 if (pSwapchain->iBB > iRt)
1880 {
1881 --pSwapchain->iBB;
1882 }
1883 else if (pSwapchain->iBB == iRt)
1884 {
1885 Assert(0);
1886 pSwapchain->iBB = 0;
1887 }
1888 }
1889 else
1890 {
1891 pSwapchain->iBB = VBOXWDDMDISP_INDEX_UNDEFINED;
1892 }
1893 pSwapchain->fFlags.bChanged = TRUE;
1894}
1895
1896#if 0
1897
1898
1899DECLINLINE(VOID) vboxWddmSwapchainSetBb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
1900{
1901 UINT iRt = vboxWddmSwapchainRtIndex(pSwapchain, pRT);
1902 Assert(iRt < pSwapchain->cRTs);
1903 pSwapchain->iBB = iRt;
1904}
1905
1906/* the paRemoved buffer should at least contain VBOXWDDMDISP_MAX_SWAPCHAIN_SIZE elements,
1907 * the function does not validate its size in any way */
1908static BOOL vboxWddmSwapchainAdjust(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pBbAlloc, PUINT pcRemoved, PVBOXWDDMDISP_ALLOCATION paRemoved)
1909{
1910 UINT cRemoved = 0;
1911 BOOL bChanged = FALSE;
1912 PVBOXWDDMDISP_RENDERTGT pCurBbRt = vboxWddmSwapchainGetBb(pSwapchain);
1913 if (pCurBb)
1914 {
1915 if (pCurBbRt->pAlloc != pBbAlloc)
1916 {
1917 bChanged = TRUE;
1918
1919 /* determine whether we need to add the current BB
1920 * or remove part or all of the current RTs in the swapchain */
1921 PVBOXWDDMDISP_RENDERTGT pCorrectRt = vboxWddmSwapchainSearchRt(pSwapchain, pBbAlloc);
1922 if (pCorrectRt)
1923 {
1924 paRemoved[cRemoved] = pCurBbRt->pAlloc;
1925 ++cRemoved;
1926 vboxWddmSwapchainRemoveRt(pSwapchain, pCurBbRt);
1927 vboxWddmSwapchainSetBb(pSwapchain, pBbAlloc);
1928 }
1929 else
1930 {
1931 /* check if the pCurBbRt stored in the swapchain match those of the pBbAlloc */
1932 if (pBbAlloc->SurfDesc.width == pCurBbRt->pAlloc->SurfDesc.width
1933 && pBbAlloc->SurfDesc.height == pCurBbRt->pAlloc->SurfDesc.height
1934 && pBbAlloc->SurfDesc.format == pCurBbRt->pAlloc->SurfDesc.format)
1935 {
1936 for (UINT i = 0; i < pSwapchain->cRTs;)
1937 {
1938 if (pSwapchain->aRTs[i].cNumFlips > 1)
1939 {
1940 paRemoved[cRemoved] = pSwapchain->aRTs[i].pAlloc;
1941 ++cRemoved;
1942 vboxWddmSwapchainRemoveRt(pSwapchain, &pSwapchain->aRTs[i]);
1943 }
1944 else
1945 {
1946 ++i;
1947 }
1948 }
1949 }
1950 else
1951 {
1952 /* remove all */
1953 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
1954 {
1955 paRemoved[cRemoved] = pSwapchain->aRTs[i].pAlloc;
1956 ++cRemoved;
1957 }
1958
1959 vboxWddmSwapchainClear(pSwapchain);
1960 }
1961
1962 vboxWddmSwapchainAllocAddTail(pSwapchain, pBbAlloc);
1963 vboxWddmSwapchainSetBb(pSwapchain, pBbAlloc);
1964 }
1965 }
1966 }
1967 else
1968 {
1969 vboxWddmSwapchainAllocAddTail(pSwapchain, pBbAlloc);
1970 bChanged = TRUE;
1971 }
1972
1973 if (!bChanged)
1974 {
1975 Assert(cRemoved == 0);
1976 }
1977
1978 *pcRemoved = cRemoved;
1979
1980 return bChanged;
1981}
1982#endif
1983static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainFindCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc)
1984{
1985 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = pBbAlloc->pSwapchain;
1986 if (pSwapchain)
1987 {
1988 /* check if this is what we expect */
1989 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pSwapchain);
1990 if (pRt->pAlloc != pBbAlloc)
1991 {
1992 /* bad, @todo: correct the swapchain by either removing the Rt and adding it to another swapchain
1993 * or by removing the pBbAlloc out of it */
1994 Assert(0);
1995 }
1996 }
1997 if (!pSwapchain)
1998 {
1999#ifdef DEBUG_misha
2000 Assert(0);
2001#endif
2002 /* first search for the swapchain the alloc might be added to */
2003 PVBOXWDDMDISP_SWAPCHAIN pCur = RTListNodeGetFirst(&pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
2004 while (pCur)
2005 {
2006 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pCur);
2007 Assert(pRt);
2008 if (pRt->cNumFlips < 2
2009 && vboxWddmSwapchainRtIndex(pCur, pRt) == 0) /* <- in case we add a rt to the swapchain on present this would mean
2010 * that the last RT in the swapchain array is now a frontbuffer and
2011 * thus the aRTs[0] is a backbuffer */
2012 {
2013 PVBOXWDDMDISP_RESOURCE pBbRc = pBbAlloc->pRc;
2014 PVBOXWDDMDISP_RESOURCE pRtRc = pRt->pAlloc->pRc;
2015 if (pBbAlloc->SurfDesc.width == pRt->pAlloc->SurfDesc.width
2016 && pBbAlloc->SurfDesc.height == pRt->pAlloc->SurfDesc.height
2017 && pBbAlloc->SurfDesc.format == pRt->pAlloc->SurfDesc.format
2018 && pBbAlloc->SurfDesc.VidPnSourceId == pRt->pAlloc->SurfDesc.VidPnSourceId
2019 && (pBbRc == pRtRc
2020 || (pBbRc->fFlags == pRtRc->fFlags
2021 && pBbRc->RcDesc.enmPool == pRtRc->RcDesc.enmPool
2022// && pBbRc->RcDesc.fFlags.Value == pRtRc->RcDesc.fFlags.Value
2023 )
2024 ))
2025 {
2026 vboxWddmSwapchainBbAddTail(pCur, pBbAlloc, TRUE);
2027 pSwapchain = pCur;
2028 break;
2029 }
2030 }
2031 if (RTListNodeIsLast(&pDevice->SwapchainList, &pCur->ListEntry))
2032 break;
2033 pCur = RTListNodeGetNext(&pCur->ListEntry, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
2034 }
2035
2036// if (!pSwapchain) need to create a new one (see below)
2037 }
2038
2039 if (!pSwapchain)
2040 {
2041 pSwapchain = vboxWddmSwapchainAlloc(pDevice);
2042 Assert(pSwapchain);
2043 if (pSwapchain)
2044 {
2045 vboxWddmSwapchainBbAddTail(pSwapchain, pBbAlloc, FALSE);
2046 }
2047 }
2048
2049 return pSwapchain;
2050}
2051
2052static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainCreateForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc)
2053{
2054 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainAlloc(pDevice);
2055 Assert(pSwapchain);
2056 if (pSwapchain)
2057 {
2058 for (UINT i = 0; i < pRc->cAllocations; ++i)
2059 {
2060 vboxWddmSwapchainBbAddTail(pSwapchain, &pRc->aAllocations[i], FALSE);
2061 }
2062 return pSwapchain;
2063 }
2064 return NULL;
2065}
2066
2067DECLINLINE(UINT) vboxWddmSwapchainIdxBb2Rt(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb)
2068{
2069 return iBb != (~0) ? (iBb + pSwapchain->iBB) % pSwapchain->cRTs : vboxWddmSwapchainIdxFb(pSwapchain);
2070}
2071
2072static HRESULT vboxWddmSwapchainRtSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb)
2073{
2074 IDirect3DSurface9 *pD3D9Surf;
2075#ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
2076 if (pSwapchain->cRTs == 1)
2077 {
2078 iBb = 0;
2079 }
2080#endif
2081 UINT iRt = vboxWddmSwapchainIdxBb2Rt(pSwapchain, iBb);
2082 Assert(iRt < pSwapchain->cRTs);
2083 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[iRt];
2084 HRESULT hr = pSwapchain->pSwapChainIf->GetBackBuffer(iBb, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
2085 Assert(hr == S_OK);
2086 if (hr == S_OK)
2087 {
2088 PVBOXWDDMDISP_ALLOCATION pAlloc = pRt->pAlloc;
2089 Assert(pD3D9Surf);
2090 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
2091 if (pAlloc->pD3DIf)
2092 {
2093 if (pSwapchain->fFlags.bChanged)
2094 {
2095 IDirect3DSurface9 *pD3D9OldSurf = (IDirect3DSurface9*)pAlloc->pD3DIf;
2096 if (pD3D9OldSurf && pD3D9OldSurf != pD3D9Surf)
2097 {
2098 VOID *pvSwapchain = NULL;
2099 HRESULT tmpHr = pD3D9OldSurf->GetContainer(IID_IDirect3DSwapChain9, &pvSwapchain);
2100 if (tmpHr == S_OK)
2101 {
2102 Assert(pvSwapchain);
2103 ((IDirect3DSwapChain9 *)pvSwapchain)->Release();
2104 }
2105 else
2106 {
2107 Assert(!pvSwapchain);
2108 }
2109 if (pvSwapchain != pSwapchain->pSwapChainIf)
2110 {
2111 Assert(iBb != (~0));
2112// Assert(0);
2113#if 0 //def DEBUG_misha
2114 vboxVDbgDumpAllocSurfData((pDevice, "Synch Src:\n", pAlloc, pD3D9OldSurf, NULL, "\n"));
2115 vboxVDbgDumpAllocData((pDevice, "Synch ALLOC:\n", pAlloc, NULL, "\n"));
2116#endif
2117 hr = pDevice->pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9Surf, NULL, D3DTEXF_NONE);
2118 Assert(hr == S_OK);
2119#if 0 //def DEBUG_misha
2120 vboxVDbgDumpAllocSurfData((pDevice, "Synch Dst:\n", pAlloc, pD3D9Surf, NULL, "\n"));
2121#endif
2122 if (pSwapchain->cRTs == 1)
2123 {
2124 /* synch bb and fb */
2125 hr = pSwapchain->pSwapChainIf->Present(NULL, NULL, NULL, NULL, 0);
2126 Assert(hr == S_OK);
2127 if (hr == S_OK)
2128 {
2129 pD3D9Surf->Release();
2130 hr = pSwapchain->pSwapChainIf->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
2131 Assert(hr == S_OK);
2132 if (hr == S_OK)
2133 {
2134 hr = pDevice->pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9Surf, NULL, D3DTEXF_NONE);
2135 Assert(hr == S_OK);
2136 }
2137 }
2138 }
2139 }
2140 }
2141 }
2142 pAlloc->pD3DIf->Release();
2143 }
2144 pAlloc->pD3DIf = pD3D9Surf;
2145 pRt->fFlags.Value = 0;
2146
2147 if (pSwapchain->fFlags.bChanged)
2148 {
2149 for (UINT i = 0; i < pDevice->cRTs; ++i)
2150 {
2151 if (pDevice->apRTs[i] == pAlloc)
2152 {
2153 hr = vboxWddmRenderTargetSet(pDevice, i, pAlloc, TRUE);
2154 Assert(hr == S_OK);
2155 }
2156 }
2157 }
2158 }
2159 return hr;
2160}
2161
2162static HRESULT vboxWddmSwapchainSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
2163{
2164 HRESULT hr = S_OK;
2165 for (int iBb = -1; iBb < int(pSwapchain->cRTs - 1); ++iBb)
2166 {
2167 hr = vboxWddmSwapchainRtSynch(pDevice, pSwapchain, (UINT)iBb);
2168 Assert(hr == S_OK);
2169 }
2170 if (pSwapchain->fFlags.bChanged)
2171 {
2172 hr = vboxWddmSwapchainKmSynch(pDevice, pSwapchain);
2173 if (hr == S_OK)
2174 {
2175 pSwapchain->fFlags.bChanged = 0;
2176 }
2177 }
2178 return hr;
2179}
2180
2181static VOID vboxWddmSwapchainFillParams(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, D3DPRESENT_PARAMETERS *pParams)
2182{
2183 Assert(pSwapchain->cRTs);
2184 Assert(pSwapchain->cRTs <= 2);
2185 memset(pParams, 0, sizeof (D3DPRESENT_PARAMETERS));
2186 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pSwapchain);
2187 PVBOXWDDMDISP_RESOURCE pRc = pRt->pAlloc->pRc;
2188 pParams->BackBufferWidth = pRt->pAlloc->SurfDesc.width;
2189 pParams->BackBufferHeight = pRt->pAlloc->SurfDesc.height;
2190 pParams->BackBufferFormat = vboxDDI2D3DFormat(pRt->pAlloc->SurfDesc.format);
2191 pParams->BackBufferCount = pSwapchain->cRTs - 1;
2192 pParams->MultiSampleType = vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType);
2193 pParams->MultiSampleQuality = pRc->RcDesc.MultisampleQuality;
2194#ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
2195 if (pSwapchain->cRTs == 1)
2196 pParams->SwapEffect = D3DSWAPEFFECT_COPY;
2197 else
2198#endif
2199 if (pRc->RcDesc.fFlags.DiscardRenderTarget)
2200 pParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
2201}
2202
2203static HRESULT vboxWddmSwapchainChkCreateIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
2204{
2205 if (!pSwapchain->fFlags.bChanged && pSwapchain->pSwapChainIf)
2206 return S_OK;
2207 /* preserve the old one */
2208 IDirect3DSwapChain9 * pOldIf = pSwapchain->pSwapChainIf;
2209 HRESULT hr = S_OK;
2210 BOOL bReuseSwapchain = FALSE;
2211 D3DPRESENT_PARAMETERS Params;
2212 D3DPRESENT_PARAMETERS OldParams;
2213 vboxWddmSwapchainFillParams(pSwapchain, &Params);
2214 /* check if we need to re-create the swapchain */
2215 if (pOldIf)
2216 {
2217 hr = pOldIf->GetPresentParameters(&OldParams);
2218 Assert(hr == S_OK);
2219 if (hr == S_OK)
2220 {
2221 if (OldParams.BackBufferCount == Params.BackBufferCount
2222// && OldParams.SwapEffect == Params.SwapEffect
2223 )
2224 {
2225 bReuseSwapchain = TRUE;
2226 }
2227 }
2228 }
2229
2230 /* first create the new one */
2231 IDirect3DSwapChain9 * pNewIf;
2232 ///
2233 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
2234 UINT cSurfs = pSwapchain->cRTs;
2235 IDirect3DDevice9 *pDevice9If = NULL;
2236 HWND hOldWnd = pSwapchain->hWnd;
2237 if (!bReuseSwapchain)
2238 {
2239//#define VBOXDISP_NEWWND_ON_SWAPCHAINUPDATE
2240#ifndef VBOXDISP_NEWWND_ON_SWAPCHAINUPDATE
2241 if (!hOldWnd)
2242#endif
2243 {
2244 hr = VBoxDispWndCreate(pAdapter, Params.BackBufferWidth, Params.BackBufferHeight, &pSwapchain->hWnd);
2245 Assert(hr == S_OK);
2246 }
2247 if (hr == S_OK)
2248 {
2249 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
2250 if (pDevice->fFlags.AllowMultithreading)
2251 fFlags |= D3DCREATE_MULTITHREADED;
2252
2253 Params.hDeviceWindow = pSwapchain->hWnd;
2254 /* @todo: it seems there should be a way to detect this correctly since
2255 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
2256 Params.Windowed = TRUE;
2257 // params.EnableAutoDepthStencil = FALSE;
2258 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
2259 // params.Flags;
2260 // params.FullScreen_RefreshRateInHz;
2261 // params.FullScreen_PresentationInterval;
2262 if (!pDevice->pDevice9If)
2263 {
2264 hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pSwapchain->hWnd, fFlags, &Params, &pDevice9If);
2265 Assert(hr == S_OK);
2266 if (hr == S_OK)
2267 {
2268 pDevice->pDevice9If = pDevice9If;
2269 hr = pDevice9If->GetSwapChain(0, &pNewIf);
2270 Assert(hr == S_OK);
2271 if (hr == S_OK)
2272 {
2273 Assert(pNewIf);
2274 }
2275 else
2276 {
2277 pDevice9If->Release();
2278 }
2279 }
2280 }
2281 else
2282 {
2283 pDevice9If = pDevice->pDevice9If;
2284 if (pOldIf)
2285 {
2286 Assert(0);
2287 /* copy current rt data to offscreen render targets */
2288 IDirect3DSurface9* pD3D9OldFb = NULL;
2289 HRESULT tmpHr = pOldIf->GetBackBuffer(~0, D3DBACKBUFFER_TYPE_MONO, &pD3D9OldFb);
2290 Assert(tmpHr == S_OK);
2291 if (tmpHr == S_OK)
2292 {
2293 /* just need a pointer to match */
2294 pD3D9OldFb->Release();
2295 }
2296 UINT cOldRts = OldParams.SwapEffect == D3DSWAPEFFECT_COPY ? 1 : OldParams.BackBufferCount + 1;
2297 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
2298 {
2299 PVBOXWDDMDISP_RENDERTGT pRT = &pSwapchain->aRTs[i];
2300 if (!pRT->pAlloc->pD3DIf)
2301 continue;
2302 IDirect3DSurface9* pD3D9OldSurf = (IDirect3DSurface9*)pRT->pAlloc->pD3DIf;
2303 VOID *pvSwapchain = NULL;
2304 tmpHr = pD3D9OldSurf->GetContainer(IID_IDirect3DSwapChain9, &pvSwapchain);
2305 if (tmpHr == S_OK)
2306 {
2307 Assert(pvSwapchain);
2308 ((IDirect3DSwapChain9 *)pvSwapchain)->Release();
2309 }
2310 else
2311 {
2312 Assert(!pvSwapchain);
2313 }
2314 if (pvSwapchain != pOldIf)
2315 continue;
2316
2317 IDirect3DSurface9* pD3D9NewSurf;
2318 tmpHr = pDevice9If->CreateRenderTarget(
2319 Params.BackBufferWidth, Params.BackBufferHeight,
2320 Params.BackBufferFormat,
2321 Params.MultiSampleType,
2322 Params.MultiSampleQuality,
2323 TRUE, /*bLockable*/
2324 &pD3D9NewSurf,
2325 NULL /* HANDLE* pSharedHandle */
2326 );
2327 Assert(tmpHr == S_OK);
2328 if (tmpHr != S_OK)
2329 continue;
2330
2331 if (pD3D9OldSurf != pD3D9OldFb && cOldRts != 1)
2332 {
2333 tmpHr = pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9NewSurf, NULL, D3DTEXF_NONE);
2334 Assert(tmpHr == S_OK);
2335 }
2336 else
2337 {
2338 tmpHr = pOldIf->GetFrontBufferData(pD3D9NewSurf);
2339 Assert(tmpHr == S_OK);
2340 }
2341
2342 if (tmpHr != S_OK)
2343 continue;
2344
2345 pRT->pAlloc->pD3DIf = pD3D9NewSurf;
2346 pD3D9OldSurf->Release();
2347 }
2348 }
2349
2350 hr = pDevice->pDevice9If->CreateAdditionalSwapChain(&Params, &pNewIf);
2351 Assert(hr == S_OK);
2352 if (hr == S_OK)
2353 {
2354 Assert(pNewIf);
2355 }
2356 }
2357 }
2358 }
2359 else
2360 {
2361 Assert(pOldIf);
2362 Assert(hOldWnd);
2363 pNewIf = pOldIf;
2364 /* to ensure the swapchain is not deleted once we release the pOldIf */
2365 pNewIf->AddRef();
2366 }
2367
2368 if (hr == S_OK)
2369 {
2370 Assert(pNewIf);
2371 pSwapchain->pSwapChainIf = pNewIf;
2372#ifndef VBOXWDDM_WITH_VISIBLE_FB
2373 pSwapchain->bRTFbCopyUpToDate = FALSE;
2374 if (!pSwapchain->pRenderTargetFbCopy)
2375 {
2376 IDirect3DSurface9* pD3D9Surf;
2377 hr = pDevice9If->CreateRenderTarget(
2378 Params.BackBufferWidth, Params.BackBufferHeight,
2379 Params.BackBufferFormat,
2380 Params.MultiSampleType,
2381 Params.MultiSampleQuality,
2382 TRUE, /*bLockable*/
2383 &pD3D9Surf,
2384 NULL /* HANDLE* pSharedHandle */
2385 );
2386 Assert(hr == S_OK);
2387 if (hr == S_OK)
2388 {
2389 Assert(pD3D9Surf);
2390 pSwapchain->pRenderTargetFbCopy = pD3D9Surf;
2391 }
2392 }
2393#endif
2394
2395 if (hr == S_OK)
2396 {
2397 for (UINT i = 0; i < cSurfs; ++i)
2398 {
2399 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[i];
2400 pRt->pAlloc->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2401 }
2402
2403 hr = vboxWddmSwapchainSynch(pDevice, pSwapchain);
2404 Assert(hr == S_OK);
2405 if (hr == S_OK)
2406 {
2407 for (UINT i = 0; i < cSurfs; ++i)
2408 {
2409 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[i];
2410 hr = vboxWddmSurfSynchMem(pRt->pAlloc->pRc, pRt->pAlloc);
2411 Assert(hr == S_OK);
2412 if (hr != S_OK)
2413 {
2414 break;
2415 }
2416 }
2417
2418 Assert(hr == S_OK);
2419 if (hr == S_OK)
2420 {
2421 Assert(pSwapchain->fFlags.Value == 0);
2422 if (pOldIf)
2423 {
2424 Assert(hOldWnd);
2425 pOldIf->Release();
2426 if (hOldWnd != pSwapchain->hWnd)
2427 {
2428 VBoxDispWndDestroy(pAdapter, hOldWnd);
2429 }
2430 }
2431 else
2432 {
2433 Assert(!hOldWnd);
2434 }
2435 return S_OK;
2436 }
2437 }
2438 pNewIf->Release();
2439 pSwapchain->pSwapChainIf = pOldIf;
2440 }
2441
2442 Assert(hr != S_OK);
2443 if (hOldWnd != pSwapchain->hWnd)
2444 {
2445 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pSwapchain->hWnd);
2446 Assert(tmpHr == S_OK);
2447 pSwapchain->hWnd = hOldWnd;
2448 }
2449 }
2450
2451 return hr;
2452}
2453
2454static HRESULT vboxWddmSwapchainCreateIfForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, PVBOXWDDMDISP_SWAPCHAIN *ppSwapchain)
2455{
2456 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainCreateForRc(pDevice, pRc);
2457 Assert(pSwapchain);
2458 *ppSwapchain = NULL;
2459 if (pSwapchain)
2460 {
2461 HRESULT hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
2462 Assert(hr == S_OK);
2463 if (hr == S_OK)
2464 {
2465 *ppSwapchain = pSwapchain;
2466 }
2467 return hr;
2468 }
2469 return E_OUTOFMEMORY;
2470}
2471
2472static HRESULT vboxWddmSwapchainPresentPerform(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
2473{
2474 HRESULT hr = pSwapchain->pSwapChainIf->Present(NULL, NULL, NULL, NULL, 0);
2475 Assert(hr == S_OK);
2476 if (hr == S_OK)
2477 {
2478 pSwapchain->bRTFbCopyUpToDate = FALSE;
2479 vboxWddmSwapchainFlip(pSwapchain);
2480 Assert(pSwapchain->fFlags.Value == 0);
2481 hr = vboxWddmSwapchainSynch(pDevice, pSwapchain);
2482 Assert(hr == S_OK);
2483 }
2484 return hr;
2485}
2486
2487static HRESULT vboxWddmSwapchainPresent(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc)
2488{
2489 BOOL bChanged = FALSE;
2490 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainFindCreate(pDevice, pBbAlloc);
2491 Assert(pSwapchain);
2492 if (pSwapchain)
2493 {
2494 HRESULT hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
2495 Assert(hr == S_OK);
2496 if (hr == S_OK)
2497 {
2498 hr = vboxWddmSwapchainPresentPerform(pDevice, pSwapchain);
2499 Assert(hr == S_OK);
2500 }
2501 return hr;
2502 }
2503 return E_OUTOFMEMORY;
2504}
2505
2506#if 0 //def DEBUG
2507static void vboxWddmDbgRenderTargetUpdateCheckSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf)
2508{
2509 IDirect3DSurface9 *pD3D9Surf;
2510 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
2511 IDirect3DDevice9 * pDevice9If = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
2512 HRESULT hr = pDevice9If->GetBackBuffer(0 /*UINT iSwapChain*/,
2513 iBBuf, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
2514 Assert(hr == S_OK);
2515 if (hr == S_OK)
2516 {
2517 Assert(pD3D9Surf);
2518 Assert(pD3D9Surf == pAlloc->pD3DIf);
2519 pD3D9Surf->Release();
2520 }
2521}
2522
2523static void vboxWddmDbgRenderTargetCheck(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB)
2524{
2525 PVBOXWDDMDISP_ALLOCATION pAlloc;
2526 UINT iBBuf = 0;
2527 Assert(iNewRTFB < pRc->cAllocations);
2528
2529 for (UINT i = 1; i < pRc->cAllocations; ++i, ++iBBuf)
2530 {
2531 UINT iAlloc = (iNewRTFB + i) % pRc->cAllocations;
2532 Assert(iAlloc != iNewRTFB);
2533 pAlloc = &pRc->aAllocations[iAlloc];
2534 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, iBBuf);
2535 }
2536
2537 pAlloc = &pRc->aAllocations[iNewRTFB];
2538#ifdef VBOXWDDM_WITH_VISIBLE_FB
2539 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, ~0UL /* <- for the frontbuffer */);
2540#else
2541 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));
2542#endif
2543
2544 for (UINT i = 0; i < pRc->cAllocations; ++i)
2545 {
2546 pAlloc = &pRc->aAllocations[i];
2547 if (iNewRTFB == i)
2548 {
2549 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));
2550 }
2551
2552 for (UINT j = i+1; j < pRc->cAllocations; ++j)
2553 {
2554 PVBOXWDDMDISP_ALLOCATION pAllocJ = &pRc->aAllocations[j];
2555 Assert(pAlloc->pD3DIf != pAllocJ->pD3DIf);
2556 }
2557 }
2558}
2559
2560# define VBOXVDBG_RTGT_STATECHECK(_pDev) (vboxWddmDbgRenderTargetCheck((_pDev), (_pDev)->aScreens[(_pDev)->iPrimaryScreen].pRenderTargetRc, (_pDev)->aScreens[(_pDev)->iPrimaryScreen].iRenderTargetFrontBuf))
2561#else
2562# define VBOXVDBG_RTGT_STATECHECK(_pDev) do{}while(0)
2563#endif
2564
2565#if 0
2566static HRESULT vboxWddmD3DDeviceCreate(PVBOXWDDMDISP_DEVICE pDevice, UINT iScreen, PVBOXWDDMDISP_RESOURCE pRc, D3DPRESENT_PARAMETERS * pParams, BOOL bLockable)
2567{
2568 UINT cSurfs = pParams->BackBufferCount + 1;
2569 Assert(pRc->cAllocations = cSurfs);
2570 IDirect3DDevice9 *pPrimaryDevice = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
2571 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[iScreen];
2572 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
2573 HRESULT hr;
2574 HWND hWnd = NULL;
2575 Assert(!pScreen->pDevice9If);
2576 Assert(!pScreen->hWnd);
2577 hr = VBoxDispWndCreate(pAdapter, pParams->BackBufferWidth, pParams->BackBufferHeight, &hWnd);
2578 Assert(hr == S_OK);
2579 if (hr == S_OK)
2580 {
2581 pScreen->hWnd = hWnd;
2582
2583 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
2584 if (pDevice->fFlags.AllowMultithreading)
2585 fFlags |= D3DCREATE_MULTITHREADED;
2586
2587 IDirect3DDevice9 *pDevice9If = NULL;
2588 pParams->hDeviceWindow = hWnd;
2589 /* @todo: it seems there should be a way to detect this correctly since
2590 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
2591 pParams->Windowed = TRUE;
2592 // params.EnableAutoDepthStencil = FALSE;
2593 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
2594 // params.Flags;
2595 // params.FullScreen_RefreshRateInHz;
2596 // params.FullScreen_PresentationInterval;
2597 hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, fFlags, pParams, &pDevice9If);
2598 Assert(hr == S_OK);
2599 if (hr == S_OK)
2600 {
2601 pScreen->pDevice9If = pDevice9If;
2602 pScreen->pRenderTargetRc = pRc;
2603 ++pDevice->cScreens;
2604
2605 for (UINT i = 0; i < cSurfs; ++i)
2606 {
2607 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2608 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2609 }
2610
2611 if (pPrimaryDevice)
2612 {
2613 for (UINT i = 0; i < cSurfs; ++i)
2614 {
2615 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2616 IDirect3DSurface9 *pRt;
2617 IDirect3DSurface9 *pSecondaryOpenedRt;
2618 HANDLE hSharedHandle = NULL;
2619 hr = pPrimaryDevice->CreateRenderTarget(
2620 pParams->BackBufferWidth, pParams->BackBufferHeight,
2621 pParams->BackBufferFormat,
2622 pParams->MultiSampleType,
2623 pParams->MultiSampleQuality,
2624 TRUE, /*BOOL Lockable*/
2625 &pRt,
2626 &hSharedHandle);
2627 Assert(hr == S_OK);
2628 if (hr == S_OK)
2629 {
2630 Assert(hSharedHandle != NULL);
2631 /* open render target for primary device */
2632 hr = pDevice9If->CreateRenderTarget(
2633 pParams->BackBufferWidth, pParams->BackBufferHeight,
2634 pParams->BackBufferFormat,
2635 pParams->MultiSampleType,
2636 pParams->MultiSampleQuality,
2637 TRUE, /*BOOL Lockable*/
2638 &pSecondaryOpenedRt,
2639 &hSharedHandle);
2640 Assert(hr == S_OK);
2641 if (hr == S_OK)
2642 {
2643 pAllocation->pD3DIf = pRt;
2644 pAllocation->pSecondaryOpenedD3DIf = pSecondaryOpenedRt;
2645 pAllocation->hSharedHandle = hSharedHandle;
2646 continue;
2647 }
2648 pRt->Release();
2649 }
2650
2651 for (UINT j = 0; j < i; ++j)
2652 {
2653 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[j];
2654 pAlloc->pD3DIf->Release();
2655 pAlloc->pSecondaryOpenedD3DIf->Release();
2656 }
2657
2658 break;
2659 }
2660 }
2661 else
2662 {
2663 pDevice->iPrimaryScreen = iScreen;
2664 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0);
2665 Assert(hr == S_OK);
2666 }
2667
2668 if (hr == S_OK)
2669 {
2670 for (UINT i = 0; i < cSurfs; ++i)
2671 {
2672 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2673 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2674 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
2675 Assert(hr == S_OK);
2676 if (hr != S_OK)
2677 {
2678 break;
2679 }
2680 }
2681
2682#ifndef VBOXWDDM_WITH_VISIBLE_FB
2683 if (!pPrimaryDevice)
2684 {
2685 if (hr == S_OK)
2686 {
2687 IDirect3DSurface9* pD3D9Surf;
2688 hr = pDevice9If->CreateRenderTarget(
2689 pParams->BackBufferWidth, pParams->BackBufferHeight,
2690 pParams->BackBufferFormat,
2691 pParams->MultiSampleType,
2692 pParams->MultiSampleQuality,
2693 bLockable,
2694 &pD3D9Surf,
2695 NULL /* HANDLE* pSharedHandle */
2696 );
2697 Assert(hr == S_OK);
2698 if (hr == S_OK)
2699 {
2700 pDevice->pRenderTargetFbCopy = pD3D9Surf;
2701 }
2702 }
2703 }
2704#endif
2705
2706 if (hr != S_OK)
2707 {
2708 for (UINT i = 0; i < cSurfs; ++i)
2709 {
2710 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2711 pAllocation->pD3DIf->Release();
2712 }
2713 }
2714 }
2715
2716 if (hr != S_OK)
2717 {
2718 pDevice9If->Release();
2719 --pDevice->cScreens;
2720 Assert(pDevice->cScreens < UINT32_MAX/2);
2721 }
2722 }
2723
2724 if (hr != S_OK)
2725 {
2726 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pScreen->hWnd);
2727 Assert(tmpHr == S_OK);
2728 }
2729 }
2730
2731 return hr;
2732}
2733#endif
2734static HRESULT vboxWddmD3DDeviceCreateDummy(PVBOXWDDMDISP_DEVICE pDevice)
2735{
2736 HRESULT hr;
2737 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);
2738 Assert(pRc);
2739 if (pRc)
2740 {
2741 pRc->RcDesc.enmFormat = D3DDDIFMT_A8R8G8B8;
2742 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
2743 pRc->RcDesc.MultisampleQuality = 0;
2744 for (UINT i = 0 ; i < pRc->cAllocations; ++i)
2745 {
2746 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
2747 pAlloc->SurfDesc.width = 0x4;
2748 pAlloc->SurfDesc.height = 0x4;
2749 pAlloc->SurfDesc.format = D3DDDIFMT_A8R8G8B8;
2750 }
2751
2752 PVBOXWDDMDISP_SWAPCHAIN pSwapchain;
2753 hr = vboxWddmSwapchainCreateIfForRc(pDevice, pRc, &pSwapchain);
2754 Assert(hr == S_OK);
2755 if (hr != S_OK)
2756 vboxResourceFree(pRc);
2757 }
2758 else
2759 {
2760 hr = E_OUTOFMEMORY;
2761 }
2762
2763 return hr;
2764}
2765
2766DECLINLINE(IDirect3DDevice9*) vboxWddmD3DDeviceGet(PVBOXWDDMDISP_DEVICE pDevice)
2767{
2768 if (pDevice->pDevice9If)
2769 return pDevice->pDevice9If;
2770 HRESULT hr = vboxWddmD3DDeviceCreateDummy(pDevice);
2771 Assert(hr == S_OK);
2772 Assert(pDevice->pDevice9If);
2773 return pDevice->pDevice9If;
2774}
2775
2776#if 0
2777static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource);
2778
2779static HRESULT vboxWddmD3DDeviceUpdate(PVBOXWDDMDISP_DEVICE pDevice, UINT iScreen, PVBOXWDDMDISP_RESOURCE pRc, D3DPRESENT_PARAMETERS * pParams, BOOL bLockable)
2780{
2781 UINT cSurfs = pParams->BackBufferCount + 1;
2782 Assert(pRc->cAllocations = cSurfs);
2783 Assert(iScreen == pDevice->iPrimaryScreen);
2784 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[iScreen];
2785 PVBOXWDDMDISP_RESOURCE pCurRc = pScreen->pRenderTargetRc;
2786 IDirect3DDevice9Ex *pNewDevice;
2787 HRESULT hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Update((IDirect3DDevice9Ex*)pScreen->pDevice9If, pParams, &pNewDevice);
2788 Assert(hr == S_OK);
2789 if (hr == S_OK)
2790 {
2791 pScreen->pDevice9If->Release();
2792 pScreen->pDevice9If = pNewDevice;
2793 pScreen->pRenderTargetRc = pRc;
2794
2795 for (UINT i = 0; i < cSurfs; ++i)
2796 {
2797 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2798 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2799 }
2800
2801#ifndef VBOXWDDM_WITH_VISIBLE_FB
2802 if (pDevice->pRenderTargetFbCopy)
2803 {
2804 pDevice->pRenderTargetFbCopy->Release();
2805 }
2806 IDirect3DSurface9* pD3D9Surf;
2807 hr = pNewDevice->CreateRenderTarget(
2808 pParams->BackBufferWidth, pParams->BackBufferHeight,
2809 pParams->BackBufferFormat,
2810 pParams->MultiSampleType,
2811 pParams->MultiSampleQuality,
2812 bLockable,
2813 &pD3D9Surf,
2814 NULL /* HANDLE* pSharedHandle */
2815 );
2816 Assert(hr == S_OK);
2817 if (hr == S_OK)
2818 {
2819 pDevice->pRenderTargetFbCopy = pD3D9Surf;
2820 }
2821#endif
2822 if (hr == S_OK)
2823 {
2824 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0);
2825 Assert(hr == S_OK);
2826 if (hr == S_OK)
2827 {
2828 for (UINT i = 0; i < cSurfs; ++i)
2829 {
2830 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2831 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2832 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
2833 Assert(hr == S_OK);
2834 if (hr != S_OK)
2835 {
2836 break;
2837 }
2838 }
2839 }
2840 }
2841 }
2842
2843
2844 if (!pCurRc->hResource)
2845 {
2846 HRESULT tmpHr = vboxWddmDDevDestroyResource(pDevice, pCurRc);
2847 Assert(tmpHr == S_OK);
2848 }
2849
2850 return hr;
2851}
2852#endif
2853/******/
2854
2855static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch)
2856{
2857 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2858 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
2859 if (pSwapchain)
2860 {
2861 /* backbuffer */
2862 Assert(vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc);
2863 }
2864
2865 HRESULT hr = S_OK;
2866 IDirect3DSurface9 *pD3D9Surf;
2867 if (!bOnSwapchainSynch && pSwapchain)
2868 {
2869 /* work-around wine double-buffering for the case we have no backbuffers */
2870 Assert(!pSwapchain->fFlags.bChanged);
2871 Assert(pSwapchain->pSwapChainIf);
2872 vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
2873 }
2874
2875#ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
2876 if (pSwapchain && vboxWddmSwapchainNumRTs(pSwapchain) == 1 && iRt == 0)
2877 {
2878 hr = pSwapchain->pSwapChainIf->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
2879 Assert(hr == S_OK);
2880 Assert(pD3D9Surf);
2881 }
2882 else
2883#endif
2884 {
2885 hr = vboxWddmSurfGet(pAlloc->pRc, pAlloc->iAlloc, &pD3D9Surf);
2886 Assert(hr == S_OK);
2887 Assert(pD3D9Surf);
2888 }
2889
2890 if (hr == S_OK)
2891 {
2892 Assert(pD3D9Surf);
2893 hr = pDevice9If->SetRenderTarget(iRt, pD3D9Surf);
2894 Assert(hr == S_OK);
2895 if (hr == S_OK)
2896 {
2897 Assert(iRt < pDevice->cRTs);
2898 pDevice->apRTs[iRt] = pAlloc;
2899 }
2900 pD3D9Surf->Release();
2901 }
2902
2903 return hr;
2904}
2905
2906/**
2907 * DLL entry point.
2908 */
2909BOOL WINAPI DllMain(HINSTANCE hInstance,
2910 DWORD dwReason,
2911 LPVOID lpReserved)
2912{
2913 switch (dwReason)
2914 {
2915 case DLL_PROCESS_ATTACH:
2916 {
2917 vboxDispLockInit();
2918
2919 vboxVDbgPrint(("VBoxDispD3D: DLL loaded.\n"));
2920#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
2921 vboxVDbgVEHandlerRegister();
2922#endif
2923 RTR3Init();
2924
2925 HRESULT hr = vboxDispCmInit();
2926 Assert(hr == S_OK);
2927 if (hr == S_OK)
2928 {
2929#ifdef VBOXDISPMP_TEST
2930 hr = vboxDispMpTstStart();
2931 Assert(hr == S_OK);
2932 if (hr == S_OK)
2933#endif
2934 {
2935// hr = VBoxScreenMRunnerStart(&g_VBoxScreenMonRunner);
2936// Assert(hr == S_OK);
2937 /* succeed in any way */
2938 hr = S_OK;
2939 if (hr == S_OK)
2940 {
2941 vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n"));
2942 return TRUE;
2943 }
2944#ifdef VBOXDISPMP_TEST
2945 vboxDispMpTstStop();
2946#endif
2947 }
2948 vboxDispCmTerm();
2949 }
2950// VbglR3Init();
2951 break;
2952 }
2953
2954 case DLL_PROCESS_DETACH:
2955 {
2956#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
2957 vboxVDbgVEHandlerUnregister();
2958#endif
2959 HRESULT hr = S_OK;
2960// hr = VBoxScreenMRunnerStop(&g_VBoxScreenMonRunner);
2961// Assert(hr == S_OK);
2962// if (hr == S_OK)
2963 {
2964#ifdef VBOXDISPMP_TEST
2965 hr = vboxDispMpTstStop();
2966 Assert(hr == S_OK);
2967 if (hr == S_OK)
2968#endif
2969 {
2970 hr = vboxDispCmTerm();
2971 Assert(hr == S_OK);
2972 if (hr == S_OK)
2973 {
2974 vboxVDbgPrint(("VBoxDispD3D: DLL unloaded.\n"));
2975 return TRUE;
2976 }
2977 }
2978 }
2979// VbglR3Term();
2980 /// @todo RTR3Term();
2981 break;
2982 }
2983
2984 default:
2985 return TRUE;
2986 }
2987 return FALSE;
2988}
2989
2990static HRESULT vboxWddmGetD3D9Caps(PVBOXWDDMDISP_ADAPTER pAdapter, D3DCAPS9 *pCaps)
2991{
2992 HRESULT hr = pAdapter->pD3D9If->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pCaps);
2993 Assert(hr == S_OK);
2994 if (hr == S_OK)
2995 {
2996 pCaps->Caps2 |= D3DCAPS2_CANSHARERESOURCE | 0x00080000 /*D3DCAPS2_CANRENDERWINDOWED*/;
2997 pCaps->DevCaps |= D3DDEVCAPS_FLOATTLVERTEX /* <- must be set according to the docs */
2998 /*| D3DDEVCAPS_HWVERTEXBUFFER | D3DDEVCAPS_HWINDEXBUFFER | D3DDEVCAPS_SUBVOLUMELOCK */;
2999 pCaps->PrimitiveMiscCaps |= D3DPMISCCAPS_INDEPENDENTWRITEMASKS
3000 | D3DPMISCCAPS_FOGINFVF
3001 | D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS;
3002 pCaps->RasterCaps |= D3DPRASTERCAPS_SUBPIXEL | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_COLORPERSPECTIVE /* keep */;
3003 pCaps->TextureCaps |= D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE;
3004 pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
3005 pCaps->VolumeTextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
3006 pCaps->GuardBandLeft = -8192.;
3007 pCaps->GuardBandTop = -8192.;
3008 pCaps->GuardBandRight = 8192.;
3009 pCaps->GuardBandBottom = 8192.;
3010 pCaps->StencilCaps |= D3DSTENCILCAPS_TWOSIDED;
3011 pCaps->DeclTypes |= D3DDTCAPS_FLOAT16_2 | D3DDTCAPS_FLOAT16_4;
3012 pCaps->VS20Caps.DynamicFlowControlDepth = 24;
3013 pCaps->VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
3014 pCaps->PS20Caps.DynamicFlowControlDepth = 24;
3015 pCaps->PS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
3016 pCaps->VertexTextureFilterCaps |= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MAGFPOINT;
3017#if 1 /* workaround for wine not returning InstructionSlots correctly for shaders v3.0 */
3018 if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
3019 {
3020 pCaps->MaxVertexShader30InstructionSlots = RT_MIN(32768, pCaps->MaxVertexShader30InstructionSlots);
3021 pCaps->MaxPixelShader30InstructionSlots = RT_MIN(32768, pCaps->MaxPixelShader30InstructionSlots);
3022 }
3023#endif
3024#ifdef DEBUG
3025 if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
3026 {
3027 Assert(pCaps->MaxVertexShader30InstructionSlots >= 512);
3028 Assert(pCaps->MaxVertexShader30InstructionSlots <= 32768);
3029 Assert(pCaps->MaxPixelShader30InstructionSlots >= 512);
3030 Assert(pCaps->MaxPixelShader30InstructionSlots <= 32768);
3031 }
3032 else if ((pCaps->VertexShaderVersion & 0xff00) == 0x0200)
3033 {
3034 Assert(pCaps->MaxVertexShader30InstructionSlots == 0);
3035 Assert(pCaps->MaxPixelShader30InstructionSlots == 0);
3036 }
3037 else
3038 {
3039 Assert(0);
3040 }
3041#endif
3042 }
3043
3044 return hr;
3045}
3046
3047static HRESULT APIENTRY vboxWddmDispGetCaps (HANDLE hAdapter, CONST D3DDDIARG_GETCAPS* pData)
3048{
3049 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
3050
3051 VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL();
3052
3053 HRESULT hr = S_OK;
3054 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
3055
3056 switch (pData->Type)
3057 {
3058 case D3DDDICAPS_DDRAW:
3059 {
3060 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
3061 Assert(pData->DataSize == sizeof (DDRAW_CAPS));
3062 if (pData->DataSize >= sizeof (DDRAW_CAPS))
3063 {
3064 memset(pData->pData, 0, sizeof (DDRAW_CAPS));
3065#ifdef VBOX_WITH_VIDEOHWACCEL
3066 if (vboxVhwaHasCKeying(pAdapter))
3067 {
3068 DDRAW_CAPS *pCaps = (DDRAW_CAPS*)pData->pData;
3069 pCaps->Caps |= DDRAW_CAPS_COLORKEY;
3070// pCaps->Caps2 |= DDRAW_CAPS2_FLIPNOVSYNC;
3071 }
3072#endif
3073 }
3074 else
3075 hr = E_INVALIDARG;
3076 break;
3077 }
3078 case D3DDDICAPS_DDRAW_MODE_SPECIFIC:
3079 {
3080 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
3081 Assert(pData->DataSize == sizeof (DDRAW_MODE_SPECIFIC_CAPS));
3082 if (pData->DataSize >= sizeof (DDRAW_MODE_SPECIFIC_CAPS))
3083 {
3084 DDRAW_MODE_SPECIFIC_CAPS * pCaps = (DDRAW_MODE_SPECIFIC_CAPS*)pData->pData;
3085 memset(&pCaps->Caps /* do not cleanup the first "Head" field,
3086 zero starting with the one following "Head", i.e. Caps */,
3087 0, sizeof (DDRAW_MODE_SPECIFIC_CAPS) - RT_OFFSETOF(DDRAW_MODE_SPECIFIC_CAPS, Caps));
3088#ifdef VBOX_WITH_VIDEOHWACCEL
3089 VBOXVHWA_INFO *pSettings = &pAdapter->aHeads[pCaps->Head].Vhwa.Settings;
3090 if (pSettings->fFlags & VBOXVHWA_F_ENABLED)
3091 {
3092 pCaps->Caps |= MODE_CAPS_OVERLAY | MODE_CAPS_OVERLAYSTRETCH;
3093
3094 if (pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
3095 {
3096 pCaps->CKeyCaps |= MODE_CKEYCAPS_DESTOVERLAY
3097 | MODE_CKEYCAPS_DESTOVERLAYYUV /* ?? */
3098 ;
3099 }
3100
3101 if (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC)
3102 {
3103 pCaps->CKeyCaps |= MODE_CKEYCAPS_SRCOVERLAY
3104 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACE /* ?? */
3105 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACEYUV /* ?? */
3106 | MODE_CKEYCAPS_SRCOVERLAYYUV /* ?? */
3107 ;
3108 }
3109
3110 pCaps->FxCaps = MODE_FXCAPS_OVERLAYSHRINKX
3111 | MODE_FXCAPS_OVERLAYSHRINKY
3112 | MODE_FXCAPS_OVERLAYSTRETCHX
3113 | MODE_FXCAPS_OVERLAYSTRETCHY;
3114
3115
3116 pCaps->MaxVisibleOverlays = pSettings->cOverlaysSupported;
3117 pCaps->MinOverlayStretch = 1;
3118 pCaps->MaxOverlayStretch = 32000;
3119 }
3120#endif
3121 }
3122 else
3123 hr = E_INVALIDARG;
3124 break;
3125 }
3126 case D3DDDICAPS_GETFORMATCOUNT:
3127 *((uint32_t*)pData->pData) = pAdapter->cFormstOps;
3128 break;
3129 case D3DDDICAPS_GETFORMATDATA:
3130 Assert(pData->DataSize == pAdapter->cFormstOps * sizeof (FORMATOP));
3131 memcpy(pData->pData, pAdapter->paFormstOps, pAdapter->cFormstOps * sizeof (FORMATOP));
3132 break;
3133 case D3DDDICAPS_GETD3DQUERYCOUNT:
3134#if 1
3135 *((uint32_t*)pData->pData) = VBOX_QUERYTYPE_COUNT();
3136#else
3137 *((uint32_t*)pData->pData) = 0;
3138#endif
3139 break;
3140 case D3DDDICAPS_GETD3DQUERYDATA:
3141#if 1
3142 Assert(pData->DataSize == VBOX_QUERYTYPE_COUNT() * sizeof (D3DDDIQUERYTYPE));
3143 memcpy(pData->pData, gVBoxQueryTypes, VBOX_QUERYTYPE_COUNT() * sizeof (D3DDDIQUERYTYPE));
3144#else
3145 Assert(0);
3146 memset(pData->pData, 0, pData->DataSize);
3147#endif
3148 break;
3149 case D3DDDICAPS_GETD3D3CAPS:
3150 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
3151 Assert(pData->DataSize == sizeof (D3DHAL_GLOBALDRIVERDATA));
3152 if (pData->DataSize >= sizeof (D3DHAL_GLOBALDRIVERDATA))
3153 {
3154 D3DHAL_GLOBALDRIVERDATA *pCaps = (D3DHAL_GLOBALDRIVERDATA *)pData->pData;
3155 memset (pCaps, 0, sizeof (D3DHAL_GLOBALDRIVERDATA));
3156 pCaps->dwSize = sizeof (D3DHAL_GLOBALDRIVERDATA);
3157 pCaps->hwCaps.dwSize = sizeof (D3DDEVICEDESC_V1);
3158 pCaps->hwCaps.dwFlags = D3DDD_COLORMODEL
3159 | D3DDD_DEVCAPS
3160 | D3DDD_DEVICERENDERBITDEPTH;
3161
3162 pCaps->hwCaps.dcmColorModel = D3DCOLOR_RGB;
3163 pCaps->hwCaps.dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP
3164// | D3DDEVCAPS_DRAWPRIMTLVERTEX
3165 | D3DDEVCAPS_EXECUTESYSTEMMEMORY
3166 | D3DDEVCAPS_EXECUTEVIDEOMEMORY
3167// | D3DDEVCAPS_FLOATTLVERTEX
3168 | D3DDEVCAPS_HWRASTERIZATION
3169// | D3DDEVCAPS_HWTRANSFORMANDLIGHT
3170// | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY
3171// | D3DDEVCAPS_TEXTUREVIDEOMEMORY
3172 ;
3173 pCaps->hwCaps.dtcTransformCaps.dwSize = sizeof (D3DTRANSFORMCAPS);
3174 pCaps->hwCaps.dtcTransformCaps.dwCaps = 0;
3175 pCaps->hwCaps.bClipping = FALSE;
3176 pCaps->hwCaps.dlcLightingCaps.dwSize = sizeof (D3DLIGHTINGCAPS);
3177 pCaps->hwCaps.dlcLightingCaps.dwCaps = 0;
3178 pCaps->hwCaps.dlcLightingCaps.dwLightingModel = 0;
3179 pCaps->hwCaps.dlcLightingCaps.dwNumLights = 0;
3180 pCaps->hwCaps.dpcLineCaps.dwSize = sizeof (D3DPRIMCAPS);
3181 pCaps->hwCaps.dpcLineCaps.dwMiscCaps = 0;
3182 pCaps->hwCaps.dpcLineCaps.dwRasterCaps = 0;
3183 pCaps->hwCaps.dpcLineCaps.dwZCmpCaps = 0;
3184 pCaps->hwCaps.dpcLineCaps.dwSrcBlendCaps = 0;
3185 pCaps->hwCaps.dpcLineCaps.dwDestBlendCaps = 0;
3186 pCaps->hwCaps.dpcLineCaps.dwAlphaCmpCaps = 0;
3187 pCaps->hwCaps.dpcLineCaps.dwShadeCaps = 0;
3188 pCaps->hwCaps.dpcLineCaps.dwTextureCaps = 0;
3189 pCaps->hwCaps.dpcLineCaps.dwTextureFilterCaps = 0;
3190 pCaps->hwCaps.dpcLineCaps.dwTextureBlendCaps = 0;
3191 pCaps->hwCaps.dpcLineCaps.dwTextureAddressCaps = 0;
3192 pCaps->hwCaps.dpcLineCaps.dwStippleWidth = 0;
3193 pCaps->hwCaps.dpcLineCaps.dwStippleHeight = 0;
3194
3195 pCaps->hwCaps.dpcTriCaps.dwSize = sizeof (D3DPRIMCAPS);
3196 pCaps->hwCaps.dpcTriCaps.dwMiscCaps = 0;
3197 pCaps->hwCaps.dpcTriCaps.dwRasterCaps = 0;
3198 pCaps->hwCaps.dpcTriCaps.dwZCmpCaps = 0;
3199 pCaps->hwCaps.dpcTriCaps.dwSrcBlendCaps = 0;
3200 pCaps->hwCaps.dpcTriCaps.dwDestBlendCaps = 0;
3201 pCaps->hwCaps.dpcTriCaps.dwAlphaCmpCaps = 0;
3202 pCaps->hwCaps.dpcTriCaps.dwShadeCaps = 0;
3203 pCaps->hwCaps.dpcTriCaps.dwTextureCaps = 0;
3204 pCaps->hwCaps.dpcTriCaps.dwTextureFilterCaps = 0;
3205 pCaps->hwCaps.dpcTriCaps.dwTextureBlendCaps = 0;
3206 pCaps->hwCaps.dpcTriCaps.dwTextureAddressCaps = 0;
3207 pCaps->hwCaps.dpcTriCaps.dwStippleWidth = 0;
3208 pCaps->hwCaps.dpcTriCaps.dwStippleHeight = 0;
3209 pCaps->hwCaps.dwDeviceRenderBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32;
3210 pCaps->hwCaps.dwDeviceZBufferBitDepth = 0;
3211 pCaps->hwCaps.dwMaxBufferSize = 0;
3212 pCaps->hwCaps.dwMaxVertexCount = 0;
3213
3214
3215 pCaps->dwNumVertices = 0;
3216 pCaps->dwNumClipVertices = 0;
3217 pCaps->dwNumTextureFormats = 0;//pAdapter->cSurfDescs;
3218 pCaps->lpTextureFormats = NULL;//pAdapter->paSurfDescs;
3219 }
3220 else
3221 hr = E_INVALIDARG;
3222 break;
3223 case D3DDDICAPS_GETD3D7CAPS:
3224 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
3225 Assert(pData->DataSize == sizeof (D3DHAL_D3DEXTENDEDCAPS));
3226 if (pData->DataSize >= sizeof (D3DHAL_D3DEXTENDEDCAPS))
3227 {
3228 memset(pData->pData, 0, sizeof (D3DHAL_D3DEXTENDEDCAPS));
3229 D3DHAL_D3DEXTENDEDCAPS *pCaps = (D3DHAL_D3DEXTENDEDCAPS*)pData->pData;
3230 pCaps->dwSize = sizeof (D3DHAL_D3DEXTENDEDCAPS);
3231 }
3232 else
3233 hr = E_INVALIDARG;
3234 break;
3235 case D3DDDICAPS_GETD3D9CAPS:
3236 {
3237 Assert(pData->DataSize == sizeof (D3DCAPS9));
3238// Assert(0);
3239 if (pData->DataSize >= sizeof (D3DCAPS9))
3240 {
3241 Assert(VBOXDISPMODE_IS_3D(pAdapter));
3242 if (VBOXDISPMODE_IS_3D(pAdapter))
3243 {
3244 D3DCAPS9* pCaps = (D3DCAPS9*)pData->pData;
3245 hr = vboxWddmGetD3D9Caps(pAdapter, pCaps);
3246 Assert(hr == S_OK);
3247 if (hr == S_OK)
3248 break;
3249
3250 vboxVDbgPrintR((__FUNCTION__": GetDeviceCaps Failed hr(%d)\n", hr));
3251 /* let's fall back to the 3D disabled case */
3252 hr = S_OK;
3253 }
3254
3255 memset(pData->pData, 0, sizeof (D3DCAPS9));
3256 }
3257 else
3258 hr = E_INVALIDARG;
3259 break;
3260 }
3261 case D3DDDICAPS_GETD3D8CAPS:
3262 {
3263 Assert(pData->DataSize == RT_OFFSETOF(D3DCAPS9, DevCaps2));
3264 if (pData->DataSize == RT_OFFSETOF(D3DCAPS9, DevCaps2))
3265 {
3266 Assert(VBOXDISPMODE_IS_3D(pAdapter));
3267 if (VBOXDISPMODE_IS_3D(pAdapter))
3268 {
3269 D3DCAPS9 Caps9;
3270 hr = vboxWddmGetD3D9Caps(pAdapter, &Caps9);
3271 Assert(hr == S_OK);
3272 if (hr == S_OK)
3273 {
3274 memcpy(pData->pData, &Caps9, RT_OFFSETOF(D3DCAPS9, DevCaps2));
3275 break;
3276 }
3277
3278 vboxVDbgPrintR((__FUNCTION__": GetDeviceCaps Failed hr(%d)\n", hr));
3279 /* let's fall back to the 3D disabled case */
3280 hr = S_OK;
3281 }
3282
3283 }
3284 else
3285 hr = E_INVALIDARG;
3286 break;
3287 }
3288 case D3DDDICAPS_GETGAMMARAMPCAPS:
3289 *((uint32_t*)pData->pData) = 0;
3290 break;
3291 case D3DDDICAPS_GETVIDEOPROCESSORCAPS:
3292 case D3DDDICAPS_GETEXTENSIONGUIDCOUNT:
3293 case D3DDDICAPS_GETDECODEGUIDCOUNT:
3294 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDCOUNT:
3295 if (pData->pData && pData->DataSize)
3296 memset(pData->pData, 0, pData->DataSize);
3297 break;
3298 case D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS:
3299 case D3DDDICAPS_GETD3D5CAPS:
3300 case D3DDDICAPS_GETD3D6CAPS:
3301 case D3DDDICAPS_GETDECODEGUIDS:
3302 case D3DDDICAPS_GETDECODERTFORMATCOUNT:
3303 case D3DDDICAPS_GETDECODERTFORMATS:
3304 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFOCOUNT:
3305 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFO:
3306 case D3DDDICAPS_GETDECODECONFIGURATIONCOUNT:
3307 case D3DDDICAPS_GETDECODECONFIGURATIONS:
3308 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDS:
3309 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATCOUNT:
3310 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATS:
3311 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT:
3312 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS:
3313 case D3DDDICAPS_GETPROCAMPRANGE:
3314 case D3DDDICAPS_FILTERPROPERTYRANGE:
3315 case D3DDDICAPS_GETEXTENSIONGUIDS:
3316 case D3DDDICAPS_GETEXTENSIONCAPS:
3317 vboxVDbgPrint((__FUNCTION__": unimplemented caps type(%d)\n", pData->Type));
3318 Assert(0);
3319 if (pData->pData && pData->DataSize)
3320 memset(pData->pData, 0, pData->DataSize);
3321 break;
3322 default:
3323 vboxVDbgPrint((__FUNCTION__": unknown caps type(%d)\n", pData->Type));
3324 Assert(0);
3325 }
3326
3327 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
3328
3329 return S_OK;
3330}
3331
3332static HRESULT APIENTRY vboxWddmDDevSetRenderState(HANDLE hDevice, CONST D3DDDIARG_RENDERSTATE* pData)
3333{
3334 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3335 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3336 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3337 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3338 Assert(pDevice);
3339 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3340 HRESULT hr = pDevice9If->SetRenderState(vboxDDI2D3DRenderStateType(pData->State), pData->Value);
3341 Assert(hr == S_OK);
3342 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3343 return hr;
3344}
3345
3346static HRESULT APIENTRY vboxWddmDDevUpdateWInfo(HANDLE hDevice, CONST D3DDDIARG_WINFO* pData)
3347{
3348 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3349// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3350// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3351 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3352 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3353 return S_OK;
3354}
3355
3356static HRESULT APIENTRY vboxWddmDDevValidateDevice(HANDLE hDevice, D3DDDIARG_VALIDATETEXTURESTAGESTATE* pData)
3357{
3358 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3359// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3360// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3361 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3362 Assert(0);
3363 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3364 return E_FAIL;
3365}
3366
3367static HRESULT APIENTRY vboxWddmDDevSetTextureStageState(HANDLE hDevice, CONST D3DDDIARG_TEXTURESTAGESTATE* pData)
3368{
3369 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3370 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3371 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3372 Assert(pDevice);
3373 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3374 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3375
3376 VBOXWDDMDISP_TSS_LOOKUP lookup = vboxDDI2D3DTestureStageStateType(pData->State);
3377 HRESULT hr;
3378
3379 if (!lookup.bSamplerState)
3380 {
3381 hr = pDevice9If->SetTextureStageState(pData->Stage, D3DTEXTURESTAGESTATETYPE(lookup.dType), pData->Value);
3382 }
3383 else
3384 {
3385 hr = pDevice9If->SetSamplerState(pData->Stage, D3DSAMPLERSTATETYPE(lookup.dType), pData->Value);
3386 }
3387
3388 Assert(hr == S_OK);
3389 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3390 return hr;
3391}
3392
3393static HRESULT APIENTRY vboxWddmDDevSetTexture(HANDLE hDevice, UINT Stage, HANDLE hTexture)
3394{
3395 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3396 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3397 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3398 Assert(pDevice);
3399 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3400 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3401 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hTexture;
3402// Assert(pRc);
3403 IDirect3DTexture9 *pD3DIfTex;
3404 if (pRc)
3405 {
3406 Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE);
3407 pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
3408#ifdef DEBUG_misha
3409 bool bDo = false;
3410
3411 if (bDo)
3412 {
3413 vboxVDbgDumpSurfData((pDevice, "SetTexture:\n", pRc, 0 /* alloc index*/, NULL, NULL, "\n"));
3414 }
3415#endif
3416 }
3417 else
3418 pD3DIfTex = NULL;
3419
3420// Assert(pD3DIfTex);
3421 HRESULT hr = pDevice9If->SetTexture(Stage, pD3DIfTex);
3422 Assert(hr == S_OK);
3423 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3424 return hr;
3425}
3426
3427static HRESULT APIENTRY vboxWddmDDevSetPixelShader(HANDLE hDevice, HANDLE hShaderHandle)
3428{
3429 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3430 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3431 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3432 Assert(pDevice);
3433 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3434 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3435 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
3436 Assert(pShader);
3437 HRESULT hr = pDevice9If->SetPixelShader(pShader);
3438 Assert(hr == S_OK);
3439 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3440 return hr;
3441}
3442
3443static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONST* pData, CONST FLOAT* pRegisters)
3444{
3445 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3446 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3447 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3448 Assert(pDevice);
3449 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3450 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3451 HRESULT hr = pDevice9If->SetPixelShaderConstantF(pData->Register, pRegisters, pData->Count);
3452 Assert(hr == S_OK);
3453 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3454 return hr;
3455}
3456
3457static HRESULT APIENTRY vboxWddmDDevSetStreamSourceUm(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEUM* pData, CONST VOID* pUMBuffer )
3458{
3459 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3460 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3461 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3462 Assert(pDevice);
3463 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3464 HRESULT hr = S_OK;
3465// IDirect3DVertexBuffer9 *pStreamData;
3466// UINT cbOffset;
3467// UINT cbStride;
3468// hr = pDevice->pDevice9If->GetStreamSource(pData->Stream, &pStreamData, &cbOffset, &cbStride);
3469// Assert(hr == S_OK);
3470// if (hr == S_OK)
3471// {
3472// if (pStreamData)
3473// {
3474// Assert(0);
3475// /* @todo: impl! */
3476// }
3477// else
3478// {
3479 Assert(pData->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm));
3480 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrcUm = &pDevice->aStreamSourceUm[pData->Stream];
3481 pStrSrcUm->pvBuffer = pUMBuffer;
3482 pStrSrcUm->cbStride = pData->Stride;
3483// }
3484// }
3485 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3486 return hr;
3487}
3488
3489static HRESULT APIENTRY vboxWddmDDevSetIndices(HANDLE hDevice, CONST D3DDDIARG_SETINDICES* pData)
3490{
3491 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3492 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3493 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3494 Assert(pDevice);
3495 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3496
3497 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3498 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hIndexBuffer;
3499 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
3500 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
3501 if (pRc)
3502 {
3503 Assert(pRc->cAllocations == 1);
3504 pAlloc = &pRc->aAllocations[0];
3505 Assert(pAlloc->pD3DIf);
3506 pIndexBuffer = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
3507 }
3508 HRESULT hr = pDevice9If->SetIndices(pIndexBuffer);
3509 Assert(hr == S_OK);
3510 if (hr == S_OK)
3511 {
3512 pDevice->pIndicesAlloc = pAlloc;
3513 pDevice->IndiciesInfo.uiStride = pData->Stride;
3514 }
3515 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3516 return hr;
3517}
3518
3519static HRESULT APIENTRY vboxWddmDDevSetIndicesUm(HANDLE hDevice, UINT IndexSize, CONST VOID* pUMBuffer)
3520{
3521 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3522 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3523 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3524 Assert(pDevice);
3525 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3526
3527 HRESULT hr = S_OK;
3528 pDevice->IndiciesUm.pvBuffer = pUMBuffer;
3529 pDevice->IndiciesUm.cbSize = IndexSize;
3530 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3531 return hr;
3532}
3533
3534static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE* pData, CONST UINT* pFlagBuffer)
3535{
3536 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3537 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3538 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3539 Assert(pDevice);
3540 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3541
3542 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3543 Assert(!pFlagBuffer);
3544 HRESULT hr = S_OK;
3545
3546//#ifdef DEBUG_misha
3547// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3548// vboxVDbgDumpSurfData((pDevice, ">>>DrawPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3549// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3550//#endif
3551
3552 if (!pDevice->cStreamSources)
3553 {
3554 if (pDevice->aStreamSourceUm[0].pvBuffer)
3555 {
3556#ifdef DEBUG
3557 for (UINT i = 1; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3558 {
3559 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3560 }
3561#endif
3562 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType,
3563 pData->PrimitiveCount,
3564 ((uint8_t*)pDevice->aStreamSourceUm[0].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[0].cbStride,
3565 pDevice->aStreamSourceUm[0].cbStride);
3566 Assert(hr == S_OK);
3567
3568// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
3569 }
3570 else
3571 {
3572 /* todo: impl */
3573 Assert(0);
3574 }
3575 }
3576 else
3577 {
3578
3579#ifdef DEBUG
3580 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3581 {
3582 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3583 }
3584
3585 uint32_t cStreams = 0;
3586 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
3587 {
3588 if (pDevice->aStreamSource[i])
3589 {
3590 ++cStreams;
3591 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
3592 }
3593 }
3594
3595 Assert(cStreams);
3596 Assert(cStreams == pDevice->cStreamSources);
3597#endif
3598 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
3599 pData->VStart,
3600 pData->PrimitiveCount);
3601 Assert(hr == S_OK);
3602
3603// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitive\n"));
3604#if 0
3605 IDirect3DVertexDeclaration9* pDecl;
3606 hr = pDevice9If->GetVertexDeclaration(&pDecl);
3607 Assert(hr == S_OK);
3608 if (hr == S_OK)
3609 {
3610 Assert(pDecl);
3611 D3DVERTEXELEMENT9 aDecls9[MAXD3DDECLLENGTH];
3612 UINT cDecls9 = 0;
3613 hr = pDecl->GetDeclaration(aDecls9, &cDecls9);
3614 Assert(hr == S_OK);
3615 if (hr == S_OK)
3616 {
3617 Assert(cDecls9);
3618 for (UINT i = 0; i < cDecls9 - 1 /* the last one is D3DDECL_END */; ++i)
3619 {
3620 D3DVERTEXELEMENT9 *pDecl9 = &aDecls9[i];
3621 Assert(pDecl9->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm) || pDecl9->Stream == 0xff);
3622 if (pDecl9->Stream != 0xff)
3623 {
3624 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrc = &pDevice->aStreamSourceUm[pDecl9->Stream];
3625 if (pStrSrc->pvBuffer)
3626 {
3627 WORD iStream = pDecl9->Stream;
3628 D3DVERTEXELEMENT9 *pLastCDecl9 = pDecl9;
3629 for (UINT j = i+1; j < cDecls9 - 1 /* the last one is D3DDECL_END */; ++j)
3630 {
3631 pDecl9 = &aDecls9[j];
3632 if (iStream == pDecl9->Stream)
3633 {
3634 pDecl9->Stream = 0xff; /* mark as done */
3635 Assert(pDecl9->Offset != pLastCDecl9->Offset);
3636 if (pDecl9->Offset > pLastCDecl9->Offset)
3637 pLastCDecl9 = pDecl9;
3638 }
3639 }
3640 /* vertex size is MAX(all Offset's) + sizeof (data_type with MAX offset) + stride*/
3641 UINT cbVertex = pLastCDecl9->Offset + pStrSrc->cbStride;
3642 UINT cbType;
3643 switch (pLastCDecl9->Type)
3644 {
3645 case D3DDECLTYPE_FLOAT1:
3646 cbType = sizeof (float);
3647 break;
3648 case D3DDECLTYPE_FLOAT2:
3649 cbType = sizeof (float) * 2;
3650 break;
3651 case D3DDECLTYPE_FLOAT3:
3652 cbType = sizeof (float) * 3;
3653 break;
3654 case D3DDECLTYPE_FLOAT4:
3655 cbType = sizeof (float) * 4;
3656 break;
3657 case D3DDECLTYPE_D3DCOLOR:
3658 cbType = 4;
3659 break;
3660 case D3DDECLTYPE_UBYTE4:
3661 cbType = 4;
3662 break;
3663 case D3DDECLTYPE_SHORT2:
3664 cbType = sizeof (short) * 2;
3665 break;
3666 case D3DDECLTYPE_SHORT4:
3667 cbType = sizeof (short) * 4;
3668 break;
3669 case D3DDECLTYPE_UBYTE4N:
3670 cbType = 4;
3671 break;
3672 case D3DDECLTYPE_SHORT2N:
3673 cbType = sizeof (short) * 2;
3674 break;
3675 case D3DDECLTYPE_SHORT4N:
3676 cbType = sizeof (short) * 4;
3677 break;
3678 case D3DDECLTYPE_USHORT2N:
3679 cbType = sizeof (short) * 2;
3680 break;
3681 case D3DDECLTYPE_USHORT4N:
3682 cbType = sizeof (short) * 4;
3683 break;
3684 case D3DDECLTYPE_UDEC3:
3685 cbType = sizeof (signed) * 3;
3686 break;
3687 case D3DDECLTYPE_DEC3N:
3688 cbType = sizeof (unsigned) * 3;
3689 break;
3690 case D3DDECLTYPE_FLOAT16_2:
3691 cbType = 2 * 2;
3692 break;
3693 case D3DDECLTYPE_FLOAT16_4:
3694 cbType = 2 * 4;
3695 break;
3696 default:
3697 Assert(0);
3698 cbType = 1;
3699 }
3700 cbVertex += cbType;
3701
3702 UINT cVertexes;
3703 switch (pData->PrimitiveType)
3704 {
3705 case D3DPT_POINTLIST:
3706 cVertexes = pData->PrimitiveCount;
3707 break;
3708 case D3DPT_LINELIST:
3709 cVertexes = pData->PrimitiveCount * 2;
3710 break;
3711 case D3DPT_LINESTRIP:
3712 cVertexes = pData->PrimitiveCount + 1;
3713 break;
3714 case D3DPT_TRIANGLELIST:
3715 cVertexes = pData->PrimitiveCount * 3;
3716 break;
3717 case D3DPT_TRIANGLESTRIP:
3718 cVertexes = pData->PrimitiveCount + 2;
3719 break;
3720 case D3DPT_TRIANGLEFAN:
3721 cVertexes = pData->PrimitiveCount + 2;
3722 break;
3723 default:
3724 Assert(0);
3725 cVertexes = pData->PrimitiveCount;
3726 }
3727 UINT cbVertexes = cVertexes * cbVertex;
3728 IDirect3DVertexBuffer9 *pCurVb = NULL, *pVb = NULL;
3729 UINT cbOffset;
3730 UINT cbStride;
3731 hr = pDevice9If->GetStreamSource(iStream, &pCurVb, &cbOffset, &cbStride);
3732 Assert(hr == S_OK);
3733 if (hr == S_OK)
3734 {
3735 if (pCurVb)
3736 {
3737 if (cbStride == pStrSrc->cbStride)
3738 {
3739 /* ensure our data feets in the buffer */
3740 D3DVERTEXBUFFER_DESC Desc;
3741 hr = pCurVb->GetDesc(&Desc);
3742 Assert(hr == S_OK);
3743 if (hr == S_OK)
3744 {
3745 if (Desc.Size >= cbVertexes)
3746 pVb = pCurVb;
3747 }
3748 }
3749 }
3750 }
3751 else
3752 {
3753 pCurVb = NULL;
3754 }
3755
3756 if (!pVb)
3757 {
3758 hr = pDevice9If->CreateVertexBuffer(cbVertexes,
3759 0, /* DWORD Usage */
3760 0, /* DWORD FVF */
3761 D3DPOOL_DEFAULT, /* D3DPOOL Pool */
3762 &pVb,
3763 NULL /*HANDLE* pSharedHandle*/);
3764 Assert(hr == S_OK);
3765 if (hr == S_OK)
3766 {
3767 hr = pDevice9If->SetStreamSource(iStream, pVb, 0, pStrSrc->cbStride);
3768 Assert(hr == S_OK);
3769 if (hr == S_OK)
3770 {
3771 if (pCurVb)
3772 pCurVb->Release();
3773 }
3774 else
3775 {
3776 pVb->Release();
3777 pVb = NULL;
3778 }
3779 }
3780 }
3781
3782 if (pVb)
3783 {
3784 Assert(hr == S_OK);
3785 VOID *pvData;
3786 hr = pVb->Lock(0, /* UINT OffsetToLock */
3787 cbVertexes,
3788 &pvData,
3789 D3DLOCK_DISCARD);
3790 Assert(hr == S_OK);
3791 if (hr == S_OK)
3792 {
3793 memcpy (pvData, ((uint8_t*)pStrSrc->pvBuffer) + pData->VStart * cbVertex, cbVertexes);
3794 HRESULT tmpHr = pVb->Unlock();
3795 Assert(tmpHr == S_OK);
3796 }
3797 }
3798 }
3799 }
3800 }
3801 }
3802 if (hr == S_OK)
3803 {
3804 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
3805 0 /* <- since we use our own StreamSource buffer which has data at the very beginning*/,
3806 pData->PrimitiveCount);
3807 Assert(hr == S_OK);
3808 }
3809 }
3810#endif
3811 }
3812
3813//#ifdef DEBUG_misha
3814// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3815// vboxVDbgDumpSurfData((pDevice, "<<<DrawPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3816// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3817//#endif
3818
3819 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3820 return hr;
3821}
3822
3823static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE* pData)
3824{
3825 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3826 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3827 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3828 Assert(pDevice);
3829 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3830
3831 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3832//#ifdef DEBUG_misha
3833// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3834// vboxVDbgDumpSurfData((pDevice, ">>>DrawIndexedPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3835// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3836//#endif
3837
3838#ifdef DEBUG
3839 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3840 {
3841 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3842 }
3843
3844 Assert(pDevice->pIndicesAlloc);
3845 Assert(!pDevice->pIndicesAlloc->LockInfo.cLocks);
3846
3847 uint32_t cStreams = 0;
3848 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
3849 {
3850 if (pDevice->aStreamSource[i])
3851 {
3852 ++cStreams;
3853 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
3854 }
3855 }
3856
3857 Assert(cStreams);
3858 Assert(cStreams == pDevice->cStreamSources);
3859#endif
3860
3861 HRESULT hr = pDevice9If->DrawIndexedPrimitive(
3862 pData->PrimitiveType,
3863 pData->BaseVertexIndex,
3864 pData->MinIndex,
3865 pData->NumVertices,
3866 pData->StartIndex,
3867 pData->PrimitiveCount);
3868 Assert(hr == S_OK);
3869
3870//#ifdef DEBUG_misha
3871// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3872// vboxVDbgDumpSurfData((pDevice, "<<<DrawIndexedPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3873// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3874//#endif
3875
3876
3877 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3878 return hr;
3879}
3880
3881static HRESULT APIENTRY vboxWddmDDevDrawRectPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWRECTPATCH* pData, CONST D3DDDIRECTPATCH_INFO* pInfo, CONST FLOAT* pPatch)
3882{
3883 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3884 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3885 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3886 Assert(pDevice);
3887 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3888 Assert(0);
3889 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3890 return E_FAIL;
3891}
3892
3893static HRESULT APIENTRY vboxWddmDDevDrawTriPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWTRIPATCH* pData, CONST D3DDDITRIPATCH_INFO* pInfo, CONST FLOAT* pPatch)
3894{
3895 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3896 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3897 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3898 Assert(pDevice);
3899 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3900 Assert(0);
3901 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3902 return E_FAIL;
3903}
3904
3905static HRESULT APIENTRY vboxWddmDDevDrawPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE2* pData)
3906{
3907 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3908 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3909 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3910 Assert(pDevice);
3911 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3912
3913 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3914 HRESULT hr;
3915
3916#if 0
3917 int stream;
3918 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
3919 {
3920 if (pDevice->aStreamSource[stream] && pDevice->aStreamSource[stream]->LockInfo.cLocks)
3921 {
3922 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
3923 if (pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite))
3924 {
3925 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf;
3926 Assert(pLock->fFlags.RangeValid);
3927 pD3D9VBuf->Lock(pLock->Range.Offset, pLock->Range.Size,
3928 &pLock->LockedRect.pBits,
3929 vboxDDI2D3DLockFlags(pLock->fFlags));
3930 RECT r;
3931 r.top = 0;
3932 r.left = pLock->Range.Offset;
3933 r.bottom = 1;
3934 r.right = pLock->Range.Offset + pLock->Range.Size;
3935
3936 vboxWddmLockUnlockMemSynch(pDevice->aStreamSource[stream], &pLock->LockedRect, &r, true /*bool bToLockInfo*/);
3937
3938 pD3D9VBuf->Unlock();
3939 }
3940 }
3941 }
3942
3943 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset, pData->PrimitiveCount);
3944#else
3945//#ifdef DEBUG_misha
3946// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3947// vboxVDbgDumpSurfData((pDevice, ">>>DrawPrimitive2:\n", pDevice->pRenderTargetRc, iBackBuf,
3948// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3949//#endif
3950
3951#ifdef DEBUG
3952 uint32_t cStreams = 0;
3953#endif
3954
3955 int stream;
3956 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
3957 {
3958 if (pDevice->aStreamSource[stream])
3959 {
3960#ifdef DEBUG
3961 ++cStreams;
3962#endif
3963 Assert(stream==0); /*only stream 0 should be accessed here*/
3964 Assert(pDevice->StreamSourceInfo[stream].uiStride!=0);
3965 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
3966
3967 if (pDevice->aStreamSource[stream]->LockInfo.cLocks)
3968 {
3969// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
3970
3971 Assert(pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite));
3972 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType, pData->PrimitiveCount,
3973 (void*)((uintptr_t)pDevice->aStreamSource[stream]->pvMem+pDevice->StreamSourceInfo[stream].uiOffset+pData->FirstVertexOffset),
3974 pDevice->StreamSourceInfo[stream].uiStride);
3975 Assert(hr == S_OK);
3976 hr = pDevice9If->SetStreamSource(stream, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf, pDevice->StreamSourceInfo[stream].uiOffset, pDevice->StreamSourceInfo[stream].uiStride);
3977 Assert(hr == S_OK);
3978 }
3979 else
3980 {
3981// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitive\n"));
3982
3983 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset/pDevice->StreamSourceInfo[stream].uiStride, pData->PrimitiveCount);
3984 Assert(hr == S_OK);
3985 }
3986 }
3987 }
3988
3989#ifdef DEBUG
3990 Assert(cStreams);
3991 Assert(cStreams == pDevice->cStreamSources);
3992#endif
3993#endif
3994
3995//#ifdef DEBUG_misha
3996// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3997// vboxVDbgDumpSurfData((pDevice, "<<<DrawPrimitive2:\n", pDevice->pRenderTargetRc, iBackBuf,
3998// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3999//#endif
4000
4001 Assert(hr == S_OK);
4002 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4003 return hr;
4004}
4005
4006static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE2* pData, UINT dwIndicesSize, CONST VOID* pIndexBuffer, CONST UINT* pFlagBuffer)
4007{
4008 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4009 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4010 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4011 Assert(pDevice);
4012 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4013 Assert(0);
4014 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4015 return E_FAIL;
4016}
4017
4018static HRESULT APIENTRY vboxWddmDDevVolBlt(HANDLE hDevice, CONST D3DDDIARG_VOLUMEBLT* pData)
4019{
4020 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4021 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4022 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4023 Assert(pDevice);
4024 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4025 Assert(0);
4026 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4027 return E_FAIL;
4028}
4029
4030static HRESULT APIENTRY vboxWddmDDevBufBlt(HANDLE hDevice, CONST D3DDDIARG_BUFFERBLT* pData)
4031{
4032 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4033 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4034 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4035 Assert(pDevice);
4036 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4037 Assert(0);
4038 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4039 return E_FAIL;
4040}
4041
4042static HRESULT APIENTRY vboxWddmDDevTexBlt(HANDLE hDevice, CONST D3DDDIARG_TEXBLT* pData)
4043{
4044 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4045 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4046 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4047 Assert(pDevice);
4048 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4049 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4050 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
4051 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
4052 /* requirements for D3DDevice9::UpdateTexture */
4053 Assert(pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4054 Assert(pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
4055 HRESULT hr = S_OK;
4056
4057#ifdef DEBUG_misha
4058 bool bDo = false;
4059 IDirect3DSurface9 *pTstSrcSurfIf = NULL;
4060 IDirect3DSurface9 *pTstDstSurfIf = NULL;
4061
4062 if (g_VDbgTstDumpEnable)
4063 {
4064 hr = vboxWddmSurfGet(pSrcRc, 0, &pTstSrcSurfIf);
4065 Assert(hr == S_OK);
4066 hr = vboxWddmSurfGet(pDstRc, 0, &pTstDstSurfIf);
4067 Assert(hr == S_OK);
4068
4069 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
4070 {
4071 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
4072 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
4073 {
4074 D3DSURFACE_DESC SrcDesc;
4075 HRESULT hr = pTstSrcSurfIf->GetDesc(&SrcDesc);
4076 Assert(hr == S_OK);
4077 if (hr == S_OK)
4078 {
4079 D3DSURFACE_DESC DstDesc;
4080 hr = pTstDstSurfIf->GetDesc(&DstDesc);
4081 Assert(hr == S_OK);
4082 if (hr == S_OK)
4083 {
4084 if (SrcDesc.Width == DstDesc.Width
4085 && SrcDesc.Height == DstDesc.Height)
4086 {
4087 bDo = true;
4088 }
4089 }
4090 }
4091 }
4092 }
4093 }
4094
4095 if (bDo)
4096 {
4097 RECT DstRect;
4098 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
4099 vboxVDbgDumpSurfData((pDevice, "TexBlt-pre Src:\n", pSrcRc, 0, &pData->SrcRect, pTstSrcSurfIf, "\n"));
4100 vboxVDbgDumpSurfData((pDevice, "TexBlt-pre Dst:\n", pDstRc, 0, &DstRect, pTstDstSurfIf, "\n"));
4101 }
4102#endif
4103
4104 if (pSrcRc->aAllocations[0].D3DWidth == pDstRc->aAllocations[0].D3DWidth
4105 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
4106 && pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat
4107 &&pData->DstPoint.x == 0 && pData->DstPoint.y == 0
4108 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
4109 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
4110 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height)
4111 {
4112 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcRc->aAllocations[0].pD3DIf;
4113 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstRc->aAllocations[0].pD3DIf;
4114 Assert(pD3DIfSrcTex);
4115 Assert(pD3DIfDstTex);
4116 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
4117 Assert(hr == S_OK);
4118 }
4119 else
4120 {
4121 IDirect3DSurface9 *pSrcSurfIf = NULL;
4122 IDirect3DSurface9 *pDstSurfIf = NULL;
4123 hr = vboxWddmSurfGet(pDstRc, 0, &pDstSurfIf);
4124 Assert(hr == S_OK);
4125 if (hr == S_OK)
4126 {
4127 hr = vboxWddmSurfGet(pSrcRc, 0, &pSrcSurfIf);
4128 Assert(hr == S_OK);
4129 if (hr == S_OK)
4130 {
4131 RECT DstRect;
4132 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
4133#ifdef DEBUG
4134 RECT tstRect = {0,0, pDstRc->aAllocations[0].SurfDesc.width, pDstRc->aAllocations[0].SurfDesc.height};
4135 Assert(vboxWddmRectIsCoveres(&tstRect, &DstRect));
4136#endif
4137 hr = pDevice9If->StretchRect(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &DstRect, D3DTEXF_NONE);
4138 Assert(hr == S_OK);
4139 pSrcSurfIf->Release();
4140 }
4141 pDstSurfIf->Release();
4142 }
4143 }
4144
4145#ifdef DEBUG_misha
4146 if (bDo)
4147 {
4148 RECT DstRect;
4149 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
4150 vboxVDbgDumpSurfData((pDevice, "TexBlt-post Src:\n", pSrcRc, 0, &pData->SrcRect, pTstSrcSurfIf, "\n"));
4151 vboxVDbgDumpSurfData((pDevice, "TexBlt-post Dst:\n", pDstRc, 0, &DstRect, pTstDstSurfIf, "\n"));
4152 }
4153
4154 if (pTstDstSurfIf)
4155 pTstDstSurfIf->Release();
4156 if (pTstSrcSurfIf)
4157 pTstSrcSurfIf->Release();
4158#endif
4159 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4160 return hr;
4161}
4162
4163static HRESULT APIENTRY vboxWddmDDevStateSet(HANDLE hDevice, D3DDDIARG_STATESET* pData)
4164{
4165 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4166 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4167 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4168 Assert(pDevice);
4169 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4170 Assert(0);
4171 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4172 return E_FAIL;
4173}
4174static HRESULT APIENTRY vboxWddmDDevSetPriority(HANDLE hDevice, CONST D3DDDIARG_SETPRIORITY* pData)
4175{
4176 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4177// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4178// Assert(pDevice);
4179// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4180 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4181 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4182 return S_OK;
4183}
4184AssertCompile(sizeof (RECT) == sizeof (D3DRECT));
4185AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DRECT, x1));
4186AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DRECT, x2));
4187AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DRECT, y1));
4188AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DRECT, y2));
4189AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DRECT, x1));
4190AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DRECT, x2));
4191AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DRECT, y1));
4192AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DRECT, y2));
4193
4194static HRESULT APIENTRY vboxWddmDDevClear(HANDLE hDevice, CONST D3DDDIARG_CLEAR* pData, UINT NumRect, CONST RECT* pRect)
4195{
4196 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4197 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4198 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4199 Assert(pDevice);
4200 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4201 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4202 HRESULT hr = pDevice9If->Clear(NumRect, (D3DRECT*)pRect /* see AssertCompile above */,
4203 pData->Flags,
4204 pData->FillColor,
4205 pData->FillDepth,
4206 pData->FillStencil);
4207 Assert(hr == S_OK);
4208 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4209 return hr;
4210}
4211static HRESULT APIENTRY vboxWddmDDevUpdatePalette(HANDLE hDevice, CONST D3DDDIARG_UPDATEPALETTE* pData, CONST PALETTEENTRY* pPaletteData)
4212{
4213 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4214 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4215 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4216 Assert(pDevice);
4217 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4218 Assert(0);
4219 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4220 return E_FAIL;
4221}
4222
4223static HRESULT APIENTRY vboxWddmDDevSetPalette(HANDLE hDevice, CONST D3DDDIARG_SETPALETTE* pData)
4224{
4225 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4226 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4227 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4228 Assert(pDevice);
4229 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4230 Assert(0);
4231 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4232 return E_FAIL;
4233}
4234
4235static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONST* pData , CONST VOID* pRegisters)
4236{
4237 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4238 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4239 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4240 Assert(pDevice);
4241 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4242 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4243 HRESULT hr = pDevice9If->SetVertexShaderConstantF(
4244 pData->Register,
4245 (CONST float*)pRegisters,
4246 pData->Count);
4247 Assert(hr == S_OK);
4248 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4249 return hr;
4250}
4251static HRESULT APIENTRY vboxWddmDDevMultiplyTransform(HANDLE hDevice, CONST D3DDDIARG_MULTIPLYTRANSFORM* pData)
4252{
4253 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4254 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4255 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4256 Assert(pDevice);
4257 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4258 Assert(0);
4259 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4260 return E_FAIL;
4261}
4262static HRESULT APIENTRY vboxWddmDDevSetTransform(HANDLE hDevice, CONST D3DDDIARG_SETTRANSFORM* pData)
4263{
4264 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4265 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4266 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4267 Assert(pDevice);
4268 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4269 Assert(0);
4270 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4271 return E_FAIL;
4272}
4273static HRESULT APIENTRY vboxWddmDDevSetViewport(HANDLE hDevice, CONST D3DDDIARG_VIEWPORTINFO* pData)
4274{
4275 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4276 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4277 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4278 Assert(pDevice);
4279 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4280
4281 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4282 pDevice->ViewPort.X = pData->X;
4283 pDevice->ViewPort.Y = pData->Y;
4284 pDevice->ViewPort.Width = pData->Width;
4285 pDevice->ViewPort.Height = pData->Height;
4286 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
4287 Assert(hr == S_OK);
4288 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4289 return hr;
4290}
4291static HRESULT APIENTRY vboxWddmDDevSetZRange(HANDLE hDevice, CONST D3DDDIARG_ZRANGE* pData)
4292{
4293 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4294 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4295 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4296 Assert(pDevice);
4297 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4298
4299 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4300 pDevice->ViewPort.MinZ = pData->MinZ;
4301 pDevice->ViewPort.MaxZ = pData->MaxZ;
4302 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
4303 Assert(hr == S_OK);
4304 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4305 return hr;
4306}
4307static HRESULT APIENTRY vboxWddmDDevSetMaterial(HANDLE hDevice, CONST D3DDDIARG_SETMATERIAL* pData)
4308{
4309 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4310 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4311 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4312 Assert(pDevice);
4313 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4314 Assert(0);
4315 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4316 return E_FAIL;
4317}
4318static HRESULT APIENTRY vboxWddmDDevSetLight(HANDLE hDevice, CONST D3DDDIARG_SETLIGHT* pData, CONST D3DDDI_LIGHT* pLightProperties)
4319{
4320 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4321 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4322 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4323 Assert(pDevice);
4324 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4325 Assert(0);
4326 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4327 return E_FAIL;
4328}
4329static HRESULT APIENTRY vboxWddmDDevCreateLight(HANDLE hDevice, CONST D3DDDIARG_CREATELIGHT* pData)
4330{
4331 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4332 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4333 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4334 Assert(pDevice);
4335 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4336 Assert(0);
4337 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4338 return E_FAIL;
4339}
4340static HRESULT APIENTRY vboxWddmDDevDestroyLight(HANDLE hDevice, CONST D3DDDIARG_DESTROYLIGHT* pData)
4341{
4342 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4343 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4344 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4345 Assert(pDevice);
4346 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4347 Assert(0);
4348 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4349 return E_FAIL;
4350}
4351static HRESULT APIENTRY vboxWddmDDevSetClipPlane(HANDLE hDevice, CONST D3DDDIARG_SETCLIPPLANE* pData)
4352{
4353 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4354 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4355 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4356 Assert(pDevice);
4357 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4358
4359 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4360 HRESULT hr = pDevice9If->SetClipPlane(pData->Index, pData->Plane);
4361 Assert(hr == S_OK);
4362 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4363 return hr;
4364}
4365
4366static HRESULT APIENTRY vboxWddmDDevGetInfo(HANDLE hDevice, UINT DevInfoID, VOID* pDevInfoStruct, UINT DevInfoSize)
4367{
4368 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4369 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4370// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4371// Assert(pDevice);
4372// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4373 HRESULT hr = S_OK;
4374 switch (DevInfoID)
4375 {
4376 case D3DDDIDEVINFOID_VCACHE:
4377 {
4378 Assert(DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE));
4379 if (DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE))
4380 {
4381 D3DDDIDEVINFO_VCACHE *pVCache = (D3DDDIDEVINFO_VCACHE*)pDevInfoStruct;
4382 pVCache->Pattern = MAKEFOURCC('C', 'A', 'C', 'H');
4383 pVCache->OptMethod = 0 /* D3DXMESHOPT_STRIPREORDER */;
4384 pVCache->CacheSize = 0;
4385 pVCache->MagicNumber = 0;
4386 }
4387 else
4388 hr = E_INVALIDARG;
4389 break;
4390 }
4391 default:
4392 Assert(0);
4393 hr = E_NOTIMPL;
4394 }
4395 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4396 return hr;
4397}
4398
4399static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
4400{
4401 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4402 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4403 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4404 Assert(pDevice);
4405 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4406 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4407 Assert(pData->SubResourceIndex < pRc->cAllocations);
4408 if (pData->SubResourceIndex >= pRc->cAllocations)
4409 return E_INVALIDARG;
4410
4411 HRESULT hr = S_OK;
4412
4413 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4414 {
4415// Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex);
4416
4417 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
4418 {
4419 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
4420 Assert(pData->SubResourceIndex < pRc->cAllocations);
4421 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4422 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
4423 Assert(pD3DIfTex);
4424 RECT *pRect = NULL;
4425 bool bNeedResynch = false;
4426 Assert(!pData->Flags.RangeValid);
4427 Assert(!pData->Flags.BoxValid);
4428 if (pData->Flags.AreaValid)
4429 {
4430 pRect = &pData->Area;
4431 }
4432
4433 /* else - we lock the entire texture, pRect == NULL */
4434
4435// Assert(!pLockAlloc->LockInfo.cLocks);
4436 if (!pLockAlloc->LockInfo.cLocks)
4437 {
4438 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
4439 &pLockAlloc->LockInfo.LockedRect,
4440 pRect,
4441 vboxDDI2D3DLockFlags(pData->Flags));
4442 Assert(hr == S_OK);
4443 if (hr == S_OK)
4444 {
4445
4446// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4447 pLockAlloc->LockInfo.fFlags = pData->Flags;
4448 if (pRect)
4449 {
4450 pLockAlloc->LockInfo.Area = *pRect;
4451 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 1);
4452// pLockAlloc->LockInfo.fFlags.AreaValid = 1;
4453 }
4454 else
4455 {
4456 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 0);
4457// pLockAlloc->LockInfo.fFlags.AreaValid = 0;
4458 }
4459
4460 bNeedResynch = !pData->Flags.Discard;
4461 }
4462 }
4463 else
4464 {
4465// Assert(pLockAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4466// if (pLockAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4467// {
4468// }
4469 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid);
4470 if (pLockAlloc->LockInfo.fFlags.AreaValid && pData->Flags.AreaValid)
4471 {
4472 Assert(pLockAlloc->LockInfo.Area.left == pData->Area.left);
4473 Assert(pLockAlloc->LockInfo.Area.top == pData->Area.top);
4474 Assert(pLockAlloc->LockInfo.Area.right == pData->Area.right);
4475 Assert(pLockAlloc->LockInfo.Area.bottom == pData->Area.bottom);
4476 }
4477 Assert(pLockAlloc->LockInfo.LockedRect.pBits);
4478
4479 bNeedResynch = pLockAlloc->LockInfo.fFlags.Discard && !pData->Flags.Discard;
4480
4481 Assert(!bNeedResynch);
4482
4483 if (/*(pLockAlloc->LockInfo.fFlags.Discard && !pData->Flags.Discard)
4484 || */
4485 (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly))
4486 {
4487 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
4488 Assert(hr == S_OK);
4489 if (hr == S_OK)
4490 {
4491 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
4492 &pLockAlloc->LockInfo.LockedRect,
4493 pRect,
4494 vboxDDI2D3DLockFlags(pData->Flags));
4495 Assert(hr == S_OK);
4496 pLockAlloc->LockInfo.fFlags.ReadOnly = 0;
4497 }
4498 }
4499 }
4500
4501 if (hr == S_OK)
4502 {
4503 ++pLockAlloc->LockInfo.cLocks;
4504
4505 if (!pData->Flags.NotifyOnly)
4506 {
4507 pData->pSurfData = pLockAlloc->LockInfo.LockedRect.pBits;
4508 pData->Pitch = pLockAlloc->LockInfo.LockedRect.Pitch;
4509 pData->SlicePitch = 0;
4510 Assert(pLockAlloc->SurfDesc.slicePitch == 0);
4511 Assert(!pLockAlloc->pvMem);
4512 }
4513 else
4514 {
4515 Assert(pLockAlloc->pvMem);
4516 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4517#if 0
4518 if (bNeedResynch)
4519 vboxWddmLockUnlockMemSynch(pLockAlloc, &pLockAlloc->LockInfo.LockedRect, pRect, false /*bool bToLockInfo*/);
4520#endif
4521 }
4522 }
4523 }
4524 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
4525 {
4526 Assert(pData->SubResourceIndex < pRc->cAllocations);
4527 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4528 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4529 BOOL bLocked = false;
4530 Assert(pD3D9VBuf);
4531 Assert(!pData->Flags.AreaValid);
4532 Assert(!pData->Flags.BoxValid);
4533 D3DDDIRANGE *pRange = NULL;
4534 if (pData->Flags.RangeValid)
4535 {
4536 pRange = &pData->Range;
4537 }
4538
4539 /* else - we lock the entire vertex buffer, pRect == NULL */
4540
4541 Assert(!pAlloc->LockInfo.cLocks);
4542 if (!pAlloc->LockInfo.cLocks)
4543 {
4544 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
4545 {
4546 hr = pD3D9VBuf->Lock(pRange ? pRange->Offset : 0,
4547 pRange ? pRange->Size : 0,
4548 &pAlloc->LockInfo.LockedRect.pBits,
4549 vboxDDI2D3DLockFlags(pData->Flags));
4550 bLocked = true;
4551 }
4552
4553 Assert(hr == S_OK);
4554 if (hr == S_OK)
4555 {
4556 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.width;
4557// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4558 pAlloc->LockInfo.fFlags = pData->Flags;
4559 if (pRange)
4560 {
4561 pAlloc->LockInfo.Range = *pRange;
4562 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
4563// pAlloc->LockInfo.fFlags.RangeValid = 1;
4564 }
4565 else
4566 {
4567 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
4568// pAlloc->LockInfo.fFlags.RangeValid = 0;
4569 }
4570 }
4571 }
4572 else
4573 {
4574// Assert(pAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4575// if (pAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4576// {
4577// }
4578 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
4579 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
4580 {
4581 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
4582 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
4583 }
4584 Assert(pAlloc->LockInfo.LockedRect.pBits);
4585 }
4586
4587 if (hr == S_OK)
4588 {
4589 ++pAlloc->LockInfo.cLocks;
4590
4591 if (!pData->Flags.NotifyOnly)
4592 {
4593 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
4594 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
4595 pData->SlicePitch = 0;
4596 Assert(pAlloc->SurfDesc.slicePitch == 0);
4597 Assert(!pAlloc->pvMem);
4598 }
4599 else
4600 {
4601 Assert(pAlloc->pvMem);
4602 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4603 if (bLocked && !pData->Flags.Discard)
4604 {
4605 RECT r, *pr;
4606 if (pRange)
4607 {
4608 r.top = 0;
4609 r.left = pRange->Offset;
4610 r.bottom = 1;
4611 r.right = pRange->Offset + pRange->Size;
4612 pr = &r;
4613 }
4614 else
4615 pr = NULL;
4616 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
4617 }
4618 }
4619 }
4620 }
4621 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
4622 {
4623 Assert(pData->SubResourceIndex < pRc->cAllocations);
4624 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4625 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
4626 BOOL bLocked = false;
4627 Assert(pD3D9IBuf);
4628 Assert(!pData->Flags.AreaValid);
4629 Assert(!pData->Flags.BoxValid);
4630 D3DDDIRANGE *pRange = NULL;
4631 if (pData->Flags.RangeValid)
4632 {
4633 pRange = &pData->Range;
4634 }
4635
4636 /* else - we lock the entire vertex buffer, pRect == NULL */
4637
4638 Assert(!pAlloc->LockInfo.cLocks);
4639 if (!pAlloc->LockInfo.cLocks)
4640 {
4641 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
4642 {
4643 hr = pD3D9IBuf->Lock(pRange ? pRange->Offset : 0,
4644 pRange ? pRange->Size : 0,
4645 &pAlloc->LockInfo.LockedRect.pBits,
4646 vboxDDI2D3DLockFlags(pData->Flags));
4647 bLocked = true;
4648 }
4649
4650 Assert(hr == S_OK);
4651 if (hr == S_OK)
4652 {
4653 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.width;
4654// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4655 pAlloc->LockInfo.fFlags = pData->Flags;
4656 if (pRange)
4657 {
4658 pAlloc->LockInfo.Range = *pRange;
4659 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
4660// pAlloc->LockInfo.fFlags.RangeValid = 1;
4661 }
4662 else
4663 {
4664 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
4665// pAlloc->LockInfo.fFlags.RangeValid = 0;
4666 }
4667 }
4668 }
4669 else
4670 {
4671// Assert(pAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4672// if (pAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4673// {
4674// }
4675 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
4676 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
4677 {
4678 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
4679 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
4680 }
4681 Assert(pAlloc->LockInfo.LockedRect.pBits);
4682 }
4683
4684 if (hr == S_OK)
4685 {
4686 ++pAlloc->LockInfo.cLocks;
4687
4688 if (!pData->Flags.NotifyOnly)
4689 {
4690 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
4691 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
4692 pData->SlicePitch = 0;
4693 Assert(pAlloc->SurfDesc.slicePitch == 0);
4694 Assert(!pAlloc->pvMem);
4695 }
4696 else
4697 {
4698 Assert(pAlloc->pvMem);
4699 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4700 if (bLocked && !pData->Flags.Discard)
4701 {
4702 RECT r, *pr;
4703 if (pRange)
4704 {
4705 r.top = 0;
4706 r.left = pRange->Offset;
4707 r.bottom = 1;
4708 r.right = pRange->Offset + pRange->Size;
4709 pr = &r;
4710 }
4711 else
4712 pr = NULL;
4713 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
4714 }
4715 }
4716 }
4717 }
4718 else
4719 {
4720 Assert(0);
4721 }
4722 }
4723 else
4724 {
4725 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4726 D3DDDICB_LOCK LockData;
4727 LockData.hAllocation = pAlloc->hAllocation;
4728 LockData.PrivateDriverData = 0;
4729 LockData.NumPages = 0;
4730 LockData.pPages = NULL;
4731 LockData.pData = NULL; /* out */
4732 LockData.Flags.Value = 0;
4733 LockData.Flags.Discard = pData->Flags.Discard;
4734 LockData.Flags.DonotWait = pData->Flags.DoNotWait;
4735
4736
4737 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
4738 Assert(hr == S_OK || (hr == D3DERR_WASSTILLDRAWING && pData->Flags.DoNotWait));
4739 if (hr == S_OK)
4740 {
4741 Assert(!pAlloc->LockInfo.cLocks);
4742
4743 uintptr_t offset;
4744 if (pData->Flags.AreaValid)
4745 {
4746 offset = pAlloc->SurfDesc.pitch * pData->Area.top +
4747 ((pAlloc->SurfDesc.bpp * pData->Area.left) >> 3);
4748 }
4749 else if (pData->Flags.RangeValid)
4750 {
4751 offset = pData->Range.Offset;
4752 }
4753 else if (pData->Flags.BoxValid)
4754 {
4755 vboxVDbgPrintF((__FUNCTION__": Implement Box area"));
4756 Assert(0);
4757 }
4758 else
4759 {
4760 offset = 0;
4761 }
4762
4763 if (!pData->Flags.ReadOnly)
4764 {
4765 if (pData->Flags.AreaValid)
4766 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, &pData->Area);
4767 else
4768 {
4769 Assert(!pData->Flags.RangeValid);
4770 Assert(!pData->Flags.BoxValid);
4771 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, NULL); /* <- NULL means the entire surface */
4772 }
4773 }
4774
4775 if (pData->Flags.Discard)
4776 {
4777 /* check if the surface was renamed */
4778 if (LockData.hAllocation)
4779 pAlloc->hAllocation = LockData.hAllocation;
4780 }
4781
4782 pData->pSurfData = ((uint8_t*)LockData.pData) + offset;
4783 pData->Pitch = pAlloc->SurfDesc.pitch;
4784 pData->SlicePitch = pAlloc->SurfDesc.slicePitch;
4785
4786 Assert(hr == S_OK);
4787 ++pAlloc->LockInfo.cLocks;
4788 }
4789 }
4790
4791 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(%d)\n", hDevice, hr));
4792 return hr;
4793}
4794static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOCK* pData)
4795{
4796 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4797 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4798 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4799 Assert(pDevice);
4800 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4801 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4802 HRESULT hr = S_OK;
4803
4804 Assert(pData->SubResourceIndex < pRc->cAllocations);
4805 if (pData->SubResourceIndex >= pRc->cAllocations)
4806 return E_INVALIDARG;
4807
4808 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4809 {
4810 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
4811 {
4812 Assert(pData->SubResourceIndex < pRc->cAllocations);
4813 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4814
4815 --pLockAlloc->LockInfo.cLocks;
4816 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
4817// pLockAlloc->LockInfo.cLocks = 0;
4818 if (!pLockAlloc->LockInfo.cLocks)
4819 {
4820 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
4821// Assert(!pLockAlloc->LockInfo.cLocks);
4822 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
4823 Assert(pD3DIfTex);
4824 /* this is a sysmem texture, update */
4825#if 0
4826 if (pLockAlloc->pvMem && !pLockAlloc->LockInfo.fFlags.ReadOnly)
4827 {
4828 vboxWddmLockUnlockMemSynch(pLockAlloc, &pLockAlloc->LockInfo.LockedRect,
4829 pLockAlloc->LockInfo.fFlags.AreaValid ? &pLockAlloc->LockInfo.Area : NULL,
4830 true /*bool bToLockInfo*/);
4831 }
4832#endif
4833 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
4834 Assert(hr == S_OK);
4835 }
4836 else
4837 {
4838 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
4839 }
4840 }
4841 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
4842 {
4843 Assert(pData->SubResourceIndex < pRc->cAllocations);
4844 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4845
4846 --pAlloc->LockInfo.cLocks;
4847 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4848 if (!pAlloc->LockInfo.cLocks
4849 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
4850 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
4851 {
4852// Assert(!pAlloc->LockInfo.cLocks);
4853 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4854 Assert(pD3D9VBuf);
4855 /* this is a sysmem texture, update */
4856 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
4857 {
4858 RECT r, *pr;
4859 if (pAlloc->LockInfo.fFlags.RangeValid)
4860 {
4861 r.top = 0;
4862 r.left = pAlloc->LockInfo.Range.Offset;
4863 r.bottom = 1;
4864 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
4865 pr = &r;
4866 }
4867 else
4868 pr = NULL;
4869 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
4870 pr,
4871 true /*bool bToLockInfo*/);
4872 }
4873 hr = pD3D9VBuf->Unlock();
4874 Assert(hr == S_OK);
4875 }
4876 else
4877 {
4878 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4879 }
4880 }
4881 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
4882 {
4883 Assert(pData->SubResourceIndex < pRc->cAllocations);
4884 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4885
4886 --pAlloc->LockInfo.cLocks;
4887 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4888 if (!pAlloc->LockInfo.cLocks
4889 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
4890 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
4891 {
4892// Assert(!pAlloc->LockInfo.cLocks);
4893 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
4894 Assert(pD3D9IBuf);
4895 /* this is a sysmem texture, update */
4896 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
4897 {
4898 RECT r, *pr;
4899 if (pAlloc->LockInfo.fFlags.RangeValid)
4900 {
4901 r.top = 0;
4902 r.left = pAlloc->LockInfo.Range.Offset;
4903 r.bottom = 1;
4904 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
4905 pr = &r;
4906 }
4907 else
4908 pr = NULL;
4909 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
4910 pr,
4911 true /*bool bToLockInfo*/);
4912 }
4913 hr = pD3D9IBuf->Unlock();
4914 Assert(hr == S_OK);
4915 }
4916 else
4917 {
4918 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4919 }
4920 }
4921 else
4922 {
4923 Assert(0);
4924 }
4925 }
4926 else
4927 {
4928 struct
4929 {
4930 D3DDDICB_UNLOCK Unlock;
4931 D3DKMT_HANDLE hAllocation;
4932 } UnlockData;
4933
4934 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4935
4936 UnlockData.Unlock.NumAllocations = 1;
4937 UnlockData.Unlock.phAllocations = &UnlockData.hAllocation;
4938 UnlockData.hAllocation = pAlloc->hAllocation;
4939
4940 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &UnlockData.Unlock);
4941 Assert(hr == S_OK);
4942 if (hr == S_OK)
4943 {
4944 Assert(pAlloc->LockInfo.cLocks);
4945 --pAlloc->LockInfo.cLocks;
4946 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4947 }
4948 }
4949
4950 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4951 return hr;
4952}
4953static HRESULT APIENTRY vboxWddmDDevLockAsync(HANDLE hDevice, D3DDDIARG_LOCKASYNC* pData)
4954{
4955 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4956 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4957 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4958 Assert(pDevice);
4959 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4960 Assert(0);
4961 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4962 return E_FAIL;
4963}
4964static HRESULT APIENTRY vboxWddmDDevUnlockAsync(HANDLE hDevice, CONST D3DDDIARG_UNLOCKASYNC* pData)
4965{
4966 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4967 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4968 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4969 Assert(pDevice);
4970 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4971 Assert(0);
4972 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4973 return E_FAIL;
4974}
4975static HRESULT APIENTRY vboxWddmDDevRename(HANDLE hDevice, CONST D3DDDIARG_RENAME* pData)
4976{
4977 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4978 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4979 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4980 Assert(pDevice);
4981 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4982 Assert(0);
4983 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4984 return E_FAIL;
4985}
4986
4987static void vboxWddmRequestAllocFree(D3DDDICB_ALLOCATE* pAlloc)
4988{
4989 RTMemFree(pAlloc);
4990}
4991
4992static D3DDDICB_ALLOCATE* vboxWddmRequestAllocAlloc(D3DDDIARG_CREATERESOURCE* pResource)
4993{
4994 /* allocate buffer for D3DDDICB_ALLOCATE + D3DDDI_ALLOCATIONINFO * numAllocs + PVBOXWDDM_RCINFO with aAllocInfos[numAllocs] */
4995 uint32_t cbBuf = sizeof (D3DDDICB_ALLOCATE);
4996 uint32_t offDdiAllocInfos = (cbBuf + 7) & ~3;
4997 uint32_t cbDdiAllocInfos = sizeof (D3DDDI_ALLOCATIONINFO) * pResource->SurfCount;
4998 cbBuf = offDdiAllocInfos + cbDdiAllocInfos;
4999 uint32_t offRcInfo = (cbBuf + 7) & ~3;
5000 uint32_t cbRcInfo = sizeof (VBOXWDDM_RCINFO);
5001 cbBuf = offRcInfo + cbRcInfo;
5002 uint32_t offAllocInfos = (cbBuf + 7) & ~3;
5003 uint32_t cbAllocInfos = sizeof (VBOXWDDM_ALLOCINFO) * pResource->SurfCount;
5004 cbBuf = offAllocInfos + cbAllocInfos;
5005 uint8_t *pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
5006 Assert(pvBuf);
5007 if (pvBuf)
5008 {
5009 D3DDDICB_ALLOCATE* pAlloc = (D3DDDICB_ALLOCATE*)pvBuf;
5010 pAlloc->NumAllocations = pResource->SurfCount;
5011 pAlloc->pAllocationInfo = (D3DDDI_ALLOCATIONINFO*)(pvBuf + offDdiAllocInfos);
5012 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)(pvBuf + offRcInfo);
5013 pAlloc->PrivateDriverDataSize = cbRcInfo;
5014 pAlloc->pPrivateDriverData = pRcInfo;
5015 pAlloc->hResource = pResource->hResource;
5016 PVBOXWDDM_ALLOCINFO pAllocInfos = (PVBOXWDDM_ALLOCINFO)(pvBuf + offAllocInfos);
5017 for (UINT i = 0; i < pResource->SurfCount; ++i)
5018 {
5019 D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pAlloc->pAllocationInfo[i];
5020 PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
5021 pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
5022 pDdiAllocInfo->PrivateDriverDataSize = sizeof (VBOXWDDM_ALLOCINFO);
5023 }
5024 return pAlloc;
5025 }
5026 return NULL;
5027}
5028
5029static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE* pResource)
5030{
5031 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5032 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5033 HRESULT hr = S_OK;
5034 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5035 Assert(pDevice);
5036 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5037 Assert(pResource);
5038 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
5039
5040 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pResource->SurfCount);
5041 Assert(pRc);
5042 if (pRc)
5043 {
5044 bool bIssueCreateResource = false;
5045 bool bCreateSwapchain = false;
5046 bool bCreateKMResource = false;
5047
5048 pRc->hResource = pResource->hResource;
5049 pRc->hKMResource = NULL;
5050 pRc->pDevice = pDevice;
5051 pRc->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
5052 pRc->RcDesc.fFlags = pResource->Flags;
5053 pRc->RcDesc.enmFormat = pResource->Format;
5054 pRc->RcDesc.enmPool = pResource->Pool;
5055 pRc->RcDesc.enmMultisampleType = pResource->MultisampleType;
5056 pRc->RcDesc.MultisampleQuality = pResource->MultisampleQuality;
5057 pRc->RcDesc.MipLevels = pResource->MipLevels;
5058 pRc->RcDesc.Fvf = pResource->Fvf;
5059 pRc->RcDesc.VidPnSourceId = pResource->VidPnSourceId;
5060 pRc->RcDesc.RefreshRate = pResource->RefreshRate;
5061 pRc->RcDesc.enmRotation = pResource->Rotation;
5062 pRc->cAllocations = pResource->SurfCount;
5063 for (UINT i = 0; i < pResource->SurfCount; ++i)
5064 {
5065 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5066 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5067 pAllocation->hAllocation = NULL;
5068 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
5069 pAllocation->iAlloc = i;
5070 pAllocation->pRc = pRc;
5071 pAllocation->D3DWidth = pSurf->Width;
5072 pAllocation->pvMem = (void*)pSurf->pSysMem;
5073 pAllocation->SurfDesc.pitch = pSurf->SysMemPitch;
5074 pAllocation->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
5075 pAllocation->SurfDesc.depth = pSurf->Depth;
5076 pAllocation->SurfDesc.width = pSurf->Width;
5077 pAllocation->SurfDesc.height = pSurf->Height;
5078 pAllocation->SurfDesc.format = pResource->Format;
5079 }
5080
5081 if (VBOXDISPMODE_IS_3D(pAdapter))
5082 {
5083 if (pResource->Flags.SharedResource)
5084 {
5085 Assert(0); /* <-- need to test that */
5086 bIssueCreateResource = true;
5087 bCreateKMResource = true;
5088 }
5089
5090 if (pResource->Flags.ZBuffer)
5091 {
5092 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5093 for (UINT i = 0; i < pResource->SurfCount; ++i)
5094 {
5095 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5096 IDirect3DSurface9 *pD3D9Surf;
5097 hr = pDevice9If->CreateDepthStencilSurface(pAllocation->SurfDesc.width,
5098 pAllocation->SurfDesc.height,
5099 vboxDDI2D3DFormat(pResource->Format),
5100 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
5101 pResource->MultisampleQuality,
5102 TRUE /* @todo: BOOL Discard */,
5103 &pD3D9Surf,
5104 NULL /*HANDLE* pSharedHandle*/);
5105 Assert(hr == S_OK);
5106 if (hr == S_OK)
5107 {
5108 Assert(pD3D9Surf);
5109 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
5110 pAllocation->pD3DIf = pD3D9Surf;
5111 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
5112 Assert(hr == S_OK);
5113 }
5114 else
5115 {
5116 for (UINT j = 0; j < i; ++j)
5117 {
5118 pRc->aAllocations[j].pD3DIf->Release();
5119 }
5120 break;
5121 }
5122 }
5123 }
5124 else if (pResource->Flags.VertexBuffer)
5125 {
5126 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5127
5128 for (UINT i = 0; i < pResource->SurfCount; ++i)
5129 {
5130 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5131 IDirect3DVertexBuffer9 *pD3D9VBuf;
5132 hr = pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width,
5133 vboxDDI2D3DUsage(pResource->Flags),
5134 pResource->Fvf,
5135 vboxDDI2D3DPool(pResource->Pool),
5136 &pD3D9VBuf,
5137 NULL /*HANDLE* pSharedHandle*/);
5138 Assert(hr == S_OK);
5139 if (hr == S_OK)
5140 {
5141 Assert(pD3D9VBuf);
5142 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_VERTEXBUFFER;
5143 pAllocation->pD3DIf = pD3D9VBuf;
5144 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
5145 {
5146 Assert(pAllocation->pvMem);
5147 D3DLOCKED_RECT lockInfo;
5148 hr = pD3D9VBuf->Lock(0, pAllocation->SurfDesc.width, &lockInfo.pBits, D3DLOCK_DISCARD);
5149 Assert(hr == S_OK);
5150 if (hr == S_OK)
5151 {
5152 lockInfo.Pitch = pAllocation->SurfDesc.pitch;
5153 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
5154 HRESULT tmpHr = pD3D9VBuf->Unlock();
5155 Assert(tmpHr == S_OK);
5156 }
5157 }
5158 else
5159 {
5160 Assert(!pAllocation->pvMem);
5161 }
5162 }
5163 else
5164 {
5165 for (UINT j = 0; j < i; ++j)
5166 {
5167 pRc->aAllocations[j].pD3DIf->Release();
5168 }
5169 break;
5170 }
5171 }
5172 }
5173 else if (pResource->Flags.IndexBuffer)
5174 {
5175 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5176
5177 for (UINT i = 0; i < pResource->SurfCount; ++i)
5178 {
5179 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5180 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5181 IDirect3DIndexBuffer9 *pD3D9IBuf;
5182 hr = pDevice9If->CreateIndexBuffer(pSurf->Width,
5183 vboxDDI2D3DUsage(pResource->Flags),
5184 vboxDDI2D3DFormat(pResource->Format),
5185 vboxDDI2D3DPool(pResource->Pool),
5186 &pD3D9IBuf,
5187 NULL /*HANDLE* pSharedHandle*/
5188 );
5189 Assert(hr == S_OK);
5190 if (hr == S_OK)
5191 {
5192 Assert(pD3D9IBuf);
5193 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_INDEXBUFFER;
5194 pAllocation->pD3DIf = pD3D9IBuf;
5195 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
5196 {
5197 Assert(pAllocation->pvMem);
5198 D3DLOCKED_RECT lockInfo;
5199 hr = pD3D9IBuf->Lock(0, pAllocation->SurfDesc.width, &lockInfo.pBits, D3DLOCK_DISCARD);
5200 Assert(hr == S_OK);
5201 if (hr == S_OK)
5202 {
5203 lockInfo.Pitch = pAllocation->SurfDesc.pitch;
5204 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
5205 HRESULT tmpHr = pD3D9IBuf->Unlock();
5206 Assert(tmpHr == S_OK);
5207 }
5208 }
5209 else
5210 {
5211 Assert(!pAllocation->pvMem);
5212 }
5213 }
5214 else
5215 {
5216 for (UINT j = 0; j < i; ++j)
5217 {
5218 pRc->aAllocations[j].pD3DIf->Release();
5219 }
5220 break;
5221 }
5222 }
5223 }
5224 else if (pResource->Flags.Texture || pResource->Flags.Value == 0)
5225 {
5226 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5227
5228#ifdef DEBUG
5229 {
5230 uint32_t tstW = pResource->pSurfList[0].Width;
5231 uint32_t tstH = pResource->pSurfList[0].Height;
5232 for (UINT i = 1; i < pResource->SurfCount; ++i)
5233 {
5234 tstW /= 2;
5235 tstH /= 2;
5236 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5237 Assert((pSurf->Width == tstW) || (!tstW && (pSurf->Width==1)));
5238 Assert((pSurf->Height == tstH) || (!tstH && (pSurf->Height==1)));
5239 }
5240 }
5241#endif
5242
5243// if (pResource->Flags.RenderTarget)
5244// bIssueCreateResource = true;
5245
5246 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
5247 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[0];
5248 IDirect3DTexture9 *pD3DIfTex;
5249 HANDLE hSharedHandle = NULL;
5250 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
5251 {
5252 Assert(pSurf->pSysMem);
5253 Assert(pSurf->SysMemPitch);
5254 UINT bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
5255 Assert(bpp);
5256 if (bpp)
5257 {
5258 pAllocation->D3DWidth = ((pSurf->SysMemPitch << 3) / bpp);
5259 if ((pSurf->SysMemPitch << 3) % bpp)
5260 {
5261 Assert(0);
5262 ++pAllocation->D3DWidth;
5263 }
5264 Assert(pAllocation->D3DWidth >= pSurf->Width);
5265 }
5266 }
5267#if 0
5268 hr = pDevice9If->CreateTexture(pSurf->Width,
5269 pAllocation->D3DWidth,
5270 pResource->SurfCount,
5271 vboxDDI2D3DUsage(pResource->Flags),
5272 vboxDDI2D3DFormat(pResource->Format),
5273 vboxDDI2D3DPool(pResource->Pool),
5274 &pD3DIfTex,
5275 NULL /* HANDLE* pSharedHandle */
5276 );
5277#else
5278 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
5279 pAllocation->D3DWidth,
5280 pSurf->Height,
5281 pResource->SurfCount,
5282 vboxDDI2D3DUsage(pResource->Flags),
5283 vboxDDI2D3DFormat(pResource->Format),
5284 vboxDDI2D3DPool(pResource->Pool),
5285 &pD3DIfTex,
5286 pResource->Flags.SharedResource ? &hSharedHandle : NULL,
5287 pResource->Pool == D3DDDIPOOL_SYSTEMMEM ? pRc->aAllocations[0].pvMem : NULL);
5288#endif
5289 Assert(hr == S_OK);
5290 if (hr == S_OK)
5291 {
5292 Assert(pD3DIfTex);
5293 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
5294 pAllocation->pD3DIf = pD3DIfTex;
5295 Assert(!!(pResource->Flags.SharedResource) == !!(hSharedHandle));
5296 pAllocation->hSharedHandle = hSharedHandle;
5297#if 0
5298 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
5299 {
5300 for (UINT i = 0; i < pResource->SurfCount; ++i)
5301 {
5302 D3DLOCKED_RECT lockInfo;
5303 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5304 Assert(pAllocation->pvMem);
5305 hr = pD3DIfTex->LockRect(i, &lockInfo, NULL, D3DLOCK_DISCARD);
5306 Assert(hr == S_OK);
5307 if (hr == S_OK)
5308 {
5309 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
5310 HRESULT tmpHr = pD3DIfTex->UnlockRect(i);
5311 Assert(tmpHr == S_OK);
5312 }
5313 else
5314 {
5315 pD3DIfTex->Release();
5316 break;
5317 }
5318 }
5319 }
5320#endif
5321 }
5322#ifdef DEBUG
5323 else
5324 {
5325 for (UINT i = 0; i < pResource->SurfCount; ++i)
5326 {
5327 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5328 Assert(!pAllocation->pvMem);
5329 }
5330 }
5331#endif
5332 }
5333 else if (pResource->Flags.RenderTarget)
5334 {
5335 HWND hWnd = NULL;
5336 bIssueCreateResource = true;
5337 Assert(pResource->SurfCount);
5338 if (RTListIsEmpty(&pDevice->SwapchainList))
5339 {
5340 bCreateSwapchain = true;
5341 Assert(bIssueCreateResource);
5342 }
5343 else
5344 {
5345 for (UINT i = 0; i < pResource->SurfCount; ++i)
5346 {
5347 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5348
5349 IDirect3DSurface9* pD3D9Surf;
5350 hr = pDevice->pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
5351 pAllocation->SurfDesc.height,
5352 vboxDDI2D3DFormat(pResource->Format),
5353 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
5354 pResource->MultisampleQuality,
5355 !pResource->Flags.NotLockable /* BOOL Lockable */,
5356 &pD3D9Surf,
5357 NULL /* HANDLE* pSharedHandle */
5358 );
5359 Assert(hr == S_OK);
5360 if (hr == S_OK)
5361 {
5362 Assert(pD3D9Surf);
5363 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
5364 pAllocation->pD3DIf = pD3D9Surf;
5365 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
5366 Assert(hr == S_OK);
5367 if (hr == S_OK)
5368 {
5369#if 0
5370 if(pResource->Flags.Primary)
5371 {
5372 for (UINT i = 0; i < pResource->SurfCount; ++i)
5373 {
5374 vboxWddmSwapchainFindCreate(pDevice, &pRc->aAllocations[i]);
5375 }
5376 Assert(bIssueCreateResource);
5377 }
5378#endif
5379 continue;
5380 }
5381
5382 /* fail branch */
5383 pD3D9Surf->Release();
5384 }
5385
5386 for (UINT j = 0; j < i; ++j)
5387 {
5388 pRc->aAllocations[j].pD3DIf->Release();
5389 }
5390 break;
5391 }
5392 }
5393 }
5394 else
5395 {
5396// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5397// Assert(pScreen->hWnd);
5398// Assert(pScreen->pDevice9If);
5399 Assert(0);
5400 }
5401 }
5402 else
5403 {
5404 bIssueCreateResource = true;
5405 bCreateKMResource = true;
5406 }
5407
5408
5409 if (hr == S_OK && bIssueCreateResource)
5410 {
5411 D3DDDICB_ALLOCATE *pDdiAllocate = vboxWddmRequestAllocAlloc(pResource);
5412 Assert(pDdiAllocate);
5413 if (pDdiAllocate)
5414 {
5415 Assert(pDdiAllocate->pPrivateDriverData);
5416 Assert(pDdiAllocate->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
5417 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)pDdiAllocate->pPrivateDriverData;
5418 pRcInfo->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
5419 pRcInfo->RcDesc = pRc->RcDesc;
5420 pRcInfo->cAllocInfos = pResource->SurfCount;
5421
5422 for (UINT i = 0; i < pResource->SurfCount; ++i)
5423 {
5424 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
5425 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5426 Assert(pDdiAllocI->pPrivateDriverData);
5427 Assert(pDdiAllocI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
5428 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
5429 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5430 pDdiAllocI->hAllocation = NULL;
5431 pDdiAllocI->pSystemMem = pSurf->pSysMem;
5432 Assert((!!(pSurf->pSysMem)) == (pResource->Pool == D3DDDIPOOL_SYSTEMMEM));
5433 pDdiAllocI->VidPnSourceId = pResource->VidPnSourceId;
5434 pDdiAllocI->Flags.Value = 0;
5435 if (pResource->Flags.Primary)
5436 {
5437 Assert(pResource->Flags.RenderTarget);
5438 pDdiAllocI->Flags.Primary = 1;
5439 }
5440
5441 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
5442 pAllocInfo->fFlags = pResource->Flags;
5443 pAllocInfo->hSharedHandle = pAllocation->hSharedHandle;
5444 pAllocInfo->SurfDesc.width = pSurf->Width;
5445 pAllocInfo->SurfDesc.height = pSurf->Height;
5446 pAllocInfo->SurfDesc.format = pResource->Format;
5447 if (!vboxWddmFormatToFourcc(pResource->Format))
5448 pAllocInfo->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
5449 else
5450 pAllocInfo->SurfDesc.bpp = 0;
5451
5452 if (pSurf->SysMemPitch)
5453 {
5454 pAllocInfo->SurfDesc.pitch = pSurf->SysMemPitch;
5455#ifdef DEBUG
5456 UINT tst = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
5457 Assert(tst == pSurf->SysMemPitch);
5458#endif
5459 }
5460 else
5461 pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
5462
5463 pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
5464 pAllocInfo->SurfDesc.depth = pSurf->Depth;
5465 pAllocInfo->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
5466 pAllocInfo->SurfDesc.VidPnSourceId = pResource->VidPnSourceId;
5467 pAllocInfo->SurfDesc.RefreshRate = pResource->RefreshRate;
5468 }
5469
5470 if (bCreateKMResource)
5471 {
5472 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
5473 Assert(hr == S_OK);
5474 Assert(pDdiAllocate->hKMResource);
5475 }
5476 else
5477 {
5478 pDdiAllocate->hResource = NULL;
5479 pDdiAllocate->NumAllocations = 1;
5480 pDdiAllocate->PrivateDriverDataSize = 0;
5481 pDdiAllocate->pPrivateDriverData = NULL;
5482 D3DDDI_ALLOCATIONINFO *pDdiAllocIBase = pDdiAllocate->pAllocationInfo;
5483
5484 for (UINT i = 0; i < pResource->SurfCount; ++i)
5485 {
5486 pDdiAllocate->pAllocationInfo = &pDdiAllocIBase[i];
5487 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
5488 Assert(hr == S_OK);
5489 Assert(!pDdiAllocate->hKMResource);
5490 if (hr == S_OK)
5491 {
5492 Assert(pDdiAllocate->pAllocationInfo->hAllocation);
5493 }
5494 else
5495 {
5496 for (UINT j = 0; i < j; ++j)
5497 {
5498 D3DDDI_ALLOCATIONINFO * pCur = &pDdiAllocIBase[i];
5499 D3DDDICB_DEALLOCATE Dealloc;
5500 Dealloc.hResource = 0;
5501 Dealloc.NumAllocations = 1;
5502 Dealloc.HandleList = &pCur->hAllocation;
5503 HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5504 Assert(tmpHr == S_OK);
5505 }
5506 break;
5507 }
5508 }
5509
5510 pDdiAllocate->pAllocationInfo = pDdiAllocIBase;
5511 }
5512
5513 if (hr == S_OK)
5514 {
5515 pRc->hKMResource = pDdiAllocate->hKMResource;
5516
5517 for (UINT i = 0; i < pResource->SurfCount; ++i)
5518 {
5519 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5520 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
5521 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
5522 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5523 pAllocation->hAllocation = pDdiAllocI->hAllocation;
5524 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
5525 pAllocation->pvMem = (void*)pSurf->pSysMem;
5526 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
5527 }
5528
5529 if(bCreateSwapchain)
5530 {
5531 PVBOXWDDMDISP_SWAPCHAIN pSwapchain;
5532 hr = vboxWddmSwapchainCreateIfForRc(pDevice, pRc, &pSwapchain);
5533 Assert(hr == S_OK);
5534 }
5535 }
5536
5537 vboxWddmRequestAllocFree(pDdiAllocate);
5538 }
5539 else
5540 {
5541 hr = E_OUTOFMEMORY;
5542 }
5543 }
5544
5545 if (hr == S_OK)
5546 pResource->hResource = pRc;
5547 else
5548 vboxResourceFree(pRc);
5549 }
5550 else
5551 {
5552 hr = E_OUTOFMEMORY;
5553 }
5554
5555
5556 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5557 return hr;
5558}
5559
5560static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource)
5561{
5562 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5563 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5564 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5565 Assert(pDevice);
5566 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5567 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
5568 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hResource;
5569
5570 HRESULT hr = S_OK;
5571
5572 Assert(pDevice);
5573 Assert(hResource);
5574
5575 if (VBOXDISPMODE_IS_3D(pAdapter))
5576 {
5577// if (pRc->RcDesc.fFlags.RenderTarget)
5578// {
5579// Assert(pDevice->hWnd);
5580// Assert(pDevice->pDevice9If);
5581// }
5582
5583 for (UINT i = 0; i < pRc->cAllocations; ++i)
5584 {
5585 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
5586 if (pAlloc->pD3DIf)
5587 pAlloc->pD3DIf->Release();
5588 if (pAlloc->pSecondaryOpenedD3DIf)
5589 pAlloc->pSecondaryOpenedD3DIf->Release();
5590
5591 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
5592 if (pSwapchain)
5593 {
5594 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainRtForAlloc(pSwapchain, pAlloc);
5595 vboxWddmSwapchainRtRemove(pSwapchain, pRt);
5596 Assert(!vboxWddmSwapchainForAlloc(pAlloc));
5597 if (!vboxWddmSwapchainNumRTs(pSwapchain))
5598 vboxWddmSwapchainDestroy(pDevice, pSwapchain);
5599 }
5600
5601 EnterCriticalSection(&pDevice->DirtyAllocListLock);
5602 if (pAlloc->DirtyAllocListEntry.pNext)
5603 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
5604 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5605 }
5606 }
5607
5608 Assert(pRc->hResource);
5609 Assert(pRc->hKMResource || VBOXDISPMODE_IS_3D(pAdapter));
5610 if (pRc->hKMResource)
5611 {
5612 if (!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED))
5613 {
5614 D3DDDICB_DEALLOCATE Dealloc;
5615 Dealloc.hResource = pRc->hResource;
5616 /* according to the docs the below two are ignored in case we set the hResource */
5617 Dealloc.NumAllocations = 0;
5618 Dealloc.HandleList = NULL;
5619 hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5620 Assert(hr == S_OK);
5621 }
5622 }
5623 else
5624 {
5625 Assert(!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED));
5626 for (UINT j = 0; j < pRc->cAllocations; ++j)
5627 {
5628 if (pRc->aAllocations[j].hAllocation)
5629 {
5630 D3DDDICB_DEALLOCATE Dealloc;
5631 Dealloc.hResource = NULL;
5632 Dealloc.NumAllocations = 1;
5633 Dealloc.HandleList = &pRc->aAllocations[j].hAllocation;
5634 HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5635 Assert(tmpHr == S_OK);
5636 }
5637 }
5638 }
5639
5640 vboxResourceFree(pRc);
5641 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5642 return hr;
5643}
5644static HRESULT APIENTRY vboxWddmDDevSetDisplayMode(HANDLE hDevice, CONST D3DDDIARG_SETDISPLAYMODE* pData)
5645{
5646 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5647 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5648 HRESULT hr = S_OK;
5649 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5650 Assert(pDevice);
5651 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5652 Assert(VBOXDISPMODE_IS_3D(pDevice->pAdapter));
5653 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
5654 Assert(pRc);
5655 Assert(pRc->cAllocations > pData->SubResourceIndex);
5656 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
5657 Assert(pRc->RcDesc.fFlags.RenderTarget);
5658 Assert(pRc->RcDesc.fFlags.Primary);
5659 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5660 Assert(pAlloc->hAllocation);
5661// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5662// Assert(pScreen->hWnd);
5663// Assert(pScreen->pDevice9If);
5664 D3DDDICB_SETDISPLAYMODE DdiDm = {0};
5665 DdiDm.hPrimaryAllocation = pAlloc->hAllocation;
5666// DdiDm.PrivateDriverFormatAttribute = 0;
5667// Assert(pScreen->pRenderTargetRc == pRc);
5668// Assert(pScreen->iRenderTargetFrontBuf == pData->SubResourceIndex);
5669
5670#if 0
5671 IDirect3DSurface9 *pSoD3DIfSurf = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
5672 hr = pScreen->pDevice9If->SetRenderTarget(0, pSoD3DIfSurf);
5673 Assert(hr == S_OK);
5674 if (hr == S_OK)
5675#endif
5676 {
5677 hr = pDevice->RtCallbacks.pfnSetDisplayModeCb(pDevice->hDevice, &DdiDm);
5678 Assert(hr == S_OK);
5679#if 0
5680 if (hr == S_OK)
5681 {
5682 D3DDDICB_LOCK DdiLock = {0};
5683 DdiLock.hAllocation = pAlloc->hAllocation;
5684 DdiLock.Flags.LockEntire = 1;
5685 DdiLock.Flags.ReadOnly = 1;
5686 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &DdiLock);
5687 Assert(hr == S_OK);
5688 if (hr == S_OK)
5689 {
5690 D3DLOCKED_RECT LockRect;
5691 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pAlloc->pD3DIf;
5692 hr = pD3DIfSurf->LockRect(&LockRect, NULL /* RECT*/, D3DLOCK_DISCARD);
5693 Assert(hr == S_OK);
5694 if (hr == S_OK)
5695 {
5696 /** @todo: take pitch into account */
5697 Assert(pAlloc->SurfDesc.pitch == LockRect.Pitch);
5698 memcpy(LockRect.pBits, DdiLock.pData, LockRect.Pitch * pAlloc->SurfDesc.height);
5699 hr = pD3DIfSurf->UnlockRect();
5700 Assert(hr == S_OK);
5701 }
5702
5703 D3DDDICB_UNLOCK DdiUnlock = {0};
5704 DdiUnlock.NumAllocations = 1;
5705 DdiUnlock.phAllocations = &pAlloc->hAllocation;
5706 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock);
5707 Assert(hr == S_OK);
5708 }
5709 hr = S_OK;
5710 }
5711#endif
5712 }
5713
5714 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5715 return hr;
5716}
5717
5718#ifdef VBOXWDDM_TEST_UHGSMI
5719int vboxUhgsmiTst(PVBOXUHGSMI pUhgsmi, uint32_t cbBuf, uint32_t cNumCals, uint64_t * pTimeMs);
5720#endif
5721
5722static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRESENT* pData)
5723{
5724 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5725 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5726 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5727// VBOXDISPPROFILE_DDI_CHKDUMPRESET(pDevice);
5728 Assert(pDevice);
5729 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5730 HRESULT hr = S_OK;
5731 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
5732 {
5733#ifdef VBOXWDDM_TEST_UHGSMI
5734 {
5735// Assert(0);
5736 static uint32_t cCals = 100000;
5737 static uint32_t cbData = 8 * 1024 * 1024;
5738 uint64_t TimeMs;
5739 int rc = vboxUhgsmiTst(&pDevice->Uhgsmi.Base, cbData, cCals, &TimeMs);
5740 uint32_t cCPS = (((uint64_t)cCals) * 1000ULL)/TimeMs;
5741// Assert(0);
5742// vboxVDbgDoMpPrintF(pDevice, "Time : %I64u ms, calls: %d, cps: %d\n", TimeMs, cCals, cCPS);
5743 }
5744#endif
5745#if 1
5746 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5747 Assert(pRc);
5748 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
5749 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5750 hr = vboxWddmSwapchainPresent(pDevice, pAlloc);
5751 Assert(hr == S_OK);
5752#else
5753 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5754 Assert(pRc);
5755 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5756 Assert(pScreen->hWnd);
5757 Assert(pScreen->pDevice9If);
5758 Assert(pRc == pScreen->pRenderTargetRc);
5759#if 1
5760 VBOXVDBG_RTGT_STATECHECK(pDevice);
5761
5762 if (pRc->RcDesc.VidPnSourceId != pDevice->iPrimaryScreen)
5763 {
5764 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5765 PVBOXWDDMDISP_SCREEN pPrimaryScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5766 Assert(pPrimaryScreen->pDevice9If);
5767 IDirect3DSurface9 *pSecondaryRt;
5768 IDirect3DSurface9 *pDataRt = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
5769 Assert(pDataRt);
5770 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5771 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pPrimaryScreen->pDevice9If);
5772 Assert(hr == S_OK);
5773 if (hr == S_OK)
5774 {
5775 hr = pScreen->pDevice9If->GetRenderTarget(0, &pSecondaryRt);
5776 Assert(hr == S_OK);
5777 if (hr == S_OK)
5778 {
5779 hr = pScreen->pDevice9If->StretchRect(pDataRt,
5780 NULL,
5781 pSecondaryRt,
5782 NULL,
5783 D3DTEXF_NONE);
5784 pSecondaryRt->Release();
5785 }
5786 }
5787 }
5788
5789 hr = pScreen->pDevice9If->Present(NULL, /* CONST RECT * pSourceRect */
5790 NULL, /* CONST RECT * pDestRect */
5791 NULL, /* HWND hDestWindowOverride */
5792 NULL /*CONST RGNDATA * pDirtyRegion */
5793 );
5794 Assert(hr == S_OK);
5795#endif
5796#endif
5797 }
5798#if 0
5799 else
5800#endif
5801 {
5802// if (pData->Flags.Flip)
5803// {
5804// Assert(pData->hSrcResource);
5805// PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5806// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5807// Assert(pScreen->hWnd);
5808// Assert(pScreen->pDevice9If);
5809// Assert(pScreen->pRenderTargetRc == pRc);
5810// Assert(pRc->cAllocations >= 2);
5811// Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5812// Assert(pRc->RcDesc.fFlags.RenderTarget);
5813// uint32_t iNewRTFB = (pScreen->iRenderTargetFrontBuf + 1) % pRc->cAllocations;
5814//
5815// Assert(pScreen->iRenderTargetFrontBuf != iNewRTFB);
5816// Assert(pData->SrcSubResourceIndex == iNewRTFB);
5817//
5818// vboxWddmRenderTargetUpdate(pDevice, pRc, iNewRTFB);
5819//
5820// /* assign a new frontbuffer index */
5821// pScreen->iRenderTargetFrontBuf = iNewRTFB;
5822//
5823// VBOXVDBG_RTGT_STATECHECK(pDevice);
5824// }
5825 D3DDDICB_PRESENT DdiPresent = {0};
5826 if (pData->hSrcResource)
5827 {
5828 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5829 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
5830 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5831 Assert(pAlloc->hAllocation);
5832 DdiPresent.hSrcAllocation = pAlloc->hAllocation;
5833 }
5834 if (pData->hDstResource)
5835 {
5836 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
5837 Assert(pRc->cAllocations > pData->DstSubResourceIndex);
5838 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->DstSubResourceIndex];
5839 Assert(pAlloc->hAllocation);
5840 DdiPresent.hDstAllocation = pAlloc->hAllocation;
5841 }
5842 DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext;
5843// DdiPresent.BroadcastContextCount;
5844// DdiPresent.BroadcastContext[D3DDDI_MAX_BROADCAST_CONTEXT];
5845
5846 hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent);
5847 Assert(hr == S_OK);
5848 }
5849
5850 VBOXDISPPROFILE_DDI_REPORT_FRAME(pDevice);
5851
5852 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5853 return hr;
5854}
5855
5856typedef struct VBOXWDDMDISP_NSCADD
5857{
5858 VOID* pvCommandBuffer;
5859 UINT cbCommandBuffer;
5860 D3DDDI_ALLOCATIONLIST* pAllocationList;
5861 UINT cAllocationList;
5862 D3DDDI_PATCHLOCATIONLIST* pPatchLocationList;
5863 UINT cPatchLocationList;
5864 UINT cAllocations;
5865}VBOXWDDMDISP_NSCADD, *PVBOXWDDMDISP_NSCADD;
5866
5867static HRESULT vboxWddmNSCAddAlloc(PVBOXWDDMDISP_NSCADD pData, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bWrite)
5868{
5869 HRESULT hr = S_OK;
5870 if (pData->cAllocationList && pData->cPatchLocationList && pData->cbCommandBuffer > 4)
5871 {
5872 memset(pData->pAllocationList, 0, sizeof (D3DDDI_ALLOCATIONLIST));
5873 pData->pAllocationList[0].hAllocation = pAlloc->hAllocation;
5874 if (bWrite)
5875 pData->pAllocationList[0].WriteOperation = 1;
5876
5877 memset(pData->pPatchLocationList, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
5878 pData->pPatchLocationList[0].PatchOffset = pData->cAllocations*4;
5879 pData->pPatchLocationList[0].AllocationIndex = pData->cAllocations;
5880
5881 pData->cbCommandBuffer -= 4;
5882 --pData->cAllocationList;
5883 --pData->cPatchLocationList;
5884 ++pData->cAllocations;
5885
5886 ++pData->pAllocationList;
5887 ++pData->pPatchLocationList;
5888 pData->pvCommandBuffer = (VOID*)(((uint8_t*)pData->pvCommandBuffer) + 4);
5889
5890 }
5891 else
5892 hr = S_FALSE;
5893
5894 return hr;
5895}
5896
5897static HRESULT vboxWddmNotifySharedChange(PVBOXWDDMDISP_DEVICE pDevice)
5898{
5899 VBOXWDDMDISP_NSCADD NscAdd;
5900 BOOL bReinitRenderData = TRUE;
5901
5902 do
5903 {
5904 if (bReinitRenderData)
5905 {
5906 NscAdd.pvCommandBuffer = pDevice->DefaultContext.ContextInfo.pCommandBuffer;
5907 NscAdd.cbCommandBuffer = pDevice->DefaultContext.ContextInfo.CommandBufferSize;
5908 NscAdd.pAllocationList = pDevice->DefaultContext.ContextInfo.pAllocationList;
5909 NscAdd.cAllocationList = pDevice->DefaultContext.ContextInfo.AllocationListSize;
5910 NscAdd.pPatchLocationList = pDevice->DefaultContext.ContextInfo.pPatchLocationList;
5911 NscAdd.cPatchLocationList = pDevice->DefaultContext.ContextInfo.PatchLocationListSize;
5912 NscAdd.cAllocations = 0;
5913 Assert(NscAdd.cbCommandBuffer >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR));
5914 if (NscAdd.cbCommandBuffer < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
5915 return E_FAIL;
5916
5917 PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pHdr = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)NscAdd.pvCommandBuffer;
5918 pHdr->enmCmd = VBOXVDMACMD_TYPE_DMA_NOP;
5919 NscAdd.pvCommandBuffer = (VOID*)(((uint8_t*)NscAdd.pvCommandBuffer) + sizeof (*pHdr));
5920 NscAdd.cbCommandBuffer -= sizeof (*pHdr);
5921 bReinitRenderData = FALSE;
5922 }
5923
5924 EnterCriticalSection(&pDevice->DirtyAllocListLock);
5925
5926 PVBOXWDDMDISP_ALLOCATION pAlloc = RTListNodeGetFirst(&pDevice->DirtyAllocList, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry);
5927 if (pAlloc)
5928 {
5929 HRESULT tmpHr = vboxWddmNSCAddAlloc(&NscAdd, pAlloc, TRUE);
5930 Assert(tmpHr == S_OK || tmpHr == S_FALSE);
5931 if (tmpHr == S_OK)
5932 {
5933 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
5934 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5935 continue;
5936 }
5937
5938 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5939
5940 }
5941 else
5942 {
5943 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5944 if (!NscAdd.cAllocations)
5945 break;
5946 }
5947
5948 D3DDDICB_RENDER RenderData = {0};
5949 RenderData.CommandLength = pDevice->DefaultContext.ContextInfo.CommandBufferSize - NscAdd.cbCommandBuffer;
5950 Assert(RenderData.CommandLength);
5951 Assert(RenderData.CommandLength < UINT32_MAX/2);
5952 RenderData.CommandOffset = 0;
5953 RenderData.NumAllocations = pDevice->DefaultContext.ContextInfo.AllocationListSize - NscAdd.cAllocationList;
5954 Assert(RenderData.NumAllocations == NscAdd.cAllocations);
5955 RenderData.NumPatchLocations = pDevice->DefaultContext.ContextInfo.PatchLocationListSize - NscAdd.cPatchLocationList;
5956 Assert(RenderData.NumPatchLocations == NscAdd.cAllocations);
5957// RenderData.NewCommandBufferSize = sizeof (VBOXVDMACMD) + 4 * (100);
5958// RenderData.NewAllocationListSize = 100;
5959// RenderData.NewPatchLocationListSize = 100;
5960 RenderData.hContext = pDevice->DefaultContext.ContextInfo.hContext;
5961
5962 HRESULT hr = pDevice->RtCallbacks.pfnRenderCb(pDevice->hDevice, &RenderData);
5963 Assert(hr == S_OK);
5964 if (hr == S_OK)
5965 {
5966 pDevice->DefaultContext.ContextInfo.CommandBufferSize = RenderData.NewCommandBufferSize;
5967 pDevice->DefaultContext.ContextInfo.pCommandBuffer = RenderData.pNewCommandBuffer;
5968 pDevice->DefaultContext.ContextInfo.AllocationListSize = RenderData.NewAllocationListSize;
5969 pDevice->DefaultContext.ContextInfo.pAllocationList = RenderData.pNewAllocationList;
5970 pDevice->DefaultContext.ContextInfo.PatchLocationListSize = RenderData.NewPatchLocationListSize;
5971 pDevice->DefaultContext.ContextInfo.pPatchLocationList = RenderData.pNewPatchLocationList;
5972 bReinitRenderData = TRUE;
5973 }
5974 else
5975 break;
5976 } while (1);
5977
5978 return S_OK;
5979}
5980
5981static HRESULT APIENTRY vboxWddmDDevFlush(HANDLE hDevice)
5982{
5983 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5984 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5985 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5986 Assert(pDevice);
5987 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5988 HRESULT hr = S_OK;
5989 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
5990 {
5991// Assert(pDevice->cScreens);
5992// UINT cProcessed = 0;
5993// for (UINT i = 0; cProcessed < pDevice->cScreens && i < RT_ELEMENTS(pDevice->aScreens); ++i)
5994// {
5995// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i];
5996// if (pScreen->pDevice9If)
5997// {
5998// ++cProcessed;
5999//// if (pScreen->pRenderTargetRc->cAllocations == 1)
6000//// {
6001//// hr = pScreen->pDevice9If->Present(NULL, NULL, NULL, NULL);
6002//// Assert(hr == S_OK);
6003//// }
6004//// else
6005 {
6006 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pDevice->pDevice9If);
6007 Assert(hr == S_OK);
6008 }
6009// }
6010// }
6011
6012 vboxWddmNotifySharedChange(pDevice);
6013 }
6014 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6015 return hr;
6016}
6017
6018AssertCompile(sizeof (D3DDDIVERTEXELEMENT) == sizeof (D3DVERTEXELEMENT9));
6019AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Stream) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Stream));
6020AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Offset) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Offset));
6021AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Type) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Type));
6022AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Method) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Method));
6023AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Usage) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Usage));
6024AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, UsageIndex) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, UsageIndex));
6025
6026AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Stream) == RT_OFFSETOF(D3DVERTEXELEMENT9, Stream));
6027AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Offset) == RT_OFFSETOF(D3DVERTEXELEMENT9, Offset));
6028AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Type) == RT_OFFSETOF(D3DVERTEXELEMENT9, Type));
6029AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Method) == RT_OFFSETOF(D3DVERTEXELEMENT9, Method));
6030AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Usage) == RT_OFFSETOF(D3DVERTEXELEMENT9, Usage));
6031AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, UsageIndex) == RT_OFFSETOF(D3DVERTEXELEMENT9, UsageIndex));
6032
6033static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderDecl(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERDECL* pData, CONST D3DDDIVERTEXELEMENT* pVertexElements)
6034{
6035 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6036 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6037 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6038 Assert(pDevice);
6039 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6040 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6041 IDirect3DVertexDeclaration9 *pDecl;
6042 static D3DVERTEXELEMENT9 DeclEnd = D3DDECL_END();
6043 D3DVERTEXELEMENT9* pVe;
6044 HRESULT hr = S_OK;
6045 bool bFreeVe = false;
6046 if(memcmp(&DeclEnd, &pVertexElements[pData->NumVertexElements], sizeof (DeclEnd)))
6047 {
6048 pVe = (D3DVERTEXELEMENT9*)RTMemAlloc(sizeof (D3DVERTEXELEMENT9) * (pData->NumVertexElements + 1));
6049 if (pVe)
6050 {
6051 memcpy(pVe, pVertexElements, sizeof (D3DVERTEXELEMENT9) * pData->NumVertexElements);
6052 pVe[pData->NumVertexElements] = DeclEnd;
6053 bFreeVe = true;
6054 }
6055 else
6056 hr = E_OUTOFMEMORY;
6057 }
6058 else
6059 pVe = (D3DVERTEXELEMENT9*)pVertexElements;
6060
6061 if (hr == S_OK)
6062 {
6063 hr = pDevice9If->CreateVertexDeclaration(
6064 pVe,
6065 &pDecl
6066 );
6067 Assert(hr == S_OK);
6068 if (hr == S_OK)
6069 {
6070 Assert(pDecl);
6071 pData->ShaderHandle = pDecl;
6072 }
6073 }
6074
6075 if (bFreeVe)
6076 RTMemFree((void*)pVe);
6077
6078 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6079 return hr;
6080}
6081static HRESULT APIENTRY vboxWddmDDevSetVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
6082{
6083 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6084 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6085 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6086 Assert(pDevice);
6087 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6088 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6089 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
6090 Assert(pDecl);
6091 HRESULT hr = pDevice9If->SetVertexDeclaration(pDecl);
6092 Assert(hr == S_OK);
6093 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6094 return hr;
6095}
6096static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
6097{
6098 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6099 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6100 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6101 Assert(pDevice);
6102 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6103 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
6104 HRESULT hr = S_OK;
6105 pDecl->Release();
6106 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6107 return hr;
6108}
6109static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderFunc(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERFUNC* pData, CONST UINT* pCode)
6110{
6111 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6112 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6113 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6114 Assert(pDevice);
6115 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6116 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6117 IDirect3DVertexShader9 *pShader;
6118 Assert(*((UINT*)((uint8_t*)pCode + pData->Size-4)) == 0x0000FFFF /* end token */);
6119 HRESULT hr = pDevice9If->CreateVertexShader((const DWORD *)pCode, &pShader);
6120 Assert(hr == S_OK);
6121 if (hr == S_OK)
6122 {
6123 Assert(pShader);
6124 pData->ShaderHandle = pShader;
6125 }
6126 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6127 return hr;
6128}
6129static HRESULT APIENTRY vboxWddmDDevSetVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
6130{
6131 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6132 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6133 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6134 Assert(pDevice);
6135 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6136 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6137 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
6138 Assert(pShader);
6139 HRESULT hr = pDevice9If->SetVertexShader(pShader);
6140 Assert(hr == S_OK);
6141 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6142 return hr;
6143}
6144static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
6145{
6146 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6147 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6148 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6149 Assert(pDevice);
6150 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6151 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
6152 HRESULT hr = S_OK;
6153 pShader->Release();
6154 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6155 return hr;
6156}
6157static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTI* pData, CONST INT* pRegisters)
6158{
6159 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6160 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6161 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6162 Assert(pDevice);
6163 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6164 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6165 HRESULT hr = pDevice9If->SetVertexShaderConstantI(pData->Register, pRegisters, pData->Count);
6166 Assert(hr == S_OK);
6167 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6168 return hr;
6169}
6170static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTB* pData, CONST BOOL* pRegisters)
6171{
6172 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6173 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6174 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6175 Assert(pDevice);
6176 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6177 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6178 HRESULT hr = pDevice9If->SetVertexShaderConstantB(pData->Register, pRegisters, pData->Count);
6179 Assert(hr == S_OK);
6180 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6181 return hr;
6182}
6183static HRESULT APIENTRY vboxWddmDDevSetScissorRect(HANDLE hDevice, CONST RECT* pRect)
6184{
6185 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6186 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6187 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6188 Assert(pDevice);
6189 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6190 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6191 HRESULT hr = pDevice9If->SetScissorRect(pRect);
6192 Assert(hr == S_OK);
6193 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6194 return hr;
6195}
6196static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCE* pData)
6197{
6198 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6199 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6200 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6201 Assert(pDevice);
6202 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6203 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6204 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hVertexBuffer;
6205 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
6206 IDirect3DVertexBuffer9 *pStreamData = NULL;
6207 if (pRc)
6208 {
6209 Assert(pRc->cAllocations == 1);
6210 pAlloc = &pRc->aAllocations[0];
6211 Assert(pAlloc->pD3DIf);
6212 pStreamData = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
6213 }
6214 HRESULT hr = pDevice9If->SetStreamSource(pData->Stream, pStreamData, pData->Offset, pData->Stride);
6215 Assert(hr == S_OK);
6216 Assert(pData->Stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS);
6217 if (hr == S_OK)
6218 {
6219 if (pDevice->aStreamSource[pData->Stream] && !pAlloc)
6220 {
6221 --pDevice->cStreamSources;
6222 Assert(pDevice->cStreamSources < UINT32_MAX/2);
6223 }
6224 else if (!pDevice->aStreamSource[pData->Stream] && pAlloc)
6225 {
6226 ++pDevice->cStreamSources;
6227 Assert(pDevice->cStreamSources <= RT_ELEMENTS(pDevice->aStreamSource));
6228 }
6229 pDevice->aStreamSource[pData->Stream] = pAlloc;
6230 pDevice->StreamSourceInfo[pData->Stream].uiOffset = pData->Offset;
6231 pDevice->StreamSourceInfo[pData->Stream].uiStride = pData->Stride;
6232 }
6233 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6234 return hr;
6235}
6236static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData)
6237{
6238 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6239 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6240 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6241 Assert(pDevice);
6242 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6243 Assert(0);
6244 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6245 return E_FAIL;
6246}
6247static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData)
6248{
6249 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6250 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6251 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6252 Assert(pDevice);
6253 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6254 Assert(0);
6255 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6256 return E_FAIL;
6257}
6258static HRESULT APIENTRY vboxWddmDDevComposeRects(HANDLE hDevice, CONST D3DDDIARG_COMPOSERECTS* pData)
6259{
6260 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6261 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6262 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6263 Assert(pDevice);
6264 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6265 Assert(0);
6266 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6267 return E_FAIL;
6268}
6269static HRESULT vboxWddmLockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc,
6270 D3DLOCKED_RECT * pLockedRect,
6271 CONST RECT *pRect,
6272 DWORD fLockFlags)
6273{
6274 HRESULT hr = E_FAIL;
6275 Assert(!pRc->aAllocations[iAlloc].LockInfo.cLocks);
6276 Assert(pRc->cAllocations > iAlloc);
6277 switch (pRc->aAllocations[0].enmD3DIfType)
6278 {
6279 case VBOXDISP_D3DIFTYPE_SURFACE:
6280 {
6281 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
6282 Assert(pD3DIfSurf);
6283 hr = pD3DIfSurf->LockRect(pLockedRect, pRect, fLockFlags);
6284 Assert(hr == S_OK);
6285 break;
6286 }
6287 case VBOXDISP_D3DIFTYPE_TEXTURE:
6288 {
6289 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
6290 Assert(pD3DIfTex);
6291 hr = pD3DIfTex->LockRect(iAlloc, pLockedRect, pRect, fLockFlags);
6292 Assert(hr == S_OK);
6293 break;
6294 }
6295 default:
6296 Assert(0);
6297 break;
6298 }
6299 return hr;
6300}
6301static HRESULT vboxWddmUnlockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc)
6302{
6303 HRESULT hr = S_OK;
6304 Assert(pRc->cAllocations > iAlloc);
6305 switch (pRc->aAllocations[0].enmD3DIfType)
6306 {
6307 case VBOXDISP_D3DIFTYPE_SURFACE:
6308 {
6309 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
6310 Assert(pD3DIfSurf);
6311 hr = pD3DIfSurf->UnlockRect();
6312 Assert(hr == S_OK);
6313 break;
6314 }
6315 case VBOXDISP_D3DIFTYPE_TEXTURE:
6316 {
6317 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
6318 Assert(pD3DIfTex);
6319 hr = pD3DIfTex->UnlockRect(iAlloc);
6320 Assert(hr == S_OK);
6321 break;
6322 }
6323 default:
6324 Assert(0);
6325 hr = E_FAIL;
6326 break;
6327 }
6328 return hr;
6329}
6330
6331static HRESULT APIENTRY vboxWddmDDevBlt(HANDLE hDevice, CONST D3DDDIARG_BLT* pData)
6332{
6333 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6334 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6335 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6336 Assert(pDevice);
6337 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6338// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
6339 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6340 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
6341 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
6342 Assert(pDstRc->cAllocations > pData->DstSubResourceIndex);
6343 Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex);
6344 HRESULT hr = S_OK;
6345 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
6346 PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
6347 PVBOXWDDMDISP_SWAPCHAIN pSrcSwapchain = vboxWddmSwapchainForAlloc(pSrcAlloc);
6348 PVBOXWDDMDISP_SWAPCHAIN pDstSwapchain = vboxWddmSwapchainForAlloc(pDstAlloc);
6349 Assert(!pDstSwapchain || vboxWddmSwapchainGetFb(pDstSwapchain)->pAlloc != pDstAlloc);
6350 /* try StretchRect */
6351 IDirect3DSurface9 *pSrcSurfIf = NULL;
6352 IDirect3DSurface9 *pDstSurfIf = NULL;
6353 hr = vboxWddmSurfGet(pDstRc, pData->DstSubResourceIndex, &pDstSurfIf);
6354 Assert(hr == S_OK);
6355 if (hr == S_OK)
6356 {
6357 Assert(pDstSurfIf);
6358 do
6359 {
6360#ifndef VBOXWDDM_WITH_VISIBLE_FB
6361 if (pSrcSwapchain
6362 && pSrcSwapchain->pRenderTargetFbCopy
6363 && vboxWddmSwapchainGetFb(pSrcSwapchain)->pAlloc == pSrcAlloc
6364# ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
6365 && vboxWddmSwapchainNumRTs(pSrcSwapchain) > 1 /* work-around wine backbuffer */
6366# endif
6367 )
6368 {
6369// Assert(pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width);
6370// Assert(pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height);
6371// Assert(pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format);
6372// Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
6373// Assert(pSrcAlloc->SurfDesc.pitch == pDstAlloc->SurfDesc.pitch);
6374// Assert(pSrcAlloc->SurfDesc.depth == pDstAlloc->SurfDesc.depth);
6375// Assert(pSrcAlloc->SurfDesc.slicePitch == pDstAlloc->SurfDesc.slicePitch);
6376// Assert(pSrcAlloc->SurfDesc.cbSize == pDstAlloc->SurfDesc.cbSize);
6377// Assert(pData->DstRect.left == 0);
6378// Assert(pData->DstRect.top == 0);
6379// Assert(pData->DstRect.right == pDstAlloc->SurfDesc.width);
6380// Assert(pData->DstRect.bottom == pDstAlloc->SurfDesc.height);
6381// Assert(pData->SrcRect.left == 0);
6382// Assert(pData->SrcRect.top == 0);
6383// Assert(pData->SrcRect.right == pSrcAlloc->SurfDesc.width);
6384// Assert(pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height);
6385# if 0
6386 if (pData->DstRect.left == 0 && pData->DstRect.top == 0
6387 && pData->DstRect.right == pDstAlloc->SurfDesc.width
6388 && pData->DstRect.bottom == pDstAlloc->SurfDesc.height
6389 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
6390 && pData->SrcRect.right == pSrcAlloc->SurfDesc.width
6391 && pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height
6392 && pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width
6393 && pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height
6394 && pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format)
6395 {
6396 hr = pDevice9If->GetFrontBufferData(0, pDstSurfIf);
6397 Assert(hr == S_OK);
6398 break;
6399 }
6400 else
6401# endif
6402 {
6403 pSrcSurfIf = pSrcSwapchain->pRenderTargetFbCopy;
6404 Assert(pSrcSurfIf);
6405 if (!pSrcSwapchain->bRTFbCopyUpToDate)
6406 {
6407 hr = pSrcSwapchain->pSwapChainIf->GetFrontBufferData(pSrcSurfIf);
6408 Assert(hr == S_OK);
6409 if (hr == S_OK)
6410 {
6411 /* do pSrcSurfIf->AddRef since we do a Release in the following if (hr == S_OK) branch */
6412 pSrcSwapchain->bRTFbCopyUpToDate = TRUE;
6413 pSrcSurfIf->AddRef();
6414 }
6415 }
6416 else
6417 {
6418 pSrcSurfIf->AddRef();
6419 }
6420 }
6421 }
6422 else
6423#endif
6424 {
6425 hr = vboxWddmSurfGet(pSrcRc, pData->SrcSubResourceIndex, &pSrcSurfIf);
6426 Assert(hr == S_OK);
6427 }
6428
6429 if (hr == S_OK)
6430 {
6431 Assert(pSrcSurfIf);
6432#ifdef DEBUG_misha
6433 bool bDo = false;
6434
6435 if (g_VDbgTstDumpEnable)
6436 {
6437 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
6438 {
6439 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
6440 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
6441 {
6442 D3DSURFACE_DESC SrcDesc;
6443 HRESULT hr = pSrcSurfIf->GetDesc(&SrcDesc);
6444 Assert(hr == S_OK);
6445 if (hr == S_OK)
6446 {
6447 D3DSURFACE_DESC DstDesc;
6448 hr = pDstSurfIf->GetDesc(&DstDesc);
6449 Assert(hr == S_OK);
6450 if (hr == S_OK)
6451 {
6452 if (SrcDesc.Width == DstDesc.Width
6453 && SrcDesc.Height == DstDesc.Height)
6454 {
6455 bDo = true;
6456 }
6457 }
6458 }
6459 }
6460 }
6461 }
6462
6463 if (bDo)
6464 {
6465 vboxVDbgDumpSurfData((pDevice, "Blt-pre Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
6466 vboxVDbgDumpSurfData((pDevice, "Blt-pre Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
6467 }
6468#endif
6469 /* we support only Point & Linear, we ignore [Begin|Continue|End]PresentToDwm */
6470 Assert((pData->Flags.Value & (~(0x00000100 | 0x00000200 | 0x00000400 | 0x00000001 | 0x00000002))) == 0);
6471 hr = pDevice9If->StretchRect(pSrcSurfIf,
6472 &pData->SrcRect,
6473 pDstSurfIf,
6474 &pData->DstRect,
6475 vboxDDI2D3DBltFlags(pData->Flags));
6476 Assert(hr == S_OK);
6477
6478#ifdef DEBUG_misha
6479 if (bDo)
6480 {
6481 vboxVDbgDumpSurfData((pDevice, "Blt-post Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
6482 vboxVDbgDumpSurfData((pDevice, "Blt-post Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
6483 }
6484#endif
6485 pSrcSurfIf->Release();
6486 }
6487 } while (0);
6488
6489 pDstSurfIf->Release();
6490 }
6491
6492 if (hr != S_OK)
6493 {
6494 /* todo: fallback to memcpy or whatever ? */
6495 Assert(0);
6496 }
6497
6498
6499#if 0
6500 if ((use pAlloc->enmD3DIfType instead!!! pDstRc->RcDesc.fFlags.Texture || pDstRc->RcDesc.fFlags.Value == 0)
6501 && (pSrcRc->RcDesc.fFlags.Texture || pSrcRc->RcDesc.fFlags.Value == 0))
6502 {
6503 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcAlloc->pD3DIf;
6504 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstAlloc->pD3DIf;
6505 Assert(pD3DIfSrcTex);
6506 Assert(pD3DIfDstTex);
6507
6508 if (pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat)
6509 {
6510 if (pSrcRc->aAllocations[0].SurfDesc.width == pDstRc->aAllocations[0].SurfDesc.width
6511 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
6512 && pData->DstRect.left == 0 && pData->DstRect.top == 0
6513 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
6514 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
6515 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height
6516 && pData->DstRect.right - pData->DstRect.left == pDstRc->aAllocations[0].SurfDesc.width
6517 && pData->DstRect.bottom - pData->DstRect.top == pDstRc->aAllocations[0].SurfDesc.height
6518 )
6519 {
6520 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
6521 Assert(hr == S_OK);
6522 }
6523 else if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
6524 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
6525 {
6526 Assert(pDstAlloc->SurfDesc.bpp);
6527 Assert(pSrcAlloc->SurfDesc.bpp);
6528 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
6529 D3DLOCKED_RECT DstRect, SrcRect;
6530 Assert(!pSrcAlloc->LockInfo.cLocks);
6531 Assert(!pDstAlloc->LockInfo.cLocks);
6532 hr = pD3DIfDstTex->LockRect(pData->DstSubResourceIndex, &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
6533 Assert(hr == S_OK);
6534 if (hr == S_OK)
6535 {
6536 hr = pD3DIfSrcTex->LockRect(pData->SrcSubResourceIndex, &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
6537 Assert(hr == S_OK);
6538 if (hr == S_OK)
6539 {
6540 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
6541 &pData->DstRect, &pData->SrcRect,
6542 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
6543 Assert(hr == S_OK);
6544
6545 pD3DIfSrcTex->UnlockRect(pData->SrcSubResourceIndex);
6546 }
6547 pD3DIfDstTex->UnlockRect(pData->DstSubResourceIndex);
6548 }
6549 }
6550 else
6551 {
6552
6553 Assert(0);
6554 /* @todo: impl */
6555 }
6556 }
6557 else
6558 {
6559 Assert(0);
6560 /* @todo: impl */
6561 }
6562 }
6563 else
6564 {
6565 if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
6566 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
6567 {
6568 Assert(pDstAlloc->SurfDesc.bpp);
6569 Assert(pSrcAlloc->SurfDesc.bpp);
6570 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
6571
6572 D3DLOCKED_RECT DstRect, SrcRect;
6573 hr = vboxWddmLockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags,
6574 &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
6575 Assert(hr == S_OK);
6576 if (hr == S_OK)
6577 {
6578 hr = vboxWddmLockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags,
6579 &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
6580 Assert(hr == S_OK);
6581 if (hr == S_OK)
6582 {
6583 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
6584 &pData->DstRect, &pData->SrcRect,
6585 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
6586 Assert(hr == S_OK);
6587
6588 HRESULT tmpHr = vboxWddmUnlockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags);
6589 Assert(tmpHr == S_OK);
6590 }
6591 HRESULT tmpHr = vboxWddmUnlockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags);
6592 Assert(tmpHr == S_OK);
6593 }
6594 }
6595 else
6596 {
6597 Assert(0);
6598 /* @todo: impl */
6599 }
6600 }
6601#endif
6602
6603 if (pDstRc->RcDesc.fFlags.SharedResource)
6604 {
6605 PVBOXWDDMDISP_ALLOCATION pAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
6606 EnterCriticalSection(&pDevice->DirtyAllocListLock);
6607 if (!pAlloc->DirtyAllocListEntry.pNext)
6608 RTListAppend(&pDevice->DirtyAllocList, &pAlloc->DirtyAllocListEntry);
6609 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
6610 }
6611
6612 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6613 return hr;
6614}
6615static HRESULT APIENTRY vboxWddmDDevColorFill(HANDLE hDevice, CONST D3DDDIARG_COLORFILL* pData)
6616{
6617 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6618 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6619 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6620 Assert(pDevice);
6621 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6622 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6623 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
6624 Assert(pRc);
6625 IDirect3DSurface9 *pSurfIf = NULL;
6626 HRESULT hr = vboxWddmSurfGet(pRc, pData->SubResourceIndex, &pSurfIf);
6627 Assert(hr == S_OK);
6628 if (hr == S_OK)
6629 {
6630 Assert(pSurfIf);
6631 hr = pDevice9If->ColorFill(pSurfIf, &pData->DstRect, pData->Color);
6632 Assert(hr == S_OK);
6633 /* @todo: check what need to do when PresentToDwm flag is set */
6634 Assert(pData->Flags.Value == 0);
6635
6636 pSurfIf->Release();
6637 }
6638 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6639 return hr;
6640}
6641static HRESULT APIENTRY vboxWddmDDevDepthFill(HANDLE hDevice, CONST D3DDDIARG_DEPTHFILL* pData)
6642{
6643 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6644 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6645 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6646 Assert(pDevice);
6647 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6648 Assert(0);
6649 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6650 return E_FAIL;
6651}
6652static HRESULT APIENTRY vboxWddmDDevCreateQuery(HANDLE hDevice, D3DDDIARG_CREATEQUERY* pData)
6653{
6654 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6655 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6656// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6657// Assert(pDevice);
6658// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6659 HRESULT hr = S_OK;
6660 if (pData->QueryType == D3DDDIQUERYTYPE_EVENT)
6661 {
6662 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)RTMemAllocZ(sizeof (VBOXWDDMDISP_QUERY));
6663 Assert(pQuery);
6664 if (pQuery)
6665 {
6666 pQuery->enmType = pData->QueryType;
6667 pData->hQuery = pQuery;
6668 }
6669 else
6670 {
6671 hr = E_OUTOFMEMORY;
6672 }
6673 }
6674 else
6675 {
6676 Assert(0);
6677 hr = E_FAIL;
6678 }
6679 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6680 return hr;
6681}
6682static HRESULT APIENTRY vboxWddmDDevDestroyQuery(HANDLE hDevice, HANDLE hQuery)
6683{
6684 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6685 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6686 HRESULT hr = S_OK;
6687// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6688// Assert(pDevice);
6689// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6690
6691 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)hQuery;
6692 Assert(pQuery);
6693 RTMemFree(pQuery);
6694 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6695 return hr;
6696}
6697static HRESULT APIENTRY vboxWddmDDevIssueQuery(HANDLE hDevice, CONST D3DDDIARG_ISSUEQUERY* pData)
6698{
6699 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6700 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6701 HRESULT hr = S_OK;
6702// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6703// Assert(pDevice);
6704// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6705
6706 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
6707 Assert(pQuery);
6708 pQuery->fQueryState.Value |= pData->Flags.Value;
6709 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6710 return hr;
6711}
6712static HRESULT APIENTRY vboxWddmDDevGetQueryData(HANDLE hDevice, CONST D3DDDIARG_GETQUERYDATA* pData)
6713{
6714 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6715 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6716 HRESULT hr = S_OK;
6717// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6718// Assert(pDevice);
6719// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6720
6721 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
6722 Assert(pQuery);
6723 switch (pQuery->enmType)
6724 {
6725 case D3DDDIQUERYTYPE_EVENT:
6726 Assert(0);
6727 pQuery->data.bData = TRUE;
6728 Assert(pData->pData);
6729 *((BOOL*)pData->pData) = TRUE;
6730 break;
6731 default:
6732 Assert(0);
6733 hr = E_FAIL;
6734 break;
6735 }
6736 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6737 return hr;
6738}
6739static HRESULT APIENTRY vboxWddmDDevSetRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETRENDERTARGET* pData)
6740{
6741 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6742 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6743 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6744 Assert(pDevice);
6745 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6746
6747 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6748 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget;
6749 Assert(pRc);
6750 Assert(pData->SubResourceIndex < pRc->cAllocations);
6751 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
6752 HRESULT hr = vboxWddmRenderTargetSet(pDevice, pData->RenderTargetIndex, pAlloc, FALSE);
6753 Assert(hr == S_OK);
6754 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6755 return hr;
6756}
6757static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDIARG_SETDEPTHSTENCIL* pData)
6758{
6759 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6760 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6761 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6762 Assert(pDevice);
6763 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6764
6765 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6766 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hZBuffer;
6767 IDirect3DSurface9 *pD3D9Surf = NULL;
6768 if (pRc)
6769 {
6770 Assert(pRc->cAllocations == 1);
6771 pD3D9Surf = (IDirect3DSurface9*)pRc->aAllocations[0].pD3DIf;
6772 Assert(pD3D9Surf);
6773 }
6774 HRESULT hr = pDevice9If->SetDepthStencilSurface(pD3D9Surf);
6775 Assert(hr == S_OK);
6776 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6777 return hr;
6778}
6779static HRESULT APIENTRY vboxWddmDDevGenerateMipSubLevels(HANDLE hDevice, CONST D3DDDIARG_GENERATEMIPSUBLEVELS* pData)
6780{
6781 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6782 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6783 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6784 Assert(pDevice);
6785 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6786
6787 Assert(0);
6788 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6789 return E_FAIL;
6790}
6791static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTI* pData, CONST INT* pRegisters)
6792{
6793 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6794 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6795 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6796 Assert(pDevice);
6797 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6798
6799 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6800 HRESULT hr = pDevice9If->SetPixelShaderConstantI(pData->Register, pRegisters, pData->Count);
6801 Assert(hr == S_OK);
6802 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6803 return hr;
6804}
6805static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTB* pData, CONST BOOL* pRegisters)
6806{
6807 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6808 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6809 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6810 Assert(pDevice);
6811 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6812
6813 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6814 HRESULT hr = pDevice9If->SetPixelShaderConstantB(pData->Register, pRegisters, pData->Count);
6815 Assert(hr == S_OK);
6816 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6817 return hr;
6818}
6819static HRESULT APIENTRY vboxWddmDDevCreatePixelShader(HANDLE hDevice, D3DDDIARG_CREATEPIXELSHADER* pData, CONST UINT* pCode)
6820{
6821 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6822 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6823 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6824 Assert(pDevice);
6825 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6826
6827 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6828 IDirect3DPixelShader9 *pShader;
6829 Assert(*((UINT*)((uint8_t*)pCode + pData->CodeSize-4)) == 0x0000FFFF /* end token */);
6830 HRESULT hr = pDevice9If->CreatePixelShader((const DWORD *)pCode, &pShader);
6831 Assert(hr == S_OK);
6832 if (hr == S_OK)
6833 {
6834 Assert(pShader);
6835 pData->ShaderHandle = pShader;
6836 }
6837 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6838 return hr;
6839}
6840static HRESULT APIENTRY vboxWddmDDevDeletePixelShader(HANDLE hDevice, HANDLE hShaderHandle)
6841{
6842 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6843 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6844 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6845 Assert(pDevice);
6846 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6847
6848 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
6849 HRESULT hr = S_OK;
6850 pShader->Release();
6851 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6852 return hr;
6853}
6854static HRESULT APIENTRY vboxWddmDDevCreateDecodeDevice(HANDLE hDevice, D3DDDIARG_CREATEDECODEDEVICE* pData)
6855{
6856 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6857 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6858 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6859 Assert(pDevice);
6860 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6861
6862 Assert(0);
6863 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6864 return E_FAIL;
6865}
6866static HRESULT APIENTRY vboxWddmDDevDestroyDecodeDevice(HANDLE hDevice, HANDLE hDecodeDevice)
6867{
6868 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6869 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6870 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6871 Assert(pDevice);
6872 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6873
6874 Assert(0);
6875 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6876 return E_FAIL;
6877}
6878static HRESULT APIENTRY vboxWddmDDevSetDecodeRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETDECODERENDERTARGET* pData)
6879{
6880 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6881 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6882 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6883 Assert(pDevice);
6884 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6885
6886 Assert(0);
6887 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6888 return E_FAIL;
6889}
6890static HRESULT APIENTRY vboxWddmDDevDecodeBeginFrame(HANDLE hDevice, D3DDDIARG_DECODEBEGINFRAME* pData)
6891{
6892 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6893 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6894 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6895 Assert(pDevice);
6896 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6897
6898 Assert(0);
6899 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6900 return E_FAIL;
6901}
6902static HRESULT APIENTRY vboxWddmDDevDecodeEndFrame(HANDLE hDevice, D3DDDIARG_DECODEENDFRAME* pData)
6903{
6904 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6905 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6906 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6907 Assert(pDevice);
6908 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6909
6910 Assert(0);
6911 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6912 return E_FAIL;
6913}
6914static HRESULT APIENTRY vboxWddmDDevDecodeExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXECUTE* pData)
6915{
6916 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6917 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6918 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6919 Assert(pDevice);
6920 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6921
6922 Assert(0);
6923 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6924 return E_FAIL;
6925}
6926static HRESULT APIENTRY vboxWddmDDevDecodeExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXTENSIONEXECUTE* pData)
6927{
6928 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6929 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6930 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6931 Assert(pDevice);
6932 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6933
6934 Assert(0);
6935 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6936 return E_FAIL;
6937}
6938static HRESULT APIENTRY vboxWddmDDevCreateVideoProcessDevice(HANDLE hDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE* pData)
6939{
6940 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6941 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6942 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6943 Assert(pDevice);
6944 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6945
6946 Assert(0);
6947 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6948 return E_FAIL;
6949}
6950static HRESULT APIENTRY vboxWddmDDevDestroyVideoProcessDevice(HANDLE hDevice, HANDLE hVideoProcessor)
6951{
6952 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6953 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6954 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6955 Assert(pDevice);
6956 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6957
6958 Assert(0);
6959 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6960 return E_FAIL;
6961}
6962static HRESULT APIENTRY vboxWddmDDevVideoProcessBeginFrame(HANDLE hDevice, HANDLE hVideoProcess)
6963{
6964 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6965 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6966 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6967 Assert(pDevice);
6968 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6969
6970 Assert(0);
6971 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6972 return E_FAIL;
6973}
6974static HRESULT APIENTRY vboxWddmDDevVideoProcessEndFrame(HANDLE hDevice, D3DDDIARG_VIDEOPROCESSENDFRAME* pData)
6975{
6976 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6977 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6978 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6979 Assert(pDevice);
6980 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6981
6982 Assert(0);
6983 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6984 return E_FAIL;
6985}
6986static HRESULT APIENTRY vboxWddmDDevSetVideoProcessRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETVIDEOPROCESSRENDERTARGET* pData)
6987{
6988 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6989 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6990 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6991 Assert(pDevice);
6992 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6993
6994 Assert(0);
6995 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6996 return E_FAIL;
6997}
6998static HRESULT APIENTRY vboxWddmDDevVideoProcessBlt(HANDLE hDevice, CONST D3DDDIARG_VIDEOPROCESSBLT* pData)
6999{
7000 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7001 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7002 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7003 Assert(pDevice);
7004 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7005
7006 Assert(0);
7007 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7008 return E_FAIL;
7009}
7010static HRESULT APIENTRY vboxWddmDDevCreateExtensionDevice(HANDLE hDevice, D3DDDIARG_CREATEEXTENSIONDEVICE* pData)
7011{
7012 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7013 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7014 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7015 Assert(pDevice);
7016 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7017
7018 Assert(0);
7019 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7020 return E_FAIL;
7021}
7022static HRESULT APIENTRY vboxWddmDDevDestroyExtensionDevice(HANDLE hDevice, HANDLE hExtension)
7023{
7024 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7025 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7026 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7027 Assert(pDevice);
7028 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7029
7030 Assert(0);
7031 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7032 return E_FAIL;
7033}
7034static HRESULT APIENTRY vboxWddmDDevExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_EXTENSIONEXECUTE* pData)
7035{
7036 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7037 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7038 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7039 Assert(pDevice);
7040 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7041
7042 Assert(0);
7043 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7044 return E_FAIL;
7045}
7046static HRESULT APIENTRY vboxWddmDDevDestroyDevice(IN HANDLE hDevice)
7047{
7048 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7049 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7050
7051 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7052 Assert(pDevice);
7053 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7054
7055 VBOXDISPPROFILE_DDI_DUMPRESET(pDevice);
7056 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
7057 if (VBOXDISPMODE_IS_3D(pAdapter))
7058 {
7059// Assert(!pDevice->cScreens);
7060 vboxWddmSwapchainDestroyAll(pDevice);
7061 if (pDevice->pDevice9If)
7062 {
7063 pDevice->pDevice9If->Release();
7064 }
7065 }
7066
7067#ifdef VBOX_WITH_CRHGSMI
7068 vboxDispLock();
7069 if (pDevice->Uhgsmi.BasePrivate.hClient)
7070 g_VBoxCrHgsmiCallbacks.pfnClientDestroy(pDevice->Uhgsmi.BasePrivate.hClient);
7071 vboxDispUnlock();
7072#endif
7073
7074 HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
7075 Assert(hr == S_OK);
7076 if (hr == S_OK)
7077 RTMemFree(pDevice);
7078 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7079 return hr;
7080}
7081
7082AssertCompile(sizeof (RECT) == sizeof (D3DDDIRECT));
7083AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DDDIRECT, left));
7084AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DDDIRECT, right));
7085AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DDDIRECT, top));
7086AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DDDIRECT, bottom));
7087AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DDDIRECT, left));
7088AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DDDIRECT, right));
7089AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DDDIRECT, top));
7090AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DDDIRECT, bottom));
7091
7092static HRESULT APIENTRY vboxWddmDDevCreateOverlay(HANDLE hDevice, D3DDDIARG_CREATEOVERLAY* pData)
7093{
7094 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7095 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7096 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7097 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
7098 Assert(pRc);
7099 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
7100 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
7101 HRESULT hr = S_OK;
7102 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)RTMemAllocZ(sizeof (VBOXWDDMDISP_OVERLAY));
7103 Assert(pOverlay);
7104 if (pOverlay)
7105 {
7106 VBOXWDDM_OVERLAY_INFO OurInfo;
7107 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
7108 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
7109 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
7110 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
7111 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
7112 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
7113 Assert(!pAlloc->LockInfo.cLocks);
7114 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
7115 D3DDDICB_CREATEOVERLAY OverInfo;
7116 OverInfo.VidPnSourceId = pData->VidPnSourceId;
7117 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
7118 Assert(pAlloc->hAllocation);
7119 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
7120 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
7121 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
7122 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
7123 OverInfo.hKernelOverlay = NULL; /* <-- out */
7124#ifndef VBOXWDDMOVERLAY_TEST
7125 hr = pDevice->RtCallbacks.pfnCreateOverlayCb(pDevice->hDevice, &OverInfo);
7126 Assert(hr == S_OK);
7127 if (hr == S_OK)
7128 {
7129 Assert(OverInfo.hKernelOverlay);
7130 pOverlay->hOverlay = OverInfo.hKernelOverlay;
7131 pOverlay->VidPnSourceId = pData->VidPnSourceId;
7132
7133 Assert(!pAlloc->LockInfo.cLocks);
7134 if (!pAlloc->LockInfo.cLocks)
7135 {
7136 /* we have reported the dirty rect, may clear it if no locks are pending currently */
7137 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
7138 }
7139
7140 pData->hOverlay = pOverlay;
7141 }
7142 else
7143 {
7144 RTMemFree(pOverlay);
7145 }
7146#else
7147 pData->hOverlay = pOverlay;
7148#endif
7149 }
7150 else
7151 hr = E_OUTOFMEMORY;
7152
7153 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7154 return hr;
7155}
7156static HRESULT APIENTRY vboxWddmDDevUpdateOverlay(HANDLE hDevice, CONST D3DDDIARG_UPDATEOVERLAY* pData)
7157{
7158 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7159 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7160 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7161 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
7162 Assert(pRc);
7163 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
7164 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
7165 HRESULT hr = S_OK;
7166 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
7167 VBOXWDDM_OVERLAY_INFO OurInfo;
7168 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
7169 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
7170 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
7171 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
7172 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
7173 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
7174 Assert(!pAlloc->LockInfo.cLocks);
7175 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
7176 D3DDDICB_UPDATEOVERLAY OverInfo;
7177 OverInfo.hKernelOverlay = pOverlay->hOverlay;
7178 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
7179 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
7180 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
7181 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
7182 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
7183#ifndef VBOXWDDMOVERLAY_TEST
7184 hr = pDevice->RtCallbacks.pfnUpdateOverlayCb(pDevice->hDevice, &OverInfo);
7185 Assert(hr == S_OK);
7186 if (hr == S_OK)
7187#endif
7188 {
7189 Assert(!pAlloc->LockInfo.cLocks);
7190 if (!pAlloc->LockInfo.cLocks)
7191 {
7192 /* we have reported the dirty rect, may clear it if no locks are pending currently */
7193 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
7194 }
7195 }
7196
7197 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7198 return hr;
7199}
7200static HRESULT APIENTRY vboxWddmDDevFlipOverlay(HANDLE hDevice, CONST D3DDDIARG_FLIPOVERLAY* pData)
7201{
7202 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7203 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7204 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7205 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSource;
7206 Assert(pRc);
7207 Assert(pRc->cAllocations > pData->SourceIndex);
7208 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SourceIndex];
7209 HRESULT hr = S_OK;
7210 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
7211 VBOXWDDM_OVERLAYFLIP_INFO OurInfo;
7212 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
7213 Assert(!pAlloc->LockInfo.cLocks);
7214 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
7215 D3DDDICB_FLIPOVERLAY OverInfo;
7216 OverInfo.hKernelOverlay = pOverlay->hOverlay;
7217 OverInfo.hSource = pAlloc->hAllocation;
7218 OverInfo.pPrivateDriverData = &OurInfo;
7219 OverInfo.PrivateDriverDataSize = sizeof (OurInfo);
7220#ifndef VBOXWDDMOVERLAY_TEST
7221 hr = pDevice->RtCallbacks.pfnFlipOverlayCb(pDevice->hDevice, &OverInfo);
7222 Assert(hr == S_OK);
7223 if (hr == S_OK)
7224#endif
7225 {
7226 Assert(!pAlloc->LockInfo.cLocks);
7227 if (!pAlloc->LockInfo.cLocks)
7228 {
7229 /* we have reported the dirty rect, may clear it if no locks are pending currently */
7230 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
7231 }
7232 }
7233
7234 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7235 return hr;
7236}
7237static HRESULT APIENTRY vboxWddmDDevGetOverlayColorControls(HANDLE hDevice, D3DDDIARG_GETOVERLAYCOLORCONTROLS* pData)
7238{
7239 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7240 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7241 Assert(0);
7242 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7243 return E_FAIL;
7244}
7245static HRESULT APIENTRY vboxWddmDDevSetOverlayColorControls(HANDLE hDevice, CONST D3DDDIARG_SETOVERLAYCOLORCONTROLS* pData)
7246{
7247 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7248 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7249 Assert(0);
7250 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7251 return E_FAIL;
7252}
7253static HRESULT APIENTRY vboxWddmDDevDestroyOverlay(HANDLE hDevice, CONST D3DDDIARG_DESTROYOVERLAY* pData)
7254{
7255 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7256 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7257 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7258 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
7259 D3DDDICB_DESTROYOVERLAY OverInfo;
7260 OverInfo.hKernelOverlay = pOverlay->hOverlay;
7261#ifndef VBOXWDDMOVERLAY_TEST
7262 HRESULT hr = pDevice->RtCallbacks.pfnDestroyOverlayCb(pDevice->hDevice, &OverInfo);
7263 Assert(hr == S_OK);
7264 if (hr == S_OK)
7265#else
7266 HRESULT hr = S_OK;
7267#endif
7268 {
7269 RTMemFree(pOverlay);
7270 }
7271
7272 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7273 return hr;
7274}
7275static HRESULT APIENTRY vboxWddmDDevQueryResourceResidency(HANDLE hDevice, CONST D3DDDIARG_QUERYRESOURCERESIDENCY* pData)
7276{
7277 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7278 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7279 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7280// Assert(pDevice);
7281// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7282
7283 Assert(0);
7284 HRESULT hr = S_OK;
7285#if 0
7286 for (UINT i = 0; i < pData->NumResources; ++i)
7287 {
7288 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->pHandleList[i];
7289 Assert(pRc->pDevice == pDevice);
7290 if (pRc->hKMResource)
7291 {
7292
7293 }
7294 }
7295#endif
7296 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7297 return hr;
7298}
7299
7300static HRESULT vboxAllocationInit(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DDDI_OPENALLOCATIONINFO *pInfo)
7301{
7302 HRESULT hr = S_OK;
7303 pAlloc->hAllocation = pInfo->hAllocation;
7304 Assert(pInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
7305 Assert(pInfo->pPrivateDriverData);
7306 if (pInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
7307 {
7308 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pInfo->pPrivateDriverData;
7309 pAlloc->enmType = pAllocInfo->enmType;
7310 Assert(pAllocInfo->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
7311 || VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE
7312 || VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE);
7313 pAlloc->pvMem = NULL;
7314 pAlloc->SurfDesc = pAllocInfo->SurfDesc;
7315 }
7316 else
7317 {
7318 vboxVDbgPrintR((__FUNCTION__": ERROR: PrivateDriverDataSize(%d) < (%d)\n", pInfo->PrivateDriverDataSize, sizeof (VBOXWDDM_ALLOCINFO)));
7319 hr = E_INVALIDARG;
7320 }
7321 return hr;
7322}
7323
7324static HRESULT APIENTRY vboxWddmDDevOpenResource(HANDLE hDevice, D3DDDIARG_OPENRESOURCE* pData)
7325{
7326 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7327 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7328 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7329 Assert(pDevice);
7330 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7331
7332 HRESULT hr = S_OK;
7333
7334 Assert(pData->NumAllocations);
7335 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pData->NumAllocations);
7336 Assert(pRc);
7337 if (pRc)
7338 {
7339 pRc->hResource = pData->hResource;
7340 pRc->hKMResource = pData->hKMResource;
7341 pRc->pDevice = pDevice;
7342 pRc->RcDesc.enmRotation = pData->Rotation;
7343 pRc->fFlags = VBOXWDDM_RESOURCE_F_OPENNED;
7344 if (!pData->pPrivateDriverData || !pData->PrivateDriverDataSize)
7345 {
7346 /* this is a "standard" allocation resource */
7347
7348 /* both should be actually zero */
7349 Assert(!pData->pPrivateDriverData && !pData->PrivateDriverDataSize);
7350 pRc->RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
7351 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
7352 pRc->RcDesc.MultisampleQuality = 0;
7353 pRc->RcDesc.MipLevels = 0;
7354 pRc->RcDesc.Fvf;
7355 pRc->RcDesc.fFlags.Value = 0;
7356
7357 Assert(pData->NumAllocations);
7358 D3DDDI_OPENALLOCATIONINFO* pDdiAllocInfo = &pData->pOpenAllocationInfo[0];
7359 Assert(pDdiAllocInfo->pPrivateDriverData);
7360 Assert(pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO));
7361 if (pDdiAllocInfo->pPrivateDriverData && pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
7362 {
7363 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocInfo->pPrivateDriverData;
7364 switch(pAllocInfo->enmType)
7365 {
7366 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
7367 pRc->RcDesc.fFlags.Primary = 1;
7368 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
7369 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
7370 pRc->RcDesc.enmFormat = pAllocInfo->SurfDesc.format;
7371 pRc->RcDesc.VidPnSourceId = pAllocInfo->SurfDesc.VidPnSourceId;
7372 pRc->RcDesc.RefreshRate = pAllocInfo->SurfDesc.RefreshRate;
7373 break;
7374 default:
7375 Assert(0);
7376 hr = E_INVALIDARG;
7377 }
7378 }
7379 else
7380 hr = E_INVALIDARG;
7381 }
7382 else
7383 {
7384 /* this is a "generic" resource whose creation is initiated by the UMD */
7385 Assert(pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
7386 if (pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO))
7387 {
7388 VBOXWDDM_RCINFO *pRcInfo = (VBOXWDDM_RCINFO*)pData->pPrivateDriverData;
7389 Assert(pRcInfo->fFlags == VBOXWDDM_RESOURCE_F_TYPE_GENERIC);
7390 Assert(pRcInfo->cAllocInfos == pData->NumAllocations);
7391 pRc->fFlags = pRcInfo->fFlags | VBOXWDDM_RESOURCE_F_OPENNED;
7392 pRc->RcDesc = pRcInfo->RcDesc;
7393 pRc->cAllocations = pData->NumAllocations;
7394
7395 for (UINT i = 0; i < pData->NumAllocations; ++i)
7396 {
7397 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
7398 D3DDDI_OPENALLOCATIONINFO* pOAI = pData->pOpenAllocationInfo;
7399 Assert(pOAI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
7400 if (pOAI->PrivateDriverDataSize != sizeof (VBOXWDDM_ALLOCINFO))
7401 {
7402 hr = E_INVALIDARG;
7403 break;
7404 }
7405 Assert(pOAI->pPrivateDriverData);
7406 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pOAI->pPrivateDriverData;
7407 pAllocation->hAllocation = pOAI->hAllocation;
7408 pAllocation->enmType = pAllocInfo->enmType;
7409 pAllocation->hSharedHandle = pAllocInfo->hSharedHandle;
7410 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
7411 Assert(pAllocation->hSharedHandle);
7412 }
7413
7414 Assert(pRc->RcDesc.fFlags.SharedResource);
7415 if (pRc->RcDesc.fFlags.Texture)
7416 {
7417 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
7418 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
7419 IDirect3DTexture9 *pD3DIfTex;
7420 HANDLE hSharedHandle = pAllocation->hSharedHandle;
7421 Assert(pAllocation->hSharedHandle);
7422
7423 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
7424 pAllocation->SurfDesc.width,
7425 pAllocation->SurfDesc.height,
7426 pRc->cAllocations,
7427 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
7428 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
7429 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
7430 &pD3DIfTex,
7431 &hSharedHandle,
7432 NULL);
7433 Assert(hr == S_OK);
7434 if (hr == S_OK)
7435 {
7436 Assert(pD3DIfTex);
7437 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
7438 pAllocation->pD3DIf = pD3DIfTex;
7439 Assert(pAllocation->hSharedHandle == hSharedHandle);
7440 Assert(pAllocation->hSharedHandle);
7441 }
7442 }
7443 else
7444 {
7445 /* impl */
7446 Assert(0);
7447 }
7448 }
7449 else
7450 hr = E_INVALIDARG;
7451 }
7452
7453 if (hr == S_OK)
7454 {
7455 for (UINT i = 0; i < pData->NumAllocations; ++i)
7456 {
7457 hr = vboxAllocationInit(&pRc->aAllocations[i], &pData->pOpenAllocationInfo[i]);
7458 Assert(hr == S_OK);
7459 if (hr != S_OK)
7460 break;
7461 }
7462 }
7463
7464 if (hr == S_OK)
7465 pData->hResource = pRc;
7466 else
7467 vboxResourceFree(pRc);
7468 }
7469 else
7470 {
7471 vboxVDbgPrintR((__FUNCTION__": vboxResourceAlloc failed for hDevice(0x%p), NumAllocations(%d)\n", hDevice, pData->NumAllocations));
7472 hr = E_OUTOFMEMORY;
7473 }
7474
7475 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7476 return hr;
7477}
7478static HRESULT APIENTRY vboxWddmDDevGetCaptureAllocationHandle(HANDLE hDevice, D3DDDIARG_GETCAPTUREALLOCATIONHANDLE* pData)
7479{
7480 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7481 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7482 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7483 Assert(pDevice);
7484 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7485
7486 Assert(0);
7487 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7488 return E_FAIL;
7489}
7490
7491static HRESULT APIENTRY vboxWddmDDevCaptureToSysMem(HANDLE hDevice, CONST D3DDDIARG_CAPTURETOSYSMEM* pData)
7492{
7493 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7494 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7495 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7496 Assert(pDevice);
7497 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7498
7499 Assert(0);
7500 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7501 return E_FAIL;
7502}
7503
7504static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIARG_CREATEDEVICE* pCreateData)
7505{
7506 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7507 HRESULT hr = S_OK;
7508 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), Interface(%d), Version(%d)\n", hAdapter, pCreateData->Interface, pCreateData->Version));
7509
7510// Assert(0);
7511 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
7512
7513 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_DEVICE, apRTs[pAdapter->cMaxSimRTs]));
7514 if (pDevice)
7515 {
7516 pDevice->cRTs = pAdapter->cMaxSimRTs;
7517 pDevice->hDevice = pCreateData->hDevice;
7518 pDevice->pAdapter = pAdapter;
7519 pDevice->u32IfVersion = pCreateData->Interface;
7520 pDevice->uRtVersion = pCreateData->Version;
7521 pDevice->RtCallbacks = *pCreateData->pCallbacks;
7522 pDevice->pvCmdBuffer = pCreateData->pCommandBuffer;
7523 pDevice->cbCmdBuffer = pCreateData->CommandBufferSize;
7524 pDevice->fFlags = pCreateData->Flags;
7525 /* Set Viewport to some default values */
7526 pDevice->ViewPort.X = 0;
7527 pDevice->ViewPort.Y = 0;
7528 pDevice->ViewPort.Width = 1;
7529 pDevice->ViewPort.Height = 1;
7530 pDevice->ViewPort.MinZ = 0.;
7531 pDevice->ViewPort.MaxZ = 1.;
7532
7533 InitializeCriticalSection(&pDevice->DirtyAllocListLock);
7534 RTListInit(&pDevice->DirtyAllocList);
7535
7536 Assert(!pCreateData->AllocationListSize);
7537 Assert(!pCreateData->PatchLocationListSize);
7538
7539 pCreateData->hDevice = pDevice;
7540
7541 pCreateData->pDeviceFuncs->pfnSetRenderState = vboxWddmDDevSetRenderState;
7542 pCreateData->pDeviceFuncs->pfnUpdateWInfo = vboxWddmDDevUpdateWInfo;
7543 pCreateData->pDeviceFuncs->pfnValidateDevice = vboxWddmDDevValidateDevice;
7544 pCreateData->pDeviceFuncs->pfnSetTextureStageState = vboxWddmDDevSetTextureStageState;
7545 pCreateData->pDeviceFuncs->pfnSetTexture = vboxWddmDDevSetTexture;
7546 pCreateData->pDeviceFuncs->pfnSetPixelShader = vboxWddmDDevSetPixelShader;
7547 pCreateData->pDeviceFuncs->pfnSetPixelShaderConst = vboxWddmDDevSetPixelShaderConst;
7548 pCreateData->pDeviceFuncs->pfnSetStreamSourceUm = vboxWddmDDevSetStreamSourceUm;
7549 pCreateData->pDeviceFuncs->pfnSetIndices = vboxWddmDDevSetIndices;
7550 pCreateData->pDeviceFuncs->pfnSetIndicesUm = vboxWddmDDevSetIndicesUm;
7551 pCreateData->pDeviceFuncs->pfnDrawPrimitive = vboxWddmDDevDrawPrimitive;
7552 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive = vboxWddmDDevDrawIndexedPrimitive;
7553 pCreateData->pDeviceFuncs->pfnDrawRectPatch = vboxWddmDDevDrawRectPatch;
7554 pCreateData->pDeviceFuncs->pfnDrawTriPatch = vboxWddmDDevDrawTriPatch;
7555 pCreateData->pDeviceFuncs->pfnDrawPrimitive2 = vboxWddmDDevDrawPrimitive2;
7556 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive2 = vboxWddmDDevDrawIndexedPrimitive2;
7557 pCreateData->pDeviceFuncs->pfnVolBlt = vboxWddmDDevVolBlt;
7558 pCreateData->pDeviceFuncs->pfnBufBlt = vboxWddmDDevBufBlt;
7559 pCreateData->pDeviceFuncs->pfnTexBlt = vboxWddmDDevTexBlt;
7560 pCreateData->pDeviceFuncs->pfnStateSet = vboxWddmDDevStateSet;
7561 pCreateData->pDeviceFuncs->pfnSetPriority = vboxWddmDDevSetPriority;
7562 pCreateData->pDeviceFuncs->pfnClear = vboxWddmDDevClear;
7563 pCreateData->pDeviceFuncs->pfnUpdatePalette = vboxWddmDDevUpdatePalette;
7564 pCreateData->pDeviceFuncs->pfnSetPalette = vboxWddmDDevSetPalette;
7565 pCreateData->pDeviceFuncs->pfnSetVertexShaderConst = vboxWddmDDevSetVertexShaderConst;
7566 pCreateData->pDeviceFuncs->pfnMultiplyTransform = vboxWddmDDevMultiplyTransform;
7567 pCreateData->pDeviceFuncs->pfnSetTransform = vboxWddmDDevSetTransform;
7568 pCreateData->pDeviceFuncs->pfnSetViewport = vboxWddmDDevSetViewport;
7569 pCreateData->pDeviceFuncs->pfnSetZRange = vboxWddmDDevSetZRange;
7570 pCreateData->pDeviceFuncs->pfnSetMaterial = vboxWddmDDevSetMaterial;
7571 pCreateData->pDeviceFuncs->pfnSetLight = vboxWddmDDevSetLight;
7572 pCreateData->pDeviceFuncs->pfnCreateLight = vboxWddmDDevCreateLight;
7573 pCreateData->pDeviceFuncs->pfnDestroyLight = vboxWddmDDevDestroyLight;
7574 pCreateData->pDeviceFuncs->pfnSetClipPlane = vboxWddmDDevSetClipPlane;
7575 pCreateData->pDeviceFuncs->pfnGetInfo = vboxWddmDDevGetInfo;
7576 pCreateData->pDeviceFuncs->pfnLock = vboxWddmDDevLock;
7577 pCreateData->pDeviceFuncs->pfnUnlock = vboxWddmDDevUnlock;
7578 pCreateData->pDeviceFuncs->pfnCreateResource = vboxWddmDDevCreateResource;
7579 pCreateData->pDeviceFuncs->pfnDestroyResource = vboxWddmDDevDestroyResource;
7580 pCreateData->pDeviceFuncs->pfnSetDisplayMode = vboxWddmDDevSetDisplayMode;
7581 pCreateData->pDeviceFuncs->pfnPresent = vboxWddmDDevPresent;
7582 pCreateData->pDeviceFuncs->pfnFlush = vboxWddmDDevFlush;
7583 pCreateData->pDeviceFuncs->pfnCreateVertexShaderFunc = vboxWddmDDevCreateVertexShaderFunc;
7584 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderFunc = vboxWddmDDevDeleteVertexShaderFunc;
7585 pCreateData->pDeviceFuncs->pfnSetVertexShaderFunc = vboxWddmDDevSetVertexShaderFunc;
7586 pCreateData->pDeviceFuncs->pfnCreateVertexShaderDecl = vboxWddmDDevCreateVertexShaderDecl;
7587 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderDecl = vboxWddmDDevDeleteVertexShaderDecl;
7588 pCreateData->pDeviceFuncs->pfnSetVertexShaderDecl = vboxWddmDDevSetVertexShaderDecl;
7589 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstI = vboxWddmDDevSetVertexShaderConstI;
7590 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstB = vboxWddmDDevSetVertexShaderConstB;
7591 pCreateData->pDeviceFuncs->pfnSetScissorRect = vboxWddmDDevSetScissorRect;
7592 pCreateData->pDeviceFuncs->pfnSetStreamSource = vboxWddmDDevSetStreamSource;
7593 pCreateData->pDeviceFuncs->pfnSetStreamSourceFreq = vboxWddmDDevSetStreamSourceFreq;
7594 pCreateData->pDeviceFuncs->pfnSetConvolutionKernelMono = vboxWddmDDevSetConvolutionKernelMono;
7595 pCreateData->pDeviceFuncs->pfnComposeRects = vboxWddmDDevComposeRects;
7596 pCreateData->pDeviceFuncs->pfnBlt = vboxWddmDDevBlt;
7597 pCreateData->pDeviceFuncs->pfnColorFill = vboxWddmDDevColorFill;
7598 pCreateData->pDeviceFuncs->pfnDepthFill = vboxWddmDDevDepthFill;
7599 pCreateData->pDeviceFuncs->pfnCreateQuery = vboxWddmDDevCreateQuery;
7600 pCreateData->pDeviceFuncs->pfnDestroyQuery = vboxWddmDDevDestroyQuery;
7601 pCreateData->pDeviceFuncs->pfnIssueQuery = vboxWddmDDevIssueQuery;
7602 pCreateData->pDeviceFuncs->pfnGetQueryData = vboxWddmDDevGetQueryData;
7603 pCreateData->pDeviceFuncs->pfnSetRenderTarget = vboxWddmDDevSetRenderTarget;
7604 pCreateData->pDeviceFuncs->pfnSetDepthStencil = vboxWddmDDevSetDepthStencil;
7605 pCreateData->pDeviceFuncs->pfnGenerateMipSubLevels = vboxWddmDDevGenerateMipSubLevels;
7606 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstI = vboxWddmDDevSetPixelShaderConstI;
7607 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstB = vboxWddmDDevSetPixelShaderConstB;
7608 pCreateData->pDeviceFuncs->pfnCreatePixelShader = vboxWddmDDevCreatePixelShader;
7609 pCreateData->pDeviceFuncs->pfnDeletePixelShader = vboxWddmDDevDeletePixelShader;
7610 pCreateData->pDeviceFuncs->pfnCreateDecodeDevice = vboxWddmDDevCreateDecodeDevice;
7611 pCreateData->pDeviceFuncs->pfnDestroyDecodeDevice = vboxWddmDDevDestroyDecodeDevice;
7612 pCreateData->pDeviceFuncs->pfnSetDecodeRenderTarget = vboxWddmDDevSetDecodeRenderTarget;
7613 pCreateData->pDeviceFuncs->pfnDecodeBeginFrame = vboxWddmDDevDecodeBeginFrame;
7614 pCreateData->pDeviceFuncs->pfnDecodeEndFrame = vboxWddmDDevDecodeEndFrame;
7615 pCreateData->pDeviceFuncs->pfnDecodeExecute = vboxWddmDDevDecodeExecute;
7616 pCreateData->pDeviceFuncs->pfnDecodeExtensionExecute = vboxWddmDDevDecodeExtensionExecute;
7617 pCreateData->pDeviceFuncs->pfnCreateVideoProcessDevice = vboxWddmDDevCreateVideoProcessDevice;
7618 pCreateData->pDeviceFuncs->pfnDestroyVideoProcessDevice = vboxWddmDDevDestroyVideoProcessDevice;
7619 pCreateData->pDeviceFuncs->pfnVideoProcessBeginFrame = vboxWddmDDevVideoProcessBeginFrame;
7620 pCreateData->pDeviceFuncs->pfnVideoProcessEndFrame = vboxWddmDDevVideoProcessEndFrame;
7621 pCreateData->pDeviceFuncs->pfnSetVideoProcessRenderTarget = vboxWddmDDevSetVideoProcessRenderTarget;
7622 pCreateData->pDeviceFuncs->pfnVideoProcessBlt = vboxWddmDDevVideoProcessBlt;
7623 pCreateData->pDeviceFuncs->pfnCreateExtensionDevice = vboxWddmDDevCreateExtensionDevice;
7624 pCreateData->pDeviceFuncs->pfnDestroyExtensionDevice = vboxWddmDDevDestroyExtensionDevice;
7625 pCreateData->pDeviceFuncs->pfnExtensionExecute = vboxWddmDDevExtensionExecute;
7626 pCreateData->pDeviceFuncs->pfnCreateOverlay = vboxWddmDDevCreateOverlay;
7627 pCreateData->pDeviceFuncs->pfnUpdateOverlay = vboxWddmDDevUpdateOverlay;
7628 pCreateData->pDeviceFuncs->pfnFlipOverlay = vboxWddmDDevFlipOverlay;
7629 pCreateData->pDeviceFuncs->pfnGetOverlayColorControls = vboxWddmDDevGetOverlayColorControls;
7630 pCreateData->pDeviceFuncs->pfnSetOverlayColorControls = vboxWddmDDevSetOverlayColorControls;
7631 pCreateData->pDeviceFuncs->pfnDestroyOverlay = vboxWddmDDevDestroyOverlay;
7632 pCreateData->pDeviceFuncs->pfnDestroyDevice = vboxWddmDDevDestroyDevice;
7633 pCreateData->pDeviceFuncs->pfnQueryResourceResidency = vboxWddmDDevQueryResourceResidency;
7634 pCreateData->pDeviceFuncs->pfnOpenResource = vboxWddmDDevOpenResource;
7635 pCreateData->pDeviceFuncs->pfnGetCaptureAllocationHandle = vboxWddmDDevGetCaptureAllocationHandle;
7636 pCreateData->pDeviceFuncs->pfnCaptureToSysMem = vboxWddmDDevCaptureToSysMem;
7637 pCreateData->pDeviceFuncs->pfnLockAsync = NULL; //vboxWddmDDevLockAsync;
7638 pCreateData->pDeviceFuncs->pfnUnlockAsync = NULL; //vboxWddmDDevUnlockAsync;
7639 pCreateData->pDeviceFuncs->pfnRename = NULL; //vboxWddmDDevRename;
7640
7641
7642 do
7643 {
7644 RTListInit(&pDevice->SwapchainList);
7645 Assert(!pCreateData->AllocationListSize
7646 && !pCreateData->PatchLocationListSize);
7647 if (!pCreateData->AllocationListSize
7648 && !pCreateData->PatchLocationListSize)
7649 {
7650#ifdef VBOX_WITH_CRHGSMI
7651 hr = vboxUhgsmiD3DInit(&pDevice->Uhgsmi, pDevice);
7652 Assert(hr == S_OK);
7653 if (hr == S_OK)
7654#endif
7655 {
7656 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7657
7658 hr = vboxDispCmCtxCreate(pDevice, &pDevice->DefaultContext);
7659 Assert(hr == S_OK);
7660 if (hr == S_OK)
7661 {
7662 #ifdef VBOXDISP_EARLYCREATEDEVICE
7663 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);
7664 Assert(pRc);
7665 if (pRc)
7666 {
7667 D3DPRESENT_PARAMETERS params;
7668 memset(&params, 0, sizeof (params));
7669 // params.BackBufferWidth = 640;
7670 // params.BackBufferHeight = 480;
7671 params.BackBufferWidth = 0x400;
7672 params.BackBufferHeight = 0x300;
7673 params.BackBufferFormat = D3DFMT_A8R8G8B8;
7674 // params.BackBufferCount = 0;
7675 params.BackBufferCount = 1;
7676 params.MultiSampleType = D3DMULTISAMPLE_NONE;
7677 params.SwapEffect = D3DSWAPEFFECT_DISCARD;
7678 // params.hDeviceWindow = hWnd;
7679 /* @todo: it seems there should be a way to detect this correctly since
7680 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
7681 params.Windowed = TRUE;
7682 // params.EnableAutoDepthStencil = FALSE;
7683 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
7684 // params.Flags;
7685 // params.FullScreen_RefreshRateInHz;
7686 // params.FullScreen_PresentationInterval;
7687
7688 hr = vboxWddmD3DDeviceCreate(pDevice, 0, pRc, &params, TRUE /*BOOL bLockable*/);
7689 Assert(hr == S_OK);
7690 if (hr == S_OK)
7691 break;
7692 vboxResourceFree(pRc);
7693 }
7694 else
7695 {
7696 hr = E_OUTOFMEMORY;
7697 }
7698 #else
7699//# define VBOXDISP_TEST_SWAPCHAIN
7700# ifdef VBOXDISP_TEST_SWAPCHAIN
7701 VBOXDISP_D3DEV(pDevice);
7702# endif
7703 break;
7704 #endif
7705
7706 HRESULT tmpHr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
7707 Assert(tmpHr == S_OK);
7708 }
7709 }
7710 }
7711 else
7712 {
7713 vboxVDbgPrintR((__FUNCTION__": Not implemented: PatchLocationListSize(%d), AllocationListSize(%d)\n",
7714 pCreateData->PatchLocationListSize, pCreateData->AllocationListSize));
7715 //pCreateData->pAllocationList = ??
7716 hr = E_FAIL;
7717 }
7718
7719 RTMemFree(pDevice);
7720 } while (0);
7721 }
7722 else
7723 {
7724 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
7725 hr = E_OUTOFMEMORY;
7726 }
7727
7728 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7729
7730 return hr;
7731}
7732
7733static HRESULT APIENTRY vboxWddmDispCloseAdapter (IN HANDLE hAdapter)
7734{
7735 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7736 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7737
7738// Assert(0);
7739
7740 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
7741 if (VBOXDISPMODE_IS_3D(pAdapter))
7742 {
7743 VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL();
7744 HRESULT hr = VBoxDispWorkerDestroy(&pAdapter->WndWorker);
7745 Assert(hr == S_OK);
7746 pAdapter->pD3D9If->Release();
7747 VBoxDispD3DClose(&pAdapter->D3D);
7748
7749#ifdef VBOX_WITH_CRHGSMI
7750 vboxUhgsmiGlobalRelease();
7751#endif
7752 }
7753
7754 vboxCapsFree(pAdapter);
7755
7756 RTMemFree(pAdapter);
7757
7758 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7759
7760 return S_OK;
7761}
7762
7763HRESULT APIENTRY OpenAdapter (__inout D3DDDIARG_OPENADAPTER* pOpenData)
7764{
7765 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7766 vboxVDbgPrint(("==> "__FUNCTION__"\n"));
7767
7768// vboxDispLock();
7769
7770 HRESULT hr = E_FAIL;
7771
7772 do
7773 {
7774
7775 VBOXWDDM_QI Query;
7776 D3DDDICB_QUERYADAPTERINFO DdiQuery;
7777 DdiQuery.PrivateDriverDataSize = sizeof(Query);
7778 DdiQuery.pPrivateDriverData = &Query;
7779 hr = pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb(pOpenData->hAdapter, &DdiQuery);
7780 Assert(hr == S_OK);
7781 if (hr != S_OK)
7782 {
7783 vboxVDbgPrintR((__FUNCTION__": pfnQueryAdapterInfoCb failed, hr (%d)\n", hr));
7784 hr = E_FAIL;
7785 break;
7786 }
7787
7788 /* check the miniport version match display version */
7789 if (Query.u32Version != VBOXVIDEOIF_VERSION)
7790 {
7791 vboxVDbgPrintR((__FUNCTION__": miniport version mismatch, expected (%d), but was (%d)\n",
7792 VBOXVIDEOIF_VERSION,
7793 Query.u32Version));
7794 hr = E_FAIL;
7795 break;
7796 }
7797
7798#ifdef VBOX_WITH_VIDEOHWACCEL
7799 Assert(Query.cInfos >= 1);
7800 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_ADAPTER, aHeads[Query.cInfos]));
7801#else
7802 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(sizeof (VBOXWDDMDISP_ADAPTER));
7803#endif
7804 Assert(pAdapter);
7805 if (pAdapter)
7806 {
7807 pAdapter->hAdapter = pOpenData->hAdapter;
7808 pAdapter->uIfVersion = pOpenData->Interface;
7809 pAdapter->uRtVersion= pOpenData->Version;
7810 pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
7811
7812 pAdapter->cHeads = Query.cInfos;
7813
7814
7815 pOpenData->hAdapter = pAdapter;
7816 pOpenData->pAdapterFuncs->pfnGetCaps = vboxWddmDispGetCaps;
7817 pOpenData->pAdapterFuncs->pfnCreateDevice = vboxWddmDispCreateDevice;
7818 pOpenData->pAdapterFuncs->pfnCloseAdapter = vboxWddmDispCloseAdapter;
7819 pOpenData->DriverVersion = D3D_UMD_INTERFACE_VERSION;
7820 /*
7821 * here we detect whether we are called by the d3d or ddraw.
7822 * in the d3d case we init our d3d environment
7823 * in the ddraw case we init 2D acceleration
7824 * if interface version is > 7, this is D3D, treat it as so
7825 * otherwise treat it as ddraw
7826 * @todo: need a more clean way of doing this */
7827
7828 if (pAdapter->uIfVersion > 7)
7829 {
7830 do
7831 {
7832#ifdef VBOX_WITH_CRHGSMI
7833 hr = vboxUhgsmiGlobalRetain();
7834 Assert(hr == S_OK);
7835 if (hr == S_OK)
7836#endif
7837 {
7838 VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL();
7839 /* try enable the 3D */
7840 hr = VBoxDispD3DOpen(&pAdapter->D3D);
7841 Assert(hr == S_OK);
7842 if (hr == S_OK)
7843 {
7844// Assert(0);
7845 hr = pAdapter->D3D.pfnDirect3DCreate9Ex(D3D_SDK_VERSION, &pAdapter->pD3D9If);
7846 Assert(hr == S_OK);
7847 if (hr == S_OK)
7848 {
7849 D3DCAPS9 Caps;
7850 memset(&Caps, 0, sizeof (Caps));
7851 hr = vboxWddmGetD3D9Caps(pAdapter, &Caps);
7852 Assert(hr == S_OK);
7853 if (hr == S_OK)
7854 {
7855 pAdapter->cMaxSimRTs = Caps.NumSimultaneousRTs;
7856 Assert(pAdapter->cMaxSimRTs);
7857 Assert(pAdapter->cMaxSimRTs < UINT32_MAX/2);
7858 hr = VBoxDispWorkerCreate(&pAdapter->WndWorker);
7859 Assert(hr == S_OK);
7860 if (hr == S_OK)
7861 {
7862 vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
7863 break;
7864 }
7865 }
7866 pAdapter->pD3D9If->Release();
7867 }
7868 else
7869 vboxVDbgPrintR((__FUNCTION__": pfnDirect3DCreate9Ex failed, hr (%d)\n", hr));
7870 VBoxDispD3DClose(&pAdapter->D3D);
7871 }
7872 else
7873 vboxVDbgPrintR((__FUNCTION__": VBoxDispD3DOpen failed, hr (%d)\n", hr));
7874#ifdef VBOX_WITH_CRHGSMI
7875 vboxUhgsmiGlobalRelease();
7876#endif
7877 }
7878 } while (0);
7879 }
7880#ifdef VBOX_WITH_VIDEOHWACCEL
7881 else
7882 {
7883 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
7884 {
7885 pAdapter->aHeads[i].Vhwa.Settings = Query.aInfos[i];
7886 }
7887 }
7888#endif
7889
7890 vboxCapsInit(pAdapter);
7891 hr = S_OK;
7892// RTMemFree(pAdapter);
7893 }
7894 else
7895 {
7896 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
7897 hr = E_OUTOFMEMORY;
7898 }
7899
7900 } while (0);
7901
7902// vboxDispUnlock();
7903
7904 vboxVDbgPrint(("<== "__FUNCTION__", hr (%d)\n", hr));
7905
7906 return hr;
7907}
7908
7909#ifdef VBOXWDDMDISP_DEBUG_PRINT
7910VOID vboxVDbgDoMpPrint(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString)
7911{
7912 uint32_t cbString = (uint32_t)strlen(szString) + 1;
7913 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
7914 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
7915 Assert(pCmd);
7916 if (pCmd)
7917 {
7918 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
7919 memcpy(pCmd->aStringBuf, szString, cbString);
7920
7921 D3DDDICB_ESCAPE DdiEscape = {0};
7922 DdiEscape.hContext = NULL;
7923 DdiEscape.hDevice = NULL;
7924 DdiEscape.Flags.Value = 0;
7925 DdiEscape.pPrivateDriverData = pCmd;
7926 DdiEscape.PrivateDriverDataSize = cbCmd;
7927
7928 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
7929 Assert(hr == S_OK);
7930
7931 RTMemFree(pCmd);
7932 }
7933}
7934VOID vboxVDbgDoMpPrintF(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString, ...)
7935{
7936 char szBuffer[4096] = {0};
7937 va_list pArgList;
7938 va_start(pArgList, szString);
7939 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
7940 va_end(pArgList);
7941
7942 if (pDevice)
7943 {
7944 vboxVDbgDoMpPrint(pDevice, szBuffer);
7945 }
7946 else
7947 {
7948 OutputDebugStringA(szBuffer);
7949 }
7950}
7951VOID vboxVDbgDoPrint(LPCSTR szString, ...)
7952{
7953 char szBuffer[1024] = {0};
7954 va_list pArgList;
7955 va_start(pArgList, szString);
7956 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
7957 va_end(pArgList);
7958
7959 OutputDebugStringA(szBuffer);
7960}
7961#endif
7962
7963#ifdef VBOXWDDMDISP_DEBUG
7964
7965bool g_VDbgTstDumpEnable = false;
7966bool g_VDbgTstDumpOnSys2VidSameSizeEnable = false;
7967
7968VOID vboxVDbgDoDumpAllocSurfData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, IDirect3DSurface9 *pSurf, const RECT *pRect, const char* pSuffix)
7969{
7970 if (pPrefix)
7971 {
7972 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
7973 }
7974
7975 D3DLOCKED_RECT Lr;
7976 if (pRect)
7977 {
7978 Assert(pRect->right > pRect->left);
7979 Assert(pRect->bottom > pRect->top);
7980 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
7981 }
7982
7983 HRESULT srcHr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
7984 Assert(srcHr == S_OK);
7985 if (srcHr == S_OK)
7986 {
7987 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
7988// Assert(bpp == pAlloc->SurfDesc.bpp);
7989// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
7990 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
7991 Lr.pBits, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, Lr.Pitch));
7992 if (pRect)
7993 {
7994 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
7995 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
7996 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
7997 }
7998 Assert(0);
7999
8000 srcHr = pSurf->UnlockRect();
8001 Assert(srcHr == S_OK);
8002 }
8003 if (pSuffix)
8004 {
8005 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
8006 }
8007}
8008
8009VOID vboxVDbgDoDumpAllocData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, const RECT *pRect, const char* pSuffix)
8010{
8011 if (pPrefix)
8012 {
8013 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
8014 }
8015
8016 if (pRect)
8017 {
8018 Assert(pRect->right > pRect->left);
8019 Assert(pRect->bottom > pRect->top);
8020 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
8021 }
8022
8023 Assert(pAlloc->hAllocation);
8024
8025 D3DDDICB_LOCK LockData;
8026 LockData.hAllocation = pAlloc->hAllocation;
8027 LockData.PrivateDriverData = 0;
8028 LockData.NumPages = 0;
8029 LockData.pPages = NULL;
8030 LockData.pData = NULL; /* out */
8031 LockData.Flags.Value = 0;
8032 LockData.Flags.LockEntire =1;
8033 LockData.Flags.ReadOnly = 1;
8034
8035 HRESULT hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
8036 Assert(hr == S_OK);
8037 if (hr == S_OK)
8038 {
8039 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
8040// Assert(bpp == pAlloc->SurfDesc.bpp);
8041// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
8042 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
8043 LockData.pData, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch));
8044 if (pRect)
8045 {
8046 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
8047 ((uint8_t*)LockData.pData) + (pRect->top * pAlloc->SurfDesc.pitch) + ((pRect->left * bpp) >> 3),
8048 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, pAlloc->SurfDesc.pitch));
8049 }
8050 Assert(0);
8051
8052 D3DDDICB_UNLOCK DdiUnlock;
8053
8054 DdiUnlock.NumAllocations = 1;
8055 DdiUnlock.phAllocations = &pAlloc->hAllocation;
8056
8057 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock);
8058 Assert(hr == S_OK);
8059 }
8060 if (pSuffix)
8061 {
8062 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
8063 }
8064}
8065
8066
8067VOID vboxVDbgDoDumpSurfData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const RECT *pRect, IDirect3DSurface9 *pSurf, const char* pSuffix)
8068{
8069 if (pPrefix)
8070 {
8071 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
8072 }
8073
8074 Assert(pRc->cAllocations > iAlloc);
8075 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
8076
8077 vboxVDbgMpPrintAlloc((pDevice, "allocation info:\n", pRc, iAlloc, "\n"));
8078
8079 D3DLOCKED_RECT Lr;
8080 if (pRect)
8081 {
8082 Assert(pRect->right > pRect->left);
8083 Assert(pRect->bottom > pRect->top);
8084 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
8085 }
8086
8087 BOOL bReleaseSurf = false;
8088 if (!pSurf)
8089 {
8090 HRESULT tmpHr = vboxWddmSurfGet(pRc, iAlloc, &pSurf);
8091 Assert(tmpHr == S_OK);
8092 bReleaseSurf = TRUE;
8093 }
8094 HRESULT srcHr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
8095 Assert(srcHr == S_OK);
8096 if (srcHr == S_OK)
8097 {
8098 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
8099// Assert(bpp == pAlloc->SurfDesc.bpp);
8100// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
8101 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
8102 Lr.pBits, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, Lr.Pitch));
8103 if (pRect)
8104 {
8105 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
8106 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
8107 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
8108 }
8109 Assert(0);
8110
8111 srcHr = pSurf->UnlockRect();
8112 Assert(srcHr == S_OK);
8113 }
8114 if (pSuffix)
8115 {
8116 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
8117 }
8118
8119 if (bReleaseSurf)
8120 pSurf->Release();
8121}
8122
8123VOID vboxVDbgDoDumpSurfDataBySurf(const PVBOXWDDMDISP_DEVICE pDevice, IDirect3DSurface9 *pSurf)
8124{
8125 D3DSURFACE_DESC Desc;
8126 HRESULT hr = pSurf->GetDesc(&Desc);
8127 Assert(hr == S_OK);
8128 if (hr == S_OK)
8129 {
8130 D3DLOCKED_RECT Lr;
8131 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
8132 Assert(hr == S_OK);
8133 if (hr == S_OK)
8134 {
8135 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
8136 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
8137 Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch));
8138
8139 Assert(0);
8140
8141 hr = pSurf->UnlockRect();
8142 Assert(hr == S_OK);
8143 }
8144 }
8145}
8146
8147void vboxVDbgDoMpPrintAlloc(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
8148{
8149 Assert(pRc->cAllocations > iAlloc);
8150 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
8151 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
8152 BOOL bFrontBuf = FALSE;
8153 if (bPrimary)
8154 {
8155 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
8156 Assert(pSwapchain);
8157 bFrontBuf = (vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc);
8158 }
8159 vboxVDbgDoMpPrintF(pDevice, "%s D3DWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
8160 pAlloc->D3DWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
8161 bPrimary ?
8162 (bFrontBuf ? "Front Buffer" : "Back Buffer")
8163 : "?Everage? Alloc",
8164 pSuffix);
8165}
8166
8167void vboxVDbgDoMpPrintRect(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const RECT *pRect, const char * pSuffix)
8168{
8169 vboxVDbgDoMpPrintF(pDevice, "%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix);
8170}
8171#endif
8172
8173#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
8174
8175static PVOID g_VBoxWDbgVEHandler = NULL;
8176LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
8177{
8178 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
8179 PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
8180 switch (pExceptionRecord->ExceptionCode)
8181 {
8182 case 0x40010006: /* <- OutputDebugString exception, ignore */
8183 case 0xe06d7363: /* <- ms compiler - generated exception related to C++ exception */
8184 break;
8185 default:
8186 AssertRelease(0);
8187 break;
8188 }
8189 return EXCEPTION_CONTINUE_SEARCH;
8190}
8191
8192void vboxVDbgVEHandlerRegister()
8193{
8194 Assert(!g_VBoxWDbgVEHandler);
8195 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
8196 Assert(g_VBoxWDbgVEHandler);
8197}
8198
8199void vboxVDbgVEHandlerUnregister()
8200{
8201 Assert(g_VBoxWDbgVEHandler);
8202 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
8203 Assert(uResult);
8204 g_VBoxWDbgVEHandler = NULL;
8205}
8206
8207#endif
8208
Note: See TracBrowser for help on using the repository browser.

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