VirtualBox

Ignore:
Timestamp:
Mar 6, 2020 11:22:07 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
136362
Message:

WDDM: Miniport: host surface management and shared surface handling, bugref:8893

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Video
Files:
1 added
8 edited

Legend:

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

    r82968 r83222  
    20482048            if (pAlloc->hSharedHandle)
    20492049            {
    2050                 if (i == 0)
    2051                 {
     2050                if (pAlloc->hSharedHandle == (HANDLE)pAlloc->hostID)
     2051                {
     2052                    /* The original shared resource is being destroyed. */
     2053                    Assert(pRc->RcDesc.fFlags.SharedResource);
     2054                }
     2055                else if (i == 0)
     2056                {
     2057                    /* This resource has been opened and maps to a the original shared resource. */
    20522058                    /* Tell miniport to remove the sid -> shared sid mapping. */
    20532059                    IGaDirect3DDevice9Ex *pGaD3DDevice9Ex = NULL;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk

    r82968 r83222  
    153153        wddm/gallium/SvgaCmd.cpp \
    154154        wddm/gallium/SvgaFifo.cpp \
     155        wddm/gallium/SvgaHostObjects.cpp \
    155156        wddm/gallium/SvgaHw.cpp \
    156157        wddm/gallium/VBoxMPGaFence.cpp \
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp

    r82968 r83222  
    7979    if (pSvga)
    8080    {
     81        NTSTATUS Status = SvgaHostObjectsCleanup(pSvga);
     82        Assert(Status == STATUS_SUCCESS); RT_NOREF(Status);
     83
    8184        if (pSvga->pu32GMRBits)
    8285        {
     
    99102        SVGARegWrite(pSvga, SVGA_REG_ENABLE, SVGA_REG_ENABLE_DISABLE);
    100103
    101         NTSTATUS Status = pDxgkInterface->DxgkCbUnmapMemory(pDxgkInterface->DeviceHandle,
    102                                                             (PVOID)pSvga->pu32FIFO);
     104        Status = pDxgkInterface->DxgkCbUnmapMemory(pDxgkInterface->DeviceHandle,
     105                                                   (PVOID)pSvga->pu32FIFO);
    103106        Assert(Status == STATUS_SUCCESS); RT_NOREF(Status);
    104107
     
    125128    /* The spinlock is required for hardware access. Init it as the very first. */
    126129    KeInitializeSpinLock(&pSvga->HwSpinLock);
     130    KeInitializeSpinLock(&pSvga->HostObjectsSpinLock);
    127131    ExInitializeFastMutex(&pSvga->SvgaMutex);
     132    // pSvga->SurfaceTree = NULL;
     133    RTListInit(&pSvga->DeletedHostObjectsList);
    128134
    129135    /* The port IO address is also needed for hardware access. */
     
    173179        else
    174180        {
    175             GALOGREL(("SVGA_ID_2 not supported. Device returned %d\n", u32SvgaId));
     181            GALOGREL(32, ("SVGA_ID_2 not supported. Device returned %d\n", u32SvgaId));
    176182            Status = STATUS_INSUFFICIENT_RESOURCES;
    177183        }
     
    454460
    455461NTSTATUS SvgaSharedSidInsert(VBOXWDDM_EXT_VMSVGA *pSvga,
    456                              GASHAREDSID *pNode,
    457462                             uint32_t u32Sid,
    458463                             uint32_t u32SharedSid)
    459464{
    460     ExAcquireFastMutex(&pSvga->SvgaMutex);
    461 
    462     GALOG(("[%p] %d -> shared %d\n", pSvga, u32Sid, u32SharedSid));
    463 
    464     pNode->Core.Key = u32Sid;
    465     pNode->u32SharedSid = u32SharedSid;
    466     RTAvlU32Insert(&pSvga->SharedSidMap, &pNode->Core);
    467 
    468     ExReleaseFastMutex(&pSvga->SvgaMutex);
     465    /* 'u32Sid' actually maps to 'u32SharedSid'. */
     466    AssertReturn(u32Sid != u32SharedSid, STATUS_INVALID_PARAMETER);
     467
     468    /* Get the surface object, which must be redirected to the 'u32SharedSid'. */
     469    SURFACEOBJECT *pSO = SvgaSurfaceObjectQuery(pSvga, u32Sid);
     470    AssertPtrReturn(pSO, STATUS_INVALID_PARAMETER);
     471
     472    /* The surface must not be redirected yet. */
     473    AssertReturn(SVGAHOSTOBJECTID(&pSO->ho) == pSO->u32SharedSid, STATUS_INVALID_PARAMETER);
     474
     475    /* The surface object to be mapped to. */
     476    SURFACEOBJECT *pSharedSO = SvgaSurfaceObjectQuery(pSvga, u32SharedSid);
     477    AssertReturnStmt(pSharedSO, SvgaSurfaceObjectRelease(pSO), STATUS_INVALID_PARAMETER);
     478
     479    pSO->u32SharedSid = u32SharedSid;
     480
     481    /* Release the redirected surface object only.
     482     * The shared surface object must keep the reference.
     483     */
     484    SvgaSurfaceObjectRelease(pSO);
    469485    return STATUS_SUCCESS;
    470486}
    471487
    472 
    473 GASHAREDSID *SvgaSharedSidRemove(VBOXWDDM_EXT_VMSVGA *pSvga,
    474                                  uint32_t u32Sid)
    475 {
    476     ExAcquireFastMutex(&pSvga->SvgaMutex);
    477 
    478     GALOG(("[%p] %d\n", pSvga, u32Sid));
    479     GASHAREDSID *pNode = (GASHAREDSID *)RTAvlU32Remove(&pSvga->SharedSidMap, u32Sid);
    480 
    481     ExReleaseFastMutex(&pSvga->SvgaMutex);
    482     return pNode;
    483 }
    484 
    485 uint32_t SvgaSharedSidGet(VBOXWDDM_EXT_VMSVGA *pSvga,
    486                           uint32_t u32Sid)
    487 {
    488     ExAcquireFastMutex(&pSvga->SvgaMutex);
    489 
    490     GASHAREDSID *p = (GASHAREDSID *)RTAvlU32Get(&pSvga->SharedSidMap, u32Sid);
    491     if (p)
    492     {
    493         GALOG(("%d -> shared %d\n", u32Sid, p->u32SharedSid));
    494         u32Sid = p->u32SharedSid;
    495     }
    496 
    497     ExReleaseFastMutex(&pSvga->SvgaMutex);
    498     return u32Sid;
     488NTSTATUS SvgaSharedSidRemove(VBOXWDDM_EXT_VMSVGA *pSvga,
     489                             uint32_t u32Sid)
     490{
     491    /* Get the surface object, which was redirected. */
     492    SURFACEOBJECT *pSO = SvgaSurfaceObjectQuery(pSvga, u32Sid);
     493    AssertPtrReturn(pSO, STATUS_INVALID_PARAMETER);
     494
     495    /* The surface must be redirected. */
     496    AssertReturn(SVGAHOSTOBJECTID(&pSO->ho) != pSO->u32SharedSid, STATUS_INVALID_PARAMETER);
     497
     498    /* The shared surface object, which the u32Sid was mapped to. */
     499    SURFACEOBJECT *pSharedSO = SvgaSurfaceObjectQuery(pSvga, pSO->u32SharedSid);
     500    AssertReturnStmt(pSharedSO, SvgaSurfaceObjectRelease(pSO), STATUS_INVALID_PARAMETER);
     501
     502    pSO->u32SharedSid = SVGAHOSTOBJECTID(&pSO->ho);
     503
     504    /* Remove the reference which was added by SvgaSharedSidInsert. */
     505    SvgaSurfaceObjectRelease(pSharedSO);
     506
     507    /* Release both surface objects. */
     508    SvgaSurfaceObjectRelease(pSharedSO);
     509    SvgaSurfaceObjectRelease(pSO);
     510    return STATUS_SUCCESS;
     511}
     512
     513typedef struct SVGAHOSTOBJECTARRAY
     514{
     515    GAHWRENDERDATA hdr;
     516    uint32_t cObjects;
     517    uint32_t u32Reserved;
     518    SVGAHOSTOBJECT *aObjects[(4096 - 2 * sizeof(uint32_t) - sizeof(GAHWRENDERDATA)) / sizeof(void *)];
     519} SVGAHOSTOBJECTARRAY;
     520AssertCompileSize(SVGAHOSTOBJECTARRAY, 4096);
     521
     522NTSTATUS SvgaProcessSurface(VBOXWDDM_EXT_VMSVGA *pSvga,
     523                            uint32_t *pu32Sid,
     524                            SVGAHOSTOBJECTARRAY *pHOA)
     525{
     526    uint32_t const u32Sid = *pu32Sid;
     527    if (u32Sid != SVGA3D_INVALID_ID)
     528    {
     529        SURFACEOBJECT *pSO = NULL;
     530        for (uint32_t i = 0; i < pHOA->cObjects; ++i)
     531        {
     532            if (   pHOA->aObjects[i]->uType == SVGA_HOST_OBJECT_SURFACE
     533                && SVGAHOSTOBJECTID(pHOA->aObjects[i]) == u32Sid)
     534            {
     535                pSO = (SURFACEOBJECT *)pHOA->aObjects[i];
     536                break;
     537            }
     538        }
     539
     540        if (!pSO)
     541        {
     542            pSO = SvgaSurfaceObjectQuery(pSvga, u32Sid);
     543            if (pSO)
     544            {
     545                AssertReturnStmt(pHOA->cObjects < RT_ELEMENTS(pHOA->aObjects),
     546                                 SvgaSurfaceObjectRelease(pSO),
     547                                 STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER);
     548                pHOA->aObjects[pHOA->cObjects++] = &pSO->ho;
     549            }
     550            else
     551            {
     552                GALOGREL(32, ("WDDM: no surface for sid %u\n", u32Sid));
     553                AssertFailed();
     554                /* Ignore the error. */
     555                return STATUS_SUCCESS;
     556            }
     557        }
     558
     559        *pu32Sid = pSO->u32SharedSid;
     560    }
     561    return STATUS_SUCCESS;
     562}
     563
     564static NTSTATUS svgaReleaseHostObjects(uint32_t iStart,
     565                                       SVGAHOSTOBJECTARRAY *pHOA)
     566{
     567    AssertReturn(iStart <= pHOA->cObjects, STATUS_INVALID_PARAMETER);
     568
     569    for (uint32_t i = iStart; i < pHOA->cObjects; ++i)
     570    {
     571        SVGAHOSTOBJECT *pHO = pHOA->aObjects[i];
     572        if (pHO->uType == SVGA_HOST_OBJECT_SURFACE)
     573        {
     574            SURFACEOBJECT *pSO = (SURFACEOBJECT *)pHO;
     575            SvgaSurfaceObjectRelease(pSO);
     576        }
     577        else
     578        {
     579            /* Should never happen. No other types of objects can be in the array. */
     580            AssertFailedReturn(STATUS_ILLEGAL_INSTRUCTION);
     581        }
     582    }
     583
     584    pHOA->cObjects = iStart;
     585
     586    return STATUS_SUCCESS;
     587}
     588
     589NTSTATUS SvgaRenderComplete(PVBOXWDDM_EXT_VMSVGA pSvga,
     590                            GAHWRENDERDATA *pHwRenderData)
     591{
     592    RT_NOREF(pSvga);
     593
     594    SVGAHOSTOBJECTARRAY *pHOA = (SVGAHOSTOBJECTARRAY *)pHwRenderData;
     595
     596    NTSTATUS Status = svgaReleaseHostObjects(0, pHOA);
     597
     598    GaMemFree(pHOA);
     599
     600    return Status;
    499601}
    500602
     
    502604                                  uint32_t u32CmdId,
    503605                                  uint8_t *pu8Cmd,
    504                                   uint32_t cbCmd)
    505 {
    506     RT_NOREF4(pSvga, u32CmdId, pu8Cmd, cbCmd);
    507 
     606                                  uint32_t cbCmd,
     607                                  SVGAHOSTOBJECTARRAY *pHOA)
     608{
    508609    NTSTATUS Status = STATUS_SUCCESS;
    509610
     
    511612    uint8_t *pCommand = (uint8_t *)&pHeader[1];
    512613
     614    uint32_t iStart = pHOA->cObjects;
     615
    513616    switch (u32CmdId)
    514617    {
     
    517620        {
    518621            SVGA3dCmdPresent *p = (SVGA3dCmdPresent *)pCommand;
    519             p->sid = SvgaSharedSidGet(pSvga, p->sid);
     622            Status = SvgaProcessSurface(pSvga, &p->sid, pHOA);
    520623        } break;
    521624        case SVGA_3D_CMD_SETRENDERTARGET:
    522625        {
    523              SVGA3dCmdSetRenderTarget *p = (SVGA3dCmdSetRenderTarget *)pCommand;
    524              p->target.sid = SvgaSharedSidGet(pSvga, p->target.sid);
     626            SVGA3dCmdSetRenderTarget *p = (SVGA3dCmdSetRenderTarget *)pCommand;
     627            Status = SvgaProcessSurface(pSvga, &p->target.sid, pHOA);
    525628        } break;
    526629        case SVGA_3D_CMD_SURFACE_COPY:
    527630        {
    528631            SVGA3dCmdSurfaceCopy *p = (SVGA3dCmdSurfaceCopy *)pCommand;
    529             p->src.sid = SvgaSharedSidGet(pSvga, p->src.sid);
    530             p->dest.sid = SvgaSharedSidGet(pSvga, p->dest.sid);
     632            Status = SvgaProcessSurface(pSvga, &p->src.sid, pHOA);
     633            if (Status == STATUS_SUCCESS)
     634                Status = SvgaProcessSurface(pSvga, &p->dest.sid, pHOA);
    531635        } break;
    532636        case SVGA_3D_CMD_SURFACE_STRETCHBLT:
    533637        {
    534638            SVGA3dCmdSurfaceStretchBlt *p = (SVGA3dCmdSurfaceStretchBlt *)pCommand;
    535             p->src.sid = SvgaSharedSidGet(pSvga, p->src.sid);
    536             p->dest.sid = SvgaSharedSidGet(pSvga, p->dest.sid);
     639            Status = SvgaProcessSurface(pSvga, &p->src.sid, pHOA);
     640            if (Status == STATUS_SUCCESS)
     641                Status = SvgaProcessSurface(pSvga, &p->dest.sid, pHOA);
    537642        } break;
    538643        case SVGA_3D_CMD_SURFACE_DMA:
    539644        {
     645            /// @todo gmrid?
    540646            SVGA3dCmdSurfaceDMA *p = (SVGA3dCmdSurfaceDMA *)pCommand;
    541             p->host.sid = SvgaSharedSidGet(pSvga, p->host.sid);
     647            Status = SvgaProcessSurface(pSvga, &p->host.sid, pHOA);
    542648        } break;
    543649        case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN:
    544650        {
    545651            SVGA3dCmdBlitSurfaceToScreen *p = (SVGA3dCmdBlitSurfaceToScreen *)pCommand;
    546             p->srcImage.sid = SvgaSharedSidGet(pSvga, p->srcImage.sid);
     652            Status = SvgaProcessSurface(pSvga, &p->srcImage.sid, pHOA);
    547653        } break;
    548654        case SVGA_3D_CMD_GENERATE_MIPMAPS:
    549655        {
    550656            SVGA3dCmdGenerateMipmaps *p = (SVGA3dCmdGenerateMipmaps *)pCommand;
    551             p->sid = SvgaSharedSidGet(pSvga, p->sid);
     657            Status = SvgaProcessSurface(pSvga, &p->sid, pHOA);
    552658        } break;
    553659        case SVGA_3D_CMD_ACTIVATE_SURFACE:
    554660        {
    555661            SVGA3dCmdActivateSurface *p = (SVGA3dCmdActivateSurface *)pCommand;
    556             p->sid = SvgaSharedSidGet(pSvga, p->sid);
     662            Status = SvgaProcessSurface(pSvga, &p->sid, pHOA);
    557663        } break;
    558664        case SVGA_3D_CMD_DEACTIVATE_SURFACE:
    559665        {
    560666            SVGA3dCmdDeactivateSurface *p = (SVGA3dCmdDeactivateSurface *)pCommand;
    561             p->sid = SvgaSharedSidGet(pSvga, p->sid);
     667            Status = SvgaProcessSurface(pSvga, &p->sid, pHOA);
    562668        } break;
    563669        case SVGA_3D_CMD_SETTEXTURESTATE:
     
    570676                if (pState->name == SVGA3D_TS_BIND_TEXTURE)
    571677                {
    572                     pState->value = SvgaSharedSidGet(pSvga, pState->value);
     678                    Status = SvgaProcessSurface(pSvga, &pState->value, pHOA);
     679                    if (Status != STATUS_SUCCESS)
     680                        break;
    573681                }
    574682
     
    577685            }
    578686        } break;
    579 
    580         /** @todo Might need (unlikely) SVGA_3D_CMD_DRAWPRIMITIVES SVGA3dVertexDecl::array::surfaceId */
     687        case SVGA_3D_CMD_DRAW_PRIMITIVES:
     688        {
     689            SVGA3dCmdDrawPrimitives *p = (SVGA3dCmdDrawPrimitives *)pCommand;
     690            AssertBreakStmt(cbCmd >= sizeof(SVGA3dCmdDrawPrimitives), Status = STATUS_ILLEGAL_INSTRUCTION);
     691            AssertBreakStmt(   p->numVertexDecls <= SVGA3D_MAX_VERTEX_ARRAYS
     692                            && p->numRanges <= SVGA3D_MAX_DRAW_PRIMITIVE_RANGES, Status = STATUS_ILLEGAL_INSTRUCTION);
     693            AssertBreakStmt(cbCmd >= p->numVertexDecls * sizeof(SVGA3dVertexDecl)
     694                                   + p->numRanges * sizeof(SVGA3dPrimitiveRange), Status = STATUS_ILLEGAL_INSTRUCTION);
     695
     696            /// @todo cid?
     697
     698            SVGA3dVertexDecl *paDecls = (SVGA3dVertexDecl *)&p[1];
     699            SVGA3dPrimitiveRange *paRanges = (SVGA3dPrimitiveRange *)&paDecls[p->numVertexDecls];
     700
     701            uint32_t i;
     702            for (i = 0; i < p->numVertexDecls; ++i)
     703            {
     704                Status = SvgaProcessSurface(pSvga, &paDecls[i].array.surfaceId, pHOA);
     705                if (Status != STATUS_SUCCESS)
     706                    break;
     707            }
     708            if (Status == STATUS_SUCCESS)
     709            {
     710                for (i = 0; i < p->numRanges; ++i)
     711                {
     712                    Status = SvgaProcessSurface(pSvga, &paRanges[i].indexArray.surfaceId, pHOA);
     713                    if (Status != STATUS_SUCCESS)
     714                        break;
     715                }
     716            }
     717        } break;
    581718
    582719        /*
     
    619756            break;
    620757    }
     758
     759    if (Status != STATUS_SUCCESS)
     760    {
     761        svgaReleaseHostObjects(iStart, pHOA);
     762    }
     763
    621764    return Status;
    622765}
     
    636779 * @param pu32TargetLength How many bytes were copied to pvTarget buffer.
    637780 * @param pu32ProcessedLength How many bytes were processed in the pvSource buffer.
     781 * @param ppvHwPrivate The hardware private data. SVGA stores information about host objects there.
    638782 */
    639783NTSTATUS SvgaRenderCommands(PVBOXWDDM_EXT_VMSVGA pSvga,
     
    643787                            uint32_t cbSource,
    644788                            uint32_t *pu32TargetLength,
    645                             uint32_t *pu32ProcessedLength)
     789                            uint32_t *pu32ProcessedLength,
     790                            GAHWRENDERDATA **ppHwRenderData)
    646791{
    647792    /* All commands consist of 32 bit dwords. */
    648793    AssertReturn(cbSource % sizeof(uint32_t) == 0, STATUS_ILLEGAL_INSTRUCTION);
     794
     795    SVGAHOSTOBJECTARRAY *pHO = (SVGAHOSTOBJECTARRAY *)GaMemAlloc(sizeof(SVGAHOSTOBJECTARRAY));
     796    if (!pHO)
     797        return STATUS_INSUFFICIENT_RESOURCES;
     798    pHO->cObjects = 0;
     799    pHO->u32Reserved = 0;
    649800
    650801    NTSTATUS Status = STATUS_SUCCESS;
     
    691842
    692843        /* Update the command in dst place if necessary. */
    693         Status = svgaUpdateCommand(pSvga, u32CmdId, pu8Dst, cbCmd);
    694         AssertBreak(Status == STATUS_SUCCESS);
     844        Status = svgaUpdateCommand(pSvga, u32CmdId, pu8Dst, cbCmd, pHO);
     845        if (Status != STATUS_SUCCESS)
     846        {
     847            Assert(Status == STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER);
     848            break;
     849        }
    695850
    696851        pu8Src += cbCmd;
     
    698853    }
    699854
    700     *pu32TargetLength = pu8Dst - (uint8_t *)pvTarget;
    701     *pu32ProcessedLength = pu8Src - (uint8_t *)pvSource;
     855    if (   Status == STATUS_SUCCESS
     856        || Status == STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER)
     857    {
     858        *pu32TargetLength = pu8Dst - (uint8_t *)pvTarget;
     859        *pu32ProcessedLength = pu8Src - (uint8_t *)pvSource;
     860        if (pHO->cObjects)
     861            *ppHwRenderData = &pHO->hdr;
     862        else
     863        {
     864            SvgaRenderComplete(pSvga, &pHO->hdr);
     865            *ppHwRenderData = NULL;
     866        }
     867    }
     868    else
     869    {
     870        SvgaRenderComplete(pSvga, &pHO->hdr);
     871    }
    702872
    703873    return Status;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h

    r82968 r83222  
    2626#include <iprt/assert.h>
    2727#include <iprt/avl.h>
     28#include <iprt/list.h>
    2829
    2930#include <VBoxGaTypes.h>
     
    8990    KSPIN_LOCK HwSpinLock;
    9091
     92    /** Maintaining the host objects lists. */
     93    KSPIN_LOCK HostObjectsSpinLock;
     94
    9195    /** AVL tree for mapping GMR id to the corresponding structure. */
    9296    AVLU32TREE GMRTree;
    9397
    94     /** Bitmap of used GMR ids. Bit 0 - GMR id 0, etc. */
    95     uint32_t *pu32GMRBits; /* Number of GMRs is controlled by the host (u32GmrMaxIds), so allocte the bitmap. */
    96     uint32_t cbGMRBits;    /* Bytes allocated for pu32GMRBits */
     98    /** AVL tree for mapping sids to the surface objects. */
     99    AVLU32TREE SurfaceTree;
     100
     101    /** List of host objects, which must be deleted at PASSIVE_LEVEL. */
     102    RTLISTANCHOR DeletedHostObjectsList;
    97103
    98104    /** SVGA data access. */
     
    105111    } lastGMRFB;
    106112
    107     /** AVL tree for mapping sids to the original sid for shared resources. */
    108     AVLU32TREE SharedSidMap;
     113    /** Bitmap of used GMR ids. Bit 0 - GMR id 0, etc. */
     114    uint32_t *pu32GMRBits; /* Number of GMRs is controlled by the host (u32GmrMaxIds), so allocate the bitmap. */
     115    uint32_t cbGMRBits;    /* Bytes allocated for pu32GMRBits */
    109116
    110117    /** Bitmap of used context ids. Bit 0 - context id 0, etc. */
     
    116123typedef struct VBOXWDDM_EXT_VMSVGA *PVBOXWDDM_EXT_VMSVGA;
    117124
     125typedef struct SVGAHOSTOBJECT SVGAHOSTOBJECT;
     126typedef DECLCALLBACK(NTSTATUS) FNHostObjectDestroy(SVGAHOSTOBJECT *pThis);
     127typedef FNHostObjectDestroy *PFNHostObjectDestroy;
     128
     129#define SVGA_HOST_OBJECT_UNDEFINED 0
     130#define SVGA_HOST_OBJECT_SURFACE   1
     131
     132/* Information about an allocated surface. */
     133typedef struct SVGAHOSTOBJECT
     134{
     135    union {
     136        /* core.Key is the object id: surface id (sid), or (curently not required) context id (cid), gmr id (gid). */
     137        struct
     138        {
     139            AVLU32NODECORE core;
     140        } avl;
     141
     142        struct {
     143            RTLISTNODE node;
     144            uint32_t u32Key;
     145        } list;
     146    } u;
     147
     148    /* By UM driver, during submission of commands, by shared surface, etc. */
     149    uint32_t volatile cRefs;
     150
     151    /* SVGA_HOST_OBJECT_ type. */
     152    uint32_t uType;
     153
     154    /* Device the object is associated with. */
     155    VBOXWDDM_EXT_VMSVGA *pSvga;
     156
     157    /* Destructor. */
     158    PFNHostObjectDestroy pfnHostObjectDestroy;
     159} SVGAHOSTOBJECT;
     160
     161#define SVGAHOSTOBJECTID(pHO) ((pHO)->u.avl.core.Key)
     162
     163/* Information about an allocated surface. */
     164typedef struct SURFACEOBJECT
     165{
     166    SVGAHOSTOBJECT ho;
     167
     168    /* The actual sid, which must be used by the commands instead of the ho.core.Key.
     169     * Equal to the AVL node key for non-shared surfaces.
     170     */
     171    uint32_t u32SharedSid;
     172} SURFACEOBJECT;
     173AssertCompile(RT_OFFSETOF(SURFACEOBJECT, ho) == 0);
     174
     175typedef struct GAHWRENDERDATA
     176{
     177    RTLISTNODE node;
     178    uint32_t u32SubmissionFenceId;
     179    uint32_t u32Reserved;
     180    /* Private data follows. */
     181} GAHWRENDERDATA;
     182
     183DECLINLINE(void) SvgaHostObjectsLock(VBOXWDDM_EXT_VMSVGA *pSvga, KIRQL *pOldIrql)
     184{
     185    KeAcquireSpinLock(&pSvga->HostObjectsSpinLock, pOldIrql);
     186}
     187
     188DECLINLINE(void) SvgaHostObjectsUnlock(VBOXWDDM_EXT_VMSVGA *pSvga, KIRQL OldIrql)
     189{
     190    KeReleaseSpinLock(&pSvga->HostObjectsSpinLock, OldIrql);
     191}
     192
     193NTSTATUS SvgaHostObjectsCleanup(VBOXWDDM_EXT_VMSVGA *pSvga);
    118194
    119195NTSTATUS SvgaAdapterStart(PVBOXWDDM_EXT_VMSVGA *ppSvga,
     
    144220NTSTATUS SvgaContextDestroy(PVBOXWDDM_EXT_VMSVGA pSvga,
    145221                            uint32_t u32Cid);
     222
     223NTSTATUS SvgaSurfaceCreate(VBOXWDDM_EXT_VMSVGA *pSvga,
     224                           GASURFCREATE *pCreateParms,
     225                           GASURFSIZE *paSizes,
     226                           uint32_t cSizes,
     227                           uint32_t *pu32Sid);
     228NTSTATUS SvgaSurfaceUnref(VBOXWDDM_EXT_VMSVGA *pSvga,
     229                          uint32_t u32Sid);
     230SURFACEOBJECT *SvgaSurfaceObjectQuery(VBOXWDDM_EXT_VMSVGA *pSvga,
     231                                      uint32_t u32Sid);
     232NTSTATUS SvgaSurfaceObjectRelease(SURFACEOBJECT *pSO);
    146233
    147234NTSTATUS SvgaFence(PVBOXWDDM_EXT_VMSVGA pSvga,
     
    175262                            uint32_t cbSource,
    176263                            uint32_t *pu32TargetLength,
    177                             uint32_t *pu32ProcessedLength);
    178 
    179 typedef struct GASHAREDSID
    180 {
    181     /** Key is sid. */
    182     AVLU32NODECORE Core;
    183     /** The original sid, the key maps to it. */
    184     uint32_t u32SharedSid;
    185 } GASHAREDSID;
     264                            uint32_t *pu32ProcessedLength,
     265                            GAHWRENDERDATA **ppHwRenderData);
     266NTSTATUS SvgaRenderComplete(PVBOXWDDM_EXT_VMSVGA pSvga,
     267                            GAHWRENDERDATA *pHwRenderData);
    186268
    187269NTSTATUS SvgaSharedSidInsert(VBOXWDDM_EXT_VMSVGA *pSvga,
    188                              GASHAREDSID *pNode,
    189270                             uint32_t u32Sid,
    190271                             uint32_t u32SharedSid);
    191 GASHAREDSID *SvgaSharedSidRemove(VBOXWDDM_EXT_VMSVGA *pSvga,
    192                                  uint32_t u32Sid);
     272NTSTATUS SvgaSharedSidRemove(VBOXWDDM_EXT_VMSVGA *pSvga,
     273                             uint32_t u32Sid);
    193274uint32_t SvgaSharedSidGet(VBOXWDDM_EXT_VMSVGA *pSvga,
    194275                          uint32_t u32Sid);
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaExt.h

    r82968 r83222  
    4040    volatile uint32_t u32PreemptionFenceId; /* Updated in GaDxgkDdiPreemptCommand. */
    4141    volatile uint32_t u32LastCompletedSeqNo; /* Updated in DPC routine. */
     42
     43    RTLISTANCHOR listHwRenderData;
    4244
    4345    struct
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaUtils.cpp

    r82968 r83222  
    2525#ifdef DEBUG
    2626    | GALOG_GROUP_TEST
     27    | GALOG_GROUP_HOSTOBJECTS
    2728//    | GALOG_GROUP_PRESENT
    2829//    | GALOG_GROUP_DXGK
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaUtils.h

    r82968 r83222  
    2828#include <VBox/log.h>
    2929
    30 #define GALOG_GROUP_RELEASE   0x00000001
    31 #define GALOG_GROUP_TEST      0x00000002
    32 #define GALOG_GROUP_DXGK      0x00000004
    33 #define GALOG_GROUP_SVGA      0x00000008
    34 #define GALOG_GROUP_SVGA_FIFO 0x00000010
    35 #define GALOG_GROUP_FENCE     0x00000020
    36 #define GALOG_GROUP_PRESENT   0x00000040
     30#define GALOG_GROUP_RELEASE     0x00000001
     31#define GALOG_GROUP_TEST        0x00000002
     32#define GALOG_GROUP_DXGK        0x00000004
     33#define GALOG_GROUP_SVGA        0x00000008
     34#define GALOG_GROUP_SVGA_FIFO   0x00000010
     35#define GALOG_GROUP_FENCE       0x00000020
     36#define GALOG_GROUP_PRESENT     0x00000040
     37#define GALOG_GROUP_HOSTOBJECTS 0x00000080
    3738
    3839#ifndef GALOG_GROUP
     
    6566
    6667#define GALOGREL_EXACT(a_Msg) GALOGG_EXACT(GALOG_GROUP_RELEASE, a_Msg)
    67 #define GALOGREL(a_Msg) GALOGG(GALOG_GROUP_RELEASE, a_Msg)
     68#define GALOGREL(a_cMax, a_Msg)  do { \
     69        static uint32_t s_cLogged = 0; \
     70        if (s_cLogged < (a_cMax)) \
     71        { \
     72            ++s_cLogged; \
     73            GALOGG(GALOG_GROUP_RELEASE, a_Msg); \
     74        } \
     75    } while (0)
    6876
    6977#define GALOGTEST_EXACT(a_Msg) GALOGG_EXACT(GALOG_GROUP_TEST, a_Msg)
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp

    r82968 r83222  
    3636    if (pGaDevExt)
    3737    {
     38        if (!RTListIsEmpty(&pGaDevExt->listHwRenderData))
     39        {
     40            GAHWRENDERDATA *pIter, *pNext;
     41            RTListForEachSafe(&pGaDevExt->listHwRenderData, pIter, pNext, GAHWRENDERDATA, node)
     42            {
     43                /* Delete the data. SvgaRenderComplete deallocates pIter. */
     44                RTListNodeRemove(&pIter->node);
     45                SvgaRenderComplete(pGaDevExt->hw.pSvga, pIter);
     46            }
     47        }
     48
    3849        /* Free fence objects. */
    3950        GaFenceObjectsDestroy(pGaDevExt, NULL);
     
    6172        if (pGaDevExt)
    6273        {
     74            RTListInit(&pGaDevExt->listHwRenderData);
     75
    6376            /* Init fence objects. */
    6477            pGaDevExt->fenceObjects.u32SeqNoSource = 0;
     
    235248{
    236249    VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga;
    237 
    238     uint32_t u32Sid;
    239     NTSTATUS Status = SvgaSurfaceIdAlloc(pSvga, &u32Sid);
    240     if (NT_SUCCESS(Status))
    241     {
    242         Status = SvgaSurfaceDefine(pSvga, pCreateParms, paSizes, cSizes, u32Sid);
    243         if (NT_SUCCESS(Status))
    244         {
    245             *pu32Sid = u32Sid;
    246         }
    247         else
    248         {
    249             SvgaSurfaceIdFree(pSvga, u32Sid);
    250         }
    251     }
    252     else
    253     {
    254         Status = STATUS_INSUFFICIENT_RESOURCES;
    255     }
    256 
    257     return Status;
     250    return SvgaSurfaceCreate(pSvga, pCreateParms, paSizes, cSizes, pu32Sid);
    258251}
    259252
     
    262255{
    263256    VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga;
    264 
    265     NTSTATUS Status = SvgaSurfaceDestroy(pSvga, u32Sid);
    266     if (NT_SUCCESS(Status))
    267     {
    268         SvgaSurfaceIdFree(pSvga, u32Sid);
    269     }
    270 
    271     return Status;
     257    return SvgaSurfaceUnref(pSvga, u32Sid);
    272258}
    273259
     
    294280                                  uint32_t u32SharedSid)
    295281{
    296     GASHAREDSID *pNode = (GASHAREDSID *)GaMemAllocZero(sizeof(GASHAREDSID));
    297     if (!pNode)
    298         return STATUS_INSUFFICIENT_RESOURCES;
    299     return SvgaSharedSidInsert(pGaDevExt->hw.pSvga, pNode, u32Sid, u32SharedSid);
     282    VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga;
     283    return SvgaSharedSidInsert(pSvga, u32Sid, u32SharedSid);
    300284}
    301285
     
    303287                                  uint32_t u32Sid)
    304288{
    305     GASHAREDSID *pNode = SvgaSharedSidRemove(pGaDevExt->hw.pSvga, u32Sid);
    306     if (pNode)
    307         GaMemFree(pNode);
    308     return STATUS_SUCCESS;
     289    VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga;
     290    return SvgaSharedSidRemove(pSvga, u32Sid);
    309291}
    310292
     
    436418    GAFENCEOBJECT *pFenceObject;  /* User mode fence associated with this command buffer. */
    437419    void          *pvDmaBuffer;   /* Pointer to the DMA buffer. */
     420    GAHWRENDERDATA *pHwRenderData; /* The hardware module private data. */
    438421} GARENDERDATA;
    439422
     
    741724            pRenderData->pFenceObject = NULL; /* Not a user request, so no user accessible fence object. */
    742725            pRenderData->pvDmaBuffer  = pPresent->pDmaBuffer;
     726            pRenderData->pHwRenderData = NULL;
    743727            cbPrivateData = sizeof(GARENDERDATA);
    744728        }
     
    843827            pRenderData->pFenceObject = NULL; /* Not a user request, so no user accessible fence object. */
    844828            pRenderData->pvDmaBuffer = pPresent->pDmaBuffer;
     829            pRenderData->pHwRenderData = NULL;
    845830            cbPrivateData = sizeof(GARENDERDATA);
    846831        }
     
    887872            pRenderData->pFenceObject = NULL; /* Not a user request, so no user accessible fence object. */
    888873            pRenderData->pvDmaBuffer  = pPresent->pDmaBuffer;
     874            pRenderData->pHwRenderData = NULL;
    889875            cbPrivateData = sizeof(GARENDERDATA);
    890876        }
     
    971957            void *pvTarget          = pRender->pDmaBuffer;
    972958            uint32_t const cbTarget = pRender->DmaSize;
     959            GAHWRENDERDATA *pHwRenderData = NULL;
    973960            if (cbTarget > GA_DMA_MIN_SUBMIT_SIZE)
    974961            {
    975962                Status = SvgaRenderCommands(pGaDevExt->hw.pSvga, pvTarget, cbTarget, pvSource, cbSource,
    976                                             &u32TargetLength, &u32ProcessedLength);
     963                                            &u32TargetLength, &u32ProcessedLength, &pHwRenderData);
    977964            }
    978965            else
     
    1009996            pRenderData->pFenceObject = pFO;
    1010997            pRenderData->pvDmaBuffer  = pRender->pDmaBuffer;
     998            pRenderData->pHwRenderData = pHwRenderData;
    1011999            cbPrivateData = sizeof(GARENDERDATA);
    10121000        }
     
    12161204        pRenderData->pFenceObject = NULL; /* Not a user request, so no user accessible fence object. */
    12171205        pRenderData->pvDmaBuffer = pBuildPagingBuffer->pDmaBuffer;
     1206        pRenderData->pHwRenderData = NULL;
    12181207        cbPrivateData = sizeof(GARENDERDATA);
    12191208    }
     
    13961385        }
    13971386
     1387        if (pRenderData->pHwRenderData)
     1388        {
     1389            GAHWRENDERDATA * const pHwRenderData = pRenderData->pHwRenderData;
     1390            pHwRenderData->u32SubmissionFenceId = pSubmitCommand->SubmissionFenceId;
     1391            pHwRenderData->u32Reserved = 0;
     1392
     1393            KIRQL OldIrql;
     1394            SvgaHostObjectsLock(pGaDevExt->hw.pSvga, &OldIrql);
     1395            RTListAppend(&pGaDevExt->listHwRenderData, &pHwRenderData->node);
     1396            SvgaHostObjectsUnlock(pGaDevExt->hw.pSvga, OldIrql);
     1397        }
     1398
    13981399        ++pRenderData;
    13991400    }
     
    14581459    VBOXWDDM_EXT_GA *pGaDevExt = pDevExt->pGa;
    14591460    if (!pGaDevExt)
     1461    {
     1462        /* Device is not initialized yet. */
     1463        return;
     1464    }
     1465
     1466    PVBOXWDDM_EXT_VMSVGA pSvga = pGaDevExt->hw.pSvga;
     1467    if (!pSvga)
    14601468    {
    14611469        /* Device is not initialized yet. */
     
    14911499
    14921500    gaFenceObjectsUnlock(pGaDevExt);
     1501
     1502    KIRQL OldIrql;
     1503    SvgaHostObjectsLock(pSvga, &OldIrql);
     1504
     1505    /* Move the completed render data objects to the local list under the lock. */
     1506    RTLISTANCHOR listHwRenderData;
     1507    RTListInit(&listHwRenderData);
     1508
     1509    if (!RTListIsEmpty(&pGaDevExt->listHwRenderData))
     1510    {
     1511        GAHWRENDERDATA *pIter, *pNext;
     1512        RTListForEachSafe(&pGaDevExt->listHwRenderData, pIter, pNext, GAHWRENDERDATA, node)
     1513        {
     1514            if (gaFenceCmp(pIter->u32SubmissionFenceId, u32LastCompletedFenceId) <= 0)
     1515            {
     1516                RTListNodeRemove(&pIter->node);
     1517                RTListAppend(&listHwRenderData, &pIter->node);
     1518            }
     1519        }
     1520    }
     1521
     1522    SvgaHostObjectsUnlock(pSvga, OldIrql);
     1523
     1524    if (!RTListIsEmpty(&listHwRenderData))
     1525    {
     1526        GAHWRENDERDATA *pIter, *pNext;
     1527        RTListForEachSafe(&listHwRenderData, pIter, pNext, GAHWRENDERDATA, node)
     1528        {
     1529            /* Delete the data. SvgaRenderComplete deallocates pIter. */
     1530            RTListNodeRemove(&pIter->node);
     1531            SvgaRenderComplete(pSvga, pIter);
     1532        }
     1533    }
    14931534}
    14941535
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