Changeset 99997 in vbox for trunk/src/VBox/Additions/WINNT/Graphics
- Timestamp:
- May 29, 2023 10:00:48 AM (20 months ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp
r99990 r99997 1754 1754 } 1755 1755 1756 NTSTATUS SvgaGenGMRReport(PVBOXWDDM_EXT_VMSVGA pSvga,1757 uint32_t u32GmrId,1758 SVGARemapGMR2Flags fRemapGMR2Flags,1759 uint32_t u32NumPages,1760 RTHCPHYS *paPhysAddresses,1761 void *pvDst,1762 uint32_t cbDst,1763 uint32_t *pcbOut)1764 {1765 /*1766 * SVGA_CMD_DEFINE_GMR2 + SVGA_CMD_REMAP_GMR2.1767 */1768 1769 AssertReturn(u32NumPages <= pSvga->u32GmrMaxPages, STATUS_INVALID_PARAMETER);1770 1771 NTSTATUS Status = STATUS_SUCCESS;1772 1773 uint32_t const cbCmdDefineGMR2 = sizeof(uint32_t)1774 + sizeof(SVGAFifoCmdDefineGMR2);1775 uint32_t const cbCmdRemapGMR2 = sizeof(uint32_t)1776 + sizeof(SVGAFifoCmdRemapGMR2);1777 uint32_t const cbPPN = (fRemapGMR2Flags & SVGA_REMAP_GMR2_PPN64) ? sizeof(uint64_t) : sizeof(uint32_t);1778 uint32_t const cbPPNArray = u32NumPages * cbPPN;1779 1780 uint32_t const cbCmd = cbCmdDefineGMR2 + cbCmdRemapGMR2 + cbPPNArray;1781 if (pcbOut)1782 *pcbOut = cbCmd;1783 1784 if (cbCmd <= cbDst)1785 {1786 uint8_t *pu8Dst = (uint8_t *)pvDst;1787 1788 SvgaCmdDefineGMR2(pu8Dst, u32GmrId, u32NumPages);1789 pu8Dst += cbCmdDefineGMR2;1790 1791 SvgaCmdRemapGMR2(pu8Dst, u32GmrId, fRemapGMR2Flags, 0, u32NumPages);1792 pu8Dst += cbCmdRemapGMR2;1793 1794 uint32_t iPage;1795 if (fRemapGMR2Flags & SVGA_REMAP_GMR2_PPN64)1796 {1797 uint64_t *paPPN64 = (uint64_t *)pu8Dst;1798 for (iPage = 0; iPage < u32NumPages; ++iPage)1799 {1800 RTHCPHYS const Phys = paPhysAddresses[iPage];1801 paPPN64[iPage] = Phys >> PAGE_SHIFT;1802 }1803 }1804 else1805 {1806 uint32_t *paPPN32 = (uint32_t *)pu8Dst;1807 for (iPage = 0; iPage < u32NumPages; ++iPage)1808 {1809 RTHCPHYS const Phys = paPhysAddresses[iPage];1810 AssertBreakStmt((Phys & UINT32_C(0xFFFFFFFF)) == Phys, Status = STATUS_INVALID_PARAMETER);1811 paPPN32[iPage] = (uint32_t)(Phys >> PAGE_SHIFT);1812 }1813 }1814 }1815 else1816 Status = STATUS_BUFFER_OVERFLOW;1817 1818 return Status;1819 }1820 1821 NTSTATUS SvgaGMRReport(PVBOXWDDM_EXT_VMSVGA pSvga,1822 uint32_t u32GmrId,1823 SVGARemapGMR2Flags fRemapGMR2Flags,1824 uint32_t u32NumPages,1825 RTHCPHYS *paPhysAddresses)1826 {1827 /*1828 * Issue SVGA_CMD_DEFINE_GMR2 + SVGA_CMD_REMAP_GMR2.1829 */1830 1831 NTSTATUS Status;1832 1833 uint32_t cbSubmit = 0;1834 SvgaGenGMRReport(pSvga, u32GmrId, fRemapGMR2Flags, u32NumPages, paPhysAddresses,1835 NULL, 0, &cbSubmit);1836 1837 void *pvCmd = SvgaReserve(pSvga, cbSubmit);1838 if (pvCmd)1839 {1840 Status = SvgaGenGMRReport(pSvga, u32GmrId, fRemapGMR2Flags, u32NumPages, paPhysAddresses,1841 pvCmd, cbSubmit, NULL);1842 AssertStmt(Status == STATUS_SUCCESS, cbSubmit = 0);1843 SvgaCommit(pSvga, cbSubmit);1844 }1845 else1846 {1847 Status = STATUS_INSUFFICIENT_RESOURCES;1848 }1849 1850 return Status;1851 }1852 1756 1853 1757 /* SVGA Guest Memory Region (GMR). Memory known for both host and guest. … … 1858 1762 /* Key is GMR id (equal to u32GmrId). */ 1859 1763 AVLU32NODECORE Core; 1860 /* Devicethe GMR is associated with. */1764 /* Pointer to a graphics context device (PVBOXWDDM_DEVICE) the GMR is associated with. */ 1861 1765 void *pvOwner; 1862 /* The memory object handle. */ 1863 RTR0MEMOBJ MemObj; 1864 /* The ring-3 mapping memory object handle. */ 1766 /* The ring-3 mapping memory object handle (from mob). */ 1865 1767 RTR0MEMOBJ MapObjR3; 1866 RTR0PTR pvR0;1867 1768 RTR3PTR pvR3; 1868 /* A corresponding MOB, which provides the G uest Memory Region ID. */1769 /* A corresponding MOB, which provides the GMR id and RTR0MEMOBJ for the region memory. */ 1869 1770 PVMSVGAMOB pMob; 1870 1771 /* The allocated size in pages. */ … … 1874 1775 } GAWDDMREGION; 1875 1776 1876 /** @todo Deferred destruction. */ 1877 static void svgaFreeGBMobForGMR(VBOXWDDM_EXT_VMSVGA *pSvga, PVMSVGAMOB pMob) 1878 { 1879 if (pMob) 1880 { 1881 if (RT_BOOL(pSvga->u32Caps & SVGA_CAP_DX)) 1882 { 1883 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DESTROY_GB_MOB, sizeof(SVGA3dCmdDestroyGBMob), SVGA3D_INVALID_ID); 1884 if (pvCmd) 1885 { 1886 SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pvCmd; 1887 pCmd->mobid = VMSVGAMOB_ID(pMob); 1888 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDestroyGBMob)); 1889 } 1890 } 1891 1892 SvgaMobFree(pSvga, pMob); 1893 } 1894 } 1895 1896 static NTSTATUS svgaCreateGBMobForGMR(VBOXWDDM_EXT_VMSVGA *pSvga, GAWDDMREGION *pRegion) 1897 { 1898 /* Allocate a new mob. */ 1899 NTSTATUS Status = SvgaMobCreate(pSvga, &pRegion->pMob, pRegion->u32NumPages, 0); 1900 Assert(NT_SUCCESS(Status)); 1901 if (NT_SUCCESS(Status)) 1902 { 1903 Status = SvgaMobSetMemObj(pRegion->pMob, pRegion->MemObj); 1777 1778 /* Allocate memory pages and the corresponding mob. 1779 */ 1780 static NTSTATUS gmrAllocMemory(VBOXWDDM_EXT_VMSVGA *pSvga, GAWDDMREGION *pRegion, uint32_t u32NumPages) 1781 { 1782 NTSTATUS Status; 1783 1784 /* Allocate memory. */ 1785 RTR0MEMOBJ MemObj; 1786 int rc = RTR0MemObjAllocPageTag(&MemObj, u32NumPages << PAGE_SHIFT, 1787 false /* executable R0 mapping */, "VMSVGAGMR"); 1788 AssertRC(rc); 1789 if (RT_SUCCESS(rc)) 1790 { 1791 if (!RTR0MemObjWasZeroInitialized(MemObj)) 1792 RT_BZERO(RTR0MemObjAddress(MemObj), (size_t)u32NumPages << PAGE_SHIFT); 1793 1794 /* Allocate corresponding mob. */ 1795 Status = SvgaMobCreate(pSvga, &pRegion->pMob, u32NumPages, 0); 1904 1796 Assert(NT_SUCCESS(Status)); 1905 1797 if (NT_SUCCESS(Status)) 1906 1798 { 1907 if (RT_BOOL(pSvga->u32Caps & SVGA_CAP_DX)) 1908 { 1909 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DEFINE_GB_MOB64, sizeof(SVGA3dCmdDefineGBMob64), SVGA3D_INVALID_ID); 1910 if (pvCmd) 1911 { 1912 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pvCmd; 1913 pCmd->mobid = VMSVGAMOB_ID(pRegion->pMob); 1914 pCmd->ptDepth = pRegion->pMob->gbo.enmMobFormat; 1915 pCmd->base = pRegion->pMob->gbo.base; 1916 pCmd->sizeInBytes = pRegion->pMob->gbo.cbGbo; 1917 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDefineGBMob64)); 1918 } 1919 else 1920 AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES); 1921 } 1922 1799 Status = SvgaMobSetMemObj(pRegion->pMob, MemObj); 1800 Assert(NT_SUCCESS(Status)); 1923 1801 if (NT_SUCCESS(Status)) 1924 1802 return STATUS_SUCCESS; 1925 1803 } 1926 } 1927 1928 svgaFreeGBMobForGMR(pSvga, pRegion->pMob); 1929 pRegion->pMob = NULL; 1930 return Status; 1931 } 1932 1933 1934 static void gmrFree(GAWDDMREGION *pRegion) 1935 { 1804 1805 if ( pRegion->pMob 1806 && pRegion->pMob->hMemObj == NIL_RTR0MEMOBJ) 1807 { 1808 /* The memory object has not been assigned to the mob yet. Clean up the local object. 1809 * Otherwise the caller will clean up. 1810 */ 1811 int rc2 = RTR0MemObjFree(MemObj, false); 1812 AssertRC(rc2); 1813 } 1814 } 1815 else 1816 AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES); 1817 1818 return Status; 1819 } 1820 1821 /* Initialize the GMR to be ready for reporting to the host. 1822 */ 1823 static NTSTATUS gmrInit(VBOXWDDM_EXT_VMSVGA *pSvga, GAWDDMREGION *pRegion, void *pvOwner, uint32_t u32NumPages) 1824 { 1825 NTSTATUS Status = gmrAllocMemory(pSvga, pRegion, u32NumPages); 1826 if (NT_SUCCESS(Status)) 1827 { 1828 int rc = RTR0MemObjMapUser(&pRegion->MapObjR3, pRegion->pMob->hMemObj, (RTR3PTR)-1, 0, 1829 RTMEM_PROT_WRITE | RTMEM_PROT_READ, NIL_RTR0PROCESS); 1830 AssertRC(rc); 1831 if (RT_SUCCESS(rc)) 1832 { 1833 uint32_t iPage; 1834 for (iPage = 0; iPage < u32NumPages; ++iPage) 1835 pRegion->aPhys[iPage] = RTR0MemObjGetPagePhysAddr(pRegion->pMob->hMemObj, iPage); 1836 1837 pRegion->pvR3 = RTR0MemObjAddressR3(pRegion->MapObjR3); 1838 1839 pRegion->pvOwner = pvOwner; 1840 pRegion->u32NumPages = u32NumPages; 1841 } 1842 else 1843 AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES); 1844 } 1845 1846 return Status; 1847 } 1848 1849 /* Send GMR creation commands to the host. 1850 */ 1851 static NTSTATUS gmrReportToHost(VBOXWDDM_EXT_VMSVGA *pSvga, GAWDDMREGION *pRegion) 1852 { 1853 /* 1854 * Issue SVGA_CMD_DEFINE_GMR2 + SVGA_CMD_REMAP_GMR2 + SVGA_3D_CMD_DEFINE_GB_MOB64. 1855 */ 1856 uint32_t const cbPPNArray = pRegion->u32NumPages * sizeof(uint64_t); 1857 1858 uint32_t cbSubmit = sizeof(uint32_t) + sizeof(SVGAFifoCmdDefineGMR2); 1859 cbSubmit += sizeof(uint32_t) + sizeof(SVGAFifoCmdRemapGMR2) + cbPPNArray; 1860 if (RT_BOOL(pSvga->u32Caps & SVGA_CAP_DX)) 1861 cbSubmit += sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdDefineGBMob64); 1862 1863 void *pvCmd = SvgaReserve(pSvga, cbSubmit); 1864 if (!pvCmd) 1865 return STATUS_INSUFFICIENT_RESOURCES; 1866 1867 uint8_t *pu8Cmd = (uint8_t *)pvCmd; 1868 1869 uint32_t *pu32CmdId; 1870 1871 pu32CmdId = (uint32_t *)pu8Cmd; 1872 *pu32CmdId = SVGA_CMD_DEFINE_GMR2; 1873 pu8Cmd += sizeof(*pu32CmdId); 1874 1875 { 1876 SVGAFifoCmdDefineGMR2 *pCmd = (SVGAFifoCmdDefineGMR2 *)pu8Cmd; 1877 pCmd->gmrId = VMSVGAMOB_ID(pRegion->pMob); 1878 pCmd->numPages = pRegion->u32NumPages; 1879 pu8Cmd += sizeof(*pCmd); 1880 } 1881 1882 pu32CmdId = (uint32_t *)pu8Cmd; 1883 *pu32CmdId = SVGA_CMD_REMAP_GMR2; 1884 pu8Cmd += sizeof(*pu32CmdId); 1885 1886 { 1887 SVGAFifoCmdRemapGMR2 *pCmd = (SVGAFifoCmdRemapGMR2 *)pu8Cmd; 1888 pCmd->gmrId = VMSVGAMOB_ID(pRegion->pMob); 1889 pCmd->flags = SVGA_REMAP_GMR2_PPN64; 1890 pCmd->offsetPages = 0; 1891 pCmd->numPages = pRegion->u32NumPages; 1892 pu8Cmd += sizeof(*pCmd); 1893 } 1894 1895 uint64_t *paPPN64 = (uint64_t *)pu8Cmd; 1896 for (uint32_t iPage = 0; iPage < pRegion->u32NumPages; ++iPage) 1897 { 1898 RTHCPHYS const Phys = pRegion->aPhys[iPage]; 1899 paPPN64[iPage] = Phys >> PAGE_SHIFT; 1900 } 1901 pu8Cmd += cbPPNArray; 1902 1903 if (RT_BOOL(pSvga->u32Caps & SVGA_CAP_DX)) 1904 { 1905 SVGA3dCmdHeader *pHdr; 1906 1907 pHdr = (SVGA3dCmdHeader *)pu8Cmd; 1908 pHdr->id = SVGA_3D_CMD_DEFINE_GB_MOB64; 1909 pHdr->size = sizeof(SVGA3dCmdDefineGBMob64); 1910 pu8Cmd += sizeof(*pHdr); 1911 1912 { 1913 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pu8Cmd; 1914 pCmd->mobid = VMSVGAMOB_ID(pRegion->pMob); 1915 pCmd->ptDepth = pRegion->pMob->gbo.enmMobFormat; 1916 pCmd->base = pRegion->pMob->gbo.base; 1917 pCmd->sizeInBytes = pRegion->pMob->gbo.cbGbo; 1918 pu8Cmd += sizeof(*pCmd); 1919 } 1920 } 1921 1922 Assert((uintptr_t)pu8Cmd - (uintptr_t)pvCmd == cbSubmit); 1923 SvgaCommit(pSvga, (uintptr_t)pu8Cmd - (uintptr_t)pvCmd); 1924 1925 return STATUS_SUCCESS; 1926 } 1927 1928 /* Destroy exising region. 1929 */ 1930 static NTSTATUS gmrDestroy(VBOXWDDM_EXT_VMSVGA *pSvga, GAWDDMREGION *pRegion) 1931 { 1932 AssertReturn(pRegion, STATUS_INVALID_PARAMETER); 1933 1934 /* Mapping must be freed prior to the mob destruction. Otherwise, due to a race condition, 1935 * SvgaMobFree could free the mapping in a system worker thread after DPC, which would not 1936 * work obviously, because the mapping was created for another process. 1937 */ 1936 1938 if (pRegion->MapObjR3 != NIL_RTR0MEMOBJ) 1937 1939 { … … 1940 1942 pRegion->MapObjR3 = NIL_RTR0MEMOBJ; 1941 1943 } 1942 if (pRegion->pMob == NULL) 1943 { 1944 /* The memory will be deleted by SvgaMobFree. */ 1945 if (pRegion->MemObj != NIL_RTR0MEMOBJ) 1946 { 1947 int rc = RTR0MemObjFree(pRegion->MemObj, true /* fFreeMappings */); 1948 AssertRC(rc); 1949 pRegion->MemObj = NIL_RTR0MEMOBJ; 1950 } 1951 } 1952 } 1953 1954 static NTSTATUS gmrAlloc(GAWDDMREGION *pRegion) 1955 { 1956 int rc = RTR0MemObjAllocPageTag(&pRegion->MemObj, pRegion->u32NumPages << PAGE_SHIFT, 1957 false /* executable R0 mapping */, "VMSVGAGMR"); 1958 AssertRC(rc); 1959 if (RT_SUCCESS(rc)) 1960 { 1961 if (!RTR0MemObjWasZeroInitialized(pRegion->MemObj)) 1962 RT_BZERO(RTR0MemObjAddress(pRegion->MemObj), (size_t)pRegion->u32NumPages << PAGE_SHIFT); 1963 1964 rc = RTR0MemObjMapUser(&pRegion->MapObjR3, pRegion->MemObj, (RTR3PTR)-1, 0, 1965 RTMEM_PROT_WRITE | RTMEM_PROT_READ, NIL_RTR0PROCESS); 1966 AssertRC(rc); 1967 if (RT_SUCCESS(rc)) 1968 { 1969 pRegion->pvR0 = RTR0MemObjAddress(pRegion->MemObj); 1970 pRegion->pvR3 = RTR0MemObjAddressR3(pRegion->MapObjR3); 1971 1972 uint32_t iPage; 1973 for (iPage = 0; iPage < pRegion->u32NumPages; ++iPage) 1974 { 1975 pRegion->aPhys[iPage] = RTR0MemObjGetPagePhysAddr(pRegion->MemObj, iPage); 1976 } 1977 1978 return STATUS_SUCCESS; 1979 } 1980 1981 int rc2 = RTR0MemObjFree(pRegion->MemObj, false); 1982 AssertRC(rc2); 1983 } 1984 1985 return STATUS_INSUFFICIENT_RESOURCES; 1986 } 1987 1988 static void gaRegionFree(VBOXWDDM_EXT_VMSVGA *pSvga, GAWDDMREGION *pRegion) 1989 { 1990 Assert(pRegion); 1991 gmrFree(pRegion); 1992 svgaFreeGBMobForGMR(pSvga, pRegion->pMob); 1944 1945 /* Issue commands to delete the gmr. */ 1946 uint32_t cbRequired = 0; 1947 SvgaMobDestroy(pSvga, pRegion->pMob, NULL, 0, &cbRequired); 1948 cbRequired += sizeof(uint32_t) + sizeof(SVGAFifoCmdDefineGMR2); 1949 1950 void *pvCmd = SvgaCmdBufReserve(pSvga, cbRequired, SVGA3D_INVALID_ID); 1951 AssertReturn(pvCmd, STATUS_INSUFFICIENT_RESOURCES); 1952 1953 uint8_t *pu8Cmd = (uint8_t *)pvCmd; 1954 uint32_t *pu32CmdId; 1955 1956 /* Undefine GMR: SVGA_CMD_DEFINE_GMR2 with numPages = 0 */ 1957 pu32CmdId = (uint32_t *)pu8Cmd; 1958 *pu32CmdId = SVGA_CMD_DEFINE_GMR2; 1959 pu8Cmd += sizeof(*pu32CmdId); 1960 1961 SVGAFifoCmdDefineGMR2 *pCmd = (SVGAFifoCmdDefineGMR2 *)pu8Cmd; 1962 pCmd->gmrId = VMSVGAMOB_ID(pRegion->pMob); 1963 pCmd->numPages = 0; 1964 pu8Cmd += sizeof(*pCmd); 1965 1966 uint32_t cbCmd = 0; 1967 NTSTATUS Status = SvgaMobDestroy(pSvga, pRegion->pMob, pu8Cmd, 1968 cbRequired - ((uintptr_t)pu8Cmd - (uintptr_t)pvCmd), 1969 &cbCmd); 1970 AssertReturn(NT_SUCCESS(Status), Status); 1971 pu8Cmd += cbCmd; 1972 1973 Assert(((uintptr_t)pu8Cmd - (uintptr_t)pvCmd) == cbRequired); 1974 SvgaCmdBufCommit(pSvga, ((uintptr_t)pu8Cmd - (uintptr_t)pvCmd)); 1975 1976 /* The mob will be deleted in DPC routine after host reports completion of the above commands. */ 1977 pRegion->pMob = NULL; 1978 1979 #ifdef DEBUG 1980 ASMAtomicDecU32(&pSvga->cAllocatedGmrs); 1981 ASMAtomicSubU32(&pSvga->cAllocatedGmrPages, pRegion->u32NumPages); 1982 #endif 1993 1983 GaMemFree(pRegion); 1984 return STATUS_SUCCESS; 1994 1985 } 1995 1986 … … 2016 2007 } 2017 2008 2009 /* Destroy all regions of a particular owner. 2010 */ 2018 2011 void SvgaRegionsDestroy(VBOXWDDM_EXT_VMSVGA *pSvga, 2019 2012 void *pvOwner) … … 2033 2026 2034 2027 /* Free all found GMRs. */ 2035 uint32_t i; 2036 for (i = 0; i < pCtx->cIds; ++i) 2028 for (uint32_t i = 0; i < pCtx->cIds; i++) 2037 2029 { 2038 2030 ExAcquireFastMutex(&pSvga->SvgaMutex); … … 2046 2038 VMSVGAMOB_ID(pRegion->pMob), pRegion->pvR3, pRegion->aPhys[0])); 2047 2039 2048 g aRegionFree(pSvga, pRegion);2040 gmrDestroy(pSvga, pRegion); 2049 2041 } 2050 2042 } … … 2066 2058 ExReleaseFastMutex(&pSvga->SvgaMutex); 2067 2059 2068 if (pRegion) 2069 { 2070 Assert(VMSVGAMOB_ID(pRegion->pMob) == u32GmrId); 2071 GALOG(("Freed gmrId %d, pv %p, aPhys[0] %RHp\n", 2072 VMSVGAMOB_ID(pRegion->pMob), pRegion->pvR3, pRegion->aPhys[0])); 2073 gaRegionFree(pSvga, pRegion); 2074 return STATUS_SUCCESS; 2075 } 2076 2077 AssertFailed(); 2078 return STATUS_INVALID_PARAMETER; 2060 AssertReturn(pRegion, STATUS_INVALID_PARAMETER); 2061 2062 Assert(VMSVGAMOB_ID(pRegion->pMob) == u32GmrId); 2063 GALOG(("Freed gmrId %d, pv %p, aPhys[0] %RHp\n", 2064 VMSVGAMOB_ID(pRegion->pMob), pRegion->pvR3, pRegion->aPhys[0])); 2065 2066 return gmrDestroy(pSvga, pRegion); 2079 2067 } 2080 2068 … … 2094 2082 ExReleaseFastMutex(&pSvga->SvgaMutex); 2095 2083 2096 if (pRegion) 2097 { 2098 Assert(VMSVGAMOB_ID(pRegion->pMob) == u32GmrId); 2099 GALOG(("Get gmrId %d, UserAddress 0x%p\n", 2100 VMSVGAMOB_ID(pRegion->pMob), pRegion->pvR3)); 2101 *pu64UserAddress = (uintptr_t)pRegion->pvR3; 2102 *pu32Size = pRegion->u32NumPages * PAGE_SIZE; 2103 return STATUS_SUCCESS; 2104 } 2105 2106 AssertFailed(); 2107 return STATUS_INVALID_PARAMETER; 2084 AssertReturn(pRegion, STATUS_INVALID_PARAMETER); 2085 2086 Assert(VMSVGAMOB_ID(pRegion->pMob) == u32GmrId); 2087 GALOG(("Get gmrId %d, UserAddress 0x%p\n", 2088 VMSVGAMOB_ID(pRegion->pMob), pRegion->pvR3)); 2089 *pu64UserAddress = (uintptr_t)pRegion->pvR3; 2090 *pu32Size = pRegion->u32NumPages * PAGE_SIZE; 2091 return STATUS_SUCCESS; 2108 2092 } 2109 2093 … … 2120 2104 NTSTATUS Status; 2121 2105 2122 const uint32_t cbAlloc = RT_UOFFSETOF(GAWDDMREGION, aPhys) + u32NumPages * sizeof(RTHCPHYS);2106 uint32_t const cbAlloc = RT_UOFFSETOF(GAWDDMREGION, aPhys) + u32NumPages * sizeof(RTHCPHYS); 2123 2107 GAWDDMREGION *pRegion = (GAWDDMREGION *)GaMemAllocZero(cbAlloc); 2124 2108 if (pRegion) 2125 2109 { 2126 /* Region id and VGPU10+ mobid are the same. So a mob is allocated along with the gmr. 2127 * The mob provides an id and also reported to the host on VGPU10. 2110 /* Region id and VGPU10+ mobid are the same. So a mob is always allocated for the gmr. 2111 * The mob provides an id and, if SVGA_CAP_DX is available, is reported to the host on VGPU10. 2112 * 2113 * Allocate memory and init pRegion fields. 2128 2114 */ 2129 pRegion->pvOwner = pvOwner; 2130 pRegion->u32NumPages = u32NumPages; 2131 pRegion->MemObj = NIL_RTR0MEMOBJ; 2132 pRegion->MapObjR3 = NIL_RTR0MEMOBJ; 2133 2134 Status = gmrAlloc(pRegion); 2115 Status = gmrInit(pSvga, pRegion, pvOwner, u32NumPages); 2135 2116 Assert(NT_SUCCESS(Status)); 2136 2117 if (NT_SUCCESS(Status)) 2137 2118 { 2138 Status = svgaCreateGBMobForGMR(pSvga, pRegion); 2139 Assert(NT_SUCCESS(Status)); 2140 if (NT_SUCCESS(Status)) 2119 if (VMSVGAMOB_ID(pRegion->pMob) < pSvga->u32GmrMaxIds) 2141 2120 { 2142 if (VMSVGAMOB_ID(pRegion->pMob) < pSvga->u32GmrMaxIds) 2121 GALOG(("Allocated gmrId %d, pv %p, aPhys[0] %RHp\n", 2122 VMSVGAMOB_ID(pRegion->pMob), pRegion->pvR3, pRegion->aPhys[0])); 2123 2124 Status = gmrReportToHost(pSvga, pRegion); 2125 Assert(NT_SUCCESS(Status)); 2126 if (NT_SUCCESS(Status)) 2143 2127 { 2144 GALOG(("Allocated gmrId %d, pv %p, aPhys[0] %RHp\n", 2145 VMSVGAMOB_ID(pRegion->pMob), pRegion->pvR3, pRegion->aPhys[0])); 2146 2147 /* Report the GMR to the host vmsvga device. */ 2148 Status = SvgaGMRReport(pSvga, 2149 VMSVGAMOB_ID(pRegion->pMob), 2150 SVGA_REMAP_GMR2_PPN64, 2151 pRegion->u32NumPages, 2152 &pRegion->aPhys[0]); 2153 Assert(NT_SUCCESS(Status)); 2154 if (NT_SUCCESS(Status)) 2155 { 2156 /* Add to the container. */ 2157 ExAcquireFastMutex(&pSvga->SvgaMutex); 2158 2159 pRegion->Core.Key = VMSVGAMOB_ID(pRegion->pMob); 2160 RTAvlU32Insert(&pSvga->GMRTree, &pRegion->Core); 2161 2162 ExReleaseFastMutex(&pSvga->SvgaMutex); 2163 2164 *pu32GmrId = VMSVGAMOB_ID(pRegion->pMob); 2165 *pu64UserAddress = (uint64_t)pRegion->pvR3; 2166 2167 /* Everything OK. */ 2168 return STATUS_SUCCESS; 2169 } 2128 pRegion->Core.Key = VMSVGAMOB_ID(pRegion->pMob); 2129 2130 ExAcquireFastMutex(&pSvga->SvgaMutex); 2131 RTAvlU32Insert(&pSvga->GMRTree, &pRegion->Core); 2132 ExReleaseFastMutex(&pSvga->SvgaMutex); 2133 2134 *pu32GmrId = VMSVGAMOB_ID(pRegion->pMob); 2135 *pu64UserAddress = (uint64_t)pRegion->pvR3; 2136 2137 #ifdef DEBUG 2138 ASMAtomicIncU32(&pSvga->cAllocatedGmrs); 2139 ASMAtomicAddU32(&pSvga->cAllocatedGmrPages, pRegion->u32NumPages); 2140 #endif 2141 /* Everything OK. */ 2142 return STATUS_SUCCESS; 2170 2143 } 2171 else2172 {2173 AssertFailed();2174 Status = STATUS_INSUFFICIENT_RESOURCES;2175 }2176 2177 svgaFreeGBMobForGMR(pSvga, pRegion->pMob);2178 2144 } 2179 2180 gmrFree(pRegion); 2181 } 2145 else 2146 AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES); 2147 } 2148 2149 /* Clean up on failure. */ 2150 if (pRegion->MapObjR3 != NIL_RTR0MEMOBJ) 2151 { 2152 int rc = RTR0MemObjFree(pRegion->MapObjR3, false); 2153 AssertRC(rc); 2154 pRegion->MapObjR3 = NIL_RTR0MEMOBJ; 2155 } 2156 2157 SvgaMobFree(pSvga, pRegion->pMob); 2158 pRegion->pMob = NULL; 2182 2159 2183 2160 GaMemFree(pRegion); 2184 2161 } 2185 2162 else 2186 { 2187 AssertFailed(); 2188 Status = STATUS_INSUFFICIENT_RESOURCES; 2189 } 2163 AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES); 2190 2164 2191 2165 return Status; … … 2417 2391 KeReleaseSpinLock(&pSvga->MobSpinLock, OldIrql); 2418 2392 2393 #ifdef DEBUG 2394 ASMAtomicSubU32(&pSvga->cAllocatedMobPages, pMob->gbo.cbGbo / PAGE_SIZE); 2395 ASMAtomicDecU32(&pSvga->cAllocatedMobs); 2396 #endif 2397 2419 2398 SvgaGboFree(&pMob->gbo); 2420 2399 … … 2458 2437 pMob->hAllocation = hAllocation; 2459 2438 *ppMob = pMob; 2439 2440 #ifdef DEBUG 2441 ASMAtomicIncU32(&pSvga->cAllocatedMobs); 2442 ASMAtomicAddU32(&pSvga->cAllocatedMobPages, cMobPages); 2443 #endif 2444 2460 2445 return STATUS_SUCCESS; 2461 2446 } -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h
r99990 r99997 266 266 RTLISTANCHOR listMobDeferredDestruction; /* Mob to be deleted after. */ 267 267 268 #ifdef DEBUG 269 /* Statistics. */ 270 uint32_t volatile cAllocatedMobs; 271 uint32_t volatile cAllocatedMobPages; 272 uint32_t volatile cAllocatedGmrs; 273 uint32_t volatile cAllocatedGmrPages; 274 #endif 275 268 276 /** Bitmap of used GMR ids. Bit 0 - GMR id 0, etc. */ 269 277 uint32_t *pu32GMRBits; /* Number of GMRs is controlled by the host (u32GmrMaxIds), so allocate the bitmap. */ … … 564 572 bool fForce); 565 573 566 NTSTATUS SvgaGenGMRReport(PVBOXWDDM_EXT_VMSVGA pSvga,567 uint32_t u32GmrId,568 SVGARemapGMR2Flags fRemapGMR2Flags,569 uint32_t u32NumPages,570 RTHCPHYS *paPhysAddresses,571 void *pvDst,572 uint32_t cbDst,573 uint32_t *pcbOut);574 NTSTATUS SvgaGMRReport(PVBOXWDDM_EXT_VMSVGA pSvga,575 uint32_t u32GmrId,576 SVGARemapGMR2Flags fRemapGMR2Flags,577 uint32_t u32NumPages,578 RTHCPHYS *paPhysAddresses);579 580 574 NTSTATUS SvgaRegionCreate(VBOXWDDM_EXT_VMSVGA *pSvga, 581 575 void *pvOwner, -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaCmd.cpp
r98103 r99997 212 212 } 213 213 214 void SvgaCmdDefineGMR2(void *pvCmd, uint32_t u32GmrId, uint32_t cPages)215 {216 uint32_t *pu32Id = (uint32_t *)pvCmd;217 SVGAFifoCmdDefineGMR2 *pCommand = (SVGAFifoCmdDefineGMR2 *)&pu32Id[1];218 219 *pu32Id = SVGA_CMD_DEFINE_GMR2;220 221 pCommand->gmrId = u32GmrId;222 pCommand->numPages = cPages;223 }224 225 void SvgaCmdRemapGMR2(void *pvCmd, uint32_t u32GmrId, SVGARemapGMR2Flags flags, uint32 offsetPages, uint32_t numPages)226 {227 uint32_t *pu32Id = (uint32_t *)pvCmd;228 SVGAFifoCmdRemapGMR2 *pCommand = (SVGAFifoCmdRemapGMR2 *)&pu32Id[1];229 230 *pu32Id = SVGA_CMD_REMAP_GMR2;231 232 pCommand->gmrId = u32GmrId;233 pCommand->flags = flags;234 pCommand->offsetPages = offsetPages;235 pCommand->numPages = numPages;236 }237 238 214 void Svga3dCmdSurfaceDMAToFB(void *pvCmd, uint32_t u32Sid, uint32_t u32Width, uint32_t u32Height, uint32_t u32Offset) 239 215 { -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaCmd.h
r98103 r99997 50 50 void Svga3dCmdDestroyContext(void *pvCmd, uint32_t u32Cid); 51 51 52 void SvgaCmdDefineGMR2(void *pvCmd, uint32_t u32GmrId, uint32_t cPages);53 void SvgaCmdRemapGMR2(void *pvCmd, uint32_t u32GmrId, SVGARemapGMR2Flags flags, uint32 offsetPages, uint32_t numPages);54 55 52 void Svga3dCmdPresent(void *pvCmd, uint32_t u32Sid, uint32_t u32Width, uint32_t u32Height); 56 53 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp
r99990 r99997 1549 1549 } 1550 1550 1551 1552 static void dxDeferredMobDestruction(PVOID IoObject, PVOID Context, PIO_WORKITEM IoWorkItem) 1553 { 1554 RT_NOREF(IoObject); 1555 IoFreeWorkItem(IoWorkItem); 1556 1557 PVBOXWDDM_EXT_VMSVGA pSvga = (PVBOXWDDM_EXT_VMSVGA)Context; 1558 if (pSvga->pMiniportMobData) 1559 { 1560 uint64_t const u64MobFence = ASMAtomicReadU64(&pSvga->pMiniportMobData->u64MobFence); 1561 1562 /* Move mobs which were deleted by the host to the local list under the lock. */ 1563 RTLISTANCHOR listDestroyedMobs; 1564 RTListInit(&listDestroyedMobs); 1565 1566 KIRQL OldIrql; 1567 SvgaHostObjectsLock(pSvga, &OldIrql); 1568 1569 PVMSVGAMOB pIter, pNext; 1570 RTListForEachSafe(&pSvga->listMobDeferredDestruction, pIter, pNext, VMSVGAMOB, node) 1571 { 1572 if (gaFenceCmp64(pIter->u64MobFence, u64MobFence) <= 0) 1573 { 1574 RTListNodeRemove(&pIter->node); 1575 RTListAppend(&listDestroyedMobs, &pIter->node); 1576 } 1577 } 1578 1579 SvgaHostObjectsUnlock(pSvga, OldIrql); 1580 1581 RTListForEachSafe(&listDestroyedMobs, pIter, pNext, VMSVGAMOB, node) 1582 { 1583 /* Delete the data. SvgaMobFree deallocates pIter. */ 1584 RTListNodeRemove(&pIter->node); 1585 SvgaMobFree(pSvga, pIter); 1586 } 1587 } 1588 } 1589 1590 1551 1591 VOID GaDxgkDdiDpcRoutine(const PVOID MiniportDeviceContext) 1552 1592 { … … 1636 1676 * Deferred MOB destruction. 1637 1677 */ 1638 if (pSvga->pMiniportMobData) 1639 { 1640 uint64_t const u64MobFence = pSvga->pMiniportMobData->u64MobFence; 1641 1642 /* Move mobs which were deleted by the host to the local list under the lock. */ 1643 RTLISTANCHOR listDestroyedMobs; 1644 RTListInit(&listDestroyedMobs); 1645 1646 SvgaHostObjectsLock(pSvga, &OldIrql); 1647 1648 if (!RTListIsEmpty(&pSvga->listMobDeferredDestruction)) 1649 { 1650 PVMSVGAMOB pIter, pNext; 1651 RTListForEachSafe(&pSvga->listMobDeferredDestruction, pIter, pNext, VMSVGAMOB, node) 1652 { 1653 if (gaFenceCmp64(pIter->u64MobFence, u64MobFence) <= 0) 1654 { 1655 RTListNodeRemove(&pIter->node); 1656 RTListAppend(&listDestroyedMobs, &pIter->node); 1657 } 1658 } 1659 } 1660 1661 SvgaHostObjectsUnlock(pSvga, OldIrql); 1662 1663 if (!RTListIsEmpty(&listDestroyedMobs)) 1664 { 1665 PVMSVGAMOB pIter, pNext; 1666 RTListForEachSafe(&listDestroyedMobs, pIter, pNext, VMSVGAMOB, node) 1667 { 1668 /* Delete the data. SvgaMobFree deallocates pIter. */ 1669 RTListNodeRemove(&pIter->node); 1670 SvgaMobFree(pSvga, pIter); 1671 } 1672 } 1678 SvgaHostObjectsLock(pSvga, &OldIrql); 1679 bool fMobs = !RTListIsEmpty(&pSvga->listMobDeferredDestruction); 1680 SvgaHostObjectsUnlock(pSvga, OldIrql); 1681 1682 if (fMobs) 1683 { 1684 /* Deallocate memory in a worker thread at PASSIVE_LEVEL. */ 1685 PIO_WORKITEM pWorkItem = IoAllocateWorkItem(pDevExt->pPDO); 1686 if (pWorkItem) 1687 IoQueueWorkItemEx(pWorkItem, dxDeferredMobDestruction, DelayedWorkQueue, pSvga); 1673 1688 } 1674 1689 }
Note:
See TracChangeset
for help on using the changeset viewer.