Changeset 99855 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Video
- Timestamp:
- May 19, 2023 7:35:22 AM (21 months ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dx
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dx/VBoxDX.cpp
r98103 r99855 679 679 pResource->pKMResource = NULL; 680 680 pResource->uMap = 0; 681 pResource->pStagingResource = 0;682 681 RTListInit(&pResource->listSRV); 683 682 RTListInit(&pResource->listRTV); … … 689 688 690 689 691 bool vboxDXCreateResource(PVBOXDX_DEVICE pDevice, PVBOXDX_RESOURCE pResource, 692 const D3D11DDIARG_CREATERESOURCE *pCreateResource) 693 { 694 pResource->pKMResource = (PVBOXDXKMRESOURCE)RTMemAllocZ(sizeof(VBOXDXKMRESOURCE)); 695 AssertReturnStmt(pResource->pKMResource, vboxDXDeviceSetError(pDevice, E_OUTOFMEMORY), false); 696 690 static HRESULT dxAllocate(PVBOXDX_DEVICE pDevice, PVBOXDX_RESOURCE pResource, D3DKMT_HANDLE *phAllocation) 691 { 697 692 D3DDDI_ALLOCATIONINFO2 ddiAllocationInfo; 698 693 RT_ZERO(ddiAllocationInfo); … … 716 711 HRESULT hr = pDevice->pRTCallbacks->pfnAllocateCb(pDevice->hRTDevice.handle, &ddiAllocate); 717 712 LogFlowFunc((" pfnAllocateCb returned %d, hKMResource 0x%X, hAllocation 0x%X", hr, ddiAllocate.hKMResource, ddiAllocationInfo.hAllocation)); 713 714 if (SUCCEEDED(hr)) 715 *phAllocation = ddiAllocationInfo.hAllocation; 716 717 return hr; 718 } 719 720 721 bool vboxDXCreateResource(PVBOXDX_DEVICE pDevice, PVBOXDX_RESOURCE pResource, 722 const D3D11DDIARG_CREATERESOURCE *pCreateResource) 723 { 724 pResource->pKMResource = (PVBOXDXKMRESOURCE)RTMemAllocZ(sizeof(VBOXDXKMRESOURCE)); 725 AssertReturnStmt(pResource->pKMResource, vboxDXDeviceSetError(pDevice, E_OUTOFMEMORY), false); 726 727 D3DKMT_HANDLE hAllocation = 0; 728 HRESULT hr = dxAllocate(pDevice, pResource, &hAllocation); 729 if (FAILED(hr)) 730 { 731 /* Might be not enough memory due to temporary staging buffers. */ 732 vboxDXFlush(pDevice, true); 733 hr = dxAllocate(pDevice, pResource, &hAllocation); 734 } 718 735 AssertReturnStmt(SUCCEEDED(hr), RTMemFree(pResource->pKMResource); vboxDXDeviceSetError(pDevice, hr), false); 719 736 720 737 pResource->pKMResource->pResource = pResource; 721 pResource->pKMResource->hAllocation = ddiAllocationInfo.hAllocation;738 pResource->pKMResource->hAllocation = hAllocation; 722 739 RTListAppend(&pDevice->listResources, &pResource->pKMResource->nodeResource); 723 740 … … 748 765 memset(ddiLock.pData, 0, pResource->AllocationDesc.cbAllocation); 749 766 750 D3DKMT_HANDLEhAllocation = vboxDXGetAllocation(pResource);767 hAllocation = vboxDXGetAllocation(pResource); 751 768 752 769 D3DDDICB_UNLOCK ddiUnlock; … … 787 804 pResource->cSubresources = pDesc->surfaceInfo.numMipLevels * pDesc->surfaceInfo.arraySize; 788 805 pResource->uMap = 0; 789 pResource->pStagingResource = 0;790 806 RTListInit(&pResource->listSRV); 791 807 RTListInit(&pResource->listRTV); … … 800 816 801 817 802 static bool dxDestroyResource(PVBOXDX_DEVICE pDevice, PVBOXDX_RESOURCE pResource) 803 { 818 /* Destroy a resource created by the system (via DDI). Primary resources are freed immediately. 819 * Other resources are moved to the deferred destruction queue (pDevice->listDestroyedResources). 820 * The 'pResource' structure will be deleted by D3D runtime in any case. 821 */ 822 void vboxDXDestroyResource(PVBOXDX_DEVICE pDevice, PVBOXDX_RESOURCE pResource) 823 { 824 /* "the driver must process its deferred-destruction queue during calls to its Flush(D3D10) function" 825 * "Primary destruction cannot be deferred by the Direct3D runtime, and the driver must call 826 * the pfnDeallocateCb function appropriately within a call to the driver's DestroyResource(D3D10) function." 827 */ 828 804 829 Assert(RTListIsEmpty(&pResource->listSRV)); 805 830 Assert(RTListIsEmpty(&pResource->listRTV)); … … 807 832 Assert(RTListIsEmpty(&pResource->listUAV)); 808 833 809 if (pResource->pStagingResource) 810 { 811 dxDestroyResource(pDevice, pResource->pStagingResource); 812 RTMemFree(pResource->pStagingResource); 813 pResource->pStagingResource = NULL; 814 } 815 816 D3DKMT_HANDLE const hAllocation = pResource->pKMResource->hAllocation; 817 RTMemFree(pResource->pKMResource); 818 819 if (!RT_BOOL(pResource->AllocationDesc.resourceInfo.MiscFlags & D3D10_DDI_RESOURCE_MISC_SHARED)) 820 { 834 /* Remove from the list of active resources. */ 835 RTListNodeRemove(&pResource->pKMResource->nodeResource); 836 837 if (pResource->AllocationDesc.fPrimary) 838 { 839 /* Delete immediately. */ 821 840 D3DDDICB_DEALLOCATE ddiDeallocate; 822 841 RT_ZERO(ddiDeallocate); 823 ddiDeallocate.hResource = NULL;842 //ddiDeallocate.hResource = NULL; 824 843 ddiDeallocate.NumAllocations = 1; 825 ddiDeallocate.HandleList = & hAllocation;844 ddiDeallocate.HandleList = &pResource->pKMResource->hAllocation; 826 845 827 846 HRESULT hr = pDevice->pRTCallbacks->pfnDeallocateCb(pDevice->hRTDevice.handle, &ddiDeallocate); 828 847 LogFlowFunc(("pfnDeallocateCb returned %d", hr)); 829 AssertReturnStmt(SUCCEEDED(hr), vboxDXDeviceSetError(pDevice, hr), false); 830 } 831 832 return true; 833 } 834 835 836 bool vboxDXDestroyResource(PVBOXDX_DEVICE pDevice, PVBOXDX_RESOURCE pResource) 837 { 838 /* "the driver must process its deferred-destruction queue during calls to its Flush(D3D10) function" 839 * "Primary destruction cannot be deferred by the Direct3D runtime, and the driver must call 840 * the pfnDeallocateCb function appropriately within a call to the driver's DestroyResource(D3D10) function." 841 */ 842 843 if (pResource->pStagingResource) 844 { 845 vboxDXDestroyResource(pDevice, pResource->pStagingResource); 846 RTMemFree(pResource->pStagingResource); 847 pResource->pStagingResource = NULL; 848 } 849 850 /* Remove from the list of active resources. */ 851 RTListNodeRemove(&pResource->pKMResource->nodeResource); 852 853 if (pResource->AllocationDesc.fPrimary) 854 return dxDestroyResource(pDevice, pResource); 855 856 if (!RT_BOOL(pResource->AllocationDesc.resourceInfo.MiscFlags & D3D10_DDI_RESOURCE_MISC_SHARED)) 857 { 858 /* Set the resource for deferred destruction. */ 859 pResource->pKMResource->pResource = NULL; 860 RTListAppend(&pDevice->listDestroyedResources, &pResource->pKMResource->nodeResource); 848 AssertStmt(SUCCEEDED(hr), vboxDXDeviceSetError(pDevice, hr)); 849 850 RTMemFree(pResource->pKMResource); 861 851 } 862 852 else 863 853 { 864 /* Opened shared resources must not be actually deleted. Just free the KM structure. */ 865 RTMemFree(pResource->pKMResource); 866 } 867 868 return true; 854 if (!RT_BOOL(pResource->AllocationDesc.resourceInfo.MiscFlags & D3D10_DDI_RESOURCE_MISC_SHARED)) 855 { 856 /* Set the resource for deferred destruction. */ 857 pResource->pKMResource->pResource = NULL; 858 RTListAppend(&pDevice->listDestroyedResources, &pResource->pKMResource->nodeResource); 859 } 860 else 861 { 862 /* Opened shared resources must not be actually deleted. Just free the KM structure. */ 863 RTMemFree(pResource->pKMResource); 864 } 865 } 869 866 } 870 867 … … 2233 2230 2234 2231 2235 static bool vboxDXCreateStagingBuffer(PVBOXDX_DEVICE pDevice, PVBOXDX_RESOURCE pResource)2232 static PVBOXDX_RESOURCE vboxDXCreateStagingBuffer(PVBOXDX_DEVICE pDevice, UINT cbAllocation) 2236 2233 { 2237 2234 PVBOXDX_RESOURCE pStagingResource = (PVBOXDX_RESOURCE)RTMemAlloc(sizeof(VBOXDX_RESOURCE) … … 2242 2239 D3D10DDI_MIPINFO mipInfo; 2243 2240 2244 /* Buffer is large enough to hold the entire resource. */ 2245 mipInfo.TexelWidth = pResource->AllocationDesc.cbAllocation; 2241 mipInfo.TexelWidth = cbAllocation; 2246 2242 mipInfo.TexelHeight = 1; 2247 2243 mipInfo.TexelDepth = 1; … … 2272 2268 { 2273 2269 if (vboxDXCreateResource(pDevice, pStagingResource, &createResource)) 2274 { 2275 pResource->pStagingResource = pStagingResource; 2276 return true; 2277 } 2270 return pStagingResource; 2278 2271 } 2279 2272 RTMemFree(pStagingResource); 2280 return false; 2273 vboxDXDeviceSetError(pDevice, E_OUTOFMEMORY); 2274 return NULL; 2275 } 2276 2277 2278 static HRESULT dxReclaimStagingAllocation(PVBOXDX_DEVICE pDevice, PVBOXDXKMRESOURCE pStagingKMResource) 2279 { 2280 BOOL fDiscarded = FALSE; 2281 D3DDDICB_RECLAIMALLOCATIONS ddiReclaimAllocations; 2282 RT_ZERO(ddiReclaimAllocations); 2283 ddiReclaimAllocations.pResources = NULL; 2284 ddiReclaimAllocations.HandleList = &pStagingKMResource->hAllocation; 2285 ddiReclaimAllocations.pDiscarded = &fDiscarded; 2286 ddiReclaimAllocations.NumAllocations = 1; 2287 2288 HRESULT hr = pDevice->pRTCallbacks->pfnReclaimAllocationsCb(pDevice->hRTDevice.handle, &ddiReclaimAllocations); 2289 LogFlowFunc(("pfnReclaimAllocationsCb returned %d, fDiscarded %d", hr, fDiscarded)); 2290 Assert(SUCCEEDED(hr)); 2291 return hr; 2292 } 2293 2294 2295 static HRESULT dxOfferStagingAllocation(PVBOXDX_DEVICE pDevice, PVBOXDXKMRESOURCE pStagingKMResource) 2296 { 2297 D3DDDICB_OFFERALLOCATIONS ddiOfferAllocations; 2298 RT_ZERO(ddiOfferAllocations); 2299 ddiOfferAllocations.pResources = NULL; 2300 ddiOfferAllocations.HandleList = &pStagingKMResource->hAllocation; 2301 ddiOfferAllocations.NumAllocations = 1; 2302 ddiOfferAllocations.Priority = D3DDDI_OFFER_PRIORITY_LOW; 2303 2304 HRESULT hr = pDevice->pRTCallbacks->pfnOfferAllocationsCb(pDevice->hRTDevice.handle, &ddiOfferAllocations); 2305 LogFlowFunc(("pfnOfferAllocationsCb returned %d", hr)); 2306 Assert(SUCCEEDED(hr)); 2307 return hr; 2281 2308 } 2282 2309 … … 2295 2322 2296 2323 /* DEFAULT resources are updated via a staging buffer. */ 2297 if (!pDstResource->pStagingResource) 2298 { 2299 if (!vboxDXCreateStagingBuffer(pDevice, pDstResource)) 2300 return; 2301 } 2302 2324 2325 /* 2326 * A simple approach for now: allocate a staging buffer for each upload and delete the buffers after a flush. 2327 */ 2328 2329 /* 2330 * Allocate a staging buffer big enough to hold the entire subresource. 2331 */ 2332 uint32_t const cbStagingBuffer = vboxDXGetSubresourceSize(pDstResource, DstSubresource); 2333 PVBOXDX_RESOURCE pStagingBuffer = vboxDXCreateStagingBuffer(pDevice, cbStagingBuffer); 2334 if (!pStagingBuffer) 2335 return; 2336 2337 /* 2338 * Copy data to staging via map/unmap. 2339 */ 2303 2340 SVGA3dBox destBox; 2304 2341 if (pDstBox) … … 2320 2357 vboxDXGetResourceBoxDimensions(pDstResource, DstSubresource, &destBox, &offPixel, &cbRow, &cRows, &Depth); 2321 2358 2322 uint32_t const offSubresource = vboxDXGetSubresourceOffset(pDstResource, DstSubresource);2323 2324 2359 UINT cbRowPitch; 2325 2360 UINT cbDepthPitch; 2326 2361 vboxDXGetSubresourcePitch(pDstResource, DstSubresource, &cbRowPitch, &cbDepthPitch); 2327 2362 2328 if (!vboxDXUpdateStagingBufferUP(pDevice, p DstResource->pStagingResource,2329 off Subresource + offPixel, cbRow, cRows, cbRowPitch, Depth, cbDepthPitch,2363 if (!vboxDXUpdateStagingBufferUP(pDevice, pStagingBuffer, 2364 offPixel, cbRow, cRows, cbRowPitch, Depth, cbDepthPitch, 2330 2365 pSysMemUP, RowPitch, DepthPitch)) 2331 2366 return; 2332 2367 2368 /* 2369 * Copy from staging to destination. 2370 */ 2333 2371 /* Inform the host that the staging buffer has been updated. Part occupied by the DstSubresource. */ 2334 2372 SVGA3dBox box; 2335 box.x = offSubresource;2373 box.x = 0; 2336 2374 box.y = 0; 2337 2375 box.z = 0; 2338 box.w = vboxDXGetSubresourceSize(pDstResource, DstSubresource);2376 box.w = cbStagingBuffer; 2339 2377 box.h = 1; 2340 2378 box.d = 1; 2341 vgpu10UpdateSubResource(pDevice, vboxDXGetAllocation(p DstResource->pStagingResource), 0, &box);2379 vgpu10UpdateSubResource(pDevice, vboxDXGetAllocation(pStagingBuffer), 0, &box); 2342 2380 2343 2381 /* Issue SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER */ 2344 uint32 srcOffset = off Subresource + offPixel;2382 uint32 srcOffset = offPixel; 2345 2383 uint32 srcPitch = cbRowPitch; 2346 2384 uint32 srcSlicePitch = cbDepthPitch; 2347 vgpu10TransferFromBuffer(pDevice, vboxDXGetAllocation(p DstResource->pStagingResource), srcOffset, srcPitch, srcSlicePitch,2385 vgpu10TransferFromBuffer(pDevice, vboxDXGetAllocation(pStagingBuffer), srcOffset, srcPitch, srcSlicePitch, 2348 2386 vboxDXGetAllocation(pDstResource), DstSubresource, destBox); 2387 2388 RTListPrepend(&pDevice->listStagingResources, &pStagingBuffer->pKMResource->nodeStaging); 2349 2389 } 2350 2390 … … 3181 3221 3182 3222 3223 static void dxDeallocateStagingResources(PVBOXDX_DEVICE pDevice) 3224 { 3225 /* Move staging resources to the deferred destruction queue. */ 3226 PVBOXDXKMRESOURCE pKMResource, pNextKMResource; 3227 RTListForEachSafe(&pDevice->listStagingResources, pKMResource, pNextKMResource, VBOXDXKMRESOURCE, nodeStaging) 3228 { 3229 RTListNodeRemove(&pKMResource->nodeStaging); 3230 3231 PVBOXDX_RESOURCE pStagingResource = pKMResource->pResource; 3232 pKMResource->pResource = NULL; 3233 3234 Assert(pStagingResource->pKMResource == pKMResource); 3235 3236 /* Remove from the list of active resources. */ 3237 RTListNodeRemove(&pKMResource->nodeResource); 3238 RTListAppend(&pDevice->listDestroyedResources, &pKMResource->nodeResource); 3239 3240 /* Staging resources are allocated by the driver. */ 3241 RTMemFree(pStagingResource); 3242 } 3243 } 3244 3245 3183 3246 static void dxDestroyDeferredResources(PVBOXDX_DEVICE pDevice) 3184 3247 { … … 3186 3249 RTListForEachSafe(&pDevice->listDestroyedResources, pKMResource, pNext, VBOXDXKMRESOURCE, nodeResource) 3187 3250 { 3188 D3DKMT_HANDLE const hAllocation = pKMResource->hAllocation;3189 3251 RTListNodeRemove(&pKMResource->nodeResource); 3190 RTMemFree(pKMResource);3191 3252 3192 3253 D3DDDICB_DEALLOCATE ddiDeallocate; … … 3194 3255 //ddiDeallocate.hResource = NULL; 3195 3256 ddiDeallocate.NumAllocations = 1; 3196 ddiDeallocate.HandleList = &hAllocation; 3197 3198 pDevice->pRTCallbacks->pfnDeallocateCb(pDevice->hRTDevice.handle, &ddiDeallocate); 3257 ddiDeallocate.HandleList = &pKMResource->hAllocation; 3258 3259 HRESULT hr = pDevice->pRTCallbacks->pfnDeallocateCb(pDevice->hRTDevice.handle, &ddiDeallocate); 3260 LogFlowFunc(("pfnDeallocateCb returned %d", hr)); 3261 AssertStmt(SUCCEEDED(hr), vboxDXDeviceSetError(pDevice, hr)); 3262 3263 RTMemFree(pKMResource); 3199 3264 } 3200 3265 } … … 3209 3274 AssertReturnStmt(SUCCEEDED(hr), vboxDXDeviceSetError(pDevice, hr), hr); 3210 3275 } 3276 3277 /* Free the staging resources which used for uploads in this command buffer. 3278 * They are moved to the deferred destruction queue. 3279 */ 3280 dxDeallocateStagingResources(pDevice); 3211 3281 3212 3282 /* Process deferred-destruction queue. */ … … 3313 3383 RTListInit(&pDevice->listResources); 3314 3384 RTListInit(&pDevice->listDestroyedResources); 3385 RTListInit(&pDevice->listStagingResources); 3315 3386 RTListInit(&pDevice->listShaders); 3316 3387 RTListInit(&pDevice->listQueries); … … 3415 3486 void vboxDXDestroyDevice(PVBOXDX_DEVICE pDevice) 3416 3487 { 3488 /* Flush will deallocate staging resources. */ 3417 3489 vboxDXFlush(pDevice, true); 3418 3490 3419 3491 PVBOXDXKMRESOURCE pKMResource, pNextKMResource; 3420 3492 RTListForEachSafe(&pDevice->listResources, pKMResource, pNextKMResource, VBOXDXKMRESOURCE, nodeResource) 3421 dxDestroyResource(pDevice, pKMResource->pResource);3493 vboxDXDestroyResource(pDevice, pKMResource->pResource); 3422 3494 3423 3495 dxDestroyDeferredResources(pDevice); -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dx/VBoxDX.h
r98103 r99855 182 182 struct VBOXDX_RESOURCE *pResource; /* The structure allocated by D3D runtime. */ 183 183 D3DKMT_HANDLE hAllocation; 184 RTLISTNODE nodeStaging; /* VBOXDX_DEVICE::listStagingResources if this resource is a staging buffer. */ 184 185 } VBOXDXKMRESOURCE, *PVBOXDXKMRESOURCE; 185 186 … … 198 199 UINT uMap; 199 200 }; 200 struct VBOXDX_RESOURCE *pStagingResource;201 201 202 202 RTLISTANCHOR listSRV; /* Shader resource views created for this resource. */ … … 386 386 RTLISTANCHOR listResources; /* All resources of this device, for cleanup. */ 387 387 RTLISTANCHOR listDestroyedResources; /* DestroyResource adds to this list. Flush actually deleted them. */ 388 RTLISTANCHOR listStagingResources; /* List of staging resources for uploads. */ 388 389 389 390 /* Shaders */ … … 436 437 bool vboxDXOpenResource(PVBOXDX_DEVICE pDevice, PVBOXDX_RESOURCE pResource, 437 438 const D3D10DDIARG_OPENRESOURCE *pOpenResource); 438 boolvboxDXDestroyResource(PVBOXDX_DEVICE pDevice, PVBOXDX_RESOURCE pResource);439 void vboxDXDestroyResource(PVBOXDX_DEVICE pDevice, PVBOXDX_RESOURCE pResource); 439 440 440 441 HRESULT vboxDXRotateResourceIdentities(PVBOXDX_DEVICE pDevice, UINT cResources, PVBOXDX_RESOURCE *papResources);
Note:
See TracChangeset
for help on using the changeset viewer.