VirtualBox

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

Last change on this file since 52226 was 52226, checked in by vboxsync, 10 years ago

wddm: preemption fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.8 KB
Line 
1/* $Id: VBoxMPVbva.h 52226 2014-07-29 12:53:58Z 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 ___VBoxMPVbva_h___
20#define ___VBoxMPVbva_h___
21
22typedef struct VBOXVBVAINFO
23{
24 VBVABUFFERCONTEXT Vbva;
25 D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId;
26 KSPIN_LOCK Lock;
27} VBOXVBVAINFO;
28
29int vboxVbvaEnable(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
30int vboxVbvaDisable(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
31int vboxVbvaDestroy(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
32int vboxVbvaCreate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, ULONG offBuffer, ULONG cbBuffer, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId);
33int vboxVbvaReportDirtyRect(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_SOURCE *pSrc, RECT *pRectOrig);
34
35#define VBOXVBVA_OP(_op, _pdext, _psrc, _arg) \
36 do { \
37 if (VBoxVBVABufferBeginUpdate(&(_psrc)->Vbva.Vbva, &VBoxCommonFromDeviceExt(_pdext)->guestCtx)) \
38 { \
39 vboxVbva##_op(_pdext, _psrc, _arg); \
40 VBoxVBVABufferEndUpdate(&(_psrc)->Vbva.Vbva); \
41 } \
42 } while (0)
43
44#define VBOXVBVA_OP_WITHLOCK_ATDPC(_op, _pdext, _psrc, _arg) \
45 do { \
46 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL); \
47 KeAcquireSpinLockAtDpcLevel(&(_psrc)->Vbva.Lock); \
48 VBOXVBVA_OP(_op, _pdext, _psrc, _arg); \
49 KeReleaseSpinLockFromDpcLevel(&(_psrc)->Vbva.Lock);\
50 } while (0)
51
52#define VBOXVBVA_OP_WITHLOCK(_op, _pdext, _psrc, _arg) \
53 do { \
54 KIRQL OldIrql; \
55 KeAcquireSpinLock(&(_psrc)->Vbva.Lock, &OldIrql); \
56 VBOXVBVA_OP(_op, _pdext, _psrc, _arg); \
57 KeReleaseSpinLock(&(_psrc)->Vbva.Lock, OldIrql); \
58 } while (0)
59
60
61#ifdef VBOX_WITH_CROGL
62/* customized VBVA implementation */
63struct VBVAEXBUFFERCONTEXT;
64
65typedef DECLCALLBACKPTR(void, PFNVBVAEXBUFFERFLUSH) (struct VBVAEXBUFFERCONTEXT *pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, void *pvFlush);
66
67/**
68 * Structure grouping the context needed for sending graphics acceleration
69 * information to the host via VBVA. Each screen has its own VBVA buffer.
70 */
71typedef struct VBVAEXBUFFERCONTEXT
72{
73 /** Offset of the buffer in the VRAM section for the screen */
74 uint32_t offVRAMBuffer;
75 /** Length of the buffer in bytes */
76 uint32_t cbBuffer;
77 /** This flag is set if we wrote to the buffer faster than the host could
78 * read it. */
79 bool fHwBufferOverflow;
80 /* the window between indexRecordFirstUncompleted and pVBVA->::indexRecordFirst represents
81 * command records processed by the host, but not completed by the guest yet */
82 volatile uint32_t indexRecordFirstUncompleted;
83 /* the window between off32DataUncompleted and pVBVA->::off32Data represents
84 * command data processed by the host, but not completed by the guest yet */
85 uint32_t off32DataUncompleted;
86 /* flush function */
87 PFNVBVAEXBUFFERFLUSH pfnFlush;
88 void *pvFlush;
89 /** The VBVA record that we are currently preparing for the host, NULL if
90 * none. */
91 struct VBVARECORD *pRecord;
92 /** Pointer to the VBVA buffer mapped into the current address space. Will
93 * be NULL if VBVA is not enabled. */
94 struct VBVABUFFER *pVBVA;
95} VBVAEXBUFFERCONTEXT, *PVBVAEXBUFFERCONTEXT;
96
97typedef struct VBVAEXBUFFERITERBASE
98{
99 struct VBVAEXBUFFERCONTEXT *pCtx;
100 /* index of the current record */
101 uint32_t iCurRecord;
102 /* offset of the current command */
103 uint32_t off32CurCmd;
104} VBVAEXBUFFERITERBASE, *PVBVAEXBUFFERITERBASE;
105
106typedef struct VBVAEXBUFFERFORWARDITER
107{
108 VBVAEXBUFFERITERBASE Base;
109} VBVAEXBUFFERFORWARDITER, *PVBVAEXBUFFERFORWARDITER;
110
111typedef struct VBVAEXBUFFERBACKWARDITER
112{
113 VBVAEXBUFFERITERBASE Base;
114} VBVAEXBUFFERBACKWARDITER, *PVBVAEXBUFFERBACKWARDITER;
115
116#define VBOXCMDVBVA_BUFFERSIZE(_cbCmdApprox) (RT_OFFSETOF(VBVABUFFER, au8Data) + ((RT_SIZEOFMEMB(VBVABUFFER, aRecords)/RT_SIZEOFMEMB(VBVABUFFER, aRecords[0])) * (_cbCmdApprox)))
117
118typedef struct VBOXCMDVBVA_PREEMPT_EL
119{
120 uint32_t u32SubmitFence;
121 uint32_t u32PreemptFence;
122} VBOXCMDVBVA_PREEMPT_EL;
123
124#define VBOXCMDVBVA_PREEMPT_EL_SIZE 16
125
126typedef struct VBOXCMDVBVA
127{
128 VBVAEXBUFFERCONTEXT Vbva;
129
130 /* last completted fence id */
131 uint32_t u32FenceCompleted;
132 /* last submitted fence id */
133 uint32_t u32FenceSubmitted;
134 /* last processed fence id (i.e. either completed or cancelled) */
135 uint32_t u32FenceProcessed;
136
137 /* node ordinal */
138 uint32_t idNode;
139
140 uint32_t cPreempt;
141 uint32_t iCurPreempt;
142 VBOXCMDVBVA_PREEMPT_EL aPreempt[VBOXCMDVBVA_PREEMPT_EL_SIZE];
143} VBOXCMDVBVA;
144
145/** @name VBVAEx APIs
146 * @{ */
147RTDECL(int) VBoxVBVAExEnable(PVBVAEXBUFFERCONTEXT pCtx,
148 PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
149 struct VBVABUFFER *pVBVA);
150RTDECL(void) VBoxVBVAExDisable(PVBVAEXBUFFERCONTEXT pCtx,
151 PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx);
152RTDECL(bool) VBoxVBVAExBufferBeginUpdate(PVBVAEXBUFFERCONTEXT pCtx,
153 PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx);
154RTDECL(void) VBoxVBVAExBufferEndUpdate(PVBVAEXBUFFERCONTEXT pCtx);
155RTDECL(bool) VBoxVBVAExWrite(PVBVAEXBUFFERCONTEXT pCtx,
156 PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
157 const void *pv, uint32_t cb);
158
159RTDECL(bool) VBoxVBVAExOrderSupported(PVBVAEXBUFFERCONTEXT pCtx, unsigned code);
160
161RTDECL(void) VBoxVBVAExSetupBufferContext(PVBVAEXBUFFERCONTEXT pCtx,
162 uint32_t offVRAMBuffer,
163 uint32_t cbBuffer,
164 PFNVBVAEXBUFFERFLUSH pfnFlush,
165 void *pvFlush);
166
167DECLINLINE(uint32_t) VBoxVBVAExGetSize(PVBVAEXBUFFERCONTEXT pCtx)
168{
169 return pCtx->pVBVA->cbData;
170}
171
172/* can be used to ensure the command will not cross the ring buffer boundary,
173 * and thus will not be splitted */
174RTDECL(uint32_t) VBoxVBVAExGetFreeTail(PVBVAEXBUFFERCONTEXT pCtx);
175/* allocates a contiguous buffer of a given size, i.e. the one that is not splitted across ringbuffer boundaries */
176RTDECL(void*) VBoxVBVAExAllocContiguous(PVBVAEXBUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, uint32_t cb);
177/* answers whether host is in "processing" state now,
178 * i.e. if "processing" is true after the command is submitted, no notification is required to be posted to host to make the commandbe processed,
179 * otherwise, host should be notified about the command */
180RTDECL(bool) VBoxVBVAExIsProcessing(PVBVAEXBUFFERCONTEXT pCtx);
181
182/* initializes iterator that starts with free record,
183 * i.e. VBoxVBVAExIterNext would return the first uncompleted record.
184 *
185 * can be used by submitter only */
186RTDECL(void) VBoxVBVAExBIterInit(PVBVAEXBUFFERCONTEXT pCtx, PVBVAEXBUFFERBACKWARDITER pIter);
187/* can be used by submitter only */
188RTDECL(void*) VBoxVBVAExBIterNext(PVBVAEXBUFFERBACKWARDITER pIter, uint32_t *pcbBuffer, bool *pfProcessed);
189
190/* completer functions
191 * completer can only use below ones, and submitter is NOT allowed to use them.
192 * Completter functions are prefixed with VBoxVBVAExC as opposed to submitter ones,
193 * that do not have the last "C" in the prefix */
194/* initializes iterator that starts with completed record,
195 * i.e. VBoxVBVAExIterPrev would return the first uncompleted record.
196 * note that we can not have iterator that starts at processed record
197 * (i.e. the one processed by host, but not completed by guest, since host modifies
198 * VBVABUFFER::off32Data and VBVABUFFER::indexRecordFirst concurrently,
199 * and so we may end up with inconsistent index-offData pair
200 *
201 * can be used by completter only */
202RTDECL(void) VBoxVBVAExCFIterInit(PVBVAEXBUFFERCONTEXT pCtx, PVBVAEXBUFFERFORWARDITER pIter);
203/* can be used by completter only */
204RTDECL(void*) VBoxVBVAExCFIterNext(PVBVAEXBUFFERFORWARDITER pIter, uint32_t *pcbBuffer, bool *pfProcessed);
205
206RTDECL(void) VBoxVBVAExCBufferCompleted(PVBVAEXBUFFERCONTEXT pCtx);
207
208/** @} */
209
210struct VBOXCMDVBVA_HDR;
211
212int VBoxCmdVbvaEnable(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva);
213int VBoxCmdVbvaDisable(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva);
214int VBoxCmdVbvaDestroy(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva);
215int VBoxCmdVbvaCreate(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, ULONG offBuffer, ULONG cbBuffer);
216int VBoxCmdVbvaSubmit(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, struct VBOXCMDVBVA_HDR *pCmd, uint32_t u32FenceID, uint32_t cbCmd);
217void VBoxCmdVbvaSubmitUnlock(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, VBOXCMDVBVA_HDR* pCmd, uint32_t u32FenceID);
218VBOXCMDVBVA_HDR* VBoxCmdVbvaSubmitLock(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, uint32_t cbCmd);
219bool VBoxCmdVbvaPreempt(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, uint32_t u32FenceID);
220uint32_t VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, bool fPingHost, uint32_t *pu32FenceSubmitted, uint32_t *pu32FenceProcessed);
221bool VBoxCmdVbvaCheckCompletedIrq(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva);
222
223/*helper functions for filling vbva commands */
224DECLINLINE(void) VBoxCVDdiPackRect(VBOXCMDVBVA_RECT *pVbvaRect, const RECT *pRect)
225{
226 pVbvaRect->xLeft = (int16_t)pRect->left;
227 pVbvaRect->yTop = (int16_t)pRect->top;
228 pVbvaRect->xRight = (int16_t)pRect->right;
229 pVbvaRect->yBottom = (int16_t)pRect->bottom;
230}
231
232DECLINLINE(void) VBoxCVDdiPackRects(VBOXCMDVBVA_RECT *paVbvaRects, const RECT *paRects, uint32_t cRects)
233{
234 for (uint32_t i = 0; i < cRects; ++i)
235 {
236 VBoxCVDdiPackRect(&paVbvaRects[i], &paRects[i]);
237 }
238
239}
240
241uint32_t VBoxCVDdiPTransferVRamSysBuildEls(VBOXCMDVBVA_PAGING_TRANSFER *pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesWritten);
242
243int VBoxCmdVbvaConConnect(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva,
244 uint32_t crVersionMajor, uint32_t crVersionMinor,
245 uint32_t *pu32ClientID);
246int VBoxCmdVbvaConDisconnect(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, uint32_t u32ClientID);
247VBOXCMDVBVA_CRCMD_CMD* VBoxCmdVbvaConCmdAlloc(PVBOXMP_DEVEXT pDevExt, uint32_t cbCmd);
248void VBoxCmdVbvaConCmdFree(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA_CRCMD_CMD* pCmd);
249int VBoxCmdVbvaConCmdSubmitAsync(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA_CRCMD_CMD* pCmd, FNVBOXSHGSMICMDCOMPLETION pfnCompletion, void *pvCompletion);
250int VBoxCmdVbvaConCmdCompletionData(void *pvCmd, VBOXCMDVBVA_CRCMD_CMD **ppCmd);
251int VBoxCmdVbvaConCmdResize(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData, const uint32_t *pTargetMap, const POINT * pVScreenPos, uint16_t fFlags);
252#endif /* #ifdef VBOX_WITH_CROGL */
253
254#endif /* #ifndef ___VBoxMPVbva_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