VirtualBox

Ignore:
Timestamp:
Oct 30, 2013 1:13:02 PM (11 years ago)
Author:
vboxsync
Message:

wddm: 1. switch to using common VBVA code 2.dx-based command submission - work in progress 3.some prototyping for getting 3D data for video recording/take snapshot

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

Legend:

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

    r44529 r49332  
    2020#include "common/VBoxMPCommon.h"
    2121
    22 static int vboxVBVAInformHost (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO * pVbva, BOOL bEnable)
    23 {
    24     int rc = VERR_NO_MEMORY;
    25     void *p = VBoxHGSMIBufferAlloc (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx,
    26                                   sizeof (VBVAENABLE_EX),
    27                                   HGSMI_CH_VBVA,
    28                                   VBVA_ENABLE);
    29     Assert(p);
    30     if (!p)
    31     {
    32         LOGREL(("HGSMIHeapAlloc failed"));
    33         rc = VERR_NO_MEMORY;
    34     }
    35     else
    36     {
    37         VBVAENABLE_EX *pEnableEx = (VBVAENABLE_EX *)p;
    38         pEnableEx->u32ScreenId = pVbva->srcId;
    39 
    40         VBVAENABLE *pEnable = &pEnableEx->Base;
    41         pEnable->u32Flags  = bEnable? VBVA_F_ENABLE: VBVA_F_DISABLE;
    42         pEnable->u32Flags |= VBVA_F_EXTENDED | VBVA_F_ABSOFFSET;
    43         pEnable->u32Offset = (uint32_t)pVbva->offVBVA;
    44         pEnable->i32Result = VERR_NOT_SUPPORTED;
    45 
    46         VBoxHGSMIBufferSubmit (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
    47 
    48         if (bEnable)
    49         {
    50             rc = pEnable->i32Result;
    51             AssertRC(rc);
    52         }
    53         else
    54             rc = VINF_SUCCESS;
    55 
    56         VBoxHGSMIBufferFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
    57     }
    58     return rc;
    59 }
    60 
    6122/*
    6223 * Public hardware buffer methods.
     
    6425int vboxVbvaEnable (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
    6526{
    66         VBVABUFFER *pVBVA = pVbva->pVBVA;
     27    if (VBoxVBVAEnable(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx,
     28            pVbva->Vbva.pVBVA, pVbva->srcId))
     29        return VINF_SUCCESS;
    6730
    68 //        DISPDBG((1, "VBoxDisp::vboxVbvaEnable screen %p vbva off 0x%x\n", ppdev->pjScreen, ppdev->layout.offVBVABuffer));
    69 
    70         pVBVA->hostFlags.u32HostEvents      = 0;
    71         pVBVA->hostFlags.u32SupportedOrders = 0;
    72         pVBVA->off32Data          = 0;
    73         pVBVA->off32Free          = 0;
    74         RtlZeroMemory (pVBVA->aRecords, sizeof (pVBVA->aRecords));
    75         pVBVA->indexRecordFirst   = 0;
    76         pVBVA->indexRecordFree    = 0;
    77         pVBVA->cbPartialWriteThreshold = 256;
    78         pVBVA->cbData             = pVbva->cbVBVA - sizeof (VBVABUFFER) + sizeof (pVBVA->au8Data);
    79 
    80         pVbva->fHwBufferOverflow = FALSE;
    81         pVbva->pRecord           = NULL;
    82 
    83         int rc = vboxVBVAInformHost (pDevExt, pVbva, TRUE);
    84         AssertRC(rc);
    85 
    86     if (!RT_SUCCESS(rc))
    87         vboxVbvaDisable (pDevExt, pVbva);
    88 
    89     return rc;
     31    WARN(("VBoxVBVAEnable failed!"));
     32    return VERR_GENERAL_FAILURE;
    9033}
    9134
    9235int vboxVbvaDisable (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
    9336{
    94 //    DISPDBG((1, "VBoxDisp::vbvaDisable called.\n"));
    95 
    96     pVbva->fHwBufferOverflow = FALSE;
    97     pVbva->pRecord           = NULL;
    98 //    ppdev->pVBVA             = NULL;
    99 
    100     return vboxVBVAInformHost (pDevExt, pVbva, FALSE);
     37    VBoxVBVADisable(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, pVbva->srcId);
     38    return VINF_SUCCESS;
    10139}
    10240
     
    10846
    10947    int rc = VBoxMPCmnMapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt),
    110                                        (void**)&pVbva->pVBVA,
     48                                       (void**)&pVbva->Vbva.pVBVA,
    11149                                       offBuffer,
    11250                                       cbBuffer);
     
    11452    if (RT_SUCCESS(rc))
    11553    {
    116         Assert(pVbva->pVBVA);
    117         pVbva->offVBVA = offBuffer;
    118         pVbva->cbVBVA = cbBuffer;
     54        Assert(pVbva->Vbva.pVBVA);
     55        VBoxVBVASetupBufferContext(&pVbva->Vbva, offBuffer, cbBuffer);
    11956        pVbva->srcId = srcId;
    12057    }
     
    12663{
    12764    int rc = VINF_SUCCESS;
    128     VBoxMPCmnUnmapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pVbva->pVBVA);
    129     memset(pVbva, 0, sizeof(VBOXVBVAINFO));
     65    VBoxMPCmnUnmapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pVbva->Vbva.pVBVA);
     66    memset(pVbva, 0, sizeof (VBOXVBVAINFO));
    13067    return rc;
    13168}
    13269
    133 /*
    134  * Private operations.
    135  */
    136 static uint32_t vboxHwBufferAvail (const VBVABUFFER *pVBVA)
    137 {
    138     int32_t i32Diff = pVBVA->off32Data - pVBVA->off32Free;
    139 
    140     return i32Diff > 0? i32Diff: pVBVA->cbData + i32Diff;
    141 }
    142 
    143 static void vboxHwBufferFlush (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
    144 {
    145     /* Issue the flush command. */
    146     void *p = VBoxHGSMIBufferAlloc (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx,
    147                               sizeof (VBVAFLUSH),
    148                               HGSMI_CH_VBVA,
    149                               VBVA_FLUSH);
    150     Assert(p);
    151     if (!p)
    152     {
    153         LOGREL(("HGSMIHeapAlloc failed"));
    154     }
    155     else
    156     {
    157         VBVAFLUSH *pFlush = (VBVAFLUSH *)p;
    158 
    159         pFlush->u32Reserved = 0;
    160 
    161         VBoxHGSMIBufferSubmit (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
    162 
    163         VBoxHGSMIBufferFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
    164     }
    165 
    166     return;
    167 }
    168 
    169 static void vboxHwBufferPlaceDataAt (VBVABUFFER *pVBVA, const void *p, uint32_t cb, uint32_t offset)
    170 {
    171     uint32_t u32BytesTillBoundary = pVBVA->cbData - offset;
    172     uint8_t  *dst                 = &pVBVA->au8Data[offset];
    173     int32_t i32Diff               = cb - u32BytesTillBoundary;
    174 
    175     if (i32Diff <= 0)
    176     {
    177         /* Chunk will not cross buffer boundary. */
    178         memcpy (dst, p, cb);
    179     }
    180     else
    181     {
    182         /* Chunk crosses buffer boundary. */
    183         memcpy (dst, p, u32BytesTillBoundary);
    184         memcpy (&pVBVA->au8Data[0], (uint8_t *)p + u32BytesTillBoundary, i32Diff);
    185     }
    186 
    187     return;
    188 }
    189 
    190 BOOL vboxVbvaBufferBeginUpdate (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
    191 {
    192     BOOL bRc = FALSE;
    193 
    194     // DISPDBG((1, "VBoxDisp::vboxHwBufferBeginUpdate called flags = 0x%08X\n",
    195     //          ppdev->pVBVA? ppdev->pVBVA->u32HostEvents: -1));
    196 
    197     if (   pVbva->pVBVA
    198         && (pVbva->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
    199     {
    200         uint32_t indexRecordNext;
    201 
    202         Assert (!pVbva->fHwBufferOverflow);
    203         Assert (pVbva->pRecord == NULL);
    204 
    205         indexRecordNext = (pVbva->pVBVA->indexRecordFree + 1) % VBVA_MAX_RECORDS;
    206 
    207         if (indexRecordNext == pVbva->pVBVA->indexRecordFirst)
    208         {
    209             /* All slots in the records queue are used. */
    210             vboxHwBufferFlush (pDevExt, pVbva);
    211         }
    212 
    213         if (indexRecordNext == pVbva->pVBVA->indexRecordFirst)
    214         {
    215 //            /* Even after flush there is no place. Fail the request. */
    216 //            LOG(("no space in the queue of records!!! first %d, last %d",
    217 //                  ppdev->pVBVA->indexRecordFirst, ppdev->pVBVA->indexRecordFree));
    218         }
    219         else
    220         {
    221             /* Initialize the record. */
    222             VBVARECORD *pRecord = &pVbva->pVBVA->aRecords[pVbva->pVBVA->indexRecordFree];
    223 
    224             pRecord->cbRecord = VBVA_F_RECORD_PARTIAL;
    225 
    226             pVbva->pVBVA->indexRecordFree = indexRecordNext;
    227 
    228             // LOG(("indexRecordNext = %d\n", indexRecordNext));
    229 
    230             /* Remember which record we are using. */
    231             pVbva->pRecord = pRecord;
    232 
    233             bRc = TRUE;
    234         }
    235     }
    236 
    237     return bRc;
    238 }
    239 
    240 void vboxVbvaBufferEndUpdate (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
    241 {
    242     VBVARECORD *pRecord;
    243 
    244     // LOG(("VBoxDisp::vboxHwBufferEndUpdate called"));
    245 
    246     Assert(pVbva->pVBVA);
    247 
    248     pRecord = pVbva->pRecord;
    249     Assert (pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
    250 
    251     /* Mark the record completed. */
    252     pRecord->cbRecord &= ~VBVA_F_RECORD_PARTIAL;
    253 
    254     pVbva->fHwBufferOverflow = FALSE;
    255     pVbva->pRecord = NULL;
    256 
    257     return;
    258 }
    259 
    260 static int vboxHwBufferWrite (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, const void *p, uint32_t cb)
    261 {
    262     VBVARECORD *pRecord;
    263     uint32_t cbHwBufferAvail;
    264 
    265     uint32_t cbWritten = 0;
    266 
    267     VBVABUFFER *pVBVA = pVbva->pVBVA;
    268     Assert(pVBVA);
    269 
    270     if (!pVBVA || pVbva->fHwBufferOverflow)
    271     {
    272         return VERR_INVALID_STATE;
    273     }
    274 
    275     Assert (pVBVA->indexRecordFirst != pVBVA->indexRecordFree);
    276 
    277     pRecord = pVbva->pRecord;
    278     Assert (pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
    279 
    280 //    LOGF(("VW %d", cb));
    281 
    282     cbHwBufferAvail = vboxHwBufferAvail (pVBVA);
    283 
    284     while (cb > 0)
    285     {
    286         uint32_t cbChunk = cb;
    287 
    288         // LOG(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n",
    289         //      pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten));
    290 
    291         if (cbChunk >= cbHwBufferAvail)
    292         {
    293             LOG(("1) avail %d, chunk %d", cbHwBufferAvail, cbChunk));
    294 
    295             vboxHwBufferFlush (pDevExt, pVbva);
    296 
    297             cbHwBufferAvail = vboxHwBufferAvail (pVBVA);
    298 
    299             if (cbChunk >= cbHwBufferAvail)
    300             {
    301                 LOG(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.",
    302                      cb, cbHwBufferAvail));
    303 
    304                 if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold)
    305                 {
    306                     LOGREL(("Buffer overflow!!!"));
    307                     pVbva->fHwBufferOverflow = TRUE;
    308                     Assert(FALSE);
    309                     return VERR_NO_MEMORY;
    310                 }
    311 
    312                 cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold;
    313             }
    314         }
    315 
    316         Assert(cbChunk <= cb);
    317         Assert(cbChunk <= vboxHwBufferAvail (pVBVA));
    318 
    319         vboxHwBufferPlaceDataAt (pVbva->pVBVA, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free);
    320 
    321         pVBVA->off32Free   = (pVBVA->off32Free + cbChunk) % pVBVA->cbData;
    322         pRecord->cbRecord += cbChunk;
    323         cbHwBufferAvail -= cbChunk;
    324 
    325         cb        -= cbChunk;
    326         cbWritten += cbChunk;
    327     }
    328 
    329     return VINF_SUCCESS;
    330 }
    331 
    332 /*
    333  * Public writer to the hardware buffer.
    334  */
    335 int vboxWrite (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, const void *pv, uint32_t cb)
    336 {
    337     return vboxHwBufferWrite (pDevExt, pVbva, pv, cb);
    338 }
    339 
    340 
    34170int vboxVbvaReportDirtyRect (PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSrc, RECT *pRectOrig)
    34271{
    343         VBVACMDHDR hdr;
     72    VBVACMDHDR hdr;
    34473
    345         RECT rect = *pRectOrig;
     74    RECT rect = *pRectOrig;
    34675
    34776//        if (rect.left < 0) rect.left = 0;
     
    35079//        if (rect.bottom > (int)ppdev->cyScreen) rect.bottom = ppdev->cyScreen;
    35180
    352         hdr.x = (int16_t)rect.left;
    353         hdr.y = (int16_t)rect.top;
    354         hdr.w = (uint16_t)(rect.right - rect.left);
    355         hdr.h = (uint16_t)(rect.bottom - rect.top);
     81    hdr.x = (int16_t)rect.left;
     82    hdr.y = (int16_t)rect.top;
     83    hdr.w = (uint16_t)(rect.right - rect.left);
     84    hdr.h = (uint16_t)(rect.bottom - rect.top);
    35685
    357         hdr.x += (int16_t)pSrc->VScreenPos.x;
    358         hdr.y += (int16_t)pSrc->VScreenPos.y;
     86    hdr.x += (int16_t)pSrc->VScreenPos.x;
     87    hdr.y += (int16_t)pSrc->VScreenPos.y;
    35988
    360         return vboxWrite (pDevExt, &pSrc->Vbva, &hdr, sizeof(hdr));
     89    if (VBoxVBVAWrite(&pSrc->Vbva.Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, &hdr, sizeof(hdr)))
     90        return VINF_SUCCESS;
     91
     92    WARN(("VBoxVBVAWrite failed"));
     93    return VERR_GENERAL_FAILURE;
    36194}
    36295
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h

    r37626 r49332  
    2222typedef struct VBOXVBVAINFO
    2323{
    24     VBOXVIDEOOFFSET offVBVA;
    25     uint32_t cbVBVA;
    26     VBVABUFFER *pVBVA;
    27     BOOL  fHwBufferOverflow;
    28     VBVARECORD *pRecord;
     24    VBVABUFFERCONTEXT Vbva;
    2925    D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId;
    3026    KSPIN_LOCK Lock;
     
    3733int vboxVbvaReportCmdOffset(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, uint32_t offCmd);
    3834int vboxVbvaReportDirtyRect(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_SOURCE *pSrc, RECT *pRectOrig);
    39 BOOL vboxVbvaBufferBeginUpdate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
    40 void vboxVbvaBufferEndUpdate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
    4135
    4236#define VBOXVBVA_OP(_op, _pdext, _psrc, _arg) \
    4337        do { \
    44             if (vboxVbvaBufferBeginUpdate(_pdext, &(_psrc)->Vbva)) \
     38            if (VBoxVBVABufferBeginUpdate(&(_psrc)->Vbva.Vbva, &VBoxCommonFromDeviceExt(_pdext)->guestCtx)) \
    4539            { \
    4640                vboxVbva##_op(_pdext, _psrc, _arg); \
    47                 vboxVbvaBufferEndUpdate(_pdext, &(_psrc)->Vbva); \
     41                VBoxVBVABufferEndUpdate(&(_psrc)->Vbva.Vbva); \
    4842            } \
    4943        } while (0)
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