VirtualBox

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

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

scm cleanup run.

  • 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
3466 Assert(pData->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm));
3467 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrcUm = &pDevice->aStreamSourceUm[pData->Stream];
3468 pStrSrcUm->pvBuffer = pUMBuffer;
3469 pStrSrcUm->cbStride = pData->Stride;
3470
3471 if (pDevice->aStreamSource[pData->Stream])
3472 {
3473 hr = pDevice->pDevice9If->SetStreamSource(pData->Stream, NULL, 0, 0);
3474 --pDevice->cStreamSources;
3475 Assert(pDevice->cStreamSources < UINT32_MAX/2);
3476 pDevice->aStreamSource[pData->Stream] = NULL;
3477 }
3478
3479 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3480 return hr;
3481}
3482
3483static HRESULT APIENTRY vboxWddmDDevSetIndices(HANDLE hDevice, CONST D3DDDIARG_SETINDICES* pData)
3484{
3485 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3486 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3487 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3488 Assert(pDevice);
3489 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3490
3491 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3492 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hIndexBuffer;
3493 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
3494 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
3495 if (pRc)
3496 {
3497 Assert(pRc->cAllocations == 1);
3498 pAlloc = &pRc->aAllocations[0];
3499 Assert(pAlloc->pD3DIf);
3500 pIndexBuffer = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
3501 }
3502 HRESULT hr = pDevice9If->SetIndices(pIndexBuffer);
3503 Assert(hr == S_OK);
3504 if (hr == S_OK)
3505 {
3506 pDevice->pIndicesAlloc = pAlloc;
3507 pDevice->IndiciesInfo.uiStride = pData->Stride;
3508 }
3509 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3510 return hr;
3511}
3512
3513static HRESULT APIENTRY vboxWddmDDevSetIndicesUm(HANDLE hDevice, UINT IndexSize, CONST VOID* pUMBuffer)
3514{
3515 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3516 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3517 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3518 Assert(pDevice);
3519 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3520
3521 HRESULT hr = S_OK;
3522 pDevice->IndiciesUm.pvBuffer = pUMBuffer;
3523 pDevice->IndiciesUm.cbSize = IndexSize;
3524 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3525 return hr;
3526}
3527
3528static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE* pData, CONST UINT* pFlagBuffer)
3529{
3530 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3531 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3532 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3533 Assert(pDevice);
3534 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3535
3536 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3537 Assert(!pFlagBuffer);
3538 HRESULT hr = S_OK;
3539
3540//#ifdef DEBUG_misha
3541// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3542// vboxVDbgDumpSurfData((pDevice, ">>>DrawPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3543// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3544//#endif
3545
3546 if (!pDevice->cStreamSources)
3547 {
3548 if (pDevice->aStreamSourceUm[0].pvBuffer)
3549 {
3550#ifdef DEBUG
3551 for (UINT i = 1; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3552 {
3553 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3554 }
3555#endif
3556 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType,
3557 pData->PrimitiveCount,
3558 ((uint8_t*)pDevice->aStreamSourceUm[0].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[0].cbStride,
3559 pDevice->aStreamSourceUm[0].cbStride);
3560 Assert(hr == S_OK);
3561
3562// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
3563 }
3564 else
3565 {
3566 /* todo: impl */
3567 Assert(0);
3568 }
3569 }
3570 else
3571 {
3572
3573#ifdef DEBUG
3574 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3575 {
3576 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3577 }
3578
3579 uint32_t cStreams = 0;
3580 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
3581 {
3582 if (pDevice->aStreamSource[i])
3583 {
3584 ++cStreams;
3585 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
3586 }
3587 }
3588
3589 Assert(cStreams);
3590 Assert(cStreams == pDevice->cStreamSources);
3591#endif
3592 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
3593 pData->VStart,
3594 pData->PrimitiveCount);
3595 Assert(hr == S_OK);
3596
3597// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitive\n"));
3598#if 0
3599 IDirect3DVertexDeclaration9* pDecl;
3600 hr = pDevice9If->GetVertexDeclaration(&pDecl);
3601 Assert(hr == S_OK);
3602 if (hr == S_OK)
3603 {
3604 Assert(pDecl);
3605 D3DVERTEXELEMENT9 aDecls9[MAXD3DDECLLENGTH];
3606 UINT cDecls9 = 0;
3607 hr = pDecl->GetDeclaration(aDecls9, &cDecls9);
3608 Assert(hr == S_OK);
3609 if (hr == S_OK)
3610 {
3611 Assert(cDecls9);
3612 for (UINT i = 0; i < cDecls9 - 1 /* the last one is D3DDECL_END */; ++i)
3613 {
3614 D3DVERTEXELEMENT9 *pDecl9 = &aDecls9[i];
3615 Assert(pDecl9->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm) || pDecl9->Stream == 0xff);
3616 if (pDecl9->Stream != 0xff)
3617 {
3618 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrc = &pDevice->aStreamSourceUm[pDecl9->Stream];
3619 if (pStrSrc->pvBuffer)
3620 {
3621 WORD iStream = pDecl9->Stream;
3622 D3DVERTEXELEMENT9 *pLastCDecl9 = pDecl9;
3623 for (UINT j = i+1; j < cDecls9 - 1 /* the last one is D3DDECL_END */; ++j)
3624 {
3625 pDecl9 = &aDecls9[j];
3626 if (iStream == pDecl9->Stream)
3627 {
3628 pDecl9->Stream = 0xff; /* mark as done */
3629 Assert(pDecl9->Offset != pLastCDecl9->Offset);
3630 if (pDecl9->Offset > pLastCDecl9->Offset)
3631 pLastCDecl9 = pDecl9;
3632 }
3633 }
3634 /* vertex size is MAX(all Offset's) + sizeof (data_type with MAX offset) + stride*/
3635 UINT cbVertex = pLastCDecl9->Offset + pStrSrc->cbStride;
3636 UINT cbType;
3637 switch (pLastCDecl9->Type)
3638 {
3639 case D3DDECLTYPE_FLOAT1:
3640 cbType = sizeof (float);
3641 break;
3642 case D3DDECLTYPE_FLOAT2:
3643 cbType = sizeof (float) * 2;
3644 break;
3645 case D3DDECLTYPE_FLOAT3:
3646 cbType = sizeof (float) * 3;
3647 break;
3648 case D3DDECLTYPE_FLOAT4:
3649 cbType = sizeof (float) * 4;
3650 break;
3651 case D3DDECLTYPE_D3DCOLOR:
3652 cbType = 4;
3653 break;
3654 case D3DDECLTYPE_UBYTE4:
3655 cbType = 4;
3656 break;
3657 case D3DDECLTYPE_SHORT2:
3658 cbType = sizeof (short) * 2;
3659 break;
3660 case D3DDECLTYPE_SHORT4:
3661 cbType = sizeof (short) * 4;
3662 break;
3663 case D3DDECLTYPE_UBYTE4N:
3664 cbType = 4;
3665 break;
3666 case D3DDECLTYPE_SHORT2N:
3667 cbType = sizeof (short) * 2;
3668 break;
3669 case D3DDECLTYPE_SHORT4N:
3670 cbType = sizeof (short) * 4;
3671 break;
3672 case D3DDECLTYPE_USHORT2N:
3673 cbType = sizeof (short) * 2;
3674 break;
3675 case D3DDECLTYPE_USHORT4N:
3676 cbType = sizeof (short) * 4;
3677 break;
3678 case D3DDECLTYPE_UDEC3:
3679 cbType = sizeof (signed) * 3;
3680 break;
3681 case D3DDECLTYPE_DEC3N:
3682 cbType = sizeof (unsigned) * 3;
3683 break;
3684 case D3DDECLTYPE_FLOAT16_2:
3685 cbType = 2 * 2;
3686 break;
3687 case D3DDECLTYPE_FLOAT16_4:
3688 cbType = 2 * 4;
3689 break;
3690 default:
3691 Assert(0);
3692 cbType = 1;
3693 }
3694 cbVertex += cbType;
3695
3696 UINT cVertexes;
3697 switch (pData->PrimitiveType)
3698 {
3699 case D3DPT_POINTLIST:
3700 cVertexes = pData->PrimitiveCount;
3701 break;
3702 case D3DPT_LINELIST:
3703 cVertexes = pData->PrimitiveCount * 2;
3704 break;
3705 case D3DPT_LINESTRIP:
3706 cVertexes = pData->PrimitiveCount + 1;
3707 break;
3708 case D3DPT_TRIANGLELIST:
3709 cVertexes = pData->PrimitiveCount * 3;
3710 break;
3711 case D3DPT_TRIANGLESTRIP:
3712 cVertexes = pData->PrimitiveCount + 2;
3713 break;
3714 case D3DPT_TRIANGLEFAN:
3715 cVertexes = pData->PrimitiveCount + 2;
3716 break;
3717 default:
3718 Assert(0);
3719 cVertexes = pData->PrimitiveCount;
3720 }
3721 UINT cbVertexes = cVertexes * cbVertex;
3722 IDirect3DVertexBuffer9 *pCurVb = NULL, *pVb = NULL;
3723 UINT cbOffset;
3724 UINT cbStride;
3725 hr = pDevice9If->GetStreamSource(iStream, &pCurVb, &cbOffset, &cbStride);
3726 Assert(hr == S_OK);
3727 if (hr == S_OK)
3728 {
3729 if (pCurVb)
3730 {
3731 if (cbStride == pStrSrc->cbStride)
3732 {
3733 /* ensure our data feets in the buffer */
3734 D3DVERTEXBUFFER_DESC Desc;
3735 hr = pCurVb->GetDesc(&Desc);
3736 Assert(hr == S_OK);
3737 if (hr == S_OK)
3738 {
3739 if (Desc.Size >= cbVertexes)
3740 pVb = pCurVb;
3741 }
3742 }
3743 }
3744 }
3745 else
3746 {
3747 pCurVb = NULL;
3748 }
3749
3750 if (!pVb)
3751 {
3752 hr = pDevice9If->CreateVertexBuffer(cbVertexes,
3753 0, /* DWORD Usage */
3754 0, /* DWORD FVF */
3755 D3DPOOL_DEFAULT, /* D3DPOOL Pool */
3756 &pVb,
3757 NULL /*HANDLE* pSharedHandle*/);
3758 Assert(hr == S_OK);
3759 if (hr == S_OK)
3760 {
3761 hr = pDevice9If->SetStreamSource(iStream, pVb, 0, pStrSrc->cbStride);
3762 Assert(hr == S_OK);
3763 if (hr == S_OK)
3764 {
3765 if (pCurVb)
3766 pCurVb->Release();
3767 }
3768 else
3769 {
3770 pVb->Release();
3771 pVb = NULL;
3772 }
3773 }
3774 }
3775
3776 if (pVb)
3777 {
3778 Assert(hr == S_OK);
3779 VOID *pvData;
3780 hr = pVb->Lock(0, /* UINT OffsetToLock */
3781 cbVertexes,
3782 &pvData,
3783 D3DLOCK_DISCARD);
3784 Assert(hr == S_OK);
3785 if (hr == S_OK)
3786 {
3787 memcpy (pvData, ((uint8_t*)pStrSrc->pvBuffer) + pData->VStart * cbVertex, cbVertexes);
3788 HRESULT tmpHr = pVb->Unlock();
3789 Assert(tmpHr == S_OK);
3790 }
3791 }
3792 }
3793 }
3794 }
3795 }
3796 if (hr == S_OK)
3797 {
3798 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
3799 0 /* <- since we use our own StreamSource buffer which has data at the very beginning*/,
3800 pData->PrimitiveCount);
3801 Assert(hr == S_OK);
3802 }
3803 }
3804#endif
3805 }
3806
3807//#ifdef DEBUG_misha
3808// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3809// vboxVDbgDumpSurfData((pDevice, "<<<DrawPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3810// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3811//#endif
3812
3813 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3814 return hr;
3815}
3816
3817static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE* pData)
3818{
3819 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3820 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3821 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3822 Assert(pDevice);
3823 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3824
3825 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3826//#ifdef DEBUG_misha
3827// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3828// vboxVDbgDumpSurfData((pDevice, ">>>DrawIndexedPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3829// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3830//#endif
3831
3832#ifdef DEBUG
3833 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
3834 {
3835 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
3836 }
3837
3838 Assert(pDevice->pIndicesAlloc);
3839 Assert(!pDevice->pIndicesAlloc->LockInfo.cLocks);
3840
3841 uint32_t cStreams = 0;
3842 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
3843 {
3844 if (pDevice->aStreamSource[i])
3845 {
3846 ++cStreams;
3847 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
3848 }
3849 }
3850
3851 Assert(cStreams);
3852 Assert(cStreams == pDevice->cStreamSources);
3853#endif
3854
3855 HRESULT hr = pDevice9If->DrawIndexedPrimitive(
3856 pData->PrimitiveType,
3857 pData->BaseVertexIndex,
3858 pData->MinIndex,
3859 pData->NumVertices,
3860 pData->StartIndex,
3861 pData->PrimitiveCount);
3862 Assert(hr == S_OK);
3863
3864//#ifdef DEBUG_misha
3865// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3866// vboxVDbgDumpSurfData((pDevice, "<<<DrawIndexedPrimitive:\n", pDevice->pRenderTargetRc, iBackBuf,
3867// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3868//#endif
3869
3870
3871 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3872 return hr;
3873}
3874
3875static HRESULT APIENTRY vboxWddmDDevDrawRectPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWRECTPATCH* pData, CONST D3DDDIRECTPATCH_INFO* pInfo, CONST FLOAT* pPatch)
3876{
3877 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3878 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3879 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3880 Assert(pDevice);
3881 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3882 Assert(0);
3883 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3884 return E_FAIL;
3885}
3886
3887static HRESULT APIENTRY vboxWddmDDevDrawTriPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWTRIPATCH* pData, CONST D3DDDITRIPATCH_INFO* pInfo, CONST FLOAT* pPatch)
3888{
3889 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3890 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3891 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3892 Assert(pDevice);
3893 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3894 Assert(0);
3895 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3896 return E_FAIL;
3897}
3898
3899static HRESULT APIENTRY vboxWddmDDevDrawPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE2* pData)
3900{
3901 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
3902 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3903 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3904 Assert(pDevice);
3905 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3906
3907 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3908 HRESULT hr;
3909
3910#if 0
3911 int stream;
3912 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
3913 {
3914 if (pDevice->aStreamSource[stream] && pDevice->aStreamSource[stream]->LockInfo.cLocks)
3915 {
3916 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
3917 if (pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite))
3918 {
3919 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf;
3920 Assert(pLock->fFlags.RangeValid);
3921 pD3D9VBuf->Lock(pLock->Range.Offset, pLock->Range.Size,
3922 &pLock->LockedRect.pBits,
3923 vboxDDI2D3DLockFlags(pLock->fFlags));
3924 RECT r;
3925 r.top = 0;
3926 r.left = pLock->Range.Offset;
3927 r.bottom = 1;
3928 r.right = pLock->Range.Offset + pLock->Range.Size;
3929
3930 vboxWddmLockUnlockMemSynch(pDevice->aStreamSource[stream], &pLock->LockedRect, &r, true /*bool bToLockInfo*/);
3931
3932 pD3D9VBuf->Unlock();
3933 }
3934 }
3935 }
3936
3937 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset, pData->PrimitiveCount);
3938#else
3939//#ifdef DEBUG_misha
3940// uint32_t iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3941// vboxVDbgDumpSurfData((pDevice, ">>>DrawPrimitive2:\n", pDevice->pRenderTargetRc, iBackBuf,
3942// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3943//#endif
3944
3945#ifdef DEBUG
3946 uint32_t cStreams = 0;
3947#endif
3948
3949 int stream;
3950 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
3951 {
3952 if (pDevice->aStreamSource[stream])
3953 {
3954#ifdef DEBUG
3955 ++cStreams;
3956#endif
3957 Assert(stream==0); /*only stream 0 should be accessed here*/
3958 Assert(pDevice->StreamSourceInfo[stream].uiStride!=0);
3959 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
3960
3961 if (pDevice->aStreamSource[stream]->LockInfo.cLocks)
3962 {
3963// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
3964
3965 Assert(pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite));
3966 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType, pData->PrimitiveCount,
3967 (void*)((uintptr_t)pDevice->aStreamSource[stream]->pvMem+pDevice->StreamSourceInfo[stream].uiOffset+pData->FirstVertexOffset),
3968 pDevice->StreamSourceInfo[stream].uiStride);
3969 Assert(hr == S_OK);
3970 hr = pDevice9If->SetStreamSource(stream, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf, pDevice->StreamSourceInfo[stream].uiOffset, pDevice->StreamSourceInfo[stream].uiStride);
3971 Assert(hr == S_OK);
3972 }
3973 else
3974 {
3975// vboxVDbgMpPrint((pDevice, __FUNCTION__": DrawPrimitive\n"));
3976
3977 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset/pDevice->StreamSourceInfo[stream].uiStride, pData->PrimitiveCount);
3978 Assert(hr == S_OK);
3979 }
3980 }
3981 }
3982
3983#ifdef DEBUG
3984 Assert(cStreams);
3985 Assert(cStreams == pDevice->cStreamSources);
3986#endif
3987#endif
3988
3989//#ifdef DEBUG_misha
3990// iBackBuf = (pDevice->iRenderTargetFrontBuf + 1) % pDevice->pRenderTargetRc->cAllocations;
3991// vboxVDbgDumpSurfData((pDevice, "<<<DrawPrimitive2:\n", pDevice->pRenderTargetRc, iBackBuf,
3992// NULL, (IDirect3DSurface9*)pDevice->pRenderTargetRc->aAllocations[iBackBuf].pD3DIf, "\n"));
3993//#endif
3994
3995 Assert(hr == S_OK);
3996 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3997 return hr;
3998}
3999
4000static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE2* pData, UINT dwIndicesSize, CONST VOID* pIndexBuffer, CONST UINT* pFlagBuffer)
4001{
4002 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4003 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4004 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4005 Assert(pDevice);
4006 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4007 Assert(0);
4008 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4009 return E_FAIL;
4010}
4011
4012static HRESULT APIENTRY vboxWddmDDevVolBlt(HANDLE hDevice, CONST D3DDDIARG_VOLUMEBLT* pData)
4013{
4014 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4015 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4016 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4017 Assert(pDevice);
4018 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4019 Assert(0);
4020 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4021 return E_FAIL;
4022}
4023
4024static HRESULT APIENTRY vboxWddmDDevBufBlt(HANDLE hDevice, CONST D3DDDIARG_BUFFERBLT* pData)
4025{
4026 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4027 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4028 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4029 Assert(pDevice);
4030 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4031 Assert(0);
4032 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4033 return E_FAIL;
4034}
4035
4036static HRESULT APIENTRY vboxWddmDDevTexBlt(HANDLE hDevice, CONST D3DDDIARG_TEXBLT* pData)
4037{
4038 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4039 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4040 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4041 Assert(pDevice);
4042 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4043 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4044 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
4045 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
4046 /* requirements for D3DDevice9::UpdateTexture */
4047 Assert(pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4048 Assert(pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
4049 HRESULT hr = S_OK;
4050
4051#ifdef DEBUG_misha
4052 bool bDo = false;
4053 IDirect3DSurface9 *pTstSrcSurfIf = NULL;
4054 IDirect3DSurface9 *pTstDstSurfIf = NULL;
4055
4056 if (g_VDbgTstDumpEnable)
4057 {
4058 hr = vboxWddmSurfGet(pSrcRc, 0, &pTstSrcSurfIf);
4059 Assert(hr == S_OK);
4060 hr = vboxWddmSurfGet(pDstRc, 0, &pTstDstSurfIf);
4061 Assert(hr == S_OK);
4062
4063 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
4064 {
4065 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
4066 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
4067 {
4068 D3DSURFACE_DESC SrcDesc;
4069 HRESULT hr = pTstSrcSurfIf->GetDesc(&SrcDesc);
4070 Assert(hr == S_OK);
4071 if (hr == S_OK)
4072 {
4073 D3DSURFACE_DESC DstDesc;
4074 hr = pTstDstSurfIf->GetDesc(&DstDesc);
4075 Assert(hr == S_OK);
4076 if (hr == S_OK)
4077 {
4078 if (SrcDesc.Width == DstDesc.Width
4079 && SrcDesc.Height == DstDesc.Height)
4080 {
4081 bDo = true;
4082 }
4083 }
4084 }
4085 }
4086 }
4087 }
4088
4089 if (bDo)
4090 {
4091 RECT DstRect;
4092 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
4093 vboxVDbgDumpSurfData((pDevice, "TexBlt-pre Src:\n", pSrcRc, 0, &pData->SrcRect, pTstSrcSurfIf, "\n"));
4094 vboxVDbgDumpSurfData((pDevice, "TexBlt-pre Dst:\n", pDstRc, 0, &DstRect, pTstDstSurfIf, "\n"));
4095 }
4096#endif
4097
4098 if (pSrcRc->aAllocations[0].D3DWidth == pDstRc->aAllocations[0].D3DWidth
4099 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
4100 && pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat
4101 &&pData->DstPoint.x == 0 && pData->DstPoint.y == 0
4102 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
4103 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
4104 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height)
4105 {
4106 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcRc->aAllocations[0].pD3DIf;
4107 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstRc->aAllocations[0].pD3DIf;
4108 Assert(pD3DIfSrcTex);
4109 Assert(pD3DIfDstTex);
4110 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
4111 Assert(hr == S_OK);
4112 }
4113 else
4114 {
4115 IDirect3DSurface9 *pSrcSurfIf = NULL;
4116 IDirect3DSurface9 *pDstSurfIf = NULL;
4117 hr = vboxWddmSurfGet(pDstRc, 0, &pDstSurfIf);
4118 Assert(hr == S_OK);
4119 if (hr == S_OK)
4120 {
4121 hr = vboxWddmSurfGet(pSrcRc, 0, &pSrcSurfIf);
4122 Assert(hr == S_OK);
4123 if (hr == S_OK)
4124 {
4125 RECT DstRect;
4126 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
4127#ifdef DEBUG
4128 RECT tstRect = {0,0, pDstRc->aAllocations[0].SurfDesc.width, pDstRc->aAllocations[0].SurfDesc.height};
4129 Assert(vboxWddmRectIsCoveres(&tstRect, &DstRect));
4130#endif
4131 hr = pDevice9If->StretchRect(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &DstRect, D3DTEXF_NONE);
4132 Assert(hr == S_OK);
4133 pSrcSurfIf->Release();
4134 }
4135 pDstSurfIf->Release();
4136 }
4137 }
4138
4139#ifdef DEBUG_misha
4140 if (bDo)
4141 {
4142 RECT DstRect;
4143 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
4144 vboxVDbgDumpSurfData((pDevice, "TexBlt-post Src:\n", pSrcRc, 0, &pData->SrcRect, pTstSrcSurfIf, "\n"));
4145 vboxVDbgDumpSurfData((pDevice, "TexBlt-post Dst:\n", pDstRc, 0, &DstRect, pTstDstSurfIf, "\n"));
4146 }
4147
4148 if (pTstDstSurfIf)
4149 pTstDstSurfIf->Release();
4150 if (pTstSrcSurfIf)
4151 pTstSrcSurfIf->Release();
4152#endif
4153 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4154 return hr;
4155}
4156
4157static HRESULT APIENTRY vboxWddmDDevStateSet(HANDLE hDevice, D3DDDIARG_STATESET* pData)
4158{
4159 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4160 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4161 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4162 Assert(pDevice);
4163 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4164 Assert(0);
4165 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4166 return E_FAIL;
4167}
4168static HRESULT APIENTRY vboxWddmDDevSetPriority(HANDLE hDevice, CONST D3DDDIARG_SETPRIORITY* pData)
4169{
4170 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4171// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4172// Assert(pDevice);
4173// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4174 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4175 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4176 return S_OK;
4177}
4178AssertCompile(sizeof (RECT) == sizeof (D3DRECT));
4179AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DRECT, x1));
4180AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DRECT, x2));
4181AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DRECT, y1));
4182AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DRECT, y2));
4183AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DRECT, x1));
4184AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DRECT, x2));
4185AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DRECT, y1));
4186AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DRECT, y2));
4187
4188static HRESULT APIENTRY vboxWddmDDevClear(HANDLE hDevice, CONST D3DDDIARG_CLEAR* pData, UINT NumRect, CONST RECT* pRect)
4189{
4190 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4191 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4192 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4193 Assert(pDevice);
4194 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4195 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4196 HRESULT hr = pDevice9If->Clear(NumRect, (D3DRECT*)pRect /* see AssertCompile above */,
4197 pData->Flags,
4198 pData->FillColor,
4199 pData->FillDepth,
4200 pData->FillStencil);
4201 Assert(hr == S_OK);
4202 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4203 return hr;
4204}
4205static HRESULT APIENTRY vboxWddmDDevUpdatePalette(HANDLE hDevice, CONST D3DDDIARG_UPDATEPALETTE* pData, CONST PALETTEENTRY* pPaletteData)
4206{
4207 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4208 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4209 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4210 Assert(pDevice);
4211 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4212 Assert(0);
4213 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4214 return E_FAIL;
4215}
4216
4217static HRESULT APIENTRY vboxWddmDDevSetPalette(HANDLE hDevice, CONST D3DDDIARG_SETPALETTE* pData)
4218{
4219 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4220 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4221 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4222 Assert(pDevice);
4223 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4224 Assert(0);
4225 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4226 return E_FAIL;
4227}
4228
4229static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONST* pData , CONST VOID* pRegisters)
4230{
4231 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4232 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4233 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4234 Assert(pDevice);
4235 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4236 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4237 HRESULT hr = pDevice9If->SetVertexShaderConstantF(
4238 pData->Register,
4239 (CONST float*)pRegisters,
4240 pData->Count);
4241 Assert(hr == S_OK);
4242 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4243 return hr;
4244}
4245static HRESULT APIENTRY vboxWddmDDevMultiplyTransform(HANDLE hDevice, CONST D3DDDIARG_MULTIPLYTRANSFORM* pData)
4246{
4247 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4248 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4249 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4250 Assert(pDevice);
4251 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4252 Assert(0);
4253 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4254 return E_FAIL;
4255}
4256static HRESULT APIENTRY vboxWddmDDevSetTransform(HANDLE hDevice, CONST D3DDDIARG_SETTRANSFORM* pData)
4257{
4258 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4259 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4260 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4261 Assert(pDevice);
4262 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4263 Assert(0);
4264 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4265 return E_FAIL;
4266}
4267static HRESULT APIENTRY vboxWddmDDevSetViewport(HANDLE hDevice, CONST D3DDDIARG_VIEWPORTINFO* pData)
4268{
4269 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4270 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4271 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4272 Assert(pDevice);
4273 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4274
4275 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4276 pDevice->ViewPort.X = pData->X;
4277 pDevice->ViewPort.Y = pData->Y;
4278 pDevice->ViewPort.Width = pData->Width;
4279 pDevice->ViewPort.Height = pData->Height;
4280 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
4281 Assert(hr == S_OK);
4282 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4283 return hr;
4284}
4285static HRESULT APIENTRY vboxWddmDDevSetZRange(HANDLE hDevice, CONST D3DDDIARG_ZRANGE* pData)
4286{
4287 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4288 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4289 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4290 Assert(pDevice);
4291 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4292
4293 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4294 pDevice->ViewPort.MinZ = pData->MinZ;
4295 pDevice->ViewPort.MaxZ = pData->MaxZ;
4296 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
4297 Assert(hr == S_OK);
4298 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4299 return hr;
4300}
4301static HRESULT APIENTRY vboxWddmDDevSetMaterial(HANDLE hDevice, CONST D3DDDIARG_SETMATERIAL* pData)
4302{
4303 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4304 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4305 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4306 Assert(pDevice);
4307 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4308 Assert(0);
4309 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4310 return E_FAIL;
4311}
4312static HRESULT APIENTRY vboxWddmDDevSetLight(HANDLE hDevice, CONST D3DDDIARG_SETLIGHT* pData, CONST D3DDDI_LIGHT* pLightProperties)
4313{
4314 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4315 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4316 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4317 Assert(pDevice);
4318 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4319 Assert(0);
4320 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4321 return E_FAIL;
4322}
4323static HRESULT APIENTRY vboxWddmDDevCreateLight(HANDLE hDevice, CONST D3DDDIARG_CREATELIGHT* pData)
4324{
4325 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4326 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4327 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4328 Assert(pDevice);
4329 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4330 Assert(0);
4331 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4332 return E_FAIL;
4333}
4334static HRESULT APIENTRY vboxWddmDDevDestroyLight(HANDLE hDevice, CONST D3DDDIARG_DESTROYLIGHT* pData)
4335{
4336 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4337 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4338 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4339 Assert(pDevice);
4340 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4341 Assert(0);
4342 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4343 return E_FAIL;
4344}
4345static HRESULT APIENTRY vboxWddmDDevSetClipPlane(HANDLE hDevice, CONST D3DDDIARG_SETCLIPPLANE* pData)
4346{
4347 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4348 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4349 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4350 Assert(pDevice);
4351 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4352
4353 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4354 HRESULT hr = pDevice9If->SetClipPlane(pData->Index, pData->Plane);
4355 Assert(hr == S_OK);
4356 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4357 return hr;
4358}
4359
4360static HRESULT APIENTRY vboxWddmDDevGetInfo(HANDLE hDevice, UINT DevInfoID, VOID* pDevInfoStruct, UINT DevInfoSize)
4361{
4362 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4363 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4364// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4365// Assert(pDevice);
4366// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4367 HRESULT hr = S_OK;
4368 switch (DevInfoID)
4369 {
4370 case D3DDDIDEVINFOID_VCACHE:
4371 {
4372 Assert(DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE));
4373 if (DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE))
4374 {
4375 D3DDDIDEVINFO_VCACHE *pVCache = (D3DDDIDEVINFO_VCACHE*)pDevInfoStruct;
4376 pVCache->Pattern = MAKEFOURCC('C', 'A', 'C', 'H');
4377 pVCache->OptMethod = 0 /* D3DXMESHOPT_STRIPREORDER */;
4378 pVCache->CacheSize = 0;
4379 pVCache->MagicNumber = 0;
4380 }
4381 else
4382 hr = E_INVALIDARG;
4383 break;
4384 }
4385 default:
4386 Assert(0);
4387 hr = E_NOTIMPL;
4388 }
4389 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4390 return hr;
4391}
4392
4393static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
4394{
4395 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4396 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4397 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4398 Assert(pDevice);
4399 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4400 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4401 Assert(pData->SubResourceIndex < pRc->cAllocations);
4402 if (pData->SubResourceIndex >= pRc->cAllocations)
4403 return E_INVALIDARG;
4404
4405 HRESULT hr = S_OK;
4406
4407 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4408 {
4409// Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex);
4410
4411 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
4412 {
4413 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
4414 Assert(pData->SubResourceIndex < pRc->cAllocations);
4415 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4416 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
4417 Assert(pD3DIfTex);
4418 RECT *pRect = NULL;
4419 bool bNeedResynch = false;
4420 Assert(!pData->Flags.RangeValid);
4421 Assert(!pData->Flags.BoxValid);
4422 if (pData->Flags.AreaValid)
4423 {
4424 pRect = &pData->Area;
4425 }
4426
4427 /* else - we lock the entire texture, pRect == NULL */
4428
4429// Assert(!pLockAlloc->LockInfo.cLocks);
4430 if (!pLockAlloc->LockInfo.cLocks)
4431 {
4432 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
4433 &pLockAlloc->LockInfo.LockedRect,
4434 pRect,
4435 vboxDDI2D3DLockFlags(pData->Flags));
4436 Assert(hr == S_OK);
4437 if (hr == S_OK)
4438 {
4439
4440// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4441 pLockAlloc->LockInfo.fFlags = pData->Flags;
4442 if (pRect)
4443 {
4444 pLockAlloc->LockInfo.Area = *pRect;
4445 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 1);
4446// pLockAlloc->LockInfo.fFlags.AreaValid = 1;
4447 }
4448 else
4449 {
4450 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 0);
4451// pLockAlloc->LockInfo.fFlags.AreaValid = 0;
4452 }
4453
4454 bNeedResynch = !pData->Flags.Discard;
4455 }
4456 }
4457 else
4458 {
4459// Assert(pLockAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4460// if (pLockAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4461// {
4462// }
4463 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid);
4464 if (pLockAlloc->LockInfo.fFlags.AreaValid && pData->Flags.AreaValid)
4465 {
4466 Assert(pLockAlloc->LockInfo.Area.left == pData->Area.left);
4467 Assert(pLockAlloc->LockInfo.Area.top == pData->Area.top);
4468 Assert(pLockAlloc->LockInfo.Area.right == pData->Area.right);
4469 Assert(pLockAlloc->LockInfo.Area.bottom == pData->Area.bottom);
4470 }
4471 Assert(pLockAlloc->LockInfo.LockedRect.pBits);
4472
4473 bNeedResynch = pLockAlloc->LockInfo.fFlags.Discard && !pData->Flags.Discard;
4474
4475 Assert(!bNeedResynch);
4476
4477 if (/*(pLockAlloc->LockInfo.fFlags.Discard && !pData->Flags.Discard)
4478 || */
4479 (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly))
4480 {
4481 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
4482 Assert(hr == S_OK);
4483 if (hr == S_OK)
4484 {
4485 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
4486 &pLockAlloc->LockInfo.LockedRect,
4487 pRect,
4488 vboxDDI2D3DLockFlags(pData->Flags));
4489 Assert(hr == S_OK);
4490 pLockAlloc->LockInfo.fFlags.ReadOnly = 0;
4491 }
4492 }
4493 }
4494
4495 if (hr == S_OK)
4496 {
4497 ++pLockAlloc->LockInfo.cLocks;
4498
4499 if (!pData->Flags.NotifyOnly)
4500 {
4501 pData->pSurfData = pLockAlloc->LockInfo.LockedRect.pBits;
4502 pData->Pitch = pLockAlloc->LockInfo.LockedRect.Pitch;
4503 pData->SlicePitch = 0;
4504 Assert(pLockAlloc->SurfDesc.slicePitch == 0);
4505 Assert(!pLockAlloc->pvMem);
4506 }
4507 else
4508 {
4509 Assert(pLockAlloc->pvMem);
4510 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4511#if 0
4512 if (bNeedResynch)
4513 vboxWddmLockUnlockMemSynch(pLockAlloc, &pLockAlloc->LockInfo.LockedRect, pRect, false /*bool bToLockInfo*/);
4514#endif
4515 }
4516 }
4517 }
4518 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
4519 {
4520 Assert(pData->SubResourceIndex < pRc->cAllocations);
4521 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4522 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4523 BOOL bLocked = false;
4524 Assert(pD3D9VBuf);
4525 Assert(!pData->Flags.AreaValid);
4526 Assert(!pData->Flags.BoxValid);
4527 D3DDDIRANGE *pRange = NULL;
4528 if (pData->Flags.RangeValid)
4529 {
4530 pRange = &pData->Range;
4531 }
4532
4533 /* else - we lock the entire vertex buffer, pRect == NULL */
4534
4535 Assert(!pAlloc->LockInfo.cLocks);
4536 if (!pAlloc->LockInfo.cLocks)
4537 {
4538 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
4539 {
4540 hr = pD3D9VBuf->Lock(pRange ? pRange->Offset : 0,
4541 pRange ? pRange->Size : 0,
4542 &pAlloc->LockInfo.LockedRect.pBits,
4543 vboxDDI2D3DLockFlags(pData->Flags));
4544 bLocked = true;
4545 }
4546
4547 Assert(hr == S_OK);
4548 if (hr == S_OK)
4549 {
4550 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.width;
4551// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4552 pAlloc->LockInfo.fFlags = pData->Flags;
4553 if (pRange)
4554 {
4555 pAlloc->LockInfo.Range = *pRange;
4556 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
4557// pAlloc->LockInfo.fFlags.RangeValid = 1;
4558 }
4559 else
4560 {
4561 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
4562// pAlloc->LockInfo.fFlags.RangeValid = 0;
4563 }
4564 }
4565 }
4566 else
4567 {
4568// Assert(pAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4569// if (pAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4570// {
4571// }
4572 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
4573 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
4574 {
4575 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
4576 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
4577 }
4578 Assert(pAlloc->LockInfo.LockedRect.pBits);
4579 }
4580
4581 if (hr == S_OK)
4582 {
4583 ++pAlloc->LockInfo.cLocks;
4584
4585 if (!pData->Flags.NotifyOnly)
4586 {
4587 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
4588 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
4589 pData->SlicePitch = 0;
4590 Assert(pAlloc->SurfDesc.slicePitch == 0);
4591 Assert(!pAlloc->pvMem);
4592 }
4593 else
4594 {
4595 Assert(pAlloc->pvMem);
4596 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4597 if (bLocked && !pData->Flags.Discard)
4598 {
4599 RECT r, *pr;
4600 if (pRange)
4601 {
4602 r.top = 0;
4603 r.left = pRange->Offset;
4604 r.bottom = 1;
4605 r.right = pRange->Offset + pRange->Size;
4606 pr = &r;
4607 }
4608 else
4609 pr = NULL;
4610 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
4611 }
4612 }
4613 }
4614 }
4615 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
4616 {
4617 Assert(pData->SubResourceIndex < pRc->cAllocations);
4618 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4619 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
4620 BOOL bLocked = false;
4621 Assert(pD3D9IBuf);
4622 Assert(!pData->Flags.AreaValid);
4623 Assert(!pData->Flags.BoxValid);
4624 D3DDDIRANGE *pRange = NULL;
4625 if (pData->Flags.RangeValid)
4626 {
4627 pRange = &pData->Range;
4628 }
4629
4630 /* else - we lock the entire vertex buffer, pRect == NULL */
4631
4632 Assert(!pAlloc->LockInfo.cLocks);
4633 if (!pAlloc->LockInfo.cLocks)
4634 {
4635 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
4636 {
4637 hr = pD3D9IBuf->Lock(pRange ? pRange->Offset : 0,
4638 pRange ? pRange->Size : 0,
4639 &pAlloc->LockInfo.LockedRect.pBits,
4640 vboxDDI2D3DLockFlags(pData->Flags));
4641 bLocked = true;
4642 }
4643
4644 Assert(hr == S_OK);
4645 if (hr == S_OK)
4646 {
4647 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.width;
4648// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
4649 pAlloc->LockInfo.fFlags = pData->Flags;
4650 if (pRange)
4651 {
4652 pAlloc->LockInfo.Range = *pRange;
4653 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
4654// pAlloc->LockInfo.fFlags.RangeValid = 1;
4655 }
4656 else
4657 {
4658 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
4659// pAlloc->LockInfo.fFlags.RangeValid = 0;
4660 }
4661 }
4662 }
4663 else
4664 {
4665// Assert(pAlloc->LockInfo.fFlags.Value == pData->Flags.Value);
4666// if (pAlloc->LockInfo.fFlags.Value != pData->Flags.Value)
4667// {
4668// }
4669 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
4670 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
4671 {
4672 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
4673 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
4674 }
4675 Assert(pAlloc->LockInfo.LockedRect.pBits);
4676 }
4677
4678 if (hr == S_OK)
4679 {
4680 ++pAlloc->LockInfo.cLocks;
4681
4682 if (!pData->Flags.NotifyOnly)
4683 {
4684 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
4685 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
4686 pData->SlicePitch = 0;
4687 Assert(pAlloc->SurfDesc.slicePitch == 0);
4688 Assert(!pAlloc->pvMem);
4689 }
4690 else
4691 {
4692 Assert(pAlloc->pvMem);
4693 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
4694 if (bLocked && !pData->Flags.Discard)
4695 {
4696 RECT r, *pr;
4697 if (pRange)
4698 {
4699 r.top = 0;
4700 r.left = pRange->Offset;
4701 r.bottom = 1;
4702 r.right = pRange->Offset + pRange->Size;
4703 pr = &r;
4704 }
4705 else
4706 pr = NULL;
4707 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
4708 }
4709 }
4710 }
4711 }
4712 else
4713 {
4714 Assert(0);
4715 }
4716 }
4717 else
4718 {
4719 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4720 D3DDDICB_LOCK LockData;
4721 LockData.hAllocation = pAlloc->hAllocation;
4722 LockData.PrivateDriverData = 0;
4723 LockData.NumPages = 0;
4724 LockData.pPages = NULL;
4725 LockData.pData = NULL; /* out */
4726 LockData.Flags.Value = 0;
4727 LockData.Flags.Discard = pData->Flags.Discard;
4728 LockData.Flags.DonotWait = pData->Flags.DoNotWait;
4729
4730
4731 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
4732 Assert(hr == S_OK || (hr == D3DERR_WASSTILLDRAWING && pData->Flags.DoNotWait));
4733 if (hr == S_OK)
4734 {
4735 Assert(!pAlloc->LockInfo.cLocks);
4736
4737 uintptr_t offset;
4738 if (pData->Flags.AreaValid)
4739 {
4740 offset = pAlloc->SurfDesc.pitch * pData->Area.top +
4741 ((pAlloc->SurfDesc.bpp * pData->Area.left) >> 3);
4742 }
4743 else if (pData->Flags.RangeValid)
4744 {
4745 offset = pData->Range.Offset;
4746 }
4747 else if (pData->Flags.BoxValid)
4748 {
4749 vboxVDbgPrintF((__FUNCTION__": Implement Box area"));
4750 Assert(0);
4751 }
4752 else
4753 {
4754 offset = 0;
4755 }
4756
4757 if (!pData->Flags.ReadOnly)
4758 {
4759 if (pData->Flags.AreaValid)
4760 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, &pData->Area);
4761 else
4762 {
4763 Assert(!pData->Flags.RangeValid);
4764 Assert(!pData->Flags.BoxValid);
4765 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, NULL); /* <- NULL means the entire surface */
4766 }
4767 }
4768
4769 if (pData->Flags.Discard)
4770 {
4771 /* check if the surface was renamed */
4772 if (LockData.hAllocation)
4773 pAlloc->hAllocation = LockData.hAllocation;
4774 }
4775
4776 pData->pSurfData = ((uint8_t*)LockData.pData) + offset;
4777 pData->Pitch = pAlloc->SurfDesc.pitch;
4778 pData->SlicePitch = pAlloc->SurfDesc.slicePitch;
4779
4780 Assert(hr == S_OK);
4781 ++pAlloc->LockInfo.cLocks;
4782 }
4783 }
4784
4785 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(%d)\n", hDevice, hr));
4786 return hr;
4787}
4788static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOCK* pData)
4789{
4790 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4791 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4792 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4793 Assert(pDevice);
4794 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4795 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4796 HRESULT hr = S_OK;
4797
4798 Assert(pData->SubResourceIndex < pRc->cAllocations);
4799 if (pData->SubResourceIndex >= pRc->cAllocations)
4800 return E_INVALIDARG;
4801
4802 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4803 {
4804 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
4805 {
4806 Assert(pData->SubResourceIndex < pRc->cAllocations);
4807 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4808
4809 --pLockAlloc->LockInfo.cLocks;
4810 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
4811// pLockAlloc->LockInfo.cLocks = 0;
4812 if (!pLockAlloc->LockInfo.cLocks)
4813 {
4814 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
4815// Assert(!pLockAlloc->LockInfo.cLocks);
4816 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
4817 Assert(pD3DIfTex);
4818 /* this is a sysmem texture, update */
4819#if 0
4820 if (pLockAlloc->pvMem && !pLockAlloc->LockInfo.fFlags.ReadOnly)
4821 {
4822 vboxWddmLockUnlockMemSynch(pLockAlloc, &pLockAlloc->LockInfo.LockedRect,
4823 pLockAlloc->LockInfo.fFlags.AreaValid ? &pLockAlloc->LockInfo.Area : NULL,
4824 true /*bool bToLockInfo*/);
4825 }
4826#endif
4827 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
4828 Assert(hr == S_OK);
4829 }
4830 else
4831 {
4832 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
4833 }
4834 }
4835 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
4836 {
4837 Assert(pData->SubResourceIndex < pRc->cAllocations);
4838 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4839
4840 --pAlloc->LockInfo.cLocks;
4841 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4842 if (!pAlloc->LockInfo.cLocks
4843 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
4844 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
4845 {
4846// Assert(!pAlloc->LockInfo.cLocks);
4847 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4848 Assert(pD3D9VBuf);
4849 /* this is a sysmem texture, update */
4850 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
4851 {
4852 RECT r, *pr;
4853 if (pAlloc->LockInfo.fFlags.RangeValid)
4854 {
4855 r.top = 0;
4856 r.left = pAlloc->LockInfo.Range.Offset;
4857 r.bottom = 1;
4858 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
4859 pr = &r;
4860 }
4861 else
4862 pr = NULL;
4863 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
4864 pr,
4865 true /*bool bToLockInfo*/);
4866 }
4867 hr = pD3D9VBuf->Unlock();
4868 Assert(hr == S_OK);
4869 }
4870 else
4871 {
4872 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4873 }
4874 }
4875 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
4876 {
4877 Assert(pData->SubResourceIndex < pRc->cAllocations);
4878 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4879
4880 --pAlloc->LockInfo.cLocks;
4881 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4882 if (!pAlloc->LockInfo.cLocks
4883 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
4884 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
4885 {
4886// Assert(!pAlloc->LockInfo.cLocks);
4887 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
4888 Assert(pD3D9IBuf);
4889 /* this is a sysmem texture, update */
4890 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
4891 {
4892 RECT r, *pr;
4893 if (pAlloc->LockInfo.fFlags.RangeValid)
4894 {
4895 r.top = 0;
4896 r.left = pAlloc->LockInfo.Range.Offset;
4897 r.bottom = 1;
4898 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
4899 pr = &r;
4900 }
4901 else
4902 pr = NULL;
4903 vboxWddmLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
4904 pr,
4905 true /*bool bToLockInfo*/);
4906 }
4907 hr = pD3D9IBuf->Unlock();
4908 Assert(hr == S_OK);
4909 }
4910 else
4911 {
4912 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4913 }
4914 }
4915 else
4916 {
4917 Assert(0);
4918 }
4919 }
4920 else
4921 {
4922 struct
4923 {
4924 D3DDDICB_UNLOCK Unlock;
4925 D3DKMT_HANDLE hAllocation;
4926 } UnlockData;
4927
4928 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4929
4930 UnlockData.Unlock.NumAllocations = 1;
4931 UnlockData.Unlock.phAllocations = &UnlockData.hAllocation;
4932 UnlockData.hAllocation = pAlloc->hAllocation;
4933
4934 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &UnlockData.Unlock);
4935 Assert(hr == S_OK);
4936 if (hr == S_OK)
4937 {
4938 Assert(pAlloc->LockInfo.cLocks);
4939 --pAlloc->LockInfo.cLocks;
4940 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
4941 }
4942 }
4943
4944 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4945 return hr;
4946}
4947static HRESULT APIENTRY vboxWddmDDevLockAsync(HANDLE hDevice, D3DDDIARG_LOCKASYNC* pData)
4948{
4949 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4950 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4951 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4952 Assert(pDevice);
4953 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4954 Assert(0);
4955 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4956 return E_FAIL;
4957}
4958static HRESULT APIENTRY vboxWddmDDevUnlockAsync(HANDLE hDevice, CONST D3DDDIARG_UNLOCKASYNC* pData)
4959{
4960 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4961 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4962 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4963 Assert(pDevice);
4964 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4965 Assert(0);
4966 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4967 return E_FAIL;
4968}
4969static HRESULT APIENTRY vboxWddmDDevRename(HANDLE hDevice, CONST D3DDDIARG_RENAME* pData)
4970{
4971 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
4972 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4973 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4974 Assert(pDevice);
4975 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4976 Assert(0);
4977 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4978 return E_FAIL;
4979}
4980
4981static void vboxWddmRequestAllocFree(D3DDDICB_ALLOCATE* pAlloc)
4982{
4983 RTMemFree(pAlloc);
4984}
4985
4986static D3DDDICB_ALLOCATE* vboxWddmRequestAllocAlloc(D3DDDIARG_CREATERESOURCE* pResource)
4987{
4988 /* allocate buffer for D3DDDICB_ALLOCATE + D3DDDI_ALLOCATIONINFO * numAllocs + PVBOXWDDM_RCINFO with aAllocInfos[numAllocs] */
4989 uint32_t cbBuf = sizeof (D3DDDICB_ALLOCATE);
4990 uint32_t offDdiAllocInfos = (cbBuf + 7) & ~3;
4991 uint32_t cbDdiAllocInfos = sizeof (D3DDDI_ALLOCATIONINFO) * pResource->SurfCount;
4992 cbBuf = offDdiAllocInfos + cbDdiAllocInfos;
4993 uint32_t offRcInfo = (cbBuf + 7) & ~3;
4994 uint32_t cbRcInfo = sizeof (VBOXWDDM_RCINFO);
4995 cbBuf = offRcInfo + cbRcInfo;
4996 uint32_t offAllocInfos = (cbBuf + 7) & ~3;
4997 uint32_t cbAllocInfos = sizeof (VBOXWDDM_ALLOCINFO) * pResource->SurfCount;
4998 cbBuf = offAllocInfos + cbAllocInfos;
4999 uint8_t *pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
5000 Assert(pvBuf);
5001 if (pvBuf)
5002 {
5003 D3DDDICB_ALLOCATE* pAlloc = (D3DDDICB_ALLOCATE*)pvBuf;
5004 pAlloc->NumAllocations = pResource->SurfCount;
5005 pAlloc->pAllocationInfo = (D3DDDI_ALLOCATIONINFO*)(pvBuf + offDdiAllocInfos);
5006 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)(pvBuf + offRcInfo);
5007 pAlloc->PrivateDriverDataSize = cbRcInfo;
5008 pAlloc->pPrivateDriverData = pRcInfo;
5009 pAlloc->hResource = pResource->hResource;
5010 PVBOXWDDM_ALLOCINFO pAllocInfos = (PVBOXWDDM_ALLOCINFO)(pvBuf + offAllocInfos);
5011 for (UINT i = 0; i < pResource->SurfCount; ++i)
5012 {
5013 D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pAlloc->pAllocationInfo[i];
5014 PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
5015 pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
5016 pDdiAllocInfo->PrivateDriverDataSize = sizeof (VBOXWDDM_ALLOCINFO);
5017 }
5018 return pAlloc;
5019 }
5020 return NULL;
5021}
5022
5023static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE* pResource)
5024{
5025 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5026 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5027 HRESULT hr = S_OK;
5028 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5029 Assert(pDevice);
5030 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5031 Assert(pResource);
5032 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
5033
5034 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pResource->SurfCount);
5035 Assert(pRc);
5036 if (pRc)
5037 {
5038 bool bIssueCreateResource = false;
5039 bool bCreateSwapchain = false;
5040 bool bCreateKMResource = false;
5041
5042 pRc->hResource = pResource->hResource;
5043 pRc->hKMResource = NULL;
5044 pRc->pDevice = pDevice;
5045 pRc->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
5046 pRc->RcDesc.fFlags = pResource->Flags;
5047 pRc->RcDesc.enmFormat = pResource->Format;
5048 pRc->RcDesc.enmPool = pResource->Pool;
5049 pRc->RcDesc.enmMultisampleType = pResource->MultisampleType;
5050 pRc->RcDesc.MultisampleQuality = pResource->MultisampleQuality;
5051 pRc->RcDesc.MipLevels = pResource->MipLevels;
5052 pRc->RcDesc.Fvf = pResource->Fvf;
5053 pRc->RcDesc.VidPnSourceId = pResource->VidPnSourceId;
5054 pRc->RcDesc.RefreshRate = pResource->RefreshRate;
5055 pRc->RcDesc.enmRotation = pResource->Rotation;
5056 pRc->cAllocations = pResource->SurfCount;
5057 for (UINT i = 0; i < pResource->SurfCount; ++i)
5058 {
5059 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5060 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5061 pAllocation->hAllocation = NULL;
5062 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
5063 pAllocation->iAlloc = i;
5064 pAllocation->pRc = pRc;
5065 pAllocation->D3DWidth = pSurf->Width;
5066 pAllocation->pvMem = (void*)pSurf->pSysMem;
5067 pAllocation->SurfDesc.pitch = pSurf->SysMemPitch;
5068 pAllocation->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
5069 pAllocation->SurfDesc.depth = pSurf->Depth;
5070 pAllocation->SurfDesc.width = pSurf->Width;
5071 pAllocation->SurfDesc.height = pSurf->Height;
5072 pAllocation->SurfDesc.format = pResource->Format;
5073 }
5074
5075 if (VBOXDISPMODE_IS_3D(pAdapter))
5076 {
5077 if (pResource->Flags.SharedResource)
5078 {
5079 Assert(0); /* <-- need to test that */
5080 bIssueCreateResource = true;
5081 bCreateKMResource = true;
5082 }
5083
5084 if (pResource->Flags.ZBuffer)
5085 {
5086 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5087 for (UINT i = 0; i < pResource->SurfCount; ++i)
5088 {
5089 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5090 IDirect3DSurface9 *pD3D9Surf;
5091 hr = pDevice9If->CreateDepthStencilSurface(pAllocation->SurfDesc.width,
5092 pAllocation->SurfDesc.height,
5093 vboxDDI2D3DFormat(pResource->Format),
5094 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
5095 pResource->MultisampleQuality,
5096 TRUE /* @todo: BOOL Discard */,
5097 &pD3D9Surf,
5098 NULL /*HANDLE* pSharedHandle*/);
5099 Assert(hr == S_OK);
5100 if (hr == S_OK)
5101 {
5102 Assert(pD3D9Surf);
5103 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
5104 pAllocation->pD3DIf = pD3D9Surf;
5105 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
5106 Assert(hr == S_OK);
5107 }
5108 else
5109 {
5110 for (UINT j = 0; j < i; ++j)
5111 {
5112 pRc->aAllocations[j].pD3DIf->Release();
5113 }
5114 break;
5115 }
5116 }
5117 }
5118 else if (pResource->Flags.VertexBuffer)
5119 {
5120 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5121
5122 for (UINT i = 0; i < pResource->SurfCount; ++i)
5123 {
5124 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5125 IDirect3DVertexBuffer9 *pD3D9VBuf;
5126 hr = pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width,
5127 vboxDDI2D3DUsage(pResource->Flags),
5128 pResource->Fvf,
5129 vboxDDI2D3DPool(pResource->Pool),
5130 &pD3D9VBuf,
5131 NULL /*HANDLE* pSharedHandle*/);
5132 Assert(hr == S_OK);
5133 if (hr == S_OK)
5134 {
5135 Assert(pD3D9VBuf);
5136 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_VERTEXBUFFER;
5137 pAllocation->pD3DIf = pD3D9VBuf;
5138 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
5139 {
5140 Assert(pAllocation->pvMem);
5141 D3DLOCKED_RECT lockInfo;
5142 hr = pD3D9VBuf->Lock(0, pAllocation->SurfDesc.width, &lockInfo.pBits, D3DLOCK_DISCARD);
5143 Assert(hr == S_OK);
5144 if (hr == S_OK)
5145 {
5146 lockInfo.Pitch = pAllocation->SurfDesc.pitch;
5147 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
5148 HRESULT tmpHr = pD3D9VBuf->Unlock();
5149 Assert(tmpHr == S_OK);
5150 }
5151 }
5152 else
5153 {
5154 Assert(!pAllocation->pvMem);
5155 }
5156 }
5157 else
5158 {
5159 for (UINT j = 0; j < i; ++j)
5160 {
5161 pRc->aAllocations[j].pD3DIf->Release();
5162 }
5163 break;
5164 }
5165 }
5166 }
5167 else if (pResource->Flags.IndexBuffer)
5168 {
5169 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5170
5171 for (UINT i = 0; i < pResource->SurfCount; ++i)
5172 {
5173 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5174 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5175 IDirect3DIndexBuffer9 *pD3D9IBuf;
5176 hr = pDevice9If->CreateIndexBuffer(pSurf->Width,
5177 vboxDDI2D3DUsage(pResource->Flags),
5178 vboxDDI2D3DFormat(pResource->Format),
5179 vboxDDI2D3DPool(pResource->Pool),
5180 &pD3D9IBuf,
5181 NULL /*HANDLE* pSharedHandle*/
5182 );
5183 Assert(hr == S_OK);
5184 if (hr == S_OK)
5185 {
5186 Assert(pD3D9IBuf);
5187 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_INDEXBUFFER;
5188 pAllocation->pD3DIf = pD3D9IBuf;
5189 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
5190 {
5191 Assert(pAllocation->pvMem);
5192 D3DLOCKED_RECT lockInfo;
5193 hr = pD3D9IBuf->Lock(0, pAllocation->SurfDesc.width, &lockInfo.pBits, D3DLOCK_DISCARD);
5194 Assert(hr == S_OK);
5195 if (hr == S_OK)
5196 {
5197 lockInfo.Pitch = pAllocation->SurfDesc.pitch;
5198 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
5199 HRESULT tmpHr = pD3D9IBuf->Unlock();
5200 Assert(tmpHr == S_OK);
5201 }
5202 }
5203 else
5204 {
5205 Assert(!pAllocation->pvMem);
5206 }
5207 }
5208 else
5209 {
5210 for (UINT j = 0; j < i; ++j)
5211 {
5212 pRc->aAllocations[j].pD3DIf->Release();
5213 }
5214 break;
5215 }
5216 }
5217 }
5218 else if (pResource->Flags.Texture || pResource->Flags.Value == 0)
5219 {
5220 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5221
5222#ifdef DEBUG
5223 {
5224 uint32_t tstW = pResource->pSurfList[0].Width;
5225 uint32_t tstH = pResource->pSurfList[0].Height;
5226 for (UINT i = 1; i < pResource->SurfCount; ++i)
5227 {
5228 tstW /= 2;
5229 tstH /= 2;
5230 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5231 Assert((pSurf->Width == tstW) || (!tstW && (pSurf->Width==1)));
5232 Assert((pSurf->Height == tstH) || (!tstH && (pSurf->Height==1)));
5233 }
5234 }
5235#endif
5236
5237// if (pResource->Flags.RenderTarget)
5238// bIssueCreateResource = true;
5239
5240 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
5241 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[0];
5242 IDirect3DTexture9 *pD3DIfTex;
5243 HANDLE hSharedHandle = NULL;
5244 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
5245 {
5246 Assert(pSurf->pSysMem);
5247 Assert(pSurf->SysMemPitch);
5248 UINT bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
5249 Assert(bpp);
5250 if (bpp)
5251 {
5252 pAllocation->D3DWidth = ((pSurf->SysMemPitch << 3) / bpp);
5253 if ((pSurf->SysMemPitch << 3) % bpp)
5254 {
5255 Assert(0);
5256 ++pAllocation->D3DWidth;
5257 }
5258 Assert(pAllocation->D3DWidth >= pSurf->Width);
5259 }
5260 }
5261#if 0
5262 hr = pDevice9If->CreateTexture(pSurf->Width,
5263 pAllocation->D3DWidth,
5264 pResource->SurfCount,
5265 vboxDDI2D3DUsage(pResource->Flags),
5266 vboxDDI2D3DFormat(pResource->Format),
5267 vboxDDI2D3DPool(pResource->Pool),
5268 &pD3DIfTex,
5269 NULL /* HANDLE* pSharedHandle */
5270 );
5271#else
5272 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
5273 pAllocation->D3DWidth,
5274 pSurf->Height,
5275 pResource->SurfCount,
5276 vboxDDI2D3DUsage(pResource->Flags),
5277 vboxDDI2D3DFormat(pResource->Format),
5278 vboxDDI2D3DPool(pResource->Pool),
5279 &pD3DIfTex,
5280 pResource->Flags.SharedResource ? &hSharedHandle : NULL,
5281 pResource->Pool == D3DDDIPOOL_SYSTEMMEM ? pRc->aAllocations[0].pvMem : NULL);
5282#endif
5283 Assert(hr == S_OK);
5284 if (hr == S_OK)
5285 {
5286 Assert(pD3DIfTex);
5287 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
5288 pAllocation->pD3DIf = pD3DIfTex;
5289 Assert(!!(pResource->Flags.SharedResource) == !!(hSharedHandle));
5290 pAllocation->hSharedHandle = hSharedHandle;
5291#if 0
5292 if (pResource->Pool == D3DDDIPOOL_SYSTEMMEM)
5293 {
5294 for (UINT i = 0; i < pResource->SurfCount; ++i)
5295 {
5296 D3DLOCKED_RECT lockInfo;
5297 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5298 Assert(pAllocation->pvMem);
5299 hr = pD3DIfTex->LockRect(i, &lockInfo, NULL, D3DLOCK_DISCARD);
5300 Assert(hr == S_OK);
5301 if (hr == S_OK)
5302 {
5303 vboxWddmLockUnlockMemSynch(pAllocation, &lockInfo, NULL, true /*bool bToLockInfo*/);
5304 HRESULT tmpHr = pD3DIfTex->UnlockRect(i);
5305 Assert(tmpHr == S_OK);
5306 }
5307 else
5308 {
5309 pD3DIfTex->Release();
5310 break;
5311 }
5312 }
5313 }
5314#endif
5315 }
5316#ifdef DEBUG
5317 else
5318 {
5319 for (UINT i = 0; i < pResource->SurfCount; ++i)
5320 {
5321 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5322 Assert(!pAllocation->pvMem);
5323 }
5324 }
5325#endif
5326 }
5327 else if (pResource->Flags.RenderTarget)
5328 {
5329 HWND hWnd = NULL;
5330 bIssueCreateResource = true;
5331 Assert(pResource->SurfCount);
5332 if (RTListIsEmpty(&pDevice->SwapchainList))
5333 {
5334 bCreateSwapchain = true;
5335 Assert(bIssueCreateResource);
5336 }
5337 else
5338 {
5339 for (UINT i = 0; i < pResource->SurfCount; ++i)
5340 {
5341 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5342
5343 IDirect3DSurface9* pD3D9Surf;
5344 hr = pDevice->pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
5345 pAllocation->SurfDesc.height,
5346 vboxDDI2D3DFormat(pResource->Format),
5347 vboxDDI2D3DMultiSampleType(pResource->MultisampleType),
5348 pResource->MultisampleQuality,
5349 !pResource->Flags.NotLockable /* BOOL Lockable */,
5350 &pD3D9Surf,
5351 NULL /* HANDLE* pSharedHandle */
5352 );
5353 Assert(hr == S_OK);
5354 if (hr == S_OK)
5355 {
5356 Assert(pD3D9Surf);
5357 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
5358 pAllocation->pD3DIf = pD3D9Surf;
5359 hr = vboxWddmSurfSynchMem(pRc, pAllocation);
5360 Assert(hr == S_OK);
5361 if (hr == S_OK)
5362 {
5363#if 0
5364 if(pResource->Flags.Primary)
5365 {
5366 for (UINT i = 0; i < pResource->SurfCount; ++i)
5367 {
5368 vboxWddmSwapchainFindCreate(pDevice, &pRc->aAllocations[i]);
5369 }
5370 Assert(bIssueCreateResource);
5371 }
5372#endif
5373 continue;
5374 }
5375
5376 /* fail branch */
5377 pD3D9Surf->Release();
5378 }
5379
5380 for (UINT j = 0; j < i; ++j)
5381 {
5382 pRc->aAllocations[j].pD3DIf->Release();
5383 }
5384 break;
5385 }
5386 }
5387 }
5388 else
5389 {
5390// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5391// Assert(pScreen->hWnd);
5392// Assert(pScreen->pDevice9If);
5393 Assert(0);
5394 }
5395 }
5396 else
5397 {
5398 bIssueCreateResource = true;
5399 bCreateKMResource = true;
5400 }
5401
5402
5403 if (hr == S_OK && bIssueCreateResource)
5404 {
5405 D3DDDICB_ALLOCATE *pDdiAllocate = vboxWddmRequestAllocAlloc(pResource);
5406 Assert(pDdiAllocate);
5407 if (pDdiAllocate)
5408 {
5409 Assert(pDdiAllocate->pPrivateDriverData);
5410 Assert(pDdiAllocate->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
5411 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)pDdiAllocate->pPrivateDriverData;
5412 pRcInfo->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
5413 pRcInfo->RcDesc = pRc->RcDesc;
5414 pRcInfo->cAllocInfos = pResource->SurfCount;
5415
5416 for (UINT i = 0; i < pResource->SurfCount; ++i)
5417 {
5418 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
5419 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5420 Assert(pDdiAllocI->pPrivateDriverData);
5421 Assert(pDdiAllocI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
5422 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
5423 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5424 pDdiAllocI->hAllocation = NULL;
5425 pDdiAllocI->pSystemMem = pSurf->pSysMem;
5426 Assert((!!(pSurf->pSysMem)) == (pResource->Pool == D3DDDIPOOL_SYSTEMMEM));
5427 pDdiAllocI->VidPnSourceId = pResource->VidPnSourceId;
5428 pDdiAllocI->Flags.Value = 0;
5429 if (pResource->Flags.Primary)
5430 {
5431 Assert(pResource->Flags.RenderTarget);
5432 pDdiAllocI->Flags.Primary = 1;
5433 }
5434
5435 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
5436 pAllocInfo->fFlags = pResource->Flags;
5437 pAllocInfo->hSharedHandle = pAllocation->hSharedHandle;
5438 pAllocInfo->SurfDesc.width = pSurf->Width;
5439 pAllocInfo->SurfDesc.height = pSurf->Height;
5440 pAllocInfo->SurfDesc.format = pResource->Format;
5441 if (!vboxWddmFormatToFourcc(pResource->Format))
5442 pAllocInfo->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
5443 else
5444 pAllocInfo->SurfDesc.bpp = 0;
5445
5446 if (pSurf->SysMemPitch)
5447 {
5448 pAllocInfo->SurfDesc.pitch = pSurf->SysMemPitch;
5449#ifdef DEBUG
5450 UINT tst = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
5451 Assert(tst == pSurf->SysMemPitch);
5452#endif
5453 }
5454 else
5455 pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
5456
5457 pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
5458 pAllocInfo->SurfDesc.depth = pSurf->Depth;
5459 pAllocInfo->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
5460 pAllocInfo->SurfDesc.VidPnSourceId = pResource->VidPnSourceId;
5461 pAllocInfo->SurfDesc.RefreshRate = pResource->RefreshRate;
5462 }
5463
5464 if (bCreateKMResource)
5465 {
5466 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
5467 Assert(hr == S_OK);
5468 Assert(pDdiAllocate->hKMResource);
5469 }
5470 else
5471 {
5472 pDdiAllocate->hResource = NULL;
5473 pDdiAllocate->NumAllocations = 1;
5474 pDdiAllocate->PrivateDriverDataSize = 0;
5475 pDdiAllocate->pPrivateDriverData = NULL;
5476 D3DDDI_ALLOCATIONINFO *pDdiAllocIBase = pDdiAllocate->pAllocationInfo;
5477
5478 for (UINT i = 0; i < pResource->SurfCount; ++i)
5479 {
5480 pDdiAllocate->pAllocationInfo = &pDdiAllocIBase[i];
5481 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
5482 Assert(hr == S_OK);
5483 Assert(!pDdiAllocate->hKMResource);
5484 if (hr == S_OK)
5485 {
5486 Assert(pDdiAllocate->pAllocationInfo->hAllocation);
5487 }
5488 else
5489 {
5490 for (UINT j = 0; i < j; ++j)
5491 {
5492 D3DDDI_ALLOCATIONINFO * pCur = &pDdiAllocIBase[i];
5493 D3DDDICB_DEALLOCATE Dealloc;
5494 Dealloc.hResource = 0;
5495 Dealloc.NumAllocations = 1;
5496 Dealloc.HandleList = &pCur->hAllocation;
5497 HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5498 Assert(tmpHr == S_OK);
5499 }
5500 break;
5501 }
5502 }
5503
5504 pDdiAllocate->pAllocationInfo = pDdiAllocIBase;
5505 }
5506
5507 if (hr == S_OK)
5508 {
5509 pRc->hKMResource = pDdiAllocate->hKMResource;
5510
5511 for (UINT i = 0; i < pResource->SurfCount; ++i)
5512 {
5513 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5514 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
5515 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
5516 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
5517 pAllocation->hAllocation = pDdiAllocI->hAllocation;
5518 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
5519 pAllocation->pvMem = (void*)pSurf->pSysMem;
5520 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
5521 }
5522
5523 if(bCreateSwapchain)
5524 {
5525 PVBOXWDDMDISP_SWAPCHAIN pSwapchain;
5526 hr = vboxWddmSwapchainCreateIfForRc(pDevice, pRc, &pSwapchain);
5527 Assert(hr == S_OK);
5528 }
5529 }
5530
5531 vboxWddmRequestAllocFree(pDdiAllocate);
5532 }
5533 else
5534 {
5535 hr = E_OUTOFMEMORY;
5536 }
5537 }
5538
5539 if (hr == S_OK)
5540 pResource->hResource = pRc;
5541 else
5542 vboxResourceFree(pRc);
5543 }
5544 else
5545 {
5546 hr = E_OUTOFMEMORY;
5547 }
5548
5549
5550 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5551 return hr;
5552}
5553
5554static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource)
5555{
5556 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5557 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5558 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5559 Assert(pDevice);
5560 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5561 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
5562 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hResource;
5563
5564 HRESULT hr = S_OK;
5565
5566 Assert(pDevice);
5567 Assert(hResource);
5568
5569 if (VBOXDISPMODE_IS_3D(pAdapter))
5570 {
5571// if (pRc->RcDesc.fFlags.RenderTarget)
5572// {
5573// Assert(pDevice->hWnd);
5574// Assert(pDevice->pDevice9If);
5575// }
5576
5577 for (UINT i = 0; i < pRc->cAllocations; ++i)
5578 {
5579 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
5580 if (pAlloc->pD3DIf)
5581 pAlloc->pD3DIf->Release();
5582 if (pAlloc->pSecondaryOpenedD3DIf)
5583 pAlloc->pSecondaryOpenedD3DIf->Release();
5584
5585 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
5586 if (pSwapchain)
5587 {
5588 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainRtForAlloc(pSwapchain, pAlloc);
5589 vboxWddmSwapchainRtRemove(pSwapchain, pRt);
5590 Assert(!vboxWddmSwapchainForAlloc(pAlloc));
5591 if (!vboxWddmSwapchainNumRTs(pSwapchain))
5592 vboxWddmSwapchainDestroy(pDevice, pSwapchain);
5593 }
5594
5595 EnterCriticalSection(&pDevice->DirtyAllocListLock);
5596 if (pAlloc->DirtyAllocListEntry.pNext)
5597 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
5598 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5599 }
5600 }
5601
5602 Assert(pRc->hResource);
5603 Assert(pRc->hKMResource || VBOXDISPMODE_IS_3D(pAdapter));
5604 if (pRc->hKMResource)
5605 {
5606 if (!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED))
5607 {
5608 D3DDDICB_DEALLOCATE Dealloc;
5609 Dealloc.hResource = pRc->hResource;
5610 /* according to the docs the below two are ignored in case we set the hResource */
5611 Dealloc.NumAllocations = 0;
5612 Dealloc.HandleList = NULL;
5613 hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5614 Assert(hr == S_OK);
5615 }
5616 }
5617 else
5618 {
5619 Assert(!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED));
5620 for (UINT j = 0; j < pRc->cAllocations; ++j)
5621 {
5622 if (pRc->aAllocations[j].hAllocation)
5623 {
5624 D3DDDICB_DEALLOCATE Dealloc;
5625 Dealloc.hResource = NULL;
5626 Dealloc.NumAllocations = 1;
5627 Dealloc.HandleList = &pRc->aAllocations[j].hAllocation;
5628 HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
5629 Assert(tmpHr == S_OK);
5630 }
5631 }
5632 }
5633
5634 vboxResourceFree(pRc);
5635 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5636 return hr;
5637}
5638static HRESULT APIENTRY vboxWddmDDevSetDisplayMode(HANDLE hDevice, CONST D3DDDIARG_SETDISPLAYMODE* pData)
5639{
5640 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5641 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5642 HRESULT hr = S_OK;
5643 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5644 Assert(pDevice);
5645 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5646 Assert(VBOXDISPMODE_IS_3D(pDevice->pAdapter));
5647 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
5648 Assert(pRc);
5649 Assert(pRc->cAllocations > pData->SubResourceIndex);
5650 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
5651 Assert(pRc->RcDesc.fFlags.RenderTarget);
5652 Assert(pRc->RcDesc.fFlags.Primary);
5653 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5654 Assert(pAlloc->hAllocation);
5655// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5656// Assert(pScreen->hWnd);
5657// Assert(pScreen->pDevice9If);
5658 D3DDDICB_SETDISPLAYMODE DdiDm = {0};
5659 DdiDm.hPrimaryAllocation = pAlloc->hAllocation;
5660// DdiDm.PrivateDriverFormatAttribute = 0;
5661// Assert(pScreen->pRenderTargetRc == pRc);
5662// Assert(pScreen->iRenderTargetFrontBuf == pData->SubResourceIndex);
5663
5664#if 0
5665 IDirect3DSurface9 *pSoD3DIfSurf = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
5666 hr = pScreen->pDevice9If->SetRenderTarget(0, pSoD3DIfSurf);
5667 Assert(hr == S_OK);
5668 if (hr == S_OK)
5669#endif
5670 {
5671 hr = pDevice->RtCallbacks.pfnSetDisplayModeCb(pDevice->hDevice, &DdiDm);
5672 Assert(hr == S_OK);
5673#if 0
5674 if (hr == S_OK)
5675 {
5676 D3DDDICB_LOCK DdiLock = {0};
5677 DdiLock.hAllocation = pAlloc->hAllocation;
5678 DdiLock.Flags.LockEntire = 1;
5679 DdiLock.Flags.ReadOnly = 1;
5680 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &DdiLock);
5681 Assert(hr == S_OK);
5682 if (hr == S_OK)
5683 {
5684 D3DLOCKED_RECT LockRect;
5685 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pAlloc->pD3DIf;
5686 hr = pD3DIfSurf->LockRect(&LockRect, NULL /* RECT*/, D3DLOCK_DISCARD);
5687 Assert(hr == S_OK);
5688 if (hr == S_OK)
5689 {
5690 /** @todo: take pitch into account */
5691 Assert(pAlloc->SurfDesc.pitch == LockRect.Pitch);
5692 memcpy(LockRect.pBits, DdiLock.pData, LockRect.Pitch * pAlloc->SurfDesc.height);
5693 hr = pD3DIfSurf->UnlockRect();
5694 Assert(hr == S_OK);
5695 }
5696
5697 D3DDDICB_UNLOCK DdiUnlock = {0};
5698 DdiUnlock.NumAllocations = 1;
5699 DdiUnlock.phAllocations = &pAlloc->hAllocation;
5700 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock);
5701 Assert(hr == S_OK);
5702 }
5703 hr = S_OK;
5704 }
5705#endif
5706 }
5707
5708 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5709 return hr;
5710}
5711
5712#ifdef VBOXWDDM_TEST_UHGSMI
5713int vboxUhgsmiTst(PVBOXUHGSMI pUhgsmi, uint32_t cbBuf, uint32_t cNumCals, uint64_t * pTimeMs);
5714#endif
5715
5716static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRESENT* pData)
5717{
5718 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5719 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5720 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5721// VBOXDISPPROFILE_DDI_CHKDUMPRESET(pDevice);
5722 Assert(pDevice);
5723 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5724 HRESULT hr = S_OK;
5725 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
5726 {
5727#ifdef VBOXWDDM_TEST_UHGSMI
5728 {
5729// Assert(0);
5730 static uint32_t cCals = 100000;
5731 static uint32_t cbData = 8 * 1024 * 1024;
5732 uint64_t TimeMs;
5733 int rc = vboxUhgsmiTst(&pDevice->Uhgsmi.Base, cbData, cCals, &TimeMs);
5734 uint32_t cCPS = (((uint64_t)cCals) * 1000ULL)/TimeMs;
5735// Assert(0);
5736// vboxVDbgDoMpPrintF(pDevice, "Time : %I64u ms, calls: %d, cps: %d\n", TimeMs, cCals, cCPS);
5737 }
5738#endif
5739#if 1
5740 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5741 Assert(pRc);
5742 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
5743 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5744 hr = vboxWddmSwapchainPresent(pDevice, pAlloc);
5745 Assert(hr == S_OK);
5746#else
5747 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5748 Assert(pRc);
5749 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5750 Assert(pScreen->hWnd);
5751 Assert(pScreen->pDevice9If);
5752 Assert(pRc == pScreen->pRenderTargetRc);
5753#if 1
5754 VBOXVDBG_RTGT_STATECHECK(pDevice);
5755
5756 if (pRc->RcDesc.VidPnSourceId != pDevice->iPrimaryScreen)
5757 {
5758 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5759 PVBOXWDDMDISP_SCREEN pPrimaryScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
5760 Assert(pPrimaryScreen->pDevice9If);
5761 IDirect3DSurface9 *pSecondaryRt;
5762 IDirect3DSurface9 *pDataRt = (IDirect3DSurface9*)pAlloc->pSecondaryOpenedD3DIf;
5763 Assert(pDataRt);
5764 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5765 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pPrimaryScreen->pDevice9If);
5766 Assert(hr == S_OK);
5767 if (hr == S_OK)
5768 {
5769 hr = pScreen->pDevice9If->GetRenderTarget(0, &pSecondaryRt);
5770 Assert(hr == S_OK);
5771 if (hr == S_OK)
5772 {
5773 hr = pScreen->pDevice9If->StretchRect(pDataRt,
5774 NULL,
5775 pSecondaryRt,
5776 NULL,
5777 D3DTEXF_NONE);
5778 pSecondaryRt->Release();
5779 }
5780 }
5781 }
5782
5783 hr = pScreen->pDevice9If->Present(NULL, /* CONST RECT * pSourceRect */
5784 NULL, /* CONST RECT * pDestRect */
5785 NULL, /* HWND hDestWindowOverride */
5786 NULL /*CONST RGNDATA * pDirtyRegion */
5787 );
5788 Assert(hr == S_OK);
5789#endif
5790#endif
5791 }
5792#if 0
5793 else
5794#endif
5795 {
5796// if (pData->Flags.Flip)
5797// {
5798// Assert(pData->hSrcResource);
5799// PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5800// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];
5801// Assert(pScreen->hWnd);
5802// Assert(pScreen->pDevice9If);
5803// Assert(pScreen->pRenderTargetRc == pRc);
5804// Assert(pRc->cAllocations >= 2);
5805// Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5806// Assert(pRc->RcDesc.fFlags.RenderTarget);
5807// uint32_t iNewRTFB = (pScreen->iRenderTargetFrontBuf + 1) % pRc->cAllocations;
5808//
5809// Assert(pScreen->iRenderTargetFrontBuf != iNewRTFB);
5810// Assert(pData->SrcSubResourceIndex == iNewRTFB);
5811//
5812// vboxWddmRenderTargetUpdate(pDevice, pRc, iNewRTFB);
5813//
5814// /* assign a new frontbuffer index */
5815// pScreen->iRenderTargetFrontBuf = iNewRTFB;
5816//
5817// VBOXVDBG_RTGT_STATECHECK(pDevice);
5818// }
5819 D3DDDICB_PRESENT DdiPresent = {0};
5820 if (pData->hSrcResource)
5821 {
5822 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
5823 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
5824 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
5825 Assert(pAlloc->hAllocation);
5826 DdiPresent.hSrcAllocation = pAlloc->hAllocation;
5827 }
5828 if (pData->hDstResource)
5829 {
5830 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
5831 Assert(pRc->cAllocations > pData->DstSubResourceIndex);
5832 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->DstSubResourceIndex];
5833 Assert(pAlloc->hAllocation);
5834 DdiPresent.hDstAllocation = pAlloc->hAllocation;
5835 }
5836 DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext;
5837// DdiPresent.BroadcastContextCount;
5838// DdiPresent.BroadcastContext[D3DDDI_MAX_BROADCAST_CONTEXT];
5839
5840 hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent);
5841 Assert(hr == S_OK);
5842 }
5843
5844 VBOXDISPPROFILE_DDI_REPORT_FRAME(pDevice);
5845
5846 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5847 return hr;
5848}
5849
5850typedef struct VBOXWDDMDISP_NSCADD
5851{
5852 VOID* pvCommandBuffer;
5853 UINT cbCommandBuffer;
5854 D3DDDI_ALLOCATIONLIST* pAllocationList;
5855 UINT cAllocationList;
5856 D3DDDI_PATCHLOCATIONLIST* pPatchLocationList;
5857 UINT cPatchLocationList;
5858 UINT cAllocations;
5859}VBOXWDDMDISP_NSCADD, *PVBOXWDDMDISP_NSCADD;
5860
5861static HRESULT vboxWddmNSCAddAlloc(PVBOXWDDMDISP_NSCADD pData, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bWrite)
5862{
5863 HRESULT hr = S_OK;
5864 if (pData->cAllocationList && pData->cPatchLocationList && pData->cbCommandBuffer > 4)
5865 {
5866 memset(pData->pAllocationList, 0, sizeof (D3DDDI_ALLOCATIONLIST));
5867 pData->pAllocationList[0].hAllocation = pAlloc->hAllocation;
5868 if (bWrite)
5869 pData->pAllocationList[0].WriteOperation = 1;
5870
5871 memset(pData->pPatchLocationList, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
5872 pData->pPatchLocationList[0].PatchOffset = pData->cAllocations*4;
5873 pData->pPatchLocationList[0].AllocationIndex = pData->cAllocations;
5874
5875 pData->cbCommandBuffer -= 4;
5876 --pData->cAllocationList;
5877 --pData->cPatchLocationList;
5878 ++pData->cAllocations;
5879
5880 ++pData->pAllocationList;
5881 ++pData->pPatchLocationList;
5882 pData->pvCommandBuffer = (VOID*)(((uint8_t*)pData->pvCommandBuffer) + 4);
5883
5884 }
5885 else
5886 hr = S_FALSE;
5887
5888 return hr;
5889}
5890
5891static HRESULT vboxWddmNotifySharedChange(PVBOXWDDMDISP_DEVICE pDevice)
5892{
5893 VBOXWDDMDISP_NSCADD NscAdd;
5894 BOOL bReinitRenderData = TRUE;
5895
5896 do
5897 {
5898 if (bReinitRenderData)
5899 {
5900 NscAdd.pvCommandBuffer = pDevice->DefaultContext.ContextInfo.pCommandBuffer;
5901 NscAdd.cbCommandBuffer = pDevice->DefaultContext.ContextInfo.CommandBufferSize;
5902 NscAdd.pAllocationList = pDevice->DefaultContext.ContextInfo.pAllocationList;
5903 NscAdd.cAllocationList = pDevice->DefaultContext.ContextInfo.AllocationListSize;
5904 NscAdd.pPatchLocationList = pDevice->DefaultContext.ContextInfo.pPatchLocationList;
5905 NscAdd.cPatchLocationList = pDevice->DefaultContext.ContextInfo.PatchLocationListSize;
5906 NscAdd.cAllocations = 0;
5907 Assert(NscAdd.cbCommandBuffer >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR));
5908 if (NscAdd.cbCommandBuffer < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
5909 return E_FAIL;
5910
5911 PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pHdr = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)NscAdd.pvCommandBuffer;
5912 pHdr->enmCmd = VBOXVDMACMD_TYPE_DMA_NOP;
5913 NscAdd.pvCommandBuffer = (VOID*)(((uint8_t*)NscAdd.pvCommandBuffer) + sizeof (*pHdr));
5914 NscAdd.cbCommandBuffer -= sizeof (*pHdr);
5915 bReinitRenderData = FALSE;
5916 }
5917
5918 EnterCriticalSection(&pDevice->DirtyAllocListLock);
5919
5920 PVBOXWDDMDISP_ALLOCATION pAlloc = RTListNodeGetFirst(&pDevice->DirtyAllocList, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry);
5921 if (pAlloc)
5922 {
5923 HRESULT tmpHr = vboxWddmNSCAddAlloc(&NscAdd, pAlloc, TRUE);
5924 Assert(tmpHr == S_OK || tmpHr == S_FALSE);
5925 if (tmpHr == S_OK)
5926 {
5927 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
5928 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5929 continue;
5930 }
5931
5932 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5933
5934 }
5935 else
5936 {
5937 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
5938 if (!NscAdd.cAllocations)
5939 break;
5940 }
5941
5942 D3DDDICB_RENDER RenderData = {0};
5943 RenderData.CommandLength = pDevice->DefaultContext.ContextInfo.CommandBufferSize - NscAdd.cbCommandBuffer;
5944 Assert(RenderData.CommandLength);
5945 Assert(RenderData.CommandLength < UINT32_MAX/2);
5946 RenderData.CommandOffset = 0;
5947 RenderData.NumAllocations = pDevice->DefaultContext.ContextInfo.AllocationListSize - NscAdd.cAllocationList;
5948 Assert(RenderData.NumAllocations == NscAdd.cAllocations);
5949 RenderData.NumPatchLocations = pDevice->DefaultContext.ContextInfo.PatchLocationListSize - NscAdd.cPatchLocationList;
5950 Assert(RenderData.NumPatchLocations == NscAdd.cAllocations);
5951// RenderData.NewCommandBufferSize = sizeof (VBOXVDMACMD) + 4 * (100);
5952// RenderData.NewAllocationListSize = 100;
5953// RenderData.NewPatchLocationListSize = 100;
5954 RenderData.hContext = pDevice->DefaultContext.ContextInfo.hContext;
5955
5956 HRESULT hr = pDevice->RtCallbacks.pfnRenderCb(pDevice->hDevice, &RenderData);
5957 Assert(hr == S_OK);
5958 if (hr == S_OK)
5959 {
5960 pDevice->DefaultContext.ContextInfo.CommandBufferSize = RenderData.NewCommandBufferSize;
5961 pDevice->DefaultContext.ContextInfo.pCommandBuffer = RenderData.pNewCommandBuffer;
5962 pDevice->DefaultContext.ContextInfo.AllocationListSize = RenderData.NewAllocationListSize;
5963 pDevice->DefaultContext.ContextInfo.pAllocationList = RenderData.pNewAllocationList;
5964 pDevice->DefaultContext.ContextInfo.PatchLocationListSize = RenderData.NewPatchLocationListSize;
5965 pDevice->DefaultContext.ContextInfo.pPatchLocationList = RenderData.pNewPatchLocationList;
5966 bReinitRenderData = TRUE;
5967 }
5968 else
5969 break;
5970 } while (1);
5971
5972 return S_OK;
5973}
5974
5975static HRESULT APIENTRY vboxWddmDDevFlush(HANDLE hDevice)
5976{
5977 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
5978 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5979 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5980 Assert(pDevice);
5981 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5982 HRESULT hr = S_OK;
5983 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
5984 {
5985// Assert(pDevice->cScreens);
5986// UINT cProcessed = 0;
5987// for (UINT i = 0; cProcessed < pDevice->cScreens && i < RT_ELEMENTS(pDevice->aScreens); ++i)
5988// {
5989// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i];
5990// if (pScreen->pDevice9If)
5991// {
5992// ++cProcessed;
5993//// if (pScreen->pRenderTargetRc->cAllocations == 1)
5994//// {
5995//// hr = pScreen->pDevice9If->Present(NULL, NULL, NULL, NULL);
5996//// Assert(hr == S_OK);
5997//// }
5998//// else
5999 {
6000 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pDevice->pDevice9If);
6001 Assert(hr == S_OK);
6002 }
6003// }
6004// }
6005
6006 vboxWddmNotifySharedChange(pDevice);
6007 }
6008 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6009 return hr;
6010}
6011
6012AssertCompile(sizeof (D3DDDIVERTEXELEMENT) == sizeof (D3DVERTEXELEMENT9));
6013AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Stream) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Stream));
6014AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Offset) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Offset));
6015AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Type) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Type));
6016AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Method) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Method));
6017AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Usage) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Usage));
6018AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, UsageIndex) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, UsageIndex));
6019
6020AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Stream) == RT_OFFSETOF(D3DVERTEXELEMENT9, Stream));
6021AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Offset) == RT_OFFSETOF(D3DVERTEXELEMENT9, Offset));
6022AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Type) == RT_OFFSETOF(D3DVERTEXELEMENT9, Type));
6023AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Method) == RT_OFFSETOF(D3DVERTEXELEMENT9, Method));
6024AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Usage) == RT_OFFSETOF(D3DVERTEXELEMENT9, Usage));
6025AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, UsageIndex) == RT_OFFSETOF(D3DVERTEXELEMENT9, UsageIndex));
6026
6027static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderDecl(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERDECL* pData, CONST D3DDDIVERTEXELEMENT* pVertexElements)
6028{
6029 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6030 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6031 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6032 Assert(pDevice);
6033 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6034 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6035 IDirect3DVertexDeclaration9 *pDecl;
6036 static D3DVERTEXELEMENT9 DeclEnd = D3DDECL_END();
6037 D3DVERTEXELEMENT9* pVe;
6038 HRESULT hr = S_OK;
6039 bool bFreeVe = false;
6040 if(memcmp(&DeclEnd, &pVertexElements[pData->NumVertexElements], sizeof (DeclEnd)))
6041 {
6042 pVe = (D3DVERTEXELEMENT9*)RTMemAlloc(sizeof (D3DVERTEXELEMENT9) * (pData->NumVertexElements + 1));
6043 if (pVe)
6044 {
6045 memcpy(pVe, pVertexElements, sizeof (D3DVERTEXELEMENT9) * pData->NumVertexElements);
6046 pVe[pData->NumVertexElements] = DeclEnd;
6047 bFreeVe = true;
6048 }
6049 else
6050 hr = E_OUTOFMEMORY;
6051 }
6052 else
6053 pVe = (D3DVERTEXELEMENT9*)pVertexElements;
6054
6055 if (hr == S_OK)
6056 {
6057 hr = pDevice9If->CreateVertexDeclaration(
6058 pVe,
6059 &pDecl
6060 );
6061 Assert(hr == S_OK);
6062 if (hr == S_OK)
6063 {
6064 Assert(pDecl);
6065 pData->ShaderHandle = pDecl;
6066 }
6067 }
6068
6069 if (bFreeVe)
6070 RTMemFree((void*)pVe);
6071
6072 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6073 return hr;
6074}
6075static HRESULT APIENTRY vboxWddmDDevSetVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
6076{
6077 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6078 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6079 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6080 Assert(pDevice);
6081 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6082 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6083 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
6084 Assert(pDecl);
6085 HRESULT hr = pDevice9If->SetVertexDeclaration(pDecl);
6086 Assert(hr == S_OK);
6087 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6088 return hr;
6089}
6090static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
6091{
6092 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6093 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6094 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6095 Assert(pDevice);
6096 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6097 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
6098 HRESULT hr = S_OK;
6099 pDecl->Release();
6100 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6101 return hr;
6102}
6103static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderFunc(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERFUNC* pData, CONST UINT* pCode)
6104{
6105 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6106 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6107 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6108 Assert(pDevice);
6109 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6110 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6111 IDirect3DVertexShader9 *pShader;
6112 Assert(*((UINT*)((uint8_t*)pCode + pData->Size-4)) == 0x0000FFFF /* end token */);
6113 HRESULT hr = pDevice9If->CreateVertexShader((const DWORD *)pCode, &pShader);
6114 Assert(hr == S_OK);
6115 if (hr == S_OK)
6116 {
6117 Assert(pShader);
6118 pData->ShaderHandle = pShader;
6119 }
6120 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6121 return hr;
6122}
6123static HRESULT APIENTRY vboxWddmDDevSetVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
6124{
6125 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6126 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6127 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6128 Assert(pDevice);
6129 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6130 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6131 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
6132 Assert(pShader);
6133 HRESULT hr = pDevice9If->SetVertexShader(pShader);
6134 Assert(hr == S_OK);
6135 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6136 return hr;
6137}
6138static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
6139{
6140 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6141 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6142 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6143 Assert(pDevice);
6144 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6145 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
6146 HRESULT hr = S_OK;
6147 pShader->Release();
6148 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6149 return hr;
6150}
6151static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTI* pData, CONST INT* pRegisters)
6152{
6153 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6154 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6155 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6156 Assert(pDevice);
6157 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6158 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6159 HRESULT hr = pDevice9If->SetVertexShaderConstantI(pData->Register, pRegisters, pData->Count);
6160 Assert(hr == S_OK);
6161 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6162 return hr;
6163}
6164static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTB* pData, CONST BOOL* pRegisters)
6165{
6166 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6167 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6168 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6169 Assert(pDevice);
6170 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6171 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6172 HRESULT hr = pDevice9If->SetVertexShaderConstantB(pData->Register, pRegisters, pData->Count);
6173 Assert(hr == S_OK);
6174 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6175 return hr;
6176}
6177static HRESULT APIENTRY vboxWddmDDevSetScissorRect(HANDLE hDevice, CONST RECT* pRect)
6178{
6179 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6180 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6181 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6182 Assert(pDevice);
6183 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6184 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6185 HRESULT hr = pDevice9If->SetScissorRect(pRect);
6186 Assert(hr == S_OK);
6187 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6188 return hr;
6189}
6190static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCE* pData)
6191{
6192 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6193 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6194 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6195 Assert(pDevice);
6196 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6197 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6198 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hVertexBuffer;
6199 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
6200 IDirect3DVertexBuffer9 *pStreamData = NULL;
6201 if (pRc)
6202 {
6203 Assert(pRc->cAllocations == 1);
6204 pAlloc = &pRc->aAllocations[0];
6205 Assert(pAlloc->pD3DIf);
6206 pStreamData = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
6207 }
6208 HRESULT hr = pDevice9If->SetStreamSource(pData->Stream, pStreamData, pData->Offset, pData->Stride);
6209 Assert(hr == S_OK);
6210 Assert(pData->Stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS);
6211 if (hr == S_OK)
6212 {
6213 if (pDevice->aStreamSource[pData->Stream] && !pAlloc)
6214 {
6215 --pDevice->cStreamSources;
6216 Assert(pDevice->cStreamSources < UINT32_MAX/2);
6217 }
6218 else if (!pDevice->aStreamSource[pData->Stream] && pAlloc)
6219 {
6220 ++pDevice->cStreamSources;
6221 Assert(pDevice->cStreamSources <= RT_ELEMENTS(pDevice->aStreamSource));
6222 }
6223 pDevice->aStreamSource[pData->Stream] = pAlloc;
6224 pDevice->StreamSourceInfo[pData->Stream].uiOffset = pData->Offset;
6225 pDevice->StreamSourceInfo[pData->Stream].uiStride = pData->Stride;
6226
6227 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrcUm = &pDevice->aStreamSourceUm[pData->Stream];
6228 pStrSrcUm->pvBuffer = NULL;
6229 pStrSrcUm->cbStride = 0;
6230 }
6231 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6232 return hr;
6233}
6234static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData)
6235{
6236 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6237 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6238 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6239 Assert(pDevice);
6240 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6241 Assert(0);
6242 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6243 return E_FAIL;
6244}
6245static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData)
6246{
6247 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6248 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6249 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6250 Assert(pDevice);
6251 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6252 Assert(0);
6253 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6254 return E_FAIL;
6255}
6256static HRESULT APIENTRY vboxWddmDDevComposeRects(HANDLE hDevice, CONST D3DDDIARG_COMPOSERECTS* pData)
6257{
6258 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6259 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6260 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6261 Assert(pDevice);
6262 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6263 Assert(0);
6264 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6265 return E_FAIL;
6266}
6267static HRESULT vboxWddmLockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc,
6268 D3DLOCKED_RECT * pLockedRect,
6269 CONST RECT *pRect,
6270 DWORD fLockFlags)
6271{
6272 HRESULT hr = E_FAIL;
6273 Assert(!pRc->aAllocations[iAlloc].LockInfo.cLocks);
6274 Assert(pRc->cAllocations > iAlloc);
6275 switch (pRc->aAllocations[0].enmD3DIfType)
6276 {
6277 case VBOXDISP_D3DIFTYPE_SURFACE:
6278 {
6279 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
6280 Assert(pD3DIfSurf);
6281 hr = pD3DIfSurf->LockRect(pLockedRect, pRect, fLockFlags);
6282 Assert(hr == S_OK);
6283 break;
6284 }
6285 case VBOXDISP_D3DIFTYPE_TEXTURE:
6286 {
6287 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
6288 Assert(pD3DIfTex);
6289 hr = pD3DIfTex->LockRect(iAlloc, pLockedRect, pRect, fLockFlags);
6290 Assert(hr == S_OK);
6291 break;
6292 }
6293 default:
6294 Assert(0);
6295 break;
6296 }
6297 return hr;
6298}
6299static HRESULT vboxWddmUnlockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc)
6300{
6301 HRESULT hr = S_OK;
6302 Assert(pRc->cAllocations > iAlloc);
6303 switch (pRc->aAllocations[0].enmD3DIfType)
6304 {
6305 case VBOXDISP_D3DIFTYPE_SURFACE:
6306 {
6307 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
6308 Assert(pD3DIfSurf);
6309 hr = pD3DIfSurf->UnlockRect();
6310 Assert(hr == S_OK);
6311 break;
6312 }
6313 case VBOXDISP_D3DIFTYPE_TEXTURE:
6314 {
6315 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
6316 Assert(pD3DIfTex);
6317 hr = pD3DIfTex->UnlockRect(iAlloc);
6318 Assert(hr == S_OK);
6319 break;
6320 }
6321 default:
6322 Assert(0);
6323 hr = E_FAIL;
6324 break;
6325 }
6326 return hr;
6327}
6328
6329static HRESULT APIENTRY vboxWddmDDevBlt(HANDLE hDevice, CONST D3DDDIARG_BLT* pData)
6330{
6331 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6332 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6333 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6334 Assert(pDevice);
6335 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6336// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
6337 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6338 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
6339 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
6340 Assert(pDstRc->cAllocations > pData->DstSubResourceIndex);
6341 Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex);
6342 HRESULT hr = S_OK;
6343 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
6344 PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
6345 PVBOXWDDMDISP_SWAPCHAIN pSrcSwapchain = vboxWddmSwapchainForAlloc(pSrcAlloc);
6346 PVBOXWDDMDISP_SWAPCHAIN pDstSwapchain = vboxWddmSwapchainForAlloc(pDstAlloc);
6347 Assert(!pDstSwapchain || vboxWddmSwapchainGetFb(pDstSwapchain)->pAlloc != pDstAlloc);
6348 /* try StretchRect */
6349 IDirect3DSurface9 *pSrcSurfIf = NULL;
6350 IDirect3DSurface9 *pDstSurfIf = NULL;
6351 hr = vboxWddmSurfGet(pDstRc, pData->DstSubResourceIndex, &pDstSurfIf);
6352 Assert(hr == S_OK);
6353 if (hr == S_OK)
6354 {
6355 Assert(pDstSurfIf);
6356 do
6357 {
6358#ifndef VBOXWDDM_WITH_VISIBLE_FB
6359 if (pSrcSwapchain
6360 && pSrcSwapchain->pRenderTargetFbCopy
6361 && vboxWddmSwapchainGetFb(pSrcSwapchain)->pAlloc == pSrcAlloc
6362# ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
6363 && vboxWddmSwapchainNumRTs(pSrcSwapchain) > 1 /* work-around wine backbuffer */
6364# endif
6365 )
6366 {
6367// Assert(pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width);
6368// Assert(pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height);
6369// Assert(pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format);
6370// Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
6371// Assert(pSrcAlloc->SurfDesc.pitch == pDstAlloc->SurfDesc.pitch);
6372// Assert(pSrcAlloc->SurfDesc.depth == pDstAlloc->SurfDesc.depth);
6373// Assert(pSrcAlloc->SurfDesc.slicePitch == pDstAlloc->SurfDesc.slicePitch);
6374// Assert(pSrcAlloc->SurfDesc.cbSize == pDstAlloc->SurfDesc.cbSize);
6375// Assert(pData->DstRect.left == 0);
6376// Assert(pData->DstRect.top == 0);
6377// Assert(pData->DstRect.right == pDstAlloc->SurfDesc.width);
6378// Assert(pData->DstRect.bottom == pDstAlloc->SurfDesc.height);
6379// Assert(pData->SrcRect.left == 0);
6380// Assert(pData->SrcRect.top == 0);
6381// Assert(pData->SrcRect.right == pSrcAlloc->SurfDesc.width);
6382// Assert(pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height);
6383# if 0
6384 if (pData->DstRect.left == 0 && pData->DstRect.top == 0
6385 && pData->DstRect.right == pDstAlloc->SurfDesc.width
6386 && pData->DstRect.bottom == pDstAlloc->SurfDesc.height
6387 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
6388 && pData->SrcRect.right == pSrcAlloc->SurfDesc.width
6389 && pData->SrcRect.bottom == pSrcAlloc->SurfDesc.height
6390 && pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width
6391 && pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height
6392 && pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format)
6393 {
6394 hr = pDevice9If->GetFrontBufferData(0, pDstSurfIf);
6395 Assert(hr == S_OK);
6396 break;
6397 }
6398 else
6399# endif
6400 {
6401 pSrcSurfIf = pSrcSwapchain->pRenderTargetFbCopy;
6402 Assert(pSrcSurfIf);
6403 if (!pSrcSwapchain->bRTFbCopyUpToDate)
6404 {
6405 hr = pSrcSwapchain->pSwapChainIf->GetFrontBufferData(pSrcSurfIf);
6406 Assert(hr == S_OK);
6407 if (hr == S_OK)
6408 {
6409 /* do pSrcSurfIf->AddRef since we do a Release in the following if (hr == S_OK) branch */
6410 pSrcSwapchain->bRTFbCopyUpToDate = TRUE;
6411 pSrcSurfIf->AddRef();
6412 }
6413 }
6414 else
6415 {
6416 pSrcSurfIf->AddRef();
6417 }
6418 }
6419 }
6420 else
6421#endif
6422 {
6423 hr = vboxWddmSurfGet(pSrcRc, pData->SrcSubResourceIndex, &pSrcSurfIf);
6424 Assert(hr == S_OK);
6425 }
6426
6427 if (hr == S_OK)
6428 {
6429 Assert(pSrcSurfIf);
6430#ifdef DEBUG_misha
6431 bool bDo = false;
6432
6433 if (g_VDbgTstDumpEnable)
6434 {
6435 if (g_VDbgTstDumpOnSys2VidSameSizeEnable)
6436 {
6437 if (pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM
6438 && pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
6439 {
6440 D3DSURFACE_DESC SrcDesc;
6441 HRESULT hr = pSrcSurfIf->GetDesc(&SrcDesc);
6442 Assert(hr == S_OK);
6443 if (hr == S_OK)
6444 {
6445 D3DSURFACE_DESC DstDesc;
6446 hr = pDstSurfIf->GetDesc(&DstDesc);
6447 Assert(hr == S_OK);
6448 if (hr == S_OK)
6449 {
6450 if (SrcDesc.Width == DstDesc.Width
6451 && SrcDesc.Height == DstDesc.Height)
6452 {
6453 bDo = true;
6454 }
6455 }
6456 }
6457 }
6458 }
6459 }
6460
6461 if (bDo)
6462 {
6463 vboxVDbgDumpSurfData((pDevice, "Blt-pre Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
6464 vboxVDbgDumpSurfData((pDevice, "Blt-pre Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
6465 }
6466#endif
6467 /* we support only Point & Linear, we ignore [Begin|Continue|End]PresentToDwm */
6468 Assert((pData->Flags.Value & (~(0x00000100 | 0x00000200 | 0x00000400 | 0x00000001 | 0x00000002))) == 0);
6469 hr = pDevice9If->StretchRect(pSrcSurfIf,
6470 &pData->SrcRect,
6471 pDstSurfIf,
6472 &pData->DstRect,
6473 vboxDDI2D3DBltFlags(pData->Flags));
6474 Assert(hr == S_OK);
6475
6476#ifdef DEBUG_misha
6477 if (bDo)
6478 {
6479 vboxVDbgDumpSurfData((pDevice, "Blt-post Src:\n", pSrcRc, pData->SrcSubResourceIndex, &pData->SrcRect, pSrcSurfIf, "\n"));
6480 vboxVDbgDumpSurfData((pDevice, "Blt-post Dst:\n", pDstRc, pData->DstSubResourceIndex, &pData->DstRect, pDstSurfIf, "\n"));
6481 }
6482#endif
6483 pSrcSurfIf->Release();
6484 }
6485 } while (0);
6486
6487 pDstSurfIf->Release();
6488 }
6489
6490 if (hr != S_OK)
6491 {
6492 /* todo: fallback to memcpy or whatever ? */
6493 Assert(0);
6494 }
6495
6496
6497#if 0
6498 if ((use pAlloc->enmD3DIfType instead!!! pDstRc->RcDesc.fFlags.Texture || pDstRc->RcDesc.fFlags.Value == 0)
6499 && (pSrcRc->RcDesc.fFlags.Texture || pSrcRc->RcDesc.fFlags.Value == 0))
6500 {
6501 IDirect3DTexture9 *pD3DIfSrcTex = (IDirect3DTexture9*)pSrcAlloc->pD3DIf;
6502 IDirect3DTexture9 *pD3DIfDstTex = (IDirect3DTexture9*)pDstAlloc->pD3DIf;
6503 Assert(pD3DIfSrcTex);
6504 Assert(pD3DIfDstTex);
6505
6506 if (pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat)
6507 {
6508 if (pSrcRc->aAllocations[0].SurfDesc.width == pDstRc->aAllocations[0].SurfDesc.width
6509 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
6510 && pData->DstRect.left == 0 && pData->DstRect.top == 0
6511 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
6512 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
6513 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height
6514 && pData->DstRect.right - pData->DstRect.left == pDstRc->aAllocations[0].SurfDesc.width
6515 && pData->DstRect.bottom - pData->DstRect.top == pDstRc->aAllocations[0].SurfDesc.height
6516 )
6517 {
6518 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex);
6519 Assert(hr == S_OK);
6520 }
6521 else if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
6522 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
6523 {
6524 Assert(pDstAlloc->SurfDesc.bpp);
6525 Assert(pSrcAlloc->SurfDesc.bpp);
6526 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
6527 D3DLOCKED_RECT DstRect, SrcRect;
6528 Assert(!pSrcAlloc->LockInfo.cLocks);
6529 Assert(!pDstAlloc->LockInfo.cLocks);
6530 hr = pD3DIfDstTex->LockRect(pData->DstSubResourceIndex, &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
6531 Assert(hr == S_OK);
6532 if (hr == S_OK)
6533 {
6534 hr = pD3DIfSrcTex->LockRect(pData->SrcSubResourceIndex, &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
6535 Assert(hr == S_OK);
6536 if (hr == S_OK)
6537 {
6538 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
6539 &pData->DstRect, &pData->SrcRect,
6540 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
6541 Assert(hr == S_OK);
6542
6543 pD3DIfSrcTex->UnlockRect(pData->SrcSubResourceIndex);
6544 }
6545 pD3DIfDstTex->UnlockRect(pData->DstSubResourceIndex);
6546 }
6547 }
6548 else
6549 {
6550
6551 Assert(0);
6552 /* @todo: impl */
6553 }
6554 }
6555 else
6556 {
6557 Assert(0);
6558 /* @todo: impl */
6559 }
6560 }
6561 else
6562 {
6563 if (pData->SrcRect.right - pData->SrcRect.left == pData->DstRect.right - pData->DstRect.left
6564 && pData->SrcRect.bottom - pData->SrcRect.top == pData->DstRect.bottom - pData->DstRect.top)
6565 {
6566 Assert(pDstAlloc->SurfDesc.bpp);
6567 Assert(pSrcAlloc->SurfDesc.bpp);
6568 Assert(pSrcAlloc->SurfDesc.bpp == pDstAlloc->SurfDesc.bpp);
6569
6570 D3DLOCKED_RECT DstRect, SrcRect;
6571 hr = vboxWddmLockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags,
6572 &DstRect, &pData->DstRect, D3DLOCK_DISCARD);
6573 Assert(hr == S_OK);
6574 if (hr == S_OK)
6575 {
6576 hr = vboxWddmLockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags,
6577 &SrcRect, &pData->SrcRect, D3DLOCK_READONLY);
6578 Assert(hr == S_OK);
6579 if (hr == S_OK)
6580 {
6581 hr = vboxWddmRectBltPerform((uint8_t *)DstRect.pBits, (uint8_t *)SrcRect.pBits,
6582 &pData->DstRect, &pData->SrcRect,
6583 DstRect.Pitch, SrcRect.Pitch, pDstAlloc->SurfDesc.bpp);
6584 Assert(hr == S_OK);
6585
6586 HRESULT tmpHr = vboxWddmUnlockRect(pSrcAlloc, pData->SrcSubResourceIndex, pSrcRc->RcDesc.fFlags);
6587 Assert(tmpHr == S_OK);
6588 }
6589 HRESULT tmpHr = vboxWddmUnlockRect(pDstAlloc, pData->DstSubResourceIndex, pDstRc->RcDesc.fFlags);
6590 Assert(tmpHr == S_OK);
6591 }
6592 }
6593 else
6594 {
6595 Assert(0);
6596 /* @todo: impl */
6597 }
6598 }
6599#endif
6600
6601 if (pDstRc->RcDesc.fFlags.SharedResource)
6602 {
6603 PVBOXWDDMDISP_ALLOCATION pAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
6604 EnterCriticalSection(&pDevice->DirtyAllocListLock);
6605 if (!pAlloc->DirtyAllocListEntry.pNext)
6606 RTListAppend(&pDevice->DirtyAllocList, &pAlloc->DirtyAllocListEntry);
6607 LeaveCriticalSection(&pDevice->DirtyAllocListLock);
6608 }
6609
6610 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6611 return hr;
6612}
6613static HRESULT APIENTRY vboxWddmDDevColorFill(HANDLE hDevice, CONST D3DDDIARG_COLORFILL* pData)
6614{
6615 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6616 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6617 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6618 Assert(pDevice);
6619 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6620 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6621 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
6622 Assert(pRc);
6623 IDirect3DSurface9 *pSurfIf = NULL;
6624 HRESULT hr = vboxWddmSurfGet(pRc, pData->SubResourceIndex, &pSurfIf);
6625 Assert(hr == S_OK);
6626 if (hr == S_OK)
6627 {
6628 Assert(pSurfIf);
6629 hr = pDevice9If->ColorFill(pSurfIf, &pData->DstRect, pData->Color);
6630 Assert(hr == S_OK);
6631 /* @todo: check what need to do when PresentToDwm flag is set */
6632 Assert(pData->Flags.Value == 0);
6633
6634 pSurfIf->Release();
6635 }
6636 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6637 return hr;
6638}
6639static HRESULT APIENTRY vboxWddmDDevDepthFill(HANDLE hDevice, CONST D3DDDIARG_DEPTHFILL* pData)
6640{
6641 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6642 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6643 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6644 Assert(pDevice);
6645 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6646 Assert(0);
6647 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6648 return E_FAIL;
6649}
6650static HRESULT APIENTRY vboxWddmDDevCreateQuery(HANDLE hDevice, D3DDDIARG_CREATEQUERY* pData)
6651{
6652 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6653 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6654// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6655// Assert(pDevice);
6656// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6657 HRESULT hr = S_OK;
6658 if (pData->QueryType == D3DDDIQUERYTYPE_EVENT)
6659 {
6660 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)RTMemAllocZ(sizeof (VBOXWDDMDISP_QUERY));
6661 Assert(pQuery);
6662 if (pQuery)
6663 {
6664 pQuery->enmType = pData->QueryType;
6665 pData->hQuery = pQuery;
6666 }
6667 else
6668 {
6669 hr = E_OUTOFMEMORY;
6670 }
6671 }
6672 else
6673 {
6674 Assert(0);
6675 hr = E_FAIL;
6676 }
6677 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6678 return hr;
6679}
6680static HRESULT APIENTRY vboxWddmDDevDestroyQuery(HANDLE hDevice, HANDLE hQuery)
6681{
6682 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6683 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6684 HRESULT hr = S_OK;
6685// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6686// Assert(pDevice);
6687// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6688
6689 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)hQuery;
6690 Assert(pQuery);
6691 RTMemFree(pQuery);
6692 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6693 return hr;
6694}
6695static HRESULT APIENTRY vboxWddmDDevIssueQuery(HANDLE hDevice, CONST D3DDDIARG_ISSUEQUERY* pData)
6696{
6697 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6698 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6699 HRESULT hr = S_OK;
6700// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6701// Assert(pDevice);
6702// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6703
6704 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
6705 Assert(pQuery);
6706 pQuery->fQueryState.Value |= pData->Flags.Value;
6707 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6708 return hr;
6709}
6710static HRESULT APIENTRY vboxWddmDDevGetQueryData(HANDLE hDevice, CONST D3DDDIARG_GETQUERYDATA* pData)
6711{
6712 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6713 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6714 HRESULT hr = S_OK;
6715// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6716// Assert(pDevice);
6717// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6718
6719 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
6720 Assert(pQuery);
6721 switch (pQuery->enmType)
6722 {
6723 case D3DDDIQUERYTYPE_EVENT:
6724 Assert(0);
6725 pQuery->data.bData = TRUE;
6726 Assert(pData->pData);
6727 *((BOOL*)pData->pData) = TRUE;
6728 break;
6729 default:
6730 Assert(0);
6731 hr = E_FAIL;
6732 break;
6733 }
6734 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6735 return hr;
6736}
6737static HRESULT APIENTRY vboxWddmDDevSetRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETRENDERTARGET* pData)
6738{
6739 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6740 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6741 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6742 Assert(pDevice);
6743 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6744
6745 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6746 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget;
6747 Assert(pRc);
6748 Assert(pData->SubResourceIndex < pRc->cAllocations);
6749 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
6750 HRESULT hr = vboxWddmRenderTargetSet(pDevice, pData->RenderTargetIndex, pAlloc, FALSE);
6751 Assert(hr == S_OK);
6752 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6753 return hr;
6754}
6755static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDIARG_SETDEPTHSTENCIL* pData)
6756{
6757 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6758 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6759 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6760 Assert(pDevice);
6761 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6762
6763 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6764 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hZBuffer;
6765 IDirect3DSurface9 *pD3D9Surf = NULL;
6766 if (pRc)
6767 {
6768 Assert(pRc->cAllocations == 1);
6769 pD3D9Surf = (IDirect3DSurface9*)pRc->aAllocations[0].pD3DIf;
6770 Assert(pD3D9Surf);
6771 }
6772 HRESULT hr = pDevice9If->SetDepthStencilSurface(pD3D9Surf);
6773 Assert(hr == S_OK);
6774 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6775 return hr;
6776}
6777static HRESULT APIENTRY vboxWddmDDevGenerateMipSubLevels(HANDLE hDevice, CONST D3DDDIARG_GENERATEMIPSUBLEVELS* pData)
6778{
6779 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6780 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6781 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6782 Assert(pDevice);
6783 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6784
6785 Assert(0);
6786 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6787 return E_FAIL;
6788}
6789static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTI* pData, CONST INT* pRegisters)
6790{
6791 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6792 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6793 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6794 Assert(pDevice);
6795 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6796
6797 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6798 HRESULT hr = pDevice9If->SetPixelShaderConstantI(pData->Register, pRegisters, pData->Count);
6799 Assert(hr == S_OK);
6800 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6801 return hr;
6802}
6803static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTB* pData, CONST BOOL* pRegisters)
6804{
6805 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6806 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6807 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6808 Assert(pDevice);
6809 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6810
6811 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6812 HRESULT hr = pDevice9If->SetPixelShaderConstantB(pData->Register, pRegisters, pData->Count);
6813 Assert(hr == S_OK);
6814 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6815 return hr;
6816}
6817static HRESULT APIENTRY vboxWddmDDevCreatePixelShader(HANDLE hDevice, D3DDDIARG_CREATEPIXELSHADER* pData, CONST UINT* pCode)
6818{
6819 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6820 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6821 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6822 Assert(pDevice);
6823 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6824
6825 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
6826 IDirect3DPixelShader9 *pShader;
6827 Assert(*((UINT*)((uint8_t*)pCode + pData->CodeSize-4)) == 0x0000FFFF /* end token */);
6828 HRESULT hr = pDevice9If->CreatePixelShader((const DWORD *)pCode, &pShader);
6829 Assert(hr == S_OK);
6830 if (hr == S_OK)
6831 {
6832 Assert(pShader);
6833 pData->ShaderHandle = pShader;
6834 }
6835 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6836 return hr;
6837}
6838static HRESULT APIENTRY vboxWddmDDevDeletePixelShader(HANDLE hDevice, HANDLE hShaderHandle)
6839{
6840 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6841 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6842 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6843 Assert(pDevice);
6844 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6845
6846 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
6847 HRESULT hr = S_OK;
6848 pShader->Release();
6849 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
6850 return hr;
6851}
6852static HRESULT APIENTRY vboxWddmDDevCreateDecodeDevice(HANDLE hDevice, D3DDDIARG_CREATEDECODEDEVICE* pData)
6853{
6854 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6855 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6856 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6857 Assert(pDevice);
6858 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6859
6860 Assert(0);
6861 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6862 return E_FAIL;
6863}
6864static HRESULT APIENTRY vboxWddmDDevDestroyDecodeDevice(HANDLE hDevice, HANDLE hDecodeDevice)
6865{
6866 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6867 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6868 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6869 Assert(pDevice);
6870 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6871
6872 Assert(0);
6873 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6874 return E_FAIL;
6875}
6876static HRESULT APIENTRY vboxWddmDDevSetDecodeRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETDECODERENDERTARGET* pData)
6877{
6878 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6879 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6880 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6881 Assert(pDevice);
6882 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6883
6884 Assert(0);
6885 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6886 return E_FAIL;
6887}
6888static HRESULT APIENTRY vboxWddmDDevDecodeBeginFrame(HANDLE hDevice, D3DDDIARG_DECODEBEGINFRAME* pData)
6889{
6890 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6891 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6892 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6893 Assert(pDevice);
6894 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6895
6896 Assert(0);
6897 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6898 return E_FAIL;
6899}
6900static HRESULT APIENTRY vboxWddmDDevDecodeEndFrame(HANDLE hDevice, D3DDDIARG_DECODEENDFRAME* pData)
6901{
6902 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6903 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6904 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6905 Assert(pDevice);
6906 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6907
6908 Assert(0);
6909 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6910 return E_FAIL;
6911}
6912static HRESULT APIENTRY vboxWddmDDevDecodeExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXECUTE* pData)
6913{
6914 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6915 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6916 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6917 Assert(pDevice);
6918 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6919
6920 Assert(0);
6921 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6922 return E_FAIL;
6923}
6924static HRESULT APIENTRY vboxWddmDDevDecodeExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXTENSIONEXECUTE* pData)
6925{
6926 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6927 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6928 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6929 Assert(pDevice);
6930 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6931
6932 Assert(0);
6933 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6934 return E_FAIL;
6935}
6936static HRESULT APIENTRY vboxWddmDDevCreateVideoProcessDevice(HANDLE hDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE* pData)
6937{
6938 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6939 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6940 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6941 Assert(pDevice);
6942 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6943
6944 Assert(0);
6945 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6946 return E_FAIL;
6947}
6948static HRESULT APIENTRY vboxWddmDDevDestroyVideoProcessDevice(HANDLE hDevice, HANDLE hVideoProcessor)
6949{
6950 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6951 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6952 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6953 Assert(pDevice);
6954 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6955
6956 Assert(0);
6957 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6958 return E_FAIL;
6959}
6960static HRESULT APIENTRY vboxWddmDDevVideoProcessBeginFrame(HANDLE hDevice, HANDLE hVideoProcess)
6961{
6962 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6963 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6964 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6965 Assert(pDevice);
6966 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6967
6968 Assert(0);
6969 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6970 return E_FAIL;
6971}
6972static HRESULT APIENTRY vboxWddmDDevVideoProcessEndFrame(HANDLE hDevice, D3DDDIARG_VIDEOPROCESSENDFRAME* pData)
6973{
6974 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6975 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6976 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6977 Assert(pDevice);
6978 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6979
6980 Assert(0);
6981 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6982 return E_FAIL;
6983}
6984static HRESULT APIENTRY vboxWddmDDevSetVideoProcessRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETVIDEOPROCESSRENDERTARGET* pData)
6985{
6986 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6987 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6988 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
6989 Assert(pDevice);
6990 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
6991
6992 Assert(0);
6993 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
6994 return E_FAIL;
6995}
6996static HRESULT APIENTRY vboxWddmDDevVideoProcessBlt(HANDLE hDevice, CONST D3DDDIARG_VIDEOPROCESSBLT* pData)
6997{
6998 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
6999 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7000 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7001 Assert(pDevice);
7002 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7003
7004 Assert(0);
7005 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7006 return E_FAIL;
7007}
7008static HRESULT APIENTRY vboxWddmDDevCreateExtensionDevice(HANDLE hDevice, D3DDDIARG_CREATEEXTENSIONDEVICE* pData)
7009{
7010 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7011 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7012 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7013 Assert(pDevice);
7014 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7015
7016 Assert(0);
7017 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7018 return E_FAIL;
7019}
7020static HRESULT APIENTRY vboxWddmDDevDestroyExtensionDevice(HANDLE hDevice, HANDLE hExtension)
7021{
7022 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7023 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7024 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7025 Assert(pDevice);
7026 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7027
7028 Assert(0);
7029 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7030 return E_FAIL;
7031}
7032static HRESULT APIENTRY vboxWddmDDevExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_EXTENSIONEXECUTE* pData)
7033{
7034 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7035 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7036 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7037 Assert(pDevice);
7038 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7039
7040 Assert(0);
7041 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7042 return E_FAIL;
7043}
7044static HRESULT APIENTRY vboxWddmDDevDestroyDevice(IN HANDLE hDevice)
7045{
7046 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7047 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7048
7049 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7050 Assert(pDevice);
7051 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7052
7053 VBOXDISPPROFILE_DDI_DUMPRESET(pDevice);
7054 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
7055 if (VBOXDISPMODE_IS_3D(pAdapter))
7056 {
7057// Assert(!pDevice->cScreens);
7058 vboxWddmSwapchainDestroyAll(pDevice);
7059 if (pDevice->pDevice9If)
7060 {
7061 pDevice->pDevice9If->Release();
7062 }
7063 }
7064
7065#ifdef VBOX_WITH_CRHGSMI
7066 vboxDispLock();
7067 if (pDevice->Uhgsmi.BasePrivate.hClient)
7068 g_VBoxCrHgsmiCallbacks.pfnClientDestroy(pDevice->Uhgsmi.BasePrivate.hClient);
7069 vboxDispUnlock();
7070#endif
7071
7072 HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
7073 Assert(hr == S_OK);
7074 if (hr == S_OK)
7075 RTMemFree(pDevice);
7076 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7077 return hr;
7078}
7079
7080AssertCompile(sizeof (RECT) == sizeof (D3DDDIRECT));
7081AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DDDIRECT, left));
7082AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DDDIRECT, right));
7083AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DDDIRECT, top));
7084AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DDDIRECT, bottom));
7085AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DDDIRECT, left));
7086AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DDDIRECT, right));
7087AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DDDIRECT, top));
7088AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DDDIRECT, bottom));
7089
7090static HRESULT APIENTRY vboxWddmDDevCreateOverlay(HANDLE hDevice, D3DDDIARG_CREATEOVERLAY* pData)
7091{
7092 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7093 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7094 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7095 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
7096 Assert(pRc);
7097 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
7098 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
7099 HRESULT hr = S_OK;
7100 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)RTMemAllocZ(sizeof (VBOXWDDMDISP_OVERLAY));
7101 Assert(pOverlay);
7102 if (pOverlay)
7103 {
7104 VBOXWDDM_OVERLAY_INFO OurInfo;
7105 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
7106 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
7107 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
7108 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
7109 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
7110 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
7111 Assert(!pAlloc->LockInfo.cLocks);
7112 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
7113 D3DDDICB_CREATEOVERLAY OverInfo;
7114 OverInfo.VidPnSourceId = pData->VidPnSourceId;
7115 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
7116 Assert(pAlloc->hAllocation);
7117 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
7118 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
7119 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
7120 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
7121 OverInfo.hKernelOverlay = NULL; /* <-- out */
7122#ifndef VBOXWDDMOVERLAY_TEST
7123 hr = pDevice->RtCallbacks.pfnCreateOverlayCb(pDevice->hDevice, &OverInfo);
7124 Assert(hr == S_OK);
7125 if (hr == S_OK)
7126 {
7127 Assert(OverInfo.hKernelOverlay);
7128 pOverlay->hOverlay = OverInfo.hKernelOverlay;
7129 pOverlay->VidPnSourceId = pData->VidPnSourceId;
7130
7131 Assert(!pAlloc->LockInfo.cLocks);
7132 if (!pAlloc->LockInfo.cLocks)
7133 {
7134 /* we have reported the dirty rect, may clear it if no locks are pending currently */
7135 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
7136 }
7137
7138 pData->hOverlay = pOverlay;
7139 }
7140 else
7141 {
7142 RTMemFree(pOverlay);
7143 }
7144#else
7145 pData->hOverlay = pOverlay;
7146#endif
7147 }
7148 else
7149 hr = E_OUTOFMEMORY;
7150
7151 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7152 return hr;
7153}
7154static HRESULT APIENTRY vboxWddmDDevUpdateOverlay(HANDLE hDevice, CONST D3DDDIARG_UPDATEOVERLAY* pData)
7155{
7156 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7157 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7158 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7159 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
7160 Assert(pRc);
7161 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
7162 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
7163 HRESULT hr = S_OK;
7164 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
7165 VBOXWDDM_OVERLAY_INFO OurInfo;
7166 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
7167 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
7168 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
7169 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
7170 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
7171 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
7172 Assert(!pAlloc->LockInfo.cLocks);
7173 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
7174 D3DDDICB_UPDATEOVERLAY OverInfo;
7175 OverInfo.hKernelOverlay = pOverlay->hOverlay;
7176 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
7177 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
7178 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
7179 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
7180 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
7181#ifndef VBOXWDDMOVERLAY_TEST
7182 hr = pDevice->RtCallbacks.pfnUpdateOverlayCb(pDevice->hDevice, &OverInfo);
7183 Assert(hr == S_OK);
7184 if (hr == S_OK)
7185#endif
7186 {
7187 Assert(!pAlloc->LockInfo.cLocks);
7188 if (!pAlloc->LockInfo.cLocks)
7189 {
7190 /* we have reported the dirty rect, may clear it if no locks are pending currently */
7191 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
7192 }
7193 }
7194
7195 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7196 return hr;
7197}
7198static HRESULT APIENTRY vboxWddmDDevFlipOverlay(HANDLE hDevice, CONST D3DDDIARG_FLIPOVERLAY* pData)
7199{
7200 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7201 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7202 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7203 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSource;
7204 Assert(pRc);
7205 Assert(pRc->cAllocations > pData->SourceIndex);
7206 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SourceIndex];
7207 HRESULT hr = S_OK;
7208 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
7209 VBOXWDDM_OVERLAYFLIP_INFO OurInfo;
7210 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
7211 Assert(!pAlloc->LockInfo.cLocks);
7212 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
7213 D3DDDICB_FLIPOVERLAY OverInfo;
7214 OverInfo.hKernelOverlay = pOverlay->hOverlay;
7215 OverInfo.hSource = pAlloc->hAllocation;
7216 OverInfo.pPrivateDriverData = &OurInfo;
7217 OverInfo.PrivateDriverDataSize = sizeof (OurInfo);
7218#ifndef VBOXWDDMOVERLAY_TEST
7219 hr = pDevice->RtCallbacks.pfnFlipOverlayCb(pDevice->hDevice, &OverInfo);
7220 Assert(hr == S_OK);
7221 if (hr == S_OK)
7222#endif
7223 {
7224 Assert(!pAlloc->LockInfo.cLocks);
7225 if (!pAlloc->LockInfo.cLocks)
7226 {
7227 /* we have reported the dirty rect, may clear it if no locks are pending currently */
7228 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
7229 }
7230 }
7231
7232 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7233 return hr;
7234}
7235static HRESULT APIENTRY vboxWddmDDevGetOverlayColorControls(HANDLE hDevice, D3DDDIARG_GETOVERLAYCOLORCONTROLS* pData)
7236{
7237 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7238 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7239 Assert(0);
7240 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7241 return E_FAIL;
7242}
7243static HRESULT APIENTRY vboxWddmDDevSetOverlayColorControls(HANDLE hDevice, CONST D3DDDIARG_SETOVERLAYCOLORCONTROLS* pData)
7244{
7245 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7246 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7247 Assert(0);
7248 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7249 return E_FAIL;
7250}
7251static HRESULT APIENTRY vboxWddmDDevDestroyOverlay(HANDLE hDevice, CONST D3DDDIARG_DESTROYOVERLAY* pData)
7252{
7253 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7254 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7255 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7256 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
7257 D3DDDICB_DESTROYOVERLAY OverInfo;
7258 OverInfo.hKernelOverlay = pOverlay->hOverlay;
7259#ifndef VBOXWDDMOVERLAY_TEST
7260 HRESULT hr = pDevice->RtCallbacks.pfnDestroyOverlayCb(pDevice->hDevice, &OverInfo);
7261 Assert(hr == S_OK);
7262 if (hr == S_OK)
7263#else
7264 HRESULT hr = S_OK;
7265#endif
7266 {
7267 RTMemFree(pOverlay);
7268 }
7269
7270 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7271 return hr;
7272}
7273static HRESULT APIENTRY vboxWddmDDevQueryResourceResidency(HANDLE hDevice, CONST D3DDDIARG_QUERYRESOURCERESIDENCY* pData)
7274{
7275 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7276 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7277 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7278// Assert(pDevice);
7279// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7280
7281 Assert(0);
7282 HRESULT hr = S_OK;
7283#if 0
7284 for (UINT i = 0; i < pData->NumResources; ++i)
7285 {
7286 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->pHandleList[i];
7287 Assert(pRc->pDevice == pDevice);
7288 if (pRc->hKMResource)
7289 {
7290
7291 }
7292 }
7293#endif
7294 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7295 return hr;
7296}
7297
7298static HRESULT vboxAllocationInit(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DDDI_OPENALLOCATIONINFO *pInfo)
7299{
7300 HRESULT hr = S_OK;
7301 pAlloc->hAllocation = pInfo->hAllocation;
7302 Assert(pInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
7303 Assert(pInfo->pPrivateDriverData);
7304 if (pInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
7305 {
7306 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pInfo->pPrivateDriverData;
7307 pAlloc->enmType = pAllocInfo->enmType;
7308 Assert(pAllocInfo->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
7309 || VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE
7310 || VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE);
7311 pAlloc->pvMem = NULL;
7312 pAlloc->SurfDesc = pAllocInfo->SurfDesc;
7313 }
7314 else
7315 {
7316 vboxVDbgPrintR((__FUNCTION__": ERROR: PrivateDriverDataSize(%d) < (%d)\n", pInfo->PrivateDriverDataSize, sizeof (VBOXWDDM_ALLOCINFO)));
7317 hr = E_INVALIDARG;
7318 }
7319 return hr;
7320}
7321
7322static HRESULT APIENTRY vboxWddmDDevOpenResource(HANDLE hDevice, D3DDDIARG_OPENRESOURCE* pData)
7323{
7324 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7325 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7326 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7327 Assert(pDevice);
7328 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7329
7330 HRESULT hr = S_OK;
7331
7332 Assert(pData->NumAllocations);
7333 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pData->NumAllocations);
7334 Assert(pRc);
7335 if (pRc)
7336 {
7337 pRc->hResource = pData->hResource;
7338 pRc->hKMResource = pData->hKMResource;
7339 pRc->pDevice = pDevice;
7340 pRc->RcDesc.enmRotation = pData->Rotation;
7341 pRc->fFlags = VBOXWDDM_RESOURCE_F_OPENNED;
7342 if (!pData->pPrivateDriverData || !pData->PrivateDriverDataSize)
7343 {
7344 /* this is a "standard" allocation resource */
7345
7346 /* both should be actually zero */
7347 Assert(!pData->pPrivateDriverData && !pData->PrivateDriverDataSize);
7348 pRc->RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
7349 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
7350 pRc->RcDesc.MultisampleQuality = 0;
7351 pRc->RcDesc.MipLevels = 0;
7352 pRc->RcDesc.Fvf;
7353 pRc->RcDesc.fFlags.Value = 0;
7354
7355 Assert(pData->NumAllocations);
7356 D3DDDI_OPENALLOCATIONINFO* pDdiAllocInfo = &pData->pOpenAllocationInfo[0];
7357 Assert(pDdiAllocInfo->pPrivateDriverData);
7358 Assert(pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO));
7359 if (pDdiAllocInfo->pPrivateDriverData && pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
7360 {
7361 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocInfo->pPrivateDriverData;
7362 switch(pAllocInfo->enmType)
7363 {
7364 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
7365 pRc->RcDesc.fFlags.Primary = 1;
7366 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
7367 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
7368 pRc->RcDesc.enmFormat = pAllocInfo->SurfDesc.format;
7369 pRc->RcDesc.VidPnSourceId = pAllocInfo->SurfDesc.VidPnSourceId;
7370 pRc->RcDesc.RefreshRate = pAllocInfo->SurfDesc.RefreshRate;
7371 break;
7372 default:
7373 Assert(0);
7374 hr = E_INVALIDARG;
7375 }
7376 }
7377 else
7378 hr = E_INVALIDARG;
7379 }
7380 else
7381 {
7382 /* this is a "generic" resource whose creation is initiated by the UMD */
7383 Assert(pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
7384 if (pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO))
7385 {
7386 VBOXWDDM_RCINFO *pRcInfo = (VBOXWDDM_RCINFO*)pData->pPrivateDriverData;
7387 Assert(pRcInfo->fFlags == VBOXWDDM_RESOURCE_F_TYPE_GENERIC);
7388 Assert(pRcInfo->cAllocInfos == pData->NumAllocations);
7389 pRc->fFlags = pRcInfo->fFlags | VBOXWDDM_RESOURCE_F_OPENNED;
7390 pRc->RcDesc = pRcInfo->RcDesc;
7391 pRc->cAllocations = pData->NumAllocations;
7392
7393 for (UINT i = 0; i < pData->NumAllocations; ++i)
7394 {
7395 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
7396 D3DDDI_OPENALLOCATIONINFO* pOAI = pData->pOpenAllocationInfo;
7397 Assert(pOAI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
7398 if (pOAI->PrivateDriverDataSize != sizeof (VBOXWDDM_ALLOCINFO))
7399 {
7400 hr = E_INVALIDARG;
7401 break;
7402 }
7403 Assert(pOAI->pPrivateDriverData);
7404 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pOAI->pPrivateDriverData;
7405 pAllocation->hAllocation = pOAI->hAllocation;
7406 pAllocation->enmType = pAllocInfo->enmType;
7407 pAllocation->hSharedHandle = pAllocInfo->hSharedHandle;
7408 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
7409 Assert(pAllocation->hSharedHandle);
7410 }
7411
7412 Assert(pRc->RcDesc.fFlags.SharedResource);
7413 if (pRc->RcDesc.fFlags.Texture)
7414 {
7415 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
7416 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
7417 IDirect3DTexture9 *pD3DIfTex;
7418 HANDLE hSharedHandle = pAllocation->hSharedHandle;
7419 Assert(pAllocation->hSharedHandle);
7420
7421 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
7422 pAllocation->SurfDesc.width,
7423 pAllocation->SurfDesc.height,
7424 pRc->cAllocations,
7425 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
7426 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
7427 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
7428 &pD3DIfTex,
7429 &hSharedHandle,
7430 NULL);
7431 Assert(hr == S_OK);
7432 if (hr == S_OK)
7433 {
7434 Assert(pD3DIfTex);
7435 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
7436 pAllocation->pD3DIf = pD3DIfTex;
7437 Assert(pAllocation->hSharedHandle == hSharedHandle);
7438 Assert(pAllocation->hSharedHandle);
7439 }
7440 }
7441 else
7442 {
7443 /* impl */
7444 Assert(0);
7445 }
7446 }
7447 else
7448 hr = E_INVALIDARG;
7449 }
7450
7451 if (hr == S_OK)
7452 {
7453 for (UINT i = 0; i < pData->NumAllocations; ++i)
7454 {
7455 hr = vboxAllocationInit(&pRc->aAllocations[i], &pData->pOpenAllocationInfo[i]);
7456 Assert(hr == S_OK);
7457 if (hr != S_OK)
7458 break;
7459 }
7460 }
7461
7462 if (hr == S_OK)
7463 pData->hResource = pRc;
7464 else
7465 vboxResourceFree(pRc);
7466 }
7467 else
7468 {
7469 vboxVDbgPrintR((__FUNCTION__": vboxResourceAlloc failed for hDevice(0x%p), NumAllocations(%d)\n", hDevice, pData->NumAllocations));
7470 hr = E_OUTOFMEMORY;
7471 }
7472
7473 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7474 return hr;
7475}
7476static HRESULT APIENTRY vboxWddmDDevGetCaptureAllocationHandle(HANDLE hDevice, D3DDDIARG_GETCAPTUREALLOCATIONHANDLE* pData)
7477{
7478 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7479 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7480 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7481 Assert(pDevice);
7482 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7483
7484 Assert(0);
7485 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7486 return E_FAIL;
7487}
7488
7489static HRESULT APIENTRY vboxWddmDDevCaptureToSysMem(HANDLE hDevice, CONST D3DDDIARG_CAPTURETOSYSMEM* pData)
7490{
7491 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7492 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7493 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
7494 Assert(pDevice);
7495 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7496
7497 Assert(0);
7498 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
7499 return E_FAIL;
7500}
7501
7502static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIARG_CREATEDEVICE* pCreateData)
7503{
7504 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7505 HRESULT hr = S_OK;
7506 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), Interface(%d), Version(%d)\n", hAdapter, pCreateData->Interface, pCreateData->Version));
7507
7508// Assert(0);
7509 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
7510
7511 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_DEVICE, apRTs[pAdapter->cMaxSimRTs]));
7512 if (pDevice)
7513 {
7514 pDevice->cRTs = pAdapter->cMaxSimRTs;
7515 pDevice->hDevice = pCreateData->hDevice;
7516 pDevice->pAdapter = pAdapter;
7517 pDevice->u32IfVersion = pCreateData->Interface;
7518 pDevice->uRtVersion = pCreateData->Version;
7519 pDevice->RtCallbacks = *pCreateData->pCallbacks;
7520 pDevice->pvCmdBuffer = pCreateData->pCommandBuffer;
7521 pDevice->cbCmdBuffer = pCreateData->CommandBufferSize;
7522 pDevice->fFlags = pCreateData->Flags;
7523 /* Set Viewport to some default values */
7524 pDevice->ViewPort.X = 0;
7525 pDevice->ViewPort.Y = 0;
7526 pDevice->ViewPort.Width = 1;
7527 pDevice->ViewPort.Height = 1;
7528 pDevice->ViewPort.MinZ = 0.;
7529 pDevice->ViewPort.MaxZ = 1.;
7530
7531 InitializeCriticalSection(&pDevice->DirtyAllocListLock);
7532 RTListInit(&pDevice->DirtyAllocList);
7533
7534 Assert(!pCreateData->AllocationListSize);
7535 Assert(!pCreateData->PatchLocationListSize);
7536
7537 pCreateData->hDevice = pDevice;
7538
7539 pCreateData->pDeviceFuncs->pfnSetRenderState = vboxWddmDDevSetRenderState;
7540 pCreateData->pDeviceFuncs->pfnUpdateWInfo = vboxWddmDDevUpdateWInfo;
7541 pCreateData->pDeviceFuncs->pfnValidateDevice = vboxWddmDDevValidateDevice;
7542 pCreateData->pDeviceFuncs->pfnSetTextureStageState = vboxWddmDDevSetTextureStageState;
7543 pCreateData->pDeviceFuncs->pfnSetTexture = vboxWddmDDevSetTexture;
7544 pCreateData->pDeviceFuncs->pfnSetPixelShader = vboxWddmDDevSetPixelShader;
7545 pCreateData->pDeviceFuncs->pfnSetPixelShaderConst = vboxWddmDDevSetPixelShaderConst;
7546 pCreateData->pDeviceFuncs->pfnSetStreamSourceUm = vboxWddmDDevSetStreamSourceUm;
7547 pCreateData->pDeviceFuncs->pfnSetIndices = vboxWddmDDevSetIndices;
7548 pCreateData->pDeviceFuncs->pfnSetIndicesUm = vboxWddmDDevSetIndicesUm;
7549 pCreateData->pDeviceFuncs->pfnDrawPrimitive = vboxWddmDDevDrawPrimitive;
7550 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive = vboxWddmDDevDrawIndexedPrimitive;
7551 pCreateData->pDeviceFuncs->pfnDrawRectPatch = vboxWddmDDevDrawRectPatch;
7552 pCreateData->pDeviceFuncs->pfnDrawTriPatch = vboxWddmDDevDrawTriPatch;
7553 pCreateData->pDeviceFuncs->pfnDrawPrimitive2 = vboxWddmDDevDrawPrimitive2;
7554 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive2 = vboxWddmDDevDrawIndexedPrimitive2;
7555 pCreateData->pDeviceFuncs->pfnVolBlt = vboxWddmDDevVolBlt;
7556 pCreateData->pDeviceFuncs->pfnBufBlt = vboxWddmDDevBufBlt;
7557 pCreateData->pDeviceFuncs->pfnTexBlt = vboxWddmDDevTexBlt;
7558 pCreateData->pDeviceFuncs->pfnStateSet = vboxWddmDDevStateSet;
7559 pCreateData->pDeviceFuncs->pfnSetPriority = vboxWddmDDevSetPriority;
7560 pCreateData->pDeviceFuncs->pfnClear = vboxWddmDDevClear;
7561 pCreateData->pDeviceFuncs->pfnUpdatePalette = vboxWddmDDevUpdatePalette;
7562 pCreateData->pDeviceFuncs->pfnSetPalette = vboxWddmDDevSetPalette;
7563 pCreateData->pDeviceFuncs->pfnSetVertexShaderConst = vboxWddmDDevSetVertexShaderConst;
7564 pCreateData->pDeviceFuncs->pfnMultiplyTransform = vboxWddmDDevMultiplyTransform;
7565 pCreateData->pDeviceFuncs->pfnSetTransform = vboxWddmDDevSetTransform;
7566 pCreateData->pDeviceFuncs->pfnSetViewport = vboxWddmDDevSetViewport;
7567 pCreateData->pDeviceFuncs->pfnSetZRange = vboxWddmDDevSetZRange;
7568 pCreateData->pDeviceFuncs->pfnSetMaterial = vboxWddmDDevSetMaterial;
7569 pCreateData->pDeviceFuncs->pfnSetLight = vboxWddmDDevSetLight;
7570 pCreateData->pDeviceFuncs->pfnCreateLight = vboxWddmDDevCreateLight;
7571 pCreateData->pDeviceFuncs->pfnDestroyLight = vboxWddmDDevDestroyLight;
7572 pCreateData->pDeviceFuncs->pfnSetClipPlane = vboxWddmDDevSetClipPlane;
7573 pCreateData->pDeviceFuncs->pfnGetInfo = vboxWddmDDevGetInfo;
7574 pCreateData->pDeviceFuncs->pfnLock = vboxWddmDDevLock;
7575 pCreateData->pDeviceFuncs->pfnUnlock = vboxWddmDDevUnlock;
7576 pCreateData->pDeviceFuncs->pfnCreateResource = vboxWddmDDevCreateResource;
7577 pCreateData->pDeviceFuncs->pfnDestroyResource = vboxWddmDDevDestroyResource;
7578 pCreateData->pDeviceFuncs->pfnSetDisplayMode = vboxWddmDDevSetDisplayMode;
7579 pCreateData->pDeviceFuncs->pfnPresent = vboxWddmDDevPresent;
7580 pCreateData->pDeviceFuncs->pfnFlush = vboxWddmDDevFlush;
7581 pCreateData->pDeviceFuncs->pfnCreateVertexShaderFunc = vboxWddmDDevCreateVertexShaderFunc;
7582 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderFunc = vboxWddmDDevDeleteVertexShaderFunc;
7583 pCreateData->pDeviceFuncs->pfnSetVertexShaderFunc = vboxWddmDDevSetVertexShaderFunc;
7584 pCreateData->pDeviceFuncs->pfnCreateVertexShaderDecl = vboxWddmDDevCreateVertexShaderDecl;
7585 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderDecl = vboxWddmDDevDeleteVertexShaderDecl;
7586 pCreateData->pDeviceFuncs->pfnSetVertexShaderDecl = vboxWddmDDevSetVertexShaderDecl;
7587 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstI = vboxWddmDDevSetVertexShaderConstI;
7588 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstB = vboxWddmDDevSetVertexShaderConstB;
7589 pCreateData->pDeviceFuncs->pfnSetScissorRect = vboxWddmDDevSetScissorRect;
7590 pCreateData->pDeviceFuncs->pfnSetStreamSource = vboxWddmDDevSetStreamSource;
7591 pCreateData->pDeviceFuncs->pfnSetStreamSourceFreq = vboxWddmDDevSetStreamSourceFreq;
7592 pCreateData->pDeviceFuncs->pfnSetConvolutionKernelMono = vboxWddmDDevSetConvolutionKernelMono;
7593 pCreateData->pDeviceFuncs->pfnComposeRects = vboxWddmDDevComposeRects;
7594 pCreateData->pDeviceFuncs->pfnBlt = vboxWddmDDevBlt;
7595 pCreateData->pDeviceFuncs->pfnColorFill = vboxWddmDDevColorFill;
7596 pCreateData->pDeviceFuncs->pfnDepthFill = vboxWddmDDevDepthFill;
7597 pCreateData->pDeviceFuncs->pfnCreateQuery = vboxWddmDDevCreateQuery;
7598 pCreateData->pDeviceFuncs->pfnDestroyQuery = vboxWddmDDevDestroyQuery;
7599 pCreateData->pDeviceFuncs->pfnIssueQuery = vboxWddmDDevIssueQuery;
7600 pCreateData->pDeviceFuncs->pfnGetQueryData = vboxWddmDDevGetQueryData;
7601 pCreateData->pDeviceFuncs->pfnSetRenderTarget = vboxWddmDDevSetRenderTarget;
7602 pCreateData->pDeviceFuncs->pfnSetDepthStencil = vboxWddmDDevSetDepthStencil;
7603 pCreateData->pDeviceFuncs->pfnGenerateMipSubLevels = vboxWddmDDevGenerateMipSubLevels;
7604 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstI = vboxWddmDDevSetPixelShaderConstI;
7605 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstB = vboxWddmDDevSetPixelShaderConstB;
7606 pCreateData->pDeviceFuncs->pfnCreatePixelShader = vboxWddmDDevCreatePixelShader;
7607 pCreateData->pDeviceFuncs->pfnDeletePixelShader = vboxWddmDDevDeletePixelShader;
7608 pCreateData->pDeviceFuncs->pfnCreateDecodeDevice = vboxWddmDDevCreateDecodeDevice;
7609 pCreateData->pDeviceFuncs->pfnDestroyDecodeDevice = vboxWddmDDevDestroyDecodeDevice;
7610 pCreateData->pDeviceFuncs->pfnSetDecodeRenderTarget = vboxWddmDDevSetDecodeRenderTarget;
7611 pCreateData->pDeviceFuncs->pfnDecodeBeginFrame = vboxWddmDDevDecodeBeginFrame;
7612 pCreateData->pDeviceFuncs->pfnDecodeEndFrame = vboxWddmDDevDecodeEndFrame;
7613 pCreateData->pDeviceFuncs->pfnDecodeExecute = vboxWddmDDevDecodeExecute;
7614 pCreateData->pDeviceFuncs->pfnDecodeExtensionExecute = vboxWddmDDevDecodeExtensionExecute;
7615 pCreateData->pDeviceFuncs->pfnCreateVideoProcessDevice = vboxWddmDDevCreateVideoProcessDevice;
7616 pCreateData->pDeviceFuncs->pfnDestroyVideoProcessDevice = vboxWddmDDevDestroyVideoProcessDevice;
7617 pCreateData->pDeviceFuncs->pfnVideoProcessBeginFrame = vboxWddmDDevVideoProcessBeginFrame;
7618 pCreateData->pDeviceFuncs->pfnVideoProcessEndFrame = vboxWddmDDevVideoProcessEndFrame;
7619 pCreateData->pDeviceFuncs->pfnSetVideoProcessRenderTarget = vboxWddmDDevSetVideoProcessRenderTarget;
7620 pCreateData->pDeviceFuncs->pfnVideoProcessBlt = vboxWddmDDevVideoProcessBlt;
7621 pCreateData->pDeviceFuncs->pfnCreateExtensionDevice = vboxWddmDDevCreateExtensionDevice;
7622 pCreateData->pDeviceFuncs->pfnDestroyExtensionDevice = vboxWddmDDevDestroyExtensionDevice;
7623 pCreateData->pDeviceFuncs->pfnExtensionExecute = vboxWddmDDevExtensionExecute;
7624 pCreateData->pDeviceFuncs->pfnCreateOverlay = vboxWddmDDevCreateOverlay;
7625 pCreateData->pDeviceFuncs->pfnUpdateOverlay = vboxWddmDDevUpdateOverlay;
7626 pCreateData->pDeviceFuncs->pfnFlipOverlay = vboxWddmDDevFlipOverlay;
7627 pCreateData->pDeviceFuncs->pfnGetOverlayColorControls = vboxWddmDDevGetOverlayColorControls;
7628 pCreateData->pDeviceFuncs->pfnSetOverlayColorControls = vboxWddmDDevSetOverlayColorControls;
7629 pCreateData->pDeviceFuncs->pfnDestroyOverlay = vboxWddmDDevDestroyOverlay;
7630 pCreateData->pDeviceFuncs->pfnDestroyDevice = vboxWddmDDevDestroyDevice;
7631 pCreateData->pDeviceFuncs->pfnQueryResourceResidency = vboxWddmDDevQueryResourceResidency;
7632 pCreateData->pDeviceFuncs->pfnOpenResource = vboxWddmDDevOpenResource;
7633 pCreateData->pDeviceFuncs->pfnGetCaptureAllocationHandle = vboxWddmDDevGetCaptureAllocationHandle;
7634 pCreateData->pDeviceFuncs->pfnCaptureToSysMem = vboxWddmDDevCaptureToSysMem;
7635 pCreateData->pDeviceFuncs->pfnLockAsync = NULL; //vboxWddmDDevLockAsync;
7636 pCreateData->pDeviceFuncs->pfnUnlockAsync = NULL; //vboxWddmDDevUnlockAsync;
7637 pCreateData->pDeviceFuncs->pfnRename = NULL; //vboxWddmDDevRename;
7638
7639
7640 do
7641 {
7642 RTListInit(&pDevice->SwapchainList);
7643 Assert(!pCreateData->AllocationListSize
7644 && !pCreateData->PatchLocationListSize);
7645 if (!pCreateData->AllocationListSize
7646 && !pCreateData->PatchLocationListSize)
7647 {
7648#ifdef VBOX_WITH_CRHGSMI
7649 hr = vboxUhgsmiD3DInit(&pDevice->Uhgsmi, pDevice);
7650 Assert(hr == S_OK);
7651 if (hr == S_OK)
7652#endif
7653 {
7654 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
7655
7656 hr = vboxDispCmCtxCreate(pDevice, &pDevice->DefaultContext);
7657 Assert(hr == S_OK);
7658 if (hr == S_OK)
7659 {
7660 #ifdef VBOXDISP_EARLYCREATEDEVICE
7661 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);
7662 Assert(pRc);
7663 if (pRc)
7664 {
7665 D3DPRESENT_PARAMETERS params;
7666 memset(&params, 0, sizeof (params));
7667 // params.BackBufferWidth = 640;
7668 // params.BackBufferHeight = 480;
7669 params.BackBufferWidth = 0x400;
7670 params.BackBufferHeight = 0x300;
7671 params.BackBufferFormat = D3DFMT_A8R8G8B8;
7672 // params.BackBufferCount = 0;
7673 params.BackBufferCount = 1;
7674 params.MultiSampleType = D3DMULTISAMPLE_NONE;
7675 params.SwapEffect = D3DSWAPEFFECT_DISCARD;
7676 // params.hDeviceWindow = hWnd;
7677 /* @todo: it seems there should be a way to detect this correctly since
7678 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
7679 params.Windowed = TRUE;
7680 // params.EnableAutoDepthStencil = FALSE;
7681 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
7682 // params.Flags;
7683 // params.FullScreen_RefreshRateInHz;
7684 // params.FullScreen_PresentationInterval;
7685
7686 hr = vboxWddmD3DDeviceCreate(pDevice, 0, pRc, &params, TRUE /*BOOL bLockable*/);
7687 Assert(hr == S_OK);
7688 if (hr == S_OK)
7689 break;
7690 vboxResourceFree(pRc);
7691 }
7692 else
7693 {
7694 hr = E_OUTOFMEMORY;
7695 }
7696 #else
7697//# define VBOXDISP_TEST_SWAPCHAIN
7698# ifdef VBOXDISP_TEST_SWAPCHAIN
7699 VBOXDISP_D3DEV(pDevice);
7700# endif
7701 break;
7702 #endif
7703
7704 HRESULT tmpHr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
7705 Assert(tmpHr == S_OK);
7706 }
7707 }
7708 }
7709 else
7710 {
7711 vboxVDbgPrintR((__FUNCTION__": Not implemented: PatchLocationListSize(%d), AllocationListSize(%d)\n",
7712 pCreateData->PatchLocationListSize, pCreateData->AllocationListSize));
7713 //pCreateData->pAllocationList = ??
7714 hr = E_FAIL;
7715 }
7716
7717 RTMemFree(pDevice);
7718 } while (0);
7719 }
7720 else
7721 {
7722 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
7723 hr = E_OUTOFMEMORY;
7724 }
7725
7726 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7727
7728 return hr;
7729}
7730
7731static HRESULT APIENTRY vboxWddmDispCloseAdapter (IN HANDLE hAdapter)
7732{
7733 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7734 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7735
7736// Assert(0);
7737
7738 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
7739 if (VBOXDISPMODE_IS_3D(pAdapter))
7740 {
7741 VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL();
7742 HRESULT hr = VBoxDispWorkerDestroy(&pAdapter->WndWorker);
7743 Assert(hr == S_OK);
7744 pAdapter->pD3D9If->Release();
7745 VBoxDispD3DClose(&pAdapter->D3D);
7746
7747#ifdef VBOX_WITH_CRHGSMI
7748 vboxUhgsmiGlobalRelease();
7749#endif
7750 }
7751
7752 vboxCapsFree(pAdapter);
7753
7754 RTMemFree(pAdapter);
7755
7756 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
7757
7758 return S_OK;
7759}
7760
7761HRESULT APIENTRY OpenAdapter (__inout D3DDDIARG_OPENADAPTER* pOpenData)
7762{
7763 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE();
7764 vboxVDbgPrint(("==> "__FUNCTION__"\n"));
7765
7766// vboxDispLock();
7767
7768 HRESULT hr = E_FAIL;
7769
7770 do
7771 {
7772
7773 VBOXWDDM_QI Query;
7774 D3DDDICB_QUERYADAPTERINFO DdiQuery;
7775 DdiQuery.PrivateDriverDataSize = sizeof(Query);
7776 DdiQuery.pPrivateDriverData = &Query;
7777 hr = pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb(pOpenData->hAdapter, &DdiQuery);
7778 Assert(hr == S_OK);
7779 if (hr != S_OK)
7780 {
7781 vboxVDbgPrintR((__FUNCTION__": pfnQueryAdapterInfoCb failed, hr (%d)\n", hr));
7782 hr = E_FAIL;
7783 break;
7784 }
7785
7786 /* check the miniport version match display version */
7787 if (Query.u32Version != VBOXVIDEOIF_VERSION)
7788 {
7789 vboxVDbgPrintR((__FUNCTION__": miniport version mismatch, expected (%d), but was (%d)\n",
7790 VBOXVIDEOIF_VERSION,
7791 Query.u32Version));
7792 hr = E_FAIL;
7793 break;
7794 }
7795
7796#ifdef VBOX_WITH_VIDEOHWACCEL
7797 Assert(Query.cInfos >= 1);
7798 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_ADAPTER, aHeads[Query.cInfos]));
7799#else
7800 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(sizeof (VBOXWDDMDISP_ADAPTER));
7801#endif
7802 Assert(pAdapter);
7803 if (pAdapter)
7804 {
7805 pAdapter->hAdapter = pOpenData->hAdapter;
7806 pAdapter->uIfVersion = pOpenData->Interface;
7807 pAdapter->uRtVersion= pOpenData->Version;
7808 pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
7809
7810 pAdapter->cHeads = Query.cInfos;
7811
7812
7813 pOpenData->hAdapter = pAdapter;
7814 pOpenData->pAdapterFuncs->pfnGetCaps = vboxWddmDispGetCaps;
7815 pOpenData->pAdapterFuncs->pfnCreateDevice = vboxWddmDispCreateDevice;
7816 pOpenData->pAdapterFuncs->pfnCloseAdapter = vboxWddmDispCloseAdapter;
7817 pOpenData->DriverVersion = D3D_UMD_INTERFACE_VERSION;
7818 /*
7819 * here we detect whether we are called by the d3d or ddraw.
7820 * in the d3d case we init our d3d environment
7821 * in the ddraw case we init 2D acceleration
7822 * if interface version is > 7, this is D3D, treat it as so
7823 * otherwise treat it as ddraw
7824 * @todo: need a more clean way of doing this */
7825
7826 if (pAdapter->uIfVersion > 7)
7827 {
7828 do
7829 {
7830#ifdef VBOX_WITH_CRHGSMI
7831 hr = vboxUhgsmiGlobalRetain();
7832 Assert(hr == S_OK);
7833 if (hr == S_OK)
7834#endif
7835 {
7836 VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL();
7837 /* try enable the 3D */
7838 hr = VBoxDispD3DOpen(&pAdapter->D3D);
7839 Assert(hr == S_OK);
7840 if (hr == S_OK)
7841 {
7842// Assert(0);
7843 hr = pAdapter->D3D.pfnDirect3DCreate9Ex(D3D_SDK_VERSION, &pAdapter->pD3D9If);
7844 Assert(hr == S_OK);
7845 if (hr == S_OK)
7846 {
7847 D3DCAPS9 Caps;
7848 memset(&Caps, 0, sizeof (Caps));
7849 hr = vboxWddmGetD3D9Caps(pAdapter, &Caps);
7850 Assert(hr == S_OK);
7851 if (hr == S_OK)
7852 {
7853 pAdapter->cMaxSimRTs = Caps.NumSimultaneousRTs;
7854 Assert(pAdapter->cMaxSimRTs);
7855 Assert(pAdapter->cMaxSimRTs < UINT32_MAX/2);
7856 hr = VBoxDispWorkerCreate(&pAdapter->WndWorker);
7857 Assert(hr == S_OK);
7858 if (hr == S_OK)
7859 {
7860 vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
7861 break;
7862 }
7863 }
7864 pAdapter->pD3D9If->Release();
7865 }
7866 else
7867 vboxVDbgPrintR((__FUNCTION__": pfnDirect3DCreate9Ex failed, hr (%d)\n", hr));
7868 VBoxDispD3DClose(&pAdapter->D3D);
7869 }
7870 else
7871 vboxVDbgPrintR((__FUNCTION__": VBoxDispD3DOpen failed, hr (%d)\n", hr));
7872#ifdef VBOX_WITH_CRHGSMI
7873 vboxUhgsmiGlobalRelease();
7874#endif
7875 }
7876 } while (0);
7877 }
7878#ifdef VBOX_WITH_VIDEOHWACCEL
7879 else
7880 {
7881 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
7882 {
7883 pAdapter->aHeads[i].Vhwa.Settings = Query.aInfos[i];
7884 }
7885 }
7886#endif
7887
7888 vboxCapsInit(pAdapter);
7889 hr = S_OK;
7890// RTMemFree(pAdapter);
7891 }
7892 else
7893 {
7894 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
7895 hr = E_OUTOFMEMORY;
7896 }
7897
7898 } while (0);
7899
7900// vboxDispUnlock();
7901
7902 vboxVDbgPrint(("<== "__FUNCTION__", hr (%d)\n", hr));
7903
7904 return hr;
7905}
7906
7907#ifdef VBOXWDDMDISP_DEBUG_PRINT
7908VOID vboxVDbgDoMpPrint(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString)
7909{
7910 uint32_t cbString = (uint32_t)strlen(szString) + 1;
7911 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
7912 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
7913 Assert(pCmd);
7914 if (pCmd)
7915 {
7916 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
7917 memcpy(pCmd->aStringBuf, szString, cbString);
7918
7919 D3DDDICB_ESCAPE DdiEscape = {0};
7920 DdiEscape.hContext = NULL;
7921 DdiEscape.hDevice = NULL;
7922 DdiEscape.Flags.Value = 0;
7923 DdiEscape.pPrivateDriverData = pCmd;
7924 DdiEscape.PrivateDriverDataSize = cbCmd;
7925
7926 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
7927 Assert(hr == S_OK);
7928
7929 RTMemFree(pCmd);
7930 }
7931}
7932VOID vboxVDbgDoMpPrintF(const PVBOXWDDMDISP_DEVICE pDevice, LPCSTR szString, ...)
7933{
7934 char szBuffer[4096] = {0};
7935 va_list pArgList;
7936 va_start(pArgList, szString);
7937 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
7938 va_end(pArgList);
7939
7940 if (pDevice)
7941 {
7942 vboxVDbgDoMpPrint(pDevice, szBuffer);
7943 }
7944 else
7945 {
7946 OutputDebugStringA(szBuffer);
7947 }
7948}
7949VOID vboxVDbgDoPrint(LPCSTR szString, ...)
7950{
7951 char szBuffer[1024] = {0};
7952 va_list pArgList;
7953 va_start(pArgList, szString);
7954 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
7955 va_end(pArgList);
7956
7957 OutputDebugStringA(szBuffer);
7958}
7959#endif
7960
7961#ifdef VBOXWDDMDISP_DEBUG
7962
7963bool g_VDbgTstDumpEnable = false;
7964bool g_VDbgTstDumpOnSys2VidSameSizeEnable = false;
7965
7966VOID vboxVDbgDoDumpAllocSurfData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, IDirect3DSurface9 *pSurf, const RECT *pRect, const char* pSuffix)
7967{
7968 if (pPrefix)
7969 {
7970 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
7971 }
7972
7973 D3DLOCKED_RECT Lr;
7974 if (pRect)
7975 {
7976 Assert(pRect->right > pRect->left);
7977 Assert(pRect->bottom > pRect->top);
7978 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
7979 }
7980
7981 HRESULT srcHr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
7982 Assert(srcHr == S_OK);
7983 if (srcHr == S_OK)
7984 {
7985 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
7986// Assert(bpp == pAlloc->SurfDesc.bpp);
7987// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
7988 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
7989 Lr.pBits, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, Lr.Pitch));
7990 if (pRect)
7991 {
7992 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
7993 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
7994 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
7995 }
7996 Assert(0);
7997
7998 srcHr = pSurf->UnlockRect();
7999 Assert(srcHr == S_OK);
8000 }
8001 if (pSuffix)
8002 {
8003 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
8004 }
8005}
8006
8007VOID vboxVDbgDoDumpAllocData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, const RECT *pRect, const char* pSuffix)
8008{
8009 if (pPrefix)
8010 {
8011 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
8012 }
8013
8014 if (pRect)
8015 {
8016 Assert(pRect->right > pRect->left);
8017 Assert(pRect->bottom > pRect->top);
8018 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
8019 }
8020
8021 Assert(pAlloc->hAllocation);
8022
8023 D3DDDICB_LOCK LockData;
8024 LockData.hAllocation = pAlloc->hAllocation;
8025 LockData.PrivateDriverData = 0;
8026 LockData.NumPages = 0;
8027 LockData.pPages = NULL;
8028 LockData.pData = NULL; /* out */
8029 LockData.Flags.Value = 0;
8030 LockData.Flags.LockEntire =1;
8031 LockData.Flags.ReadOnly = 1;
8032
8033 HRESULT hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
8034 Assert(hr == S_OK);
8035 if (hr == S_OK)
8036 {
8037 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
8038// Assert(bpp == pAlloc->SurfDesc.bpp);
8039// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
8040 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
8041 LockData.pData, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch));
8042 if (pRect)
8043 {
8044 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
8045 ((uint8_t*)LockData.pData) + (pRect->top * pAlloc->SurfDesc.pitch) + ((pRect->left * bpp) >> 3),
8046 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, pAlloc->SurfDesc.pitch));
8047 }
8048 Assert(0);
8049
8050 D3DDDICB_UNLOCK DdiUnlock;
8051
8052 DdiUnlock.NumAllocations = 1;
8053 DdiUnlock.phAllocations = &pAlloc->hAllocation;
8054
8055 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock);
8056 Assert(hr == S_OK);
8057 }
8058 if (pSuffix)
8059 {
8060 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
8061 }
8062}
8063
8064
8065VOID vboxVDbgDoDumpSurfData(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const RECT *pRect, IDirect3DSurface9 *pSurf, const char* pSuffix)
8066{
8067 if (pPrefix)
8068 {
8069 vboxVDbgMpPrint((pDevice, "%s", pPrefix));
8070 }
8071
8072 Assert(pRc->cAllocations > iAlloc);
8073 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
8074
8075 vboxVDbgMpPrintAlloc((pDevice, "allocation info:\n", pRc, iAlloc, "\n"));
8076
8077 D3DLOCKED_RECT Lr;
8078 if (pRect)
8079 {
8080 Assert(pRect->right > pRect->left);
8081 Assert(pRect->bottom > pRect->top);
8082 vboxVDbgMpPrintRect((pDevice, "rect: ", pRect, "\n"));
8083 }
8084
8085 BOOL bReleaseSurf = false;
8086 if (!pSurf)
8087 {
8088 HRESULT tmpHr = vboxWddmSurfGet(pRc, iAlloc, &pSurf);
8089 Assert(tmpHr == S_OK);
8090 bReleaseSurf = TRUE;
8091 }
8092 HRESULT srcHr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
8093 Assert(srcHr == S_OK);
8094 if (srcHr == S_OK)
8095 {
8096 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
8097// Assert(bpp == pAlloc->SurfDesc.bpp);
8098// Assert(pAlloc->SurfDesc.pitch == Lr.Pitch);
8099 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
8100 Lr.pBits, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, Lr.Pitch));
8101 if (pRect)
8102 {
8103 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
8104 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
8105 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
8106 }
8107 Assert(0);
8108
8109 srcHr = pSurf->UnlockRect();
8110 Assert(srcHr == S_OK);
8111 }
8112 if (pSuffix)
8113 {
8114 vboxVDbgMpPrint((pDevice, "%s\n", pSuffix));
8115 }
8116
8117 if (bReleaseSurf)
8118 pSurf->Release();
8119}
8120
8121VOID vboxVDbgDoDumpSurfDataBySurf(const PVBOXWDDMDISP_DEVICE pDevice, IDirect3DSurface9 *pSurf)
8122{
8123 D3DSURFACE_DESC Desc;
8124 HRESULT hr = pSurf->GetDesc(&Desc);
8125 Assert(hr == S_OK);
8126 if (hr == S_OK)
8127 {
8128 D3DLOCKED_RECT Lr;
8129 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
8130 Assert(hr == S_OK);
8131 if (hr == S_OK)
8132 {
8133 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
8134 vboxVDbgMpPrint((pDevice, "<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
8135 Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch));
8136
8137 Assert(0);
8138
8139 hr = pSurf->UnlockRect();
8140 Assert(hr == S_OK);
8141 }
8142 }
8143}
8144
8145void vboxVDbgDoMpPrintAlloc(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
8146{
8147 Assert(pRc->cAllocations > iAlloc);
8148 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
8149 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
8150 BOOL bFrontBuf = FALSE;
8151 if (bPrimary)
8152 {
8153 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
8154 Assert(pSwapchain);
8155 bFrontBuf = (vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc);
8156 }
8157 vboxVDbgDoMpPrintF(pDevice, "%s D3DWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
8158 pAlloc->D3DWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
8159 bPrimary ?
8160 (bFrontBuf ? "Front Buffer" : "Back Buffer")
8161 : "?Everage? Alloc",
8162 pSuffix);
8163}
8164
8165void vboxVDbgDoMpPrintRect(const PVBOXWDDMDISP_DEVICE pDevice, const char * pPrefix, const RECT *pRect, const char * pSuffix)
8166{
8167 vboxVDbgDoMpPrintF(pDevice, "%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix);
8168}
8169#endif
8170
8171#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
8172
8173static PVOID g_VBoxWDbgVEHandler = NULL;
8174LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
8175{
8176 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
8177 PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
8178 switch (pExceptionRecord->ExceptionCode)
8179 {
8180 case 0x40010006: /* <- OutputDebugString exception, ignore */
8181 case 0xe06d7363: /* <- ms compiler - generated exception related to C++ exception */
8182 break;
8183 default:
8184 AssertRelease(0);
8185 break;
8186 }
8187 return EXCEPTION_CONTINUE_SEARCH;
8188}
8189
8190void vboxVDbgVEHandlerRegister()
8191{
8192 Assert(!g_VBoxWDbgVEHandler);
8193 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
8194 Assert(g_VBoxWDbgVEHandler);
8195}
8196
8197void vboxVDbgVEHandlerUnregister()
8198{
8199 Assert(g_VBoxWDbgVEHandler);
8200 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
8201 Assert(uResult);
8202 g_VBoxWDbgVEHandler = NULL;
8203}
8204
8205#endif
8206
Note: See TracBrowser for help on using the repository browser.

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