VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispCm.cpp@ 36046

Last change on this file since 36046 was 36046, checked in by vboxsync, 14 years ago

wddm/3d: debugging

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
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.virtualbox.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#include "VBoxDispD3DCmn.h"
16#include "VBoxDispD3D.h"
17#include "../../../include/VBoxDisplay.h"
18
19#include <iprt/list.h>
20
21
22typedef struct VBOXDISPCM_SESSION
23{
24 HANDLE hEvent;
25 CRITICAL_SECTION CritSect;
26 RTLISTNODE CtxList;
27 bool bQueryMp;
28} VBOXDISPCM_SESSION, *PVBOXDISPCM_SESSION;
29
30typedef struct VBOXDISPCM_MGR
31{
32 VBOXDISPCM_SESSION Session;
33} VBOXDISPCM_MGR, *PVBOXDISPCM_MGR;
34
35/* the cm is one per process */
36static VBOXDISPCM_MGR g_pVBoxCmMgr;
37
38HRESULT vboxDispCmSessionTerm(PVBOXDISPCM_SESSION pSession)
39{
40#ifdef DEBUG_misha
41 Assert(RTListIsEmpty(&pSession->CtxList));
42#endif
43 BOOL bRc = CloseHandle(pSession->hEvent);
44 Assert(bRc);
45 if (bRc)
46 {
47 DeleteCriticalSection(&pSession->CritSect);
48 return S_OK;
49 }
50 DWORD winEr = GetLastError();
51 HRESULT hr = HRESULT_FROM_WIN32(winEr);
52 return hr;
53}
54
55HRESULT vboxDispCmSessionInit(PVBOXDISPCM_SESSION pSession)
56{
57 HANDLE hEvent = CreateEvent(NULL,
58 FALSE, /* BOOL bManualReset */
59 FALSE, /* BOOL bInitialState */
60 NULL /* LPCTSTR lpName */
61 );
62 Assert(hEvent);
63 if (hEvent)
64 {
65 pSession->hEvent = hEvent;
66 InitializeCriticalSection(&pSession->CritSect);
67 RTListInit(&pSession->CtxList);
68 pSession->bQueryMp = false;
69 return S_OK;
70 }
71 DWORD winEr = GetLastError();
72 HRESULT hr = HRESULT_FROM_WIN32(winEr);
73 return hr;
74}
75
76void vboxDispCmSessionCtxAdd(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_CONTEXT pContext)
77{
78 EnterCriticalSection(&pSession->CritSect);
79 RTListAppend(&pSession->CtxList, &pContext->ListNode);
80 LeaveCriticalSection(&pSession->CritSect);
81}
82
83void vboxDispCmSessionCtxRemoveLocked(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_CONTEXT pContext)
84{
85 RTListNodeRemove(&pContext->ListNode);
86}
87
88void vboxDispCmSessionCtxRemove(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_CONTEXT pContext)
89{
90 EnterCriticalSection(&pSession->CritSect);
91 vboxDispCmSessionCtxRemoveLocked(pSession, pContext);
92 LeaveCriticalSection(&pSession->CritSect);
93}
94
95HRESULT vboxDispCmInit()
96{
97 HRESULT hr = vboxDispCmSessionInit(&g_pVBoxCmMgr.Session);
98 Assert(hr == S_OK);
99 return hr;
100}
101
102HRESULT vboxDispCmTerm()
103{
104 HRESULT hr = vboxDispCmSessionTerm(&g_pVBoxCmMgr.Session);
105 Assert(hr == S_OK);
106 return hr;
107}
108
109HRESULT vboxDispCmCtxCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT pContext)
110{
111 VBOXWDDM_CREATECONTEXT_INFO Info;
112 Info.u32IfVersion = pDevice->u32IfVersion;
113 Info.enmType = VBOXDISPMODE_IS_3D(pDevice->pAdapter) ? VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D : VBOXWDDM_CONTEXT_TYPE_CUSTOM_2D;
114 Info.hUmEvent = (uint64_t)g_pVBoxCmMgr.Session.hEvent;
115 Info.u64UmInfo = (uint64_t)pContext;
116
117 pContext->ContextInfo.NodeOrdinal = 0;
118 pContext->ContextInfo.EngineAffinity = 0;
119 pContext->ContextInfo.Flags.Value = 0;
120 pContext->ContextInfo.pPrivateDriverData = &Info;
121 pContext->ContextInfo.PrivateDriverDataSize = sizeof (Info);
122 pContext->ContextInfo.hContext = 0;
123 pContext->ContextInfo.pCommandBuffer = NULL;
124 pContext->ContextInfo.CommandBufferSize = 0;
125 pContext->ContextInfo.pAllocationList = NULL;
126 pContext->ContextInfo.AllocationListSize = 0;
127 pContext->ContextInfo.pPatchLocationList = NULL;
128 pContext->ContextInfo.PatchLocationListSize = 0;
129
130 HRESULT hr = S_OK;
131 hr = pDevice->RtCallbacks.pfnCreateContextCb(pDevice->hDevice, &pContext->ContextInfo);
132 Assert(hr == S_OK);
133 if (hr == S_OK)
134 {
135 Assert(pContext->ContextInfo.hContext);
136 pContext->ContextInfo.pPrivateDriverData = NULL;
137 pContext->ContextInfo.PrivateDriverDataSize = 0;
138 vboxDispCmSessionCtxAdd(&g_pVBoxCmMgr.Session, pContext);
139 pContext->pDevice = pDevice;
140 }
141 else
142 {
143 exit(1);
144 }
145
146 return hr;
147}
148
149HRESULT vboxDispCmSessionCtxDestroy(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT pContext)
150{
151 EnterCriticalSection(&pSession->CritSect);
152 Assert(pContext->ContextInfo.hContext);
153 D3DDDICB_DESTROYCONTEXT DestroyContext;
154 Assert(pDevice->DefaultContext.ContextInfo.hContext);
155 DestroyContext.hContext = pDevice->DefaultContext.ContextInfo.hContext;
156 HRESULT hr = pDevice->RtCallbacks.pfnDestroyContextCb(pDevice->hDevice, &DestroyContext);
157 Assert(hr == S_OK);
158 if (hr == S_OK)
159 {
160 vboxDispCmSessionCtxRemoveLocked(pSession, pContext);
161 }
162 LeaveCriticalSection(&pSession->CritSect);
163 return hr;
164}
165
166HRESULT vboxDispCmCtxDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT pContext)
167{
168 return vboxDispCmSessionCtxDestroy(&g_pVBoxCmMgr.Session, pDevice, pContext);
169}
170
171static HRESULT vboxDispCmSessionCmdQueryData(PVBOXDISPCM_SESSION pSession, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd)
172{
173
174 HRESULT hr = S_OK;
175 D3DDDICB_ESCAPE DdiEscape;
176 DdiEscape.Flags.Value = 0;
177 DdiEscape.pPrivateDriverData = pCmd;
178 DdiEscape.PrivateDriverDataSize = cbCmd;
179
180 pCmd->EscapeHdr.escapeCode = VBOXESC_GETVBOXVIDEOCMCMD;
181 /* lock to ensure the context is not destroyed */
182 EnterCriticalSection(&pSession->CritSect);
183 /* use any context for identifying the kernel CmSession. We're using the first one */
184 PVBOXWDDMDISP_CONTEXT pContext = RTListGetFirst(&pSession->CtxList, VBOXWDDMDISP_CONTEXT, ListNode);
185 if (pContext)
186 {
187 PVBOXWDDMDISP_DEVICE pDevice = pContext->pDevice;
188 DdiEscape.hDevice = pDevice->hDevice;
189 DdiEscape.hContext = pContext->ContextInfo.hContext;
190 Assert (DdiEscape.hContext);
191 Assert (DdiEscape.hDevice);
192 hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
193 LeaveCriticalSection(&pSession->CritSect);
194 Assert(hr == S_OK);
195 if (hr == S_OK)
196 {
197 if (!pCmd->Hdr.cbCmdsReturned && !pCmd->Hdr.cbRemainingFirstCmd)
198 hr = S_FALSE;
199 }
200 else
201 {
202 vboxVDbgPrint(("DispD3D: vboxDispCmSessionCmdQueryData, pfnEscapeCb failed hr (0x%x)\n", hr));
203 exit(1);
204 }
205 }
206 else
207 {
208 LeaveCriticalSection(&pSession->CritSect);
209 hr = S_FALSE;
210 }
211
212 return hr;
213}
214
215HRESULT vboxDispCmSessionCmdGet(PVBOXDISPCM_SESSION pSession, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd, DWORD dwMilliseconds)
216{
217 Assert(cbCmd >= sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
218 if (cbCmd < sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD))
219 return E_INVALIDARG;
220
221 do
222 {
223
224 if (pSession->bQueryMp)
225 {
226 HRESULT hr = vboxDispCmSessionCmdQueryData(pSession, pCmd, cbCmd);
227 Assert(hr == S_OK || hr == S_FALSE);
228 if (hr == S_OK || hr != S_FALSE)
229 {
230 return hr;
231 }
232
233 pSession->bQueryMp = false;
234 }
235
236 DWORD dwResult = WaitForSingleObject(pSession->hEvent, dwMilliseconds);
237 switch(dwResult)
238 {
239 case WAIT_OBJECT_0:
240 {
241 pSession->bQueryMp = true;
242 break; /* <- query commands */
243 }
244 case WAIT_TIMEOUT:
245 {
246 Assert(!pSession->bQueryMp);
247 return WAIT_TIMEOUT;
248 }
249 default:
250 Assert(0);
251 return E_FAIL;
252 }
253 } while (1);
254
255 /* should never be here */
256 Assert(0);
257 return E_FAIL;
258}
259
260HRESULT vboxDispCmCmdGet(PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd, DWORD dwMilliseconds)
261{
262 return vboxDispCmSessionCmdGet(&g_pVBoxCmMgr.Session, pCmd, cbCmd, dwMilliseconds);
263}
264
265void vboxDispCmLog(LPCSTR pszMsg)
266{
267 PVBOXDISPCM_SESSION pSession = &g_pVBoxCmMgr.Session;
268
269 EnterCriticalSection(&pSession->CritSect);
270 /* use any context for identifying the kernel CmSession. We're using the first one */
271 PVBOXWDDMDISP_CONTEXT pContext = RTListGetFirst(&pSession->CtxList, VBOXWDDMDISP_CONTEXT, ListNode);
272 Assert(pContext);
273 if (pContext)
274 {
275 PVBOXWDDMDISP_DEVICE pDevice = pContext->pDevice;
276 Assert(pDevice);
277 vboxVDbgPrint(("%s", pszMsg));
278 }
279 LeaveCriticalSection(&pSession->CritSect);
280}
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