VirtualBox

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

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

wddm/3d: fix hgcm fallback (for insufficient hgsmi resources)

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