VirtualBox

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

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

wddm/3d: rendering fixes

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