Changeset 94847 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Video
- Timestamp:
- May 5, 2022 12:50:37 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPDX.cpp
r94835 r94847 283 283 } 284 284 285 286 static NTSTATUS svgaRenderPatches(PVBOXWDDM_CONTEXT pContext, DXGKARG_RENDER *pRender, void *pvDmaBuffer, uint32_t cbDmaBuffer) 287 { 288 /** @todo Verify that patch is within the DMA buffer. */ 289 RT_NOREF(pContext, cbDmaBuffer); 290 NTSTATUS Status = STATUS_SUCCESS; 291 uint32_t cOut = 0; 292 for (unsigned i = 0; i < pRender->PatchLocationListInSize; ++i) 293 { 294 D3DDDI_PATCHLOCATIONLIST const *pIn = &pRender->pPatchLocationListIn[i]; 295 void * const pPatchAddress = (uint8_t *)pvDmaBuffer + pIn->PatchOffset; 296 VBOXDXALLOCATIONTYPE const enmAllocationType = (VBOXDXALLOCATIONTYPE)pIn->DriverId; 297 298 DXGK_ALLOCATIONLIST *pAllocationListEntry = &pRender->pAllocationList[pIn->AllocationIndex]; 299 PVBOXWDDM_OPENALLOCATION pOA = (PVBOXWDDM_OPENALLOCATION)pAllocationListEntry->hDeviceSpecificAllocation; 300 if (pOA) 301 { 302 PVBOXWDDM_ALLOCATION pAllocation = pOA->pAllocation; 303 /* Allocation type determines what the patch is about. */ 304 Assert(pAllocation->dx.desc.enmAllocationType == enmAllocationType); 305 if (enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE) 306 { 307 /* Surfaces might also need a mobid. */ 308 if (pAllocationListEntry->SegmentId == 3) 309 { 310 /* DEFAULT resources only require the sid, because they exist outside the guest. */ 311 if (pAllocation->dx.sid != SVGA3D_INVALID_ID) 312 { 313 *(uint32_t *)pPatchAddress = pAllocation->dx.sid; 314 continue; 315 } 316 } 317 else 318 { 319 /* For Aperture segment, the surface need a mob too. */ 320 if ( pAllocation->dx.sid != SVGA3D_INVALID_ID 321 && pAllocation->dx.mobid != SVGA3D_INVALID_ID) 322 { 323 *(uint32_t *)pPatchAddress = pAllocation->dx.sid; 324 continue; 325 } 326 } 327 } 328 else if (enmAllocationType == VBOXDXALLOCATIONTYPE_SHADERS) 329 { 330 if (pAllocation->dx.mobid != SVGA3D_INVALID_ID) 331 { 332 *(uint32_t *)pPatchAddress = pAllocation->dx.mobid; 333 continue; 334 } 335 } 336 } 337 else 338 { 339 if ( enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE 340 || enmAllocationType == VBOXDXALLOCATIONTYPE_SHADERS) 341 { 342 *(uint32_t *)pPatchAddress = SVGA3D_INVALID_ID; 343 continue; 344 } 345 } 346 347 pRender->pPatchLocationListOut[cOut++] = *pIn; 348 } 349 350 GALOG(("pvDmaBuffer = %p, cbDmaBuffer = %u, cOut = %u\n", pvDmaBuffer, cbDmaBuffer, cOut)); 351 352 pRender->pPatchLocationListOut = &pRender->pPatchLocationListOut[cOut]; 353 return Status; 354 } 355 356 357 NTSTATUS APIENTRY DxgkDdiDXRender(PVBOXWDDM_CONTEXT pContext, DXGKARG_RENDER *pRender) 358 { 359 PVBOXWDDM_DEVICE pDevice = pContext->pDevice; 360 PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter; 361 VBOXWDDM_EXT_GA *pGaDevExt = pDevExt->pGa; 362 363 GALOG(("[%p] Command %p/%d, Dma %p/%d, Private %p/%d, MO %d, S %d, Phys 0x%RX64, AL %p/%d, PLLIn %p/%d, PLLOut %p/%d\n", 364 pContext, 365 pRender->pCommand, pRender->CommandLength, 366 pRender->pDmaBuffer, pRender->DmaSize, 367 pRender->pDmaBufferPrivateData, pRender->DmaBufferPrivateDataSize, 368 pRender->MultipassOffset, pRender->DmaBufferSegmentId, pRender->DmaBufferPhysicalAddress.QuadPart, 369 pRender->pAllocationList, pRender->AllocationListSize, 370 pRender->pPatchLocationListIn, pRender->PatchLocationListInSize, 371 pRender->pPatchLocationListOut, pRender->PatchLocationListOutSize 372 )); 373 374 AssertReturn(pRender->DmaBufferPrivateDataSize >= sizeof(GARENDERDATA), STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER); 375 376 GARENDERDATA *pRenderData = NULL; /* Pointer to the DMA buffer description. */ 377 uint32_t cbPrivateData = 0; /* Bytes to place into the private data buffer. */ 378 uint32_t u32TargetLength = 0; /* Bytes to place into the DMA buffer. */ 379 uint32_t u32ProcessedLength = 0; /* Bytes consumed from command buffer. */ 380 381 /* Calculate where the commands start. */ 382 void const *pvSource = (uint8_t *)pRender->pCommand + pRender->MultipassOffset; 383 uint32_t cbSource = pRender->CommandLength - pRender->MultipassOffset; 384 385 NTSTATUS Status = STATUS_SUCCESS; 386 __try 387 { 388 /* Generate DMA buffer from the supplied command buffer. 389 * Store the command buffer descriptor to pDmaBufferPrivateData. 390 * 391 * The display miniport driver must validate the command buffer. 392 * 393 * Copy commands to the pDmaBuffer. 394 */ 395 Status = SvgaRenderCommandsD3D(pGaDevExt->hw.pSvga, pContext->pSvgaContext, 396 pRender->pDmaBuffer, pRender->DmaSize, pvSource, cbSource, 397 &u32TargetLength, &u32ProcessedLength); 398 if (NT_SUCCESS(Status)) 399 { 400 Status = svgaRenderPatches(pContext, pRender, pRender->pDmaBuffer, u32ProcessedLength); 401 } 402 403 /* Fill RenderData description in any case, it will be ignored if the above code failed. */ 404 pRenderData = (GARENDERDATA *)pRender->pDmaBufferPrivateData; 405 pRenderData->u32DataType = GARENDERDATA_TYPE_RENDER; 406 pRenderData->cbData = u32TargetLength; 407 pRenderData->pFenceObject = NULL; 408 pRenderData->pvDmaBuffer = pRender->pDmaBuffer; /** @todo Should not be needed for D3D context. */ 409 pRenderData->pHwRenderData = NULL; 410 cbPrivateData = sizeof(GARENDERDATA); 411 GALOG(("Status = 0x%x\n", Status)); 412 } 413 __except (EXCEPTION_EXECUTE_HANDLER) 414 { 415 Status = STATUS_INVALID_PARAMETER; 416 } 417 418 switch (Status) 419 { 420 case STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER: 421 pRender->MultipassOffset += u32ProcessedLength; 422 RT_FALL_THRU(); 423 case STATUS_SUCCESS: 424 { 425 Assert(pRenderData); 426 if (u32TargetLength == 0) 427 { 428 DEBUG_BREAKPOINT_TEST(); 429 /* Trigger command submission anyway by increasing pDmaBufferPrivateData */ 430 /* Update the DMA buffer description. */ 431 pRenderData->u32DataType = GARENDERDATA_TYPE_FENCE; 432 pRenderData->cbData = u32TargetLength; 433 /* pRenderData->pFenceObject stays */ 434 pRenderData->pvDmaBuffer = NULL; /* Not used */ 435 } 436 pRender->pDmaBuffer = (uint8_t *)pRender->pDmaBuffer + u32TargetLength; 437 pRender->pDmaBufferPrivateData = (uint8_t *)pRender->pDmaBufferPrivateData + cbPrivateData; 438 } break; 439 default: break; 440 } 441 442 return Status; 443 } 444 445 446 NTSTATUS APIENTRY DxgkDdiDXPresent(const HANDLE hContext, DXGKARG_PRESENT *pPresent) 447 { 448 NTSTATUS Status = STATUS_SUCCESS; 449 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext; 450 PVBOXWDDM_DEVICE pDevice = pContext->pDevice; 451 PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter; 452 453 DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX]; 454 //DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX]; 455 456 if (pPresent->Flags.Blt) 457 { 458 //PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pSrc); 459 //PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDst); 460 461 //GALOGG(GALOG_GROUP_PRESENT, ("Blt: sid=%x -> sid=%x\n", pSrcAlloc->AllocData.hostID, pDstAlloc->AllocData.hostID)); 462 463 DEBUG_BREAKPOINT_TEST(); 464 465 /* Generate empty DMA buffer. 466 * Store the command buffer descriptor to pDmaBufferPrivateData. 467 */ 468 GARENDERDATA *pRenderData = NULL; 469 uint32_t u32TargetLength = 0; 470 uint32_t cbPrivateData = 0; 471 472 if (pPresent->DmaBufferPrivateDataSize >= sizeof(GARENDERDATA)) 473 { 474 /* Fill RenderData description in any case, it will be ignored if the above code failed. */ 475 pRenderData = (GARENDERDATA *)pPresent->pDmaBufferPrivateData; 476 pRenderData->u32DataType = GARENDERDATA_TYPE_PRESENT; 477 pRenderData->cbData = u32TargetLength; 478 pRenderData->pFenceObject = NULL; /* Not a user request, so no user accessible fence object. */ 479 pRenderData->pvDmaBuffer = pPresent->pDmaBuffer; 480 pRenderData->pHwRenderData = NULL; 481 cbPrivateData = sizeof(GARENDERDATA); 482 } 483 else 484 { 485 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 486 } 487 488 switch (Status) 489 { 490 case STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER: 491 if (pRenderData == NULL) 492 { 493 /* Not enough space in pDmaBufferPrivateData. */ 494 break; 495 } 496 RT_FALL_THRU(); 497 case STATUS_SUCCESS: 498 { 499 pPresent->pDmaBuffer = (uint8_t *)pPresent->pDmaBuffer + u32TargetLength; 500 pPresent->pDmaBufferPrivateData = (uint8_t *)pPresent->pDmaBufferPrivateData + cbPrivateData; 501 } break; 502 default: break; 503 } 504 } 505 else if (pPresent->Flags.Flip) 506 { 507 PVBOXWDDM_OPENALLOCATION pOa = (PVBOXWDDM_OPENALLOCATION)pSrc->hDeviceSpecificAllocation; 508 PVBOXWDDM_ALLOCATION pSrcAllocation = pOa->pAllocation; 509 Assert(pSrcAllocation->dx.desc.fPrimary); 510 511 GALOGG(GALOG_GROUP_PRESENT, ("Flip: sid=%u %dx%d\n", 512 pSrcAllocation->dx.sid, pSrcAllocation->dx.desc.surfaceInfo.size.width, pSrcAllocation->dx.desc.surfaceInfo.size.height)); 513 514 /* Generate DMA buffer containing the present commands. 515 * Store the command buffer descriptor to pDmaBufferPrivateData. 516 */ 517 GARENDERDATA *pRenderData = NULL; 518 uint32_t u32TargetLength = 0; 519 uint32_t cbPrivateData = 0; 520 521 if (pPresent->DmaBufferPrivateDataSize >= sizeof(GARENDERDATA)) 522 { 523 void *pvTarget = pPresent->pDmaBuffer; 524 const uint32_t cbTarget = pPresent->DmaSize; 525 /* SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN */ 526 RECT rect; 527 rect.left = 0; 528 rect.top = 0; 529 rect.right = pSrcAllocation->dx.desc.surfaceInfo.size.width; 530 rect.bottom = pSrcAllocation->dx.desc.surfaceInfo.size.height; 531 uint32_t const cInClipRects = pPresent->SubRectCnt - pPresent->MultipassOffset; 532 uint32_t cOutClipRects = 0; 533 Status = SvgaGenBlitSurfaceToScreen(pDevExt->pGa->hw.pSvga, 534 pSrcAllocation->dx.sid, 535 &rect, 536 pSrcAllocation->dx.desc.PrimaryDesc.VidPnSourceId, 537 &rect, 538 cInClipRects, 539 pPresent->pDstSubRects + pPresent->MultipassOffset, 540 pvTarget, cbTarget, &u32TargetLength, &cOutClipRects); 541 if (Status == STATUS_BUFFER_OVERFLOW) 542 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 543 544 if (Status == STATUS_SUCCESS) 545 { 546 if (cOutClipRects < cInClipRects) 547 { 548 /* Not all rectangles were copied. */ 549 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 550 } 551 552 /* Advance the current rectangle index. */ 553 pPresent->MultipassOffset += cOutClipRects; 554 } 555 556 /* Fill RenderData description in any case, it will be ignored if the above code failed. */ 557 pRenderData = (GARENDERDATA *)pPresent->pDmaBufferPrivateData; 558 pRenderData->u32DataType = GARENDERDATA_TYPE_PRESENT; 559 pRenderData->cbData = u32TargetLength; 560 pRenderData->pFenceObject = NULL; /* Not a user request, so no user accessible fence object. */ 561 pRenderData->pvDmaBuffer = pPresent->pDmaBuffer; 562 pRenderData->pHwRenderData = NULL; 563 cbPrivateData = sizeof(GARENDERDATA); 564 } 565 else 566 { 567 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 568 } 569 570 switch (Status) 571 { 572 case STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER: 573 if (pRenderData == NULL) 574 { 575 /* Not enough space in pDmaBufferPrivateData. */ 576 break; 577 } 578 RT_FALL_THRU(); 579 case STATUS_SUCCESS: 580 { 581 pPresent->pDmaBuffer = (uint8_t *)pPresent->pDmaBuffer + u32TargetLength; 582 pPresent->pDmaBufferPrivateData = (uint8_t *)pPresent->pDmaBufferPrivateData + cbPrivateData; 583 } break; 584 default: break; 585 } 586 } 587 else if (pPresent->Flags.ColorFill) 588 { 589 LogRelMax(16, ("ColorFill is not implemented\n")); 590 AssertFailed(); 591 592 /* Generate empty DMA buffer. 593 * Store the command buffer descriptor to pDmaBufferPrivateData. 594 */ 595 GARENDERDATA *pRenderData = NULL; 596 uint32_t u32TargetLength = 0; 597 uint32_t cbPrivateData = 0; 598 599 if (pPresent->DmaBufferPrivateDataSize >= sizeof(GARENDERDATA)) 600 { 601 /* Fill RenderData description in any case, it will be ignored if the above code failed. */ 602 pRenderData = (GARENDERDATA *)pPresent->pDmaBufferPrivateData; 603 pRenderData->u32DataType = GARENDERDATA_TYPE_PRESENT; 604 pRenderData->cbData = u32TargetLength; 605 pRenderData->pFenceObject = NULL; /* Not a user request, so no user accessible fence object. */ 606 pRenderData->pvDmaBuffer = pPresent->pDmaBuffer; 607 pRenderData->pHwRenderData = NULL; 608 cbPrivateData = sizeof(GARENDERDATA); 609 } 610 else 611 { 612 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 613 } 614 615 switch (Status) 616 { 617 case STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER: 618 if (pRenderData == NULL) 619 { 620 /* Not enough space in pDmaBufferPrivateData. */ 621 break; 622 } 623 RT_FALL_THRU(); 624 case STATUS_SUCCESS: 625 { 626 pPresent->pDmaBuffer = (uint8_t *)pPresent->pDmaBuffer + u32TargetLength; 627 pPresent->pDmaBufferPrivateData = (uint8_t *)pPresent->pDmaBufferPrivateData + cbPrivateData; 628 } break; 629 default: break; 630 } 631 } 632 else 633 { 634 WARN(("cmd NOT IMPLEMENTED!! Flags(0x%x)", pPresent->Flags.Value)); 635 Status = STATUS_NOT_SUPPORTED; 636 } 637 638 return Status; 639 } 640 641 642 static NTSTATUS svgaPagingMapApertureSegment(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer, uint32_t *pcbCommands) 643 { 644 VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga; 645 646 /* Define a MOB for the supplied MDL and bind the allocation to the MOB. */ 647 648 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->MapApertureSegment.hAllocation; 649 AssertReturn(pAllocation, STATUS_INVALID_PARAMETER); 650 AssertReturn(pBuildPagingBuffer->MapApertureSegment.SegmentId == 2, STATUS_INVALID_PARAMETER); 651 652 /** @todo Mobs require locked pages. Could DX provide a Mdl without locked pages? */ 653 Assert(pBuildPagingBuffer->MapApertureSegment.pMdl->MdlFlags & MDL_PAGES_LOCKED); 654 655 if (pAllocation->dx.mobid != SVGA3D_INVALID_ID) 656 { 657 AssertFailed(); 658 return STATUS_SUCCESS; 659 } 660 661 PVMSVGAMOB pMob; 662 NTSTATUS Status = SvgaMobCreate(pSvga, &pMob, 663 pBuildPagingBuffer->MapApertureSegment.NumberOfPages, 664 pBuildPagingBuffer->MapApertureSegment.hAllocation); 665 AssertReturn(NT_SUCCESS(Status), Status); 666 667 Status = SvgaMobFillPageTableForMDL(pSvga, pMob, pBuildPagingBuffer->MapApertureSegment.pMdl, 668 pBuildPagingBuffer->MapApertureSegment.MdlOffset); 669 AssertReturnStmt(NT_SUCCESS(Status), SvgaMobFree(pSvga, pMob), Status); 670 671 pAllocation->dx.mobid = VMSVGAMOB_ID(pMob); 672 673 uint32_t cbRequired = sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdDefineGBMob64); 674 if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE) 675 { 676 cbRequired += sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdBindGBSurface); 677 cbRequired += sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdUpdateGBSurface); 678 } 679 680 if (pBuildPagingBuffer->DmaSize < cbRequired) 681 { 682 SvgaMobFree(pSvga, pMob); 683 return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 684 } 685 686 /* Add to the container. */ 687 ExAcquireFastMutex(&pSvga->SvgaMutex); 688 RTAvlU32Insert(&pSvga->MobTree, &pMob->core); 689 ExReleaseFastMutex(&pSvga->SvgaMutex); 690 691 uint8_t *pu8Cmd = (uint8_t *)pBuildPagingBuffer->pDmaBuffer; 692 693 SVGA3dCmdHeader *pHdr = (SVGA3dCmdHeader *)pu8Cmd; 694 pHdr->id = SVGA_3D_CMD_DEFINE_GB_MOB64; 695 pHdr->size = sizeof(SVGA3dCmdDefineGBMob64); 696 pu8Cmd += sizeof(*pHdr); 697 698 { 699 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pu8Cmd; 700 pCmd->mobid = VMSVGAMOB_ID(pMob); 701 pCmd->ptDepth = pMob->enmMobFormat; 702 pCmd->base = pMob->base; 703 pCmd->sizeInBytes = pMob->cbMob; 704 pu8Cmd += sizeof(*pCmd); 705 } 706 707 if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE) 708 { 709 /* Bind. */ 710 pHdr = (SVGA3dCmdHeader *)pu8Cmd; 711 pHdr->id = SVGA_3D_CMD_BIND_GB_SURFACE; 712 pHdr->size = sizeof(SVGA3dCmdBindGBSurface); 713 pu8Cmd += sizeof(*pHdr); 714 715 { 716 SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pu8Cmd; 717 pCmd->sid = pAllocation->dx.sid; 718 pCmd->mobid = VMSVGAMOB_ID(pMob); 719 pu8Cmd += sizeof(*pCmd); 720 } 721 722 /* Update */ 723 pHdr = (SVGA3dCmdHeader *)pu8Cmd; 724 pHdr->id = SVGA_3D_CMD_UPDATE_GB_SURFACE; 725 pHdr->size = sizeof(SVGA3dCmdUpdateGBSurface); 726 pu8Cmd += sizeof(*pHdr); 727 728 { 729 SVGA3dCmdUpdateGBSurface *pCmd = (SVGA3dCmdUpdateGBSurface *)pu8Cmd; 730 pCmd->sid = pAllocation->dx.sid; 731 pu8Cmd += sizeof(*pCmd); 732 } 733 } 734 735 *pcbCommands = (uintptr_t)pu8Cmd - (uintptr_t)pBuildPagingBuffer->pDmaBuffer; 736 737 return STATUS_SUCCESS; 738 } 739 740 static NTSTATUS svgaPagingUnmapApertureSegment(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer, uint32_t *pcbCommands) 741 { 742 VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga; 743 744 /* Unbind the allocation from the MOB and destroy the MOB which is bound to the allocation. */ 745 746 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->UnmapApertureSegment.hAllocation; 747 AssertReturn(pAllocation, STATUS_INVALID_PARAMETER); 748 AssertReturn(pBuildPagingBuffer->UnmapApertureSegment.SegmentId == 2, STATUS_INVALID_PARAMETER); 749 750 if (pAllocation->dx.mobid == SVGA3D_INVALID_ID) 751 { 752 DEBUG_BREAKPOINT_TEST(); 753 return STATUS_SUCCESS; 754 } 755 756 /* Find the mob. */ 757 ExAcquireFastMutex(&pSvga->SvgaMutex); 758 PVMSVGAMOB pMob = (PVMSVGAMOB)RTAvlU32Get(&pSvga->MobTree, pAllocation->dx.mobid); 759 ExReleaseFastMutex(&pSvga->SvgaMutex); 760 AssertReturn(pMob, STATUS_INVALID_PARAMETER); 761 762 uint32_t cbRequired = sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdDestroyGBMob); 763 if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE) 764 { 765 cbRequired += sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdBindGBSurface); 766 } 767 768 if (pBuildPagingBuffer->DmaSize < cbRequired) 769 { 770 SvgaMobFree(pSvga, pMob); 771 return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 772 } 773 774 uint8_t *pu8Cmd = (uint8_t *)pBuildPagingBuffer->pDmaBuffer; 775 776 SVGA3dCmdHeader *pHdr; 777 if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE) 778 { 779 /* Unbind. */ 780 pHdr = (SVGA3dCmdHeader *)pu8Cmd; 781 pHdr->id = SVGA_3D_CMD_BIND_GB_SURFACE; 782 pHdr->size = sizeof(SVGA3dCmdBindGBSurface); 783 pu8Cmd += sizeof(*pHdr); 784 785 { 786 SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pu8Cmd; 787 pCmd->sid = pAllocation->dx.sid; 788 pCmd->mobid = SVGA3D_INVALID_ID; 789 pu8Cmd += sizeof(*pCmd); 790 } 791 } 792 793 pHdr = (SVGA3dCmdHeader *)pu8Cmd; 794 pHdr->id = SVGA_3D_CMD_DESTROY_GB_MOB; 795 pHdr->size = sizeof(SVGA3dCmdDestroyGBMob); 796 pu8Cmd += sizeof(*pHdr); 797 798 { 799 SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pu8Cmd; 800 pCmd->mobid = VMSVGAMOB_ID(pMob); 801 pu8Cmd += sizeof(*pCmd); 802 } 803 804 *pcbCommands = (uintptr_t)pu8Cmd - (uintptr_t)pBuildPagingBuffer->pDmaBuffer; 805 806 SvgaMobFree(pSvga, pMob); 807 pAllocation->dx.mobid = SVGA3D_INVALID_ID; 808 809 return STATUS_SUCCESS; 810 } 811 812 813 NTSTATUS DxgkDdiDXBuildPagingBuffer(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer) 814 { 815 AssertReturn(pBuildPagingBuffer->DmaBufferPrivateDataSize >= sizeof(GARENDERDATA), STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER); 816 817 NTSTATUS Status = STATUS_SUCCESS; 818 uint32_t cbCommands = 0; 819 switch (pBuildPagingBuffer->Operation) 820 { 821 case DXGK_OPERATION_TRANSFER: 822 { 823 DEBUG_BREAKPOINT_TEST(); 824 break; 825 } 826 case DXGK_OPERATION_FILL: 827 { 828 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Fill.hAllocation; 829 RT_NOREF(pAllocation); 830 DEBUG_BREAKPOINT_TEST(); 831 break; 832 } 833 case DXGK_OPERATION_DISCARD_CONTENT: 834 { 835 DEBUG_BREAKPOINT_TEST(); 836 break; 837 } 838 case DXGK_OPERATION_MAP_APERTURE_SEGMENT: 839 { 840 Status = svgaPagingMapApertureSegment(pDevExt, pBuildPagingBuffer, &cbCommands); 841 break; 842 } 843 case DXGK_OPERATION_UNMAP_APERTURE_SEGMENT: 844 { 845 Status = svgaPagingUnmapApertureSegment(pDevExt, pBuildPagingBuffer, &cbCommands); 846 break; 847 } 848 default: 849 AssertFailedStmt(Status = STATUS_NOT_IMPLEMENTED); 850 } 851 852 /* Fill RenderData description in any case, it will be ignored if the above code failed. */ 853 GARENDERDATA *pRenderData = (GARENDERDATA *)pBuildPagingBuffer->pDmaBufferPrivateData; 854 pRenderData->u32DataType = GARENDERDATA_TYPE_PAGING; 855 pRenderData->cbData = cbCommands; 856 pRenderData->pFenceObject = NULL; 857 pRenderData->pvDmaBuffer = pBuildPagingBuffer->pDmaBuffer; 858 pRenderData->pHwRenderData = NULL; 859 860 switch (Status) 861 { 862 case STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER: 863 AssertFailed(); /** @todo test */ 864 RT_FALL_THRU(); 865 case STATUS_SUCCESS: 866 { 867 pBuildPagingBuffer->pDmaBuffer = (uint8_t *)pBuildPagingBuffer->pDmaBuffer + cbCommands; 868 pBuildPagingBuffer->pDmaBufferPrivateData = (uint8_t *)pBuildPagingBuffer->pDmaBufferPrivateData + sizeof(GARENDERDATA); 869 } break; 870 default: break; 871 } 872 873 return Status; 874 } 875
Note:
See TracChangeset
for help on using the changeset viewer.