VirtualBox

Ignore:
Timestamp:
May 5, 2025 6:17:33 PM (4 days ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168723
Message:

WDDM: Miniport: unify handling of guest backing memory for surfaces, object tables, etc. bugref:10885

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPDX.cpp

    r106061 r109165  
    55
    66/*
    7  * Copyright (C) 2022-2024 Oracle and/or its affiliates.
     7 * Copyright (C) 2022-2025 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    9999
    100100
    101 static void svgaFreeGBMobForAllocation(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation)
    102 {
    103     AssertReturnVoid(pAllocation->dx.SegmentId == 3 || pAllocation->dx.desc.fPrimary);
    104 
    105     uint32_t cbRequired = 0;
    106     SvgaMobDestroy(pSvga, pAllocation->dx.gb.pMob, NULL, 0, &cbRequired);
    107     void *pvCmd = SvgaCmdBufReserve(pSvga, cbRequired, SVGA3D_INVALID_ID);
    108     if (pvCmd)
    109     {
    110         SvgaMobDestroy(pSvga, pAllocation->dx.gb.pMob, pvCmd, cbRequired, &cbRequired);
    111         SvgaCmdBufCommit(pSvga, cbRequired);
    112     }
    113 
    114     pAllocation->dx.gb.pMob = NULL;
    115     pAllocation->dx.mobid = SVGA3D_INVALID_ID;
    116 }
    117 
    118 
    119 static NTSTATUS svgaCreateGBMobForAllocation(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation)
     101static void svgaDestroyMobForAllocation(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation)
     102{
     103    if (pAllocation->dx.mobid != SVGA3D_INVALID_ID)
     104    {
     105        uint32_t cbRequired = 0;
     106        SvgaMobDestroy(pSvga, SVGA3D_INVALID_ID, NULL, 0, &cbRequired);
     107        void *pvCmd = SvgaCmdBufReserve(pSvga, cbRequired, SVGA3D_INVALID_ID);
     108        if (pvCmd)
     109        {
     110            SvgaMobDestroy(pSvga, pAllocation->dx.mobid, pvCmd, cbRequired, &cbRequired);
     111            SvgaCmdBufCommit(pSvga, cbRequired);
     112        }
     113
     114        pAllocation->dx.mobid = SVGA3D_INVALID_ID;
     115    }
     116}
     117
     118
     119static NTSTATUS svgaDefineMobForAllocation(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation)
    120120{
    121121    AssertReturn(pAllocation->dx.SegmentId == 3 || pAllocation->dx.desc.fPrimary, STATUS_INVALID_PARAMETER);
    122122
    123     uint32_t const cbGB = RT_ALIGN_32(pAllocation->dx.desc.cbAllocation, PAGE_SIZE);
    124 
    125     /* Allocate guest backing pages. */
    126     RTR0MEMOBJ hMemObjGB;
    127     int rc = RTR0MemObjAllocPageTag(&hMemObjGB, cbGB, false /* executable R0 mapping */, "VMSVGAGB");
    128     AssertRCReturn(rc, STATUS_INSUFFICIENT_RESOURCES);
    129 
    130     /* Allocate a new mob. */
    131     NTSTATUS Status = SvgaMobCreate(pSvga, &pAllocation->dx.gb.pMob, cbGB >> PAGE_SHIFT, 0);
    132     Assert(NT_SUCCESS(Status));
     123    /* Allocate a mobid. */
     124    NTSTATUS Status = SvgaMobAlloc(pSvga, &pAllocation->dx.mobid, pAllocation->dx.pGbo);
    133125    if (NT_SUCCESS(Status))
    134126    {
    135         Status = SvgaMobSetMemObj(pAllocation->dx.gb.pMob, hMemObjGB);
    136         Assert(NT_SUCCESS(Status));
    137         if (NT_SUCCESS(Status))
    138         {
    139             pAllocation->dx.mobid = VMSVGAMOB_ID(pAllocation->dx.gb.pMob);
    140 
    141             void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DEFINE_GB_MOB64, sizeof(SVGA3dCmdDefineGBMob64), SVGA3D_INVALID_ID);
    142             if (pvCmd)
    143             {
    144                 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pvCmd;
    145                 pCmd->mobid       = VMSVGAMOB_ID(pAllocation->dx.gb.pMob);
    146                 pCmd->ptDepth     = pAllocation->dx.gb.pMob->gbo.enmMobFormat;
    147                 pCmd->base        = pAllocation->dx.gb.pMob->gbo.base;
    148                 pCmd->sizeInBytes = pAllocation->dx.gb.pMob->gbo.cbGbo;
    149                 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDefineGBMob64));
    150             }
    151             else
    152                 AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES);
    153 
    154             if (NT_SUCCESS(Status))
    155                 return STATUS_SUCCESS;
    156         }
    157     }
    158 
    159     svgaFreeGBMobForAllocation(pSvga, pAllocation);
     127        /* Inform the host about the mob. */
     128        uint32_t cbCmd = 0;
     129        SvgaMobDefine(pSvga, SVGA3D_INVALID_ID, NULL, 0, &cbCmd);
     130        void *pvCmd = SvgaCmdBufReserve(pSvga, cbCmd, SVGA3D_INVALID_ID);
     131        if (pvCmd)
     132        {
     133            SvgaMobDefine(pSvga, pAllocation->dx.mobid, pvCmd, cbCmd, &cbCmd);
     134            SvgaCmdBufCommit(pSvga, cbCmd);
     135            return STATUS_SUCCESS;
     136        }
     137
     138        AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES);
     139        /* Deallocate mobid. */
     140        SvgaMobFree(pSvga, &pAllocation->dx.mobid);
     141    }
     142
    160143    return Status;
    161144}
     
    210193    {
    211194        /* USAGE_STAGING */
    212         /** @todo Maybe use VRAM? */
    213         pAllocationInfo->PreferredSegment.SegmentId0 = 0;
     195        pAllocationInfo->PreferredSegment.Value      = 0;
    214196        pAllocationInfo->SupportedReadSegmentSet     = 2; /* Aperture */
    215197        pAllocationInfo->SupportedWriteSegmentSet    = 2; /* Aperture */
     
    231213    if (pAllocation->dx.SegmentId == 3 || pAllocation->dx.desc.fPrimary)
    232214    {
    233         Status = svgaCreateGBMobForAllocation(pSvga, pAllocation);
     215        uint32_t const cbGB = RT_ALIGN_32(pAllocation->dx.desc.cbAllocation, PAGE_SIZE);
     216
     217        Status = SvgaGboCreate(pSvga, &pAllocation->dx.pGbo, cbGB, "VMSVGAGB");
    234218        if (NT_SUCCESS(Status))
    235219        {
    236             Status = svgaCreateSurfaceForAllocation(pSvga, pAllocation);
     220            Status = svgaDefineMobForAllocation(pSvga, pAllocation);
     221            if (NT_SUCCESS(Status))
     222            {
     223                Status = svgaCreateSurfaceForAllocation(pSvga, pAllocation);
     224                if (!NT_SUCCESS(Status))
     225                    svgaDestroyMobForAllocation(pSvga, pAllocation);
     226            }
     227
    237228            if (!NT_SUCCESS(Status))
    238                 svgaFreeGBMobForAllocation(pSvga, pAllocation);
     229                SvgaGboUnreference(pSvga, &pAllocation->dx.pGbo);
    239230        }
    240231    }
     
    273264    {
    274265        void *pvCmd;
    275         if (pAllocation->dx.SegmentId == 3 || pAllocation->dx.desc.fPrimary)
    276         {
     266        if (pAllocation->dx.mobid != SVGA3D_INVALID_ID)
     267        {
     268            /* Unbind mob */
     269            Assert(pAllocation->dx.SegmentId == 3 || pAllocation->dx.desc.fPrimary);
     270
    277271            pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_BIND_GB_SURFACE, sizeof(SVGA3dCmdBindGBSurface), SVGA3D_INVALID_ID);
    278272            if (pvCmd)
     
    294288
    295289        Status = SvgaSurfaceIdFree(pSvga, pAllocation->dx.sid);
    296 
    297         if (pAllocation->dx.SegmentId == 3 || pAllocation->dx.desc.fPrimary)
    298             svgaFreeGBMobForAllocation(pSvga, pAllocation);
    299 
    300290        pAllocation->dx.sid = SVGA3D_INVALID_ID;
     291
     292        svgaDestroyMobForAllocation(pSvga, pAllocation);
    301293    }
    302294    return Status;
     
    306298static NTSTATUS svgaDestroyAllocationShaders(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation)
    307299{
    308     NTSTATUS Status = STATUS_SUCCESS;
    309     if (pAllocation->dx.mobid != SVGA3D_INVALID_ID)
    310     {
    311         void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DESTROY_GB_MOB, sizeof(SVGA3dCmdDestroyGBMob), SVGA3D_INVALID_ID);
    312         if (pvCmd)
    313         {
    314             SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pvCmd;
    315             pCmd->mobid = pAllocation->dx.mobid;
    316             SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDestroyGBMob));
    317         }
    318         else
    319             AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES);
    320 
    321         pAllocation->dx.mobid = SVGA3D_INVALID_ID;
    322     }
    323     return Status;
     300    svgaDestroyMobForAllocation(pSvga, pAllocation);
     301    return STATUS_SUCCESS;
    324302}
    325303
     
    344322    pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_D3D;
    345323    pAllocation->dx.desc = *(PVBOXDXALLOCATIONDESC)pAllocationInfo->pPrivateDriverData;
    346     pAllocation->dx.desc.cbAllocation = pAllocation->dx.desc.cbAllocation;
    347324    pAllocation->dx.sid = SVGA3D_INVALID_ID;
    348325    pAllocation->dx.mobid = SVGA3D_INVALID_ID;
    349     pAllocation->dx.SegmentId = 0;
    350     pAllocation->dx.pMDL = 0;
     326    //pAllocation->dx.SegmentId = 0;
     327    //pAllocation->dx.pGbo = 0;
    351328
    352329    KeInitializeSpinLock(&pAllocation->OpenLock);
     
    396373    else
    397374        AssertFailedReturn(STATUS_INVALID_PARAMETER);
     375
     376    SvgaGboUnreference(pDevExt->pGa->hw.pSvga, &pAllocation->dx.pGbo);
    398377
    399378    RT_ZERO(*pAllocation);
     
    756735            if (pBuildPagingBuffer->Fill.Destination.SegmentId == 3 || pAllocation->dx.desc.fPrimary)
    757736            {
    758                 AssertReturn(pAllocation->dx.gb.pMob->hMemObj != NIL_RTR0MEMOBJ, STATUS_INVALID_PARAMETER);
    759                 pvDst = RTR0MemObjAddress(pAllocation->dx.gb.pMob->hMemObj);
     737                AssertReturn(pAllocation->dx.pGbo->hMemObj != NIL_RTR0MEMOBJ, STATUS_INVALID_PARAMETER);
     738                pvDst = RTR0MemObjAddress(pAllocation->dx.pGbo->hMemObj);
    760739            }
    761740            else
    762741            {
    763                 AssertReturn(pAllocation->dx.pMDL != NULL, STATUS_INVALID_PARAMETER);
     742                AssertReturn(pAllocation->dx.pGbo->flags.fMdl && pAllocation->dx.pGbo->pMdl != NULL, STATUS_INVALID_PARAMETER);
    764743                DEBUG_BREAKPOINT_TEST();
    765                 pvDst = MmGetSystemAddressForMdlSafe(pAllocation->dx.pMDL, NormalPagePriority);
     744                pvDst = MmGetSystemAddressForMdlSafe(pAllocation->dx.pGbo->pMdl, NormalPagePriority);
    766745                AssertReturn(pvDst, STATUS_INSUFFICIENT_RESOURCES);
    767746            }
     
    855834    }
    856835
    857     PVMSVGAMOB pMob;
    858     NTSTATUS Status = SvgaMobCreate(pSvga, &pMob,
    859                                     pBuildPagingBuffer->MapApertureSegment.NumberOfPages,
    860                                     pBuildPagingBuffer->MapApertureSegment.hAllocation);
    861     AssertReturn(NT_SUCCESS(Status), Status);
    862 
    863     Status = SvgaGboFillPageTableForMDL(&pMob->gbo, pBuildPagingBuffer->MapApertureSegment.pMdl,
    864                                         pBuildPagingBuffer->MapApertureSegment.MdlOffset);
    865     AssertReturnStmt(NT_SUCCESS(Status), SvgaMobFree(pSvga, pMob), Status);
    866 
    867     uint32_t cbRequired = sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdDefineGBMob64);
     836    uint32_t cbRequired = 0;
     837    SvgaMobDefine(pSvga, SVGA3D_INVALID_ID, NULL, 0, &cbRequired);
    868838    if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE)
    869839    {
     
    873843
    874844    if (pBuildPagingBuffer->DmaSize < cbRequired)
    875     {
    876         SvgaMobFree(pSvga, pMob);
    877845        return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
    878     }
    879 
    880     pAllocation->dx.mobid = VMSVGAMOB_ID(pMob);
     846
     847    Assert(pAllocation->dx.pGbo == NULL);
     848
     849    NTSTATUS Status = SvgaGboCreateForMdl(pSvga, &pAllocation->dx.pGbo,
     850                                          pBuildPagingBuffer->MapApertureSegment.NumberOfPages,
     851                                          pBuildPagingBuffer->MapApertureSegment.pMdl,
     852                                          pBuildPagingBuffer->MapApertureSegment.MdlOffset);
     853    AssertReturn(NT_SUCCESS(Status), Status);
     854
     855    Status = SvgaMobAlloc(pSvga, &pAllocation->dx.mobid, pAllocation->dx.pGbo);
     856    AssertReturnStmt(NT_SUCCESS(Status), SvgaGboUnreference(pSvga, &pAllocation->dx.pGbo), Status);
    881857
    882858    uint8_t *pu8Cmd = (uint8_t *)pBuildPagingBuffer->pDmaBuffer;
    883859
    884     SVGA3dCmdHeader *pHdr = (SVGA3dCmdHeader *)pu8Cmd;
    885     pHdr->id   = SVGA_3D_CMD_DEFINE_GB_MOB64;
    886     pHdr->size = sizeof(SVGA3dCmdDefineGBMob64);
    887     pu8Cmd += sizeof(*pHdr);
    888 
    889     {
    890     SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pu8Cmd;
    891     pCmd->mobid       = VMSVGAMOB_ID(pMob);
    892     pCmd->ptDepth     = pMob->gbo.enmMobFormat;
    893     pCmd->base        = pMob->gbo.base;
    894     pCmd->sizeInBytes = pMob->gbo.cbGbo;
    895     pu8Cmd += sizeof(*pCmd);
    896     }
     860    uint32_t cbCmd = 0;
     861    SvgaMobDefine(pSvga, pAllocation->dx.mobid, pu8Cmd,
     862                  cbRequired - ((uintptr_t)pu8Cmd - (uintptr_t)pBuildPagingBuffer->pDmaBuffer),
     863                  &cbCmd);
     864    pu8Cmd += cbCmd;
     865
     866    SVGA3dCmdHeader *pHdr;
    897867
    898868    if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE)
     
    907877        SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pu8Cmd;
    908878        pCmd->sid         = pAllocation->dx.sid;
    909         pCmd->mobid       = VMSVGAMOB_ID(pMob);
     879        pCmd->mobid       = pAllocation->dx.mobid;
    910880        pu8Cmd += sizeof(*pCmd);
    911881        }
     
    945915    }
    946916
    947     /* Find the mob. */
    948     PVMSVGAMOB pMob = SvgaMobQuery(pSvga, pAllocation->dx.mobid);
    949     AssertReturn(pMob, STATUS_INVALID_PARAMETER);
    950 
    951917    uint32_t cbRequired = 0;
    952     SvgaMobDestroy(pSvga, pMob, NULL, 0, &cbRequired);
     918    SvgaMobDestroy(pSvga, SVGA3D_INVALID_ID, NULL, 0, &cbRequired);
    953919    if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE)
    954920        cbRequired += sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdBindGBSurface);
     
    977943
    978944    uint32_t cbCmd = 0;
    979     NTSTATUS Status = SvgaMobDestroy(pSvga, pMob, pu8Cmd,
     945    NTSTATUS Status = SvgaMobDestroy(pSvga, pAllocation->dx.mobid, pu8Cmd,
    980946                                     cbRequired - ((uintptr_t)pu8Cmd - (uintptr_t)pBuildPagingBuffer->pDmaBuffer),
    981947                                     &cbCmd);
     
    984950
    985951    pAllocation->dx.mobid = SVGA3D_INVALID_ID;
     952    SvgaGboUnreference(pSvga, &pAllocation->dx.pGbo);
    986953
    987954    *pcbCommands = (uintptr_t)pu8Cmd - (uintptr_t)pBuildPagingBuffer->pDmaBuffer;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette