VirtualBox

Ignore:
Timestamp:
May 9, 2022 6:48:47 AM (3 years ago)
Author:
vboxsync
Message:

WDDM: Fill and DiscardContent paging operations; various fixes. bugref:9845

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h

    r94889 r94927  
    209209        uint32_t                sid;                        /* For surfaces. */
    210210        uint32_t                mobid;                      /* For surfaces and shaders. */
     211        uint32_t                SegmentId;                  /* Segment of the allocation. */
     212        union
     213        {
     214            PMDL                pMDL;                       /* Guest backing for aperture segment 2. */
     215            struct
     216            {
     217                RTR0MEMOBJ      hMemObjGB;                  /* Guest backing pages for host segment 3. */
     218                struct VMSVGAMOB *pMob;                     /* Mob for the pages. */
     219            } gb;
     220        };
    211221    } dx;
    212222#endif /* VBOX_WITH_VMSVGA3D_DX */
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp

    r94881 r94927  
    16041604static void vmsvgaDXGetSegmentDescription(PVBOXMP_DEVEXT pDevExt, int idxSegment, VBOXDXSEGMENTDESCRIPTOR *pDesc)
    16051605{
     1606    /** @todo 2 segments for pDevExt->fLegacy flag. */
    16061607    /* 3 segments:
    16071608     * 1: The usual VRAM, CpuVisible;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp

    r94881 r94927  
    19651965
    19661966    NTSTATUS Status;
     1967    AssertCompile(NIL_RTR0MEMOBJ == 0);
    19671968
    19681969    *ppMob = (PVMSVGAMOB)GaMemAllocZero(sizeof(VMSVGAMOB));
     
    19861987        ExReleaseFastMutex(&pSvga->SvgaMutex);
    19871988
    1988         if (pMob->hMemObj)
    1989         {
    1990             int rc = RTR0MemObjFree(pMob->hMemObj, true);
     1989        if (pMob->hMemObjPT != NIL_RTR0MEMOBJ)
     1990        {
     1991            int rc = RTR0MemObjFree(pMob->hMemObjPT, true);
    19911992            AssertRC(rc);
     1993            pMob->hMemObjPT = NIL_RTR0MEMOBJ;
    19921994        }
    19931995
     
    20352037    if (pMob->cDescriptionPages)
    20362038    {
    2037         int rc = RTR0MemObjAllocPageTag(&pMob->hMemObj, pMob->cDescriptionPages * PAGE_SIZE,
     2039        int rc = RTR0MemObjAllocPageTag(&pMob->hMemObjPT, pMob->cDescriptionPages * PAGE_SIZE,
    20382040                                        false /* executable R0 mapping */, "VMSVGAMOB");
    20392041        AssertRCReturnStmt(rc, SvgaMobFree(pSvga, pMob), STATUS_INSUFFICIENT_RESOURCES);
     
    20442046             * Skip the level 2 page at index 0.
    20452047             */
    2046             PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObj);
     2048            PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObjPT);
    20472049            for (unsigned i = 1; i < pMob->cDescriptionPages; ++i)
    2048                 paPpn[i - 1] = RTR0MemObjGetPagePhysAddr(pMob->hMemObj, i) >> PAGE_SHIFT;
     2050                paPpn[i - 1] = RTR0MemObjGetPagePhysAddr(pMob->hMemObjPT, i) >> PAGE_SHIFT;
    20492051        }
    20502052    }
     
    20722074    {
    20732075        /* The first of pages is alway the base. It is either the level 2 page or the single level 1 page */
    2074         pMob->base = RTR0MemObjGetPagePhysAddr(pMob->hMemObj, 0) >> PAGE_SHIFT;
    2075 
    2076         PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObj);
     2076        pMob->base = RTR0MemObjGetPagePhysAddr(pMob->hMemObjPT, 0) >> PAGE_SHIFT;
     2077
     2078        PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObjPT);
    20772079        PPN64 *paPpnMdlPfn;
    20782080        if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2)
     
    21022104    {
    21032105        /* The first of pages is alway the base. It is either the level 2 page or the single level 1 page */
    2104         pMob->base = RTR0MemObjGetPagePhysAddr(pMob->hMemObj, 0) >> PAGE_SHIFT;
    2105 
    2106         PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObj);
     2106        pMob->base = RTR0MemObjGetPagePhysAddr(pMob->hMemObjPT, 0) >> PAGE_SHIFT;
     2107
     2108        PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObjPT);
    21072109        PPN64 *paPpnMob;
    21082110        if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2)
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h

    r94881 r94927  
    147147    SVGAMobFormat               enmMobFormat;               /* Page table format. */
    148148    PPN64                       base;                       /* Page which contains the page table. */
    149     RTR0MEMOBJ                  hMemObj                  /* Page table pages. */
     149    RTR0MEMOBJ                  hMemObjPT;                  /* Page table pages. */
    150150    HANDLE                      hAllocation;                /* Allocation which is bound to the mob. */
    151151} VMSVGAMOB, *PVMSVGAMOB;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaRender.cpp

    r94835 r94927  
    18131813{
    18141814    SVGA3dCmdDXDefineDepthStencilView_v2 *pCmd = (SVGA3dCmdDXDefineDepthStencilView_v2 *)&pHeader[1];
    1815     RT_NOREF(pSvga, pSvgaContext, pCmd);
    1816     return STATUS_SUCCESS;
     1815    DEBUG_VERIFYCMD_RETURN();
     1816    return SvgaCOTNotifyId(pSvga, pSvgaContext, SVGA_COTABLE_DSVIEW, pCmd->depthStencilViewId);
    18171817}
    18181818
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPDX.cpp

    r94904 r94927  
    2727#include "SvgaHw.h"
    2828
     29#include <iprt/memobj.h>
    2930
    3031bool SvgaIsDXSupported(PVBOXMP_DEVEXT pDevExt)
     
    3637
    3738
    38 static NTSTATUS svgaCreateSurfaceForAllocation(PVBOXWDDM_EXT_GA pGaDevExt, PVBOXWDDM_ALLOCATION pAllocation)
    39 {
    40     VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga;
     39static NTSTATUS svgaCreateSurfaceForAllocation(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation)
     40{
    4141    NTSTATUS Status = SvgaSurfaceIdAlloc(pSvga, &pAllocation->dx.sid);
     42    Assert(NT_SUCCESS(Status));
    4243    if (NT_SUCCESS(Status))
    4344    {
     
    5859        }
    5960        else
    60             Status = STATUS_INSUFFICIENT_RESOURCES;
    61     }
     61            AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES);
     62
     63        if (NT_SUCCESS(Status))
     64        {
     65            if (pAllocation->dx.SegmentId == 3)
     66            {
     67                pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_BIND_GB_SURFACE, sizeof(SVGA3dCmdBindGBSurface), SVGA3D_INVALID_ID);
     68                if (pvCmd)
     69                {
     70                    SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pvCmd;
     71                    pCmd->sid = pAllocation->dx.sid;
     72                    pCmd->mobid = pAllocation->dx.mobid;
     73                    SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdBindGBSurface));
     74                }
     75                else
     76                    AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES);
     77            }
     78        }
     79    }
     80
     81    if (!NT_SUCCESS(Status))
     82        SvgaSurfaceIdFree(pSvga, pAllocation->dx.sid);
     83
    6284    return Status;
    6385}
    6486
    6587
     88static void svgaFreeGBMobForAllocation(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation)
     89{
     90    AssertReturnVoid(pAllocation->dx.SegmentId == 3);
     91
     92    void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DESTROY_GB_MOB, sizeof(SVGA3dCmdDestroyGBMob), SVGA3D_INVALID_ID);
     93    if (pvCmd)
     94    {
     95        SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pvCmd;
     96        pCmd->mobid = VMSVGAMOB_ID(pAllocation->dx.gb.pMob);
     97        SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDestroyGBMob));
     98    }
     99
     100    if (pAllocation->dx.gb.pMob)
     101    {
     102        SvgaMobFree(pSvga, pAllocation->dx.gb.pMob);
     103        pAllocation->dx.gb.pMob = NULL;
     104    }
     105
     106    if (pAllocation->dx.gb.hMemObjGB != NIL_RTR0MEMOBJ)
     107    {
     108        RTR0MemObjFree(pAllocation->dx.gb.hMemObjGB, true);
     109        pAllocation->dx.gb.hMemObjGB = NIL_RTR0MEMOBJ;
     110    }
     111
     112    pAllocation->dx.mobid = SVGA3D_INVALID_ID;
     113}
     114
     115
     116static NTSTATUS svgaCreateGBMobForAllocation(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation)
     117{
     118    AssertReturn(pAllocation->dx.SegmentId == 3, STATUS_INVALID_PARAMETER);
     119
     120    uint32_t const cbGB = RT_ALIGN_32(pAllocation->dx.desc.cbAllocation, PAGE_SIZE);
     121
     122    /* Allocate guest backing pages. */
     123    int rc = RTR0MemObjAllocPageTag(&pAllocation->dx.gb.hMemObjGB, cbGB, false /* executable R0 mapping */, "VMSVGAGB");
     124    AssertRCReturn(rc, STATUS_INSUFFICIENT_RESOURCES);
     125
     126    /* Allocate a new mob. */
     127    NTSTATUS Status = SvgaMobCreate(pSvga, &pAllocation->dx.gb.pMob, cbGB >> PAGE_SHIFT, 0);
     128    Assert(NT_SUCCESS(Status));
     129    if (NT_SUCCESS(Status))
     130    {
     131        Status = SvgaMobFillPageTableForMemObj(pSvga, pAllocation->dx.gb.pMob, pAllocation->dx.gb.hMemObjGB);
     132        Assert(NT_SUCCESS(Status));
     133        if (NT_SUCCESS(Status))
     134        {
     135            pAllocation->dx.mobid = VMSVGAMOB_ID(pAllocation->dx.gb.pMob);
     136
     137            void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DEFINE_GB_MOB64, sizeof(SVGA3dCmdDefineGBMob64), SVGA3D_INVALID_ID);
     138            if (pvCmd)
     139            {
     140                SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pvCmd;
     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;
     145                SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDefineGBMob64));
     146            }
     147            else
     148                AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES);
     149
     150            if (NT_SUCCESS(Status))
     151                return STATUS_SUCCESS;
     152        }
     153    }
     154
     155    svgaFreeGBMobForAllocation(pSvga, pAllocation);
     156    return Status;
     157}
     158
     159
    66160static NTSTATUS svgaCreateAllocationSurface(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation, DXGK_ALLOCATIONINFO *pAllocationInfo)
    67161{
    68     NTSTATUS Status = svgaCreateSurfaceForAllocation(pDevExt->pGa, pAllocation);
    69     AssertReturn(NT_SUCCESS(Status), Status);
     162    VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga;
    70163
    71164    /* Fill data for WDDM. */
     
    87180//            pAllocationInfo->SupportedWriteSegmentSet    = 1; /* VRAM */
    88181//            pAllocationInfo->Flags.CpuVisible            = 1;
     182//
     183//            pAllocation->dx.SegmentId = 1;
    89184//        }
    90185//        else
     
    93188            pAllocationInfo->SupportedReadSegmentSet     = 4; /* Host */
    94189            pAllocationInfo->SupportedWriteSegmentSet    = 4; /* Host */
     190
     191            pAllocation->dx.SegmentId = 3;
    95192        }
    96193    }
     
    103200        pAllocationInfo->SupportedWriteSegmentSet    = 2; /* Aperture */
    104201        pAllocationInfo->Flags.CpuVisible            = 1;
     202
     203        pAllocation->dx.SegmentId = 2;
    105204    }
    106205    else if (pAllocation->dx.desc.surfaceInfo.surfaceFlags
     
    113212        pAllocationInfo->SupportedWriteSegmentSet    = 2; /* Aperture */
    114213        pAllocationInfo->Flags.CpuVisible            = 1;
     214
     215        pAllocation->dx.SegmentId = 2;
    115216    }
    116217    pAllocationInfo->EvictionSegmentSet              = 0;
     
    119220    pAllocationInfo->pAllocationUsageHint            = NULL;
    120221    pAllocationInfo->AllocationPriority              = D3DDDI_ALLOCATIONPRIORITY_NORMAL;
     222
     223    /* Allocations in the host VRAM still need guest backing. */
     224    NTSTATUS Status;
     225    if (pAllocation->dx.SegmentId == 3)
     226    {
     227        Status = svgaCreateGBMobForAllocation(pSvga, pAllocation);
     228        if (NT_SUCCESS(Status))
     229        {
     230            Status = svgaCreateSurfaceForAllocation(pSvga, pAllocation);
     231            if (!NT_SUCCESS(Status))
     232                svgaFreeGBMobForAllocation(pSvga, pAllocation);
     233        }
     234    }
     235    else
     236        Status = svgaCreateSurfaceForAllocation(pSvga, pAllocation);
     237
    121238    return Status;
    122239}
     
    144261
    145262
    146 static NTSTATUS svgaDestroyAllocationSurface(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
    147 {
    148     VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga;
     263static NTSTATUS svgaDestroyAllocationSurface(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation)
     264{
    149265    NTSTATUS Status = STATUS_SUCCESS;
    150266    if (pAllocation->dx.sid != SVGA3D_INVALID_ID)
    151267    {
    152         void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DESTROY_GB_SURFACE, sizeof(SVGA3dCmdDestroyGBSurface), SVGA3D_INVALID_ID);
     268        void *pvCmd;
     269        if (pAllocation->dx.SegmentId == 3)
     270        {
     271            pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_BIND_GB_SURFACE, sizeof(SVGA3dCmdBindGBSurface), SVGA3D_INVALID_ID);
     272            if (pvCmd)
     273            {
     274                SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pvCmd;
     275                pCmd->sid = pAllocation->dx.sid;
     276                pCmd->mobid = SVGA3D_INVALID_ID;
     277                SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdBindGBSurface));
     278            }
     279        }
     280
     281        pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DESTROY_GB_SURFACE, sizeof(SVGA3dCmdDestroyGBSurface), SVGA3D_INVALID_ID);
    153282        if (pvCmd)
    154283        {
     
    157286            SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDestroyGBSurface));
    158287        }
    159         else
    160             Status = STATUS_INSUFFICIENT_RESOURCES;
    161 
    162         if (NT_SUCCESS(Status))
    163             Status = SvgaSurfaceIdFree(pSvga, pAllocation->dx.sid);
     288
     289        Status = SvgaSurfaceIdFree(pSvga, pAllocation->dx.sid);
     290
     291        if (pAllocation->dx.SegmentId == 3)
     292            svgaFreeGBMobForAllocation(pSvga, pAllocation);
     293
     294        pAllocation->dx.sid = SVGA3D_INVALID_ID;
    164295    }
    165296    return Status;
     
    167298
    168299
    169 static NTSTATUS svgaDestroyAllocationShaders(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
    170 {
    171     VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga;
     300static NTSTATUS svgaDestroyAllocationShaders(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation)
     301{
     302    NTSTATUS Status = STATUS_SUCCESS;
    172303    if (pAllocation->dx.mobid != SVGA3D_INVALID_ID)
    173304    {
     
    180311        }
    181312        else
    182             AssertFailedReturn(STATUS_INSUFFICIENT_RESOURCES);
    183     }
    184     return STATUS_SUCCESS;
     313            AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES);
     314
     315        pAllocation->dx.mobid = SVGA3D_INVALID_ID;
     316    }
     317    return Status;
    185318}
    186319
     
    207340    pAllocation->dx.sid = SVGA3D_INVALID_ID;
    208341    pAllocation->dx.mobid = SVGA3D_INVALID_ID;
     342    pAllocation->dx.SegmentId = 0;
     343    pAllocation->dx.pMDL = 0;
    209344
    210345    /* Legacy. Unused. */
     
    237372
    238373    if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE)
    239         Status = svgaDestroyAllocationSurface(pDevExt, pAllocation);
     374        Status = svgaDestroyAllocationSurface(pDevExt->pGa->hw.pSvga, pAllocation);
    240375    else if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SHADERS)
    241         Status = svgaDestroyAllocationShaders(pDevExt, pAllocation);
     376        Status = svgaDestroyAllocationShaders(pDevExt->pGa->hw.pSvga, pAllocation);
    242377    else
    243378        AssertFailedReturn(STATUS_INVALID_PARAMETER);
     
    309444                {
    310445                    /* 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                     }
     446                    Assert(pAllocation->dx.sid != SVGA3D_INVALID_ID);
     447                    Assert(pAllocation->dx.mobid != SVGA3D_INVALID_ID);
     448                    Assert(pAllocation->dx.SegmentId == 3);
     449
     450                    *(uint32_t *)pPatchAddress = pAllocation->dx.sid;
     451                    continue;
    316452                }
    317453                else
    318454                {
    319                     /* For Aperture segment, the surface need a mob too. */
     455                    /* For Aperture segment, the surface need a mob too, which must be created in BuildPagingBuffer. */
    320456                    if (   pAllocation->dx.sid != SVGA3D_INVALID_ID
    321457                        && pAllocation->dx.mobid != SVGA3D_INVALID_ID)
     
    640776
    641777
     778static NTSTATUS svgaPagingFill(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer, uint32_t *pcbCommands)
     779{
     780    VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga;
     781    RT_NOREF(pSvga);
     782
     783    PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Fill.hAllocation;
     784    AssertReturn(pAllocation, STATUS_INVALID_PARAMETER);
     785
     786    AssertReturn((pBuildPagingBuffer->Fill.FillSize & 3) == 0, STATUS_INVALID_PARAMETER);
     787    AssertReturn(   pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_D3D
     788                 || pBuildPagingBuffer->Fill.Destination.SegmentId == pAllocation->dx.SegmentId, STATUS_INVALID_PARAMETER);
     789
     790    NTSTATUS Status = STATUS_SUCCESS;
     791    switch (pBuildPagingBuffer->Fill.Destination.SegmentId)
     792    {
     793        case 1: /* VRAM */
     794        {
     795            uint64_t const offVRAM = pBuildPagingBuffer->Fill.Destination.SegmentAddress.QuadPart;
     796            AssertReturn(   offVRAM < pDevExt->cbVRAMCpuVisible
     797                         && pBuildPagingBuffer->Fill.FillSize <= pDevExt->cbVRAMCpuVisible - offVRAM, STATUS_INVALID_PARAMETER);
     798            ASMMemFill32((uint8_t *)pDevExt->pvVisibleVram + offVRAM, pBuildPagingBuffer->Fill.FillSize, pBuildPagingBuffer->Fill.FillPattern);
     799            break;
     800        }
     801        case 2: /* Aperture */
     802        case 3: /* Host */
     803        {
     804            if (pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_D3D)
     805                break;
     806
     807            void *pvDst;
     808            if (pBuildPagingBuffer->Fill.Destination.SegmentId == 3)
     809            {
     810                AssertReturn(pAllocation->dx.gb.hMemObjGB != NIL_RTR0MEMOBJ, STATUS_INVALID_PARAMETER);
     811                pvDst = RTR0MemObjAddress(pAllocation->dx.gb.hMemObjGB);
     812            }
     813            else
     814            {
     815                AssertReturn(pAllocation->dx.pMDL != NULL, STATUS_INVALID_PARAMETER);
     816                DEBUG_BREAKPOINT_TEST();
     817                pvDst = MmGetSystemAddressForMdlSafe(pAllocation->dx.pMDL, NormalPagePriority);
     818                AssertReturn(pvDst, STATUS_INSUFFICIENT_RESOURCES);
     819            }
     820
     821            /* Fill the guest backing pages. */
     822            uint32_t const cbFill = RT_MIN(pBuildPagingBuffer->Fill.FillSize, pAllocation->dx.desc.cbAllocation);
     823            ASMMemFill32(pvDst, cbFill, pBuildPagingBuffer->Fill.FillPattern);
     824
     825            /* Emit UPDATE_GB_SURFACE */
     826            uint8_t *pu8Cmd = (uint8_t *)pBuildPagingBuffer->pDmaBuffer;
     827            uint32_t cbRequired = sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdUpdateGBSurface);
     828            if (pBuildPagingBuffer->DmaSize < cbRequired)
     829            {
     830                Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
     831                break;
     832            }
     833
     834            SVGA3dCmdHeader *pHdr = (SVGA3dCmdHeader *)pu8Cmd;
     835            pHdr->id   = SVGA_3D_CMD_UPDATE_GB_SURFACE;
     836            pHdr->size = sizeof(SVGA3dCmdUpdateGBSurface);
     837            pu8Cmd += sizeof(*pHdr);
     838
     839            SVGA3dCmdUpdateGBSurface *pCmd = (SVGA3dCmdUpdateGBSurface *)pu8Cmd;
     840            pCmd->sid = pAllocation->dx.sid;
     841            pu8Cmd += sizeof(*pCmd);
     842
     843            *pcbCommands = (uintptr_t)pu8Cmd - (uintptr_t)pBuildPagingBuffer->pDmaBuffer;
     844            break;
     845        }
     846        default:
     847            AssertFailedReturn(STATUS_INVALID_PARAMETER);
     848    }
     849    return Status;
     850}
     851
     852
     853static NTSTATUS svgaPagingDiscardContent(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer, uint32_t *pcbCommands)
     854{
     855    VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga;
     856    RT_NOREF(pSvga);
     857
     858    PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->DiscardContent.hAllocation;
     859    AssertReturn(pAllocation, STATUS_INVALID_PARAMETER);
     860    AssertReturn(   pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_D3D
     861                 || pBuildPagingBuffer->DiscardContent.SegmentId == pAllocation->dx.SegmentId, STATUS_INVALID_PARAMETER);
     862
     863    if (pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_D3D)
     864        return STATUS_SUCCESS;
     865
     866    if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE)
     867    {
     868        /* Emit INVALIDATE_GB_SURFACE */
     869        uint8_t *pu8Cmd = (uint8_t *)pBuildPagingBuffer->pDmaBuffer;
     870        uint32_t cbRequired = sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdInvalidateGBSurface);
     871        if (pBuildPagingBuffer->DmaSize < cbRequired)
     872            return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
     873
     874        SVGA3dCmdHeader *pHdr = (SVGA3dCmdHeader *)pu8Cmd;
     875        pHdr->id   = SVGA_3D_CMD_INVALIDATE_GB_SURFACE;
     876        pHdr->size = sizeof(SVGA3dCmdInvalidateGBSurface);
     877        pu8Cmd += sizeof(*pHdr);
     878
     879        SVGA3dCmdUpdateGBSurface *pCmd = (SVGA3dCmdUpdateGBSurface *)pu8Cmd;
     880        pCmd->sid = pAllocation->dx.sid;
     881        pu8Cmd += sizeof(*pCmd);
     882
     883        *pcbCommands = (uintptr_t)pu8Cmd - (uintptr_t)pBuildPagingBuffer->pDmaBuffer;
     884    }
     885
     886    return STATUS_SUCCESS;
     887}
     888
     889
    642890static NTSTATUS svgaPagingMapApertureSegment(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer, uint32_t *pcbCommands)
    643891{
     
    655903    if (pAllocation->dx.mobid != SVGA3D_INVALID_ID)
    656904    {
    657         AssertFailed();
     905        DEBUG_BREAKPOINT_TEST();
    658906        return STATUS_SUCCESS;
    659907    }
     
    8261074        case DXGK_OPERATION_FILL:
    8271075        {
    828             PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Fill.hAllocation;
    829             RT_NOREF(pAllocation);
    830             DEBUG_BREAKPOINT_TEST();
     1076            Status = svgaPagingFill(pDevExt, pBuildPagingBuffer, &cbCommands);
    8311077            break;
    8321078        }
    8331079        case DXGK_OPERATION_DISCARD_CONTENT:
    8341080        {
    835             DEBUG_BREAKPOINT_TEST();
     1081            Status = svgaPagingDiscardContent(pDevExt, pBuildPagingBuffer, &cbCommands);
    8361082            break;
    8371083        }
Note: See TracChangeset for help on using the changeset viewer.

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