VirtualBox

Changeset 88096 in vbox


Ignore:
Timestamp:
Mar 11, 2021 8:00:49 PM (4 years ago)
Author:
vboxsync
Message:

DevHDA: Separate DMA transfer function for output (hdaR3StreamDoDmaOutput) so I can reduce it without thinking about recording/input streams. bugref:9890

Location:
trunk/src/VBox/Devices/Audio
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/HDAStream.cpp

    r88094 r88096  
    12961296         * make sure that we process them first as a whole. */
    12971297        if (pStreamShared->State.cfPosAdjustLeft)
    1298             cbChunk = RT_MIN(cbChunk, uint32_t(pStreamShared->State.cfPosAdjustLeft * pStreamR3->State.Mapping.cbFrameSize));
     1298            cbChunk = RT_MIN(cbChunk, (uint32_t)pStreamShared->State.cfPosAdjustLeft * pStreamR3->State.Mapping.cbFrameSize);
    12991299
    13001300        if (!cbChunk)
     
    16861686    return VINF_SUCCESS;
    16871687}
     1688
     1689
     1690/**
     1691 * Does DMA transfer for an HDA output stream.
     1692 *
     1693 * This transfers one DMA timer period worth of data from the guest and into the
     1694 * internal DMA buffer.
     1695 *
     1696 * @returns IPRT status code.
     1697 * @param   pDevIns             The device instance.
     1698 * @param   pThis               The shared HDA device state.
     1699 * @param   pThisCC             The ring-3 HDA device state.
     1700 * @param   pStreamShared       HDA stream to update (shared).
     1701 * @param   pStreamR3           HDA stream to update (ring-3).
     1702 * @param   cbToProcessMax      How much data (in bytes) to process as maximum.
     1703 *                              Caller should already have made sure this is at
     1704 *                              least one
     1705 * @remarks Caller owns the stream lock.
     1706 */
     1707static int hdaR3StreamDoDmaOutput(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, PHDASTREAM pStreamShared,
     1708                                  PHDASTREAMR3 pStreamR3, uint32_t cbToProcessMax, uint64_t tsNowNs)
     1709{
     1710    PHDASTREAMPERIOD const  pPeriod = &pStreamShared->State.Period;
     1711    uint8_t const           uSD     = pStreamShared->u8SD;
     1712    LogFlowFunc(("ENTER - #%u cbToProcessMax=%#x\n", uSD, cbToProcessMax));
     1713
     1714
     1715    /*
     1716     * Check if we should skip town...
     1717     */
     1718
     1719    /* Stream not running (anymore)? */
     1720    if (pStreamShared->State.fRunning)
     1721    { /* likely */ }
     1722    else
     1723    {
     1724        Log3Func(("[SD%RU8] Not running, skipping transfer\n", uSD));
     1725        return VINF_SUCCESS;
     1726    }
     1727
     1728    if (!(HDA_STREAM_REG(pThis, STS, uSD) & HDA_SDSTS_BCIS))
     1729    { /* likely */ }
     1730    else
     1731    {
     1732        Log3Func(("[SD%RU8] BCIS bit set, skipping transfer\n", uSD));
     1733#ifdef HDA_STRICT
     1734        /* Timing emulation bug or guest is misbehaving -- let me know. */
     1735        AssertMsgFailed(("BCIS bit for stream #%RU8 still set when it shouldn't\n", uSD));
     1736#endif
     1737        return VINF_SUCCESS;
     1738    }
     1739
     1740    /*
     1741     * Stream sanity checks.
     1742     */
     1743    /* Register sanity checks. */
     1744    Assert(uSD < HDA_MAX_STREAMS);
     1745    Assert(pStreamShared->u64BDLBase);
     1746    Assert(pStreamShared->u32CBL);
     1747    Assert(pStreamShared->u8FIFOS);
     1748
     1749    /* State sanity checks. */
     1750    Assert(ASMAtomicReadBool(&pStreamShared->State.fInReset) == false);
     1751    Assert(ASMAtomicReadBool(&pStreamShared->State.fRunning));
     1752
     1753    /* Transfer sanity checks. */
     1754    Assert(pStreamShared->State.cbTransferSize);
     1755    Assert(pStreamShared->State.cbTransferChunk <= pStreamShared->State.cbTransferSize);
     1756
     1757    /*
     1758     * Some timestamp stuff for logging/debugging.
     1759     */
     1760    /*const uint64_t tsNowNs = RTTimeNanoTS();*/
     1761    Log3Func(("[SD%RU8] tsDeltaNs=%'RU64 ns\n", uSD, tsNowNs - pStreamShared->State.tsLastTransferNs));
     1762    pStreamShared->State.tsLastTransferNs = tsNowNs;
     1763    pStreamShared->State.tsTransferLast   = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer);
     1764
     1765    /*
     1766     * Fetch the next BDL entry.
     1767     */
     1768    int      rc    = VINF_SUCCESS;
     1769    PHDABDLE pBDLE = &pStreamShared->State.BDLE;
     1770    if (hdaR3BDLEIsComplete(pBDLE))
     1771    {
     1772        rc = hdaR3BDLEFetch(pDevIns, pBDLE, pStreamShared->u64BDLBase, pStreamShared->State.uCurBDLE);
     1773        AssertRCReturn(rc, rc);
     1774    }
     1775
     1776    /*
     1777     * The caller should have made sure we've got at least cbTransferSize
     1778     * of buffer available.   We will not transfer more than that.
     1779     */
     1780    Assert(pStreamShared->State.cbTransferChunk == pStreamShared->State.cbTransferSize);
     1781    Assert(cbToProcessMax >= pStreamShared->State.cbTransferSize);
     1782    if (cbToProcessMax > pStreamShared->State.cbTransferSize)
     1783        cbToProcessMax = pStreamShared->State.cbTransferSize;
     1784    uint32_t cbLeft = cbToProcessMax;
     1785
     1786    /*
     1787     * Whether an interrupt has been sent (asserted) for this transfer period already or not.
     1788     *
     1789     * Note: Windows 10 relies on this, e.g. sending more than one interrupt per transfer period
     1790     *       confuses the Windows' audio driver and will screw up the audio data. So only send
     1791     *       one interrupt per transfer period.
     1792     *
     1793     * Note! This only applies if the transfer heuristics isn't active.
     1794     */
     1795    /** @todo r=bird: Of course the guest gets confused if you bundle interrupts.
     1796     *        Unless the buffers are really small, this is stuff that won't happen
     1797     *        on real hardware.  */
     1798    /** @todo Disallow non-heuristics approach!  It only complicates the code. */
     1799    bool fInterruptSent = false;
     1800
     1801    /* Set the FIFORDY bit on the stream while doing the transfer. */
     1802    /** @todo r=bird: I don't get the HDA_SDSTS_FIFORDY logic.  Unless we're
     1803     *        assuming SMP guest and that it can get stream registers while we're
     1804     *        here.  Only it cannot do the later because we're sitting on the big
     1805     *        HDA device lock, see assertions in hdaR3Timer().  So, this is an
     1806     *        pointless guesture given that we clear it again after the loop. */
     1807    HDA_STREAM_REG(pThis, STS, uSD) |= HDA_SDSTS_FIFORDY;
     1808
     1809    while (cbLeft)
     1810    {
     1811        /* Limit the chunk to the stream's FIFO size and what's left to process. */
     1812        uint32_t cbChunk = RT_MIN(cbLeft, pStreamShared->u8FIFOS);
     1813
     1814        /* Limit the chunk to the remaining data of the current BDLE. */
     1815        cbChunk = RT_MIN(cbChunk, pBDLE->Desc.u32BufSize - pBDLE->State.u32BufOff);
     1816
     1817        /* If there are position adjustment frames left to be processed,
     1818         * make sure that we process them first as a whole. */
     1819        if (pStreamShared->State.cfPosAdjustLeft)
     1820            cbChunk = RT_MIN(cbChunk, (uint32_t)pStreamShared->State.cfPosAdjustLeft * pStreamR3->State.Mapping.cbFrameSize);
     1821
     1822        /** @todo wtf is this for? Move on to the next BDLE! */
     1823        if (!cbChunk)
     1824            break;
     1825
     1826        uint32_t   cbDMA    = 0;
     1827        PRTCIRCBUF pCircBuf = pStreamR3->State.pCircBuf;
     1828        uint8_t   *pabFIFO  = pStreamShared->abFIFO;
     1829
     1830        STAM_PROFILE_START(&pThis->StatOut, a);
     1831
     1832        rc = hdaR3DMARead(pDevIns, pThis, pStreamShared, pStreamR3, pabFIFO, cbChunk, &cbDMA /* pcbRead */);
     1833        if (RT_SUCCESS(rc))
     1834        {
     1835            /** @todo wtf? Caller passed us the RTCircBufFree value via cbToProcessMax.   */
     1836            const uint32_t cbFree = (uint32_t)RTCircBufFree(pCircBuf);
     1837
     1838            /*
     1839             * Most guests don't use different stream frame sizes than
     1840             * the default one, so save a bit of CPU time and don't go into
     1841             * the frame extraction code below.
     1842             *
     1843             * Only macOS guests need the frame extraction branch below at the moment AFAIK.
     1844             */
     1845            if (pStreamR3->State.Mapping.cbFrameSize == HDA_FRAME_SIZE_DEFAULT)
     1846            {
     1847                uint32_t cbDMARead = 0;
     1848                uint32_t cbDMALeft = RT_MIN(cbDMA, cbFree);
     1849
     1850                while (cbDMALeft)
     1851                {
     1852                    void *pvBuf; size_t cbBuf;
     1853                    RTCircBufAcquireWriteBlock(pCircBuf, cbDMALeft, &pvBuf, &cbBuf);
     1854
     1855                    if (cbBuf)
     1856                    {
     1857                        memcpy(pvBuf, pabFIFO + cbDMARead, cbBuf);
     1858                        cbDMARead += (uint32_t)cbBuf;
     1859                        cbDMALeft -= (uint32_t)cbBuf;
     1860#ifdef VBOX_WITH_DTRACE
     1861                        VBOXDD_HDA_STREAM_DMA_OUT((uint32_t)uSD, (uint32_t)cbBuf, pStreamR3->State.offWrite);
     1862#endif
     1863                        pStreamR3->State.offWrite += cbBuf;
     1864                    }
     1865
     1866                    RTCircBufReleaseWriteBlock(pCircBuf, cbBuf);
     1867                }
     1868            }
     1869            else
     1870            {
     1871                /*
     1872                 * The following code extracts the required audio stream (channel) data
     1873                 * of non-interleaved *and* interleaved audio streams.
     1874                 *
     1875                 * We by default only support 2 channels with 16-bit samples (HDA_FRAME_SIZE),
     1876                 * but an HDA audio stream can have interleaved audio data of multiple audio
     1877                 * channels in such a single stream ("AA,AA,AA vs. AA,BB,AA,BB").
     1878                 *
     1879                 * So take this into account by just handling the first channel in such a stream ("A")
     1880                 * and just discard the other channel's data.
     1881                 *
     1882                 * I know, the following code is horribly slow, but seems to work for now.
     1883                 */
     1884                /** @todo Optimize channel data extraction! Use some SSE(3) / intrinsics? */
     1885                for (unsigned m = 0; m < pStreamR3->State.Mapping.cMappings; m++)
     1886                {
     1887                    const uint32_t cbFrame  = pStreamR3->State.Mapping.cbFrameSize;
     1888
     1889                    Assert(cbFree >= cbDMA);
     1890
     1891                    PPDMAUDIOSTREAMMAP pMap = &pStreamR3->State.Mapping.paMappings[m];
     1892                    AssertPtr(pMap);
     1893
     1894                    Log3Func(("Mapping #%u: Start (cbDMA=%RU32, cbFrame=%RU32, offNext=%RU32)\n",
     1895                              m, cbDMA, cbFrame, pMap->offNext));
     1896
     1897
     1898                    /* Skip the current DMA chunk if the chunk is smaller than what the current stream mapping needs to read
     1899                     * the next associated frame (pointed to at pMap->cbOff).
     1900                     *
     1901                     * This can happen if the guest did not come up with enough data within a certain time period, especially
     1902                     * when using multi-channel speaker (> 2 channels [stereo]) setups. */
     1903                    if (pMap->offNext > cbChunk)
     1904                    {
     1905                        Log2Func(("Mapping #%u: Skipped (cbChunk=%RU32, cbMapOff=%RU32)\n", m, cbChunk, pMap->offNext));
     1906                        continue;
     1907                    }
     1908
     1909                    uint8_t *pbSrcBuf = pabFIFO;
     1910                    size_t cbSrcOff   = pMap->offNext;
     1911
     1912                    for (unsigned i = 0; i < cbDMA / cbFrame; i++)
     1913                    {
     1914                        void *pvDstBuf; size_t cbDstBuf;
     1915                        RTCircBufAcquireWriteBlock(pCircBuf, pMap->cbStep, &pvDstBuf, &cbDstBuf);
     1916
     1917                        Assert(cbDstBuf >= pMap->cbStep);
     1918
     1919                        if (cbDstBuf)
     1920                        {
     1921                            Log3Func(("Mapping #%u: Frame #%02u:    cbStep=%u, offFirst=%u, offNext=%u, cbDstBuf=%u, cbSrcOff=%u\n",
     1922                                      m, i, pMap->cbStep, pMap->offFirst, pMap->offNext, cbDstBuf, cbSrcOff));
     1923
     1924                            memcpy(pvDstBuf, pbSrcBuf + cbSrcOff, cbDstBuf);
     1925
     1926#if 0 /* Too slow, even for release builds, so disabled it. */
     1927                            if (pStreamR3->Dbg.Runtime.fEnabled)
     1928                                DrvAudioHlpFileWrite(pStreamR3->Dbg.Runtime.pFileDMAMapped, pvDstBuf, cbDstBuf,
     1929                                                     0 /* fFlags */);
     1930#endif
     1931                            Assert(cbSrcOff <= cbDMA);
     1932                            if (cbSrcOff + cbFrame + pMap->offFirst<= cbDMA)
     1933                                cbSrcOff += cbFrame + pMap->offFirst;
     1934
     1935#ifdef VBOX_WITH_DTRACE
     1936                            VBOXDD_HDA_STREAM_DMA_OUT((uint32_t)uSD, (uint32_t)cbDstBuf, pStreamR3->State.offWrite);
     1937#endif
     1938                            Log3Func(("Mapping #%u: Frame #%02u:    -> cbSrcOff=%zu\n", m, i, cbSrcOff));
     1939                            pStreamR3->State.offWrite += cbDstBuf;
     1940                        }
     1941
     1942                        RTCircBufReleaseWriteBlock(pCircBuf, cbDstBuf);
     1943                    }
     1944
     1945                    Log3Func(("Mapping #%u: End cbSize=%u, cbDMA=%RU32, cbSrcOff=%zu\n",
     1946                              m, pMap->cbStep, cbDMA, cbSrcOff));
     1947
     1948                    Assert(cbSrcOff <= cbDMA);
     1949
     1950                    const uint32_t cbSrcLeft = cbDMA - (uint32_t)cbSrcOff;
     1951                    if (cbSrcLeft)
     1952                    {
     1953                        Log3Func(("Mapping #%u: cbSrcLeft=%RU32\n", m, cbSrcLeft));
     1954
     1955                        if (cbSrcLeft >= pMap->cbStep)
     1956                        {
     1957                            void *pvDstBuf; size_t cbDstBuf;
     1958                            RTCircBufAcquireWriteBlock(pCircBuf, pMap->cbStep, &pvDstBuf, &cbDstBuf);
     1959
     1960                            Assert(cbDstBuf >= pMap->cbStep);
     1961
     1962                            if (cbDstBuf)
     1963                            {
     1964                                memcpy(pvDstBuf, pbSrcBuf + cbSrcOff, cbDstBuf);
     1965#ifdef VBOX_WITH_DTRACE
     1966                                VBOXDD_HDA_STREAM_DMA_OUT((uint32_t)uSD, (uint32_t)cbDstBuf, pStreamR3->State.offWrite);
     1967#endif
     1968                                pStreamR3->State.offWrite += cbDstBuf;
     1969                            }
     1970
     1971                            RTCircBufReleaseWriteBlock(pCircBuf, cbDstBuf);
     1972                        }
     1973
     1974                        Assert(pMap->cbFrame >= cbSrcLeft);
     1975                        pMap->offNext = pMap->cbFrame - cbSrcLeft;
     1976                    }
     1977                    else
     1978                        pMap->offNext = 0;
     1979
     1980                    Log3Func(("Mapping #%u finish (cbSrcOff=%zu, offNext=%zu)\n", m, cbSrcOff, pMap->offNext));
     1981                }
     1982            }
     1983        }
     1984        else
     1985            LogRel(("HDA: Reading from stream #%RU8 DMA failed with %Rrc\n", uSD, rc));
     1986
     1987        STAM_PROFILE_STOP(&pThis->StatOut, a);
     1988
     1989        if (cbDMA)
     1990        {
     1991            /* We always increment the position of DMA buffer counter because we're always reading
     1992             * into an intermediate DMA buffer. */
     1993            pBDLE->State.u32BufOff += (uint32_t)cbDMA;
     1994            Assert(pBDLE->State.u32BufOff <= pBDLE->Desc.u32BufSize);
     1995
     1996            /* Are we done doing the position adjustment?
     1997             * Only then do the transfer accounting .*/
     1998            if (pStreamShared->State.cfPosAdjustLeft == 0)
     1999            {
     2000                Assert(cbLeft >= cbDMA);
     2001                cbLeft        -= cbDMA;
     2002            }
     2003
     2004            Log3Func(("[SD%RU8] cbDMA=%RU32 -> %R[bdle]\n", uSD, cbDMA, pBDLE));
     2005        }
     2006
     2007        /*
     2008         * Is the buffer descriptor complete.
     2009         */
     2010        if (hdaR3BDLEIsComplete(pBDLE))
     2011        {
     2012            Log3Func(("[SD%RU8] Completed %R[bdle]\n", uSD, pBDLE));
     2013
     2014            /* Make sure to also update the wall clock when a BDLE is complete.
     2015             * Needed for Windows 10 guests. */
     2016            hdaR3WalClkSet(pThis, pThisCC,
     2017                             hdaWalClkGetCurrent(pThis)
     2018                           + hdaR3StreamPeriodFramesToWalClk(pPeriod,
     2019                                                               pBDLE->Desc.u32BufSize
     2020                                                             / pStreamR3->State.Mapping.cbFrameSize),
     2021                           false /* fForce */);
     2022
     2023            /*
     2024             * Update the stream's current position.
     2025             *
     2026             * Do this as accurate and close to the actual data transfer as possible.
     2027             * All guetsts rely on this, depending on the mechanism they use (LPIB register or DMA counters).
     2028             *
     2029             * Note for Windows 10: The OS' driver is *very* picky about *when* the (DMA) positions get updated!
     2030             *                      Not doing this at the right time will result in ugly sound crackles!
     2031             */
     2032            hdaR3StreamSetPositionAdd(pStreamShared, pDevIns, pThis, pBDLE->Desc.u32BufSize);
     2033
     2034            /* Does the current BDLE require an interrupt to be sent? */
     2035            if (   hdaR3BDLENeedsInterrupt(pBDLE)
     2036                /* Are we done doing the position adjustment?
     2037                 * It can happen that a BDLE which is handled while doing the
     2038                 * position adjustment requires an interrupt on completion (IOC) being set.
     2039                 *
     2040                 * In such a case we need to skip such an interrupt and just move on. */
     2041                && pStreamShared->State.cfPosAdjustLeft == 0)
     2042            {
     2043                /* If the IOCE ("Interrupt On Completion Enable") bit of the SDCTL register is set
     2044                 * we need to generate an interrupt.
     2045                 */
     2046                if (HDA_STREAM_REG(pThis, CTL, uSD) & HDA_SDCTL_IOCE)
     2047                {
     2048                    /* Assert the interrupt before actually fetching the next BDLE below. */
     2049                    if (!fInterruptSent)
     2050                    {
     2051#if 1
     2052                        pStreamShared->State.cTransferPendingInterrupts = 1;
     2053                        Log3Func(("[SD%RU8] Scheduling interrupt\n", uSD));
     2054#else
     2055                        /* ??*/
     2056                        AssertMsg(pStreamShared->State.cTransferPendingInterrupts <= 32, ("Too many pending interrupts (%RU8) for stream #%RU8\n", pStreamShared->State.cTransferPendingInterrupts, uSD));
     2057                        Log3Func(("[SD%RU8] Scheduling interrupt (now %RU8 total)\n", uSD, pStreamShared->State.cTransferPendingInterrupts));
     2058#endif
     2059
     2060                        /*
     2061                         * Set the stream's BCIS bit.
     2062                         *
     2063                         * Note: This only must be done if the whole period is complete, and not if only
     2064                         * one specific BDL entry is complete (if it has the IOC bit set).
     2065                         *
     2066                         * This will otherwise confuses the guest when it 1) deasserts the interrupt,
     2067                         * 2) reads SDSTS (with BCIS set) and then 3) too early reads a (wrong) WALCLK value.
     2068                         *
     2069                         * snd_hda_intel on Linux will tell.
     2070                         */
     2071                        /** @todo r=bird: The above comment does not match what we're doing.  This is
     2072                         *        just a flag indicating that the IOC is why the driver got an IRQ. */
     2073                        HDA_STREAM_REG(pThis, STS, uSD) |= HDA_SDSTS_BCIS;
     2074
     2075                        /* Trigger an interrupt first and let hdaRegWriteSDSTS() deal with
     2076                         * ending / beginning a period. */
     2077                        HDA_PROCESS_INTERRUPT(pDevIns, pThis);
     2078
     2079                        fInterruptSent = true;
     2080                    }
     2081                }
     2082            }
     2083
     2084            /*
     2085             * Advance.
     2086             */
     2087            if (pStreamShared->State.uCurBDLE >= pStreamShared->u16LVI)
     2088                pStreamShared->State.uCurBDLE = 0;
     2089            else
     2090                pStreamShared->State.uCurBDLE++;
     2091
     2092            /* Fetch the next BDLE entry. */
     2093            hdaR3BDLEFetch(pDevIns, pBDLE, pStreamShared->u64BDLBase, pStreamShared->State.uCurBDLE);
     2094        }
     2095
     2096        /* Do the position adjustment accounting. */
     2097        pStreamShared->State.cfPosAdjustLeft -= RT_MIN(pStreamShared->State.cfPosAdjustLeft, cbDMA / pStreamR3->State.Mapping.cbFrameSize);
     2098
     2099        if (RT_FAILURE(rc))
     2100            break;
     2101    }
     2102
     2103    /* Remove the FIFORDY bit again. */
     2104    HDA_STREAM_REG(pThis, STS, uSD) &= ~HDA_SDSTS_FIFORDY;
     2105
     2106    /* Sanity. */
     2107    Assert(cbLeft == 0);
     2108    uint32_t const cbProcessed = cbToProcessMax - cbLeft;
     2109
     2110    /* Only do the data accounting if we don't have to do any position
     2111     * adjustment anymore. */
     2112    if (pStreamShared->State.cfPosAdjustLeft == 0)
     2113    {
     2114        hdaR3StreamPeriodInc(pPeriod, RT_MIN(cbProcessed / pStreamR3->State.Mapping.cbFrameSize,
     2115                                             hdaR3StreamPeriodGetRemainingFrames(pPeriod)));
     2116    }
     2117
     2118    const bool fTransferComplete = cbLeft == 0;
     2119    if (fTransferComplete)
     2120    {
     2121        /*
     2122         * Try updating the wall clock.
     2123         *
     2124         * Note 1) Only certain guests (like Linux' snd_hda_intel) rely on the WALCLK register
     2125         *         in order to determine the correct timing of the sound device. Other guests
     2126         *         like Windows 7 + 10 (or even more exotic ones like Haiku) will completely
     2127         *         ignore this.
     2128         *
     2129         * Note 2) When updating the WALCLK register too often / early (or even in a non-monotonic
     2130         *         fashion) this *will* upset guest device drivers and will completely fuck up the
     2131         *         sound output. Running VLC on the guest will tell!
     2132         */
     2133        const bool fWalClkSet = hdaR3WalClkSet(pThis, pThisCC,
     2134                                               RT_MIN(  hdaWalClkGetCurrent(pThis)
     2135                                                      + hdaR3StreamPeriodFramesToWalClk(pPeriod,
     2136                                                                                          cbProcessed
     2137                                                                                        / pStreamR3->State.Mapping.cbFrameSize),
     2138                                                      hdaR3WalClkGetMax(pThis, pThisCC)),
     2139                                               false /* fForce */);
     2140        RT_NOREF(fWalClkSet);
     2141    }
     2142
     2143    Log3Func(("[SD%RU8] %R[bdle] -- %#RX32/%#RX32 @ %#RX64 - fTransferComplete=%d (%d) cTransferPendingInterrupts=%RU8\n",
     2144              uSD, pBDLE, cbProcessed, pStreamShared->State.cbTransferSize, pStreamR3->State.offWrite - cbProcessed,
     2145              fTransferComplete, cbLeft, pStreamShared->State.cTransferPendingInterrupts));
     2146
     2147    LogFlowFuncLeave();
     2148    return VINF_SUCCESS;
     2149}
     2150
    16882151
    16892152/**
     
    18592322             * Do the DMA transfer.
    18602323             */
     2324# ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
     2325            rc2 = PDMDevHlpCritSectEnter(pDevIns, &pStreamShared->CritSect, VERR_IGNORED);
     2326            AssertRC(rc2);
     2327# endif
     2328
    18612329            uint64_t const offWriteBefore = pStreamR3->State.offWrite;
    1862             rc2 = hdaR3StreamTransfer(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, cbStreamFree);
     2330            rc2 = hdaR3StreamDoDmaOutput(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, cbStreamFree, tsNowNs);
    18632331            AssertRC(rc2);
     2332
     2333# ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
     2334            rc2 = PDMDevHlpCritSectLeave(pDevIns, &pStreamShared->CritSect);
     2335            AssertRC(rc2);
     2336# endif
    18642337
    18652338            /*
  • trunk/src/VBox/Devices/Audio/HDAStreamPeriod.cpp

    r88028 r88096  
    221221 *
    222222 * @return  Calculated wall clock value.
    223  * @param   pPeriod             Stream period to calculate wall clock value for.
    224  * @param   uFrames             Number of audio frames to calculate wall clock value for.
     223 * @param   pPeriod     Stream period to calculate wall clock value for.
     224 * @param   cFrames     Number of audio frames to calculate wall clock value for.
    225225 *
    226226 * @remark  Calculation depends on the given stream period and assumes a 24 MHz wall clock counter (WALCLK).
    227227 */
    228 uint64_t hdaR3StreamPeriodFramesToWalClk(PHDASTREAMPERIOD pPeriod, uint32_t uFrames)
     228uint64_t hdaR3StreamPeriodFramesToWalClk(PHDASTREAMPERIOD pPeriod, uint32_t cFrames)
    229229{
    230230    /* Prevent division by zero. */
     
    232232
    233233    /* 24 MHz wall clock (WALCLK): 42ns resolution. */
    234     return ASMMultU64ByU32DivByU32(uFrames, 24000000, uHz);
     234    return ASMMultU32ByU32DivByU32(cFrames, 24000000, uHz);
    235235}
    236236
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