VirtualBox

Ignore:
Timestamp:
Aug 9, 2021 11:02:15 AM (3 years ago)
Author:
vboxsync
Message:

3D/VMSVGA: Syncing access to command buffers from EMT and FIFO threads, bugref:9845

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

Legend:

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

    r90255 r90578  
    2727#include <iprt/memobj.h>
    2828
    29 static NTSTATUS SvgaCmdBufSubmit(VBOXWDDM_EXT_VMSVGA *pSvga, uint32_t cbSubmit)
    30 {
     29static NTSTATUS SvgaCmdBufSubmit(VBOXWDDM_EXT_VMSVGA *pSvga, uint32_t cbSubmit, uint32_t idx)
     30{
     31    AssertReturn(idx < pSvga->u32NumCmdBufs, VERR_INVALID_PARAMETER);
     32    AssertReturn(cbSubmit <= PAGE_SIZE, VERR_INVALID_PARAMETER);
    3133    int rc = STATUS_SUCCESS;
    32     SVGACBHeader *pHdr = (SVGACBHeader *)pSvga->pvR0Hdr;
     34    SVGACBHeader *pHdr = &((SVGACBHeader *)pSvga->pvR0Hdr)[idx];
     35    RTHCPHYS paHdr = pSvga->paHdr + idx * sizeof(SVGACBHeader);
    3336
    3437    pHdr->status = SVGA_CB_STATUS_NONE;
    3538    pHdr->errorOffset = 0;
    3639    pHdr->id = 0;
    37     pHdr->flags = SVGA_CB_FLAG_NONE;
     40    pHdr->flags = SVGA_CB_FLAG_NO_IRQ;
    3841    pHdr->length = cbSubmit;
    3942    pHdr->ptr.pa = pSvga->paCmd;
    4043
    41     SVGARegWrite(pSvga, SVGA_REG_COMMAND_HIGH, (uint32_t)(pSvga->paHdr >> 32));
    42     SVGARegWrite(pSvga, SVGA_REG_COMMAND_LOW, (uint32_t)pSvga->paHdr | SVGA_CB_CONTEXT_0);
     44    SVGARegWrite(pSvga, SVGA_REG_COMMAND_HIGH, (uint32_t)(paHdr >> 32));
     45    SVGARegWrite(pSvga, SVGA_REG_COMMAND_LOW, (uint32_t)paHdr | SVGA_CB_CONTEXT_0);
    4346
    4447    return rc;
     
    5356    if (enable)
    5457    {
    55         rc = RTR0MemObjAllocPageTag(&pSvga->hMemObj, 2 << PAGE_SHIFT,
     58        pSvga->u32NumCmdBufs = 8;
     59
     60        rc = RTR0MemObjAllocPageTag(&pSvga->hMemObj, 2 * PAGE_SIZE,
    5661                                false /* executable R0 mapping */, "WDDMGA");
    5762
    5863        pSvga->pvR0Hdr = RTR0MemObjAddress(pSvga->hMemObj);
    5964        pSvga->paHdr   = RTR0MemObjGetPagePhysAddr(pSvga->hMemObj, 0/*iPage*/);
     65        memset(pSvga->pvR0Hdr, 0, PAGE_SIZE);
    6066
    6167        pSvga->pvR0Cmd = (uint8_t *)pSvga->pvR0Hdr + PAGE_SIZE;
    6268        pSvga->paCmd   = RTR0MemObjGetPagePhysAddr(pSvga->hMemObj, 1/*iPage*/);
     69        memset(pSvga->pvR0Cmd, 0, PAGE_SIZE);
    6370    }
    6471
     
    6875    pHdr->errorOffset = 0;
    6976    pHdr->id = 0;
    70     pHdr->flags = SVGA_CB_FLAG_NONE;
     77    pHdr->flags = SVGA_CB_FLAG_NO_IRQ;
    7178    pHdr->length = sizeof(uint32_t) + sizeof(SVGADCCmdStartStop);
    7279    pHdr->ptr.pa = pSvga->paCmd;
     
    8794        pSvga->hMemObj = NIL_RTR0MEMOBJ;
    8895    }
     96    else
     97    {
     98        uint32_t idx;
     99
     100        for(idx = 0; idx < pSvga->u32NumCmdBufs; idx++)
     101        {
     102            pHdr->status = SVGA_CB_STATUS_COMPLETED;
     103            pHdr->errorOffset = 0;
     104            pHdr->id = 0;
     105            pHdr->flags = SVGA_CB_FLAG_NO_IRQ;
     106            pHdr->length = 0;
     107            pHdr->ptr.pa = 0;
     108
     109            pHdr++;
     110        }
     111    }
    89112
    90113    AssertRC(rc);
    91114    return rc;
     115}
     116
     117static uint32_t SvgaCmdBufReserve(VBOXWDDM_EXT_VMSVGA *pSvga)
     118{
     119    SVGACBHeader *pHdr = (SVGACBHeader *)pSvga->pvR0Hdr;
     120    uint32_t idx;
     121
     122    for(idx = 0; idx < pSvga->u32NumCmdBufs; idx++)
     123    {
     124        if (ASMAtomicCmpXchgU32((volatile uint32_t *)&pHdr->status, SVGA_CB_STATUS_NONE, SVGA_CB_STATUS_COMPLETED))
     125        {
     126            return idx;
     127        }
     128
     129        pHdr++;
     130    }
     131
     132    return UINT32_MAX;
    92133}
    93134
     
    11281169{
    11291170    NTSTATUS Status = STATUS_SUCCESS;
    1130 
    11311171    uint32_t cbSubmit = 0;
     1172    uint32_t idx = UINT32_MAX;
     1173    void *pvCmd = NULL;
     1174
    11321175    SvgaGenBlitGMRFBToScreen(pSvga, idDstScreen, xSrc, ySrc, pDstRect,
    11331176                             NULL, 0, &cbSubmit);
    11341177
    1135     void *pvCmd;
    1136 
    11371178    if (pSvga->u32Caps & SVGA_CAP_COMMAND_BUFFERS)
    11381179    {
    1139         pvCmd = pSvga->pvR0Cmd;
     1180        idx = SvgaCmdBufReserve(pSvga);
     1181
     1182        if (idx < pSvga->u32NumCmdBufs)
     1183        {
     1184            pvCmd = pSvga->pvR0Cmd;
     1185        }
     1186        else
     1187        {
     1188            GALOGREL(32, ("WDDM: SvgaCmdBufReserve failed\n"));
     1189        }
    11401190    }
    11411191    else
     
    11521202        if (pSvga->u32Caps & SVGA_CAP_COMMAND_BUFFERS)
    11531203        {
    1154             SvgaCmdBufSubmit(pSvga, cbSubmit);
     1204            SvgaCmdBufSubmit(pSvga, cbSubmit, idx);
    11551205        }
    11561206        else
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h

    r90188 r90578  
    6969    RTR0PTR  pvR0Hdr, pvR0Cmd;
    7070    RTHCPHYS paHdr, paCmd;
     71    uint32_t u32NumCmdBufs;
    7172
    7273    /**
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