VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp@ 38660

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

Wddm/3D: fix incorrect window border blurs under aero on ati cards

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

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