Changeset 94881 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Video
- Timestamp:
- May 6, 2022 4:45:02 AM (3 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk
r94584 r94881 166 166 ifdef VBOX_WITH_VMSVGA3D_DX 167 167 VBoxWddm_DEFS += VBOX_WITH_VMSVGA3D_DX 168 VBoxWddm_SOURCES += \ 169 wddm/gallium/SvgaRender.cpp \ 170 wddm/gallium/VBoxMPDX.cpp 168 171 endif 169 172 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h
r94584 r94881 34 34 #include "VBoxMPSa.h" 35 35 #include "VBoxMPVModes.h" 36 37 #ifdef DEBUG_sunlover 38 #define DEBUG_BREAKPOINT_TEST() do { ASMBreakpoint(); } while (0) 39 #else 40 #define DEBUG_BREAKPOINT_TEST() do { } while (0) 41 #endif 36 42 37 43 #if 0 … … 192 198 #endif 193 199 VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType; 200 #ifdef VBOX_WITH_VMSVGA3D_DX 201 /* Direct3D driver data for .enmType == VBOXWDDM_ALLOC_TYPE_D3D. */ 202 struct 203 { 204 VBOXDXALLOCATIONDESC desc; 205 uint32_t sid; /* For surfaces. */ 206 uint32_t mobid; /* For surfaces and shaders. */ 207 } dx; 208 #endif /* VBOX_WITH_VMSVGA3D_DX */ 194 209 } VBOXWDDM_ALLOCATION, *PVBOXWDDM_ALLOCATION; 195 210 … … 235 250 236 251 #define VBOXWDDM_INVALID_COORD ((LONG)((~0UL) >> 1)) 252 253 #ifdef VBOX_WITH_VMSVGA 254 struct VMSVGACONTEXT; 255 #endif 237 256 238 257 typedef struct VBOXWDDM_CONTEXT … … 247 266 VBOXVIDEOCM_ALLOC_CONTEXT AllocContext; 248 267 #ifdef VBOX_WITH_VMSVGA 249 uint32_t u32Cid; /* SVGA context id of this context. */268 struct VMSVGACONTEXT *pSvgaContext; 250 269 #endif 251 270 } VBOXWDDM_CONTEXT, *PVBOXWDDM_CONTEXT; -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
r94584 r94881 30 30 #include <iprt/initterm.h> 31 31 #include <iprt/utf16.h> 32 #include <iprt/x86.h> 32 33 33 34 #include <VBox/VBoxGuestLib.h> … … 1591 1592 } 1592 1593 1594 #ifdef VBOX_WITH_VMSVGA3D_DX 1595 typedef struct VBOXDXSEGMENTDESCRIPTOR 1596 { 1597 DXGK_SEGMENTFLAGS Flags; 1598 PHYSICAL_ADDRESS CpuTranslatedAddress; 1599 SIZE_T Size; 1600 } VBOXDXSEGMENTDESCRIPTOR; 1601 1602 #define VBOXDX_SEGMENTS_COUNT 3 1603 1604 static void vmsvgaDXGetSegmentDescription(PVBOXMP_DEVEXT pDevExt, int idxSegment, VBOXDXSEGMENTDESCRIPTOR *pDesc) 1605 { 1606 /* 3 segments: 1607 * 1: The usual VRAM, CpuVisible; 1608 * 2: Aperture segment for guest backed objects; 1609 * 3: Host resources, CPU invisible. 1610 */ 1611 RT_ZERO(*pDesc); 1612 if (idxSegment == 0) 1613 { 1614 pDesc->CpuTranslatedAddress = VBoxCommonFromDeviceExt(pDevExt)->phVRAM; 1615 pDesc->Size = pDevExt->cbVRAMCpuVisible & X86_PAGE_4K_BASE_MASK; 1616 pDesc->Flags.CpuVisible = 1; 1617 } 1618 else if (idxSegment == 1) 1619 { 1620 pDesc->Size = _2G; /** @todo */ 1621 pDesc->Flags.CpuVisible = 1; 1622 pDesc->Flags.Aperture = 1; 1623 } 1624 else if (idxSegment == 2) 1625 { 1626 pDesc->Size = _2G; /** @todo */ 1627 } 1628 } 1629 #endif 1630 1593 1631 /** 1594 1632 * DxgkDdiQueryAdapterInfo … … 1694 1732 if (!g_VBoxDisplayOnly) 1695 1733 { 1734 #ifdef VBOX_WITH_VMSVGA3D_DX 1735 if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA && SvgaIsDXSupported(pDevExt)) 1736 { 1737 DXGK_QUERYSEGMENTOUT *pOut = (DXGK_QUERYSEGMENTOUT *)pQueryAdapterInfo->pOutputData; 1738 if (!pOut->pSegmentDescriptor) 1739 pOut->NbSegment = VBOXDX_SEGMENTS_COUNT; /* Return the number of segments. */ 1740 else if (pOut->NbSegment == VBOXDX_SEGMENTS_COUNT) 1741 { 1742 DXGK_SEGMENTDESCRIPTOR *paDesc = pOut->pSegmentDescriptor; 1743 for (unsigned i = 0; i < VBOXDX_SEGMENTS_COUNT; ++i) 1744 { 1745 VBOXDXSEGMENTDESCRIPTOR desc; 1746 vmsvgaDXGetSegmentDescription(pDevExt, i, &desc); 1747 paDesc[i].CpuTranslatedAddress = desc.CpuTranslatedAddress; 1748 paDesc[i].Size = desc.Size; 1749 paDesc[i].CommitLimit = desc.Size; 1750 paDesc[i].Flags = desc.Flags; 1751 } 1752 1753 pOut->PagingBufferSegmentId = 0; 1754 pOut->PagingBufferSize = PAGE_SIZE; 1755 pOut->PagingBufferPrivateDataSize = PAGE_SIZE; 1756 } 1757 else 1758 { 1759 WARN(("NbSegment %d", pOut->NbSegment)); 1760 Status = STATUS_INVALID_PARAMETER; 1761 } 1762 break; 1763 } 1764 #endif 1696 1765 /* no need for DXGK_QUERYSEGMENTIN as it contains AGP aperture info, which (AGP aperture) we do not support 1697 1766 * DXGK_QUERYSEGMENTIN *pQsIn = (DXGK_QUERYSEGMENTIN*)pQueryAdapterInfo->pInputData; */ … … 1804 1873 1805 1874 case DXGKQAITYPE_QUERYSEGMENT3: 1875 #ifdef VBOX_WITH_VMSVGA3D_DX 1876 if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA && SvgaIsDXSupported(pDevExt)) 1877 { 1878 DXGK_QUERYSEGMENTOUT3 *pOut = (DXGK_QUERYSEGMENTOUT3 *)pQueryAdapterInfo->pOutputData; 1879 if (!pOut->pSegmentDescriptor) 1880 pOut->NbSegment = VBOXDX_SEGMENTS_COUNT; /* Return the number of segments. */ 1881 else if (pOut->NbSegment == VBOXDX_SEGMENTS_COUNT) 1882 { 1883 DXGK_SEGMENTDESCRIPTOR3 *paDesc = pOut->pSegmentDescriptor; 1884 for (unsigned i = 0; i < VBOXDX_SEGMENTS_COUNT; ++i) 1885 { 1886 VBOXDXSEGMENTDESCRIPTOR desc; 1887 vmsvgaDXGetSegmentDescription(pDevExt, i, &desc); 1888 paDesc[i].Flags = desc.Flags; 1889 paDesc[i].CpuTranslatedAddress = desc.CpuTranslatedAddress; 1890 paDesc[i].Size = desc.Size; 1891 paDesc[i].CommitLimit = desc.Size; 1892 } 1893 1894 pOut->PagingBufferSegmentId = 0; 1895 pOut->PagingBufferSize = PAGE_SIZE; 1896 pOut->PagingBufferPrivateDataSize = PAGE_SIZE; 1897 } 1898 else 1899 { 1900 WARN(("NbSegment %d", pOut->NbSegment)); 1901 Status = STATUS_INVALID_PARAMETER; 1902 } 1903 break; 1904 } 1905 #endif 1806 1906 LOGREL(("DXGKQAITYPE_QUERYSEGMENT3 treating as unsupported!")); 1807 1907 Status = STATUS_NOT_SUPPORTED; … … 2195 2295 vboxVDbgBreakFv(); 2196 2296 2297 #ifdef VBOX_WITH_VMSVGA3D_DX 2298 /* The driver distinguished between the legacy and the new D3D(DX) requests by checking the size. */ 2299 AssertCompile(sizeof(VBOXDXALLOCATIONDESC) != sizeof(VBOXWDDM_ALLOCINFO)); 2300 2301 /* Check if this is a request from the new D3D driver. */ 2302 if ( pCreateAllocation->PrivateDriverDataSize == 0 2303 && pCreateAllocation->NumAllocations == 1 2304 && pCreateAllocation->pAllocationInfo[0].PrivateDriverDataSize == sizeof(VBOXDXALLOCATIONDESC)) 2305 return DxgkDdiDXCreateAllocation(hAdapter, pCreateAllocation); 2306 #endif 2307 2197 2308 PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter; 2198 2309 NTSTATUS Status = STATUS_SUCCESS; … … 2282 2393 2283 2394 vboxVDbgBreakFv(); 2395 2396 #ifdef VBOX_WITH_VMSVGA3D_DX 2397 /* Check if this is a request from the D3D driver. */ 2398 if (pDestroyAllocation->NumAllocations >= 1) 2399 { 2400 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pDestroyAllocation->pAllocationList[0]; 2401 if (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_D3D) 2402 return DxgkDdiDXDestroyAllocation(hAdapter, pDestroyAllocation); 2403 } 2404 #endif 2284 2405 2285 2406 NTSTATUS Status = STATUS_SUCCESS; … … 2330 2451 2331 2452 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pDescribeAllocation->hAllocation; 2453 #ifdef VBOX_WITH_VMSVGA3D_DX 2454 /* Check if this is a request from the D3D driver. */ 2455 if (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_D3D) 2456 return DxgkDdiDXDescribeAllocation(hAdapter, pDescribeAllocation); 2457 #endif 2332 2458 pDescribeAllocation->Width = pAllocation->AllocData.SurfDesc.width; 2333 2459 pDescribeAllocation->Height = pAllocation->AllocData.SurfDesc.height; … … 4150 4276 { 4151 4277 DXGK_OPENALLOCATIONINFO* pInfo = &pOpenAllocation->pOpenAllocation[i]; 4278 #ifdef VBOX_WITH_VMSVGA3D_DX 4279 Assert( pInfo->PrivateDriverDataSize == sizeof(VBOXDXALLOCATIONDESC) 4280 || pInfo->PrivateDriverDataSize == sizeof(VBOXWDDM_ALLOCINFO)); 4281 #else 4152 4282 Assert(pInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO)); 4283 #endif 4153 4284 Assert(pInfo->pPrivateDriverData); 4154 4285 PVBOXWDDM_ALLOCATION pAllocation = vboxWddmGetAllocationFromHandle(pDevExt, pInfo->hAllocation); … … 4450 4581 #endif 4451 4582 #ifdef VBOX_WITH_VMSVGA3D_DX 4452 /** @todo Implement buffers submittion and memory menagement for this new type of context **/4453 4583 case VBOXWDDM_CONTEXT_TYPE_VMSVGA_D3D: 4454 4584 { -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp
r94635 r94881 27 27 #include <iprt/memobj.h> 28 28 29 /** @todo The size of each Object Table should not be hardcoded but estimated using some VMSVGA device limits **/ 29 30 static NTSTATUS SvgaObjectTablesDestroy(VBOXWDDM_EXT_VMSVGA *pSvga) 31 { 32 NTSTATUS Status = STATUS_SUCCESS; 33 34 for (uint32_t i = 0; i < RT_ELEMENTS(pSvga->aOT); ++i) 35 { 36 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_SET_OTABLE_BASE64, sizeof(SVGA3dCmdSetOTableBase64), SVGA3D_INVALID_ID); 37 AssertBreakStmt(pvCmd, Status = STATUS_INSUFFICIENT_RESOURCES); 38 39 SVGA3dCmdSetOTableBase64 *pCmd = (SVGA3dCmdSetOTableBase64 *)pvCmd; 40 pCmd->type = (SVGAOTableType)i; 41 pCmd->baseAddress = 0; 42 pCmd->sizeInBytes = 0; 43 pCmd->validSizeInBytes = 0; 44 pCmd->ptDepth = SVGA3D_MOBFMT_INVALID; 45 46 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdSetOTableBase64)); 47 } 48 49 SvgaCmdBufFlush(pSvga); 50 51 for (uint32_t i = 0; i < RT_ELEMENTS(pSvga->aOT); ++i) 52 { 53 SvgaMobFree(pSvga, pSvga->aOT[i].pMob); 54 pSvga->aOT[i].pMob = 0; 55 56 RTR0MemObjFree(pSvga->aOT[i].hMemObj, true); 57 pSvga->aOT[i].hMemObj = NIL_RTR0MEMOBJ; 58 } 59 60 return Status; 61 } 62 30 63 static NTSTATUS SvgaObjectTablesInit(VBOXWDDM_EXT_VMSVGA *pSvga) 31 64 { 32 int rc = RTR0MemObjAllocPageTag(&pSvga->hMemObjOTables, (SVGA_OTABLE_DXCONTEXT + 1) * PAGE_SIZE,33 false /* executable R0 mapping */, "WDDMGA");34 AssertRCReturn(rc, STATUS_INSUFFICIENT_RESOURCES);35 36 for (uint32_t idOTable = 0; idOTable < SVGA_OTABLE_DX_MAX; idOTable++)37 {38 RTHCPHYS paOT = RTR0MemObjGetPagePhysAddr(pSvga->hMemObjOTables, idOTable);39 40 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_SET_OTABLE_BASE64, sizeof(SVGA3dCmdSetOTableBase64), SVGA3D_INVALID_ID);41 AssertBreak(pvCmd);42 43 SVGA3dCmdSetOTableBase64 *pCmd = (SVGA3dCmdSetOTableBase64 *)pvCmd;44 pCmd->type = (SVGAOTableType)idOTable;45 pCmd->baseAddress = paOT >> 12;46 pCmd->sizeInBytes = PAGE_SIZE;47 pCmd->validSizeInBytes = 0;48 pCmd->ptDepth = SVGA3D_MOBFMT_PTDEPTH64_0;49 50 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdSetOTableBase64));51 }52 53 SvgaCmdBufFlush(pSvga);54 return STATUS_SUCCESS;55 }56 57 static NTSTATUS SvgaObjectTablesDestroy(VBOXWDDM_EXT_VMSVGA *pSvga)58 {59 65 NTSTATUS Status = STATUS_SUCCESS; 60 if (pSvga->hMemObjOTables != NIL_RTR0MEMOBJ) 61 { 62 for (uint32_t idOTable = 0; idOTable < SVGA_OTABLE_DX_MAX; idOTable++) 66 67 /* Allocate OTables. */ 68 for (uint32_t i = 0; i < RT_ELEMENTS(pSvga->aOT); ++i) 69 { 70 /** @todo Proper size for each. */ 71 uint32_t cbOT = 16 * PAGE_SIZE; 72 73 /* Allocate pages for the new OTable. */ 74 int rc = RTR0MemObjAllocPageTag(&pSvga->aOT[i].hMemObj, cbOT, false /* executable R0 mapping */, "VMSVGAOT"); 75 AssertRCBreakStmt(rc, Status = STATUS_INSUFFICIENT_RESOURCES); 76 77 /* Allocate a new mob. */ 78 Status = SvgaMobCreate(pSvga, &pSvga->aOT[i].pMob, cbOT >> PAGE_SHIFT, 0); 79 AssertBreak(NT_SUCCESS(Status)); 80 81 Status = SvgaMobFillPageTableForMemObj(pSvga, pSvga->aOT[i].pMob, pSvga->aOT[i].hMemObj); 82 AssertBreak(NT_SUCCESS(Status)); 83 } 84 85 if (NT_SUCCESS(Status)) 86 { 87 /* Emit commands */ 88 for (uint32_t i = 0; i < RT_ELEMENTS(pSvga->aOT); ++i) 63 89 { 64 90 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_SET_OTABLE_BASE64, sizeof(SVGA3dCmdSetOTableBase64), SVGA3D_INVALID_ID); 65 AssertBreakStmt(pvCmd, S TATUS_INSUFFICIENT_RESOURCES);91 AssertBreakStmt(pvCmd, Status = STATUS_INSUFFICIENT_RESOURCES); 66 92 67 93 SVGA3dCmdSetOTableBase64 *pCmd = (SVGA3dCmdSetOTableBase64 *)pvCmd; 68 pCmd->type = (SVGAOTableType)i dOTable;69 pCmd->baseAddress = 0;70 pCmd->sizeInBytes = 0;94 pCmd->type = (SVGAOTableType)i; 95 pCmd->baseAddress = pSvga->aOT[i].pMob->base; 96 pCmd->sizeInBytes = pSvga->aOT[i].pMob->cbMob; 71 97 pCmd->validSizeInBytes = 0; 72 pCmd->ptDepth = SVGA3D_MOBFMT_INVALID;98 pCmd->ptDepth = pSvga->aOT[i].pMob->enmMobFormat; 73 99 74 100 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdSetOTableBase64)); 75 101 } 76 102 77 if (NT_SUCCESS(Status)) 78 SvgaCmdBufFlush(pSvga); 79 80 int rc = RTR0MemObjFree(pSvga->hMemObjOTables, true); 81 AssertRCStmt(rc, Status = STATUS_INVALID_PARAMETER); 82 pSvga->hMemObjOTables = NIL_RTR0MEMOBJ; 83 } 84 return Status; 103 SvgaCmdBufFlush(pSvga); 104 } 105 106 if (!NT_SUCCESS(Status)) 107 SvgaObjectTablesDestroy(pSvga); 108 109 return STATUS_SUCCESS; 85 110 } 86 111 … … 413 438 ExReleaseFastMutex(&pSvga->SvgaMutex); 414 439 return Status; 440 } 441 442 NTSTATUS SvgaDXContextIdAlloc(PVBOXWDDM_EXT_VMSVGA pSvga, 443 uint32_t *pu32Cid) 444 { 445 return SvgaIdAlloc(pSvga, pSvga->au32DXContextBits, sizeof(pSvga->au32DXContextBits), 446 SVGA3D_MAX_CONTEXT_IDS, pu32Cid); 447 } 448 449 NTSTATUS SvgaDXContextIdFree(PVBOXWDDM_EXT_VMSVGA pSvga, 450 uint32_t u32Cid) 451 { 452 return SvgaIdFree(pSvga, pSvga->au32DXContextBits, sizeof(pSvga->au32DXContextBits), 453 SVGA3D_MAX_CONTEXT_IDS, u32Cid); 454 } 455 456 NTSTATUS SvgaMobIdAlloc(PVBOXWDDM_EXT_VMSVGA pSvga, 457 uint32_t *pu32MobId) 458 { 459 return SvgaIdAlloc(pSvga, pSvga->au32MobBits, sizeof(pSvga->au32MobBits), 460 SVGA3D_MAX_MOBS, pu32MobId); 461 } 462 463 NTSTATUS SvgaMobIdFree(PVBOXWDDM_EXT_VMSVGA pSvga, 464 uint32_t u32MobId) 465 { 466 return SvgaIdFree(pSvga, pSvga->au32MobBits, sizeof(pSvga->au32MobBits), 467 SVGA3D_MAX_MOBS, u32MobId); 415 468 } 416 469 … … 1849 1902 return Status; 1850 1903 } 1904 1905 NTSTATUS SvgaDXContextCreate(PVBOXWDDM_EXT_VMSVGA pSvga, 1906 uint32_t u32Cid) 1907 { 1908 NTSTATUS Status = STATUS_SUCCESS; 1909 1910 /* 1911 * Issue SVGA_3D_CMD_DX_DEFINE_CONTEXT. 1912 */ 1913 uint32_t cbSubmit = sizeof(SVGA3dCmdHeader) 1914 + sizeof(SVGA3dCmdDXDefineContext); 1915 void *pvCmd = SvgaReserve(pSvga, cbSubmit); 1916 if (pvCmd) 1917 { 1918 SVGA3dCmdHeader *pHeader = (SVGA3dCmdHeader *)pvCmd; 1919 SVGA3dCmdDXDefineContext *pCommand = (SVGA3dCmdDXDefineContext *)&pHeader[1]; 1920 1921 pHeader->id = SVGA_3D_CMD_DX_DEFINE_CONTEXT; 1922 pHeader->size = sizeof(SVGA3dCmdDXDefineContext); 1923 pCommand->cid = u32Cid; 1924 1925 SvgaCommit(pSvga, cbSubmit); 1926 } 1927 else 1928 Status = STATUS_INSUFFICIENT_RESOURCES; 1929 1930 return Status; 1931 } 1932 1933 NTSTATUS SvgaDXContextDestroy(PVBOXWDDM_EXT_VMSVGA pSvga, 1934 uint32_t u32Cid) 1935 { 1936 NTSTATUS Status = STATUS_SUCCESS; 1937 1938 /* 1939 * Issue SVGA_3D_CMD_DX_DESTROY_CONTEXT. 1940 */ 1941 uint32_t cbSubmit = sizeof(SVGA3dCmdHeader) 1942 + sizeof(SVGA3dCmdDXDestroyContext); 1943 void *pvCmd = SvgaReserve(pSvga, cbSubmit); 1944 if (pvCmd) 1945 { 1946 SVGA3dCmdHeader *pHeader = (SVGA3dCmdHeader *)pvCmd; 1947 SVGA3dCmdDXDestroyContext *pCommand = (SVGA3dCmdDXDestroyContext *)&pHeader[1]; 1948 1949 pHeader->id = SVGA_3D_CMD_DX_DESTROY_CONTEXT; 1950 pHeader->size = sizeof(SVGA3dCmdDXDestroyContext); 1951 pCommand->cid = u32Cid; 1952 1953 SvgaCommit(pSvga, cbSubmit); 1954 } 1955 else 1956 Status = STATUS_INSUFFICIENT_RESOURCES; 1957 1958 return Status; 1959 } 1960 1961 NTSTATUS SvgaMobAlloc(VBOXWDDM_EXT_VMSVGA *pSvga, 1962 PVMSVGAMOB *ppMob) 1963 { 1964 GALOG(("[%p]\n", pSvga)); 1965 1966 NTSTATUS Status; 1967 1968 *ppMob = (PVMSVGAMOB)GaMemAllocZero(sizeof(VMSVGAMOB)); 1969 AssertReturn(*ppMob, STATUS_INSUFFICIENT_RESOURCES); 1970 1971 Status = SvgaMobIdAlloc(pSvga, &VMSVGAMOB_ID(*ppMob)); 1972 AssertReturnStmt(NT_SUCCESS(Status), GaMemFree(*ppMob), STATUS_INSUFFICIENT_RESOURCES); 1973 1974 return STATUS_SUCCESS; 1975 } 1976 1977 void SvgaMobFree(VBOXWDDM_EXT_VMSVGA *pSvga, 1978 PVMSVGAMOB pMob) 1979 { 1980 GALOG(("[%p] %p\n", pSvga, pMob)); 1981 1982 if (pMob) 1983 { 1984 ExAcquireFastMutex(&pSvga->SvgaMutex); 1985 RTAvlU32Remove(&pSvga->MobTree, pMob->core.Key); 1986 ExReleaseFastMutex(&pSvga->SvgaMutex); 1987 1988 if (pMob->hMemObj) 1989 { 1990 int rc = RTR0MemObjFree(pMob->hMemObj, true); 1991 AssertRC(rc); 1992 } 1993 1994 NTSTATUS Status = SvgaMobIdFree(pSvga, VMSVGAMOB_ID(pMob)); 1995 Assert(NT_SUCCESS(Status)); RT_NOREF(Status); 1996 GaMemFree(pMob); 1997 } 1998 } 1999 2000 2001 NTSTATUS SvgaMobCreate(VBOXWDDM_EXT_VMSVGA *pSvga, 2002 PVMSVGAMOB *ppMob, 2003 uint32_t cMobPages, 2004 HANDLE hAllocation) 2005 { 2006 PVMSVGAMOB pMob; 2007 NTSTATUS Status = SvgaMobAlloc(pSvga, &pMob); 2008 AssertReturn(NT_SUCCESS(Status), Status); 2009 2010 /* 2011 * Calculate how many pages are needed to describe the mob. 2012 * Use 64 bit mob format for 32 bit driver too in order to simplify the code. 2013 */ 2014 uint32_t const cPageEntriesPerPage = PAGE_SIZE / sizeof(PPN64); 2015 if (cMobPages == 1) 2016 { 2017 pMob->cDescriptionPages = 0; 2018 pMob->enmMobFormat = SVGA3D_MOBFMT_PTDEPTH64_0; 2019 } 2020 else if (cMobPages <= cPageEntriesPerPage) 2021 { 2022 pMob->cDescriptionPages = 1; 2023 pMob->enmMobFormat = SVGA3D_MOBFMT_PTDEPTH64_1; 2024 } 2025 else if (cMobPages <= cPageEntriesPerPage * cPageEntriesPerPage) 2026 { 2027 uint32_t const cLevel1Pages = 2028 (cMobPages + cPageEntriesPerPage - 1) / cPageEntriesPerPage; 2029 pMob->cDescriptionPages = 1 + cLevel1Pages; /* One level 2 page and level 1 pages. */ 2030 pMob->enmMobFormat = SVGA3D_MOBFMT_PTDEPTH64_2; 2031 } 2032 else 2033 AssertFailedReturnStmt(SvgaMobFree(pSvga, pMob), STATUS_INVALID_PARAMETER); 2034 2035 if (pMob->cDescriptionPages) 2036 { 2037 int rc = RTR0MemObjAllocPageTag(&pMob->hMemObj, pMob->cDescriptionPages * PAGE_SIZE, 2038 false /* executable R0 mapping */, "VMSVGAMOB"); 2039 AssertRCReturnStmt(rc, SvgaMobFree(pSvga, pMob), STATUS_INSUFFICIENT_RESOURCES); 2040 2041 if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2) 2042 { 2043 /* Store the page numbers of level 1 pages into the level 2 page. 2044 * Skip the level 2 page at index 0. 2045 */ 2046 PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObj); 2047 for (unsigned i = 1; i < pMob->cDescriptionPages; ++i) 2048 paPpn[i - 1] = RTR0MemObjGetPagePhysAddr(pMob->hMemObj, i) >> PAGE_SHIFT; 2049 } 2050 } 2051 2052 pMob->base = UINT64_C(~0); /* base will be assigned by SvgaMobFillPageTable* */ 2053 pMob->cbMob = cMobPages << PAGE_SHIFT; 2054 pMob->hAllocation = hAllocation; 2055 2056 *ppMob = pMob; 2057 return STATUS_SUCCESS; 2058 } 2059 2060 2061 NTSTATUS SvgaMobFillPageTableForMDL(VBOXWDDM_EXT_VMSVGA *pSvga, 2062 PVMSVGAMOB pMob, 2063 PMDL pMdl, 2064 uint32_t MdlOffset) 2065 { 2066 RT_NOREF(pSvga); 2067 2068 PPFN_NUMBER paMdlPfn = &MmGetMdlPfnArray(pMdl)[MdlOffset]; 2069 if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_0) 2070 pMob->base = paMdlPfn[0]; 2071 else 2072 { 2073 /* The first of pages is alway the base. It is either the level 2 page or the single level 1 page */ 2074 pMob->base = RTR0MemObjGetPagePhysAddr(pMob->hMemObj, 0) >> PAGE_SHIFT; 2075 2076 PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObj); 2077 PPN64 *paPpnMdlPfn; 2078 if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2) 2079 paPpnMdlPfn = &paPpn[PAGE_SIZE / sizeof(PPN64)]; /* Level 1 pages follow the level 2 page. */ 2080 else if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_1) 2081 paPpnMdlPfn = paPpn; 2082 else 2083 AssertFailedReturn(STATUS_INVALID_PARAMETER); 2084 2085 /* Store Mdl page numbers into the level 1 description pages. */ 2086 for (unsigned i = 0; i < pMob->cbMob >> PAGE_SHIFT; ++i) 2087 paPpnMdlPfn[i] = paMdlPfn[i]; 2088 } 2089 return STATUS_SUCCESS; 2090 } 2091 2092 2093 NTSTATUS SvgaMobFillPageTableForMemObj(VBOXWDDM_EXT_VMSVGA *pSvga, 2094 PVMSVGAMOB pMob, 2095 RTR0MEMOBJ hMemObj) 2096 { 2097 RT_NOREF(pSvga); 2098 2099 if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_0) 2100 pMob->base = RTR0MemObjGetPagePhysAddr(hMemObj, 0) >> PAGE_SHIFT; 2101 else 2102 { 2103 /* The first of pages is alway the base. It is either the level 2 page or the single level 1 page */ 2104 pMob->base = RTR0MemObjGetPagePhysAddr(pMob->hMemObj, 0) >> PAGE_SHIFT; 2105 2106 PPN64 *paPpn = (PPN64 *)RTR0MemObjAddress(pMob->hMemObj); 2107 PPN64 *paPpnMob; 2108 if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_2) 2109 paPpnMob = &paPpn[PAGE_SIZE / sizeof(PPN64)]; /* Level 1 pages follow the level 2 page. */ 2110 else if (pMob->enmMobFormat == SVGA3D_MOBFMT_PTDEPTH64_1) 2111 paPpnMob = paPpn; 2112 else 2113 AssertFailedReturn(STATUS_INVALID_PARAMETER); 2114 2115 /* Store page numbers into the level 1 description pages. */ 2116 for (unsigned i = 0; i < pMob->cbMob >> PAGE_SHIFT; ++i) 2117 paPpnMob[i] = RTR0MemObjGetPagePhysAddr(hMemObj, i) >> PAGE_SHIFT;; 2118 } 2119 return STATUS_SUCCESS; 2120 } 2121 2122 2123 NTSTATUS SvgaCOTNotifyId(VBOXWDDM_EXT_VMSVGA *pSvga, 2124 PVMSVGACONTEXT pSvgaContext, 2125 SVGACOTableType enmType, 2126 uint32_t id) 2127 { 2128 AssertReturn(enmType < RT_ELEMENTS(pSvgaContext->aCOT), STATUS_INVALID_PARAMETER); 2129 PVMSVGACOT pCOT = &pSvgaContext->aCOT[enmType]; 2130 2131 if (id < pCOT->cEntries) 2132 return STATUS_SUCCESS; /* Still large enough. */ 2133 2134 AssertReturn(id < SVGA_COTABLE_MAX_IDS, STATUS_INVALID_PARAMETER); 2135 2136 /* Allocate a new larger mob and inform the host. */ 2137 static uint32_t const s_acbEntry[SVGA_COTABLE_MAX] = 2138 { 2139 sizeof(SVGACOTableDXRTViewEntry), 2140 sizeof(SVGACOTableDXDSViewEntry), 2141 sizeof(SVGACOTableDXSRViewEntry), 2142 sizeof(SVGACOTableDXElementLayoutEntry), 2143 sizeof(SVGACOTableDXBlendStateEntry), 2144 sizeof(SVGACOTableDXDepthStencilEntry), 2145 sizeof(SVGACOTableDXRasterizerStateEntry), 2146 sizeof(SVGACOTableDXSamplerEntry), 2147 sizeof(SVGACOTableDXStreamOutputEntry), 2148 sizeof(SVGACOTableDXQueryEntry), 2149 sizeof(SVGACOTableDXShaderEntry), 2150 sizeof(SVGACOTableDXUAViewEntry), 2151 }; 2152 2153 /** @todo Grow COTable. Readback and delete old mob. */ 2154 Assert(pCOT->cEntries == 0); 2155 2156 uint32_t cbRequired = (id + 1) * s_acbEntry[enmType]; 2157 cbRequired = RT_ALIGN_32(cbRequired, PAGE_SIZE); 2158 2159 /* Try to double the current size. */ 2160 uint32_t cbCOT = pCOT->cEntries ? pCOT->cEntries * s_acbEntry[enmType] : PAGE_SIZE; 2161 cbCOT += PAGE_SIZE * 15; /// @todo Large enough. Remove this line and implement COTable reallocation. 2162 while (cbRequired > cbCOT) 2163 cbCOT *= 2; 2164 2165 /* Allocate pages for the new COTable. */ 2166 RTR0MEMOBJ hMemObjCOT; 2167 int rc = RTR0MemObjAllocPageTag(&hMemObjCOT, cbCOT, false /* executable R0 mapping */, "VMSVGACOT"); 2168 AssertRCReturn(rc, STATUS_INSUFFICIENT_RESOURCES); 2169 2170 /* Allocate a new mob. */ 2171 PVMSVGAMOB pMob; 2172 NTSTATUS Status = SvgaMobCreate(pSvga, &pMob, cbCOT >> PAGE_SHIFT, 0); 2173 AssertReturnStmt(NT_SUCCESS(Status), 2174 RTR0MemObjFree(hMemObjCOT, true), 2175 Status); 2176 2177 Status = SvgaMobFillPageTableForMemObj(pSvga, pMob, hMemObjCOT); 2178 AssertReturnStmt(NT_SUCCESS(Status), 2179 SvgaMobFree(pSvga, pMob); RTR0MemObjFree(hMemObjCOT, true), 2180 Status); 2181 2182 /* Emit commands. */ 2183 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DEFINE_GB_MOB64, sizeof(SVGA3dCmdDefineGBMob64), SVGA3D_INVALID_ID); 2184 AssertReturnStmt(pvCmd, 2185 SvgaMobFree(pSvga, pMob); RTR0MemObjFree(hMemObjCOT, true), 2186 STATUS_INSUFFICIENT_RESOURCES); 2187 2188 SVGA3dCmdDefineGBMob64 *pCmd1 = (SVGA3dCmdDefineGBMob64 *)pvCmd; 2189 pCmd1->mobid = VMSVGAMOB_ID(pMob); 2190 pCmd1->ptDepth = pMob->enmMobFormat; 2191 pCmd1->base = pMob->base; 2192 pCmd1->sizeInBytes = pMob->cbMob; 2193 SvgaCmdBufCommit(pSvga, sizeof(*pCmd1)); 2194 2195 pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DX_SET_COTABLE, sizeof(SVGA3dCmdDXSetCOTable), SVGA3D_INVALID_ID); 2196 AssertReturnStmt(pvCmd, 2197 SvgaMobFree(pSvga, pMob); RTR0MemObjFree(hMemObjCOT, true), 2198 STATUS_INSUFFICIENT_RESOURCES); 2199 2200 SVGA3dCmdDXSetCOTable *pCmd2 = (SVGA3dCmdDXSetCOTable *)pvCmd; 2201 pCmd2->cid = pSvgaContext->u32Cid; 2202 pCmd2->mobid = VMSVGAMOB_ID(pMob); 2203 pCmd2->type = enmType; 2204 pCmd2->validSizeInBytes = pCOT->cEntries * s_acbEntry[enmType]; 2205 SvgaCmdBufCommit(pSvga, sizeof(*pCmd2)); 2206 2207 SvgaCmdBufFlush(pSvga); 2208 2209 pCOT->pMob = pMob; 2210 pCOT->hMemObj = hMemObjCOT; 2211 pCOT->cEntries = cbCOT / s_acbEntry[enmType]; 2212 2213 return STATUS_SUCCESS; 2214 } -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h
r94635 r94881 137 137 } VMSVGACBSTATE, *PVMSVGACBSTATE; 138 138 139 /* Contexts + One shaders mob per context + surfaces. */ 140 #define SVGA3D_MAX_MOBS (SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_SURFACE_IDS) 141 142 typedef struct VMSVGAMOB 143 { 144 AVLU32NODECORE core; /* AVL entry. Key is mobid, allocated by the miniport. */ 145 uint32_t cbMob; /* Size of mob in bytes. */ 146 uint32_t cDescriptionPages; /* How many pages are required to hold PPN64 page table. */ 147 SVGAMobFormat enmMobFormat; /* Page table format. */ 148 PPN64 base; /* Page which contains the page table. */ 149 RTR0MEMOBJ hMemObj; /* Page table pages. */ 150 HANDLE hAllocation; /* Allocation which is bound to the mob. */ 151 } VMSVGAMOB, *PVMSVGAMOB; 152 153 #define VMSVGAMOB_ID(a_pMob) ((a_pMob)->core.Key) 154 139 155 /* VMSVGA specific part of Gallium device extension. */ 140 156 typedef struct VBOXWDDM_EXT_VMSVGA … … 188 204 AVLU32TREE SurfaceTree; 189 205 206 /** AVL tree for mapping mobid to the corresponding structure. */ 207 AVLU32TREE MobTree; 208 190 209 /** List of host objects, which must be deleted at PASSIVE_LEVEL. */ 191 210 RTLISTANCHOR DeletedHostObjectsList; … … 200 219 } lastGMRFB; 201 220 221 struct 222 { 223 PVMSVGAMOB pMob; 224 RTR0MEMOBJ hMemObj; 225 } aOT[SVGA_OTABLE_DX_MAX]; 226 202 227 /** Bitmap of used GMR ids. Bit 0 - GMR id 0, etc. */ 203 228 uint32_t *pu32GMRBits; /* Number of GMRs is controlled by the host (u32GmrMaxIds), so allocate the bitmap. */ … … 209 234 /** Bitmap of used surface ids. Bit 0 - surface id 0, etc. */ 210 235 uint32_t au32SurfaceBits[(SVGA3D_MAX_SURFACE_IDS + 31) / 32]; 236 237 /** Bitmap of used DX context ids. Bit 0 - context id 0, etc. */ 238 uint32_t au32DXContextBits[(SVGA3D_MAX_CONTEXT_IDS + 31) / 32]; 239 240 /** Bitmap of used MOB ids. Bit 0 - context id 0, etc. */ 241 uint32_t au32MobBits[(SVGA3D_MAX_MOBS + 31) / 32]; 211 242 } VBOXWDDM_EXT_VMSVGA; 212 243 typedef struct VBOXWDDM_EXT_VMSVGA *PVBOXWDDM_EXT_VMSVGA; 244 245 typedef struct VMSVGACOT 246 { 247 PVMSVGAMOB pMob; /* COTable mob. */ 248 RTR0MEMOBJ hMemObj; /* COTable pages. */ 249 uint32_t cEntries; /* How many objects can be stored in the COTable. */ 250 uint32_t cNewEntries; /* New size of the COTable for rebind. */ 251 bool fRebind : 1; /* Mob must be reallocated and host must be informed. */ 252 } VMSVGACOT, *PVMSVGACOT; 253 254 typedef struct VMSVGACONTEXT 255 { 256 uint32_t u32Cid; /* SVGA context id of this context. */ 257 bool fDXContext : 1; /* Whether this context is a DX context or VGPU9. */ 258 bool fDebugVerifyCommands : 1; 259 VMSVGACOT aCOT[SVGA_COTABLE_MAX]; /* Context Object Tables. */ 260 } VMSVGACONTEXT, *PVMSVGACONTEXT; 213 261 214 262 typedef struct SVGAHOSTOBJECT SVGAHOSTOBJECT; … … 495 543 void *pvOwner); 496 544 545 NTSTATUS SvgaDXContextIdAlloc(PVBOXWDDM_EXT_VMSVGA pSvga, 546 uint32_t *pu32Cid); 547 548 NTSTATUS SvgaDXContextIdFree(PVBOXWDDM_EXT_VMSVGA pSvga, 549 uint32_t u32Cid); 550 551 NTSTATUS SvgaMobIdAlloc(PVBOXWDDM_EXT_VMSVGA pSvga, 552 uint32_t *pu32MobId); 553 554 NTSTATUS SvgaMobIdFree(PVBOXWDDM_EXT_VMSVGA pSvga, 555 uint32_t u32MobId); 556 557 NTSTATUS SvgaDXContextCreate(PVBOXWDDM_EXT_VMSVGA pSvga, 558 uint32_t u32Cid); 559 560 NTSTATUS SvgaDXContextDestroy(PVBOXWDDM_EXT_VMSVGA pSvga, 561 uint32_t u32Cid); 562 563 NTSTATUS SvgaRenderCommandsD3D(PVBOXWDDM_EXT_VMSVGA pSvga, 564 PVMSVGACONTEXT pSvgaContext, 565 void *pvTarget, 566 uint32_t cbTarget, 567 const void *pvSource, 568 uint32_t cbSource, 569 uint32_t *pu32TargetLength, 570 uint32_t *pu32ProcessedLength); 571 572 #ifdef DEBUG 573 NTSTATUS SvgaDebugCommandsD3D(PVBOXWDDM_EXT_VMSVGA pSvga, 574 PVMSVGACONTEXT pSvgaContext, 575 const void *pvSource, 576 uint32_t cbSource); 577 #endif 578 579 NTSTATUS SvgaMobAlloc(VBOXWDDM_EXT_VMSVGA *pSvga, 580 PVMSVGAMOB *ppMob); 581 void SvgaMobFree(VBOXWDDM_EXT_VMSVGA *pSvga, 582 PVMSVGAMOB pMob); 583 NTSTATUS SvgaMobCreate(VBOXWDDM_EXT_VMSVGA *pSvga, 584 PVMSVGAMOB *ppMob, 585 uint32_t cMobPages, 586 HANDLE hAllocation); 587 NTSTATUS SvgaMobFillPageTableForMDL(VBOXWDDM_EXT_VMSVGA *pSvga, 588 PVMSVGAMOB pMob, 589 PMDL pMdl, 590 uint32_t MdlOffset); 591 NTSTATUS SvgaMobFillPageTableForMemObj(VBOXWDDM_EXT_VMSVGA *pSvga, 592 PVMSVGAMOB pMob, 593 RTR0MEMOBJ hMemObj); 594 595 NTSTATUS SvgaCOTNotifyId(VBOXWDDM_EXT_VMSVGA *pSvga, 596 PVMSVGACONTEXT pSvgaContext, 597 SVGACOTableType enmType, 598 uint32_t id); 599 497 600 #endif /* !GA_INCLUDED_SRC_WINNT_Graphics_Video_mp_wddm_gallium_Svga_h */ -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaExt.h
r93115 r94881 110 110 GAFENCEOBJECT *pFO); 111 111 112 /* 113 * Description of DMA buffer content. 114 * These structures are stored in DmaBufferPrivateData. 115 */ 116 typedef struct GARENDERDATA 117 { 118 uint32_t u32DataType; /* GARENDERDATA_TYPE_* */ 119 uint32_t cbData; /* How many bytes. */ 120 GAFENCEOBJECT *pFenceObject; /* User mode fence associated with this command buffer. */ 121 void *pvDmaBuffer; /* Pointer to the DMA buffer. */ 122 GAHWRENDERDATA *pHwRenderData; /* The hardware module private data. */ 123 } GARENDERDATA; 124 125 #define GARENDERDATA_TYPE_RENDER 1 126 #define GARENDERDATA_TYPE_PRESENT 2 127 #define GARENDERDATA_TYPE_PAGING 3 128 #define GARENDERDATA_TYPE_FENCE 4 129 112 130 #endif /* !GA_INCLUDED_SRC_WINNT_Graphics_Video_mp_wddm_gallium_VBoxMPGaExt_h */ -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp
r94631 r94881 27 27 #include "SvgaHw.h" 28 28 29 #include <iprt/memobj.h> 29 30 #include <iprt/time.h> 30 31 … … 163 164 AssertReturn(pContext->NodeOrdinal == 0, STATUS_NOT_SUPPORTED); 164 165 166 pContext->pSvgaContext = (PVMSVGACONTEXT)GaMemAllocZero(sizeof(VMSVGACONTEXT)); 167 AssertReturn(pContext->pSvgaContext, STATUS_INSUFFICIENT_RESOURCES); 168 169 pContext->pSvgaContext->fDXContext = RT_BOOL(pInfo->u.vmsvga.u32Flags & VBOXWDDM_F_GA_CONTEXT_VGPU10); 170 165 171 VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga; 166 172 uint32_t u32Cid; 167 NTSTATUS Status = SvgaContextIdAlloc(pSvga, &u32Cid); 173 NTSTATUS Status; 174 if (pContext->pSvgaContext->fDXContext) 175 Status = SvgaDXContextIdAlloc(pSvga, &u32Cid); 176 else 177 Status = SvgaContextIdAlloc(pSvga, &u32Cid); 168 178 if (NT_SUCCESS(Status)) 169 179 { 170 Status = SvgaContextCreate(pSvga, u32Cid); 180 if (pContext->pSvgaContext->fDXContext) 181 Status = SvgaDXContextCreate(pSvga, u32Cid); 182 else 183 Status = SvgaContextCreate(pSvga, u32Cid); 171 184 if (Status == STATUS_SUCCESS) 172 185 { … … 174 187 RT_NOREF(pInfo); 175 188 176 /* Init pContext fields, which are relevant to the galliumcontext. */177 pContext-> u32Cid = u32Cid;178 179 GALOG(("pGaDevExt = %p, cid = %d \n", pGaDevExt, u32Cid));189 /* Init pContext fields, which are relevant to the VMSVGA context. */ 190 pContext->pSvgaContext->u32Cid = u32Cid; 191 192 GALOG(("pGaDevExt = %p, cid = %d (%d)\n", pGaDevExt, u32Cid, pContext->pSvgaContext->fDXContext ? "DX" : "VGPU9")); 180 193 } 181 194 else 182 195 { 183 SvgaContextIdFree(pSvga, u32Cid); 184 } 185 } 186 196 AssertFailed(); 197 if (pContext->pSvgaContext->fDXContext) 198 SvgaDXContextIdFree(pSvga, u32Cid); 199 else 200 SvgaContextIdFree(pSvga, u32Cid); 201 } 202 } 203 204 if (!NT_SUCCESS(Status)) 205 { 206 GaMemFree(pContext->pSvgaContext); 207 pContext->pSvgaContext = 0; 208 } 187 209 return Status; 188 210 } … … 191 213 PVBOXWDDM_CONTEXT pContext) 192 214 { 193 GALOG(("u32Cid = %d\n", pContext->u32Cid)); 215 PVMSVGACONTEXT pSvgaContext = pContext->pSvgaContext; 216 if (!pSvgaContext) 217 return STATUS_SUCCESS; 218 pContext->pSvgaContext = 0; 219 220 GALOG(("u32Cid = %d\n", pSvgaContext->u32Cid)); 194 221 195 222 VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga; 196 223 197 SvgaContextDestroy(pSvga, pContext->u32Cid); 198 199 return SvgaContextIdFree(pSvga, pContext->u32Cid); 224 NTSTATUS Status; 225 if (pSvgaContext->fDXContext) 226 { 227 SvgaDXContextDestroy(pSvga, pSvgaContext->u32Cid); 228 Status = SvgaDXContextIdFree(pSvga, pSvgaContext->u32Cid); 229 } 230 else 231 { 232 SvgaContextDestroy(pSvga, pSvgaContext->u32Cid); 233 Status = SvgaContextIdFree(pSvga, pSvgaContext->u32Cid); 234 } 235 236 GaMemFree(pSvgaContext); 237 return Status; 200 238 } 201 239 … … 409 447 } 410 448 } 411 412 /*413 * Description of DMA buffer content.414 * These structures are stored in DmaBufferPrivateData.415 */416 typedef struct GARENDERDATA417 {418 uint32_t u32DataType; /* GARENDERDATA_TYPE_* */419 uint32_t cbData; /* How many bytes. */420 GAFENCEOBJECT *pFenceObject; /* User mode fence associated with this command buffer. */421 void *pvDmaBuffer; /* Pointer to the DMA buffer. */422 GAHWRENDERDATA *pHwRenderData; /* The hardware module private data. */423 } GARENDERDATA;424 425 #define GARENDERDATA_TYPE_RENDER 1426 #define GARENDERDATA_TYPE_PRESENT 2427 #define GARENDERDATA_TYPE_PAGING 3428 #define GARENDERDATA_TYPE_FENCE 4429 449 430 450 /* If there are no commands but we need to trigger fence submission anyway, then submit a buffer of this size. */ … … 671 691 } 672 692 693 static NTSTATUS APIENTRY gaPresentGA3D(const HANDLE hContext, 694 DXGKARG_PRESENT *pPresent); 695 673 696 NTSTATUS APIENTRY GaDxgkDdiPresent(const HANDLE hContext, 674 697 DXGKARG_PRESENT *pPresent) 675 698 { 676 NTSTATUS Status = STATUS_SUCCESS;677 699 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext; 678 700 PVBOXWDDM_DEVICE pDevice = pContext->pDevice; … … 680 702 681 703 SvgaFlush(pDevExt->pGa->hw.pSvga); 682 683 DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];684 DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];685 704 686 705 GALOGG(GALOG_GROUP_PRESENT, ("%s: [%ld, %ld, %ld, %ld] -> [%ld, %ld, %ld, %ld] (SubRectCnt=%u)\n", … … 693 712 GALOGG(GALOG_GROUP_PRESENT, (" sub#%u = [%ld, %ld, %ld, %ld]\n", 694 713 i, pPresent->pDstSubRects[i].left, pPresent->pDstSubRects[i].top, pPresent->pDstSubRects[i].right, pPresent->pDstSubRects[i].bottom)); 714 715 NTSTATUS Status; 716 if (pContext->enmType == VBOXWDDM_CONTEXT_TYPE_GA_3D) 717 Status = gaPresentGA3D(pContext, pPresent); 718 #ifdef VBOX_WITH_VMSVGA3D_DX 719 else if (pContext->enmType == VBOXWDDM_CONTEXT_TYPE_VMSVGA_D3D) 720 Status = DxgkDdiDXPresent(pContext, pPresent); 721 #endif 722 else 723 AssertFailedStmt(Status = STATUS_INVALID_PARAMETER); 724 return Status; 725 } 726 727 static NTSTATUS APIENTRY gaPresentGA3D(const HANDLE hContext, 728 DXGKARG_PRESENT *pPresent) 729 { 730 NTSTATUS Status = STATUS_SUCCESS; 731 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext; 732 PVBOXWDDM_DEVICE pDevice = pContext->pDevice; 733 PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter; 734 735 DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX]; 736 DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX]; 695 737 696 738 if (pPresent->Flags.Blt) … … 910 952 } 911 953 954 static NTSTATUS gaRenderGA3D(PVBOXWDDM_CONTEXT pContext, DXGKARG_RENDER *pRender); 955 912 956 NTSTATUS APIENTRY GaDxgkDdiRender(const HANDLE hContext, DXGKARG_RENDER *pRender) 913 957 { 914 958 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext; 959 AssertReturn( pContext 960 && ( pContext->enmType == VBOXWDDM_CONTEXT_TYPE_GA_3D 961 || pContext->enmType == VBOXWDDM_CONTEXT_TYPE_VMSVGA_D3D), STATUS_INVALID_PARAMETER); 962 AssertReturn(pRender->CommandLength > pRender->MultipassOffset, STATUS_INVALID_PARAMETER); 963 964 PVBOXWDDM_DEVICE pDevice = pContext->pDevice; 965 PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter; 966 SvgaFlush(pDevExt->pGa->hw.pSvga); 967 968 NTSTATUS Status; 969 if (pContext->enmType == VBOXWDDM_CONTEXT_TYPE_GA_3D) 970 Status = gaRenderGA3D(pContext, pRender); 971 #ifdef VBOX_WITH_VMSVGA3D_DX 972 else if (pContext->enmType == VBOXWDDM_CONTEXT_TYPE_VMSVGA_D3D) 973 Status = DxgkDdiDXRender(pContext, pRender); 974 #endif 975 else 976 AssertFailedStmt(Status = STATUS_INVALID_PARAMETER); 977 return Status; 978 } 979 980 static NTSTATUS gaRenderGA3D(PVBOXWDDM_CONTEXT pContext, DXGKARG_RENDER *pRender) 981 { 915 982 PVBOXWDDM_DEVICE pDevice = pContext->pDevice; 916 983 PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter; 917 984 VBOXWDDM_EXT_GA *pGaDevExt = pDevExt->pGa; 918 919 SvgaFlush(pDevExt->pGa->hw.pSvga);920 921 AssertReturn(pContext && pContext->enmType == VBOXWDDM_CONTEXT_TYPE_GA_3D, STATUS_INVALID_PARAMETER);922 AssertReturn(pRender->CommandLength > pRender->MultipassOffset, STATUS_INVALID_PARAMETER);923 /* Expect 32 bit handle at the start of the command buffer. */924 AssertReturn(pRender->CommandLength >= sizeof(uint32_t), STATUS_INVALID_PARAMETER);925 985 926 986 GARENDERDATA *pRenderData = NULL; /* Pointer to the DMA buffer description. */ … … 930 990 931 991 GALOG(("[%p] Command %p/%d, Dma %p/%d, Private %p/%d, MO %d, S %d, Phys 0x%RX64, AL %p/%d, PLLIn %p/%d, PLLOut %p/%d\n", 932 hContext,992 pContext, 933 993 pRender->pCommand, pRender->CommandLength, 934 994 pRender->pDmaBuffer, pRender->DmaSize, … … 940 1000 )); 941 1001 942 /* 32 bit handle at the start of the command buffer. */ 1002 /* Expect 32 bit handle at the start of the command buffer. */ 1003 AssertReturn(pRender->CommandLength >= sizeof(uint32_t), STATUS_INVALID_PARAMETER); 1004 1005 /* Skip 32 bit handle. */ 943 1006 if (pRender->MultipassOffset == 0) 944 1007 pRender->MultipassOffset += sizeof(uint32_t); … … 1032 1095 if (u32TargetLength == 0) 1033 1096 { 1034 /* Trigger command submission anyway by increasing pDmaBuffer */ 1035 u32TargetLength = GA_DMA_MIN_SUBMIT_SIZE; 1036 1097 /* Trigger command submission anyway by increasing pRender->pDmaBufferPrivateData */ 1037 1098 /* Update the DMA buffer description. */ 1038 1099 pRenderData->u32DataType = GARENDERDATA_TYPE_FENCE; 1039 pRenderData->cbData = u32TargetLength;1100 pRenderData->cbData = 0; 1040 1101 /* pRenderData->pFenceObject stays */ 1041 1102 pRenderData->pvDmaBuffer = NULL; /* Not used */ … … 1061 1122 } 1062 1123 1124 static NTSTATUS gaBuildPagingBufferOld(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer); 1125 1063 1126 NTSTATUS APIENTRY GaDxgkDdiBuildPagingBuffer(const HANDLE hAdapter, 1064 1127 DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer) 1065 1128 { 1066 NTSTATUS Status = STATUS_SUCCESS;1067 1129 PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter; 1068 1130 … … 1074 1136 pBuildPagingBuffer->pDmaBuffer, 1075 1137 pBuildPagingBuffer->DmaSize)); 1138 1139 NTSTATUS Status; 1140 #ifdef VBOX_WITH_VMSVGA3D_DX 1141 /** @todo Old code did not generate any paging command actually. So probably one function is enough. */ 1142 if (SvgaIsDXSupported(pDevExt)) 1143 Status = DxgkDdiDXBuildPagingBuffer(pDevExt, pBuildPagingBuffer); 1144 else 1145 #endif 1146 Status = gaBuildPagingBufferOld(pDevExt, pBuildPagingBuffer); 1147 return Status; 1148 } 1149 1150 static NTSTATUS gaBuildPagingBufferOld(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer) 1151 { 1152 NTSTATUS Status = STATUS_SUCCESS; 1076 1153 1077 1154 /* Generate DMA buffer containing the commands. … … 1241 1318 } 1242 1319 1320 static NTSTATUS gaPatchGA3D(PVBOXMP_DEVEXT pDevExt, const DXGKARG_PATCH *pPatch); 1321 1243 1322 NTSTATUS APIENTRY GaDxgkDdiPatch(const HANDLE hAdapter, const DXGKARG_PATCH *pPatch) 1244 1323 { … … 1247 1326 SvgaFlush(pDevExt->pGa->hw.pSvga); 1248 1327 1249 GALOG(("\n")); 1328 GALOG(("pDmaBuffer = %p, cbDmaBuffer = %u, cPatches = %u\n", 1329 pPatch->pDmaBuffer, pPatch->DmaBufferSubmissionEndOffset - pPatch->DmaBufferSubmissionStartOffset, 1330 pPatch->PatchLocationListSubmissionLength)); 1331 1332 /* The driver does not need to modify paging and present commands here. */ 1333 if (pPatch->Flags.Paging || pPatch->Flags.Present) 1334 return STATUS_SUCCESS; 1335 1336 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pPatch->hContext; 1337 1338 NTSTATUS Status; 1339 if (pContext->enmType == VBOXWDDM_CONTEXT_TYPE_GA_3D) 1340 Status = gaPatchGA3D(pDevExt, pPatch); 1341 #ifdef VBOX_WITH_VMSVGA3D_DX 1342 else if (pContext->enmType == VBOXWDDM_CONTEXT_TYPE_VMSVGA_D3D) 1343 Status = DxgkDdiDXPatch(pDevExt, pPatch); 1344 #endif 1345 else 1346 AssertFailedStmt(Status = STATUS_INVALID_PARAMETER); 1347 return Status; 1348 } 1349 1350 static NTSTATUS gaPatchGA3D(PVBOXMP_DEVEXT pDevExt, const DXGKARG_PATCH *pPatch) 1351 { 1352 RT_NOREF(pDevExt); 1250 1353 1251 1354 uint8_t *pu8DMABuffer = (uint8_t *)pPatch->pDmaBuffer + pPatch->DmaBufferSubmissionStartOffset; … … 1306 1409 pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset, cbPrivateData)); 1307 1410 1308 uint32_t c bDmaBufferSubmission = pSubmitCommand->DmaBufferSubmissionEndOffset - pSubmitCommand->DmaBufferSubmissionStartOffset;1411 uint32_t const cbDmaBufferSubmission = pSubmitCommand->DmaBufferSubmissionEndOffset - pSubmitCommand->DmaBufferSubmissionStartOffset; 1309 1412 uint32_t cDataBlocks = cbPrivateData / sizeof(GARENDERDATA); 1310 1413 … … 1322 1425 1323 1426 GARENDERDATA const *pRenderData = (GARENDERDATA *)pvPrivateData; 1427 uint32_t cbData = 0; 1324 1428 while (cDataBlocks--) 1325 1429 { 1326 1430 GALOG(("pRenderData %p: u32DataType %u, pvDmaBuffer %p, cbData %u\n", 1327 1431 pRenderData, pRenderData->u32DataType, pRenderData->pvDmaBuffer, pRenderData->cbData)); 1432 1433 cbData += pRenderData->cbData; 1328 1434 AssertReturn(cbDmaBufferSubmission >= pRenderData->cbData, STATUS_INVALID_PARAMETER); 1329 cbDmaBufferSubmission -= pRenderData->cbData; 1330 1331 void *pvDmaBuffer = NULL; 1332 if ( pRenderData->u32DataType == GARENDERDATA_TYPE_RENDER 1333 || pRenderData->u32DataType == GARENDERDATA_TYPE_FENCE) 1334 { 1335 if (pRenderData->u32DataType == GARENDERDATA_TYPE_RENDER) 1336 { 1337 pvDmaBuffer = pRenderData->pvDmaBuffer; 1338 AssertPtrReturn(pvDmaBuffer, STATUS_INVALID_PARAMETER); 1339 } 1340 1435 1436 if (pRenderData->pFenceObject) 1437 { 1341 1438 GAFENCEOBJECT * const pFO = pRenderData->pFenceObject; 1342 if (pFO) /* Can be NULL if the user mode driver does not need the fence for this buffer. */ 1343 { 1344 GALOG(("pFO = %p, u32FenceHandle = %d, Fence = %d\n", 1345 pFO, pFO->u32FenceHandle, pSubmitCommand->SubmissionFenceId)); 1346 1347 gaFenceObjectsLock(pGaDevExt); 1348 1349 Assert(pFO->u32FenceState == GAFENCE_STATE_IDLE); 1350 pFO->u32SubmissionFenceId = pSubmitCommand->SubmissionFenceId; 1351 pFO->u32FenceState = GAFENCE_STATE_SUBMITTED; 1352 pFO->u64SubmittedTS = RTTimeNanoTS(); 1353 1354 gaFenceObjectsUnlock(pGaDevExt); 1355 } 1356 } 1357 else if (pRenderData->u32DataType == GARENDERDATA_TYPE_PRESENT) 1358 { 1359 pvDmaBuffer = pRenderData->pvDmaBuffer; 1360 AssertPtrReturn(pvDmaBuffer, STATUS_INVALID_PARAMETER); 1361 } 1362 else if (pRenderData->u32DataType == GARENDERDATA_TYPE_PAGING) 1363 { 1364 pvDmaBuffer = pRenderData->pvDmaBuffer; 1365 AssertPtrReturn(pvDmaBuffer, STATUS_INVALID_PARAMETER); 1366 } 1367 else 1368 { 1369 AssertFailedReturn(STATUS_INVALID_PARAMETER); 1370 } 1371 1372 if (pGaDevExt->hw.pSvga->pCBState) 1373 { 1374 if (pRenderData->cbData && pvDmaBuffer) 1375 { 1376 PVMSVGACB pCB; 1377 NTSTATUS Status = SvgaCmdBufAllocUMD(pGaDevExt->hw.pSvga, pSubmitCommand->DmaBufferPhysicalAddress, 1378 pSubmitCommand->DmaBufferSize, pRenderData->cbData, 1379 SVGA3D_INVALID_ID, &pCB); 1380 GALOG(("Allocated UMD buffer %p\n", pCB)); 1381 if (NT_SUCCESS(Status)) 1382 { 1383 Status = SvgaCmdBufSubmitUMD(pGaDevExt->hw.pSvga, pCB); 1384 Assert(NT_SUCCESS(Status)); RT_NOREF(Status); 1385 } 1386 } 1387 } 1388 else if (pvDmaBuffer) 1389 { 1390 Assert(pSubmitCommand->DmaBufferSegmentId == 0); 1391 1392 uint32_t const cbSubmit = pRenderData->cbData; 1393 if (cbSubmit) 1394 { 1395 /* Copy DmaBuffer to Fifo. */ 1396 void *pvCmd = SvgaFifoReserve(pGaDevExt->hw.pSvga, cbSubmit); 1397 AssertPtrReturn(pvCmd, STATUS_INSUFFICIENT_RESOURCES); 1398 1399 /* pvDmaBuffer is the actual address of the current data block. 1400 * Therefore do not use pSubmitCommand->DmaBufferSubmissionStartOffset here. 1401 */ 1402 memcpy(pvCmd, pvDmaBuffer, cbSubmit); 1403 SvgaFifoCommit(pGaDevExt->hw.pSvga, cbSubmit); 1404 } 1405 else 1406 { 1407 /* 'Paging' buffers can be empty, implementation is incomplete. See GaDxgkDdiBuildPagingBuffer. */ 1408 if (pSubmitCommand->Flags.Paging == 0) 1409 { 1410 LogRelMax(16, ("WDDM: Zero sized command buffer. Flags 0x%x, type %d\n", pSubmitCommand->Flags.Value, pRenderData->u32DataType)); 1411 AssertFailed(); 1412 } 1413 } 1439 GALOG(("pFO = %p, u32FenceHandle = %d, Fence = %d\n", 1440 pFO, pFO->u32FenceHandle, pSubmitCommand->SubmissionFenceId)); 1441 1442 gaFenceObjectsLock(pGaDevExt); 1443 1444 Assert(pFO->u32FenceState == GAFENCE_STATE_IDLE); 1445 pFO->u32SubmissionFenceId = pSubmitCommand->SubmissionFenceId; 1446 pFO->u32FenceState = GAFENCE_STATE_SUBMITTED; 1447 pFO->u64SubmittedTS = RTTimeNanoTS(); 1448 1449 gaFenceObjectsUnlock(pGaDevExt); 1414 1450 } 1415 1451 … … 1427 1463 1428 1464 ++pRenderData; 1465 } 1466 1467 if (cbDmaBufferSubmission) 1468 { 1469 if (pGaDevExt->hw.pSvga->pCBState) 1470 { 1471 PVMSVGACONTEXT pSvgaContext = pContext->pSvgaContext; 1472 uint32_t const cid = (pSvgaContext && pSvgaContext->fDXContext) ? pSvgaContext->u32Cid : SVGA3D_INVALID_ID; 1473 1474 PHYSICAL_ADDRESS phys = pSubmitCommand->DmaBufferPhysicalAddress; 1475 phys.QuadPart += pSubmitCommand->DmaBufferSubmissionStartOffset; 1476 1477 PVMSVGACB pCB; 1478 NTSTATUS Status = SvgaCmdBufAllocUMD(pGaDevExt->hw.pSvga, phys, 1479 pSubmitCommand->DmaBufferSize - pSubmitCommand->DmaBufferSubmissionStartOffset, 1480 cbDmaBufferSubmission, cid, &pCB); 1481 GALOG(("Allocated UMD buffer %p\n", pCB)); 1482 if (NT_SUCCESS(Status)) 1483 { 1484 Status = SvgaCmdBufSubmitUMD(pGaDevExt->hw.pSvga, pCB); 1485 Assert(NT_SUCCESS(Status)); RT_NOREF(Status); 1486 } 1487 } 1488 else 1489 { 1490 Assert(pSubmitCommand->DmaBufferSegmentId == 0); 1491 1492 /* This requires the virtual address of the buffer, which is stored in RenderData. */ 1493 if (cbPrivateData >= sizeof(GARENDERDATA)) 1494 { 1495 pRenderData = (GARENDERDATA *)pvPrivateData; 1496 if (pRenderData->pvDmaBuffer) 1497 { 1498 void *pvDmaBuffer = (uint8_t *)pRenderData->pvDmaBuffer + pSubmitCommand->DmaBufferSubmissionStartOffset; 1499 uint32_t const cbSubmit = cbDmaBufferSubmission; 1500 1501 /* Copy DmaBuffer to Fifo. */ 1502 void *pvCmd = SvgaFifoReserve(pGaDevExt->hw.pSvga, cbSubmit); 1503 AssertPtrReturn(pvCmd, STATUS_INSUFFICIENT_RESOURCES); 1504 1505 /* pvDmaBuffer is the actual address of the current data block. 1506 * Therefore do not use pSubmitCommand->DmaBufferSubmissionStartOffset here. 1507 */ 1508 memcpy(pvCmd, pvDmaBuffer, cbSubmit); 1509 SvgaFifoCommit(pGaDevExt->hw.pSvga, cbSubmit); 1510 } 1511 } 1512 } 1429 1513 } 1430 1514 … … 1761 1845 } 1762 1846 1847 PVMSVGACONTEXT pSvgaContext = pContext->pSvgaContext; 1848 if (!pSvgaContext) 1849 { 1850 Status = STATUS_NOT_SUPPORTED; 1851 break; 1852 } 1853 1763 1854 VBOXDISPIFESCAPE_GAGETCID *pGaGetCid = (VBOXDISPIFESCAPE_GAGETCID *)pEscapeHdr; 1764 pGaGetCid->u32Cid = p Context->u32Cid;1855 pGaGetCid->u32Cid = pSvgaContext->u32Cid; 1765 1856 Status = STATUS_SUCCESS; 1766 1857 break; -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.h
r93115 r94881 113 113 NTSTATUS GaVidPnSourceCheckPos(PVBOXMP_DEVEXT pDevExt, UINT iSource); 114 114 115 #ifdef VBOX_WITH_VMSVGA3D_DX 116 bool SvgaIsDXSupported(PVBOXMP_DEVEXT pDevExt); 117 NTSTATUS APIENTRY DxgkDdiDXCreateAllocation(CONST HANDLE hAdapter, DXGKARG_CREATEALLOCATION *pCreateAllocation); 118 NTSTATUS APIENTRY DxgkDdiDXDestroyAllocation(CONST HANDLE hAdapter, CONST DXGKARG_DESTROYALLOCATION *pDestroyAllocation); 119 NTSTATUS APIENTRY DxgkDdiDXDescribeAllocation(CONST HANDLE hAdapter, DXGKARG_DESCRIBEALLOCATION *pDescribeAllocation); 120 NTSTATUS APIENTRY DxgkDdiDXRender(PVBOXWDDM_CONTEXT pContext, DXGKARG_RENDER *pRender); 121 NTSTATUS APIENTRY DxgkDdiDXPresent(const HANDLE hContext, DXGKARG_PRESENT *pPresent); 122 NTSTATUS APIENTRY DxgkDdiDXBuildPagingBuffer(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer); 123 NTSTATUS APIENTRY DxgkDdiDXPatch(PVBOXMP_DEVEXT pDevExt, const DXGKARG_PATCH *pPatch); 124 #endif /* VBOX_WITH_VMSVGA3D_DX */ 125 115 126 #endif /* !GA_INCLUDED_SRC_WINNT_Graphics_Video_mp_wddm_gallium_VBoxMPGaWddm_h */
Note:
See TracChangeset
for help on using the changeset viewer.