VirtualBox

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

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

wddm: avoid unnecessary window creation (caused img flickering for MacOS guest), etc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 KB
Line 
1/* $Id: VBoxDispD3D.h 39150 2011-10-31 13:37:06Z vboxsync $ */
2
3/** @file
4 * VBoxVideo Display D3D User mode dll
5 */
6
7/*
8 * Copyright (C) 2011 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#ifndef ___VBoxDispD3D_h___
20#define ___VBoxDispD3D_h___
21
22#include "VBoxDispD3DIf.h"
23#include "common/wddm/VBoxMPIf.h"
24#ifdef VBOX_WITH_CRHGSMI
25#include "VBoxUhgsmiDisp.h"
26#endif
27
28#include <iprt/cdefs.h>
29#include <iprt/list.h>
30
31#define VBOXWDDMDISP_MAX_VERTEX_STREAMS 16
32#define VBOXWDDMDISP_MAX_SWAPCHAIN_SIZE 16
33/* maximum number of direct render targets to be used before
34 * switching to offscreen rendering */
35#ifdef DEBUG_misha
36#define VBOXWDDMDISP_MAX_DIRECT_RTS 0
37#else
38#define VBOXWDDMDISP_MAX_DIRECT_RTS 3
39#endif
40
41#define VBOXWDDMDISP_IS_TEXTURE(_f) ((_f).Texture || (_f).Value == 0)
42
43#ifdef VBOX_WITH_VIDEOHWACCEL
44typedef struct VBOXDISPVHWA_INFO
45{
46 VBOXVHWA_INFO Settings;
47}VBOXDISPVHWA_INFO;
48
49/* represents settings secific to
50 * display device (head) on the multiple-head graphics card
51 * currently used for 2D (overlay) only since in theory its settings
52 * can differ per each frontend's framebuffer. */
53typedef struct VBOXWDDMDISP_HEAD
54{
55 VBOXDISPVHWA_INFO Vhwa;
56} VBOXWDDMDISP_HEAD;
57#endif
58
59typedef struct VBOXWDDMDISP_ADAPTER
60{
61 HANDLE hAdapter;
62 UINT uIfVersion;
63 UINT uRtVersion;
64 VBOXDISPD3D D3D;
65 IDirect3D9Ex * pD3D9If;
66 D3DDDI_ADAPTERCALLBACKS RtCallbacks;
67 uint32_t cFormstOps;
68 FORMATOP *paFormstOps;
69 uint32_t cSurfDescs;
70 DDSURFACEDESC *paSurfDescs;
71 UINT cMaxSimRTs;
72#ifdef VBOX_WITH_VIDEOHWACCEL
73 uint32_t cHeads;
74 VBOXWDDMDISP_HEAD aHeads[1];
75#endif
76} VBOXWDDMDISP_ADAPTER, *PVBOXWDDMDISP_ADAPTER;
77
78typedef struct VBOXWDDMDISP_CONTEXT
79{
80 RTLISTNODE ListNode;
81 struct VBOXWDDMDISP_DEVICE *pDevice;
82 D3DDDICB_CREATECONTEXT ContextInfo;
83} VBOXWDDMDISP_CONTEXT, *PVBOXWDDMDISP_CONTEXT;
84
85typedef struct VBOXWDDMDISP_STREAMSOURCEUM
86{
87 CONST VOID* pvBuffer;
88 UINT cbStride;
89} VBOXWDDMDISP_STREAMSOURCEUM, *PVBOXWDDMDISP_STREAMSOURCEUM;
90
91typedef struct VBOXWDDMDISP_INDICIESUM
92{
93 CONST VOID* pvBuffer;
94 UINT cbSize;
95} VBOXWDDMDISP_INDICIESUM, *PVBOXWDDMDISP_INDICIESUM;
96
97struct VBOXWDDMDISP_ALLOCATION;
98
99typedef struct VBOXWDDMDISP_STREAM_SOURCE_INFO
100{
101 UINT uiOffset;
102 UINT uiStride;
103} VBOXWDDMDISP_STREAM_SOURCE_INFO;
104
105typedef struct VBOXWDDMDISP_INDICES_INFO
106{
107 UINT uiStride;
108} VBOXWDDMDISP_INDICES_INFO;
109
110typedef struct VBOXWDDMDISP_RENDERTGT_FLAGS
111{
112 union
113 {
114 struct
115 {
116 UINT bAdded : 1;
117 UINT bRemoved : 1;
118 UINT Reserved : 30;
119 };
120 uint32_t Value;
121 };
122}VBOXWDDMDISP_RENDERTGT_FLAGS;
123
124typedef struct VBOXWDDMDISP_RENDERTGT
125{
126 struct VBOXWDDMDISP_ALLOCATION *pAlloc;
127 UINT cNumFlips;
128 VBOXWDDMDISP_RENDERTGT_FLAGS fFlags;
129} VBOXWDDMDISP_RENDERTGT, *PVBOXWDDMDISP_RENDERTGT;
130
131#define VBOXWDDMDISP_INDEX_UNDEFINED (~0)
132typedef struct VBOXWDDMDISP_SWAPCHAIN_FLAGS
133{
134 union
135 {
136 struct
137 {
138 UINT bChanged : 1;
139 UINT bRtReportingPresent : 1; /* use VBox extension method for performing present */
140 UINT bSwitchReportingPresent : 1; /* switch to use VBox extension method for performing present on next present */
141 UINT Reserved : 30;
142 };
143 uint32_t Value;
144 };
145}VBOXWDDMDISP_SWAPCHAIN_FLAGS;
146
147typedef struct VBOXWDDMDISP_SWAPCHAIN
148{
149 RTLISTNODE ListEntry;
150 UINT iBB; /* Backbuffer index */
151 UINT cRTs; /* Number of render targets in the swapchain */
152 VBOXWDDMDISP_SWAPCHAIN_FLAGS fFlags;
153#ifndef VBOXWDDM_WITH_VISIBLE_FB
154 IDirect3DSurface9 *pRenderTargetFbCopy;
155 BOOL bRTFbCopyUpToDate;
156#endif
157 IDirect3DSwapChain9 *pSwapChainIf;
158 /* a read-only hWnd we receive from wine
159 * we use it for visible region notifications only,
160 * it MUST NOT be destroyed on swapchain destruction,
161 * wine will handle that for us */
162 HWND hWnd;
163 VBOXDISP_KMHANDLE hSwapchainKm;
164 VBOXWDDMDISP_RENDERTGT aRTs[VBOXWDDMDISP_MAX_SWAPCHAIN_SIZE];
165} VBOXWDDMDISP_SWAPCHAIN, *PVBOXWDDMDISP_SWAPCHAIN;
166
167typedef struct VBOXWDDMDISP_DEVICE
168{
169 HANDLE hDevice;
170 PVBOXWDDMDISP_ADAPTER pAdapter;
171 IDirect3DDevice9 *pDevice9If;
172 RTLISTNODE SwapchainList;
173 UINT u32IfVersion;
174 UINT uRtVersion;
175 D3DDDI_DEVICECALLBACKS RtCallbacks;
176 VOID *pvCmdBuffer;
177 UINT cbCmdBuffer;
178 D3DDDI_CREATEDEVICEFLAGS fFlags;
179 /* number of StreamSources set */
180 UINT cStreamSources;
181 VBOXWDDMDISP_STREAMSOURCEUM aStreamSourceUm[VBOXWDDMDISP_MAX_VERTEX_STREAMS];
182 struct VBOXWDDMDISP_ALLOCATION *aStreamSource[VBOXWDDMDISP_MAX_VERTEX_STREAMS];
183 VBOXWDDMDISP_STREAM_SOURCE_INFO StreamSourceInfo[VBOXWDDMDISP_MAX_VERTEX_STREAMS];
184 VBOXWDDMDISP_INDICIESUM IndiciesUm;
185 struct VBOXWDDMDISP_ALLOCATION *pIndicesAlloc;
186 VBOXWDDMDISP_INDICES_INFO IndiciesInfo;
187 /* need to cache the ViewPort data because IDirect3DDevice9::SetViewport
188 * is split into two calls : SetViewport & SetZRange */
189 D3DVIEWPORT9 ViewPort;
190 VBOXWDDMDISP_CONTEXT DefaultContext;
191#ifdef VBOX_WITH_CRHGSMI
192 VBOXUHGSMI_PRIVATE_D3D Uhgsmi;
193#endif
194
195 /* no lock is needed for this since we're guaranteed the per-device calls are not reentrant */
196 RTLISTNODE DirtyAllocList;
197
198 UINT cRTs;
199 struct VBOXWDDMDISP_ALLOCATION * apRTs[1];
200} VBOXWDDMDISP_DEVICE, *PVBOXWDDMDISP_DEVICE;
201
202typedef struct VBOXWDDMDISP_LOCKINFO
203{
204 uint32_t cLocks;
205 union {
206 D3DDDIRANGE Range;
207 RECT Area;
208 D3DDDIBOX Box;
209 };
210 D3DDDI_LOCKFLAGS fFlags;
211 D3DLOCKED_RECT LockedRect;
212#ifdef VBOXWDDMDISP_DEBUG
213 PVOID pvData;
214#endif
215} VBOXWDDMDISP_LOCKINFO;
216
217typedef enum
218{
219 VBOXDISP_D3DIFTYPE_UNDEFINED = 0,
220 VBOXDISP_D3DIFTYPE_SURFACE,
221 VBOXDISP_D3DIFTYPE_TEXTURE,
222 VBOXDISP_D3DIFTYPE_CUBE_TEXTURE,
223 VBOXDISP_D3DIFTYPE_VERTEXBUFFER,
224 VBOXDISP_D3DIFTYPE_INDEXBUFFER
225} VBOXDISP_D3DIFTYPE;
226
227typedef struct VBOXWDDMDISP_ALLOCATION
228{
229 D3DKMT_HANDLE hAllocation;
230 VBOXWDDM_ALLOC_TYPE enmType;
231 UINT iAlloc;
232 struct VBOXWDDMDISP_RESOURCE *pRc;
233 void* pvMem;
234 UINT D3DWidth;
235 /* object type is defined by enmD3DIfType enum */
236 IUnknown *pD3DIf;
237 VBOXDISP_D3DIFTYPE enmD3DIfType;
238 /* list entry used to add allocation to the dirty alloc list */
239 RTLISTNODE DirtyAllocListEntry;
240 BOOLEAN fDirtyWrite;
241 HANDLE hSharedHandle;
242 VBOXWDDMDISP_LOCKINFO LockInfo;
243 VBOXWDDM_DIRTYREGION DirtyRegion; /* <- dirty region to notify host about */
244 VBOXWDDM_SURFACE_DESC SurfDesc;
245 PVBOXWDDMDISP_SWAPCHAIN pSwapchain;
246} VBOXWDDMDISP_ALLOCATION, *PVBOXWDDMDISP_ALLOCATION;
247
248typedef struct VBOXWDDMDISP_RESOURCE
249{
250 HANDLE hResource;
251 D3DKMT_HANDLE hKMResource;
252 PVBOXWDDMDISP_DEVICE pDevice;
253 VBOXWDDMDISP_RESOURCE_FLAGS fFlags;
254 VBOXWDDM_RC_DESC RcDesc;
255 UINT cAllocations;
256 VBOXWDDMDISP_ALLOCATION aAllocations[1];
257} VBOXWDDMDISP_RESOURCE, *PVBOXWDDMDISP_RESOURCE;
258
259typedef struct VBOXWDDMDISP_QUERY
260{
261 D3DDDIQUERYTYPE enmType;
262 D3DDDI_ISSUEQUERYFLAGS fQueryState;
263 union
264 {
265 BOOL bData;
266 UINT u32Data;
267 } data ;
268} VBOXWDDMDISP_QUERY, *PVBOXWDDMDISP_QUERY;
269
270typedef struct VBOXWDDMDISP_TSS_LOOKUP
271{
272 BOOL bSamplerState;
273 DWORD dType;
274} VBOXWDDMDISP_TSS_LOOKUP;
275
276typedef struct VBOXWDDMDISP_OVERLAY
277{
278 D3DKMT_HANDLE hOverlay;
279 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId;
280 PVBOXWDDMDISP_RESOURCE *pResource;
281} VBOXWDDMDISP_OVERLAY, *PVBOXWDDMDISP_OVERLAY;
282
283#define VBOXDISP_CUBEMAP_LEVELS_COUNT(pRc) (((pRc)->cAllocations)/6)
284#define VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, idx) ((D3DCUBEMAP_FACES)(D3DCUBEMAP_FACE_POSITIVE_X+(idx)%VBOXDISP_CUBEMAP_LEVELS_COUNT(pRc)))
285#define VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, idx) ((idx)%VBOXDISP_CUBEMAP_LEVELS_COUNT(pRc))
286
287#ifdef VBOX_WITH_CRHGSMI
288HRESULT vboxUhgsmiGlobalSetCurrent();
289HRESULT vboxUhgsmiGlobalClearCurrent();
290#endif
291
292DECLINLINE(PVBOXWDDMDISP_SWAPCHAIN) vboxWddmSwapchainForAlloc(PVBOXWDDMDISP_ALLOCATION pAlloc)
293{
294 return pAlloc->pSwapchain;
295}
296
297DECLINLINE(UINT) vboxWddmSwapchainIdxFb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
298{
299 return (pSwapchain->iBB + pSwapchain->cRTs - 1) % pSwapchain->cRTs;
300}
301
302/* if swapchain contains only one surface returns this surface */
303DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainGetBb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
304{
305 if (pSwapchain->cRTs)
306 {
307 Assert(pSwapchain->iBB < pSwapchain->cRTs);
308 return &pSwapchain->aRTs[pSwapchain->iBB];
309 }
310 return NULL;
311}
312
313DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainGetFb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
314{
315 if (pSwapchain->cRTs)
316 {
317 UINT iFb = vboxWddmSwapchainIdxFb(pSwapchain);
318 return &pSwapchain->aRTs[iFb];
319 }
320 return NULL;
321}
322
323/* on success increments the surface ref counter,
324 * i.e. one must call pSurf->Release() once the surface is not needed*/
325DECLINLINE(HRESULT) vboxWddmSurfGet(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc, IDirect3DSurface9 **ppSurf)
326{
327 HRESULT hr = S_OK;
328 Assert(pRc->cAllocations > iAlloc);
329 switch (pRc->aAllocations[0].enmD3DIfType)
330 {
331 case VBOXDISP_D3DIFTYPE_SURFACE:
332 {
333 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
334 Assert(pD3DIfSurf);
335 pD3DIfSurf->AddRef();
336 *ppSurf = pD3DIfSurf;
337 break;
338 }
339 case VBOXDISP_D3DIFTYPE_TEXTURE:
340 {
341 Assert(pRc->cAllocations == 1); /* <- vboxWddmSurfGet is typically used in Blt & ColorFill functions
342 * in this case, if texture is used as a destination,
343 * we should update sub-layers as well which is not done currently
344 * so for now check vboxWddmSurfGet is used for one-level textures */
345 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
346 IDirect3DSurface9 *pSurfaceLevel;
347 Assert(pD3DIfTex);
348 hr = pD3DIfTex->GetSurfaceLevel(iAlloc, &pSurfaceLevel);
349 Assert(hr == S_OK);
350 if (hr == S_OK)
351 {
352 *ppSurf = pSurfaceLevel;
353 }
354 break;
355 }
356 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
357 {
358 Assert(0);
359 IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9*)pRc->aAllocations[0].pD3DIf;
360 IDirect3DSurface9 *pSurfaceLevel;
361 Assert(pD3DIfCubeTex);
362 hr = pD3DIfCubeTex->GetCubeMapSurface(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, iAlloc),
363 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, iAlloc), &pSurfaceLevel);
364 Assert(hr == S_OK);
365 if (hr == S_OK)
366 {
367 *ppSurf = pSurfaceLevel;
368 }
369 break;
370 }
371 default:
372 Assert(0);
373 hr = E_FAIL;
374 break;
375 }
376 return hr;
377}
378
379HRESULT vboxWddmLockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc,
380 D3DLOCKED_RECT * pLockedRect,
381 CONST RECT *pRect,
382 DWORD fLockFlags);
383HRESULT vboxWddmUnlockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc);
384
385#define VBOXDISPMODE_IS_3D(_p) (!!((_p)->pD3D9If))
386#ifdef VBOXDISP_EARLYCREATEDEVICE
387#define VBOXDISP_D3DEV(_p) (_p)->pDevice9If
388#else
389#define VBOXDISP_D3DEV(_p) vboxWddmD3DDeviceGet(_p)
390#endif
391
392#endif /* #ifndef ___VBoxDispD3D_h___ */
Note: See TracBrowser for help on using the repository browser.

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