VirtualBox

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

Last change on this file since 39508 was 39508, checked in by vboxsync, 13 years ago

wddm/d3d: fix surface rederence

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

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