Changeset 94927 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPDX.cpp
- Timestamp:
- May 9, 2022 6:48:47 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPDX.cpp
r94904 r94927 27 27 #include "SvgaHw.h" 28 28 29 #include <iprt/memobj.h> 29 30 30 31 bool SvgaIsDXSupported(PVBOXMP_DEVEXT pDevExt) … … 36 37 37 38 38 static NTSTATUS svgaCreateSurfaceForAllocation(PVBOXWDDM_EXT_GA pGaDevExt, PVBOXWDDM_ALLOCATION pAllocation) 39 { 40 VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga; 39 static NTSTATUS svgaCreateSurfaceForAllocation(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation) 40 { 41 41 NTSTATUS Status = SvgaSurfaceIdAlloc(pSvga, &pAllocation->dx.sid); 42 Assert(NT_SUCCESS(Status)); 42 43 if (NT_SUCCESS(Status)) 43 44 { … … 58 59 } 59 60 else 60 Status = STATUS_INSUFFICIENT_RESOURCES; 61 } 61 AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES); 62 63 if (NT_SUCCESS(Status)) 64 { 65 if (pAllocation->dx.SegmentId == 3) 66 { 67 pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_BIND_GB_SURFACE, sizeof(SVGA3dCmdBindGBSurface), SVGA3D_INVALID_ID); 68 if (pvCmd) 69 { 70 SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pvCmd; 71 pCmd->sid = pAllocation->dx.sid; 72 pCmd->mobid = pAllocation->dx.mobid; 73 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdBindGBSurface)); 74 } 75 else 76 AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES); 77 } 78 } 79 } 80 81 if (!NT_SUCCESS(Status)) 82 SvgaSurfaceIdFree(pSvga, pAllocation->dx.sid); 83 62 84 return Status; 63 85 } 64 86 65 87 88 static void svgaFreeGBMobForAllocation(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation) 89 { 90 AssertReturnVoid(pAllocation->dx.SegmentId == 3); 91 92 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DESTROY_GB_MOB, sizeof(SVGA3dCmdDestroyGBMob), SVGA3D_INVALID_ID); 93 if (pvCmd) 94 { 95 SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pvCmd; 96 pCmd->mobid = VMSVGAMOB_ID(pAllocation->dx.gb.pMob); 97 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDestroyGBMob)); 98 } 99 100 if (pAllocation->dx.gb.pMob) 101 { 102 SvgaMobFree(pSvga, pAllocation->dx.gb.pMob); 103 pAllocation->dx.gb.pMob = NULL; 104 } 105 106 if (pAllocation->dx.gb.hMemObjGB != NIL_RTR0MEMOBJ) 107 { 108 RTR0MemObjFree(pAllocation->dx.gb.hMemObjGB, true); 109 pAllocation->dx.gb.hMemObjGB = NIL_RTR0MEMOBJ; 110 } 111 112 pAllocation->dx.mobid = SVGA3D_INVALID_ID; 113 } 114 115 116 static NTSTATUS svgaCreateGBMobForAllocation(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation) 117 { 118 AssertReturn(pAllocation->dx.SegmentId == 3, STATUS_INVALID_PARAMETER); 119 120 uint32_t const cbGB = RT_ALIGN_32(pAllocation->dx.desc.cbAllocation, PAGE_SIZE); 121 122 /* Allocate guest backing pages. */ 123 int rc = RTR0MemObjAllocPageTag(&pAllocation->dx.gb.hMemObjGB, cbGB, false /* executable R0 mapping */, "VMSVGAGB"); 124 AssertRCReturn(rc, STATUS_INSUFFICIENT_RESOURCES); 125 126 /* Allocate a new mob. */ 127 NTSTATUS Status = SvgaMobCreate(pSvga, &pAllocation->dx.gb.pMob, cbGB >> PAGE_SHIFT, 0); 128 Assert(NT_SUCCESS(Status)); 129 if (NT_SUCCESS(Status)) 130 { 131 Status = SvgaMobFillPageTableForMemObj(pSvga, pAllocation->dx.gb.pMob, pAllocation->dx.gb.hMemObjGB); 132 Assert(NT_SUCCESS(Status)); 133 if (NT_SUCCESS(Status)) 134 { 135 pAllocation->dx.mobid = VMSVGAMOB_ID(pAllocation->dx.gb.pMob); 136 137 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DEFINE_GB_MOB64, sizeof(SVGA3dCmdDefineGBMob64), SVGA3D_INVALID_ID); 138 if (pvCmd) 139 { 140 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pvCmd; 141 pCmd->mobid = VMSVGAMOB_ID(pAllocation->dx.gb.pMob); 142 pCmd->ptDepth = pAllocation->dx.gb.pMob->enmMobFormat; 143 pCmd->base = pAllocation->dx.gb.pMob->base; 144 pCmd->sizeInBytes = pAllocation->dx.gb.pMob->cbMob; 145 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDefineGBMob64)); 146 } 147 else 148 AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES); 149 150 if (NT_SUCCESS(Status)) 151 return STATUS_SUCCESS; 152 } 153 } 154 155 svgaFreeGBMobForAllocation(pSvga, pAllocation); 156 return Status; 157 } 158 159 66 160 static NTSTATUS svgaCreateAllocationSurface(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation, DXGK_ALLOCATIONINFO *pAllocationInfo) 67 161 { 68 NTSTATUS Status = svgaCreateSurfaceForAllocation(pDevExt->pGa, pAllocation); 69 AssertReturn(NT_SUCCESS(Status), Status); 162 VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga; 70 163 71 164 /* Fill data for WDDM. */ … … 87 180 // pAllocationInfo->SupportedWriteSegmentSet = 1; /* VRAM */ 88 181 // pAllocationInfo->Flags.CpuVisible = 1; 182 // 183 // pAllocation->dx.SegmentId = 1; 89 184 // } 90 185 // else … … 93 188 pAllocationInfo->SupportedReadSegmentSet = 4; /* Host */ 94 189 pAllocationInfo->SupportedWriteSegmentSet = 4; /* Host */ 190 191 pAllocation->dx.SegmentId = 3; 95 192 } 96 193 } … … 103 200 pAllocationInfo->SupportedWriteSegmentSet = 2; /* Aperture */ 104 201 pAllocationInfo->Flags.CpuVisible = 1; 202 203 pAllocation->dx.SegmentId = 2; 105 204 } 106 205 else if (pAllocation->dx.desc.surfaceInfo.surfaceFlags … … 113 212 pAllocationInfo->SupportedWriteSegmentSet = 2; /* Aperture */ 114 213 pAllocationInfo->Flags.CpuVisible = 1; 214 215 pAllocation->dx.SegmentId = 2; 115 216 } 116 217 pAllocationInfo->EvictionSegmentSet = 0; … … 119 220 pAllocationInfo->pAllocationUsageHint = NULL; 120 221 pAllocationInfo->AllocationPriority = D3DDDI_ALLOCATIONPRIORITY_NORMAL; 222 223 /* Allocations in the host VRAM still need guest backing. */ 224 NTSTATUS Status; 225 if (pAllocation->dx.SegmentId == 3) 226 { 227 Status = svgaCreateGBMobForAllocation(pSvga, pAllocation); 228 if (NT_SUCCESS(Status)) 229 { 230 Status = svgaCreateSurfaceForAllocation(pSvga, pAllocation); 231 if (!NT_SUCCESS(Status)) 232 svgaFreeGBMobForAllocation(pSvga, pAllocation); 233 } 234 } 235 else 236 Status = svgaCreateSurfaceForAllocation(pSvga, pAllocation); 237 121 238 return Status; 122 239 } … … 144 261 145 262 146 static NTSTATUS svgaDestroyAllocationSurface(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation) 147 { 148 VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga; 263 static NTSTATUS svgaDestroyAllocationSurface(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation) 264 { 149 265 NTSTATUS Status = STATUS_SUCCESS; 150 266 if (pAllocation->dx.sid != SVGA3D_INVALID_ID) 151 267 { 152 void *pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DESTROY_GB_SURFACE, sizeof(SVGA3dCmdDestroyGBSurface), SVGA3D_INVALID_ID); 268 void *pvCmd; 269 if (pAllocation->dx.SegmentId == 3) 270 { 271 pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_BIND_GB_SURFACE, sizeof(SVGA3dCmdBindGBSurface), SVGA3D_INVALID_ID); 272 if (pvCmd) 273 { 274 SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pvCmd; 275 pCmd->sid = pAllocation->dx.sid; 276 pCmd->mobid = SVGA3D_INVALID_ID; 277 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdBindGBSurface)); 278 } 279 } 280 281 pvCmd = SvgaCmdBuf3dCmdReserve(pSvga, SVGA_3D_CMD_DESTROY_GB_SURFACE, sizeof(SVGA3dCmdDestroyGBSurface), SVGA3D_INVALID_ID); 153 282 if (pvCmd) 154 283 { … … 157 286 SvgaCmdBufCommit(pSvga, sizeof(SVGA3dCmdDestroyGBSurface)); 158 287 } 159 else 160 Status = STATUS_INSUFFICIENT_RESOURCES; 161 162 if (NT_SUCCESS(Status)) 163 Status = SvgaSurfaceIdFree(pSvga, pAllocation->dx.sid); 288 289 Status = SvgaSurfaceIdFree(pSvga, pAllocation->dx.sid); 290 291 if (pAllocation->dx.SegmentId == 3) 292 svgaFreeGBMobForAllocation(pSvga, pAllocation); 293 294 pAllocation->dx.sid = SVGA3D_INVALID_ID; 164 295 } 165 296 return Status; … … 167 298 168 299 169 static NTSTATUS svgaDestroyAllocationShaders( PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation)170 { 171 VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga;300 static NTSTATUS svgaDestroyAllocationShaders(VBOXWDDM_EXT_VMSVGA *pSvga, PVBOXWDDM_ALLOCATION pAllocation) 301 { 302 NTSTATUS Status = STATUS_SUCCESS; 172 303 if (pAllocation->dx.mobid != SVGA3D_INVALID_ID) 173 304 { … … 180 311 } 181 312 else 182 AssertFailedReturn(STATUS_INSUFFICIENT_RESOURCES); 183 } 184 return STATUS_SUCCESS; 313 AssertFailedStmt(Status = STATUS_INSUFFICIENT_RESOURCES); 314 315 pAllocation->dx.mobid = SVGA3D_INVALID_ID; 316 } 317 return Status; 185 318 } 186 319 … … 207 340 pAllocation->dx.sid = SVGA3D_INVALID_ID; 208 341 pAllocation->dx.mobid = SVGA3D_INVALID_ID; 342 pAllocation->dx.SegmentId = 0; 343 pAllocation->dx.pMDL = 0; 209 344 210 345 /* Legacy. Unused. */ … … 237 372 238 373 if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE) 239 Status = svgaDestroyAllocationSurface(pDevExt , pAllocation);374 Status = svgaDestroyAllocationSurface(pDevExt->pGa->hw.pSvga, pAllocation); 240 375 else if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SHADERS) 241 Status = svgaDestroyAllocationShaders(pDevExt , pAllocation);376 Status = svgaDestroyAllocationShaders(pDevExt->pGa->hw.pSvga, pAllocation); 242 377 else 243 378 AssertFailedReturn(STATUS_INVALID_PARAMETER); … … 309 444 { 310 445 /* DEFAULT resources only require the sid, because they exist outside the guest. */ 311 if (pAllocation->dx.sid != SVGA3D_INVALID_ID) 312 { 313 *(uint32_t *)pPatchAddress = pAllocation->dx.sid; 314 continue; 315 } 446 Assert(pAllocation->dx.sid != SVGA3D_INVALID_ID); 447 Assert(pAllocation->dx.mobid != SVGA3D_INVALID_ID); 448 Assert(pAllocation->dx.SegmentId == 3); 449 450 *(uint32_t *)pPatchAddress = pAllocation->dx.sid; 451 continue; 316 452 } 317 453 else 318 454 { 319 /* For Aperture segment, the surface need a mob too . */455 /* For Aperture segment, the surface need a mob too, which must be created in BuildPagingBuffer. */ 320 456 if ( pAllocation->dx.sid != SVGA3D_INVALID_ID 321 457 && pAllocation->dx.mobid != SVGA3D_INVALID_ID) … … 640 776 641 777 778 static NTSTATUS svgaPagingFill(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer, uint32_t *pcbCommands) 779 { 780 VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga; 781 RT_NOREF(pSvga); 782 783 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Fill.hAllocation; 784 AssertReturn(pAllocation, STATUS_INVALID_PARAMETER); 785 786 AssertReturn((pBuildPagingBuffer->Fill.FillSize & 3) == 0, STATUS_INVALID_PARAMETER); 787 AssertReturn( pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_D3D 788 || pBuildPagingBuffer->Fill.Destination.SegmentId == pAllocation->dx.SegmentId, STATUS_INVALID_PARAMETER); 789 790 NTSTATUS Status = STATUS_SUCCESS; 791 switch (pBuildPagingBuffer->Fill.Destination.SegmentId) 792 { 793 case 1: /* VRAM */ 794 { 795 uint64_t const offVRAM = pBuildPagingBuffer->Fill.Destination.SegmentAddress.QuadPart; 796 AssertReturn( offVRAM < pDevExt->cbVRAMCpuVisible 797 && pBuildPagingBuffer->Fill.FillSize <= pDevExt->cbVRAMCpuVisible - offVRAM, STATUS_INVALID_PARAMETER); 798 ASMMemFill32((uint8_t *)pDevExt->pvVisibleVram + offVRAM, pBuildPagingBuffer->Fill.FillSize, pBuildPagingBuffer->Fill.FillPattern); 799 break; 800 } 801 case 2: /* Aperture */ 802 case 3: /* Host */ 803 { 804 if (pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_D3D) 805 break; 806 807 void *pvDst; 808 if (pBuildPagingBuffer->Fill.Destination.SegmentId == 3) 809 { 810 AssertReturn(pAllocation->dx.gb.hMemObjGB != NIL_RTR0MEMOBJ, STATUS_INVALID_PARAMETER); 811 pvDst = RTR0MemObjAddress(pAllocation->dx.gb.hMemObjGB); 812 } 813 else 814 { 815 AssertReturn(pAllocation->dx.pMDL != NULL, STATUS_INVALID_PARAMETER); 816 DEBUG_BREAKPOINT_TEST(); 817 pvDst = MmGetSystemAddressForMdlSafe(pAllocation->dx.pMDL, NormalPagePriority); 818 AssertReturn(pvDst, STATUS_INSUFFICIENT_RESOURCES); 819 } 820 821 /* Fill the guest backing pages. */ 822 uint32_t const cbFill = RT_MIN(pBuildPagingBuffer->Fill.FillSize, pAllocation->dx.desc.cbAllocation); 823 ASMMemFill32(pvDst, cbFill, pBuildPagingBuffer->Fill.FillPattern); 824 825 /* Emit UPDATE_GB_SURFACE */ 826 uint8_t *pu8Cmd = (uint8_t *)pBuildPagingBuffer->pDmaBuffer; 827 uint32_t cbRequired = sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdUpdateGBSurface); 828 if (pBuildPagingBuffer->DmaSize < cbRequired) 829 { 830 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 831 break; 832 } 833 834 SVGA3dCmdHeader *pHdr = (SVGA3dCmdHeader *)pu8Cmd; 835 pHdr->id = SVGA_3D_CMD_UPDATE_GB_SURFACE; 836 pHdr->size = sizeof(SVGA3dCmdUpdateGBSurface); 837 pu8Cmd += sizeof(*pHdr); 838 839 SVGA3dCmdUpdateGBSurface *pCmd = (SVGA3dCmdUpdateGBSurface *)pu8Cmd; 840 pCmd->sid = pAllocation->dx.sid; 841 pu8Cmd += sizeof(*pCmd); 842 843 *pcbCommands = (uintptr_t)pu8Cmd - (uintptr_t)pBuildPagingBuffer->pDmaBuffer; 844 break; 845 } 846 default: 847 AssertFailedReturn(STATUS_INVALID_PARAMETER); 848 } 849 return Status; 850 } 851 852 853 static NTSTATUS svgaPagingDiscardContent(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer, uint32_t *pcbCommands) 854 { 855 VBOXWDDM_EXT_VMSVGA *pSvga = pDevExt->pGa->hw.pSvga; 856 RT_NOREF(pSvga); 857 858 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->DiscardContent.hAllocation; 859 AssertReturn(pAllocation, STATUS_INVALID_PARAMETER); 860 AssertReturn( pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_D3D 861 || pBuildPagingBuffer->DiscardContent.SegmentId == pAllocation->dx.SegmentId, STATUS_INVALID_PARAMETER); 862 863 if (pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_D3D) 864 return STATUS_SUCCESS; 865 866 if (pAllocation->dx.desc.enmAllocationType == VBOXDXALLOCATIONTYPE_SURFACE) 867 { 868 /* Emit INVALIDATE_GB_SURFACE */ 869 uint8_t *pu8Cmd = (uint8_t *)pBuildPagingBuffer->pDmaBuffer; 870 uint32_t cbRequired = sizeof(SVGA3dCmdHeader) + sizeof(SVGA3dCmdInvalidateGBSurface); 871 if (pBuildPagingBuffer->DmaSize < cbRequired) 872 return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; 873 874 SVGA3dCmdHeader *pHdr = (SVGA3dCmdHeader *)pu8Cmd; 875 pHdr->id = SVGA_3D_CMD_INVALIDATE_GB_SURFACE; 876 pHdr->size = sizeof(SVGA3dCmdInvalidateGBSurface); 877 pu8Cmd += sizeof(*pHdr); 878 879 SVGA3dCmdUpdateGBSurface *pCmd = (SVGA3dCmdUpdateGBSurface *)pu8Cmd; 880 pCmd->sid = pAllocation->dx.sid; 881 pu8Cmd += sizeof(*pCmd); 882 883 *pcbCommands = (uintptr_t)pu8Cmd - (uintptr_t)pBuildPagingBuffer->pDmaBuffer; 884 } 885 886 return STATUS_SUCCESS; 887 } 888 889 642 890 static NTSTATUS svgaPagingMapApertureSegment(PVBOXMP_DEVEXT pDevExt, DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer, uint32_t *pcbCommands) 643 891 { … … 655 903 if (pAllocation->dx.mobid != SVGA3D_INVALID_ID) 656 904 { 657 AssertFailed();905 DEBUG_BREAKPOINT_TEST(); 658 906 return STATUS_SUCCESS; 659 907 } … … 826 1074 case DXGK_OPERATION_FILL: 827 1075 { 828 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Fill.hAllocation; 829 RT_NOREF(pAllocation); 830 DEBUG_BREAKPOINT_TEST(); 1076 Status = svgaPagingFill(pDevExt, pBuildPagingBuffer, &cbCommands); 831 1077 break; 832 1078 } 833 1079 case DXGK_OPERATION_DISCARD_CONTENT: 834 1080 { 835 DEBUG_BREAKPOINT_TEST();1081 Status = svgaPagingDiscardContent(pDevExt, pBuildPagingBuffer, &cbCommands); 836 1082 break; 837 1083 }
Note:
See TracChangeset
for help on using the changeset viewer.