VirtualBox

Changeset 42028 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Jul 5, 2012 3:22:55 PM (12 years ago)
Author:
vboxsync
Message:

wddm/crOpenGL: moreon kernel-based cr commands submission

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk

    r41636 r42028  
    9494 endif
    9595 
    96  VBoxVideoWddm_INCS       += ../../../include .. . ../../../../common/VBoxGuestLib $(VBOX_PATH_CROGL_INCLUDE) $(VBOX_PATH_CROGL_GENFILES)
     96 VBoxVideoWddm_INCS       += \
     97    ../../../include \
     98    .. \
     99    . \
     100    ../../../../common/VBoxGuestLib \
     101    $(VBOX_PATH_CROGL_INCLUDE) \
     102    $(VBOX_PATH_CROGL_GENFILES) \
     103    $(PATH_ROOT)/src/VBox/GuestHost/OpenGL/packer
    97104 VBoxVideoWddm_LDFLAGS.x86 += /Entry:DriverEntry@8
    98105 VBoxVideoWddm_LDFLAGS.amd64 += /Entry:DriverEntry
     
    114121        $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
    115122        $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
     123 if defined(VBOX_WITH_CROGL) && defined(VBOX_WDDM_WITH_CRCMD)
     124   VBoxVideoWddm_SOURCES   += \
     125        $(PATH_ROOT)/src/VBox/GuestHost/OpenGL/packer/pack_buffer.c \
     126        $(PATH_ROOT)/src/VBox/GuestHost/OpenGL/packer/pack_bounds.c \
     127        $(VBOX_PATH_CROGL_GENFILES)/pack_bounds_swap.c \
     128        wddm/VBoxMPCrUtil.cpp
     129   VBoxVideoWddm_DEFS       + VBOX_WDDM_WITH_CRCMD
     130 endif
    116131 ifdef VBOXWDDM_WITH_VBVA
    117132  VBoxVideoWddm_SOURCES   += \
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp

    r41485 r42028  
    2525#include <cr_protocol.h>
    2626
    27 # if 0
     27# ifdef VBOX_WDDM_WITH_CRCMD
    2828#  include <cr_pack.h>
    2929
    30 typedef struct PVBOXMP_SHGSMIPACKER
     30typedef struct VBOXMP_CRSHGSMICON_BUFDR
     31{
     32    uint32_t cbBuf;
     33    void *pvBuf;
     34} VBOXMP_CRSHGSMICON_BUFDR, *PVBOXMP_CRSHGSMICON_BUFDR;
     35
     36typedef struct VBOXMP_CRSHGSMICON_BUFDR_CACHE
     37{
     38    volatile PVBOXMP_CRSHGSMICON_BUFDR pBufDr;
     39} VBOXMP_CRSHGSMICON_BUFDR_CACHE, *PVBOXMP_CRSHGSMICON_BUFDR_CACHE;
     40
     41typedef struct VBOXMP_CRSHGSMICON
    3142{
    3243    PVBOXMP_DEVEXT pDevExt;
     44    PVBOXMP_CRCTLCON pCtlCon;
     45    uint32_t u32ClientID;
     46    VBOXMP_CRSHGSMICON_BUFDR_CACHE CmdDrCache;
     47    VBOXMP_CRSHGSMICON_BUFDR_CACHE WbDrCache;
     48} VBOXMP_CRSHGSMICON, *PVBOXMP_CRSHGSMICON;
     49
     50typedef struct VBOXMP_CRSHGSMIPACKER
     51{
     52    PVBOXMP_CRSHGSMICON pCon;
    3353    CRPackContext CrPacker;
    3454    CRPackBuffer CrBuffer;
    35 } PVBOXMP_SHGSMIPACKER, *PPVBOXMP_SHGSMIPACKER;
     55} VBOXMP_CRSHGSMIPACKER, *PVBOXMP_CRSHGSMIPACKER;
    3656
    3757static void* vboxMpCrShgsmiBufferAlloc(PVBOXMP_DEVEXT pDevExt, HGSMISIZE cbData)
     
    4060}
    4161
     62static VBOXVIDEOOFFSET vboxMpCrShgsmiBufferOffset(PVBOXMP_DEVEXT pDevExt, void *pvBuffer)
     63{
     64    return HGSMIPointerToOffset(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx.Heap.area, (const HGSMIBUFFERHEADER *)pvBuffer);
     65}
     66
    4267static void vboxMpCrShgsmiBufferFree(PVBOXMP_DEVEXT pDevExt, void *pvBuffer)
    4368{
     
    4570}
    4671
     72static void* vboxMpCrShgsmiConAlloc(PVBOXMP_CRSHGSMICON pCon, uint32_t cbBuffer)
     73{
     74    return vboxMpCrShgsmiBufferAlloc(pCon->pDevExt, cbBuffer);
     75}
     76
     77static VBOXVIDEOOFFSET vboxMpCrShgsmiConBufOffset(PVBOXMP_CRSHGSMICON pCon, void* pvBuffer)
     78{
     79    return vboxMpCrShgsmiBufferOffset(pCon->pDevExt, pvBuffer);
     80}
     81
     82
     83static void vboxMpCrShgsmiConFree(PVBOXMP_CRSHGSMICON pCon, void* pvBuffer)
     84{
     85    vboxMpCrShgsmiBufferFree(pCon->pDevExt, pvBuffer);
     86}
     87
     88#define VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers) VBOXWDDM_ROUNDBOUND((VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[_cBuffers]))), 8)
     89#define VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(_pDr, _cBuffers, _type) ((_type*)(((uint8_t*)(_pDr)) + VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers)))
     90#define VBOXMP_CRSHGSMICON_DR_SIZE(_cBuffers, _cbCmdBuf) ( VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers) + _cbCmdBuf)
     91
     92static int vboxMpCrShgsmiBufCacheBufReinit(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, PVBOXMP_CRSHGSMICON_BUFDR pDr, uint32_t cbRequested)
     93{
     94    if (pDr->cbBuf >= cbRequested)
     95        return VINF_SUCCESS;
     96
     97    if (pDr->pvBuf)
     98        vboxMpCrShgsmiConFree(pCon, pDr->pvBuf);
     99
     100    pDr->pvBuf = vboxMpCrShgsmiConAlloc(pCon, cbRequested);
     101    if (!pDr->pvBuf)
     102    {
     103        WARN(("vboxMpCrShgsmiConAlloc failed"));
     104        pDr->cbBuf = 0;
     105        return VERR_NO_MEMORY;
     106    }
     107
     108    pDr->cbBuf = cbRequested;
     109    return VINF_SUCCESS;
     110}
     111
     112static void vboxMpCrShgsmiBufCacheFree(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, PVBOXMP_CRSHGSMICON_BUFDR pDr)
     113{
     114    if (ASMAtomicCmpXchgPtr(&pCache->pBufDr, pDr, NULL))
     115        return;
     116
     117    /* the value is already cached, free the current one */
     118    vboxMpCrShgsmiConFree(pCon, pDr->pvBuf);
     119    vboxWddmMemFree(pDr);
     120}
     121
     122static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheGetAllocDr(PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
     123{
     124    PVBOXMP_CRSHGSMICON_BUFDR pBufDr = (PVBOXMP_CRSHGSMICON_BUFDR)ASMAtomicXchgPtr((void * volatile *)&pCache->pBufDr, NULL);
     125    if (!pBufDr)
     126    {
     127        pBufDr = (PVBOXMP_CRSHGSMICON_BUFDR)vboxWddmMemAllocZero(sizeof (*pBufDr));
     128        if (!pBufDr)
     129        {
     130            WARN(("vboxWddmMemAllocZero failed!"));
     131            return NULL;
     132        }
     133    }
     134    return pBufDr;
     135}
     136
     137static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAlloc(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, uint32_t cbBuffer)
     138{
     139    PVBOXMP_CRSHGSMICON_BUFDR pBufDr = vboxMpCrShgsmiBufCacheGetAllocDr(pCache);
     140    int rc = vboxMpCrShgsmiBufCacheBufReinit(pCon, pCache, pBufDr, cbBuffer);
     141    if (RT_SUCCESS(rc))
     142        return pBufDr;
     143
     144    WARN(("vboxMpCrShgsmiBufCacheBufReinit failed, rc %d", rc));
     145
     146    vboxMpCrShgsmiBufCacheFree(pCon, pCache, pBufDr);
     147    return NULL;
     148}
     149
     150static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAllocAny(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, uint32_t cbBuffer)
     151{
     152    PVBOXMP_CRSHGSMICON_BUFDR pBufDr = vboxMpCrShgsmiBufCacheGetAllocDr(pCache);
     153
     154    if (pBufDr->cbBuf)
     155        return pBufDr;
     156
     157    int rc = vboxMpCrShgsmiBufCacheBufReinit(pCon, pCache, pBufDr, cbBuffer);
     158    if (RT_SUCCESS(rc))
     159        return pBufDr;
     160
     161    WARN(("vboxMpCrShgsmiBufCacheBufReinit failed, rc %d", rc));
     162
     163    vboxMpCrShgsmiBufCacheFree(pCon, pCache, pBufDr);
     164    return NULL;
     165}
     166
     167
     168static int vboxMpCrShgsmiBufCacheInit(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
     169{
     170    memset(pCache, 0, sizeof (*pCache));
     171    return VINF_SUCCESS;
     172}
     173
     174static void vboxMpCrShgsmiBufCacheTerm(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
     175{
     176    if (pCache->pBufDr)
     177        vboxMpCrShgsmiBufCacheFree(pCon, pCache, pCache->pBufDr);
     178}
     179
     180static int vboxMpCrShgsmiConConnect(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_DEVEXT pDevExt, PVBOXMP_CRCTLCON pCrCtlCon)
     181{
     182    memset(pCon, 0, sizeof (*pCon));
     183    int rc = vboxMpCrShgsmiBufCacheInit(pCon, &pCon->CmdDrCache);
     184    if (RT_SUCCESS(rc))
     185    {
     186        rc = vboxMpCrShgsmiBufCacheInit(pCon, &pCon->WbDrCache);
     187        if (RT_SUCCESS(rc))
     188        {
     189            rc = VBoxMpCrCtlConConnect(pCrCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &pCon->u32ClientID);
     190            if (RT_SUCCESS(rc))
     191            {
     192                pCon->pDevExt = pDevExt;
     193                pCon->pCtlCon = pCrCtlCon;
     194                return VINF_SUCCESS;
     195            }
     196            else
     197            {
     198                WARN(("VBoxMpCrCtlConConnect failed rc %d", rc));
     199            }
     200            vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->WbDrCache);
     201        }
     202        else
     203        {
     204            WARN(("vboxMpCrShgsmiBufCacheInit2 failed rc %d", rc));
     205        }
     206        vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
     207    }
     208    else
     209    {
     210        WARN(("vboxMpCrShgsmiBufCacheInit1 failed rc %d", rc));
     211    }
     212
     213    return rc;
     214}
     215
     216static int vboxMpCrShgsmiConDisconnect(PVBOXMP_CRSHGSMICON pCon)
     217{
     218    int rc = VBoxMpCrCtlConDisconnect(pCon->pCtlCon, pCon->u32ClientID);
     219    if (RT_FAILURE(rc))
     220    {
     221        WARN(("VBoxMpCrCtlConDisconnect failed rc %d", rc));
     222        return rc;
     223    }
     224
     225    vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->WbDrCache);
     226    vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
     227
     228    return VINF_SUCCESS;
     229}
     230
     231typedef DECLCALLBACK(void) FNVBOXMP_CRSHGSMICON_SEND_COMPLETION(PVBOXMP_CRSHGSMICON pCon, void *pvRx, uint32_t cbRx, void *pvCtx);
     232typedef FNVBOXMP_CRSHGSMICON_SEND_COMPLETION *PFNVBOXMP_CRSHGSMICON_SEND_COMPLETION;
     233
     234typedef struct VBOXMP_CRSHGSMICON_SEND_COMPLETION
     235{
     236    PVBOXMP_CRSHGSMICON pCon;
     237    PFNVBOXMP_CRSHGSMICON_SEND_COMPLETION pvnCompletion;
     238    void *pvCompletion;
     239} VBOXMP_CRSHGSMICON_SEND_COMPLETION, *PVBOXMP_CRSHGSMICON_SEND_COMPLETION;
     240
     241static DECLCALLBACK(VOID) vboxMpCrShgsmiConSendAsyncCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
     242{
     243    /* we should be called from our DPC routine */
     244    Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
     245
     246    PVBOXMP_CRSHGSMICON_SEND_COMPLETION pData = (PVBOXMP_CRSHGSMICON_SEND_COMPLETION)pvContext;
     247    PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_DDI_CMD(pCmd);
     248    PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
     249    VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
     250    UINT cBufs = pBody->cBuffers;
     251    /* the first one is a command buffer: obtain it and get the result */
     252
     253    /* if write back buffer is too small, issue read command.
     254     * we can use exactly the same command buffer for it */
     255    /* impl */
     256    Assert(0);
     257}
     258
     259static int vboxMpCrShgsmiConSendAsync(PVBOXMP_CRSHGSMICON pCon, void *pvTx, uint32_t cbTx, PFNVBOXMP_CRSHGSMICON_SEND_COMPLETION pfnCompletion, void *pvCompletion)
     260{
     261    const uint32_t cBuffers = 3;
     262    const uint32_t cbCmd = VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (CRVBOXHGSMIWRITEREAD));
     263    PVBOXMP_CRSHGSMICON_BUFDR pCmdDr = vboxMpCrShgsmiBufCacheAlloc(pCon, &pCon->CmdDrCache, cbCmd);
     264    if (!pCmdDr)
     265    {
     266        WARN(("vboxMpCrShgsmiBufCacheAlloc for cmd dr failed"));
     267        return VERR_NO_MEMORY;
     268    }
     269    PVBOXMP_CRSHGSMICON_BUFDR pWbDr = vboxMpCrShgsmiBufCacheAllocAny(pCon, &pCon->WbDrCache, 1000);
     270    if (!pWbDr)
     271    {
     272        WARN(("vboxMpCrShgsmiBufCacheAlloc for wb dr failed"));
     273        vboxMpCrShgsmiBufCacheFree(pCon, &pCon->CmdDrCache, pCmdDr);
     274        return VERR_NO_MEMORY;
     275    }
     276
     277    PVBOXVDMACBUF_DR pDr = (PVBOXVDMACBUF_DR)pCmdDr->pvBuf;
     278    pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
     279    pDr->cbBuf = cbCmd;
     280    pDr->rc = VERR_NOT_IMPLEMENTED;
     281
     282    PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
     283    pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
     284    pHdr->u32CmdSpecific = 0;
     285    VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
     286    pBody->cBuffers = cBuffers;
     287    CRVBOXHGSMIWRITEREAD *pCmd = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pDr, cBuffers, CRVBOXHGSMIWRITEREAD);
     288    pCmd->hdr.result      = VERR_WRONG_ORDER;
     289    pCmd->hdr.u32ClientID = pCon->u32ClientID;
     290    pCmd->hdr.u32Function = SHCRGL_GUEST_FN_WRITE_READ;
     291    //    pCmd->hdr.u32Reserved = 0;
     292    pCmd->iBuffer = 1;
     293    pCmd->iWriteback = 2;
     294    pCmd->cbWriteback = 0;
     295
     296    VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
     297    pBufCmd->offBuffer = vboxMpCrShgsmiConBufOffset(pCon, pCmd);
     298    pBufCmd->cbBuffer = sizeof (*pCmd);
     299    pBufCmd->u32GuestData = 0;
     300    pBufCmd->u64GuestData = (uint64_t)pCmdDr;
     301
     302    pBufCmd = &pBody->aBuffers[1];
     303    pBufCmd->offBuffer = vboxMpCrShgsmiConBufOffset(pCon, pvTx);
     304    pBufCmd->cbBuffer = cbTx;
     305    pBufCmd->u32GuestData = 0;
     306    pBufCmd->u64GuestData = 0;
     307
     308    pBufCmd = &pBody->aBuffers[2];
     309    pBufCmd->offBuffer = vboxMpCrShgsmiConBufOffset(pCon, pWbDr->pvBuf);
     310    pBufCmd->cbBuffer = pWbDr->cbBuf;
     311    pBufCmd->u32GuestData = 0;
     312    pBufCmd->u64GuestData = (uint64_t)pWbDr;
     313
     314    PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
     315    PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
     316    vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxMpCrShgsmiConSendAsyncCompletion, pDr);
     317    /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
     318    vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
     319    int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
     320    if (RT_SUCCESS(rc))
     321    {
     322        return STATUS_SUCCESS;
     323    }
     324
     325    /* impl failure branch */
     326    Assert(0);
     327    return rc;
     328}
     329
     330static CRMessageOpcodes *
     331vboxMpCrPackerPrependHeader( CRPackBuffer *buf, unsigned int *len, unsigned int senderID )
     332{
     333    UINT num_opcodes;
     334    CRMessageOpcodes *hdr;
     335
     336    Assert(buf);
     337    Assert(buf->opcode_current < buf->opcode_start);
     338    Assert(buf->opcode_current >= buf->opcode_end);
     339    Assert(buf->data_current > buf->data_start);
     340    Assert(buf->data_current <= buf->data_end);
     341
     342    num_opcodes = (UINT)(buf->opcode_start - buf->opcode_current);
     343    hdr = (CRMessageOpcodes *)
     344        ( buf->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
     345
     346    Assert((void *) hdr >= buf->pack);
     347
     348    hdr->header.type = CR_MESSAGE_OPCODES;
     349    hdr->numOpcodes  = num_opcodes;
     350
     351    *len = (UINT)(buf->data_current - (unsigned char *) hdr);
     352
     353    return hdr;
     354}
     355
    47356static void vboxMpCrShgsmiPackerCbFlush(void *pvFlush)
    48357{
    49     PPVBOXMP_SHGSMIPACKER pPacker = (PPVBOXMP_SHGSMIPACKER)pvFlush;
     358    PVBOXMP_CRSHGSMIPACKER pPacker = (PVBOXMP_CRSHGSMIPACKER)pvFlush;
    50359
    51360    crPackReleaseBuffer(&pPacker->CrPacker);
     
    65374}
    66375
    67 static int vboxMpCrShgsmiPackerInit(PPVBOXMP_SHGSMIPACKER pPacker, PVBOXMP_DEVEXT pDevExt)
     376int vboxMpCrShgsmiPackerInit(PVBOXMP_CRSHGSMIPACKER pPacker, PVBOXMP_CRSHGSMICON pCon)
    68377{
    69378    memset(pPacker, 0, sizeof (*pPacker));
    70379
    71     static const cbBuffer = 1000;
    72     void *pvBuffer = vboxMpCrShgsmiBufferAlloc(pDevExt, cbBuffer);
     380    static const HGSMISIZE cbBuffer = 1000;
     381    void *pvBuffer = vboxMpCrShgsmiConAlloc(pCon, cbBuffer);
    73382    if (!pvBuffer)
    74383    {
    75         WARN(("vboxMpCrShgsmiBufferAlloc failed"));
     384        WARN(("vboxMpCrShgsmiConAlloc failed"));
    76385        return VERR_NO_MEMORY;
    77386    }
     387    pPacker->pCon = pCon;
    78388    crPackInitBuffer(&pPacker->CrBuffer, pvBuffer, cbBuffer, cbBuffer);
    79389    crPackSetBuffer(&pPacker->CrPacker, &pPacker->CrBuffer);
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