VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxCrHgsmi.cpp@ 34981

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

Todo.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1#include <VBox/VBoxCrHgsmi.h>
2#include <iprt/err.h>
3
4#include "VBoxUhgsmiKmt.h"
5
6static VBOXDISPKMT_CALLBACKS g_VBoxCrHgsmiKmtCallbacks;
7static int g_bVBoxKmtCallbacksInited = 0;
8
9#ifdef VBOX_CRHGSMI_WITH_D3DDEV
10static VBOXCRHGSMI_CALLBACKS g_VBoxCrHgsmiCallbacks;
11static HMODULE g_hVBoxCrHgsmiProvider = NULL;
12static uint32_t g_cVBoxCrHgsmiProvider = 0;
13
14
15typedef VBOXWDDMDISP_DECL(int) FNVBOXDISPCRHGSMI_INIT(PVBOXCRHGSMI_CALLBACKS pCallbacks);
16typedef FNVBOXDISPCRHGSMI_INIT *PFNVBOXDISPCRHGSMI_INIT;
17
18typedef VBOXWDDMDISP_DECL(int) FNVBOXDISPCRHGSMI_TERM();
19typedef FNVBOXDISPCRHGSMI_TERM *PFNVBOXDISPCRHGSMI_TERM;
20
21typedef VBOXWDDMDISP_DECL(HVBOXCRHGSMI_CLIENT) FNVBOXDISPCRHGSMI_QUERY_CLIENT();
22typedef FNVBOXDISPCRHGSMI_QUERY_CLIENT *PFNVBOXDISPCRHGSMI_QUERY_CLIENT;
23
24static PFNVBOXDISPCRHGSMI_INIT g_pfnVBoxDispCrHgsmiInit = NULL;
25static PFNVBOXDISPCRHGSMI_TERM g_pfnVBoxDispCrHgsmiTerm = NULL;
26static PFNVBOXDISPCRHGSMI_QUERY_CLIENT g_pfnVBoxDispCrHgsmiQueryClient = NULL;
27
28VBOXCRHGSMI_DECL(int) VBoxCrHgsmiInit(PVBOXCRHGSMI_CALLBACKS pCallbacks)
29{
30 if (!g_bVBoxKmtCallbacksInited)
31 {
32 HRESULT hr = vboxDispKmtCallbacksInit(&g_VBoxCrHgsmiKmtCallbacks);
33 Assert(hr == S_OK);
34 if (hr == S_OK)
35 g_bVBoxKmtCallbacksInited = 1;
36 else
37 g_bVBoxKmtCallbacksInited = -1;
38 }
39
40 Assert(g_bVBoxKmtCallbacksInited);
41 if (g_bVBoxKmtCallbacksInited < 0)
42 {
43 Assert(0);
44 return VERR_NOT_SUPPORTED;
45 }
46
47 g_VBoxCrHgsmiCallbacks = *pCallbacks;
48 if (!g_hVBoxCrHgsmiProvider)
49 {
50 /** @todo GetModuleHandleEx() only is available for WinXP and up ... */
51 BOOL bRc = GetModuleHandleEx(0, L"VBoxDispD3D", &g_hVBoxCrHgsmiProvider);
52// g_hVBoxCrHgsmiProvider = GetModuleHandle(L"VBoxDispD3D");
53 if (bRc)
54 {
55 g_pfnVBoxDispCrHgsmiInit = (PFNVBOXDISPCRHGSMI_INIT)GetProcAddress(g_hVBoxCrHgsmiProvider, "VBoxDispCrHgsmiInit");
56 Assert(g_pfnVBoxDispCrHgsmiInit);
57 if (g_pfnVBoxDispCrHgsmiInit)
58 {
59 g_pfnVBoxDispCrHgsmiInit(pCallbacks);
60 }
61
62 g_pfnVBoxDispCrHgsmiTerm = (PFNVBOXDISPCRHGSMI_TERM)GetProcAddress(g_hVBoxCrHgsmiProvider, "VBoxDispCrHgsmiTerm");
63 Assert(g_pfnVBoxDispCrHgsmiTerm);
64
65 g_pfnVBoxDispCrHgsmiQueryClient = (PFNVBOXDISPCRHGSMI_QUERY_CLIENT)GetProcAddress(g_hVBoxCrHgsmiProvider, "VBoxDispCrHgsmiQueryClient");
66 Assert(g_pfnVBoxDispCrHgsmiQueryClient);
67 }
68#ifdef DEBUG_misha
69 else
70 {
71 DWORD winEr = GetLastError();
72 Assert(0);
73 }
74#endif
75 }
76
77 if (g_hVBoxCrHgsmiProvider)
78 {
79 if (g_pfnVBoxDispCrHgsmiInit)
80 {
81 g_pfnVBoxDispCrHgsmiInit(pCallbacks);
82 }
83 ++g_cVBoxCrHgsmiProvider;
84 return VINF_SUCCESS;
85 }
86
87 /* we're called from ogl ICD driver*/
88 Assert(0);
89
90 return VINF_SUCCESS;
91}
92
93static __declspec(thread) PVBOXUHGSMI_PRIVATE_KMT gt_pHgsmiGL = NULL;
94
95VBOXCRHGSMI_DECL(HVBOXCRHGSMI_CLIENT) VBoxCrHgsmiQueryClient()
96{
97
98 HVBOXCRHGSMI_CLIENT hClient;
99 if (g_pfnVBoxDispCrHgsmiQueryClient)
100 {
101 hClient = g_pfnVBoxDispCrHgsmiQueryClient();
102//#ifdef DEBUG_misha
103// Assert(hClient);
104//#endif
105 if (hClient)
106 return hClient;
107 }
108 PVBOXUHGSMI_PRIVATE_KMT pHgsmiGL = gt_pHgsmiGL;
109 if (pHgsmiGL)
110 {
111 Assert(pHgsmiGL->BasePrivate.hClient);
112 return pHgsmiGL->BasePrivate.hClient;
113 }
114 pHgsmiGL = (PVBOXUHGSMI_PRIVATE_KMT)RTMemAllocZ(sizeof (*pHgsmiGL));
115 if (pHgsmiGL)
116 {
117#if 0
118 HRESULT hr = vboxUhgsmiKmtCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
119#else
120 HRESULT hr = vboxUhgsmiKmtEscCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
121#endif
122 Assert(hr == S_OK);
123 if (hr == S_OK)
124 {
125 hClient = g_VBoxCrHgsmiCallbacks.pfnClientCreate(&pHgsmiGL->BasePrivate.Base);
126 Assert(hClient);
127 if (hClient)
128 {
129 pHgsmiGL->BasePrivate.hClient = hClient;
130 gt_pHgsmiGL = pHgsmiGL;
131 return hClient;
132 }
133 vboxUhgsmiKmtDestroy(pHgsmiGL);
134 }
135 RTMemFree(pHgsmiGL);
136 }
137
138 return NULL;
139}
140#else
141static int vboxCrHgsmiInitPerform(VBOXDISPKMT_CALLBACKS *pCallbacks)
142{
143 HRESULT hr = vboxDispKmtCallbacksInit(pCallbacks);
144 /*Assert(hr == S_OK);*/
145 if (hr == S_OK)
146 {
147 /* check if we can create the hgsmi */
148 PVBOXUHGSMI pHgsmi = VBoxCrHgsmiCreate();
149 if (pHgsmi)
150 {
151 /* yes, we can, so this is wddm mode */
152 VBoxCrHgsmiDestroy(pHgsmi);
153 Log(("CrHgsmi: WDDM mode supported\n"));
154 return 1;
155 }
156 vboxDispKmtCallbacksTerm(pCallbacks);
157 }
158 Log(("CrHgsmi: unsupported\n"));
159 return -1;
160}
161
162VBOXCRHGSMI_DECL(int) VBoxCrHgsmiInit()
163{
164 if (!g_bVBoxKmtCallbacksInited)
165 {
166 g_bVBoxKmtCallbacksInited = vboxCrHgsmiInitPerform(&g_VBoxCrHgsmiKmtCallbacks);
167 Assert(g_bVBoxKmtCallbacksInited);
168 }
169
170 return g_bVBoxKmtCallbacksInited > 0 ? VINF_SUCCESS : VERR_NOT_SUPPORTED;
171}
172
173VBOXCRHGSMI_DECL(PVBOXUHGSMI) VBoxCrHgsmiCreate()
174{
175 PVBOXUHGSMI_PRIVATE_KMT pHgsmiGL = (PVBOXUHGSMI_PRIVATE_KMT)RTMemAllocZ(sizeof (*pHgsmiGL));
176 if (pHgsmiGL)
177 {
178#if 0
179 HRESULT hr = vboxUhgsmiKmtCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
180#else
181 HRESULT hr = vboxUhgsmiKmtEscCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
182#endif
183 Log(("CrHgsmi: faled to create KmtEsc UHGSMI instance, hr (0x%x)\n", hr));
184 if (hr == S_OK)
185 {
186 return &pHgsmiGL->BasePrivate.Base;
187 }
188 RTMemFree(pHgsmiGL);
189 }
190
191 return NULL;
192}
193
194VBOXCRHGSMI_DECL(void) VBoxCrHgsmiDestroy(PVBOXUHGSMI pHgsmi)
195{
196 PVBOXUHGSMI_PRIVATE_KMT pHgsmiGL = VBOXUHGSMIKMT_GET(pHgsmi);
197 HRESULT hr = vboxUhgsmiKmtDestroy(pHgsmiGL);
198 Assert(hr == S_OK);
199 if (hr == S_OK)
200 {
201 RTMemFree(pHgsmiGL);
202 }
203}
204#endif
205
206VBOXCRHGSMI_DECL(int) VBoxCrHgsmiTerm()
207{
208#if 0
209 PVBOXUHGSMI_PRIVATE_KMT pHgsmiGL = gt_pHgsmiGL;
210 if (pHgsmiGL)
211 {
212 g_VBoxCrHgsmiCallbacks.pfnClientDestroy(pHgsmiGL->BasePrivate.hClient);
213 vboxUhgsmiKmtDestroy(pHgsmiGL);
214 gt_pHgsmiGL = NULL;
215 }
216
217 if (g_pfnVBoxDispCrHgsmiTerm)
218 g_pfnVBoxDispCrHgsmiTerm();
219#endif
220 if (g_bVBoxKmtCallbacksInited > 0)
221 {
222 vboxDispKmtCallbacksTerm(&g_VBoxCrHgsmiKmtCallbacks);
223 }
224 return VINF_SUCCESS;
225}
226
227VBOXCRHGSMI_DECL(void) VBoxCrHgsmiLog(char * szString)
228{
229 VBOXDISPKMT_ADAPTER Adapter;
230 HRESULT hr = vboxDispKmtOpenAdapter(&g_VBoxCrHgsmiKmtCallbacks, &Adapter);
231 Assert(hr == S_OK);
232 if (hr == S_OK)
233 {
234 uint32_t cbString = (uint32_t)strlen(szString) + 1;
235 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
236 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
237 Assert(pCmd);
238 if (pCmd)
239 {
240 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
241 memcpy(pCmd->aStringBuf, szString, cbString);
242
243 D3DKMT_ESCAPE EscapeData = {0};
244 EscapeData.hAdapter = Adapter.hAdapter;
245 //EscapeData.hDevice = NULL;
246 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
247 // EscapeData.Flags.HardwareAccess = 1;
248 EscapeData.pPrivateDriverData = pCmd;
249 EscapeData.PrivateDriverDataSize = cbCmd;
250 //EscapeData.hContext = NULL;
251
252 int Status = g_VBoxCrHgsmiKmtCallbacks.pfnD3DKMTEscape(&EscapeData);
253 Assert(!Status);
254
255 RTMemFree(pCmd);
256 }
257 hr = vboxDispKmtCloseAdapter(&Adapter);
258 Assert(hr == S_OK);
259 }
260}
261
262///* to be used by injection thread and by ogl ICD driver for hgsmi initialization*/
263//VBOXCRHGSMI_DECL(int) VBoxCrHgsmiCustomCreate(PVBOXUHGSMI *ppHgsmi)
264//{
265// PVBOXUHGSMI_PRIVATE_KMT pHgsmi = RTMemAllocZ(sizeof (*pHgsmi));
266// if (pHgsmi)
267// {
268// HRESULT hr = vboxUhgsmiKmtCreate(pHgsmi, FALSE);
269// Assert(hr == S_OK);
270// if (hr == S_OK)
271// {
272// *ppHgsmi = &pHgsmi->BasePrivate.Base;
273// return VINF_SUCCESS;
274// }
275// RTMemFree(pHgsmi);
276// return VERR_GENERAL_FAILURE;
277// }
278// return VERR_NO_MEMORY;
279//}
280//
281//VBOXCRHGSMI_DECL(int) VBoxCrHgsmiCustomDestroy(PVBOXUHGSMI pHgsmi)
282//{
283// PVBOXUHGSMI_PRIVATE_KMT pHgsmiKmt = VBOXUHGSMIKMT_GET(pHgsmi);
284// HRESULT hr = vboxUhgsmiKmtDestroy(pHgsmiKmt, FALSE);
285// Assert(hr == S_OK);
286// if (hr == S_OK)
287// {
288// RTMemFree(pHgsmiKmt);
289// return VINF_SUCCESS;
290// }
291// return VERR_GENERAL_FAILURE;
292//}
293
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