VirtualBox

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

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

wddm/3d: visible regions impl & fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 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} VBOXDISPCM_SESSION, *PVBOXDISPCM_SESSION;
28
29typedef struct VBOXDISPCM_MGR
30{
31 VBOXDISPCM_SESSION Session;
32} VBOXDISPCM_MGR, *PVBOXDISPCM_MGR;
33
34/* the cm is one per process */
35static VBOXDISPCM_MGR g_pVBoxCmMgr;
36
37HRESULT vboxDispCmSessionTerm(PVBOXDISPCM_SESSION pSession)
38{
39 Assert(RTListIsEmpty(&pSession->CtxList));
40 BOOL bRc = CloseHandle(pSession->hEvent);
41 Assert(bRc);
42 if (bRc)
43 {
44 DeleteCriticalSection(&pSession->CritSect);
45 return S_OK;
46 }
47 DWORD winEr = GetLastError();
48 HRESULT hr = HRESULT_FROM_WIN32(winEr);
49 return hr;
50}
51
52HRESULT vboxDispCmSessionInit(PVBOXDISPCM_SESSION pSession)
53{
54 HANDLE hEvent = CreateEvent(NULL,
55 FALSE, /* BOOL bManualReset */
56 FALSE, /* BOOL bInitialState */
57 NULL /* LPCTSTR lpName */
58 );
59 Assert(hEvent);
60 if (hEvent)
61 {
62 pSession->hEvent = hEvent;
63 InitializeCriticalSection(&pSession->CritSect);
64 RTListInit(&pSession->CtxList);
65 return S_OK;
66 }
67 DWORD winEr = GetLastError();
68 HRESULT hr = HRESULT_FROM_WIN32(winEr);
69 return hr;
70}
71
72void vboxDispCmSessionCtxAdd(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_CONTEXT pContext)
73{
74 EnterCriticalSection(&pSession->CritSect);
75 RTListAppend(&pSession->CtxList, &pContext->ListNode);
76 LeaveCriticalSection(&pSession->CritSect);
77}
78
79void vboxDispCmSessionCtxRemoveLocked(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_CONTEXT pContext)
80{
81 RTListNodeRemove(&pContext->ListNode);
82}
83
84void vboxDispCmSessionCtxRemove(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_CONTEXT pContext)
85{
86 EnterCriticalSection(&pSession->CritSect);
87 vboxDispCmSessionCtxRemoveLocked(pSession, pContext);
88 LeaveCriticalSection(&pSession->CritSect);
89}
90
91HRESULT vboxDispCmInit()
92{
93 HRESULT hr = vboxDispCmSessionInit(&g_pVBoxCmMgr.Session);
94 Assert(hr == S_OK);
95 return hr;
96}
97
98HRESULT vboxDispCmTerm()
99{
100 HRESULT hr = vboxDispCmSessionTerm(&g_pVBoxCmMgr.Session);
101 Assert(hr == S_OK);
102 return hr;
103}
104
105HRESULT vboxDispCmCtxCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT pContext)
106{
107 VBOXWDDM_CREATECONTEXT_INFO Info;
108 Info.u32IfVersion = pDevice->u32IfVersion;
109 Info.u32IsD3D = VBOXDISPMODE_IS_3D(pDevice->pAdapter);
110 Info.hUmEvent = (uint64_t)g_pVBoxCmMgr.Session.hEvent;
111 Info.u64UmInfo = (uint64_t)pContext;
112
113 pContext->ContextInfo.NodeOrdinal = 0;
114 pContext->ContextInfo.EngineAffinity = 0;
115 pContext->ContextInfo.Flags.Value = 0;
116 pContext->ContextInfo.pPrivateDriverData = &Info;
117 pContext->ContextInfo.PrivateDriverDataSize = sizeof (Info);
118 pContext->ContextInfo.hContext = 0;
119 pContext->ContextInfo.pCommandBuffer = NULL;
120 pContext->ContextInfo.CommandBufferSize = 0;
121 pContext->ContextInfo.pAllocationList = NULL;
122 pContext->ContextInfo.AllocationListSize = 0;
123 pContext->ContextInfo.pPatchLocationList = NULL;
124 pContext->ContextInfo.PatchLocationListSize = 0;
125
126 HRESULT hr = S_OK;
127 hr = pDevice->RtCallbacks.pfnCreateContextCb(pDevice->hDevice, &pContext->ContextInfo);
128 Assert(hr == S_OK);
129 if (hr == S_OK)
130 {
131 Assert(pContext->ContextInfo.hContext);
132 pContext->ContextInfo.pPrivateDriverData = NULL;
133 pContext->ContextInfo.PrivateDriverDataSize = 0;
134 vboxDispCmSessionCtxAdd(&g_pVBoxCmMgr.Session, pContext);
135 pContext->pDevice = pDevice;
136 }
137 return hr;
138}
139
140HRESULT vboxDispCmSessionCtxDestroy(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT pContext)
141{
142 EnterCriticalSection(&pSession->CritSect);
143 Assert(pContext->ContextInfo.hContext);
144 D3DDDICB_DESTROYCONTEXT DestroyContext;
145 Assert(pDevice->DefaultContext.ContextInfo.hContext);
146 DestroyContext.hContext = pDevice->DefaultContext.ContextInfo.hContext;
147 HRESULT hr = pDevice->RtCallbacks.pfnDestroyContextCb(pDevice->hDevice, &DestroyContext);
148 Assert(hr == S_OK);
149 if (hr == S_OK)
150 {
151 vboxDispCmSessionCtxRemoveLocked(pSession, pContext);
152 }
153 LeaveCriticalSection(&pSession->CritSect);
154 return hr;
155}
156
157HRESULT vboxDispCmCtxDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT pContext)
158{
159 return vboxDispCmSessionCtxDestroy(&g_pVBoxCmMgr.Session, pDevice, pContext);
160}
161
162HRESULT vboxDispCmSessionCmdGet(PVBOXDISPCM_SESSION pSession, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd, DWORD dwMilliseconds)
163{
164 Assert(cbCmd >= sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
165 if (cbCmd < sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD))
166 return E_INVALIDARG;
167
168 do
169 {
170 DWORD dwResult = WaitForSingleObject(pSession->hEvent, dwMilliseconds);
171 switch(dwResult)
172 {
173 case WAIT_OBJECT_0:
174 {
175 HRESULT hr = S_OK;
176 D3DDDICB_ESCAPE DdiEscape;
177 DdiEscape.Flags.Value = 0;
178 DdiEscape.pPrivateDriverData = pCmd;
179 DdiEscape.PrivateDriverDataSize = cbCmd;
180
181 pCmd->EscapeHdr.escapeCode = VBOXESC_GETVBOXVIDEOCMCMD;
182 /* lock to ensure the context is not distructed */
183 EnterCriticalSection(&pSession->CritSect);
184 /* use any context for identifying the kernel CmSession. We're using the first one */
185 PVBOXWDDMDISP_CONTEXT pContext = RTListNodeGetFirst(&pSession->CtxList, VBOXWDDMDISP_CONTEXT, ListNode);
186 if (pContext)
187 {
188 PVBOXWDDMDISP_DEVICE pDevice = pContext->pDevice;
189 DdiEscape.hDevice = pDevice->hDevice;
190 DdiEscape.hContext = pContext->ContextInfo.hContext;
191 Assert (DdiEscape.hContext);
192 Assert (DdiEscape.hDevice);
193 hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
194 LeaveCriticalSection(&pSession->CritSect);
195 Assert(hr == S_OK);
196 if (hr == S_OK)
197 {
198 if (!pCmd->Hdr.cbCmdsReturned && !pCmd->Hdr.cbRemainingFirstCmd)
199 break; /* <- break to enter a new wait cycle */
200 }
201 }
202 else
203 {
204 LeaveCriticalSection(&pSession->CritSect);
205 pCmd->Hdr.cbCmdsReturned = 0;
206 pCmd->Hdr.cbRemainingCmds = 0;
207 pCmd->Hdr.cbRemainingFirstCmd = 0;
208 }
209
210 return hr;
211 }
212 case WAIT_TIMEOUT:
213 {
214 pCmd->Hdr.cbCmdsReturned = 0;
215 pCmd->Hdr.cbRemainingCmds = 0;
216 pCmd->Hdr.cbRemainingFirstCmd = 0;
217 return WAIT_TIMEOUT;
218 }
219 default:
220 AssertBreakpoint();
221 return E_FAIL;
222 }
223 } while (1);
224}
225
226HRESULT vboxDispCmCmdGet(PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd, DWORD dwMilliseconds)
227{
228 return vboxDispCmSessionCmdGet(&g_pVBoxCmMgr.Session, pCmd, cbCmd, dwMilliseconds);
229}
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