VirtualBox

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

最後變更 在這個檔案從35036是 34939,由 vboxsync 提交於 14 年 前

wddm/3d: impl missing lock/unlock surface functionality, remove deprecated assertions, disable some todo assertions

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

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