VirtualBox

Changeset 53779 in vbox


Ignore:
Timestamp:
Jan 13, 2015 10:59:10 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
97585
Message:

vmsvga fifo handling optimizations.

File:
1 edited

Legend:

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

    r53775 r53779  
    18681868#ifdef IN_RING3
    18691869
    1870 static void *vmsvgaFIFOGetCmdBuffer(PPDMTHREAD pThread, uint32_t *pFIFO, uint32_t cbCmd, uint32_t *pSize, void **ppfBounceBuffer)
     1870/**
     1871 * Reads (more) payload into the command buffer.
     1872 *
     1873 * @returns pbBounceBuf on success
     1874 * @retval  (void *)1 if the thread was requested to stop.
     1875 * @retval  NULL on FIFO error.
     1876 *
     1877 * @param   pThread         The calling PDM thread handle.
     1878 * @param   cbPayloadReq    The number of bytes of payload requested.
     1879 * @param   pFIFO           The FIFO.
     1880 * @param   offCurrentCmd   The FIFO byte offset of the current command.
     1881 * @param   offFifoMin      The start byte offset of the command FIFO.
     1882 * @param   offFifoMax      The end byte offset of the command FIFO.
     1883 * @param   pbBounceBuf     The bounch buffer. Same size as the entire FIFO, so
     1884 *                          always sufficient size.
     1885 * @param   pcbAlreadyRead  How much payload we've already read into the bounce
     1886 *                          buffer. (We will NEVER re-read anything.)
     1887 */
     1888static void *vmsvgaFIFOGetCmdPayload(PPDMTHREAD pThread, uint32_t cbPayloadReq, uint32_t volatile *pFIFO,
     1889                                    uint32_t offCurrentCmd, uint32_t offFifoMin, uint32_t offFifoMax,
     1890                                    uint8_t *pbBounceBuf, uint32_t *pcbAlreadyRead)
    18711891{
    1872     uint32_t cbLeft;
    1873     uint32_t cbFIFOCmd = pFIFO[SVGA_FIFO_MAX] - pFIFO[SVGA_FIFO_MIN];
    1874     uint32_t u32Current = pFIFO[SVGA_FIFO_STOP] + sizeof(uint32_t);     /* skip command dword */
    1875     uint8_t *pCmdBuffer;
    1876 
    1877     Assert(ppfBounceBuffer);
    1878     /* Commands bigger than the fifo buffer are invalid. */
    1879     AssertReturn(cbCmd <= cbFIFOCmd, NULL);
    1880 
    1881     *pSize          += cbCmd;
    1882     *ppfBounceBuffer = NULL;
    1883 
    1884     while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    1885     {
    1886         Assert(pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP]);
    1887 
    1888         if (pFIFO[SVGA_FIFO_NEXT_CMD] >= u32Current)
    1889             cbLeft = pFIFO[SVGA_FIFO_NEXT_CMD] - u32Current;
     1892    Assert(pbBounceBuf);
     1893    Assert(pcbAlreadyRead);
     1894    Assert(offFifoMin < offFifoMax);
     1895    Assert(offCurrentCmd >= offFifoMin && offCurrentCmd < offFifoMax);
     1896    Assert(offFifoMax <= VMSVGA_FIFO_SIZE);
     1897
     1898    /*
     1899     * Check if the requested payload size has already been satisfied                                                                                                .
     1900     *                                                                                                                                                       .
     1901     * When called to read more, the caller is responsible for making sure the                                                                               .
     1902     * new command size (cbRequsted) never is smaller than what has already                                                                                  .
     1903     * been read.
     1904     */
     1905    uint32_t cbAlreadyRead = *pcbAlreadyRead;
     1906    if (cbPayloadReq <= cbAlreadyRead)
     1907    {
     1908        AssertLogRelReturn(cbPayloadReq == cbAlreadyRead, NULL);
     1909        return pbBounceBuf;
     1910    }
     1911
     1912    /*
     1913     * Commands bigger than the fifo buffer are invalid.
     1914     */
     1915    uint32_t const cbFifoCmd = offFifoMax - offFifoMin;
     1916    AssertMsgReturn(cbPayloadReq <= cbFifoCmd, ("cbPayloadReq=%#x cbFifoCmd=%#x\n", cbPayloadReq, cbFifoCmd), NULL);
     1917
     1918    /*
     1919     * Move offCurrentCmd past the command dword.
     1920     */
     1921    offCurrentCmd += sizeof(uint32_t);
     1922    if (offCurrentCmd >= offFifoMax)
     1923        offCurrentCmd = offFifoMin;
     1924
     1925    /*
     1926     * Do we have sufficient payload data available already?
     1927     */
     1928    uint32_t cbAfter, cbBefore;
     1929    uint32_t offNextCmd = pFIFO[SVGA_FIFO_NEXT_CMD];
     1930    if (offNextCmd > offCurrentCmd)
     1931    {
     1932        if (RT_LIKELY(offNextCmd < offFifoMax))
     1933            cbAfter = offNextCmd - offCurrentCmd;
    18901934        else
    1891             cbLeft = cbFIFOCmd - (u32Current - pFIFO[SVGA_FIFO_NEXT_CMD]);
    1892 
    1893         if (cbCmd <= cbLeft)
    1894             break;
    1895 
    1896         /* Guest still busy copying into the FIFO; wait a bit. */
    1897         Log(("Guest still copying (%x vs %x) current %x next %x stop %x; sleep a bit\n", cbCmd, cbLeft, u32Current, pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP]));
    1898         RTThreadSleep(2);
    1899     }
    1900 
    1901     if (u32Current + cbCmd <= pFIFO[SVGA_FIFO_MAX])
    1902     {
    1903         pCmdBuffer = (uint8_t *)pFIFO + u32Current;
     1935        {
     1936            LogRelMax(16, ("vmsvgaFIFOGetCmdPayload: Invalid offNextCmd=%#x (offFifoMin=%#x offFifoMax=%#x)\n",
     1937                           offNextCmd, offFifoMin, offFifoMax));
     1938            /** @todo release counter.   */
     1939            cbAfter = offFifoMax - offCurrentCmd;
     1940        }
     1941        cbBefore = 0;
    19041942    }
    19051943    else
    19061944    {
    1907         /* command data split; allocate memory and copy. */
    1908         uint8_t *pFIFOMin = (uint8_t *)pFIFO + pFIFO[SVGA_FIFO_MIN];
    1909         uint32_t cbPart1 = pFIFO[SVGA_FIFO_MAX] - u32Current;
    1910         uint32_t cbPart2 = cbCmd - cbPart1;
    1911 
    1912         LogFlow(("Split data buffer at %x (%d-%d)\n", u32Current, cbPart1, cbPart2));
    1913         pCmdBuffer = (uint8_t *)RTMemAlloc(cbCmd);
    1914         AssertReturn(pCmdBuffer, NULL);
    1915         *ppfBounceBuffer = (void *)pCmdBuffer;
    1916 
    1917         memcpy(pCmdBuffer,           (uint8_t *)pFIFO + u32Current, cbPart1);
    1918         memcpy(pCmdBuffer + cbPart1,  pFIFOMin,                     cbPart2);
    1919     }
    1920 
    1921     return pCmdBuffer;
     1945        cbAfter  = offFifoMax - offCurrentCmd;
     1946        if (offNextCmd >= offFifoMin)
     1947            cbBefore = offNextCmd - offFifoMin;
     1948        else
     1949        {
     1950            LogRelMax(16, ("vmsvgaFIFOGetCmdPayload: Invalid offNextCmd=%#x (offFifoMin=%#x offFifoMax=%#x)\n",
     1951                           offNextCmd, offFifoMin, offFifoMax));
     1952            /** @todo release counter.   */
     1953            cbBefore = 0;
     1954        }
     1955    }
     1956    if (cbAfter + cbBefore < cbPayloadReq)
     1957    {
     1958        /*
     1959         * Insufficient, must wait for it to arrive.
     1960         */
     1961        for (;;)
     1962        {
     1963            if (pThread->enmState != PDMTHREADSTATE_RUNNING)
     1964                return (void *)(uintptr_t)1;
     1965            Log(("Guest still copying (%x vs %x) current %x next %x stop %x; sleep a bit\n",
     1966                 cbPayloadReq, cbAfter + cbBefore, offCurrentCmd, offNextCmd, pFIFO[SVGA_FIFO_STOP]));
     1967            RTThreadSleep(1);
     1968            /** @todo release counter.   */
     1969
     1970            offNextCmd = pFIFO[SVGA_FIFO_NEXT_CMD];
     1971            if (offNextCmd > offCurrentCmd)
     1972            {
     1973                cbAfter = RT_MIN(offNextCmd, offFifoMax) - offCurrentCmd;
     1974                cbBefore = 0;
     1975            }
     1976            else
     1977            {
     1978                cbAfter  = offFifoMax - offCurrentCmd;
     1979                cbBefore = RT_MAX(offNextCmd, offFifoMin) - offFifoMin;
     1980            }
     1981
     1982            if (cbAfter + cbBefore >= cbPayloadReq)
     1983                break;
     1984        }
     1985    }
     1986
     1987    /*
     1988     * Copy out the memory and update what pcbAlreadyRead points to.
     1989     */
     1990    if (cbAfter >= cbPayloadReq)
     1991        memcpy(pbBounceBuf + cbAlreadyRead,
     1992               (uint8_t *)pFIFO + offCurrentCmd + cbAlreadyRead,
     1993               cbPayloadReq - cbAlreadyRead);
     1994    else
     1995    {
     1996        LogFlow(("Split data buffer at %x (%u-%u)\n", offCurrentCmd, cbAfter, cbBefore));
     1997        if (cbAlreadyRead < cbAfter)
     1998        {
     1999            memcpy(pbBounceBuf + cbAlreadyRead,
     2000                   (uint8_t *)pFIFO + offCurrentCmd + cbAlreadyRead,
     2001                   cbAfter - cbAlreadyRead);
     2002            cbAlreadyRead += cbAfter - cbAlreadyRead;
     2003        }
     2004        memcpy(pbBounceBuf + cbAlreadyRead,
     2005               (uint8_t *)pFIFO + offFifoMin + cbAlreadyRead - cbAfter,
     2006               cbPayloadReq - cbAlreadyRead);
     2007    }
     2008    *pcbAlreadyRead = cbPayloadReq;
     2009    return pbBounceBuf;
    19222010}
    19232011
     2012/**
     2013 * Macro for checking if a fixed FIFO register is valid according to the
     2014 * current FIFO configuration.
     2015 *
     2016 * @returns true / false.
     2017 * @param   a_iIndex        The fifo register index (like SVGA_FIFO_CAPABILITIES).
     2018 * @param   a_offFifoMin    A valid SVGA_FIFO_MIN value.
     2019 */
     2020#define VMSVGA_IS_VALID_FIFO_REG(a_iIndex, a_offFifoMin) ( ((a_iIndex) + 1) * sizeof(uint32_t) <= (a_offFifoMin) )
    19242021
    19252022/* The async FIFO handling thread. */
     
    19332030        return VINF_SUCCESS;
    19342031
     2032    /*
     2033     * Allocate a bounce buffer for command we get from the FIFO.
     2034     * (All code must return via the end of the function to free this buffer.)
     2035     */
     2036    uint8_t *pbBounceBuf = (uint8_t *)RTMemAllocZ(VMSVGA_FIFO_SIZE);
     2037    AssertReturn(pbBounceBuf, VERR_NO_MEMORY);
     2038
    19352039    LogFlow(("vmsvgaFIFOLoop: started loop\n"));
     2040    uint32_t volatile * const pFIFO = pThis->svga.pFIFOR3;
    19362041    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    19372042    {
    1938         uint32_t *pFIFO = pThis->svga.pFIFOR3;
    19392043
    19402044        /* Wait for at most 250 ms to start polling. */
     
    19442048        {
    19452049            LogFlow(("vmsvgaFIFOLoop: thread state %x\n", pThread->enmState));
    1946             return VINF_SUCCESS;
     2050            break;
    19472051        }
    19482052        if (rc == VERR_TIMEOUT)
     
    20122116        {
    20132117            pThis->svga.fBusy = false;
    2014             pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
     2118            if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_BUSY, pFIFO[SVGA_FIFO_MIN]))
     2119                pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
    20152120            continue;   /* device not enabled. */
    20162121        }
    20172122
    2018         if (pFIFO[SVGA_FIFO_STOP] >= pFIFO[SVGA_FIFO_MAX])
    2019         {
    2020             Log(("vmsvgaFIFOLoop: Invalid stop %x max=%x\n", pFIFO[SVGA_FIFO_STOP], pFIFO[SVGA_FIFO_MAX]));
    2021             continue;   /* invalid. */
    2022         }
    2023 
    2024         if (pFIFO[SVGA_FIFO_MAX] < VMSVGA_FIFO_SIZE)
    2025         {
    2026             Log(("vmsvgaFIFOLoop: Invalid max %x fifo max=%x\n", pFIFO[SVGA_FIFO_MAX], VMSVGA_FIFO_SIZE));
    2027             continue;   /* invalid. */
    2028         }
    2029 
    2030         if (pFIFO[SVGA_FIFO_STOP] < pFIFO[SVGA_FIFO_MIN])
    2031         {
    2032             Log(("vmsvgaFIFOLoop: Invalid stop %x min=%x\n", pFIFO[SVGA_FIFO_STOP], pFIFO[SVGA_FIFO_MIN]));
    2033             continue;   /* invalid. */
    2034         }
     2123        /*
     2124         * Get and check the min/max values.  We ASSUME that they will remain
     2125         * unchanged while we process requests.  A further ASSUMPTION is that
     2126         * the guest won't mess with SVGA_FIFO_NEXT_CMD while we're busy, so
     2127         * we don't read it back while in the loop.
     2128         */
     2129        uint32_t const offFifoMin    = pFIFO[SVGA_FIFO_MIN];
     2130        uint32_t const offFifoMax    = pFIFO[SVGA_FIFO_MAX];
     2131        uint32_t       offCurrentCmd = pFIFO[SVGA_FIFO_STOP];
     2132        if (RT_UNLIKELY(   !VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_STOP, offFifoMin)
     2133                        || offFifoMax <= offFifoMin
     2134                        || offFifoMax > VMSVGA_FIFO_SIZE
     2135                        || offCurrentCmd < offFifoMin
     2136                        || offCurrentCmd > offFifoMax))
     2137        {
     2138            LogRelMax(8, ("vmsvgaFIFOLoop: Bad fifo: min=%#x stop=%#x max=%#x\n", offFifoMin, offCurrentCmd, offFifoMax));
     2139            /** @todo Should we clear SVGA_FIFO_BUSY here like we do above? */
     2140            continue;
     2141        }
     2142        if (RT_UNLIKELY(offCurrentCmd & 3))
     2143        {
     2144            LogRelMax(8, ("vmsvgaFIFOLoop: Misaligned offCurrentCmd=%#x?\n", offCurrentCmd));
     2145            offCurrentCmd = ~UINT32_C(3);
     2146        }
     2147
     2148/**
     2149 * Macro for shortening calls to vmsvgaFIFOGetCmdPayload.
     2150 *
     2151 * Will break out of the switch on failure.
     2152 * Will restart and quit the loop if the thread was requested to stop.
     2153 *
     2154 * @param   a_cbPayloadReq  How much payload to fetch.
     2155 * @remarks Access a bunch of variables in the current scope!
     2156 */
     2157# define VMSVGAFIFO_GET_CMD_BUFFER_BREAK(a_PtrVar, a_Type, a_cbPayloadReq) \
     2158            if (1) { \
     2159                (a_PtrVar) = (a_Type *)vmsvgaFIFOGetCmdPayload(pThread, (a_cbPayloadReq), pFIFO, \
     2160                                                               offCurrentCmd, offFifoMin, offFifoMax, \
     2161                                                               pbBounceBuf, &cbPayload); \
     2162                if (RT_UNLIKELY((uintptr_t)(a_PtrVar) < 2)) { if ((uintptr_t)(a_PtrVar) == 1) continue; break; } \
     2163            } else do {} while (0)
     2164/**
     2165 * Macro for shortening calls to vmsvgaFIFOGetCmdPayload for refetching the
     2166 * buffer after figuring out the actual command size.
     2167 * Will break out of the switch on failure.
     2168 * @param   a_cbPayloadReq  How much payload to fetch.
     2169 * @remarks Access a bunch of variables in the current scope!
     2170 */
     2171# define VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(a_PtrVar, a_Type, a_cbPayloadReq) \
     2172            if (1) { \
     2173                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(a_PtrVar, a_Type, a_cbPayloadReq); \
     2174            } else do {} while (0)
     2175
     2176        /*
     2177         * Mark the FIFO as busy.
     2178         */
    20352179        pThis->svga.fBusy = true;
    2036         pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
    2037 
    2038         /* Execute all queued FIFO commands. */
    2039         while (     pThread->enmState == PDMTHREADSTATE_RUNNING
    2040                &&   pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP])
    2041         {
    2042             uint32_t u32Cmd;
    2043             uint32_t u32Current, size;
     2180        if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_BUSY, offFifoMin))
     2181            pFIFO[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
     2182
     2183        /*
     2184         * Execute all queued FIFO commands.
     2185         * Quit if pending external command or changes in the thread state.
     2186         */
     2187        bool fDone = false;
     2188        while (   !(fDone = pFIFO[SVGA_FIFO_NEXT_CMD] == offCurrentCmd)
     2189               && pThread->enmState == PDMTHREADSTATE_RUNNING)
     2190        {
     2191            uint32_t cbPayload = 0;
    20442192            uint32_t u32IrqStatus = 0;
    20452193            bool     fTriggerIrq = false;
    2046             void    *pBounceBuffer = NULL;
     2194
     2195            Assert(offCurrentCmd < offFifoMax && offCurrentCmd >= offFifoMin);
    20472196
    20482197            /* First check any pending actions. */
     
    20572206                break;
    20582207
    2059             u32Current = pFIFO[SVGA_FIFO_STOP];
    2060 
    2061             u32Cmd = u32Current / sizeof(uint32_t);
    2062             LogFlow(("vmsvgaFIFOLoop: FIFO command (iCmd=0x%x) %s 0x%x\n", u32Cmd, vmsvgaFIFOCmdToString(pFIFO[u32Cmd]), pFIFO[u32Cmd]));
    2063             size = sizeof(uint32_t);    /* command dword */
    2064 
    2065             switch (pFIFO[u32Cmd])
     2208            /*
     2209             * Process the command.
     2210             */
     2211            SVGAFifoCmdId const enmCmdId = (SVGAFifoCmdId)pFIFO[offCurrentCmd / sizeof(uint32_t)];
     2212            LogFlow(("vmsvgaFIFOLoop: FIFO command (iCmd=0x%x) %s 0x%x\n",
     2213                     offCurrentCmd / sizeof(uint32_t), vmsvgaFIFOCmdToString(enmCmdId), enmCmdId));
     2214            switch (enmCmdId)
    20662215            {
    20672216            case SVGA_CMD_INVALID_CMD:
     
    20712220            case SVGA_CMD_FENCE:
    20722221            {
    2073                 SVGAFifoCmdFence *pCmdFence = (SVGAFifoCmdFence *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdFence), &size, &pBounceBuffer);
    2074 
    2075                 Log(("vmsvgaFIFOLoop: SVGA_CMD_FENCE %x\n", pCmdFence->fence));
    2076                 pFIFO[SVGA_FIFO_FENCE] = pCmdFence->fence;
    2077                 if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE)
     2222                SVGAFifoCmdFence *pCmdFence;
     2223                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmdFence, SVGAFifoCmdFence, sizeof(*pCmdFence));
     2224                if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE, offFifoMin))
    20782225                {
    2079                     Log(("vmsvgaFIFOLoop: any fence irq\n"));
    2080                     u32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE;
     2226                    Log(("vmsvgaFIFOLoop: SVGA_CMD_FENCE %x\n", pCmdFence->fence));
     2227                    pFIFO[SVGA_FIFO_FENCE] = pCmdFence->fence;
     2228
     2229                    if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE)
     2230                    {
     2231                        Log(("vmsvgaFIFOLoop: any fence irq\n"));
     2232                        u32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE;
     2233                    }
     2234                    else
     2235                    if (    VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE_GOAL, offFifoMin)
     2236                        &&  (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FENCE_GOAL)
     2237                        &&  pFIFO[SVGA_FIFO_FENCE_GOAL] == pCmdFence->fence)
     2238                    {
     2239                        Log(("vmsvgaFIFOLoop: fence goal reached irq (fence=%x)\n", pCmdFence->fence));
     2240                        u32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL;
     2241                    }
    20812242                }
    20822243                else
    2083                 if (    (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FENCE_GOAL)
    2084                     &&  pFIFO[SVGA_FIFO_FENCE_GOAL] == pCmdFence->fence)
    2085                 {
    2086                     Log(("vmsvgaFIFOLoop: fence goal reached irq (fence=%x)\n", pCmdFence->fence));
    2087                     u32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL;
    2088                 }
     2244                    Log(("SVGA_CMD_FENCE is bogus when offFifoMin is %#x!\n", offFifoMin));
    20892245                break;
    20902246            }
     
    20922248            case SVGA_CMD_UPDATE_VERBOSE:
    20932249            {
    2094                 SVGAFifoCmdUpdate *pUpdate = (SVGAFifoCmdUpdate *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdUpdate), &size, &pBounceBuffer);
    2095 
     2250                SVGAFifoCmdUpdate *pUpdate;
     2251                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pUpdate, SVGAFifoCmdUpdate, sizeof(*pUpdate));
    20962252                Log(("vmsvgaFIFOLoop: UPDATE (%d,%d)(%d,%d)\n", pUpdate->x, pUpdate->y, pUpdate->width, pUpdate->height));
    20972253                vgaR3UpdateDisplay(pThis, pUpdate->x, pUpdate->y, pUpdate->width, pUpdate->height);
     
    21022258            {
    21032259                /* Followed by bitmap data. */
    2104                 SVGAFifoCmdDefineCursor *pCursor = (SVGAFifoCmdDefineCursor *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDefineCursor), &size, &pBounceBuffer);
    2105 
    2106                 AssertFailed();
     2260                SVGAFifoCmdDefineCursor *pCursor;
     2261                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCursor, SVGAFifoCmdDefineCursor, sizeof(*pCursor));
     2262                AssertFailed(); /** @todo implement when necessary. */
    21072263                break;
    21082264            }
     
    21112267            {
    21122268                /* Followed by bitmap data. */
    2113                 SVGAFifoCmdDefineAlphaCursor *pCursor = (SVGAFifoCmdDefineAlphaCursor *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDefineAlphaCursor), &size, &pBounceBuffer);
    21142269                uint32_t cbCursorShape, cbAndMask;
    21152270                uint8_t *pCursorCopy;
    21162271                uint32_t cbCmd;
    21172272
     2273                SVGAFifoCmdDefineAlphaCursor *pCursor;
     2274                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCursor, SVGAFifoCmdDefineAlphaCursor, sizeof(*pCursor));
     2275
    21182276                Log(("vmsvgaFIFOLoop: ALPHA_CURSOR id=%d size (%d,%d) hotspot (%d,%d)\n", pCursor->id, pCursor->width, pCursor->height, pCursor->hotspotX, pCursor->hotspotY));
    21192277
    21202278                /* Check against a reasonable upper limit to prevent integer overflows in the sanity checks below. */
    2121                 AssertReturn(pCursor->height < 2048 && pCursor->width < 2048, VERR_INVALID_PARAMETER);
    2122 
    2123                 /* Refetch the command buffer with the added bitmap data; undo size increase (ugly) */
     2279                AssertBreak(pCursor->height < 2048 && pCursor->width < 2048);
     2280
     2281                /* Refetch the bitmap data as well. */
    21242282                cbCmd = sizeof(SVGAFifoCmdDefineAlphaCursor) + pCursor->width * pCursor->height * sizeof(uint32_t) /* 32-bit BRGA format */;
    2125                 size  = sizeof(uint32_t);    /* command dword */
    2126                 if (pBounceBuffer)
    2127                     RTMemFree(pBounceBuffer);
    2128                 pCursor = (SVGAFifoCmdDefineAlphaCursor *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, cbCmd, &size, &pBounceBuffer);
     2283                VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCursor, SVGAFifoCmdDefineAlphaCursor, cbCmd);
     2284                /** @todo Would be more efficient to copy the data straight into pCursorCopy (memcpy below). */
    21292285
    21302286                /* The mouse pointer interface always expects an AND mask followed by the color data (XOR mask). */
     
    21692325            {
    21702326                /* Followed by nsize bytes of data. */
    2171                 SVGAFifoCmdEscape *pEscape = (SVGAFifoCmdEscape *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdEscape), &size, &pBounceBuffer);
    2172                 uint32_t cbCmd;
     2327                SVGAFifoCmdEscape *pEscape;
     2328                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pEscape, SVGAFifoCmdEscape, sizeof(*pEscape));
    21732329
    21742330                /* Refetch the command buffer with the variable data; undo size increase (ugly) */
    2175                 cbCmd = sizeof(SVGAFifoCmdEscape) + pEscape->size;
    2176                 size  = sizeof(uint32_t);    /* command dword */
    2177                 if (pBounceBuffer)
    2178                     RTMemFree(pBounceBuffer);
    2179                 pEscape = (SVGAFifoCmdEscape *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, cbCmd, &size, &pBounceBuffer);
     2331                AssertBreak(pEscape->size < VMSVGA_FIFO_SIZE);
     2332                uint32_t cbCmd = sizeof(SVGAFifoCmdEscape) + pEscape->size;
     2333                VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pEscape, SVGAFifoCmdEscape, cbCmd);
    21802334
    21812335                if (pEscape->nsid == SVGA_ESCAPE_NSID_VMWARE)
    21822336                {
    2183                     Assert(pEscape->size >= sizeof(uint32_t));
     2337                    AssertBreak(pEscape->size >= sizeof(uint32_t));
    21842338                    uint32_t cmd = *(uint32_t *)(pEscape + 1);
    21852339                    Log(("vmsvgaFIFOLoop: ESCAPE (%x %x) VMWARE cmd=%x\n", pEscape->nsid, pEscape->size, cmd));
     
    21902344                    {
    21912345                        SVGAEscapeVideoSetRegs *pVideoCmd = (SVGAEscapeVideoSetRegs *)(pEscape + 1);
     2346                        AssertBreak(pEscape->size >= sizeof(pVideoCmd->header));
    21922347                        uint32_t cRegs = (pEscape->size - sizeof(pVideoCmd->header)) / sizeof(pVideoCmd->items[0]);
    21932348
     
    22022357                    case SVGA_ESCAPE_VMWARE_VIDEO_FLUSH:
    22032358                        SVGAEscapeVideoFlush *pVideoCmd = (SVGAEscapeVideoFlush *)(pEscape + 1);
     2359                        AssertBreak(pEscape->size >= sizeof(*pVideoCmd));
    22042360                        Log(("SVGA_ESCAPE_VMWARE_VIDEO_FLUSH: stream %x\n", pVideoCmd->streamId));
    22052361                        break;
     
    22142370            case SVGA_CMD_DEFINE_GMR2:
    22152371            {
    2216                 SVGAFifoCmdDefineGMR2 *pCmd = (SVGAFifoCmdDefineGMR2 *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDefineGMR2), &size, &pBounceBuffer);
     2372                SVGAFifoCmdDefineGMR2 *pCmd;
     2373                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineGMR2, sizeof(*pCmd));
    22172374                Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_GMR2 id=%x %x pages\n", pCmd->gmrId, pCmd->numPages));
    22182375
     
    22362393            case SVGA_CMD_REMAP_GMR2:
    22372394            {
    2238                 /* Followed by page descriptors. */
    2239                 SVGAFifoCmdRemapGMR2 *pCmd = (SVGAFifoCmdRemapGMR2 *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdRemapGMR2), &size, &pBounceBuffer);
     2395                /* Followed by page descriptors or guest ptr. */
     2396                SVGAFifoCmdRemapGMR2 *pCmd;
     2397                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdRemapGMR2, sizeof(*pCmd));
    22402398                uint32_t cbPageDesc = (pCmd->flags & SVGA_REMAP_GMR2_PPN64) ? sizeof(uint64_t) : sizeof(uint32_t);
    22412399                uint32_t cbCmd;
     
    22432401
    22442402                Log(("vmsvgaFIFOLoop: SVGA_CMD_REMAP_GMR2 id=%x flags=%x offset=%x npages=%x\n", pCmd->gmrId, pCmd->flags, pCmd->offsetPages, pCmd->numPages));
    2245 
    2246                 /* Refetch the command buffer with the variable data; undo size increase (ugly) */
     2403                AssertBreak(pCmd->gmrId < VMSVGA_MAX_GMR_IDS);
     2404
     2405                /* Calculate the size of what comes after next and fetch it. */
    22472406                cbCmd = sizeof(SVGAFifoCmdRemapGMR2);
    22482407                if (pCmd->flags & SVGA_REMAP_GMR2_VIA_GMR)
     
    22552414                }
    22562415                else
     2416                {
     2417                    AssertBreak(pCmd->numPages <= VMSVGA_FIFO_SIZE);
    22572418                    cbCmd += cbPageDesc * pCmd->numPages;
    2258                 size = sizeof(uint32_t);    /* command dword */
    2259 
    2260                 if (pBounceBuffer)
    2261                     RTMemFree(pBounceBuffer);
    2262                 pCmd = (SVGAFifoCmdRemapGMR2 *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, cbCmd, &size, &pBounceBuffer);
    2263                 AssertReturn(pCmd, VERR_INTERNAL_ERROR);
    2264 
    2265                 PGMR pGMR = &pSVGAState->aGMR[pCmd->gmrId];
     2419                }
     2420                VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdRemapGMR2, cbCmd);
    22662421
    22672422                /* Validate current GMR id. */
    22682423                AssertBreak(pCmd->gmrId < VMSVGA_MAX_GMR_IDS);
     2424                PGMR pGMR = &pSVGAState->aGMR[pCmd->gmrId];
    22692425                AssertBreak(pCmd->offsetPages + pCmd->numPages <= pGMR->cMaxPages);
    22702426                AssertBreak(!pCmd->offsetPages || pGMR->paDesc); /* @todo */
     
    23732529            case SVGA_CMD_DEFINE_SCREEN:
    23742530            {
    2375                 /* @note optional size depending on the capabilities */
     2531                /* Note! The size of this command is specified by the guest and depends on capabilities. */
    23762532                Assert(!(pThis->svga.pFIFOR3[SVGA_FIFO_CAPABILITIES] & SVGA_FIFO_CAP_SCREEN_OBJECT));
    2377                 SVGAFifoCmdDefineScreen *pCmd = (SVGAFifoCmdDefineScreen *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDefineScreen), &size, &pBounceBuffer);
     2533                SVGAFifoCmdDefineScreen *pCmd;
     2534                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineScreen, sizeof(pCmd->screen.structSize));
     2535                RT_BZERO(&pCmd->screen.id, sizeof(*pCmd) - RT_OFFSETOF(SVGAFifoCmdDefineScreen, screen.structSize));
     2536                VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineScreen, RT_MAX(sizeof(pCmd->screen.structSize), pCmd->screen.structSize));
    23782537
    23792538                Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN id=%x flags=%x size=(%d,%d) root=(%d,%d)\n", pCmd->screen.id, pCmd->screen.flags, pCmd->screen.size.width, pCmd->screen.size.height, pCmd->screen.root.x, pCmd->screen.root.y));
     
    23892548                    Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_BLANKING\n"));
    23902549
     2550                /** @todo multi monitor support and screen object capabilities.   */
    23912551                pThis->svga.uWidth  = pCmd->screen.size.width;
    23922552                pThis->svga.uHeight = pCmd->screen.size.height;
     
    23972557            case SVGA_CMD_DESTROY_SCREEN:
    23982558            {
    2399                 SVGAFifoCmdDestroyScreen *pCmd = (SVGAFifoCmdDestroyScreen *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDestroyScreen), &size, &pBounceBuffer);
     2559                SVGAFifoCmdDestroyScreen *pCmd;
     2560                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDestroyScreen, sizeof(*pCmd));
    24002561
    24012562                Log(("vmsvgaFIFOLoop: SVGA_CMD_DESTROY_SCREEN id=%x\n", pCmd->screenId));
     
    24052566            case SVGA_CMD_DEFINE_GMRFB:
    24062567            {
    2407                 SVGAFifoCmdDefineGMRFB *pCmd = (SVGAFifoCmdDefineGMRFB *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDefineGMRFB), &size, &pBounceBuffer);
     2568                SVGAFifoCmdDefineGMRFB *pCmd;
     2569                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineGMRFB, sizeof(*pCmd));
    24082570
    24092571                Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_GMRFB gmr=%x offset=%x bytesPerLine=%x bpp=%d color depth=%d\n", pCmd->ptr.gmrId, pCmd->ptr.offset, pCmd->bytesPerLine, pCmd->format.s.bitsPerPixel, pCmd->format.s.colorDepth));
     
    24162578            case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
    24172579            {
    2418                 SVGAFifoCmdBlitGMRFBToScreen *pCmd = (SVGAFifoCmdBlitGMRFBToScreen *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdBlitGMRFBToScreen), &size, &pBounceBuffer);
    24192580                uint32_t width, height;
     2581                SVGAFifoCmdBlitGMRFBToScreen *pCmd;
     2582                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdBlitGMRFBToScreen, sizeof(*pCmd));
    24202583
    24212584                Log(("vmsvgaFIFOLoop: SVGA_CMD_BLIT_GMRFB_TO_SCREEN src=(%d,%d) dest id=%d (%d,%d)(%d,%d)\n", pCmd->srcOrigin.x, pCmd->srcOrigin.y, pCmd->destScreenId, pCmd->destRect.left, pCmd->destRect.top, pCmd->destRect.right, pCmd->destRect.bottom));
    24222585
    2423                 /* @todo */
     2586                /** @todo Support GMRFB.format.s.bitsPerPixel != pThis->svga.uBpp  */
    24242587                AssertBreak(pSVGAState->GMRFB.format.s.bitsPerPixel == pThis->svga.uBpp);
    24252588                AssertBreak(pCmd->destScreenId == 0);
     
    24512614                unsigned cbCopyWidth  = (width * RT_ALIGN(pThis->svga.uBpp, 8)) / 8;
    24522615
    2453                 AssertReturn(offsetDest < pThis->vram_size, VERR_INVALID_PARAMETER);
     2616                AssertBreak(offsetDest < pThis->vram_size);
    24542617
    24552618                rc = vmsvgaGMRTransfer(pThis, SVGA3D_WRITE_HOST_VRAM, pThis->CTX_SUFF(vram_ptr) + offsetDest, pThis->svga.cbScanline, pSVGAState->GMRFB.ptr, offsetSource, pSVGAState->GMRFB.bytesPerLine, cbCopyWidth, height);
     
    24612624            case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
    24622625            {
    2463                 SVGAFifoCmdBlitScreenToGMRFB *pCmd = (SVGAFifoCmdBlitScreenToGMRFB *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdBlitScreenToGMRFB), &size, &pBounceBuffer);
    2464 
    2465                 /* @note this can fetch 3d render results as well!! */
     2626                SVGAFifoCmdBlitScreenToGMRFB *pCmd;
     2627                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdBlitScreenToGMRFB, sizeof(*pCmd));
     2628
     2629                /* Note! This can fetch 3d render results as well!! */
    24662630                Log(("vmsvgaFIFOLoop: SVGA_CMD_BLIT_SCREEN_TO_GMRFB dest=(%d,%d) src id=%d (%d,%d)(%d,%d)\n", pCmd->destOrigin.x, pCmd->destOrigin.y, pCmd->srcScreenId, pCmd->srcRect.left, pCmd->srcRect.top, pCmd->srcRect.right, pCmd->srcRect.bottom));
    24672631                AssertFailed();
     
    24712635            case SVGA_CMD_ANNOTATION_FILL:
    24722636            {
    2473                 SVGAFifoCmdAnnotationFill *pCmd = (SVGAFifoCmdAnnotationFill *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdAnnotationFill), &size, &pBounceBuffer);
     2637                SVGAFifoCmdAnnotationFill *pCmd;
     2638                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdAnnotationFill, sizeof(*pCmd));
    24742639
    24752640                Log(("vmsvgaFIFOLoop: SVGA_CMD_ANNOTATION_FILL red=%x green=%x blue=%x\n", pCmd->color.s.r, pCmd->color.s.g, pCmd->color.s.b));
     
    24802645            case SVGA_CMD_ANNOTATION_COPY:
    24812646            {
    2482                 SVGAFifoCmdAnnotationCopy *pCmd = (SVGAFifoCmdAnnotationCopy*)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdAnnotationCopy), &size, &pBounceBuffer);
     2647                SVGAFifoCmdAnnotationCopy *pCmd;
     2648                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdAnnotationCopy, sizeof(*pCmd));
    24832649
    24842650                Log(("vmsvgaFIFOLoop: SVGA_CMD_ANNOTATION_COPY\n"));
     
    24892655            default:
    24902656# ifdef VBOX_WITH_VMSVGA3D
    2491                 if (    pFIFO[u32Cmd] >= SVGA_3D_CMD_BASE
    2492                     &&  pFIFO[u32Cmd] < SVGA_3D_CMD_MAX)
     2657                if (    enmCmdId >= SVGA_3D_CMD_BASE
     2658                    &&  enmCmdId < SVGA_3D_CMD_MAX)
    24932659                {
    24942660                    /* All 3d commands start with a common header, which defines the size of the command. */
    2495                     SVGA3dCmdHeader *pHdr = (SVGA3dCmdHeader *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGA3dCmdHeader), &size, &pBounceBuffer);
    2496                     uint32_t cbCmd;
    2497 
    2498                     /* Refetch the command buffer with the variable data; undo size increase (ugly) */
    2499                     cbCmd = sizeof(SVGA3dCmdHeader) + pHdr->size;
    2500                     size  = sizeof(uint32_t);    /* command dword */
    2501                     if (pBounceBuffer)
    2502                         RTMemFree(pBounceBuffer);
    2503                     pHdr = (SVGA3dCmdHeader *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, cbCmd, &size, &pBounceBuffer);
    2504 
    2505                     switch (pFIFO[u32Cmd])
     2661                    SVGA3dCmdHeader *pHdr;
     2662                    VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pHdr, SVGA3dCmdHeader, sizeof(*pHdr));
     2663                    AssertBreak(pHdr->size < VMSVGA_FIFO_SIZE);
     2664                    uint32_t cbCmd = sizeof(SVGA3dCmdHeader) + pHdr->size;
     2665                    VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pHdr, SVGA3dCmdHeader, cbCmd);
     2666
     2667/**
     2668 * Check that the 3D command has at least a_cbMin of payload bytes after the
     2669 * header.  Will break out of the switch if it doesn't.
     2670 */
     2671#  define VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(a_cbMin) \
     2672    AssertMsgBreak((a_cbMin) <= pHdr->size, ("size=%#x a_cbMin=%#zx\n", pHdr->size, (size_t)(a_cbMin)))
     2673                    switch (enmCmdId)
    25062674                    {
    25072675                    case SVGA_3D_CMD_SURFACE_DEFINE:
    25082676                    {
     2677                        uint32_t                cMipLevels;
    25092678                        SVGA3dCmdDefineSurface *pCmd = (SVGA3dCmdDefineSurface *)(pHdr + 1);
    2510                         uint32_t                cMipLevels;
     2679                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    25112680
    25122681                        cMipLevels = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dSize);
     
    25202689                    case SVGA_3D_CMD_SURFACE_DEFINE_V2:
    25212690                    {
     2691                        uint32_t                   cMipLevels;
    25222692                        SVGA3dCmdDefineSurface_v2 *pCmd = (SVGA3dCmdDefineSurface_v2 *)(pHdr + 1);
    2523                         uint32_t                   cMipLevels;
     2693                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    25242694
    25252695                        cMipLevels = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dSize);
     
    25312701                    {
    25322702                        SVGA3dCmdDestroySurface *pCmd = (SVGA3dCmdDestroySurface *)(pHdr + 1);
     2703                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    25332704                        rc = vmsvga3dSurfaceDestroy(pThis, pCmd->sid);
    25342705                        break;
     
    25372708                    case SVGA_3D_CMD_SURFACE_COPY:
    25382709                    {
     2710                        uint32_t              cCopyBoxes;
    25392711                        SVGA3dCmdSurfaceCopy *pCmd = (SVGA3dCmdSurfaceCopy *)(pHdr + 1);
    2540                         uint32_t              cCopyBoxes;
     2712                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    25412713
    25422714                        cCopyBoxes = (pHdr->size - sizeof(pCmd)) / sizeof(SVGA3dCopyBox);
     
    25482720                    {
    25492721                        SVGA3dCmdSurfaceStretchBlt *pCmd = (SVGA3dCmdSurfaceStretchBlt *)(pHdr + 1);
     2722                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    25502723
    25512724                        rc = vmsvga3dSurfaceStretchBlt(pThis, pCmd->dest, pCmd->boxDest, pCmd->src, pCmd->boxSrc, pCmd->mode);
     
    25552728                    case SVGA_3D_CMD_SURFACE_DMA:
    25562729                    {
     2730                        uint32_t             cCopyBoxes;
    25572731                        SVGA3dCmdSurfaceDMA *pCmd = (SVGA3dCmdSurfaceDMA *)(pHdr + 1);
    2558                         uint32_t             cCopyBoxes;
     2732                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    25592733
    25602734                        cCopyBoxes = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dCopyBox);
     
    25672741                    case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN:
    25682742                    {
     2743                        uint32_t                      cRects;
    25692744                        SVGA3dCmdBlitSurfaceToScreen *pCmd = (SVGA3dCmdBlitSurfaceToScreen *)(pHdr + 1);
    2570                         uint32_t                      cRects;
     2745                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    25712746
    25722747                        cRects = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGASignedRect);
     
    25782753                    {
    25792754                        SVGA3dCmdDefineContext *pCmd = (SVGA3dCmdDefineContext *)(pHdr + 1);
     2755                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    25802756
    25812757                        rc = vmsvga3dContextDefine(pThis, pCmd->cid, false /*fOtherProfile*/);
     
    25862762                    {
    25872763                        SVGA3dCmdDestroyContext *pCmd = (SVGA3dCmdDestroyContext *)(pHdr + 1);
     2764                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    25882765
    25892766                        rc = vmsvga3dContextDestroy(pThis, pCmd->cid);
     
    25942771                    {
    25952772                        SVGA3dCmdSetTransform *pCmd = (SVGA3dCmdSetTransform *)(pHdr + 1);
     2773                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    25962774
    25972775                        rc = vmsvga3dSetTransform(pThis, pCmd->cid, pCmd->type, pCmd->matrix);
     
    26022780                    {
    26032781                        SVGA3dCmdSetZRange *pCmd = (SVGA3dCmdSetZRange *)(pHdr + 1);
     2782                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26042783
    26052784                        rc = vmsvga3dSetZRange(pThis, pCmd->cid, pCmd->zRange);
     
    26092788                    case SVGA_3D_CMD_SETRENDERSTATE:
    26102789                    {
     2790                        uint32_t                 cRenderStates;
    26112791                        SVGA3dCmdSetRenderState *pCmd = (SVGA3dCmdSetRenderState *)(pHdr + 1);
    2612                         uint32_t                 cRenderStates;
     2792                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26132793
    26142794                        cRenderStates = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dRenderState);
     
    26202800                    {
    26212801                        SVGA3dCmdSetRenderTarget *pCmd = (SVGA3dCmdSetRenderTarget *)(pHdr + 1);
     2802                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26222803
    26232804                        rc = vmsvga3dSetRenderTarget(pThis, pCmd->cid, pCmd->type, pCmd->target);
     
    26272808                    case SVGA_3D_CMD_SETTEXTURESTATE:
    26282809                    {
     2810                        uint32_t                  cTextureStates;
    26292811                        SVGA3dCmdSetTextureState *pCmd = (SVGA3dCmdSetTextureState *)(pHdr + 1);
    2630                         uint32_t                  cTextureStates;
     2812                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26312813
    26322814                        cTextureStates = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dTextureState);
     
    26382820                    {
    26392821                        SVGA3dCmdSetMaterial *pCmd = (SVGA3dCmdSetMaterial *)(pHdr + 1);
     2822                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26402823
    26412824                        rc = vmsvga3dSetMaterial(pThis, pCmd->cid, pCmd->face, &pCmd->material);
     
    26462829                    {
    26472830                        SVGA3dCmdSetLightData *pCmd = (SVGA3dCmdSetLightData *)(pHdr + 1);
     2831                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26482832
    26492833                        rc = vmsvga3dSetLightData(pThis, pCmd->cid, pCmd->index, &pCmd->data);
     
    26542838                    {
    26552839                        SVGA3dCmdSetLightEnabled *pCmd = (SVGA3dCmdSetLightEnabled *)(pHdr + 1);
     2840                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26562841
    26572842                        rc = vmsvga3dSetLightEnabled(pThis, pCmd->cid, pCmd->index, pCmd->enabled);
     
    26622847                    {
    26632848                        SVGA3dCmdSetViewport *pCmd = (SVGA3dCmdSetViewport *)(pHdr + 1);
     2849                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26642850
    26652851                        rc = vmsvga3dSetViewPort(pThis, pCmd->cid, &pCmd->rect);
     
    26702856                    {
    26712857                        SVGA3dCmdSetClipPlane *pCmd = (SVGA3dCmdSetClipPlane *)(pHdr + 1);
     2858                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26722859
    26732860                        rc = vmsvga3dSetClipPlane(pThis, pCmd->cid, pCmd->index, pCmd->plane);
     
    26782865                    {
    26792866                        SVGA3dCmdClear  *pCmd = (SVGA3dCmdClear *)(pHdr + 1);
     2867                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26802868                        uint32_t         cRects;
    26812869
     
    26882876                    {
    26892877                        SVGA3dCmdPresent *pCmd = (SVGA3dCmdPresent *)(pHdr + 1);
     2878                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    26902879                        uint32_t          cRects;
    26912880
     
    27012890                    {
    27022891                        SVGA3dCmdDefineShader *pCmd = (SVGA3dCmdDefineShader *)(pHdr + 1);
     2892                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    27032893                        uint32_t               cbData;
    27042894
     
    27112901                    {
    27122902                        SVGA3dCmdDestroyShader *pCmd = (SVGA3dCmdDestroyShader *)(pHdr + 1);
     2903                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    27132904
    27142905                        rc = vmsvga3dShaderDestroy(pThis, pCmd->cid, pCmd->shid, pCmd->type);
     
    27192910                    {
    27202911                        SVGA3dCmdSetShader *pCmd = (SVGA3dCmdSetShader *)(pHdr + 1);
     2912                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    27212913
    27222914                        rc = vmsvga3dShaderSet(pThis, pCmd->cid, pCmd->type, pCmd->shid);
     
    27272919                    {
    27282920                        SVGA3dCmdSetShaderConst *pCmd = (SVGA3dCmdSetShaderConst *)(pHdr + 1);
     2921                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    27292922
    27302923                        uint32_t cRegisters = (pHdr->size - sizeof(*pCmd)) / sizeof(pCmd->values) + 1;
     
    27362929                    {
    27372930                        SVGA3dCmdDrawPrimitives *pCmd = (SVGA3dCmdDrawPrimitives *)(pHdr + 1);
     2931                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    27382932                        uint32_t                 cVertexDivisor;
    27392933
     
    27562950                    {
    27572951                        SVGA3dCmdSetScissorRect *pCmd = (SVGA3dCmdSetScissorRect *)(pHdr + 1);
     2952                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    27582953
    27592954                        rc = vmsvga3dSetScissorRect(pThis, pCmd->cid, &pCmd->rect);
     
    27642959                    {
    27652960                        SVGA3dCmdBeginQuery *pCmd = (SVGA3dCmdBeginQuery *)(pHdr + 1);
     2961                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    27662962
    27672963                        rc = vmsvga3dQueryBegin(pThis, pCmd->cid, pCmd->type);
     
    27722968                    {
    27732969                        SVGA3dCmdEndQuery *pCmd = (SVGA3dCmdEndQuery *)(pHdr + 1);
     2970                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    27742971
    27752972                        rc = vmsvga3dQueryEnd(pThis, pCmd->cid, pCmd->type, pCmd->guestResult);
     
    27802977                    {
    27812978                        SVGA3dCmdWaitForQuery *pCmd = (SVGA3dCmdWaitForQuery *)(pHdr + 1);
     2979                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    27822980
    27832981                        rc = vmsvga3dQueryWait(pThis, pCmd->cid, pCmd->type, pCmd->guestResult);
     
    27882986                    {
    27892987                        SVGA3dCmdGenerateMipmaps *pCmd = (SVGA3dCmdGenerateMipmaps *)(pHdr + 1);
     2988                        VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
    27902989
    27912990                        rc = vmsvga3dGenerateMipmaps(pThis, pCmd->sid, pCmd->filter);
     
    28033002                    AssertFailed();
    28043003            }
    2805             if (pBounceBuffer)
    2806                 RTMemFree(pBounceBuffer);
    28073004
    28083005            /* Go to the next slot */
    2809             if (u32Current + size >= pFIFO[SVGA_FIFO_MAX])
    2810                 ASMAtomicWriteU32(&pFIFO[SVGA_FIFO_STOP], pFIFO[SVGA_FIFO_MIN] + u32Current + size - pFIFO[SVGA_FIFO_MAX]);
    2811             else
    2812                 ASMAtomicWriteU32(&pFIFO[SVGA_FIFO_STOP], u32Current + size);
     3006            Assert(cbPayload + sizeof(uint32_t) <= offFifoMax - offFifoMin);
     3007            offCurrentCmd += RT_ALIGN_32(cbPayload + sizeof(uint32_t), sizeof(uint32_t));
     3008            if (offCurrentCmd >= offFifoMax)
     3009            {
     3010                offCurrentCmd -= offFifoMax - offFifoMin;
     3011                Assert(offCurrentCmd >= offFifoMin);
     3012                Assert(offCurrentCmd <  offFifoMax);
     3013            }
     3014            ASMAtomicWriteU32(&pFIFO[SVGA_FIFO_STOP], offCurrentCmd);
    28133015
    28143016            /* FIFO progress might trigger an interrupt. */
     
    28273029            }
    28283030        }
    2829         /* Done? */
    2830         if (pFIFO[SVGA_FIFO_NEXT_CMD] == pFIFO[SVGA_FIFO_STOP])
    2831         {
    2832             Log(("vmsvgaFIFOLoop: emptied the FIFO next=%x stop=%x\n", pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP]));
     3031
     3032        /* If really done, clear the busy flag. */
     3033        if (fDone)
     3034        {
     3035            Log(("vmsvgaFIFOLoop: emptied the FIFO next=%x stop=%x\n", pFIFO[SVGA_FIFO_NEXT_CMD], offCurrentCmd));
    28333036            pThis->svga.fBusy = false;
    2834             pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
    2835         }
    2836     }
     3037            if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_BUSY, offFifoMin))
     3038                pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
     3039        }
     3040    }
     3041
     3042    /*
     3043     * Free the bounce buffer. (There are no returns above!)
     3044     */
     3045    RTMemFree(pbBounceBuf);
     3046
    28373047    return VINF_SUCCESS;
    28383048}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette