VirtualBox

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

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

wddm/3d: some fixes + profiling & debugging

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

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