Changeset 95086 in vbox for trunk/src/VBox/Additions/WINNT
- Timestamp:
- May 25, 2022 5:31:21 AM (3 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp
r94927 r95086 51 51 for (uint32_t i = 0; i < RT_ELEMENTS(pSvga->aOT); ++i) 52 52 { 53 SvgaMobFree(pSvga, pSvga->aOT[i].pMob); 54 pSvga->aOT[i].pMob = 0; 53 SvgaGboFree(&pSvga->aOT[i].gbo); 55 54 56 55 RTR0MemObjFree(pSvga->aOT[i].hMemObj, true); … … 61 60 } 62 61 63 static NTSTATUS SvgaObjectTablesInit(VBOXWDDM_EXT_VMSVGA *pSvga) 64 { 65 NTSTATUS Status = STATUS_SUCCESS; 66 67 /* Allocate OTables. */ 68 for (uint32_t i = 0; i < RT_ELEMENTS(pSvga->aOT); ++i) 69 { 70 /** @todo Proper size for each. */ 71 uint32_t cbOT = 16 * PAGE_SIZE; 72 73 /* Allocate pages for the new OTable. */ 74 int rc = RTR0MemObjAllocPageTag(&pSvga->aOT[i].hMemObj, cbOT, false /* executable R0 mapping */, "VMSVGAOT"); 75 AssertRCBreakStmt(rc, Status = STATUS_INSUFFICIENT_RESOURCES); 76 77 /* Allocate a new mob. */ 78 Status = SvgaMobCreate(pSvga, &pSvga->aOT[i].pMob, cbOT >> PAGE_SHIFT, 0); 79 AssertBreak(NT_SUCCESS(Status)); 80 81 Status = SvgaMobFillPageTableForMemObj(pSvga, pSvga->aOT[i].pMob, pSvga->aOT[i].hMemObj); 82 AssertBreak(NT_SUCCESS(Status)); 83 } 84 85 if (NT_SUCCESS(Status)) 86 { 87 /* Emit commands */ 88 for (uint32_t i = 0; i < RT_ELEMENTS(pSvga->aOT); ++i) 89 { 90 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_SET_OTABLE_BASE64, sizeof(SVGA3dCmdSetOTableBase64), SVGA3D_INVALID_ID); 91 AssertBreakStmt(pvCmd, Status = STATUS_INSUFFICIENT_RESOURCES); 92 62 63 struct VMSVGAOTFREE 64 { 65 VMSVGAGBO gbo; 66 RTR0MEMOBJ hMemObj; 67 }; 68 69 70 static DECLCALLBACK(void) svgaOTFreeCb(VBOXWDDM_EXT_VMSVGA *pSvga, void *pvData, uint32_t cbData) 71 { 72 RT_NOREF(pSvga); 73 AssertReturnVoid(cbData == sizeof(struct VMSVGAOTFREE)); 74 struct VMSVGAOTFREE *p = (struct VMSVGAOTFREE *)pvData; 75 SvgaGboFree(&p->gbo); 76 RTR0MemObjFree(p->hMemObj, true); 77 } 78 79 80 typedef struct VMSVGAOTINFO 81 { 82 uint32_t cbEntry; 83 uint32_t cMaxEntries; 84 } VMSVGAOTINFO, *PVMSVGAOTINFO; 85 86 87 static VMSVGAOTINFO const s_aOTInfo[SVGA_OTABLE_DX_MAX] = 88 { 89 { sizeof(SVGAOTableMobEntry), SVGA3D_MAX_MOBS }, /* SVGA_OTABLE_MOB */ 90 { sizeof(SVGAOTableSurfaceEntry), SVGA3D_MAX_SURFACE_IDS }, /* SVGA_OTABLE_SURFACE */ 91 { sizeof(SVGAOTableContextEntry), 0 /* not used */ }, /* SVGA_OTABLE_CONTEXT */ 92 { sizeof(SVGAOTableShaderEntry), 0 /* not used */ }, /* SVGA_OTABLE_SHADER */ 93 { sizeof(SVGAOTableScreenTargetEntry), 64 /*VBOX_VIDEO_MAX_SCREENS*/ }, /* SVGA_OTABLE_SCREENTARGET */ 94 { sizeof(SVGAOTableDXContextEntry), SVGA3D_MAX_CONTEXT_IDS }, /* SVGA_OTABLE_DXCONTEXT */ 95 }; 96 97 98 static NTSTATUS svgaObjectTablesNotify(VBOXWDDM_EXT_VMSVGA *pSvga, SVGAOTableType enmType, uint32_t id) 99 { 100 AssertCompile(RT_ELEMENTS(pSvga->aOT) == RT_ELEMENTS(s_aOTInfo)); 101 AssertReturn(enmType < RT_ELEMENTS(pSvga->aOT), STATUS_INVALID_PARAMETER); 102 103 if (!RT_BOOL(pSvga->u32Caps & SVGA_CAP_GBOBJECTS)) 104 return STATUS_SUCCESS; /* No otables for such host device. */ 105 106 PVMSVGAOT pOT = &pSvga->aOT[enmType]; 107 if (id < pOT->cEntries) 108 return STATUS_SUCCESS; /* Still large enough. */ 109 110 VMSVGAOTINFO const *pOTInfo = &s_aOTInfo[enmType]; 111 AssertReturn(id < pOTInfo->cMaxEntries, STATUS_INVALID_PARAMETER); 112 113 /* 114 * Allocate a new larger mob and inform the host. 115 */ 116 uint32_t cbRequired = (id + 1) * pOTInfo->cbEntry; 117 cbRequired = RT_ALIGN_32(cbRequired, PAGE_SIZE); 118 119 /* Try to double the current size. */ 120 uint32_t cbOT = pOT->cEntries ? pOT->cEntries * pOTInfo->cbEntry : PAGE_SIZE; 121 while (cbRequired > cbOT) 122 cbOT *= 2; 123 124 /* Allocate pages for the new COTable. */ 125 RTR0MEMOBJ hMemObjOT; 126 int rc = RTR0MemObjAllocPageTag(&hMemObjOT, cbOT, false /* executable R0 mapping */, "VMSVGAOT"); 127 AssertRCReturn(rc, STATUS_INSUFFICIENT_RESOURCES); 128 129 memset(RTR0MemObjAddress(hMemObjOT), 0, cbOT); 130 131 /* Allocate a new gbo. */ 132 VMSVGAGBO gbo; 133 NTSTATUS Status = SvgaGboInit(&gbo, cbOT >> PAGE_SHIFT); 134 AssertReturnStmt(NT_SUCCESS(Status), 135 RTR0MemObjFree(hMemObjOT, true), 136 Status); 137 138 Status = SvgaGboFillPageTableForMemObj(&gbo, hMemObjOT); 139 AssertReturnStmt(NT_SUCCESS(Status), 140 SvgaGboFree(&gbo); RTR0MemObjFree(hMemObjOT, true), 141 Status); 142 143 if (pOT->cEntries == 0) 144 { 145 /* Set the pages for OTable. */ 146 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_SET_OTABLE_BASE64, sizeof(SVGA3dCmdSetOTableBase64), SVGA3D_INVALID_ID); 147 if (pvCmd) 148 { 93 149 SVGA3dCmdSetOTableBase64 *pCmd = (SVGA3dCmdSetOTableBase64 *)pvCmd; 94 pCmd->type = (SVGAOTableType)i;95 pCmd->baseAddress = pSvga->aOT[i].pMob->base;96 pCmd->sizeInBytes = pSvga->aOT[i].pMob->cbMob;150 pCmd->type = enmType; 151 pCmd->baseAddress = gbo.base; 152 pCmd->sizeInBytes = gbo.cbGbo; 97 153 pCmd->validSizeInBytes = 0; 98 pCmd->ptDepth = pSvga->aOT[i].pMob->enmMobFormat;99 100 SvgaCmdBufCommit(pSvga, sizeof( SVGA3dCmdSetOTableBase64));154 pCmd->ptDepth = gbo.enmMobFormat; 155 156 SvgaCmdBufCommit(pSvga, sizeof(*pCmd)); 101 157 } 102 103 SvgaCmdBufFlush(pSvga); 104 } 105 106 if (!NT_SUCCESS(Status)) 107 SvgaObjectTablesDestroy(pSvga); 158 else 159 AssertFailedReturnStmt(SvgaGboFree(&gbo); RTR0MemObjFree(hMemObjOT, true), 160 STATUS_INSUFFICIENT_RESOURCES); 161 } 162 else 163 { 164 /* Grow OTable and delete the old mob. */ 165 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_GROW_OTABLE, sizeof(SVGA3dCmdGrowOTable), SVGA3D_INVALID_ID); 166 if (pvCmd) 167 { 168 SVGA3dCmdGrowOTable *pCmd = (SVGA3dCmdGrowOTable *)pvCmd; 169 pCmd->type = enmType; 170 pCmd->baseAddress = gbo.base; 171 pCmd->sizeInBytes = gbo.cbGbo; 172 pCmd->validSizeInBytes = pOT->cEntries * pOTInfo->cbEntry; 173 pCmd->ptDepth = gbo.enmMobFormat; 174 175 SvgaCmdBufCommit(pSvga, sizeof(*pCmd)); 176 } 177 else 178 AssertFailedReturnStmt(SvgaGboFree(&gbo); RTR0MemObjFree(hMemObjOT, true), 179 STATUS_INSUFFICIENT_RESOURCES); 180 181 /* Command buffer completion callback to free the COT. */ 182 struct VMSVGAOTFREE callbackData; 183 callbackData.gbo = pOT->gbo; 184 callbackData.hMemObj = pOT->hMemObj; 185 SvgaCmdBufSetCompletionCallback(pSvga, svgaOTFreeCb, &callbackData, sizeof(callbackData)); 186 187 memset(&pOT->gbo, 0, sizeof(pOT->gbo)); 188 pOT->hMemObj = NIL_RTR0MEMOBJ; 189 } 190 191 SvgaCmdBufFlush(pSvga); 192 193 pOT->gbo = gbo; 194 pOT->hMemObj = hMemObjOT; 195 pOT->cEntries = cbOT / pOTInfo->cbEntry; 108 196 109 197 return STATUS_SUCCESS; … … 203 291 } 204 292 205 if (pSvga->u32Caps & SVGA_CAP_GBOBJECTS)206 {207 /** @todo DX contexts are available if SVGA_CAP_GBOBJECTS, SVGA_CAP_DX and SVGA3D_DEVCAP_DXCONTEXT are all enabled. */208 Status = SvgaObjectTablesInit(pSvga);209 AssertReturn(NT_SUCCESS(Status), Status);210 }211 212 293 uint32_t u32IRQMask = SVGA_IRQFLAG_ANY_FENCE; 213 294 if (pSvga->pCBState) … … 271 352 KeInitializeSpinLock(&pSvga->HwSpinLock); 272 353 KeInitializeSpinLock(&pSvga->HostObjectsSpinLock); 354 KeInitializeSpinLock(&pSvga->IdSpinLock); 273 355 ExInitializeFastMutex(&pSvga->SvgaMutex); 356 KeInitializeSpinLock(&pSvga->MobSpinLock); 357 // pSvga->GMRTree = NULL; 274 358 // pSvga->SurfaceTree = NULL; 359 // pSvga->MobTree = NULL; 275 360 RTListInit(&pSvga->DeletedHostObjectsList); 276 361 … … 301 386 if (pSvga->u32GmrMaxIds > 0) 302 387 { 303 pSvga->GMRTree = NULL;304 388 pSvga->cbGMRBits = ((pSvga->u32GmrMaxIds + 31) / 32) * 4; /* 32bit align and 4 bytes per 32 bit. */ 305 389 pSvga->pu32GMRBits = (uint32_t *)GaMemAllocZero(pSvga->cbGMRBits); … … 410 494 411 495 412 NTSTATUS SvgaIdAlloc(PVBOXWDDM_EXT_VMSVGA pSvga, 413 uint32_t *pu32Bits, 414 uint32_t cbBits, 415 uint32_t u32Limit, 416 uint32_t *pu32Id) 417 { 418 NTSTATUS Status; 419 ExAcquireFastMutex(&pSvga->SvgaMutex); 420 421 Status = GaIdAlloc(pu32Bits, cbBits, u32Limit, pu32Id); 422 423 ExReleaseFastMutex(&pSvga->SvgaMutex); 424 return Status; 425 } 426 427 NTSTATUS SvgaIdFree(PVBOXWDDM_EXT_VMSVGA pSvga, 428 uint32_t *pu32Bits, 429 uint32_t cbBits, 430 uint32_t u32Limit, 431 uint32_t u32Id) 432 { 433 NTSTATUS Status; 434 ExAcquireFastMutex(&pSvga->SvgaMutex); 435 436 Status = GaIdFree(pu32Bits, cbBits, u32Limit, u32Id); 437 438 ExReleaseFastMutex(&pSvga->SvgaMutex); 439 return Status; 496 DECLINLINE(NTSTATUS) svgaIdAlloc(PVBOXWDDM_EXT_VMSVGA pSvga, 497 uint32_t *pu32Bits, 498 uint32_t cbBits, 499 uint32_t u32Limit, 500 uint32_t *pu32Id) 501 { 502 KIRQL OldIrql; 503 KeAcquireSpinLock(&pSvga->IdSpinLock, &OldIrql); 504 NTSTATUS Status = GaIdAlloc(pu32Bits, cbBits, u32Limit, pu32Id); 505 KeReleaseSpinLock(&pSvga->IdSpinLock, OldIrql); 506 return Status; 507 } 508 509 510 DECLINLINE(NTSTATUS) svgaIdFree(PVBOXWDDM_EXT_VMSVGA pSvga, 511 uint32_t *pu32Bits, 512 uint32_t cbBits, 513 uint32_t u32Limit, 514 uint32_t u32Id) 515 { 516 KIRQL OldIrql; 517 KeAcquireSpinLock(&pSvga->IdSpinLock, &OldIrql); 518 NTSTATUS Status = GaIdFree(pu32Bits, cbBits, u32Limit, u32Id); 519 KeReleaseSpinLock(&pSvga->IdSpinLock, OldIrql); 520 return Status; 521 } 522 523 524 static NTSTATUS svgaOTableIdAlloc(PVBOXWDDM_EXT_VMSVGA pSvga, 525 uint32_t *pu32Bits, 526 uint32_t cbBits, 527 SVGAOTableType enmType, 528 uint32_t *pu32Id) 529 { 530 AssertReturn(enmType < RT_ELEMENTS(s_aOTInfo), STATUS_INVALID_PARAMETER); 531 VMSVGAOTINFO const *pOTInfo = &s_aOTInfo[enmType]; 532 Assert(pOTInfo->cMaxEntries <= cbBits * 8); 533 534 NTSTATUS Status = svgaIdAlloc(pSvga, pu32Bits, cbBits, pOTInfo->cMaxEntries, pu32Id); 535 if (NT_SUCCESS(Status)) 536 { 537 ExAcquireFastMutex(&pSvga->SvgaMutex); 538 Status = svgaObjectTablesNotify(pSvga, enmType, *pu32Id); 539 ExReleaseFastMutex(&pSvga->SvgaMutex); 540 541 if (!NT_SUCCESS(Status)) 542 svgaIdFree(pSvga, pu32Bits, cbBits, pOTInfo->cMaxEntries, *pu32Id); 543 } 544 545 return Status; 546 } 547 548 static NTSTATUS svgaOTableIdFree(PVBOXWDDM_EXT_VMSVGA pSvga, 549 uint32_t *pu32Bits, 550 uint32_t cbBits, 551 SVGAOTableType enmType, 552 uint32_t u32Id) 553 { 554 AssertReturn(enmType < RT_ELEMENTS(s_aOTInfo), STATUS_INVALID_PARAMETER); 555 VMSVGAOTINFO const *pOTInfo = &s_aOTInfo[enmType]; 556 return svgaIdFree(pSvga, pu32Bits, cbBits, pOTInfo->cMaxEntries, u32Id); 440 557 } 441 558 … … 443 560 uint32_t *pu32Cid) 444 561 { 445 return SvgaIdAlloc(pSvga, pSvga->au32DXContextBits, sizeof(pSvga->au32DXContextBits),446 SVGA3D_MAX_CONTEXT_IDS, pu32Cid);562 return svgaOTableIdAlloc(pSvga, pSvga->au32DXContextBits, sizeof(pSvga->au32DXContextBits), 563 SVGA_OTABLE_DXCONTEXT, pu32Cid); 447 564 } 448 565 … … 450 567 uint32_t u32Cid) 451 568 { 452 return SvgaIdFree(pSvga, pSvga->au32DXContextBits, sizeof(pSvga->au32DXContextBits),453 SVGA3D_MAX_CONTEXT_IDS, u32Cid);569 return svgaOTableIdFree(pSvga, pSvga->au32DXContextBits, sizeof(pSvga->au32DXContextBits), 570 SVGA_OTABLE_DXCONTEXT, u32Cid); 454 571 } 455 572 … … 457 574 uint32_t *pu32MobId) 458 575 { 459 return SvgaIdAlloc(pSvga, pSvga->au32MobBits, sizeof(pSvga->au32MobBits),460 SVGA3D_MAX_MOBS, pu32MobId);576 return svgaOTableIdAlloc(pSvga, pSvga->au32MobBits, sizeof(pSvga->au32MobBits), 577 SVGA_OTABLE_MOB, pu32MobId); 461 578 } 462 579 … … 464 581 uint32_t u32MobId) 465 582 { 466 return SvgaIdFree(pSvga, pSvga->au32MobBits, sizeof(pSvga->au32MobBits),467 SVGA3D_MAX_MOBS, u32MobId);583 return svgaOTableIdFree(pSvga, pSvga->au32MobBits, sizeof(pSvga->au32MobBits), 584 SVGA_OTABLE_MOB, u32MobId); 468 585 } 469 586 … … 471 588 uint32_t *pu32Cid) 472 589 { 473 return SvgaIdAlloc(pSvga, pSvga->au32ContextBits, sizeof(pSvga->au32ContextBits),474 SVGA3D_MAX_CONTEXT_IDS, pu32Cid);590 return svgaOTableIdAlloc(pSvga, pSvga->au32ContextBits, sizeof(pSvga->au32ContextBits), 591 SVGA_OTABLE_CONTEXT, pu32Cid); 475 592 } 476 593 … … 478 595 uint32_t u32Cid) 479 596 { 480 return SvgaIdFree(pSvga, pSvga->au32ContextBits, sizeof(pSvga->au32ContextBits),481 SVGA3D_MAX_CONTEXT_IDS, u32Cid);597 return svgaOTableIdFree(pSvga, pSvga->au32ContextBits, sizeof(pSvga->au32ContextBits), 598 SVGA_OTABLE_CONTEXT, u32Cid); 482 599 } 483 600 … … 485 602 uint32_t *pu32Sid) 486 603 { 487 return SvgaIdAlloc(pSvga, pSvga->au32SurfaceBits, sizeof(pSvga->au32SurfaceBits),488 SVGA3D_MAX_SURFACE_IDS, pu32Sid);604 return svgaOTableIdAlloc(pSvga, pSvga->au32SurfaceBits, sizeof(pSvga->au32SurfaceBits), 605 SVGA_OTABLE_SURFACE, pu32Sid); 489 606 } 490 607 … … 492 609 uint32_t u32Sid) 493 610 { 494 return SvgaIdFree(pSvga, pSvga->au32SurfaceBits, sizeof(pSvga->au32SurfaceBits),495 SVGA3D_MAX_SURFACE_IDS, u32Sid);611 return svgaOTableIdFree(pSvga, pSvga->au32SurfaceBits, sizeof(pSvga->au32SurfaceBits), 612 SVGA_OTABLE_SURFACE, u32Sid); 496 613 } 497 614 … … 499 616 uint32_t *pu32GMRId) 500 617 { 501 return SvgaIdAlloc(pSvga, pSvga->pu32GMRBits, pSvga->cbGMRBits,618 return svgaIdAlloc(pSvga, pSvga->pu32GMRBits, pSvga->cbGMRBits, 502 619 pSvga->u32GmrMaxIds, pu32GMRId); 503 620 } … … 506 623 uint32_t u32GMRId) 507 624 { 508 return SvgaIdFree(pSvga, pSvga->pu32GMRBits, pSvga->cbGMRBits,625 return svgaIdFree(pSvga, pSvga->pu32GMRBits, pSvga->cbGMRBits, 509 626 pSvga->u32GmrMaxIds, u32GMRId); 510 627 } … … 1959 2076 } 1960 2077 1961 NTSTATUS SvgaMobAlloc(VBOXWDDM_EXT_VMSVGA *pSvga, 1962 PVMSVGAMOB *ppMob) 2078 /* 2079 * 2080 * Guest Backed Objects. 2081 * 2082 */ 2083 2084 void SvgaGboFree(VMSVGAGBO *pGbo) 2085 { 2086 if (pGbo->hMemObjPT != NIL_RTR0MEMOBJ) 2087 { 2088 int rc = RTR0MemObjFree(pGbo->hMemObjPT, true); 2089 AssertRC(rc); 2090 pGbo->hMemObjPT = NIL_RTR0MEMOBJ; 2091 } 2092 memset(pGbo, 0, sizeof(*pGbo)); 2093 } 2094 2095 NTSTATUS SvgaGboInit(VMSVGAGBO *pGbo, uint32_t cPages) 2096 { 2097 /* 2098 * Calculate how many pages are needed to describe the gbo. 2099 * Use 64 bit mob format for 32 bit driver too in order to simplify the code for now. 2100 */ 2101 uint32_t const cPageEntriesPerPage = PAGE_SIZE / sizeof(PPN64); 2102 if (cPages == 1) 2103 { 2104 pGbo->cPTPages = 0; 2105 pGbo->enmMobFormat = SVGA3D_MOBFMT_PTDEPTH64_0; 2106 } 2107 else if (cPages <= cPageEntriesPerPage) 2108 { 2109 pGbo->cPTPages = 1; 2110 pGbo->enmMobFormat = SVGA3D_MOBFMT_PTDEPTH64_1; 2111 } 2112 else if (cPages <= cPageEntriesPerPage * cPageEntriesPerPage) 2113 { 2114 uint32_t const cLevel1Pages = 2115 (cPages + cPageEntriesPerPage - 1) / cPageEntriesPerPage; 2116 pGbo->cPTPages = 1 + cLevel1Pages; /* One level 2 page and level 1 pages. */ 2117 pGbo->enmMobFormat = SVGA3D_MOBFMT_PTDEPTH64_2; 2118 } 2119 else 2120 AssertFailedReturn(STATUS_INVALID_PARAMETER); 2121 2122 if (pGbo->cPTPages) 2123 { 2124 int rc = RTR0MemObjAllocPageTag(&pGbo->hMemObjPT, pGbo->cPTPages * PAGE_SIZE, 2125 false /* executable R0 mapping */, "VMSVGAGBO"); 2126 AssertRCReturn(rc, STATUS_INSUFFICIENT_RESOURCES); 2127 2128 if (pGbo->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2) 2129 { 2130 /* Store the page numbers of level 1 pages into the level 2 page. 2131 * Skip the level 2 page at index 0. 2132 */ 2133 PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pGbo->hMemObjPT); 2134 for (unsigned i = 1; i < pGbo->cPTPages; ++i) 2135 paPpn[i - 1] = RTR0MemObjGetPagePhysAddr(pGbo->hMemObjPT, i) >> PAGE_SHIFT; 2136 } 2137 } 2138 else 2139 pGbo->hMemObjPT = NIL_RTR0MEMOBJ; 2140 2141 pGbo->base = UINT64_C(~0); /* base will be assigned by SvgaGboFillPageTable* */ 2142 pGbo->cbGbo = cPages << PAGE_SHIFT; 2143 return STATUS_SUCCESS; 2144 } 2145 2146 2147 NTSTATUS SvgaGboFillPageTableForMDL(PVMSVGAGBO pGbo, 2148 PMDL pMdl, 2149 uint32_t MdlOffset) 2150 { 2151 PPFN_NUMBER paMdlPfn = &MmGetMdlPfnArray(pMdl)[MdlOffset]; 2152 if (pGbo->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_0) 2153 pGbo->base = paMdlPfn[0]; 2154 else 2155 { 2156 /* The first of pages is alway the base. It is either the level 2 page or the single level 1 page */ 2157 pGbo->base = RTR0MemObjGetPagePhysAddr(pGbo->hMemObjPT, 0) >> PAGE_SHIFT; 2158 2159 PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pGbo->hMemObjPT); 2160 PPN64 *paPpnMdlPfn; 2161 if (pGbo->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2) 2162 paPpnMdlPfn = &paPpn[PAGE_SIZE / sizeof(PPN64)]; /* Level 1 pages follow the level 2 page. */ 2163 else if (pGbo->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_1) 2164 paPpnMdlPfn = paPpn; 2165 else 2166 AssertFailedReturn(STATUS_INVALID_PARAMETER); 2167 2168 /* Store Mdl page numbers into the level 1 description pages. */ 2169 for (unsigned i = 0; i < pGbo->cbGbo >> PAGE_SHIFT; ++i) 2170 paPpnMdlPfn[i] = paMdlPfn[i]; 2171 } 2172 return STATUS_SUCCESS; 2173 } 2174 2175 2176 NTSTATUS SvgaGboFillPageTableForMemObj(PVMSVGAGBO pGbo, 2177 RTR0MEMOBJ hMemObj) 2178 { 2179 if (pGbo->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_0) 2180 pGbo->base = RTR0MemObjGetPagePhysAddr(hMemObj, 0) >> PAGE_SHIFT; 2181 else 2182 { 2183 /* The first of pages is alway the base. It is either the level 2 page or the single level 1 page */ 2184 pGbo->base = RTR0MemObjGetPagePhysAddr(pGbo->hMemObjPT, 0) >> PAGE_SHIFT; 2185 2186 PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pGbo->hMemObjPT); 2187 PPN64 *paPpnGbo; 2188 if (pGbo->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2) 2189 paPpnGbo = &paPpn[PAGE_SIZE / sizeof(PPN64)]; /* Level 1 pages follow the level 2 page. */ 2190 else if (pGbo->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_1) 2191 paPpnGbo = paPpn; 2192 else 2193 AssertFailedReturn(STATUS_INVALID_PARAMETER); 2194 2195 /* Store page numbers into the level 1 description pages. */ 2196 for (unsigned i = 0; i < pGbo->cbGbo >> PAGE_SHIFT; ++i) 2197 paPpnGbo[i] = RTR0MemObjGetPagePhysAddr(hMemObj, i) >> PAGE_SHIFT; 2198 } 2199 return STATUS_SUCCESS; 2200 } 2201 2202 2203 /* 2204 * 2205 * Memory OBjects. 2206 * 2207 */ 2208 2209 static NTSTATUS svgaMobAlloc(VBOXWDDM_EXT_VMSVGA *pSvga, 2210 PVMSVGAMOB *ppMob) 1963 2211 { 1964 2212 GALOG(("[%p]\n", pSvga)); … … 1973 2221 AssertReturnStmt(NT_SUCCESS(Status), GaMemFree(*ppMob), STATUS_INSUFFICIENT_RESOURCES); 1974 2222 2223 KIRQL OldIrql; 2224 KeAcquireSpinLock(&pSvga->MobSpinLock, &OldIrql); 2225 bool fInserted = RTAvlU32Insert(&pSvga->MobTree, &(*ppMob)->core); 2226 KeReleaseSpinLock(&pSvga->MobSpinLock, OldIrql); 2227 Assert(fInserted); RT_NOREF(fInserted); 2228 2229 GALOG(("mobid = %u\n", VMSVGAMOB_ID(*ppMob))); 1975 2230 return STATUS_SUCCESS; 1976 2231 } … … 1983 2238 if (pMob) 1984 2239 { 1985 ExAcquireFastMutex(&pSvga->SvgaMutex); 2240 GALOG(("mobid = %u\n", VMSVGAMOB_ID(pMob))); 2241 2242 KIRQL OldIrql; 2243 KeAcquireSpinLock(&pSvga->MobSpinLock, &OldIrql); 1986 2244 RTAvlU32Remove(&pSvga->MobTree, pMob->core.Key); 1987 ExReleaseFastMutex(&pSvga->SvgaMutex); 1988 1989 if (pMob->hMemObjPT != NIL_RTR0MEMOBJ) 1990 { 1991 int rc = RTR0MemObjFree(pMob->hMemObjPT, true); 1992 AssertRC(rc); 1993 pMob->hMemObjPT = NIL_RTR0MEMOBJ; 1994 } 2245 KeReleaseSpinLock(&pSvga->MobSpinLock, OldIrql); 2246 2247 SvgaGboFree(&pMob->gbo); 1995 2248 1996 2249 NTSTATUS Status = SvgaMobIdFree(pSvga, VMSVGAMOB_ID(pMob)); … … 2000 2253 } 2001 2254 2255 PVMSVGAMOB SvgaMobQuery(VBOXWDDM_EXT_VMSVGA *pSvga, 2256 uint32_t mobid) 2257 { 2258 KIRQL OldIrql; 2259 KeAcquireSpinLock(&pSvga->MobSpinLock, &OldIrql); 2260 PVMSVGAMOB pMob = (PVMSVGAMOB)RTAvlU32Get(&pSvga->MobTree, mobid); 2261 KeReleaseSpinLock(&pSvga->MobSpinLock, OldIrql); 2262 2263 GALOG(("[%p] mobid = %u -> %p\n", pSvga, mobid, pMob)); 2264 return pMob; 2265 } 2002 2266 2003 2267 NTSTATUS SvgaMobCreate(VBOXWDDM_EXT_VMSVGA *pSvga, … … 2007 2271 { 2008 2272 PVMSVGAMOB pMob; 2009 NTSTATUS Status = SvgaMobAlloc(pSvga, &pMob);2273 NTSTATUS Status = svgaMobAlloc(pSvga, &pMob); 2010 2274 AssertReturn(NT_SUCCESS(Status), Status); 2011 2275 2012 /* 2013 * Calculate how many pages are needed to describe the mob. 2014 * Use 64 bit mob format for 32 bit driver too in order to simplify the code. 2015 */ 2016 uint32_t const cPageEntriesPerPage = PAGE_SIZE / sizeof(PPN64); 2017 if (cMobPages == 1) 2018 { 2019 pMob->cDescriptionPages = 0; 2020 pMob->enmMobFormat = SVGA3D_MOBFMT_PTDEPTH64_0; 2021 } 2022 else if (cMobPages <= cPageEntriesPerPage) 2023 { 2024 pMob->cDescriptionPages = 1; 2025 pMob->enmMobFormat = SVGA3D_MOBFMT_PTDEPTH64_1; 2026 } 2027 else if (cMobPages <= cPageEntriesPerPage * cPageEntriesPerPage) 2028 { 2029 uint32_t const cLevel1Pages = 2030 (cMobPages + cPageEntriesPerPage - 1) / cPageEntriesPerPage; 2031 pMob->cDescriptionPages = 1 + cLevel1Pages; /* One level 2 page and level 1 pages. */ 2032 pMob->enmMobFormat = SVGA3D_MOBFMT_PTDEPTH64_2; 2033 } 2034 else 2035 AssertFailedReturnStmt(SvgaMobFree(pSvga, pMob), STATUS_INVALID_PARAMETER); 2036 2037 if (pMob->cDescriptionPages) 2038 { 2039 int rc = RTR0MemObjAllocPageTag(&pMob->hMemObjPT, pMob->cDescriptionPages * PAGE_SIZE, 2040 false /* executable R0 mapping */, "VMSVGAMOB"); 2041 AssertRCReturnStmt(rc, SvgaMobFree(pSvga, pMob), STATUS_INSUFFICIENT_RESOURCES); 2042 2043 if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2) 2044 { 2045 /* Store the page numbers of level 1 pages into the level 2 page. 2046 * Skip the level 2 page at index 0. 2047 */ 2048 PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObjPT); 2049 for (unsigned i = 1; i < pMob->cDescriptionPages; ++i) 2050 paPpn[i - 1] = RTR0MemObjGetPagePhysAddr(pMob->hMemObjPT, i) >> PAGE_SHIFT; 2051 } 2052 } 2053 2054 pMob->base = UINT64_C(~0); /* base will be assigned by SvgaMobFillPageTable* */ 2055 pMob->cbMob = cMobPages << PAGE_SHIFT; 2276 Status = SvgaGboInit(&pMob->gbo, cMobPages); 2277 AssertReturnStmt(NT_SUCCESS(Status), SvgaMobFree(pSvga, pMob), Status); 2278 2056 2279 pMob->hAllocation = hAllocation; 2057 2058 2280 *ppMob = pMob; 2059 2281 return STATUS_SUCCESS; … … 2061 2283 2062 2284 2063 NTSTATUS SvgaMobFillPageTableForMDL(VBOXWDDM_EXT_VMSVGA *pSvga, 2064 PVMSVGAMOB pMob, 2065 PMDL pMdl, 2066 uint32_t MdlOffset) 2067 { 2068 RT_NOREF(pSvga); 2069 2070 PPFN_NUMBER paMdlPfn = &MmGetMdlPfnArray(pMdl)[MdlOffset]; 2071 if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_0) 2072 pMob->base = paMdlPfn[0]; 2073 else 2074 { 2075 /* The first of pages is alway the base. It is either the level 2 page or the single level 1 page */ 2076 pMob->base = RTR0MemObjGetPagePhysAddr(pMob->hMemObjPT, 0) >> PAGE_SHIFT; 2077 2078 PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObjPT); 2079 PPN64 *paPpnMdlPfn; 2080 if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2) 2081 paPpnMdlPfn = &paPpn[PAGE_SIZE / sizeof(PPN64)]; /* Level 1 pages follow the level 2 page. */ 2082 else if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_1) 2083 paPpnMdlPfn = paPpn; 2084 else 2085 AssertFailedReturn(STATUS_INVALID_PARAMETER); 2086 2087 /* Store Mdl page numbers into the level 1 description pages. */ 2088 for (unsigned i = 0; i < pMob->cbMob >> PAGE_SHIFT; ++i) 2089 paPpnMdlPfn[i] = paMdlPfn[i]; 2090 } 2091 return STATUS_SUCCESS; 2092 } 2093 2094 2095 NTSTATUS SvgaMobFillPageTableForMemObj(VBOXWDDM_EXT_VMSVGA *pSvga, 2096 PVMSVGAMOB pMob, 2097 RTR0MEMOBJ hMemObj) 2098 { 2099 RT_NOREF(pSvga); 2100 2101 if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_0) 2102 pMob->base = RTR0MemObjGetPagePhysAddr(hMemObj, 0) >> PAGE_SHIFT; 2103 else 2104 { 2105 /* The first of pages is alway the base. It is either the level 2 page or the single level 1 page */ 2106 pMob->base = RTR0MemObjGetPagePhysAddr(pMob->hMemObjPT, 0) >> PAGE_SHIFT; 2107 2108 PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObjPT); 2109 PPN64 *paPpnMob; 2110 if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2) 2111 paPpnMob = &paPpn[PAGE_SIZE / sizeof(PPN64)]; /* Level 1 pages follow the level 2 page. */ 2112 else if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_1) 2113 paPpnMob = paPpn; 2114 else 2115 AssertFailedReturn(STATUS_INVALID_PARAMETER); 2116 2117 /* Store page numbers into the level 1 description pages. */ 2118 for (unsigned i = 0; i < pMob->cbMob >> PAGE_SHIFT; ++i) 2119 paPpnMob[i] = RTR0MemObjGetPagePhysAddr(hMemObj, i) >> PAGE_SHIFT;; 2120 } 2121 return STATUS_SUCCESS; 2285 struct VMSVGACOTFREE 2286 { 2287 PVMSVGAMOB pMob; 2288 RTR0MEMOBJ hMemObj; 2289 }; 2290 2291 2292 static DECLCALLBACK(void) svgaCOTMobFreeCb(VBOXWDDM_EXT_VMSVGA *pSvga, void *pvData, uint32_t cbData) 2293 { 2294 AssertReturnVoid(cbData == sizeof(struct VMSVGACOTFREE)); 2295 struct VMSVGACOTFREE *p = (struct VMSVGACOTFREE *)pvData; 2296 SvgaMobFree(pSvga, p->pMob); 2297 RTR0MemObjFree(p->hMemObj, true); 2122 2298 } 2123 2299 … … 2152 2328 sizeof(SVGACOTableDXUAViewEntry), 2153 2329 }; 2154 2155 /** @todo Grow COTable. Readback and delete old mob. */ 2156 Assert(pCOT->cEntries == 0); 2330 AssertCompile(RT_ELEMENTS(pSvgaContext->aCOT) == RT_ELEMENTS(s_acbEntry)); 2157 2331 2158 2332 uint32_t cbRequired = (id + 1) * s_acbEntry[enmType]; … … 2161 2335 /* Try to double the current size. */ 2162 2336 uint32_t cbCOT = pCOT->cEntries ? pCOT->cEntries * s_acbEntry[enmType] : PAGE_SIZE; 2163 cbCOT += PAGE_SIZE * 15; /// @todo Large enough. Remove this line and implement COTable reallocation.2164 2337 while (cbRequired > cbCOT) 2165 2338 cbCOT *= 2; … … 2177 2350 Status); 2178 2351 2179 Status = Svga MobFillPageTableForMemObj(pSvga, pMob, hMemObjCOT);2352 Status = SvgaGboFillPageTableForMemObj(&pMob->gbo, hMemObjCOT); 2180 2353 AssertReturnStmt(NT_SUCCESS(Status), 2181 2354 SvgaMobFree(pSvga, pMob); RTR0MemObjFree(hMemObjCOT, true), … … 2184 2357 /* Emit commands. */ 2185 2358 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DEFINE_GB_MOB64, sizeof(SVGA3dCmdDefineGBMob64), SVGA3D_INVALID_ID); 2186 AssertReturnStmt(pvCmd, 2187 SvgaMobFree(pSvga, pMob); RTR0MemObjFree(hMemObjCOT, true), 2188 STATUS_INSUFFICIENT_RESOURCES); 2189 2190 SVGA3dCmdDefineGBMob64 *pCmd1 = (SVGA3dCmdDefineGBMob64 *)pvCmd; 2191 pCmd1->mobid = VMSVGAMOB_ID(pMob); 2192 pCmd1->ptDepth = pMob->enmMobFormat; 2193 pCmd1->base = pMob->base; 2194 pCmd1->sizeInBytes = pMob->cbMob; 2195 SvgaCmdBufCommit(pSvga, sizeof(*pCmd1)); 2196 2197 pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DX_SET_COTABLE, sizeof(SVGA3dCmdDXSetCOTable), SVGA3D_INVALID_ID); 2198 AssertReturnStmt(pvCmd, 2199 SvgaMobFree(pSvga, pMob); RTR0MemObjFree(hMemObjCOT, true), 2200 STATUS_INSUFFICIENT_RESOURCES); 2201 2202 SVGA3dCmdDXSetCOTable *pCmd2 = (SVGA3dCmdDXSetCOTable *)pvCmd; 2203 pCmd2->cid = pSvgaContext->u32Cid; 2204 pCmd2->mobid = VMSVGAMOB_ID(pMob); 2205 pCmd2->type = enmType; 2206 pCmd2->validSizeInBytes = pCOT->cEntries * s_acbEntry[enmType]; 2207 SvgaCmdBufCommit(pSvga, sizeof(*pCmd2)); 2359 if (pvCmd) 2360 { 2361 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pvCmd; 2362 pCmd->mobid = VMSVGAMOB_ID(pMob); 2363 pCmd->ptDepth = pMob->gbo.enmMobFormat; 2364 pCmd->base = pMob->gbo.base; 2365 pCmd->sizeInBytes = pMob->gbo.cbGbo; 2366 SvgaCmdBufCommit(pSvga, sizeof(*pCmd)); 2367 } 2368 else 2369 AssertFailedReturnStmt(SvgaMobFree(pSvga, pMob); RTR0MemObjFree(hMemObjCOT, true), 2370 STATUS_INSUFFICIENT_RESOURCES); 2371 2372 if (pCOT->cEntries == 0) 2373 { 2374 /* Set the mob for COTable. */ 2375 pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DX_SET_COTABLE, sizeof(SVGA3dCmdDXSetCOTable), SVGA3D_INVALID_ID); 2376 if (pvCmd) 2377 { 2378 SVGA3dCmdDXSetCOTable *pCmd = (SVGA3dCmdDXSetCOTable *)pvCmd; 2379 pCmd->cid = pSvgaContext->u32Cid; 2380 pCmd->mobid = VMSVGAMOB_ID(pMob); 2381 pCmd->type = enmType; 2382 pCmd->validSizeInBytes = pCOT->cEntries * s_acbEntry[enmType]; 2383 SvgaCmdBufCommit(pSvga, sizeof(*pCmd)); 2384 } 2385 else 2386 AssertFailedReturnStmt(SvgaMobFree(pSvga, pMob); RTR0MemObjFree(hMemObjCOT, true), 2387 STATUS_INSUFFICIENT_RESOURCES); 2388 } 2389 else 2390 { 2391 /* Grow COTable and delete old mob. */ 2392 pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DX_GROW_COTABLE, sizeof(SVGA3dCmdDXGrowCOTable), SVGA3D_INVALID_ID); 2393 if (pvCmd) 2394 { 2395 SVGA3dCmdDXGrowCOTable *pCmd = (SVGA3dCmdDXGrowCOTable *)pvCmd; 2396 pCmd->cid = pSvgaContext->u32Cid; 2397 pCmd->mobid = VMSVGAMOB_ID(pMob); 2398 pCmd->type = enmType; 2399 pCmd->validSizeInBytes = pCOT->cEntries * s_acbEntry[enmType]; 2400 SvgaCmdBufCommit(pSvga, sizeof(*pCmd)); 2401 } 2402 else 2403 AssertFailedReturnStmt(SvgaMobFree(pSvga, pMob); RTR0MemObjFree(hMemObjCOT, true), 2404 STATUS_INSUFFICIENT_RESOURCES); 2405 2406 pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DESTROY_GB_MOB, sizeof(SVGA3dCmdDestroyGBMob), SVGA3D_INVALID_ID); 2407 if (pvCmd) 2408 { 2409 SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pvCmd; 2410 pCmd->mobid = VMSVGAMOB_ID(pCOT->pMob); 2411 SvgaCmdBufCommit(pSvga, sizeof(*pCmd)); 2412 } 2413 else 2414 AssertFailedReturnStmt(SvgaMobFree(pSvga, pMob); RTR0MemObjFree(hMemObjCOT, true), 2415 STATUS_INSUFFICIENT_RESOURCES); 2416 2417 /* Command buffer completion callback to free the COT. */ 2418 struct VMSVGACOTFREE callbackData; 2419 callbackData.pMob = pCOT->pMob; 2420 callbackData.hMemObj = pCOT->hMemObj; 2421 SvgaCmdBufSetCompletionCallback(pSvga, svgaCOTMobFreeCb, &callbackData, sizeof(callbackData)); 2422 2423 pCOT->pMob = NULL; 2424 pCOT->hMemObj = NIL_RTR0MEMOBJ; 2425 } 2208 2426 2209 2427 SvgaCmdBufFlush(pSvga); -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h
r94927 r95086 73 73 typedef int32_t VMSVGACBHEADERHANDLE; 74 74 #define VMSVGACBHEADER_NIL (-1) 75 76 struct VBOXWDDM_EXT_VMSVGA; 77 typedef DECLCALLBACKTYPE(void, FNCBCOMPLETION, (struct VBOXWDDM_EXT_VMSVGA *pSvga, void *pvData, uint32_t cbData)); 78 typedef FNCBCOMPLETION *PFNCBCOMPLETION; 79 80 typedef struct VMSVGACBCOMPLETION 81 { 82 RTLISTNODE nodeCompletion; /* VMSVGACB::listCompletion */ 83 PFNCBCOMPLETION pfn; /* Function to call. */ 84 uint32_t cb; /* Size of data in bytes. */ 85 /* cb bytes follow. */ 86 } VMSVGACBCOMPLETION, *PVMSVGACBCOMPLETION; 75 87 76 88 typedef enum VMSVGACBTYPE … … 101 113 PHYSICAL_ADDRESS DmaBufferPhysicalAddress; /* VMSVGACB_UMD */ 102 114 } commands; 115 RTLISTANCHOR listCompletion; /* VMSVGACBCOMPLETION to be called on completion. */ 103 116 #ifdef DEBUG 104 117 bool fSubmitted : 1; … … 137 150 } VMSVGACBSTATE, *PVMSVGACBSTATE; 138 151 139 /* Contexts + One shaders mob per context + surfaces. */ 140 #define SVGA3D_MAX_MOBS (SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_SURFACE_IDS) 141 142 typedef struct VMSVGAMOB 143 { 144 AVLU32NODECORE core; /* AVL entry. Key is mobid, allocated by the miniport. */ 145 uint32_t cbMob; /* Size of mob in bytes. */ 146 uint32_t cDescriptionPages; /* How many pages are required to hold PPN64 page table. */ 152 /* Guest Backed Object: a set of locked pages and a page table for the host to access. */ 153 typedef struct VMSVGAGBO 154 { 155 uint32_t cbGbo; /* Size of gbo in bytes. */ 156 uint32_t cPTPages; /* How many pages are required to hold PPN64 page table. */ 147 157 SVGAMobFormat enmMobFormat; /* Page table format. */ 148 158 PPN64 base; /* Page which contains the page table. */ 149 159 RTR0MEMOBJ hMemObjPT; /* Page table pages. */ 160 } VMSVGAGBO, *PVMSVGAGBO; 161 162 /* Contexts + One shaders mob per context + surfaces. */ 163 #define SVGA3D_MAX_MOBS (SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_SURFACE_IDS) 164 165 /* Memory OBject: a gbo with an id, possibly bound to an allocation. */ 166 typedef struct VMSVGAMOB 167 { 168 AVLU32NODECORE core; /* AVL entry. Key is mobid, allocated by the miniport. */ 150 169 HANDLE hAllocation; /* Allocation which is bound to the mob. */ 170 VMSVGAGBO gbo; /* Gbo for this mob. */ 151 171 } VMSVGAMOB, *PVMSVGAMOB; 152 172 153 173 #define VMSVGAMOB_ID(a_pMob) ((a_pMob)->core.Key) 174 175 typedef struct VMSVGAOT 176 { 177 VMSVGAGBO gbo; 178 RTR0MEMOBJ hMemObj; 179 uint32_t cEntries; /* How many objects can be stored in the OTable. */ 180 } VMSVGAOT, *PVMSVGAOT; 154 181 155 182 /* VMSVGA specific part of Gallium device extension. */ … … 160 187 /** Pointer to FIFO MMIO region. */ 161 188 volatile uint32_t *pu32FIFO; 162 163 /** Used only with SVGA_CAP_COMMAND_BUFFERS capability. */164 RTR0MEMOBJ hMemObj;165 RTR0PTR pvR0Hdr, pvR0Cmd;166 RTHCPHYS paHdr, paCmd;167 uint32_t u32NumCmdBufs;168 169 RTR0MEMOBJ hMemObjOTables;170 189 171 190 /** … … 190 209 /** Command buffers state. */ 191 210 PVMSVGACBSTATE pCBState; 211 /** Whether the host has generated an IRQ for buffer completion or error. */ 192 212 bool volatile fCommandBufferIrq; 193 213 … … 198 218 KSPIN_LOCK HostObjectsSpinLock; 199 219 220 /** For ids allocation. */ 221 KSPIN_LOCK IdSpinLock; 222 200 223 /** AVL tree for mapping GMR id to the corresponding structure. */ 201 224 AVLU32TREE GMRTree; … … 212 235 /** SVGA data access. */ 213 236 FAST_MUTEX SvgaMutex; 237 238 /** MOB access: MobTree. */ 239 KSPIN_LOCK MobSpinLock; 214 240 215 241 struct … … 219 245 } lastGMRFB; 220 246 221 struct 222 { 223 PVMSVGAMOB pMob; 224 RTR0MEMOBJ hMemObj; 225 } aOT[SVGA_OTABLE_DX_MAX]; 247 VMSVGAOT aOT[SVGA_OTABLE_DX_MAX]; 226 248 227 249 /** Bitmap of used GMR ids. Bit 0 - GMR id 0, etc. */ … … 248 270 RTR0MEMOBJ hMemObj; /* COTable pages. */ 249 271 uint32_t cEntries; /* How many objects can be stored in the COTable. */ 250 uint32_t cNewEntries; /* New size of the COTable for rebind. */251 bool fRebind : 1; /* Mob must be reallocated and host must be informed. */252 272 } VMSVGACOT, *PVMSVGACOT; 253 273 … … 577 597 #endif 578 598 579 NTSTATUS SvgaMobAlloc(VBOXWDDM_EXT_VMSVGA *pSvga, 580 PVMSVGAMOB *ppMob); 599 NTSTATUS SvgaGboInit(VMSVGAGBO *pGbo, uint32_t cPages); 600 void SvgaGboFree(VMSVGAGBO *pGbo); 601 NTSTATUS SvgaGboFillPageTableForMDL(PVMSVGAGBO pGbo, 602 PMDL pMdl, 603 uint32_t MdlOffset); 604 NTSTATUS SvgaGboFillPageTableForMemObj(PVMSVGAGBO pGbo, 605 RTR0MEMOBJ hMemObj); 606 581 607 void SvgaMobFree(VBOXWDDM_EXT_VMSVGA *pSvga, 582 608 PVMSVGAMOB pMob); 609 PVMSVGAMOB SvgaMobQuery(VBOXWDDM_EXT_VMSVGA *pSvga, 610 uint32_t mobid); 583 611 NTSTATUS SvgaMobCreate(VBOXWDDM_EXT_VMSVGA *pSvga, 584 612 PVMSVGAMOB *ppMob, 585 613 uint32_t cMobPages, 586 614 HANDLE hAllocation); 587 NTSTATUS SvgaMobFillPageTableForMDL(VBOXWDDM_EXT_VMSVGA *pSvga,588 PVMSVGAMOB pMob,589 PMDL pMdl,590 uint32_t MdlOffset);591 NTSTATUS SvgaMobFillPageTableForMemObj(VBOXWDDM_EXT_VMSVGA *pSvga,592 PVMSVGAMOB pMob,593 RTR0MEMOBJ hMemObj);594 615 595 616 NTSTATUS SvgaCOTNotifyId(VBOXWDDM_EXT_VMSVGA *pSvga, -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaFifo.cpp
r94635 r95086 446 446 /* Buffer header is not allocated. */ 447 447 pCB->hHeader = VMSVGACBHEADER_NIL; 448 RTListInit(&pCB->listCompletion); 448 449 449 450 *ppCB = pCB; … … 754 755 755 756 757 static void svgaCBCallCompletion(PVBOXWDDM_EXT_VMSVGA pSvga, PVMSVGACB pCB) 758 { 759 PVMSVGACBCOMPLETION pIter, pNext; 760 RTListForEachSafe(&pCB->listCompletion, pIter, pNext, VMSVGACBCOMPLETION, nodeCompletion) 761 { 762 pIter->pfn(pSvga, &pIter[1], pIter->cb); 763 RTListNodeRemove(&pIter->nodeCompletion); 764 RTMemFree(pIter); 765 } 766 } 767 768 756 769 /** Process command buffers processed by the host at DPC level. 757 770 * … … 812 825 /* Just delete the buffer. */ 813 826 RTListNodeRemove(&pIter->nodeQueue); 827 svgaCBCallCompletion(pSvga, pIter); 814 828 svgaCBFree(pCBState, pIter); 815 829 break; … … 841 855 842 856 857 void SvgaCmdBufSetCompletionCallback(PVBOXWDDM_EXT_VMSVGA pSvga, PFNCBCOMPLETION pfn, void const *pv, uint32_t cb) 858 { 859 VMSVGACBCOMPLETION *p = (VMSVGACBCOMPLETION *)RTMemAlloc(sizeof(VMSVGACBCOMPLETION) + cb); 860 AssertReturnVoid(p); 861 862 p->pfn = pfn; 863 p->cb = cb; 864 memcpy(&p[1], pv, cb); 865 866 PVMSVGACBSTATE pCBState = pSvga->pCBState; 867 ExAcquireFastMutex(&pCBState->CBCurrentMutex); 868 RTListAppend(&pCBState->pCBCurrent->listCompletion, &p->nodeCompletion); 869 ExReleaseFastMutex(&pCBState->CBCurrentMutex); 870 } 871 872 843 873 NTSTATUS SvgaCmdBufDestroy(PVBOXWDDM_EXT_VMSVGA pSvga) 844 874 { 875 /** PVMSVGACBSTATE pCBState as parameter. */ 845 876 PVMSVGACBSTATE pCBState = pSvga->pCBState; 846 877 if (pCBState == NULL) … … 878 909 NTSTATUS SvgaCmdBufInit(PVBOXWDDM_EXT_VMSVGA pSvga) 879 910 { 911 /** PVMSVGACBSTATE *ppCBState as parameter. */ 880 912 NTSTATUS Status; 881 913 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaFifo.h
r94631 r95086 41 41 void SvgaCmdBufFlush(PVBOXWDDM_EXT_VMSVGA pSvga); 42 42 void SvgaCmdBufProcess(PVBOXWDDM_EXT_VMSVGA pSvga); 43 void SvgaCmdBufSetCompletionCallback(PVBOXWDDM_EXT_VMSVGA pSvga, PFNCBCOMPLETION pfn, void const *pv, uint32_t cb); 43 44 44 45 NTSTATUS SvgaCmdBufAllocUMD(PVBOXWDDM_EXT_VMSVGA pSvga, PHYSICAL_ADDRESS DmaBufferPhysicalAddress, -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPDX.cpp
r95010 r95086 129 129 if (NT_SUCCESS(Status)) 130 130 { 131 Status = Svga MobFillPageTableForMemObj(pSvga, pAllocation->dx.gb.pMob, pAllocation->dx.gb.hMemObjGB);131 Status = SvgaGboFillPageTableForMemObj(&pAllocation->dx.gb.pMob->gbo, pAllocation->dx.gb.hMemObjGB); 132 132 Assert(NT_SUCCESS(Status)); 133 133 if (NT_SUCCESS(Status)) … … 140 140 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pvCmd; 141 141 pCmd->mobid = VMSVGAMOB_ID(pAllocation->dx.gb.pMob); 142 pCmd->ptDepth = pAllocation->dx.gb.pMob-> enmMobFormat;143 pCmd->base = pAllocation->dx.gb.pMob-> base;144 pCmd->sizeInBytes = pAllocation->dx.gb.pMob-> cbMob;142 pCmd->ptDepth = pAllocation->dx.gb.pMob->gbo.enmMobFormat; 143 pCmd->base = pAllocation->dx.gb.pMob->gbo.base; 144 pCmd->sizeInBytes = pAllocation->dx.gb.pMob->gbo.cbGbo; 145 145 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDefineGBMob64)); 146 146 } … … 721 721 AssertReturn(NT_SUCCESS(Status), Status); 722 722 723 Status = Svga MobFillPageTableForMDL(pSvga, pMob, pBuildPagingBuffer->MapApertureSegment.pMdl,723 Status = SvgaGboFillPageTableForMDL(&pMob->gbo, pBuildPagingBuffer->MapApertureSegment.pMdl, 724 724 pBuildPagingBuffer->MapApertureSegment.MdlOffset); 725 725 AssertReturnStmt(NT_SUCCESS(Status), SvgaMobFree(pSvga, pMob), Status); … … 737 737 return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 738 738 } 739 740 /* Add to the container. */741 ExAcquireFastMutex(&pSvga->SvgaMutex);742 RTAvlU32Insert(&pSvga->MobTree, &pMob->core);743 ExReleaseFastMutex(&pSvga->SvgaMutex);744 739 745 740 pAllocation->dx.mobid = VMSVGAMOB_ID(pMob); … … 755 750 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pu8Cmd; 756 751 pCmd->mobid = VMSVGAMOB_ID(pMob); 757 pCmd->ptDepth = pMob-> enmMobFormat;758 pCmd->base = pMob-> base;759 pCmd->sizeInBytes = pMob-> cbMob;752 pCmd->ptDepth = pMob->gbo.enmMobFormat; 753 pCmd->base = pMob->gbo.base; 754 pCmd->sizeInBytes = pMob->gbo.cbGbo; 760 755 pu8Cmd += sizeof(*pCmd); 761 756 } … … 811 806 812 807 /* Find the mob. */ 813 ExAcquireFastMutex(&pSvga->SvgaMutex); 814 PVMSVGAMOB pMob = (PVMSVGAMOB)RTAvlU32Get(&pSvga->MobTree, pAllocation->dx.mobid); 815 ExReleaseFastMutex(&pSvga->SvgaMutex); 808 PVMSVGAMOB pMob = SvgaMobQuery(pSvga, pAllocation->dx.mobid); 816 809 AssertReturn(pMob, STATUS_INVALID_PARAMETER); 817 810 … … 903 896 } 904 897 905 /* Fill RenderData description in any case, it will be ignored if the above code failed. */ 906 GARENDERDATA *pRenderData = (GARENDERDATA *)pBuildPagingBuffer->pDmaBufferPrivateData; 907 pRenderData->u32DataType = GARENDERDATA_TYPE_PAGING; 908 pRenderData->cbData = cbCommands; 909 pRenderData->pFenceObject = NULL; 910 pRenderData->pvDmaBuffer = pBuildPagingBuffer->pDmaBuffer; 911 pRenderData->pHwRenderData = NULL; 912 913 switch (Status) 914 { 915 case STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER: 916 DEBUG_BREAKPOINT_TEST(); 917 RT_FALL_THRU(); 918 case STATUS_SUCCESS: 919 { 898 if ( Status == STATUS_SUCCESS 899 || Status == STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER) 900 { 901 if (cbCommands) 902 { 903 GARENDERDATA *pRenderData = (GARENDERDATA *)pBuildPagingBuffer->pDmaBufferPrivateData; 904 pRenderData->u32DataType = GARENDERDATA_TYPE_PAGING; 905 pRenderData->cbData = cbCommands; 906 pRenderData->pFenceObject = NULL; 907 pRenderData->pvDmaBuffer = pBuildPagingBuffer->pDmaBuffer; 908 pRenderData->pHwRenderData = NULL; 909 920 910 pBuildPagingBuffer->pDmaBuffer = (uint8_t *)pBuildPagingBuffer->pDmaBuffer + cbCommands; 921 911 pBuildPagingBuffer->pDmaBufferPrivateData = (uint8_t *)pBuildPagingBuffer->pDmaBufferPrivateData + sizeof(GARENDERDATA); 922 } break; 923 default: break; 912 } 924 913 } 925 914 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp
r94975 r95086 162 162 PVBOXWDDM_CONTEXT pContext) 163 163 { 164 VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga; 165 NTSTATUS Status; 166 164 167 AssertReturn(pContext->NodeOrdinal == 0, STATUS_NOT_SUPPORTED); 165 168 166 pContext->pSvgaContext = (PVMSVGACONTEXT)GaMemAllocZero(sizeof(VMSVGACONTEXT)); 167 AssertReturn(pContext->pSvgaContext, STATUS_INSUFFICIENT_RESOURCES); 168 169 pContext->pSvgaContext->fDXContext = RT_BOOL(pInfo->u.vmsvga.u32Flags & VBOXWDDM_F_GA_CONTEXT_VGPU10); 170 171 VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga; 169 /* 170 * Allocate SVGA context and initialize it. 171 */ 172 PVMSVGACONTEXT pSvgaContext = (PVMSVGACONTEXT)GaMemAllocZero(sizeof(VMSVGACONTEXT)); 173 AssertReturn(pSvgaContext, STATUS_INSUFFICIENT_RESOURCES); 174 175 pSvgaContext->fDXContext = RT_BOOL(pInfo->u.vmsvga.u32Flags & VBOXWDDM_F_GA_CONTEXT_VGPU10); 176 172 177 uint32_t u32Cid; 173 NTSTATUS Status; 174 if (pContext->pSvgaContext->fDXContext) 178 if (pSvgaContext->fDXContext) 175 179 Status = SvgaDXContextIdAlloc(pSvga, &u32Cid); 176 180 else … … 178 182 if (NT_SUCCESS(Status)) 179 183 { 180 if (p Context->pSvgaContext->fDXContext)184 if (pSvgaContext->fDXContext) 181 185 Status = SvgaDXContextCreate(pSvga, u32Cid); 182 186 else … … 184 188 if (Status == STATUS_SUCCESS) 185 189 { 186 /** @todo Save other pInfo fields. */ 187 RT_NOREF(pInfo); 188 189 /* Init pContext fields, which are relevant to the VMSVGA context. */ 190 pContext->pSvgaContext->u32Cid = u32Cid; 191 192 GALOG(("pGaDevExt = %p, cid = %d (%d)\n", pGaDevExt, u32Cid, pContext->pSvgaContext->fDXContext ? "DX" : "VGPU9")); 190 pSvgaContext->u32Cid = u32Cid; 191 GALOG(("pGaDevExt = %p, cid = %d (%s)\n", pGaDevExt, u32Cid, pSvgaContext->fDXContext ? "DX" : "VGPU9")); 193 192 } 194 193 else 195 194 { 196 195 AssertFailed(); 197 if (p Context->pSvgaContext->fDXContext)196 if (pSvgaContext->fDXContext) 198 197 SvgaDXContextIdFree(pSvga, u32Cid); 199 198 else … … 202 201 } 203 202 204 if (!NT_SUCCESS(Status)) 205 { 206 GaMemFree(pContext->pSvgaContext); 207 pContext->pSvgaContext = 0; 208 } 203 if (NT_SUCCESS(Status)) 204 pContext->pSvgaContext = pSvgaContext; 205 else 206 GaMemFree(pSvgaContext); 209 207 return Status; 210 208 } … … 213 211 PVBOXWDDM_CONTEXT pContext) 214 212 { 213 VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga; 214 215 215 PVMSVGACONTEXT pSvgaContext = pContext->pSvgaContext; 216 216 if (!pSvgaContext) 217 217 return STATUS_SUCCESS; 218 pContext->pSvgaContext = 0;218 pContext->pSvgaContext = NULL; 219 219 220 220 GALOG(("u32Cid = %d\n", pSvgaContext->u32Cid)); 221 222 VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga;223 221 224 222 NTSTATUS Status; 225 223 if (pSvgaContext->fDXContext) 226 224 { 225 for (unsigned i = 0; i < RT_ELEMENTS(pSvgaContext->aCOT); ++i) 226 { 227 PVMSVGACOT pCOT = &pSvgaContext->aCOT[i]; 228 if (pCOT->pMob) 229 { 230 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DX_SET_COTABLE, sizeof(SVGA3dCmdDXSetCOTable), SVGA3D_INVALID_ID); 231 if (pvCmd) 232 { 233 SVGA3dCmdDXSetCOTable *pCmd = (SVGA3dCmdDXSetCOTable *)pvCmd; 234 pCmd->cid = pSvgaContext->u32Cid; 235 pCmd->mobid = SVGA3D_INVALID_ID; 236 pCmd->type = (SVGACOTableType)i; 237 pCmd->validSizeInBytes = 0; 238 SvgaCmdBufCommit(pSvga, sizeof(*pCmd)); 239 } 240 241 pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DESTROY_GB_MOB, sizeof(SVGA3dCmdDestroyGBMob), SVGA3D_INVALID_ID); 242 if (pvCmd) 243 { 244 SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pvCmd; 245 pCmd->mobid = VMSVGAMOB_ID(pCOT->pMob); 246 SvgaCmdBufCommit(pSvga, sizeof(*pCmd)); 247 } 248 249 SvgaMobFree(pSvga, pCOT->pMob); 250 pCOT->pMob = NULL; 251 } 252 253 if (pCOT->hMemObj != NIL_RTR0MEMOBJ) 254 { 255 RTR0MemObjFree(pCOT->hMemObj, true); 256 pCOT->hMemObj = NIL_RTR0MEMOBJ; 257 } 258 } 259 227 260 SvgaDXContextDestroy(pSvga, pSvgaContext->u32Cid); 228 261 Status = SvgaDXContextIdFree(pSvga, pSvgaContext->u32Cid); … … 233 266 Status = SvgaContextIdFree(pSvga, pSvgaContext->u32Cid); 234 267 } 268 269 SvgaFlush(pSvga); 235 270 236 271 GaMemFree(pSvgaContext);
Note:
See TracChangeset
for help on using the changeset viewer.