VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h@ 41379

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

wddm: fix smp racing

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 KB
Line 
1/* $Id: VBoxMPVdma.h 40785 2012-04-06 05:42:14Z vboxsync $ */
2
3/** @file
4 * VBox WDDM Miniport driver
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 ___VBoxMPVdma_h___
20#define ___VBoxMPVdma_h___
21
22#include <iprt/cdefs.h>
23#include <iprt/asm.h>
24#include <VBox/VBoxVideo.h>
25#include <VBox/HGSMI/HGSMI.h>
26
27typedef struct _VBOXMP_DEVEXT *PVBOXMP_DEVEXT;
28
29/* ddi dma command queue handling */
30typedef enum
31{
32 VBOXVDMADDI_STATE_UNCKNOWN = 0,
33 VBOXVDMADDI_STATE_NOT_DX_CMD,
34 VBOXVDMADDI_STATE_NOT_QUEUED,
35 VBOXVDMADDI_STATE_PENDING,
36 VBOXVDMADDI_STATE_SUBMITTED,
37 VBOXVDMADDI_STATE_COMPLETED
38} VBOXVDMADDI_STATE;
39
40typedef struct VBOXVDMADDI_CMD *PVBOXVDMADDI_CMD;
41typedef DECLCALLBACK(VOID) FNVBOXVDMADDICMDCOMPLETE_DPC(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext);
42typedef FNVBOXVDMADDICMDCOMPLETE_DPC *PFNVBOXVDMADDICMDCOMPLETE_DPC;
43
44typedef struct VBOXVDMADDI_CMD
45{
46 LIST_ENTRY QueueEntry;
47 VBOXVDMADDI_STATE enmState;
48 uint32_t u32NodeOrdinal;
49 uint32_t u32FenceId;
50 DXGK_INTERRUPT_TYPE enmComplType;
51 PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete;
52 PVOID pvComplete;
53} VBOXVDMADDI_CMD, *PVBOXVDMADDI_CMD;
54
55typedef struct VBOXVDMADDI_CMD_QUEUE
56{
57 volatile uint32_t cQueuedCmds;
58 LIST_ENTRY CmdQueue;
59} VBOXVDMADDI_CMD_QUEUE, *PVBOXVDMADDI_CMD_QUEUE;
60
61typedef struct VBOXVDMADDI_NODE
62{
63 VBOXVDMADDI_CMD_QUEUE CmdQueue;
64 UINT uLastCompletedFenceId;
65} VBOXVDMADDI_NODE, *PVBOXVDMADDI_NODE;
66
67VOID vboxVdmaDdiNodesInit(PVBOXMP_DEVEXT pDevExt);
68BOOLEAN vboxVdmaDdiCmdCompletedIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType);
69VOID vboxVdmaDdiCmdSubmittedIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd);
70
71NTSTATUS vboxVdmaDdiCmdCompleted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType);
72NTSTATUS vboxVdmaDdiCmdSubmitted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd);
73
74DECLINLINE(VOID) vboxVdmaDdiCmdInit(PVBOXVDMADDI_CMD pCmd,
75 uint32_t u32NodeOrdinal, uint32_t u32FenceId,
76 PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete, PVOID pvComplete)
77{
78 pCmd->QueueEntry.Blink = NULL;
79 pCmd->QueueEntry.Flink = NULL;
80 pCmd->enmState = VBOXVDMADDI_STATE_NOT_QUEUED;
81 pCmd->u32NodeOrdinal = u32NodeOrdinal;
82 pCmd->u32FenceId = u32FenceId;
83 pCmd->pfnComplete = pfnComplete;
84 pCmd->pvComplete = pvComplete;
85}
86
87/* marks the command a submitted in a way that it is invisible for dx runtime,
88 * i.e. the dx runtime won't be notified about the command completion
89 * this is used to submit commands initiated by the driver, but not by the dx runtime */
90DECLINLINE(VOID) vboxVdmaDdiCmdSubmittedNotDx(PVBOXVDMADDI_CMD pCmd)
91{
92 Assert(pCmd->enmState == VBOXVDMADDI_STATE_NOT_QUEUED);
93 pCmd->enmState = VBOXVDMADDI_STATE_NOT_DX_CMD;
94}
95
96NTSTATUS vboxVdmaDdiCmdFenceComplete(PVBOXMP_DEVEXT pDevExt, uint32_t u32NodeOrdinal, uint32_t u32FenceId, DXGK_INTERRUPT_TYPE enmComplType);
97
98DECLCALLBACK(VOID) vboxVdmaDdiCmdCompletionCbFree(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext);
99
100VOID vboxVdmaDdiCmdGetCompletedListIsr(PVBOXMP_DEVEXT pDevExt, LIST_ENTRY *pList);
101
102BOOLEAN vboxVdmaDdiCmdIsCompletedListEmptyIsr(PVBOXMP_DEVEXT pDevExt);
103
104#define VBOXVDMADDI_CMD_FROM_ENTRY(_pEntry) ((PVBOXVDMADDI_CMD)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(VBOXVDMADDI_CMD, QueueEntry)))
105
106DECLINLINE(VOID) vboxVdmaDdiCmdHandleCompletedList(PVBOXMP_DEVEXT pDevExt, LIST_ENTRY *pList)
107{
108 LIST_ENTRY *pEntry = pList->Flink;
109 while (pEntry != pList)
110 {
111 PVBOXVDMADDI_CMD pCmd = VBOXVDMADDI_CMD_FROM_ENTRY(pEntry);
112 pEntry = pEntry->Flink;
113 if (pCmd->pfnComplete)
114 pCmd->pfnComplete(pDevExt, pCmd, pCmd->pvComplete);
115 }
116}
117
118#ifdef VBOXWDDM_RENDER_FROM_SHADOW
119NTSTATUS vboxVdmaHlpUpdatePrimary(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, RECT* pRect);
120#endif
121
122#if 0
123typedef DECLCALLBACK(int) FNVBOXVDMASUBMIT(struct _DEVICE_EXTENSION* pDevExt, struct VBOXVDMAINFO * pInfo, HGSMIOFFSET offDr, PVOID pvContext);
124typedef FNVBOXVDMASUBMIT *PFNVBOXVDMASUBMIT;
125
126typedef struct VBOXVDMASUBMIT
127{
128 PFNVBOXVDMASUBMIT pfnSubmit;
129 PVOID pvContext;
130} VBOXVDMASUBMIT, *PVBOXVDMASUBMIT;
131#endif
132
133/* start */
134typedef enum
135{
136 VBOXVDMAPIPE_STATE_CLOSED = 0,
137 VBOXVDMAPIPE_STATE_CREATED = 1,
138 VBOXVDMAPIPE_STATE_OPENNED = 2,
139 VBOXVDMAPIPE_STATE_CLOSING = 3
140} VBOXVDMAPIPE_STATE;
141
142typedef struct VBOXVDMAPIPE
143{
144 KSPIN_LOCK SinchLock;
145 KEVENT Event;
146 LIST_ENTRY CmdListHead;
147 VBOXVDMAPIPE_STATE enmState;
148 /* true iff the other end needs Event notification */
149 bool bNeedNotify;
150} VBOXVDMAPIPE, *PVBOXVDMAPIPE;
151
152typedef struct VBOXVDMAPIPE_CMD_HDR
153{
154 LIST_ENTRY ListEntry;
155} VBOXVDMAPIPE_CMD_HDR, *PVBOXVDMAPIPE_CMD_HDR;
156
157#define VBOXVDMAPIPE_CMD_HDR_FROM_ENTRY(_pE) ( (PVBOXVDMAPIPE_CMD_HDR)((uint8_t *)(_pE) - RT_OFFSETOF(VBOXVDMAPIPE_CMD_HDR, ListEntry)) )
158
159typedef enum
160{
161 VBOXVDMAPIPE_CMD_TYPE_UNDEFINED = 0,
162 VBOXVDMAPIPE_CMD_TYPE_RECTSINFO,
163 VBOXVDMAPIPE_CMD_TYPE_DMACMD,
164 VBOXVDMAPIPE_CMD_TYPE_FINISH, /* ensures all previously submitted commands are completed */
165 VBOXVDMAPIPE_CMD_TYPE_CANCEL
166} VBOXVDMAPIPE_CMD_TYPE;
167
168typedef struct VBOXVDMAPIPE_CMD_DR
169{
170 VBOXVDMAPIPE_CMD_HDR PipeHdr;
171 VBOXVDMAPIPE_CMD_TYPE enmType;
172 volatile uint32_t cRefs;
173} VBOXVDMAPIPE_CMD_DR, *PVBOXVDMAPIPE_CMD_DR;
174
175#define VBOXVDMAPIPE_CMD_DR_FROM_ENTRY(_pE) ( (PVBOXVDMAPIPE_CMD_DR)VBOXVDMAPIPE_CMD_HDR_FROM_ENTRY(_pE) )
176
177typedef struct VBOXWDDM_DMA_ALLOCINFO
178{
179 PVBOXWDDM_ALLOCATION pAlloc;
180 VBOXVIDEOOFFSET offAlloc;
181 UINT segmentIdAlloc : 31;
182 UINT fWriteOp : 1;
183 D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId;
184} VBOXWDDM_DMA_ALLOCINFO, *PVBOXWDDM_DMA_ALLOCINFO;
185
186typedef struct VBOXVDMAPIPE_RECTS
187{
188 RECT ContextRect;
189 VBOXWDDM_RECTS_INFO UpdateRects;
190} VBOXVDMAPIPE_RECTS, *PVBOXVDMAPIPE_RECTS;
191
192typedef struct VBOXVDMAPIPE_CMD_RECTSINFO
193{
194 VBOXVDMAPIPE_CMD_DR Hdr;
195 PVBOXWDDM_CONTEXT pContext;
196 struct VBOXWDDM_SWAPCHAIN *pSwapchain;
197 VBOXVDMAPIPE_RECTS ContextsRects;
198} VBOXVDMAPIPE_CMD_RECTSINFO, *PVBOXVDMAPIPE_CMD_RECTSINFO;
199
200typedef struct VBOXVDMAPIPE_CMD_FINISH
201{
202 VBOXVDMAPIPE_CMD_DR Hdr;
203 PVBOXWDDM_CONTEXT pContext;
204 PKEVENT pEvent;
205} VBOXVDMAPIPE_CMD_FINISH, *PVBOXVDMAPIPE_CMD_FINISH;
206
207typedef struct VBOXVDMAPIPE_CMD_CANCEL
208{
209 VBOXVDMAPIPE_CMD_DR Hdr;
210 PVBOXWDDM_CONTEXT pContext;
211 PVBOXWDDM_SWAPCHAIN pSwapchain;
212 PKEVENT pEvent;
213} VBOXVDMAPIPE_CMD_CANCEL, *PVBOXVDMAPIPE_CMD_CANCEL;
214
215typedef struct VBOXVDMAPIPE_FLAGS_DMACMD
216{
217 union
218 {
219 struct
220 {
221 UINT fRealOp : 1;
222 UINT fVisibleRegions : 1;
223 UINT Reserve : 30;
224 };
225 UINT Value;
226 };
227} VBOXVDMAPIPE_FLAGS_DMACMD, *PVBOXVDMAPIPE_FLAGS_DMACMD;
228typedef struct VBOXVDMAPIPE_CMD_DMACMD
229{
230 VBOXVDMAPIPE_CMD_DR Hdr;
231#ifndef VBOX_WDDM_IRQ_COMPLETION
232 VBOXVDMADDI_CMD DdiCmd;
233#endif
234 PVBOXWDDM_CONTEXT pContext;
235 VBOXVDMACMD_TYPE enmCmd;
236 VBOXVDMAPIPE_FLAGS_DMACMD fFlags;
237} VBOXVDMAPIPE_CMD_DMACMD, *PVBOXVDMAPIPE_CMD_DMACMD;
238
239typedef struct VBOXVDMA_CLRFILL
240{
241 VBOXWDDM_DMA_ALLOCINFO Alloc;
242 UINT Color;
243 VBOXWDDM_RECTS_INFO Rects;
244} VBOXVDMA_CLRFILL, *PVBOXVDMA_CLRFILL;
245
246typedef struct VBOXVDMAPIPE_CMD_DMACMD_CLRFILL
247{
248 VBOXVDMAPIPE_CMD_DMACMD Hdr;
249 VBOXVDMA_CLRFILL ClrFill;
250} VBOXVDMAPIPE_CMD_DMACMD_CLRFILL, *PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL;
251
252typedef struct VBOXVDMA_BLT
253{
254 VBOXWDDM_DMA_ALLOCINFO SrcAlloc;
255 VBOXWDDM_DMA_ALLOCINFO DstAlloc;
256 RECT SrcRect;
257 VBOXVDMAPIPE_RECTS DstRects;
258} VBOXVDMA_BLT, *PVBOXVDMA_BLT;
259
260typedef struct VBOXVDMAPIPE_CMD_DMACMD_BLT
261{
262 VBOXVDMAPIPE_CMD_DMACMD Hdr;
263 VBOXVDMA_BLT Blt;
264} VBOXVDMAPIPE_CMD_DMACMD_BLT, *PVBOXVDMAPIPE_CMD_DMACMD_BLT;
265
266typedef struct VBOXVDMA_FLIP
267{
268 VBOXWDDM_DMA_ALLOCINFO Alloc;
269} VBOXVDMA_FLIP, *PVBOXVDMA_FLIP;
270
271typedef struct VBOXVDMAPIPE_CMD_DMACMD_FLIP
272{
273 VBOXVDMAPIPE_CMD_DMACMD Hdr;
274 VBOXVDMA_FLIP Flip;
275} VBOXVDMAPIPE_CMD_DMACMD_FLIP, *PVBOXVDMAPIPE_CMD_DMACMD_FLIP;
276
277typedef struct VBOXVDMA_SHADOW2PRIMARY
278{
279 VBOXWDDM_DMA_ALLOCINFO ShadowAlloc;
280 RECT SrcRect;
281 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId;
282} VBOXVDMA_SHADOW2PRIMARY, *PVBOXVDMA_SHADOW2PRIMARY;
283
284typedef struct VBOXVDMAGG
285{
286 VBOXVDMAPIPE CmdPipe;
287 PKTHREAD pThread;
288} VBOXVDMAGG, *PVBOXVDMAGG;
289
290/* DMA commands are currently submitted over HGSMI */
291typedef struct VBOXVDMAINFO
292{
293#ifdef VBOX_WITH_VDMA
294 VBOXSHGSMI CmdHeap;
295#endif
296 UINT uLastCompletedPagingBufferCmdFenceId;
297 BOOL fEnabled;
298 /* dma-related commands list processed on the guest w/o host part involvement (guest-guest commands) */
299 VBOXVDMAGG DmaGg;
300} VBOXVDMAINFO, *PVBOXVDMAINFO;
301
302int vboxVdmaCreate (PVBOXMP_DEVEXT pDevExt, VBOXVDMAINFO *pInfo
303#ifdef VBOX_WITH_VDMA
304 , ULONG offBuffer, ULONG cbBuffer
305#endif
306#if 0
307 , PFNVBOXVDMASUBMIT pfnSubmit, PVOID pvContext
308#endif
309 );
310int vboxVdmaDisable(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo);
311int vboxVdmaEnable(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo);
312int vboxVdmaDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo);
313
314#ifdef VBOX_WITH_VDMA
315int vboxVdmaFlush(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo);
316int vboxVdmaCBufDrSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr);
317int vboxVdmaCBufDrSubmitSynch(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr);
318struct VBOXVDMACBUF_DR* vboxVdmaCBufDrCreate(PVBOXVDMAINFO pInfo, uint32_t cbTrailingData);
319void vboxVdmaCBufDrFree(PVBOXVDMAINFO pInfo, struct VBOXVDMACBUF_DR* pDr);
320
321#define VBOXVDMACBUF_DR_DATA_OFFSET() (sizeof (VBOXVDMACBUF_DR))
322#define VBOXVDMACBUF_DR_SIZE(_cbData) (VBOXVDMACBUF_DR_DATA_OFFSET() + (_cbData))
323#define VBOXVDMACBUF_DR_DATA(_pDr) ( ((uint8_t*)(_pDr)) + VBOXVDMACBUF_DR_DATA_OFFSET() )
324
325AssertCompile(sizeof (VBOXVDMADDI_CMD) <= RT_SIZEOFMEMB(VBOXVDMACBUF_DR, aGuestData));
326#define VBOXVDMADDI_CMD_FROM_BUF_DR(_pDr) ((PVBOXVDMADDI_CMD)(_pDr)->aGuestData)
327#define VBOXVDMACBUF_DR_FROM_DDI_CMD(_pCmd) ((PVBOXVDMACBUF_DR)(((uint_8*)(_pCmd)) - RT_OFFSETOF(VBOXVDMACBUF_DR, aGuestData)))
328
329#endif
330NTSTATUS vboxVdmaGgCmdSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pCmd);
331PVBOXVDMAPIPE_CMD_DR vboxVdmaGgCmdCreate(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_TYPE enmType, uint32_t cbCmd);
332DECLINLINE(void) vboxVdmaGgCmdAddRef(PVBOXVDMAPIPE_CMD_DR pDr)
333{
334 ASMAtomicIncU32(&pDr->cRefs);
335}
336void vboxVdmaGgCmdDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pDr);
337DECLINLINE(void) vboxVdmaGgCmdRelease(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pDr)
338{
339 uint32_t cRefs = ASMAtomicDecU32(&pDr->cRefs);
340 Assert(cRefs < UINT32_MAX/2);
341 if (!cRefs)
342 vboxVdmaGgCmdDestroy(pDevExt, pDr);
343}
344NTSTATUS vboxVdmaGgCmdFinish(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_CONTEXT *pContext, PKEVENT pEvent);
345NTSTATUS vboxVdmaGgCmdCancel(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, PVBOXWDDM_SWAPCHAIN pSwapchain);
346
347NTSTATUS vboxVdmaPostHideSwapchain(PVBOXWDDM_SWAPCHAIN pSwapchain);
348
349NTSTATUS vboxVdmaGgCmdDmaNotifyCompleted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD pCmd, DXGK_INTERRUPT_TYPE enmComplType);
350NTSTATUS vboxVdmaGgCmdDmaNotifySubmitted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD pCmd);
351VOID vboxVdmaGgCmdDmaNotifyInit(PVBOXVDMAPIPE_CMD_DMACMD pCmd,
352 uint32_t u32NodeOrdinal, uint32_t u32FenceId,
353 PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete, PVOID pvComplete);
354
355NTSTATUS vboxVdmaGgDmaBltPerform(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pSrcAlloc, RECT* pSrcRect,
356 PVBOXWDDM_ALLOCATION pDstAlloc, RECT* pDstRect);
357
358#define VBOXVDMAPIPE_CMD_DR_FROM_DDI_CMD(_pCmd) ((PVBOXVDMAPIPE_CMD_DR)(((uint8_t*)(_pCmd)) - RT_OFFSETOF(VBOXVDMAPIPE_CMD_DR, DdiCmd)))
359DECLCALLBACK(VOID) vboxVdmaGgDdiCmdRelease(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext);
360#endif /* #ifndef ___VBoxMPVdma_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