VirtualBox

Changeset 86838 in vbox for trunk/src/VBox/Devices/Graphics


Ignore:
Timestamp:
Nov 9, 2020 11:16:50 PM (4 years ago)
Author:
vboxsync
Message:

Devices/Graphics: A couple of new commands; a more generic handler for creating a surface; cleaned saved state data for a surface; increased saved state version; possibility to build DX11 backend. bugref:9830

Location:
trunk/src/VBox/Devices/Graphics
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp

    r86479 r86838  
    3737#endif
    3838
     39#ifdef DUMP_BITMAPS
     40# include <iprt/formats/bmp.h>
     41# include <stdio.h>
     42#endif
    3943
    4044#if defined(LOG_ENABLED) || defined(VBOX_STRICT)
     
    272276
    273277
     278#if !defined(VMSVGA3D_DX)
     279/*
     280 * Stubs for old backends.
     281 */
     282int vmsvga3dScreenTargetBind(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, uint32_t sid)
     283{
     284    RT_NOREF(pThisCC, pScreen, sid);
     285    return VERR_NOT_IMPLEMENTED;
     286}
     287
     288int vmsvga3dScreenTargetUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, SVGA3dRect const *pRect)
     289{
     290    RT_NOREF(pThisCC, pScreen, pRect);
     291    return VERR_NOT_IMPLEMENTED;
     292}
     293
     294int vmsvga3dSurfaceMap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox, VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap)
     295{
     296    RT_NOREF(pThisCC, pImage, pBox, enmMapType, pMap);
     297    return VERR_NOT_IMPLEMENTED;
     298}
     299
     300int vmsvga3dSurfaceUnmap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten)
     301{
     302    RT_NOREF(pThisCC, pImage, pMap, fWritten);
     303    return VERR_NOT_IMPLEMENTED;
     304}
     305#endif
     306
     307
     308/*
     309 *
     310 * Guest-Backed Objects (GBO).
     311 *
     312 */
     313
     314static int vmsvgaR3GboCreate(PVMSVGAR3STATE pSvgaR3State, SVGAMobFormat ptDepth, PPN64 baseAddress, uint32_t sizeInBytes, bool fGCPhys64, PVMSVGAGBO pGbo)
     315{
     316    ASSERT_GUEST_RETURN(sizeInBytes <= _128M, VERR_INVALID_PARAMETER); /** @todo Less than SVGA_REG_MOB_MAX_SIZE */
     317
     318    /*
     319     * The 'baseAddress' is a page number and points to the 'root page' of the GBO.
     320     * Content of the root page depends on the ptDepth value:
     321     * SVGA3D_MOBFMT_PTDEPTH[64]_0 - the only data page;
     322     * SVGA3D_MOBFMT_PTDEPTH[64]_1 - array of page numbers for data pages;
     323     * SVGA3D_MOBFMT_PTDEPTH[64]_2 - array of page numbers for SVGA3D_MOBFMT_PTDEPTH[64]_1 pages.
     324     * The code below extracts the page addresses of the GBO.
     325     */
     326
     327    /* Verify and normalize the ptDepth value. */
     328    if (RT_LIKELY(ptDepth >= SVGA3D_MOBFMT_PTDEPTH64_0 && ptDepth <= SVGA3D_MOBFMT_PTDEPTH64_2))
     329        ASSERT_GUEST_RETURN(fGCPhys64, VERR_INVALID_PARAMETER);
     330    else if (ptDepth >= SVGA3D_MOBFMT_PTDEPTH_0 && ptDepth <= SVGA3D_MOBFMT_PTDEPTH_2)
     331    {
     332        ASSERT_GUEST_RETURN(!fGCPhys64, VERR_INVALID_PARAMETER);
     333        /* Shift ptDepth to the SVGA3D_MOBFMT_PTDEPTH64_x range. */
     334        ptDepth = (SVGAMobFormat)(ptDepth + SVGA3D_MOBFMT_PTDEPTH64_0 - SVGA3D_MOBFMT_PTDEPTH_0);
     335    }
     336    else if (ptDepth == SVGA3D_MOBFMT_RANGE)
     337    { }
     338    else
     339        ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER);
     340
     341    uint32_t const cPPNsPerPage = X86_PAGE_SIZE / (fGCPhys64 ? sizeof(PPN64) : sizeof(PPN));
     342
     343    pGbo->cbTotal = sizeInBytes;
     344    pGbo->cTotalPages = (sizeInBytes + X86_PAGE_SIZE - 1) >> X86_PAGE_SHIFT;
     345
     346    /* Allocate the maximum amount possible (everything non-continuous) */
     347    PVMSVGAGBODESCRIPTOR paDescriptors = (PVMSVGAGBODESCRIPTOR)RTMemAlloc(pGbo->cTotalPages * sizeof(VMSVGAGBODESCRIPTOR));
     348    AssertReturn(paDescriptors, VERR_NO_MEMORY);
     349
     350    int rc = VINF_SUCCESS;
     351    if (ptDepth == SVGA3D_MOBFMT_PTDEPTH64_0)
     352    {
     353        ASSERT_GUEST_STMT_RETURN(pGbo->cTotalPages == 1,
     354                                 RTMemFree(paDescriptors),
     355                                 VERR_INVALID_PARAMETER);
     356
     357        RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT;
     358        GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
     359        paDescriptors[0].GCPhys   = GCPhys;
     360        paDescriptors[0].cPages = 1;
     361    }
     362    else if (ptDepth == SVGA3D_MOBFMT_PTDEPTH64_1)
     363    {
     364        ASSERT_GUEST_STMT_RETURN(pGbo->cTotalPages <= cPPNsPerPage,
     365                                 RTMemFree(paDescriptors),
     366                                 VERR_INVALID_PARAMETER);
     367
     368        /* Read the root page. */
     369        uint8_t au8RootPage[X86_PAGE_SIZE];
     370        RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT;
     371        rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhys, &au8RootPage, sizeof(au8RootPage));
     372        if (RT_SUCCESS(rc))
     373        {
     374            PPN64 *paPPN64 = (PPN64 *)&au8RootPage[0];
     375            PPN *paPPN32 = (PPN *)&au8RootPage[0];
     376            for (uint32_t iPPN = 0; iPPN < pGbo->cTotalPages; ++iPPN)
     377            {
     378                GCPhys = (RTGCPHYS)(fGCPhys64 ? paPPN64[iPPN] : paPPN32[iPPN]) << X86_PAGE_SHIFT;
     379                GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
     380                paDescriptors[iPPN].GCPhys   = GCPhys;
     381                paDescriptors[iPPN].cPages = 1;
     382            }
     383        }
     384    }
     385    else if (ptDepth == SVGA3D_MOBFMT_PTDEPTH64_2)
     386    {
     387        ASSERT_GUEST_STMT_RETURN(pGbo->cTotalPages <= cPPNsPerPage * cPPNsPerPage,
     388                                 RTMemFree(paDescriptors),
     389                                 VERR_INVALID_PARAMETER);
     390
     391        /* Read the Level2 root page. */
     392        uint8_t au8RootPageLevel2[X86_PAGE_SIZE];
     393        RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT;
     394        rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhys, &au8RootPageLevel2, sizeof(au8RootPageLevel2));
     395        if (RT_SUCCESS(rc))
     396        {
     397            uint32_t cPagesLeft = pGbo->cTotalPages;
     398
     399            PPN64 *paPPN64Level2 = (PPN64 *)&au8RootPageLevel2[0];
     400            PPN *paPPN32Level2 = (PPN *)&au8RootPageLevel2[0];
     401
     402            uint32_t const cPPNsLevel2 = (pGbo->cTotalPages + cPPNsPerPage - 1) / cPPNsPerPage;
     403            for (uint32_t iPPNLevel2 = 0; iPPNLevel2 < cPPNsLevel2; ++iPPNLevel2)
     404            {
     405                /* Read the Level1 root page. */
     406                uint8_t au8RootPage[X86_PAGE_SIZE];
     407                RTGCPHYS GCPhysLevel1 = (RTGCPHYS)(fGCPhys64 ? paPPN64Level2[iPPNLevel2] : paPPN32Level2[iPPNLevel2]) << X86_PAGE_SHIFT;
     408                GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
     409                rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhysLevel1, &au8RootPage, sizeof(au8RootPage));
     410                if (RT_SUCCESS(rc))
     411                {
     412                    PPN64 *paPPN64 = (PPN64 *)&au8RootPage[0];
     413                    PPN *paPPN32 = (PPN *)&au8RootPage[0];
     414
     415                    uint32_t const cPPNs = RT_MIN(cPagesLeft, cPPNsPerPage);
     416                    for (uint32_t iPPN = 0; iPPN < cPPNs; ++iPPN)
     417                    {
     418                        GCPhys = (RTGCPHYS)(fGCPhys64 ? paPPN64[iPPN] : paPPN32[iPPN]) << X86_PAGE_SHIFT;
     419                        GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
     420                        paDescriptors[iPPN + iPPNLevel2 * cPPNsPerPage].GCPhys   = GCPhys;
     421                        paDescriptors[iPPN + iPPNLevel2 * cPPNsPerPage].cPages = 1;
     422                    }
     423                    cPagesLeft -= cPPNs;
     424                }
     425            }
     426        }
     427    }
     428    else if (ptDepth == SVGA3D_MOBFMT_RANGE)
     429    {
     430        RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT;
     431        GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
     432        paDescriptors[0].GCPhys = GCPhys;
     433        paDescriptors[0].cPages = pGbo->cTotalPages;
     434    }
     435    else
     436    {
     437        AssertFailed();
     438        return VERR_INTERNAL_ERROR; /* ptDepth should be already verified. */
     439    }
     440
     441    /* Compress the descriptors. */
     442    if (ptDepth != SVGA3D_MOBFMT_RANGE)
     443    {
     444        uint32_t iDescriptor = 0;
     445        for (uint32_t i = 1; i < pGbo->cTotalPages; ++i)
     446        {
     447            /* Continuous physical memory? */
     448            if (paDescriptors[i].GCPhys == paDescriptors[iDescriptor].GCPhys + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE)
     449            {
     450                Assert(paDescriptors[iDescriptor].cPages);
     451                paDescriptors[iDescriptor].cPages++;
     452                Log5Func(("Page %x GCPhys=%RGp successor\n", i, paDescriptors[i].GCPhys));
     453            }
     454            else
     455            {
     456                iDescriptor++;
     457                paDescriptors[iDescriptor].GCPhys   = paDescriptors[i].GCPhys;
     458                paDescriptors[iDescriptor].cPages = 1;
     459                Log5Func(("Page %x GCPhys=%RGp\n", i, paDescriptors[iDescriptor].GCPhys));
     460            }
     461        }
     462
     463        pGbo->cDescriptors = iDescriptor + 1;
     464        Log5Func(("Nr of descriptors %d\n", pGbo->cDescriptors));
     465    }
     466    else
     467        pGbo->cDescriptors = 1;
     468
     469    if (RT_LIKELY(pGbo->cDescriptors < pGbo->cTotalPages))
     470    {
     471        pGbo->paDescriptors = (PVMSVGAGBODESCRIPTOR)RTMemRealloc(paDescriptors, pGbo->cDescriptors * sizeof(VMSVGAGBODESCRIPTOR));
     472        AssertReturn(pGbo->paDescriptors, VERR_NO_MEMORY);
     473    }
     474    else
     475        pGbo->paDescriptors = paDescriptors;
     476
     477    return VINF_SUCCESS;
     478}
     479
     480
     481static void vmsvgaR3GboDestroy(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo)
     482{
     483    RT_NOREF(pSvgaR3State);
     484    if (RT_LIKELY(VMSVGA_IS_GBO_CREATED(pGbo)))
     485    {
     486        RTMemFree(pGbo->paDescriptors);
     487        RT_ZERO(pGbo);
     488    }
     489}
     490
     491
     492typedef enum VMSVGAGboTransferDirection
     493{
     494    VMSVGAGboTransferDirection_Read,
     495    VMSVGAGboTransferDirection_Write,
     496} VMSVGAGboTransferDirection;
     497
     498static int vmsvgaR3GboTransfer(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo,
     499                               uint32_t off, void *pvData, uint32_t cbData,
     500                               VMSVGAGboTransferDirection enmDirection)
     501{
     502// ASMBreakpoint();
     503    int rc = VINF_SUCCESS;
     504    uint8_t *pu8CurrentHost  = (uint8_t *)pvData;
     505
     506    /* Find the right descriptor */
     507    PCVMSVGAGBODESCRIPTOR const paDescriptors = pGbo->paDescriptors;
     508    uint32_t iDescriptor = 0;                               /* Index in the descriptor array. */
     509    uint32_t offDescriptor = 0;                             /* GMR offset of the current descriptor. */
     510    while (offDescriptor + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE <= off)
     511    {
     512        offDescriptor += paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE;
     513        AssertReturn(offDescriptor < pGbo->cbTotal, VERR_INTERNAL_ERROR); /* overflow protection */
     514        ++iDescriptor;
     515        AssertReturn(iDescriptor < pGbo->cDescriptors, VERR_INTERNAL_ERROR);
     516    }
     517
     518    while (cbData)
     519    {
     520        uint32_t cbToCopy;
     521        if (off + cbData <= offDescriptor + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE)
     522            cbToCopy = cbData;
     523        else
     524        {
     525            cbToCopy = (offDescriptor + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE - off);
     526            AssertReturn(cbToCopy <= cbData, VERR_INVALID_PARAMETER);
     527        }
     528
     529        RTGCPHYS const GCPhys = paDescriptors[iDescriptor].GCPhys + off - offDescriptor;
     530        Log5Func(("%s phys=%RGp\n", (enmDirection == VMSVGAGboTransferDirection_Read) ? "READ" : "WRITE", GCPhys));
     531
     532        if (enmDirection == VMSVGAGboTransferDirection_Read)
     533            rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhys, pu8CurrentHost, cbToCopy);
     534        else
     535            rc = PDMDevHlpPCIPhysWrite(pSvgaR3State->pDevIns, GCPhys, pu8CurrentHost, cbToCopy);
     536        AssertRCBreak(rc);
     537
     538        cbData         -= cbToCopy;
     539        off            += cbToCopy;
     540        pu8CurrentHost += cbToCopy;
     541
     542        /* Go to the next descriptor if there's anything left. */
     543        if (cbData)
     544        {
     545            offDescriptor += paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE;
     546            AssertReturn(offDescriptor < pGbo->cbTotal, VERR_INTERNAL_ERROR);
     547            ++iDescriptor;
     548            AssertReturn(iDescriptor < pGbo->cDescriptors, VERR_INTERNAL_ERROR);
     549        }
     550    }
     551    return rc;
     552}
     553
     554
     555static int vmsvgaR3GboWrite(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo,
     556                            uint32_t off, void const *pvData, uint32_t cbData)
     557{
     558    return vmsvgaR3GboTransfer(pSvgaR3State, pGbo,
     559                               off, (void *)pvData, cbData,
     560                               VMSVGAGboTransferDirection_Write);
     561}
     562
     563
     564static int vmsvgaR3GboRead(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo,
     565                           uint32_t off, void *pvData, uint32_t cbData)
     566{
     567    return vmsvgaR3GboTransfer(pSvgaR3State, pGbo,
     568                               off, pvData, cbData,
     569                               VMSVGAGboTransferDirection_Read);
     570}
     571
     572
     573/*
     574 *
     575 * Object Tables.
     576 *
     577 */
     578
     579static int vmsvgaR3OTableVerifyIndex(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGboOTable,
     580                                     uint32_t idx, uint32_t cbEntry)
     581{
     582    RT_NOREF(pSvgaR3State);
     583
     584    /* The table must exist and the index must be within the table. */
     585    ASSERT_GUEST_RETURN(VMSVGA_IS_GBO_CREATED(pGboOTable), VERR_INVALID_PARAMETER);
     586    ASSERT_GUEST_RETURN(idx < pGboOTable->cbTotal / cbEntry, VERR_INVALID_PARAMETER);
     587    RT_UNTRUSTED_VALIDATED_FENCE();
     588    return VINF_SUCCESS;
     589}
     590
     591
     592static int vmsvgaR3OTableRead(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGboOTable,
     593                              uint32_t idx, uint32_t cbEntry,
     594                              void *pvData, uint32_t cbData)
     595{
     596    AssertReturn(cbData <= cbEntry, VERR_INVALID_PARAMETER);
     597
     598    int rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, pGboOTable, idx, cbEntry);
     599    if (RT_SUCCESS(rc))
     600    {
     601        uint32_t const off = idx * cbEntry;
     602        rc = vmsvgaR3GboRead(pSvgaR3State, pGboOTable, off, pvData, cbData);
     603    }
     604    return rc;
     605}
     606
     607static int vmsvgaR3OTableWrite(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGboOTable,
     608                               uint32_t idx, uint32_t cbEntry,
     609                               void const *pvData, uint32_t cbData)
     610{
     611    AssertReturn(cbData <= cbEntry, VERR_INVALID_PARAMETER);
     612
     613    int rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, pGboOTable, idx, cbEntry);
     614    if (RT_SUCCESS(rc))
     615    {
     616        uint32_t const off = idx * cbEntry;
     617        rc = vmsvgaR3GboWrite(pSvgaR3State, pGboOTable, off, pvData, cbData);
     618    }
     619    return rc;
     620}
     621
     622
     623/*
     624 *
     625 * The guest's Memory OBjects (MOB).
     626 *
     627 */
     628
     629static int vmsvgaR3MobCreate(PVMSVGAR3STATE pSvgaR3State,
     630                             SVGAMobFormat ptDepth, PPN64 baseAddress, uint32_t sizeInBytes, SVGAMobId mobid,
     631                             bool fGCPhys64, PVMSVGAMOB pMob)
     632{
     633    RT_ZERO(*pMob);
     634
     635    /* Update the entry in the pSvgaR3State->pGboOTableMob. */
     636    SVGAOTableMobEntry entry;
     637    entry.ptDepth     = ptDepth;
     638    entry.sizeInBytes = sizeInBytes;
     639    entry.base        = baseAddress;
     640    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableMob,
     641                                 mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE, &entry, sizeof(entry));
     642    if (RT_SUCCESS(rc))
     643    {
     644        /* Create the corresponding GBO. */
     645        rc = vmsvgaR3GboCreate(pSvgaR3State, ptDepth, baseAddress, sizeInBytes, fGCPhys64, &pMob->Gbo);
     646        if (RT_SUCCESS(rc))
     647        {
     648            /* Add to the tree of known GBOs and the LRU list. */
     649            pMob->Core.Key = mobid;
     650            if (RTAvlU32Insert(&pSvgaR3State->MOBTree, &pMob->Core))
     651            {
     652                RTListPrepend(&pSvgaR3State->MOBLRUList, &pMob->nodeLRU);
     653                return VINF_SUCCESS;
     654            }
     655
     656            vmsvgaR3GboDestroy(pSvgaR3State, &pMob->Gbo);
     657        }
     658    }
     659
     660    return rc;
     661}
     662
     663
     664static int vmsvgaR3MobDestroy(PVMSVGAR3STATE pSvgaR3State, SVGAMobId mobid)
     665{
     666    /* Update the entry in the pSvgaR3State->pGboOTableMob. */
     667    SVGAOTableMobEntry entry;
     668    RT_ZERO(entry);
     669    vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableMob,
     670                        mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE, &entry, sizeof(entry));
     671
     672    PVMSVGAMOB pMob = (PVMSVGAMOB)RTAvlU32Remove(&pSvgaR3State->MOBTree, mobid);
     673    if (pMob)
     674    {
     675        RTListNodeRemove(&pMob->nodeLRU);
     676        vmsvgaR3GboDestroy(pSvgaR3State, &pMob->Gbo);
     677        RTMemFree(pMob);
     678        return VINF_SUCCESS;
     679    }
     680
     681    return VERR_INVALID_PARAMETER;
     682}
     683
     684
     685static PVMSVGAMOB vmsvgaR3MobGet(PVMSVGAR3STATE pSvgaR3State, SVGAMobId mobid)
     686{
     687    PVMSVGAMOB pMob = (PVMSVGAMOB)RTAvlU32Get(&pSvgaR3State->MOBTree, mobid);
     688    if (pMob)
     689    {
     690        /* Move to the head of the LRU list. */
     691        RTListNodeRemove(&pMob->nodeLRU);
     692        RTListPrepend(&pSvgaR3State->MOBLRUList, &pMob->nodeLRU);
     693    }
     694
     695    return pMob;
     696}
     697
     698/*
     699 * Screen objects.
     700 */
    274701VMSVGASCREENOBJECT *vmsvgaR3GetScreenObject(PVGASTATECC pThisCC, uint32_t idScreen)
    275702{
     
    435862
    436863#ifdef VBOX_WITH_VMSVGA3D
     864
     865/*
     866 * SVGA_3D_CMD_* handlers.
     867 */
     868
     869
     870/** SVGA_3D_CMD_SURFACE_DEFINE 1040, SVGA_3D_CMD_SURFACE_DEFINE_V2 1070
     871 *
     872 * @param pThisCC         The VGA/VMSVGA state for the current context.
     873 * @param pCmd            The VMSVGA command.
     874 * @param cMipLevelSizes  Number of elements in the paMipLevelSizes array.
     875 * @param paMipLevelSizes Arrays of surface sizes for each face and miplevel.
     876 */
     877static void vmsvga3dCmdDefineSurface(PVGASTATECC pThisCC, SVGA3dCmdDefineSurface_v2 const *pCmd,
     878                                     uint32_t cMipLevelSizes, SVGA3dSize *paMipLevelSizes)
     879{
     880    ASSERT_GUEST_RETURN_VOID(pCmd->sid < SVGA3D_MAX_SURFACE_IDS);
     881    ASSERT_GUEST_RETURN_VOID(cMipLevelSizes >= 1);
     882    RT_UNTRUSTED_VALIDATED_FENCE();
     883
     884    /* Number of faces (cFaces) is specified as the number of the first non-zero elements in the 'face' array.
     885     * Since only plain surfaces (cFaces == 1) and cubemaps (cFaces == 6) are supported
     886     * (see also SVGA3dCmdDefineSurface definition in svga3d_reg.h), we ignore anything else.
     887     */
     888    uint32_t cRemainingMipLevels = cMipLevelSizes;
     889    uint32_t cFaces = 0;
     890    for (uint32_t i = 0; i < SVGA3D_MAX_SURFACE_FACES; ++i)
     891    {
     892        if (pCmd->face[i].numMipLevels == 0)
     893            break;
     894
     895        /* All SVGA3dSurfaceFace structures must have the same value of numMipLevels field */
     896        ASSERT_GUEST_RETURN_VOID(pCmd->face[i].numMipLevels == pCmd->face[0].numMipLevels);
     897
     898        /* numMipLevels value can't be greater than the number of remaining elements in the paMipLevelSizes array. */
     899        ASSERT_GUEST_RETURN_VOID(pCmd->face[i].numMipLevels <= cRemainingMipLevels);
     900        cRemainingMipLevels -= pCmd->face[i].numMipLevels;
     901
     902        ++cFaces;
     903    }
     904    for (uint32_t i = cFaces; i < SVGA3D_MAX_SURFACE_FACES; ++i)
     905        ASSERT_GUEST_RETURN_VOID(pCmd->face[i].numMipLevels == 0);
     906
     907    /* cFaces must be 6 for a cubemap and 1 otherwise. */
     908    ASSERT_GUEST_RETURN_VOID(cFaces == (uint32_t)((pCmd->surfaceFlags & SVGA3D_SURFACE_CUBEMAP) ? 6 : 1));
     909
     910    /* Sum of face[i].numMipLevels must be equal to cMipLevels. */
     911    ASSERT_GUEST_RETURN_VOID(cRemainingMipLevels == 0);
     912    RT_UNTRUSTED_VALIDATED_FENCE();
     913
     914    /* Verify paMipLevelSizes */
     915    uint32_t cWidth  = paMipLevelSizes[0].width;
     916    uint32_t cHeight = paMipLevelSizes[0].height;
     917    uint32_t cDepth  = paMipLevelSizes[0].depth;
     918    for (uint32_t i = 1; i < pCmd->face[0].numMipLevels; ++i)
     919    {
     920        cWidth >>= 1;
     921        if (cWidth == 0) cWidth = 1;
     922        cHeight >>= 1;
     923        if (cHeight == 0) cHeight = 1;
     924        cDepth >>= 1;
     925        if (cDepth == 0) cDepth = 1;
     926        for (uint32_t iFace = 0; iFace < cFaces; ++iFace)
     927        {
     928            uint32_t const iMipLevelSize = iFace * pCmd->face[0].numMipLevels + i;
     929            ASSERT_GUEST_RETURN_VOID(   cWidth  == paMipLevelSizes[iMipLevelSize].width
     930                                     && cHeight == paMipLevelSizes[iMipLevelSize].height
     931                                     && cDepth  == paMipLevelSizes[iMipLevelSize].depth);
     932        }
     933    }
     934    RT_UNTRUSTED_VALIDATED_FENCE();
     935
     936    /* Create the surface. */
     937    vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format,
     938                          pCmd->multisampleCount, pCmd->autogenFilter,
     939                          pCmd->face[0].numMipLevels, &paMipLevelSizes[0]);
     940}
     941
     942
     943/* SVGA_3D_CMD_DEFINE_GB_MOB 1093 */
     944static void vmsvga3dCmdDefineGBMob(PVGASTATECC pThisCC, SVGA3dCmdDefineGBMob const *pCmd)
     945{
     946    ASMBreakpoint();
     947    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     948
     949    ASSERT_GUEST_RETURN_VOID(pCmd->mobid != SVGA_ID_INVALID); /* The guest should not use this id. */
     950
     951    /* Maybe just update the OTable and create Gbo when the MOB is actually accessed? */
     952    /* Allocate a structure for the MOB. */
     953    PVMSVGAMOB pMob = (PVMSVGAMOB)RTMemAllocZ(sizeof(*pMob));
     954    AssertPtrReturnVoid(pMob);
     955
     956    int rc = vmsvgaR3MobCreate(pSvgaR3State, pCmd->ptDepth, pCmd->base, pCmd->sizeInBytes, pCmd->mobid, /*fGCPhys64=*/ false, pMob);
     957    if (RT_SUCCESS(rc))
     958    {
     959        return;
     960    }
     961
     962    AssertFailed();
     963
     964    RTMemFree(pMob);
     965}
     966
     967
     968/* SVGA_3D_CMD_DESTROY_GB_MOB 1094 */
     969static void vmsvga3dCmdDestroyGBMob(PVGASTATECC pThisCC, SVGA3dCmdDestroyGBMob const *pCmd)
     970{
     971//    ASMBreakpoint();
     972    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     973
     974    ASSERT_GUEST_RETURN_VOID(pCmd->mobid != SVGA_ID_INVALID); /* The guest should not use this id. */
     975
     976    int rc = vmsvgaR3MobDestroy(pSvgaR3State, pCmd->mobid);
     977    if (RT_SUCCESS(rc))
     978    {
     979        return;
     980    }
     981
     982    AssertFailed();
     983}
     984
     985
     986/* SVGA_3D_CMD_DEFINE_GB_SURFACE 1097 */
     987static void vmsvga3dCmdDefineGBSurface(PVGASTATECC pThisCC, SVGA3dCmdDefineGBSurface const *pCmd)
     988{
     989//     ASMBreakpoint();
     990    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     991
     992    /* Update the entry in the pSvgaR3State->pGboOTableSurface. */
     993    SVGAOTableSurfaceEntry entry;
     994    RT_ZERO(entry);
     995    entry.format = pCmd->format;
     996    entry.surfaceFlags = pCmd->surfaceFlags;
     997    entry.numMipLevels = pCmd->numMipLevels;
     998    entry.multisampleCount = pCmd->multisampleCount;
     999    entry.autogenFilter = pCmd->autogenFilter;
     1000    entry.size = pCmd->size;
     1001    entry.mobid = SVGA_ID_INVALID;
     1002    // entry.arraySize = 0;
     1003    // entry.mobPitch = 0;
     1004    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
     1005                                 pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
     1006    if (RT_SUCCESS(rc))
     1007    {
     1008        /* Create the host surface. */
     1009        /** @todo fGBO = true flag. */
     1010        vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format,
     1011                              pCmd->multisampleCount, pCmd->autogenFilter,
     1012                              pCmd->numMipLevels, &pCmd->size);
     1013    }
     1014}
     1015
     1016
     1017/* SVGA_3D_CMD_DESTROY_GB_SURFACE 1098 */
     1018static void vmsvga3dCmdDestroyGBSurface(PVGASTATECC pThisCC, SVGA3dCmdDestroyGBSurface const *pCmd)
     1019{
     1020//     ASMBreakpoint();
     1021    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1022
     1023    /* Update the entry in the pSvgaR3State->pGboOTableSurface. */
     1024    SVGAOTableSurfaceEntry entry;
     1025    RT_ZERO(entry);
     1026    entry.mobid = SVGA_ID_INVALID;
     1027    vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
     1028                        pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
     1029
     1030    vmsvga3dSurfaceDestroy(pThisCC, pCmd->sid);
     1031}
     1032
     1033
     1034/* SVGA_3D_CMD_BIND_GB_SURFACE 1099 */
     1035static void vmsvga3dCmdBindGBSurface(PVGASTATECC pThisCC, SVGA3dCmdBindGBSurface const *pCmd)
     1036{
     1037//     ASMBreakpoint();
     1038    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1039    RT_NOREF(pCmd, pSvgaR3State);
     1040
     1041    /* Assign the mobid to the surface. */
     1042    int rc = VINF_SUCCESS;
     1043    if (pCmd->mobid != SVGA_ID_INVALID)
     1044        rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, &pSvgaR3State->GboOTableMob,
     1045                                       pCmd->mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE);
     1046    if (RT_SUCCESS(rc))
     1047    {
     1048        SVGAOTableSurfaceEntry entry;
     1049        rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
     1050                                pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
     1051        if (RT_SUCCESS(rc))
     1052        {
     1053            entry.mobid = pCmd->mobid;
     1054            rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
     1055                                     pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
     1056            if (RT_SUCCESS(rc))
     1057            {
     1058                /* */
     1059            }
     1060        }
     1061    }
     1062}
     1063
     1064
     1065#ifdef DUMP_BITMAPS
     1066static int vmsvga3dBmpWrite(const char *pszFilename, VMSVGA3D_MAPPED_SURFACE const *pMap)
     1067{
     1068    if (pMap->cbPixel != 4)
     1069        return VERR_NOT_SUPPORTED;
     1070
     1071    int const w = pMap->box.w;
     1072    int const h = pMap->box.h;
     1073
     1074    const int cbBitmap = w * h * 4;
     1075
     1076    FILE *f = fopen(pszFilename, "wb");
     1077    if (!f)
     1078        return VERR_FILE_NOT_FOUND;
     1079
     1080    {
     1081        BMPFILEHDR fileHdr;
     1082        RT_ZERO(fileHdr);
     1083        fileHdr.uType      = BMP_HDR_MAGIC;
     1084        fileHdr.cbFileSize = sizeof(BMPFILEHDR) + sizeof(BMPWIN3XINFOHDR) + cbBitmap;
     1085        fileHdr.offBits    = sizeof(BMPFILEHDR) + sizeof(BMPWIN3XINFOHDR);
     1086
     1087        BMPWIN3XINFOHDR coreHdr;
     1088        RT_ZERO(coreHdr);
     1089        coreHdr.cbSize      = sizeof(coreHdr);
     1090        coreHdr.uWidth      = w;
     1091        coreHdr.uHeight     = -h;
     1092        coreHdr.cPlanes     = 1;
     1093        coreHdr.cBits       = 32;
     1094        coreHdr.cbSizeImage = cbBitmap;
     1095
     1096        fwrite(&fileHdr, 1, sizeof(fileHdr), f);
     1097        fwrite(&coreHdr, 1, sizeof(coreHdr), f);
     1098    }
     1099
     1100    if (pMap->cbPixel == 4)
     1101    {
     1102        const uint8_t *s = (uint8_t *)pMap->pvData;
     1103        for (int32_t y = 0; y < h; ++y)
     1104        {
     1105            fwrite(s, 1, w * pMap->cbPixel, f);
     1106
     1107            s += pMap->cbRowPitch;
     1108        }
     1109    }
     1110
     1111    fclose(f);
     1112
     1113    return VINF_SUCCESS;
     1114}
     1115
     1116
     1117void vmsvga3dMapWriteBmpFile(VMSVGA3D_MAPPED_SURFACE const *pMap, char const *pszPrefix)
     1118{
     1119    static int idxBitmap = 0;
     1120    char *pszFilename = RTStrAPrintf2("bmp\\%s%d.bmp", pszPrefix, idxBitmap++);
     1121    vmsvga3dBmpWrite(pszFilename, pMap);
     1122    RTStrFree(pszFilename);
     1123}
     1124#endif /* DUMP_BITMAPS */
     1125
     1126
     1127/* SVGA_3D_CMD_UPDATE_GB_IMAGE 1101 */
     1128static void vmsvga3dCmdUpdateGBImage(PVGASTATECC pThisCC, SVGA3dCmdUpdateGBImage const *pCmd)
     1129{
     1130//     ASMBreakpoint();
     1131    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1132
     1133    LogFlowFunc(("sid=%u @%u,%u,%u %ux%ux%u\n",
     1134                 pCmd->image.sid, pCmd->box.x, pCmd->box.y, pCmd->box.z, pCmd->box.w, pCmd->box.h, pCmd->box.d));
     1135
     1136    /* "update a surface from its backing MOB." */
     1137    SVGAOTableSurfaceEntry entrySurface;
     1138    int rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
     1139                            pCmd->image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entrySurface, sizeof(entrySurface));
     1140    if (RT_SUCCESS(rc))
     1141    {
     1142        PVMSVGAMOB pMob = vmsvgaR3MobGet(pSvgaR3State, entrySurface.mobid);
     1143        if (pMob)
     1144        {
     1145            VMSVGA3D_MAPPED_SURFACE map;
     1146            rc = vmsvga3dSurfaceMap(pThisCC, &pCmd->image, &pCmd->box, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
     1147            if (RT_SUCCESS(rc))
     1148            {
     1149                /* Copy MOB -> mapped surface. */
     1150                uint32_t offSrc = pCmd->box.x * map.cbPixel
     1151                                + pCmd->box.y * entrySurface.size.width * map.cbPixel
     1152                                + pCmd->box.z * entrySurface.size.height * entrySurface.size.width * map.cbPixel;
     1153                uint8_t *pu8Dst = (uint8_t *)map.pvData;
     1154                for (uint32_t z = 0; z < pCmd->box.d; ++z)
     1155                {
     1156                    for (uint32_t y = 0; y < pCmd->box.h; ++y)
     1157                    {
     1158                        rc = vmsvgaR3GboRead(pSvgaR3State, &pMob->Gbo, offSrc, pu8Dst, pCmd->box.w * map.cbPixel);
     1159                        if (RT_FAILURE(rc))
     1160                            break;
     1161
     1162                        pu8Dst += map.cbRowPitch;
     1163                        offSrc += entrySurface.size.width * map.cbPixel;
     1164                    }
     1165
     1166                    pu8Dst += map.cbDepthPitch;
     1167                    offSrc += entrySurface.size.height * entrySurface.size.width * map.cbPixel;
     1168                }
     1169
     1170                // vmsvga3dMapWriteBmpFile(&map, "Dynamic");
     1171
     1172                vmsvga3dSurfaceUnmap(pThisCC, &pCmd->image, &map, /* fWritten =  */true);
     1173            }
     1174        }
     1175    }
     1176}
     1177
     1178
     1179/* SVGA_3D_CMD_INVALIDATE_GB_SURFACE 1106 */
     1180static void vmsvga3dCmdInvalidateGBSurface(PVGASTATECC pThisCC, SVGA3dCmdInvalidateGBSurface const *pCmd)
     1181{
     1182//     ASMBreakpoint();
     1183    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1184    RT_NOREF(pSvgaR3State, pCmd);
     1185    /** @todo Implement. */
     1186}
     1187
     1188
     1189/* SVGA_3D_CMD_SET_OTABLE_BASE64 1115 */
     1190static void vmsvga3dCmdSetOTableBase64(PVGASTATECC pThisCC, SVGA3dCmdSetOTableBase64 const *pCmd)
     1191{
     1192    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1193
     1194    /*
     1195     * Create a GBO for the table.
     1196     */
     1197    PVMSVGAGBO pGbo;
     1198    switch (pCmd->type)
     1199    {
     1200        case SVGA_OTABLE_MOB:
     1201        {
     1202            pGbo = &pSvgaR3State->GboOTableMob;
     1203            break;
     1204        }
     1205        case SVGA_OTABLE_SURFACE:
     1206        {
     1207            pGbo = &pSvgaR3State->GboOTableSurface;
     1208            break;
     1209        }
     1210        case SVGA_OTABLE_CONTEXT:
     1211        {
     1212            pGbo = &pSvgaR3State->GboOTableContext;
     1213            break;
     1214        }
     1215        case SVGA_OTABLE_SHADER:
     1216        {
     1217            pGbo = &pSvgaR3State->GboOTableShader;
     1218            break;
     1219        }
     1220        case SVGA_OTABLE_SCREENTARGET:
     1221        {
     1222            pGbo = &pSvgaR3State->GboOTableScreenTarget;
     1223            break;
     1224        }
     1225        default:
     1226            pGbo = NULL;
     1227            ASSERT_GUEST_FAILED();
     1228            break;
     1229    }
     1230
     1231    if (pGbo)
     1232    {
     1233        /* Recreate. */
     1234        vmsvgaR3GboDestroy(pSvgaR3State, pGbo);
     1235        int rc = vmsvgaR3GboCreate(pSvgaR3State, pCmd->ptDepth, pCmd->baseAddress, pCmd->sizeInBytes, /*fGCPhys64=*/ true, pGbo);
     1236        AssertRC(rc);
     1237    }
     1238}
     1239
     1240
     1241/* SVGA_3D_CMD_DEFINE_GB_SCREENTARGET 1124 */
     1242static void vmsvga3dCmdDefineGBScreenTarget(PVGASTATE pThis, PVGASTATECC pThisCC, SVGA3dCmdDefineGBScreenTarget const *pCmd)
     1243{
     1244//     ASMBreakpoint();
     1245    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1246
     1247    ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens));
     1248    ASSERT_GUEST_RETURN_VOID(pCmd->width > 0 && pCmd->width <= pThis->svga.u32MaxWidth); /* SVGA_REG_SCREENTARGET_MAX_WIDTH */
     1249    ASSERT_GUEST_RETURN_VOID(pCmd->height > 0 && pCmd->height <= pThis->svga.u32MaxHeight); /* SVGA_REG_SCREENTARGET_MAX_HEIGHT */
     1250    RT_UNTRUSTED_VALIDATED_FENCE();
     1251
     1252    /* Update the entry in the pSvgaR3State->pGboOTableScreenTarget. */
     1253    SVGAOTableScreenTargetEntry entry;
     1254    RT_ZERO(entry);
     1255    entry.image.sid = SVGA_ID_INVALID;
     1256    // entry.image.face = 0;
     1257    // entry.image.mipmap = 0;
     1258    entry.width = pCmd->width;
     1259    entry.height = pCmd->height;
     1260    entry.xRoot = pCmd->xRoot;
     1261    entry.yRoot = pCmd->yRoot;
     1262    entry.flags = pCmd->flags;
     1263    entry.dpi = pCmd->dpi;
     1264    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget,
     1265                                 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
     1266    if (RT_SUCCESS(rc))
     1267    {
     1268        /* Screen objects and screen targets are similar, therefore we will use the same for both. */
     1269        /** @todo Generic screen object/target interface. */
     1270        VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid];
     1271        pScreen->fDefined  = true;
     1272        pScreen->fModified = true;
     1273        pScreen->fuScreen  = SVGA_SCREEN_MUST_BE_SET
     1274                           | (RT_BOOL(pCmd->flags & SVGA_STFLAG_PRIMARY) ? SVGA_SCREEN_IS_PRIMARY : 0);
     1275        pScreen->idScreen  = pCmd->stid;
     1276
     1277        pScreen->xOrigin = pCmd->xRoot;
     1278        pScreen->yOrigin = pCmd->yRoot;
     1279        pScreen->cWidth  = pCmd->width;
     1280        pScreen->cHeight = pCmd->height;
     1281        pScreen->offVRAM = 0; /* Always for screen targets, they use either a separate memory buffer or a host window. */
     1282        pScreen->cbPitch = pCmd->width * 4;
     1283        pScreen->cBpp    = 32;
     1284
     1285        if (RT_LIKELY(pThis->svga.f3DEnabled))
     1286            vmsvga3dDefineScreen(pThis, pThisCC, pScreen);
     1287
     1288        if (!pScreen->pHwScreen)
     1289        {
     1290            /* System memory buffer. */
     1291            pScreen->pvScreenBitmap = RTMemAllocZ(pScreen->cHeight * pScreen->cbPitch);
     1292        }
     1293
     1294        pThis->svga.fGFBRegisters = false;
     1295        vmsvgaR3ChangeMode(pThis, pThisCC);
     1296    }
     1297}
     1298
     1299
     1300/* SVGA_3D_CMD_DESTROY_GB_SCREENTARGET 1125 */
     1301static void vmsvga3dCmdDestroyGBScreenTarget(PVGASTATE pThis, PVGASTATECC pThisCC, SVGA3dCmdDestroyGBScreenTarget const *pCmd)
     1302{
     1303//    ASMBreakpoint();
     1304    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1305
     1306    ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens));
     1307    RT_UNTRUSTED_VALIDATED_FENCE();
     1308
     1309    /* Update the entry in the pSvgaR3State->pGboOTableScreenTarget. */
     1310    SVGAOTableScreenTargetEntry entry;
     1311    RT_ZERO(entry);
     1312    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget,
     1313                                 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
     1314    if (RT_SUCCESS(rc))
     1315    {
     1316        /* Screen objects and screen targets are similar, therefore we will use the same for both. */
     1317        /** @todo Generic screen object/target interface. */
     1318        VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid];
     1319        pScreen->fModified = true;
     1320        pScreen->fDefined  = false;
     1321        pScreen->idScreen  = pCmd->stid;
     1322
     1323        if (RT_LIKELY(pThis->svga.f3DEnabled))
     1324            vmsvga3dDestroyScreen(pThisCC, pScreen);
     1325
     1326        vmsvgaR3ChangeMode(pThis, pThisCC);
     1327
     1328        RTMemFree(pScreen->pvScreenBitmap);
     1329        pScreen->pvScreenBitmap = NULL;
     1330    }
     1331}
     1332
     1333
     1334/* SVGA_3D_CMD_BIND_GB_SCREENTARGET 1126 */
     1335static void vmsvga3dCmdBindGBScreenTarget(PVGASTATECC pThisCC, SVGA3dCmdBindGBScreenTarget const *pCmd)
     1336{
     1337//     ASMBreakpoint();
     1338    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1339
     1340    /* "Binding a surface to a Screen Target the same as flipping" */
     1341
     1342    ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens));
     1343    ASSERT_GUEST_RETURN_VOID(pCmd->image.face == 0 && pCmd->image.mipmap == 0);
     1344    RT_UNTRUSTED_VALIDATED_FENCE();
     1345
     1346    /* Assign the surface to the screen target. */
     1347    int rc = VINF_SUCCESS;
     1348    if (pCmd->image.sid != SVGA_ID_INVALID)
     1349        rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
     1350                                       pCmd->image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE);
     1351    if (RT_SUCCESS(rc))
     1352    {
     1353        SVGAOTableScreenTargetEntry entry;
     1354        rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget,
     1355                                pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
     1356        if (RT_SUCCESS(rc))
     1357        {
     1358            entry.image = pCmd->image;
     1359            rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget,
     1360                                     pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
     1361            if (RT_SUCCESS(rc))
     1362            {
     1363                VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid];
     1364                rc = vmsvga3dScreenTargetBind(pThisCC, pScreen, pCmd->image.sid);
     1365                AssertRC(rc);
     1366            }
     1367        }
     1368    }
     1369}
     1370
     1371
     1372/* SVGA_3D_CMD_UPDATE_GB_SCREENTARGET 1127 */
     1373static void vmsvga3dCmdUpdateGBScreenTarget(PVGASTATECC pThisCC, SVGA3dCmdUpdateGBScreenTarget const *pCmd)
     1374{
     1375//     ASMBreakpoint();
     1376    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1377
     1378    /* Update the screen target from its backing surface. */
     1379    ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens));
     1380    RT_UNTRUSTED_VALIDATED_FENCE();
     1381
     1382    /* Get the screen target info. */
     1383    SVGAOTableScreenTargetEntry entryScreenTarget;
     1384    int rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget,
     1385                                pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entryScreenTarget, sizeof(entryScreenTarget));
     1386    if (RT_SUCCESS(rc))
     1387    {
     1388        ASSERT_GUEST_RETURN_VOID(entryScreenTarget.image.face == 0 && entryScreenTarget.image.mipmap == 0);
     1389        RT_UNTRUSTED_VALIDATED_FENCE();
     1390
     1391        if (entryScreenTarget.image.sid != SVGA_ID_INVALID)
     1392        {
     1393            SVGAOTableSurfaceEntry entrySurface;
     1394            rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
     1395                                    entryScreenTarget.image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entrySurface, sizeof(entrySurface));
     1396            if (RT_SUCCESS(rc))
     1397            {
     1398                /* Copy entrySurface.mobid content to the screen target. */
     1399                if (entrySurface.mobid != SVGA_ID_INVALID)
     1400                {
     1401                    RT_UNTRUSTED_VALIDATED_FENCE();
     1402                    SVGA3dRect targetRect = pCmd->rect;
     1403
     1404                    VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid];
     1405                    if (pScreen->pHwScreen)
     1406                    {
     1407                        /* Copy the screen target surface to the backend's screen. */
     1408                        vmsvga3dScreenTargetUpdate(pThisCC, pScreen, &targetRect);
     1409                    }
     1410                    else if (pScreen->pvScreenBitmap)
     1411                    {
     1412                        /* Copy the screen target surface to the memory buffer. */
     1413                        VMSVGA3D_MAPPED_SURFACE map;
     1414                        rc = vmsvga3dSurfaceMap(pThisCC, &entryScreenTarget.image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
     1415                        if (RT_SUCCESS(rc))
     1416                        {
     1417                            uint8_t const *pu8Src = (uint8_t *)map.pvData
     1418                                                  + targetRect.x * map.cbPixel
     1419                                                  + targetRect.y * map.cbRowPitch;
     1420                            uint8_t *pu8Dst = (uint8_t *)pScreen->pvScreenBitmap
     1421                                            + targetRect.x * map.cbPixel
     1422                                            + targetRect.y * map.box.w * map.cbPixel;
     1423                            for (uint32_t y = 0; y < targetRect.h; ++y)
     1424                            {
     1425                                memcpy(pu8Dst, pu8Src, targetRect.w * map.cbPixel);
     1426
     1427                                pu8Src += map.cbRowPitch;
     1428                                pu8Dst += map.box.w * map.cbPixel;
     1429                            }
     1430
     1431                            vmsvga3dSurfaceUnmap(pThisCC, &entryScreenTarget.image, &map, /* fWritten =  */ false);
     1432
     1433                            vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->rect.x, pCmd->rect.y, pCmd->rect.w, pCmd->rect.h);
     1434                        }
     1435                        else
     1436                            AssertFailed();
     1437                    }
     1438                }
     1439            }
     1440        }
     1441    }
     1442}
     1443
     1444
     1445/* SVGA_3D_CMD_DEFINE_GB_MOB64 1135 */
     1446static void vmsvga3dCmdDefineGBMob64(PVGASTATECC pThisCC, SVGA3dCmdDefineGBMob64 const *pCmd)
     1447{
     1448//     ASMBreakpoint();
     1449    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1450
     1451    ASSERT_GUEST_RETURN_VOID(pCmd->mobid != SVGA_ID_INVALID); /* The guest should not use this id. */
     1452
     1453    /* Maybe just update the OTable and create Gbo when the MOB is actually accessed? */
     1454    /* Allocate a structure for the MOB. */
     1455    PVMSVGAMOB pMob = (PVMSVGAMOB)RTMemAllocZ(sizeof(*pMob));
     1456    AssertPtrReturnVoid(pMob);
     1457
     1458    int rc = vmsvgaR3MobCreate(pSvgaR3State, pCmd->ptDepth, pCmd->base, pCmd->sizeInBytes, pCmd->mobid, /*fGCPhys64=*/ true, pMob);
     1459    if (RT_SUCCESS(rc))
     1460    {
     1461        return;
     1462    }
     1463
     1464    RTMemFree(pMob);
     1465}
     1466
     1467
    4371468/** @def VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK
    4381469 * Check that the 3D command has at least a_cbMin of payload bytes after the
     
    4731504        STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDefine);
    4741505
    475         uint32_t const cMipLevels = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize);
    476         vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, (uint32_t)pCmd->surfaceFlags, pCmd->format, pCmd->face, 0,
    477                               SVGA3D_TEX_FILTER_NONE, cMipLevels, (SVGA3dSize *)(pCmd + 1));
     1506        SVGA3dCmdDefineSurface_v2 cmd;
     1507        cmd.sid              = pCmd->sid;
     1508        cmd.surfaceFlags     = pCmd->surfaceFlags;
     1509        cmd.format           = pCmd->format;
     1510        memcpy(cmd.face, pCmd->face, sizeof(cmd.face));
     1511        cmd.multisampleCount = 0;
     1512        cmd.autogenFilter    = SVGA3D_TEX_FILTER_NONE;
     1513
     1514        uint32_t const cMipLevelSizes = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize);
     1515        vmsvga3dCmdDefineSurface(pThisCC, &cmd, cMipLevelSizes, (SVGA3dSize *)(pCmd + 1));
    4781516# ifdef DEBUG_GMR_ACCESS
    4791517        VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3ResetGmrHandlers, 1, pThis);
     
    4881526        STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDefineV2);
    4891527
    490         uint32_t const cMipLevels = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize);
    491         vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format, pCmd->face,
    492                               pCmd->multisampleCount, pCmd->autogenFilter,
    493                               cMipLevels, (SVGA3dSize *)(pCmd + 1));
     1528        uint32_t const cMipLevelSizes = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize);
     1529        vmsvga3dCmdDefineSurface(pThisCC, pCmd, cMipLevelSizes, (SVGA3dSize *)(pCmd + 1));
     1530# ifdef DEBUG_GMR_ACCESS
     1531        VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3ResetGmrHandlers, 1, pThis);
     1532# endif
    4941533        break;
    4951534    }
     
    9712010        SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pvCmd;
    9722011        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    973         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2012        vmsvga3dCmdDestroyGBMob(pThisCC, pCmd);
    9742013        break;
    9752014    }
     
    9932032        SVGA3dCmdDefineGBSurface *pCmd = (SVGA3dCmdDefineGBSurface *)pvCmd;
    9942033        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    995         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2034        vmsvga3dCmdDefineGBSurface(pThisCC, pCmd);
    9962035        break;
    9972036    }
     
    10012040        SVGA3dCmdDestroyGBSurface *pCmd = (SVGA3dCmdDestroyGBSurface *)pvCmd;
    10022041        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    1003         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2042        vmsvga3dCmdDestroyGBSurface(pThisCC, pCmd);
    10042043        break;
    10052044    }
     
    10092048        SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pvCmd;
    10102049        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    1011         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2050        vmsvga3dCmdBindGBSurface(pThisCC, pCmd);
    10122051        break;
    10132052    }
     
    10252064        SVGA3dCmdUpdateGBImage *pCmd = (SVGA3dCmdUpdateGBImage *)pvCmd;
    10262065        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    1027         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2066        vmsvga3dCmdUpdateGBImage(pThisCC, pCmd);
    10282067        break;
    10292068    }
     
    10652104        SVGA3dCmdInvalidateGBSurface *pCmd = (SVGA3dCmdInvalidateGBSurface *)pvCmd;
    10662105        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    1067         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2106        vmsvga3dCmdInvalidateGBSurface(pThisCC, pCmd);
    10682107        break;
    10692108    }
     
    11372176        SVGA3dCmdSetOTableBase64 *pCmd = (SVGA3dCmdSetOTableBase64 *)pvCmd;
    11382177        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    1139         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2178        vmsvga3dCmdSetOTableBase64(pThisCC, pCmd);
    11402179        break;
    11412180    }
     
    12062245        SVGA3dCmdDefineGBScreenTarget *pCmd = (SVGA3dCmdDefineGBScreenTarget *)pvCmd;
    12072246        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    1208         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2247        vmsvga3dCmdDefineGBScreenTarget(pThis, pThisCC, pCmd);
    12092248        break;
    12102249    }
     
    12142253        SVGA3dCmdDestroyGBScreenTarget *pCmd = (SVGA3dCmdDestroyGBScreenTarget *)pvCmd;
    12152254        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    1216         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2255        vmsvga3dCmdDestroyGBScreenTarget(pThis, pThisCC, pCmd);
    12172256        break;
    12182257    }
     
    12222261        SVGA3dCmdBindGBScreenTarget *pCmd = (SVGA3dCmdBindGBScreenTarget *)pvCmd;
    12232262        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    1224         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2263        vmsvga3dCmdBindGBScreenTarget(pThisCC, pCmd);
    12252264        break;
    12262265    }
     
    12302269        SVGA3dCmdUpdateGBScreenTarget *pCmd = (SVGA3dCmdUpdateGBScreenTarget *)pvCmd;
    12312270        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    1232         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2271        vmsvga3dCmdUpdateGBScreenTarget(pThisCC, pCmd);
    12332272        break;
    12342273    }
     
    12952334        SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pvCmd;
    12962335        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    1297         VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
     2336        vmsvga3dCmdDefineGBMob64(pThisCC, pCmd);
    12982337        break;
    12992338    }
     
    27133752}
    27143753
     3754
     3755/**
     3756 * Clip.
     3757 *
     3758 * @param   pBound  Bounding rectangle.
     3759 * @param   pRect   Rectangle to be clipped.
     3760 */
     3761void vmsvgaR3Clip3dRect(SVGA3dRect const *pBound, SVGA3dRect RT_UNTRUSTED_GUEST *pRect)
     3762{
     3763    uint32_t const leftBound   = pBound->x;
     3764    uint32_t const rightBound  = pBound->x + pBound->w;
     3765    uint32_t const topBound    = pBound->y;
     3766    uint32_t const bottomBound = pBound->y + pBound->h;
     3767
     3768    uint32_t x = pRect->x;
     3769    uint32_t y = pRect->y;
     3770    uint32_t w = pRect->w;
     3771    uint32_t h = pRect->h;
     3772
     3773    /* Make sure that right and bottom coordinates can be safely computed. */
     3774    if (x > rightBound)
     3775        x = rightBound;
     3776    if (w > rightBound - x)
     3777        w = rightBound - x;
     3778    if (y > bottomBound)
     3779        y = bottomBound;
     3780    if (h > bottomBound - y)
     3781        h = bottomBound - y;
     3782
     3783    /* Switch from x, y, w, h to left, top, right, bottom. */
     3784    uint32_t left   = x;
     3785    uint32_t right  = x + w;
     3786    uint32_t top    = y;
     3787    uint32_t bottom = y + h;
     3788
     3789    /* A standard left, right, bottom, top clipping. */
     3790    if (left < leftBound)
     3791        left = leftBound;
     3792    if (right < leftBound)
     3793        right = leftBound;
     3794
     3795    if (left > rightBound)
     3796        left = rightBound;
     3797    if (right > rightBound)
     3798        right = rightBound;
     3799
     3800    if (top < topBound)
     3801        top = topBound;
     3802    if (bottom < topBound)
     3803        bottom = topBound;
     3804
     3805    if (top > bottomBound)
     3806        top = bottomBound;
     3807    if (bottom > bottomBound)
     3808        bottom = bottomBound;
     3809
     3810    /* Back to x, y, w, h representation. */
     3811    pRect->x = left;
     3812    pRect->y = top;
     3813    pRect->w = right - left;
     3814    pRect->h = bottom - top;
     3815}
     3816
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-internal.h

    r86265 r86838  
    2929#endif
    3030
     31#include <iprt/avl.h>
     32#include <iprt/list.h>
     33
    3134
    3235/*********************************************************************************************************************************
     
    4750typedef struct
    4851{
    49     uint32_t                    cMaxPages;
    50     uint32_t                    cbTotal;
    51     uint32_t                    numDescriptors;
    52     PVMSVGAGMRDESCRIPTOR        paDesc;
     52    uint32_t                cMaxPages;
     53    uint32_t                cbTotal;
     54    uint32_t                numDescriptors;
     55    PVMSVGAGMRDESCRIPTOR    paDesc;
    5356} GMR, *PGMR;
     57
     58/*
     59 * GBO (Guest Backed Object).
     60 * A GBO is a list of the guest pages. GBOs are used for VMSVGA MOBs (Memory OBjects)
     61 * and Object Tables which the guest shares with the host.
     62 *
     63 * A GBO is similar to a GMR. Nevertheless I'll create a new code for GBOs in order
     64 * to avoid tweaking and possibly breaking existing code. Moreover it will be probably possible to
     65 * map the guest pages into the host R3 memory and access them directly.
     66 */
     67
     68/* GBO descriptor. */
     69typedef struct VMSVGAGBODESCRIPTOR
     70{
     71   RTGCPHYS                 GCPhys;
     72   uint64_t                 cPages;
     73} VMSVGAGBODESCRIPTOR, *PVMSVGAGBODESCRIPTOR;
     74typedef VMSVGAGBODESCRIPTOR const *PCVMSVGAGBODESCRIPTOR;
     75
     76/* GBO.
     77 */
     78typedef struct VMSVGAGBO
     79{
     80    uint32_t                u32Reserved;
     81    uint32_t                cTotalPages;
     82    uint32_t                cbTotal;
     83    uint32_t                cDescriptors;
     84    PVMSVGAGBODESCRIPTOR    paDescriptors;
     85} VMSVGAGBO, *PVMSVGAGBO;
     86typedef VMSVGAGBO const *PCVMSVGAGBO;
     87
     88#define VMSVGA_IS_GBO_CREATED(a_Gbo) ((a_Gbo)->paDescriptors != NULL)
     89
     90/* MOB is also a GBO.
     91 */
     92typedef struct VMSVGAMOB
     93{
     94    AVLU32NODECORE          Core; /* Key is the mobid. */
     95    RTLISTNODE              nodeLRU;
     96    VMSVGAGBO               Gbo;
     97} VMSVGAMOB, *PVMSVGAMOB;
     98typedef VMSVGAMOB const *PCVMSVGAMOB;
     99
    54100
    55101typedef struct VMSVGACMDBUF *PVMSVGACMDBUF;
     
    84130typedef struct VMSVGAR3STATE
    85131{
     132    PPDMDEVINS              pDevIns; /* Stored here to use with PDMDevHlp* */
    86133    GMR                    *paGMR; // [VMSVGAState::cGMR]
    87134    struct
     
    127174    /** Critical section for accessing the command buffer data. */
    128175    RTCRITSECT              CritSectCmdBuf;
     176
     177    /**  */
     178    VMSVGAGBO               GboOTableMob;
     179    VMSVGAGBO               GboOTableSurface;
     180    VMSVGAGBO               GboOTableContext;
     181    VMSVGAGBO               GboOTableShader;
     182    VMSVGAGBO               GboOTableScreenTarget;
     183
     184    /** Tree of guest's Memory OBjects. Key is mobid. */
     185    AVLU32TREE              MOBTree;
     186    /** Least Recently Used list of MOBs.
     187     * To unmap older MOBs when the guest exceeds SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB (SVGA_REG_GBOBJECT_MEM_SIZE_KB) value. */
     188    RTLISTANCHOR            MOBLRUList;
    129189
    130190    /** Tracks how much time we waste reading SVGA_REG_BUSY with a busy FIFO. */
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp

    r86479 r86838  
    248248    SSMFIELD_ENTRY(             VMSVGASCREENOBJECT, fDefined),
    249249    SSMFIELD_ENTRY(             VMSVGASCREENOBJECT, fModified),
     250    SSMFIELD_ENTRY_VER(         VMSVGASCREENOBJECT, cDpi, VGA_SAVEDSTATE_VERSION_VMSVGA_MIPLEVELS),
    250251    SSMFIELD_ENTRY_TERM()
    251252};
     
    626627        }
    627628
    628         rc = pThisCC->pDrv->pfnVBVAResize(pThisCC->pDrv, &view, &screen, pThisCC->pbVRam, /*fResetInputMapping=*/ true);
     629        void *pvVRAM = pScreen->pvScreenBitmap ? pScreen->pvScreenBitmap : pThisCC->pbVRam;
     630        rc = pThisCC->pDrv->pfnVBVAResize(pThisCC->pDrv, &view, &screen, pvVRAM, /*fResetInputMapping=*/ true);
    629631        AssertRC(rc);
    630632    }
     
    24732475
    24742476/**
    2475  * HC access handler for the FIFO.
     2477 * HC access handler for GMRs.
    24762478 *
    24772479 * @returns VINF_SUCCESS if the handler have carried out the operation.
     
    26312633 * @param pDevIns     The device instance.
    26322634 * @param pThis       The shared VGA/VMSVGA state.
    2633  * @param fIRQ        SVGA_IRQFLAG_* bits.
     2635 * @param u32IrqStatus SVGA_IRQFLAG_* bits.
    26342636 * @thread FIFO or EMT.
    26352637 */
    2636 static void vmsvgaR3CmdBufRaiseIRQ(PPDMDEVINS pDevIns, PVGASTATE pThis, uint32_t fIRQ)
     2638static void vmsvgaR3CmdBufRaiseIRQ(PPDMDEVINS pDevIns, PVGASTATE pThis, uint32_t u32IrqStatus)
    26372639{
    26382640    int rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->CritSect, VERR_IGNORED);
    26392641    AssertRC(rc);
    26402642
    2641     if (pThis->svga.u32IrqMask & fIRQ)
    2642     {
    2643         LogFunc(("Trigger interrupt with status %#x\n", fIRQ));
    2644         ASMAtomicOrU32(&pThis->svga.u32IrqStatus, fIRQ);
     2643    if (pThis->svga.u32IrqMask & u32IrqStatus)
     2644    {
     2645        LogFunc(("Trigger interrupt with status %#x\n", u32IrqStatus));
     2646        ASMAtomicOrU32(&pThis->svga.u32IrqStatus, u32IrqStatus);
    26452647        PDMDevHlpPCISetIrq(pDevIns, 0, 1);
    26462648    }
     
    30863088 * @param cbCommands   Size of the command buffer.
    30873089 * @param poffNextCmd  Where to store the offset of the first unprocessed command.
     3090 * @param pu32IrqStatus Where to store SVGA_IRQFLAG_ if the IRQ is generated by the last command in the buffer.
    30883091 * @return SVGACBStatus code.
    30893092 * @thread FIFO
    30903093 */
    3091 static SVGACBStatus vmsvgaR3CmdBufProcessCommands(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, void const *pvCommands, uint32_t cbCommands, uint32_t *poffNextCmd)
     3094static SVGACBStatus vmsvgaR3CmdBufProcessCommands(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, void const *pvCommands, uint32_t cbCommands, uint32_t *poffNextCmd, uint32_t *pu32IrqStatus)
    30923095{
    30933096    SVGACBStatus CBstatus = SVGA_CB_STATUS_COMPLETED;
     
    31443147                    pFIFO[SVGA_FIFO_FENCE] = pCmd->fence;
    31453148
    3146                     uint32_t u32IrqStatus = 0;
    31473149                    if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE)
    31483150                    {
    31493151                        Log(("any fence irq\n"));
    3150                         u32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE;
     3152                        *pu32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE;
    31513153                    }
    31523154                    else if (    VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE_GOAL, offFifoMin)
     
    31553157                    {
    31563158                        Log(("fence goal reached irq (fence=%#x)\n", pCmd->fence));
    3157                         u32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL;
     3159                        *pu32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL;
    31583160                    }
    3159 
    3160                     if (u32IrqStatus)
    3161                         vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, u32IrqStatus);
    31623161                }
    31633162                else
     
    33213320                break;
    33223321            }
    3323 # endif // VBOX_WITH_VMSVGA3D
     3322# endif /* VBOX_WITH_VMSVGA3D */
    33243323            case SVGA_CMD_DEFINE_SCREEN:
    33253324            {
     
    34323431        pu8Cmd += cbCmd;
    34333432        cbRemain -= cbCmd;
     3433
     3434        /* If this is not the last command in the buffer, then generate IRQ, if required.
     3435         * This avoids a double call to vmsvgaR3CmdBufRaiseIRQ if FENCE is the last command
     3436         * in the buffer (usually the case).
     3437         */
     3438        if (RT_LIKELY(!(cbRemain && *pu32IrqStatus)))
     3439        { /* likely */ }
     3440        else
     3441        {
     3442            vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, *pu32IrqStatus);
     3443            *pu32IrqStatus = 0;
     3444        }
    34343445    }
    34353446
     
    34923503        SVGACBStatus CBstatus = SVGA_CB_STATUS_NONE;
    34933504        uint32_t offNextCmd = 0;
     3505        uint32_t u32IrqStatus = 0;
    34943506
    34953507        /* Process one buffer. */
    3496         CBstatus = vmsvgaR3CmdBufProcessCommands(pDevIns, pThis, pThisCC, pCmdBuf->pvCommands, pCmdBuf->hdr.length, &offNextCmd);
    3497 
    3498         uint32_t fIRQ = 0;
     3508        CBstatus = vmsvgaR3CmdBufProcessCommands(pDevIns, pThis, pThisCC, pCmdBuf->pvCommands, pCmdBuf->hdr.length, &offNextCmd, &u32IrqStatus);
     3509
    34993510        if (!RT_BOOL(pCmdBuf->hdr.flags & SVGA_CB_FLAG_NO_IRQ))
    3500             fIRQ |= SVGA_IRQFLAG_COMMAND_BUFFER;
     3511            u32IrqStatus |= SVGA_IRQFLAG_COMMAND_BUFFER;
    35013512        if (CBstatus == SVGA_CB_STATUS_COMMAND_ERROR)
    3502             fIRQ |= SVGA_IRQFLAG_ERROR;
     3513            u32IrqStatus |= SVGA_IRQFLAG_ERROR;
    35033514
    35043515        vmsvgaR3CmdBufWriteStatus(pDevIns, pCmdBuf->GCPhysCB, CBstatus, offNextCmd);
    3505         if (fIRQ)
    3506             vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, fIRQ);
     3516        if (u32IrqStatus)
     3517            vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, u32IrqStatus);
    35073518
    35083519        vmsvgaR3CmdBufFree(pCmdBuf);
     
    53805391 *
    53815392 * @returns VBox status code.
     5393 * @param   pDevIns        The PDM device instance.
    53825394 * @param   pThis          The shared VGA/VMSVGA instance data.
    53835395 * @param   pSVGAState     Pointer to the structure. It is already allocated.
    53845396 */
    5385 static int vmsvgaR3StateInit(PVGASTATE pThis, PVMSVGAR3STATE pSVGAState)
     5397static int vmsvgaR3StateInit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVMSVGAR3STATE pSVGAState)
    53865398{
    53875399    int rc = VINF_SUCCESS;
    53885400    RT_ZERO(*pSVGAState);
     5401    pSVGAState->pDevIns = pDevIns;
    53895402
    53905403    pSVGAState->paGMR = (PGMR)RTMemAllocZ(pThis->svga.cGMR * sizeof(GMR));
     
    54015414
    54025415    vmsvgaR3CmdBufCtxInit(&pSVGAState->CmdBufCtxDC);
     5416
     5417    RTListInit(&pSVGAState->MOBLRUList);
    54035418    return rc;
    54045419}
     
    58085823
    58095824    vmsvgaR3StateTerm(pThis, pThisCC->svga.pSvgaR3State);
    5810     vmsvgaR3StateInit(pThis, pThisCC->svga.pSvgaR3State);
     5825    vmsvgaR3StateInit(pDevIns, pThis, pThisCC->svga.pSvgaR3State);
    58115826
    58125827    RT_BZERO(pThisCC->svga.pbVgaFrameBufferR3, VMSVGA_VGA_FB_BACKUP_SIZE);
     
    59255940    AssertReturn(pThisCC->svga.pSvgaR3State, VERR_NO_MEMORY);
    59265941
    5927     rc = vmsvgaR3StateInit(pThis, pThisCC->svga.pSvgaR3State);
     5942    rc = vmsvgaR3StateInit(pDevIns, pThis, pThisCC->svga.pSvgaR3State);
    59285943    AssertMsgRCReturn(rc, ("Failed to create pSvgaR3State.\n"), rc);
    59295944
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h

    r86266 r86838  
    254254    /** Bits per pixel. */
    255255    uint32_t    cBpp;
     256    /** The physical DPI that the guest expects for this screen. Zero, if the guest is not DPI aware. */
     257    uint32_t    cDpi;
    256258    bool        fDefined;
    257259    bool        fModified;
     260    void       *pvScreenBitmap;
    258261#ifdef VBOX_WITH_VMSVGA3D
    259262    /** Pointer to the HW accelerated (3D) screen data. */
     
    361364    uint32_t                    uPadding1;
    362365#endif
    363     /** Number of GMRs. */
     366    /** Number of GMRs (VMSVGA_MAX_GMR_IDS, count of elements in VMSVGAR3STATE::paGMR array). */
    364367    uint32_t                    cGMR;
    365368    uint32_t                    uScreenOffset; /* Used only for loading older saved states. */
     
    566569void vmsvgaR3ClipBox(const SVGA3dSize *pSize, SVGA3dBox *pBox);
    567570void vmsvgaR3ClipRect(SVGASignedRect const *pBound, SVGASignedRect *pRect);
     571void vmsvgaR3Clip3dRect(SVGA3dRect const *pBound, SVGA3dRect RT_UNTRUSTED_GUEST *pRect);
    568572
    569573#endif /* !VBOX_INCLUDED_SRC_Graphics_DevVGA_SVGA_h */
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-info.cpp

    r86024 r86838  
    291291        for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
    292292        {
    293             Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
    294             PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[iFace * pSurface->faces[0].numMipLevels];
    295             for (uint32_t i = 0; i < pSurface->faces[iFace].numMipLevels; i++, pMipmapLevel++)
     293            PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[iFace * pSurface->cLevels];
     294            for (uint32_t i = 0; i < pSurface->cLevels; i++, pMipmapLevel++)
    296295            {
    297296                if (VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
     
    498497                            AssertMsgFailed(("%#x\n", fSwitchFlags));
    499498                    }
     499#elif defined(VMSVGA3D_DX)
     500                    /** @todo */
     501                    RT_NOREF(pState);
    500502#else
    501503# error "misconfigured"
     
    15221524# ifdef VMSVGA3D_DIRECT3D
    15231525    pHlp->pfnPrintf(pHlp, "pDevice:                 %p\n", pContext->pDevice);
     1526# elif defined(VMSVGA3D_DX)
     1527    /** @todo */
    15241528# else
    15251529    pHlp->pfnPrintf(pHlp, "hdc:                     %p\n", pContext->hdc);
     
    19191923    const uint32_t u32Seq = ASMAtomicIncU32(&sSeq);
    19201924
    1921     for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; ++i)
     1925    for (uint32_t i = 0; i < pSurface->cLevels; ++i)
    19221926    {
    19231927        if (!pSurface->paMipmapLevels[i].pSurfaceData)
     
    19781982    vmsvga3dInfoU32Flags(pHlp, pSurface->surfaceFlags, "SVGA3D_SURFACE_", g_aSvga3DSurfaceFlags, RT_ELEMENTS(g_aSvga3DSurfaceFlags));
    19791983    pHlp->pfnPrintf(pHlp, "\n");
    1980     if (pSurface->cFaces == 0)
     1984    if (pSurface->cFaces != 0)
    19811985        pHlp->pfnPrintf(pHlp, "Faces:                   %u\n", pSurface->cFaces);
     1986    if (pSurface->cLevels != 0)
     1987        pHlp->pfnPrintf(pHlp, "Mipmap levels:  %u\n", pSurface->cLevels);
    19821988    for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
    19831989    {
    1984         Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
    1985         if (pSurface->faces[iFace].numMipLevels == 0)
    1986             pHlp->pfnPrintf(pHlp, "Faces[%u] Mipmap levels:  %u\n", iFace, pSurface->faces[iFace].numMipLevels);
    1987 
    1988         uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
    1989         for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
     1990        uint32_t iMipmap = iFace * pSurface->cLevels;
     1991        for (uint32_t iLevel = 0; iLevel < pSurface->cLevels; iLevel++, iMipmap++)
    19901992        {
    19911993            pHlp->pfnPrintf(pHlp, "Face #%u, mipmap #%u[%u]:%s  cx=%u, cy=%u, cz=%u, cbSurface=%#x, cbPitch=%#x",
     
    20302032    pHlp->pfnPrintf(pHlp, "fStencilAsTexture:       %RTbool\n", pSurface->fStencilAsTexture);
    20312033
     2034#elif defined(VMSVGA3D_DX)
     2035    /** @todo */
    20322036#elif defined(VMSVGA3D_OPENGL)
    20332037    /** @todo   */
     
    20392043        for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
    20402044        {
    2041             uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
    2042             for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
     2045            uint32_t iMipmap = iFace * pSurface->cLevels;
     2046            for (uint32_t iLevel = 0; iLevel < pSurface->cLevels; iLevel++, iMipmap++)
    20432047                if (pSurface->paMipmapLevels[iMipmap].pSurfaceData)
    20442048                {
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h

    r86809 r86838  
    2929#endif
    3030#ifdef VMSVGA3D_OPENGL
    31 # ifdef VMSVGA3D_DIRECT3D
     31# if defined(VMSVGA3D_DIRECT3D) || defined(VMSVGA3D_DX)
    3232#  error "Both VMSVGA3D_DIRECT3D and VMSVGA3D_OPENGL cannot be defined at the same time."
    3333# endif
    34 #elif !defined(VMSVGA3D_DIRECT3D)
     34#elif !defined(VMSVGA3D_DIRECT3D) && !defined(VMSVGA3D_DX)
    3535# error "Either VMSVGA3D_OPENGL or VMSVGA3D_DIRECT3D must be defined."
    3636#endif
     
    5151#  include <d3d9.h>
    5252#  include <iprt/avl.h>
     53# elif defined(VMSVGA3D_DX)
     54#  include <d3d11.h>
    5355# else
    5456#  include <GL/gl.h>
     
    536538#endif
    537539
     540/* The 3D backend surface. The actual structure is 3D API specific. */
     541typedef struct VMSVGA3DBACKENDSURFACE *PVMSVGA3DBACKENDSURFACE;
     542
    538543/**
    539544 * VMSVGA3d surface.
     
    541546typedef struct VMSVGA3DSURFACE
    542547{
     548    PVMSVGA3DBACKENDSURFACE pBackendSurface;
     549
    543550    uint32_t                id;
    544551#ifdef VMSVGA3D_OPENGL
     
    566573    GLuint                  idEmulated; /* GL name of the intermediate texture. */
    567574#endif
    568     SVGA3dSurfaceFace       faces[SVGA3D_MAX_SURFACE_FACES];
    569     uint32_t                cFaces;
    570     uint32_t                cMipmapLevels;
    571     PVMSVGA3DMIPMAPLEVEL    paMipmapLevels;
     575    uint32_t                cFaces; /* Number of faces: 6 for cubemaps, 1 for everything else. */
     576    uint32_t                cLevels; /* Number of mipmap levels per face. */
     577    PVMSVGA3DMIPMAPLEVEL    paMipmapLevels; /* cFaces * cLevels elements. */
    572578    uint32_t                multiSampleCount;
    573579    SVGA3dTextureFilter     autogenFilter;
     
    646652    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, formatGL),
    647653    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, typeGL),
    648     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, id),
    649654# endif
    650     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, faces),
    651655    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, cFaces),
    652     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, paMipmapLevels),
     656    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, cLevels),
    653657    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, multiSampleCount),
    654658    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, autogenFilter),
    655 # ifdef VMSVGA3D_DIRECT3D
    656     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, format), /** @todo format duplicated. */
    657     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, formatD3D),
    658     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, fUsageD3D),
    659     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, multiSampleTypeD3D),
    660 # endif
    661659    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, cbBlock),
    662     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, fDirty),
    663 # ifdef VMSVGA3D_DIRECT3D
    664     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, hSharedObject),
    665     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, pQuery),
    666     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, u.pSurface),
    667     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, bounce.pTexture),
    668     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, pSharedObjectTree),
    669     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, fStencilAsTexture),
    670 # endif
    671660    SSMFIELD_ENTRY_TERM()
    672661};
     
    687676#ifdef VMSVGA3D_DIRECT3D
    688677# define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->u.pSurface != NULL)
     678#elif defined(VMSVGA3D_DX)
     679# define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->pBackendSurface != NULL)
    689680#else
    690681# define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->oglId.texture != OPENGL_INVALID_ID)
     
    701692   (   (a_pSurface)->enmD3DResType == VMSVGA3D_D3DRESTYPE_VERTEX_BUFFER \
    702693    || (a_pSurface)->enmD3DResType == VMSVGA3D_D3DRESTYPE_INDEX_BUFFER)
     694#elif defined(VMSVGA3D_DX)
     695  /** @todo */
     696# define VMSVGA3DSURFACE_NEEDS_DATA(a_pSurface) (false)
    703697#else
    704698# define VMSVGA3DSURFACE_NEEDS_DATA(a_pSurface) \
     
    719713        IDirect3DVertexShader9     *pVertexShader;
    720714        IDirect3DPixelShader9      *pPixelShader;
     715#elif defined(VMSVGA3D_DX)
     716        /** todo */
    721717#else
    722718        void                       *pVertexShader;
     
    770766#ifdef VMSVGA3D_DIRECT3D
    771767    IDirect3DQuery9    *pQuery;
     768#elif defined(VMSVGA3D_DX)
     769    /** @todo */
    772770#else /* VMSVGA3D_OPENGL */
    773771    GLuint              idQuery;
     
    785783#ifdef VMSVGA3D_DIRECT3D
    786784    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DQUERY, pQuery),
     785#elif defined(VMSVGA3D_DX)
     786    /** @todo */
    787787#else /* VMSVGA3D_OPENGL */
    788788    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DQUERY, idQuery),
     
    796796#ifdef VMSVGA3D_DIRECT3D
    797797#define VMSVGA3DQUERY_EXISTS(p) ((p)->pQuery && (p)->enmQueryState != VMSVGA3DQUERYSTATE_NULL)
     798#elif defined(VMSVGA3D_DX)
     799    /** @todo */
     800#define VMSVGA3DQUERY_EXISTS(p) (false)
    798801#else
    799802#define VMSVGA3DQUERY_EXISTS(p) ((p)->idQuery && (p)->enmQueryState != VMSVGA3DQUERYSTATE_NULL)
     
    813816    IDirect3DDevice9Ex     *pDevice;
    814817#  endif
     818# elif defined(VMSVGA3D_DX)
     819    /** @todo */
    815820# else
    816821    /* Device context of the context window. */
     
    911916#  ifdef VMSVGA3D_DIRECT3D
    912917    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, pDevice),
     918#  elif defined(VMSVGA3D_DX)
     919    /** @todo */
    913920#  else
    914921    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, hdc),
     
    967974#endif
    968975
     976/* The 3D backend. The actual structure is 3D API specific. */
     977typedef struct VMSVGA3DBACKEND *PVMSVGA3DBACKEND;
     978
    969979/**
    970980 * VMSVGA3d state data.
     
    9961006    bool                    fSupportedFormatYUY2 : 1;
    9971007    bool                    fSupportedFormatA8B8G8R8 : 1;
     1008# elif defined(VMSVGA3D_DX)
     1009    PVMSVGA3DBACKEND        pBackend;
    9981010# endif
    9991011    /** Window Thread. */
     
    12971309                                    PVMSVGA3DMIPMAPLEVEL *ppMipmapLevel)
    12981310{
    1299     /* Can use faces[0].numMipLevels, because numMipLevels is the same for all faces. */
    1300     const uint32_t numMipLevels = pSurface->faces[0].numMipLevels;
    1301 
    13021311    AssertMsgReturn(face < pSurface->cFaces,
    13031312                    ("cFaces %d, face %d\n", pSurface->cFaces, face),
    13041313                    VERR_INVALID_PARAMETER);
    1305     AssertMsgReturn(mipmap < numMipLevels,
    1306                     ("numMipLevels %d, mipmap %d", numMipLevels, mipmap),
     1314    AssertMsgReturn(mipmap < pSurface->cLevels,
     1315                    ("numMipLevels %d, mipmap %d", pSurface->cLevels, mipmap),
    13071316                    VERR_INVALID_PARAMETER);
    13081317
    1309     *ppMipmapLevel = &pSurface->paMipmapLevels[face * numMipLevels + mipmap];
     1318    *ppMipmapLevel = &pSurface->paMipmapLevels[face * pSurface->cLevels + mipmap];
    13101319    return VINF_SUCCESS;
    13111320}
     
    13271336    return Face;
    13281337}
     1338#elif defined(VMSVGA3D_DX)
     1339DECLINLINE(D3D11_TEXTURECUBE_FACE) vmsvga3dCubemapFaceFromIndex(uint32_t iFace)
     1340{
     1341    D3D11_TEXTURECUBE_FACE Face;
     1342    switch (iFace)
     1343    {
     1344        case 0: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_X; break;
     1345        case 1: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_X; break;
     1346        case 2: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_Y; break;
     1347        case 3: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_Y; break;
     1348        case 4: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_Z; break;
     1349        default:
     1350        case 5: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_Z; break;
     1351    }
     1352    return Face;
     1353}
    13291354#else /* VMSVGA3D_OPENGL */
    13301355DECLINLINE(GLenum) vmsvga3dCubemapFaceFromIndex(uint32_t iFace)
     
    13541379                                 const char *pszPath, const char *pszNamePrefix, const char *pszNameSuffix);
    13551380
    1356 #ifdef VMSVGA3D_DIRECT3D
     1381#if defined(VMSVGA3D_DIRECT3D) || defined(VMSVGA3D_DX)
    13571382#define D3D_RELEASE(ptr) do { \
    13581383    if (ptr)                  \
     
    13621387    }                         \
    13631388} while (0)
    1364 
     1389#endif
     1390
     1391#if defined(VMSVGA3D_DIRECT3D)
    13651392HRESULT D3D9UpdateTexture(PVMSVGA3DCONTEXT pContext,
    13661393                          PVMSVGA3DSURFACE pSurface);
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp

    r86809 r86838  
    23662366    LogFunc(("sid=%u\n", pSurface->id));
    23672367
    2368     uint32_t const numMipLevels = pSurface->faces[0].numMipLevels;
     2368    uint32_t const numMipLevels = pSurface->cLevels;
    23692369
    23702370    /* Fugure out what kind of texture we are creating. */
     
    24252425    glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
    24262426    VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    2427     glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, pSurface->faces[0].numMipLevels - 1);
     2427    glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, pSurface->cLevels - 1);
    24282428    VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    24292429
     
    57225722                    {
    57235723                        Log(("CreateTexture (%d,%d) levels=%d\n",
    5724                               pSurface->paMipmapLevels[0].mipmapSize.width, pSurface->paMipmapLevels[0].mipmapSize.height, pSurface->faces[0].numMipLevels));
     5724                              pSurface->paMipmapLevels[0].mipmapSize.width, pSurface->paMipmapLevels[0].mipmapSize.height, pSurface->cLevels));
    57255725                        rc = vmsvga3dBackCreateTexture(pState, pContext, cid, pSurface);
    57265726                        AssertRCReturn(rc, rc);
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-savedstate.cpp

    r82968 r86838  
    147147}
    148148
     149static int vmsvga3dLoadVMSVGA3DSURFACEPreMipLevels(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, VMSVGA3DSURFACE *pSurface)
     150{
     151    typedef struct VMSVGA3DSURFACEPreMipLevels
     152    {
     153        uint32_t            id;
     154#ifdef VMSVGA3D_OPENGL
     155        uint32_t            idWeakContextAssociation;
     156#else
     157        uint32_t            idAssociatedContext;
     158#endif
     159        uint32_t            surfaceFlags;
     160        SVGA3dSurfaceFormat format;
     161#ifdef VMSVGA3D_OPENGL
     162        GLint               internalFormatGL;
     163        GLint               formatGL;
     164        GLint               typeGL;
     165#endif
     166        SVGA3dSurfaceFace   faces[SVGA3D_MAX_SURFACE_FACES];
     167        uint32_t            cFaces;
     168        uint32_t            multiSampleCount;
     169        SVGA3dTextureFilter autogenFilter;
     170        uint32_t            cbBlock;
     171    } VMSVGA3DSURFACEPreMipLevels;
     172
     173    static SSMFIELD const s_aVMSVGA3DSURFACEFieldsPreMipLevels[] =
     174    {
     175        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, id),
     176#ifdef VMSVGA3D_OPENGL
     177        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, idWeakContextAssociation),
     178#else
     179        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, idAssociatedContext),
     180#endif
     181        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, surfaceFlags),
     182        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, format),
     183#ifdef VMSVGA3D_OPENGL
     184        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, internalFormatGL),
     185        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, formatGL),
     186        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, typeGL),
     187#endif
     188        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, faces),
     189        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, cFaces),
     190        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, multiSampleCount),
     191        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, autogenFilter),
     192#ifdef VMSVGA3D_DIRECT3D
     193        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, format), /* Yes, the 'format' field is duplicated. */
     194#endif
     195        SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, cbBlock),
     196        SSMFIELD_ENTRY_TERM()
     197    };
     198
     199    VMSVGA3DSURFACEPreMipLevels surfacePreMipLevels;
     200    int rc = pDevIns->pHlpR3->pfnSSMGetStructEx(pSSM, &surfacePreMipLevels, sizeof(surfacePreMipLevels), 0, s_aVMSVGA3DSURFACEFieldsPreMipLevels, NULL);
     201    if (RT_SUCCESS(rc))
     202    {
     203        pSurface->id                       = surfacePreMipLevels.id;
     204#ifdef VMSVGA3D_OPENGL
     205        pSurface->idWeakContextAssociation = surfacePreMipLevels.idWeakContextAssociation;
     206#else
     207        pSurface->idAssociatedContext      = surfacePreMipLevels.idAssociatedContext;
     208#endif
     209        pSurface->surfaceFlags             = surfacePreMipLevels.surfaceFlags;
     210        pSurface->format                   = surfacePreMipLevels.format;
     211#ifdef VMSVGA3D_OPENGL
     212        pSurface->internalFormatGL         = surfacePreMipLevels.internalFormatGL;
     213        pSurface->formatGL                 = surfacePreMipLevels.formatGL;
     214        pSurface->typeGL                   = surfacePreMipLevels.typeGL;
     215#endif
     216        pSurface->cLevels                  = surfacePreMipLevels.faces[0].numMipLevels;
     217        pSurface->cFaces                   = surfacePreMipLevels.cFaces;
     218        pSurface->multiSampleCount         = surfacePreMipLevels.multiSampleCount;
     219        pSurface->autogenFilter            = surfacePreMipLevels.autogenFilter;
     220        pSurface->cbBlock                  = surfacePreMipLevels.cbBlock;
     221    }
     222    return rc;
     223}
     224
    149225int vmsvga3dLoadExec(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    150226{
     
    408484
    409485            /* Fetch the surface structure first. */
    410             rc = pHlp->pfnSSMGetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL);
     486            if (RT_LIKELY(uVersion >= VGA_SAVEDSTATE_VERSION_VMSVGA_MIPLEVELS))
     487                rc = pHlp->pfnSSMGetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL);
     488            else
     489                rc = vmsvga3dLoadVMSVGA3DSURFACEPreMipLevels(pDevIns, pSSM, &surface);
    411490            AssertRCReturn(rc, rc);
    412491
    413492            {
    414                 uint32_t             cMipLevels = surface.faces[0].numMipLevels * surface.cFaces;
     493                uint32_t             cMipLevels = surface.cLevels * surface.cFaces;
    415494                PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
    416495                AssertReturn(pMipmapLevel, VERR_NO_MEMORY);
     
    421500                for (uint32_t face=0; face < surface.cFaces; face++)
    422501                {
    423                     for (uint32_t j = 0; j < surface.faces[0].numMipLevels; j++)
     502                    for (uint32_t j = 0; j < surface.cLevels; j++)
    424503                    {
    425                         uint32_t idx = j + face * surface.faces[0].numMipLevels;
     504                        uint32_t idx = j + face * surface.cLevels;
    426505                        /* Load the mip map level struct. */
    427506                        rc = pHlp->pfnSSMGetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0,
     
    433512                }
    434513
    435                 rc = vmsvga3dSurfaceDefine(pThisCC, sid, surface.surfaceFlags, surface.format, surface.faces,
    436                                            surface.multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);
     514                rc = vmsvga3dSurfaceDefine(pThisCC, sid, surface.surfaceFlags, surface.format, surface.multiSampleCount,
     515                                           surface.autogenFilter, surface.cLevels, &pMipmapLevelSize[0]);
    437516                AssertRCReturn(rc, rc);
    438517
     
    447526
    448527            /* Load the mip map level data. */
    449             for (uint32_t j = 0; j < pSurface->faces[0].numMipLevels * pSurface->cFaces; j++)
     528            for (uint32_t j = 0; j < pSurface->cLevels * pSurface->cFaces; j++)
    450529            {
    451530                PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[j];
     
    684763            for (uint32_t face=0; face < pSurface->cFaces; face++)
    685764            {
    686                 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
     765                for (uint32_t i = 0; i < pSurface->cLevels; i++)
    687766                {
    688                     uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
     767                    uint32_t idx = i + face * pSurface->cLevels;
    689768                    PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[idx];
    690769
     
    698777            for (uint32_t face=0; face < pSurface->cFaces; face++)
    699778            {
    700                 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
     779                for (uint32_t i = 0; i < pSurface->cLevels; i++)
    701780                {
    702                     uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
     781                    uint32_t idx = i + face * pSurface->cLevels;
    703782                    PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[idx];
    704783
     
    877956
    878957                        RTMemFree(pData);
     958#elif defined(VMSVGA3D_DX)
     959                        /** @todo */
    879960#elif defined(VMSVGA3D_OPENGL)
    880961                        void *pData = NULL;
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp

    r86576 r86838  
    11961196        const uint32_t cHeight = pSurface->paMipmapLevels[0].mipmapSize.height;
    11971197        const uint32_t cDepth = pSurface->paMipmapLevels[0].mipmapSize.depth;
    1198         const uint32_t numMipLevels = pSurface->faces[0].numMipLevels;
     1198        const uint32_t numMipLevels = pSurface->cLevels;
    11991199
    12001200        LogFunc(("Create shared %stexture copy d3d (%d,%d,%d) cMip=%d usage %x format %x.\n",
     
    18531853    const uint32_t cHeight = pSurface->paMipmapLevels[0].mipmapSize.height;
    18541854    const uint32_t cDepth = pSurface->paMipmapLevels[0].mipmapSize.depth;
    1855     const uint32_t numMipLevels = pSurface->faces[0].numMipLevels;
     1855    const uint32_t numMipLevels = pSurface->cLevels;
    18561856
    18571857    /*
     
    19081908    {
    19091909        Assert(pSurface->cFaces == 1);
    1910         Assert(pSurface->faces[0].numMipLevels == 1);
     1910        Assert(pSurface->cLevels == 1);
    19111911        Assert(cDepth == 1);
    19121912
     
    22232223
    22242224        /* We will now use the bounce texture for all memory accesses, so free our surface memory buffer. */
    2225         for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
     2225        for (uint32_t i = 0; i < pSurface->cLevels; i++)
    22262226        {
    22272227            RTMemFree(pSurface->paMipmapLevels[i].pSurfaceData);
     
    27092709                SVGA3dTextureFilter const   autogenFilter    = pSurface->autogenFilter;
    27102710                uint32_t const              cFaces           = pSurface->cFaces;
    2711                 uint32_t const              cMipLevels       = pSurface->faces[0].numMipLevels;
     2711                uint32_t const              cMipLevels       = pSurface->cLevels;
    27122712
    27132713                SVGA3dSize *pMipLevelSize = (SVGA3dSize *)RTMemAllocZ(cMipLevels * cFaces * sizeof(SVGA3dSize));
     
    27232723                }
    27242724
    2725                 SVGA3dSurfaceFace aFaces[SVGA3D_MAX_SURFACE_FACES];
    2726                 AssertCompile(sizeof(aFaces) == sizeof(pSurface->faces));
    2727                 memcpy(aFaces, pSurface->faces, sizeof(pSurface->faces));
    2728 
    27292725                /* Recreate the surface with the original settings; destroys the contents, but that seems fairly safe since the context is also destroyed. */
    27302726#ifdef DEBUG_sunlover
     
    27362732                AssertRC(rc);
    27372733
    2738                 rc = vmsvga3dSurfaceDefine(pThisCC, sid, surfaceFlags, format, aFaces, multisampleCount, autogenFilter,
    2739                                            cMipLevels * cFaces, pMipLevelSize);
     2734                rc = vmsvga3dSurfaceDefine(pThisCC, sid, surfaceFlags, format, multisampleCount, autogenFilter,
     2735                                           cMipLevels, &pMipLevelSize[0]);
    27402736                AssertRC(rc);
    27412737
     
    40594055            {
    40604056                Log(("vmsvga3dSetRenderTarget: sync dirty depth/stencil buffer\n"));
    4061                 Assert(pRenderTarget->faces[0].numMipLevels == 1);
    4062 
    4063                 for (uint32_t i = 0; i < pRenderTarget->faces[0].numMipLevels; i++)
     4057                Assert(pRenderTarget->cLevels == 1);
     4058
     4059                for (uint32_t i = 0; i < pRenderTarget->cLevels; i++)
    40644060                {
    40654061                    if (pRenderTarget->paMipmapLevels[i].fDirty)
     
    44014397                {
    44024398                    Assert(pSurface->idAssociatedContext == SVGA3D_INVALID_ID);
    4403                     LogFunc(("CreateTexture (%d,%d) level=%d fUsage=%x format=%x\n", pSurface->paMipmapLevels[0].mipmapSize.width, pSurface->paMipmapLevels[0].mipmapSize.height, pSurface->faces[0].numMipLevels, pSurface->fUsageD3D, pSurface->formatD3D));
     4399                    LogFunc(("CreateTexture (%d,%d) level=%d fUsage=%x format=%x\n", pSurface->paMipmapLevels[0].mipmapSize.width, pSurface->paMipmapLevels[0].mipmapSize.height, pSurface->cLevels, pSurface->fUsageD3D, pSurface->formatD3D));
    44044400                    rc = vmsvga3dBackCreateTexture(pState, pContext, cid, pSurface);
    44054401                    AssertRCReturn(rc, rc);
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp

    r86024 r86838  
    5050 * @param   surfaceFlags        .
    5151 * @param   format              .
    52  * @param   face                .
    5352 * @param   multisampleCount    .
    5453 * @param   autogenFilter       .
    55  * @param   cMipLevels          .
    56  * @param   paMipLevelSizes     .
     54 * @param   numMipLevels        .
     55 * @param   pMipLevel0Size      .
    5756 */
    58 int vmsvga3dSurfaceDefine(PVGASTATECC pThisCC, uint32_t sid, uint32_t surfaceFlags, SVGA3dSurfaceFormat format,
    59                           SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES], uint32_t multisampleCount,
    60                           SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *paMipLevelSizes)
     57int vmsvga3dSurfaceDefine(PVGASTATECC pThisCC, uint32_t sid, SVGA3dSurfaceFlags surfaceFlags, SVGA3dSurfaceFormat format,
     58                          uint32_t multisampleCount, SVGA3dTextureFilter autogenFilter,
     59                          uint32_t numMipLevels, SVGA3dSize const *pMipLevel0Size)
    6160{
    6261    PVMSVGA3DSURFACE pSurface;
    6362    PVMSVGA3DSTATE   pState = pThisCC->svga.p3dState;
    64     AssertReturn(pState, VERR_NO_MEMORY);
    65 
    66     Log(("vmsvga3dSurfaceDefine: sid=%u surfaceFlags=%x format=%s (%x) multiSampleCount=%d autogenFilter=%d, cMipLevels=%d size=(%d,%d,%d)\n",
    67          sid, surfaceFlags, vmsvgaLookupEnum((int)format, &g_SVGA3dSurfaceFormat2String), format, multisampleCount, autogenFilter,
    68          cMipLevels, paMipLevelSizes->width, paMipLevelSizes->height, paMipLevelSizes->depth));
     63    AssertReturn(pState, VERR_INVALID_STATE);
     64
     65    LogFunc(("sid=%u surfaceFlags=%#x format=%s (%#x) multiSampleCount=%d autogenFilter=%d, numMipLevels=%d size=(%dx%dx%d)\n",
     66             sid, surfaceFlags, vmsvgaLookupEnum((int)format, &g_SVGA3dSurfaceFormat2String), format, multisampleCount, autogenFilter,
     67             numMipLevels, pMipLevel0Size->width, pMipLevel0Size->height, pMipLevel0Size->depth));
    6968
    7069    AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    71     AssertReturn(cMipLevels >= 1, VERR_INVALID_PARAMETER);
    72 
    73     /* Number of faces (cFaces) is specified as the number of the first non-zero elements in the 'face' array.
    74      * Since only plain surfaces (cFaces == 1) and cubemaps (cFaces == 6) are supported
    75      * (see also SVGA3dCmdDefineSurface definition in svga3d_reg.h), we ignore anything else.
    76      */
    77     uint32_t cRemainingMipLevels = cMipLevels;
    78     uint32_t cFaces = 0;
    79     for (uint32_t i = 0; i < SVGA3D_MAX_SURFACE_FACES; ++i)
    80     {
    81         if (face[i].numMipLevels == 0)
    82             break;
    83 
    84         /* All SVGA3dSurfaceFace structures must have the same value of numMipLevels field */
    85         AssertReturn(face[i].numMipLevels == face[0].numMipLevels, VERR_INVALID_PARAMETER);
    86 
    87         /* numMipLevels value can't be greater than the number of remaining elements in the paMipLevelSizes array. */
    88         AssertReturn(face[i].numMipLevels <= cRemainingMipLevels, VERR_INVALID_PARAMETER);
    89         cRemainingMipLevels -= face[i].numMipLevels;
    90 
    91         ++cFaces;
    92     }
    93     for (uint32_t i = cFaces; i < SVGA3D_MAX_SURFACE_FACES; ++i)
    94         AssertReturn(face[i].numMipLevels == 0, VERR_INVALID_PARAMETER);
    95 
    96     /* cFaces must be 6 for a cubemap and 1 otherwise. */
    97     AssertReturn(cFaces == (uint32_t)((surfaceFlags & SVGA3D_SURFACE_CUBEMAP) ? 6 : 1), VERR_INVALID_PARAMETER);
    98 
    99     /* Sum of face[i].numMipLevels must be equal to cMipLevels. */
    100     AssertReturn(cRemainingMipLevels == 0, VERR_INVALID_PARAMETER);
     70    AssertReturn(numMipLevels >= 1, VERR_INVALID_PARAMETER);
    10171
    10272    if (sid >= pState->cSurfaces)
     
    12696    pSurface->idWeakContextAssociation = SVGA3D_INVALID_ID;
    12797    pSurface->oglId.buffer          = OPENGL_INVALID_ID;
     98#elif defined(VMSVGA3D_DX)
     99    // pSurface->pBackendSurface       = NULL;
    128100#else /* VMSVGA3D_DIRECT3D */
    129101    pSurface->idAssociatedContext   = SVGA3D_INVALID_ID;
     
    132104#endif
    133105
     106    /** @todo This 'switch' and the sufraceFlags tweaks should not be necessary.
     107     * The actual surface type will be figured out when the surface is actually used later.
     108     * The backends code must be reviewed for unnecessary dependencies on the surfaceFlags value.
     109     */
    134110    /* The surface type is sort of undefined now, even though the hints and format can help to clear that up.
    135111     * In some case we'll have to wait until the surface is used to create the D3D object.
     
    145121    case SVGA3D_Z_DF24:
    146122    case SVGA3D_Z_D24S8_INT:
     123        Assert(surfaceFlags & SVGA3D_SURFACE_HINT_DEPTHSTENCIL);
    147124        surfaceFlags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
    148125        break;
     
    171148    case SVGA3D_A1R5G5B5:
    172149    case SVGA3D_A4R4G4B4:
     150        Assert(surfaceFlags & (SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_SCREENTARGET));
    173151        surfaceFlags |= SVGA3D_SURFACE_HINT_TEXTURE;
    174152        break;
     
    210188    pSurface->surfaceFlags      = surfaceFlags;
    211189    pSurface->format            = format;
    212     memcpy(pSurface->faces, face, sizeof(pSurface->faces));
    213     pSurface->cFaces            = cFaces;
     190    /* cFaces is 6 for a cubemaps and 1 otherwise. */
     191    pSurface->cFaces            = (uint32_t)((surfaceFlags & SVGA3D_SURFACE_CUBEMAP) ? 6 : 1);
     192    pSurface->cLevels           = numMipLevels;
    214193    pSurface->multiSampleCount  = multisampleCount;
    215194    pSurface->autogenFilter     = autogenFilter;
    216195    Assert(autogenFilter != SVGA3D_TEX_FILTER_FLATCUBIC);
    217196    Assert(autogenFilter != SVGA3D_TEX_FILTER_GAUSSIANCUBIC);
    218     pSurface->cMipmapLevels     = cMipLevels;
    219     pSurface->paMipmapLevels    = (PVMSVGA3DMIPMAPLEVEL)RTMemAllocZ(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
     197    pSurface->paMipmapLevels    = (PVMSVGA3DMIPMAPLEVEL)RTMemAllocZ(numMipLevels * pSurface->cFaces * sizeof(VMSVGA3DMIPMAPLEVEL));
    220198    AssertReturn(pSurface->paMipmapLevels, VERR_NO_MEMORY);
    221 
    222     for (uint32_t i=0; i < cMipLevels; i++)
    223         pSurface->paMipmapLevels[i].mipmapSize = paMipLevelSizes[i];
    224199
    225200    pSurface->cbBlock = vmsvga3dSurfaceFormatSize(format, &pSurface->cxBlock, &pSurface->cyBlock);
    226201    AssertReturn(pSurface->cbBlock, VERR_INVALID_PARAMETER);
     202
     203    /** @todo cbMemRemaining = value of SVGA_REG_MOB_MAX_SIZE */
     204    uint32_t cbMemRemaining = SVGA3D_MAX_SURFACE_MEM_SIZE; /* Do not allow more than this for a surface. */
     205    SVGA3dSize mipmapSize = *pMipLevel0Size;
     206    for (uint32_t i = 0; i < numMipLevels; ++i)
     207    {
     208        for (uint32_t iFace = 0; iFace < pSurface->cFaces; ++iFace)
     209        {
     210            uint32_t const iMipmap = iFace * numMipLevels + i;
     211            LogFunc(("[%d] face %d mip level %d (%d,%d,%d) cbBlock=%#x block %dx%d\n",
     212                     iMipmap, iFace, i, mipmapSize.width, mipmapSize.height, mipmapSize.depth,
     213                     pSurface->cbBlock, pSurface->cxBlock, pSurface->cyBlock));
     214
     215            uint32_t cBlocksX;
     216            uint32_t cBlocksY;
     217            if (RT_LIKELY(pSurface->cxBlock == 1 && pSurface->cyBlock == 1))
     218            {
     219                cBlocksX = mipmapSize.width;
     220                cBlocksY = mipmapSize.height;
     221            }
     222            else
     223            {
     224                cBlocksX = mipmapSize.width / pSurface->cxBlock;
     225                if (mipmapSize.width % pSurface->cxBlock)
     226                    ++cBlocksX;
     227                cBlocksY = mipmapSize.height / pSurface->cyBlock;
     228                if (mipmapSize.height % pSurface->cyBlock)
     229                    ++cBlocksY;
     230            }
     231
     232            AssertReturn(cBlocksX > 0 && cBlocksY > 0 && mipmapSize.depth > 0, VERR_INVALID_PARAMETER);
     233
     234            const uint32_t cMaxBlocksX = cbMemRemaining / pSurface->cbBlock;
     235            if (cBlocksX > cMaxBlocksX)
     236                return VERR_INVALID_PARAMETER;
     237            const uint32_t cbSurfacePitch = pSurface->cbBlock * cBlocksX;
     238            LogFunc(("cbSurfacePitch=0x%x\n", cbSurfacePitch));
     239
     240            const uint32_t cMaxBlocksY = cbMemRemaining / cbSurfacePitch;
     241            if (cBlocksY > cMaxBlocksY)
     242                return VERR_INVALID_PARAMETER;
     243            const uint32_t cbSurfacePlane = cbSurfacePitch * cBlocksY;
     244
     245            const uint32_t cMaxDepth = cbMemRemaining / cbSurfacePlane;
     246            if (mipmapSize.depth > cMaxDepth)
     247                return VERR_INVALID_PARAMETER;
     248            const uint32_t cbSurface = cbSurfacePlane * mipmapSize.depth;
     249
     250            PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[iMipmap];
     251            pMipmapLevel->mipmapSize     = mipmapSize;
     252            pMipmapLevel->cBlocksX       = cBlocksX;
     253            pMipmapLevel->cBlocksY       = cBlocksY;
     254            pMipmapLevel->cBlocks        = cBlocksX * cBlocksY * mipmapSize.depth;
     255            pMipmapLevel->cbSurfacePitch = cbSurfacePitch;
     256            pMipmapLevel->cbSurfacePlane = cbSurfacePlane;
     257            pMipmapLevel->cbSurface      = cbSurface;
     258            pMipmapLevel->pSurfaceData   = NULL;
     259
     260            cbMemRemaining -= cbSurface;
     261        }
     262
     263        mipmapSize.width >>= 1;
     264        if (mipmapSize.width == 0) mipmapSize.width = 1;
     265        mipmapSize.height >>= 1;
     266        if (mipmapSize.height == 0) mipmapSize.height = 1;
     267        mipmapSize.depth >>= 1;
     268        if (mipmapSize.depth == 0) mipmapSize.depth = 1;
     269    }
    227270
    228271#ifdef VMSVGA3D_DIRECT3D
     
    246289    /* pSurface->bounce.pTexture = NULL; */
    247290    /* pSurface->emulated.pTexture = NULL; */
     291#elif defined(VMSVGA3D_DX)
     292    /* Nothing, because all backend specific data reside in pSurface->pBackendSurface. */
    248293#else
    249294    /* pSurface->fEmulated = false; */
     
    264309
    265310    /* Allocate buffer to hold the surface data until we can move it into a D3D object */
    266     uint32_t cbMemRemaining = SVGA3D_MAX_SURFACE_MEM_SIZE; /* Do not allow more than this for a surface. */
    267     for (uint32_t i = 0; i < cMipLevels; ++i)
     311    for (uint32_t i = 0; i < numMipLevels * pSurface->cFaces; ++i)
    268312    {
    269313        PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[i];
    270         LogFunc(("[%d] face %d mip level %d (%d,%d,%d) cbBlock=0x%x block %dx%d\n",
    271                  i, i / pSurface->faces[0].numMipLevels, i % pSurface->faces[0].numMipLevels,
    272                  pMipmapLevel->mipmapSize.width, pMipmapLevel->mipmapSize.height, pMipmapLevel->mipmapSize.depth,
    273                  pSurface->cbBlock, pSurface->cxBlock, pSurface->cyBlock));
    274 
    275         uint32_t cBlocksX;
    276         uint32_t cBlocksY;
    277         if (RT_LIKELY(pSurface->cxBlock == 1 && pSurface->cyBlock == 1))
    278         {
    279             cBlocksX = pMipmapLevel->mipmapSize.width;
    280             cBlocksY = pMipmapLevel->mipmapSize.height;
    281         }
    282         else
    283         {
    284             cBlocksX = pMipmapLevel->mipmapSize.width / pSurface->cxBlock;
    285             if (pMipmapLevel->mipmapSize.width % pSurface->cxBlock)
    286                 ++cBlocksX;
    287             cBlocksY = pMipmapLevel->mipmapSize.height / pSurface->cyBlock;
    288             if (pMipmapLevel->mipmapSize.height % pSurface->cyBlock)
    289                 ++cBlocksY;
    290         }
    291 
    292         if (   cBlocksX == 0
    293             || cBlocksY == 0
    294             || pMipmapLevel->mipmapSize.depth == 0)
    295             return VERR_INVALID_PARAMETER;
    296 
    297         const uint32_t cMaxBlocksX = cbMemRemaining / pSurface->cbBlock;
    298         if (cBlocksX > cMaxBlocksX)
    299             return VERR_INVALID_PARAMETER;
    300         const uint32_t cbSurfacePitch = pSurface->cbBlock * cBlocksX;
    301         LogFunc(("cbSurfacePitch=0x%x\n", cbSurfacePitch));
    302 
    303         const uint32_t cMaxBlocksY = cbMemRemaining / cbSurfacePitch;
    304         if (cBlocksY > cMaxBlocksY)
    305             return VERR_INVALID_PARAMETER;
    306         const uint32_t cbSurfacePlane = cbSurfacePitch * cBlocksY;
    307 
    308         const uint32_t cMaxDepth = cbMemRemaining / cbSurfacePlane;
    309         if (pMipmapLevel->mipmapSize.depth > cMaxDepth)
    310             return VERR_INVALID_PARAMETER;
    311         const uint32_t cbSurface = cbSurfacePlane * pMipmapLevel->mipmapSize.depth;
    312 
    313         pMipmapLevel->cBlocksX       = cBlocksX;
    314         pMipmapLevel->cBlocksY       = cBlocksY;
    315         pMipmapLevel->cBlocks        = cBlocksX * cBlocksY * pMipmapLevel->mipmapSize.depth;
    316         pMipmapLevel->cbSurfacePitch = cbSurfacePitch;
    317         pMipmapLevel->cbSurfacePlane = cbSurfacePlane;
    318         pMipmapLevel->cbSurface      = cbSurface;
    319         pMipmapLevel->pSurfaceData   = RTMemAllocZ(cbSurface);
     314        pMipmapLevel->pSurfaceData = RTMemAllocZ(pMipmapLevel->cbSurface);
    320315        AssertReturn(pMipmapLevel->pSurfaceData, VERR_NO_MEMORY);
    321 
    322         cbMemRemaining -= cbSurface;
    323316    }
    324317    return VINF_SUCCESS;
     
    363356    if (pSurface->paMipmapLevels)
    364357    {
    365         for (uint32_t i = 0; i < pSurface->cMipmapLevels; ++i)
     358        for (uint32_t i = 0; i < pSurface->cLevels * pSurface->cFaces; ++i)
    366359            RTMemFreeZ(pSurface->paMipmapLevels[i].pSurfaceData, pSurface->paMipmapLevels[i].cbSurface);
    367360        RTMemFree(pSurface->paMipmapLevels);
     
    405398    AssertRCReturn(rc, rc);
    406399
    407     /* Can use faces[0].numMipLevels, because numMipLevels is the same for all faces. */
    408400    AssertReturn(pSrcSfcImg->face < pSrcSurface->cFaces, VERR_INVALID_PARAMETER);
    409     AssertReturn(pSrcSfcImg->mipmap < pSrcSurface->faces[0].numMipLevels, VERR_INVALID_PARAMETER);
     401    AssertReturn(pSrcSfcImg->mipmap < pSrcSurface->cLevels, VERR_INVALID_PARAMETER);
    410402    AssertReturn(pDstSfcImg->face < pDstSurface->cFaces, VERR_INVALID_PARAMETER);
    411     AssertReturn(pDstSfcImg->mipmap < pDstSurface->faces[0].numMipLevels, VERR_INVALID_PARAMETER);
     403    AssertReturn(pDstSfcImg->mipmap < pDstSurface->cLevels, VERR_INVALID_PARAMETER);
    412404
    413405    PVMSVGA3DCONTEXT pContext;
     
    514506        /* Flush the drawing pipeline for this surface as it could be used in a shared context. */
    515507        vmsvga3dSurfaceFlush(pSurface);
    516 
     508#elif defined(VMSVGA3D_DX)
     509        /** @todo */
    517510#else /* VMSVGA3D_OPENGL */
    518511        pContext = &pState->SharedCtx;
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h

    r86024 r86838  
    4949
    5050
     51typedef enum VMSVGA3D_SURFACE_MAP
     52{
     53    VMSVGA3D_SURFACE_MAP_READ,
     54    VMSVGA3D_SURFACE_MAP_WRITE,
     55    VMSVGA3D_SURFACE_MAP_READ_WRITE,
     56    VMSVGA3D_SURFACE_MAP_WRITE_DISCARD,
     57} VMSVGA3D_SURFACE_MAP;
     58
     59typedef struct VMSVGA3D_MAPPED_SURFACE
     60{
     61    VMSVGA3D_SURFACE_MAP enmMapType;
     62    SVGA3dBox box;
     63    uint32_t cbPixel;
     64    uint32_t cbRowPitch;
     65    uint32_t cbDepthPitch;
     66    void *pvData;
     67} VMSVGA3D_MAPPED_SURFACE;
     68
     69#ifdef DUMP_BITMAPS
     70void vmsvga3dMapWriteBmpFile(VMSVGA3D_MAPPED_SURFACE const *pMap, char const *pszPrefix);
     71#endif
     72
    5173/* DevVGA-SVGA.cpp: */
    5274void vmsvgaR33dSurfaceUpdateHeapBuffersOnFifoThread(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t sid);
     
    6385int vmsvga3dQueryCaps(PVGASTATECC pThisCC, uint32_t idx3dCaps, uint32_t *pu32Val);
    6486
    65 int vmsvga3dSurfaceDefine(PVGASTATECC pThisCC, uint32_t sid, uint32_t surfaceFlags, SVGA3dSurfaceFormat format,
    66                           SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES], uint32_t multisampleCount,
    67                           SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *pMipLevelSize);
     87int vmsvga3dSurfaceDefine(PVGASTATECC pThisCC, uint32_t sid, SVGA3dSurfaceFlags surfaceFlags, SVGA3dSurfaceFormat format,
     88                          uint32_t multisampleCount, SVGA3dTextureFilter autogenFilter,
     89                          uint32_t cMipLevels, SVGA3dSize const *pMipLevel0Size);
    6890int vmsvga3dSurfaceDestroy(PVGASTATECC pThisCC, uint32_t sid);
    6991int vmsvga3dSurfaceCopy(PVGASTATECC pThisCC, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src,
     
    108130int vmsvga3dQueryWait(PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t cid, SVGA3dQueryType type, SVGAGuestPtr guestResult);
    109131
     132int vmsvga3dScreenTargetBind(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, uint32_t sid);
     133int vmsvga3dScreenTargetUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, SVGA3dRect const *pRect);
     134
     135int vmsvga3dSurfaceMap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox, VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap);
     136int vmsvga3dSurfaceUnmap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten);
     137
    110138/* DevVGA-SVGA3d-shared.h: */
    111139#if defined(RT_OS_WINDOWS) && defined(IN_RING3)
  • trunk/src/VBox/Devices/Graphics/DevVGASavedState.h

    r83274 r86838  
    4747    } while (0)
    4848
    49 #define VGA_SAVEDSTATE_VERSION                   22
     49#define VGA_SAVEDSTATE_VERSION                   23
     50#define VGA_SAVEDSTATE_VERSION_VMSVGA_MIPLEVELS  23 /* Surface struct with number of miplevels. */
    5051#define VGA_SAVEDSTATE_VERSION_VMSVGA_CURSOR     22 /* Legacy cursor registers. */
    5152#define VGA_SAVEDSTATE_VERSION_VMSVGA_SCREENS    21 /* Screen objects. */
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