VirtualBox

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

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

wddm/3d: chromium hgsmi fixes

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