VirtualBox

Changeset 67972 in vbox


Ignore:
Timestamp:
Jul 14, 2017 1:44:02 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
116974
Message:

bugref:8863: several DevVGA-SVGA fixes

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h

    r64483 r67972  
    523523    SVGA3dSurfaceFace       faces[SVGA3D_MAX_SURFACE_FACES];
    524524    uint32_t                cFaces;
     525    uint32_t                cMipmapLevels;
    525526    PVMSVGA3DMIPMAPLEVEL    pMipmapLevels;
    526527    uint32_t                multiSampleCount;
     
    10601061                               PVMSVGA3DSURFACE pSurface);
    10611062
    1062 #endif
    1063 
     1063void vmsvgaClipCopyBox(const SVGA3dSize *pSizeSrc,
     1064                       const SVGA3dSize *pSizeDest,
     1065                       SVGA3dCopyBox *pBox);
     1066void vmsvgaClipBox(const SVGA3dSize *pSize,
     1067                   SVGA3dBox *pBox);
     1068
     1069#endif
     1070
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp

    r65381 r67972  
    19051905        srcBox.w = pBox[i].w;
    19061906        srcBox.h = pBox[i].h;
    1907         srcBox.d = pBox[i].z; /* XXX what about pBox[i].d? */
     1907        srcBox.d = pBox[i].d;
    19081908
    19091909        destBox.x = pBox[i].x;
     
    19121912        destBox.w = pBox[i].w;
    19131913        destBox.h = pBox[i].h;
    1914         destBox.z = pBox[i].z; /* XXX initializing destBox.z again? What about pBox[i].d and destBox.d? */
     1914        destBox.d = pBox[i].d;
    19151915
    19161916        rc = vmsvga3dSurfaceStretchBlt(pThis, &dest, &destBox, &src, &srcBox, SVGA3D_STRETCH_BLT_LINEAR);
     
    29252925            continue;
    29262926
    2927         if (RT_LIKELY(ClippedRect.w < VMSVGA_MAX_Y))
     2927        if (RT_LIKELY(ClippedRect.w < VMSVGA_MAX_X))
    29282928        { /* likely */ }
    29292929        else
    2930             ClippedRect.w = VMSVGA_MAX_Y;
    2931         if (RT_LIKELY(ClippedRect.w < VMSVGA_MAX_Y))
     2930            ClippedRect.w = VMSVGA_MAX_X;
     2931        if (RT_LIKELY(ClippedRect.h < VMSVGA_MAX_Y))
    29322932        { /* likely */ }
    29332933        else
    2934             ClippedRect.w = VMSVGA_MAX_Y;
     2934            ClippedRect.h = VMSVGA_MAX_Y;
    29352935
    29362936
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp

    r65381 r67972  
    10521052#endif /* LOG_ENABLED */
    10531053
     1054/** Unsigned coordinates in pBox. Clip to [0; pSizeSrc), [0;pSizeDest).
     1055 *
     1056 * @param pSizeSrc  Source surface dimensions.
     1057 * @param pSizeDest Destination surface dimensions.
     1058 * @param pBox      Coordinates to be clipped.
     1059 */
     1060void vmsvgaClipCopyBox(const SVGA3dSize *pSizeSrc,
     1061                       const SVGA3dSize *pSizeDest,
     1062                       SVGA3dCopyBox *pBox)
     1063{
     1064    /* Src x, w */
     1065    if (pBox->srcx > pSizeSrc->width)
     1066        pBox->srcx = pSizeSrc->width;
     1067    if (pBox->w > pSizeSrc->width - pBox->srcx)
     1068        pBox->w = pSizeSrc->width - pBox->srcx;
     1069
     1070    /* Src y, h */
     1071    if (pBox->srcy > pSizeSrc->height)
     1072        pBox->srcy = pSizeSrc->height;
     1073    if (pBox->h > pSizeSrc->height - pBox->srcy)
     1074        pBox->h = pSizeSrc->height - pBox->srcy;
     1075
     1076    /* Src z, d */
     1077    if (pBox->srcz > pSizeSrc->depth)
     1078        pBox->srcz = pSizeSrc->depth;
     1079    if (pBox->d > pSizeSrc->depth - pBox->srcz)
     1080        pBox->d = pSizeSrc->depth - pBox->srcz;
     1081
     1082    /* Dest x, w */
     1083    if (pBox->x > pSizeDest->width)
     1084        pBox->x = pSizeDest->width;
     1085    if (pBox->w > pSizeDest->width - pBox->x)
     1086        pBox->w = pSizeDest->width - pBox->x;
     1087
     1088    /* Dest y, h */
     1089    if (pBox->y > pSizeDest->height)
     1090        pBox->y = pSizeDest->height;
     1091    if (pBox->h > pSizeDest->height - pBox->y)
     1092        pBox->h = pSizeDest->height - pBox->y;
     1093
     1094    /* Dest z, d */
     1095    if (pBox->z > pSizeDest->depth)
     1096        pBox->z = pSizeDest->depth;
     1097    if (pBox->d > pSizeDest->depth - pBox->z)
     1098        pBox->d = pSizeDest->depth - pBox->z;
     1099}
     1100
     1101/** Unsigned coordinates in pBox. Clip to [0; pSize).
     1102 *
     1103 * @param pSize     Source surface dimensions.
     1104 * @param pBox      Coordinates to be clipped.
     1105 */
     1106void vmsvgaClipBox(const SVGA3dSize *pSize,
     1107                   SVGA3dBox *pBox)
     1108{
     1109    /* x, w */
     1110    if (pBox->x > pSize->width)
     1111        pBox->x = pSize->width;
     1112    if (pBox->w > pSize->width - pBox->x)
     1113        pBox->w = pSize->width - pBox->x;
     1114
     1115    /* y, h */
     1116    if (pBox->y > pSize->height)
     1117        pBox->y = pSize->height;
     1118    if (pBox->h > pSize->height - pBox->y)
     1119        pBox->h = pSize->height - pBox->y;
     1120
     1121    /* z, d */
     1122    if (pBox->z > pSize->depth)
     1123        pBox->z = pSize->depth;
     1124    if (pBox->d > pSize->depth - pBox->z)
     1125        pBox->d = pSize->depth - pBox->z;
     1126}
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp

    r67572 r67972  
    13191319    AssertReturn(pSurfaceDest->faces[0].numMipLevels > dest.mipmap, VERR_INVALID_PARAMETER);
    13201320
     1321    const VMSVGA3DMIPMAPLEVEL *pMipmapLevelSrc = &pSurfaceSrc->pMipmapLevels[src.mipmap];
     1322    const VMSVGA3DMIPMAPLEVEL *pMipmapLevelDest = &pSurfaceDest->pMipmapLevels[dest.mipmap];
     1323
    13211324   // AssertMsgReturn(pSurfaceSrc->format == pSurfaceDest->format, ("Format mismatch (%d vs %d)!!\n", pSurfaceSrc->format, pSurfaceDest->format), VERR_INVALID_PARAMETER);
    13221325
     1326    /** @todo Support cubemaps. */
    13231327    bool fSrcTexture  = !!(pSurfaceSrc->flags & SVGA3D_SURFACE_HINT_TEXTURE);
    13241328    bool fDestTexture = !!(pSurfaceDest->flags & SVGA3D_SURFACE_HINT_TEXTURE);
     
    13881392            IDirect3DSurface9 *pDest;
    13891393
    1390             RectSrc.left    = pBox[i].srcx;
    1391             RectSrc.top     = pBox[i].srcy;
    1392             RectSrc.right   = pBox[i].srcx + pBox[i].w;   /* exclusive */
    1393             RectSrc.bottom  = pBox[i].srcy + pBox[i].h;   /* exclusive */
    1394             RectDest.left   = pBox[i].x;
    1395             RectDest.top    = pBox[i].y;
    1396             RectDest.right  = pBox[i].x + pBox[i].w;   /* exclusive */
    1397             RectDest.bottom = pBox[i].y + pBox[i].h;   /* exclusive */
     1394            SVGA3dCopyBox clipBox = pBox[i];
     1395            vmsvgaClipCopyBox(&pMipmapLevelSrc->size, &pMipmapLevelDest->size, &clipBox);
     1396            if (   !clipBox.w
     1397                || !clipBox.h
     1398                || !clipBox.d)
     1399            {
     1400                LogFunc(("Skipped empty box.\n"));
     1401                continue;
     1402            }
     1403
     1404            RectSrc.left    = clipBox.srcx;
     1405            RectSrc.top     = clipBox.srcy;
     1406            RectSrc.right   = clipBox.srcx + clipBox.w;   /* exclusive */
     1407            RectSrc.bottom  = clipBox.srcy + clipBox.h;   /* exclusive */
     1408            RectDest.left   = clipBox.x;
     1409            RectDest.top    = clipBox.y;
     1410            RectDest.right  = clipBox.x + clipBox.w;   /* exclusive */
     1411            RectDest.bottom = clipBox.y + clipBox.h;   /* exclusive */
    13981412
    13991413            Log(("vmsvga3dSurfaceCopy: (StretchRect) copy src sid=%x face=%d mipmap=%d (%d,%d)(%d,%d) to dest sid=%x face=%d mipmap=%d (%d,%d)\n", sidSrc, src.face, src.mipmap, RectSrc.left, RectSrc.top, RectSrc.right, RectSrc.bottom, sidDest, dest.face, dest.mipmap, pBox[i].x, pBox[i].y));
    14001414
    14011415            if (    sidSrc == sidDest
    1402                 &&  pBox[i].srcx == pBox[i].x
    1403                 &&  pBox[i].srcy == pBox[i].y)
     1416                &&  clipBox.srcx == clipBox.x
     1417                &&  clipBox.srcy == clipBox.y)
    14041418            {
    14051419                Log(("vmsvga3dSurfaceCopy: redundant copy to the same surface at the same coordinates. Ignore. \n"));
     
    14071421            }
    14081422            Assert(sidSrc != sidDest);
    1409             Assert(!pBox[i].srcz && !pBox[i].z);
     1423            Assert(!clipBox.srcz && !clipBox.z);
    14101424
    14111425            if (fSrcTexture)
     
    14461460    for (uint32_t i = 0; i < cCopyBoxes; i++)
    14471461    {
    1448         HRESULT        hr = D3D_OK;
     1462        HRESULT        hr;
    14491463        D3DLOCKED_RECT LockedSrcRect;
    14501464        D3DLOCKED_RECT LockedDestRect;
    1451         RECT           Rect;
    1452 
    1453         Rect.left   = pBox[i].srcx;
    1454         Rect.top    = pBox[i].srcy;
    1455         Rect.right  = pBox[i].srcx + pBox[i].w;   /* exclusive */
    1456         Rect.bottom = pBox[i].srcy + pBox[i].h;   /* exclusive */
    1457 
    1458         Log(("vmsvga3dSurfaceCopy: (manual) copy sid=%x face=%d mipmap=%d (%d,%d)(%d,%d) to sid=%x face=%d mipmap=%d (%d,%d)\n", sidSrc, src.face, src.mipmap, Rect.left, Rect.top, Rect.right, Rect.bottom, sidDest, dest.face, dest.mipmap, pBox[i].x, pBox[i].y));
    1459 
    1460         Assert(!pBox[i].srcz && !pBox[i].z);
     1465        RECT           RectSrc;
     1466        RECT           RectDest;
     1467
     1468        SVGA3dCopyBox clipBox = pBox[i];
     1469        vmsvgaClipCopyBox(&pMipmapLevelSrc->size, &pMipmapLevelDest->size, &clipBox);
     1470        if (   !clipBox.w
     1471            || !clipBox.h
     1472            || !clipBox.d)
     1473        {
     1474            LogFunc(("Skipped empty box.\n"));
     1475            continue;
     1476        }
     1477
     1478        RectSrc.left    = clipBox.srcx;
     1479        RectSrc.top     = clipBox.srcy;
     1480        RectSrc.right   = clipBox.srcx + clipBox.w;   /* exclusive */
     1481        RectSrc.bottom  = clipBox.srcy + clipBox.h;   /* exclusive */
     1482        RectDest.left   = clipBox.x;
     1483        RectDest.top    = clipBox.y;
     1484        RectDest.right  = clipBox.x + clipBox.w;   /* exclusive */
     1485        RectDest.bottom = clipBox.y + clipBox.h;   /* exclusive */
     1486
     1487        LogFunc(("(manual) copy sid=%x face=%d mipmap=%d (%d,%d)(%d,%d) to sid=%x face=%d mipmap=%d (%d,%d)\n",
     1488                 sidSrc, src.face, src.mipmap, RectSrc.left, RectSrc.top, RectSrc.right, RectSrc.bottom,
     1489                 sidDest, dest.face, dest.mipmap, pBox[i].x, pBox[i].y));
     1490
     1491        Assert(!clipBox.srcz && !clipBox.z);
     1492        Assert(pSurfaceSrc->cbBlock == pSurfaceDest->cbBlock);
    14611493
    14621494        if (!pSurfaceSrc->u.pSurface)
    14631495        {
    1464             LockedSrcRect.pBits = (void *)pSurfaceSrc->pMipmapLevels[src.mipmap].pSurfaceData;
    1465             LockedSrcRect.Pitch  = pSurfaceSrc->pMipmapLevels[src.mipmap].cbSurfacePitch;
     1496            LockedSrcRect.pBits = (uint8_t *)pMipmapLevelSrc->pSurfaceData +
     1497                                  pMipmapLevelSrc->cbSurfacePitch * clipBox.srcy + pSurfaceSrc->cbBlock * clipBox.srcx;
     1498            LockedSrcRect.Pitch = pMipmapLevelSrc->cbSurfacePitch;
    14661499        }
    14671500        else
    14681501        {
    1469             /* Must flush the other context's 3d pipeline to make sure all drawing is complete for the surface we're about to use. */
     1502            /** @todo This branch is dead code. Because if the source is a hardware surface, then
     1503             *  the code above creates hardware surface for the destination and does the copy in hardware.
     1504             *  I.e. we can not get here with pSurfaceSrc->u.pSurface != NULL.
     1505             */
     1506
     1507            /* Must flush the context's 3d pipeline to make sure all drawing is complete for the surface we're about to use. */
    14701508            vmsvga3dSurfaceFlush(pThis, pSurfaceSrc);
    14711509
     
    14751513                hr = pSurfaceSrc->u.pTexture->LockRect(src.mipmap, /* Texture level */
    14761514                                                       &LockedSrcRect,
    1477                                                        &Rect,
     1515                                                       &RectSrc,
    14781516                                                       D3DLOCK_READONLY);
    14791517            }
    14801518            else
    14811519                hr = pSurfaceSrc->u.pSurface->LockRect(&LockedSrcRect,
    1482                                                        &Rect,
     1520                                                       &RectSrc,
    14831521                                                       D3DLOCK_READONLY);
    1484             AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSurfaceCopy: LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
     1522            AssertMsgReturn(hr == D3D_OK, ("LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
    14851523        }
    14861524
    14871525        if (!pSurfaceDest->u.pSurface)
    14881526        {
    1489             LockedDestRect.pBits = (void *)pSurfaceDest->pMipmapLevels[dest.mipmap].pSurfaceData;
    1490             LockedDestRect.Pitch  = pSurfaceDest->pMipmapLevels[dest.mipmap].cbSurfacePitch;
     1527            LockedDestRect.pBits = (uint8_t *)pMipmapLevelDest->pSurfaceData +
     1528                                   pMipmapLevelDest->cbSurfacePitch * clipBox.y + pSurfaceDest->cbBlock * clipBox.x;
     1529            LockedDestRect.Pitch = pMipmapLevelDest->cbSurfacePitch;
    14911530        }
    14921531        else
    14931532        {
    1494             /* Must flush the other context's 3d pipeline to make sure all drawing is complete for the surface we're about to use. */
     1533            /* Must flush the context's 3d pipeline to make sure all drawing is complete for the surface we're about to use. */
    14951534            vmsvga3dSurfaceFlush(pThis, pSurfaceDest);
    14961535
     
    15011540                    /* pSurfaceDest->u.pTexture can't be locked, see vmsvga3dBackCreateTexture */
    15021541                    hr = pSurfaceDest->bounce.pTexture->LockRect(dest.mipmap, /* texture level */
    1503                                                             &LockedDestRect,
    1504                                                             &Rect,
    1505                                                             0);
     1542                                                                 &LockedDestRect,
     1543                                                                 &RectDest,
     1544                                                                 0);
    15061545                }
    15071546                else
     
    15091548                    hr = pSurfaceDest->u.pTexture->LockRect(dest.mipmap, /* texture level */
    15101549                                                            &LockedDestRect,
    1511                                                             &Rect,
     1550                                                            &RectDest,
    15121551                                                            0);
    15131552                }
     
    15151554            else
    15161555                hr = pSurfaceDest->u.pSurface->LockRect(&LockedDestRect,
    1517                                                         &Rect,
     1556                                                        &RectDest,
    15181557                                                        0);
    1519             AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSurfaceCopy: LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
    1520         }
    1521 
    1522         uint8_t *pDest = (uint8_t *)LockedDestRect.pBits + LockedDestRect.Pitch * pBox[i].y + pBox[i].x * pSurfaceDest->cbBlock;
    1523         uint8_t *pSrc  = (uint8_t *)LockedSrcRect.pBits + LockedSrcRect.Pitch * pBox[i].srcy + pBox[i].srcx * pSurfaceSrc->cbBlock;
    1524 
    1525         for (int32_t j = Rect.top; j < Rect.bottom; j++)
    1526         {
    1527             memcpy(pDest, pSrc, pBox[i].w * pSurfaceSrc->cbBlock);
     1558            AssertMsgReturn(hr == D3D_OK, ("LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
     1559        }
     1560
     1561        uint8_t *pDest = (uint8_t *)LockedDestRect.pBits;
     1562        const uint8_t *pSrc = (uint8_t *)LockedSrcRect.pBits;
     1563
     1564        for (uint32_t j = 0; j < clipBox.h; ++j)
     1565        {
     1566            memcpy(pDest, pSrc, clipBox.w * pSurfaceSrc->cbBlock);
    15281567
    15291568            pDest += LockedDestRect.Pitch;
     
    15601599            else
    15611600                hr = pSurfaceDest->u.pSurface->UnlockRect();
    1562             AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSurfaceCopy: Unlock failed with %x\n", hr), VERR_INTERNAL_ERROR);
     1601            AssertMsgReturn(hr == D3D_OK, ("Unlock failed with %x\n", hr), VERR_INTERNAL_ERROR);
    15631602        }
    15641603
     
    15691608            else
    15701609                hr = pSurfaceSrc->u.pSurface->UnlockRect();
    1571             AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSurfaceCopy: Unlock failed with %x\n", hr), VERR_INTERNAL_ERROR);
     1610            AssertMsgReturn(hr == D3D_OK, ("Unlock failed with %x\n", hr), VERR_INTERNAL_ERROR);
    15721611        }
    15731612    }
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp

    r66519 r67972  
    7575     * (see also SVGA3dCmdDefineSurface definition in svga3d_reg.h), we ignore anything else.
    7676     */
     77    uint32_t cRemainingMipLevels = cMipLevels;
    7778    uint32_t cFaces = 0;
    7879    for (uint32_t i = 0; i < SVGA3D_MAX_SURFACE_FACES; ++i)
     
    8384        /* All SVGA3dSurfaceFace structures must have the same value of numMipLevels field */
    8485        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
    8591        ++cFaces;
    8692    }
     
    9096    /* cFaces must be 6 for a cubemap and 1 otherwise. */
    9197    AssertReturn(cFaces == (uint32_t)((surfaceFlags & SVGA3D_SURFACE_CUBEMAP) ? 6 : 1), VERR_INVALID_PARAMETER);
    92     AssertReturn(cMipLevels == cFaces * face[0].numMipLevels, VERR_INVALID_PARAMETER);
     98
     99    /* Sum of face[i].numMipLevels must be equal to cMipLevels. */
     100    AssertReturn(cRemainingMipLevels == 0, VERR_INVALID_PARAMETER);
    93101
    94102    if (sid >= pState->cSurfaces)
     
    212220    Assert(autogenFilter != SVGA3D_TEX_FILTER_FLATCUBIC);
    213221    Assert(autogenFilter != SVGA3D_TEX_FILTER_GAUSSIANCUBIC);
     222    pSurface->cMipmapLevels     = cMipLevels;
    214223    pSurface->pMipmapLevels     = (PVMSVGA3DMIPMAPLEVEL)RTMemAllocZ(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
    215224    AssertReturn(pSurface->pMipmapLevels, VERR_NO_MEMORY);
     
    219228
    220229    pSurface->cbBlock = vmsvga3dSurfaceFormatSize(format);
     230    AssertReturn(pSurface->cbBlock, VERR_INVALID_PARAMETER);
    221231
    222232#ifdef VMSVGA3D_DIRECT3D
     
    276286
    277287    /* Allocate buffer to hold the surface data until we can move it into a D3D object */
     288    uint32_t cbMemRemaining = SVGA3D_MAX_SURFACE_MEM_SIZE; /* Do not allow more than this for a surface. */
    278289    for (uint32_t i = 0; i < cMipLevels; ++i)
    279290    {
    280291        PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[i];
    281         LogFunc(("[%d] face %d mip level %d (%d,%d,%d)\n", i, i / pSurface->faces[0].numMipLevels, i % pSurface->faces[0].numMipLevels, pMipmapLevel->size.width, pMipmapLevel->size.height, pMipmapLevel->size.depth));
    282         LogFunc(("cbPitch=0x%x cbBlock=0x%x\n", pSurface->cbBlock * pMipmapLevel->size.width, pSurface->cbBlock));
    283 
    284         pMipmapLevel->cbSurfacePitch = pSurface->cbBlock * pMipmapLevel->size.width;
    285         pMipmapLevel->cbSurface      = pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height * pMipmapLevel->size.depth;
    286         pMipmapLevel->pSurfaceData   = RTMemAllocZ(pMipmapLevel->cbSurface);
     292        LogFunc(("[%d] face %d mip level %d (%d,%d,%d) cbBlock=0x%x\n",
     293                 i, i / pSurface->faces[0].numMipLevels, i % pSurface->faces[0].numMipLevels,
     294                 pMipmapLevel->size.width, pMipmapLevel->size.height, pMipmapLevel->size.depth, pSurface->cbBlock));
     295
     296        if (   pMipmapLevel->size.width == 0
     297            || pMipmapLevel->size.height == 0
     298            || pMipmapLevel->size.depth == 0)
     299            return VERR_INVALID_PARAMETER;
     300
     301        const uint32_t cMaxWidth = cbMemRemaining / pSurface->cbBlock;
     302        if (pMipmapLevel->size.width > cMaxWidth)
     303            return VERR_INVALID_PARAMETER;
     304        const uint32_t cbSurfacePitch = pSurface->cbBlock * pMipmapLevel->size.width;
     305        LogFunc(("cbPitch=0x%x\n", cbSurfacePitch));
     306
     307        const uint32_t cMaxHeight = cbMemRemaining / cbSurfacePitch;
     308        if (pMipmapLevel->size.height > cMaxHeight)
     309            return VERR_INVALID_PARAMETER;
     310        const uint32_t cbSurfacePlane = cbSurfacePitch * pMipmapLevel->size.height;
     311
     312        const uint32_t cMaxDepth = cbMemRemaining / cbSurfacePlane;
     313        if (pMipmapLevel->size.depth > cMaxDepth)
     314            return VERR_INVALID_PARAMETER;
     315        const uint32_t cbSurface = cbSurfacePlane * pMipmapLevel->size.depth;
     316
     317        pMipmapLevel->cbSurfacePitch = cbSurfacePitch;
     318        pMipmapLevel->cbSurface      = cbSurface;
     319        pMipmapLevel->pSurfaceData   = RTMemAllocZ(cbSurface);
    287320        AssertReturn(pMipmapLevel->pSurfaceData, VERR_NO_MEMORY);
     321
     322        cbMemRemaining -= cbSurface;
    288323    }
    289324    return VINF_SUCCESS;
     
    328363        if (pSurface->pMipmapLevels)
    329364        {
    330             for (uint32_t face=0; face < pSurface->cFaces; face++)
    331             {
    332                 for (uint32_t i=0; i < pSurface->faces[face].numMipLevels; i++)
    333                 {
    334                     uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
    335                     if (pSurface->pMipmapLevels[idx].pSurfaceData)
    336                         RTMemFree(pSurface->pMipmapLevels[idx].pSurfaceData);
    337                 }
    338             }
     365            for (uint32_t i = 0; i < pSurface->cMipmapLevels; ++i)
     366                RTMemFree(pSurface->pMipmapLevels[i].pSurfaceData);
    339367            RTMemFree(pSurface->pMipmapLevels);
    340368        }
     
    428456    }
    429457
     458    SVGA3dBox clipSrcBox = *pSrcBox;
     459    SVGA3dBox clipDstBox = *pDstBox;
     460    vmsvgaClipBox(&pSrcSurface->pMipmapLevels[pSrcSfcImg->mipmap].size, &clipSrcBox);
     461    vmsvgaClipBox(&pDstSurface->pMipmapLevels[pDstSfcImg->mipmap].size, &clipDstBox);
     462
    430463    return vmsvga3dBackSurfaceStretchBlt(pThis, pState,
    431                                          pDstSurface, pDstSfcImg->mipmap, pDstBox,
    432                                          pSrcSurface, pSrcSfcImg->mipmap, pSrcBox,
     464                                         pDstSurface, pDstSfcImg->mipmap, &clipDstBox,
     465                                         pSrcSurface, pSrcSfcImg->mipmap, &clipSrcBox,
    433466                                         enmMode, pContext);
    434467}
     
    485518
    486519            Log(("Copy box %d (%d,%d,%d)(%d,%d,%d) dest (%d,%d)\n", i, paBoxes[i].srcx, paBoxes[i].srcy, paBoxes[i].srcz, paBoxes[i].w, paBoxes[i].h, paBoxes[i].d, paBoxes[i].x, paBoxes[i].y));
     520
    487521            /* Apparently we're supposed to clip it (gmr test sample) */
    488             if (paBoxes[i].x + paBoxes[i].w > pMipLevel->size.width)
    489                 paBoxes[i].w = pMipLevel->size.width - paBoxes[i].x;
    490             if (paBoxes[i].y + paBoxes[i].h > pMipLevel->size.height)
    491                 paBoxes[i].h = pMipLevel->size.height - paBoxes[i].y;
    492             if (paBoxes[i].z + paBoxes[i].d > pMipLevel->size.depth)
    493                 paBoxes[i].d = pMipLevel->size.depth - paBoxes[i].z;
    494 
    495             if (    !paBoxes[i].w
    496                 ||  !paBoxes[i].h
    497                 ||  !paBoxes[i].d
    498                 ||   paBoxes[i].x > pMipLevel->size.width
    499                 ||   paBoxes[i].y > pMipLevel->size.height
    500                 ||   paBoxes[i].z > pMipLevel->size.depth)
     522            SVGA3dCopyBox clipBox = paBoxes[i];
     523            vmsvgaClipCopyBox(&pMipLevel->size, &pMipLevel->size, &clipBox);
     524            if (   !clipBox.w
     525                || !clipBox.h
     526                || !clipBox.d)
    501527            {
    502528                Log(("Empty box; skip\n"));
     
    504530            }
    505531
    506             uDestOffset = paBoxes[i].x * pSurface->cbBlock + paBoxes[i].y * pMipLevel->cbSurfacePitch + paBoxes[i].z * pMipLevel->size.height * pMipLevel->cbSurfacePitch;
    507             AssertReturn(uDestOffset + paBoxes[i].w * pSurface->cbBlock * paBoxes[i].h * paBoxes[i].d <= pMipLevel->cbSurface, VERR_INTERNAL_ERROR);
    508 
    509             cbSrcPitch = (guest.pitch == 0) ? paBoxes[i].w * pSurface->cbBlock : guest.pitch;
     532            uDestOffset = clipBox.x * pSurface->cbBlock + clipBox.y * pMipLevel->cbSurfacePitch + clipBox.z * pMipLevel->size.height * pMipLevel->cbSurfacePitch;
     533            AssertReturn(uDestOffset + clipBox.w * pSurface->cbBlock * clipBox.h * clipBox.d <= pMipLevel->cbSurface, VERR_INTERNAL_ERROR);
     534
     535            cbSrcPitch = (guest.pitch == 0) ? clipBox.w * pSurface->cbBlock : guest.pitch;
    510536#ifdef MANUAL_FLIP_SURFACE_DATA
    511537            pBufferStart =    (uint8_t *)pMipLevel->pSurfaceData
    512                             + paBoxes[i].x * pSurface->cbBlock
    513                             + pMipLevel->cbSurface - paBoxes[i].y * pMipLevel->cbSurfacePitch
     538                            + clipBox.x * pSurface->cbBlock
     539                            + pMipLevel->cbSurface - clipBox.y * pMipLevel->cbSurfacePitch
    514540                            - pMipLevel->cbSurfacePitch;      /* flip image during copy */
    515541#else
     
    525551#endif
    526552                                   guest.ptr,
    527                                    paBoxes[i].srcx * pSurface->cbBlock + (paBoxes[i].srcy + paBoxes[i].srcz * paBoxes[i].h) * cbSrcPitch,
     553                                   clipBox.srcx * pSurface->cbBlock + (clipBox.srcy + clipBox.srcz * clipBox.h) * cbSrcPitch,
    528554                                   cbSrcPitch,
    529                                    paBoxes[i].w * pSurface->cbBlock,
    530                                    paBoxes[i].d * paBoxes[i].h);
     555                                   clipBox.w * pSurface->cbBlock,
     556                                   clipBox.d * clipBox.h);
    531557
    532558            Log4(("first line:\n%.*Rhxd\n", pMipLevel->cbSurfacePitch, pMipLevel->pSurfaceData));
     
    555581        for (unsigned i = 0; i < cCopyBoxes; i++)
    556582        {
     583            Log(("Copy box %d (%d,%d,%d)(%d,%d,%d) dest (%d,%d)\n", i, paBoxes[i].srcx, paBoxes[i].srcy, paBoxes[i].srcz, paBoxes[i].w, paBoxes[i].h, paBoxes[i].d, paBoxes[i].x, paBoxes[i].y));
     584
     585            /** @todo Is d == 0 valid? */
     586            Assert((paBoxes[i].d == 1 || paBoxes[i].d == 0) && paBoxes[i].z == 0);
     587
    557588            /* Apparently we're supposed to clip it (gmr test sample) */
    558             if (paBoxes[i].x + paBoxes[i].w > pMipLevel->size.width)
    559                 paBoxes[i].w = pMipLevel->size.width - paBoxes[i].x;
    560             if (paBoxes[i].y + paBoxes[i].h > pMipLevel->size.height)
    561                 paBoxes[i].h = pMipLevel->size.height - paBoxes[i].y;
    562             if (paBoxes[i].z + paBoxes[i].d > pMipLevel->size.depth)
    563                 paBoxes[i].d = pMipLevel->size.depth - paBoxes[i].z;
    564 
    565             Assert((paBoxes[i].d == 1 || paBoxes[i].d == 0) && paBoxes[i].z == 0);
    566 
    567             if (    !paBoxes[i].w
    568                 ||  !paBoxes[i].h
    569                 ||   paBoxes[i].x > pMipLevel->size.width
    570                 ||   paBoxes[i].y > pMipLevel->size.height)
     589            SVGA3dCopyBox clipBox = paBoxes[i];
     590            vmsvgaClipCopyBox(&pMipLevel->size, &pMipLevel->size, &clipBox);
     591            if (   !clipBox.w
     592                || !clipBox.h
     593                || !clipBox.d)
    571594            {
    572595                Log(("Empty box; skip\n"));
     
    574597            }
    575598
    576             Log(("Copy box %d (%d,%d,%d)(%d,%d,%d) dest (%d,%d)\n", i, paBoxes[i].srcx, paBoxes[i].srcy, paBoxes[i].srcz, paBoxes[i].w, paBoxes[i].h, paBoxes[i].d, paBoxes[i].x, paBoxes[i].y));
    577 
    578             uint32_t cbSrcPitch = (guest.pitch == 0) ? paBoxes[i].w * pSurface->cbBlock : guest.pitch;
     599            uint32_t cbSrcPitch = (guest.pitch == 0) ? clipBox.w * pSurface->cbBlock : guest.pitch;
    579600            rc = vmsvga3dBackSurfaceDMACopyBox(pThis, pState, pSurface, host.mipmap, guest.ptr, cbSrcPitch, transfer,
    580                                                &paBoxes[i], pContext, rc, i);
     601                                               &clipBox, pContext, rc, i);
    581602        }
    582603    }
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h

    r62679 r67972  
    3131/** Arbitrary upper limit; seen 8 so far. */
    3232#define SVGA3D_MAX_LIGHTS                       32
     33/** Arbitrary upper limit; 2GB enough for 32768x16384*4. */
     34#define SVGA3D_MAX_SURFACE_MEM_SIZE             0x80000000
    3335
    3436
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