VirtualBox

Ignore:
Timestamp:
Feb 8, 2019 4:06:59 PM (6 years ago)
Author:
vboxsync
Message:

WDDM: Gallium Miniport Driver: handle empty command buffers. bugref:8893

File:
1 edited

Legend:

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

    r76884 r77225  
    711711            case STATUS_SUCCESS:
    712712            {
    713                 if (u32TargetLength)
    714                 {
    715                     pPresent->pDmaBuffer = (uint8_t *)pPresent->pDmaBuffer + u32TargetLength;
    716                     pPresent->pDmaBufferPrivateData = (uint8_t *)pPresent->pDmaBufferPrivateData + cbPrivateData;
    717                 }
     713                pPresent->pDmaBuffer = (uint8_t *)pPresent->pDmaBuffer + u32TargetLength;
     714                pPresent->pDmaBufferPrivateData = (uint8_t *)pPresent->pDmaBufferPrivateData + cbPrivateData;
    718715            } break;
    719716            default: break;
     
    828825            case STATUS_SUCCESS:
    829826            {
    830                 if (u32TargetLength)
    831                 {
    832                     pPresent->pDmaBuffer = (uint8_t *)pPresent->pDmaBuffer + u32TargetLength;
    833                     pPresent->pDmaBufferPrivateData = (uint8_t *)pPresent->pDmaBufferPrivateData + cbPrivateData;
    834                 }
     827                pPresent->pDmaBuffer = (uint8_t *)pPresent->pDmaBuffer + u32TargetLength;
     828                pPresent->pDmaBufferPrivateData = (uint8_t *)pPresent->pDmaBufferPrivateData + cbPrivateData;
    835829            } break;
    836830            default: break;
     
    839833    else if (pPresent->Flags.ColorFill)
    840834    {
    841         GALOG(("ColorFill\n"));
     835        LogRelMax(16, ("ColorFill is not implemented\n"));
    842836        AssertFailed();
     837
     838        /* Generate empty DMA buffer.
     839         * Store the command buffer descriptor to pDmaBufferPrivateData.
     840         */
     841        GARENDERDATA *pRenderData = NULL;
     842        uint32_t u32TargetLength = 0;
     843        uint32_t cbPrivateData = 0;
     844
     845        if (pPresent->DmaBufferPrivateDataSize >= sizeof(GARENDERDATA))
     846        {
     847            /* Fill RenderData description in any case, it will be ignored if the above code failed. */
     848            pRenderData = (GARENDERDATA *)pPresent->pDmaBufferPrivateData;
     849            pRenderData->u32DataType  = GARENDERDATA_TYPE_PRESENT;
     850            pRenderData->cbData       = u32TargetLength;
     851            pRenderData->pFenceObject = NULL; /* Not a user request, so no user accessible fence object. */
     852            pRenderData->pvDmaBuffer  = pPresent->pDmaBuffer;
     853            cbPrivateData = sizeof(GARENDERDATA);
     854        }
     855        else
     856        {
     857            Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
     858        }
     859
     860        switch (Status)
     861        {
     862            case STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER:
     863                if (pRenderData == NULL)
     864                {
     865                    /* Not enough space in pDmaBufferPrivateData. */
     866                    break;
     867                }
     868                RT_FALL_THRU();
     869            case STATUS_SUCCESS:
     870            {
     871                pPresent->pDmaBuffer = (uint8_t *)pPresent->pDmaBuffer + u32TargetLength;
     872                pPresent->pDmaBufferPrivateData = (uint8_t *)pPresent->pDmaBufferPrivateData + cbPrivateData;
     873            } break;
     874            default: break;
     875        }
    843876    }
    844877    else
     
    11661199        case STATUS_SUCCESS:
    11671200        {
    1168             if (u32TargetLength)
    1169             {
    1170                 pBuildPagingBuffer->pDmaBuffer = (uint8_t *)pBuildPagingBuffer->pDmaBuffer + u32TargetLength;
    1171                 pBuildPagingBuffer->pDmaBufferPrivateData = (uint8_t *)pBuildPagingBuffer->pDmaBufferPrivateData + cbPrivateData;
    1172             }
     1201            pBuildPagingBuffer->pDmaBuffer = (uint8_t *)pBuildPagingBuffer->pDmaBuffer + u32TargetLength;
     1202            pBuildPagingBuffer->pDmaBufferPrivateData = (uint8_t *)pBuildPagingBuffer->pDmaBufferPrivateData + cbPrivateData;
    11731203        } break;
    11741204        default: break;
     
    12421272    uint32_t cbDmaBufferSubmission = pSubmitCommand->DmaBufferSubmissionEndOffset - pSubmitCommand->DmaBufferSubmissionStartOffset;
    12431273    uint32_t cDataBlocks = cbPrivateData / sizeof(GARENDERDATA);
    1244     AssertReturn(cDataBlocks, STATUS_INVALID_PARAMETER);
    1245 
    1246     GARENDERDATA *pRenderData = (GARENDERDATA *)pvPrivateData;
     1274
     1275    if (cDataBlocks == 0)
     1276    {
     1277        /* Sometimes a zero sized paging buffer is submitted.
     1278         * Seen this on W10.17763 right after DXGK_OPERATION_DISCARD_CONTENT.
     1279         * Can not ignore such block, since a new SubmissionFenceId is passed.
     1280         * Try to handle it by emitting the fence command only.
     1281         */
     1282        Assert(cbPrivateData == 0);
     1283        Assert(pSubmitCommand->Flags.Paging);
     1284        LogRelMax(16, ("WDDM: empty buffer: cbPrivateData %d, flags 0x%x\n", cbPrivateData, pSubmitCommand->Flags.Value));
     1285    }
     1286
     1287    GARENDERDATA const *pRenderData = (GARENDERDATA *)pvPrivateData;
    12471288    while (cDataBlocks--)
    12481289    {
     
    12931334        if (pvDmaBuffer)
    12941335        {
    1295             /* Copy DmaBuffer to Fifo. */
    12961336            Assert(pSubmitCommand->DmaBufferSegmentId == 0);
    12971337
    12981338            uint32_t const cbSubmit = pRenderData->cbData;
    1299 
    1300             void *pvCmd = SvgaFifoReserve(pGaDevExt->hw.pSvga, cbSubmit);
    1301             AssertPtrReturn(pvCmd, STATUS_INSUFFICIENT_RESOURCES);
    1302 
    1303             /* pvDmaBuffer is the actual address of the current data block.
    1304              * Therefore do not use pSubmitCommand->DmaBufferSubmissionStartOffset here.
    1305              */
    1306             memcpy(pvCmd, pvDmaBuffer, cbSubmit);
    1307             SvgaFifoCommit(pGaDevExt->hw.pSvga, cbSubmit);
     1339            if (cbSubmit)
     1340            {
     1341                /* Copy DmaBuffer to Fifo. */
     1342                void *pvCmd = SvgaFifoReserve(pGaDevExt->hw.pSvga, cbSubmit);
     1343                AssertPtrReturn(pvCmd, STATUS_INSUFFICIENT_RESOURCES);
     1344
     1345                /* pvDmaBuffer is the actual address of the current data block.
     1346                 * Therefore do not use pSubmitCommand->DmaBufferSubmissionStartOffset here.
     1347                 */
     1348                memcpy(pvCmd, pvDmaBuffer, cbSubmit);
     1349                SvgaFifoCommit(pGaDevExt->hw.pSvga, cbSubmit);
     1350            }
     1351            else
     1352            {
     1353                /* 'Paging' buffers can be empty, implementation is incomplete. See GaDxgkDdiBuildPagingBuffer. */
     1354                if (pSubmitCommand->Flags.Paging == 0)
     1355                {
     1356                    LogRelMax(16, ("WDDM: Zero sized command buffer. Flags 0x%x, type %d\n", pSubmitCommand->Flags.Value, pRenderData->u32DataType));
     1357                    AssertFailed();
     1358                }
     1359            }
    13081360        }
    13091361
    13101362        ++pRenderData;
    13111363    }
     1364
     1365    ASMAtomicWriteU32(&pGaDevExt->u32LastSubmittedFenceId, pSubmitCommand->SubmissionFenceId);
    13121366
    13131367    /* Submit the fence. */
    13141368    SvgaFence(pGaDevExt->hw.pSvga, pSubmitCommand->SubmissionFenceId);
    1315 
    1316     ASMAtomicWriteU32(&pGaDevExt->u32LastSubmittedFenceId, pSubmitCommand->SubmissionFenceId);
    13171369
    13181370    GALOG(("done %d\n", pSubmitCommand->SubmissionFenceId));
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