VirtualBox

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

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

3d/wddm: fix up stream source tracking

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