VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.cpp@ 27429

Last change on this file since 27429 was 27383, checked in by vboxsync, 15 years ago

wddm: basic Video DMA impl, guest driver bugfix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 KB
Line 
1/*
2 * Copyright (C) 2010 Sun Microsystems, Inc.
3 *
4 * This file is part of VirtualBox Open Source Edition (OSE), as
5 * available from http://www.virtualbox.org. This file is free software;
6 * you can redistribute it and/or modify it under the terms of the GNU
7 * General Public License (GPL) as published by the Free Software
8 * Foundation, in version 2 as it comes in the "COPYING" file of the
9 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
10 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
11 *
12 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
13 * Clara, CA 95054 USA or visit http://www.sun.com if you need
14 * additional information or have any questions.
15 */
16
17#include "../VBoxVideo.h"
18#include "../Helper.h"
19
20#include <VBox/VBoxGuestLib.h>
21#include <VBox/VBoxVideo.h>
22#include "VBoxVideoVdma.h"
23#include "../VBoxVideo.h"
24
25/*
26 * This is currently used by VDMA. It is invisible for Vdma API clients since
27 * Vdma transport may change if we choose to use another (e.g. more light-weight)
28 * transport for DMA commands submission
29 */
30
31
32static int vboxVdmaInformHost (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo, VBOXVDMA_CTL_TYPE enmCtl)
33{
34 int rc = VINF_SUCCESS;
35
36 PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMICommandAlloc (&pDevExt->u.primary.hgsmiAdapterHeap, sizeof (VBOXVDMA_CTL), HGSMI_CH_VBVA, VBVA_VDMA_CTL);
37 if (pCmd)
38 {
39 pCmd->enmCtl = enmCtl;
40 pCmd->u32Offset = pInfo->CmdHeap.area.offBase;
41 pCmd->i32Result = VERR_NOT_SUPPORTED;
42
43 VBoxSHGSMICommandSubmitSynch (&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
44
45 rc = pCmd->i32Result;
46 AssertRC(rc);
47
48 VBoxSHGSMICommandFree (&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
49 }
50 else
51 {
52 drprintf((__FUNCTION__": HGSMIHeapAlloc failed\n"));
53 rc = VERR_OUT_OF_RESOURCES;
54 }
55
56 return rc;
57}
58
59/* create a DMACommand buffer */
60int vboxVdmaCreate (PDEVICE_EXTENSION pDevExt, VBOXVDMAINFO *pInfo, ULONG offBuffer, ULONG cbBuffer)
61{
62 Assert((offBuffer & 0xfff) == 0);
63 Assert((cbBuffer & 0xfff) == 0);
64 Assert(offBuffer);
65 Assert(cbBuffer);
66
67 if((offBuffer & 0xfff)
68 || (cbBuffer & 0xfff)
69 || !offBuffer
70 || !cbBuffer)
71 {
72 drprintf((__FUNCTION__": invalid parameters: offBuffer(0x%x), cbBuffer(0x%x)", offBuffer, cbBuffer));
73 return VERR_INVALID_PARAMETER;
74 }
75
76 pInfo->fEnabled = FALSE;
77 PVOID pvBuffer;
78
79 int rc = VBoxMapAdapterMemory (pDevExt,
80 &pvBuffer,
81 offBuffer,
82 cbBuffer);
83 Assert(RT_SUCCESS(rc));
84 if (RT_SUCCESS(rc))
85 {
86 /* Setup a HGSMI heap within the adapter information area. */
87 rc = HGSMIHeapSetup (&pInfo->CmdHeap,
88 pvBuffer,
89 cbBuffer,
90 offBuffer,
91 false /*fOffsetBased*/);
92 Assert(RT_SUCCESS(rc));
93 if(RT_SUCCESS(rc))
94 return rc;
95 else
96 drprintf((__FUNCTION__": HGSMIHeapSetup failed rc = 0x%x\n", rc));
97
98 VBoxUnmapAdapterMemory(pDevExt, &pvBuffer, cbBuffer);
99 }
100 else
101 drprintf((__FUNCTION__": VBoxMapAdapterMemory failed rc = 0x%x\n", rc));
102
103 return rc;
104}
105
106int vboxVdmaDisable (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
107{
108 dfprintf((__FUNCTION__"\n"));
109
110 Assert(pInfo->fEnabled);
111 if (!pInfo->fEnabled)
112 return VINF_ALREADY_INITIALIZED;
113
114 /* ensure nothing else is submitted */
115 pInfo->fEnabled = FALSE;
116
117 int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_TYPE_DISABLE);
118 AssertRC(rc);
119 return rc;
120}
121
122int vboxVdmaEnable (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
123{
124 dfprintf((__FUNCTION__"\n"));
125
126 Assert(!pInfo->fEnabled);
127 if (pInfo->fEnabled)
128 return VINF_ALREADY_INITIALIZED;
129
130 int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_TYPE_ENABLE);
131 Assert(RT_SUCCESS(rc));
132 if (RT_SUCCESS(rc))
133 pInfo->fEnabled = TRUE;
134
135 return rc;
136}
137
138int vboxVdmaFlush (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
139{
140 dfprintf((__FUNCTION__"\n"));
141
142 Assert(pInfo->fEnabled);
143 if (!pInfo->fEnabled)
144 return VINF_ALREADY_INITIALIZED;
145
146 int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_TYPE_FLUSH);
147 Assert(RT_SUCCESS(rc));
148
149 return rc;
150}
151
152int vboxVdmaDestroy (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
153{
154 int rc = VINF_SUCCESS;
155 Assert(!pInfo->fEnabled);
156 if (pInfo->fEnabled)
157 rc = vboxVdmaDisable (pDevExt, pInfo);
158 VBoxUnmapAdapterMemory (pDevExt, (void**)&pInfo->CmdHeap.area.pu8Base, pInfo->CmdHeap.area.cbArea);
159 return rc;
160}
161
162void vboxVdmaCBufDrFree (PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr)
163{
164 VBoxSHGSMICommandFree (&pInfo->CmdHeap, pDr);
165}
166
167PVBOXVDMACBUF_DR vboxVdmaCBufDrCreate (PVBOXVDMAINFO pInfo, uint32_t cbTrailingData)
168{
169 uint32_t cbDr = sizeof (VBOXVDMACBUF_DR) + cbTrailingData;
170 PVBOXVDMACBUF_DR pDr = (PVBOXVDMACBUF_DR)VBoxSHGSMICommandAlloc (&pInfo->CmdHeap, cbDr, HGSMI_CH_VBVA, VBVA_VDMA_CMD);
171 Assert(pDr);
172 if (pDr)
173 memset (pDr, 0, cbDr);
174 else
175 drprintf((__FUNCTION__": VBoxSHGSMICommandAlloc returned NULL\n"));
176
177 return pDr;
178}
179
180static DECLCALLBACK(void) vboxVdmaCBufDrCompletion(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext)
181{
182 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pvContext;
183 PVBOXVDMAINFO pInfo = &pDevExt->u.primary.Vdma;
184
185 vboxVdmaCBufDrFree (pInfo, (PVBOXVDMACBUF_DR)pvCmd);
186}
187
188static DECLCALLBACK(void) vboxVdmaCBufDrCompletionIrq(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext,
189 PFNVBOXSHGSMICMDCOMPLETION *ppfnCompletion, void **ppvCompletion)
190{
191 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pvContext;
192 PVBOXVDMAINFO pVdma = &pDevExt->u.primary.Vdma;
193 DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
194 PVBOXVDMACBUF_DR pDr = (PVBOXVDMACBUF_DR)pvCmd;
195
196 memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
197
198 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pDr->u64GuestContext;
199
200 if (RT_SUCCESS(pDr->rc))
201 {
202 notify.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED;
203 notify.DmaCompleted.SubmissionFenceId = pDr->u32FenceId;
204 if (pContext)
205 {
206 notify.DmaCompleted.NodeOrdinal = pContext->NodeOrdinal;
207 notify.DmaCompleted.EngineOrdinal = 0;
208 pContext->uLastCompletedCmdFenceId = pDr->u32FenceId;
209 }
210 else
211 pVdma->uLastCompletedPagingBufferCmdFenceId = pDr->u32FenceId;
212 pDevExt->bSetNotifyDxDpc = TRUE;
213 }
214 else if (pDr->rc == VERR_INTERRUPTED)
215 {
216 notify.InterruptType = DXGK_INTERRUPT_DMA_PREEMPTED;
217 notify.DmaPreempted.PreemptionFenceId = pDr->u32FenceId;
218 if (pContext)
219 {
220 notify.DmaPreempted.LastCompletedFenceId = pContext->uLastCompletedCmdFenceId;
221 notify.DmaPreempted.NodeOrdinal = pContext->NodeOrdinal;
222 notify.DmaPreempted.EngineOrdinal = 0;
223 }
224 else
225 notify.DmaPreempted.LastCompletedFenceId = pVdma->uLastCompletedPagingBufferCmdFenceId;
226
227 pDevExt->bSetNotifyDxDpc = TRUE;
228 }
229 else
230 {
231 AssertBreakpoint();
232 notify.InterruptType = DXGK_INTERRUPT_DMA_FAULTED;
233 notify.DmaFaulted.FaultedFenceId = pDr->u32FenceId;
234 notify.DmaFaulted.Status = STATUS_UNSUCCESSFUL; /* @todo: better status ? */
235 if (pContext)
236 {
237 notify.DmaFaulted.NodeOrdinal = pContext->NodeOrdinal;
238 notify.DmaFaulted.EngineOrdinal = 0;
239 }
240 pDevExt->bSetNotifyDxDpc = TRUE;
241 }
242
243 pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
244
245 /* inform SHGSMI we want to be called at DPC later */
246 *ppfnCompletion = vboxVdmaCBufDrCompletion;
247 *ppvCompletion = pvContext;
248}
249
250void vboxVdmaCBufDrSubmit (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr)
251{
252 VBoxSHGSMICommandSubmitAsynchIrq (&pInfo->CmdHeap, pDr, vboxVdmaCBufDrCompletionIrq, pDevExt, VBOXSHGSMI_FLAG_GH_ASYNCH_FORCE);
253}
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