Changeset 30441 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm
- Timestamp:
- Jun 24, 2010 7:57:40 PM (14 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoCm.cpp
r30405 r30441 48 48 PKEVENT pUmEvent; 49 49 /* synch lock */ 50 KSPIN_LOCK SpinLock;50 FAST_MUTEX Mutex; 51 51 /* indicates whether event signaling is needed on cmd add */ 52 52 bool bEventNeeded; … … 110 110 static void vboxVideoCmCmdPostByHdr(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_CMD_DR pHdr, uint32_t cbSize) 111 111 { 112 KIRQL OldIrql;113 112 bool bSignalEvent = false; 114 113 if (cbSize != VBOXVIDEOCM_SUBMITSIZE_DEFAULT) … … 118 117 pHdr->CmdHdr.cbCmd = cbSize; 119 118 } 120 KeAcquireSpinLock(&pSession->SpinLock, &OldIrql); 119 120 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 121 ExAcquireFastMutex(&pSession->Mutex); 122 121 123 InsertHeadList(&pSession->CommandsList, &pHdr->QueueList); 122 124 if (pSession->bEventNeeded) … … 125 127 bSignalEvent = true; 126 128 } 127 KeReleaseSpinLock(&pSession->SpinLock, OldIrql); 129 130 ExReleaseFastMutex(&pSession->Mutex); 128 131 129 132 if (bSignalEvent) … … 168 171 void vboxVideoCmSessionCtxAdd(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_CTX pContext) 169 172 { 170 KIRQL OldIrql;171 KeAcquireSpinLock(&pSession->SpinLock, &OldIrql);173 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 174 ExAcquireFastMutex(&pSession->Mutex); 172 175 vboxVideoCmSessionCtxAddLocked(pSession, pContext); 173 KeReleaseSpinLock(&pSession->SpinLock, OldIrql); 176 ExReleaseFastMutex(&pSession->Mutex); 177 174 178 } 175 179 … … 183 187 } 184 188 185 DECLINLINE(void) vboxVideoLeDetach(LIST_ENTRY *pList, LIST_ENTRY *pDstList)186 {187 pDstList = pList;188 pDstList->Flink->Blink = pDstList;189 pDstList->Blink->Flink = pDstList;190 }191 189 /** 192 190 * @return true iff the given session is destroyed … … 194 192 bool vboxVideoCmSessionCtxRemove(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_CTX pContext) 195 193 { 196 KIRQL OldIrql;197 194 bool bDestroy; 198 195 LIST_ENTRY RemainedList; … … 200 197 LIST_ENTRY *pPrev; 201 198 InitializeListHead(&RemainedList); 202 KeAcquireSpinLock(&pSession->SpinLock, &OldIrql); 199 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 200 ExAcquireFastMutex(&pSession->Mutex); 203 201 pContext->pSession = NULL; 204 202 RemoveEntryList(&pContext->SessionEntry); … … 230 228 } 231 229 } 232 KeReleaseSpinLock(&pSession->SpinLock, OldIrql);230 ExReleaseFastMutex(&pSession->Mutex); 233 231 234 232 for (pCur = RemainedList.Flink; pCur != &RemainedList; pCur = RemainedList.Flink) … … 257 255 InitializeListHead(&pSession->CommandsList); 258 256 pSession->pUmEvent = pUmEvent; 259 KeInitializeSpinLock(&pSession->SpinLock); 257 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 258 ExInitializeFastMutex(&pSession->Mutex); 260 259 pSession->bEventNeeded = true; 261 260 vboxVideoCmSessionCtxAddLocked(pSession, pContext); … … 368 367 LIST_ENTRY DetachedList; 369 368 PLIST_ENTRY pCurEntry; 370 KIRQL OldIrql;371 369 uint32_t cbCmdsReturned = 0; 372 370 uint32_t cbRemainingCmds = 0; … … 378 376 // PVBOXWDDM_GETVBOXVIDEOCMCMD_HDR *pvCmd 379 377 380 KeAcquireSpinLock(&pSession->SpinLock, &OldIrql); 378 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 379 ExAcquireFastMutex(&pSession->Mutex); 381 380 382 381 do … … 426 425 } while (1); 427 426 428 KeReleaseSpinLock(&pSession->SpinLock, OldIrql);427 ExReleaseFastMutex(&pSession->Mutex); 429 428 430 429 pvCmd->cbCmdsReturned = 0; -
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoIf.h
r30405 r30441 159 159 struct 160 160 { 161 UINT bPositionRect Valid: 1;162 UINT b VisibleRectsValid: 1;163 UINT bAddHiddenRects Valid: 1;161 UINT bPositionRect : 1; 162 UINT bAddVisibleRects : 1; 163 UINT bAddHiddenRects : 1; 164 164 UINT Reserved : 29; 165 165 }; … … 298 298 } 299 299 300 DECLINLINE(bool) vboxWddmRectIntersection(const RECT *pRect1, const RECT *pRect2, RECT *pResult) 301 { 302 if (pRect1->left < pRect2->left) 303 { 304 if (pRect1->right >= pRect2->left) 305 pResult->left = pRect2->left; 306 else 307 return false; 308 } 309 else 310 { 311 if (pRect2->right >= pRect1->left) 312 pResult->left = pRect1->left; 313 else 314 return false; 315 } 316 317 pResult->right = RT_MIN(pRect1->right, pRect2->right); 318 319 if (pRect1->top < pRect2->top) 320 { 321 if (pRect1->bottom >= pRect2->top) 322 pResult->top = pRect2->top; 323 else 324 return false; 325 } 326 else 327 { 328 if (pRect2->bottom >= pRect1->top) 329 pResult->top = pRect1->top; 330 else 331 return false; 332 } 333 334 pResult->bottom = RT_MIN(pRect1->bottom, pRect2->bottom); 335 336 return true; 300 DECLINLINE(bool) vboxWddmRectIntersection(const RECT *a, const RECT *b, RECT *rect) 301 { 302 Assert(a); 303 Assert(b); 304 Assert(rect); 305 rect->left = RT_MAX(a->left, b->left); 306 rect->right = RT_MIN(a->right, b->right); 307 rect->top = RT_MAX(a->top, b->top); 308 rect->bottom = RT_MIN(a->bottom, b->bottom); 309 return (rect->right>rect->left) && (rect->bottom>rect->top); 337 310 } 338 311 -
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.cpp
r29670 r30441 18 18 #include "VBoxVideoVdma.h" 19 19 #include "../VBoxVideo.h" 20 21 22 NTSTATUS vboxVdmaPipeConstruct(PVBOXVDMAPIPE pPipe) 23 { 24 KeInitializeSpinLock(&pPipe->SinchLock); 25 KeInitializeEvent(&pPipe->Event, SynchronizationEvent, FALSE); 26 InitializeListHead(&pPipe->CmdListHead); 27 pPipe->enmState = VBOXVDMAPIPE_STATE_CREATED; 28 pPipe->bNeedNotify = true; 29 return STATUS_SUCCESS; 30 } 31 32 NTSTATUS vboxVdmaPipeSvrOpen(PVBOXVDMAPIPE pPipe) 33 { 34 NTSTATUS Status = STATUS_SUCCESS; 35 KIRQL OldIrql; 36 KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql); 37 Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED); 38 switch (pPipe->enmState) 39 { 40 case VBOXVDMAPIPE_STATE_CREATED: 41 pPipe->enmState = VBOXVDMAPIPE_STATE_OPENNED; 42 pPipe->bNeedNotify = false; 43 break; 44 case VBOXVDMAPIPE_STATE_OPENNED: 45 pPipe->bNeedNotify = false; 46 break; 47 default: 48 AssertBreakpoint(); 49 Status = STATUS_INVALID_PIPE_STATE; 50 break; 51 } 52 53 KeReleaseSpinLock(&pPipe->SinchLock, OldIrql); 54 return Status; 55 } 56 57 NTSTATUS vboxVdmaPipeSvrClose(PVBOXVDMAPIPE pPipe) 58 { 59 NTSTATUS Status = STATUS_SUCCESS; 60 KIRQL OldIrql; 61 KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql); 62 Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED 63 || pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSING); 64 switch (pPipe->enmState) 65 { 66 case VBOXVDMAPIPE_STATE_CLOSING: 67 pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSED; 68 break; 69 case VBOXVDMAPIPE_STATE_CLOSED: 70 break; 71 default: 72 AssertBreakpoint(); 73 Status = STATUS_INVALID_PIPE_STATE; 74 break; 75 } 76 77 KeReleaseSpinLock(&pPipe->SinchLock, OldIrql); 78 return Status; 79 } 80 81 NTSTATUS vboxVdmaPipeCltClose(PVBOXVDMAPIPE pPipe) 82 { 83 NTSTATUS Status = STATUS_SUCCESS; 84 KIRQL OldIrql; 85 KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql); 86 bool bNeedNotify = false; 87 Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED 88 || pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED 89 || pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED); 90 switch (pPipe->enmState) 91 { 92 case VBOXVDMAPIPE_STATE_OPENNED: 93 pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSING; 94 bNeedNotify = pPipe->bNeedNotify; 95 pPipe->bNeedNotify = false; 96 break; 97 case VBOXVDMAPIPE_STATE_CREATED: 98 pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSED; 99 pPipe->bNeedNotify = false; 100 break; 101 case VBOXVDMAPIPE_STATE_CLOSED: 102 break; 103 default: 104 AssertBreakpoint(); 105 Status = STATUS_INVALID_PIPE_STATE; 106 break; 107 } 108 109 KeReleaseSpinLock(&pPipe->SinchLock, OldIrql); 110 111 if (bNeedNotify) 112 { 113 KeSetEvent(&pPipe->Event, 0, FALSE); 114 } 115 return Status; 116 } 117 118 NTSTATUS vboxVdmaPipeDestruct(PVBOXVDMAPIPE pPipe) 119 { 120 Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED 121 || pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED); 122 /* ensure the pipe is closed */ 123 NTSTATUS Status = vboxVdmaPipeCltClose(pPipe); 124 Assert(Status == STATUS_SUCCESS); 125 126 Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED); 127 128 return Status; 129 } 130 131 NTSTATUS vboxVdmaPipeSvrCmdGetList(PVBOXVDMAPIPE pPipe, PLIST_ENTRY pDetachHead) 132 { 133 PLIST_ENTRY pEntry = NULL; 134 KIRQL OldIrql; 135 NTSTATUS Status = STATUS_SUCCESS; 136 VBOXVDMAPIPE_STATE enmState = VBOXVDMAPIPE_STATE_CLOSED; 137 do 138 { 139 KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql); 140 Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED 141 || pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSING); 142 Assert(pPipe->enmState >= VBOXVDMAPIPE_STATE_OPENNED); 143 enmState = pPipe->enmState; 144 if (enmState >= VBOXVDMAPIPE_STATE_OPENNED) 145 { 146 vboxVideoLeDetach(&pPipe->CmdListHead, pDetachHead); 147 pPipe->bNeedNotify = false; 148 } 149 else 150 { 151 Status = STATUS_INVALID_PIPE_STATE; 152 break; 153 } 154 155 KeReleaseSpinLock(&pPipe->SinchLock, OldIrql); 156 157 if (!IsListEmpty(pDetachHead)) 158 { 159 Assert(Status == STATUS_SUCCESS); 160 break; 161 } 162 163 if (enmState == VBOXVDMAPIPE_STATE_OPENNED) 164 { 165 KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql); 166 pPipe->bNeedNotify = true; 167 KeReleaseSpinLock(&pPipe->SinchLock, OldIrql); 168 169 Status = KeWaitForSingleObject(&pPipe->Event, Executive, KernelMode, FALSE, NULL /* PLARGE_INTEGER Timeout */); 170 Assert(Status == STATUS_SUCCESS); 171 if (Status != STATUS_SUCCESS) 172 break; 173 } 174 Assert(enmState > VBOXVDMAPIPE_STATE_OPENNED); 175 Status = STATUS_PIPE_CLOSING; 176 } while (1); 177 178 return Status; 179 } 180 181 NTSTATUS vboxVdmaPipeCltCmdPut(PVBOXVDMAPIPE pPipe, PVBOXVDMAPIPE_CMD_HDR pCmd) 182 { 183 NTSTATUS Status = STATUS_SUCCESS; 184 KIRQL OldIrql; 185 bool bNeedNotify = false; 186 187 KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql); 188 189 Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED); 190 if (pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED) 191 { 192 bNeedNotify = pPipe->bNeedNotify; 193 InsertHeadList(&pPipe->CmdListHead, &pCmd->ListEntry); 194 pPipe->bNeedNotify = false; 195 } 196 else 197 Status = STATUS_INVALID_PIPE_STATE; 198 199 KeReleaseSpinLock(&pPipe->SinchLock, OldIrql); 200 201 if (bNeedNotify) 202 { 203 KeSetEvent(&pPipe->Event, 0, FALSE); 204 } 205 206 return Status; 207 } 208 209 PVBOXVDMAPIPE_CMD_DR vboxVdmaGgCmdCreate(PVBOXVDMAGG pVdma, uint32_t cbCmd) 210 { 211 return (PVBOXVDMAPIPE_CMD_DR)vboxWddmMemAllocZero(cbCmd); 212 } 213 214 void vboxVdmaGgCmdDestroy(PVBOXVDMAPIPE_CMD_DR pDr) 215 { 216 vboxWddmMemFree(pDr); 217 } 218 219 220 /** 221 * helper function used for system thread creation 222 */ 223 static NTSTATUS vboxVdmaGgThreadCreate(PKTHREAD * ppThread, PKSTART_ROUTINE pStartRoutine, PVOID pStartContext) 224 { 225 NTSTATUS fStatus; 226 HANDLE hThread; 227 OBJECT_ATTRIBUTES fObjectAttributes; 228 229 Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); 230 231 InitializeObjectAttributes(&fObjectAttributes, NULL, OBJ_KERNEL_HANDLE, 232 NULL, NULL); 233 234 fStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, 235 &fObjectAttributes, NULL, NULL, 236 (PKSTART_ROUTINE) pStartRoutine, pStartContext); 237 if (!NT_SUCCESS(fStatus)) 238 return fStatus; 239 240 ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, 241 KernelMode, (PVOID*) ppThread, NULL); 242 ZwClose(hThread); 243 return STATUS_SUCCESS; 244 } 245 246 DECLINLINE(void) vboxVdmaDirtyRectsCalcIntersection(const RECT *pArea, const PVBOXWDDM_RECTS_INFO pRects, PVBOXWDDM_RECTS_INFO pResult) 247 { 248 pResult->cRects = 0; 249 for (uint32_t i = 0; i < pRects->cRects; ++i) 250 { 251 if (vboxWddmRectIntersection(pArea, &pRects->aRects[i], &pResult->aRects[pResult->cRects])) 252 { 253 ++pResult->cRects; 254 } 255 } 256 } 257 /** 258 * @param pDevExt 259 */ 260 NTSTATUS vboxVdmaGgDirtyRectsProcess(VBOXVDMAPIPE_CMD_RECTSINFO *pRectsInfo) 261 { 262 PVBOXWDDM_CONTEXT pContext = pRectsInfo->pContext; 263 PDEVICE_EXTENSION pDevExt = pContext->pDevice->pAdapter; 264 RECT * pContextRect = &pRectsInfo->ContextRect; 265 PVBOXWDDM_RECTS_INFO pRects = &pRectsInfo->UpdateRects; 266 NTSTATUS Status = STATUS_SUCCESS; 267 PVBOXVIDEOCM_CMD_RECTS pCmd = NULL; 268 uint32_t cbCmd = VBOXVIDEOCM_CMD_RECTS_SIZE4CRECTS(pRects->cRects); 269 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 270 ExAcquireFastMutex(&pDevExt->ContextMutex); 271 for (PLIST_ENTRY pCur = pDevExt->ContextList3D.Flink; pCur != &pDevExt->ContextList3D; pCur = pCur->Flink) 272 { 273 if (pCur != &pContext->ListEntry) 274 { 275 PVBOXWDDM_CONTEXT pCurContext = VBOXWDDMENTRY_2_CONTEXT(pCur); 276 if (!pCmd) 277 { 278 pCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdCreate(&pCurContext->CmContext, cbCmd); 279 Assert(pCmd); 280 if (!pCmd) 281 { 282 Status = STATUS_NO_MEMORY; 283 break; 284 } 285 } 286 else 287 { 288 pCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdReinitForContext(pCmd, &pCurContext->CmContext); 289 } 290 291 vboxVdmaDirtyRectsCalcIntersection(&pContext->ViewRect, pRects, &pCmd->RectsInfo); 292 if (pCmd->RectsInfo.cRects) 293 { 294 Assert(pCmd->fFlags.Value == 0); 295 pCmd->fFlags.bAddHiddenRects = 1; 296 vboxVideoCmCmdSubmit(pCmd, VBOXVIDEOCM_CMD_RECTS_SIZE4CRECTS(pCmd->RectsInfo.cRects)); 297 pCmd = NULL; 298 } 299 } 300 else 301 { 302 bool bRectShanged = (pContext->ViewRect.left != pContextRect->left 303 || pContext->ViewRect.top != pContextRect->top 304 || pContext->ViewRect.right != pContextRect->right 305 || pContext->ViewRect.bottom != pContextRect->bottom); 306 PVBOXVIDEOCM_CMD_RECTS pDrCmd; 307 308 if (bRectShanged) 309 { 310 uint32_t cbDrCmd = VBOXVIDEOCM_CMD_RECTS_SIZE4CRECTS(pRects->cRects + 1); 311 pDrCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdCreate(&pContext->CmContext, cbDrCmd); 312 Assert(pDrCmd); 313 if (!pDrCmd) 314 { 315 Status = STATUS_NO_MEMORY; 316 break; 317 } 318 pDrCmd->RectsInfo.cRects = pRects->cRects + 1; 319 } 320 else 321 { 322 if (pCmd) 323 { 324 pDrCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdReinitForContext(pCmd, &pContext->CmContext); 325 pCmd = NULL; 326 } 327 else 328 { 329 pDrCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdCreate(&pContext->CmContext, cbCmd); 330 Assert(pDrCmd); 331 if (!pDrCmd) 332 { 333 Status = STATUS_NO_MEMORY; 334 break; 335 } 336 } 337 pDrCmd->RectsInfo.cRects = pRects->cRects; 338 } 339 340 Assert(pDrCmd->fFlags.Value == 0); 341 RECT *pDirtyRect; 342 if (bRectShanged) 343 { 344 pDrCmd->fFlags.bPositionRect = 1; 345 pDrCmd->RectsInfo.aRects[0] = *pContextRect; 346 pDirtyRect = &pDrCmd->RectsInfo.aRects[1]; 347 } 348 else 349 pDirtyRect = &pDrCmd->RectsInfo.aRects[0]; 350 351 pDrCmd->fFlags.bAddVisibleRects = 1; 352 memcpy (pDirtyRect, pRects->aRects, sizeof (RECT) * pRects->cRects); 353 354 vboxVideoCmCmdSubmit(pDrCmd, VBOXVIDEOCM_SUBMITSIZE_DEFAULT); 355 } 356 } 357 InsertHeadList(&pDevExt->ContextList3D, &pContext->ListEntry); 358 ExReleaseFastMutex(&pDevExt->ContextMutex); 359 360 361 if (pCmd) 362 vboxVideoCmCmdRelease(pCmd); 363 364 return Status; 365 } 366 367 368 static VOID vboxVdmaGgWorkerThread(PVOID pvUser) 369 { 370 PVBOXVDMAGG pVdma = (PVBOXVDMAGG)pvUser; 371 372 NTSTATUS Status = vboxVdmaPipeSvrOpen(&pVdma->CmdPipe); 373 Assert(Status == STATUS_SUCCESS); 374 if (Status == STATUS_SUCCESS) 375 { 376 do 377 { 378 LIST_ENTRY CmdList; 379 Status = vboxVdmaPipeSvrCmdGetList(&pVdma->CmdPipe, &CmdList); 380 Assert(Status == STATUS_SUCCESS || Status == STATUS_PIPE_CLOSING); 381 if (Status == STATUS_SUCCESS) 382 { 383 for (PLIST_ENTRY pCur = CmdList.Blink; pCur != &CmdList; pCur = CmdList.Blink) 384 { 385 PVBOXVDMAPIPE_CMD_DR pDr = VBOXVDMAPIPE_CMD_DR_FROM_ENTRY(pCur); 386 switch (pDr->enmType) 387 { 388 case VBOXVDMAPIPE_CMD_TYPE_RECTSINFO: 389 { 390 PVBOXVDMAPIPE_CMD_RECTSINFO pRects = (PVBOXVDMAPIPE_CMD_RECTSINFO)pDr; 391 Status = vboxVdmaGgDirtyRectsProcess(pRects); 392 Assert(Status == STATUS_SUCCESS); 393 break; 394 } 395 case VBOXVDMAPIPE_CMD_TYPE_DMACMD: 396 default: 397 AssertBreakpoint(); 398 } 399 RemoveEntryList(pCur); 400 vboxVdmaGgCmdDestroy(pDr); 401 } 402 } 403 else 404 break; 405 } while (1); 406 } 407 408 /* always try to close the pipe to make sure the client side is notified */ 409 Status = vboxVdmaPipeSvrClose(&pVdma->CmdPipe); 410 Assert(Status == STATUS_SUCCESS); 411 } 412 413 NTSTATUS vboxVdmaGgConstruct(PVBOXVDMAGG pVdma) 414 { 415 NTSTATUS Status = vboxVdmaPipeConstruct(&pVdma->CmdPipe); 416 Assert(Status == STATUS_SUCCESS); 417 if (Status == STATUS_SUCCESS) 418 { 419 Status = vboxVdmaGgThreadCreate(&pVdma->pThread, vboxVdmaGgWorkerThread, pVdma); 420 Assert(Status == STATUS_SUCCESS); 421 if (Status == STATUS_SUCCESS) 422 return STATUS_SUCCESS; 423 424 NTSTATUS tmpStatus = vboxVdmaPipeDestruct(&pVdma->CmdPipe); 425 Assert(tmpStatus == STATUS_SUCCESS); 426 } 427 428 /* we're here ONLY in case of an error */ 429 Assert(Status != STATUS_SUCCESS); 430 return Status; 431 } 432 433 NTSTATUS vboxVdmaGgDestruct(PVBOXVDMAGG pVdma) 434 { 435 /* this informs the server thread that it should complete all current commands and exit */ 436 NTSTATUS Status = vboxVdmaPipeCltClose(&pVdma->CmdPipe); 437 Assert(Status == STATUS_SUCCESS); 438 if (Status == STATUS_SUCCESS) 439 { 440 Status = KeWaitForSingleObject(pVdma->pThread, Executive, KernelMode, FALSE, NULL /* PLARGE_INTEGER Timeout */); 441 Assert(Status == STATUS_SUCCESS); 442 if (Status == STATUS_SUCCESS) 443 { 444 Status = vboxVdmaPipeDestruct(&pVdma->CmdPipe); 445 Assert(Status == STATUS_SUCCESS); 446 } 447 } 448 449 return Status; 450 } 451 452 NTSTATUS vboxVdmaGgCmdPost(PVBOXVDMAGG pVdma, PVBOXVDMAPIPE_CMD_DR pCmd) 453 { 454 return vboxVdmaPipeCltCmdPut(&pVdma->CmdPipe, &pCmd->PipeHdr); 455 } 456 457 /* end */ 20 458 21 459 /* … … 139 577 Assert(RT_SUCCESS(rc)); 140 578 if(RT_SUCCESS(rc)) 141 return rc; 579 { 580 NTSTATUS Status = vboxVdmaGgConstruct(&pInfo->DmaGg); 581 Assert(Status == STATUS_SUCCESS); 582 if (Status == STATUS_SUCCESS) 583 return VINF_SUCCESS; 584 rc = VERR_GENERAL_FAILURE; 585 } 142 586 else 143 587 drprintf((__FUNCTION__": HGSMIHeapSetup failed rc = 0x%x\n", rc)); … … 200 644 { 201 645 int rc = VINF_SUCCESS; 202 Assert(!pInfo->fEnabled); 203 if (pInfo->fEnabled) 204 rc = vboxVdmaDisable (pDevExt, pInfo); 205 VBoxUnmapAdapterMemory (pDevExt, (void**)&pInfo->CmdHeap.area.pu8Base, pInfo->CmdHeap.area.cbArea); 646 NTSTATUS Status = vboxVdmaGgDestruct(&pInfo->DmaGg); 647 Assert(Status == STATUS_SUCCESS); 648 if (Status == STATUS_SUCCESS) 649 { 650 Assert(!pInfo->fEnabled); 651 if (pInfo->fEnabled) 652 rc = vboxVdmaDisable (pDevExt, pInfo); 653 VBoxUnmapAdapterMemory (pDevExt, (void**)&pInfo->CmdHeap.area.pu8Base, pInfo->CmdHeap.area.cbArea); 654 } 655 else 656 rc = VERR_GENERAL_FAILURE; 206 657 return rc; 207 658 } -
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.h
r29670 r30441 28 28 #endif 29 29 30 /* start */ 31 typedef enum 32 { 33 VBOXVDMAPIPE_STATE_CLOSED = 0, 34 VBOXVDMAPIPE_STATE_CREATED = 1, 35 VBOXVDMAPIPE_STATE_OPENNED = 2, 36 VBOXVDMAPIPE_STATE_CLOSING = 3 37 } VBOXVDMAPIPE_STATE; 38 39 typedef struct VBOXVDMAPIPE 40 { 41 KSPIN_LOCK SinchLock; 42 KEVENT Event; 43 LIST_ENTRY CmdListHead; 44 VBOXVDMAPIPE_STATE enmState; 45 /* true iff the other end needs Event notification */ 46 bool bNeedNotify; 47 } VBOXVDMAPIPE, *PVBOXVDMAPIPE; 48 49 typedef struct VBOXVDMAPIPE_CMD_HDR 50 { 51 LIST_ENTRY ListEntry; 52 } VBOXVDMAPIPE_CMD_HDR, *PVBOXVDMAPIPE_CMD_HDR; 53 54 #define VBOXVDMAPIPE_CMD_HDR_FROM_ENTRY(_pE) ( (PVBOXVDMAPIPE_CMD_HDR)((uint8_t *)(_pE) - RT_OFFSETOF(VBOXVDMAPIPE_CMD_HDR, ListEntry)) ) 55 56 typedef enum 57 { 58 VBOXVDMAPIPE_CMD_TYPE_UNDEFINED = 0, 59 VBOXVDMAPIPE_CMD_TYPE_RECTSINFO = 1, 60 VBOXVDMAPIPE_CMD_TYPE_DMACMD = 2 61 } VBOXVDMAPIPE_CMD_TYPE; 62 63 typedef struct VBOXVDMAPIPE_CMD_DR 64 { 65 VBOXVDMAPIPE_CMD_HDR PipeHdr; 66 VBOXVDMAPIPE_CMD_TYPE enmType; 67 } VBOXVDMAPIPE_CMD_DR, *PVBOXVDMAPIPE_CMD_DR; 68 69 #define VBOXVDMAPIPE_CMD_DR_FROM_ENTRY(_pE) ( (PVBOXVDMAPIPE_CMD_DR)VBOXVDMAPIPE_CMD_HDR_FROM_ENTRY(_pE) ) 70 71 typedef struct VBOXVDMAPIPE_CMD_RECTSINFO 72 { 73 VBOXVDMAPIPE_CMD_DR Hdr; 74 PVBOXWDDM_CONTEXT pContext; 75 RECT ContextRect; 76 VBOXWDDM_RECTS_INFO UpdateRects; 77 } VBOXVDMAPIPE_CMD_RECTSINFO, *PVBOXVDMAPIPE_CMD_RECTSINFO; 78 79 typedef struct VBOXVDMAGG 80 { 81 VBOXVDMAPIPE CmdPipe; 82 PKTHREAD pThread; 83 } VBOXVDMAGG, *PVBOXVDMAGG; 84 30 85 /* DMA commands are currently submitted over HGSMI */ 31 86 typedef struct VBOXVDMAINFO … … 37 92 VBOXVDMASUBMIT Submitter; 38 93 #endif 94 /* dma-related commands list processed on the guest w/o host part involvement (guest-guest commands) */ 95 VBOXVDMAGG DmaGg; 39 96 } VBOXVDMAINFO, *PVBOXVDMAINFO; 40 97 -
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp
r30405 r30441 14 14 #include "../Helper.h" 15 15 16 #include <iprt/asm.h> 17 16 18 #include <VBox/VBoxGuestLib.h> 17 19 #include <VBox/VBoxVideo.h> … … 36 38 { 37 39 ExFreePool(pvMem); 38 }39 40 DECLINLINE(void) vboxWddmDirtyRectsCalcIntersection(const RECT *pArea, const PVBOXWDDM_RECTS_INFO pRects, PVBOXWDDM_RECTS_INFO pResult)41 {42 pResult->cRects = 0;43 for (uint32_t i = 0; i < pRects->cRects; ++i)44 {45 if (vboxWddmRectIntersection(pArea, &pRects->aRects[i], &pResult->aRects[pResult->cRects]))46 {47 ++pResult->cRects;48 }49 }50 }51 /**52 * @param pDevExt53 */54 NTSTATUS vboxWddmDirtyRectsProcess(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_CONTEXT pContext, const RECT * pContextRect, const PVBOXWDDM_RECTS_INFO pRects)55 {56 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);57 58 NTSTATUS Status = STATUS_SUCCESS;59 PVBOXVIDEOCM_CMD_RECTS pCmd = NULL;60 uint32_t cbCmd = VBOXVIDEOCM_CMD_RECTS_SIZE4CRECTS(pRects->cRects);61 KeAcquireSpinLockAtDpcLevel(&pDevExt->SynchLock);62 for (PLIST_ENTRY pCur = pDevExt->ContextList3D.Flink; pCur != &pDevExt->ContextList3D; pCur = pCur->Flink)63 {64 if (pCur != &pContext->ListEntry)65 {66 PVBOXWDDM_CONTEXT pCurContext = VBOXWDDMENTRY_2_CONTEXT(pCur);67 if (!pCmd)68 {69 pCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdCreate(&pCurContext->CmContext, cbCmd);70 Assert(pCmd);71 if (!pCmd)72 {73 Status = STATUS_NO_MEMORY;74 break;75 }76 }77 else78 {79 pCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdReinitForContext(pCmd, &pCurContext->CmContext);80 }81 82 vboxWddmDirtyRectsCalcIntersection(&pContext->ViewRect, pRects, &pCmd->RectsInfo);83 if (pCmd->RectsInfo.cRects)84 {85 Assert(pCmd->fFlags.Value == 0);86 pCmd->fFlags.bAddHiddenRectsValid = 1;87 vboxVideoCmCmdSubmit(pCmd, VBOXVIDEOCM_CMD_RECTS_SIZE4CRECTS(pCmd->RectsInfo.cRects));88 pCmd = NULL;89 }90 }91 else92 {93 bool bRectShanged = (pContext->ViewRect.left != pContextRect->left94 || pContext->ViewRect.top != pContextRect->top95 || pContext->ViewRect.right != pContextRect->right96 || pContext->ViewRect.bottom != pContextRect->bottom);97 PVBOXVIDEOCM_CMD_RECTS pDrCmd;98 99 if (bRectShanged)100 {101 uint32_t cbDrCmd = VBOXVIDEOCM_CMD_RECTS_SIZE4CRECTS(pRects->cRects + 1);102 pDrCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdCreate(&pContext->CmContext, cbDrCmd);103 Assert(pDrCmd);104 if (!pDrCmd)105 {106 Status = STATUS_NO_MEMORY;107 break;108 }109 pDrCmd->RectsInfo.cRects = pRects->cRects + 1;110 }111 else112 {113 if (pCmd)114 {115 pDrCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdReinitForContext(pCmd, &pContext->CmContext);116 pCmd = NULL;117 }118 else119 {120 pDrCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdCreate(&pContext->CmContext, cbCmd);121 Assert(pDrCmd);122 if (!pDrCmd)123 {124 Status = STATUS_NO_MEMORY;125 break;126 }127 }128 pDrCmd->RectsInfo.cRects = pRects->cRects;129 }130 131 Assert(pDrCmd->fFlags.Value == 0);132 RECT *pDirtyRect;133 if (bRectShanged)134 {135 pDrCmd->fFlags.bPositionRectValid = 1;136 pDrCmd->RectsInfo.aRects[0] = *pContextRect;137 pDirtyRect = &pDrCmd->RectsInfo.aRects[1];138 }139 else140 pDirtyRect = &pDrCmd->RectsInfo.aRects[0];141 142 pDrCmd->fFlags.bVisibleRectsValid = 1;143 memcpy (pDirtyRect, pRects->aRects, sizeof (RECT) * pRects->cRects);144 145 vboxVideoCmCmdSubmit(pDrCmd, VBOXVIDEOCM_SUBMITSIZE_DEFAULT);146 }147 }148 InsertHeadList(&pDevExt->ContextList3D, &pContext->ListEntry);149 KeReleaseSpinLockFromDpcLevel(&pDevExt->SynchLock);150 151 if (pCmd)152 vboxVideoCmCmdRelease(pCmd);153 154 return Status;155 40 } 156 41 … … 770 655 vboxVideoCmInit(&pContext->CmMgr); 771 656 InitializeListHead(&pContext->ContextList3D); 772 KeInitializeSpinLock(&pContext->SynchLock); 657 pContext->cContexts3D = 0; 658 ExInitializeFastMutex(&pContext->ContextMutex); 773 659 } 774 660 else … … 2034 1920 * we do not expect any other flags to be set here */ 2035 1921 // Assert(pPatch->Flags.Value == 2 || pPatch->Flags.Value == 4); 2036 Assert(pPatch->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATE _DATA));2037 Assert(pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATE _DATA));2038 if (pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATE _DATA))2039 { 2040 PVBOXWDDM_DMA_PRIVATE_DATA pPrivateData = (PVBOXWDDM_DMA_PRIVATE_DATA)((uint8_t*)pPatch->pDmaBufferPrivateData + pPatch->DmaBufferPrivateDataSubmissionStartOffset);1922 Assert(pPatch->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR)); 1923 Assert(pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR)); 1924 if (pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR)) 1925 { 1926 VBOXWDDM_DMA_PRIVATEDATA_HDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_HDR*)((uint8_t*)pPatch->pDmaBufferPrivateData + pPatch->DmaBufferPrivateDataSubmissionStartOffset); 2041 1927 switch (pPrivateData->enmCmd) 2042 1928 { 2043 #ifdef VBOXWDDM_RENDER_FROM_SHADOW2044 1929 case VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY: 1930 case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT: 2045 1931 { 2046 1932 const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[0]; … … 2049 1935 const DXGK_ALLOCATIONLIST *pAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex]; 2050 1936 Assert(pAllocationList->SegmentId); 2051 pPrivateData->segmentIdShadow = pAllocationList->SegmentId; 2052 pPrivateData->offShadow = (VBOXVIDEOOFFSET)pAllocationList->PhysicalAddress.QuadPart; 1937 pPrivateData->SrcAllocInfo.segmentIdAlloc = pAllocationList->SegmentId; 1938 pPrivateData->SrcAllocInfo.offAlloc = (VBOXVIDEOOFFSET)pAllocationList->PhysicalAddress.QuadPart; 1939 #ifdef VBOXWDDM_RENDER_FROM_SHADOW 1940 if (!pPrivateData->fFlags.bShadow2PrimaryUpdate) 1941 #endif 1942 { 1943 pPatchList = &pPatch->pPatchLocationList[1]; 1944 Assert(pPatchList->AllocationIndex == DXGK_PRESENT_DESTINATION_INDEX); 1945 Assert(pPatchList->PatchOffset == 4); 1946 const DXGK_ALLOCATIONLIST *pAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex]; 1947 Assert(pAllocationList->SegmentId); 1948 pPrivateData->DstAllocInfo.segmentIdAlloc = pAllocationList->SegmentId; 1949 pPrivateData->DstAllocInfo.offAlloc = (VBOXVIDEOOFFSET)pAllocationList->PhysicalAddress.QuadPart; 1950 } 2053 1951 break; 2054 1952 } 2055 #endif2056 1953 default: 2057 1954 { 1955 AssertBreakpoint(); 2058 1956 uint8_t *pBuf = ((uint8_t *)pPatch->pDmaBuffer) + pPatch->DmaBufferSubmissionStartOffset; 2059 1957 for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i) … … 2080 1978 else 2081 1979 { 2082 drprintf((__FUNCTION__": DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXWDDM_DMA_PRIVATE _DATA) (%d)\n",1980 drprintf((__FUNCTION__": DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR) (%d)\n", 2083 1981 pPatch->DmaBufferPrivateDataSubmissionEndOffset, 2084 1982 pPatch->DmaBufferPrivateDataSubmissionStartOffset, 2085 sizeof (VBOXWDDM_DMA_PRIVATE _DATA)));1983 sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR))); 2086 1984 return STATUS_INVALID_PARAMETER; 2087 1985 } … … 2096 1994 { 2097 1995 PDEVICE_EXTENSION pDevExt; 2098 PVBOXWDDM_DMA_PRIVATE _DATApTransactionData;1996 PVBOXWDDM_DMA_PRIVATEDATA_HDR pTransactionData; 2099 1997 UINT SubmissionFenceId; 2100 1998 } VBOXWDDM_SHADOW_UPDATE_COMPLETION, *PVBOXWDDM_SHADOW_UPDATE_COMPLETION; … … 2142 2040 /* the DMA command buffer is located in system RAM, the host will need to pick it from there */ 2143 2041 //BufInfo.fFlags = 0; /* see VBOXVDMACBUF_FLAG_xx */ 2144 Assert(pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATE _DATA));2145 if (pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset < sizeof (VBOXWDDM_DMA_PRIVATE _DATA))2146 { 2147 drprintf((__FUNCTION__": DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXWDDM_DMA_PRIVATE _DATA) (%d)\n",2042 Assert(pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR)); 2043 if (pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset < sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR)) 2044 { 2045 drprintf((__FUNCTION__": DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR) (%d)\n", 2148 2046 pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset, 2149 2047 pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset, 2150 sizeof (VBOXWDDM_DMA_PRIVATE _DATA)));2048 sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR))); 2151 2049 return STATUS_INVALID_PARAMETER; 2152 2050 } 2153 2051 2154 PVBOXWDDM_DMA_PRIVATE_DATA pPrivateData = (PVBOXWDDM_DMA_PRIVATE_DATA)((uint8_t*)pSubmitCommand->pDmaBufferPrivateData + pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset); 2052 PVBOXWDDM_DMA_PRIVATEDATA_HDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_HDR)((uint8_t*)pSubmitCommand->pDmaBufferPrivateData + pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset); 2053 BOOLEAN bRet; 2155 2054 Assert(pPrivateData); 2156 2055 switch (pPrivateData->enmCmd) … … 2159 2058 case VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY: 2160 2059 { 2161 VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pPrivateData-> srcId];2162 BOOLEAN bRet;2163 vboxWddmCheckUpdateShadowAddress(pDevExt, pSource, pPrivateData->segmentIdShadow, pPrivateData->offShadow);2164 VBOXVBVA_OP(ReportDirtyRect, pDevExt, &pSource->Vbva, &p PrivateData->rect);2060 VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pPrivateData->SrcAllocInfo.srcId]; 2061 vboxWddmCheckUpdateShadowAddress(pDevExt, pSource, pPrivateData->SrcAllocInfo.segmentIdAlloc, pPrivateData->SrcAllocInfo.offAlloc); 2062 PVBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW pRFS = (PVBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW)pPrivateData; 2063 VBOXVBVA_OP(ReportDirtyRect, pDevExt, &pSource->Vbva, &pRFS->rect); 2165 2064 /* get DPC data at IRQL */ 2166 2065 … … 2177 2076 break; 2178 2077 } 2078 case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT: 2079 { 2080 uint32_t cContexts3D = ASMAtomicReadU32(&pDevExt->cContexts3D); 2081 if (cContexts3D) 2082 { 2083 2084 } 2085 VBOXWDDM_SHADOW_UPDATE_COMPLETION context; 2086 context.pDevExt = pDevExt; 2087 context.pTransactionData = pPrivateData; 2088 context.SubmissionFenceId = pSubmitCommand->SubmissionFenceId; 2089 Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution( 2090 pDevExt->u.primary.DxgkInterface.DeviceHandle, 2091 vboxWddmNotifyShadowUpdateCompletion, 2092 &context, 2093 0, /* IN ULONG MessageNumber */ 2094 &bRet); 2095 break; 2096 } 2097 2179 2098 #endif 2180 2099 default: … … 3640 3559 } 3641 3560 3561 static void vboxWddmPopulateDmaAllocInfo(PVBOXWDDM_DMA_ALLOCINFO pInfo, PVBOXWDDM_ALLOCATION pAlloc, DXGK_ALLOCATIONLIST *pDmaAlloc) 3562 { 3563 pInfo->pAlloc = pAlloc; 3564 if (pDmaAlloc->SegmentId) 3565 { 3566 pInfo->offAlloc = (VBOXVIDEOOFFSET)pDmaAlloc->PhysicalAddress.QuadPart; 3567 pInfo->segmentIdAlloc = pDmaAlloc->SegmentId; 3568 } 3569 else 3570 pInfo->segmentIdAlloc = 0; 3571 pInfo->srcId = pAlloc->SurfDesc.VidPnSourceId; 3572 } 3642 3573 /** 3643 3574 * DxgkDdiPresent … … 3660 3591 PDEVICE_EXTENSION pDevExt = pDevice->pAdapter; 3661 3592 3662 Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATE _DATA));3663 if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXWDDM_DMA_PRIVATE _DATA))3664 { 3665 drprintf((__FUNCTION__": Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATE _DATA (%d)\n", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATE_DATA)));3593 Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR)); 3594 if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR)) 3595 { 3596 drprintf((__FUNCTION__": Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_HDR (%d)\n", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_HDR))); 3666 3597 /* @todo: can this actually happen? what status tu return? */ 3667 3598 return STATUS_INVALID_PARAMETER; 3668 3599 } 3669 3600 3670 PVBOXWDDM_DMA_PRIVATE_DATA pPrivateData = (PVBOXWDDM_DMA_PRIVATE_DATA)pPresent->pDmaBufferPrivateData; 3671 pPrivateData->pContext = (PVBOXWDDM_CONTEXT)hContext; 3601 PVBOXWDDM_DMA_PRIVATEDATA_HDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_HDR)pPresent->pDmaBufferPrivateData; 3602 pPrivateData->pContext = pContext; 3603 pPrivateData->fFlags.Value = 0; 3604 uint32_t cContexts3D = ASMAtomicReadU32(&pDevExt->cContexts3D); 3605 #define VBOXWDDM_DUMMY_DMABUFFER_SIZE sizeof(RECT) 3672 3606 3673 3607 if (pPresent->Flags.Blt) … … 3699 3633 } 3700 3634 #endif 3701 if (pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE 3702 && pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE) 3635 /* issue VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE ONLY in case there are no 3D contexts currently 3636 * otherwise we would need info about all rects being updated on primary for visible rect reporting */ 3637 if (!cContexts3D) 3703 3638 { 3704 Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM); 3705 Assert(pDstAlloc->bAssigned); 3706 Assert(pDstAlloc->bVisible); 3707 if (pDstAlloc->bAssigned 3708 && pDstAlloc->bVisible) 3639 if (pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE 3640 && pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE) 3709 3641 { 3710 VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->SurfDesc.VidPnSourceId]; 3711 vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pDstAlloc->SurfDesc.VidPnSourceId); 3712 Assert(pPresent->SrcRect.left == pPresent->DstRect.left); 3713 Assert(pPresent->SrcRect.right == pPresent->DstRect.right); 3714 Assert(pPresent->SrcRect.top == pPresent->DstRect.top); 3715 Assert(pPresent->SrcRect.bottom == pPresent->DstRect.bottom); 3716 RECT rect; 3717 if (pPresent->SubRectCnt) 3642 Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM); 3643 Assert(pDstAlloc->bAssigned); 3644 Assert(pDstAlloc->bVisible); 3645 if (pDstAlloc->bAssigned 3646 && pDstAlloc->bVisible) 3718 3647 { 3719 rect = pPresent->pDstSubRects[0];3720 for (UINT i = 1; i < pPresent->SubRectCnt; ++i)3648 Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW)); 3649 if (pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW)) 3721 3650 { 3722 vboxWddmRectUnited(&rect, &rect, &pPresent->pDstSubRects[i]); 3723 } 3724 } 3725 else 3726 rect = pPresent->SrcRect; 3727 3728 // if (pSrc->SegmentId) 3729 // { 3730 // vboxWddmCheckUpdateShadowAddress(pDevExt, pSource, pSrc->SegmentId, (VBOXVIDEOOFFSET)pSrc->PhysicalAddress.QuadPart); 3731 // VBOXVBVA_OP(ReportDirtyRect, pDevExt, &pSource->Vbva, &rect); 3732 // } 3733 // else 3734 { 3735 #define VBOXWDDM_DUMMY_DMABUFFER_SIZE sizeof(RECT) 3736 pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE; 3737 pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRIVATE_DATA); 3738 Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE); 3739 Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATE_DATA)); 3740 if (pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE 3741 && pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATE_DATA)) 3742 { 3651 VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->SurfDesc.VidPnSourceId]; 3652 vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pDstAlloc->SurfDesc.VidPnSourceId); 3653 Assert(pPresent->SrcRect.left == pPresent->DstRect.left); 3654 Assert(pPresent->SrcRect.right == pPresent->DstRect.right); 3655 Assert(pPresent->SrcRect.top == pPresent->DstRect.top); 3656 Assert(pPresent->SrcRect.bottom == pPresent->DstRect.bottom); 3657 RECT rect; 3658 if (pPresent->SubRectCnt) 3659 { 3660 rect = pPresent->pDstSubRects[0]; 3661 for (UINT i = 1; i < pPresent->SubRectCnt; ++i) 3662 { 3663 vboxWddmRectUnited(&rect, &rect, &pPresent->pDstSubRects[i]); 3664 } 3665 } 3666 else 3667 rect = pPresent->SrcRect; 3668 3669 3670 pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW); 3671 pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE; 3672 Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE); 3743 3673 memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST)); 3744 // pPresent->pPatchLocationListOut->PatchOffset = 0;3745 // ++pPresent->pPatchLocationListOut;3746 3674 pPresent->pPatchLocationListOut->PatchOffset = 0; 3747 3675 pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX; … … 3751 3679 ++pPresent->pPatchLocationListOut; 3752 3680 3681 3753 3682 /* we do not know the shadow address yet, perform dummy DMA cycle */ 3754 pPrivateData->rect = rect; 3755 pPrivateData->srcId = pDstAlloc->SurfDesc.VidPnSourceId; 3683 pPrivateData->fFlags.bShadow2PrimaryUpdate = 1; 3756 3684 pPrivateData->enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY; 3757 if (pSrc->SegmentId) 3758 { 3759 pPrivateData->segmentIdShadow = pSrc->SegmentId; 3760 pPrivateData->offShadow = (VBOXVIDEOOFFSET)pSrc->PhysicalAddress.QuadPart; 3761 } 3685 vboxWddmPopulateDmaAllocInfo(&pPrivateData->SrcAllocInfo, pSrcAlloc, pSrc); 3686 // no need to fill dst surf info here 3687 // vboxWddmPopulateDmaAllocInfo(&pPrivateData->DstAllocInfo, pDstAlloc, pDst); 3688 PVBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW pRFS = (PVBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW)pPrivateData; 3689 pRFS->rect = rect; 3690 break; 3762 3691 } 3763 3692 else 3764 3693 { 3765 /* this should not happen actually */3766 // drprintf((__FUNCTION__": cbCmd too small!! (%d)\n", cbCmd));3767 3694 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 3695 break; 3768 3696 } 3769 3697 } 3770 break;3771 3698 } 3772 3699 } 3773 3700 3774 /* we're here because this is NOT a shadow->primary update */ 3701 /* we're here because this is NOT a shadow->primary update 3702 * or because there are d3d contexts and we need to report visible rects */ 3775 3703 #endif 3776 UINT cbCmd = pPresent->DmaSize; 3704 UINT cbCmd = pPresent->DmaBufferPrivateDataSize; 3705 pPrivateData->enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT; 3706 3707 if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D) 3708 { 3709 vboxWddmPopulateDmaAllocInfo(&pPrivateData->SrcAllocInfo, pSrcAlloc, pSrc); 3710 3711 if (pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE 3712 && pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE) 3713 { 3714 #ifdef VBOXWDDM_RENDER_FROM_SHADOW 3715 Assert(cContexts3D); 3716 #endif 3717 pPrivateData->fFlags.bShadow2PrimaryUpdate = 1; 3718 Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM); 3719 } 3720 #ifdef VBOXWDDM_RENDER_FROM_SHADOW /* <- no need to fill dst surf info here */ 3721 else 3722 #endif 3723 { 3724 vboxWddmPopulateDmaAllocInfo(&pPrivateData->DstAllocInfo, pDstAlloc, pDst); 3725 } 3726 } 3727 /* else - no need to fill any surf info since we need this request for visible rects */ 3728 3729 PVBOXWDDM_DMA_PRESENT_BLT pBlt = (PVBOXWDDM_DMA_PRESENT_BLT)pPrivateData; 3730 pBlt->SrcRect = pPresent->SrcRect; 3731 pBlt->DstRects.cRects = 1; 3732 pBlt->DstRects.aRects[0] = pPresent->DstRect; 3733 UINT cbHead = RT_OFFSETOF(VBOXWDDM_DMA_PRESENT_BLT, DstRects.aRects[1]); 3734 Assert(pPresent->SubRectCnt > pPresent->MultipassOffset); 3735 UINT cbRects = (pPresent->SubRectCnt - pPresent->MultipassOffset) * sizeof (RECT); 3736 pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + cbHead + cbRects; 3737 cbCmd -= cbHead; 3738 Assert(cbCmd < UINT32_MAX/2); 3739 Assert(cbCmd > sizeof (RECT)); 3740 if (cbCmd < cbRects) 3741 { 3742 cbCmd -= cbRects; 3743 memcpy(&pBlt->DstRects.aRects[pPresent->MultipassOffset + 1], pPresent->pDstSubRects, cbRects); 3744 pBlt->DstRects.cRects += cbRects/sizeof (RECT); 3745 } 3746 else 3747 { 3748 UINT cbFitingRects = (cbCmd/sizeof (RECT)) * sizeof (RECT); 3749 Assert(cbFitingRects); 3750 memcpy(&pBlt->DstRects.aRects[pPresent->MultipassOffset + 1], pPresent->pDstSubRects, cbFitingRects); 3751 cbCmd -= cbFitingRects; 3752 pPresent->MultipassOffset += cbFitingRects/sizeof (RECT); 3753 pBlt->DstRects.cRects += cbFitingRects/sizeof (RECT); 3754 Assert(pPresent->SubRectCnt > pPresent->MultipassOffset); 3755 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 3756 } 3757 3758 pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE; 3759 Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE); 3760 memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST)); 3761 pPresent->pPatchLocationListOut->PatchOffset = 0; 3762 pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX; 3763 ++pPresent->pPatchLocationListOut; 3764 pPresent->pPatchLocationListOut->PatchOffset = 4; 3765 pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX; 3766 ++pPresent->pPatchLocationListOut; 3767 3768 break; 3769 3770 cbCmd = pPresent->DmaSize; 3777 3771 3778 3772 Assert(pPresent->SubRectCnt); … … 3823 3817 pPrivateData->enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT; 3824 3818 pTransfer->cDstSubRects = i; 3825 pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATE _DATA);3819 pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATEDATA_HDR); 3826 3820 } 3827 3821 else … … 3845 3839 drprintf((__FUNCTION__": failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation)); 3846 3840 Status = STATUS_INVALID_HANDLE; 3847 } } 3841 } 3842 } 3848 3843 else 3849 3844 { … … 3911 3906 Assert(i); 3912 3907 pTransfer->cDstSubRects = i; 3913 pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATE _DATA);3908 pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATEDATA_HDR); 3914 3909 } 3915 3910 else … … 4060 4055 if (Status == STATUS_SUCCESS) 4061 4056 { 4062 KIRQL OldIrql;4063 KeAcquireSpinLock(&pDevExt->SynchLock, &OldIrql);4057 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 4058 ExAcquireFastMutex(&pDevExt->ContextMutex); 4064 4059 InsertHeadList(&pDevExt->ContextList3D, &pContext->ListEntry); 4065 KeReleaseSpinLock(&pDevExt->SynchLock, OldIrql); 4060 ASMAtomicIncU32(&pDevExt->cContexts3D); 4061 ExReleaseFastMutex(&pDevExt->ContextMutex); 4066 4062 } 4067 4063 } … … 4082 4078 pCreateContext->ContextInfo.DmaBufferSize = VBOXWDDM_C_DMA_BUFFER_SIZE; 4083 4079 pCreateContext->ContextInfo.DmaBufferSegmentSet = 0; 4084 pCreateContext->ContextInfo.DmaBufferPrivateDataSize = sizeof (VBOXWDDM_DMA_PRIVATE_DATA);4080 pCreateContext->ContextInfo.DmaBufferPrivateDataSize = VBOXWDDM_C_DMA_PRIVATEDATA_SIZE; 4085 4081 pCreateContext->ContextInfo.AllocationListSize = VBOXWDDM_C_ALLOC_LIST_SIZE; 4086 4082 pCreateContext->ContextInfo.PatchLocationListSize = VBOXWDDM_C_PATH_LOCATION_LIST_SIZE; … … 4112 4108 if (pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D) 4113 4109 { 4114 KIRQL OldIrql;4115 KeAcquireSpinLock(&pDevExt->SynchLock, &OldIrql);4110 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 4111 ExAcquireFastMutex(&pDevExt->ContextMutex); 4116 4112 RemoveEntryList(&pContext->ListEntry); 4117 KeReleaseSpinLock(&pDevExt->SynchLock, OldIrql); 4113 uint32_t cContexts = ASMAtomicDecU32(&pDevExt->cContexts3D); 4114 ExReleaseFastMutex(&pDevExt->ContextMutex); 4115 Assert(cContexts < UINT32_MAX/2); 4118 4116 } 4119 4117 -
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.h
r30405 r30441 17 17 /* one page size */ 18 18 #define VBOXWDDM_C_DMA_BUFFER_SIZE 0x1000 19 #define VBOXWDDM_C_DMA_PRIVATEDATA_SIZE 0x4000 19 20 #define VBOXWDDM_C_ALLOC_LIST_SIZE 0xc00 20 21 #define VBOXWDDM_C_PATH_LOCATION_LIST_SIZE 0xc00 … … 132 133 #define VBOXWDDMENTRY_2_CONTEXT(_pE) ((PVBOXWDDM_CONTEXT)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_CONTEXT, ListEntry))) 133 134 134 typedef struct VBOXWDDM_DMA_PRIVATE_DATA 135 typedef struct VBOXWDDM_DMA_ALLOCINFO 136 { 137 PVBOXWDDM_ALLOCATION pAlloc; 138 VBOXVIDEOOFFSET offAlloc; 139 UINT segmentIdAlloc; 140 D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId; 141 } VBOXWDDM_DMA_ALLOCINFO, *PVBOXWDDM_DMA_ALLOCINFO; 142 143 typedef struct VBOXWDDM_DMA_PRIVATEDATA_FLAFS 144 { 145 union 146 { 147 struct 148 { 149 UINT bCmdInDmaBuffer : 1; 150 UINT bShadow2PrimaryUpdate : 1; 151 UINT bSrcAllocValid : 1; 152 UINT bDstAllocValid : 1; 153 UINT bReserved : 28; 154 }; 155 uint32_t Value; 156 }; 157 } VBOXWDDM_DMA_PRIVATEDATA_FLAFS, *PVBOXWDDM_DMA_PRIVATEDATA_FLAFS; 158 159 typedef struct VBOXWDDM_DMA_PRIVATEDATA_HDR 135 160 { 136 161 PVBOXWDDM_CONTEXT pContext; 162 VBOXWDDM_DMA_PRIVATEDATA_FLAFS fFlags; 137 163 VBOXVDMACMD_TYPE enmCmd; 164 VBOXWDDM_DMA_ALLOCINFO SrcAllocInfo; 165 VBOXWDDM_DMA_ALLOCINFO DstAllocInfo; 166 }VBOXWDDM_DMA_PRIVATEDATA_HDR, *PVBOXWDDM_DMA_PRIVATEDATA_HDR; 167 138 168 #ifdef VBOXWDDM_RENDER_FROM_SHADOW 169 170 typedef struct VBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW 171 { 172 VBOXWDDM_DMA_PRIVATEDATA_HDR Hdr; 139 173 RECT rect; 140 VBOXVIDEOOFFSET offShadow; 141 UINT segmentIdShadow; 142 D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId; 143 #endif 144 // uint8_t Reserved[8]; 145 }VBOXWDDM_DMA_PRIVATE_DATA, *PVBOXWDDM_DMA_PRIVATE_DATA; 174 } VBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW, *PVBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW; 175 176 #endif 177 178 typedef struct VBOXWDDM_DMA_PRESENT_BLT 179 { 180 VBOXWDDM_DMA_PRIVATEDATA_HDR Hdr; 181 RECT SrcRect; 182 VBOXWDDM_RECTS_INFO DstRects; 183 }VBOXWDDM_DMA_PRESENT_BLT, *PVBOXWDDM_DMA_PRESENT_BLT; 184 146 185 147 186 typedef struct VBOXWDDM_OPENALLOCATION
Note:
See TracChangeset
for help on using the changeset viewer.